mirror of
https://github.com/hyprwm/Hyprland
synced 2024-12-18 18:29:48 +01:00
seat: avoid sending pointless 'keymap' and 'repeat_info' events (#8276)
#### Describe your PR, what does it fix/add? Fix lag spikes when pressing more than 6 keys at the same time. #### Is there anything you want to mention? (unchecked code, possible bugs, found problems, breaking compatibility, etc.) Debugging process: <details> This is triggered by typing some applications, like CopyQ or XWayland. Typing in Firefox doesn't lead to lag, however it itself does lag handling these events. Profiling CopyQ shows that paths leading to `QtWaylandClient::QWaylandInputDevice::Keyboard::keyboard` take over 80% of processing time of an otherwise idle program. Looking at output of 'wev' even when it's not focused shows same events received over and over again. ``` [14: wl_keyboard] repeat_info: rate: 25 keys/sec; delay: 300 ms [14: wl_keyboard] keymap: format: 1 (xkb v1), size: 64754 ``` Looking at what passes through CInputManager::onKeyboardKey() -> CSeatManager::setKeyboard() shows Hyprland 'switching' between endpoints of the same keyboard, one of them being named like the other but with '-1' suffix. </details> Tested changing layouts in Fcitx5 and with following config. ``` input:kb_layout = us,cz input:kb_variant = ,qwerty input:kb_options = grp:alt_shift_toggle ``` Also tested changing 'input:repeat_delay' while running. Curiously, now these events appear in the output of 'wev' only once. Changing layouts still seems to work fine though. #### Is it ready for merging, or does it need work? Ready for merging.
This commit is contained in:
parent
7188ee4f99
commit
d679d20029
2 changed files with 22 additions and 6 deletions
|
@ -317,12 +317,13 @@ void CWLKeyboardResource::sendKeymap(SP<IKeyboard> keyboard) {
|
|||
if (!(PROTO::seat->currentCaps & eHIDCapabilityType::HID_INPUT_CAPABILITY_KEYBOARD))
|
||||
return;
|
||||
|
||||
wl_keyboard_keymap_format format = keyboard ? WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1 : WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP;
|
||||
int fd;
|
||||
uint32_t size;
|
||||
std::string_view keymap;
|
||||
int fd;
|
||||
uint32_t size;
|
||||
if (keyboard) {
|
||||
fd = keyboard->xkbKeymapFD;
|
||||
size = keyboard->xkbKeymapString.length() + 1;
|
||||
keymap = keyboard->xkbKeymapString;
|
||||
fd = keyboard->xkbKeymapFD;
|
||||
size = keyboard->xkbKeymapString.length() + 1;
|
||||
} else {
|
||||
fd = open("/dev/null", O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
|
@ -332,6 +333,15 @@ void CWLKeyboardResource::sendKeymap(SP<IKeyboard> keyboard) {
|
|||
size = 0;
|
||||
}
|
||||
|
||||
if (keymap == lastKeymap) {
|
||||
if (!keyboard)
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
lastKeymap = keymap;
|
||||
|
||||
const wl_keyboard_keymap_format format = keyboard ? WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1 : WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP;
|
||||
|
||||
resource->sendKeymap(format, fd, size);
|
||||
|
||||
if (!keyboard)
|
||||
|
@ -396,8 +406,10 @@ void CWLKeyboardResource::sendMods(uint32_t depressed, uint32_t latched, uint32_
|
|||
}
|
||||
|
||||
void CWLKeyboardResource::repeatInfo(uint32_t rate, uint32_t delayMs) {
|
||||
if (!owner || resource->version() < 4)
|
||||
if (!owner || resource->version() < 4 || (rate == lastRate && delayMs == lastDelayMs))
|
||||
return;
|
||||
lastRate = rate;
|
||||
lastDelayMs = delayMs;
|
||||
|
||||
resource->sendRepeatInfo(rate, delayMs);
|
||||
}
|
||||
|
|
|
@ -119,6 +119,10 @@ class CWLKeyboardResource {
|
|||
struct {
|
||||
CHyprSignalListener destroySurface;
|
||||
} listeners;
|
||||
|
||||
std::string lastKeymap = "<none>";
|
||||
uint32_t lastRate = 0;
|
||||
uint32_t lastDelayMs = 0;
|
||||
};
|
||||
|
||||
class CWLSeatResource {
|
||||
|
|
Loading…
Reference in a new issue