From ae3ef3f7652291ce0512932c23c5419949ded97c Mon Sep 17 00:00:00 2001 From: Lucas Murray Date: Wed, 23 Dec 2009 01:36:44 +0000 Subject: [PATCH] Allow the quick tiling keyboard shortcuts to move the window between Xinerama screens. svn path=/trunk/KDE/kdebase/workspace/; revision=1065319 --- client.h | 2 +- geometry.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++--------- placement.cpp | 4 ++-- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/client.h b/client.h index e97ceb7c79..aa7272158a 100644 --- a/client.h +++ b/client.h @@ -236,7 +236,7 @@ class Client * This will also handle preserving and restoring of window geometry as necessary. * @param mode The tile mode (left/right) to give this window. */ - void setQuickTileMode( QuickTileMode mode ); + void setQuickTileMode( QuickTileMode mode, bool keyboard = false ); void growHorizontal(); void shrinkHorizontal(); diff --git a/geometry.cpp b/geometry.cpp index 58def96eb7..989731b5af 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -3297,7 +3297,7 @@ QRect Client::electricBorderMaximizeGeometry() return ret; } -void Client::setQuickTileMode( QuickTileMode mode ) +void Client::setQuickTileMode( QuickTileMode mode, bool keyboard ) { // Only allow quick tile on a regular or maximized window if( !isResizable() && maximizeMode() != MaximizeFull ) @@ -3318,18 +3318,56 @@ void Client::setQuickTileMode( QuickTileMode mode ) { // Untiling, so just restore geometry, and we're done. setGeometry( geom_pretile ); + checkWorkspacePosition(); // Just in case it's a different screen quick_tile_mode = QuickTileNone; return; } else { - // Check they aren't retiling in an existing direction, so we don't overwrite the saved geometry needlessly - if ( quick_tile_mode == mode ) - return; + QPoint whichScreen = keyboard ? geometry().center() : cursorPos(); - // 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_pretile = geometry(); + // 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_pretile. + if( quick_tile_mode == mode ) + { + const int numScreens = Kephal::ScreenUtils::numScreens(); + const int curScreen = screen(); + int nextScreen = curScreen; + QRect screens[numScreens]; + for( int i = 0; i < numScreens; ++i ) // Cache + screens[i] = Kephal::ScreenUtils::screenGeometry( 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( nextScreen == curScreen ) + return; // No other screens + + // Move to other screen + geom_pretile.translate( + screens[nextScreen].x() - screens[curScreen].x(), + screens[nextScreen].y() - screens[curScreen].y() ); + whichScreen = screens[nextScreen].center(); + + // Swap sides + if( mode == QuickTileLeft ) + mode = QuickTileRight; + else + mode = QuickTileLeft; + } + else + // 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_pretile = geometry(); // Temporary, so the maximize code doesn't get all confused quick_tile_mode = QuickTileNone; @@ -3337,12 +3375,12 @@ void Client::setQuickTileMode( QuickTileMode mode ) // Do the actual tile. if( mode == QuickTileLeft ) { - QRect max = workspace()->clientArea( MaximizeArea, cursorPos(), desktop() ); + QRect max = workspace()->clientArea( MaximizeArea, whichScreen, desktop() ); setGeometry( QRect( max.x(), max.y(), max.width()/2, max.height() ) ); } else { - QRect max = workspace()->clientArea( MaximizeArea, cursorPos(), desktop() ); + QRect max = workspace()->clientArea( MaximizeArea, whichScreen, desktop() ); setGeometry( QRect( max.x() + max.width()/2, max.y(), max.width()/2, max.height() ) ); } diff --git a/placement.cpp b/placement.cpp index c27bc390ec..482926294d 100644 --- a/placement.cpp +++ b/placement.cpp @@ -727,7 +727,7 @@ void Workspace::slotWindowQuickTileLeft() if( !active_client ) return; - active_client->setQuickTileMode( QuickTileLeft ); + active_client->setQuickTileMode( QuickTileLeft, true ); } void Workspace::slotWindowQuickTileRight() @@ -735,7 +735,7 @@ void Workspace::slotWindowQuickTileRight() if( !active_client ) return; - active_client->setQuickTileMode( QuickTileRight ); + active_client->setQuickTileMode( QuickTileRight, true ); } int Workspace::packPositionLeft( const Client* cl, int oldx, bool left_edge ) const