keyboard mod fixes

This commit is contained in:
Vaxry 2024-06-26 12:30:03 +02:00
parent 12c5de14c8
commit e1adef12f5
6 changed files with 49 additions and 53 deletions

View file

@ -1114,7 +1114,7 @@ std::string switchXKBLayoutRequest(eHyprCtlOutputFormat format, std::string requ
const auto LAYOUTS = xkb_keymap_num_layouts(KEEB->xkbKeymap); const auto LAYOUTS = xkb_keymap_num_layouts(KEEB->xkbKeymap);
xkb_layout_index_t activeLayout = 0; xkb_layout_index_t activeLayout = 0;
while (activeLayout < LAYOUTS) { while (activeLayout < LAYOUTS) {
if (xkb_state_layout_index_is_active(KEEB->xkbTranslationState, activeLayout, XKB_STATE_LAYOUT_EFFECTIVE) == 1) if (xkb_state_layout_index_is_active(KEEB->xkbState, activeLayout, XKB_STATE_LAYOUT_EFFECTIVE) == 1)
break; break;
activeLayout++; activeLayout++;

View file

@ -27,11 +27,11 @@ IKeyboard::~IKeyboard() {
} }
void IKeyboard::clearManuallyAllocd() { void IKeyboard::clearManuallyAllocd() {
if (xkbTranslationState) if (xkbStaticState)
xkb_state_unref(xkbTranslationState); xkb_state_unref(xkbStaticState);
if (xkbInternalTranslationState) if (xkbState)
xkb_state_unref(xkbInternalTranslationState); xkb_state_unref(xkbState);
if (xkbKeymap) if (xkbKeymap)
xkb_keymap_unref(xkbKeymap); xkb_keymap_unref(xkbKeymap);
@ -39,9 +39,10 @@ void IKeyboard::clearManuallyAllocd() {
if (xkbKeymapFD >= 0) if (xkbKeymapFD >= 0)
close(xkbKeymapFD); close(xkbKeymapFD);
xkbKeymap = nullptr; xkbKeymap = nullptr;
xkbTranslationState = nullptr; xkbState = nullptr;
xkbKeymapFD = -1; xkbStaticState = nullptr;
xkbKeymapFD = -1;
} }
void IKeyboard::setKeymap(const SStringRuleNames& rules) { void IKeyboard::setKeymap(const SStringRuleNames& rules) {
@ -99,9 +100,9 @@ void IKeyboard::setKeymap(const SStringRuleNames& rules) {
// set internal translation state // set internal translation state
// demo sunao ni ienai // demo sunao ni ienai
xkbInternalTranslationState = xkb_state_new(xkbKeymap); xkbStaticState = xkb_state_new(xkbKeymap);
updateXKBTranslationState(); updateXKBTranslationState(xkbKeymap);
const auto NUMLOCKON = g_pConfigManager->getDeviceInt(hlName, "numlock_by_default", "input:numlock_by_default"); const auto NUMLOCKON = g_pConfigManager->getDeviceInt(hlName, "numlock_by_default", "input:numlock_by_default");
@ -151,17 +152,17 @@ void IKeyboard::setKeymap(const SStringRuleNames& rules) {
void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) { void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
if (xkbTranslationState) if (xkbState)
xkb_state_unref(xkbTranslationState); xkb_state_unref(xkbState);
if (keymap) { if (keymap) {
Debug::log(LOG, "Updating keyboard {:x}'s translation state from a provided keymap", (uintptr_t)this); Debug::log(LOG, "Updating keyboard {:x}'s translation state from a provided keymap", (uintptr_t)this);
xkbTranslationState = xkb_state_new(keymap); xkbState = xkb_state_new(keymap);
return; return;
} }
const auto KEYMAP = xkbKeymap; const auto KEYMAP = xkbKeymap;
const auto STATE = xkbInternalTranslationState; const auto STATE = xkbState;
const auto LAYOUTSNUM = xkb_keymap_num_layouts(KEYMAP); const auto LAYOUTSNUM = xkb_keymap_num_layouts(KEYMAP);
const auto PCONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS); const auto PCONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
@ -200,7 +201,7 @@ void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
} }
xkbTranslationState = xkb_state_new(KEYMAP); xkbState = xkb_state_new(KEYMAP);
xkb_keymap_unref(KEYMAP); xkb_keymap_unref(KEYMAP);
xkb_context_unref(PCONTEXT); xkb_context_unref(PCONTEXT);
@ -221,7 +222,7 @@ void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
const auto NEWKEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); const auto NEWKEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
xkbTranslationState = xkb_state_new(NEWKEYMAP); xkbState = xkb_state_new(NEWKEYMAP);
xkb_keymap_unref(NEWKEYMAP); xkb_keymap_unref(NEWKEYMAP);
xkb_context_unref(PCONTEXT); xkb_context_unref(PCONTEXT);
@ -229,7 +230,7 @@ void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
std::string IKeyboard::getActiveLayout() { std::string IKeyboard::getActiveLayout() {
const auto KEYMAP = xkbKeymap; const auto KEYMAP = xkbKeymap;
const auto STATE = xkbTranslationState; const auto STATE = xkbState;
const auto LAYOUTSNUM = xkb_keymap_num_layouts(KEYMAP); const auto LAYOUTSNUM = xkb_keymap_num_layouts(KEYMAP);
for (uint32_t i = 0; i < LAYOUTSNUM; ++i) { for (uint32_t i = 0; i < LAYOUTSNUM; ++i) {
@ -246,12 +247,12 @@ std::string IKeyboard::getActiveLayout() {
} }
void IKeyboard::updateLEDs() { void IKeyboard::updateLEDs() {
if (xkbTranslationState == nullptr) if (xkbState == nullptr)
return; return;
uint32_t leds = 0; uint32_t leds = 0;
for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) { for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) {
if (xkb_state_led_index_is_active(xkbTranslationState, ledIndexes.at(i))) if (xkb_state_led_index_is_active(xkbState, ledIndexes.at(i)))
leds |= (1 << i); leds |= (1 << i);
} }
@ -259,7 +260,7 @@ void IKeyboard::updateLEDs() {
} }
void IKeyboard::updateLEDs(uint32_t leds) { void IKeyboard::updateLEDs(uint32_t leds) {
if (!xkbTranslationState) if (!xkbState)
return; return;
if (isVirtual() && g_pInputManager->shouldIgnoreVirtualKeyboard(self.lock())) if (isVirtual() && g_pInputManager->shouldIgnoreVirtualKeyboard(self.lock()))
@ -288,10 +289,10 @@ uint32_t IKeyboard::getModifiers() {
} }
void IKeyboard::updateModifiers(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group) { void IKeyboard::updateModifiers(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group) {
if (!xkbTranslationState) if (!xkbState)
return; return;
xkb_state_update_mask(xkbTranslationState, depressed, latched, locked, 0, 0, group); xkb_state_update_mask(xkbState, depressed, latched, locked, 0, 0, group);
if (!updateModifiersState()) if (!updateModifiersState())
return; return;
@ -300,13 +301,13 @@ void IKeyboard::updateModifiers(uint32_t depressed, uint32_t latched, uint32_t l
} }
bool IKeyboard::updateModifiersState() { bool IKeyboard::updateModifiersState() {
if (!xkbTranslationState) if (!xkbState)
return false; return false;
auto depressed = xkb_state_serialize_mods(xkbTranslationState, XKB_STATE_MODS_DEPRESSED); auto depressed = xkb_state_serialize_mods(xkbState, XKB_STATE_MODS_DEPRESSED);
auto latched = xkb_state_serialize_mods(xkbTranslationState, XKB_STATE_MODS_LATCHED); auto latched = xkb_state_serialize_mods(xkbState, XKB_STATE_MODS_LATCHED);
auto locked = xkb_state_serialize_mods(xkbTranslationState, XKB_STATE_MODS_LOCKED); auto locked = xkb_state_serialize_mods(xkbState, XKB_STATE_MODS_LOCKED);
auto group = xkb_state_serialize_layout(xkbTranslationState, XKB_STATE_LAYOUT_EFFECTIVE); auto group = xkb_state_serialize_layout(xkbState, XKB_STATE_LAYOUT_EFFECTIVE);
if (depressed == modifiersState.depressed && latched == modifiersState.latched && locked == modifiersState.locked && group == modifiersState.group) if (depressed == modifiersState.depressed && latched == modifiersState.latched && locked == modifiersState.locked && group == modifiersState.group)
return false; return false;
@ -318,3 +319,15 @@ bool IKeyboard::updateModifiersState() {
return true; return true;
} }
void IKeyboard::updateXkbStateWithKey(uint32_t xkbKey, bool pressed) {
xkb_state_update_key(xkbState, xkbKey, pressed ? XKB_KEY_DOWN : XKB_KEY_UP);
if (updateModifiersState()) {
keyboardEvents.modifiers.emit(SModifiersEvent{
.depressed = modifiersState.depressed,
.latched = modifiersState.latched,
.locked = modifiersState.locked,
.group = modifiersState.group,
});
}
}

View file

@ -58,12 +58,13 @@ class IKeyboard : public IHID {
uint32_t getModifiers(); uint32_t getModifiers();
void updateModifiers(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group); void updateModifiers(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group);
bool updateModifiersState(); // rets whether changed bool updateModifiersState(); // rets whether changed
void updateXkbStateWithKey(uint32_t xkbKey, bool pressed);
bool active = false; bool active = false;
bool enabled = true; bool enabled = true;
xkb_layout_index_t activeLayout = 0; xkb_layout_index_t activeLayout = 0;
xkb_state * xkbTranslationState = nullptr, *xkbInternalTranslationState = nullptr; xkb_state * xkbState = nullptr, *xkbStaticState /* Static state: never gets modifiers or layout changes sent, used for keybinds. */ = nullptr;
xkb_keymap* xkbKeymap = nullptr; xkb_keymap* xkbKeymap = nullptr;
struct { struct {

View file

@ -32,12 +32,7 @@ CKeyboard::CKeyboard(SP<Aquamarine::IKeyboard> keeb) : keyboard(keeb) {
listeners.key = keeb->events.key.registerListener([this](std::any d) { listeners.key = keeb->events.key.registerListener([this](std::any d) {
auto E = std::any_cast<Aquamarine::IKeyboard::SKeyEvent>(d); auto E = std::any_cast<Aquamarine::IKeyboard::SKeyEvent>(d);
uint32_t xkbKeycode = E.key + 8; updateXkbStateWithKey(E.key + 8, E.pressed);
xkb_state_update_key(xkbTranslationState, xkbKeycode, E.pressed ? XKB_KEY_DOWN : XKB_KEY_UP);
// we have to do this for DRM sessions, as they never send modifiers events
if (g_pCompositor->m_pAqBackend->hasSession())
updateModifiersState();
keyboardEvents.key.emit(SKeyEvent{ keyboardEvents.key.emit(SKeyEvent{
.timeMs = E.timeMs, .timeMs = E.timeMs,

View file

@ -366,8 +366,8 @@ bool CKeybindManager::onKeyEvent(std::any event, SP<IKeyboard> pKeyboard) {
const auto KEYCODE = e.keycode + 8; // Because to xkbcommon it's +8 from libinput const auto KEYCODE = e.keycode + 8; // Because to xkbcommon it's +8 from libinput
const xkb_keysym_t keysym = xkb_state_key_get_one_sym(pKeyboard->resolveBindsBySym ? pKeyboard->xkbTranslationState : m_pXKBTranslationState, KEYCODE); const xkb_keysym_t keysym = xkb_state_key_get_one_sym(pKeyboard->resolveBindsBySym ? pKeyboard->xkbStaticState : m_pXKBTranslationState, KEYCODE);
const xkb_keysym_t internalKeysym = xkb_state_key_get_one_sym(pKeyboard->xkbInternalTranslationState, KEYCODE); const xkb_keysym_t internalKeysym = xkb_state_key_get_one_sym(pKeyboard->xkbState, KEYCODE);
if (handleInternalKeybinds(internalKeysym)) if (handleInternalKeybinds(internalKeysym))
return true; return true;
@ -2121,7 +2121,7 @@ void CKeybindManager::sendshortcut(std::string args) {
if (!g_pKeybindManager->m_mKeyToCodeCache.contains(KEYPAIRSTRING)) { if (!g_pKeybindManager->m_mKeyToCodeCache.contains(KEYPAIRSTRING)) {
xkb_keymap* km = KB->xkbKeymap; xkb_keymap* km = KB->xkbKeymap;
xkb_state* ks = KB->xkbTranslationState; xkb_state* ks = KB->xkbState;
xkb_keycode_t keycode_min, keycode_max; xkb_keycode_t keycode_min, keycode_max;
keycode_min = xkb_keymap_min_keycode(km); keycode_min = xkb_keymap_min_keycode(km);

View file

@ -1156,10 +1156,6 @@ static void removeFromHIDs(WP<IHID> hid) {
} }
void CInputManager::destroyKeyboard(SP<IKeyboard> pKeyboard) { void CInputManager::destroyKeyboard(SP<IKeyboard> pKeyboard) {
if (pKeyboard->xkbTranslationState)
xkb_state_unref(pKeyboard->xkbTranslationState);
pKeyboard->xkbTranslationState = nullptr;
std::erase_if(m_vKeyboards, [pKeyboard](const auto& other) { return other == pKeyboard; }); std::erase_if(m_vKeyboards, [pKeyboard](const auto& other) { return other == pKeyboard; });
if (m_vKeyboards.size() > 0) { if (m_vKeyboards.size() > 0) {
@ -1225,19 +1221,10 @@ void CInputManager::destroyTabletPad(SP<CTabletPad> pad) {
} }
void CInputManager::updateKeyboardsLeds(SP<IKeyboard> pKeyboard) { void CInputManager::updateKeyboardsLeds(SP<IKeyboard> pKeyboard) {
if (!pKeyboard || !pKeyboard->xkbTranslationState) if (!pKeyboard)
return; return;
// FIXME: pKeyboard->updateLEDs();
// uint32_t leds = 0;
// for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) {
// if (xkb_state_led_index_is_active(pKeyboard->xkbTranslationState, keyboard->led_indexes[i]))
// leds |= (1 << i);
// }
// for (auto& k : m_vKeyboards) {
// k->updateLEDs(leds);
// }
} }
void CInputManager::onKeyboardKey(std::any event, SP<IKeyboard> pKeyboard) { void CInputManager::onKeyboardKey(std::any event, SP<IKeyboard> pKeyboard) {