Merge branch 'Plasma/5.18' into Plasma/5.19
This commit is contained in:
commit
578ede2dd7
2 changed files with 72 additions and 0 deletions
|
@ -60,6 +60,7 @@ private Q_SLOTS:
|
||||||
void testCaptionWmName();
|
void testCaptionWmName();
|
||||||
void testCaptionMultipleWindows();
|
void testCaptionMultipleWindows();
|
||||||
void testFullscreenWindowGroups();
|
void testFullscreenWindowGroups();
|
||||||
|
void testActivateFocusedWindow();
|
||||||
};
|
};
|
||||||
|
|
||||||
void X11ClientTest::initTestCase()
|
void X11ClientTest::initTestCase()
|
||||||
|
@ -1000,5 +1001,71 @@ void X11ClientTest::testFullscreenWindowGroups()
|
||||||
QTRY_COMPARE(client->layer(), ActiveLayer);
|
QTRY_COMPARE(client->layer(), ActiveLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void X11ClientTest::testActivateFocusedWindow()
|
||||||
|
{
|
||||||
|
// The window manager may call XSetInputFocus() on a window that already has focus, in which
|
||||||
|
// case no FocusIn event will be generated and the window won't be marked as active. This test
|
||||||
|
// verifies that we handle that subtle case properly.
|
||||||
|
|
||||||
|
QScopedPointer<xcb_connection_t, XcbConnectionDeleter> connection(xcb_connect(nullptr, nullptr));
|
||||||
|
QVERIFY(!xcb_connection_has_error(connection.data()));
|
||||||
|
|
||||||
|
QSignalSpy windowCreatedSpy(workspace(), &Workspace::clientAdded);
|
||||||
|
QVERIFY(windowCreatedSpy.isValid());
|
||||||
|
|
||||||
|
const QRect windowGeometry(0, 0, 100, 200);
|
||||||
|
xcb_size_hints_t hints;
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
xcb_icccm_size_hints_set_position(&hints, 1, windowGeometry.x(), windowGeometry.y());
|
||||||
|
xcb_icccm_size_hints_set_size(&hints, 1, windowGeometry.width(), windowGeometry.height());
|
||||||
|
|
||||||
|
// Create the first test window.
|
||||||
|
const xcb_window_t window1 = xcb_generate_id(connection.data());
|
||||||
|
xcb_create_window(connection.data(), XCB_COPY_FROM_PARENT, window1, rootWindow(),
|
||||||
|
windowGeometry.x(), windowGeometry.y(),
|
||||||
|
windowGeometry.width(), windowGeometry.height(),
|
||||||
|
0, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, 0, nullptr);
|
||||||
|
xcb_icccm_set_wm_normal_hints(connection.data(), window1, &hints);
|
||||||
|
xcb_change_property(connection.data(), XCB_PROP_MODE_REPLACE, window1,
|
||||||
|
atoms->wm_client_leader, XCB_ATOM_WINDOW, 32, 1, &window1);
|
||||||
|
xcb_map_window(connection.data(), window1);
|
||||||
|
xcb_flush(connection.data());
|
||||||
|
QVERIFY(windowCreatedSpy.wait());
|
||||||
|
X11Client *client1 = windowCreatedSpy.first().first().value<X11Client *>();
|
||||||
|
QVERIFY(client1);
|
||||||
|
QCOMPARE(client1->windowId(), window1);
|
||||||
|
QCOMPARE(client1->isActive(), true);
|
||||||
|
|
||||||
|
// Create the second test window.
|
||||||
|
const xcb_window_t window2 = xcb_generate_id(connection.data());
|
||||||
|
xcb_create_window(connection.data(), XCB_COPY_FROM_PARENT, window2, rootWindow(),
|
||||||
|
windowGeometry.x(), windowGeometry.y(),
|
||||||
|
windowGeometry.width(), windowGeometry.height(),
|
||||||
|
0, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, 0, nullptr);
|
||||||
|
xcb_icccm_set_wm_normal_hints(connection.data(), window2, &hints);
|
||||||
|
xcb_change_property(connection.data(), XCB_PROP_MODE_REPLACE, window2,
|
||||||
|
atoms->wm_client_leader, XCB_ATOM_WINDOW, 32, 1, &window2);
|
||||||
|
xcb_map_window(connection.data(), window2);
|
||||||
|
xcb_flush(connection.data());
|
||||||
|
QVERIFY(windowCreatedSpy.wait());
|
||||||
|
X11Client *client2 = windowCreatedSpy.last().first().value<X11Client *>();
|
||||||
|
QVERIFY(client2);
|
||||||
|
QCOMPARE(client2->windowId(), window2);
|
||||||
|
QCOMPARE(client2->isActive(), true);
|
||||||
|
|
||||||
|
// When the second test window is destroyed, the window manager will attempt to activate the
|
||||||
|
// next client in the focus chain, which is the first window.
|
||||||
|
xcb_set_input_focus(connection.data(), XCB_INPUT_FOCUS_POINTER_ROOT, window1, XCB_CURRENT_TIME);
|
||||||
|
xcb_destroy_window(connection.data(), window2);
|
||||||
|
xcb_flush(connection.data());
|
||||||
|
QVERIFY(Test::waitForWindowDestroyed(client2));
|
||||||
|
QVERIFY(client1->isActive());
|
||||||
|
|
||||||
|
// Destroy the first test window.
|
||||||
|
xcb_destroy_window(connection.data(), window1);
|
||||||
|
xcb_flush(connection.data());
|
||||||
|
QVERIFY(Test::waitForWindowDestroyed(client1));
|
||||||
|
}
|
||||||
|
|
||||||
WAYLANDTEST_MAIN(X11ClientTest)
|
WAYLANDTEST_MAIN(X11ClientTest)
|
||||||
#include "x11_client_test.moc"
|
#include "x11_client_test.moc"
|
||||||
|
|
|
@ -2025,6 +2025,11 @@ void X11Client::setOnAllActivities(bool on)
|
||||||
*/
|
*/
|
||||||
void X11Client::takeFocus()
|
void X11Client::takeFocus()
|
||||||
{
|
{
|
||||||
|
// Force a FocusIn event if the window is already focused but inactive.
|
||||||
|
Xcb::CurrentInput currentInput;
|
||||||
|
if (!currentInput.isNull() && currentInput.window() == window())
|
||||||
|
workspace()->focusToNull();
|
||||||
|
|
||||||
if (rules()->checkAcceptFocus(info->input()))
|
if (rules()->checkAcceptFocus(info->input()))
|
||||||
m_client.focus();
|
m_client.focus();
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue