Don't crash because of automatic deleting of groups.
BUG: 138834 svn path=/trunk/KDE/kdebase/workspace/; revision=613847
This commit is contained in:
parent
0cbf093fdd
commit
ce58330fc4
2 changed files with 29 additions and 4 deletions
30
group.cpp
30
group.cpp
|
@ -176,7 +176,8 @@ Group::Group( Window leader_P, Workspace* workspace_P )
|
||||||
leader_wid( leader_P ),
|
leader_wid( leader_P ),
|
||||||
_workspace( workspace_P ),
|
_workspace( workspace_P ),
|
||||||
leader_info( NULL ),
|
leader_info( NULL ),
|
||||||
user_time( -1U )
|
user_time( -1U ),
|
||||||
|
refcount( 0 )
|
||||||
{
|
{
|
||||||
if( leader_P != None )
|
if( leader_P != None )
|
||||||
{
|
{
|
||||||
|
@ -234,7 +235,25 @@ void Group::removeMember( Client* member_P )
|
||||||
// kDebug() << kBacktrace() << endl;
|
// kDebug() << kBacktrace() << endl;
|
||||||
Q_ASSERT( _members.contains( member_P ));
|
Q_ASSERT( _members.contains( member_P ));
|
||||||
_members.removeAll( 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 );
|
workspace()->removeGroup( this, Allowed );
|
||||||
delete this;
|
delete this;
|
||||||
|
@ -907,7 +926,8 @@ void Client::checkGroup( Group* set_group, bool force )
|
||||||
{
|
{
|
||||||
TRANSIENCY_CHECK( this );
|
TRANSIENCY_CHECK( this );
|
||||||
Group* old_group = in_group;
|
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 != NULL )
|
||||||
{
|
{
|
||||||
if( set_group != in_group )
|
if( set_group != in_group )
|
||||||
|
@ -996,7 +1016,7 @@ void Client::checkGroup( Group* set_group, bool force )
|
||||||
if( groupTransient())
|
if( groupTransient())
|
||||||
{
|
{
|
||||||
// no longer transient for ones in the old group
|
// 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();
|
for( ClientList::ConstIterator it = old_group->members().begin();
|
||||||
it != old_group->members().end();
|
it != old_group->members().end();
|
||||||
|
@ -1028,6 +1048,8 @@ void Client::checkGroup( Group* set_group, bool force )
|
||||||
addTransient( *it );
|
addTransient( *it );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if( old_group != NULL )
|
||||||
|
old_group->deref(); // can be now deleted if empty
|
||||||
checkGroupTransients();
|
checkGroupTransients();
|
||||||
checkActiveModal();
|
checkActiveModal();
|
||||||
workspace()->updateClientLayer( this );
|
workspace()->updateClientLayer( this );
|
||||||
|
|
3
group.h
3
group.h
|
@ -41,6 +41,8 @@ class Group
|
||||||
bool groupEvent( XEvent* e );
|
bool groupEvent( XEvent* e );
|
||||||
void updateUserTime( Time time = CurrentTime );
|
void updateUserTime( Time time = CurrentTime );
|
||||||
Time userTime() const;
|
Time userTime() const;
|
||||||
|
void ref();
|
||||||
|
void deref();
|
||||||
private:
|
private:
|
||||||
void getIcons();
|
void getIcons();
|
||||||
void startupIdChanged();
|
void startupIdChanged();
|
||||||
|
@ -50,6 +52,7 @@ class Group
|
||||||
Workspace* _workspace;
|
Workspace* _workspace;
|
||||||
NETWinInfo* leader_info;
|
NETWinInfo* leader_info;
|
||||||
Time user_time;
|
Time user_time;
|
||||||
|
int refcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Window Group::leader() const
|
inline Window Group::leader() const
|
||||||
|
|
Loading…
Reference in a new issue