diff --git a/COMPOSITE_TODO b/COMPOSITE_TODO index c6d06a7e98..314486b54e 100644 --- a/COMPOSITE_TODO +++ b/COMPOSITE_TODO @@ -49,10 +49,6 @@ General TODO ! - scene_xrender.cpp also requires XFixes ! - check whether it compiles fine without XComposite/XDamage -! the opacity slider in the Alt+F3 menu doesn't work - - looks like the hack with adding custom widgets to popups no longer works - - it should probably be just changed to normal menu with reasonable opacity values - ? Expose events for overlay window - is it necessary to track it, like with root window? diff --git a/useractions.cpp b/useractions.cpp index 44b59b4434..46e00e148b 100644 --- a/useractions.cpp +++ b/useractions.cpp @@ -101,22 +101,18 @@ QMenu* Workspace::clientPopup() desk_popup_index = popup->actions().count(); if (options->useTranslucency){ - QMenu *trans_popup = new QMenu( popup ); - QVBoxLayout *transLayout = new QVBoxLayout(trans_popup); - trans_popup->setLayout( transLayout ); - transButton = new QPushButton(trans_popup); - transButton->setObjectName("transButton"); - transButton->setToolTip( i18n("Reset opacity to default value")); - transSlider = new QSlider(trans_popup); - transSlider->setObjectName( "transSlider" ); - transSlider->setRange( 0, 100 ); - transSlider->setValue( 100 ); - transSlider->setOrientation( Qt::Vertical ); - transSlider->setToolTip( i18n("Slide this to set the window's opacity")); - connect(transButton, SIGNAL(clicked()), SLOT(resetClientOpacity())); - connect(transButton, SIGNAL(clicked()), trans_popup, SLOT(hide())); - connect(transSlider, SIGNAL(valueChanged(int)), SLOT(setTransButtonText(int))); - connect(transSlider, SIGNAL(valueChanged(int)), this, SLOT(setPopupClientOpacity(int))); + trans_popup = new QMenu( popup ); + trans_popup->setFont(KGlobalSettings::menuFont()); + connect( trans_popup, SIGNAL( triggered(QAction*) ), this, SLOT( setPopupClientOpacity(QAction*))); + const int levels[] = { 100, 90, 75, 50, 25, 10 }; + for( unsigned int i = 0; + i < sizeof( levels ) / sizeof( levels[ 0 ] ); + ++i ) + { + action = trans_popup->addAction( QString::number( levels[ i ] ) + "%" ); + action->setCheckable( true ); + action->setData( levels[ i ] ); + } action = popup->addMenu( trans_popup ); action->setText( i18n("&Opacity") ); } @@ -163,34 +159,14 @@ QMenu* Workspace::clientPopup() return popup; } -void Workspace::setPopupClientOpacity(int value) +void Workspace::setPopupClientOpacity( QAction* action ) { if( active_popup_client == NULL ) return; - active_popup_client->setOpacity( value / 100.0 ); + int level = action->data().toInt(); + active_popup_client->setOpacity( level / 100.0 ); } -void Workspace::resetClientOpacity() - { - if( active_popup_client == NULL ) - return; - active_popup_client->setOpacity( 1.0 ); - } - -void Workspace::setTransButtonText(int value) - { - value = 100 - value; - if(value < 0) - transButton->setText("000 %"); - else if (value >= 100 ) - transButton->setText("100 %"); - else if(value < 10) - transButton->setText("00"+QString::number(value)+" %"); - else if(value < 100) - transButton->setText('0'+QString::number(value)+" %"); - } - - /*! The client popup menu will become visible soon. @@ -225,6 +201,16 @@ void Workspace::clientPopupAboutToShow() mNoBorderOpAction->setChecked( active_popup_client->noBorder() ); mMinimizeOpAction->setEnabled( active_popup_client->isMinimizable() ); mCloseOpAction->setEnabled( active_popup_client->isCloseable() ); + if (options->useTranslucency) + { + foreach( QAction* action, trans_popup->actions()) + { + if( action->data().toInt() == qRound( active_popup_client->opacity() * 100 )) + action->setChecked( true ); + else + action->setChecked( false ); + } + } } diff --git a/workspace.cpp b/workspace.cpp index 537aee11e0..9abe76df15 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -96,6 +96,7 @@ Workspace::Workspace( bool restore ) popupinfo (0), popup (0), advanced_popup (0), + trans_popup (0), desk_popup (0), desk_popup_index (0), keys (0), diff --git a/workspace.h b/workspace.h index e5f64da0c3..e5e91e354a 100644 --- a/workspace.h +++ b/workspace.h @@ -18,6 +18,8 @@ License. See the file "COPYING" for the exact licensing terms. #include #include #include +#include +#include #include "utils.h" #include "kdecoration.h" @@ -77,7 +79,7 @@ class Workspace : public QObject, public KDecorationDefines virtual ~Workspace(); static Workspace * self() { return _self; } - + bool workspaceEvent( XEvent * ); KDecoration* createDecoration( KDecorationBridge* bridge ); @@ -87,6 +89,9 @@ class Workspace : public QObject, public KDecorationDefines template< typename T > Client* findClient( T predicate ); template< typename T1, typename T2 > void forEachClient( T1 procedure, T2 predicate ); template< typename T > void forEachClient( T procedure ); + template< typename T > Unmanaged* findUnmanaged( T predicate ); + template< typename T1, typename T2 > void forEachUnmanaged( T1 procedure, T2 predicate ); + template< typename T > void forEachUnmanaged( T procedure ); QRect clientArea( clientAreaOption, const QPoint& p, int desktop ) const; QRect clientArea( clientAreaOption, const Client* c ) const; @@ -181,7 +186,7 @@ class Workspace : public QObject, public KDecorationDefines ClientList ensureStackingOrder( const ClientList& clients ) const; - Client* topClientOnDesktop( int desktop, bool unconstrained = false, bool only_normal = true ) const; + Client* topClientOnDesktop( int desktop, bool unconstrained = false ) const; Client* findDesktop( bool topmost, int desktop ) const; void sendClientToDesktop( Client* c, int desktop, bool dont_activate ); void windowToPreviousDesktop( Client* c ); @@ -242,6 +247,9 @@ class Workspace : public QObject, public KDecorationDefines void removeGroup( Group* group, allowed_t ); Group* findClientLeaderGroup( const Client* c ) const; + // only called from Unmanaged::release() + void removeUnmanaged( Unmanaged*, allowed_t ); + bool checkStartupNotification( Window w, KStartupInfoId& id, KStartupInfoData& data ); void focusToNull(); // SELI public? @@ -276,6 +284,17 @@ class Workspace : public QObject, public KDecorationDefines void requestDelayFocus( Client* ); void toggleTopDockShadows(bool on); + + void addDamage( const QRect& r ); + void addDamage( int x, int y, int w, int h ); + void addDamageFull(); + // creates XComposite overlay window, cal initOverlay() afterwards + bool createOverlay(); + // init overlay and the destination window in it + void setupOverlay( Window window ); + // destroys XComposite overlay window + void destroyOverlay(); + Window overlayWindow(); public slots: void refresh(); @@ -406,11 +425,9 @@ class Workspace : public QObject, public KDecorationDefines void cleanupTemporaryRules(); void writeWindowRules(); void slotBlockShortcuts(int data); - // kompmgr - void setPopupClientOpacity(int v); - void resetClientOpacity(); - void setTransButtonText(int value); - // end + void setPopupClientOpacity( QAction* action ); + void performCompositing(); + void lostCMSelection(); protected: bool keyPressMouseEmulation( XKeyEvent& ev ); @@ -458,6 +475,8 @@ class Workspace : public QObject, public KDecorationDefines // this is the right way to create a new client Client* createClient( Window w, bool is_mapped ); void addClient( Client* c, allowed_t ); + Unmanaged* createUnmanaged( Window w ); + void addUnmanaged( Unmanaged* c, allowed_t ); Window findSpecialEventWindow( XEvent* e ); @@ -499,6 +518,9 @@ class Workspace : public QObject, public KDecorationDefines void closeActivePopup(); void updateClientArea( bool force ); + + void setupCompositing(); + void finishCompositing(); SystemTrayWindowList systemTrayWins; @@ -535,10 +557,11 @@ class Workspace : public QObject, public KDecorationDefines ClientList clients; ClientList desktops; + UnmanagedList unmanaged; - ClientList unconstrained_stacking_order; // topmost last - ClientList stacking_order; // topmost last - QVector< ClientList > focus_chain; // currently ative last + ClientList unconstrained_stacking_order; + ClientList stacking_order; + QVector< ClientList > focus_chain; ClientList global_focus_chain; // this one is only for things like tabbox's MRU ClientList should_get_focus; // last is most recent ClientList attention_chain; @@ -572,6 +595,7 @@ class Workspace : public QObject, public KDecorationDefines QMenu *popup; QMenu *advanced_popup; + QMenu *trans_popup; QMenu *desk_popup; int desk_popup_index; @@ -655,7 +679,11 @@ class Workspace : public QObject, public KDecorationDefines bool forced_global_mouse_grab; friend class StackingUpdatesBlocker; - //kompmgr + KSelectionOwner* cm_selection; + QTimer compositeTimer; + QTime lastCompositePaint; + QRegion damage_region; + Window overlay; // XComposite overlay window QSlider *transSlider; QPushButton *transButton; }; @@ -800,6 +828,11 @@ inline bool Workspace::globalShortcutsDisabled() const return global_shortcuts_disabled || global_shortcuts_disabled_for_client; } +inline Window Workspace::overlayWindow() + { + return overlay; + } + template< typename T > inline Client* Workspace::findClient( T predicate ) { @@ -827,7 +860,27 @@ inline void Workspace::forEachClient( T procedure ) return forEachClient( procedure, TruePredicate()); } -KWIN_COMPARE_PREDICATE( ClientMatchPredicate, const Client*, cl == value ); +template< typename T > +inline Unmanaged* Workspace::findUnmanaged( T predicate ) + { + return findUnmanagedInList( unmanaged, predicate ); + } + +template< typename T1, typename T2 > +inline void Workspace::forEachUnmanaged( T1 procedure, T2 predicate ) + { + for ( UnmanagedList::ConstIterator it = unmanaged.begin(); it != unmanaged.end(); ++it) + if ( predicate( const_cast< const Unmanaged* >( *it))) + procedure( *it ); + } + +template< typename T > +inline void Workspace::forEachUnmanaged( T procedure ) + { + return forEachUnmanaged( procedure, TruePredicate()); + } + +KWIN_COMPARE_PREDICATE( ClientMatchPredicate, Client, const Client*, cl == value ); inline bool Workspace::hasClient( const Client* c ) { return findClient( ClientMatchPredicate( c ));