Support modifier only shortcuts on X11
Summary: With this change KWin/X11 reuses Wayland's modifier only shortcut architecture. The XInput2 event filter also listens for * XI_RawKeyPress * XI_RawKeyRelease Those events are also reported if another X11 client grabs keyboard input. Thus KWin gets all key events, just like on Wayland. All key events are then sent through the Xkb class which performs the mapping from key codes to key syms and is able to detect whether the modifier got pressed/released without another key being pressed. This change will require a few follow up changes, which are required also for Wayland: * ignore if another input device got interacted (e.g. mouse press, touch screen, scroll, etc) * use the layout from XServer instead of using our own (needed on Wayland in nested setup) The biggest disadvantage of the change is that it triggers a wake up of KWin on every key event. But as KWin already listens to all pointer events that's not a big difference and normally a key event will wake up the compositor any way. Reviewers: #plasma Subscribers: kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D2425
This commit is contained in:
parent
1eac18a8fd
commit
2c333417fa
2 changed files with 24 additions and 7 deletions
21
cursor.cpp
21
cursor.cpp
|
@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
// kwin
|
||||
#include <kwinglobals.h>
|
||||
#include "input.h"
|
||||
#include "keyboard_input.h"
|
||||
#include "main.h"
|
||||
#include "utils.h"
|
||||
#include "x11eventfilter.h"
|
||||
|
@ -42,6 +43,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <X11/Xlib.h>
|
||||
#if HAVE_X11_XINPUT
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#include <X11/extensions/XI2proto.h>
|
||||
#else
|
||||
#define XI_RawMotion 0
|
||||
#endif
|
||||
|
@ -263,14 +265,24 @@ class XInputEventFilter : public X11EventFilter
|
|||
{
|
||||
public:
|
||||
XInputEventFilter(X11Cursor *parent, int xi_opcode)
|
||||
: X11EventFilter(XCB_GE_GENERIC, xi_opcode, QVector<int>{XI_RawMotion, XI_RawButtonPress, XI_RawButtonRelease})
|
||||
: X11EventFilter(XCB_GE_GENERIC, xi_opcode, QVector<int>{XI_RawMotion, XI_RawButtonPress, XI_RawButtonRelease, XI_RawKeyPress, XI_RawKeyRelease})
|
||||
, m_x11Cursor(parent)
|
||||
{}
|
||||
virtual ~XInputEventFilter() = default;
|
||||
|
||||
bool event(xcb_generic_event_t *event) override {
|
||||
Q_UNUSED(event)
|
||||
m_x11Cursor->schedulePoll();
|
||||
xcb_ge_generic_event_t *ge = reinterpret_cast<xcb_ge_generic_event_t *>(event);
|
||||
switch (ge->event_type) {
|
||||
case XI_RawKeyPress:
|
||||
input()->keyboard()->xkb()->updateKey(reinterpret_cast<xXIRawEvent*>(event)->detail - 8, InputRedirection::KeyboardKeyPressed);
|
||||
break;
|
||||
case XI_RawKeyRelease:
|
||||
input()->keyboard()->xkb()->updateKey(reinterpret_cast<xXIRawEvent*>(event)->detail - 8, InputRedirection::KeyboardKeyReleased);
|
||||
break;
|
||||
default:
|
||||
m_x11Cursor->schedulePoll();
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -332,6 +344,7 @@ void X11Cursor::initXInput()
|
|||
}
|
||||
m_hasXInput = true;
|
||||
m_xiOpcode = xi_opcode;
|
||||
input()->keyboard()->xkb()->reconfigure();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
@ -391,6 +404,8 @@ void X11Cursor::doStartMousePolling()
|
|||
XISetMask(mask1, XI_RawMotion);
|
||||
XISetMask(mask1, XI_RawButtonPress);
|
||||
XISetMask(mask1, XI_RawButtonRelease);
|
||||
XISetMask(mask1, XI_RawKeyPress);
|
||||
XISetMask(mask1, XI_RawKeyRelease);
|
||||
|
||||
evmasks[0].deviceid = XIAllMasterDevices;
|
||||
evmasks[0].mask_len = sizeof(mask1);
|
||||
|
|
|
@ -308,10 +308,12 @@ void Xkb::updateModifiers()
|
|||
|
||||
QDBusConnection::sessionBus().asyncCall(msg);
|
||||
}
|
||||
waylandServer()->seat()->updateKeyboardModifiers(xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_DEPRESSED)),
|
||||
xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_LATCHED)),
|
||||
xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_LOCKED)),
|
||||
layout);
|
||||
if (waylandServer()) {
|
||||
waylandServer()->seat()->updateKeyboardModifiers(xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_DEPRESSED)),
|
||||
xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_LATCHED)),
|
||||
xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_LOCKED)),
|
||||
layout);
|
||||
}
|
||||
}
|
||||
|
||||
xkb_keysym_t Xkb::toKeysym(uint32_t key)
|
||||
|
|
Loading…
Reference in a new issue