summaryrefslogtreecommitdiffstats
path: root/kwin/useractions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kwin/useractions.cpp')
-rw-r--r--kwin/useractions.cpp1119
1 files changed, 1119 insertions, 0 deletions
diff --git a/kwin/useractions.cpp b/kwin/useractions.cpp
new file mode 100644
index 000000000..b722bf1a1
--- /dev/null
+++ b/kwin/useractions.cpp
@@ -0,0 +1,1119 @@
+/*****************************************************************
+ 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>
+
+You can Freely distribute this program under the GNU General Public
+License. See the file "COPYING" for the exact licensing terms.
+******************************************************************/
+
+/*
+
+ This file contains things relevant to direct user actions, such as
+ responses to global keyboard shortcuts, or selecting actions
+ from the window operations menu.
+
+*/
+
+#include "client.h"
+#include "workspace.h"
+
+#include <fixx11h.h>
+#include <qhbox.h>
+#include <qpushbutton.h>
+#include <qslider.h>
+#include <qtooltip.h>
+#include <qpopupmenu.h>
+#include <kglobalsettings.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kglobalaccel.h>
+#include <kapplication.h>
+#include <qregexp.h>
+
+#include "killwindow.h"
+#include "tabbox.h"
+
+namespace KWinInternal
+{
+
+//****************************************
+// Workspace
+//****************************************
+
+QPopupMenu* Workspace::clientPopup()
+ {
+ if ( !popup )
+ {
+ popup = new QPopupMenu;
+ popup->setCheckable( TRUE );
+ popup->setFont(KGlobalSettings::menuFont());
+ connect( popup, SIGNAL( aboutToShow() ), this, SLOT( clientPopupAboutToShow() ) );
+ connect( popup, SIGNAL( activated(int) ), this, SLOT( clientPopupActivated(int) ) );
+
+ advanced_popup = new QPopupMenu( popup );
+ advanced_popup->setCheckable( TRUE );
+ advanced_popup->setFont(KGlobalSettings::menuFont());
+ connect( advanced_popup, SIGNAL( activated(int) ), this, SLOT( clientPopupActivated(int) ) );
+ advanced_popup->insertItem( SmallIconSet( "up" ),
+ i18n("Keep &Above Others")+'\t'+keys->shortcut("Window Above Other Windows").seq(0).toString(), Options::KeepAboveOp );
+ advanced_popup->insertItem( SmallIconSet( "down" ),
+ i18n("Keep &Below Others")+'\t'+keys->shortcut("Window Below Other Windows").seq(0).toString(), Options::KeepBelowOp );
+ advanced_popup->insertItem( SmallIconSet( "window_fullscreen" ),
+ i18n("&Fullscreen")+'\t'+keys->shortcut("Window Fullscreen").seq(0).toString(), Options::FullScreenOp );
+ advanced_popup->insertItem( i18n("&No Border")+'\t'+keys->shortcut("Window No Border").seq(0).toString(), Options::NoBorderOp );
+ advanced_popup->insertItem( SmallIconSet("key_bindings"),
+ i18n("Window &Shortcut...")+'\t'+keys->shortcut("Setup Window Shortcut").seq(0).toString(), Options::SetupWindowShortcutOp );
+ advanced_popup->insertItem( SmallIconSet( "wizard" ), i18n("&Special Window Settings..."), Options::WindowRulesOp );
+ advanced_popup->insertItem( SmallIconSet( "wizard" ), i18n("&Special Application Settings..."), Options::ApplicationRulesOp );
+
+ popup->insertItem(i18n("Ad&vanced"), advanced_popup );
+ desk_popup_index = popup->count();
+
+ if (options->useTranslucency){
+ QPopupMenu *trans_popup = new QPopupMenu( popup );
+ QVBox *transBox = new QVBox(trans_popup);
+ transButton = new QPushButton(transBox, "transButton");
+ QToolTip::add(transButton, i18n("Reset opacity to default value"));
+ transSlider = new QSlider(0, 100, 1, 100, Qt::Vertical, transBox, "transSlider");
+ QToolTip::add(transSlider, i18n("Slide this to set the window's opacity"));
+ connect(transButton, SIGNAL(clicked()), SLOT(resetClientOpacity()));
+ connect(transButton, SIGNAL(clicked()), trans_popup, SLOT(hide()));
+ connect(transSlider, SIGNAL(valueChanged(int)), SLOT(setTransButtonText(int)));
+ connect(transSlider, SIGNAL(valueChanged(int)), this, SLOT(setPopupClientOpacity(int)));
+// connect(transSlider, SIGNAL(sliderReleased()), trans_popup, SLOT(hide()));
+ trans_popup->insertItem(transBox);
+ popup->insertItem(i18n("&Opacity"), trans_popup );
+ }
+
+ popup->insertItem( SmallIconSet( "move" ), i18n("&Move")+'\t'+keys->shortcut("Window Move").seq(0).toString(), Options::MoveOp );
+ popup->insertItem( i18n("Re&size")+'\t'+keys->shortcut("Window Resize").seq(0).toString(), Options::ResizeOp );
+ popup->insertItem( i18n("Mi&nimize")+'\t'+keys->shortcut("Window Minimize").seq(0).toString(), Options::MinimizeOp );
+ popup->insertItem( i18n("Ma&ximize")+'\t'+keys->shortcut("Window Maximize").seq(0).toString(), Options::MaximizeOp );
+ popup->insertItem( i18n("Sh&ade")+'\t'+keys->shortcut("Window Shade").seq(0).toString(), Options::ShadeOp );
+
+ popup->insertSeparator();
+
+ if (!KGlobal::config()->isImmutable() &&
+ !kapp->authorizeControlModules(Workspace::configModules(true)).isEmpty())
+ {
+ popup->insertItem(SmallIconSet( "configure" ), i18n("Configur&e Window Behavior..."), this, SLOT( configureWM() ));
+ popup->insertSeparator();
+ }
+
+ popup->insertItem( SmallIconSet( "fileclose" ), i18n("&Close")+'\t'+keys->shortcut("Window Close").seq(0).toString(), Options::CloseOp );
+ }
+ return popup;
+ }
+
+//sets the transparency of the client to given value(given by slider)
+void Workspace::setPopupClientOpacity(int value)
+ {
+ active_popup_client->setCustomOpacityFlag(true);
+ value = 100 - value;
+ value<100?active_popup_client->setOpacity(true, (uint)((value/100.0)*0xffffffff)):active_popup_client->setOpacity(false,0xffffffff);
+ }
+
+void Workspace::setTransButtonText(int value)
+ {
+ value = 100 - value;
+ if(value < 0)
+ transButton->setText("000 %");
+ else if (value >= 100 )
+ transButton->setText("100 %");
+ else if(value < 10)
+ transButton->setText("00"+QString::number(value)+" %");
+ else if(value < 100)
+ transButton->setText("0"+QString::number(value)+" %");
+ }
+
+void Workspace::resetClientOpacity()
+ {
+ active_popup_client->setCustomOpacityFlag(false);
+ active_popup_client->updateOpacity();
+ transSlider->setValue(100-active_popup_client->opacityPercentage());
+ setTransButtonText(100-active_popup_client->opacityPercentage());
+ }
+
+
+/*!
+ The client popup menu will become visible soon.
+
+ Adjust the items according to the respective popup client.
+ */
+void Workspace::clientPopupAboutToShow()
+ {
+ if ( !active_popup_client || !popup )
+ return;
+
+ if ( numberOfDesktops() == 1 )
+ {
+ delete desk_popup;
+ desk_popup = 0;
+ }
+ else
+ {
+ initDesktopPopup();
+ }
+
+ popup->setItemEnabled( Options::ResizeOp, active_popup_client->isResizable() );
+ popup->setItemEnabled( Options::MoveOp, active_popup_client->isMovable() );
+ popup->setItemEnabled( Options::MaximizeOp, active_popup_client->isMaximizable() );
+ popup->setItemChecked( Options::MaximizeOp, active_popup_client->maximizeMode() == Client::MaximizeFull );
+ // This should be checked also when hover unshaded
+ popup->setItemChecked( Options::ShadeOp, active_popup_client->shadeMode() != ShadeNone );
+ popup->setItemEnabled( Options::ShadeOp, active_popup_client->isShadeable());
+ advanced_popup->setItemChecked( Options::KeepAboveOp, active_popup_client->keepAbove() );
+ advanced_popup->setItemChecked( Options::KeepBelowOp, active_popup_client->keepBelow() );
+ advanced_popup->setItemChecked( Options::FullScreenOp, active_popup_client->isFullScreen() );
+ advanced_popup->setItemEnabled( Options::FullScreenOp, active_popup_client->userCanSetFullScreen() );
+ advanced_popup->setItemChecked( Options::NoBorderOp, active_popup_client->noBorder() );
+ advanced_popup->setItemEnabled( Options::NoBorderOp, active_popup_client->userCanSetNoBorder() );
+ popup->setItemEnabled( Options::MinimizeOp, active_popup_client->isMinimizable() );
+ popup->setItemEnabled( Options::CloseOp, active_popup_client->isCloseable() );
+ if (options->useTranslucency)
+ {
+ transSlider->setValue(100-active_popup_client->opacityPercentage());
+ setTransButtonText(100-active_popup_client->opacityPercentage());
+ }
+ }
+
+
+void Workspace::initDesktopPopup()
+ {
+ if (desk_popup)
+ return;
+
+ desk_popup = new QPopupMenu( popup );
+ desk_popup->setCheckable( TRUE );
+ desk_popup->setFont(KGlobalSettings::menuFont());
+ connect( desk_popup, SIGNAL( activated(int) ),
+ this, SLOT( slotSendToDesktop(int) ) );
+ connect( desk_popup, SIGNAL( aboutToShow() ),
+ this, SLOT( desktopPopupAboutToShow() ) );
+
+ popup->insertItem(i18n("To &Desktop"), desk_popup, -1, desk_popup_index );
+ }
+
+/*!
+ Adjusts the desktop popup to the current values and the location of
+ the popup client.
+ */
+void Workspace::desktopPopupAboutToShow()
+ {
+ if ( !desk_popup )
+ return;
+
+ desk_popup->clear();
+ desk_popup->insertItem( i18n("&All Desktops"), 0 );
+ if ( active_popup_client && active_popup_client->isOnAllDesktops() )
+ desk_popup->setItemChecked( 0, TRUE );
+ desk_popup->insertSeparator( -1 );
+ int id;
+ const int BASE = 10;
+ for ( int i = 1; i <= numberOfDesktops(); i++ )
+ {
+ QString basic_name("%1 %2");
+ if (i<BASE)
+ {
+ basic_name.prepend('&');
+ }
+ id = desk_popup->insertItem(
+ basic_name
+ .arg(i)
+ .arg( desktopName(i).replace( '&', "&&" )),
+ i );
+ if ( active_popup_client &&
+ !active_popup_client->isOnAllDesktops() && active_popup_client->desktop() == i )
+ desk_popup->setItemChecked( id, TRUE );
+ }
+ }
+
+void Workspace::closeActivePopup()
+ {
+ if( active_popup )
+ {
+ active_popup->close();
+ active_popup = NULL;
+ active_popup_client = NULL;
+ }
+ }
+
+/*!
+ Create the global accel object \c keys.
+ */
+void Workspace::initShortcuts()
+ {
+ keys = new KGlobalAccel( this );
+ // a separate KGlobalAccel is needed for the shortcut for disabling global shortcuts,
+ // otherwise it would also disable itself
+ disable_shortcuts_keys = new KGlobalAccel( this );
+ disable_shortcuts_keys->disableBlocking( true );
+#define IN_KWIN
+#include "kwinbindings.cpp"
+ readShortcuts();
+ }
+
+void Workspace::readShortcuts()
+ {
+ keys->readSettings();
+ disable_shortcuts_keys->readSettings();
+
+ cutWalkThroughDesktops = keys->shortcut("Walk Through Desktops");
+ cutWalkThroughDesktopsReverse = keys->shortcut("Walk Through Desktops (Reverse)");
+ cutWalkThroughDesktopList = keys->shortcut("Walk Through Desktop List");
+ cutWalkThroughDesktopListReverse = keys->shortcut("Walk Through Desktop List (Reverse)");
+ cutWalkThroughWindows = keys->shortcut("Walk Through Windows");
+ cutWalkThroughWindowsReverse = keys->shortcut("Walk Through Windows (Reverse)");
+
+ keys->updateConnections();
+ disable_shortcuts_keys->updateConnections();
+
+ delete popup;
+ popup = NULL; // so that it's recreated next time
+ desk_popup = NULL;
+ }
+
+
+void Workspace::setupWindowShortcut( Client* c )
+ {
+ assert( client_keys_dialog == NULL );
+ keys->suspend( true );
+ disable_shortcuts_keys->suspend( true );
+ client_keys->suspend( true );
+ client_keys_dialog = new ShortcutDialog( c->shortcut());
+ client_keys_client = c;
+ connect( client_keys_dialog, SIGNAL( dialogDone( bool )), SLOT( setupWindowShortcutDone( bool )));
+ QRect r = clientArea( ScreenArea, c );
+ QSize size = client_keys_dialog->sizeHint();
+ QPoint pos = c->pos() + c->clientPos();
+ 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 );
+ client_keys_dialog->show();
+ active_popup = client_keys_dialog;
+ active_popup_client = c;
+ }
+
+void Workspace::setupWindowShortcutDone( bool ok )
+ {
+ keys->suspend( false );
+ disable_shortcuts_keys->suspend( false );
+ client_keys->suspend( false );
+ if( ok )
+ {
+ client_keys_client->setShortcut( KShortcut( client_keys_dialog->shortcut()).toString());
+ }
+ closeActivePopup();
+ delete client_keys_dialog;
+ client_keys_dialog = NULL;
+ client_keys_client = NULL;
+ }
+
+void Workspace::clientShortcutUpdated( Client* c )
+ {
+ QString key = QString::number( c->window());
+ client_keys->remove( key );
+ if( !c->shortcut().isNull())
+ {
+ client_keys->insert( key, key );
+ client_keys->setShortcut( key, c->shortcut());
+ client_keys->setSlot( key, c, SLOT( shortcutActivated()));
+ client_keys->setActionEnabled( key, true );
+ }
+ client_keys->updateConnections();
+ }
+
+void Workspace::clientPopupActivated( int id )
+ {
+ WindowOperation op = static_cast< WindowOperation >( id );
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ QString type;
+ switch( op )
+ {
+ case FullScreenOp:
+ if( !c->isFullScreen() && c->userCanSetFullScreen())
+ type = "fullscreenaltf3";
+ break;
+ case NoBorderOp:
+ if( !c->noBorder() && c->userCanSetNoBorder())
+ type = "noborderaltf3";
+ break;
+ default:
+ break;
+ };
+ if( !type.isEmpty())
+ helperDialog( type, c );
+ performWindowOperation( c, op );
+ }
+
+
+void Workspace::performWindowOperation( Client* c, Options::WindowOperation op )
+ {
+ if ( !c )
+ return;
+
+ if (op == Options::MoveOp || op == Options::UnrestrictedMoveOp )
+ QCursor::setPos( c->geometry().center() );
+ if (op == Options::ResizeOp || op == Options::UnrestrictedResizeOp )
+ QCursor::setPos( c->geometry().bottomRight());
+ switch ( op )
+ {
+ case Options::MoveOp:
+ c->performMouseCommand( Options::MouseMove, QCursor::pos() );
+ break;
+ case Options::UnrestrictedMoveOp:
+ c->performMouseCommand( Options::MouseUnrestrictedMove, QCursor::pos() );
+ break;
+ case Options::ResizeOp:
+ c->performMouseCommand( Options::MouseResize, QCursor::pos() );
+ break;
+ case Options::UnrestrictedResizeOp:
+ c->performMouseCommand( Options::MouseUnrestrictedResize, QCursor::pos() );
+ break;
+ case Options::CloseOp:
+ c->closeWindow();
+ 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, QCursor::pos());
+ break;
+ case Options::OnAllDesktopsOp:
+ c->setOnAllDesktops( !c->isOnAllDesktops() );
+ break;
+ case Options::FullScreenOp:
+ c->setFullScreen( !c->isFullScreen(), true );
+ break;
+ case Options::NoBorderOp:
+ c->setUserNoBorder( !c->isUserNoBorder());
+ 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())
+ lowerClient( c );
+ break;
+ }
+ case Options::OperationsOp:
+ c->performMouseCommand( Options::MouseShade, QCursor::pos());
+ break;
+ case Options::WindowRulesOp:
+ editWindowRules( c, false );
+ break;
+ case Options::ApplicationRulesOp:
+ editWindowRules( c, true );
+ break;
+ case Options::SetupWindowShortcutOp:
+ setupWindowShortcut( c );
+ break;
+ case Options::LowerOp:
+ lowerClient(c);
+ break;
+ case Options::NoOp:
+ break;
+ }
+ }
+
+/*!
+ Performs a mouse command on this client (see options.h)
+ */
+bool Client::performMouseCommand( Options::MouseCommand command, QPoint globalPos, bool handled )
+ {
+ bool replay = FALSE;
+ switch (command)
+ {
+ case Options::MouseRaise:
+ workspace()->raiseClient( this );
+ break;
+ case Options::MouseLower:
+ workspace()->lowerClient( this );
+ break;
+ case Options::MouseShade :
+ toggleShade();
+ cancelShadeHover();
+ break;
+ case Options::MouseSetShade:
+ setShade( ShadeNormal );
+ cancelShadeHover();
+ break;
+ case Options::MouseUnsetShade:
+ setShade( ShadeNone );
+ cancelShadeHover();
+ break;
+ case Options::MouseOperationsMenu:
+ if ( isActive() && options->clickRaise )
+ autoRaise();
+ workspace()->showWindowMenu( globalPos, this );
+ break;
+ case Options::MouseToggleRaiseAndLower:
+ workspace()->raiseOrLowerClient( this );
+ break;
+ case Options::MouseActivateAndRaise:
+ replay = isActive(); // for clickraise mode
+ workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled && replay );
+ break;
+ case Options::MouseActivateAndLower:
+ workspace()->requestFocus( this );
+ workspace()->lowerClient( this );
+ break;
+ case Options::MouseActivate:
+ replay = isActive(); // for clickraise mode
+ workspace()->takeActivity( this, ActivityFocus, handled && replay );
+ break;
+ case Options::MouseActivateRaiseAndPassClick:
+ workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled );
+ replay = TRUE;
+ break;
+ case Options::MouseActivateAndPassClick:
+ workspace()->takeActivity( this, ActivityFocus, handled );
+ replay = TRUE;
+ break;
+ case Options::MouseActivateRaiseAndMove:
+ case Options::MouseActivateRaiseAndUnrestrictedMove:
+ workspace()->raiseClient( this );
+ workspace()->requestFocus( this );
+ if( options->moveMode == Options::Transparent && isMovable())
+ move_faked_activity = workspace()->fakeRequestedActivity( this );
+ // fallthrough
+ case Options::MouseMove:
+ case Options::MouseUnrestrictedMove:
+ {
+ if (!isMovable())
+ break;
+ 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 );
+ setCursor( mode );
+ if( !startMoveResize())
+ {
+ buttonDown = false;
+ setCursor( mode );
+ }
+ break;
+ }
+ case Options::MouseResize:
+ case Options::MouseUnrestrictedResize:
+ {
+ if (!isResizable() || isShade())
+ break;
+ 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 );
+ setCursor( mode );
+ if( !startMoveResize())
+ {
+ buttonDown = false;
+ setCursor( mode );
+ }
+ 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 (opacity_ < 0xFFFFFFFF)
+ {
+ if (opacity_ < 0xF3333333)
+ {
+ setOpacity(TRUE, opacity_ + 0xCCCCCCC);
+ custom_opacity = true;
+ }
+ else
+ {
+ setOpacity(FALSE, 0xFFFFFFFF);
+ custom_opacity = false;
+ }
+ }
+ break;
+ case Options::MouseOpacityLess:
+ if (opacity_ > 0)
+ {
+ setOpacity(TRUE, (opacity_ > 0xCCCCCCC) ? opacity_ - 0xCCCCCCC : 0);
+ custom_opacity = true;
+ }
+ break;
+ case Options::MouseNothing:
+ replay = TRUE;
+ break;
+ }
+ return replay;
+ }
+
+// KDE4 remove me
+void Workspace::showWindowMenuAt( unsigned long, int, int )
+ {
+ slotWindowOperations();
+ }
+
+void Workspace::slotActivateAttentionWindow()
+ {
+ if( attention_chain.count() > 0 )
+ activateClient( attention_chain.first());
+ }
+
+void Workspace::slotSwitchDesktopNext()
+ {
+ int d = currentDesktop() + 1;
+ if ( d > numberOfDesktops() )
+ {
+ if ( options->rollOverDesktops )
+ {
+ d = 1;
+ }
+ else
+ {
+ return;
+ }
+ }
+ setCurrentDesktop(d);
+ }
+
+void Workspace::slotSwitchDesktopPrevious()
+ {
+ int d = currentDesktop() - 1;
+ if ( d <= 0 )
+ {
+ if ( options->rollOverDesktops )
+ d = numberOfDesktops();
+ else
+ return;
+ }
+ setCurrentDesktop(d);
+ }
+
+void Workspace::slotSwitchDesktopRight()
+ {
+ int desktop = desktopToRight( currentDesktop());
+ if( desktop == currentDesktop())
+ return;
+ setCurrentDesktop( desktop );
+ }
+
+void Workspace::slotSwitchDesktopLeft()
+ {
+ int desktop = desktopToLeft( currentDesktop());
+ if( desktop == currentDesktop())
+ return;
+ setCurrentDesktop( desktop );
+ }
+
+void Workspace::slotSwitchDesktopUp()
+ {
+ int desktop = desktopUp( currentDesktop());
+ if( desktop == currentDesktop())
+ return;
+ setCurrentDesktop( desktop );
+ }
+
+void Workspace::slotSwitchDesktopDown()
+ {
+ int desktop = desktopDown( currentDesktop());
+ if( desktop == currentDesktop())
+ return;
+ setCurrentDesktop( desktop );
+ }
+
+void Workspace::slotSwitchToDesktop( int i )
+ {
+ setCurrentDesktop( i );
+ }
+
+
+void Workspace::slotWindowToDesktop( int i )
+ {
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ if( i >= 1 && i <= numberOfDesktops() && c
+ && !c->isDesktop()
+ && !c->isDock()
+ && !c->isTopMenu())
+ sendClientToDesktop( c, i, true );
+ }
+
+/*!
+ Maximizes the popup client
+ */
+void Workspace::slotWindowMaximize()
+ {
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ if ( c )
+ performWindowOperation( c, Options::MaximizeOp );
+ }
+
+/*!
+ Maximizes the popup client vertically
+ */
+void Workspace::slotWindowMaximizeVertical()
+ {
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ if ( c )
+ performWindowOperation( c, Options::VMaximizeOp );
+ }
+
+/*!
+ Maximizes the popup client horiozontally
+ */
+void Workspace::slotWindowMaximizeHorizontal()
+ {
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ if ( c )
+ performWindowOperation( c, Options::HMaximizeOp );
+ }
+
+
+/*!
+ Minimizes the popup client
+ */
+void Workspace::slotWindowMinimize()
+ {
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ performWindowOperation( c, Options::MinimizeOp );
+ }
+
+/*!
+ Shades/unshades the popup client respectively
+ */
+void Workspace::slotWindowShade()
+ {
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ performWindowOperation( c, Options::ShadeOp );
+ }
+
+/*!
+ Raises the popup client
+ */
+void Workspace::slotWindowRaise()
+ {
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ if ( c )
+ raiseClient( c );
+ }
+
+/*!
+ Lowers the popup client
+ */
+void Workspace::slotWindowLower()
+ {
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ if ( c )
+ lowerClient( c );
+ }
+
+/*!
+ Does a toggle-raise-and-lower on the popup client;
+ */
+void Workspace::slotWindowRaiseOrLower()
+ {
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ if ( c )
+ raiseOrLowerClient( c );
+ }
+
+void Workspace::slotWindowOnAllDesktops()
+ {
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ if( c )
+ c->setOnAllDesktops( !c->isOnAllDesktops());
+ }
+
+void Workspace::slotWindowFullScreen()
+ {
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ if( c )
+ performWindowOperation( c, Options::FullScreenOp );
+ }
+
+void Workspace::slotWindowNoBorder()
+ {
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ if( c )
+ performWindowOperation( c, Options::NoBorderOp );
+ }
+
+void Workspace::slotWindowAbove()
+ {
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ if( c )
+ performWindowOperation( c, Options::KeepAboveOp );
+ }
+
+void Workspace::slotWindowBelow()
+ {
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ if( c )
+ performWindowOperation( c, Options::KeepBelowOp );
+ }
+void Workspace::slotSetupWindowShortcut()
+ {
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ if( c )
+ performWindowOperation( c, Options::SetupWindowShortcutOp );
+ }
+
+/*!
+ Move window to next desktop
+ */
+void Workspace::slotWindowToNextDesktop()
+ {
+ windowToNextDesktop( active_popup_client ? active_popup_client : active_client );
+ }
+
+void Workspace::windowToNextDesktop( Client* c )
+ {
+ int d = currentDesktop() + 1;
+ if ( d > numberOfDesktops() )
+ d = 1;
+ if (c && !c->isDesktop()
+ && !c->isDock() && !c->isTopMenu())
+ {
+ setClientIsMoving( c );
+ setCurrentDesktop( d );
+ setClientIsMoving( NULL );
+ }
+ }
+
+/*!
+ Move window to previous desktop
+ */
+void Workspace::slotWindowToPreviousDesktop()
+ {
+ windowToPreviousDesktop( active_popup_client ? active_popup_client : active_client );
+ }
+
+void Workspace::windowToPreviousDesktop( Client* c )
+ {
+ int d = currentDesktop() - 1;
+ if ( d <= 0 )
+ d = numberOfDesktops();
+ if (c && !c->isDesktop()
+ && !c->isDock() && !c->isTopMenu())
+ {
+ setClientIsMoving( c );
+ setCurrentDesktop( d );
+ setClientIsMoving( NULL );
+ }
+ }
+
+void Workspace::slotWindowToDesktopRight()
+ {
+ int d = desktopToRight( currentDesktop());
+ if( d == currentDesktop())
+ return;
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ if (c && !c->isDesktop()
+ && !c->isDock() && !c->isTopMenu())
+ {
+ setClientIsMoving( c );
+ setCurrentDesktop( d );
+ setClientIsMoving( NULL );
+ }
+ }
+
+void Workspace::slotWindowToDesktopLeft()
+ {
+ int d = desktopToLeft( currentDesktop());
+ if( d == currentDesktop())
+ return;
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ if (c && !c->isDesktop()
+ && !c->isDock() && !c->isTopMenu())
+ {
+ setClientIsMoving( c );
+ setCurrentDesktop( d );
+ setClientIsMoving( NULL );
+ }
+ }
+
+void Workspace::slotWindowToDesktopUp()
+ {
+ int d = desktopUp( currentDesktop());
+ if( d == currentDesktop())
+ return;
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ if (c && !c->isDesktop()
+ && !c->isDock() && !c->isTopMenu())
+ {
+ setClientIsMoving( c );
+ setCurrentDesktop( d );
+ setClientIsMoving( NULL );
+ }
+ }
+
+void Workspace::slotWindowToDesktopDown()
+ {
+ int d = desktopDown( currentDesktop());
+ if( d == currentDesktop())
+ return;
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ if (c && !c->isDesktop()
+ && !c->isDock() && !c->isTopMenu())
+ {
+ setClientIsMoving( c );
+ setCurrentDesktop( d );
+ setClientIsMoving( NULL );
+ }
+ }
+
+
+/*!
+ Kill Window feature, similar to xkill
+ */
+void Workspace::slotKillWindow()
+ {
+ KillWindow kill( this );
+ kill.start();
+ }
+
+/*!
+ Sends the popup client to desktop \a desk
+
+ Internal slot for the window operation menu
+ */
+void Workspace::slotSendToDesktop( int desk )
+ {
+ if ( !active_popup_client )
+ return;
+ if ( desk == 0 )
+ { // the 'on_all_desktops' menu entry
+ active_popup_client->setOnAllDesktops( !active_popup_client->isOnAllDesktops());
+ return;
+ }
+
+ sendClientToDesktop( active_popup_client, desk, false );
+
+ }
+
+/*!
+ Shows the window operations popup menu for the activeClient()
+ */
+void Workspace::slotWindowOperations()
+ {
+ if ( !active_client )
+ return;
+ QPoint pos = active_client->pos() + active_client->clientPos();
+ showWindowMenu( pos.x(), pos.y(), active_client );
+ }
+
+void Workspace::showWindowMenu( const QRect &pos, Client* cl )
+ {
+ if (!kapp->authorizeKAction("kwin_rmb"))
+ return;
+ if( !cl )
+ return;
+ if( active_popup_client != NULL ) // recursion
+ return;
+ if ( cl->isDesktop()
+ || cl->isDock()
+ || cl->isTopMenu())
+ return;
+
+ active_popup_client = cl;
+ QPopupMenu* p = clientPopup();
+ active_popup = p;
+ int x = pos.left();
+ int y = pos.bottom();
+ if (y == pos.top())
+ p->exec( QPoint( x, y ) );
+ else
+ {
+ QRect area = clientArea(ScreenArea, QPoint(x, y), currentDesktop());
+ clientPopupAboutToShow(); // needed for sizeHint() to be correct :-/
+ int popupHeight = p->sizeHint().height();
+ if (y + popupHeight < area.height())
+ p->exec( QPoint( x, y ) );
+ else
+ p->exec( QPoint( x, pos.top() - popupHeight ) );
+ }
+ // active popup may be already changed (e.g. the window shortcut dialog)
+ if( active_popup == p )
+ closeActivePopup();
+ }
+
+/*!
+ Closes the popup client
+ */
+void Workspace::slotWindowClose()
+ {
+ if ( tab_box->isVisible())
+ return;
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ performWindowOperation( c, Options::CloseOp );
+ }
+
+/*!
+ Starts keyboard move mode for the popup client
+ */
+void Workspace::slotWindowMove()
+ {
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ performWindowOperation( c, Options::UnrestrictedMoveOp );
+ }
+
+/*!
+ Starts keyboard resize mode for the popup client
+ */
+void Workspace::slotWindowResize()
+ {
+ Client* c = active_popup_client ? active_popup_client : active_client;
+ performWindowOperation( c, Options::UnrestrictedResizeOp );
+ }
+
+void Client::setShortcut( const QString& _cut )
+ {
+ QString cut = rules()->checkShortcut( _cut );
+ if( cut.isEmpty())
+ return setShortcutInternal( KShortcut());
+// Format:
+// base+(abcdef)<space>base+(abcdef)
+// E.g. Alt+Ctrl+(ABCDEF) Win+X,Win+(ABCDEF)
+ if( !cut.contains( '(' ) && !cut.contains( ')' ) && !cut.contains( ' ' ))
+ {
+ if( workspace()->shortcutAvailable( KShortcut( cut ), this ))
+ setShortcutInternal( KShortcut( cut ));
+ else
+ setShortcutInternal( KShortcut());
+ return;
+ }
+ QValueList< KShortcut > keys;
+ QStringList groups = QStringList::split( ' ', cut );
+ for( QStringList::ConstIterator it = groups.begin();
+ it != groups.end();
+ ++it )
+ {
+ QRegExp reg( "(.*\\+)\\((.*)\\)" );
+ if( reg.search( *it ) > -1 )
+ {
+ QString base = reg.cap( 1 );
+ QString list = reg.cap( 2 );
+ for( unsigned int i = 0;
+ i < list.length();
+ ++i )
+ {
+ KShortcut c( base + list[ i ] );
+ if( !c.isNull())
+ keys.append( c );
+ }
+ }
+ }
+ for( QValueList< KShortcut >::ConstIterator it = keys.begin();
+ it != keys.end();
+ ++it )
+ {
+ if( _shortcut == *it ) // current one is in the list
+ return;
+ }
+ for( QValueList< KShortcut >::ConstIterator it = keys.begin();
+ it != keys.end();
+ ++it )
+ {
+ if( workspace()->shortcutAvailable( *it, this ))
+ {
+ setShortcutInternal( *it );
+ return;
+ }
+ }
+ setShortcutInternal( KShortcut());
+ }
+
+void Client::setShortcutInternal( const KShortcut& cut )
+ {
+ if( _shortcut == cut )
+ return;
+ _shortcut = cut;
+ updateCaption();
+ workspace()->clientShortcutUpdated( this );
+ }
+
+bool Workspace::shortcutAvailable( const KShortcut& cut, Client* ignore ) const
+ {
+ // TODO check global shortcuts etc.
+ for( ClientList::ConstIterator it = clients.begin();
+ it != clients.end();
+ ++it )
+ {
+ if( (*it) != ignore && (*it)->shortcut() == cut )
+ return false;
+ }
+ return true;
+ }
+
+} // namespace