From 03b23e21d9702db50e5b1ac956613b38ee00e695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Mon, 23 Dec 2013 02:28:54 +0100 Subject: [PATCH] fix shortcut driven quicktiling 1. swapping direction would rather toggle tiling 2. the next screen was calculated wrongly (found outmost) 3. the electrictborder geometry was not updated when swapping the mode on screen changes BUG: 329136 FIXED-IN: 4.11.6 CCBUG: 222921 REVIEW: 114648 --- geometry.cpp | 86 +++++++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/geometry.cpp b/geometry.cpp index 07be3cd9db..e0d0aebdac 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -3146,14 +3146,12 @@ void Client::setQuickTileMode(QuickTileMode mode, bool keyboard) if (!isResizable() && maximizeMode() != MaximizeFull) return; - if (mode == QuickTileMaximize) - { + if (mode == QuickTileMaximize) { TabSynchronizer syncer(this, TabGroup::QuickTile|TabGroup::Geometry|TabGroup::Maximized); quick_tile_mode = QuickTileNone; - if (maximizeMode() == MaximizeFull) + if (maximizeMode() == MaximizeFull) { setMaximize(false, false); - else - { + } else { setMaximize(true, true); QRect clientArea = workspace()->clientArea(MaximizeArea, this); if (geometry().top() != clientArea.top()) { @@ -3194,27 +3192,13 @@ void Client::setQuickTileMode(QuickTileMode mode, bool keyboard) return; } - // First, check if the requested tile negates the tile we're in now: move right when left or left when right - // is the same as explicitly untiling this window, so allow it. - if (mode == QuickTileNone || ((quick_tile_mode & QuickTileHorizontal) && (mode & QuickTileHorizontal))) { - TabSynchronizer syncer(this, TabGroup::QuickTile|TabGroup::Geometry); - - quick_tile_mode = QuickTileNone; - // Untiling, so just restore geometry, and we're done. - if (!geom_restore.isValid()) // invalid if we started maximized and wait for placement - geom_restore = geometry(); - // decorations may turn off some borders when tiled - const ForceGeometry_t geom_mode = decoration && checkBorderSizes(false) ? ForceGeometrySet : NormalGeometrySet; - setGeometry(geom_restore, geom_mode); - checkWorkspacePosition(); // Just in case it's a different screen - return; - } else { + if (mode != QuickTileNone) { TabSynchronizer syncer(this, TabGroup::QuickTile|TabGroup::Geometry); QPoint whichScreen = keyboard ? geometry().center() : cursorPos(); // If trying to tile to the side that the window is already tiled to move the window to the next - // screen if it exists, otherwise ignore the request to prevent corrupting geom_restore. + // screen if it exists, otherwise toggle the mode (set QuickTileNone) if (quick_tile_mode == mode) { const int numScreens = screens()->count(); const int curScreen = screen(); @@ -3223,32 +3207,37 @@ void Client::setQuickTileMode(QuickTileMode mode, bool keyboard) for (int i = 0; i < numScreens; ++i) // Cache screens[i] = Screens::self()->geometry(i); for (int i = 0; i < numScreens; ++i) { + if (i == curScreen) continue; - if (((mode == QuickTileLeft && - screens[i].center().x() < screens[nextScreen].center().x()) || - (mode == QuickTileRight && - screens[i].center().x() > screens[nextScreen].center().x())) && - // Must be in horizontal line - (screens[i].bottom() > screens[nextScreen].top() || - screens[i].top() < screens[nextScreen].bottom())) - nextScreen = i; + + if (screens[i].bottom() <= screens[curScreen].top() || screens[i].top() >= screens[curScreen].bottom()) + continue; // not in horizontal line + + const int x = screens[i].center().x(); + if ((mode & QuickTileHorizontal) == QuickTileLeft) { + if (x >= screens[curScreen].center().x() || (curScreen != nextScreen && x <= screens[nextScreen].center().x())) + continue; // not left of current or more left then found next + } else if ((mode & QuickTileHorizontal) == QuickTileRight) { + if (x <= screens[curScreen].center().x() || (curScreen != nextScreen && x >= screens[nextScreen].center().x())) + continue; // not right of current or more right then found next + } + + nextScreen = i; } - if (nextScreen == curScreen) - return; // No other screens - // Move to other screen - geom_restore.translate( - screens[nextScreen].x() - screens[curScreen].x(), - screens[nextScreen].y() - screens[curScreen].y()); - whichScreen = screens[nextScreen].center(); + if (nextScreen == curScreen) { + mode = QuickTileNone; // No other screens, toggle tiling + } else { + // Move to other screen + geom_restore.translate(screens[nextScreen].topLeft() - screens[curScreen].topLeft()); + whichScreen = screens[nextScreen].center(); - // Swap sides - if (mode == QuickTileLeft) - mode = QuickTileRight; - else - mode = QuickTileLeft; - } else { + // Swap sides + mode = ~mode & QuickTileHorizontal; + } + setElectricBorderMode(mode); // used by ::electricBorderMaximizeGeometry(.) + } else if (quick_tile_mode == QuickTileNone) { // Not coming out of an existing tile, not shifting monitors, we're setting a brand new tile. // Store geometry first, so we can go out of this tile later. geom_restore = geometry(); @@ -3266,6 +3255,19 @@ void Client::setQuickTileMode(QuickTileMode mode, bool keyboard) // Store the mode change quick_tile_mode = mode; } + + if (mode == QuickTileNone) { + TabSynchronizer syncer(this, TabGroup::QuickTile|TabGroup::Geometry); + + quick_tile_mode = QuickTileNone; + // Untiling, so just restore geometry, and we're done. + if (!geom_restore.isValid()) // invalid if we started maximized and wait for placement + geom_restore = geometry(); + // decorations may turn off some borders when tiled + const ForceGeometry_t geom_mode = decoration && checkBorderSizes(false) ? ForceGeometrySet : NormalGeometrySet; + setGeometry(geom_restore, geom_mode); + checkWorkspacePosition(); // Just in case it's a different screen + } } } // namespace