Improve keyboard handling for internal windows
So far the key handler in the InternalWindowEventFilter used the PointerInputRedirection's internal window. This had the result that key events were only delivered to an internal window if the window was under the cursor. This change tries sending the event to the latest created and visible window. Thus e.g. with nested context menus it goes to the current sub menu as expected. The return value of sendEvent is used to filter out the event.
This commit is contained in:
parent
36facda110
commit
521470b04a
2 changed files with 29 additions and 5 deletions
|
@ -44,6 +44,7 @@ private Q_SLOTS:
|
||||||
void testEnterLeave();
|
void testEnterLeave();
|
||||||
void testPointerPressRelease();
|
void testPointerPressRelease();
|
||||||
void testPointerAxis();
|
void testPointerAxis();
|
||||||
|
void testKeyboard_data();
|
||||||
void testKeyboard();
|
void testKeyboard();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -237,6 +238,14 @@ void InternalWindowTest::testPointerAxis()
|
||||||
QTRY_COMPARE(wheelSpy.count(), 2);
|
QTRY_COMPARE(wheelSpy.count(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InternalWindowTest::testKeyboard_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QPoint>("cursorPos");
|
||||||
|
|
||||||
|
QTest::newRow("on Window") << QPoint(50, 50);
|
||||||
|
QTest::newRow("outside Window") << QPoint(250, 250);
|
||||||
|
}
|
||||||
|
|
||||||
void InternalWindowTest::testKeyboard()
|
void InternalWindowTest::testKeyboard()
|
||||||
{
|
{
|
||||||
QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded);
|
QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded);
|
||||||
|
@ -252,7 +261,8 @@ void InternalWindowTest::testKeyboard()
|
||||||
QCOMPARE(clientAddedSpy.count(), 1);
|
QCOMPARE(clientAddedSpy.count(), 1);
|
||||||
|
|
||||||
quint32 timestamp = 1;
|
quint32 timestamp = 1;
|
||||||
waylandServer()->backend()->pointerMotion(QPoint(50, 50), timestamp++);
|
QFETCH(QPoint, cursorPos);
|
||||||
|
waylandServer()->backend()->pointerMotion(cursorPos, timestamp++);
|
||||||
|
|
||||||
waylandServer()->backend()->keyboardKeyPressed(KEY_A, timestamp++);
|
waylandServer()->backend()->keyboardKeyPressed(KEY_A, timestamp++);
|
||||||
QTRY_COMPARE(pressSpy.count(), 1);
|
QTRY_COMPARE(pressSpy.count(), 1);
|
||||||
|
|
22
input.cpp
22
input.cpp
|
@ -385,13 +385,27 @@ class InternalWindowEventFilter : public InputEventFilter {
|
||||||
return e.isAccepted();
|
return e.isAccepted();
|
||||||
}
|
}
|
||||||
bool keyEvent(QKeyEvent *event) override {
|
bool keyEvent(QKeyEvent *event) override {
|
||||||
auto internal = input()->pointer()->internalWindow();
|
const auto &internalClients = waylandServer()->internalClients();
|
||||||
if (!internal) {
|
if (internalClients.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QWindow *found = nullptr;
|
||||||
|
auto it = internalClients.end();
|
||||||
|
do {
|
||||||
|
it--;
|
||||||
|
if (QWindow *w = (*it)->internalWindow()) {
|
||||||
|
if (!w->isVisible()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
found = w;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (it != internalClients.begin());
|
||||||
|
if (!found) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
event->setAccepted(false);
|
event->setAccepted(false);
|
||||||
QCoreApplication::sendEvent(internal.data(), event);
|
return QCoreApplication::sendEvent(found, event);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue