keyboard mod fixes

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

View file

@ -1141,7 +1141,7 @@ std::string switchXKBLayoutRequest(eHyprCtlOutputFormat format, std::string requ
const auto LAYOUTS = xkb_keymap_num_layouts(KEEB->xkbKeymap);
xkb_layout_index_t activeLayout = 0;
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;
activeLayout++;

View file

@ -27,11 +27,11 @@ IKeyboard::~IKeyboard() {
}
void IKeyboard::clearManuallyAllocd() {
if (xkbTranslationState)
xkb_state_unref(xkbTranslationState);
if (xkbStaticState)
xkb_state_unref(xkbStaticState);
if (xkbInternalTranslationState)
xkb_state_unref(xkbInternalTranslationState);
if (xkbState)
xkb_state_unref(xkbState);
if (xkbKeymap)
xkb_keymap_unref(xkbKeymap);
@ -40,7 +40,8 @@ void IKeyboard::clearManuallyAllocd() {
close(xkbKeymapFD);
xkbKeymap = nullptr;
xkbTranslationState = nullptr;
xkbState = nullptr;
xkbStaticState = nullptr;
xkbKeymapFD = -1;
}
@ -99,9 +100,9 @@ void IKeyboard::setKeymap(const SStringRuleNames& rules) {
// set internal translation state
// 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");
@ -151,17 +152,17 @@ void IKeyboard::setKeymap(const SStringRuleNames& rules) {
void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
if (xkbTranslationState)
xkb_state_unref(xkbTranslationState);
if (xkbState)
xkb_state_unref(xkbState);
if (keymap) {
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;
}
const auto KEYMAP = xkbKeymap;
const auto STATE = xkbInternalTranslationState;
const auto STATE = xkbState;
const auto LAYOUTSNUM = xkb_keymap_num_layouts(KEYMAP);
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);
}
xkbTranslationState = xkb_state_new(KEYMAP);
xkbState = xkb_state_new(KEYMAP);
xkb_keymap_unref(KEYMAP);
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);
xkbTranslationState = xkb_state_new(NEWKEYMAP);
xkbState = xkb_state_new(NEWKEYMAP);
xkb_keymap_unref(NEWKEYMAP);
xkb_context_unref(PCONTEXT);
@ -229,7 +230,7 @@ void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
std::string IKeyboard::getActiveLayout() {
const auto KEYMAP = xkbKeymap;
const auto STATE = xkbTranslationState;
const auto STATE = xkbState;
const auto LAYOUTSNUM = xkb_keymap_num_layouts(KEYMAP);
for (uint32_t i = 0; i < LAYOUTSNUM; ++i) {
@ -246,12 +247,12 @@ std::string IKeyboard::getActiveLayout() {
}
void IKeyboard::updateLEDs() {
if (xkbTranslationState == nullptr)
if (xkbState == nullptr)
return;
uint32_t leds = 0;
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);
}
@ -259,7 +260,7 @@ void IKeyboard::updateLEDs() {
}
void IKeyboard::updateLEDs(uint32_t leds) {
if (!xkbTranslationState)
if (!xkbState)
return;
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) {
if (!xkbTranslationState)
if (!xkbState)
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())
return;
@ -300,13 +301,13 @@ void IKeyboard::updateModifiers(uint32_t depressed, uint32_t latched, uint32_t l
}
bool IKeyboard::updateModifiersState() {
if (!xkbTranslationState)
if (!xkbState)
return false;
auto depressed = xkb_state_serialize_mods(xkbTranslationState, XKB_STATE_MODS_DEPRESSED);
auto latched = xkb_state_serialize_mods(xkbTranslationState, XKB_STATE_MODS_LATCHED);
auto locked = xkb_state_serialize_mods(xkbTranslationState, XKB_STATE_MODS_LOCKED);
auto group = xkb_state_serialize_layout(xkbTranslationState, XKB_STATE_LAYOUT_EFFECTIVE);
auto depressed = xkb_state_serialize_mods(xkbState, XKB_STATE_MODS_DEPRESSED);
auto latched = xkb_state_serialize_mods(xkbState, XKB_STATE_MODS_LATCHED);
auto locked = xkb_state_serialize_mods(xkbState, XKB_STATE_MODS_LOCKED);
auto group = xkb_state_serialize_layout(xkbState, XKB_STATE_LAYOUT_EFFECTIVE);
if (depressed == modifiersState.depressed && latched == modifiersState.latched && locked == modifiersState.locked && group == modifiersState.group)
return false;
@ -318,3 +319,15 @@ bool IKeyboard::updateModifiersState() {
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();
void updateModifiers(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group);
bool updateModifiersState(); // rets whether changed
void updateXkbStateWithKey(uint32_t xkbKey, bool pressed);
bool active = false;
bool enabled = true;
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;
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) {
auto E = std::any_cast<Aquamarine::IKeyboard::SKeyEvent>(d);
uint32_t xkbKeycode = E.key + 8;
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();
updateXkbStateWithKey(E.key + 8, E.pressed);
keyboardEvents.key.emit(SKeyEvent{
.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 xkb_keysym_t keysym = xkb_state_key_get_one_sym(pKeyboard->resolveBindsBySym ? pKeyboard->xkbTranslationState : m_pXKBTranslationState, KEYCODE);
const xkb_keysym_t internalKeysym = xkb_state_key_get_one_sym(pKeyboard->xkbInternalTranslationState, 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->xkbState, KEYCODE);
if (handleInternalKeybinds(internalKeysym))
return true;
@ -2121,7 +2121,7 @@ void CKeybindManager::sendshortcut(std::string args) {
if (!g_pKeybindManager->m_mKeyToCodeCache.contains(KEYPAIRSTRING)) {
xkb_keymap* km = KB->xkbKeymap;
xkb_state* ks = KB->xkbTranslationState;
xkb_state* ks = KB->xkbState;
xkb_keycode_t keycode_min, keycode_max;
keycode_min = xkb_keymap_min_keycode(km);

View file

@ -1192,10 +1192,6 @@ static void removeFromHIDs(WP<IHID> hid) {
}
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; });
if (m_vKeyboards.size() > 0) {
@ -1261,19 +1257,10 @@ void CInputManager::destroyTabletPad(SP<CTabletPad> pad) {
}
void CInputManager::updateKeyboardsLeds(SP<IKeyboard> pKeyboard) {
if (!pKeyboard || !pKeyboard->xkbTranslationState)
if (!pKeyboard)
return;
// FIXME:
// 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);
// }
pKeyboard->updateLEDs();
}
void CInputManager::onKeyboardKey(std::any event, SP<IKeyboard> pKeyboard) {