Configurable mouse actions in present windows for clicking a window and desktop.

It's possible to activate a window, exit without activating, bring window to current desktop, send window on all desktops, mimize the window and close the window.
Clicking desktop allows to activate selected window, exit without activating, show the desktop (minimize all apps) and of course do nothing.
FEATURE: 163116

svn path=/trunk/KDE/kdebase/workspace/; revision=988788
This commit is contained in:
Martin Gräßlin 2009-06-28 17:17:29 +00:00
parent 7b16349392
commit a26c5b1225
7 changed files with 566 additions and 98 deletions

View file

@ -421,6 +421,12 @@ void EffectsHandlerImpl::windowToDesktop( EffectWindow* w, int desktop )
Workspace::self()->sendClientToDesktop( cl, desktop, true );
}
void EffectsHandlerImpl::setShowingDesktop( bool showing )
{
Workspace::self()->setShowingDesktop( showing );
}
int EffectsHandlerImpl::currentDesktop() const
{
return Workspace::self()->currentDesktop();
@ -1446,6 +1452,30 @@ WindowQuadList EffectWindowImpl::buildQuads( bool force ) const
return sceneWindow()->buildQuads( force );
}
void EffectWindowImpl::minimize() const
{
if( Client* c = dynamic_cast< Client* >( toplevel ))
{
c->minimize();
}
}
void EffectWindowImpl::unminimize() const
{
if( Client* c = dynamic_cast< Client* >( toplevel ))
{
c->unminimize();
}
}
void EffectWindowImpl::closeWindow() const
{
if( Client* c = dynamic_cast< Client* >( toplevel ))
{
c->closeWindow();
}
}
EffectWindow* effectWindow( Toplevel* w )
{
EffectWindowImpl* ret = w->effectWindow();

View file

@ -55,6 +55,7 @@ class EffectsHandlerImpl : public EffectsHandler
virtual EffectWindow* activeWindow() const;
virtual void moveWindow( EffectWindow* w, const QPoint& pos );
virtual void windowToDesktop( EffectWindow* w, int desktop );
virtual void setShowingDesktop( bool showing );
virtual int currentDesktop() const;
virtual int numberOfDesktops() const;
@ -257,6 +258,10 @@ class EffectWindowImpl : public EffectWindow
virtual WindowQuadList buildQuads( bool force = false ) const;
virtual void minimize() const;
virtual void unminimize() const;
virtual void closeWindow() const;
const Toplevel* window() const;
Toplevel* window();

View file

@ -141,6 +141,12 @@ void PresentWindowsEffect::reconfigure( ReconfigureFlags )
m_fillGaps = conf.readEntry( "FillGaps", true );
m_fadeDuration = double( animationTime( 150 ));
m_showPanel = conf.readEntry( "ShowPanel", false );
m_leftButtonWindow = (WindowMouseAction)conf.readEntry( "LeftButtonWindow", (int)WindowActivateAction );
m_middleButtonWindow = (WindowMouseAction)conf.readEntry( "MiddleButtonWindow", (int)WindowNoAction );
m_rightButtonWindow = (WindowMouseAction)conf.readEntry( "RightButtonWindow", (int)WindowExitAction );
m_leftButtonDesktop = (DesktopMouseAction)conf.readEntry( "LeftButtonDesktop", (int)DesktopExitAction );
m_middleButtonDesktop = (DesktopMouseAction)conf.readEntry( "MiddleButtonDesktop", (int)DesktopNoAction );
m_rightButtonDesktop = (DesktopMouseAction)conf.readEntry( "RightButtonDesktop", (int)DesktopNoAction );
}
const void* PresentWindowsEffect::proxy() const
@ -375,12 +381,14 @@ void PresentWindowsEffect::windowInputMouseEvent( Window w, QEvent *e )
// Which window are we hovering over? Always trigger as we don't always get move events before clicking
// We cannot use m_motionManager.windowAtPoint() as the window might not be visible
EffectWindowList windows = m_motionManager.managedWindows();
bool hovering = false;
for( int i = 0; i < windows.size(); i++ )
{
assert( m_windowData.contains( windows.at( i )));
if( m_motionManager.transformedGeometry( windows.at( i )).contains( cursorPos() ) &&
m_windowData[windows.at( i )].visible )
{
hovering = true;
if( windows.at( i ) && m_highlightedWindow != windows.at( i ))
setHighlightedWindow( windows.at( i ));
break;
@ -393,12 +401,110 @@ void PresentWindowsEffect::windowInputMouseEvent( Window w, QEvent *e )
QMouseEvent* me = static_cast<QMouseEvent*>( e );
if( me->button() == Qt::LeftButton )
{
if( hovering )
{
// mouse is hovering above a window - use MouseActionsWindow
mouseActionWindow( m_leftButtonWindow );
}
else
{
// mouse is hovering above desktop - use MouseActionsDesktop
mouseActionDesktop( m_leftButtonDesktop );
}
}
if( me->button() == Qt::MidButton )
{
if( hovering )
{
// mouse is hovering above a window - use MouseActionsWindow
mouseActionWindow( m_middleButtonWindow );
}
else
{
// mouse is hovering above desktop - use MouseActionsDesktop
mouseActionDesktop( m_middleButtonDesktop );
}
}
if( me->button() == Qt::RightButton )
{
if( hovering )
{
// mouse is hovering above a window - use MouseActionsWindow
mouseActionWindow( m_rightButtonWindow );
}
else
{
// mouse is hovering above desktop - use MouseActionsDesktop
mouseActionDesktop( m_rightButtonDesktop );
}
}
}
void PresentWindowsEffect::mouseActionWindow( WindowMouseAction& action )
{
switch( action )
{
case WindowActivateAction:
if( m_highlightedWindow )
effects->activateWindow( m_highlightedWindow );
setActive( false );
break;
case WindowExitAction:
setActive( false );
break;
case WindowToCurrentDesktopAction:
if( m_highlightedWindow )
effects->windowToDesktop( m_highlightedWindow, effects->currentDesktop() );
break;
case WindowToAllDesktopsAction:
if( m_highlightedWindow )
{
if( m_highlightedWindow->isOnAllDesktops() )
effects->windowToDesktop( m_highlightedWindow, effects->currentDesktop() );
else
effects->windowToDesktop( m_highlightedWindow, NET::OnAllDesktops );
}
// TODO: User mouse actions. E.g. right-click stickies and middle-click brings to current desktop
break;
case WindowMinimizeAction:
if( m_highlightedWindow )
{
if( m_highlightedWindow->isMinimized() )
m_highlightedWindow->unminimize();
else
m_highlightedWindow->minimize();
}
break;
case WindowCloseAction:
if( m_highlightedWindow )
{
m_highlightedWindow->closeWindow();
}
break;
default:
break;
}
}
void PresentWindowsEffect::mouseActionDesktop( DesktopMouseAction& action )
{
switch( action )
{
case DesktopActivateAction:
if( m_highlightedWindow )
effects->activateWindow( m_highlightedWindow );
setActive( false );
break;
case DesktopExitAction:
setActive( false );
break;
case DesktopShowDesktopAction:
effects->setShowingDesktop( true );
setActive( false );
default:
break;
}
}
void PresentWindowsEffect::grabbedKeyboardEvent( QKeyEvent *e )
{

View file

@ -97,6 +97,23 @@ class PresentWindowsEffect
ModeSelectedDesktop, // Shows windows of selected desktop via property (m_desktop)
ModeWindowGroup // Shows windows selected via property
};
enum WindowMouseAction
{
WindowActivateAction = 0, // Activates the window and deactivates the effect
WindowExitAction = 1, // Deactivates the effect without activating new window
WindowToCurrentDesktopAction = 2, // Brings window to current desktop
WindowToAllDesktopsAction = 3, // Brings window to all desktops
WindowMinimizeAction = 4, // Minimize the window
WindowCloseAction = 5, // Closes the window
WindowNoAction = 6 // nothing
};
enum DesktopMouseAction
{
DesktopActivateAction = 0, // Activates the window and deactivates the effect
DesktopExitAction = 1, // Deactivates the effect without activating new window
DesktopShowDesktopAction = 2, // Minimizes all windows
DesktopNoAction = 3 // nothing
};
public slots:
void setActive( bool active, bool closingTab = false ); // HACK: closingTab shouldn't be needed
@ -136,6 +153,10 @@ class PresentWindowsEffect
EffectWindow* relativeWindow( EffectWindow *w, int xdiff, int ydiff, bool wrap ) const;
EffectWindow* findFirstWindow() const;
// Helper functions for mouse actions
void mouseActionWindow( WindowMouseAction& action );
void mouseActionDesktop( DesktopMouseAction& action );
private:
PresentWindowsEffectProxy m_proxy;
friend class PresentWindowsEffectProxy;
@ -186,6 +207,14 @@ class PresentWindowsEffect
long m_atomDesktop;
// Present windows for group of window ids
long m_atomWindows;
// Mouse Actions
WindowMouseAction m_leftButtonWindow;
WindowMouseAction m_middleButtonWindow;
WindowMouseAction m_rightButtonWindow;
DesktopMouseAction m_leftButtonDesktop;
DesktopMouseAction m_middleButtonDesktop;
DesktopMouseAction m_rightButtonDesktop;
};
} // namespace

View file

@ -76,6 +76,12 @@ PresentWindowsEffectConfig::PresentWindowsEffectConfig(QWidget* parent, const QV
connect( m_ui->accuracySlider, SIGNAL( valueChanged( int )), this, SLOT( changed() ));
connect( m_ui->fillGapsBox, SIGNAL( stateChanged( int )), this, SLOT( changed() ));
connect( m_ui->shortcutEditor, SIGNAL( keyChange() ), this, SLOT( changed() ));
connect( m_ui->leftButtonWindowCombo, SIGNAL( currentIndexChanged( int )), this, SLOT( changed() ));
connect( m_ui->middleButtonWindowCombo, SIGNAL( currentIndexChanged( int )), this, SLOT( changed() ));
connect( m_ui->rightButtonWindowCombo, SIGNAL( currentIndexChanged( int )), this, SLOT( changed() ));
connect( m_ui->leftButtonDesktopCombo, SIGNAL( currentIndexChanged( int )), this, SLOT( changed() ));
connect( m_ui->middleButtonDesktopCombo, SIGNAL( currentIndexChanged( int )), this, SLOT( changed() ));
connect( m_ui->rightButtonDesktopCombo, SIGNAL( currentIndexChanged( int )), this, SLOT( changed() ));
load();
}
@ -118,6 +124,20 @@ void PresentWindowsEffectConfig::load()
bool fillGaps = conf.readEntry( "FillGaps", true );
m_ui->fillGapsBox->setChecked( fillGaps );
int leftButtonWindow = conf.readEntry( "LeftButtonWindow", int( PresentWindowsEffect::WindowActivateAction ));
m_ui->leftButtonWindowCombo->setCurrentIndex( leftButtonWindow );
int middleButtonWindow = conf.readEntry( "MiddleButtonWindow", int( PresentWindowsEffect::WindowNoAction ));
m_ui->middleButtonWindowCombo->setCurrentIndex( middleButtonWindow );
int rightButtonWindow = conf.readEntry( "RightButtonWindow", int( PresentWindowsEffect::WindowExitAction ));
m_ui->rightButtonWindowCombo->setCurrentIndex( rightButtonWindow );
int leftButtonDesktop = conf.readEntry( "LeftButtonDesktop", int( PresentWindowsEffect::DesktopExitAction ));
m_ui->leftButtonDesktopCombo->setCurrentIndex( leftButtonDesktop );
int middleButtonDesktop = conf.readEntry( "MiddleButtonDesktop", int( PresentWindowsEffect::DesktopNoAction ));
m_ui->middleButtonDesktopCombo->setCurrentIndex( middleButtonDesktop );
int rightButtonDesktop = conf.readEntry( "RightButtonDesktop", int( PresentWindowsEffect::DesktopNoAction ));
m_ui->rightButtonDesktopCombo->setCurrentIndex( rightButtonDesktop );
emit changed(false);
}
@ -143,6 +163,20 @@ void PresentWindowsEffectConfig::save()
conf.writeEntry( "FillGaps", m_ui->fillGapsBox->isChecked() );
int leftButtonWindow = m_ui->leftButtonWindowCombo->currentIndex();
conf.writeEntry( "LeftButtonWindow", leftButtonWindow );
int middleButtonWindow = m_ui->middleButtonWindowCombo->currentIndex();
conf.writeEntry( "MiddleButtonWindow", middleButtonWindow );
int rightButtonWindow = m_ui->rightButtonWindowCombo->currentIndex();
conf.writeEntry( "RightButtonWindow", rightButtonWindow );
int leftButtonDesktop = m_ui->leftButtonDesktopCombo->currentIndex();
conf.writeEntry( "LeftButtonDesktop", leftButtonDesktop );
int middleButtonDesktop = m_ui->middleButtonDesktopCombo->currentIndex();
conf.writeEntry( "MiddleButtonDesktop", middleButtonDesktop );
int rightButtonDesktop = m_ui->rightButtonDesktopCombo->currentIndex();
conf.writeEntry( "RightButtonDesktop", rightButtonDesktop );
m_ui->shortcutEditor->save();
conf.sync();
@ -163,6 +197,12 @@ void PresentWindowsEffectConfig::defaults()
m_ui->accuracySlider->setSliderPosition( 1 );
m_ui->fillGapsBox->setChecked( true );
m_ui->shortcutEditor->allDefault();
m_ui->leftButtonWindowCombo->setCurrentIndex( int( PresentWindowsEffect::WindowActivateAction ));
m_ui->middleButtonWindowCombo->setCurrentIndex( int( PresentWindowsEffect::WindowNoAction ));
m_ui->rightButtonWindowCombo->setCurrentIndex( int( PresentWindowsEffect::WindowExitAction ));
m_ui->leftButtonDesktopCombo->setCurrentIndex( int( PresentWindowsEffect::DesktopExitAction ));
m_ui->middleButtonDesktopCombo->setCurrentIndex( int( PresentWindowsEffect::DesktopNoAction ));
m_ui->rightButtonDesktopCombo->setCurrentIndex( int( PresentWindowsEffect::DesktopNoAction ));
emit changed(true);
}

View file

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>KWin::PresentWindowsEffectConfigForm</class>
<widget class="QWidget" name="KWin::PresentWindowsEffectConfigForm">
@ -5,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>535</width>
<height>345</height>
<width>542</width>
<height>441</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
@ -32,7 +33,7 @@
<item row="0" column="1">
<widget class="QSpinBox" name="rearrangeDurationSpin">
<property name="sizePolicy">
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -70,7 +71,7 @@
<item row="1" column="1">
<widget class="QComboBox" name="layoutCombo">
<property name="sizePolicy">
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -130,16 +131,16 @@
</layout>
</widget>
</item>
<item row="1" column="0" colspan="2" >
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Activation</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" colspan="2">
<widget class="KWin::GlobalShortcutsEditor" native="1" name="shortcutEditor" >
<widget class="KWin::GlobalShortcutsEditor" name="shortcutEditor" native="true">
<property name="sizePolicy">
<sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -238,6 +239,258 @@
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Windows</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Left button:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="leftButtonWindowCombo">
<item>
<property name="text">
<string>Activate window</string>
</property>
</item>
<item>
<property name="text">
<string>End effect</string>
</property>
</item>
<item>
<property name="text">
<string>Bring window to current desktop</string>
</property>
</item>
<item>
<property name="text">
<string>Send window to all desktops</string>
</property>
</item>
<item>
<property name="text">
<string>(Un-)Minimize window</string>
</property>
</item>
<item>
<property name="text">
<string>Close window</string>
</property>
</item>
<item>
<property name="text">
<string>No action</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Middle button:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="middleButtonWindowCombo">
<item>
<property name="text">
<string>Activate window</string>
</property>
</item>
<item>
<property name="text">
<string>End effect</string>
</property>
</item>
<item>
<property name="text">
<string>Bring window to current desktop</string>
</property>
</item>
<item>
<property name="text">
<string>Send window to all desktops</string>
</property>
</item>
<item>
<property name="text">
<string>(Un-)Minimize window</string>
</property>
</item>
<item>
<property name="text">
<string>Close window</string>
</property>
</item>
<item>
<property name="text">
<string>No action</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Right button:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="rightButtonWindowCombo">
<item>
<property name="text">
<string>Activate window</string>
</property>
</item>
<item>
<property name="text">
<string>End effect</string>
</property>
</item>
<item>
<property name="text">
<string>Bring window to current desktop</string>
</property>
</item>
<item>
<property name="text">
<string>Send window to all desktops</string>
</property>
</item>
<item>
<property name="text">
<string>(Un-)Minimize window</string>
</property>
</item>
<item>
<property name="text">
<string>Close window</string>
</property>
</item>
<item>
<property name="text">
<string>No action</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="1">
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Desktop</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Left button:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="leftButtonDesktopCombo">
<item>
<property name="text">
<string>Activate window</string>
</property>
</item>
<item>
<property name="text">
<string>End effect</string>
</property>
</item>
<item>
<property name="text">
<string>Show desktop</string>
</property>
</item>
<item>
<property name="text">
<string>No action</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Middle button:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="middleButtonDesktopCombo">
<item>
<property name="text">
<string>Activate window</string>
</property>
</item>
<item>
<property name="text">
<string>End effect</string>
</property>
</item>
<item>
<property name="text">
<string>Show desktop</string>
</property>
</item>
<item>
<property name="text">
<string>No action</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Right button:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="rightButtonDesktopCombo">
<item>
<property name="text">
<string>Activate window</string>
</property>
</item>
<item>
<property name="text">
<string>End effect</string>
</property>
</item>
<item>
<property name="text">
<string>Show desktop</string>
</property>
</item>
<item>
<property name="text">
<string>No action</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>

View file

@ -170,7 +170,7 @@ X-KDE-Library=kwin4_effect_cooleffect
#define KWIN_EFFECT_API_MAKE_VERSION( major, minor ) (( major ) << 8 | ( minor ))
#define KWIN_EFFECT_API_VERSION_MAJOR 0
#define KWIN_EFFECT_API_VERSION_MINOR 100
#define KWIN_EFFECT_API_VERSION_MINOR 101
#define KWIN_EFFECT_API_VERSION KWIN_EFFECT_API_MAKE_VERSION( \
KWIN_EFFECT_API_VERSION_MAJOR, KWIN_EFFECT_API_VERSION_MINOR )
@ -557,6 +557,7 @@ class KWIN_EXPORT EffectsHandler
virtual EffectWindow* activeWindow() const = 0 ;
virtual void moveWindow( EffectWindow* w, const QPoint& pos ) = 0;
virtual void windowToDesktop( EffectWindow* w, int desktop ) = 0;
virtual void setShowingDesktop( bool showing ) = 0;
// Desktops
/**
@ -948,6 +949,10 @@ class KWIN_EXPORT EffectWindow
* Returns the unmodified window quad list. Can also be used to force rebuilding.
*/
virtual WindowQuadList buildQuads( bool force = false ) const = 0;
virtual void minimize() const = 0;
virtual void unminimize() const = 0;
virtual void closeWindow() const = 0;
};
class KWIN_EXPORT EffectWindowGroup