backends/x11: Implement own keyboard interception
At the moment, the keyboard interception code in the effects system relies on Qt code processing key events. However, since QDesktopWidget is removed in Qt 6, this is a blocker for Qt 6 port. This change ports the X11 backend to private xkb keymap as indicates in the todo comment. It allows us to drop the last QDesktopWidget usage.
This commit is contained in:
parent
7aee88581f
commit
bcd43ff44d
14 changed files with 388 additions and 35 deletions
|
@ -236,6 +236,9 @@ set_package_properties(XKB PROPERTIES
|
|||
PURPOSE "Required for building KWin with Wayland support"
|
||||
)
|
||||
|
||||
pkg_check_modules(XKBX11 IMPORTED_TARGET xkbcommon-x11 REQUIRED)
|
||||
add_feature_info(XKBX11 XKBX11_FOUND "Required for handling keyboard events in X11 backend")
|
||||
|
||||
find_package(Libinput 1.19)
|
||||
set_package_properties(Libinput PROPERTIES TYPE REQUIRED PURPOSE "Required for input handling on Wayland.")
|
||||
|
||||
|
@ -294,6 +297,7 @@ find_package(XCB 1.10 REQUIRED COMPONENTS
|
|||
SYNC
|
||||
XCB
|
||||
XFIXES
|
||||
XKB
|
||||
XINERAMA
|
||||
)
|
||||
set_package_properties(XCB PROPERTIES TYPE REQUIRED)
|
||||
|
|
|
@ -2,8 +2,10 @@ set(X11PLATFORM_SOURCES
|
|||
x11_standalone_cursor.cpp
|
||||
x11_standalone_edge.cpp
|
||||
x11_standalone_effects.cpp
|
||||
x11_standalone_effects_keyboard_interception_filter.cpp
|
||||
x11_standalone_effects_mouse_interception_filter.cpp
|
||||
x11_standalone_egl_backend.cpp
|
||||
x11_standalone_keyboard.cpp
|
||||
x11_standalone_logging.cpp
|
||||
x11_standalone_non_composited_outline.cpp
|
||||
x11_standalone_output.cpp
|
||||
|
@ -16,7 +18,7 @@ set(X11PLATFORM_SOURCES
|
|||
)
|
||||
|
||||
add_library(KWinX11Platform OBJECT ${X11PLATFORM_SOURCES})
|
||||
target_link_libraries(KWinX11Platform kwin KF5::Crash X11::X11)
|
||||
target_link_libraries(KWinX11Platform kwin KF5::Crash X11::X11 XCB::XKB PkgConfig::XKBX11)
|
||||
if (QT_MAJOR_VERSION EQUAL "5")
|
||||
target_link_libraries(KWinX11Platform Qt::X11Extras)
|
||||
endif()
|
||||
|
|
|
@ -12,9 +12,10 @@
|
|||
#include "screenedge.h"
|
||||
#include "utils/common.h"
|
||||
#include "workspace.h"
|
||||
#include "x11_standalone_effects_keyboard_interception_filter.h"
|
||||
#include "x11_standalone_effects_mouse_interception_filter.h"
|
||||
|
||||
#include <QDesktopWidget>
|
||||
#include "x11_standalone_keyboard.h"
|
||||
#include "x11_standalone_platform.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
@ -43,21 +44,22 @@ EffectsHandlerImplX11::~EffectsHandlerImplX11()
|
|||
|
||||
bool EffectsHandlerImplX11::doGrabKeyboard()
|
||||
{
|
||||
auto keyboard = static_cast<X11StandalonePlatform *>(kwinApp()->platform())->keyboard();
|
||||
if (!keyboard->xkbKeymap()) {
|
||||
return false;
|
||||
}
|
||||
bool ret = grabXKeyboard();
|
||||
if (!ret) {
|
||||
return false;
|
||||
}
|
||||
// Workaround for Qt 5.9 regression introduced with 2b34aefcf02f09253473b096eb4faffd3e62b5f4
|
||||
// we no longer get any events for the root window, one needs to call winId() on the desktop window
|
||||
// TODO: change effects event handling to create the appropriate QKeyEvent without relying on Qt
|
||||
// as it's done already in the Wayland case.
|
||||
qApp->desktop()->winId();
|
||||
m_x11KeyboardInterception = std::make_unique<EffectsKeyboardInterceptionX11Filter>(this, keyboard);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EffectsHandlerImplX11::doUngrabKeyboard()
|
||||
{
|
||||
ungrabXKeyboard();
|
||||
m_x11KeyboardInterception.reset();
|
||||
}
|
||||
|
||||
void EffectsHandlerImplX11::doStartMouseInterception(Qt::CursorShape shape)
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
namespace KWin
|
||||
{
|
||||
class EffectsMouseInterceptionX11Filter;
|
||||
class EffectsKeyboardInterceptionX11Filter;
|
||||
|
||||
class EffectsHandlerImplX11 : public EffectsHandlerImpl
|
||||
{
|
||||
|
@ -40,6 +41,7 @@ protected:
|
|||
private:
|
||||
Xcb::Window m_mouseInterceptionWindow;
|
||||
std::unique_ptr<EffectsMouseInterceptionX11Filter> m_x11MouseInterception;
|
||||
std::unique_ptr<EffectsKeyboardInterceptionX11Filter> m_x11KeyboardInterception;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "x11_standalone_effects_keyboard_interception_filter.h"
|
||||
#include "x11_standalone_effects.h"
|
||||
#include "x11_standalone_keyboard.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QKeyEvent>
|
||||
#include <QtXkbCommonSupport/private/qxkbcommon_p.h>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
EffectsKeyboardInterceptionX11Filter::EffectsKeyboardInterceptionX11Filter(EffectsHandlerImpl *effects, X11Keyboard *keyboard)
|
||||
: X11EventFilter(QVector<int>{XCB_KEY_PRESS, XCB_KEY_RELEASE})
|
||||
, m_effects(effects)
|
||||
, m_keyboard(keyboard)
|
||||
{
|
||||
}
|
||||
|
||||
bool EffectsKeyboardInterceptionX11Filter::event(xcb_generic_event_t *event)
|
||||
{
|
||||
switch (event->response_type & ~0x80) {
|
||||
case XCB_KEY_PRESS: {
|
||||
const auto keyEvent = reinterpret_cast<xcb_key_press_event_t *>(event);
|
||||
processKey(true, keyEvent->detail, keyEvent->time);
|
||||
return true;
|
||||
}
|
||||
case XCB_KEY_RELEASE: {
|
||||
const auto keyEvent = reinterpret_cast<xcb_key_release_event_t *>(event);
|
||||
processKey(false, keyEvent->detail, keyEvent->time);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void EffectsKeyboardInterceptionX11Filter::processKey(bool press, xcb_keycode_t keycode, xcb_timestamp_t timestamp)
|
||||
{
|
||||
const xkb_keysym_t keysym = xkb_state_key_get_one_sym(m_keyboard->xkbState(), keycode);
|
||||
|
||||
Qt::KeyboardModifiers modifiers = m_keyboard->modifiers();
|
||||
if (QXkbCommon::isKeypad(keysym)) {
|
||||
modifiers |= Qt::KeypadModifier;
|
||||
}
|
||||
|
||||
const int qtKey = QXkbCommon::keysymToQtKey(keysym, modifiers, m_keyboard->xkbState(), keycode);
|
||||
const QString text = QXkbCommon::lookupString(m_keyboard->xkbState(), keycode);
|
||||
|
||||
QKeyEvent keyEvent(press ? QEvent::KeyPress : QEvent::KeyRelease, qtKey, modifiers, text);
|
||||
keyEvent.setTimestamp(timestamp);
|
||||
|
||||
m_effects->grabbedKeyboardEvent(&keyEvent);
|
||||
}
|
||||
|
||||
} // namespace KWin
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "x11eventfilter.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class EffectsHandlerImpl;
|
||||
class X11Keyboard;
|
||||
|
||||
class EffectsKeyboardInterceptionX11Filter : public X11EventFilter
|
||||
{
|
||||
public:
|
||||
explicit EffectsKeyboardInterceptionX11Filter(EffectsHandlerImpl *effects, X11Keyboard *keyboard);
|
||||
|
||||
bool event(xcb_generic_event_t *event) override;
|
||||
|
||||
private:
|
||||
void processKey(bool press, xcb_keycode_t keycode, xcb_timestamp_t timestamp);
|
||||
|
||||
EffectsHandlerImpl *m_effects;
|
||||
X11Keyboard *m_keyboard;
|
||||
};
|
||||
|
||||
} // namespace KWin
|
224
src/backends/x11/standalone/x11_standalone_keyboard.cpp
Normal file
224
src/backends/x11/standalone/x11_standalone_keyboard.cpp
Normal file
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "x11_standalone_keyboard.h"
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#define explicit dont_use_cxx_explicit
|
||||
#include <xcb/xkb.h>
|
||||
#undef explicit
|
||||
#include <xkbcommon/xkbcommon-x11.h>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class X11KeyboardFilter : public X11EventFilter
|
||||
{
|
||||
public:
|
||||
X11KeyboardFilter(X11Keyboard *kbd, int eventType)
|
||||
: X11EventFilter(eventType)
|
||||
, m_kbd(kbd)
|
||||
{
|
||||
}
|
||||
|
||||
bool event(xcb_generic_event_t *event) override
|
||||
{
|
||||
return m_kbd->event(event);
|
||||
}
|
||||
|
||||
private:
|
||||
X11Keyboard *m_kbd;
|
||||
};
|
||||
|
||||
X11Keyboard::X11Keyboard()
|
||||
: m_xkbContext(xkb_context_new(XKB_CONTEXT_NO_FLAGS))
|
||||
{
|
||||
const xcb_query_extension_reply_t *reply = xcb_get_extension_data(kwinApp()->x11Connection(), &xcb_xkb_id);
|
||||
if (!reply || !reply->present) {
|
||||
qWarning() << "XKeyboard extension is unavailable";
|
||||
return;
|
||||
}
|
||||
|
||||
m_deviceId = xkb_x11_get_core_keyboard_device_id(kwinApp()->x11Connection());
|
||||
if (m_deviceId == -1) {
|
||||
qWarning() << "xkb_x11_get_core_keyboard_device_id() failed";
|
||||
return;
|
||||
}
|
||||
|
||||
enum {
|
||||
requiredEvents =
|
||||
(XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY
|
||||
| XCB_XKB_EVENT_TYPE_MAP_NOTIFY
|
||||
| XCB_XKB_EVENT_TYPE_STATE_NOTIFY),
|
||||
|
||||
requiredNknDetails =
|
||||
(XCB_XKB_NKN_DETAIL_KEYCODES),
|
||||
|
||||
requiredMapParts =
|
||||
(XCB_XKB_MAP_PART_KEY_TYPES
|
||||
| XCB_XKB_MAP_PART_KEY_SYMS
|
||||
| XCB_XKB_MAP_PART_MODIFIER_MAP
|
||||
| XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS
|
||||
| XCB_XKB_MAP_PART_KEY_ACTIONS
|
||||
| XCB_XKB_MAP_PART_VIRTUAL_MODS
|
||||
| XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP),
|
||||
|
||||
requiredStateDetails =
|
||||
(XCB_XKB_STATE_PART_MODIFIER_BASE
|
||||
| XCB_XKB_STATE_PART_MODIFIER_LATCH
|
||||
| XCB_XKB_STATE_PART_MODIFIER_LOCK
|
||||
| XCB_XKB_STATE_PART_GROUP_BASE
|
||||
| XCB_XKB_STATE_PART_GROUP_LATCH
|
||||
| XCB_XKB_STATE_PART_GROUP_LOCK),
|
||||
};
|
||||
|
||||
static const xcb_xkb_select_events_details_t details = {
|
||||
.affectNewKeyboard = requiredNknDetails,
|
||||
.newKeyboardDetails = requiredNknDetails,
|
||||
.affectState = requiredStateDetails,
|
||||
.stateDetails = requiredStateDetails,
|
||||
};
|
||||
|
||||
xcb_void_cookie_t cookie =
|
||||
xcb_xkb_select_events_aux_checked(kwinApp()->x11Connection(),
|
||||
m_deviceId,
|
||||
requiredEvents,
|
||||
0,
|
||||
0,
|
||||
requiredMapParts,
|
||||
requiredMapParts,
|
||||
&details);
|
||||
|
||||
xcb_generic_error_t *error = xcb_request_check(kwinApp()->x11Connection(), cookie);
|
||||
if (error) {
|
||||
free(error);
|
||||
return;
|
||||
}
|
||||
|
||||
updateKeymap();
|
||||
|
||||
m_filter = std::make_unique<X11KeyboardFilter>(this, reply->first_event);
|
||||
}
|
||||
|
||||
X11Keyboard::~X11Keyboard()
|
||||
{
|
||||
if (m_xkbState) {
|
||||
xkb_state_unref(m_xkbState);
|
||||
m_xkbState = nullptr;
|
||||
}
|
||||
if (m_xkbKeymap) {
|
||||
xkb_keymap_unref(m_xkbKeymap);
|
||||
m_xkbKeymap = nullptr;
|
||||
}
|
||||
if (m_xkbContext) {
|
||||
xkb_context_unref(m_xkbContext);
|
||||
m_xkbContext = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool X11Keyboard::event(xcb_generic_event_t *gevent)
|
||||
{
|
||||
union xkb_event {
|
||||
struct
|
||||
{
|
||||
uint8_t response_type;
|
||||
uint8_t xkbType;
|
||||
uint16_t sequence;
|
||||
xcb_timestamp_t time;
|
||||
uint8_t deviceID;
|
||||
} any;
|
||||
xcb_xkb_new_keyboard_notify_event_t new_keyboard_notify;
|
||||
xcb_xkb_map_notify_event_t map_notify;
|
||||
xcb_xkb_state_notify_event_t state_notify;
|
||||
} *event = reinterpret_cast<union xkb_event *>(gevent);
|
||||
|
||||
if (event->any.deviceID == m_deviceId) {
|
||||
switch (event->any.xkbType) {
|
||||
case XCB_XKB_NEW_KEYBOARD_NOTIFY:
|
||||
if (event->new_keyboard_notify.changed & XCB_XKB_NKN_DETAIL_KEYCODES) {
|
||||
updateKeymap();
|
||||
}
|
||||
break;
|
||||
|
||||
case XCB_XKB_MAP_NOTIFY:
|
||||
updateKeymap();
|
||||
break;
|
||||
|
||||
case XCB_XKB_STATE_NOTIFY:
|
||||
xkb_state_update_mask(m_xkbState,
|
||||
event->state_notify.baseMods,
|
||||
event->state_notify.latchedMods,
|
||||
event->state_notify.lockedMods,
|
||||
event->state_notify.baseGroup,
|
||||
event->state_notify.latchedGroup,
|
||||
event->state_notify.lockedGroup);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void X11Keyboard::updateKeymap()
|
||||
{
|
||||
xkb_keymap *keymap = xkb_x11_keymap_new_from_device(m_xkbContext, kwinApp()->x11Connection(), m_deviceId, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
if (!keymap) {
|
||||
qWarning() << "xkb_x11_keymap_new_from_device() failed";
|
||||
return;
|
||||
}
|
||||
|
||||
xkb_state *state = xkb_x11_state_new_from_device(keymap, kwinApp()->x11Connection(), m_deviceId);
|
||||
if (!state) {
|
||||
xkb_keymap_unref(keymap);
|
||||
qWarning() << "xkb_x11_state_new_from_device() failed";
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_xkbState) {
|
||||
xkb_state_unref(m_xkbState);
|
||||
}
|
||||
if (m_xkbKeymap) {
|
||||
xkb_keymap_unref(m_xkbKeymap);
|
||||
}
|
||||
|
||||
m_xkbState = state;
|
||||
m_xkbKeymap = keymap;
|
||||
}
|
||||
|
||||
xkb_keymap *X11Keyboard::xkbKeymap() const
|
||||
{
|
||||
return m_xkbKeymap;
|
||||
}
|
||||
|
||||
xkb_state *X11Keyboard::xkbState() const
|
||||
{
|
||||
return m_xkbState;
|
||||
}
|
||||
|
||||
Qt::KeyboardModifiers X11Keyboard::modifiers() const
|
||||
{
|
||||
Qt::KeyboardModifiers mods;
|
||||
|
||||
if (xkb_state_mod_name_is_active(m_xkbState, XKB_MOD_NAME_SHIFT, XKB_STATE_MODS_EFFECTIVE) == 1 || xkb_state_mod_name_is_active(m_xkbState, XKB_MOD_NAME_CAPS, XKB_STATE_MODS_EFFECTIVE) == 1) {
|
||||
mods |= Qt::ShiftModifier;
|
||||
}
|
||||
if (xkb_state_mod_name_is_active(m_xkbState, XKB_MOD_NAME_ALT, XKB_STATE_MODS_EFFECTIVE) == 1) {
|
||||
mods |= Qt::AltModifier;
|
||||
}
|
||||
if (xkb_state_mod_name_is_active(m_xkbState, XKB_MOD_NAME_CTRL, XKB_STATE_MODS_EFFECTIVE) == 1) {
|
||||
mods |= Qt::ControlModifier;
|
||||
}
|
||||
if (xkb_state_mod_name_is_active(m_xkbState, XKB_MOD_NAME_LOGO, XKB_STATE_MODS_EFFECTIVE) == 1) {
|
||||
mods |= Qt::MetaModifier;
|
||||
}
|
||||
|
||||
return mods;
|
||||
}
|
||||
|
||||
} // namespace KWin
|
43
src/backends/x11/standalone/x11_standalone_keyboard.h
Normal file
43
src/backends/x11/standalone/x11_standalone_keyboard.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "x11eventfilter.h"
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class X11KeyboardFilter;
|
||||
|
||||
class X11Keyboard
|
||||
{
|
||||
public:
|
||||
X11Keyboard();
|
||||
~X11Keyboard();
|
||||
|
||||
xkb_keymap *xkbKeymap() const;
|
||||
xkb_state *xkbState() const;
|
||||
Qt::KeyboardModifiers modifiers() const;
|
||||
|
||||
bool event(xcb_generic_event_t *event);
|
||||
|
||||
private:
|
||||
void updateKeymap();
|
||||
|
||||
xkb_context *m_xkbContext = nullptr;
|
||||
xkb_keymap *m_xkbKeymap = nullptr;
|
||||
xkb_state *m_xkbState = nullptr;
|
||||
int32_t m_deviceId = 0;
|
||||
|
||||
std::unique_ptr<X11KeyboardFilter> m_filter;
|
||||
};
|
||||
|
||||
} // namespace KWin
|
|
@ -33,6 +33,7 @@
|
|||
#include "workspace.h"
|
||||
#include "x11_standalone_effects.h"
|
||||
#include "x11_standalone_egl_backend.h"
|
||||
#include "x11_standalone_keyboard.h"
|
||||
#include "x11_standalone_logging.h"
|
||||
#include "x11_standalone_non_composited_outline.h"
|
||||
#include "x11_standalone_output.h"
|
||||
|
@ -121,6 +122,8 @@ X11StandalonePlatform::X11StandalonePlatform(QObject *parent)
|
|||
m_updateOutputsTimer->setSingleShot(true);
|
||||
connect(m_updateOutputsTimer.get(), &QTimer::timeout, this, &X11StandalonePlatform::updateOutputs);
|
||||
|
||||
m_keyboard = std::make_unique<X11Keyboard>();
|
||||
|
||||
setSupportsGammaControl(true);
|
||||
}
|
||||
|
||||
|
@ -646,6 +649,11 @@ Outputs X11StandalonePlatform::outputs() const
|
|||
return m_outputs;
|
||||
}
|
||||
|
||||
X11Keyboard *X11StandalonePlatform::keyboard() const
|
||||
{
|
||||
return m_keyboard.get();
|
||||
}
|
||||
|
||||
RenderLoop *X11StandalonePlatform::renderLoop() const
|
||||
{
|
||||
return m_renderLoop.get();
|
||||
|
|
|
@ -26,6 +26,7 @@ class XInputIntegration;
|
|||
class WindowSelector;
|
||||
class X11EventFilter;
|
||||
class X11Output;
|
||||
class X11Keyboard;
|
||||
|
||||
class KWIN_EXPORT X11StandalonePlatform : public Platform
|
||||
{
|
||||
|
@ -63,6 +64,7 @@ public:
|
|||
void scheduleUpdateOutputs();
|
||||
void updateOutputs();
|
||||
|
||||
X11Keyboard *keyboard() const;
|
||||
RenderLoop *renderLoop() const;
|
||||
Outputs outputs() const override;
|
||||
|
||||
|
@ -92,6 +94,7 @@ private:
|
|||
std::unique_ptr<WindowSelector> m_windowSelector;
|
||||
std::unique_ptr<X11EventFilter> m_screenEdgesFilter;
|
||||
std::unique_ptr<X11EventFilter> m_randrEventFilter;
|
||||
std::unique_ptr<X11Keyboard> m_keyboard;
|
||||
std::unique_ptr<RenderLoop> m_renderLoop;
|
||||
QVector<Output *> m_outputs;
|
||||
};
|
||||
|
|
|
@ -148,10 +148,6 @@ static xcb_window_t findEventWindow(xcb_generic_event_t *event)
|
|||
bool Workspace::workspaceEvent(xcb_generic_event_t *e)
|
||||
{
|
||||
const uint8_t eventType = e->response_type & ~0x80;
|
||||
if (effects && static_cast<EffectsHandlerImpl *>(effects)->hasKeyboardGrab()
|
||||
&& (eventType == XCB_KEY_PRESS || eventType == XCB_KEY_RELEASE)) {
|
||||
return false; // let Qt process it, it'll be intercepted again in eventFilter()
|
||||
}
|
||||
|
||||
const xcb_window_t eventWindow = findEventWindow(e);
|
||||
if (eventWindow != XCB_WINDOW_NONE) {
|
||||
|
@ -311,19 +307,6 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Used only to filter events that need to be processed by Qt first
|
||||
// (e.g. keyboard input to be composed), otherwise events are
|
||||
// handle by the XEvent filter above
|
||||
bool Workspace::workspaceEvent(QEvent *e)
|
||||
{
|
||||
if ((e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease || e->type() == QEvent::ShortcutOverride)
|
||||
&& effects && static_cast<EffectsHandlerImpl *>(effects)->hasKeyboardGrab()) {
|
||||
static_cast<EffectsHandlerImpl *>(effects)->grabbedKeyboardEvent(static_cast<QKeyEvent *>(e));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ****************************************
|
||||
// Client
|
||||
// ****************************************
|
||||
|
|
|
@ -259,14 +259,6 @@ void ApplicationX11::performStartup()
|
|||
createTabletModeManager();
|
||||
}
|
||||
|
||||
bool ApplicationX11::notify(QObject *o, QEvent *e)
|
||||
{
|
||||
if (e->spontaneous() && Workspace::self()->workspaceEvent(e)) {
|
||||
return true;
|
||||
}
|
||||
return QApplication::notify(o, e);
|
||||
}
|
||||
|
||||
void ApplicationX11::setupCrashHandler()
|
||||
{
|
||||
KCrash::setEmergencySaveFunction(ApplicationX11::crashHandler);
|
||||
|
|
|
@ -26,7 +26,6 @@ public:
|
|||
|
||||
protected:
|
||||
void performStartup() override;
|
||||
bool notify(QObject *o, QEvent *e) override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void lostSelection();
|
||||
|
|
|
@ -93,7 +93,6 @@ public:
|
|||
}
|
||||
|
||||
bool workspaceEvent(xcb_generic_event_t *);
|
||||
bool workspaceEvent(QEvent *);
|
||||
|
||||
bool hasWindow(const Window *);
|
||||
|
||||
|
|
Loading…
Reference in a new issue