diff --git a/client.cpp b/client.cpp index 637595dfe7..8cdb98d144 100644 --- a/client.cpp +++ b/client.cpp @@ -125,6 +125,7 @@ Client::Client( Workspace *ws ) not_obscured = false; urgency = false; ignore_focus_stealing = false; + check_active_modal = false; Pdeletewindow = 0; Ptakefocus = 0; @@ -156,6 +157,7 @@ Client::~Client() assert( frame == None && wrapper == None ); assert( decoration == NULL ); assert( block_geometry == 0 ); + assert( !check_active_modal ); delete info; delete bridge; } diff --git a/client.h b/client.h index ce8d8c3ebc..695a3f70d8 100644 --- a/client.h +++ b/client.h @@ -452,6 +452,7 @@ private slots: uint not_obscured : 1; uint urgency : 1; // XWMHints, UrgencyHint uint ignore_focus_stealing : 1; // don't apply focus stealing prevention to this client + uint check_active_modal : 1; // see Client::addTransient() void getWMHints(); void readIcons(); void getWindowProtocols(); diff --git a/group.cpp b/group.cpp index ca036db7b8..d9f1a99661 100644 --- a/group.cpp +++ b/group.cpp @@ -417,7 +417,7 @@ void Client::setTransient( Window new_transient_for_id ) transient_for = workspace()->findClient( WindowMatchPredicate( transient_for_id )); assert( transient_for != NULL ); // verifyTransient() had to check this transient_for->addTransient( this ); - } + } // checkGroup() will check 'check_active_modal' checkGroup( NULL, true ); // force, because transiency has changed workspace()->updateClientLayer( this ); } @@ -625,8 +625,8 @@ void Client::addTransient( Client* cl ) // assert( !cl->hasTransient( this, true )); will be fixed in checkGroupTransients() assert( cl != this ); transients_list.append( cl ); - if( workspace()->mostRecentlyActivatedClient() == this && cl->isModal()) - workspace()->activateClient( findModal()); + if( workspace()->mostRecentlyActivatedClient() == this && cl->isModal()) + check_active_modal = true; // kdDebug() << "ADDTRANS:" << this << ":" << cl << endl; // kdDebug() << kdBacktrace() << endl; // for( ClientList::ConstIterator it = transients_list.begin(); @@ -859,6 +859,17 @@ void Client::checkGroup( Group* set_group, bool force ) } } checkGroupTransients(); + // if the active window got new modal transient, activate it + // cannot be done in AddTransient(), because there may temporarily + // exist loops, breaking findModal + Client* check_modal = workspace()->mostRecentlyActivatedClient(); + if( check_modal != NULL && check_modal->check_active_modal ) + { + Client* new_modal = check_modal->findModal(); + if( new_modal != NULL && new_modal != check_modal ) + workspace()->activateClient( new_modal ); + check_modal->check_active_modal = false; + } workspace()->updateClientLayer( this ); }