From 199cad52f0599872e57a2fcb391a459e48146be0 Mon Sep 17 00:00:00 2001 From: David Faure Date: Sun, 31 Jan 2021 20:59:41 +0100 Subject: [PATCH] Compress notifications about new mouse/keyboard. When resuming from suspend, I get 5 "new pointer" and 5 "new keyboard" events (on a laptop with USB mouse/keyboard, but also stuff like "Thinkpad Extra Buttons" adds more notifications than one would expect) KGlobalAccelImpl::x11MappingNotify is still called 15 times, but that's better than 145 times... "new pointer" notifications end up calling `kcminit mouse`, better also compress that. --- kcms/keyboard/xinput_helper.cpp | 30 +++++++++++++++++++++++++----- kcms/keyboard/xinput_helper.h | 5 ++++- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/kcms/keyboard/xinput_helper.cpp b/kcms/keyboard/xinput_helper.cpp index 14974ada7..bade5ea33 100644 --- a/kcms/keyboard/xinput_helper.cpp +++ b/kcms/keyboard/xinput_helper.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -56,9 +57,21 @@ static const int DEVICE_POINTER = 2; XInputEventNotifier::XInputEventNotifier(QWidget* parent): XEventNotifier(), //TODO: destruct properly? xinputEventType(-1), - udevNotifier(nullptr) + udevNotifier(nullptr), + keyboardNotificationTimer(new QTimer(this)), + mouseNotificationTimer(new QTimer(this)) { - Q_UNUSED(parent) + Q_UNUSED(parent) + + // emit signal only once, even after X11 re-enables N keyboards after resuming from suspend + keyboardNotificationTimer->setSingleShot(true); + keyboardNotificationTimer->setInterval(500); + connect(keyboardNotificationTimer, &QTimer::timeout, this, &XInputEventNotifier::newKeyboardDevice); + + // same for mouse + mouseNotificationTimer->setSingleShot(true); + mouseNotificationTimer->setInterval(500); + connect(mouseNotificationTimer, &QTimer::timeout, this, &XInputEventNotifier::newPointerDevice); } void XInputEventNotifier::start() @@ -83,11 +96,18 @@ bool XInputEventNotifier::processOtherEvents(xcb_generic_event_t* event) { int newDeviceType = getNewDeviceEventType(event); if( newDeviceType == DEVICE_KEYBOARD ) { - emit(newKeyboardDevice()); + if (!keyboardNotificationTimer->isActive()) { + keyboardNotificationTimer->start(); + } } else if( newDeviceType == DEVICE_POINTER ) { - emit(newPointerDevice()); - emit(newKeyboardDevice()); // arghhh, looks like X resets xkb map even when only pointer device is connected + if (!mouseNotificationTimer->isActive()) { + mouseNotificationTimer->start(); + } + // arghhh, looks like X resets xkb map even when only pointer device is connected + if (!keyboardNotificationTimer->isActive()) { + keyboardNotificationTimer->start(); + } } return true; } diff --git a/kcms/keyboard/xinput_helper.h b/kcms/keyboard/xinput_helper.h index e29fdc22a..52b6a12b4 100644 --- a/kcms/keyboard/xinput_helper.h +++ b/kcms/keyboard/xinput_helper.h @@ -25,13 +25,14 @@ #include #include +class QTimer; class UdevDeviceNotifier; class XInputEventNotifier: public XEventNotifier { Q_OBJECT public: - XInputEventNotifier(QWidget* parent=nullptr); + explicit XInputEventNotifier(QWidget* parent=nullptr); void start() override; void stop() override; @@ -51,6 +52,8 @@ private: int xinputEventType; Display* display; UdevDeviceNotifier *udevNotifier; + QTimer* keyboardNotificationTimer; + QTimer* mouseNotificationTimer; }; #endif /* XINPUT_HELPER_H_ */ -- GitLab