diff --git a/group.cpp b/group.cpp index 031744d608..840c9bcf07 100644 --- a/group.cpp +++ b/group.cpp @@ -177,7 +177,8 @@ Group::Group( Window leader_P, Workspace* workspace_P ) leader_wid( leader_P ), _workspace( workspace_P ), leader_info( NULL ), - user_time( -1U ) + user_time( -1U ), + refcount( 0 ) { if( leader_P != None ) { @@ -237,7 +238,25 @@ void Group::removeMember( Client* member_P ) // kDebug() << kBacktrace() << endl; Q_ASSERT( _members.contains( member_P )); _members.removeAll( member_P ); - if( _members.isEmpty()) +// there are cases when automatic deleting of groups must be delayed, +// e.g. when removing a member and doing some operation on the possibly +// other members of the group (which would be however deleted already +// if there were no other members) + if( refcount == 0 && _members.isEmpty()) + { + workspace()->removeGroup( this, Allowed ); + delete this; + } + } + +void Group::ref() + { + ++refcount; + } + +void Group::deref() + { + if( --refcount == 0 && _members.isEmpty()) { workspace()->removeGroup( this, Allowed ); delete this; @@ -914,7 +933,8 @@ void Client::checkGroup( Group* set_group, bool force ) { TRANSIENCY_CHECK( this ); Group* old_group = in_group; - Window old_group_leader = old_group != NULL ? old_group->leader() : None; + if( old_group != NULL ) + old_group->ref(); // turn off automatic deleting if( set_group != NULL ) { if( set_group != in_group ) @@ -1003,7 +1023,7 @@ void Client::checkGroup( Group* set_group, bool force ) if( groupTransient()) { // no longer transient for ones in the old group - if( old_group != NULL && workspace()->findGroup( old_group_leader ) == old_group ) // if it still exists + if( old_group != NULL ) { for( ClientList::ConstIterator it = old_group->members().begin(); it != old_group->members().end(); @@ -1035,6 +1055,8 @@ void Client::checkGroup( Group* set_group, bool force ) addTransient( *it ); } } + if( old_group != NULL ) + old_group->deref(); // can be now deleted if empty checkGroupTransients(); checkActiveModal(); workspace()->updateClientLayer( this ); diff --git a/group.h b/group.h index 7a29eab0d8..2811f68088 100644 --- a/group.h +++ b/group.h @@ -42,6 +42,8 @@ class Group bool groupEvent( XEvent* e ); void updateUserTime( Time time = CurrentTime ); Time userTime() const; + void ref(); + void deref(); EffectWindowGroupImpl* effectGroup(); private: void getIcons(); @@ -52,6 +54,7 @@ class Group Workspace* _workspace; NETWinInfo* leader_info; Time user_time; + int refcount; EffectWindowGroupImpl* effect_group; };