2007-11-27 22:40:25 +03:00
/********************************************************************
2007-04-29 21:35:43 +04:00
KWin - the KDE window manager
This file is part of the KDE project .
Copyright ( C ) 1999 , 2000 Matthias Ettrich < ettrich @ kde . org >
Copyright ( C ) 2003 Lubos Lunak < l . lunak @ kde . org >
2007-11-27 22:40:25 +03:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-04-29 21:35:43 +04:00
/*
This file contains things relevant to direct user actions , such as
responses to global keyboard shortcuts , or selecting actions
from the window operations menu .
*/
2012-03-23 11:03:09 +04:00
///////////////////////////////////////////////////////////////////////////////
// NOTE: if you change the menu, keep kde-workspace/libs/taskmanager/taskactions.cpp in sync
//////////////////////////////////////////////////////////////////////////////
2012-08-19 14:00:53 +04:00
# include "useractions.h"
2013-02-26 11:45:44 +04:00
# include "cursor.h"
2007-04-29 21:35:43 +04:00
# include "client.h"
2013-04-08 14:31:16 +04:00
# include "decorations.h"
2007-04-29 21:35:43 +04:00
# include "workspace.h"
# include "effects.h"
2013-04-03 14:19:27 +04:00
# include "screens.h"
2012-11-16 11:23:47 +04:00
# include "virtualdesktops.h"
2007-04-29 21:35:43 +04:00
2012-08-31 15:28:31 +04:00
# ifdef KWIN_BUILD_SCRIPTING
# include "scripting/scripting.h"
# endif
2012-02-26 14:38:16 +04:00
# ifdef KWIN_BUILD_ACTIVITIES
2013-04-04 18:14:12 +04:00
# include "activities.h"
2011-12-05 18:33:14 +04:00
# include <KActivities/Info>
2012-02-26 14:38:16 +04:00
# endif
2010-05-12 00:30:20 +04:00
2013-04-25 19:21:54 +04:00
# include <KDE/KKeySequenceWidget>
2012-08-19 14:00:53 +04:00
# include <KDE/KProcess>
# include <KDE/KToolInvocation>
2012-03-23 05:06:46 +04:00
# ifndef KWIN_NO_XF86VM
# include <X11/extensions/xf86vmode.h>
# endif
2007-04-29 21:35:43 +04:00
# include <fixx11h.h>
2013-08-28 14:27:09 +04:00
# include <QAction>
2013-03-25 00:57:26 +04:00
# include <QCheckBox>
2013-08-19 13:42:16 +04:00
# include <QtConcurrentRun>
2007-04-29 21:35:43 +04:00
# include <QPushButton>
2013-08-28 14:27:09 +04:00
# include <KDE/KGlobalAccel>
2013-03-07 15:55:39 +04:00
# include <KDE/KLocalizedString>
2007-04-29 21:35:43 +04:00
# include <kconfig.h>
# include <QRegExp>
2013-08-19 14:44:30 +04:00
# include <QDialogButtonBox>
2013-04-25 19:21:54 +04:00
# include <QLabel>
2013-08-19 14:44:30 +04:00
# include <QLayout>
2007-04-29 21:35:43 +04:00
# include <QMenu>
# include <QVBoxLayout>
# include <kauthorized.h>
# include <kactioncollection.h>
# include "killwindow.h"
2011-06-30 15:02:30 +04:00
# ifdef KWIN_BUILD_TABBOX
2007-04-29 21:35:43 +04:00
# include "tabbox.h"
2011-06-30 15:02:30 +04:00
# endif
2007-04-29 21:35:43 +04:00
namespace KWin
{
2012-08-19 14:00:53 +04:00
UserActionsMenu : : UserActionsMenu ( QObject * parent )
: QObject ( parent )
, m_menu ( NULL )
, m_desktopMenu ( NULL )
, m_screenMenu ( NULL )
, m_activityMenu ( NULL )
, m_addTabsMenu ( NULL )
, m_switchToTabMenu ( NULL )
2012-08-31 15:28:31 +04:00
# ifdef KWIN_BUILD_SCRIPTING
, m_scriptsMenu ( NULL )
# endif
2012-08-19 14:00:53 +04:00
, m_resizeOperation ( NULL )
, m_moveOperation ( NULL )
, m_maximizeOperation ( NULL )
, m_shadeOperation ( NULL )
, m_keepAboveOperation ( NULL )
, m_keepBelowOperation ( NULL )
, m_fullScreenOperation ( NULL )
, m_noBorderOperation ( NULL )
, m_minimizeOperation ( NULL )
, m_closeOperation ( NULL )
, m_removeFromTabGroup ( NULL )
, m_closeTabGroup ( NULL )
, m_client ( QWeakPointer < Client > ( ) )
{
}
2007-04-29 21:35:43 +04:00
2012-08-19 14:00:53 +04:00
UserActionsMenu : : ~ UserActionsMenu ( )
2011-01-30 17:34:42 +03:00
{
2012-08-19 14:00:53 +04:00
discard ( ) ;
}
2007-04-29 21:35:43 +04:00
2012-08-19 14:00:53 +04:00
bool UserActionsMenu : : isShown ( ) const
{
return m_menu & & m_menu - > isVisible ( ) ;
}
2007-04-29 21:35:43 +04:00
2012-08-19 14:00:53 +04:00
bool UserActionsMenu : : hasClient ( ) const
{
2012-12-21 00:26:33 +04:00
return ! m_client . isNull ( ) & & isShown ( ) ;
2012-08-19 14:00:53 +04:00
}
2012-03-23 11:03:09 +04:00
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : close ( )
{
if ( ! m_menu ) {
return ;
}
m_menu - > close ( ) ;
2012-12-21 00:26:33 +04:00
m_client . clear ( ) ;
2012-08-19 14:00:53 +04:00
}
2012-03-23 11:03:09 +04:00
2012-08-19 14:00:53 +04:00
bool UserActionsMenu : : isMenuClient ( const Client * c ) const
{
if ( ! c | | m_client . isNull ( ) ) {
return false ;
}
return c = = m_client . data ( ) ;
}
2011-01-30 17:34:42 +03:00
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : show ( const QRect & pos , const QWeakPointer < Client > & cl )
{
2013-07-23 09:02:52 +04:00
if ( ! KAuthorized : : authorizeKAction ( QStringLiteral ( " kwin_rmb " ) ) )
2012-08-19 14:00:53 +04:00
return ;
if ( cl . isNull ( ) )
return ;
2012-12-21 00:26:33 +04:00
if ( isShown ( ) ) // recursion
2012-08-19 14:00:53 +04:00
return ;
if ( cl . data ( ) - > isDesktop ( )
| | cl . data ( ) - > isDock ( ) )
return ;
2011-01-30 17:34:42 +03:00
2012-08-19 14:00:53 +04:00
m_client = cl ;
init ( ) ;
Workspace * ws = Workspace : : self ( ) ;
int x = pos . left ( ) ;
int y = pos . bottom ( ) ;
2013-03-25 00:57:26 +04:00
if ( y = = pos . top ( ) ) {
m_client . data ( ) - > blockActivityUpdates ( true ) ;
2012-08-19 14:00:53 +04:00
m_menu - > exec ( QPoint ( x , y ) ) ;
2013-03-25 00:57:26 +04:00
if ( ! m_client . isNull ( ) )
m_client . data ( ) - > blockActivityUpdates ( false ) ;
}
2012-08-19 14:00:53 +04:00
else {
2013-03-25 00:57:26 +04:00
m_client . data ( ) - > blockActivityUpdates ( true ) ;
2012-11-16 11:23:47 +04:00
QRect area = ws - > clientArea ( ScreenArea , QPoint ( x , y ) , VirtualDesktopManager : : self ( ) - > current ( ) ) ;
2012-08-19 14:00:53 +04:00
menuAboutToShow ( ) ; // needed for sizeHint() to be correct :-/
int popupHeight = m_menu - > sizeHint ( ) . height ( ) ;
if ( y + popupHeight < area . height ( ) )
m_menu - > exec ( QPoint ( x , y ) ) ;
else
m_menu - > exec ( QPoint ( x , pos . top ( ) - popupHeight ) ) ;
2013-03-25 00:57:26 +04:00
if ( ! m_client . isNull ( ) )
m_client . data ( ) - > blockActivityUpdates ( true ) ;
2012-08-19 14:00:53 +04:00
}
}
2011-01-30 17:34:42 +03:00
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : helperDialog ( const QString & message , const QWeakPointer < Client > & c )
{
QStringList args ;
QString type ;
2013-08-19 13:42:16 +04:00
auto shortcut = [ ] ( const QString & name ) {
KActionCollection * keys = Workspace : : self ( ) - > actionCollection ( ) ;
QAction * action = keys - > action ( name ) ;
2012-08-19 14:00:53 +04:00
assert ( action ! = NULL ) ;
2013-08-19 13:42:16 +04:00
const auto shortcuts = KGlobalAccel : : self ( ) - > shortcut ( action ) ;
return QStringLiteral ( " %1 (%2) " ) . arg ( action - > text ( ) )
. arg ( shortcuts . isEmpty ( ) ? QString ( ) : shortcuts . first ( ) . toString ( QKeySequence : : NativeText ) ) ;
} ;
if ( message = = QStringLiteral ( " noborderaltf3 " ) ) {
2013-07-23 09:02:52 +04:00
args < < QStringLiteral ( " --msgbox " ) < < i18n (
2012-08-19 14:00:53 +04:00
" You have selected to show a window without its border. \n "
" Without the border, you will not be able to enable the border "
" again using the mouse: use the window operations menu instead, "
" activated using the %1 keyboard shortcut. " ,
2013-08-19 13:42:16 +04:00
shortcut ( QStringLiteral ( " Window Operations Menu " ) ) ) ;
2013-07-23 09:02:52 +04:00
type = QStringLiteral ( " altf3warning " ) ;
} else if ( message = = QStringLiteral ( " fullscreenaltf3 " ) ) {
args < < QStringLiteral ( " --msgbox " ) < < i18n (
2012-08-19 14:00:53 +04:00
" You have selected to show a window in fullscreen mode. \n "
" If the application itself does not have an option to turn the fullscreen "
" mode off you will not be able to disable it "
" again using the mouse: use the window operations menu instead, "
" activated using the %1 keyboard shortcut. " ,
2013-08-19 13:42:16 +04:00
shortcut ( QStringLiteral ( " Window Operations Menu " ) ) ) ;
2013-07-23 09:02:52 +04:00
type = QStringLiteral ( " altf3warning " ) ;
2012-08-19 14:00:53 +04:00
} else
abort ( ) ;
if ( ! type . isEmpty ( ) ) {
2013-07-23 09:02:52 +04:00
KConfig cfg ( QStringLiteral ( " kwin_dialogsrc " ) ) ;
2012-08-19 14:00:53 +04:00
KConfigGroup cg ( & cfg , " Notification Messages " ) ; // Depends on KMessageBox
if ( ! cg . readEntry ( type , true ) )
return ;
2013-07-23 09:02:52 +04:00
args < < QStringLiteral ( " --dontagain " ) < < QStringLiteral ( " kwin_dialogsrc: " ) + type ;
2012-08-19 14:00:53 +04:00
}
if ( ! c . isNull ( ) )
2013-07-23 09:02:52 +04:00
args < < QStringLiteral ( " --embed " ) < < QString : : number ( c . data ( ) - > window ( ) ) ;
2013-08-19 13:42:16 +04:00
QtConcurrent : : run ( [ args ] ( ) {
KProcess : : startDetached ( QStringLiteral ( " kdialog " ) , args ) ;
} ) ;
2012-08-19 14:00:53 +04:00
}
2012-03-23 11:03:09 +04:00
2011-01-30 17:34:42 +03:00
2012-08-19 14:00:53 +04:00
QStringList configModules ( bool controlCenter )
{
QStringList args ;
2013-07-23 09:02:52 +04:00
args < < QStringLiteral ( " kwindecoration " ) ;
2012-08-19 14:00:53 +04:00
if ( controlCenter )
2013-07-23 09:02:52 +04:00
args < < QStringLiteral ( " kwinoptions " ) ;
else if ( KAuthorized : : authorizeControlModule ( QStringLiteral ( " kde-kwinoptions.desktop " ) ) )
args < < QStringLiteral ( " kwinactions " ) < < QStringLiteral ( " kwinfocus " ) < < QStringLiteral ( " kwinmoving " ) < < QStringLiteral ( " kwinadvanced " )
< < QStringLiteral ( " kwinrules " ) < < QStringLiteral ( " kwincompositing " )
2012-08-19 14:00:53 +04:00
# ifdef KWIN_BUILD_TABBOX
2013-07-23 09:02:52 +04:00
< < QStringLiteral ( " kwintabbox " )
2012-08-19 14:00:53 +04:00
# endif
# ifdef KWIN_BUILD_SCREENEDGES
2013-07-23 09:02:52 +04:00
< < QStringLiteral ( " kwinscreenedges " )
2012-08-19 14:00:53 +04:00
# endif
# ifdef KWIN_BUILD_SCRIPTING
2013-07-23 09:02:52 +04:00
< < QStringLiteral ( " kwinscripts " )
2012-08-19 14:00:53 +04:00
# endif
;
return args ;
}
2012-03-23 11:03:09 +04:00
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : configureWM ( )
{
QStringList args ;
2013-07-23 09:02:52 +04:00
args < < QStringLiteral ( " --icon " ) < < QStringLiteral ( " preferences-system-windows " ) < < configModules ( false ) ;
KToolInvocation : : kdeinitExec ( QStringLiteral ( " kcmshell4 " ) , args ) ;
2012-08-19 14:00:53 +04:00
}
2007-04-29 21:35:43 +04:00
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : init ( )
{
if ( m_menu ) {
return ;
}
m_menu = new QMenu ;
connect ( m_menu , SIGNAL ( aboutToShow ( ) ) , this , SLOT ( menuAboutToShow ( ) ) ) ;
2012-11-25 21:50:01 +04:00
connect ( m_menu , SIGNAL ( triggered ( QAction * ) ) , this , SLOT ( slotWindowOperation ( QAction * ) ) , Qt : : QueuedConnection ) ;
2012-08-19 14:00:53 +04:00
QMenu * advancedMenu = new QMenu ( m_menu ) ;
2013-09-06 16:56:16 +04:00
auto setShortcut = [ ] ( QAction * action , const QString & actionName ) {
const auto shortcuts = KGlobalAccel : : self ( ) - > shortcut ( Workspace : : self ( ) - > actionCollection ( ) - > action ( actionName ) ) ;
if ( ! shortcuts . isEmpty ( ) ) {
action - > setShortcut ( shortcuts . first ( ) ) ;
}
} ;
2012-08-19 14:00:53 +04:00
m_moveOperation = advancedMenu - > addAction ( i18n ( " &Move " ) ) ;
2013-09-06 17:12:35 +04:00
m_moveOperation - > setIcon ( QIcon : : fromTheme ( QStringLiteral ( " transform-move " ) ) ) ;
2013-09-06 16:56:16 +04:00
setShortcut ( m_moveOperation , QStringLiteral ( " Window Move " ) ) ;
2012-08-19 14:00:53 +04:00
m_moveOperation - > setData ( Options : : UnrestrictedMoveOp ) ;
m_resizeOperation = advancedMenu - > addAction ( i18n ( " Re&size " ) ) ;
2013-09-06 16:56:16 +04:00
setShortcut ( m_resizeOperation , QStringLiteral ( " Window Resize " ) ) ;
2012-08-19 14:00:53 +04:00
m_resizeOperation - > setData ( Options : : ResizeOp ) ;
m_keepAboveOperation = advancedMenu - > addAction ( i18n ( " Keep &Above Others " ) ) ;
2013-09-06 16:56:16 +04:00
setShortcut ( m_keepAboveOperation , QStringLiteral ( " Window Above Other Windows " ) ) ;
2012-08-19 14:00:53 +04:00
m_keepAboveOperation - > setCheckable ( true ) ;
m_keepAboveOperation - > setData ( Options : : KeepAboveOp ) ;
m_keepBelowOperation = advancedMenu - > addAction ( i18n ( " Keep &Below Others " ) ) ;
2013-09-06 17:12:35 +04:00
m_keepBelowOperation - > setIcon ( QIcon : : fromTheme ( QStringLiteral ( " go-down " ) ) ) ;
2013-09-06 16:56:16 +04:00
setShortcut ( m_keepBelowOperation , QStringLiteral ( " Window Below Other Windows " ) ) ;
2012-08-19 14:00:53 +04:00
m_keepBelowOperation - > setCheckable ( true ) ;
m_keepBelowOperation - > setData ( Options : : KeepBelowOp ) ;
m_fullScreenOperation = advancedMenu - > addAction ( i18n ( " &Fullscreen " ) ) ;
2013-09-06 17:12:35 +04:00
m_fullScreenOperation - > setIcon ( QIcon : : fromTheme ( QStringLiteral ( " view-fullscreen " ) ) ) ;
2013-09-06 16:56:16 +04:00
setShortcut ( m_fullScreenOperation , QStringLiteral ( " Window Fullscreen " ) ) ;
2012-08-19 14:00:53 +04:00
m_fullScreenOperation - > setCheckable ( true ) ;
m_fullScreenOperation - > setData ( Options : : FullScreenOp ) ;
m_shadeOperation = advancedMenu - > addAction ( i18n ( " Sh&ade " ) ) ;
2013-09-06 16:56:16 +04:00
setShortcut ( m_shadeOperation , QStringLiteral ( " Window Shade " ) ) ;
2012-08-19 14:00:53 +04:00
m_shadeOperation - > setCheckable ( true ) ;
m_shadeOperation - > setData ( Options : : ShadeOp ) ;
m_noBorderOperation = advancedMenu - > addAction ( i18n ( " &No Border " ) ) ;
2013-09-06 16:56:16 +04:00
setShortcut ( m_noBorderOperation , QStringLiteral ( " Window No Border " ) ) ;
2012-08-19 14:00:53 +04:00
m_noBorderOperation - > setCheckable ( true ) ;
m_noBorderOperation - > setData ( Options : : NoBorderOp ) ;
advancedMenu - > addSeparator ( ) ;
QAction * action = advancedMenu - > addAction ( i18n ( " Window &Shortcut... " ) ) ;
2013-09-06 17:12:35 +04:00
action - > setIcon ( QIcon : : fromTheme ( QStringLiteral ( " configure-shortcuts " ) ) ) ;
2013-09-06 16:56:16 +04:00
setShortcut ( action , QStringLiteral ( " Setup Window Shortcut " ) ) ;
2012-08-19 14:00:53 +04:00
action - > setData ( Options : : SetupWindowShortcutOp ) ;
action = advancedMenu - > addAction ( i18n ( " &Special Window Settings... " ) ) ;
2013-09-06 17:12:35 +04:00
action - > setIcon ( QIcon : : fromTheme ( QStringLiteral ( " preferences-system-windows-actions " ) ) ) ;
2012-08-19 14:00:53 +04:00
action - > setData ( Options : : WindowRulesOp ) ;
action = advancedMenu - > addAction ( i18n ( " S&pecial Application Settings... " ) ) ;
2013-09-06 17:12:35 +04:00
action - > setIcon ( QIcon : : fromTheme ( QStringLiteral ( " preferences-system-windows-actions " ) ) ) ;
2012-08-19 14:00:53 +04:00
action - > setData ( Options : : ApplicationRulesOp ) ;
2013-09-04 18:10:36 +04:00
if ( ! KSharedConfig : : openConfig ( ) - > isImmutable ( ) & &
2012-08-19 14:00:53 +04:00
! KAuthorized : : authorizeControlModules ( configModules ( true ) ) . isEmpty ( ) ) {
advancedMenu - > addSeparator ( ) ;
action = advancedMenu - > addAction ( i18nc ( " Entry in context menu of window decoration to open the configuration module of KWin " ,
" Window &Manager Settings... " ) ) ;
2013-09-06 17:12:35 +04:00
action - > setIcon ( QIcon : : fromTheme ( QStringLiteral ( " configure " ) ) ) ;
2012-08-19 14:00:53 +04:00
connect ( action , SIGNAL ( triggered ( ) ) , this , SLOT ( configureWM ( ) ) ) ;
}
2011-01-30 17:34:42 +03:00
2012-08-19 14:00:53 +04:00
m_minimizeOperation = m_menu - > addAction ( i18n ( " Mi&nimize " ) ) ;
2013-09-06 16:56:16 +04:00
setShortcut ( m_minimizeOperation , QStringLiteral ( " Window Minimize " ) ) ;
2012-08-19 14:00:53 +04:00
m_minimizeOperation - > setData ( Options : : MinimizeOp ) ;
m_maximizeOperation = m_menu - > addAction ( i18n ( " Ma&ximize " ) ) ;
2013-09-06 16:56:16 +04:00
setShortcut ( m_maximizeOperation , QStringLiteral ( " Window Maximize " ) ) ;
2012-08-19 14:00:53 +04:00
m_maximizeOperation - > setCheckable ( true ) ;
m_maximizeOperation - > setData ( Options : : MaximizeOp ) ;
m_menu - > addSeparator ( ) ;
// Actions for window tabbing
2013-04-08 14:31:16 +04:00
if ( decorationPlugin ( ) - > supportsTabbing ( ) ) {
2012-08-19 14:00:53 +04:00
m_removeFromTabGroup = m_menu - > addAction ( i18n ( " &Untab " ) ) ;
2013-09-06 16:56:16 +04:00
setShortcut ( m_removeFromTabGroup , QStringLiteral ( " Untab " ) ) ;
2012-08-19 14:00:53 +04:00
m_removeFromTabGroup - > setData ( Options : : RemoveTabFromGroupOp ) ;
2009-11-15 06:24:04 +03:00
2012-08-19 14:00:53 +04:00
m_closeTabGroup = m_menu - > addAction ( i18n ( " Close Entire &Group " ) ) ;
2013-09-06 17:12:35 +04:00
m_closeTabGroup - > setIcon ( QIcon : : fromTheme ( QStringLiteral ( " window-close " ) ) ) ;
2013-09-06 16:56:16 +04:00
setShortcut ( m_closeTabGroup , QStringLiteral ( " Close TabGroup " ) ) ;
2012-08-19 14:00:53 +04:00
m_closeTabGroup - > setData ( Options : : CloseTabGroupOp ) ;
2010-05-07 20:03:14 +04:00
2012-08-19 14:00:53 +04:00
m_menu - > addSeparator ( ) ;
}
2009-04-27 21:30:33 +04:00
2012-08-19 14:00:53 +04:00
m_menu - > addSeparator ( ) ;
2007-04-29 21:35:43 +04:00
2012-08-19 14:00:53 +04:00
action = m_menu - > addMenu ( advancedMenu ) ;
2013-05-15 22:55:49 +04:00
action - > setText ( i18n ( " &More Actions " ) ) ;
2007-04-29 21:35:43 +04:00
2012-08-19 14:00:53 +04:00
m_menu - > addSeparator ( ) ;
2008-08-07 15:51:20 +04:00
2012-08-19 14:00:53 +04:00
m_closeOperation = m_menu - > addAction ( i18n ( " &Close " ) ) ;
2013-09-06 17:12:35 +04:00
m_closeOperation - > setIcon ( QIcon : : fromTheme ( QStringLiteral ( " window-close " ) ) ) ;
2013-09-06 16:56:16 +04:00
setShortcut ( m_closeOperation , QStringLiteral ( " Window Close " ) ) ;
2012-08-19 14:00:53 +04:00
m_closeOperation - > setData ( Options : : CloseOp ) ;
2011-08-19 23:53:30 +04:00
}
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : discard ( )
2011-08-19 23:53:30 +04:00
{
2012-08-19 14:00:53 +04:00
delete m_menu ;
m_menu = NULL ;
m_desktopMenu = NULL ;
m_screenMenu = NULL ;
m_activityMenu = NULL ;
m_switchToTabMenu = NULL ;
m_addTabsMenu = NULL ;
2012-08-31 15:28:31 +04:00
# ifdef KWIN_BUILD_SCRIPTING
m_scriptsMenu = NULL ;
# endif
2011-08-19 23:53:30 +04:00
}
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : menuAboutToShow ( )
2011-01-30 17:34:42 +03:00
{
2012-08-19 14:00:53 +04:00
if ( m_client . isNull ( ) | | ! m_menu )
2007-04-29 21:35:43 +04:00
return ;
2012-11-16 11:23:47 +04:00
if ( VirtualDesktopManager : : self ( ) - > count ( ) = = 1 ) {
2012-08-19 14:00:53 +04:00
delete m_desktopMenu ;
m_desktopMenu = 0 ;
2011-01-30 17:34:42 +03:00
} else {
2007-04-29 21:35:43 +04:00
initDesktopPopup ( ) ;
2011-01-30 17:34:42 +03:00
}
2013-04-03 14:19:27 +04:00
if ( screens ( ) - > count ( ) = = 1 | | ( ! m_client . data ( ) - > isMovable ( ) & & ! m_client . data ( ) - > isMovableAcrossScreens ( ) ) ) {
2012-08-19 14:00:53 +04:00
delete m_screenMenu ;
m_screenMenu = NULL ;
2012-08-18 00:32:06 +04:00
} else {
initScreenPopup ( ) ;
}
2012-04-12 23:52:44 +04:00
# ifdef KWIN_BUILD_ACTIVITIES
2013-04-04 18:14:12 +04:00
Activities : : self ( ) - > update ( true , false , this , " showHideActivityMenu " ) ;
2012-04-12 23:52:44 +04:00
# endif
2007-04-29 21:35:43 +04:00
2012-08-19 14:00:53 +04:00
m_resizeOperation - > setEnabled ( m_client . data ( ) - > isResizable ( ) ) ;
m_moveOperation - > setEnabled ( m_client . data ( ) - > isMovableAcrossScreens ( ) ) ;
m_maximizeOperation - > setEnabled ( m_client . data ( ) - > isMaximizable ( ) ) ;
m_maximizeOperation - > setChecked ( m_client . data ( ) - > maximizeMode ( ) = = Client : : MaximizeFull ) ;
m_shadeOperation - > setEnabled ( m_client . data ( ) - > isShadeable ( ) ) ;
m_shadeOperation - > setChecked ( m_client . data ( ) - > shadeMode ( ) ! = ShadeNone ) ;
m_keepAboveOperation - > setChecked ( m_client . data ( ) - > keepAbove ( ) ) ;
m_keepBelowOperation - > setChecked ( m_client . data ( ) - > keepBelow ( ) ) ;
m_fullScreenOperation - > setEnabled ( m_client . data ( ) - > userCanSetFullScreen ( ) ) ;
m_fullScreenOperation - > setChecked ( m_client . data ( ) - > isFullScreen ( ) ) ;
m_noBorderOperation - > setEnabled ( m_client . data ( ) - > userCanSetNoBorder ( ) ) ;
m_noBorderOperation - > setChecked ( m_client . data ( ) - > noBorder ( ) ) ;
m_minimizeOperation - > setEnabled ( m_client . data ( ) - > isMinimizable ( ) ) ;
m_closeOperation - > setEnabled ( m_client . data ( ) - > isCloseable ( ) ) ;
2013-04-08 14:31:16 +04:00
if ( decorationPlugin ( ) - > supportsTabbing ( ) ) {
2012-01-12 10:42:55 +04:00
initTabbingPopups ( ) ;
} else {
2012-08-19 14:00:53 +04:00
delete m_addTabsMenu ;
m_addTabsMenu = 0 ;
2011-01-30 17:34:42 +03:00
}
2012-08-31 15:28:31 +04:00
# ifdef KWIN_BUILD_SCRIPTING
// drop the existing scripts menu
delete m_scriptsMenu ;
m_scriptsMenu = NULL ;
// ask scripts whether they want to add entries for the given Client
m_scriptsMenu = new QMenu ( m_menu ) ;
2013-04-04 11:11:17 +04:00
QList < QAction * > scriptActions = Scripting : : self ( ) - > actionsForUserActionMenu ( m_client . data ( ) , m_scriptsMenu ) ;
2012-08-31 15:28:31 +04:00
if ( ! scriptActions . isEmpty ( ) ) {
m_scriptsMenu - > addActions ( scriptActions ) ;
QAction * action = m_scriptsMenu - > menuAction ( ) ;
// set it as the first item after desktop
m_menu - > insertAction ( m_closeOperation , action ) ;
action - > setText ( i18n ( " &Extensions " ) ) ;
} else {
delete m_scriptsMenu ;
m_scriptsMenu = NULL ;
}
# endif
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : showHideActivityMenu ( )
2012-04-12 23:52:44 +04:00
{
# ifdef KWIN_BUILD_ACTIVITIES
2013-04-04 18:14:12 +04:00
const QStringList & openActivities_ = Activities : : self ( ) - > running ( ) ;
2013-11-01 15:29:05 +04:00
qDebug ( ) < < " activities: " < < openActivities_ . size ( ) ;
2012-04-12 23:52:44 +04:00
if ( openActivities_ . size ( ) < 2 ) {
2012-08-19 14:00:53 +04:00
delete m_activityMenu ;
m_activityMenu = 0 ;
2012-04-12 23:52:44 +04:00
} else {
initActivityPopup ( ) ;
}
# endif
}
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : selectPopupClientTab ( QAction * action )
2011-01-30 17:34:42 +03:00
{
2012-08-19 14:00:53 +04:00
if ( ! ( ! m_client . isNull ( ) & & m_client . data ( ) - > tabGroup ( ) ) | | ! action - > data ( ) . isValid ( ) )
2012-01-12 10:42:55 +04:00
return ;
if ( Client * other = action - > data ( ) . value < Client * > ( ) ) {
2012-08-19 14:00:53 +04:00
m_client . data ( ) - > tabGroup ( ) - > setCurrent ( other ) ;
2009-11-15 06:24:04 +03:00
return ;
}
2012-01-12 10:42:55 +04:00
// failed conversion, try "1" & "2", being prev and next
int direction = action - > data ( ) . toInt ( ) ;
if ( direction = = 1 )
2012-08-19 14:00:53 +04:00
m_client . data ( ) - > tabGroup ( ) - > activatePrev ( ) ;
2012-01-12 10:42:55 +04:00
else if ( direction = = 2 )
2012-08-19 14:00:53 +04:00
m_client . data ( ) - > tabGroup ( ) - > activateNext ( ) ;
2011-01-30 17:34:42 +03:00
}
2009-11-15 06:24:04 +03:00
2012-01-12 10:42:55 +04:00
static QString shortCaption ( const QString & s )
2011-01-30 17:34:42 +03:00
{
2012-01-12 10:42:55 +04:00
if ( s . length ( ) < 64 )
return s ;
QString ss = s ;
2013-07-23 09:02:52 +04:00
return ss . replace ( 32 , s . length ( ) - 64 , QStringLiteral ( " ... " ) ) ;
2012-01-12 10:42:55 +04:00
}
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : rebuildTabListPopup ( )
2012-01-12 10:42:55 +04:00
{
2012-08-19 14:00:53 +04:00
Q_ASSERT ( m_switchToTabMenu ) ;
2012-01-12 10:42:55 +04:00
2012-08-19 14:00:53 +04:00
m_switchToTabMenu - > clear ( ) ;
2012-01-12 10:42:55 +04:00
// whatever happens "0x1" and "0x2" are no heap positions ;-)
2012-08-19 14:00:53 +04:00
m_switchToTabMenu - > addAction ( i18nc ( " Switch to tab -> Previous " , " Previous " ) ) - > setData ( 1 ) ;
m_switchToTabMenu - > addAction ( i18nc ( " Switch to tab -> Next " , " Next " ) ) - > setData ( 2 ) ;
2012-01-12 10:42:55 +04:00
2012-08-19 14:00:53 +04:00
m_switchToTabMenu - > addSeparator ( ) ;
2012-01-12 10:42:55 +04:00
2012-08-19 14:00:53 +04:00
for ( QList < Client * > : : const_iterator i = m_client . data ( ) - > tabGroup ( ) - > clients ( ) . constBegin ( ) ,
end = m_client . data ( ) - > tabGroup ( ) - > clients ( ) . constEnd ( ) ; i ! = end ; + + i ) {
if ( ( * i ) - > noBorder ( ) | | * i = = m_client . data ( ) - > tabGroup ( ) - > current ( ) )
2012-01-12 10:42:55 +04:00
continue ; // cannot tab there anyway
2012-08-19 14:00:53 +04:00
m_switchToTabMenu - > addAction ( shortCaption ( ( * i ) - > caption ( ) ) ) - > setData ( QVariant : : fromValue ( * i ) ) ;
2009-11-15 06:24:04 +03:00
}
2011-01-30 17:34:42 +03:00
}
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : entabPopupClient ( QAction * action )
2011-01-30 17:34:42 +03:00
{
2012-08-19 14:00:53 +04:00
if ( m_client . isNull ( ) | | ! action - > data ( ) . isValid ( ) )
2012-01-12 10:42:55 +04:00
return ;
2012-01-12 10:42:55 +04:00
Client * other = action - > data ( ) . value < Client * > ( ) ;
2012-08-19 14:00:53 +04:00
if ( ! Workspace : : self ( ) - > clientList ( ) . contains ( other ) ) // might have been lost betwenn pop-up and selection
2012-01-12 10:42:55 +04:00
return ;
2012-08-19 14:00:53 +04:00
m_client . data ( ) - > tabBehind ( other , true ) ;
2012-01-12 10:42:55 +04:00
if ( options - > focusPolicyIsReasonable ( ) )
2012-08-19 14:00:53 +04:00
Workspace : : self ( ) - > requestFocus ( m_client . data ( ) ) ;
2011-01-30 17:34:42 +03:00
}
2009-11-15 06:24:04 +03:00
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : rebuildTabGroupPopup ( )
2011-01-30 17:34:42 +03:00
{
2012-08-19 14:00:53 +04:00
Q_ASSERT ( m_addTabsMenu ) ;
2012-01-12 10:42:55 +04:00
2012-08-19 14:00:53 +04:00
m_addTabsMenu - > clear ( ) ;
2012-01-12 10:42:55 +04:00
QList < Client * > handled ;
2012-08-19 14:00:53 +04:00
const ClientList & clientList = Workspace : : self ( ) - > clientList ( ) ;
for ( QList < Client * > : : const_iterator i = clientList . constBegin ( ) , end = clientList . constEnd ( ) ; i ! = end ; + + i ) {
if ( * i = = m_client . data ( ) | | ( * i ) - > noBorder ( ) )
2012-01-12 10:42:55 +04:00
continue ;
2012-08-19 14:00:53 +04:00
m_addTabsMenu - > addAction ( shortCaption ( ( * i ) - > caption ( ) ) ) - > setData ( QVariant : : fromValue ( * i ) ) ;
2012-01-12 10:42:55 +04:00
}
2013-03-24 01:20:35 +04:00
if ( m_addTabsMenu - > actions ( ) . isEmpty ( ) )
m_addTabsMenu - > addAction ( i18nc ( " There's no window available to be attached as tab to this one " , " None available " ) ) - > setEnabled ( false ) ;
2011-01-30 17:34:42 +03:00
}
2009-11-15 06:24:04 +03:00
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : initTabbingPopups ( )
2011-01-30 17:34:42 +03:00
{
2012-01-12 10:42:55 +04:00
bool needTabManagers = false ;
2012-08-19 14:00:53 +04:00
if ( m_client . data ( ) - > tabGroup ( ) & & m_client . data ( ) - > tabGroup ( ) - > count ( ) > 1 ) {
2012-01-12 10:42:55 +04:00
needTabManagers = true ;
2012-08-19 14:00:53 +04:00
if ( ! m_switchToTabMenu ) {
m_switchToTabMenu = new QMenu ( i18n ( " Switch to Tab " ) , m_menu ) ;
connect ( m_switchToTabMenu , SIGNAL ( triggered ( QAction * ) ) , SLOT ( selectPopupClientTab ( QAction * ) ) ) ;
connect ( m_switchToTabMenu , SIGNAL ( aboutToShow ( ) ) , SLOT ( rebuildTabListPopup ( ) ) ) ;
m_menu - > insertMenu ( m_removeFromTabGroup , m_switchToTabMenu ) ;
2009-11-15 06:24:04 +03:00
}
2012-01-12 10:42:55 +04:00
} else {
2012-08-19 14:00:53 +04:00
delete m_switchToTabMenu ;
m_switchToTabMenu = 0 ;
2012-01-12 10:42:55 +04:00
}
2012-08-19 14:00:53 +04:00
if ( ! m_addTabsMenu ) {
2013-05-15 22:55:49 +04:00
m_addTabsMenu = new QMenu ( i18n ( " &Attach as tab to " ) , m_menu ) ;
2012-08-19 14:00:53 +04:00
connect ( m_addTabsMenu , SIGNAL ( triggered ( QAction * ) ) , SLOT ( entabPopupClient ( QAction * ) ) ) ;
connect ( m_addTabsMenu , SIGNAL ( aboutToShow ( ) ) , SLOT ( rebuildTabGroupPopup ( ) ) ) ;
m_menu - > insertMenu ( m_removeFromTabGroup , m_addTabsMenu ) ;
2009-11-15 06:24:04 +03:00
}
2012-01-12 10:42:55 +04:00
2012-08-19 14:00:53 +04:00
m_removeFromTabGroup - > setVisible ( needTabManagers ) ;
m_closeTabGroup - > setVisible ( needTabManagers ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : initDesktopPopup ( )
2011-01-30 17:34:42 +03:00
{
2012-08-19 14:00:53 +04:00
if ( m_desktopMenu )
2007-04-29 21:35:43 +04:00
return ;
2012-08-19 14:00:53 +04:00
m_desktopMenu = new QMenu ( m_menu ) ;
connect ( m_desktopMenu , SIGNAL ( triggered ( QAction * ) ) , SLOT ( slotSendToDesktop ( QAction * ) ) ) ;
connect ( m_desktopMenu , SIGNAL ( aboutToShow ( ) ) , SLOT ( desktopPopupAboutToShow ( ) ) ) ;
2007-04-29 21:35:43 +04:00
2012-08-19 14:00:53 +04:00
QAction * action = m_desktopMenu - > menuAction ( ) ;
2009-07-01 19:16:26 +04:00
// set it as the first item
2012-08-19 14:00:53 +04:00
m_menu - > insertAction ( m_minimizeOperation , action ) ;
2012-03-23 11:03:09 +04:00
action - > setText ( i18n ( " Move To &Desktop " ) ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : initScreenPopup ( )
2012-08-18 00:32:06 +04:00
{
2012-08-19 14:00:53 +04:00
if ( m_screenMenu ) {
2012-08-18 00:32:06 +04:00
return ;
}
2012-08-19 14:00:53 +04:00
m_screenMenu = new QMenu ( m_menu ) ;
connect ( m_screenMenu , SIGNAL ( triggered ( QAction * ) ) , SLOT ( slotSendToScreen ( QAction * ) ) ) ;
connect ( m_screenMenu , SIGNAL ( aboutToShow ( ) ) , SLOT ( screenPopupAboutToShow ( ) ) ) ;
2012-08-18 00:32:06 +04:00
2012-08-19 14:00:53 +04:00
QAction * action = m_screenMenu - > menuAction ( ) ;
2012-08-18 00:32:06 +04:00
// set it as the first item after desktop
2012-08-19 14:00:53 +04:00
m_menu - > insertAction ( m_activityMenu ? m_activityMenu - > menuAction ( ) : m_minimizeOperation , action ) ;
2012-08-18 00:32:06 +04:00
action - > setText ( i18n ( " Move To &Screen " ) ) ;
}
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : initActivityPopup ( )
2011-01-30 17:34:42 +03:00
{
2012-08-19 14:00:53 +04:00
if ( m_activityMenu )
2010-05-12 00:30:20 +04:00
return ;
2012-08-19 14:00:53 +04:00
m_activityMenu = new QMenu ( m_menu ) ;
connect ( m_activityMenu , SIGNAL ( triggered ( QAction * ) ) ,
2011-01-30 17:34:42 +03:00
this , SLOT ( slotToggleOnActivity ( QAction * ) ) ) ;
2012-08-19 14:00:53 +04:00
connect ( m_activityMenu , SIGNAL ( aboutToShow ( ) ) ,
2011-01-30 17:34:42 +03:00
this , SLOT ( activityPopupAboutToShow ( ) ) ) ;
2010-05-12 00:30:20 +04:00
2012-08-19 14:00:53 +04:00
QAction * action = m_activityMenu - > menuAction ( ) ;
2010-05-12 00:30:20 +04:00
// set it as the first item
2012-08-19 14:00:53 +04:00
m_menu - > insertAction ( m_minimizeOperation , action ) ;
2011-01-30 17:34:42 +03:00
action - > setText ( i18n ( " Ac&tivities " ) ) ; //FIXME is that a good string?
}
2010-05-12 00:30:20 +04:00
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : desktopPopupAboutToShow ( )
2011-01-30 17:34:42 +03:00
{
2012-08-19 14:00:53 +04:00
if ( ! m_desktopMenu )
2007-04-29 21:35:43 +04:00
return ;
2012-11-16 11:23:47 +04:00
const VirtualDesktopManager * vds = VirtualDesktopManager : : self ( ) ;
2007-04-29 21:35:43 +04:00
2012-08-19 14:00:53 +04:00
m_desktopMenu - > clear ( ) ;
QActionGroup * group = new QActionGroup ( m_desktopMenu ) ;
QAction * action = m_desktopMenu - > addAction ( i18n ( " &All Desktops " ) ) ;
2011-01-30 17:34:42 +03:00
action - > setData ( 0 ) ;
action - > setCheckable ( true ) ;
2012-03-23 11:11:55 +04:00
group - > addAction ( action ) ;
2007-04-29 21:35:43 +04:00
2012-08-19 14:00:53 +04:00
if ( ! m_client . isNull ( ) & & m_client . data ( ) - > isOnAllDesktops ( ) )
2011-01-30 17:34:42 +03:00
action - > setChecked ( true ) ;
2012-08-19 14:00:53 +04:00
m_desktopMenu - > addSeparator ( ) ;
2007-04-29 21:35:43 +04:00
2012-11-16 11:23:47 +04:00
const uint BASE = 10 ;
for ( uint i = 1 ; i < = vds - > count ( ) ; + + i ) {
2013-07-23 09:02:52 +04:00
QString basic_name ( QStringLiteral ( " %1 %2 " ) ) ;
2011-01-30 17:34:42 +03:00
if ( i < BASE ) {
2013-07-23 09:02:52 +04:00
basic_name . prepend ( QStringLiteral ( " & " ) ) ;
2007-04-29 21:35:43 +04:00
}
2013-07-23 09:02:52 +04:00
action = m_desktopMenu - > addAction ( basic_name . arg ( i ) . arg ( vds - > name ( i ) . replace ( QStringLiteral ( " & " ) , QStringLiteral ( " && " ) ) ) ) ;
2011-01-30 17:34:42 +03:00
action - > setData ( i ) ;
action - > setCheckable ( true ) ;
2012-03-23 11:11:55 +04:00
group - > addAction ( action ) ;
2007-04-29 21:35:43 +04:00
2012-08-19 14:00:53 +04:00
if ( ! m_client . isNull ( ) & &
2012-11-16 11:23:47 +04:00
! m_client . data ( ) - > isOnAllDesktops ( ) & & m_client . data ( ) - > isOnDesktop ( i ) )
2011-01-30 17:34:42 +03:00
action - > setChecked ( true ) ;
2007-04-29 21:35:43 +04:00
}
2012-04-29 19:32:34 +04:00
2012-08-19 14:00:53 +04:00
m_desktopMenu - > addSeparator ( ) ;
action = m_desktopMenu - > addAction ( i18nc ( " Create a new desktop and move there the window " , " &New Desktop " ) ) ;
2012-11-16 11:23:47 +04:00
action - > setData ( vds - > count ( ) + 1 ) ;
2012-04-29 19:32:34 +04:00
2012-11-16 11:23:47 +04:00
if ( vds - > count ( ) > = vds - > maximum ( ) )
2012-04-29 19:32:34 +04:00
action - > setEnabled ( false ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : screenPopupAboutToShow ( )
2012-08-18 00:32:06 +04:00
{
2012-08-19 14:00:53 +04:00
if ( ! m_screenMenu ) {
2012-08-18 00:32:06 +04:00
return ;
}
2012-08-19 14:00:53 +04:00
m_screenMenu - > clear ( ) ;
QActionGroup * group = new QActionGroup ( m_screenMenu ) ;
2012-08-18 00:32:06 +04:00
2013-04-03 14:19:27 +04:00
for ( int i = 0 ; i < screens ( ) - > count ( ) ; + + i ) {
2012-08-18 00:32:06 +04:00
// TODO: retrieve the screen name?
// assumption: there are not more than 9 screens attached.
2012-08-19 14:00:53 +04:00
QAction * action = m_screenMenu - > addAction ( i18nc ( " @item:inmenu List of all Screens to send a window to " ,
2012-08-18 00:32:06 +04:00
" Screen &%1 " , ( i + 1 ) ) ) ;
action - > setData ( i ) ;
action - > setCheckable ( true ) ;
2012-08-19 14:00:53 +04:00
if ( ! m_client . isNull ( ) & & i = = m_client . data ( ) - > screen ( ) ) {
2012-08-18 00:32:06 +04:00
action - > setChecked ( true ) ;
}
group - > addAction ( action ) ;
}
}
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : activityPopupAboutToShow ( )
2011-01-30 17:34:42 +03:00
{
2012-08-19 14:00:53 +04:00
if ( ! m_activityMenu )
2010-05-12 00:30:20 +04:00
return ;
2012-02-26 14:38:16 +04:00
# ifdef KWIN_BUILD_ACTIVITIES
2012-08-19 14:00:53 +04:00
m_activityMenu - > clear ( ) ;
QAction * action = m_activityMenu - > addAction ( i18n ( " &All Activities " ) ) ;
2011-01-30 17:34:42 +03:00
action - > setData ( QString ( ) ) ;
action - > setCheckable ( true ) ;
2010-05-12 00:30:20 +04:00
2012-08-19 14:00:53 +04:00
if ( ! m_client . isNull ( ) & & m_client . data ( ) - > isOnAllActivities ( ) )
2011-01-30 17:34:42 +03:00
action - > setChecked ( true ) ;
2012-08-19 14:00:53 +04:00
m_activityMenu - > addSeparator ( ) ;
2010-05-12 00:30:20 +04:00
2013-04-04 18:14:12 +04:00
foreach ( const QString & id , Activities : : self ( ) - > running ( ) ) {
2011-11-05 02:23:52 +04:00
KActivities : : Info activity ( id ) ;
2010-11-01 22:53:22 +03:00
QString name = activity . name ( ) ;
2010-05-12 00:30:20 +04:00
name . replace ( ' & ' , " && " ) ;
2013-03-25 00:57:26 +04:00
QWidgetAction * action = new QWidgetAction ( m_activityMenu ) ;
QCheckBox * box = new QCheckBox ( name , m_activityMenu ) ;
action - > setDefaultWidget ( box ) ;
const QString icon = activity . icon ( ) ;
if ( ! icon . isEmpty ( ) )
2013-09-06 17:12:35 +04:00
box - > setIcon ( QIcon : : fromTheme ( icon ) ) ;
2013-03-25 00:57:26 +04:00
box - > setBackgroundRole ( m_activityMenu - > backgroundRole ( ) ) ;
box - > setForegroundRole ( m_activityMenu - > foregroundRole ( ) ) ;
box - > setPalette ( m_activityMenu - > palette ( ) ) ;
connect ( box , SIGNAL ( clicked ( bool ) ) , action , SIGNAL ( triggered ( bool ) ) ) ;
m_activityMenu - > addAction ( action ) ;
2011-01-30 17:34:42 +03:00
action - > setData ( id ) ;
2010-05-12 00:30:20 +04:00
2012-08-19 14:00:53 +04:00
if ( ! m_client . isNull ( ) & &
! m_client . data ( ) - > isOnAllActivities ( ) & & m_client . data ( ) - > isOnActivity ( id ) )
2013-03-25 00:57:26 +04:00
box - > setChecked ( true ) ;
2010-05-12 00:30:20 +04:00
}
2012-02-26 14:38:16 +04:00
# endif
2011-01-30 17:34:42 +03:00
}
2010-05-12 00:30:20 +04:00
2012-08-19 14:00:53 +04:00
void UserActionsMenu : : slotWindowOperation ( QAction * action )
{
if ( ! action - > data ( ) . isValid ( ) )
return ;
Options : : WindowOperation op = static_cast < Options : : WindowOperation > ( action - > data ( ) . toInt ( ) ) ;
QWeakPointer < Client > c = ( ! m_client . isNull ( ) ) ? m_client : QWeakPointer < Client > ( Workspace : : self ( ) - > activeClient ( ) ) ;
if ( c . isNull ( ) )
return ;
QString type ;
switch ( op ) {
case Options : : FullScreenOp :
if ( ! c . data ( ) - > isFullScreen ( ) & & c . data ( ) - > userCanSetFullScreen ( ) )
2013-07-23 09:02:52 +04:00
type = QStringLiteral ( " fullscreenaltf3 " ) ;
2012-08-19 14:00:53 +04:00
break ;
case Options : : NoBorderOp :
if ( ! c . data ( ) - > noBorder ( ) & & c . data ( ) - > userCanSetNoBorder ( ) )
2013-07-23 09:02:52 +04:00
type = QStringLiteral ( " noborderaltf3 " ) ;
2012-08-19 14:00:53 +04:00
break ;
default :
break ;
} ;
if ( ! type . isEmpty ( ) )
helperDialog ( type , c ) ;
2013-08-19 14:15:42 +04:00
// need to delay performing the window operation as we need to have the
// user actions menu closed before we destroy the decoration. Otherwise Qt crashes
qRegisterMetaType < KDecorationDefines : : WindowOperation > ( ) ;
QMetaObject : : invokeMethod ( workspace ( ) , " performWindowOperation " ,
Qt : : QueuedConnection ,
Q_ARG ( KWin : : Client * , c . data ( ) ) ,
Q_ARG ( KDecorationDefines : : WindowOperation , op ) ) ;
2012-08-19 14:00:53 +04:00
}
void UserActionsMenu : : slotSendToDesktop ( QAction * action )
{
2012-11-16 11:23:47 +04:00
bool ok = false ;
uint desk = action - > data ( ) . toUInt ( & ok ) ;
if ( ! ok ) {
return ;
}
2012-08-19 14:00:53 +04:00
if ( m_client . isNull ( ) )
return ;
Workspace * ws = Workspace : : self ( ) ;
2012-11-16 11:23:47 +04:00
VirtualDesktopManager * vds = VirtualDesktopManager : : self ( ) ;
2012-08-19 14:00:53 +04:00
if ( desk = = 0 ) {
// the 'on_all_desktops' menu entry
m_client . data ( ) - > setOnAllDesktops ( ! m_client . data ( ) - > isOnAllDesktops ( ) ) ;
return ;
2012-11-16 11:23:47 +04:00
} else if ( desk > vds - > count ( ) ) {
vds - > setCount ( desk ) ;
2012-08-19 14:00:53 +04:00
}
ws - > sendClientToDesktop ( m_client . data ( ) , desk , false ) ;
}
void UserActionsMenu : : slotSendToScreen ( QAction * action )
{
const int screen = action - > data ( ) . toInt ( ) ;
if ( m_client . isNull ( ) ) {
return ;
}
2013-04-03 14:19:27 +04:00
if ( screen > = screens ( ) - > count ( ) ) {
2012-08-19 14:00:53 +04:00
return ;
}
2013-04-03 14:19:27 +04:00
Workspace : : self ( ) - > sendClientToScreen ( m_client . data ( ) , screen ) ;
2012-08-19 14:00:53 +04:00
}
void UserActionsMenu : : slotToggleOnActivity ( QAction * action )
{
2013-04-04 18:14:12 +04:00
# ifdef KWIN_BUILD_ACTIVITIES
2012-08-19 14:00:53 +04:00
QString activity = action - > data ( ) . toString ( ) ;
if ( m_client . isNull ( ) )
return ;
if ( activity . isEmpty ( ) ) {
// the 'on_all_activities' menu entry
m_client . data ( ) - > setOnAllActivities ( ! m_client . data ( ) - > isOnAllActivities ( ) ) ;
return ;
}
2013-04-04 18:14:12 +04:00
Activities : : self ( ) - > toggleClientOnActivity ( m_client . data ( ) , activity , false ) ;
2013-03-25 00:57:26 +04:00
if ( m_activityMenu & & m_activityMenu - > isVisible ( ) & & m_activityMenu - > actions ( ) . count ( ) ) {
m_activityMenu - > actions ( ) . at ( 0 ) - > setChecked ( m_client . data ( ) - > isOnAllActivities ( ) ) ;
}
2013-04-04 18:14:12 +04:00
# endif
2012-08-19 14:00:53 +04:00
}
2013-04-25 19:21:54 +04:00
//****************************************
// ShortcutDialog
//****************************************
ShortcutDialog : : ShortcutDialog ( const QKeySequence & cut )
: _shortcut ( cut )
2013-08-19 14:44:30 +04:00
, m_buttons ( new QDialogButtonBox ( QDialogButtonBox : : Ok | QDialogButtonBox : : Cancel , this ) )
2013-04-25 19:21:54 +04:00
{
QWidget * vBoxContainer = new QWidget ( this ) ;
vBoxContainer - > setLayout ( new QVBoxLayout ( vBoxContainer ) ) ;
vBoxContainer - > layout ( ) - > addWidget ( widget = new KKeySequenceWidget ( vBoxContainer ) ) ;
vBoxContainer - > layout ( ) - > addWidget ( warning = new QLabel ( vBoxContainer ) ) ;
warning - > hide ( ) ;
widget - > setKeySequence ( cut ) ;
// To not check for conflicting shortcuts. The widget would use a message
// box which brings down kwin.
widget - > setCheckForConflictsAgainst ( KKeySequenceWidget : : None ) ;
// It's a global shortcut so don't allow multikey shortcuts
widget - > setMultiKeyShortcutsAllowed ( false ) ;
// Listen to changed shortcuts
connect (
widget , SIGNAL ( keySequenceChanged ( QKeySequence ) ) ,
SLOT ( keySequenceChanged ( QKeySequence ) ) ) ;
2013-08-19 14:44:30 +04:00
QVBoxLayout * mainLayout = new QVBoxLayout ( this ) ;
mainLayout - > addWidget ( vBoxContainer ) ;
m_buttons - > button ( QDialogButtonBox : : Ok ) - > setDefault ( true ) ;
connect ( m_buttons , & QDialogButtonBox : : accepted , this , & ShortcutDialog : : accept ) ;
connect ( m_buttons , & QDialogButtonBox : : rejected , this , & QDialog : : reject ) ;
mainLayout - > addWidget ( m_buttons ) ;
2013-04-25 19:21:54 +04:00
widget - > setFocus ( ) ;
2013-08-19 14:44:30 +04:00
setWindowFlags ( Qt : : Popup | Qt : : X11BypassWindowManagerHint ) ;
2013-04-25 19:21:54 +04:00
}
void ShortcutDialog : : accept ( )
{
QKeySequence seq = shortcut ( ) ;
if ( ! seq . isEmpty ( ) ) {
if ( seq [ 0 ] = = Qt : : Key_Escape ) {
reject ( ) ;
return ;
}
if ( seq [ 0 ] = = Qt : : Key_Space
| | ( seq [ 0 ] & Qt : : KeyboardModifierMask ) = = 0 ) {
// clear
widget - > clearKeySequence ( ) ;
2013-08-19 14:44:30 +04:00
QDialog : : accept ( ) ;
2013-04-25 19:21:54 +04:00
return ;
}
}
2013-08-19 14:44:30 +04:00
QDialog : : accept ( ) ;
2013-04-25 19:21:54 +04:00
}
void ShortcutDialog : : done ( int r )
{
2013-08-19 14:44:30 +04:00
QDialog : : done ( r ) ;
2013-04-25 19:21:54 +04:00
emit dialogDone ( r = = Accepted ) ;
}
void ShortcutDialog : : keySequenceChanged ( const QKeySequence & seq )
{
activateWindow ( ) ; // where is the kbd focus lost? cause of popup state?
if ( _shortcut = = seq )
return ; // don't try to update the same
if ( seq . isEmpty ( ) ) { // clear
_shortcut = seq ;
return ;
}
// Check if the key sequence is used currently
QString sc = seq . toString ( ) ;
// NOTICE - seq.toString() & the entries in "conflicting" randomly get invalidated after the next call (if no sc has been set & conflicting isn't empty?!)
QList < KGlobalShortcutInfo > conflicting = KGlobalAccel : : getGlobalShortcutsByKey ( seq ) ;
if ( ! conflicting . isEmpty ( ) ) {
const KGlobalShortcutInfo & conflict = conflicting . at ( 0 ) ;
warning - > setText ( i18nc ( " '%1' is a keyboard shortcut like 'ctrl+w' " ,
" <b>%1</b> is already in use " , sc ) ) ;
warning - > setToolTip ( i18nc ( " keyboard shortcut '%1' is used by action '%2' in application '%3' " ,
" <b>%1</b> is used by %2 in %3 " , sc , conflict . friendlyName ( ) , conflict . componentFriendlyName ( ) ) ) ;
warning - > show ( ) ;
widget - > setKeySequence ( shortcut ( ) ) ;
} else if ( seq ! = _shortcut ) {
warning - > hide ( ) ;
2013-08-19 14:44:30 +04:00
if ( QPushButton * ok = m_buttons - > button ( QDialogButtonBox : : Ok ) )
2013-04-25 19:21:54 +04:00
ok - > setFocus ( ) ;
}
_shortcut = seq ;
}
QKeySequence ShortcutDialog : : shortcut ( ) const
{
return _shortcut ;
}
2012-08-19 14:00:53 +04:00
//****************************************
// Workspace
//****************************************
void Workspace : : slotIncreaseWindowOpacity ( )
{
if ( ! active_client ) {
return ;
}
active_client - > setOpacity ( qMin ( active_client - > opacity ( ) + 0.05 , 1.0 ) ) ;
}
void Workspace : : slotLowerWindowOpacity ( )
{
if ( ! active_client ) {
return ;
}
active_client - > setOpacity ( qMax ( active_client - > opacity ( ) - 0.05 , 0.05 ) ) ;
}
2007-04-29 21:35:43 +04:00
void Workspace : : closeActivePopup ( )
2011-01-30 17:34:42 +03:00
{
if ( active_popup ) {
2007-04-29 21:35:43 +04:00
active_popup - > close ( ) ;
active_popup = NULL ;
active_popup_client = NULL ;
}
2012-08-19 14:00:53 +04:00
m_userActionsMenu - > close ( ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
2013-09-09 11:41:37 +04:00
template < typename Slot >
void Workspace : : initShortcut ( const QString & actionName , const QString & description , const QKeySequence & shortcut , Slot slot , const QVariant & data )
{
QAction * a = keys - > addAction ( actionName ) ;
a - > setText ( description ) ;
if ( data . isValid ( ) ) {
a - > setData ( data ) ;
}
KGlobalAccel : : self ( ) - > setDefaultShortcut ( a , QList < QKeySequence > ( ) < < shortcut ) ;
KGlobalAccel : : self ( ) - > setShortcut ( a , QList < QKeySequence > ( ) < < shortcut ) ;
connect ( a , & QAction : : triggered , this , slot ) ;
}
2007-04-29 21:35:43 +04:00
/*!
Create the global accel object \ c keys .
*/
void Workspace : : initShortcuts ( )
2011-01-30 17:34:42 +03:00
{
keys = new KActionCollection ( this ) ;
2007-04-29 21:35:43 +04:00
KActionCollection * actionCollection = keys ;
QAction * a = 0L ;
# define IN_KWIN
# include "kwinbindings.cpp"
2011-06-30 15:02:30 +04:00
# ifdef KWIN_BUILD_TABBOX
2013-04-04 11:41:18 +04:00
TabBox : : TabBox : : self ( ) - > initShortcuts ( actionCollection ) ;
2011-07-20 15:25:00 +04:00
# endif
2012-11-16 11:23:47 +04:00
VirtualDesktopManager : : self ( ) - > initShortcuts ( actionCollection ) ;
2012-08-19 14:00:53 +04:00
m_userActionsMenu - > discard ( ) ; // so that it's recreated next time
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
2011-01-30 17:34:42 +03:00
void Workspace : : setupWindowShortcut ( Client * c )
{
assert ( client_keys_dialog = = NULL ) ;
2009-10-05 10:59:10 +04:00
// TODO: PORT ME (KGlobalAccel related)
//keys->setEnabled( false );
//disable_shortcuts_keys->setEnabled( false );
//client_keys->setEnabled( false );
2013-09-06 12:31:38 +04:00
client_keys_dialog = new ShortcutDialog ( c - > shortcut ( ) ) ;
2007-04-29 21:35:43 +04:00
client_keys_client = c ;
2011-01-30 17:34:42 +03:00
connect ( client_keys_dialog , SIGNAL ( dialogDone ( bool ) ) , SLOT ( setupWindowShortcutDone ( bool ) ) ) ;
QRect r = clientArea ( ScreenArea , c ) ;
2007-04-29 21:35:43 +04:00
QSize size = client_keys_dialog - > sizeHint ( ) ;
QPoint pos = c - > pos ( ) + c - > clientPos ( ) ;
2011-01-30 17:34:42 +03:00
if ( pos . x ( ) + size . width ( ) > = r . right ( ) )
pos . setX ( r . right ( ) - size . width ( ) ) ;
if ( pos . y ( ) + size . height ( ) > = r . bottom ( ) )
pos . setY ( r . bottom ( ) - size . height ( ) ) ;
client_keys_dialog - > move ( pos ) ;
2007-04-29 21:35:43 +04:00
client_keys_dialog - > show ( ) ;
active_popup = client_keys_dialog ;
active_popup_client = c ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
2011-01-30 17:34:42 +03:00
void Workspace : : setupWindowShortcutDone ( bool ok )
{
2007-11-01 22:24:35 +03:00
// keys->setEnabled( true );
// disable_shortcuts_keys->setEnabled( true );
// client_keys->setEnabled( true );
2011-01-30 17:34:42 +03:00
if ( ok )
2013-09-06 12:31:38 +04:00
client_keys_client - > setShortcut ( client_keys_dialog - > shortcut ( ) . toString ( ) ) ;
2007-04-29 21:35:43 +04:00
closeActivePopup ( ) ;
2008-06-01 15:36:07 +04:00
client_keys_dialog - > deleteLater ( ) ;
2007-04-29 21:35:43 +04:00
client_keys_dialog = NULL ;
client_keys_client = NULL ;
2013-02-10 15:53:09 +04:00
if ( active_client )
2013-04-26 11:47:45 +04:00
active_client - > takeFocus ( ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
2011-01-30 17:34:42 +03:00
void Workspace : : clientShortcutUpdated ( Client * c )
{
2013-07-23 09:02:52 +04:00
QString key = QStringLiteral ( " _k_session:%1 " ) . arg ( c - > window ( ) ) ;
QAction * action = client_keys - > action ( key ) ;
2011-01-30 17:34:42 +03:00
if ( ! c - > shortcut ( ) . isEmpty ( ) ) {
if ( action = = NULL ) { // new shortcut
action = client_keys - > addAction ( QString ( key ) ) ;
action - > setText ( i18n ( " Activate Window (%1) " , c - > caption ( ) ) ) ;
connect ( action , SIGNAL ( triggered ( bool ) ) , c , SLOT ( shortcutActivated ( ) ) ) ;
}
2008-10-01 00:44:40 +04:00
2008-06-01 15:36:07 +04:00
// no autoloading, since it's configured explicitly here and is not meant to be reused
// (the key is the window id anyway, which is kind of random)
2013-09-06 12:31:38 +04:00
KGlobalAccel : : self ( ) - > setShortcut ( action , QList < QKeySequence > ( ) < < c - > shortcut ( ) ,
2013-08-19 15:51:29 +04:00
KGlobalAccel : : NoAutoloading ) ;
action - > setEnabled ( true ) ;
2011-01-30 17:34:42 +03:00
} else {
2013-08-19 15:51:29 +04:00
KGlobalAccel : : self ( ) - > removeAllShortcuts ( action ) ;
2011-01-30 17:34:42 +03:00
delete action ;
2007-04-29 21:35:43 +04:00
}
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
2011-01-30 17:34:42 +03:00
void Workspace : : performWindowOperation ( Client * c , Options : : WindowOperation op )
{
if ( ! c )
2007-04-29 21:35:43 +04:00
return ;
2011-01-30 17:34:42 +03:00
if ( op = = Options : : MoveOp | | op = = Options : : UnrestrictedMoveOp )
2013-02-26 11:45:44 +04:00
Cursor : : setPos ( c - > geometry ( ) . center ( ) ) ;
2011-01-30 17:34:42 +03:00
if ( op = = Options : : ResizeOp | | op = = Options : : UnrestrictedResizeOp )
2013-02-26 11:45:44 +04:00
Cursor : : setPos ( c - > geometry ( ) . bottomRight ( ) ) ;
2011-01-30 17:34:42 +03:00
switch ( op ) {
case Options : : MoveOp :
c - > performMouseCommand ( Options : : MouseMove , cursorPos ( ) ) ;
break ;
case Options : : UnrestrictedMoveOp :
c - > performMouseCommand ( Options : : MouseUnrestrictedMove , cursorPos ( ) ) ;
break ;
case Options : : ResizeOp :
c - > performMouseCommand ( Options : : MouseResize , cursorPos ( ) ) ;
break ;
case Options : : UnrestrictedResizeOp :
c - > performMouseCommand ( Options : : MouseUnrestrictedResize , cursorPos ( ) ) ;
break ;
case Options : : CloseOp :
2012-07-14 13:11:02 +04:00
QMetaObject : : invokeMethod ( c , " closeWindow " , Qt : : QueuedConnection ) ;
2011-01-30 17:34:42 +03:00
break ;
case Options : : MaximizeOp :
c - > maximize ( c - > maximizeMode ( ) = = Client : : MaximizeFull
? Client : : MaximizeRestore : Client : : MaximizeFull ) ;
break ;
case Options : : HMaximizeOp :
c - > maximize ( c - > maximizeMode ( ) ^ Client : : MaximizeHorizontal ) ;
break ;
case Options : : VMaximizeOp :
c - > maximize ( c - > maximizeMode ( ) ^ Client : : MaximizeVertical ) ;
break ;
case Options : : RestoreOp :
c - > maximize ( Client : : MaximizeRestore ) ;
break ;
case Options : : MinimizeOp :
c - > minimize ( ) ;
break ;
case Options : : ShadeOp :
c - > performMouseCommand ( Options : : MouseShade , cursorPos ( ) ) ;
break ;
case Options : : OnAllDesktopsOp :
c - > setOnAllDesktops ( ! c - > isOnAllDesktops ( ) ) ;
break ;
case Options : : FullScreenOp :
c - > setFullScreen ( ! c - > isFullScreen ( ) , true ) ;
break ;
case Options : : NoBorderOp :
c - > setNoBorder ( ! c - > noBorder ( ) ) ;
break ;
case Options : : KeepAboveOp : {
StackingUpdatesBlocker blocker ( this ) ;
bool was = c - > keepAbove ( ) ;
c - > setKeepAbove ( ! c - > keepAbove ( ) ) ;
if ( was & & ! c - > keepAbove ( ) )
raiseClient ( c ) ;
break ;
}
case Options : : KeepBelowOp : {
StackingUpdatesBlocker blocker ( this ) ;
bool was = c - > keepBelow ( ) ;
c - > setKeepBelow ( ! c - > keepBelow ( ) ) ;
if ( was & & ! c - > keepBelow ( ) )
2007-04-29 21:35:43 +04:00
lowerClient ( c ) ;
2011-01-30 17:34:42 +03:00
break ;
}
case Options : : OperationsOp :
c - > performMouseCommand ( Options : : MouseShade , cursorPos ( ) ) ;
break ;
case Options : : WindowRulesOp :
2013-04-26 16:40:35 +04:00
RuleBook : : self ( ) - > edit ( c , false ) ;
2011-01-30 17:34:42 +03:00
break ;
case Options : : ApplicationRulesOp :
2013-04-26 16:40:35 +04:00
RuleBook : : self ( ) - > edit ( c , true ) ;
2011-01-30 17:34:42 +03:00
break ;
case Options : : SetupWindowShortcutOp :
setupWindowShortcut ( c ) ;
break ;
case Options : : LowerOp :
lowerClient ( c ) ;
break ;
2012-01-12 10:42:55 +04:00
case Options : : TabDragOp : // Handled by decoration itself
2011-01-30 17:34:42 +03:00
case Options : : NoOp :
break ;
2012-01-12 10:42:55 +04:00
case Options : : RemoveTabFromGroupOp :
2012-08-25 20:20:34 +04:00
if ( c - > untab ( c - > geometry ( ) . translated ( cascadeOffset ( c ) ) ) & & options - > focusPolicyIsReasonable ( ) )
2012-01-12 10:42:55 +04:00
takeActivity ( c , ActivityFocus | ActivityRaise , true ) ;
2011-01-30 17:34:42 +03:00
break ;
2012-01-12 10:42:55 +04:00
case Options : : ActivateNextTabOp :
if ( c - > tabGroup ( ) )
c - > tabGroup ( ) - > activateNext ( ) ;
2011-01-30 17:34:42 +03:00
break ;
2012-01-12 10:42:55 +04:00
case Options : : ActivatePreviousTabOp :
if ( c - > tabGroup ( ) )
c - > tabGroup ( ) - > activatePrev ( ) ;
2011-01-30 17:34:42 +03:00
break ;
2012-01-12 10:42:55 +04:00
case Options : : CloseTabGroupOp :
c - > tabGroup ( ) - > closeAll ( ) ;
2012-07-13 12:13:38 +04:00
break ;
2007-04-29 21:35:43 +04:00
}
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
2009-11-17 10:17:49 +03:00
/**
* Called by the decoration in the new API to determine what buttons the user has configured for
* window tab dragging and the operations menu .
*/
2011-01-30 17:34:42 +03:00
Options : : WindowOperation Client : : mouseButtonToWindowOperation ( Qt : : MouseButtons button )
{
2009-11-17 10:17:49 +03:00
Options : : MouseCommand com = Options : : MouseNothing ;
bool active = isActive ( ) ;
2011-01-30 17:34:42 +03:00
if ( ! wantsInput ( ) ) // we cannot be active, use it anyway
2009-11-17 10:17:49 +03:00
active = true ;
2011-01-30 17:34:42 +03:00
if ( button = = Qt : : LeftButton )
2009-11-17 10:17:49 +03:00
com = active ? options - > commandActiveTitlebar1 ( ) : options - > commandInactiveTitlebar1 ( ) ;
2011-01-30 17:34:42 +03:00
else if ( button = = Qt : : MidButton )
2009-11-17 10:17:49 +03:00
com = active ? options - > commandActiveTitlebar2 ( ) : options - > commandInactiveTitlebar2 ( ) ;
2011-01-30 17:34:42 +03:00
else if ( button = = Qt : : RightButton )
2009-11-17 10:17:49 +03:00
com = active ? options - > commandActiveTitlebar3 ( ) : options - > commandInactiveTitlebar3 ( ) ;
// TODO: Complete the list
2012-01-12 10:42:55 +04:00
if ( com = = Options : : MouseDragTab )
return Options : : TabDragOp ;
2011-01-30 17:34:42 +03:00
if ( com = = Options : : MouseOperationsMenu )
2009-11-17 10:17:49 +03:00
return Options : : OperationsOp ;
return Options : : NoOp ;
2011-01-30 17:34:42 +03:00
}
2009-11-17 10:17:49 +03:00
2007-04-29 21:35:43 +04:00
/*!
Performs a mouse command on this client ( see options . h )
*/
2011-01-30 17:34:42 +03:00
bool Client : : performMouseCommand ( Options : : MouseCommand command , const QPoint & globalPos , bool handled )
{
2007-04-29 21:35:43 +04:00
bool replay = false ;
2011-01-30 17:34:42 +03:00
switch ( command ) {
case Options : : MouseRaise :
workspace ( ) - > raiseClient ( this ) ;
break ;
2012-02-14 02:50:49 +04:00
case Options : : MouseLower : {
2011-01-30 17:34:42 +03:00
workspace ( ) - > lowerClient ( this ) ;
2012-02-14 02:50:49 +04:00
// used to be activateNextClient(this), then topClientOnDesktop
// since this is a mouseOp it's however safe to use the client under the mouse instead
2012-02-22 02:55:55 +04:00
if ( isActive ( ) & & options - > focusPolicyIsReasonable ( ) ) {
2012-02-14 02:50:49 +04:00
Client * next = workspace ( ) - > clientUnderMouse ( screen ( ) ) ;
if ( next & & next ! = this )
workspace ( ) - > requestFocus ( next , false ) ;
}
2011-01-30 17:34:42 +03:00
break ;
2012-02-14 02:50:49 +04:00
}
2011-01-30 17:34:42 +03:00
case Options : : MouseShade :
toggleShade ( ) ;
cancelShadeHoverTimer ( ) ;
break ;
case Options : : MouseSetShade :
setShade ( ShadeNormal ) ;
cancelShadeHoverTimer ( ) ;
break ;
case Options : : MouseUnsetShade :
setShade ( ShadeNone ) ;
cancelShadeHoverTimer ( ) ;
break ;
case Options : : MouseOperationsMenu :
2012-02-20 13:25:13 +04:00
if ( isActive ( ) & & options - > isClickRaise ( ) )
2011-01-30 17:34:42 +03:00
autoRaise ( ) ;
2013-05-03 21:13:12 +04:00
workspace ( ) - > showWindowMenu ( QRect ( globalPos , globalPos ) , this ) ;
2011-01-30 17:34:42 +03:00
break ;
case Options : : MouseToggleRaiseAndLower :
workspace ( ) - > raiseOrLowerClient ( this ) ;
break ;
2011-10-10 22:45:32 +04:00
case Options : : MouseActivateAndRaise : {
2011-01-30 17:34:42 +03:00
replay = isActive ( ) ; // for clickraise mode
2011-10-10 22:45:32 +04:00
bool mustReplay = ! rules ( ) - > checkAcceptFocus ( input ) ;
if ( mustReplay ) {
2012-04-08 12:07:35 +04:00
ToplevelList : : const_iterator it = workspace ( ) - > stackingOrder ( ) . constEnd ( ) ,
2011-10-10 22:45:32 +04:00
begin = workspace ( ) - > stackingOrder ( ) . constBegin ( ) ;
while ( mustReplay & & - - it ! = begin & & * it ! = this ) {
2012-04-08 12:07:35 +04:00
Client * c = qobject_cast < Client * > ( * it ) ;
if ( ! c | | ( c - > keepAbove ( ) & & ! keepAbove ( ) ) | | ( keepBelow ( ) & & ! c - > keepBelow ( ) ) )
2011-10-10 22:45:32 +04:00
continue ; // can never raise above "it"
2012-04-08 12:07:35 +04:00
mustReplay = ! ( c - > isOnCurrentDesktop ( ) & & c - > isOnCurrentActivity ( ) & & c - > geometry ( ) . intersects ( geometry ( ) ) ) ;
2011-10-10 22:45:32 +04:00
}
}
2011-01-30 17:34:42 +03:00
workspace ( ) - > takeActivity ( this , ActivityFocus | ActivityRaise , handled & & replay ) ;
2013-04-03 14:19:27 +04:00
screens ( ) - > setCurrent ( globalPos ) ;
2011-10-10 22:45:32 +04:00
replay = replay | | mustReplay ;
2011-01-30 17:34:42 +03:00
break ;
2011-10-10 22:45:32 +04:00
}
2011-01-30 17:34:42 +03:00
case Options : : MouseActivateAndLower :
workspace ( ) - > requestFocus ( this ) ;
workspace ( ) - > lowerClient ( this ) ;
2013-04-03 14:19:27 +04:00
screens ( ) - > setCurrent ( globalPos ) ;
2011-10-10 22:45:32 +04:00
replay = replay | | ! rules ( ) - > checkAcceptFocus ( input ) ;
2011-01-30 17:34:42 +03:00
break ;
case Options : : MouseActivate :
replay = isActive ( ) ; // for clickraise mode
workspace ( ) - > takeActivity ( this , ActivityFocus , handled & & replay ) ;
2013-04-03 14:19:27 +04:00
screens ( ) - > setCurrent ( globalPos ) ;
2011-10-10 22:45:32 +04:00
replay = replay | | ! rules ( ) - > checkAcceptFocus ( input ) ;
2011-01-30 17:34:42 +03:00
break ;
case Options : : MouseActivateRaiseAndPassClick :
workspace ( ) - > takeActivity ( this , ActivityFocus | ActivityRaise , handled ) ;
2013-04-03 14:19:27 +04:00
screens ( ) - > setCurrent ( globalPos ) ;
2011-01-30 17:34:42 +03:00
replay = true ;
break ;
case Options : : MouseActivateAndPassClick :
workspace ( ) - > takeActivity ( this , ActivityFocus , handled ) ;
2013-04-03 14:19:27 +04:00
screens ( ) - > setCurrent ( globalPos ) ;
2011-01-30 17:34:42 +03:00
replay = true ;
break ;
case Options : : MouseActivateRaiseAndMove :
case Options : : MouseActivateRaiseAndUnrestrictedMove :
workspace ( ) - > raiseClient ( this ) ;
workspace ( ) - > requestFocus ( this ) ;
2013-04-03 14:19:27 +04:00
screens ( ) - > setCurrent ( globalPos ) ;
2007-04-29 21:35:43 +04:00
// fallthrough
2011-01-30 17:34:42 +03:00
case Options : : MouseMove :
case Options : : MouseUnrestrictedMove : {
if ( ! isMovableAcrossScreens ( ) )
2007-04-29 21:35:43 +04:00
break ;
2011-01-30 17:34:42 +03:00
if ( moveResizeMode )
finishMoveResize ( false ) ;
mode = PositionCenter ;
buttonDown = true ;
moveOffset = QPoint ( globalPos . x ( ) - x ( ) , globalPos . y ( ) - y ( ) ) ; // map from global
invertedMoveOffset = rect ( ) . bottomRight ( ) - moveOffset ;
unrestrictedMoveResize = ( command = = Options : : MouseActivateRaiseAndUnrestrictedMove
| | command = = Options : : MouseUnrestrictedMove ) ;
if ( ! startMoveResize ( ) )
buttonDown = false ;
updateCursor ( ) ;
break ;
}
case Options : : MouseResize :
case Options : : MouseUnrestrictedResize : {
if ( ! isResizable ( ) | | isShade ( ) )
2007-04-29 21:35:43 +04:00
break ;
2011-01-30 17:34:42 +03:00
if ( moveResizeMode )
finishMoveResize ( false ) ;
buttonDown = true ;
moveOffset = QPoint ( globalPos . x ( ) - x ( ) , globalPos . y ( ) - y ( ) ) ; // map from global
int x = moveOffset . x ( ) , y = moveOffset . y ( ) ;
bool left = x < width ( ) / 3 ;
bool right = x > = 2 * width ( ) / 3 ;
bool top = y < height ( ) / 3 ;
bool bot = y > = 2 * height ( ) / 3 ;
if ( top )
mode = left ? PositionTopLeft : ( right ? PositionTopRight : PositionTop ) ;
else if ( bot )
mode = left ? PositionBottomLeft : ( right ? PositionBottomRight : PositionBottom ) ;
else
mode = ( x < width ( ) / 2 ) ? PositionLeft : PositionRight ;
invertedMoveOffset = rect ( ) . bottomRight ( ) - moveOffset ;
unrestrictedMoveResize = ( command = = Options : : MouseUnrestrictedResize ) ;
if ( ! startMoveResize ( ) )
buttonDown = false ;
updateCursor ( ) ;
break ;
}
case Options : : MouseMaximize :
maximize ( Client : : MaximizeFull ) ;
break ;
case Options : : MouseRestore :
maximize ( Client : : MaximizeRestore ) ;
break ;
case Options : : MouseMinimize :
minimize ( ) ;
break ;
case Options : : MouseAbove : {
StackingUpdatesBlocker blocker ( workspace ( ) ) ;
if ( keepBelow ( ) )
setKeepBelow ( false ) ;
else
setKeepAbove ( true ) ;
break ;
}
case Options : : MouseBelow : {
StackingUpdatesBlocker blocker ( workspace ( ) ) ;
if ( keepAbove ( ) )
setKeepAbove ( false ) ;
else
setKeepBelow ( true ) ;
break ;
}
case Options : : MousePreviousDesktop :
workspace ( ) - > windowToPreviousDesktop ( this ) ;
break ;
case Options : : MouseNextDesktop :
workspace ( ) - > windowToNextDesktop ( this ) ;
break ;
case Options : : MouseOpacityMore :
if ( ! isDesktop ( ) ) // No point in changing the opacity of the desktop
setOpacity ( qMin ( opacity ( ) + 0.1 , 1.0 ) ) ;
break ;
case Options : : MouseOpacityLess :
if ( ! isDesktop ( ) ) // No point in changing the opacity of the desktop
setOpacity ( qMax ( opacity ( ) - 0.1 , 0.1 ) ) ;
break ;
2012-01-12 10:42:55 +04:00
case Options : : MousePreviousTab :
if ( tabGroup ( ) )
tabGroup ( ) - > activatePrev ( ) ;
2011-01-30 17:34:42 +03:00
break ;
2012-01-12 10:42:55 +04:00
case Options : : MouseNextTab :
if ( tabGroup ( ) )
tabGroup ( ) - > activateNext ( ) ;
2011-01-30 17:34:42 +03:00
break ;
case Options : : MouseClose :
closeWindow ( ) ;
break ;
2012-01-12 10:42:55 +04:00
case Options : : MouseDragTab :
2011-01-30 17:34:42 +03:00
case Options : : MouseNothing :
replay = true ;
break ;
2007-04-29 21:35:43 +04:00
}
2011-01-30 17:34:42 +03:00
return replay ;
}
2007-04-29 21:35:43 +04:00
void Workspace : : slotActivateAttentionWindow ( )
2011-01-30 17:34:42 +03:00
{
if ( attention_chain . count ( ) > 0 )
activateClient ( attention_chain . first ( ) ) ;
}
2007-04-29 21:35:43 +04:00
2012-11-16 11:23:47 +04:00
static uint senderValue ( QObject * sender )
2011-01-30 17:34:42 +03:00
{
2011-02-16 21:23:54 +03:00
QAction * act = qobject_cast < QAction * > ( sender ) ;
2012-11-16 11:23:47 +04:00
bool ok = false ; uint i = - 1 ;
2011-02-16 21:23:54 +03:00
if ( act )
i = act - > data ( ) . toUInt ( & ok ) ;
if ( ok )
return i ;
return - 1 ;
}
2012-02-21 21:42:09 +04:00
# define USABLE_ACTIVE_CLIENT (active_client && !(active_client->isDesktop() || active_client->isDock()))
2007-04-29 21:35:43 +04:00
2011-02-16 21:23:54 +03:00
void Workspace : : slotWindowToDesktop ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT ) {
2012-11-16 11:23:47 +04:00
const uint i = senderValue ( sender ( ) ) ;
2012-02-17 02:44:00 +04:00
if ( i < 1 )
return ;
2012-11-16 11:23:47 +04:00
if ( i > = 1 & & i < = VirtualDesktopManager : : self ( ) - > count ( ) )
2012-02-17 02:44:00 +04:00
sendClientToDesktop ( active_client , i , true ) ;
}
2011-01-30 17:34:42 +03:00
}
2013-03-23 23:44:10 +04:00
static bool screenSwitchImpossible ( )
{
2013-04-03 14:19:27 +04:00
if ( ! screens ( ) - > isCurrentFollowsMouse ( ) )
2013-03-23 23:44:10 +04:00
return false ;
QStringList args ;
2013-07-23 09:02:52 +04:00
args < < QStringLiteral ( " --passivepopup " ) < < i18n ( " The window manager is configured to consider the screen with the mouse on it as active one. \n "
" Therefore it is not possible to switch to a screen explicitly. " ) < < QStringLiteral ( " 20 " ) ;
KProcess : : startDetached ( QStringLiteral ( " kdialog " ) , args ) ;
2013-03-23 23:44:10 +04:00
return true ;
}
2011-02-16 21:23:54 +03:00
void Workspace : : slotSwitchToScreen ( )
2011-01-30 17:34:42 +03:00
{
2013-03-23 23:44:10 +04:00
if ( screenSwitchImpossible ( ) )
return ;
2011-02-16 21:23:54 +03:00
const int i = senderValue ( sender ( ) ) ;
if ( i > - 1 )
setCurrentScreen ( i ) ;
2011-01-30 17:34:42 +03:00
}
2007-05-07 17:13:48 +04:00
void Workspace : : slotSwitchToNextScreen ( )
2011-01-30 17:34:42 +03:00
{
2013-03-23 23:44:10 +04:00
if ( screenSwitchImpossible ( ) )
return ;
2013-04-03 14:19:27 +04:00
setCurrentScreen ( ( screens ( ) - > current ( ) + 1 ) % screens ( ) - > count ( ) ) ;
2011-01-30 17:34:42 +03:00
}
2007-05-07 17:13:48 +04:00
2013-05-19 16:23:49 +04:00
void Workspace : : slotSwitchToPrevScreen ( )
{
if ( screenSwitchImpossible ( ) )
return ;
setCurrentScreen ( ( screens ( ) - > current ( ) + screens ( ) - > count ( ) - 1 ) % screens ( ) - > count ( ) ) ;
}
2011-02-16 21:23:54 +03:00
void Workspace : : slotWindowToScreen ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT ) {
const int i = senderValue ( sender ( ) ) ;
if ( i < 0 )
return ;
2013-04-03 14:19:27 +04:00
if ( i > = 0 & & i < = screens ( ) - > count ( ) ) {
2012-02-17 02:44:00 +04:00
sendClientToScreen ( active_client , i ) ;
}
2007-05-07 17:13:48 +04:00
}
2011-01-30 17:34:42 +03:00
}
2007-05-07 17:13:48 +04:00
void Workspace : : slotWindowToNextScreen ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT )
2013-04-03 14:19:27 +04:00
sendClientToScreen ( active_client , ( active_client - > screen ( ) + 1 ) % screens ( ) - > count ( ) ) ;
2011-01-30 17:34:42 +03:00
}
2007-05-07 17:13:48 +04:00
2013-05-19 16:23:49 +04:00
void Workspace : : slotWindowToPrevScreen ( )
{
if ( USABLE_ACTIVE_CLIENT )
sendClientToScreen ( active_client , ( active_client - > screen ( ) + screens ( ) - > count ( ) - 1 ) % screens ( ) - > count ( ) ) ;
}
2007-04-29 21:35:43 +04:00
/*!
Maximizes the popup client
*/
void Workspace : : slotWindowMaximize ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT )
performWindowOperation ( active_client , Options : : MaximizeOp ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
/*!
Maximizes the popup client vertically
*/
void Workspace : : slotWindowMaximizeVertical ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT )
performWindowOperation ( active_client , Options : : VMaximizeOp ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
/*!
Maximizes the popup client horiozontally
*/
void Workspace : : slotWindowMaximizeHorizontal ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT )
performWindowOperation ( active_client , Options : : HMaximizeOp ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
/*!
Minimizes the popup client
*/
void Workspace : : slotWindowMinimize ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT )
performWindowOperation ( active_client , Options : : MinimizeOp ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
/*!
Shades / unshades the popup client respectively
*/
void Workspace : : slotWindowShade ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT )
performWindowOperation ( active_client , Options : : ShadeOp ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
/*!
Raises the popup client
*/
void Workspace : : slotWindowRaise ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT )
raiseClient ( active_client ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
/*!
Lowers the popup client
*/
void Workspace : : slotWindowLower ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT ) {
lowerClient ( active_client ) ;
2009-01-28 13:03:37 +03:00
// As this most likely makes the window no longer visible change the
// keyboard focus to the next available window.
//activateNextClient( c ); // Doesn't work when we lower a child window
2012-02-22 02:55:55 +04:00
if ( active_client - > isActive ( ) & & options - > focusPolicyIsReasonable ( ) ) {
2012-03-08 03:25:08 +04:00
if ( options - > isNextFocusPrefersMouse ( ) ) {
2012-02-22 02:55:55 +04:00
Client * next = clientUnderMouse ( active_client - > screen ( ) ) ;
if ( next & & next ! = active_client )
requestFocus ( next , false ) ;
} else {
2012-11-16 11:23:47 +04:00
activateClient ( topClientOnDesktop ( VirtualDesktopManager : : self ( ) - > current ( ) , - 1 ) ) ;
2012-02-22 02:55:55 +04:00
}
}
2007-04-29 21:35:43 +04:00
}
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
/*!
Does a toggle - raise - and - lower on the popup client ;
*/
void Workspace : : slotWindowRaiseOrLower ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT )
raiseOrLowerClient ( active_client ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
void Workspace : : slotWindowOnAllDesktops ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT )
active_client - > setOnAllDesktops ( ! active_client - > isOnAllDesktops ( ) ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
void Workspace : : slotWindowFullScreen ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT )
performWindowOperation ( active_client , Options : : FullScreenOp ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
void Workspace : : slotWindowNoBorder ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT )
performWindowOperation ( active_client , Options : : NoBorderOp ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
void Workspace : : slotWindowAbove ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT )
performWindowOperation ( active_client , Options : : KeepAboveOp ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
void Workspace : : slotWindowBelow ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT )
performWindowOperation ( active_client , Options : : KeepBelowOp ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
void Workspace : : slotSetupWindowShortcut ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT )
performWindowOperation ( active_client , Options : : SetupWindowShortcutOp ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
2009-09-12 12:01:44 +04:00
/*!
Toggles show desktop
*/
void Workspace : : slotToggleShowDesktop ( )
2011-01-30 17:34:42 +03:00
{
setShowingDesktop ( ! showingDesktop ( ) ) ;
}
2009-09-12 12:01:44 +04:00
2012-11-16 11:23:47 +04:00
template < typename Direction >
void windowToDesktop ( Client * c )
{
VirtualDesktopManager * vds = VirtualDesktopManager : : self ( ) ;
Workspace * ws = Workspace : : self ( ) ;
Direction functor ;
// TODO: why is options->isRollOverDesktops() not honored?
const int desktop = functor ( 0 , true ) ;
if ( c & & ! c - > isDesktop ( )
& & ! c - > isDock ( ) ) {
ws - > setClientIsMoving ( c ) ;
vds - > setCurrent ( desktop ) ;
ws - > setClientIsMoving ( NULL ) ;
}
}
2007-04-29 21:35:43 +04:00
/*!
Move window to next desktop
*/
void Workspace : : slotWindowToNextDesktop ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT )
windowToNextDesktop ( active_client ) ;
2011-01-30 17:34:42 +03:00
}
2008-06-02 23:52:02 +04:00
2011-01-30 17:34:42 +03:00
void Workspace : : windowToNextDesktop ( Client * c )
{
2012-11-16 11:23:47 +04:00
windowToDesktop < DesktopNext > ( c ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
/*!
Move window to previous desktop
*/
void Workspace : : slotWindowToPreviousDesktop ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT )
windowToPreviousDesktop ( active_client ) ;
2011-01-30 17:34:42 +03:00
}
2008-06-02 23:52:02 +04:00
2011-01-30 17:34:42 +03:00
void Workspace : : windowToPreviousDesktop ( Client * c )
{
2012-11-16 11:23:47 +04:00
windowToDesktop < DesktopPrevious > ( c ) ;
}
template < typename Direction >
void activeClientToDesktop ( )
{
VirtualDesktopManager * vds = VirtualDesktopManager : : self ( ) ;
Workspace * ws = Workspace : : self ( ) ;
const int current = vds - > current ( ) ;
Direction functor ;
const int d = functor ( current , options - > isRollOverDesktops ( ) ) ;
if ( d = = current ) {
return ;
2007-04-29 21:35:43 +04:00
}
2012-11-16 11:23:47 +04:00
ws - > setClientIsMoving ( ws - > activeClient ( ) ) ;
vds - > setCurrent ( d ) ;
ws - > setClientIsMoving ( NULL ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
void Workspace : : slotWindowToDesktopRight ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT ) {
2012-11-16 11:23:47 +04:00
activeClientToDesktop < DesktopRight > ( ) ;
2007-04-29 21:35:43 +04:00
}
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
void Workspace : : slotWindowToDesktopLeft ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT ) {
2012-11-16 11:23:47 +04:00
activeClientToDesktop < DesktopLeft > ( ) ;
2007-04-29 21:35:43 +04:00
}
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
void Workspace : : slotWindowToDesktopUp ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT ) {
2012-11-16 11:23:47 +04:00
activeClientToDesktop < DesktopAbove > ( ) ;
2007-04-29 21:35:43 +04:00
}
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
void Workspace : : slotWindowToDesktopDown ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT ) {
2012-11-16 11:23:47 +04:00
activeClientToDesktop < DesktopBelow > ( ) ;
2007-04-29 21:35:43 +04:00
}
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
2012-01-12 10:42:55 +04:00
void Workspace : : slotActivateNextTab ( )
2011-01-30 17:34:42 +03:00
{
2012-01-12 10:42:55 +04:00
if ( active_client & & active_client - > tabGroup ( ) )
active_client - > tabGroup ( ) - > activateNext ( ) ;
2011-01-30 17:34:42 +03:00
}
2009-11-15 06:24:04 +03:00
2012-01-12 10:42:55 +04:00
void Workspace : : slotActivatePrevTab ( )
2011-01-30 17:34:42 +03:00
{
2012-01-12 10:42:55 +04:00
if ( active_client & & active_client - > tabGroup ( ) )
active_client - > tabGroup ( ) - > activatePrev ( ) ;
2011-01-30 17:34:42 +03:00
}
2009-11-15 06:24:04 +03:00
2012-01-12 10:42:55 +04:00
void Workspace : : slotUntab ( )
2011-01-30 17:34:42 +03:00
{
2012-01-12 10:42:55 +04:00
if ( active_client )
2012-08-25 20:20:34 +04:00
active_client - > untab ( active_client - > geometry ( ) . translated ( cascadeOffset ( active_client ) ) ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
/*!
Kill Window feature , similar to xkill
*/
void Workspace : : slotKillWindow ( )
2011-01-30 17:34:42 +03:00
{
2012-12-27 17:26:46 +04:00
if ( m_windowKiller . isNull ( ) ) {
m_windowKiller . reset ( new KillWindow ( ) ) ;
}
m_windowKiller - > start ( ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
2009-10-03 17:09:38 +04:00
/*!
Switches to the nearest window in given direction
*/
2011-01-30 17:34:42 +03:00
void Workspace : : switchWindow ( Direction direction )
{
if ( ! active_client )
2009-10-03 17:09:38 +04:00
return ;
Client * c = active_client ;
Client * switchTo = 0 ;
int bestScore = 0 ;
int d = c - > desktop ( ) ;
// Centre of the active window
2011-01-30 17:34:42 +03:00
QPoint curPos ( c - > pos ( ) . x ( ) + c - > geometry ( ) . width ( ) / 2 ,
c - > pos ( ) . y ( ) + c - > geometry ( ) . height ( ) / 2 ) ;
2009-10-03 17:09:38 +04:00
2012-04-08 12:07:35 +04:00
ToplevelList clist = stackingOrder ( ) ;
for ( ToplevelList : : Iterator i = clist . begin ( ) ; i ! = clist . end ( ) ; + + i ) {
2012-06-03 11:07:41 +04:00
Client * client = qobject_cast < Client * > ( * i ) ;
2012-04-08 12:07:35 +04:00
if ( ! client ) {
continue ;
}
if ( client - > wantsTabFocus ( ) & & * i ! = c & &
client - > desktop ( ) = = d & & ! client - > isMinimized ( ) & & ( * i ) - > isOnCurrentActivity ( ) ) {
2009-10-03 17:09:38 +04:00
// Centre of the other window
2012-04-08 12:07:35 +04:00
QPoint other ( client - > pos ( ) . x ( ) + client - > geometry ( ) . width ( ) / 2 ,
client - > pos ( ) . y ( ) + client - > geometry ( ) . height ( ) / 2 ) ;
2009-10-03 17:09:38 +04:00
int distance ;
int offset ;
2011-01-30 17:34:42 +03:00
switch ( direction ) {
case DirectionNorth :
distance = curPos . y ( ) - other . y ( ) ;
offset = qAbs ( other . x ( ) - curPos . x ( ) ) ;
break ;
case DirectionEast :
distance = other . x ( ) - curPos . x ( ) ;
offset = qAbs ( other . y ( ) - curPos . y ( ) ) ;
break ;
case DirectionSouth :
distance = other . y ( ) - curPos . y ( ) ;
offset = qAbs ( other . x ( ) - curPos . x ( ) ) ;
break ;
case DirectionWest :
distance = curPos . x ( ) - other . x ( ) ;
offset = qAbs ( other . y ( ) - curPos . y ( ) ) ;
break ;
default :
distance = - 1 ;
offset = - 1 ;
}
2009-10-03 17:09:38 +04:00
2011-01-30 17:34:42 +03:00
if ( distance > 0 ) {
2009-10-03 17:09:38 +04:00
// Inverse score
2011-01-30 17:34:42 +03:00
int score = distance + offset + ( ( offset * offset ) / distance ) ;
if ( score < bestScore | | ! switchTo ) {
2012-04-08 12:07:35 +04:00
switchTo = client ;
2009-10-03 17:09:38 +04:00
bestScore = score ;
}
}
}
}
2012-03-16 03:13:29 +04:00
if ( switchTo ) {
if ( switchTo - > tabGroup ( ) )
switchTo = switchTo - > tabGroup ( ) - > current ( ) ;
2011-01-30 17:34:42 +03:00
activateClient ( switchTo ) ;
2012-03-16 03:13:29 +04:00
}
2011-01-30 17:34:42 +03:00
}
2009-10-03 17:09:38 +04:00
/*!
Switches to upper window
*/
void Workspace : : slotSwitchWindowUp ( )
2011-01-30 17:34:42 +03:00
{
switchWindow ( DirectionNorth ) ;
}
2009-10-03 17:09:38 +04:00
/*!
Switches to lower window
*/
void Workspace : : slotSwitchWindowDown ( )
2011-01-30 17:34:42 +03:00
{
switchWindow ( DirectionSouth ) ;
}
2009-10-03 17:09:38 +04:00
/*!
Switches to window on the right
*/
void Workspace : : slotSwitchWindowRight ( )
2011-01-30 17:34:42 +03:00
{
switchWindow ( DirectionEast ) ;
}
2009-10-03 17:09:38 +04:00
/*!
Switches to window on the left
*/
void Workspace : : slotSwitchWindowLeft ( )
2011-01-30 17:34:42 +03:00
{
switchWindow ( DirectionWest ) ;
}
2009-10-03 17:09:38 +04:00
2007-04-29 21:35:43 +04:00
/*!
Shows the window operations popup menu for the activeClient ( )
*/
void Workspace : : slotWindowOperations ( )
2011-01-30 17:34:42 +03:00
{
if ( ! active_client )
2007-04-29 21:35:43 +04:00
return ;
QPoint pos = active_client - > pos ( ) + active_client - > clientPos ( ) ;
2013-05-03 21:13:12 +04:00
showWindowMenu ( QRect ( pos , pos ) , active_client ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
2011-01-30 17:34:42 +03:00
void Workspace : : showWindowMenu ( const QRect & pos , Client * cl )
{
2012-08-19 14:00:53 +04:00
m_userActionsMenu - > show ( pos , cl ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
/*!
Closes the popup client
*/
void Workspace : : slotWindowClose ( )
2011-01-30 17:34:42 +03:00
{
2009-09-13 15:36:45 +04:00
// TODO: why?
// if ( tab_box->isVisible())
// return;
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT )
performWindowOperation ( active_client , Options : : CloseOp ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
/*!
Starts keyboard move mode for the popup client
*/
void Workspace : : slotWindowMove ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT )
performWindowOperation ( active_client , Options : : UnrestrictedMoveOp ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
/*!
Starts keyboard resize mode for the popup client
*/
void Workspace : : slotWindowResize ( )
2011-01-30 17:34:42 +03:00
{
2012-02-17 02:44:00 +04:00
if ( USABLE_ACTIVE_CLIENT )
performWindowOperation ( active_client , Options : : UnrestrictedResizeOp ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
2012-03-23 05:06:46 +04:00
void Workspace : : slotInvertScreen ( )
{
2013-08-01 12:26:39 +04:00
using namespace Xcb : : RandR ;
2012-03-23 05:06:46 +04:00
bool succeeded = false ;
//BEGIN Xrandr inversion - does atm NOT work with the nvidia blob
2013-08-01 12:26:39 +04:00
ScreenResources res ( active_client ? active_client - > window ( ) : rootWindow ( ) ) ;
if ( ! res . isNull ( ) ) {
for ( int j = 0 ; j < res - > num_crtcs ; + + j ) {
auto crtc = res . crtcs ( ) [ j ] ;
CrtcGamma gamma ( crtc ) ;
if ( gamma . isNull ( ) ) {
continue ;
}
if ( gamma - > size ) {
2013-09-02 15:14:39 +04:00
qDebug ( ) < < " inverting screen using XRRSetCrtcGamma " ;
2012-03-23 05:06:46 +04:00
const int half = gamma - > size / 2 + 1 ;
2013-08-01 12:26:39 +04:00
uint16_t * red = gamma . red ( ) ;
uint16_t * green = gamma . green ( ) ;
uint16_t * blue = gamma . blue ( ) ;
2012-03-23 05:06:46 +04:00
for ( int i = 0 ; i < half ; + + i ) {
2013-08-01 12:26:39 +04:00
auto invert = [ & gamma , i ] ( uint16_t * ramp ) {
qSwap ( ramp [ i ] , ramp [ gamma - > size - 1 - i ] ) ;
} ;
invert ( red ) ;
invert ( green ) ;
invert ( blue ) ;
2012-03-23 05:06:46 +04:00
}
2013-08-01 12:26:39 +04:00
xcb_randr_set_crtc_gamma ( connection ( ) , crtc , gamma - > size , red , green , blue ) ;
2012-03-23 05:06:46 +04:00
succeeded = true ;
}
}
}
if ( succeeded )
return ;
//BEGIN XF86VidMode inversion - only works if optionally libXxf86vm is linked
# ifndef KWIN_NO_XF86VM
int size = 0 ;
// TODO: this doesn't work with screen numbers in twinview - probably relevant only for multihead?
const int scrn = 0 ; // active_screen
if ( XF86VidModeGetGammaRampSize ( display ( ) , scrn , & size ) ) {
unsigned short * red , * green , * blue ;
red = new unsigned short [ size ] ;
green = new unsigned short [ size ] ;
blue = new unsigned short [ size ] ;
if ( XF86VidModeGetGammaRamp ( display ( ) , scrn , size , red , green , blue ) ) {
2013-09-02 15:14:39 +04:00
qDebug ( ) < < " inverting screen using XF86VidModeSetGammaRamp " ;
2012-03-23 05:06:46 +04:00
const int half = size / 2 + 1 ;
unsigned short swap ;
for ( int i = 0 ; i < half ; + + i ) {
swap = red [ i ] ; red [ i ] = red [ size - 1 - i ] ; red [ size - 1 - i ] = swap ;
swap = green [ i ] ; green [ i ] = green [ size - 1 - i ] ; green [ size - 1 - i ] = swap ;
swap = blue [ i ] ; blue [ i ] = blue [ size - 1 - i ] ; blue [ size - 1 - i ] = swap ;
}
XF86VidModeSetGammaRamp ( display ( ) , scrn , size , red , green , blue ) ;
succeeded = true ;
}
delete [ ] red ;
delete [ ] green ;
delete [ ] blue ;
}
if ( succeeded )
return ;
# endif
//BEGIN effect plugin inversion - atm only works with OpenGL and has an overhead to it
if ( effects ) {
if ( Effect * inverter = static_cast < EffectsHandlerImpl * > ( effects ) - > provides ( Effect : : ScreenInversion ) ) {
2013-09-02 15:14:39 +04:00
qDebug ( ) < < " inverting screen using Effect plugin " ;
2012-03-23 05:06:46 +04:00
QMetaObject : : invokeMethod ( inverter , " toggleScreenInversion " , Qt : : DirectConnection ) ;
}
}
if ( ! succeeded )
2013-09-02 15:14:39 +04:00
qDebug ( ) < < " sorry - neither Xrandr, nor XF86VidModeSetGammaRamp worked and there's no inversion supplying effect plugin either " ;
2012-03-23 05:06:46 +04:00
}
2012-02-17 02:44:00 +04:00
# undef USABLE_ACTIVE_CLIENT
2011-01-30 17:34:42 +03:00
void Client : : setShortcut ( const QString & _cut )
{
QString cut = rules ( ) - > checkShortcut ( _cut ) ;
if ( cut . isEmpty ( ) )
2013-09-06 12:31:38 +04:00
return setShortcutInternal ( ) ;
2007-04-29 21:35:43 +04:00
// Format:
// base+(abcdef)<space>base+(abcdef)
2013-02-13 16:57:21 +04:00
// E.g. Alt+Ctrl+(ABCDEF);Meta+X,Meta+(ABCDEF)
2013-07-23 09:02:52 +04:00
if ( ! cut . contains ( QStringLiteral ( " ( " ) ) & & ! cut . contains ( QStringLiteral ( " ) " ) ) & & ! cut . contains ( QStringLiteral ( " - " ) ) ) {
2013-09-06 12:31:38 +04:00
if ( workspace ( ) - > shortcutAvailable ( cut , this ) )
setShortcutInternal ( QKeySequence ( cut ) ) ;
2007-04-29 21:35:43 +04:00
else
2013-09-06 12:31:38 +04:00
setShortcutInternal ( ) ;
2007-04-29 21:35:43 +04:00
return ;
2011-01-30 17:34:42 +03:00
}
2013-09-06 12:31:38 +04:00
QList < QKeySequence > keys ;
2013-07-23 09:02:52 +04:00
QStringList groups = cut . split ( QStringLiteral ( " - " ) ) ;
2011-01-30 17:34:42 +03:00
for ( QStringList : : ConstIterator it = groups . constBegin ( ) ;
it ! = groups . constEnd ( ) ;
+ + it ) {
2013-07-23 09:02:52 +04:00
QRegExp reg ( QStringLiteral ( " (.* \\ +) \ \ ( ( . * ) \ \ ) " )) ;
2011-01-30 17:34:42 +03:00
if ( reg . indexIn ( * it ) > - 1 ) {
QString base = reg . cap ( 1 ) ;
QString list = reg . cap ( 2 ) ;
for ( int i = 0 ;
i < list . length ( ) ;
+ + i ) {
2013-09-06 12:31:38 +04:00
QKeySequence c ( base + list [ i ] ) ;
2011-01-30 17:34:42 +03:00
if ( ! c . isEmpty ( ) )
keys . append ( c ) ;
2007-04-29 21:35:43 +04:00
}
2013-02-13 16:55:08 +04:00
} else {
// regexp doesn't match, so it should be a normal shortcut
2013-09-06 12:31:38 +04:00
QKeySequence c ( * it ) ;
2013-02-13 16:55:08 +04:00
if ( ! c . isEmpty ( ) ) {
keys . append ( c ) ;
}
2007-04-29 21:35:43 +04:00
}
2011-01-30 17:34:42 +03:00
}
2013-09-06 12:31:38 +04:00
for ( auto it = keys . constBegin ( ) ;
2011-01-30 17:34:42 +03:00
it ! = keys . constEnd ( ) ;
+ + it ) {
if ( _shortcut = = * it ) // current one is in the list
2007-04-29 21:35:43 +04:00
return ;
2011-01-30 17:34:42 +03:00
}
2013-09-06 12:31:38 +04:00
for ( auto it = keys . constBegin ( ) ;
2011-01-30 17:34:42 +03:00
it ! = keys . constEnd ( ) ;
+ + it ) {
if ( workspace ( ) - > shortcutAvailable ( * it , this ) ) {
setShortcutInternal ( * it ) ;
2007-04-29 21:35:43 +04:00
return ;
}
}
2013-09-06 12:31:38 +04:00
setShortcutInternal ( ) ;
2011-01-30 17:34:42 +03:00
}
2007-04-29 21:35:43 +04:00
2013-09-06 12:31:38 +04:00
void Client : : setShortcutInternal ( const QKeySequence & cut )
2011-01-30 17:34:42 +03:00
{
if ( _shortcut = = cut )
2007-04-29 21:35:43 +04:00
return ;
_shortcut = cut ;
updateCaption ( ) ;
2008-09-30 16:03:20 +04:00
#if 0
2011-01-30 17:34:42 +03:00
workspace ( ) - > clientShortcutUpdated ( this ) ;
2008-09-30 16:03:20 +04:00
# else
// Workaround for kwin<->kglobalaccel deadlock, when KWin has X grab and the kded
// kglobalaccel module tries to create the key grab. KWin should preferably grab
// they keys itself anyway :(.
2011-01-30 17:34:42 +03:00
QTimer : : singleShot ( 0 , this , SLOT ( delayedSetShortcut ( ) ) ) ;
2008-09-30 16:03:20 +04:00
# endif
2011-01-30 17:34:42 +03:00
}
2008-09-30 16:03:20 +04:00
void Client : : delayedSetShortcut ( )
2011-01-30 17:34:42 +03:00
{
workspace ( ) - > clientShortcutUpdated ( this ) ;
}
2007-04-29 21:35:43 +04:00
2013-09-06 12:31:38 +04:00
bool Workspace : : shortcutAvailable ( const QKeySequence & cut , Client * ignore ) const
2011-01-30 17:34:42 +03:00
{
2013-02-13 16:53:45 +04:00
2013-09-06 12:31:38 +04:00
if ( ! KGlobalAccel : : getGlobalShortcutsByKey ( cut ) . isEmpty ( ) ) {
return false ;
2013-02-13 16:53:45 +04:00
}
2011-01-30 17:34:42 +03:00
for ( ClientList : : ConstIterator it = clients . constBegin ( ) ;
it ! = clients . constEnd ( ) ;
+ + it ) {
if ( ( * it ) ! = ignore & & ( * it ) - > shortcut ( ) = = cut )
2008-06-02 23:52:02 +04:00
return false ;
2007-04-29 21:35:43 +04:00
}
2011-01-30 17:34:42 +03:00
return true ;
}
2007-04-29 21:35:43 +04:00
} // namespace