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
This commit is contained in:
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
, 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<tabBoxWindows.count(); i++ )
{
mWindowsToPresent.append( tabBoxWindows[ i ] );
}
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())
{
@ -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; i<windowlist.count(); i++ )
{
EffectWindow *w = windowlist[ i ];
WindowData *windowData = &mWindowData[ w ];
if( windowData->slot != -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"

View file

@ -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

View file

@ -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);
}

View file

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