Extend on the quicktiling(/snap) work by mgraesslin in r1021305:

- Add hotkeys for snap left/snap right, kwin won't need a seperate hotkey for snap up, as maximize will do that job for us, and it already has a hotkey
 - Add geometry restoring to quick tile, meaning that windows can be moved back to their original state after a tile, useful if just looking at something quickly.

Thanks to mgraesslin for review and lots of mentoring.

svn path=/trunk/KDE/kdebase/workspace/; revision=1022987
icc-effect-5.14.5
Robin Harold Burchell 2009-09-13 17:09:44 +00:00
parent cb7e8d9644
commit 102ec081e2
7 changed files with 111 additions and 5 deletions

View File

@ -127,6 +127,7 @@ Client::Client( Workspace* ws )
// Set the initial mapping state
mapping_state = Withdrawn;
quick_tile_mode = QuickTileNone;
desk = 0; // No desktop yet
mode = PositionCenter;

View File

@ -229,6 +229,12 @@ class Client
bool isElectricBorderMaximizing() const;
QRect electricBorderMaximizeGeometry();
/** Set the quick tile mode ("snap") of this window.
* 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 growHorizontal();
void shrinkHorizontal();
void growVertical();
@ -492,6 +498,11 @@ class Client
Kept ///< The frame should be unmapped, but is kept (For compositing)
};
MappingState mapping_state;
/** The quick tile mode of this window.
*/
QuickTileMode quick_tile_mode;
void readTransient();
Window verifyTransientFor( Window transient_for, bool set );
void addTransient( Client* cl );

View File

@ -2169,7 +2169,15 @@ void Client::maximize( MaximizeMode m )
Sets the maximization according to \a vertically and \a horizontally
*/
void Client::setMaximize( bool vertically, bool horizontally )
{ // changeMaximize() flips the state, so change from set->flip
{
// If maximizing, and a quick tile mode is set, drop it:
// this will restore the original geometry, meaning we can save it correctly here,
// as well as moving from maximized to quick tiled properly if desired.
// (remember, a quick tile is technically not maximized in any way!)
if( (vertically || horizontally) && quick_tile_mode != QuickTileNone )
setQuickTileMode( QuickTileNone );
// changeMaximize() flips the state, so change from set->flip
changeMaximize(
max_mode & MaximizeVertical ? !vertically : vertically,
max_mode & MaximizeHorizontal ? !horizontally : horizontally,
@ -2691,6 +2699,10 @@ bool Client::startMoveResize()
}
if ( maximizeMode() != MaximizeRestore )
resetMaximize();
// Undo any quick tile state this window has (it will trigger a resize, but that's expected)
if( quick_tile_mode != QuickTileNone )
setQuickTileMode( QuickTileNone );
moveResizeMode = true;
workspace()->setClientIsMoving(this);
initialMoveResizeGeom = moveResizeGeom = geometry();
@ -2742,14 +2754,12 @@ void Client::finishMoveResize( bool cancel )
break;
case ElectricLeftMode:
{
QRect max = workspace()->clientArea( MaximizeArea, cursorPos() ,workspace()->currentDesktop() );
setGeometry( QRect( max.x(), max.y(), max.width()/2, max.height() ) );
setQuickTileMode( QuickTileLeft );
break;
}
case ElectricRightMode:
{
QRect max = workspace()->clientArea( MaximizeArea, cursorPos() ,workspace()->currentDesktop() );
setGeometry( QRect( max.x() + max.width()/2, max.y(), max.width()/2, max.height() ) );
setQuickTileMode( QuickTileRight );
break;
}
}
@ -3221,4 +3231,58 @@ QRect Client::electricBorderMaximizeGeometry()
return ret;
}
void Client::setQuickTileMode( QuickTileMode mode )
{
// Only allow quick tile on a regular or maximized window
if( !isResizable() && maximizeMode() != MaximizeFull )
return;
// restore from maximized so that it is possible to tile maximized windows with one hit or by dragging
if( maximizeMode() == MaximizeFull )
{
setMaximize(false, false);
checkMaximizeGeometry();
}
// 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 == QuickTileLeft && mode == QuickTileRight) ||
(quick_tile_mode == QuickTileRight && mode == QuickTileLeft) )
{
// Untiling, so just restore geometry, and we're done.
setGeometry( geom_restore );
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;
// 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();
// Temporary, so the maximize code doesn't get all confused
quick_tile_mode = QuickTileNone;
// Do the actual tile.
if( mode == QuickTileLeft )
{
QRect max = workspace()->clientArea( MaximizeArea, this );
setGeometry( QRect( max.x(), max.y(), max.width()/2, max.height() ) );
}
else
{
QRect max = workspace()->clientArea( MaximizeArea, this);
setGeometry( QRect( max.x() + max.width()/2, max.y(), max.width()/2, max.height() ) );
}
// Store the mode change
quick_tile_mode = mode;
}
}
} // namespace

View File

@ -115,6 +115,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
0, slotWindowShrinkHorizontal() );
DEF2( "Window Shrink Vertical", I18N_NOOP("Pack Shrink Window Vertically"),
0, slotWindowShrinkVertical() );
DEF2( "Window Quick Tile Left", I18N_NOOP("Quick Tile Window to the Left"),
0, slotWindowQuickTileLeft() );
DEF2( "Window Quick Tile Right", I18N_NOOP("Quick Tile Window to the Right"),
0, slotWindowQuickTileRight() );
a = actionCollection->addAction( "Group:Window Desktop" );
a->setText( i18n("Window & Desktop") );

View File

@ -79,6 +79,13 @@ enum ElectricMaximizingMode
ElectricRightMode
};
enum QuickTileMode
{
QuickTileNone,
QuickTileLeft,
QuickTileRight
};
// TODO: Hardcoding is bad, need to add some way of registering global actions to these.
// When designing the new system we must keep in mind that we have conditional actions
// such as "only when moving windows" desktop switching that the current global action

View File

@ -721,6 +721,23 @@ void Client::shrinkVertical()
setGeometry( geom );
}
void Workspace::slotWindowQuickTileLeft()
{
if( !active_client )
return;
active_client->setQuickTileMode( QuickTileLeft );
}
void Workspace::slotWindowQuickTileRight()
{
if( !active_client )
return;
active_client->setQuickTileMode( QuickTileRight );
}
int Workspace::packPositionLeft( const Client* cl, int oldx, bool left_edge ) const
{
int newx = clientArea( MovementArea, cl ).left();

View File

@ -569,6 +569,8 @@ class Workspace : public QObject, public KDecorationDefines
void slotWindowGrowVertical();
void slotWindowShrinkHorizontal();
void slotWindowShrinkVertical();
void slotWindowQuickTileLeft();
void slotWindowQuickTileRight();
void slotWalkThroughDesktops();
void slotWalkBackThroughDesktops();