|
|
|
|
@ -13,8 +13,11 @@ |
|
|
|
|
#include "wayland_server.h" |
|
|
|
|
#include "window.h" |
|
|
|
|
#include "workspace.h" |
|
|
|
|
#include "x11window.h" |
|
|
|
|
|
|
|
|
|
#include <KWayland/Client/surface.h> |
|
|
|
|
#include <netwm.h> |
|
|
|
|
#include <xcb/xcb_icccm.h> |
|
|
|
|
|
|
|
|
|
namespace KWin |
|
|
|
|
{ |
|
|
|
|
@ -36,6 +39,7 @@ private Q_SLOTS: |
|
|
|
|
void testSwitchToWindowBelow(); |
|
|
|
|
void testSwitchToWindowMaximized(); |
|
|
|
|
void testSwitchToWindowFullScreen(); |
|
|
|
|
void testActiveFullscreen(); |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
void stackScreensHorizontally(); |
|
|
|
|
@ -530,6 +534,68 @@ void ActivationTest::stackScreensVertically() |
|
|
|
|
Test::setOutputConfig(screenGeometries); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static X11Window *createX11Window(xcb_connection_t *connection, const QRect &geometry, std::function<void(xcb_window_t)> setup = {}) |
|
|
|
|
{ |
|
|
|
|
xcb_window_t windowId = xcb_generate_id(connection); |
|
|
|
|
xcb_create_window(connection, XCB_COPY_FROM_PARENT, windowId, rootWindow(), |
|
|
|
|
geometry.x(), |
|
|
|
|
geometry.y(), |
|
|
|
|
geometry.width(), |
|
|
|
|
geometry.height(), |
|
|
|
|
0, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, 0, nullptr); |
|
|
|
|
|
|
|
|
|
xcb_size_hints_t hints; |
|
|
|
|
memset(&hints, 0, sizeof(hints)); |
|
|
|
|
xcb_icccm_size_hints_set_position(&hints, 1, geometry.x(), geometry.y()); |
|
|
|
|
xcb_icccm_size_hints_set_size(&hints, 1, geometry.width(), geometry.height()); |
|
|
|
|
xcb_icccm_set_wm_normal_hints(connection, windowId, &hints); |
|
|
|
|
|
|
|
|
|
if (setup) { |
|
|
|
|
setup(windowId); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
xcb_map_window(connection, windowId); |
|
|
|
|
xcb_flush(connection); |
|
|
|
|
|
|
|
|
|
QSignalSpy windowCreatedSpy(workspace(), &Workspace::windowAdded); |
|
|
|
|
if (!windowCreatedSpy.wait()) { |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
return windowCreatedSpy.last().first().value<X11Window *>(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ActivationTest::testActiveFullscreen() |
|
|
|
|
{ |
|
|
|
|
// Tests that an active X11 fullscreen window gets removed from the active layer
|
|
|
|
|
// when activating a Wayland window, even if there's a pending activation request
|
|
|
|
|
// for the X11 window
|
|
|
|
|
Test::setOutputConfig({QRect(0, 0, 1280, 1024)}); |
|
|
|
|
|
|
|
|
|
Test::XcbConnectionPtr c = Test::createX11Connection(); |
|
|
|
|
QVERIFY(!xcb_connection_has_error(c.get())); |
|
|
|
|
X11Window *x11Window = createX11Window(c.get(), QRect(0, 0, 100, 200)); |
|
|
|
|
|
|
|
|
|
// make it fullscreen
|
|
|
|
|
x11Window->setFullScreen(true); |
|
|
|
|
QVERIFY(x11Window->isFullScreen()); |
|
|
|
|
QCOMPARE(x11Window->layer(), Layer::ActiveLayer); |
|
|
|
|
|
|
|
|
|
// now, activate it again
|
|
|
|
|
workspace()->activateWindow(x11Window); |
|
|
|
|
|
|
|
|
|
// now, create and activate a Wayland window
|
|
|
|
|
std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface()); |
|
|
|
|
std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get())); |
|
|
|
|
auto waylandWindow = Test::renderAndWaitForShown(surface.get(), QSize(500, 300), Qt::blue); |
|
|
|
|
QVERIFY(waylandWindow); |
|
|
|
|
|
|
|
|
|
// the Wayland window should become active
|
|
|
|
|
// and the X11 window should not be in the active layer anymore
|
|
|
|
|
QSignalSpy stackingOrder(workspace(), &Workspace::stackingOrderChanged); |
|
|
|
|
workspace()->activateWindow(waylandWindow); |
|
|
|
|
QCOMPARE(workspace()->activeWindow(), waylandWindow); |
|
|
|
|
QCOMPARE(x11Window->layer(), Layer::NormalLayer); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
WAYLANDTEST_MAIN(KWin::ActivationTest) |
|
|
|
|
|