From 42e26ff6086e7901e6e40f7a64546ba276b19276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Thu, 5 Feb 2004 18:16:53 +0000 Subject: [PATCH] Use WM_CLIENT_LEADER for grouping if a window is group transient but has no group set. This should take care of comment #20 in #69519. svn path=/trunk/kdebase/kwin/; revision=285366 --- group.cpp | 67 ++++++++++++++++++++++++++++++++++++++++------------- manage.cpp | 2 +- workspace.h | 3 ++- 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/group.cpp b/group.cpp index 087d0cfb72..aafa51cb40 100644 --- a/group.cpp +++ b/group.cpp @@ -48,24 +48,26 @@ QPixmap Group::icon() const { if( leader_client != NULL ) return leader_client->icon(); - else + else if( leader_wid != None ) { QPixmap ic; Client::readIcons( leader_wid, &ic, NULL ); return ic; } + return QPixmap(); } QPixmap Group::miniIcon() const { if( leader_client != NULL ) return leader_client->miniIcon(); - else + else if( leader_wid != None ) { QPixmap ic; Client::readIcons( leader_wid, NULL, &ic ); return ic; } + return QPixmap(); } void Group::addMember( Client* member_P ) @@ -110,7 +112,7 @@ void Group::lostLeader() // Workspace //*************************************** -Group* Workspace::findGroup( Window leader ) +Group* Workspace::findGroup( Window leader ) const { assert( leader != None ); for( GroupList::ConstIterator it = groups.begin(); @@ -121,6 +123,22 @@ Group* Workspace::findGroup( Window leader ) return NULL; } +// Client is group transient, but has no group set. Try to find +// group with windows with the same client leader. +Group* Workspace::findClientLeaderGroup( const Client* c ) const + { + for( ClientList::ConstIterator it = clients.begin(); + it != clients.end(); + ++it ) + { + if( *it == c ) + continue; + if( (*it)->wmClientLeader() == c->wmClientLeader()) + return (*it)->group(); + } + return NULL; + } + void Workspace::updateMinimizedOfTransients( Client* c ) { // if mainwindow is minimized or shaded, minimize transients too @@ -248,19 +266,23 @@ bool Client::sameAppWindowRoleMatch( const Client* c1, const Client* c2, bool ac while( c1->transientFor() != NULL ) c1 = c1->transientFor(); if( c1->groupTransient()) - return c1->group() == c2->group() + return c1->group() == c2->group(); +#if 0 // if a group transient is in its own group, it didn't possibly have a group, // and therefore should be considered belonging to the same app like // all other windows from the same app || c1->group()->leaderClient() == c1 || c2->group()->leaderClient() == c2; +#endif } if( c2->isTransient()) { while( c2->transientFor() != NULL ) c2 = c2->transientFor(); if( c2->groupTransient()) - return c1->group() == c2->group() + return c1->group() == c2->group(); +#if 0 || c1->group()->leaderClient() == c1 || c2->group()->leaderClient() == c2; +#endif } int pos1 = c1->windowRole().find( '#' ); int pos2 = c2->windowRole().find( '#' ); @@ -349,8 +371,15 @@ void Client::setTransient( Window new_transient_for_id ) removeFromMainClients(); transient_for = NULL; transient_for_id = new_transient_for_id; - if( groupTransient()) + if( transient_for_id != None && !groupTransient()) { + transient_for = workspace()->findClient( WindowMatchPredicate( transient_for_id )); + assert( transient_for != NULL ); // verifyTransient() had to check this + transient_for->addTransient( this ); + } + checkGroup(); // first check group + if( groupTransient()) + { // and make transient for all in the group for( ClientList::ConstIterator it = group()->members().begin(); it != group()->members().end(); ++it ) @@ -360,13 +389,6 @@ void Client::setTransient( Window new_transient_for_id ) (*it)->addTransient( this ); } } - else if( transient_for_id != None ) - { - transient_for = workspace()->findClient( WindowMatchPredicate( transient_for_id )); - assert( transient_for != NULL ); // verifyTransient() had to check this - transient_for->addTransient( this ); - } - checkGroup(); checkGroupTransients(); workspace()->updateClientLayer( this ); } @@ -710,8 +732,22 @@ void Client::checkGroup() in_group->addMember( this ); } } + else if( groupTransient()) + { // group transient which actually doesn't have a group :( + // try creating group with other windows with the same client leader + Group* new_group = workspace()->findClientLeaderGroup( this ); + if( new_group == NULL ) + new_group = new Group( None, workspace()); + if( new_group != in_group ) + { + if( in_group != NULL ) + in_group->removeMember( this ); + in_group = new_group; + in_group->addMember( this ); + } + } else // not transient without a group, put it in its own group - { // (can be also group transient which actually doesn't have a group :( ) + { if( in_group != NULL && in_group->leader() != window()) { in_group->removeMember( this ); @@ -719,9 +755,8 @@ void Client::checkGroup() } if( in_group == NULL ) { - in_group = new Group( window(), workspace()); + in_group = new Group( None, workspace()); in_group->addMember( this ); - in_group->gotLeader( this ); } } } diff --git a/manage.cpp b/manage.cpp index a3421e61eb..606fd595a1 100644 --- a/manage.cpp +++ b/manage.cpp @@ -104,11 +104,11 @@ bool Client::manage( Window w, bool isMapped ) fetchName(); fetchIconicName(); getWMHints(); // needs to be done before readTransient() because of reading the group + getWmClientLeader(); // needs to be done before readTransient() because of same app comparing readTransient(); getIcons(); getWindowProtocols(); getWmNormalHints(); // get xSizeHint - getWmClientLeader(); window_role = getStringProperty( w, qt_window_role ); // TODO try to obey all state information from info->state() diff --git a/workspace.h b/workspace.h index 197ae103a6..1fb08c9fd5 100644 --- a/workspace.h +++ b/workspace.h @@ -80,9 +80,10 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine template< typename T1, typename T2 > void forEachClient( T1 procedure, T2 predicate ); template< typename T > void forEachClient( T procedure ); - Group* findGroup( Window leader ); + Group* findGroup( Window leader ) const; void addGroup( Group* group, allowed_t ); void removeGroup( Group* group, allowed_t ); + Group* findClientLeaderGroup( const Client* c ) const; QRect clientArea( clientAreaOption, const QPoint& p, int desktop ) const; QRect clientArea( clientAreaOption, const Client* c ) const;