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
icc-effect-5.14.5
Martin Gräßlin 2008-08-13 12:25:19 +00:00
parent 4816464bea
commit ca14652fc0
4 changed files with 160 additions and 52 deletions

View File

@ -49,6 +49,7 @@ PresentWindowsEffect::PresentWindowsEffect()
#ifdef KWIN_HAVE_OPENGL_COMPOSITING #ifdef KWIN_HAVE_OPENGL_COMPOSITING
, filterTexture( NULL ) , filterTexture( NULL )
#endif #endif
, mTabBoxMode( false )
{ {
KConfigGroup conf = effects->effectConfig("PresentWindows"); KConfigGroup conf = effects->effectConfig("PresentWindows");
@ -65,6 +66,7 @@ PresentWindowsEffect::PresentWindowsEffect()
borderActivate = (ElectricBorder)conf.readEntry("BorderActivate", (int)ElectricNone); borderActivate = (ElectricBorder)conf.readEntry("BorderActivate", (int)ElectricNone);
borderActivateAll = (ElectricBorder)conf.readEntry("BorderActivateAll", (int)ElectricTopLeft); borderActivateAll = (ElectricBorder)conf.readEntry("BorderActivateAll", (int)ElectricTopLeft);
drawWindowCaptions = conf.readEntry("DrawWindowCaptions", true); drawWindowCaptions = conf.readEntry("DrawWindowCaptions", true);
tabBox = conf.readEntry("TabBox", false);
effects->reserveElectricBorder( borderActivate ); effects->reserveElectricBorder( borderActivate );
effects->reserveElectricBorder( borderActivateAll ); effects->reserveElectricBorder( borderActivateAll );
@ -238,6 +240,8 @@ void PresentWindowsEffect::postPaintScreen()
void PresentWindowsEffect::windowInputMouseEvent( Window w, QEvent* e ) void PresentWindowsEffect::windowInputMouseEvent( Window w, QEvent* e )
{ {
if( mTabBoxMode )
return;
assert( w == mInput ); assert( w == mInput );
if( e->type() == QEvent::MouseMove ) if( e->type() == QEvent::MouseMove )
{ // Repaint if the highlighted window changed. { // Repaint if the highlighted window changed.
@ -302,16 +306,32 @@ void PresentWindowsEffect::setActive(bool active)
windowFilter.clear(); windowFilter.clear();
mWindowsToPresent.clear(); mWindowsToPresent.clear();
const EffectWindowList& originalwindowlist = effects->stackingOrder(); const EffectWindowList& originalwindowlist = effects->stackingOrder();
// Filter out special windows such as panels and taskbars if( mTabBoxMode )
foreach( EffectWindow* window, originalwindowlist )
{ {
if( window->isSpecialWindow() ) EffectWindowList tabBoxWindows = effects->currentTabBoxWindowList();
continue; int selectedWindow = tabBoxWindows.indexOf( effects->currentTabBoxWindow() );
if( window->isDeleted()) for( int i=selectedWindow; i<tabBoxWindows.count(); i++ )
continue; {
if( !mShowWindowsFromAllDesktops && !window->isOnCurrentDesktop() ) mWindowsToPresent.append( tabBoxWindows[ i ] );
continue; }
mWindowsToPresent.append(window); for( int i=selectedWindow-1; 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()) if( mWindowsToPresent.isEmpty())
{ {
@ -321,7 +341,10 @@ void PresentWindowsEffect::setActive(bool active)
mActiveness = 0; mActiveness = 0;
effectActivated(); effectActivated();
rearrangeWindows(); rearrangeWindows();
setHighlightedWindow( effects->activeWindow()); if( mTabBoxMode )
setHighlightedWindow( effects->currentTabBoxWindow() );
else
setHighlightedWindow( effects->activeWindow() );
} }
else else
{ {
@ -736,43 +759,75 @@ void PresentWindowsEffect::assignSlots( EffectWindowList windowlist, const QRect
} }
int slotwidth = area.width() / columns; int slotwidth = area.width() / columns;
int slotheight = area.height() / rows; int slotheight = area.height() / rows;
foreach( EffectWindow* w, windowlist ) if( mTabBoxMode )
{ {
WindowData *windowData = &mWindowData[ w ]; for( int i=0; i<windowlist.count(); i++ )
if( windowData->slot != -1 ) {
continue; // it already has a slot EffectWindow *w = windowlist[ i ];
QPoint pos = w->geometry().center(); WindowData *windowData = &mWindowData[ w ];
if( pos.x() < area.left()) if( windowData->slot != -1 )
pos.setX( area.left()); continue; // it already has a slot
if( pos.x() > area.right()) int x = i%columns;
pos.setX( area.right()); int y = i/columns;
if( pos.y() < area.top()) QPoint pos = w->geometry().center();
pos.setY( area.top()); if( pos.x() < area.left())
if( pos.y() > area.bottom()) pos.setX( area.left());
pos.setY( area.bottom()); if( pos.x() > area.right())
int distance = INT_MAX; pos.setX( area.right());
for( int x = 0; if( pos.y() < area.top())
x < columns; pos.setY( area.top());
++x ) if( pos.y() > area.bottom())
for( int y = 0; pos.setY( area.bottom());
y < rows; int distance = INT_MAX;
++y ) 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 slot = x + y * columns; int dist = int( sqrt( (double)(xdiff * xdiff + ydiff * ydiff) ));
if( taken[ slot ] ) windowData->slot = i;
continue; windowData->x = x;
int xdiff = pos.x() - ( area.x() + slotwidth * x + slotwidth / 2 ); // slotwidth/2 for center windowData->y = y;
int ydiff = pos.y() - ( area.y() + slotheight * y + slotheight / 2 ); windowData->slot_distance = dist;
int dist = int( sqrt( (double)(xdiff * xdiff + ydiff * ydiff) )); }
if( dist < distance ) }
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; int slot = x + y * columns;
windowData->slot = slot; if( taken[ slot ] )
windowData->x = x; continue;
windowData->y = y; int xdiff = pos.x() - ( area.x() + slotwidth * x + slotwidth / 2 ); // slotwidth/2 for center
windowData->slot_distance = distance; 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 #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 } // namespace
#include "presentwindows.moc" #include "presentwindows.moc"

View File

@ -54,6 +54,10 @@ class PresentWindowsEffect
virtual bool borderActivated( ElectricBorder border ); virtual bool borderActivated( ElectricBorder border );
virtual void grabbedKeyboardEvent( QKeyEvent* e ); virtual void grabbedKeyboardEvent( QKeyEvent* e );
virtual void tabBoxAdded( int mode );
virtual void tabBoxClosed();
virtual void tabBoxUpdated();
public slots: public slots:
void setActive(bool active); void setActive(bool active);
void toggleActive() { mShowWindowsFromAllDesktops = false; setActive(!mActivated); } void toggleActive() { mShowWindowsFromAllDesktops = false; setActive(!mActivated); }
@ -143,6 +147,8 @@ class PresentWindowsEffect
ElectricBorder borderActivate; ElectricBorder borderActivate;
ElectricBorder borderActivateAll; ElectricBorder borderActivateAll;
bool drawWindowCaptions; bool drawWindowCaptions;
bool mTabBoxMode;
bool tabBox;
}; };
} // namespace } // namespace

View File

@ -51,23 +51,27 @@ PresentWindowsEffectConfig::PresentWindowsEffectConfig(QWidget* parent, const QV
connect(mDrawWindowText, SIGNAL(stateChanged(int)), this, SLOT(changed())); connect(mDrawWindowText, SIGNAL(stateChanged(int)), this, SLOT(changed()));
layout->addWidget(mDrawWindowText, 0, 0); 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 " 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->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; mActivateCombo = new QComboBox;
addItems(mActivateCombo); addItems(mActivateCombo);
connect(mActivateCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(changed())); 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; mActivateAllCombo = new QComboBox;
addItems(mActivateAllCombo); addItems(mActivateAllCombo);
connect(mActivateAllCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(changed())); 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 // Shortcut config
KActionCollection* actionCollection = new KActionCollection( this, componentData() ); KActionCollection* actionCollection = new KActionCollection( this, componentData() );
@ -84,9 +88,9 @@ PresentWindowsEffectConfig::PresentWindowsEffectConfig(QWidget* parent, const QV
mShortcutEditor = new KShortcutsEditor(actionCollection, this, mShortcutEditor = new KShortcutsEditor(actionCollection, this,
KShortcutsEditor::GlobalAction, KShortcutsEditor::LetterShortcutsDisallowed); KShortcutsEditor::GlobalAction, KShortcutsEditor::LetterShortcutsDisallowed);
connect(mShortcutEditor, SIGNAL(keyChange()), this, SLOT(changed())); 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(); load();
} }
@ -130,6 +134,9 @@ void PresentWindowsEffectConfig::load()
bool drawWindowCaptions = conf.readEntry("DrawWindowCaptions", true); bool drawWindowCaptions = conf.readEntry("DrawWindowCaptions", true);
mDrawWindowText->setChecked(drawWindowCaptions); mDrawWindowText->setChecked(drawWindowCaptions);
bool tabBox = conf.readEntry("TabBox", false);
mTabBoxCheck->setChecked(tabBox);
emit changed(false); emit changed(false);
} }
@ -153,6 +160,9 @@ void PresentWindowsEffectConfig::save()
bool drawWindowCaptions = mDrawWindowText->isChecked(); bool drawWindowCaptions = mDrawWindowText->isChecked();
conf.writeEntry("DrawWindowCaptions", drawWindowCaptions); conf.writeEntry("DrawWindowCaptions", drawWindowCaptions);
bool tabBox = mTabBoxCheck->isChecked();
conf.writeEntry("TabBox", tabBox);
conf.sync(); conf.sync();
mShortcutEditor->save(); // undo() will restore to this state from now on mShortcutEditor->save(); // undo() will restore to this state from now on
@ -167,6 +177,7 @@ void PresentWindowsEffectConfig::defaults()
mActivateCombo->setCurrentIndex( (int)ElectricNone - 1 ); mActivateCombo->setCurrentIndex( (int)ElectricNone - 1 );
mActivateAllCombo->setCurrentIndex( (int)ElectricTopLeft ); mActivateAllCombo->setCurrentIndex( (int)ElectricTopLeft );
mDrawWindowText->setChecked(true); mDrawWindowText->setChecked(true);
mTabBoxCheck->setChecked(false);
mShortcutEditor->allDefault(); mShortcutEditor->allDefault();
emit changed(true); emit changed(true);
} }

View File

@ -46,6 +46,7 @@ class PresentWindowsEffectConfig : public KCModule
private: private:
QCheckBox* mDrawWindowText; QCheckBox* mDrawWindowText;
QCheckBox* mTabBoxCheck;
QComboBox* mActivateCombo; QComboBox* mActivateCombo;
QComboBox* mActivateAllCombo; QComboBox* mActivateAllCombo;
KShortcutsEditor* mShortcutEditor; KShortcutsEditor* mShortcutEditor;