From d257da0a001cb9c7ab2d3561791e538f1b3b1315 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Wed, 2 Nov 2022 18:20:37 +0200 Subject: [PATCH] Use StrutRects to represent restricted areas This saves us some StrutRects -> QRegion conversions and it might be useful for floating point struts. --- autotests/integration/struts_test.cpp | 86 ++++++++++++++------------- src/utils/common.h | 2 +- src/window.cpp | 27 ++++++--- src/workspace.cpp | 46 +++++++++----- src/workspace.h | 4 +- 5 files changed, 99 insertions(+), 66 deletions(-) diff --git a/autotests/integration/struts_test.cpp b/autotests/integration/struts_test.cpp index eb0a738890..96b9876045 100644 --- a/autotests/integration/struts_test.cpp +++ b/autotests/integration/struts_test.cpp @@ -28,6 +28,8 @@ #include #include +Q_DECLARE_METATYPE(KWin::StrutRects) + namespace KWin { @@ -103,30 +105,30 @@ void StrutsTest::testWaylandStruts_data() QTest::addColumn("screen0Maximized"); QTest::addColumn("screen1Maximized"); QTest::addColumn("workArea"); - QTest::addColumn("restrictedMoveArea"); + QTest::addColumn("restrictedMoveArea"); - QTest::newRow("bottom/0") << QVector{QRect(0, 992, 1280, 32)} << QRectF(0, 0, 1280, 992) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 992) << QRegion(0, 992, 1280, 32); - QTest::newRow("bottom/1") << QVector{QRect(1280, 992, 1280, 32)} << QRectF(0, 0, 1280, 1024) << QRectF(1280, 0, 1280, 992) << QRectF(0, 0, 2560, 992) << QRegion(1280, 992, 1280, 32); - QTest::newRow("top/0") << QVector{QRect(0, 0, 1280, 32)} << QRectF(0, 32, 1280, 992) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 32, 2560, 992) << QRegion(0, 0, 1280, 32); - QTest::newRow("top/1") << QVector{QRect(1280, 0, 1280, 32)} << QRectF(0, 0, 1280, 1024) << QRectF(1280, 32, 1280, 992) << QRectF(0, 32, 2560, 992) << QRegion(1280, 0, 1280, 32); - QTest::newRow("left/0") << QVector{QRect(0, 0, 32, 1024)} << QRectF(32, 0, 1248, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(32, 0, 2528, 1024) << QRegion(0, 0, 32, 1024); - QTest::newRow("left/1") << QVector{QRect(1280, 0, 32, 1024)} << QRectF(0, 0, 1280, 1024) << QRectF(1312, 0, 1248, 1024) << QRectF(0, 0, 2560, 1024) << QRegion(1280, 0, 32, 1024); - QTest::newRow("right/0") << QVector{QRect(1248, 0, 32, 1024)} << QRectF(0, 0, 1248, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 1024) << QRegion(1248, 0, 32, 1024); - QTest::newRow("right/1") << QVector{QRect(2528, 0, 32, 1024)} << QRectF(0, 0, 1280, 1024) << QRectF(1280, 0, 1248, 1024) << QRectF(0, 0, 2528, 1024) << QRegion(2528, 0, 32, 1024); + QTest::newRow("bottom/0") << QVector{QRect(0, 992, 1280, 32)} << QRectF(0, 0, 1280, 992) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 992) << StrutRects{StrutRect(0, 992, 1280, 32)}; + QTest::newRow("bottom/1") << QVector{QRect(1280, 992, 1280, 32)} << QRectF(0, 0, 1280, 1024) << QRectF(1280, 0, 1280, 992) << QRectF(0, 0, 2560, 992) << StrutRects{StrutRect(1280, 992, 1280, 32)}; + QTest::newRow("top/0") << QVector{QRect(0, 0, 1280, 32)} << QRectF(0, 32, 1280, 992) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 32, 2560, 992) << StrutRects{StrutRect(0, 0, 1280, 32)}; + QTest::newRow("top/1") << QVector{QRect(1280, 0, 1280, 32)} << QRectF(0, 0, 1280, 1024) << QRectF(1280, 32, 1280, 992) << QRectF(0, 32, 2560, 992) << StrutRects{StrutRect(1280, 0, 1280, 32)}; + QTest::newRow("left/0") << QVector{QRect(0, 0, 32, 1024)} << QRectF(32, 0, 1248, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(32, 0, 2528, 1024) << StrutRects{StrutRect(0, 0, 32, 1024)}; + QTest::newRow("left/1") << QVector{QRect(1280, 0, 32, 1024)} << QRectF(0, 0, 1280, 1024) << QRectF(1312, 0, 1248, 1024) << QRectF(0, 0, 2560, 1024) << StrutRects{StrutRect(1280, 0, 32, 1024)}; + QTest::newRow("right/0") << QVector{QRect(1248, 0, 32, 1024)} << QRectF(0, 0, 1248, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 1024) << StrutRects{StrutRect(1248, 0, 32, 1024)}; + QTest::newRow("right/1") << QVector{QRect(2528, 0, 32, 1024)} << QRectF(0, 0, 1280, 1024) << QRectF(1280, 0, 1248, 1024) << QRectF(0, 0, 2528, 1024) << StrutRects{StrutRect(2528, 0, 32, 1024)}; // same with partial panels not covering the whole area - QTest::newRow("part bottom/0") << QVector{QRect(100, 992, 1080, 32)} << QRectF(0, 0, 1280, 992) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 992) << QRegion(100, 992, 1080, 32); - QTest::newRow("part bottom/1") << QVector{QRect(1380, 992, 1080, 32)} << QRectF(0, 0, 1280, 1024) << QRectF(1280, 0, 1280, 992) << QRectF(0, 0, 2560, 992) << QRegion(1380, 992, 1080, 32); - QTest::newRow("part top/0") << QVector{QRect(100, 0, 1080, 32)} << QRectF(0, 32, 1280, 992) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 32, 2560, 992) << QRegion(100, 0, 1080, 32); - QTest::newRow("part top/1") << QVector{QRect(1380, 0, 1080, 32)} << QRectF(0, 0, 1280, 1024) << QRectF(1280, 32, 1280, 992) << QRectF(0, 32, 2560, 992) << QRegion(1380, 0, 1080, 32); - QTest::newRow("part left/0") << QVector{QRect(0, 100, 32, 824)} << QRectF(32, 0, 1248, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(32, 0, 2528, 1024) << QRegion(0, 100, 32, 824); - QTest::newRow("part left/1") << QVector{QRect(1280, 100, 32, 824)} << QRectF(0, 0, 1280, 1024) << QRectF(1312, 0, 1248, 1024) << QRectF(0, 0, 2560, 1024) << QRegion(1280, 100, 32, 824); - QTest::newRow("part right/0") << QVector{QRect(1248, 100, 32, 824)} << QRectF(0, 0, 1248, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 1024) << QRegion(1248, 100, 32, 824); - QTest::newRow("part right/1") << QVector{QRect(2528, 100, 32, 824)} << QRectF(0, 0, 1280, 1024) << QRectF(1280, 0, 1248, 1024) << QRectF(0, 0, 2528, 1024) << QRegion(2528, 100, 32, 824); + QTest::newRow("part bottom/0") << QVector{QRect(100, 992, 1080, 32)} << QRectF(0, 0, 1280, 992) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 992) << StrutRects{StrutRect(100, 992, 1080, 32)}; + QTest::newRow("part bottom/1") << QVector{QRect(1380, 992, 1080, 32)} << QRectF(0, 0, 1280, 1024) << QRectF(1280, 0, 1280, 992) << QRectF(0, 0, 2560, 992) << StrutRects{StrutRect(1380, 992, 1080, 32)}; + QTest::newRow("part top/0") << QVector{QRect(100, 0, 1080, 32)} << QRectF(0, 32, 1280, 992) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 32, 2560, 992) << StrutRects{StrutRect(100, 0, 1080, 32)}; + QTest::newRow("part top/1") << QVector{QRect(1380, 0, 1080, 32)} << QRectF(0, 0, 1280, 1024) << QRectF(1280, 32, 1280, 992) << QRectF(0, 32, 2560, 992) << StrutRects{StrutRect(1380, 0, 1080, 32)}; + QTest::newRow("part left/0") << QVector{QRect(0, 100, 32, 824)} << QRectF(32, 0, 1248, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(32, 0, 2528, 1024) << StrutRects{StrutRect(0, 100, 32, 824)}; + QTest::newRow("part left/1") << QVector{QRect(1280, 100, 32, 824)} << QRectF(0, 0, 1280, 1024) << QRectF(1312, 0, 1248, 1024) << QRectF(0, 0, 2560, 1024) << StrutRects{StrutRect(1280, 100, 32, 824)}; + QTest::newRow("part right/0") << QVector{QRect(1248, 100, 32, 824)} << QRectF(0, 0, 1248, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 1024) << StrutRects{StrutRect(1248, 100, 32, 824)}; + QTest::newRow("part right/1") << QVector{QRect(2528, 100, 32, 824)} << QRectF(0, 0, 1280, 1024) << QRectF(1280, 0, 1248, 1024) << QRectF(0, 0, 2528, 1024) << StrutRects{StrutRect(2528, 100, 32, 824)}; // multiple panels - QTest::newRow("two bottom panels") << QVector{QRect(100, 992, 1080, 32), QRect(1380, 984, 1080, 40)} << QRectF(0, 0, 1280, 992) << QRectF(1280, 0, 1280, 984) << QRectF(0, 0, 2560, 984) << QRegion(100, 992, 1080, 32).united(QRegion(1380, 984, 1080, 40)); - QTest::newRow("two left panels") << QVector{QRect(0, 10, 32, 390), QRect(0, 450, 40, 100)} << QRectF(40, 0, 1240, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(40, 0, 2520, 1024) << QRegion(0, 10, 32, 390).united(QRegion(0, 450, 40, 100)); + QTest::newRow("two bottom panels") << QVector{QRect(100, 992, 1080, 32), QRect(1380, 984, 1080, 40)} << QRectF(0, 0, 1280, 992) << QRectF(1280, 0, 1280, 984) << QRectF(0, 0, 2560, 984) << StrutRects{StrutRect(100, 992, 1080, 32), StrutRect(1380, 984, 1080, 40)}; + QTest::newRow("two left panels") << QVector{QRect(0, 10, 32, 390), QRect(0, 450, 40, 100)} << QRectF(40, 0, 1240, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(40, 0, 2520, 1024) << StrutRects{StrutRect(0, 10, 32, 390), StrutRect(0, 450, 40, 100)}; } void StrutsTest::testWaylandStruts() @@ -156,7 +158,7 @@ void StrutsTest::testWaylandStruts() // combined QCOMPARE(workspace()->clientArea(WorkArea, outputs[0], desktop), QRect(0, 0, 2560, 1024)); QCOMPARE(workspace()->clientArea(FullArea, outputs[0], desktop), QRect(0, 0, 2560, 1024)); - QCOMPARE(workspace()->restrictedMoveArea(desktop), QRegion()); + QCOMPARE(workspace()->restrictedMoveArea(desktop), StrutRects()); QFETCH(QVector, windowGeometries); // create the panels @@ -214,7 +216,7 @@ void StrutsTest::testWaylandStruts() it = windows.erase(it); QVERIFY(destroyedSpy.wait()); } - QCOMPARE(workspace()->restrictedMoveArea(desktop), QRegion()); + QCOMPARE(workspace()->restrictedMoveArea(desktop), StrutRects()); } void StrutsTest::testMoveWaylandPanel() @@ -353,7 +355,7 @@ void StrutsTest::testX11Struts_data() QTest::addColumn("screen0Maximized"); QTest::addColumn("screen1Maximized"); QTest::addColumn("workArea"); - QTest::addColumn("restrictedMoveArea"); + QTest::addColumn("restrictedMoveArea"); QTest::newRow("bottom panel/no strut") << QRect(0, 980, 1280, 44) << 0 << 0 << 0 << 0 @@ -364,7 +366,7 @@ void StrutsTest::testX11Struts_data() << QRectF(0, 0, 1280, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 1024) - << QRegion(); + << StrutRects(); QTest::newRow("bottom panel/strut") << QRect(0, 980, 1280, 44) << 0 << 0 << 0 << 44 << 0 << 0 @@ -374,7 +376,7 @@ void StrutsTest::testX11Struts_data() << QRectF(0, 0, 1280, 980) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 980) - << QRegion(0, 980, 1279, 44); + << StrutRects{StrutRect(0, 980, 1279, 44)}; QTest::newRow("top panel/no strut") << QRect(0, 0, 1280, 44) << 0 << 0 << 0 << 0 << 0 << 0 @@ -384,7 +386,7 @@ void StrutsTest::testX11Struts_data() << QRectF(0, 0, 1280, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 1024) - << QRegion(); + << StrutRects(); QTest::newRow("top panel/strut") << QRect(0, 0, 1280, 44) << 0 << 0 << 44 << 0 << 0 << 0 @@ -394,7 +396,7 @@ void StrutsTest::testX11Struts_data() << QRectF(0, 44, 1280, 980) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 44, 2560, 980) - << QRegion(0, 0, 1279, 44); + << StrutRects{StrutRect(0, 0, 1279, 44)}; QTest::newRow("left panel/no strut") << QRect(0, 0, 60, 1024) << 0 << 0 << 0 << 0 << 0 << 0 @@ -404,7 +406,7 @@ void StrutsTest::testX11Struts_data() << QRectF(0, 0, 1280, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 1024) - << QRegion(); + << StrutRects(); QTest::newRow("left panel/strut") << QRect(0, 0, 60, 1024) << 60 << 0 << 0 << 0 << 0 << 1023 @@ -414,7 +416,7 @@ void StrutsTest::testX11Struts_data() << QRectF(60, 0, 1220, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(60, 0, 2500, 1024) - << QRegion(0, 0, 60, 1023); + << StrutRects{StrutRect(0, 0, 60, 1023)}; QTest::newRow("right panel/no strut") << QRect(1220, 0, 60, 1024) << 0 << 0 << 0 << 0 << 0 << 0 @@ -424,7 +426,7 @@ void StrutsTest::testX11Struts_data() << QRectF(0, 0, 1280, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 1024) - << QRegion(); + << StrutRects(); QTest::newRow("right panel/strut") << QRect(1220, 0, 60, 1024) << 0 << 1340 << 0 << 0 << 0 << 0 @@ -434,7 +436,7 @@ void StrutsTest::testX11Struts_data() << QRectF(0, 0, 1220, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 1024) - << QRegion(1220, 0, 60, 1023); + << StrutRects{StrutRect(1220, 0, 60, 1023)}; // second screen QTest::newRow("bottom panel 1/no strut") << QRect(1280, 980, 1280, 44) << 0 << 0 << 0 << 0 @@ -445,7 +447,7 @@ void StrutsTest::testX11Struts_data() << QRectF(0, 0, 1280, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 1024) - << QRegion(); + << StrutRects(); QTest::newRow("bottom panel 1/strut") << QRect(1280, 980, 1280, 44) << 0 << 0 << 0 << 44 << 0 << 0 @@ -455,7 +457,7 @@ void StrutsTest::testX11Struts_data() << QRectF(0, 0, 1280, 1024) << QRectF(1280, 0, 1280, 980) << QRectF(0, 0, 2560, 980) - << QRegion(1280, 980, 1279, 44); + << StrutRects{StrutRect(1280, 980, 1279, 44)}; QTest::newRow("top panel 1/no strut") << QRect(1280, 0, 1280, 44) << 0 << 0 << 0 << 0 << 0 << 0 @@ -465,7 +467,7 @@ void StrutsTest::testX11Struts_data() << QRectF(0, 0, 1280, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 1024) - << QRegion(); + << StrutRects(); QTest::newRow("top panel 1 /strut") << QRect(1280, 0, 1280, 44) << 0 << 0 << 44 << 0 << 0 << 0 @@ -475,7 +477,7 @@ void StrutsTest::testX11Struts_data() << QRectF(0, 0, 1280, 1024) << QRectF(1280, 44, 1280, 980) << QRectF(0, 44, 2560, 980) - << QRegion(1280, 0, 1279, 44); + << StrutRects{StrutRect(1280, 0, 1279, 44)}; QTest::newRow("left panel 1/no strut") << QRect(1280, 0, 60, 1024) << 0 << 0 << 0 << 0 << 0 << 0 @@ -485,7 +487,7 @@ void StrutsTest::testX11Struts_data() << QRectF(0, 0, 1280, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 1024) - << QRegion(); + << StrutRects(); QTest::newRow("left panel 1/strut") << QRect(1280, 0, 60, 1024) << 1340 << 0 << 0 << 0 << 0 << 1023 @@ -495,7 +497,7 @@ void StrutsTest::testX11Struts_data() << QRectF(0, 0, 1280, 1024) << QRectF(1340, 0, 1220, 1024) << QRectF(0, 0, 2560, 1024) - << QRegion(1280, 0, 60, 1023); + << StrutRects{StrutRect(1280, 0, 60, 1023)}; // invalid struts QTest::newRow("bottom panel/ invalid strut") << QRect(0, 980, 1280, 44) << 1280 << 0 << 0 << 44 @@ -506,7 +508,7 @@ void StrutsTest::testX11Struts_data() << QRectF(0, 0, 1280, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 1024) - << QRegion(0, 980, 1280, 44); + << StrutRects{StrutRect(0, 980, 1279, 44), StrutRect(0, 980, 1280, 44)}; QTest::newRow("top panel/ invalid strut") << QRect(0, 0, 1280, 44) << 1280 << 0 << 44 << 0 << 0 << 44 @@ -516,7 +518,7 @@ void StrutsTest::testX11Struts_data() << QRectF(0, 0, 1280, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 1024) - << QRegion(0, 0, 1280, 44); + << StrutRects{StrutRect(0, 0, 1279, 44), StrutRect(0, 0, 1280, 44)}; QTest::newRow("top panel/invalid strut 2") << QRect(0, 0, 1280, 44) << 0 << 0 << 1024 << 0 << 0 << 0 @@ -526,7 +528,7 @@ void StrutsTest::testX11Struts_data() << QRectF(0, 0, 1280, 1024) << QRectF(1280, 0, 1280, 1024) << QRectF(0, 0, 2560, 1024) - << QRegion(); + << StrutRects(); } struct XcbConnectionDeleter @@ -562,7 +564,7 @@ void StrutsTest::testX11Struts() // combined QCOMPARE(workspace()->clientArea(WorkArea, outputs[0], desktop), QRect(0, 0, 2560, 1024)); QCOMPARE(workspace()->clientArea(FullArea, outputs[0], desktop), QRect(0, 0, 2560, 1024)); - QCOMPARE(workspace()->restrictedMoveArea(desktop), QRegion()); + QCOMPARE(workspace()->restrictedMoveArea(desktop), StrutRects()); // create an xcb window std::unique_ptr c(xcb_connect(nullptr, nullptr)); @@ -672,7 +674,7 @@ void StrutsTest::testX11Struts() // combined QCOMPARE(workspace()->clientArea(WorkArea, outputs[0], desktop), QRect(0, 0, 2560, 1024)); QCOMPARE(workspace()->clientArea(FullArea, outputs[0], desktop), QRect(0, 0, 2560, 1024)); - QCOMPARE(workspace()->restrictedMoveArea(desktop), QRegion()); + QCOMPARE(workspace()->restrictedMoveArea(desktop), StrutRects()); } void StrutsTest::test363804() @@ -941,7 +943,7 @@ void StrutsTest::testWindowMoveWithPanelBetweenScreens() QCOMPARE(workspace()->clientArea(PlacementArea, outputs[1], desktop), QRect(1390, 0, 1656, 1050)); QCOMPARE(workspace()->clientArea(MaximizeArea, outputs[1], desktop), QRect(1390, 0, 1656, 1050)); QCOMPARE(workspace()->clientArea(WorkArea, outputs[0], desktop), QRect(0, 0, 3046, 1050)); - QCOMPARE(workspace()->restrictedMoveArea(desktop), QRegion(1366, 0, 24, 1050)); + QCOMPARE(workspace()->restrictedMoveArea(desktop), StrutRects{StrutRect(1366, 0, 24, 1050)}); // create another window and try to move it diff --git a/src/utils/common.h b/src/utils/common.h index 43ec0bdd93..b2474c07f5 100644 --- a/src/utils/common.h +++ b/src/utils/common.h @@ -61,7 +61,7 @@ enum StrutArea { }; Q_DECLARE_FLAGS(StrutAreas, StrutArea) -class StrutRect : public QRect +class KWIN_EXPORT StrutRect : public QRect { public: explicit StrutRect(QRect rect = QRect(), StrutArea area = StrutAreaInvalid); diff --git a/src/window.cpp b/src/window.cpp index c88d969a6d..692f80b3b1 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1920,8 +1920,11 @@ void Window::handleInteractiveMoveResize(int x, int y, int x_root, int y_root) // Make sure the titlebar isn't behind a restricted area. We don't need to restrict // the other directions. If not visible enough, move the window to the closest valid // point. We bruteforce this by slowly moving the window back to its previous position + const StrutRects strut = workspace()->restrictedMoveArea(VirtualDesktopManager::self()->currentDesktop()); QRegion availableArea(workspace()->clientArea(FullArea, this, workspace()->activeOutput()).toRect()); - availableArea -= workspace()->restrictedMoveArea(VirtualDesktopManager::self()->currentDesktop()); + for (const QRect &rect : strut) { + availableArea -= rect; + } bool transposed = false; int requiredPixels; QRectF bTitleRect = titleBarRect(nextMoveResizeGeom, transposed, requiredPixels); @@ -2050,9 +2053,11 @@ void Window::handleInteractiveMoveResize(int x, int y, int x_root, int y_root) nextMoveResizeGeom = geometry; if (!isUnrestrictedInteractiveMoveResize()) { - const QRegion strut = workspace()->restrictedMoveArea(VirtualDesktopManager::self()->currentDesktop()); + const StrutRects strut = workspace()->restrictedMoveArea(VirtualDesktopManager::self()->currentDesktop()); QRegion availableArea(workspace()->clientArea(FullArea, this, workspace()->activeOutput()).toRect()); - availableArea -= strut; // Strut areas + for (const QRect &rect : strut) { + availableArea -= rect; // Strut areas + } bool transposed = false; int requiredPixels; QRectF bTitleRect = titleBarRect(nextMoveResizeGeom, transposed, requiredPixels); @@ -2139,10 +2144,18 @@ StrutRect Window::strutRect(StrutArea area) const StrutRects Window::strutRects() const { StrutRects region; - region += strutRect(StrutAreaTop); - region += strutRect(StrutAreaRight); - region += strutRect(StrutAreaBottom); - region += strutRect(StrutAreaLeft); + if (const StrutRect strut = strutRect(StrutAreaTop); strut.isValid()) { + region += strut; + } + if (const StrutRect strut = strutRect(StrutAreaRight); strut.isValid()) { + region += strut; + } + if (const StrutRect strut = strutRect(StrutAreaBottom); strut.isValid()) { + region += strut; + } + if (const StrutRect strut = strutRect(StrutAreaLeft); strut.isValid()) { + region += strut; + } return region; } diff --git a/src/workspace.cpp b/src/workspace.cpp index cb4bc0c7e9..bab270ad48 100644 --- a/src/workspace.cpp +++ b/src/workspace.cpp @@ -2418,8 +2418,13 @@ void Workspace::updateClientArea() } StrutRects strutRegion = window->strutRects(); const QRect clientsScreenRect = window->output()->geometry(); - for (auto strut = strutRegion.begin(); strut != strutRegion.end(); strut++) { - *strut = StrutRect((*strut).intersected(clientsScreenRect), (*strut).area()); + for (int i = strutRegion.size() - 1; i >= 0; --i) { + const StrutRect clipped = StrutRect(strutRegion[i].intersected(clientsScreenRect), strutRegion[i].area()); + if (clipped.isEmpty()) { + strutRegion.removeAt(i); + } else { + strutRegion[i] = clipped; + } } // Ignore offscreen xinerama struts. These interfere with the larger monitors on the setup @@ -2528,20 +2533,21 @@ QRect Workspace::geometry() const return m_geometry; } -static QRegion strutsToRegion(StrutAreas areas, const StrutRects &strut) +StrutRects Workspace::restrictedMoveArea(const VirtualDesktop *desktop, StrutAreas areas) const { - QRegion region; + const StrutRects strut = m_restrictedAreas.value(desktop); + if (areas == StrutAreaAll) { + return strut; + } + + StrutRects ret; + ret.reserve(strut.size()); for (const StrutRect &rect : strut) { - if (areas & rect.area()) { - region += rect; + if (rect.area() & areas) { + ret.append(rect); } } - return region; -} - -QRegion Workspace::restrictedMoveArea(const VirtualDesktop *desktop, StrutAreas areas) const -{ - return strutsToRegion(areas, m_restrictedAreas[desktop]); + return ret; } bool Workspace::inUpdateClientArea() const @@ -2549,9 +2555,21 @@ bool Workspace::inUpdateClientArea() const return m_inUpdateClientArea; } -QRegion Workspace::previousRestrictedMoveArea(const VirtualDesktop *desktop, StrutAreas areas) const +StrutRects Workspace::previousRestrictedMoveArea(const VirtualDesktop *desktop, StrutAreas areas) const { - return strutsToRegion(areas, m_oldRestrictedAreas[desktop]); + const StrutRects strut = m_oldRestrictedAreas.value(desktop); + if (areas == StrutAreaAll) { + return strut; + } + + StrutRects ret; + ret.reserve(strut.size()); + for (const StrutRect &rect : strut) { + if (rect.area() & areas) { + ret.append(rect); + } + } + return ret; } QHash Workspace::previousScreenSizes() const diff --git a/src/workspace.h b/src/workspace.h index 1258e3f502..3f4423007b 100644 --- a/src/workspace.h +++ b/src/workspace.h @@ -169,7 +169,7 @@ public: * Returns the geometry of this Workspace, i.e. the bounding rectangle of all outputs. */ QRect geometry() const; - QRegion restrictedMoveArea(const VirtualDesktop *desktop, StrutAreas areas = StrutAreaAll) const; + StrutRects restrictedMoveArea(const VirtualDesktop *desktop, StrutAreas areas = StrutAreaAll) const; bool initializing() const; @@ -296,7 +296,7 @@ public: // True when performing Workspace::updateClientArea(). // The calls below are valid only in that case. bool inUpdateClientArea() const; - QRegion previousRestrictedMoveArea(const VirtualDesktop *desktop, StrutAreas areas = StrutAreaAll) const; + StrutRects previousRestrictedMoveArea(const VirtualDesktop *desktop, StrutAreas areas = StrutAreaAll) const; QHash previousScreenSizes() const; int oldDisplayWidth() const; int oldDisplayHeight() const;