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
This commit is contained in:
Thomas Lübking 2013-12-23 02:28:54 +01:00
parent 45c3835fd7
commit 03b23e21d9

View file

@ -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