Instead of the somewhat fragile way of trying to clean up Client/Unmanaged
instances and keeping them around after the window is closed, create class Deleted as a representation of a closed window. svn path=/branches/work/kwin_composite/; revision=626356
This commit is contained in:
parent
0fdc6c4469
commit
77f803a563
36 changed files with 190 additions and 147 deletions
|
@ -50,6 +50,7 @@ set(kwin_KDEINIT_SRCS
|
|||
scene_xrender.cpp
|
||||
scene_opengl.cpp
|
||||
glutils.cpp
|
||||
deleted.cpp
|
||||
effects.cpp
|
||||
effects/fadein.cpp
|
||||
effects/fadeout.cpp
|
||||
|
|
|
@ -67,10 +67,12 @@ General TODO
|
|||
|
||||
* handle properly deleted windows that reappear (windowReadded() function?)
|
||||
|
||||
? consider using an extra class for representing deleted windows
|
||||
/ consider using an extra class for representing deleted windows
|
||||
- cleaning up Client/Unmanaged instances may still leave e.g. timers around if they're overlooked
|
||||
- an extra class could copy some interesting data and "replace" the old instance
|
||||
|
||||
+ Deleted::windowType() does not work
|
||||
|
||||
|
||||
OpenGL TODO
|
||||
=================================
|
||||
|
@ -224,6 +226,10 @@ Effects TODO
|
|||
initiated by the user or by the application
|
||||
* - fade-out needs framework for disappearing windows (see the todo entry)
|
||||
|
||||
+ add API that'll hide the internals (for making backwards compatibility easier, etc.)
|
||||
- effects should have access only to classes from this API
|
||||
- hide the fact that Client/Unmanaged become Deleted in windowClosed()
|
||||
|
||||
+ minimize/shade effects
|
||||
- to replace the ones from KWin core
|
||||
- Client::animateMinimizeOrUnminimize()
|
||||
|
|
86
client.cpp
86
client.cpp
|
@ -30,6 +30,7 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#include "rules.h"
|
||||
#include "scene.h"
|
||||
#include "effects.h"
|
||||
#include "deleted.h"
|
||||
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <QX11Info>
|
||||
|
@ -108,6 +109,7 @@ Client::Client( Workspace *ws )
|
|||
|
||||
shade_mode = ShadeNone;
|
||||
active = false;
|
||||
deleting = false;
|
||||
keep_above = false;
|
||||
keep_below = false;
|
||||
motif_noborder = false;
|
||||
|
@ -174,11 +176,16 @@ void Client::deleteClient( Client* c, allowed_t )
|
|||
*/
|
||||
void Client::releaseWindow( bool on_shutdown )
|
||||
{
|
||||
assert( !deleting());
|
||||
delete_refcount = 1;
|
||||
assert( !deleting );
|
||||
deleting = true;
|
||||
if( effects )
|
||||
effects->windowClosed( this );
|
||||
finishCompositing( false ); // don't discard pixmap
|
||||
{
|
||||
Deleted* del = Deleted::create( this );
|
||||
effects->windowClosed( this, del );
|
||||
scene->windowClosed( this, del );
|
||||
del->unrefWindow();
|
||||
}
|
||||
finishCompositing();
|
||||
workspace()->discardUsedWindowRules( this, true ); // remove ForceTemporarily rules
|
||||
StackingUpdatesBlocker blocker( workspace());
|
||||
if (moveResizeMode)
|
||||
|
@ -193,9 +200,7 @@ void Client::releaseWindow( bool on_shutdown )
|
|||
if( !on_shutdown )
|
||||
workspace()->clientHidden( this );
|
||||
XUnmapWindow( display(), frameId()); // destroying decoration would cause ugly visual effect
|
||||
// destroyDecoration();
|
||||
delete decoration;
|
||||
decoration = NULL;
|
||||
destroyDecoration();
|
||||
cleanGrouping();
|
||||
if( !on_shutdown )
|
||||
{
|
||||
|
@ -203,11 +208,9 @@ void Client::releaseWindow( bool on_shutdown )
|
|||
// only when the window is being unmapped, not when closing down KWin
|
||||
// (NETWM sections 5.5,5.7)
|
||||
info->setDesktop( 0 );
|
||||
// desk = 0; - do not reset internal state, it may still be used by effects
|
||||
desk = 0;
|
||||
info->setState( 0, info->state()); // reset all state flags
|
||||
}
|
||||
else
|
||||
workspace()->addDeleted( this, Allowed );
|
||||
XDeleteProperty( display(), client, atoms->kde_net_wm_user_creation_time);
|
||||
XDeleteProperty( display(), client, atoms->net_frame_extents );
|
||||
XDeleteProperty( display(), client, atoms->kde_net_wm_frame_strut );
|
||||
|
@ -225,25 +228,30 @@ void Client::releaseWindow( bool on_shutdown )
|
|||
// may do map+unmap before we initially map the window by calling rawShow() from manage().
|
||||
XUnmapWindow( display(), client );
|
||||
}
|
||||
cleanUp();
|
||||
client = None;
|
||||
XDestroyWindow( display(), wrapper );
|
||||
wrapper = None;
|
||||
XDestroyWindow( display(), frameId());
|
||||
// frame = None;
|
||||
--block_geometry_updates; // don't use GeometryUpdatesBlocker, it would now set the geometry
|
||||
unrefWindow(); // will delete if recount is == 0
|
||||
workspace()->addDamage( geometry());
|
||||
deleteClient( this, Allowed );
|
||||
}
|
||||
|
||||
// like releaseWindow(), but this one is called when the window has been already destroyed
|
||||
// (e.g. the application closed it)
|
||||
void Client::destroyClient()
|
||||
{
|
||||
assert( !deleting());
|
||||
delete_refcount = 1;
|
||||
assert( !deleting );
|
||||
deleting = true;
|
||||
if( effects )
|
||||
effects->windowClosed( this );
|
||||
finishCompositing( false ); // don't discard pixmap
|
||||
{
|
||||
Deleted* del = Deleted::create( this );
|
||||
effects->windowClosed( this, del );
|
||||
scene->windowClosed( this, del );
|
||||
del->unrefWindow();
|
||||
}
|
||||
finishCompositing();
|
||||
workspace()->discardUsedWindowRules( this, true ); // remove ForceTemporarily rules
|
||||
StackingUpdatesBlocker blocker( workspace());
|
||||
if (moveResizeMode)
|
||||
|
@ -255,50 +263,16 @@ void Client::destroyClient()
|
|||
setModal( false );
|
||||
hidden = true; // so that it's not considered visible anymore
|
||||
workspace()->clientHidden( this );
|
||||
// destroyDecoration();
|
||||
delete decoration;
|
||||
decoration = NULL;
|
||||
destroyDecoration();
|
||||
cleanGrouping();
|
||||
workspace()->removeClient( this, Allowed );
|
||||
cleanUp();
|
||||
client = None; // invalidate
|
||||
XDestroyWindow( display(), wrapper );
|
||||
wrapper = None;
|
||||
XDestroyWindow( display(), frameId());
|
||||
// frame = None;
|
||||
--block_geometry_updates; // don't use GeometryUpdatesBlocker, it would now set the geometry
|
||||
unrefWindow(); // will delete if recount is == 0
|
||||
}
|
||||
|
||||
// All clean-up code shared between releaseWindow() and destroyClient().
|
||||
// Clean up everything that should not affect a deleted Client until it's
|
||||
// really deleted by unrefWindow(). I.e. stop watching events, turn off timers
|
||||
// and so on.
|
||||
void Client::cleanUp()
|
||||
{
|
||||
if( Extensions::shapeAvailable())
|
||||
XShapeSelectInput( display(), client, NoEventMask );
|
||||
XSelectInput( display(), client, NoEventMask );
|
||||
delete autoRaiseTimer;
|
||||
autoRaiseTimer = NULL;
|
||||
delete shadeHoverTimer;
|
||||
shadeHoverTimer = NULL;
|
||||
delete ping_timer;
|
||||
ping_timer = NULL;
|
||||
delete process_killer;
|
||||
process_killer = NULL;
|
||||
delete demandAttentionKNotifyTimer;
|
||||
demandAttentionKNotifyTimer = NULL;
|
||||
}
|
||||
|
||||
void Client::unrefWindow()
|
||||
{
|
||||
if( --delete_refcount > 0 )
|
||||
return;
|
||||
workspace()->removeDeleted( this );
|
||||
workspace()->addDamage( geometry());
|
||||
destroyDecoration( true ); // only now gravitate etc., otherwise window pixmap would be wrong
|
||||
discardWindowPixmap();
|
||||
deleteClient( this, Allowed );
|
||||
}
|
||||
|
||||
|
@ -343,9 +317,9 @@ void Client::updateDecoration( bool check_workspace_pos, bool force )
|
|||
addDamageFull();
|
||||
}
|
||||
|
||||
void Client::destroyDecoration( bool force )
|
||||
void Client::destroyDecoration()
|
||||
{
|
||||
if( decoration != NULL || force )
|
||||
if( decoration != NULL )
|
||||
{
|
||||
delete decoration;
|
||||
decoration = NULL;
|
||||
|
@ -360,7 +334,7 @@ void Client::destroyDecoration( bool force )
|
|||
workarea_diff_y = save_workarea_diff_y;
|
||||
if( compositing() )
|
||||
discardWindowPixmap();
|
||||
if( scene != NULL && !deleting())
|
||||
if( scene != NULL && !deleting )
|
||||
scene->windowGeometryShapeChanged( this );
|
||||
addDamageFull();
|
||||
}
|
||||
|
@ -895,7 +869,7 @@ void Client::toggleShade()
|
|||
|
||||
void Client::updateVisibility()
|
||||
{
|
||||
if( deleting())
|
||||
if( deleting )
|
||||
return;
|
||||
bool show = true;
|
||||
if( hidden )
|
||||
|
@ -953,7 +927,7 @@ void Client::updateVisibility()
|
|||
void Client::setMappingState(int s)
|
||||
{
|
||||
assert( client != None );
|
||||
assert( !deleting() || s == WithdrawnState );
|
||||
assert( !deleting || s == WithdrawnState );
|
||||
if( mapping_state == s )
|
||||
return;
|
||||
bool was_unmanaged = ( mapping_state == WithdrawnState );
|
||||
|
|
5
client.h
5
client.h
|
@ -91,7 +91,6 @@ class Client
|
|||
|
||||
void releaseWindow( bool on_shutdown = false );
|
||||
void destroyClient();
|
||||
virtual void unrefWindow();
|
||||
|
||||
enum Sizemode // how to resize the window in order to obey constains (mainly aspect ratios)
|
||||
{
|
||||
|
@ -358,7 +357,6 @@ class Client
|
|||
void updateWindowRules();
|
||||
void finishWindowRules();
|
||||
void setShortcutInternal( const KShortcut& cut );
|
||||
void cleanUp();
|
||||
|
||||
void updateWorkareaDiffs();
|
||||
void checkDirection( int new_diff, int old_diff, QRect& rect, const QRect& area );
|
||||
|
@ -387,7 +385,7 @@ class Client
|
|||
|
||||
void embedClient( Window w, const XWindowAttributes &attr );
|
||||
void detectNoBorder();
|
||||
void destroyDecoration( bool force = false );
|
||||
void destroyDecoration();
|
||||
void updateFrameExtents();
|
||||
|
||||
void rawShow(); // just shows it
|
||||
|
@ -432,6 +430,7 @@ class Client
|
|||
ClientList transients_list; // SELI make this ordered in stacking order?
|
||||
ShadeMode shade_mode;
|
||||
uint active :1;
|
||||
uint deleting : 1; // true when doing cleanup and destroying the client
|
||||
uint keep_above : 1; // NET::KeepAbove (was stays_on_top)
|
||||
uint skip_taskbar :1;
|
||||
uint original_skip_taskbar :1; // unaffected by KWin
|
||||
|
|
|
@ -29,6 +29,7 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#include "workspace.h"
|
||||
#include "client.h"
|
||||
#include "unmanaged.h"
|
||||
#include "deleted.h"
|
||||
#include "effects.h"
|
||||
#include "scene.h"
|
||||
#include "scene_basic.h"
|
||||
|
@ -137,13 +138,17 @@ void Workspace::finishCompositing()
|
|||
return;
|
||||
delete cm_selection;
|
||||
foreach( Client* c, clients )
|
||||
scene->windowDeleted( c );
|
||||
scene->windowClosed( c, NULL );
|
||||
foreach( Unmanaged* c, unmanaged )
|
||||
scene->windowClosed( c, NULL );
|
||||
foreach( Deleted* c, deleted )
|
||||
scene->windowDeleted( c );
|
||||
foreach( Client* c, clients )
|
||||
c->finishCompositing();
|
||||
foreach( Unmanaged* c, unmanaged )
|
||||
c->finishCompositing();
|
||||
foreach( Deleted* c, deleted )
|
||||
c->finishCompositing();
|
||||
XCompositeUnredirectSubwindows( display(), rootWindow(), CompositeRedirectManual );
|
||||
compositeTimer.stop();
|
||||
delete effects;
|
||||
|
@ -222,7 +227,7 @@ void Workspace::performCompositing()
|
|||
else if( Unmanaged* c = findUnmanaged( HandleMatchPredicate( children[ i ] )))
|
||||
windows.append( c );
|
||||
}
|
||||
foreach( Toplevel* c, pending_deleted ) // TODO remember stacking order somehow
|
||||
foreach( Deleted* c, deleted ) // TODO remember stacking order somehow
|
||||
windows.append( c );
|
||||
QRegion damage = damage_region;
|
||||
// clear all damage, so that post-pass can add damage for the next repaint
|
||||
|
@ -292,13 +297,12 @@ void Toplevel::setupCompositing()
|
|||
damage_region = QRegion( 0, 0, width(), height());
|
||||
}
|
||||
|
||||
void Toplevel::finishCompositing( bool discard_pixmap )
|
||||
void Toplevel::finishCompositing()
|
||||
{
|
||||
if( damage_handle == None )
|
||||
return;
|
||||
XDamageDestroy( display(), damage_handle );
|
||||
if( discard_pixmap )
|
||||
discardWindowPixmap();
|
||||
discardWindowPixmap();
|
||||
damage_handle = None;
|
||||
damage_region = QRegion();
|
||||
}
|
||||
|
|
10
effects.cpp
10
effects.cpp
|
@ -47,11 +47,11 @@ void Effect::windowAdded( Toplevel* )
|
|||
{
|
||||
}
|
||||
|
||||
void Effect::windowClosed( Toplevel* )
|
||||
void Effect::windowClosed( Toplevel*, Deleted* )
|
||||
{
|
||||
}
|
||||
|
||||
void Effect::windowDeleted( Toplevel* )
|
||||
void Effect::windowDeleted( Deleted* )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -147,16 +147,16 @@ void EffectsHandler::windowAdded( Toplevel* c )
|
|||
e->windowAdded( c );
|
||||
}
|
||||
|
||||
void EffectsHandler::windowDeleted( Toplevel* c )
|
||||
void EffectsHandler::windowDeleted( Deleted* c )
|
||||
{
|
||||
foreach( Effect* e, effects )
|
||||
e->windowDeleted( c );
|
||||
}
|
||||
|
||||
void EffectsHandler::windowClosed( Toplevel* c )
|
||||
void EffectsHandler::windowClosed( Toplevel* c, Deleted* deleted )
|
||||
{
|
||||
foreach( Effect* e, effects )
|
||||
e->windowClosed( c );
|
||||
e->windowClosed( c, deleted );
|
||||
}
|
||||
|
||||
void EffectsHandler::windowActivated( Toplevel* c )
|
||||
|
|
|
@ -73,8 +73,8 @@ class Effect
|
|||
// called when moved/resized or once after it's finished
|
||||
virtual void windowUserMovedResized( Toplevel* c, bool first, bool last );
|
||||
virtual void windowAdded( Toplevel* c );
|
||||
virtual void windowDeleted( Toplevel* c );
|
||||
virtual void windowClosed( Toplevel* c );
|
||||
virtual void windowClosed( Toplevel* c, Deleted* deleted );
|
||||
virtual void windowDeleted( Deleted* c );
|
||||
virtual void windowActivated( Toplevel* c );
|
||||
virtual void windowMinimized( Toplevel* c );
|
||||
virtual void windowUnminimized( Toplevel* c );
|
||||
|
@ -111,8 +111,8 @@ class EffectsHandler
|
|||
void startPaint();
|
||||
void windowUserMovedResized( Toplevel* c, bool first, bool last );
|
||||
void windowAdded( Toplevel* c );
|
||||
void windowClosed( Toplevel* c );
|
||||
void windowDeleted( Toplevel* c );
|
||||
void windowClosed( Toplevel* c, Deleted* deleted );
|
||||
void windowDeleted( Deleted* c );
|
||||
void windowActivated( Toplevel* c );
|
||||
void windowMinimized( Toplevel* c );
|
||||
void windowUnminimized( Toplevel* c );
|
||||
|
|
|
@ -84,7 +84,7 @@ void DialogParentEffect::windowActivated( Toplevel* t )
|
|||
}
|
||||
}
|
||||
|
||||
void DialogParentEffect::windowDeleted( Toplevel* t )
|
||||
void DialogParentEffect::windowClosed( Toplevel* t, Deleted* )
|
||||
{
|
||||
// If this window is a dialog, we need to damage it's parent window, so
|
||||
// that the effect could be run for it
|
||||
|
|
|
@ -32,7 +32,7 @@ class DialogParentEffect
|
|||
virtual void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void postPaintWindow( Scene::Window* w );
|
||||
|
||||
virtual void windowDeleted( Toplevel* c );
|
||||
virtual void windowClosed( Toplevel* c, Deleted* );
|
||||
virtual void windowActivated( Toplevel* c );
|
||||
|
||||
protected:
|
||||
|
|
|
@ -57,7 +57,7 @@ void FadeInEffect::windowAdded( Toplevel* c )
|
|||
}
|
||||
}
|
||||
|
||||
void FadeInEffect::windowDeleted( Toplevel* c )
|
||||
void FadeInEffect::windowClosed( Toplevel* c, Deleted* )
|
||||
{
|
||||
windows.remove( c );
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ class FadeInEffect
|
|||
virtual void postPaintWindow( Scene::Window* w );
|
||||
// TODO react also on virtual desktop changes
|
||||
virtual void windowAdded( Toplevel* c );
|
||||
virtual void windowDeleted( Toplevel* c );
|
||||
virtual void windowClosed( Toplevel* c, Deleted* );
|
||||
private:
|
||||
QMap< const Toplevel*, double > windows;
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#include "fadeout.h"
|
||||
|
||||
#include <client.h>
|
||||
#include <deleted.h>
|
||||
|
||||
namespace KWinInternal
|
||||
{
|
||||
|
@ -28,7 +29,7 @@ void FadeOutEffect::prePaintWindow( Scene::Window* w, int* mask, QRegion* region
|
|||
else
|
||||
{
|
||||
windows.remove( w->window());
|
||||
w->window()->unrefWindow();
|
||||
static_cast< Deleted* >( w->window())->unrefWindow();
|
||||
}
|
||||
}
|
||||
effects->prePaintWindow( w, mask, region, time );
|
||||
|
@ -50,18 +51,18 @@ void FadeOutEffect::postPaintWindow( Scene::Window* w )
|
|||
effects->postPaintWindow( w );
|
||||
}
|
||||
|
||||
void FadeOutEffect::windowClosed( Toplevel* c )
|
||||
void FadeOutEffect::windowClosed( Toplevel* c, Deleted* d )
|
||||
{
|
||||
Client* cc = dynamic_cast< Client* >( c );
|
||||
if( cc == NULL || cc->isOnCurrentDesktop())
|
||||
{
|
||||
windows[ c ] = 1; // count down to 0
|
||||
c->addDamageFull();
|
||||
c->refWindow();
|
||||
windows[ d ] = 1; // count down to 0
|
||||
d->addDamageFull();
|
||||
d->refWindow();
|
||||
}
|
||||
}
|
||||
|
||||
void FadeOutEffect::windowDeleted( Toplevel* c )
|
||||
void FadeOutEffect::windowDeleted( Deleted* c )
|
||||
{
|
||||
windows.remove( c );
|
||||
}
|
||||
|
|
|
@ -26,8 +26,8 @@ class FadeOutEffect
|
|||
virtual void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void postPaintWindow( Scene::Window* w );
|
||||
// TODO react also on virtual desktop changes
|
||||
virtual void windowClosed( Toplevel* c );
|
||||
virtual void windowDeleted( Toplevel* c );
|
||||
virtual void windowClosed( Toplevel* c, Deleted* d );
|
||||
virtual void windowDeleted( Deleted* c );
|
||||
private:
|
||||
QMap< const Toplevel*, double > windows;
|
||||
};
|
||||
|
|
|
@ -20,6 +20,7 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
// Include the class definition.
|
||||
#include "howto.h"
|
||||
|
||||
#include "deleted.h"
|
||||
|
||||
// Note that currently effects need to be manually enabled in the EffectsHandler
|
||||
// class constructor (in effects.cpp).
|
||||
|
@ -137,8 +138,15 @@ void HowtoEffect::windowActivated( Toplevel* c )
|
|||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
void HowtoEffect::windowClosed( Toplevel* c, Deleted* d )
|
||||
{
|
||||
if( fade_window == c )
|
||||
fade_window = d;
|
||||
}
|
||||
|
||||
// This function is called when a window is destroyed.
|
||||
void HowtoEffect::windowDeleted( Toplevel* c )
|
||||
void HowtoEffect::windowDeleted( Deleted* c )
|
||||
{
|
||||
// If the window to be faded out and in is destroyed, just reset the pointer.
|
||||
// This effect then will do nothing and just call the next effect.
|
||||
|
|
|
@ -51,8 +51,11 @@ class HowtoEffect
|
|||
// Notification functions: These inform the effect about changes such as a new window
|
||||
// being activated.
|
||||
|
||||
// TODO
|
||||
virtual void windowClosed( Toplevel* c, Deleted* d );
|
||||
|
||||
// The given window has been deleted (destroyed).
|
||||
virtual void windowDeleted( Toplevel* c );
|
||||
virtual void windowDeleted( Deleted* c );
|
||||
|
||||
// The given window has been activated.
|
||||
virtual void windowActivated( Toplevel* c );
|
||||
|
|
|
@ -131,7 +131,7 @@ void PresentWindowsEffect::windowActivated( Toplevel* t )
|
|||
rearrangeWindows();
|
||||
}
|
||||
|
||||
void PresentWindowsEffect::windowDeleted( Toplevel* t )
|
||||
void PresentWindowsEffect::windowClosed( Toplevel* t, Deleted* )
|
||||
{
|
||||
rearrangeWindows();
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ class PresentWindowsEffect
|
|||
virtual void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void postPaintScreen();
|
||||
|
||||
virtual void windowDeleted( Toplevel* c );
|
||||
virtual void windowClosed( Toplevel* c, Deleted* );
|
||||
virtual void windowActivated( Toplevel* c );
|
||||
virtual void windowInputMouseEvent( Window w, QEvent* e );
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ void ScaleInEffect::windowAdded( Toplevel* c )
|
|||
}
|
||||
}
|
||||
|
||||
void ScaleInEffect::windowDeleted( Toplevel* c )
|
||||
void ScaleInEffect::windowClosed( Toplevel* c, Deleted* )
|
||||
{
|
||||
windows.remove( c );
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ class ScaleInEffect
|
|||
virtual void postPaintWindow( Scene::Window* w );
|
||||
// TODO react also on virtual desktop changes
|
||||
virtual void windowAdded( Toplevel* c );
|
||||
virtual void windowDeleted( Toplevel* c );
|
||||
virtual void windowClosed( Toplevel* c, Deleted* );
|
||||
private:
|
||||
QMap< const Toplevel*, double > windows;
|
||||
};
|
||||
|
|
|
@ -62,7 +62,7 @@ void ShakyMoveEffect::windowUserMovedResized( Toplevel* c, bool first, bool last
|
|||
}
|
||||
}
|
||||
|
||||
void ShakyMoveEffect::windowDeleted( Toplevel* c )
|
||||
void ShakyMoveEffect::windowClosed( Toplevel* c, Deleted* )
|
||||
{
|
||||
windows.remove( c );
|
||||
if( windows.isEmpty())
|
||||
|
|
|
@ -30,7 +30,7 @@ class ShakyMoveEffect
|
|||
virtual void prePaintScreen( int* mask, QRegion* region, int time );
|
||||
virtual void prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time );
|
||||
virtual void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void windowDeleted( Toplevel* c );
|
||||
virtual void windowClosed( Toplevel* c, Deleted* );
|
||||
private slots:
|
||||
void tick();
|
||||
private:
|
||||
|
|
|
@ -64,6 +64,7 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#include <X11/extensions/shape.h>
|
||||
|
||||
#include "client.h"
|
||||
#include "deleted.h"
|
||||
#include "effects.h"
|
||||
|
||||
namespace KWinInternal
|
||||
|
@ -290,7 +291,7 @@ QRegion Scene::Window::shape() const
|
|||
|
||||
bool Scene::Window::isVisible() const
|
||||
{
|
||||
if( toplevel->deleting())
|
||||
if( dynamic_cast< Deleted* >( toplevel ) != NULL )
|
||||
return false;
|
||||
if( Client* c = dynamic_cast< Client* >( toplevel ))
|
||||
return c->isShown( true ) && c->isOnCurrentDesktop();
|
||||
|
|
12
scene.h
12
scene.h
|
@ -20,6 +20,7 @@ namespace KWinInternal
|
|||
{
|
||||
|
||||
class Workspace;
|
||||
class Deleted;
|
||||
class WindowPaintData;
|
||||
class ScreenPaintData;
|
||||
|
||||
|
@ -43,8 +44,10 @@ class Scene
|
|||
virtual void windowOpacityChanged( Toplevel* ) = 0;
|
||||
// a new window has been created
|
||||
virtual void windowAdded( Toplevel* ) = 0;
|
||||
// a window has been closed
|
||||
virtual void windowClosed( Toplevel*, Deleted* ) = 0;
|
||||
// a window has been destroyed
|
||||
virtual void windowDeleted( Toplevel* ) = 0;
|
||||
virtual void windowDeleted( Deleted* ) = 0;
|
||||
// Flags controlling how painting is done.
|
||||
enum
|
||||
{
|
||||
|
@ -128,6 +131,7 @@ class Scene::Window
|
|||
// shape of the window
|
||||
QRegion shape() const;
|
||||
void discardShape();
|
||||
void updateToplevel( Toplevel* c );
|
||||
Window() {} // QMap sucks even in Qt4
|
||||
protected:
|
||||
Toplevel* toplevel;
|
||||
|
@ -174,6 +178,12 @@ Toplevel* Scene::Window::window()
|
|||
return toplevel;
|
||||
}
|
||||
|
||||
inline
|
||||
void Scene::Window::updateToplevel( Toplevel* c )
|
||||
{
|
||||
toplevel = c;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
|
|
@ -77,7 +77,11 @@ void SceneBasic::windowAdded( Toplevel* )
|
|||
{
|
||||
}
|
||||
|
||||
void SceneBasic::windowDeleted( Toplevel* )
|
||||
void SceneBasic::windowClosed( Toplevel*, Deleted* )
|
||||
{
|
||||
}
|
||||
|
||||
void SceneBasic::windowDeleted( Deleted* )
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,8 @@ class SceneBasic
|
|||
virtual void windowGeometryShapeChanged( Toplevel* );
|
||||
virtual void windowOpacityChanged( Toplevel* );
|
||||
virtual void windowAdded( Toplevel* );
|
||||
virtual void windowDeleted( Toplevel* );
|
||||
virtual void windowClosed( Toplevel*, Deleted* );
|
||||
virtual void windowDeleted( Deleted* );
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -59,6 +59,7 @@ Sources and other compositing managers:
|
|||
|
||||
#include "utils.h"
|
||||
#include "client.h"
|
||||
#include "deleted.h"
|
||||
#include "effects.h"
|
||||
#include "glutils.h"
|
||||
|
||||
|
@ -565,7 +566,24 @@ void SceneOpenGL::windowAdded( Toplevel* c )
|
|||
windows[ c ] = Window( c );
|
||||
}
|
||||
|
||||
void SceneOpenGL::windowDeleted( Toplevel* c )
|
||||
void SceneOpenGL::windowClosed( Toplevel* c, Deleted* deleted )
|
||||
{
|
||||
assert( windows.contains( c ));
|
||||
if( deleted != NULL )
|
||||
{ // replace c with deleted
|
||||
Window& w = windows[ c ];
|
||||
w.updateToplevel( deleted );
|
||||
windows[ deleted ] = w;
|
||||
windows.remove( c );
|
||||
}
|
||||
else
|
||||
{
|
||||
windows[ c ].free();
|
||||
windows.remove( c );
|
||||
}
|
||||
}
|
||||
|
||||
void SceneOpenGL::windowDeleted( Deleted* c )
|
||||
{
|
||||
assert( windows.contains( c ));
|
||||
windows[ c ].free();
|
||||
|
|
|
@ -31,7 +31,8 @@ class SceneOpenGL
|
|||
virtual void windowGeometryShapeChanged( Toplevel* );
|
||||
virtual void windowOpacityChanged( Toplevel* );
|
||||
virtual void windowAdded( Toplevel* );
|
||||
virtual void windowDeleted( Toplevel* );
|
||||
virtual void windowClosed( Toplevel*, Deleted* );
|
||||
virtual void windowDeleted( Deleted* );
|
||||
protected:
|
||||
virtual void paintGenericScreen( int mask, ScreenPaintData data );
|
||||
virtual void paintBackground( QRegion region );
|
||||
|
|
|
@ -33,6 +33,7 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
|
||||
#include "toplevel.h"
|
||||
#include "client.h"
|
||||
#include "deleted.h"
|
||||
#include "effects.h"
|
||||
|
||||
namespace KWinInternal
|
||||
|
@ -230,7 +231,24 @@ void SceneXrender::windowOpacityChanged( Toplevel* c )
|
|||
w.discardAlpha();
|
||||
}
|
||||
|
||||
void SceneXrender::windowDeleted( Toplevel* c )
|
||||
void SceneXrender::windowClosed( Toplevel* c, Deleted* deleted )
|
||||
{
|
||||
assert( windows.contains( c ));
|
||||
if( deleted != NULL )
|
||||
{ // replace c with deleted
|
||||
Window& w = windows[ c ];
|
||||
w.updateToplevel( deleted );
|
||||
windows[ deleted ] = w;
|
||||
windows.remove( c );
|
||||
}
|
||||
else
|
||||
{
|
||||
windows[ c ].free();
|
||||
windows.remove( c );
|
||||
}
|
||||
}
|
||||
|
||||
void SceneXrender::windowDeleted( Deleted* c )
|
||||
{
|
||||
assert( windows.contains( c ));
|
||||
windows[ c ].free();
|
||||
|
|
|
@ -33,7 +33,8 @@ class SceneXrender
|
|||
virtual void windowGeometryShapeChanged( Toplevel* );
|
||||
virtual void windowOpacityChanged( Toplevel* );
|
||||
virtual void windowAdded( Toplevel* );
|
||||
virtual void windowDeleted( Toplevel* );
|
||||
virtual void windowClosed( Toplevel*, Deleted* );
|
||||
virtual void windowDeleted( Deleted* );
|
||||
Picture bufferPicture();
|
||||
protected:
|
||||
virtual void paintBackground( QRegion region );
|
||||
|
|
16
toplevel.cpp
16
toplevel.cpp
|
@ -15,7 +15,6 @@ namespace KWinInternal
|
|||
|
||||
Toplevel::Toplevel( Workspace* ws )
|
||||
: vis( None )
|
||||
, delete_refcount( -1 )
|
||||
, id( None )
|
||||
, wspace( ws )
|
||||
, window_pix( None )
|
||||
|
@ -79,6 +78,21 @@ void Toplevel::detectShape( Window id )
|
|||
is_shape = Extensions::hasShape( id );
|
||||
}
|
||||
|
||||
// used only by Deleted::copy()
|
||||
void Toplevel::copyToDeleted( Toplevel* c )
|
||||
{
|
||||
geom = c->geom;
|
||||
vis = c->vis;
|
||||
bit_depth = c->bit_depth;
|
||||
id = c->id;
|
||||
wspace = c->wspace;
|
||||
window_pix = c->window_pix;
|
||||
c->window_pix = None;
|
||||
damage_handle = None;
|
||||
damage_region = c->damage_region;
|
||||
is_shape = c->is_shape;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "toplevel.moc"
|
||||
|
|
21
toplevel.h
21
toplevel.h
|
@ -59,18 +59,13 @@ class Toplevel
|
|||
int depth() const;
|
||||
bool hasAlpha() const;
|
||||
void setupCompositing();
|
||||
void finishCompositing( bool discard_pixmap = true );
|
||||
void finishCompositing();
|
||||
void addDamage( const QRect& r );
|
||||
void addDamage( int x, int y, int w, int h );
|
||||
void addDamageFull();
|
||||
QRegion damage() const;
|
||||
void resetDamage( const QRect& r );
|
||||
|
||||
// used by effects to keep the window around for e.g. fadeout effects when it's destroyed
|
||||
void refWindow();
|
||||
virtual void unrefWindow() = 0;
|
||||
bool deleting() const;
|
||||
|
||||
protected:
|
||||
virtual ~Toplevel();
|
||||
void setHandle( Window id );
|
||||
|
@ -81,10 +76,11 @@ class Toplevel
|
|||
QRect geom;
|
||||
Visual* vis;
|
||||
int bit_depth;
|
||||
int delete_refcount;
|
||||
virtual void debug( kdbgstream& stream ) const = 0;
|
||||
void copyToDeleted( Toplevel* c );
|
||||
friend kdbgstream& operator<<( kdbgstream& stream, const Toplevel* );
|
||||
private:
|
||||
// when adding new data members, check also copyToDeleted()
|
||||
Window id;
|
||||
Workspace* wspace;
|
||||
Pixmap window_pix;
|
||||
|
@ -226,17 +222,6 @@ inline bool Toplevel::hasAlpha() const
|
|||
return depth() == 32;
|
||||
}
|
||||
|
||||
inline void Toplevel::refWindow()
|
||||
{
|
||||
assert( delete_refcount >= 0 );
|
||||
++delete_refcount;
|
||||
}
|
||||
|
||||
inline bool Toplevel::deleting() const
|
||||
{
|
||||
return delete_refcount >= 0;
|
||||
}
|
||||
|
||||
#ifdef NDEBUG
|
||||
inline
|
||||
kndbgstream& operator<<( kndbgstream& stream, const Toplevel* ) { return stream; }
|
||||
|
|
|
@ -12,6 +12,7 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
|
||||
#include "workspace.h"
|
||||
#include "effects.h"
|
||||
#include "deleted.h"
|
||||
|
||||
#include <X11/extensions/shape.h>
|
||||
|
||||
|
@ -70,24 +71,18 @@ bool Unmanaged::track( Window w )
|
|||
|
||||
void Unmanaged::release()
|
||||
{
|
||||
assert( !deleting());
|
||||
delete_refcount = 1;
|
||||
if( effects )
|
||||
effects->windowClosed( this );
|
||||
finishCompositing( false ); // don't discard pixmap
|
||||
{
|
||||
Deleted* del = Deleted::create( this );
|
||||
effects->windowClosed( this, del );
|
||||
scene->windowClosed( this, del );
|
||||
del->unrefWindow();
|
||||
}
|
||||
finishCompositing();
|
||||
workspace()->removeUnmanaged( this, Allowed );
|
||||
if( Extensions::shapeAvailable())
|
||||
XShapeSelectInput( display(), handle(), NoEventMask );
|
||||
XSelectInput( display(), handle(), NoEventMask );
|
||||
unrefWindow(); // will delete if recount is == 0
|
||||
}
|
||||
|
||||
void Unmanaged::unrefWindow()
|
||||
{
|
||||
if( --delete_refcount > 0 )
|
||||
return;
|
||||
discardWindowPixmap();
|
||||
workspace()->removeDeleted( this );
|
||||
workspace()->addDamage( geometry());
|
||||
deleteUnmanaged( this, Allowed );
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ class Unmanaged
|
|||
virtual NET::WindowType windowType( bool direct = false, int supported_types = SUPPORTED_WINDOW_TYPES_MASK ) const;
|
||||
static void deleteUnmanaged( Unmanaged* c, allowed_t );
|
||||
virtual double opacity() const;
|
||||
virtual void unrefWindow();
|
||||
protected:
|
||||
virtual void debug( kdbgstream& stream ) const;
|
||||
private:
|
||||
|
|
3
utils.h
3
utils.h
|
@ -75,6 +75,7 @@ const QPoint invalidPoint( INT_MIN, INT_MIN );
|
|||
class Toplevel;
|
||||
class Client;
|
||||
class Unmanaged;
|
||||
class Deleted;
|
||||
class Group;
|
||||
class Options;
|
||||
|
||||
|
@ -84,6 +85,8 @@ typedef QList< Client* > ClientList;
|
|||
typedef QList< const Client* > ConstClientList;
|
||||
typedef QList< Unmanaged* > UnmanagedList;
|
||||
typedef QList< const Unmanaged* > ConstUnmanagedList;
|
||||
typedef QList< Deleted* > DeletedList;
|
||||
typedef QList< const Deleted* > ConstDeletedList;
|
||||
|
||||
typedef QList< Group* > GroupList;
|
||||
typedef QList< const Group* > ConstGroupList;
|
||||
|
|
|
@ -616,31 +616,28 @@ void Workspace::removeClient( Client* c, allowed_t )
|
|||
tab_box->repaint();
|
||||
|
||||
updateClientArea();
|
||||
|
||||
addDeleted( c, Allowed );
|
||||
}
|
||||
|
||||
void Workspace::removeUnmanaged( Unmanaged* c, allowed_t )
|
||||
{
|
||||
assert( unmanaged.contains( c ));
|
||||
unmanaged.removeAll( c );
|
||||
addDeleted( c, Allowed );
|
||||
}
|
||||
|
||||
void Workspace::addDeleted( Toplevel* c, allowed_t )
|
||||
void Workspace::addDeleted( Deleted* c, allowed_t )
|
||||
{
|
||||
assert( !pending_deleted.contains( c ));
|
||||
pending_deleted.append( c );
|
||||
assert( !deleted.contains( c ));
|
||||
deleted.append( c );
|
||||
}
|
||||
|
||||
void Workspace::removeDeleted( Toplevel* c )
|
||||
void Workspace::removeDeleted( Deleted* c, allowed_t )
|
||||
{
|
||||
assert( pending_deleted.contains( c ));
|
||||
assert( deleted.contains( c ));
|
||||
if( scene )
|
||||
scene->windowDeleted( c );
|
||||
if( effects )
|
||||
effects->windowDeleted( c );
|
||||
pending_deleted.removeAll( c );
|
||||
deleted.removeAll( c );
|
||||
}
|
||||
|
||||
void Workspace::updateFocusChains( Client* c, FocusChainChange change )
|
||||
|
|
|
@ -247,8 +247,8 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
Group* findClientLeaderGroup( const Client* c ) const;
|
||||
|
||||
void removeUnmanaged( Unmanaged*, allowed_t ); // only called from Unmanaged::release()
|
||||
void removeDeleted( Toplevel* );
|
||||
void addDeleted( Toplevel*, allowed_t );
|
||||
void removeDeleted( Deleted*, allowed_t );
|
||||
void addDeleted( Deleted*, allowed_t );
|
||||
|
||||
bool checkStartupNotification( Window w, KStartupInfoId& id, KStartupInfoData& data );
|
||||
|
||||
|
@ -558,7 +558,7 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
ClientList clients;
|
||||
ClientList desktops;
|
||||
UnmanagedList unmanaged;
|
||||
ToplevelList pending_deleted;
|
||||
DeletedList deleted;
|
||||
|
||||
ClientList unconstrained_stacking_order;
|
||||
ClientList stacking_order;
|
||||
|
|
Loading…
Reference in a new issue