[kwinrules] Use native event filter for mouse button release detection
The event filtering on Qt level does not work any more. The information is not updated properly. Grabbing the mouse through QWidget resets the cursor shape to the default shape, so it cannot be used. As we don't want Qt to ever see the events it's a good idea to use a native event filter to filter the events away before they are delivered to Qt. To simplify the handling the grabber widget is put into a QScopedPointer.
This commit is contained in:
parent
3956c73c53
commit
7d21d612fe
2 changed files with 19 additions and 16 deletions
|
@ -49,7 +49,7 @@ DetectWidget::DetectWidget(QWidget* parent)
|
|||
|
||||
DetectDialog::DetectDialog(QWidget* parent, const char* name)
|
||||
: KDialog(parent),
|
||||
grabber(NULL)
|
||||
grabber()
|
||||
{
|
||||
setObjectName(name);
|
||||
setModal(true);
|
||||
|
@ -168,7 +168,7 @@ void DetectDialog::selectWindow()
|
|||
// use a dialog, so that all user input is blocked
|
||||
// use WX11BypassWM and moving away so that it's not actually visible
|
||||
// grab only mouse, so that keyboard can be used e.g. for switching windows
|
||||
grabber = new KDialog(0, Qt::X11BypassWindowManagerHint);
|
||||
grabber.reset(new KDialog(0, Qt::X11BypassWindowManagerHint));
|
||||
grabber->move(-1000, -1000);
|
||||
grabber->setModal(true);
|
||||
grabber->show();
|
||||
|
@ -177,24 +177,26 @@ void DetectDialog::selectWindow()
|
|||
if (XGrabPointer(QX11Info::display(), grabber->winId(), false, ButtonReleaseMask,
|
||||
GrabModeAsync, GrabModeAsync, None, QCursor(Qt::CrossCursor).handle(),
|
||||
CurrentTime) == Success) { // ...so we use the far more convincing CurrentTime
|
||||
grabber->grabMouse(Qt::CrossCursor); // do anyway, so that Qt updates the mouseGrabber info
|
||||
grabber->installEventFilter(this);
|
||||
QCoreApplication::instance()->installNativeEventFilter(this);
|
||||
} else {
|
||||
// ... and if we fail, cleanup, so we won't receive random events
|
||||
delete grabber;
|
||||
grabber = 0;
|
||||
grabber.reset();
|
||||
}
|
||||
}
|
||||
|
||||
bool DetectDialog::eventFilter(QObject* o, QEvent* e)
|
||||
bool DetectDialog::nativeEventFilter(const QByteArray &eventType, void *message, long int*)
|
||||
{
|
||||
if (o != grabber)
|
||||
if (eventType != QByteArrayLiteral("xcb_generic_event_t")) {
|
||||
return false;
|
||||
if (e->type() != QEvent::MouseButtonRelease)
|
||||
}
|
||||
auto *event = reinterpret_cast<xcb_generic_event_t *>(message);
|
||||
if ((event->response_type & ~0x80) != XCB_BUTTON_RELEASE) {
|
||||
return false;
|
||||
delete grabber;
|
||||
grabber = NULL;
|
||||
if (static_cast< QMouseEvent* >(e)->button() != Qt::LeftButton) {
|
||||
}
|
||||
QCoreApplication::instance()->removeNativeEventFilter(this);
|
||||
grabber.reset();
|
||||
auto *me = reinterpret_cast<xcb_button_press_event_t*>(event);
|
||||
if (me->detail != XCB_BUTTON_INDEX_1) {
|
||||
emit detectionDone(false);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <KDialog>
|
||||
#include <kwindowsystem.h>
|
||||
#include <QAbstractNativeEventFilter>
|
||||
|
||||
#include "../../rules.h"
|
||||
//Added by qt3to4:
|
||||
|
@ -42,7 +43,7 @@ public:
|
|||
};
|
||||
|
||||
class DetectDialog
|
||||
: public KDialog
|
||||
: public KDialog, public QAbstractNativeEventFilter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -57,10 +58,10 @@ public:
|
|||
Rules::StringMatch titleMatch() const;
|
||||
QByteArray selectedMachine() const;
|
||||
const KWindowInfo& windowInfo() const;
|
||||
|
||||
virtual bool nativeEventFilter(const QByteArray& eventType, void* message, long int* result) override;
|
||||
Q_SIGNALS:
|
||||
void detectionDone(bool);
|
||||
protected:
|
||||
virtual bool eventFilter(QObject* o, QEvent* e);
|
||||
private Q_SLOTS:
|
||||
void selectWindow();
|
||||
private:
|
||||
|
@ -75,7 +76,7 @@ private:
|
|||
QByteArray extrarole;
|
||||
QByteArray machine;
|
||||
DetectWidget* widget;
|
||||
KDialog* grabber;
|
||||
QScopedPointer<KDialog> grabber;
|
||||
KWindowInfo info;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue