diff --git a/activation.cpp b/activation.cpp index 067ed9ee7f..c946c1b1c8 100644 --- a/activation.cpp +++ b/activation.cpp @@ -489,7 +489,7 @@ bool Workspace::allowClientActivation( const Client* c, Time time, bool focus_in // a window to be fully raised upon its own request (XRaiseWindow), // if refused, it will be raised only on top of windows belonging // to the same application -bool Workspace::allowFullClientRaising( const Client* c ) +bool Workspace::allowFullClientRaising( const Client* c, Time time ) { if( session_saving && options->focusStealingPreventionLevel <= 2 ) // <= normal @@ -516,15 +516,10 @@ bool Workspace::allowFullClientRaising( const Client* c ) } if( options->focusStealingPreventionLevel == 3 ) // high return false; - if( !c->hasUserTimeSupport()) - { - kdDebug( 1212 ) << "Raising: No support" << endl; - if( options->focusStealingPreventionLevel == 1 ) // low - return true; - } - // options->focusStealingPreventionLevel == 2 // normal - kdDebug( 1212 ) << "Raising: Refusing" << endl; - return false; + Time user_time = ac->userTime(); + kdDebug( 1212 ) << "Raising, compared:" << time << ":" << user_time + << ":" << ( timestampCompare( time, user_time ) >= 0 ) << endl; + return timestampCompare( time, user_time ) >= 0; // time >= user_time } // called from Client after FocusIn that wasn't initiated by KWin and the client diff --git a/client.h b/client.h index cab6fe9072..5d1dc5c88f 100644 --- a/client.h +++ b/client.h @@ -245,7 +245,7 @@ class Client : public QObject, public KDecorationDefines void NETMoveResize( int x_root, int y_root, NET::Direction direction ); void NETMoveResizeWindow( int flags, int x, int y, int width, int height ); - void restackWindow( Window above, int detail, NET::RequestSource source, bool send_event = false ); + void restackWindow( Window above, int detail, NET::RequestSource source, Time timestamp, bool send_event = false ); void gotPing( Time timestamp ); diff --git a/events.cpp b/events.cpp index c9aadb9a68..c5386115b4 100644 --- a/events.cpp +++ b/events.cpp @@ -89,7 +89,7 @@ void WinInfo::changeState( unsigned long state, unsigned long mask ) // **************************************** RootInfo::RootInfo( Workspace* ws, Display *dpy, Window w, const char *name, unsigned long pr[], int pr_num, int scr ) - : NETRootInfo2( dpy, w, name, pr, pr_num, scr ) + : NETRootInfo3( dpy, w, name, pr, pr_num, scr ) { workspace = ws; } @@ -161,10 +161,10 @@ void RootInfo::gotPing( Window w, Time timestamp ) c->gotPing( timestamp ); } -void RootInfo::restackWindow( Window w, Window above, int detail ) +void RootInfo::restackWindow( Window w, RequestSource source, Window above, int detail, Time timestamp ) { if( Client* c = workspace->findClient( WindowMatchPredicate( w ))) - c->restackWindow( above, detail, NET::FromTool, true ); + c->restackWindow( above, detail, source, timestamp, true ); } // **************************************** @@ -791,7 +791,7 @@ void Client::configureRequestEvent( XConfigureRequestEvent* e ) configureRequest( e->value_mask, e->x, e->y, e->width, e->height ); if ( e->value_mask & CWStackMode ) - restackWindow( e->above, e->detail, NET::FromApplication ); + restackWindow( e->above, e->detail, NET::FromApplication, userTime(), false ); // TODO sending a synthetic configure notify always is fine, even in cases where // the ICCCM doesn't require this - it can be though of as 'the WM decided to move diff --git a/layers.cpp b/layers.cpp index 71e3aef77b..c63f9d9f42 100644 --- a/layers.cpp +++ b/layers.cpp @@ -367,9 +367,9 @@ void Workspace::raiseClientWithinApplication( Client* c ) } } -void Workspace::raiseClientRequest( Client* c ) +void Workspace::raiseClientRequest( Client* c, NET::RequestSource src, Time timestamp ) { - if( allowFullClientRaising( c )) + if( src == NET::FromTool || allowFullClientRaising( c, timestamp )) raiseClient( c ); else { @@ -378,16 +378,16 @@ void Workspace::raiseClientRequest( Client* c ) } } -void Workspace::lowerClientRequest( Client* c ) +void Workspace::lowerClientRequest( Client* c, NET::RequestSource src, Time /*timestamp*/ ) { // If the client has support for all this focus stealing prevention stuff, // do only lowering within the application, as that's the more logical // variant of lowering when application requests it. // No demanding of attention here of course. - if( c->hasUserTimeSupport()) - lowerClientWithinApplication( c ); - else + if( src == NET::FromTool || !c->hasUserTimeSupport()) lowerClient( c ); + else + lowerClientWithinApplication( c ); } void Workspace::restackClientUnderActive( Client* c ) @@ -605,24 +605,18 @@ bool Workspace::keepTransientAbove( const Client* mainwindow, const Client* tran // Client //******************************* -void Client::restackWindow( Window /*above TODO */, int detail, NET::RequestSource source, bool send_event ) +void Client::restackWindow( Window /*above TODO */, int detail, NET::RequestSource src, Time timestamp, bool send_event ) { switch ( detail ) { case Above: case TopIf: - if( source == NET::FromTool ) - workspace()->raiseClient( this ); - else - workspace()->raiseClientRequest( this ); - break; + workspace()->raiseClientRequest( this, src, timestamp ); + break; case Below: case BottomIf: - if( source == NET::FromTool ) - workspace()->lowerClient( this ); - else - workspace()->lowerClientRequest( this ); - break; + workspace()->lowerClientRequest( this, src, timestamp ); + break; case Opposite: default: break; diff --git a/workspace.h b/workspace.h index c52ffbfa26..83d925191f 100644 --- a/workspace.h +++ b/workspace.h @@ -134,8 +134,8 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine QPoint adjustClientPosition( Client* c, QPoint pos ); void raiseClient( Client* c ); void lowerClient( Client* c ); - void raiseClientRequest( Client* c ); - void lowerClientRequest( Client* c ); + void raiseClientRequest( Client* c, NET::RequestSource src, Time timestamp ); + void lowerClientRequest( Client* c, NET::RequestSource src, Time timestamp ); void restackClientUnderActive( Client* ); void updateClientLayer( Client* c ); void raiseOrLowerClient( Client * ); @@ -346,7 +346,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine ClientList constrainedStackingOrder(); void raiseClientWithinApplication( Client* c ); void lowerClientWithinApplication( Client* c ); - bool allowFullClientRaising( const Client* c ); + bool allowFullClientRaising( const Client* c, Time timestamp ); bool keepTransientAbove( const Client* mainwindow, const Client* transient ); void blockStackingUpdates( bool block ); void updateCurrentTopMenu(); @@ -539,7 +539,7 @@ class StackingUpdatesBlocker }; // NET WM Protocol handler class -class RootInfo : public NETRootInfo2 +class RootInfo : public NETRootInfo3 { private: typedef KWinInternal::Client Client; // because of NET::Client @@ -554,7 +554,7 @@ class RootInfo : public NETRootInfo2 virtual void moveResize(Window w, int x_root, int y_root, unsigned long direction); virtual void moveResizeWindow(Window w, int flags, int x, int y, int width, int height ); virtual void gotPing(Window w, Time timestamp); - virtual void restackWindow(Window w, Window above, int detail); + virtual void restackWindow(Window w, RequestSource source, Window above, int detail, Time timestamp); private: Workspace* workspace; };