diff --git a/autotests/integration/quick_tiling_test.cpp b/autotests/integration/quick_tiling_test.cpp index 9fd86c2513..94544331b4 100644 --- a/autotests/integration/quick_tiling_test.cpp +++ b/autotests/integration/quick_tiling_test.cpp @@ -178,7 +178,6 @@ void QuickTilingTest::testQuickTiling() c->sendToScreen(1); QCOMPARE(c->screen(), 1); // quick tile should not be changed - QEXPECT_FAIL("maximize", "Maximize loses the state", Continue); QCOMPARE(c->quickTileMode(), mode); QTEST(c->geometry(), "secondScreen"); } diff --git a/geometry.cpp b/geometry.cpp index 812db7c143..64b5d67ca1 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -3299,6 +3299,7 @@ void AbstractClient::setQuickTileMode(QuickTileMode mode, bool keyboard) setMaximize(false, false); } else { QRect prev_geom_restore = geometryRestore(); // setMaximize() would set moveResizeGeom as geom_restore + m_quickTileMode = QuickTileMaximize; setMaximize(true, true); QRect clientArea = workspace()->clientArea(MaximizeArea, this); if (geometry().top() != clientArea.top()) { @@ -3306,7 +3307,6 @@ void AbstractClient::setQuickTileMode(QuickTileMode mode, bool keyboard) r.moveTop(clientArea.top()); setGeometry(r); } - m_quickTileMode = QuickTileMaximize; setGeometryRestore(prev_geom_restore); } emit quickTileModeChanged(); @@ -3326,8 +3326,6 @@ void AbstractClient::setQuickTileMode(QuickTileMode mode, bool keyboard) TabSynchronizer syncer(this, TabGroup::QuickTile|TabGroup::Geometry|TabGroup::Maximized); - setMaximize(false, false); - if (mode != QuickTileNone) { m_quickTileMode = mode; // decorations may turn off some borders when tiled @@ -3337,6 +3335,9 @@ void AbstractClient::setQuickTileMode(QuickTileMode mode, bool keyboard) } // Store the mode change m_quickTileMode = mode; + + setMaximize(false, false); + emit quickTileModeChanged(); return; diff --git a/shell_client.cpp b/shell_client.cpp index 25bee757da..74ed7d54f3 100644 --- a/shell_client.cpp +++ b/shell_client.cpp @@ -658,6 +658,15 @@ void ShellClient::changeMaximize(bool horizontal, bool vertical, bool adjust) if (changeMaximizeRecursion) { return; } + + if (!isResizable()) { + return; + } + + const QRect clientArea = isElectricBorderMaximizing() ? + workspace()->clientArea(MaximizeArea, Cursor::pos(), desktop()) : + workspace()->clientArea(MaximizeArea, this); + MaximizeMode oldMode = m_maximizeMode; StackingUpdatesBlocker blocker(workspace()); RequestGeometryBlocker geometryBlocker(this); @@ -686,12 +695,45 @@ void ShellClient::changeMaximize(bool horizontal, bool vertical, bool adjust) changeMaximizeRecursion = false; } + // TODO: borderless maximized windows + + // Conditional quick tiling exit points + const auto oldQuickTileMode = quickTileMode(); + if (quickTileMode() != QuickTileNone) { + if (oldMode == MaximizeFull && + !clientArea.contains(m_geomMaximizeRestore.center())) { + // Not restoring on the same screen + // TODO: The following doesn't work for some reason + //quick_tile_mode = QuickTileNone; // And exit quick tile mode manually + } else if ((oldMode == MaximizeVertical && m_maximizeMode == MaximizeRestore) || + (oldMode == MaximizeFull && m_maximizeMode == MaximizeHorizontal)) { + // Modifying geometry of a tiled window + updateQuickTileMode(QuickTileNone); // Exit quick tile mode without restoring geometry + } + } + // TODO: check rules if (m_maximizeMode == MaximizeFull) { m_geomMaximizeRestore = geometry(); + // TODO: Client has more checks + if (options->electricBorderMaximize()) { + updateQuickTileMode(QuickTileMaximize); + } else { + updateQuickTileMode(QuickTileNone); + } + if (quickTileMode() != oldQuickTileMode) { + emit quickTileModeChanged(); + } requestGeometry(workspace()->clientArea(MaximizeArea, this)); workspace()->raiseClient(this); } else { + if (m_maximizeMode == MaximizeRestore) { + updateQuickTileMode(QuickTileNone); + } + if (quickTileMode() != oldQuickTileMode) { + emit quickTileModeChanged(); + } + if (m_geomMaximizeRestore.isValid()) { requestGeometry(m_geomMaximizeRestore); } else {