Skip to content

Commit

Permalink
Move to runtime the decision to use x11 or not
Browse files Browse the repository at this point in the history
Summary:
Instead of deciding at build time which backend to use, see which is
used upon construction.
This will make it possible to have an alternative wayland
implementation.

Test Plan: See D20442

Subscribers: kde-frameworks-devel

Tags: #frameworks

Differential Revision: https://phabricator.kde.org/D20443
  • Loading branch information
aleixpol committed Jun 22, 2019
1 parent 560f015 commit 0fe2990
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 117 deletions.
34 changes: 17 additions & 17 deletions src/CMakeLists.txt
Expand Up @@ -14,20 +14,7 @@ set(kguiaddons_LIB_SRCS
util/urlhandler.cpp
)

set (kmodifierkeyinfoprovider_impl "dummy")
if (NOT APPLE AND X11_FOUND AND X11_Xkb_FOUND AND XCB_XCB_FOUND)
find_package(Qt5X11Extras ${REQUIRED_QT_VERSION} NO_MODULE)
if (Qt5X11Extras_FOUND)
include_directories (
${X11_Xkb_INCLUDE_PATH}
${X11_Xlib_INCLUDE_PATH}
${XCB_XCB_INCLUDE_DIR}
)
set (kmodifierkeyinfoprovider_impl "x11")
endif()
endif ()

set (kguiaddons_LIB_SRCS ${kguiaddons_LIB_SRCS} util/kmodifierkeyinfoprovider_${kmodifierkeyinfoprovider_impl}.cpp)
set (kguiaddons_LIB_SRCS ${kguiaddons_LIB_SRCS} util/kmodifierkeyinfoprovider.cpp)

add_library(KF5GuiAddons ${kguiaddons_LIB_SRCS})

Expand All @@ -45,9 +32,20 @@ target_include_directories(KF5GuiAddons INTERFACE "$<INSTALL_INTERFACE:${KDE_INS
target_compile_definitions(KF5GuiAddons INTERFACE "$<INSTALL_INTERFACE:KGUIADDONS_LIB>")
target_link_libraries(KF5GuiAddons PUBLIC Qt5::Gui)

if (kmodifierkeyinfoprovider_impl STREQUAL "x11")
target_link_libraries(KF5GuiAddons LINK_PRIVATE ${X11_LIBRARIES} ${XCB_XCB_LIBRARY} Qt5::X11Extras)
endif()
set(WITH_XCB)
if (NOT APPLE AND X11_FOUND AND X11_Xkb_FOUND AND XCB_XCB_FOUND)
find_package(Qt5X11Extras ${REQUIRED_QT_VERSION} NO_MODULE)
if (Qt5X11Extras_FOUND)
add_library(kmodifierkey_xcb MODULE util/kmodifierkeyinfoprovider_xcb.cpp)
target_include_directories (kmodifierkey_xcb PRIVATE
${X11_Xkb_INCLUDE_PATH}
${X11_Xlib_INCLUDE_PATH}
${XCB_XCB_INCLUDE_DIR}
)
target_link_libraries(kmodifierkey_xcb PRIVATE ${X11_LIBRARIES} ${XCB_XCB_LIBRARY} Qt5::X11Extras KF5::GuiAddons)
install( TARGETS kmodifierkey_xcb DESTINATION ${PLUGIN_INSTALL_DIR}/kf5/kguiaddons/kmodifierkey/)
endif()
endif ()

set_target_properties(KF5GuiAddons PROPERTIES VERSION ${KGUIADDONS_VERSION_STRING}
SOVERSION ${KGUIADDONS_SOVERSION}
Expand Down Expand Up @@ -107,12 +105,14 @@ if (PythonModuleGeneration_FOUND)
util/kiconutils.h
util/kimagecache.h
util/kmodifierkeyinfo.h
util/kmodifierkeyinfoprovider_p.h
)
endif()

install(TARGETS KF5GuiAddons EXPORT KF5GuiAddonsTargets ${KF5_INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/kguiaddons_export.h
util/kmodifierkeyinfoprovider_p.h
util/klocalimagecacheimpl.h # implementation detail, no forwarding header
${KGuiAddons_HEADERS}
DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/KGuiAddons COMPONENT Devel
Expand Down
16 changes: 15 additions & 1 deletion src/util/kmodifierkeyinfo.cpp
Expand Up @@ -20,9 +20,23 @@

#include "kmodifierkeyinfo.h"
#include "kmodifierkeyinfoprovider_p.h"
#include <QPluginLoader>

#include <QDebug>
#include <QGuiApplication>

KModifierKeyInfoProvider* createProvider()
{
QPluginLoader loader(QStringLiteral("kf5/kguiaddons/kmodifierkey/kmodifierkey_")+qGuiApp->platformName());
auto instance = dynamic_cast<KModifierKeyInfoProvider*>(loader.instance());
if (instance)
return instance;
qWarning() << "Error: could not load plugin for platform" << loader.fileName() << "error:" << loader.errorString() << loader.instance();
return new KModifierKeyInfoProvider;
}

KModifierKeyInfo::KModifierKeyInfo(QObject *parent)
: QObject(parent), p(new KModifierKeyInfoProvider)
: QObject(parent), p(createProvider())
{
connect(p, &KModifierKeyInfoProvider::keyPressed,
this, &KModifierKeyInfo::keyPressed);
Expand Down
41 changes: 40 additions & 1 deletion src/util/kmodifierkeyinfoprovider.cpp
Expand Up @@ -20,6 +20,29 @@

#include "kmodifierkeyinfoprovider_p.h"

KModifierKeyInfoProvider::KModifierKeyInfoProvider()
: QObject(nullptr)
{
}

KModifierKeyInfoProvider::~KModifierKeyInfoProvider()
{
}

bool KModifierKeyInfoProvider::setKeyLatched(Qt::Key key, bool latched)
{
Q_UNUSED(key);
Q_UNUSED(latched);
return false;
}

bool KModifierKeyInfoProvider::setKeyLocked(Qt::Key key, bool locked)
{
Q_UNUSED(key);
Q_UNUSED(locked);
return false;
}

bool KModifierKeyInfoProvider::isKeyPressed(Qt::Key key) const
{
if (m_modifierStates.contains(key)) {
Expand Down Expand Up @@ -62,4 +85,20 @@ const QList<Qt::Key> KModifierKeyInfoProvider::knownKeys() const
return m_modifierStates.keys();
}

#include "moc_kmodifierkeyinfoprovider_p.cpp"
void KModifierKeyInfoProvider::stateUpdated(Qt::Key key, KModifierKeyInfoProvider::ModifierStates newState)
{
auto &state = m_modifierStates[key];
if (newState != state) {
const auto difference = (newState ^ state);
state = newState;
if (difference & Pressed) {
emit keyPressed(key, newState & Pressed);
}
if (difference & Latched) {
emit keyLatched(key, newState & Latched);
}
if (difference & Locked) {
emit keyLocked(key, newState & Locked);
}
}
}
53 changes: 0 additions & 53 deletions src/util/kmodifierkeyinfoprovider_dummy.cpp

This file was deleted.

26 changes: 8 additions & 18 deletions src/util/kmodifierkeyinfoprovider_p.h
Expand Up @@ -24,13 +24,14 @@
#include <QAbstractNativeEventFilter>
#include <QHash>
#include <QObject>
#include "kguiaddons_export.h"

/**
* Background class that implements the behaviour of KModifierKeyInfo for
* the different supported platforms.
* @internal
*/
class KModifierKeyInfoProvider : public QObject, public QAbstractNativeEventFilter
class KGUIADDONS_EXPORT KModifierKeyInfoProvider : public QObject
{
Q_OBJECT

Expand All @@ -41,6 +42,7 @@ class KModifierKeyInfoProvider : public QObject, public QAbstractNativeEventFilt
Latched = 0x2,
Locked = 0x4
};
Q_ENUM(ModifierState);
Q_DECLARE_FLAGS(ModifierStates, ModifierState)

KModifierKeyInfoProvider();
Expand All @@ -66,7 +68,7 @@ class KModifierKeyInfoProvider : public QObject, public QAbstractNativeEventFilt
* @param latched true to latch the key, false to unlatch it
* @return true if the key is known, false else
*/
bool setKeyLatched(Qt::Key key, bool latched);
virtual bool setKeyLatched(Qt::Key key, bool latched);

/**
* Detect if a key is locked.
Expand All @@ -81,7 +83,7 @@ class KModifierKeyInfoProvider : public QObject, public QAbstractNativeEventFilt
* @param latched true to lock the key, false to unlock it
* @return true if the key is known, false else
*/
bool setKeyLocked(Qt::Key key, bool locked);
virtual bool setKeyLocked(Qt::Key key, bool locked);

/**
* Check if a mouse button is pressed.
Expand All @@ -103,8 +105,6 @@ class KModifierKeyInfoProvider : public QObject, public QAbstractNativeEventFilt
*/
const QList<Qt::Key> knownKeys() const;

bool nativeEventFilter(const QByteArray &eventType, void *message, long int *result) override;

Q_SIGNALS:
void keyLatched(Qt::Key key, bool state);
void keyLocked(Qt::Key key, bool state);
Expand All @@ -114,26 +114,16 @@ class KModifierKeyInfoProvider : public QObject, public QAbstractNativeEventFilt
void keyRemoved(Qt::Key key);

protected:
void xkbUpdateModifierMapping();
void xkbModifierStateChanged(unsigned char mods, unsigned char latched_mods,
unsigned char locked_mods);
void xkbButtonStateChanged(unsigned short ptr_buttons);
void stateUpdated(Qt::Key key, KModifierKeyInfoProvider::ModifierStates state);

private:
// the state of each known modifier
QHash<Qt::Key, ModifierStates> m_modifierStates;

// the state of each known mouse button
QHash<Qt::MouseButton, bool> m_buttonStates;

int m_xkbEv;
bool m_xkbAvailable;

// maps a Qt::Key to a modifier mask
QHash<Qt::Key, unsigned int> m_xkbModifiers;
// maps a Qt::MouseButton to a button mask
QHash<Qt::MouseButton, unsigned short> m_xkbButtons;
};

Q_DECLARE_INTERFACE(KModifierKeyInfoProvider, "org.kde.kguiaddons.KModifierKeyInfoProvider")
Q_DECLARE_OPERATORS_FOR_FLAGS(KModifierKeyInfoProvider::ModifierStates)

#endif
Expand Up @@ -20,7 +20,7 @@
*/

#include "kmodifierkeyinfo.h"
#include "kmodifierkeyinfoprovider_p.h"
#include "kmodifierkeyinfoprovider_xcb.h"

#include <QGuiApplication>
#include <QX11Info>
Expand Down Expand Up @@ -61,16 +61,15 @@ unsigned int xkbVirtualModifier(XkbDescPtr xkb, const char *name)
XFree(modStr);
if (nameEqual) {
XkbVirtualModsToReal(xkb, 1 << i, &mask);
break;
break;
}
}
}
return mask;
}

KModifierKeyInfoProvider::KModifierKeyInfoProvider()
: QObject(nullptr)
, QAbstractNativeEventFilter()
KModifierKeyInfoProviderXcb::KModifierKeyInfoProviderXcb()
: KModifierKeyInfoProvider()
, m_xkbEv(0)
, m_xkbAvailable(false)
{
Expand Down Expand Up @@ -111,14 +110,14 @@ KModifierKeyInfoProvider::KModifierKeyInfoProvider()
}
}

KModifierKeyInfoProvider::~KModifierKeyInfoProvider()
KModifierKeyInfoProviderXcb::~KModifierKeyInfoProviderXcb()
{
if (m_xkbAvailable) {
QCoreApplication::instance()->removeNativeEventFilter(this);
}
}

bool KModifierKeyInfoProvider::setKeyLatched(Qt::Key key, bool latched)
bool KModifierKeyInfoProviderXcb::setKeyLatched(Qt::Key key, bool latched)
{
if (!m_xkbModifiers.contains(key)) {
return false;
Expand All @@ -128,7 +127,7 @@ bool KModifierKeyInfoProvider::setKeyLatched(Qt::Key key, bool latched)
m_xkbModifiers[key], latched ? m_xkbModifiers[key] : 0);
}

bool KModifierKeyInfoProvider::setKeyLocked(Qt::Key key, bool locked)
bool KModifierKeyInfoProviderXcb::setKeyLocked(Qt::Key key, bool locked)
{
if (!m_xkbModifiers.contains(key)) {
return false;
Expand Down Expand Up @@ -208,7 +207,7 @@ typedef union {
} _xkb_event;
}

bool KModifierKeyInfoProvider::nativeEventFilter(const QByteArray &eventType, void *message, long int *result)
bool KModifierKeyInfoProviderXcb::nativeEventFilter(const QByteArray &eventType, void *message, long int *result)
{
Q_UNUSED(result)
if (!m_xkbAvailable || eventType != "xcb_generic_event_t") {
Expand All @@ -233,12 +232,11 @@ bool KModifierKeyInfoProvider::nativeEventFilter(const QByteArray &eventType, vo
return false;
}

void KModifierKeyInfoProvider::xkbModifierStateChanged(unsigned char mods,
void KModifierKeyInfoProviderXcb::xkbModifierStateChanged(unsigned char mods,
unsigned char latched_mods,
unsigned char locked_mods)
{
// detect keyboard modifiers
ModifierStates oldState;
ModifierStates newState;

QHash<Qt::Key, unsigned int>::const_iterator it;
Expand All @@ -248,7 +246,6 @@ void KModifierKeyInfoProvider::xkbModifierStateChanged(unsigned char mods,
continue;
}
newState = Nothing;
oldState = m_modifierStates[it.key()];

// determine the new state
if (mods & it.value()) {
Expand All @@ -261,23 +258,11 @@ void KModifierKeyInfoProvider::xkbModifierStateChanged(unsigned char mods,
newState |= Locked;
}

if (newState != oldState) {
m_modifierStates[it.key()] = newState;

if ((newState ^ oldState) & Pressed) {
emit keyPressed(it.key(), newState & Pressed);
}
if ((newState ^ oldState) & Latched) {
emit keyLatched(it.key(), newState & Latched);
}
if ((newState ^ oldState) & Locked) {
emit keyLocked(it.key(), newState & Locked);
}
}
stateUpdated(it.key(), newState);
}
}

void KModifierKeyInfoProvider::xkbButtonStateChanged(unsigned short ptr_buttons)
void KModifierKeyInfoProviderXcb::xkbButtonStateChanged(unsigned short ptr_buttons)
{
// detect mouse button states
bool newButtonState;
Expand All @@ -293,7 +278,7 @@ void KModifierKeyInfoProvider::xkbButtonStateChanged(unsigned short ptr_buttons)
}
}

void KModifierKeyInfoProvider::xkbUpdateModifierMapping()
void KModifierKeyInfoProviderXcb::xkbUpdateModifierMapping()
{
if (!m_xkbAvailable) {
return;
Expand Down

0 comments on commit 0fe2990

Please sign in to comment.