Allow moving of maximized windows across screens

BUG: 131299

svn path=/trunk/KDE/kdebase/workspace/; revision=837644
This commit is contained in:
Lucas Murray 2008-07-25 10:31:47 +00:00
parent e1683ef06f
commit 0581746327
6 changed files with 51 additions and 19 deletions

View file

@ -182,6 +182,7 @@ class Client
bool isResizable() const;
bool isMovable() const;
bool isMovableAcrossScreens() const;
bool isCloseable() const; // may be closed by the user (may have a close button)
void takeActivity( int flags, bool handled, allowed_t ); // takes ActivityFlags as arg (in utils.h)

View file

@ -1144,6 +1144,13 @@ bool EffectWindowImpl::isMovable() const
return false;
}
bool EffectWindowImpl::isMovableAcrossScreens() const
{
if( Client* c = dynamic_cast< Client* >( toplevel ))
return c->isMovableAcrossScreens();
return false;
}
bool EffectWindowImpl::isUserMove() const
{
if( Client* c = dynamic_cast< Client* >( toplevel ))

View file

@ -200,6 +200,7 @@ class EffectWindowImpl : public EffectWindow
virtual QSize size() const;
virtual QRect rect() const;
virtual bool isMovable() const;
virtual bool isMovableAcrossScreens() const;
virtual bool isUserMove() const;
virtual bool isUserResize() const;
virtual QRect iconGeometry() const;

View file

@ -1720,6 +1720,20 @@ bool Client::isMovable() const
return true;
}
/*!
Returns whether the window is moveable across Xinerama screens
*/
bool Client::isMovableAcrossScreens() const
{
if( !motif_may_move )
return false;
if( isSpecialWindow() && !isSplash() && !isToolbar()) // allow moving of splashscreens :)
return false;
if( rules()->checkPosition( invalidPoint ) != invalidPoint ) // forced position
return false;
return true;
}
/*!
Returns whether the window is resizable or has a fixed size.
*/
@ -2607,7 +2621,7 @@ void Client::delayedMoveResize()
void Client::handleMoveResize( int x, int y, int x_root, int y_root )
{
if(( mode == PositionCenter && !isMovable())
if(( mode == PositionCenter && !isMovableAcrossScreens() )
|| ( mode != PositionCenter && ( isShade() || !isResizable())))
return;
@ -2760,20 +2774,28 @@ void Client::handleMoveResize( int x, int y, int x_root, int y_root )
else if( isMove())
{
assert( mode == PositionCenter );
// first move, then snap, then check bounds
moveResizeGeom.moveTopLeft( topleft );
moveResizeGeom.moveTopLeft( workspace()->adjustClientPosition( this, moveResizeGeom.topLeft(),
unrestrictedMoveResize ) );
// NOTE: This is duped in checkUnrestrictedMoveResize().
if( moveResizeGeom.bottom() < desktopArea.top() + titlebar_marge - 1 ) // titlebar mustn't go out
moveResizeGeom.moveBottom( desktopArea.top() + titlebar_marge - 1 );
// no need to check top_marge, titlebar_marge already handles it
if( moveResizeGeom.top() > desktopArea.bottom() - bottom_marge )
moveResizeGeom.moveTop( desktopArea.bottom() - bottom_marge );
if( moveResizeGeom.right() < desktopArea.left() + left_marge )
moveResizeGeom.moveRight( desktopArea.left() + left_marge );
if( moveResizeGeom.left() > desktopArea.right() - right_marge )
moveResizeGeom.moveLeft(desktopArea.right() - right_marge );
if( !isMovable() ) // isMovableAcrossScreens() must have been true to get here
{ // Special moving of maximized windows on Xinerama screens
int screen = workspace()->screenNumber( globalPos );
moveResizeGeom = workspace()->clientArea( MaximizeArea, screen, 0 );
}
else
{
// first move, then snap, then check bounds
moveResizeGeom.moveTopLeft( topleft );
moveResizeGeom.moveTopLeft( workspace()->adjustClientPosition( this, moveResizeGeom.topLeft(),
unrestrictedMoveResize ));
// NOTE: This is duped in checkUnrestrictedMoveResize().
if( moveResizeGeom.bottom() < desktopArea.top() + titlebar_marge - 1 ) // titlebar mustn't go out
moveResizeGeom.moveBottom( desktopArea.top() + titlebar_marge - 1 );
// no need to check top_marge, titlebar_marge already handles it
if( moveResizeGeom.top() > desktopArea.bottom() - bottom_marge )
moveResizeGeom.moveTop( desktopArea.bottom() - bottom_marge );
if( moveResizeGeom.right() < desktopArea.left() + left_marge )
moveResizeGeom.moveRight( desktopArea.left() + left_marge );
if( moveResizeGeom.left() > desktopArea.right() - right_marge )
moveResizeGeom.moveLeft(desktopArea.right() - right_marge );
}
if( moveResizeGeom.topLeft() != previousMoveResizeGeom.topLeft())
update = true;
}

View file

@ -162,7 +162,7 @@ X-KDE-Library=kwin4_effect_cooleffect
#define KWIN_EFFECT_API_MAKE_VERSION( major, minor ) (( major ) << 8 | ( minor ))
#define KWIN_EFFECT_API_VERSION_MAJOR 0
#define KWIN_EFFECT_API_VERSION_MINOR 21
#define KWIN_EFFECT_API_VERSION_MINOR 22
#define KWIN_EFFECT_API_VERSION KWIN_EFFECT_API_MAKE_VERSION( \
KWIN_EFFECT_API_VERSION_MAJOR, KWIN_EFFECT_API_VERSION_MINOR )
@ -629,6 +629,7 @@ class KWIN_EXPORT EffectWindow
virtual QSize size() const = 0;
virtual QRect rect() const = 0;
virtual bool isMovable() const = 0;
virtual bool isMovableAcrossScreens() const = 0;
virtual bool isUserMove() const = 0;
virtual bool isUserResize() const = 0;
virtual QRect iconGeometry() const = 0;

View file

@ -220,7 +220,7 @@ void Workspace::clientPopupAboutToShow()
}
mResizeOpAction->setEnabled( active_popup_client->isResizable() );
mMoveOpAction->setEnabled( active_popup_client->isMovable() );
mMoveOpAction->setEnabled( active_popup_client->isMovableAcrossScreens() );
mMaximizeOpAction->setEnabled( active_popup_client->isMaximizable() );
mMaximizeOpAction->setChecked( active_popup_client->maximizeMode() == Client::MaximizeFull );
mShadeOpAction->setEnabled( active_popup_client->isShadeable() );
@ -610,13 +610,13 @@ bool Client::performMouseCommand( Options::MouseCommand command, const QPoint &g
workspace()->raiseClient( this );
workspace()->requestFocus( this );
workspace()->setActiveScreenMouse( globalPos );
if( options->moveMode == Options::Transparent && isMovable())
if( options->moveMode == Options::Transparent && isMovableAcrossScreens())
move_faked_activity = workspace()->fakeRequestedActivity( this );
// fallthrough
case Options::MouseMove:
case Options::MouseUnrestrictedMove:
{
if (!isMovable())
if (!isMovableAcrossScreens())
break;
if( moveResizeMode )
finishMoveResize( false );