mirror of
https://github.com/hyprwm/Hyprland
synced 2025-12-20 09:10:08 +01:00
IME: do not share keys/mods states from grabbed keyboards with ime keys/mods (#11917)
This commit is contained in:
parent
05aa4e1c54
commit
88e34d7dd2
1 changed files with 36 additions and 11 deletions
|
|
@ -1451,16 +1451,34 @@ void CInputManager::onKeyboardKey(const IKeyboard::SKeyEvent& event, SP<IKeyboar
|
||||||
passEvent = g_pKeybindManager->onKeyEvent(event, pKeyboard);
|
passEvent = g_pKeybindManager->onKeyEvent(event, pKeyboard);
|
||||||
|
|
||||||
if (passEvent) {
|
if (passEvent) {
|
||||||
|
auto state = event.state;
|
||||||
|
auto pressed = state == WL_KEYBOARD_KEY_STATE_PRESSED;
|
||||||
|
|
||||||
|
// use merged keys states when sending to ime or when sending to seat with no ime
|
||||||
|
// if passing from ime, send keys directly without merging
|
||||||
|
if (USEIME || !HASIME) {
|
||||||
|
const auto ANYPRESSED = shareKeyFromAllKBs(event.keycode, pressed);
|
||||||
|
|
||||||
|
// do not turn released event into pressed event (when one keyboard has a key released but some
|
||||||
|
// other keyboard still has the key pressed)
|
||||||
|
// maybe we should keep track of pressed keys for inputs like m_pressed for seat outputs below,
|
||||||
|
// to avoid duplicate pressed events, but this should work well enough
|
||||||
|
if (!pressed && ANYPRESSED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pressed = ANYPRESSED;
|
||||||
|
state = pressed ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED;
|
||||||
|
}
|
||||||
|
|
||||||
if (USEIME) {
|
if (USEIME) {
|
||||||
IME->setKeyboard(pKeyboard);
|
IME->setKeyboard(pKeyboard);
|
||||||
IME->sendKey(event.timeMs, event.keycode, event.state);
|
IME->sendKey(event.timeMs, event.keycode, state);
|
||||||
} else {
|
} else {
|
||||||
const auto PRESSED = shareKeyFromAllKBs(event.keycode, event.state == WL_KEYBOARD_KEY_STATE_PRESSED);
|
|
||||||
const auto CONTAINS = std::ranges::contains(m_pressed, event.keycode);
|
const auto CONTAINS = std::ranges::contains(m_pressed, event.keycode);
|
||||||
|
|
||||||
if (CONTAINS && PRESSED)
|
if (CONTAINS && pressed)
|
||||||
return;
|
return;
|
||||||
if (!CONTAINS && !PRESSED)
|
if (!CONTAINS && !pressed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (CONTAINS)
|
if (CONTAINS)
|
||||||
|
|
@ -1469,7 +1487,7 @@ void CInputManager::onKeyboardKey(const IKeyboard::SKeyEvent& event, SP<IKeyboar
|
||||||
m_pressed.emplace_back(event.keycode);
|
m_pressed.emplace_back(event.keycode);
|
||||||
|
|
||||||
g_pSeatManager->setKeyboard(pKeyboard);
|
g_pSeatManager->setKeyboard(pKeyboard);
|
||||||
g_pSeatManager->sendKeyboardKey(event.timeMs, event.keycode, event.state);
|
g_pSeatManager->sendKeyboardKey(event.timeMs, event.keycode, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateKeyboardsLeds(pKeyboard);
|
updateKeyboardsLeds(pKeyboard);
|
||||||
|
|
@ -1482,14 +1500,21 @@ void CInputManager::onKeyboardMod(SP<IKeyboard> pKeyboard) {
|
||||||
|
|
||||||
const bool DISALLOWACTION = pKeyboard->isVirtual() && shouldIgnoreVirtualKeyboard(pKeyboard);
|
const bool DISALLOWACTION = pKeyboard->isVirtual() && shouldIgnoreVirtualKeyboard(pKeyboard);
|
||||||
|
|
||||||
|
const auto IME = m_relay.m_inputMethod.lock();
|
||||||
|
const bool HASIME = IME && IME->hasGrab();
|
||||||
|
const bool USEIME = HASIME && !DISALLOWACTION;
|
||||||
|
|
||||||
auto MODS = pKeyboard->m_modifiersState;
|
auto MODS = pKeyboard->m_modifiersState;
|
||||||
|
|
||||||
|
// use merged mods states when sending to ime or when sending to seat with no ime
|
||||||
|
// if passing from ime, send mods directly without merging
|
||||||
|
if (USEIME || !HASIME) {
|
||||||
const auto ALLMODS = shareModsFromAllKBs(MODS.depressed);
|
const auto ALLMODS = shareModsFromAllKBs(MODS.depressed);
|
||||||
MODS.depressed = ALLMODS;
|
MODS.depressed = ALLMODS;
|
||||||
m_lastMods = MODS.depressed;
|
m_lastMods = MODS.depressed; // for hyprland keybinds use; not for sending to seat
|
||||||
|
}
|
||||||
|
|
||||||
const auto IME = m_relay.m_inputMethod.lock();
|
if (USEIME) {
|
||||||
|
|
||||||
if (IME && IME->hasGrab() && !DISALLOWACTION) {
|
|
||||||
IME->setKeyboard(pKeyboard);
|
IME->setKeyboard(pKeyboard);
|
||||||
IME->sendMods(MODS.depressed, MODS.latched, MODS.locked, MODS.group);
|
IME->sendMods(MODS.depressed, MODS.latched, MODS.locked, MODS.group);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue