diff --git a/composite.cpp b/composite.cpp index 2906f21f0d..c410052131 100644 --- a/composite.cpp +++ b/composite.cpp @@ -35,6 +35,10 @@ License. See the file "COPYING" for the exact licensing terms. #include "scene_xrender.h" #include "scene_opengl.h" +#include + +#include + #include namespace KWinInternal @@ -53,6 +57,11 @@ void Workspace::setupCompositing() return; if( scene != NULL ) return; + char selection_name[ 100 ]; + sprintf( selection_name, "_NET_WM_CM_S%d", DefaultScreen( display())); + cm_selection = new KSelectionOwner( selection_name ); + connect( cm_selection, SIGNAL( lostOwnership()), SLOT( lostCMSelection())); + cm_selection->claim( true ); // force claiming char type = 'O'; if( getenv( "KWIN_COMPOSE" )) type = getenv( "KWIN_COMPOSE" )[ 0 ]; @@ -98,6 +107,7 @@ void Workspace::finishCompositing() { if( scene == NULL ) return; + delete cm_selection; foreach( Client* c, clients ) scene->windowDeleted( c ); foreach( Unmanaged* c, unmanaged ) @@ -127,6 +137,12 @@ void Workspace::finishCompositing() popup = NULL; } +void Workspace::lostCMSelection() + { + kDebug( 1212 ) << "Lost compositing manager selection" << endl; + finishCompositing(); + } + void Workspace::addDamage( int x, int y, int w, int h ) { if( !compositing()) diff --git a/workspace.cpp b/workspace.cpp index 67860b12d0..537aee11e0 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -42,6 +42,9 @@ License. See the file "COPYING" for the exact licensing terms. #include "group.h" #include "rules.h" #include "kwinadaptor.h" +#include "unmanaged.h" +#include "scene.h" +#include "effects.h" #include #include @@ -122,7 +125,12 @@ Workspace::Workspace( bool restore ) topmenu_space( NULL ), set_active_client_recursion( 0 ), block_stacking_updates( 0 ), - forced_global_mouse_grab( false ) + forced_global_mouse_grab( false ), + cm_selection( NULL ), + damage_region( None ), + overlay( None ), + transSlider( NULL ), + transButton( NULL ) { new KWinAdaptor( "org.kde.kwin", "/KWin", QDBusConnection::sessionBus(), this ); @@ -166,10 +174,12 @@ Workspace::Workspace( bool restore ) ColormapChangeMask | SubstructureRedirectMask | SubstructureNotifyMask | - FocusChangeMask // for NotifyDetailNone + FocusChangeMask | // for NotifyDetailNone + ExposureMask ); - Shape::init(); + Extensions::init(); + setupCompositing(); // compatibility long data = 1; @@ -318,6 +328,7 @@ void Workspace::init() connect(&reconfigureTimer, SIGNAL(timeout()), this, SLOT(slotReconfigure())); connect( &updateToolWindowsTimer, SIGNAL( timeout()), this, SLOT( slotUpdateToolWindows())); + connect( &compositeTimer, SIGNAL( timeout()), SLOT( performCompositing())); connect(KGlobalSettings::self(), SIGNAL(appearanceChanged()), this, SLOT(slotReconfigure())); @@ -355,7 +366,11 @@ void Workspace::init() XWindowAttributes attr; XGetWindowAttributes(display(), wins[i], &attr); if (attr.override_redirect ) + { + if( attr.map_state != IsUnmapped && attr.c_class != InputOnly && compositing()) + createUnmanaged( wins[ i ] ); continue; + } if( topmenu_space && topmenu_space->winId() == wins[ i ] ) continue; if (attr.map_state != IsUnmapped) @@ -418,6 +433,7 @@ void Workspace::init() Workspace::~Workspace() { + finishCompositing(); blockStackingUpdates( true ); // TODO grabXServer(); // use stacking_order, so that kwin --replace keeps stacking order @@ -429,6 +445,10 @@ Workspace::~Workspace() (*it)->releaseWindow( true ); // no removeClient() is called ! } + for( UnmanagedList::ConstIterator it = unmanaged.begin(); + it != unmanaged.end(); + ++it ) + (*it)->release(); delete desktop_widget; delete tab_box; delete popupinfo; @@ -472,6 +492,28 @@ Client* Workspace::createClient( Window w, bool is_mapped ) return NULL; } addClient( c, Allowed ); + if( scene ) + scene->windowAdded( c ); + if( effects ) + effects->windowAdded( c ); + return c; + } + +Unmanaged* Workspace::createUnmanaged( Window w ) + { + if( w == overlay ) + return NULL; + Unmanaged* c = new Unmanaged( this ); + if( !c->track( w )) + { + Unmanaged::deleteUnmanaged( c, Allowed ); + return NULL; + } + addUnmanaged( c, Allowed ); + if( scene ) + scene->windowAdded( c ); + if( effects ) + effects->windowAdded( c ); return c; } @@ -514,6 +556,11 @@ void Workspace::addClient( Client* c, allowed_t ) updateToolWindows( true ); } +void Workspace::addUnmanaged( Unmanaged* c, allowed_t ) + { + unmanaged.append( c ); + } + /* Destroys the client \a c */ @@ -533,6 +580,10 @@ void Workspace::removeClient( Client* c, allowed_t ) Notify::raise( Notify::Delete ); Q_ASSERT( clients.contains( c ) || desktops.contains( c )); + if( scene ) + scene->windowDeleted( c ); + if( effects ) + effects->windowDeleted( c ); clients.removeAll( c ); desktops.removeAll( c ); unconstrained_stacking_order.removeAll( c ); @@ -568,6 +619,16 @@ void Workspace::removeClient( Client* c, allowed_t ) updateClientArea(); } +void Workspace::removeUnmanaged( Unmanaged* c, allowed_t ) + { + assert( unmanaged.contains( c )); + if( scene ) + scene->windowDeleted( c ); + if( effects ) + effects->windowDeleted( c ); + unmanaged.removeAll( c ); + } + void Workspace::updateFocusChains( Client* c, FocusChainChange change ) { if( !c->wantsTabFocus()) // doesn't want tab focus, remove @@ -593,13 +654,7 @@ void Workspace::updateFocusChains( Client* c, FocusChainChange change ) focus_chain[ i ].prepend( c ); } else if( !focus_chain[ i ].contains( c )) - { // add it after the active one - if( active_client != NULL && active_client != c - && !focus_chain[ i ].isEmpty() && focus_chain[ i ].last() == active_client ) - focus_chain[ i ].insert( focus_chain[ i ].size() - 1, c ); - else - focus_chain[ i ].append( c ); // otherwise add as the first one - } + focus_chain[ i ].prepend( c ); // otherwise add as the last one } } else //now only on desktop, remove it anywhere else @@ -619,13 +674,7 @@ void Workspace::updateFocusChains( Client* c, FocusChainChange change ) focus_chain[ i ].prepend( c ); } else if( !focus_chain[ i ].contains( c )) - { // add it after the active one - if( active_client != NULL && active_client != c - && !focus_chain[ i ].isEmpty() && focus_chain[ i ].last() == active_client ) - focus_chain[ i ].insert( focus_chain[ i ].size() - 1, c ); - else - focus_chain[ i ].append( c ); // otherwise add as the first one - } + focus_chain[ i ].prepend( c ); } else focus_chain[ i ].removeAll( c ); @@ -642,13 +691,7 @@ void Workspace::updateFocusChains( Client* c, FocusChainChange change ) global_focus_chain.prepend( c ); } else if( !global_focus_chain.contains( c )) - { // add it after the active one - if( active_client != NULL && active_client != c - && !global_focus_chain.isEmpty() && global_focus_chain.last() == active_client ) - global_focus_chain.insert( global_focus_chain.size() - 1, c ); - else - global_focus_chain.append( c ); // otherwise add as the first one - } + global_focus_chain.prepend( c ); } void Workspace::updateCurrentTopMenu() @@ -882,7 +925,7 @@ void Workspace::slotSettingsChanged(int category) /*! Reread settings */ -KWIN_PROCEDURE( CheckBorderSizesProcedure, cl->checkBorderSizes() ); +KWIN_PROCEDURE( CheckBorderSizesProcedure, Client, cl->checkBorderSizes() ); void Workspace::slotReconfigure() { @@ -939,6 +982,11 @@ void Workspace::slotReconfigure() updateTopMenuGeometry(); updateCurrentTopMenu(); } + + if( options->useTranslucency ) + setupCompositing(); + else + finishCompositing(); loadWindowRules(); for( ClientList::Iterator it = clients.begin(); @@ -1640,7 +1688,7 @@ void Workspace::slotGrabWindow() QPixmap snapshot = QPixmap::grabWindow( active_client->frameId() ); //No XShape - no work. - if( Shape::available()) + if( Extensions::shapeAvailable()) { //As the first step, get the mask from XShape. int count, order; @@ -1993,7 +2041,8 @@ void Workspace::createBorderWindows() XSetWindowAttributes attributes; unsigned long valuemask; attributes.override_redirect = True; - attributes.event_mask = ( EnterWindowMask | LeaveWindowMask ); + attributes.event_mask = (EnterWindowMask | LeaveWindowMask | + VisibilityChangeMask); valuemask= (CWOverrideRedirect | CWEventMask | CWCursor ); attributes.cursor = XCreateFontCursor(display(), XC_sb_up_arrow); diff --git a/workspace.h b/workspace.h index 23b5822d01..a79d029799 100644 --- a/workspace.h +++ b/workspace.h @@ -19,6 +19,7 @@ License. See the file "COPYING" for the exact licensing terms. #include #include #include +#include #include "utils.h" #include "kdecoration.h" @@ -428,6 +429,7 @@ class Workspace : public QObject, public KDecorationDefines void resetClientOpacity(); void setTransButtonText(int value); void performCompositing(); + void lostCMSelection(); protected: bool keyPressMouseEmulation( XKeyEvent& ev ); @@ -677,6 +679,8 @@ class Workspace : public QObject, public KDecorationDefines Window null_focus_window; bool forced_global_mouse_grab; friend class StackingUpdatesBlocker; + + KSelectionOwner* cm_selection; QTimer compositeTimer; QTime lastCompositePaint; QRegion damage_region;