diff --git a/autotests/integration/decoration_input_test.cpp b/autotests/integration/decoration_input_test.cpp
--- a/autotests/integration/decoration_input_test.cpp
+++ b/autotests/integration/decoration_input_test.cpp
@@ -170,9 +170,12 @@
QTest::newRow("topLeft") << QPoint(0, 0) << Qt::TopLeftSection << Test::ShellSurfaceType::WlShell;
QTest::newRow("top") << QPoint(250, 0) << Qt::TopSection << Test::ShellSurfaceType::WlShell;
QTest::newRow("topRight") << QPoint(499, 0) << Qt::TopRightSection << Test::ShellSurfaceType::WlShell;
- QTest::newRow("topLeft|xdg") << QPoint(0, 0) << Qt::TopLeftSection << Test::ShellSurfaceType::XdgShellV5;
- QTest::newRow("top|xdg") << QPoint(250, 0) << Qt::TopSection << Test::ShellSurfaceType::XdgShellV5;
- QTest::newRow("topRight|xdg") << QPoint(499, 0) << Qt::TopRightSection << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("topLeft|xdgv5") << QPoint(0, 0) << Qt::TopLeftSection << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("top|xdgv5") << QPoint(250, 0) << Qt::TopSection << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("topRight|xdgv5") << QPoint(499, 0) << Qt::TopRightSection << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("topLeft|xdgv6") << QPoint(0, 0) << Qt::TopLeftSection << Test::ShellSurfaceType::XdgShellV6;
+ QTest::newRow("top|xdgv6") << QPoint(250, 0) << Qt::TopSection << Test::ShellSurfaceType::XdgShellV6;
+ QTest::newRow("topRight|xdgv6") << QPoint(499, 0) << Qt::TopRightSection << Test::ShellSurfaceType::XdgShellV6;
}
void DecorationInputTest::testAxis()
@@ -224,9 +227,12 @@
QTest::newRow("topLeft") << QPoint(0, 0) << Qt::TopLeftSection << Test::ShellSurfaceType::WlShell;
QTest::newRow("top") << QPoint(250, 0) << Qt::TopSection << Test::ShellSurfaceType::WlShell;
QTest::newRow("topRight") << QPoint(499, 0) << Qt::TopRightSection << Test::ShellSurfaceType::WlShell;
- QTest::newRow("topLeft|xdg") << QPoint(0, 0) << Qt::TopLeftSection << Test::ShellSurfaceType::XdgShellV5;
- QTest::newRow("top|xdg") << QPoint(250, 0) << Qt::TopSection << Test::ShellSurfaceType::XdgShellV5;
- QTest::newRow("topRight|xdg") << QPoint(499, 0) << Qt::TopRightSection << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("topLeft|xdgv5") << QPoint(0, 0) << Qt::TopLeftSection << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("top|xdgv5") << QPoint(250, 0) << Qt::TopSection << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("topRight|xdgv5") << QPoint(499, 0) << Qt::TopRightSection << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("topLeft|xdgv6") << QPoint(0, 0) << Qt::TopLeftSection << Test::ShellSurfaceType::XdgShellV6;
+ QTest::newRow("top|xdgv6") << QPoint(250, 0) << Qt::TopSection << Test::ShellSurfaceType::XdgShellV6;
+ QTest::newRow("topRight|xdgv6") << QPoint(499, 0) << Qt::TopRightSection << Test::ShellSurfaceType::XdgShellV6;
}
void KWin::DecorationInputTest::testDoubleClick()
@@ -279,9 +285,13 @@
QTest::newRow("topLeft") << QPoint(0, 0) << Qt::TopLeftSection << Test::ShellSurfaceType::WlShell;
QTest::newRow("top") << QPoint(250, 0) << Qt::TopSection << Test::ShellSurfaceType::WlShell;
QTest::newRow("topRight") << QPoint(499, 0) << Qt::TopRightSection << Test::ShellSurfaceType::WlShell;
- QTest::newRow("topLeft|xdg") << QPoint(0, 0) << Qt::TopLeftSection << Test::ShellSurfaceType::XdgShellV5;
- QTest::newRow("top|xdg") << QPoint(250, 0) << Qt::TopSection << Test::ShellSurfaceType::XdgShellV5;
- QTest::newRow("topRight|xdg") << QPoint(499, 0) << Qt::TopRightSection << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("topLeft|xdgv5") << QPoint(0, 0) << Qt::TopLeftSection << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("top|xdgv5") << QPoint(250, 0) << Qt::TopSection << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("topRight|xdgv5") << QPoint(499, 0) << Qt::TopRightSection << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("topLeft|xdgv6") << QPoint(0, 0) << Qt::TopLeftSection << Test::ShellSurfaceType::XdgShellV6;
+ QTest::newRow("top|xdgv6") << QPoint(250, 0) << Qt::TopSection << Test::ShellSurfaceType::XdgShellV6;
+ QTest::newRow("topRight|xdgv6") << QPoint(499, 0) << Qt::TopRightSection << Test::ShellSurfaceType::XdgShellV6;
+
}
void KWin::DecorationInputTest::testDoubleTap()
@@ -330,6 +340,7 @@
QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell;
QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6;
}
void DecorationInputTest::testHover()
@@ -380,10 +391,14 @@
QTest::newRow("To left") << QPoint(-10, 0) << QPoint(-20, 0) << QPoint(-30, 0) << Test::ShellSurfaceType::WlShell;
QTest::newRow("To bottom") << QPoint(0, 10) << QPoint(0, 20) << QPoint(0, 30) << Test::ShellSurfaceType::WlShell;
QTest::newRow("To top") << QPoint(0, -10) << QPoint(0, -20) << QPoint(0, -30) << Test::ShellSurfaceType::WlShell;
- QTest::newRow("To right|xdg") << QPoint(10, 0) << QPoint(20, 0) << QPoint(30, 0) << Test::ShellSurfaceType::XdgShellV5;
- QTest::newRow("To left|xdg") << QPoint(-10, 0) << QPoint(-20, 0) << QPoint(-30, 0) << Test::ShellSurfaceType::XdgShellV5;
- QTest::newRow("To bottom|xdg") << QPoint(0, 10) << QPoint(0, 20) << QPoint(0, 30) << Test::ShellSurfaceType::XdgShellV5;
- QTest::newRow("To top|xdg") << QPoint(0, -10) << QPoint(0, -20) << QPoint(0, -30) << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("To right|xdgv5") << QPoint(10, 0) << QPoint(20, 0) << QPoint(30, 0) << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("To left|xdgv5") << QPoint(-10, 0) << QPoint(-20, 0) << QPoint(-30, 0) << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("To bottom|xdgv5") << QPoint(0, 10) << QPoint(0, 20) << QPoint(0, 30) << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("To top|xdgv5") << QPoint(0, -10) << QPoint(0, -20) << QPoint(0, -30) << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("To right|xdgv6") << QPoint(10, 0) << QPoint(20, 0) << QPoint(30, 0) << Test::ShellSurfaceType::XdgShellV6;
+ QTest::newRow("To left|xdgv6") << QPoint(-10, 0) << QPoint(-20, 0) << QPoint(-30, 0) << Test::ShellSurfaceType::XdgShellV6;
+ QTest::newRow("To bottom|xdgv6") << QPoint(0, 10) << QPoint(0, 20) << QPoint(0, 30) << Test::ShellSurfaceType::XdgShellV6;
+ QTest::newRow("To top|xdgv6") << QPoint(0, -10) << QPoint(0, -20) << QPoint(0, -30) << Test::ShellSurfaceType::XdgShellV6;
}
void DecorationInputTest::testPressToMove()
@@ -445,10 +460,14 @@
QTest::newRow("To left") << QPoint(-10, 0) << QPoint(-20, 0) << QPoint(-30, 0) << Test::ShellSurfaceType::WlShell;
QTest::newRow("To bottom") << QPoint(0, 10) << QPoint(0, 20) << QPoint(0, 30) << Test::ShellSurfaceType::WlShell;
QTest::newRow("To top") << QPoint(0, -10) << QPoint(0, -20) << QPoint(0, -30) << Test::ShellSurfaceType::WlShell;
- QTest::newRow("To right|xdg") << QPoint(10, 0) << QPoint(20, 0) << QPoint(30, 0) << Test::ShellSurfaceType::XdgShellV5;
- QTest::newRow("To left|xdg") << QPoint(-10, 0) << QPoint(-20, 0) << QPoint(-30, 0) << Test::ShellSurfaceType::XdgShellV5;
- QTest::newRow("To bottom|xdg") << QPoint(0, 10) << QPoint(0, 20) << QPoint(0, 30) << Test::ShellSurfaceType::XdgShellV5;
- QTest::newRow("To top|xdg") << QPoint(0, -10) << QPoint(0, -20) << QPoint(0, -30) << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("To right|xdgv5") << QPoint(10, 0) << QPoint(20, 0) << QPoint(30, 0) << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("To left|xdgv5") << QPoint(-10, 0) << QPoint(-20, 0) << QPoint(-30, 0) << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("To bottom|xdgv5") << QPoint(0, 10) << QPoint(0, 20) << QPoint(0, 30) << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("To top|xdgv5") << QPoint(0, -10) << QPoint(0, -20) << QPoint(0, -30) << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("To right|xdgv6") << QPoint(10, 0) << QPoint(20, 0) << QPoint(30, 0) << Test::ShellSurfaceType::XdgShellV6;
+ QTest::newRow("To left|xdgv6") << QPoint(-10, 0) << QPoint(-20, 0) << QPoint(-30, 0) << Test::ShellSurfaceType::XdgShellV6;
+ QTest::newRow("To bottom|xdgv6") << QPoint(0, 10) << QPoint(0, 20) << QPoint(0, 30) << Test::ShellSurfaceType::XdgShellV6;
+ QTest::newRow("To top|xdgv6") << QPoint(0, -10) << QPoint(0, -20) << QPoint(0, -30) << Test::ShellSurfaceType::XdgShellV6;
}
void DecorationInputTest::testTapToMove()
@@ -508,10 +527,13 @@
QTest::newRow("wlShell - left") << Test::ShellSurfaceType::WlShell << Qt::LeftEdge << Qt::SizeHorCursor;
QTest::newRow("xdgShellV5 - left") << Test::ShellSurfaceType::XdgShellV5 << Qt::LeftEdge << Qt::SizeHorCursor;
+ QTest::newRow("xdgShellV6 - left") << Test::ShellSurfaceType::XdgShellV6 << Qt::LeftEdge << Qt::SizeHorCursor;
QTest::newRow("wlShell - right") << Test::ShellSurfaceType::WlShell << Qt::RightEdge << Qt::SizeHorCursor;
QTest::newRow("xdgShellV5 - right") << Test::ShellSurfaceType::XdgShellV5 << Qt::RightEdge << Qt::SizeHorCursor;
+ QTest::newRow("xdgShellV6 - right") << Test::ShellSurfaceType::XdgShellV6 << Qt::RightEdge << Qt::SizeHorCursor;
QTest::newRow("wlShell - bottom") << Test::ShellSurfaceType::WlShell << Qt::BottomEdge << Qt::SizeVerCursor;
QTest::newRow("xdgShellV5 - bottom") << Test::ShellSurfaceType::XdgShellV5 << Qt::BottomEdge << Qt::SizeVerCursor;
+ QTest::newRow("xdgShellV6 - bottom") << Test::ShellSurfaceType::XdgShellV6 << Qt::BottomEdge << Qt::SizeVerCursor;
}
void DecorationInputTest::testResizeOutsideWindow()
diff --git a/autotests/integration/dont_crash_no_border.cpp b/autotests/integration/dont_crash_no_border.cpp
--- a/autotests/integration/dont_crash_no_border.cpp
+++ b/autotests/integration/dont_crash_no_border.cpp
@@ -101,6 +101,7 @@
QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell;
QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6;
}
void DontCrashNoBorder::testCreateWindow()
diff --git a/autotests/integration/effects/fade_test.cpp b/autotests/integration/effects/fade_test.cpp
--- a/autotests/integration/effects/fade_test.cpp
+++ b/autotests/integration/effects/fade_test.cpp
@@ -119,6 +119,7 @@
QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell;
QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6;
}
void FadeTest::testWindowCloseAfterWindowHidden()
diff --git a/autotests/integration/helper/kill.cpp b/autotests/integration/helper/kill.cpp
--- a/autotests/integration/helper/kill.cpp
+++ b/autotests/integration/helper/kill.cpp
@@ -18,7 +18,10 @@
along with this program. If not, see .
*********************************************************************/
#include
+#include
+#include
#include
+#include
int main(int argc, char *argv[])
{
@@ -28,5 +31,14 @@
w.setGeometry(QRect(0, 0, 100, 200));
w.show();
+ //after showing the window block the main thread
+ //1 as we want it to come after the singleshots in qApp construction
+ QTimer::singleShot(1, []() {
+ //block
+ while(true) {
+ sleep(100000);
+ }
+ });
+
return app.exec();
}
diff --git a/autotests/integration/kwin_wayland_test.h b/autotests/integration/kwin_wayland_test.h
--- a/autotests/integration/kwin_wayland_test.h
+++ b/autotests/integration/kwin_wayland_test.h
@@ -118,7 +118,8 @@
KWayland::Client::Surface *createSurface(QObject *parent = nullptr);
enum class ShellSurfaceType {
WlShell,
- XdgShellV5
+ XdgShellV5,
+ XdgShellV6
};
QObject *createShellSurface(ShellSurfaceType type, KWayland::Client::Surface *surface, QObject *parent = nullptr);
KWayland::Client::ShellSurface *createShellSurface(KWayland::Client::Surface *surface, QObject *parent = nullptr);
diff --git a/autotests/integration/move_resize_window_test.cpp b/autotests/integration/move_resize_window_test.cpp
--- a/autotests/integration/move_resize_window_test.cpp
+++ b/autotests/integration/move_resize_window_test.cpp
@@ -502,6 +502,7 @@
QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell;
QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6;
}
void MoveResizeWindowTest::testClientSideMove()
diff --git a/autotests/integration/plasma_surface_test.cpp b/autotests/integration/plasma_surface_test.cpp
--- a/autotests/integration/plasma_surface_test.cpp
+++ b/autotests/integration/plasma_surface_test.cpp
@@ -256,12 +256,16 @@
QTest::newRow("always visible - wlShell") << Test::ShellSurfaceType::WlShell << PlasmaShellSurface::PanelBehavior::AlwaysVisible << true << QRect(0, 50, 1280, 974) << KWin::DockLayer;
QTest::newRow("always visible - xdgShellV5") << Test::ShellSurfaceType::XdgShellV5 << PlasmaShellSurface::PanelBehavior::AlwaysVisible << true << QRect(0, 50, 1280, 974) << KWin::DockLayer;
+ QTest::newRow("always visible - xdgShellV6") << Test::ShellSurfaceType::XdgShellV6 << PlasmaShellSurface::PanelBehavior::AlwaysVisible << true << QRect(0, 50, 1280, 974) << KWin::DockLayer;
QTest::newRow("autohide - wlShell") << Test::ShellSurfaceType::WlShell << PlasmaShellSurface::PanelBehavior::AutoHide << false << QRect(0, 0, 1280, 1024) << KWin::AboveLayer;
QTest::newRow("autohide - xdgShellV5") << Test::ShellSurfaceType::XdgShellV5 << PlasmaShellSurface::PanelBehavior::AutoHide << false << QRect(0, 0, 1280, 1024) << KWin::AboveLayer;
+ QTest::newRow("autohide - xdgShellV6") << Test::ShellSurfaceType::XdgShellV6 << PlasmaShellSurface::PanelBehavior::AutoHide << false << QRect(0, 0, 1280, 1024) << KWin::AboveLayer;
QTest::newRow("windows can cover - wlShell") << Test::ShellSurfaceType::WlShell << PlasmaShellSurface::PanelBehavior::WindowsCanCover << false << QRect(0, 0, 1280, 1024) << KWin::NormalLayer;
QTest::newRow("windows can cover - xdgShellV5") << Test::ShellSurfaceType::XdgShellV5 << PlasmaShellSurface::PanelBehavior::WindowsCanCover << false << QRect(0, 0, 1280, 1024) << KWin::NormalLayer;
+ QTest::newRow("windows can cover - xdgShellV6") << Test::ShellSurfaceType::XdgShellV6 << PlasmaShellSurface::PanelBehavior::WindowsCanCover << false << QRect(0, 0, 1280, 1024) << KWin::NormalLayer;
QTest::newRow("windows go below - wlShell") << Test::ShellSurfaceType::WlShell << PlasmaShellSurface::PanelBehavior::WindowsGoBelow << false << QRect(0, 0, 1280, 1024) << KWin::DockLayer;
QTest::newRow("windows go below - xdgShellV5") << Test::ShellSurfaceType::XdgShellV5 << PlasmaShellSurface::PanelBehavior::WindowsGoBelow << false << QRect(0, 0, 1280, 1024) << KWin::DockLayer;
+ QTest::newRow("windows go below - xdgShellV6") << Test::ShellSurfaceType::XdgShellV6 << PlasmaShellSurface::PanelBehavior::WindowsGoBelow << false << QRect(0, 0, 1280, 1024) << KWin::DockLayer;
}
void PlasmaSurfaceTest::testPanelTypeHasStrut()
diff --git a/autotests/integration/pointer_constraints_test.cpp b/autotests/integration/pointer_constraints_test.cpp
--- a/autotests/integration/pointer_constraints_test.cpp
+++ b/autotests/integration/pointer_constraints_test.cpp
@@ -129,6 +129,10 @@
QTest::newRow("XdgShellV5 - bottomRight") << Test::ShellSurfaceType::XdgShellV5 << bottomRight << 1 << 1;
QTest::newRow("XdgShellV5 - topLeft") << Test::ShellSurfaceType::XdgShellV5 << topLeft << -1 << -1;
QTest::newRow("XdgShellV5 - topRight") << Test::ShellSurfaceType::XdgShellV5 << topRight << 1 << -1;
+ QTest::newRow("XdgShellV6 - bottomLeft") << Test::ShellSurfaceType::XdgShellV6 << bottomLeft << -1 << 1;
+ QTest::newRow("XdgShellV6 - bottomRight") << Test::ShellSurfaceType::XdgShellV6 << bottomRight << 1 << 1;
+ QTest::newRow("XdgShellV6 - topLeft") << Test::ShellSurfaceType::XdgShellV6 << topLeft << -1 << -1;
+ QTest::newRow("XdgShellV6 - topRight") << Test::ShellSurfaceType::XdgShellV6 << topRight << 1 << -1;
}
void TestPointerConstraints::testConfinedPointer()
@@ -255,6 +259,7 @@
QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell;
QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6;
}
void TestPointerConstraints::testLockedPointer()
@@ -305,6 +310,7 @@
QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell;
QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6;
}
void TestPointerConstraints::testBreakConstrainedPointer()
@@ -393,6 +399,7 @@
QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell;
QTest::newRow("XdgShellV5") << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("XdgShellV6") << Test::ShellSurfaceType::XdgShellV6;
}
void TestPointerConstraints::testCloseWindowWithLockedPointer()
diff --git a/autotests/integration/scene_qpainter_test.cpp b/autotests/integration/scene_qpainter_test.cpp
--- a/autotests/integration/scene_qpainter_test.cpp
+++ b/autotests/integration/scene_qpainter_test.cpp
@@ -151,6 +151,7 @@
QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell;
QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6;
}
void SceneQPainterTest::testWindow()
@@ -255,6 +256,7 @@
QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell;
QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6;
}
void SceneQPainterTest::testCompositorRestart()
diff --git a/autotests/integration/shell_client_test.cpp b/autotests/integration/shell_client_test.cpp
--- a/autotests/integration/shell_client_test.cpp
+++ b/autotests/integration/shell_client_test.cpp
@@ -75,8 +75,8 @@
void testDesktopFileName();
void testCaptionSimplified();
void testCaptionMultipleWindows();
- void testKillWindow_data();
- void testKillWindow();
+ void testUnresponsiveWindow_data();
+ void testUnresponsiveWindow();
void testX11WindowId_data();
void testX11WindowId();
};
@@ -120,6 +120,7 @@
QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell;
QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6;
}
void TestShellClient::testMapUnmapMap()
@@ -281,6 +282,7 @@
QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell;
QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6;
}
void TestShellClient::testWindowOutputs()
@@ -327,6 +329,7 @@
QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell;
QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6;
}
void TestShellClient::testMinimizeActiveWindow()
@@ -368,9 +371,12 @@
QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell << ServerSideDecoration::Mode::Client;
QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5 << ServerSideDecoration::Mode::Client;
+ QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6 << ServerSideDecoration::Mode::Client;
+
QTest::newRow("wlShell - deco") << Test::ShellSurfaceType::WlShell << ServerSideDecoration::Mode::Server;
QTest::newRow("xdgShellV5 - deco") << Test::ShellSurfaceType::XdgShellV5 << ServerSideDecoration::Mode::Server;
+ QTest::newRow("xdgShellV6 - deco") << Test::ShellSurfaceType::XdgShellV6 << ServerSideDecoration::Mode::Server;
}
void TestShellClient::testFullscreen()
@@ -411,6 +417,7 @@
qobject_cast(shellSurface.data())->setFullscreen();
break;
case Test::ShellSurfaceType::XdgShellV5:
+ case Test::ShellSurfaceType::XdgShellV6:
qobject_cast(shellSurface.data())->setFullscreen(true);
break;
default:
@@ -441,6 +448,7 @@
qobject_cast(shellSurface.data())->setToplevel();
break;
case Test::ShellSurfaceType::XdgShellV5:
+ case Test::ShellSurfaceType::XdgShellV6:
qobject_cast(shellSurface.data())->setFullscreen(false);
break;
default:
@@ -465,9 +473,11 @@
QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell << ServerSideDecoration::Mode::Client;
QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5 << ServerSideDecoration::Mode::Client;
+ QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6 << ServerSideDecoration::Mode::Client;
QTest::newRow("wlShell - deco") << Test::ShellSurfaceType::WlShell << ServerSideDecoration::Mode::Server;
QTest::newRow("xdgShellV5 - deco") << Test::ShellSurfaceType::XdgShellV5 << ServerSideDecoration::Mode::Server;
+ QTest::newRow("xdgShellV6 - deco") << Test::ShellSurfaceType::XdgShellV6 << ServerSideDecoration::Mode::Server;
}
void TestShellClient::testMaximizedToFullscreen()
@@ -506,6 +516,7 @@
qobject_cast(shellSurface.data())->setMaximized();
break;
case Test::ShellSurfaceType::XdgShellV5:
+ case Test::ShellSurfaceType::XdgShellV6:
qobject_cast(shellSurface.data())->setMaximized(true);
break;
default:
@@ -524,6 +535,7 @@
qobject_cast(shellSurface.data())->setFullscreen();
break;
case Test::ShellSurfaceType::XdgShellV5:
+ case Test::ShellSurfaceType::XdgShellV6:
qobject_cast(shellSurface.data())->setFullscreen(true);
break;
default:
@@ -556,6 +568,7 @@
qobject_cast(shellSurface.data())->setToplevel();
break;
case Test::ShellSurfaceType::XdgShellV5:
+ case Test::ShellSurfaceType::XdgShellV6:
qobject_cast(shellSurface.data())->setFullscreen(false);
break;
default:
@@ -567,6 +580,7 @@
QCOMPARE(sizeChangeRequestedSpy.count(), 1);
QEXPECT_FAIL("wlShell - deco", "With decoration incorrect geometry requested", Continue);
QEXPECT_FAIL("xdgShellV5 - deco", "With decoration incorrect geometry requested", Continue);
+ QEXPECT_FAIL("xdgShellV6 - deco", "With decoration incorrect geometry requested", Continue);
QCOMPARE(sizeChangeRequestedSpy.last().first().toSize(), QSize(100, 50));
// TODO: should switch to fullscreen once it's updated
QVERIFY(!c->isFullScreen());
@@ -579,6 +593,7 @@
QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell;
QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6;
}
void TestShellClient::testWindowOpensLargerThanScreen()
@@ -615,6 +630,7 @@
QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell;
QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6;
}
void TestShellClient::testHidden()
@@ -741,15 +757,21 @@
QCOMPARE(c4->captionSuffix(), QStringLiteral(" <4>"));
}
-void TestShellClient::testKillWindow_data()
+void TestShellClient::testUnresponsiveWindow_data()
{
+ QTest::addColumn("shellInterface");//see env selection in qwaylandintegration.cpp
QTest::addColumn("socketMode");
- QTest::newRow("display") << false;
- QTest::newRow("socket") << true;
+ //wl-shell ping is not implemented
+ //QTest::newRow("wl-shell display") << "wl-shell" << false;
+ //QTest::newRow("wl-shell socket") << "wl-shell" << true;
+ QTest::newRow("xdgv5 display") << "xdg-shell-v5" << false;
+ QTest::newRow("xdgv5 socket") << "xdg-shell-v5" << true;
+ QTest::newRow("xdgv6 display") << "xdg-shell-v6" << false;
+ QTest::newRow("xdgv6 socket") << "xdg-shell-v6" << true;
}
-void TestShellClient::testKillWindow()
+void TestShellClient::testUnresponsiveWindow()
{
// this test verifies that killWindow properly terminates a process
// for this an external binary is launched
@@ -760,7 +782,10 @@
QScopedPointer process(new QProcess);
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+
+ QFETCH(QString, shellInterface);
QFETCH(bool, socketMode);
+ env.insert("QT_WAYLAND_SHELL_INTEGRATION", shellInterface);
if (socketMode) {
int sx[2];
QVERIFY(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sx) >= 0);
@@ -781,20 +806,46 @@
AbstractClient *killClient = nullptr;
QVERIFY(shellClientAddedSpy.wait());
killClient = shellClientAddedSpy.first().first().value();
- QVERIFY(killClient);
- QSignalSpy finishedSpy(process.data(), static_cast(&QProcess::finished));
- QVERIFY(finishedSpy.isValid());
- killClient->killWindow();
- QVERIFY(finishedSpy.wait());
- QVERIFY(!finishedSpy.isEmpty());
+ QSignalSpy unresponsiveSpy(killClient, &AbstractClient::unresponsiveChanged);
+ QSignalSpy killedSpy(process.data(), static_cast(&QProcess::finished));
+ QSignalSpy deletedSpy(killClient, &QObject::destroyed);
+
+ qint64 startTime = QDateTime::currentMSecsSinceEpoch();
+
+ //wait for the process to be frozen
+ QTest::qWait(10);
+
+ //pretend the user clicked the close button
+ killClient->closeWindow();
+
+ //client should not yet be marked unresponsive nor killed
+ QVERIFY(!killClient->unresponsive());
+ QVERIFY(killedSpy.isEmpty());
+
+ QVERIFY(unresponsiveSpy.wait());
+ //client should be marked unresponsive but not killed
+ auto elapsed1 = QDateTime::currentMSecsSinceEpoch() - startTime;
+ QVERIFY(elapsed1 > 900 && elapsed1 < 1200); //ping timer is 1s, but coarse timers on a test across two processes means we need a fuzzy compare
+ QVERIFY(killClient->unresponsive());
+ QVERIFY(killedSpy.isEmpty());
+
+ QVERIFY(deletedSpy.wait());
+ if (!socketMode) {
+ //process was killed - because we're across process this could happen in either order
+ QVERIFY(killedSpy.count() || killedSpy.wait());
+ }
+
+ auto elapsed2 = QDateTime::currentMSecsSinceEpoch() - startTime;
+ QVERIFY(elapsed2 > 1800); //second ping comes in a second later
}
void TestShellClient::testX11WindowId_data()
{
QTest::addColumn("type");
QTest::newRow("wlShell") << Test::ShellSurfaceType::WlShell;
QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5;
+ QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6;
}
void TestShellClient::testX11WindowId()
diff --git a/autotests/integration/test_helpers.cpp b/autotests/integration/test_helpers.cpp
--- a/autotests/integration/test_helpers.cpp
+++ b/autotests/integration/test_helpers.cpp
@@ -62,6 +62,7 @@
ServerSideDecorationManager *decoration = nullptr;
Shell *shell = nullptr;
XdgShell *xdgShellV5 = nullptr;
+ XdgShell *xdgShellV6 = nullptr;
ShmPool *shm = nullptr;
Seat *seat = nullptr;
PlasmaShell *plasmaShell = nullptr;
@@ -148,6 +149,10 @@
if (!s_waylandConnection.xdgShellV5->isValid()) {
return false;
}
+ s_waylandConnection.xdgShellV6 = registry->createXdgShell(registry->interface(Registry::Interface::XdgShellUnstableV6).name, registry->interface(Registry::Interface::XdgShellUnstableV6).version);
+ if (!s_waylandConnection.xdgShellV6->isValid()) {
+ return false;
+ }
if (flags.testFlag(AdditionalWaylandInterface::Seat)) {
s_waylandConnection.seat = registry->createSeat(registry->interface(Registry::Interface::Seat).name, registry->interface(Registry::Interface::Seat).version);
if (!s_waylandConnection.seat->isValid()) {
@@ -204,6 +209,8 @@
s_waylandConnection.pointerConstraints = nullptr;
delete s_waylandConnection.xdgShellV5;
s_waylandConnection.xdgShellV5 = nullptr;
+ delete s_waylandConnection.xdgShellV6;
+ s_waylandConnection.xdgShellV6 = nullptr;
delete s_waylandConnection.shell;
s_waylandConnection.shell = nullptr;
delete s_waylandConnection.shm;
@@ -393,13 +400,28 @@
return s;
}
+XdgShellSurface *createXdgShellV6Surface(Surface *surface, QObject *parent)
+{
+ if (!s_waylandConnection.xdgShellV6) {
+ return nullptr;
+ }
+ auto s = s_waylandConnection.xdgShellV6->createSurface(surface, parent);
+ if (!s->isValid()) {
+ delete s;
+ return nullptr;
+ }
+ return s;
+}
+
QObject *createShellSurface(ShellSurfaceType type, KWayland::Client::Surface *surface, QObject *parent)
{
switch (type) {
case ShellSurfaceType::WlShell:
return createShellSurface(surface, parent);
case ShellSurfaceType::XdgShellV5:
return createXdgShellV5Surface(surface, parent);
+ case ShellSurfaceType::XdgShellV6:
+ return createXdgShellV6Surface(surface, parent);
default:
Q_UNREACHABLE();
return nullptr;
diff --git a/shell_client.h b/shell_client.h
--- a/shell_client.h
+++ b/shell_client.h
@@ -37,6 +37,14 @@
namespace KWin
{
+/**
+ * @brief The reason for which the server pinged a client surface
+ */
+enum class PingReason {
+ CloseWindow = 0,
+ FocusWindow
+};
+
class KWIN_EXPORT ShellClient : public AbstractClient
{
Q_OBJECT
@@ -218,6 +226,7 @@
bool m_transient = false;
bool m_hidden = false;
bool m_internal;
+ bool m_hasPopupGrab = false;
qreal m_opacity = 1.0;
class RequestGeometryBlocker {
@@ -244,6 +253,7 @@
QRect m_blockedRequestGeometry;
QString m_caption;
QString m_captionSuffix;
+ QHash m_pingSerials;
bool m_compositingSetup = false;
};
diff --git a/shell_client.cpp b/shell_client.cpp
--- a/shell_client.cpp
+++ b/shell_client.cpp
@@ -228,8 +228,48 @@
connect(s, &SurfaceInterface::destroyed, this, &ShellClient::destroyClient);
if (m_shellSurface) {
initSurface(m_shellSurface);
+ // TODO: verify grab serial
+ m_hasPopupGrab = m_shellSurface->isPopup();
} else if (m_xdgShellSurface) {
initSurface(m_xdgShellSurface);
+
+ auto global = static_cast(m_xdgShellSurface->global());
+ connect(global, &XdgShellInterface::pingDelayed,
+ this, [this](qint32 serial) {
+ auto it = m_pingSerials.find(serial);
+ if (it != m_pingSerials.end()) {
+ qCDebug(KWIN_CORE) << "First ping timeout:" << caption();
+ setUnresponsive(true);
+ }
+ });
+
+ connect(global, &XdgShellInterface::pingTimeout,
+ this, [this](qint32 serial) {
+ auto it = m_pingSerials.find(serial);
+ if (it != m_pingSerials.end()) {
+ if (it.value() == PingReason::CloseWindow) {
+ qCDebug(KWIN_CORE) << "Final ping timeout on a close attempt, asking to kill:" << caption();
+
+ //for internal windows, killing the window will delete this
+ QPointer guard(this);
+ killWindow();
+ if (!guard) {
+ return;
+ }
+ }
+ m_pingSerials.erase(it);
+ }
+ });
+
+ connect(global, &XdgShellInterface::pongReceived,
+ this, [this](qint32 serial){
+ auto it = m_pingSerials.find(serial);
+ if (it != m_pingSerials.end()) {
+ setUnresponsive(false);
+ m_pingSerials.erase(it);
+ }
+ });
+
connect(m_xdgShellSurface, &XdgShellSurfaceInterface::windowMenuRequested, this,
[this] (SeatInterface *seat, quint32 serial, const QPoint &surfacePos) {
// TODO: check serial on seat
@@ -249,10 +289,21 @@
}
m_xdgShellSurface->configure(xdgSurfaceStates());
};
+ configure();
connect(this, &AbstractClient::activeChanged, this, configure);
connect(this, &AbstractClient::clientStartUserMovedResized, this, configure);
connect(this, &AbstractClient::clientFinishUserMovedResized, this, configure);
} else if (m_xdgShellPopup) {
+ connect(m_xdgShellPopup, &XdgShellPopupInterface::grabRequested, this, [this](SeatInterface *seat, quint32 serial) {
+ Q_UNUSED(seat)
+ Q_UNUSED(serial)
+ //TODO - should check the parent had focus
+ m_hasPopupGrab = true;
+ });
+
+ QRect position = QRect(m_xdgShellPopup->transientOffset(), m_xdgShellPopup->initialSize());
+ m_xdgShellPopup->configure(position);
+
connect(m_xdgShellPopup, &XdgShellPopupInterface::destroyed, this, &ShellClient::destroyClient);
}
@@ -588,12 +639,11 @@
{
if (m_xdgShellSurface && isCloseable()) {
m_xdgShellSurface->close();
- return;
- }
- if (m_qtExtendedSurface && isCloseable()) {
+ const qint32 pingSerial = static_cast(m_xdgShellSurface->global())->ping(m_xdgShellSurface);
+ m_pingSerials.insert(pingSerial, PingReason::CloseWindow);
+ } else if (m_qtExtendedSurface && isCloseable()) {
m_qtExtendedSurface->close();
- }
- if (m_internalWindow) {
+ } else if (m_internalWindow) {
m_internalWindow->hide();
}
}
@@ -846,6 +896,10 @@
void ShellClient::takeFocus()
{
if (rules()->checkAcceptFocus(wantsInput())) {
+ if (m_xdgShellSurface) {
+ const qint32 pingSerial = static_cast(m_xdgShellSurface->global())->ping(m_xdgShellSurface);
+ m_pingSerials.insert(pingSerial, PingReason::FocusWindow);
+ }
setActive(true);
}
@@ -1032,6 +1086,15 @@
if (m_xdgShellSurface) {
m_xdgShellSurface->configure(xdgSurfaceStates(), size);
}
+ if (m_xdgShellPopup) {
+ auto parent = transientFor();
+ if (parent) {
+ const QPoint globalClientContentPos = parent->geometry().topLeft() + parent->clientPos();
+ const QPoint relativeOffset = rect.topLeft() -globalClientContentPos;
+ m_xdgShellPopup->configure(QRect(relativeOffset, rect.size()));
+ }
+ }
+
m_blockedRequestGeometry = QRect();
if (m_internal) {
m_internalWindow->setGeometry(QRect(rect.topLeft() + QPoint(borderLeft(), borderTop()), rect.size() - QSize(borderLeft() + borderRight(), borderTop() + borderBottom())));
@@ -1414,6 +1477,9 @@
if (isLockScreen()) {
return false;
}
+ if (m_xdgShellPopup) {
+ return false;
+ }
if (m_shellSurface) {
if (m_shellSurface->isTransient() && !m_shellSurface->acceptsKeyboardFocus()) {
return false;
@@ -1520,18 +1586,17 @@
bool ShellClient::hasPopupGrab() const
{
- if (m_shellSurface) {
- // TODO: verify grab serial
- return m_shellSurface->isPopup();
- }
- return false;
+ return m_hasPopupGrab;
}
void ShellClient::popupDone()
{
if (m_shellSurface) {
m_shellSurface->popupDone();
}
+ if (m_xdgShellPopup) {
+ m_xdgShellPopup->popupDone();
+ }
}
void ShellClient::updateClientOutputs()
diff --git a/wayland_server.h b/wayland_server.h
--- a/wayland_server.h
+++ b/wayland_server.h
@@ -205,6 +205,7 @@
KWayland::Server::SeatInterface *m_seat = nullptr;
KWayland::Server::ShellInterface *m_shell = nullptr;
KWayland::Server::XdgShellInterface *m_xdgShell = nullptr;
+ KWayland::Server::XdgShellInterface *m_xdgShell6 = nullptr;
KWayland::Server::PlasmaShellInterface *m_plasmaShell = nullptr;
KWayland::Server::PlasmaWindowManagementInterface *m_windowManagement = nullptr;
KWayland::Server::QtSurfaceExtensionInterface *m_qtExtendedSurface = nullptr;
diff --git a/wayland_server.cpp b/wayland_server.cpp
--- a/wayland_server.cpp
+++ b/wayland_server.cpp
@@ -201,6 +201,13 @@
connect(m_xdgShell, &XdgShellInterface::surfaceCreated, this, &WaylandServer::createSurface);
// TODO: verify seat and serial
connect(m_xdgShell, &XdgShellInterface::popupCreated, this, &WaylandServer::createSurface);
+
+ m_xdgShell6 = m_display->createXdgShell(XdgShellInterfaceVersion::UnstableV6, m_display);
+ m_xdgShell6->create();
+ connect(m_xdgShell6, &XdgShellInterface::surfaceCreated, this, &WaylandServer::createSurface);
+ connect(m_xdgShell6, &XdgShellInterface::xdgPopupCreated, this, &WaylandServer::createSurface);
+
+
m_display->createShm();
m_seat = m_display->createSeat(m_display);
m_seat->create();