InputRedirection for keyboard events
Major new functionality is xkbcommon support. InputRedirection holds an instance to a small wrapper class which has the xkb context, keymap and state. The keymap is initialied from the file descriptor we get from the Wayland backend. InputRedirection uses this to translate the keycodes into keysymbols and to QString and to track the modifiers as provided by the Qt::KeybordModifiers flags. This provides us enough information for internal usage (e.g. pass through effects if they have "grabbed" the keyboard). If KWin doesn't filter out the key events, it passes them on to the currently active Client respectively an unmanaged on top of the stack. This needs still some improvement (not each unmanaged should get the event). The Client/Unmnaged still uses xtest extension to send the key events to the window. So keylogging is still possible.icc-effect-5.14.5
parent
104e89aff2
commit
6baf794f88
|
@ -61,6 +61,11 @@ configure_file(libkwineffects/kwinconfig.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/lib
|
|||
# for kwin internal things
|
||||
set(HAVE_WAYLAND ${Wayland_Client_FOUND})
|
||||
set(HAVE_WAYLAND_EGL ${Wayland_Egl_FOUND} AND ${Wayland_Client_FOUND})
|
||||
if(${HAVE_WAYLAND})
|
||||
set(HAVE_XKB ${XKB_FOUND})
|
||||
else()
|
||||
set(HAVE_XKB FALSE)
|
||||
endif()
|
||||
configure_file(config-kwin.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kwin.h )
|
||||
|
||||
|
||||
|
|
10
client.cpp
10
client.cpp
|
@ -2586,6 +2586,16 @@ void Client::sendPointerAxisEvent(InputRedirection::PointerAxis axis, qreal delt
|
|||
}
|
||||
}
|
||||
|
||||
void Client::sendKeybordKeyEvent(uint32_t key, InputRedirection::KeyboardKeyState state)
|
||||
{
|
||||
// TODO: don't use xtest
|
||||
uint8_t type = XCB_KEY_PRESS;
|
||||
if (state == InputRedirection::KeyboardKeyReleased) {
|
||||
type = XCB_KEY_RELEASE;
|
||||
}
|
||||
xcb_test_fake_input(connection(), type, key + 8, XCB_TIME_CURRENT_TIME, frameId(), 0, 0, 0);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "client.moc"
|
||||
|
|
1
client.h
1
client.h
|
@ -656,6 +656,7 @@ public:
|
|||
|
||||
void sendPointerButtonEvent(uint32_t button, InputRedirection::PointerButtonState state) override;
|
||||
void sendPointerAxisEvent(InputRedirection::PointerAxis axis, qreal delta) override;
|
||||
void sendKeybordKeyEvent(uint32_t key, InputRedirection::KeyboardKeyState state) override;
|
||||
|
||||
public Q_SLOTS:
|
||||
void closeWindow();
|
||||
|
|
|
@ -10,3 +10,4 @@
|
|||
#define KWIN_VERSION_STRING "${KDE4WORKSPACE_VERSION}"
|
||||
#cmakedefine01 HAVE_WAYLAND
|
||||
#cmakedefine01 HAVE_WAYLAND_EGL
|
||||
#cmakedefine01 HAVE_XKB
|
||||
|
|
12
effects.cpp
12
effects.cpp
|
@ -741,9 +741,11 @@ bool EffectsHandlerImpl::grabKeyboard(Effect* effect)
|
|||
{
|
||||
if (keyboard_grab_effect != NULL)
|
||||
return false;
|
||||
bool ret = grabXKeyboard();
|
||||
if (!ret)
|
||||
return false;
|
||||
if (kwinApp()->operationMode() == Application::OperationModeX11) {
|
||||
bool ret = grabXKeyboard();
|
||||
if (!ret)
|
||||
return false;
|
||||
}
|
||||
keyboard_grab_effect = effect;
|
||||
return true;
|
||||
}
|
||||
|
@ -751,7 +753,9 @@ bool EffectsHandlerImpl::grabKeyboard(Effect* effect)
|
|||
void EffectsHandlerImpl::ungrabKeyboard()
|
||||
{
|
||||
assert(keyboard_grab_effect != NULL);
|
||||
ungrabXKeyboard();
|
||||
if (kwinApp()->operationMode() == Application::OperationModeX11) {
|
||||
ungrabXKeyboard();
|
||||
}
|
||||
keyboard_grab_effect = NULL;
|
||||
}
|
||||
|
||||
|
|
183
input.cpp
183
input.cpp
|
@ -22,18 +22,140 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "effects.h"
|
||||
#include "unmanaged.h"
|
||||
#include "workspace.h"
|
||||
// KDE
|
||||
#include <kkeyserver.h>
|
||||
// TODO: remove xtest
|
||||
#include <xcb/xtest.h>
|
||||
// system
|
||||
#include <linux/input.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
#if HAVE_XKB
|
||||
Xkb::Xkb()
|
||||
: m_context(xkb_context_new(static_cast<xkb_context_flags>(0)))
|
||||
, m_keymap(NULL)
|
||||
, m_state(NULL)
|
||||
, m_shiftModifier(0)
|
||||
, m_controlModifier(0)
|
||||
, m_altModifier(0)
|
||||
, m_metaModifier(0)
|
||||
, m_modifiers(Qt::NoModifier)
|
||||
{
|
||||
if (!m_context) {
|
||||
qDebug() << "Could not create xkb context";
|
||||
}
|
||||
}
|
||||
|
||||
Xkb::~Xkb()
|
||||
{
|
||||
xkb_state_unref(m_state);
|
||||
xkb_keymap_unref(m_keymap);
|
||||
xkb_context_unref(m_context);
|
||||
}
|
||||
|
||||
void Xkb::installKeymap(int fd, uint32_t size)
|
||||
{
|
||||
if (!m_context) {
|
||||
return;
|
||||
}
|
||||
char *map = reinterpret_cast<char*>(mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0));
|
||||
if (map == MAP_FAILED) {
|
||||
return;
|
||||
}
|
||||
xkb_keymap *keymap = xkb_keymap_new_from_string(m_context, map, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_MAP_COMPILE_PLACEHOLDER);
|
||||
munmap(map, size);
|
||||
if (!keymap) {
|
||||
qDebug() << "Could not map keymap from file";
|
||||
return;
|
||||
}
|
||||
xkb_state *state = xkb_state_new(keymap);
|
||||
if (!state) {
|
||||
qDebug() << "Could not create XKB state";
|
||||
xkb_keymap_unref(keymap);
|
||||
return;
|
||||
}
|
||||
// now release the old ones
|
||||
xkb_state_unref(m_state);
|
||||
xkb_keymap_unref(m_keymap);
|
||||
|
||||
m_keymap = keymap;
|
||||
m_state = state;
|
||||
|
||||
m_shiftModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_SHIFT);
|
||||
m_controlModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_CTRL);
|
||||
m_altModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_ALT);
|
||||
m_metaModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_LOGO);
|
||||
}
|
||||
|
||||
void Xkb::updateModifiers(uint32_t modsDepressed, uint32_t modsLatched, uint32_t modsLocked, uint32_t group)
|
||||
{
|
||||
if (!m_keymap || !m_state) {
|
||||
return;
|
||||
}
|
||||
xkb_state_update_mask(m_state, modsDepressed, modsLatched, modsLocked, 0, 0, group);
|
||||
Qt::KeyboardModifiers mods = Qt::NoModifier;
|
||||
if (xkb_state_mod_index_is_active(m_state, m_shiftModifier, XKB_STATE_MODS_EFFECTIVE) == 1) {
|
||||
mods |= Qt::ShiftModifier;
|
||||
}
|
||||
if (xkb_state_mod_index_is_active(m_state, m_altModifier, XKB_STATE_MODS_EFFECTIVE) == 1) {
|
||||
mods |= Qt::AltModifier;
|
||||
}
|
||||
if (xkb_state_mod_index_is_active(m_state, m_controlModifier, XKB_STATE_MODS_EFFECTIVE) == 1) {
|
||||
mods |= Qt::ControlModifier;
|
||||
}
|
||||
if (xkb_state_mod_index_is_active(m_state, m_metaModifier, XKB_STATE_MODS_EFFECTIVE) == 1) {
|
||||
mods |= Qt::MetaModifier;
|
||||
}
|
||||
m_modifiers = mods;
|
||||
}
|
||||
|
||||
void Xkb::updateKey(uint32_t key, InputRedirection::KeyboardKeyState state)
|
||||
{
|
||||
if (!m_keymap || !m_state) {
|
||||
return;
|
||||
}
|
||||
xkb_state_update_key(m_state, key + 8, static_cast<xkb_key_direction>(state));
|
||||
}
|
||||
|
||||
xkb_keysym_t Xkb::toKeysym(uint32_t key)
|
||||
{
|
||||
if (!m_state) {
|
||||
return XKB_KEY_NoSymbol;
|
||||
}
|
||||
return xkb_state_key_get_one_sym(m_state, key + 8);
|
||||
}
|
||||
|
||||
QString Xkb::toString(xkb_keysym_t keysym)
|
||||
{
|
||||
if (!m_state || keysym == XKB_KEY_NoSymbol) {
|
||||
return QString();
|
||||
}
|
||||
QByteArray byteArray(7, 0);
|
||||
int ok = xkb_keysym_to_utf8(keysym, byteArray.data(), byteArray.size());
|
||||
if (ok == -1 || ok == 0) {
|
||||
return QString();
|
||||
}
|
||||
return QString::fromUtf8(byteArray.constData());
|
||||
}
|
||||
|
||||
Qt::Key Xkb::toQtKey(xkb_keysym_t keysym)
|
||||
{
|
||||
int key = Qt::Key_unknown;
|
||||
KKeyServer::symXToKeyQt(keysym, &key);
|
||||
return static_cast<Qt::Key>(key);
|
||||
}
|
||||
#endif
|
||||
|
||||
KWIN_SINGLETON_FACTORY(InputRedirection)
|
||||
|
||||
InputRedirection::InputRedirection(QObject *parent)
|
||||
: QObject(parent)
|
||||
#if HAVE_XKB
|
||||
, m_xkb(new Xkb())
|
||||
#endif
|
||||
, m_pointerWindow()
|
||||
{
|
||||
}
|
||||
|
@ -71,9 +193,8 @@ void InputRedirection::processPointerMotion(const QPointF &pos, uint32_t time)
|
|||
emit globalPointerChanged(m_globalPointer);
|
||||
|
||||
// TODO: check which part of KWin would like to intercept the event
|
||||
// TODO: keyboard modifiers
|
||||
QMouseEvent event(QEvent::MouseMove, m_globalPointer.toPoint(), m_globalPointer.toPoint(),
|
||||
Qt::NoButton, qtButtonStates(), 0);
|
||||
Qt::NoButton, qtButtonStates(), keyboardModifiers());
|
||||
// check whether an effect has a mouse grab
|
||||
if (effects && static_cast<EffectsHandlerImpl*>(effects)->checkInputWindowEvent(&event)) {
|
||||
// an effect grabbed the pointer, we do not forward the event to surfaces
|
||||
|
@ -97,9 +218,8 @@ void InputRedirection::processPointerButton(uint32_t button, InputRedirection::P
|
|||
m_pointerButtons[button] = state;
|
||||
emit pointerButtonStateChanged(button, state);
|
||||
|
||||
// TODO: keyboard modifiers
|
||||
QMouseEvent event(buttonStateToEvent(state), m_globalPointer.toPoint(), m_globalPointer.toPoint(),
|
||||
buttonToQtMouseButton(button), qtButtonStates(), 0);
|
||||
buttonToQtMouseButton(button), qtButtonStates(), keyboardModifiers());
|
||||
// check whether an effect has a mouse grab
|
||||
if (effects && static_cast<EffectsHandlerImpl*>(effects)->checkInputWindowEvent(&event)) {
|
||||
// an effect grabbed the pointer, we do not forward the event to surfaces
|
||||
|
@ -130,6 +250,51 @@ void InputRedirection::processPointerAxis(InputRedirection::PointerAxis axis, qr
|
|||
m_pointerWindow.data()->sendPointerAxisEvent(axis, delta);
|
||||
}
|
||||
|
||||
void InputRedirection::processKeyboardKey(uint32_t key, InputRedirection::KeyboardKeyState state, uint32_t time)
|
||||
{
|
||||
Q_UNUSED(time)
|
||||
#if HAVE_XKB
|
||||
m_xkb->updateKey(key, state);
|
||||
// TODO: process global shortcuts
|
||||
// TODO: pass to internal parts of KWin
|
||||
if (effects && static_cast< EffectsHandlerImpl* >(effects)->hasKeyboardGrab()) {
|
||||
const xkb_keysym_t keysym = m_xkb->toKeysym(key);
|
||||
// TODO: start auto-repeat
|
||||
// TODO: add modifiers to the event
|
||||
const QEvent::Type type = (state == KeyboardKeyPressed) ? QEvent::KeyPress : QEvent::KeyRelease;
|
||||
QKeyEvent event(type, m_xkb->toQtKey(keysym), m_xkb->modifiers(), m_xkb->toString(keysym));
|
||||
static_cast< EffectsHandlerImpl* >(effects)->grabbedKeyboardEvent(&event);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// TODO: handle move resize
|
||||
// check unmanaged
|
||||
if (!workspace()->unmanagedList().isEmpty()) {
|
||||
// TODO: better check whether this unmanaged should get the key event
|
||||
workspace()->unmanagedList().first()->sendKeybordKeyEvent(key, state);
|
||||
return;
|
||||
}
|
||||
if (Client *client = workspace()->activeClient()) {
|
||||
client->sendKeybordKeyEvent(key, state);
|
||||
}
|
||||
}
|
||||
|
||||
void InputRedirection::processKeyboardModifiers(uint32_t modsDepressed, uint32_t modsLatched, uint32_t modsLocked, uint32_t group)
|
||||
{
|
||||
// TODO: send to proper Client and also send when active Client changes
|
||||
#if HAVE_XKB
|
||||
m_xkb->updateModifiers(modsDepressed, modsLatched, modsLocked, group);
|
||||
#endif
|
||||
}
|
||||
|
||||
void InputRedirection::processKeymapChange(int fd, uint32_t size)
|
||||
{
|
||||
// TODO: should we pass the keymap to our Clients? Or only to the currently active one and update
|
||||
#if HAVE_XKB
|
||||
m_xkb->installKeymap(fd, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
QEvent::Type InputRedirection::buttonStateToEvent(InputRedirection::PointerButtonState state)
|
||||
{
|
||||
switch (state) {
|
||||
|
@ -241,4 +406,14 @@ uint8_t InputRedirection::toXPointerButton(InputRedirection::PointerAxis axis, q
|
|||
return XCB_BUTTON_INDEX_ANY;
|
||||
}
|
||||
|
||||
Qt::KeyboardModifiers InputRedirection::keyboardModifiers() const
|
||||
{
|
||||
#if HAVE_XKB
|
||||
return m_xkb->modifiers();
|
||||
#else
|
||||
return Qt::NoModifier;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
|
58
input.h
58
input.h
|
@ -25,10 +25,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <QPoint>
|
||||
#include <QEvent>
|
||||
#include <QWeakPointer>
|
||||
#include <config-kwin.h>
|
||||
#if HAVE_XKB
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#endif
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
class Toplevel;
|
||||
class Xkb;
|
||||
|
||||
/**
|
||||
* @brief This class is responsible for redirecting incoming input to the surface which currently
|
||||
|
@ -51,6 +56,10 @@ public:
|
|||
PointerAxisVertical,
|
||||
PointerAxisHorizontal
|
||||
};
|
||||
enum KeyboardKeyState {
|
||||
KeyboardKeyReleased,
|
||||
KeyboardKeyPressed
|
||||
};
|
||||
virtual ~InputRedirection();
|
||||
|
||||
/**
|
||||
|
@ -66,6 +75,7 @@ public:
|
|||
*/
|
||||
PointerButtonState pointerButtonState(uint32_t button) const;
|
||||
Qt::MouseButtons qtButtonStates() const;
|
||||
Qt::KeyboardModifiers keyboardModifiers() const;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
@ -79,6 +89,18 @@ public:
|
|||
* @internal
|
||||
*/
|
||||
void processPointerAxis(PointerAxis axis, qreal delta, uint32_t time);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processKeyboardKey(uint32_t key, KeyboardKeyState state, uint32_t time);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processKeyboardModifiers(uint32_t modsDepressed, uint32_t modsLatched, uint32_t modsLocked, uint32_t group);
|
||||
/**
|
||||
* @internal
|
||||
**/
|
||||
void processKeymapChange(int fd, uint32_t size);
|
||||
|
||||
static uint8_t toXPointerButton(uint32_t button);
|
||||
static uint8_t toXPointerButton(PointerAxis axis, qreal delta);
|
||||
|
@ -114,6 +136,9 @@ private:
|
|||
Toplevel *findToplevel(const QPoint &pos);
|
||||
QPointF m_globalPointer;
|
||||
QHash<uint32_t, PointerButtonState> m_pointerButtons;
|
||||
#if HAVE_XKB
|
||||
QScopedPointer<Xkb> m_xkb;
|
||||
#endif
|
||||
/**
|
||||
* @brief The Toplevel which currently receives pointer events
|
||||
*/
|
||||
|
@ -123,6 +148,31 @@ private:
|
|||
friend InputRedirection *input();
|
||||
};
|
||||
|
||||
#if HAVE_XKB
|
||||
class Xkb
|
||||
{
|
||||
public:
|
||||
Xkb();
|
||||
~Xkb();
|
||||
void installKeymap(int fd, uint32_t size);
|
||||
void updateModifiers(uint32_t modsDepressed, uint32_t modsLatched, uint32_t modsLocked, uint32_t group);
|
||||
void updateKey(uint32_t key, InputRedirection::KeyboardKeyState state);
|
||||
xkb_keysym_t toKeysym(uint32_t key);
|
||||
QString toString(xkb_keysym_t keysym);
|
||||
Qt::Key toQtKey(xkb_keysym_t keysym);
|
||||
Qt::KeyboardModifiers modifiers() const;
|
||||
private:
|
||||
xkb_context *m_context;
|
||||
xkb_keymap *m_keymap;
|
||||
xkb_state *m_state;
|
||||
xkb_mod_index_t m_shiftModifier;
|
||||
xkb_mod_index_t m_controlModifier;
|
||||
xkb_mod_index_t m_altModifier;
|
||||
xkb_mod_index_t m_metaModifier;
|
||||
Qt::KeyboardModifiers m_modifiers;
|
||||
};
|
||||
#endif
|
||||
|
||||
inline
|
||||
InputRedirection *input()
|
||||
{
|
||||
|
@ -146,6 +196,14 @@ InputRedirection::PointerButtonState InputRedirection::pointerButtonState(uint32
|
|||
}
|
||||
}
|
||||
|
||||
#if HAVE_XKB
|
||||
inline
|
||||
Qt::KeyboardModifiers Xkb::modifiers() const
|
||||
{
|
||||
return m_modifiers;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace KWin
|
||||
|
||||
#endif // KWIN_INPUT_H
|
||||
|
|
|
@ -521,6 +521,12 @@ void Toplevel::sendPointerAxisEvent(InputRedirection::PointerAxis axis, qreal de
|
|||
Q_UNUSED(delta)
|
||||
}
|
||||
|
||||
void Toplevel::sendKeybordKeyEvent(uint32_t key, InputRedirection::KeyboardKeyState state)
|
||||
{
|
||||
Q_UNUSED(key)
|
||||
Q_UNUSED(state)
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "toplevel.moc"
|
||||
|
|
|
@ -325,6 +325,7 @@ public:
|
|||
virtual void sendPointerLeaveEvent(const QPointF &globalPos);
|
||||
virtual void sendPointerButtonEvent(uint32_t button, InputRedirection::PointerButtonState state);
|
||||
virtual void sendPointerAxisEvent(InputRedirection::PointerAxis axis, qreal delta);
|
||||
virtual void sendKeybordKeyEvent(uint32_t key, InputRedirection::KeyboardKeyState state);
|
||||
|
||||
Q_SIGNALS:
|
||||
void opacityChanged(KWin::Toplevel* toplevel, qreal oldOpacity);
|
||||
|
|
|
@ -174,6 +174,16 @@ void Unmanaged::sendPointerAxisEvent(InputRedirection::PointerAxis axis, qreal d
|
|||
}
|
||||
}
|
||||
|
||||
void Unmanaged::sendKeybordKeyEvent(uint32_t key, InputRedirection::KeyboardKeyState state)
|
||||
{
|
||||
// TODO: don't use xtest
|
||||
uint8_t type = XCB_KEY_PRESS;
|
||||
if (state == InputRedirection::KeyboardKeyReleased) {
|
||||
type = XCB_KEY_RELEASE;
|
||||
}
|
||||
xcb_test_fake_input(connection(), type, key + 8, XCB_TIME_CURRENT_TIME, window(), 0, 0, 0);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "unmanaged.moc"
|
||||
|
|
|
@ -50,6 +50,7 @@ public:
|
|||
|
||||
void sendPointerButtonEvent(uint32_t button, InputRedirection::PointerButtonState state) override;
|
||||
void sendPointerAxisEvent(InputRedirection::PointerAxis axis, qreal delta) override;
|
||||
void sendKeybordKeyEvent(uint32_t key, InputRedirection::KeyboardKeyState state) override;
|
||||
protected:
|
||||
virtual void debug(QDebug& stream) const;
|
||||
virtual bool shouldUnredirect() const;
|
||||
|
|
|
@ -162,9 +162,10 @@ static void keyboardHandleKeymap(void *data, wl_keyboard *keyboard,
|
|||
{
|
||||
Q_UNUSED(data)
|
||||
Q_UNUSED(keyboard)
|
||||
Q_UNUSED(format)
|
||||
Q_UNUSED(fd)
|
||||
Q_UNUSED(size)
|
||||
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
|
||||
return;
|
||||
}
|
||||
input()->processKeymapChange(fd, size);
|
||||
}
|
||||
|
||||
static void keyboardHandleEnter(void *data, wl_keyboard *keyboard,
|
||||
|
@ -192,12 +193,7 @@ static void keyboardHandleKey(void *data, wl_keyboard *keyboard, uint32_t serial
|
|||
Q_UNUSED(data)
|
||||
Q_UNUSED(keyboard)
|
||||
Q_UNUSED(serial)
|
||||
Q_UNUSED(time)
|
||||
uint8_t type = XCB_KEY_PRESS;
|
||||
if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
|
||||
type = XCB_KEY_RELEASE;
|
||||
}
|
||||
xcb_test_fake_input(connection(), type, key + 8 /*magic*/, XCB_TIME_CURRENT_TIME, XCB_WINDOW_NONE, 0, 0, 0);
|
||||
input()->processKeyboardKey(key, static_cast<InputRedirection::KeyboardKeyState>(state), time);
|
||||
}
|
||||
|
||||
static void keyboardHandleModifiers(void *data, wl_keyboard *keyboard, uint32_t serial, uint32_t modsDepressed,
|
||||
|
@ -206,10 +202,7 @@ static void keyboardHandleModifiers(void *data, wl_keyboard *keyboard, uint32_t
|
|||
Q_UNUSED(data)
|
||||
Q_UNUSED(keyboard)
|
||||
Q_UNUSED(serial)
|
||||
Q_UNUSED(modsDepressed)
|
||||
Q_UNUSED(modsLatched)
|
||||
Q_UNUSED(modsLocked)
|
||||
Q_UNUSED(group)
|
||||
input()->processKeyboardModifiers(modsDepressed, modsLatched, modsLocked, group);
|
||||
}
|
||||
|
||||
static void bufferRelease(void *data, wl_buffer *wl_buffer)
|
||||
|
|
Loading…
Reference in New Issue