From ca14652fc09e2f0de8bfb5cbe9d559ee9e37e367 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Wed, 13 Aug 2008 12:25:19 +0000 Subject: [PATCH] Present windows effect can be used for window switching (alt+tab) as well. CCMAIL: kwin@kde.org svn path=/trunk/KDE/kdebase/workspace/; revision=846399 --- effects/presentwindows.cpp | 178 ++++++++++++++++++++++-------- effects/presentwindows.h | 6 + effects/presentwindows_config.cpp | 27 +++-- effects/presentwindows_config.h | 1 + 4 files changed, 160 insertions(+), 52 deletions(-) diff --git a/effects/presentwindows.cpp b/effects/presentwindows.cpp index ce24dcc2c4..84b0907f8f 100644 --- a/effects/presentwindows.cpp +++ b/effects/presentwindows.cpp @@ -49,6 +49,7 @@ PresentWindowsEffect::PresentWindowsEffect() #ifdef KWIN_HAVE_OPENGL_COMPOSITING , filterTexture( NULL ) #endif + , mTabBoxMode( false ) { KConfigGroup conf = effects->effectConfig("PresentWindows"); @@ -65,6 +66,7 @@ PresentWindowsEffect::PresentWindowsEffect() borderActivate = (ElectricBorder)conf.readEntry("BorderActivate", (int)ElectricNone); borderActivateAll = (ElectricBorder)conf.readEntry("BorderActivateAll", (int)ElectricTopLeft); drawWindowCaptions = conf.readEntry("DrawWindowCaptions", true); + tabBox = conf.readEntry("TabBox", false); effects->reserveElectricBorder( borderActivate ); effects->reserveElectricBorder( borderActivateAll ); @@ -238,6 +240,8 @@ void PresentWindowsEffect::postPaintScreen() void PresentWindowsEffect::windowInputMouseEvent( Window w, QEvent* e ) { + if( mTabBoxMode ) + return; assert( w == mInput ); if( e->type() == QEvent::MouseMove ) { // Repaint if the highlighted window changed. @@ -302,16 +306,32 @@ void PresentWindowsEffect::setActive(bool active) windowFilter.clear(); mWindowsToPresent.clear(); const EffectWindowList& originalwindowlist = effects->stackingOrder(); - // Filter out special windows such as panels and taskbars - foreach( EffectWindow* window, originalwindowlist ) + if( mTabBoxMode ) { - if( window->isSpecialWindow() ) - continue; - if( window->isDeleted()) - continue; - if( !mShowWindowsFromAllDesktops && !window->isOnCurrentDesktop() ) - continue; - mWindowsToPresent.append(window); + EffectWindowList tabBoxWindows = effects->currentTabBoxWindowList(); + int selectedWindow = tabBoxWindows.indexOf( effects->currentTabBoxWindow() ); + for( int i=selectedWindow; i=0; i-- ) + { + mWindowsToPresent.append( tabBoxWindows[ i ] ); + } + } + else + { + // Filter out special windows such as panels and taskbars + foreach( EffectWindow* window, originalwindowlist ) + { + if( window->isSpecialWindow() ) + continue; + if( window->isDeleted()) + continue; + if( !mShowWindowsFromAllDesktops && !window->isOnCurrentDesktop() ) + continue; + mWindowsToPresent.append(window); + } } if( mWindowsToPresent.isEmpty()) { @@ -321,7 +341,10 @@ void PresentWindowsEffect::setActive(bool active) mActiveness = 0; effectActivated(); rearrangeWindows(); - setHighlightedWindow( effects->activeWindow()); + if( mTabBoxMode ) + setHighlightedWindow( effects->currentTabBoxWindow() ); + else + setHighlightedWindow( effects->activeWindow() ); } else { @@ -736,43 +759,75 @@ void PresentWindowsEffect::assignSlots( EffectWindowList windowlist, const QRect } int slotwidth = area.width() / columns; int slotheight = area.height() / rows; - foreach( EffectWindow* w, windowlist ) + if( mTabBoxMode ) { - WindowData *windowData = &mWindowData[ w ]; - if( windowData->slot != -1 ) - continue; // it already has a slot - QPoint pos = w->geometry().center(); - if( pos.x() < area.left()) - pos.setX( area.left()); - if( pos.x() > area.right()) - pos.setX( area.right()); - if( pos.y() < area.top()) - pos.setY( area.top()); - if( pos.y() > area.bottom()) - pos.setY( area.bottom()); - int distance = INT_MAX; - for( int x = 0; - x < columns; - ++x ) - for( int y = 0; - y < rows; - ++y ) - { - int slot = x + y * columns; - if( taken[ slot ] ) - continue; - int xdiff = pos.x() - ( area.x() + slotwidth * x + slotwidth / 2 ); // slotwidth/2 for center - int ydiff = pos.y() - ( area.y() + slotheight * y + slotheight / 2 ); - int dist = int( sqrt( (double)(xdiff * xdiff + ydiff * ydiff) )); - if( dist < distance ) + for( int i=0; islot != -1 ) + continue; // it already has a slot + int x = i%columns; + int y = i/columns; + QPoint pos = w->geometry().center(); + if( pos.x() < area.left()) + pos.setX( area.left()); + if( pos.x() > area.right()) + pos.setX( area.right()); + if( pos.y() < area.top()) + pos.setY( area.top()); + if( pos.y() > area.bottom()) + pos.setY( area.bottom()); + int distance = INT_MAX; + int xdiff = pos.x() - ( area.x() + slotwidth * x + slotwidth / 2 ); // slotwidth/2 for center + int ydiff = pos.y() - ( area.y() + slotheight * y + slotheight / 2 ); + int dist = int( sqrt( (double)(xdiff * xdiff + ydiff * ydiff) )); + windowData->slot = i; + windowData->x = x; + windowData->y = y; + windowData->slot_distance = dist; + } + } + else + { + foreach( EffectWindow* w, windowlist ) + { + WindowData *windowData = &mWindowData[ w ]; + if( windowData->slot != -1 ) + continue; // it already has a slot + QPoint pos = w->geometry().center(); + if( pos.x() < area.left()) + pos.setX( area.left()); + if( pos.x() > area.right()) + pos.setX( area.right()); + if( pos.y() < area.top()) + pos.setY( area.top()); + if( pos.y() > area.bottom()) + pos.setY( area.bottom()); + int distance = INT_MAX; + for( int x = 0; + x < columns; + ++x ) + for( int y = 0; + y < rows; + ++y ) { - distance = dist; - windowData->slot = slot; - windowData->x = x; - windowData->y = y; - windowData->slot_distance = distance; + int slot = x + y * columns; + if( taken[ slot ] ) + continue; + int xdiff = pos.x() - ( area.x() + slotwidth * x + slotwidth / 2 ); // slotwidth/2 for center + int ydiff = pos.y() - ( area.y() + slotheight * y + slotheight / 2 ); + int dist = int( sqrt( (double)(xdiff * xdiff + ydiff * ydiff) )); + if( dist < distance ) + { + distance = dist; + windowData->slot = slot; + windowData->x = x; + windowData->y = y; + windowData->slot_distance = distance; + } } - } + } } } @@ -1122,5 +1177,40 @@ void PresentWindowsEffect::paintWindowIcon( EffectWindow* w, WindowPaintData& pa #endif } +void PresentWindowsEffect::tabBoxAdded( int mode ) + { + if( effects->activeFullScreenEffect() && effects->activeFullScreenEffect() != this ) + return; + if( mActivated ) + return; + if( !tabBox ) + return; + if( mode == TabBoxWindowsMode && effects->currentTabBoxWindowList().count() > 0 ) + { + mTabBoxMode = true; + setActive( true ); + if( mActivated ) + effects->refTabBox(); + } + } + +void PresentWindowsEffect::tabBoxClosed() + { + if( mActivated ) + { + mTabBoxMode = false; + effects->unrefTabBox(); + setActive( false ); + } + } + +void PresentWindowsEffect::tabBoxUpdated() + { + if( mActivated ) + { + setHighlightedWindow( effects->currentTabBoxWindow() ); + } + } + } // namespace #include "presentwindows.moc" diff --git a/effects/presentwindows.h b/effects/presentwindows.h index 8407ebf8dd..09904bb5a4 100644 --- a/effects/presentwindows.h +++ b/effects/presentwindows.h @@ -54,6 +54,10 @@ class PresentWindowsEffect virtual bool borderActivated( ElectricBorder border ); virtual void grabbedKeyboardEvent( QKeyEvent* e ); + virtual void tabBoxAdded( int mode ); + virtual void tabBoxClosed(); + virtual void tabBoxUpdated(); + public slots: void setActive(bool active); void toggleActive() { mShowWindowsFromAllDesktops = false; setActive(!mActivated); } @@ -143,6 +147,8 @@ class PresentWindowsEffect ElectricBorder borderActivate; ElectricBorder borderActivateAll; bool drawWindowCaptions; + bool mTabBoxMode; + bool tabBox; }; } // namespace diff --git a/effects/presentwindows_config.cpp b/effects/presentwindows_config.cpp index 81f9720df0..e67a4552fa 100644 --- a/effects/presentwindows_config.cpp +++ b/effects/presentwindows_config.cpp @@ -51,23 +51,27 @@ PresentWindowsEffectConfig::PresentWindowsEffectConfig(QWidget* parent, const QV connect(mDrawWindowText, SIGNAL(stateChanged(int)), this, SLOT(changed())); layout->addWidget(mDrawWindowText, 0, 0); + mTabBoxCheck = new QCheckBox(i18n("Use for window switching"), this); + connect(mTabBoxCheck, SIGNAL(stateChanged(int)), this, SLOT(changed())); + layout->addWidget(mTabBoxCheck, 1, 0 ); + layout->addWidget(new QLabel(i18n("Activate when cursor is at a specific edge " - "or corner of the screen:"), this), 1, 0, 1, 3); + "or corner of the screen:"), this), 2, 0, 1, 3); layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Fixed), 2, 0, 2, 1); - layout->addWidget(new QLabel(i18n("for windows on current desktop: "), this), 2, 1); + layout->addWidget(new QLabel(i18n("for windows on current desktop: "), this), 3, 1); mActivateCombo = new QComboBox; addItems(mActivateCombo); connect(mActivateCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(changed())); - layout->addWidget(mActivateCombo, 2, 2); + layout->addWidget(mActivateCombo, 3, 2); - layout->addWidget(new QLabel(i18n("for windows on all desktops: "), this), 3, 1); + layout->addWidget(new QLabel(i18n("for windows on all desktops: "), this), 4, 1); mActivateAllCombo = new QComboBox; addItems(mActivateAllCombo); connect(mActivateAllCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(changed())); - layout->addWidget(mActivateAllCombo, 3, 2); + layout->addWidget(mActivateAllCombo, 4, 2); - layout->addItem(new QSpacerItem(10, 10, QSizePolicy::Fixed, QSizePolicy::Expanding), 4, 0, 1, 3); + layout->addItem(new QSpacerItem(10, 10, QSizePolicy::Fixed, QSizePolicy::Expanding), 5, 0, 1, 3); // Shortcut config KActionCollection* actionCollection = new KActionCollection( this, componentData() ); @@ -84,9 +88,9 @@ PresentWindowsEffectConfig::PresentWindowsEffectConfig(QWidget* parent, const QV mShortcutEditor = new KShortcutsEditor(actionCollection, this, KShortcutsEditor::GlobalAction, KShortcutsEditor::LetterShortcutsDisallowed); connect(mShortcutEditor, SIGNAL(keyChange()), this, SLOT(changed())); - layout->addWidget(mShortcutEditor, 5, 0, 1, 3); + layout->addWidget(mShortcutEditor, 6, 0, 1, 3); - layout->addItem(new QSpacerItem(10, 10, QSizePolicy::Minimum, QSizePolicy::Expanding), 6, 0, 1, 3); + layout->addItem(new QSpacerItem(10, 10, QSizePolicy::Minimum, QSizePolicy::Expanding), 7, 0, 1, 3); load(); } @@ -130,6 +134,9 @@ void PresentWindowsEffectConfig::load() bool drawWindowCaptions = conf.readEntry("DrawWindowCaptions", true); mDrawWindowText->setChecked(drawWindowCaptions); + bool tabBox = conf.readEntry("TabBox", false); + mTabBoxCheck->setChecked(tabBox); + emit changed(false); } @@ -153,6 +160,9 @@ void PresentWindowsEffectConfig::save() bool drawWindowCaptions = mDrawWindowText->isChecked(); conf.writeEntry("DrawWindowCaptions", drawWindowCaptions); + bool tabBox = mTabBoxCheck->isChecked(); + conf.writeEntry("TabBox", tabBox); + conf.sync(); mShortcutEditor->save(); // undo() will restore to this state from now on @@ -167,6 +177,7 @@ void PresentWindowsEffectConfig::defaults() mActivateCombo->setCurrentIndex( (int)ElectricNone - 1 ); mActivateAllCombo->setCurrentIndex( (int)ElectricTopLeft ); mDrawWindowText->setChecked(true); + mTabBoxCheck->setChecked(false); mShortcutEditor->allDefault(); emit changed(true); } diff --git a/effects/presentwindows_config.h b/effects/presentwindows_config.h index 376ab4dc72..29c7683732 100644 --- a/effects/presentwindows_config.h +++ b/effects/presentwindows_config.h @@ -46,6 +46,7 @@ class PresentWindowsEffectConfig : public KCModule private: QCheckBox* mDrawWindowText; + QCheckBox* mTabBoxCheck; QComboBox* mActivateCombo; QComboBox* mActivateAllCombo; KShortcutsEditor* mShortcutEditor;