use qt native event filter instead of xlib directly
This commit is contained in:
parent
f3796d1416
commit
40af227b7f
|
@ -2,7 +2,7 @@
|
||||||
#include <QQmlApplicationEngine>
|
#include <QQmlApplicationEngine>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
#include "xlib_wrapper.h"
|
#include "xcbEventFilter.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -11,7 +11,9 @@ int main(int argc, char *argv[])
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
engine.load(QUrl(QStringLiteral("qrc:/fookb.qml")));
|
engine.load(QUrl(QStringLiteral("qrc:/fookb.qml")));
|
||||||
|
|
||||||
XlibWrapper xlib;
|
// Install event filter to handle mapping change
|
||||||
|
XcbEventFilter eventFilter;
|
||||||
|
app.installNativeEventFilter(&eventFilter);
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
SOURCES = fookb.cpp \
|
SOURCES = fookb.cpp \
|
||||||
xlib_wrapper.cpp
|
xcbEventFilter.cpp
|
||||||
HEADERS = xlib_wrapper.h
|
HEADERS = xcbEventFilter.h
|
||||||
TARGET = fookb
|
TARGET = fookb
|
||||||
|
|
||||||
RESOURCES = fookb.qrc
|
RESOURCES = fookb.qrc
|
||||||
QT += widgets qml
|
QT += widgets qml
|
||||||
QMAKE_LFLAGS +=-lX11
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include "xcbEventFilter.h"
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include <xcb/xcb.h>
|
||||||
|
|
||||||
|
XcbEventFilter::XcbEventFilter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
XcbEventFilter::~XcbEventFilter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XcbEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *)
|
||||||
|
{
|
||||||
|
if (eventType == "xcb_generic_event_t") {
|
||||||
|
xcb_generic_event_t* ev = static_cast<xcb_generic_event_t *>(message);
|
||||||
|
qDebug() << "XCB Event";
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef XCB_EVENT_FILTER_H
|
||||||
|
#define XCB_EVENT_FILTER_H
|
||||||
|
|
||||||
|
#include <QAbstractNativeEventFilter>
|
||||||
|
|
||||||
|
class XcbEventFilter : public QAbstractNativeEventFilter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
XcbEventFilter();
|
||||||
|
~XcbEventFilter() override;
|
||||||
|
bool nativeEventFilter(const QByteArray &eventType, void *message, long *) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // XCB_EVENT_FILTER_H
|
|
@ -1,75 +0,0 @@
|
||||||
#include "xlib_wrapper.h"
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
/* X Window headers */
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <X11/Xutil.h>
|
|
||||||
/* XKB fun */
|
|
||||||
#include <X11/XKBlib.h>
|
|
||||||
|
|
||||||
XlibWrapper::XlibWrapper()
|
|
||||||
{
|
|
||||||
timer = new QTimer(this);
|
|
||||||
timer->setSingleShot(true);
|
|
||||||
connect(timer, SIGNAL(timeout()),
|
|
||||||
this, SLOT(XlibWrapperSlot()));
|
|
||||||
timer->start(1000);
|
|
||||||
}
|
|
||||||
/* Instead of this, should subscribe to the correct QEvent */
|
|
||||||
/*
|
|
||||||
* https://doc.qt.io/qt-5/qabstractnativeeventfilter.html
|
|
||||||
*
|
|
||||||
* case XCB_MAPPING_NOTIFY:
|
|
||||||
m_keyboard->handleMappingNotifyEvent((xcb_mapping_notify_event_t *)event);
|
|
||||||
break;
|
|
||||||
*/
|
|
||||||
|
|
||||||
void XlibWrapper::XlibWrapperSlot()
|
|
||||||
{
|
|
||||||
int event_rtrn;
|
|
||||||
int error_rtrn;
|
|
||||||
int reason_rtrn;
|
|
||||||
Display *dpy;
|
|
||||||
XkbEvent labuda;
|
|
||||||
|
|
||||||
int state = 0;
|
|
||||||
|
|
||||||
qDebug() << "Timer...";
|
|
||||||
dpy = XkbOpenDisplay(NULL,
|
|
||||||
&event_rtrn,
|
|
||||||
&error_rtrn, NULL, NULL, &reason_rtrn);
|
|
||||||
if (dpy == NULL) {
|
|
||||||
qDebug() << "Cannot open display";
|
|
||||||
qApp->quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We would like receive the only Xkb event: XkbStateNotify. And only
|
|
||||||
* when XkbLockGroup happens. */
|
|
||||||
if (False == XkbSelectEvents(dpy,
|
|
||||||
XkbUseCoreKbd,
|
|
||||||
XkbAllEventsMask,
|
|
||||||
0)) {
|
|
||||||
qDebug() << "Cannot XkbSelectEvents.";
|
|
||||||
qApp->quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (False == XkbSelectEventDetails(dpy,
|
|
||||||
XkbUseCoreKbd,
|
|
||||||
XkbStateNotify,
|
|
||||||
XkbAllEventsMask,
|
|
||||||
XkbGroupLockMask)) {
|
|
||||||
qDebug() << "Cannot XkbSelectEventDetails.";
|
|
||||||
qApp->quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
XNextEvent(dpy, &labuda.core);
|
|
||||||
state = labuda.state.group;
|
|
||||||
/* Should not be necessary, here works only with 2 keyboard dispositions */
|
|
||||||
if ((state < 0) || (state > 1))
|
|
||||||
state = 1;
|
|
||||||
qDebug() << "XNextEvent";
|
|
||||||
/* TODO: update flag depending on state */
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
#ifndef XLIB_WRAPPER_H
|
|
||||||
#define XLIB_WRAPPER_H
|
|
||||||
|
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
class XlibWrapper : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
XlibWrapper();
|
|
||||||
QTimer *timer;
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void XlibWrapperSlot();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // XLIB_WRAPPER_H
|
|
Loading…
Reference in New Issue