diff --git a/activation.cpp b/activation.cpp index f1bc56ae20..b040b7b62c 100644 --- a/activation.cpp +++ b/activation.cpp @@ -235,6 +235,7 @@ void Workspace::setActiveClient( Client* c, allowed_t ) focus_chain.append( c ); active_client->demandAttention( false ); } + pending_take_activity = NULL; updateCurrentTopMenu(); updateToolWindows( false ); @@ -352,10 +353,15 @@ void Workspace::takeActivity( Client* c, int flags, bool handled ) c->takeActivity( flags, handled, Allowed ); } -void Workspace::handleActivityRaise( Client* c, Time timestamp ) +void Workspace::handleTakeActivity( Client* c, /*Time timestamp*/, int flags ) { - if( last_restack == CurrentTime || timestampCompare( timestamp, last_restack ) >= 0 ) + if( pending_take_activity != c ) // pending_take_activity is reset when doing restack or activation + return; + if(( flags & ActivityRaise ) != 0 ) raiseClient( c ); + if(( flags & ActivityFocus ) != 0 && c->isShown( false )) + c->takeFocus( Allowed ); + pending_take_activity = NULL; } /*! diff --git a/client.cpp b/client.cpp index 83eb946f65..637595dfe7 100644 --- a/client.cpp +++ b/client.cpp @@ -1139,15 +1139,7 @@ void Client::takeActivity( int flags, bool handled, allowed_t ) previous_activity_timestamp = qt_x_time; previous_client = this; #endif - int flg = 0; - if( flags & ActivityFocus ) - { - flg |= 1 << 0; - workspace()->setShouldGetFocus( this ); - } - if( flags & ActivityRaise ) - flg |= 1 << 1; - sendClientMessage(window(), atoms->wm_protocols, atoms->net_wm_take_activity, flg ); + workspace()->sendTakeActivity( this, qt_x_time, flags ); } // performs the actual focusing of the window using XSetInputFocus and WM_TAKE_FOCUS diff --git a/events.cpp b/events.cpp index e398c3c2f2..c054979d00 100644 --- a/events.cpp +++ b/events.cpp @@ -110,7 +110,7 @@ void RootInfo::changeActiveWindow( Window w, NET::RequestSource src, Time timest { if( timestamp == CurrentTime ) timestamp = c->userTime(); - if( src != NET::FromApplication && src != NET::FromActivity && src != FromTool ) + if( src != NET::FromApplication && src != FromTool ) src = NET::FromTool; if( src == NET::FromTool ) workspace->activateClient( c ); @@ -137,15 +137,18 @@ void RootInfo::restackWindow( Window w, RequestSource src, Window above, int det { if( timestamp == CurrentTime ) timestamp = c->userTime(); - if( src != NET::FromApplication && src != NET::FromActivity && src != FromTool ) + if( src != NET::FromApplication && src != FromTool ) src = NET::FromTool; - if( src == NET::FromActivity ) - workspace->handleActivityRaise( c, timestamp ); - else - c->restackWindow( above, detail, src, timestamp, true ); + c->restackWindow( above, detail, src, timestamp, true ); } } +void RootInfo::gotTakeActivity( Window w, Time timestamp, long flags ) + { + if( Client* c = workspace->findClient( WindowMatchPredicate( w ))) + workspace->handleTakeActivity( c, timestamp, flags ); + } + void RootInfo::closeWindow(Window w) { Client* c = workspace->findClient( WindowMatchPredicate( w )); diff --git a/layers.cpp b/layers.cpp index 6666aad349..a3a52d956c 100644 --- a/layers.cpp +++ b/layers.cpp @@ -341,7 +341,7 @@ void Workspace::raiseClient( Client* c ) if( !c->isSpecialWindow()) { most_recently_raised = c; - last_restack = qt_x_time; + pending_take_activity = NULL; } } diff --git a/workspace.cpp b/workspace.cpp index abd809470d..a71c669bc7 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -69,7 +69,7 @@ Workspace::Workspace( bool restore ) last_active_client (0), most_recently_raised (0), movingClient(0), - last_restack (CurrentTime), + pending_take_activity ( NULL ), was_user_interaction (false), session_saving (false), control_grab (false), @@ -505,6 +505,8 @@ void Workspace::removeClient( Client* c, allowed_t ) Q_ASSERT( c != active_client ); if ( c == last_active_client ) last_active_client = 0; + if( c == pending_take_activity ) + pending_take_activity = NULL; updateStackingOrder( true ); @@ -1329,6 +1331,12 @@ void Workspace::sendPingToWindow( Window window, Time timestamp ) rootInfo->sendPing( window, timestamp ); } +void Workspace::sendTakeActivity( Client* c, Time timestamp, long flags ) + { + rootInfo->takeActivity( c->window(), timestamp, flags ); + pending_take_activity = c; + } + /*! Takes a screenshot of the current window and puts it in the clipboard. diff --git a/workspace.h b/workspace.h index b33d94ec91..ef9f0edbd2 100644 --- a/workspace.h +++ b/workspace.h @@ -107,7 +107,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine void activateClient( Client*, bool force = FALSE ); void requestFocus( Client* c, bool force = FALSE ); void takeActivity( Client* c, int flags, bool handled ); // flags are ActivityFlags - void handleActivityRaise( Client* c, Time timestamp ); + void handleTakeActivity( Client* c, Time timestamp, int flags ); // flags are ActivityFlags bool allowClientActivation( const Client* c, Time time = -1U, bool focus_in = false, bool session_active = false ); void restoreFocus(); @@ -212,6 +212,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine bool isNotManaged( const QString& title ); // ### setter or getter ? void sendPingToWindow( Window w, Time timestamp ); // called from Client::pingWindow() + void sendTakeActivity( Client* c, Time timestamp, long flags ); // called from Client::takeActivity() // only called from Client::destroyClient() or Client::releaseWindow() void removeClient( Client*, allowed_t ); @@ -427,7 +428,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine Client* last_active_client; Client* most_recently_raised; // used _only_ by raiseOrLowerClient() Client* movingClient; - Time last_restack; + Client* pending_take_activity; ClientList clients; ClientList desktops; @@ -559,6 +560,7 @@ class RootInfo : public NETRootInfo3 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, RequestSource source, Window above, int detail, Time timestamp); + virtual void gotTakeActivity(Window w, Time timestamp, long flags ); private: Workspace* workspace; };