diff --git a/effects/highlightwindow/highlightwindow.cpp b/effects/highlightwindow/highlightwindow.cpp index 89d7c48fdd..a7d9b6d1f0 100644 --- a/effects/highlightwindow/highlightwindow.cpp +++ b/effects/highlightwindow/highlightwindow.cpp @@ -129,10 +129,12 @@ void HighlightWindowEffect::windowDeleted( EffectWindow* w ) void HighlightWindowEffect::propertyNotify( EffectWindow* w, long a ) { - if( !w || a != m_atom ) + if( a != m_atom ) return; // Not our atom - QByteArray byteData = w->readProperty( m_atom, m_atom, 32 ); + // if the window is null, the property was set on the root window - see events.cpp + QByteArray byteData = w ? w->readProperty( m_atom, m_atom, 32 ) : + effects->readRootProperty( m_atom, m_atom, 32 ); if( byteData.length() < 1 ) { // Property was removed, clearing highlight finishHighlighting(); @@ -174,7 +176,8 @@ void HighlightWindowEffect::propertyNotify( EffectWindow* w, long a ) return; } prepareHighlighting(); - m_windowOpacity[w] = 1.0; // Because it's not in stackingOrder() yet + if( w ) + m_windowOpacity[w] = 1.0; // Because it's not in stackingOrder() yet /* TODO: Finish thumbnails of offscreen windows, not sure if it's worth it though if( !m_highlightedWindow->isOnCurrentDesktop() ) diff --git a/kcmkwin/kwintabbox/main.ui b/kcmkwin/kwintabbox/main.ui index ddaa03b4bb..d8b1d69ea8 100644 --- a/kcmkwin/kwintabbox/main.ui +++ b/kcmkwin/kwintabbox/main.ui @@ -6,8 +6,8 @@ 0 0 - 490 - 332 + 541 + 305 @@ -19,186 +19,211 @@ - - - General + + + + + List windows: + + + listModeCombo + + + + + + + + 0 + 0 + + + + + Current Desktop + + + + + All Desktops + + + + + Current Desktop Grouped by Applications + + + + + All Desktops Grouped by Applications + + + + + + + + Sort order: + + + switchingModeCombo + + + + + + + + 0 + 0 + + + + + Recently used + + + + + Stacking order + + + + + + + + + + Adds an entry to minimize all windows. + + + Include desktop - - - QFormLayout::ExpandingFieldsGrow - - - - - List windows: - - - listModeCombo - - - - - - - - 0 - 0 - - - - - Current Desktop - - - - - All Desktops - - - - - Current Desktop Grouped by Applications - - - - - All Desktops Grouped by Applications - - - - - - - - Sort order: - - - switchingModeCombo - - - - - - - - 0 - 0 - - - - - Recently used - - - - - Stacking order - - - - - - - - Show outline of selected window - - - - - - - Effect: - - - effectCombo - - - - - - - - - - 0 - 0 - - - - The effect to replace the list window when desktop effects are active. - - - - - - - - 0 - 0 - - - - - - - - - - - - - Adds an entry to minimize all windows. - - - Include desktop - - - - - - - Display list while switching + + + Qt::Horizontal - - true - - - - - - The currently selected window will be highlighted by fading out all other windows. This option requires desktop effects to be active. - - - Highlight selected window - - - - - - - Configure Layout... - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + + The currently selected window will be highlighted by fading out all other windows. This option requires desktop effects to be active. + + + Highlight selected window + + + + + + + Show outline of selected window + + + + + + + + + Effect: + + + effectCombo + + + + + + + + + + 0 + 0 + + + + The effect to replace the list window when desktop effects are active. + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + Qt::Horizontal + + + + + + + + + Display list while switching + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Configure Layout... + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + @@ -238,9 +263,24 @@ effectCombo effectConfigButton effectInfoButton - showTabBox - highlightWindowCheck - + + + showTabBox + toggled(bool) + layoutConfigButton + setEnabled(bool) + + + 81 + 211 + + + 295 + 216 + + + + diff --git a/layers.cpp b/layers.cpp index 50a17843d7..143e79be93 100644 --- a/layers.cpp +++ b/layers.cpp @@ -457,21 +457,14 @@ void Workspace::lowerClientRequest( Client* c, NET::RequestSource src, Time /*ti lowerClientWithinApplication( c ); } -void Workspace::restackClientUnderActive( Client* c ) - { - if( c->isTopMenu()) - return; - if( !active_client || active_client == c ) - { - raiseClient( c ); - return; - } - assert( unconstrained_stacking_order.contains( active_client )); - if( Client::belongToSameApplication( active_client, c )) +void Workspace::restack( Client* c, Client* under ) + { + assert( unconstrained_stacking_order.contains( under )); + if( Client::belongToSameApplication( under, c )) { // put it below the active window if it's the same app unconstrained_stacking_order.removeAll( c ); - unconstrained_stacking_order.insert( unconstrained_stacking_order.indexOf( active_client ), c ); + unconstrained_stacking_order.insert( unconstrained_stacking_order.indexOf( under ), c ); } else { // put in the stacking order below _all_ windows belonging to the active application @@ -479,7 +472,7 @@ void Workspace::restackClientUnderActive( Client* c ) it != unconstrained_stacking_order.end(); ++it ) { // TODO ignore topmenus? - if( Client::belongToSameApplication( active_client, *it )) + if( Client::belongToSameApplication( under, *it )) { if( *it != c ) { @@ -495,12 +488,12 @@ void Workspace::restackClientUnderActive( Client* c ) desktop <= numberOfDesktops(); ++desktop ) { // do for every virtual desktop to handle the case of onalldesktop windows - if( c->wantsTabFocus() && c->isOnDesktop( desktop ) && focus_chain[ desktop ].contains( active_client )) + if( c->wantsTabFocus() && c->isOnDesktop( desktop ) && focus_chain[ desktop ].contains( under )) { - if( Client::belongToSameApplication( active_client, c )) + if( Client::belongToSameApplication( under, c )) { // put it after the active window if it's the same app focus_chain[ desktop ].removeAll( c ); - focus_chain[ desktop ].insert( focus_chain[ desktop ].indexOf( active_client ), c ); + focus_chain[ desktop ].insert( focus_chain[ desktop ].indexOf( under ), c ); } else { // put it in focus_chain[currentDesktop()] after all windows belonging to the active applicationa @@ -509,7 +502,7 @@ void Workspace::restackClientUnderActive( Client* c ) i >= 0; --i ) { - if( Client::belongToSameApplication( active_client, focus_chain[ desktop ].at( i ))) + if( Client::belongToSameApplication( under, focus_chain[ desktop ].at( i ))) { focus_chain[ desktop ].insert( i, c ); break; @@ -519,12 +512,12 @@ void Workspace::restackClientUnderActive( Client* c ) } } // the same for global_focus_chain - if( c->wantsTabFocus() && global_focus_chain.contains( active_client )) + if( c->wantsTabFocus() && global_focus_chain.contains( under )) { - if( Client::belongToSameApplication( active_client, c )) + if( Client::belongToSameApplication( under, c )) { global_focus_chain.removeAll( c ); - global_focus_chain.insert( global_focus_chain.indexOf( active_client ), c ); + global_focus_chain.insert( global_focus_chain.indexOf( under ), c ); } else { @@ -533,7 +526,7 @@ void Workspace::restackClientUnderActive( Client* c ) i >= 0; --i ) { - if( Client::belongToSameApplication( active_client, global_focus_chain.at( i ) )) + if( Client::belongToSameApplication( under, global_focus_chain.at( i ) )) { global_focus_chain.insert( i, c ); break; @@ -544,6 +537,18 @@ void Workspace::restackClientUnderActive( Client* c ) updateStackingOrder(); } +void Workspace::restackClientUnderActive( Client* c ) + { + if( c->isTopMenu()) + return; + if( !active_client || active_client == c ) + { + raiseClient( c ); + return; + } + restack( c, active_client ); + } + void Workspace::restoreSessionStackingOrder( Client* c ) { if( c->sessionStackingOrder() < 0 ) diff --git a/tabbox.h b/tabbox.h index 20e7aa2323..bc6b2072cc 100644 --- a/tabbox.h +++ b/tabbox.h @@ -54,6 +54,8 @@ class TabBoxHandlerImpl : public TabBoxHandler virtual int nextDesktopFocusChain( int desktop ) const; virtual int numberOfDesktops() const; virtual TabBoxClientList stackingOrder() const; + virtual void raiseClient( TabBoxClient *client ) const; + virtual void restack( TabBoxClient *c, TabBoxClient *under ); virtual TabBoxClient* clientToAddToList( TabBoxClient* client, int desktop, bool allDesktops ) const; virtual TabBoxClient* desktopClient() const; }; @@ -102,7 +104,7 @@ class TabBox : public QObject void nextPrev( bool next = true); void delayedShow(); - void hide(); + void hide( bool abort = false ); void refDisplay(); void unrefDisplay(); diff --git a/tabbox/tabboxhandler.cpp b/tabbox/tabboxhandler.cpp index 65d2d3c6fb..b6bd8bde9f 100644 --- a/tabbox/tabboxhandler.cpp +++ b/tabbox/tabboxhandler.cpp @@ -39,6 +39,7 @@ along with this program. If not, see . // KDE #include #include +#include namespace KWin { @@ -48,7 +49,7 @@ namespace TabBox class TabBoxHandlerPrivate { public: - TabBoxHandlerPrivate(); + TabBoxHandlerPrivate( TabBoxHandler *q ); ~TabBoxHandlerPrivate(); @@ -67,12 +68,13 @@ class TabBoxHandlerPrivate /** * Ends window highlighting */ - void endHighlightWindows(); + void endHighlightWindows( bool abort = false ); ClientModel* clientModel() const; DesktopModel* desktopModel() const; void parseConfig( const QString& fileName ); + TabBoxHandler *q; // public pointer // members TabBoxConfig config; TabBoxView* view; @@ -87,11 +89,15 @@ class TabBoxHandlerPrivate */ bool isShown; QMap< QString, ItemLayoutConfig > tabBoxLayouts; + TabBoxClient *lastRaisedClient, *lastRaisedClientSucc; }; -TabBoxHandlerPrivate::TabBoxHandlerPrivate() +TabBoxHandlerPrivate::TabBoxHandlerPrivate( TabBoxHandler *q ) { + this->q = q; isShown = false; + lastRaisedClient = 0; + lastRaisedClientSucc = 0; config = TabBoxConfig(); view = new TabBoxView(); XSetWindowAttributes attr; @@ -230,11 +236,45 @@ void TabBoxHandlerPrivate::updateHighlightWindows() { if( !isShown || config.tabBoxMode() != TabBoxConfig::ClientTabBox ) return; - QVector< WId > data( 2 ); + Display *dpy = QX11Info::display(); - const WId wId = view->winId(); - data[ 0 ] = wId; - data[ 1 ] = view->clientModel()->data( index, ClientModel::WIdRole ).toULongLong(); + TabBoxClient *currentClient = q->client( index ); + + if( !KWindowSystem::compositingActive() ) + { + if( lastRaisedClient ) + { + if ( lastRaisedClientSucc ) + q->restack( lastRaisedClient, lastRaisedClientSucc ); + // TODO lastRaisedClient->setMinimized( lastRaisedClientWasMinimized ); + } + + lastRaisedClient = currentClient; + if( lastRaisedClient ) + { + // TODO if ( (lastRaisedClientWasMinimized = lastRaisedClient->isMinimized()) ) + // lastRaisedClient->setMinimized( false ); + TabBoxClientList order = q->stackingOrder(); + int succIdx = order.indexOf( lastRaisedClient ) + 1; // this is likely related to the index parameter?! + lastRaisedClientSucc = ( succIdx < order.count() ) ? order.at( succIdx ) : 0; + q->raiseClient( lastRaisedClient ); + } + } + + WId wId; + QVector< WId > data; + if ( config.isShowTabBox() ) + { + wId = view->winId(); + data.resize(2); + data[ 1 ] = wId; + } + else + { + wId = QX11Info::appRootWindow(); + data.resize(1); + } + data[ 0 ] = currentClient ? currentClient->window() : 0L; if( config.isShowOutline() ) { data.resize( 6 ); @@ -248,12 +288,16 @@ void TabBoxHandlerPrivate::updateHighlightWindows() reinterpret_cast(data.data()), data.size()); } -void TabBoxHandlerPrivate::endHighlightWindows() +void TabBoxHandlerPrivate::endHighlightWindows( bool abort ) { + if ( abort && lastRaisedClient && lastRaisedClientSucc ) + q->restack( lastRaisedClient, lastRaisedClientSucc ); + lastRaisedClient = 0; + lastRaisedClientSucc = 0; // highlight windows Display *dpy = QX11Info::display(); Atom atom = XInternAtom(dpy, "_KDE_WINDOW_HIGHLIGHT", False); - XDeleteProperty( dpy, view->winId(), atom ); + XDeleteProperty( dpy, config.isShowTabBox() ? view->winId() : QX11Info::appRootWindow(), atom ); } /*********************************************************** @@ -411,7 +455,7 @@ TabBoxHandler::TabBoxHandler() : QObject() { KWin::TabBox::tabBox = this; - d = new TabBoxHandlerPrivate; + d = new TabBoxHandlerPrivate( this ); } TabBoxHandler::~TabBoxHandler() @@ -448,6 +492,8 @@ void TabBoxHandler::setConfig( const TabBoxConfig& config ) void TabBoxHandler::show() { d->isShown = true; + d->lastRaisedClient = 0; + d->lastRaisedClientSucc = 0; // show the outline if( d->config.isShowOutline() ) { @@ -457,19 +503,19 @@ void TabBoxHandler::show() { d->view->show(); d->view->updateGeometry(); - if( d->config.isHighlightWindows() ) - { - d->updateHighlightWindows(); - } + } + if( d->config.isHighlightWindows() ) + { + d->updateHighlightWindows(); } } -void TabBoxHandler::hide() +void TabBoxHandler::hide( bool abort ) { d->isShown = false; if( d->config.isHighlightWindows() ) { - d->endHighlightWindows(); + d->endHighlightWindows( abort ); } if( d->config.isShowOutline() ) { @@ -577,7 +623,7 @@ void TabBoxHandler::setCurrentIndex( const QModelIndex& index ) { d->updateOutline(); } - if( d->config.isShowTabBox() && d->config.isHighlightWindows() ) + if( d->config.isHighlightWindows() ) { d->updateHighlightWindows(); } diff --git a/tabbox/tabboxhandler.h b/tabbox/tabboxhandler.h index 3096fc44c2..741b107cbf 100644 --- a/tabbox/tabboxhandler.h +++ b/tabbox/tabboxhandler.h @@ -136,6 +136,18 @@ class TabBoxHandler : public QObject * @return The next desktop in the current focus chain. */ virtual int nextDesktopFocusChain( int desktop ) const = 0; + + /** + * Raise a client (w/o activating it) + */ + virtual void raiseClient( TabBoxClient* c ) const = 0; + + /** + * @param c The client to be restacked + * @param under The client the other one will be placed below + */ + virtual void restack( TabBoxClient *c, TabBoxClient *under ) = 0; + /** * @return The current stacking order of TabBoxClients */ @@ -191,7 +203,7 @@ class TabBoxHandler : public QObject * Removes the outline if active. * @see show */ - void hide(); + void hide( bool abort = false ); /** * Sets the current model index in the view and updates diff --git a/workspace.h b/workspace.h index acd13e6a26..931745cf22 100644 --- a/workspace.h +++ b/workspace.h @@ -158,6 +158,7 @@ class Workspace : public QObject, public KDecorationDefines void raiseClientRequest( Client* c, NET::RequestSource src, Time timestamp ); void lowerClientRequest( Client* c, NET::RequestSource src, Time timestamp ); void restackClientUnderActive( Client* ); + void restack( Client *c, Client *under ); void updateClientLayer( Client* c ); void raiseOrLowerClient( Client* ); void restoreSessionStackingOrder( Client* c ); @@ -358,7 +359,7 @@ class Workspace : public QObject, public KDecorationDefines int previousDesktopStatic( int iDesktop ) const; void refTabBox(); void unrefTabBox(); - void closeTabBox(); + void closeTabBox( bool abort = false ); // Tabbing void addClientGroup( ClientGroup* group );