1 /********************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
5 Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
6 Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *********************************************************************/
24 This file contains things relevant to direct user actions, such as
25 responses to global keyboard shortcuts, or selecting actions
26 from the window operations menu.
31 #include "workspace.h"
35 #include <QPushButton>
38 #include <kglobalsettings.h>
39 #include <kiconloader.h>
42 #include <kglobalaccel.h>
43 #include <kapplication.h>
46 #include <QVBoxLayout>
47 #include <kauthorized.h>
48 #include <kactioncollection.h>
51 #include "killwindow.h"
57 //****************************************
59 //****************************************
61 QMenu
* Workspace::clientPopup()
66 popup
->setFont(KGlobalSettings::menuFont());
67 connect( popup
, SIGNAL( aboutToShow() ), this, SLOT( clientPopupAboutToShow() ) );
68 connect( popup
, SIGNAL( triggered(QAction
*) ), this, SLOT( clientPopupActivated(QAction
*) ) );
70 advanced_popup
= new QMenu( popup
);
71 advanced_popup
->setFont(KGlobalSettings::menuFont());
73 mKeepAboveOpAction
= advanced_popup
->addAction( i18n("Keep &Above Others") );
74 mKeepAboveOpAction
->setIcon( KIcon( "go-up" ) );
75 KAction
*kaction
= qobject_cast
<KAction
*>( keys
->action("Window Above Other Windows") );
77 mKeepAboveOpAction
->setShortcut( kaction
->globalShortcut().primary() );
78 mKeepAboveOpAction
->setCheckable( true );
79 mKeepAboveOpAction
->setData( Options::KeepAboveOp
);
81 mKeepBelowOpAction
= advanced_popup
->addAction( i18n("Keep &Below Others") );
82 mKeepBelowOpAction
->setIcon( KIcon( "go-down" ) );
83 kaction
= qobject_cast
<KAction
*>( keys
->action("Window Below Other Windows") );
85 mKeepBelowOpAction
->setShortcut( kaction
->globalShortcut().primary() );
86 mKeepBelowOpAction
->setCheckable( true );
87 mKeepBelowOpAction
->setData( Options::KeepBelowOp
);
89 mFullScreenOpAction
= advanced_popup
->addAction( i18n("&Fullscreen") );
90 mFullScreenOpAction
->setIcon( KIcon( "view-fullscreen" ) );
91 kaction
= qobject_cast
<KAction
*>( keys
->action("Window Fullscreen") );
93 mFullScreenOpAction
->setShortcut( kaction
->globalShortcut().primary() );
94 mFullScreenOpAction
->setCheckable( true );
95 mFullScreenOpAction
->setData( Options::FullScreenOp
);
97 mNoBorderOpAction
= advanced_popup
->addAction( i18n("&No Border") );
98 kaction
= qobject_cast
<KAction
*>( keys
->action("Window No Border") );
100 mNoBorderOpAction
->setShortcut( kaction
->globalShortcut().primary() );
101 mNoBorderOpAction
->setCheckable( true );
102 mNoBorderOpAction
->setData( Options::NoBorderOp
);
104 QAction
*action
= advanced_popup
->addAction( i18n("Window &Shortcut...") );
105 action
->setIcon( KIcon("configure-shortcuts") );
106 kaction
= qobject_cast
<KAction
*>( keys
->action("Setup Window Shortcut") );
108 action
->setShortcut( kaction
->globalShortcut().primary() );
109 action
->setData( Options::SetupWindowShortcutOp
);
111 action
= advanced_popup
->addAction( i18n("&Special Window Settings...") );
112 action
->setIcon( KIcon( "wizard" ) );
113 action
->setData( Options::WindowRulesOp
);
115 action
= advanced_popup
->addAction( i18n("&Special Application Settings...") );
116 action
->setIcon( KIcon( "wizard" ) );
117 action
->setData( Options::ApplicationRulesOp
);
119 action
= popup
->addMenu( advanced_popup
);
120 action
->setText( i18n("Ad&vanced") );
124 trans_popup
= new QMenu( popup
);
125 trans_popup
->setFont(KGlobalSettings::menuFont());
126 connect( trans_popup
, SIGNAL( triggered(QAction
*) ), this, SLOT( setPopupClientOpacity(QAction
*)));
127 const int levels
[] = { 100, 90, 75, 50, 25, 10 };
128 for( unsigned int i
= 0;
129 i
< sizeof( levels
) / sizeof( levels
[ 0 ] );
132 action
= trans_popup
->addAction( QString::number( levels
[ i
] ) + "%" );
133 action
->setCheckable( true );
134 action
->setData( levels
[ i
] );
136 action
= popup
->addMenu( trans_popup
);
137 action
->setText( i18n("&Opacity") );
140 mMoveOpAction
= popup
->addAction( i18n("&Move") );
141 mMoveOpAction
->setIcon( KIcon( "transform-move" ) );
142 kaction
= qobject_cast
<KAction
*>( keys
->action("Window Move") );
144 mMoveOpAction
->setShortcut( kaction
->globalShortcut().primary() );
145 mMoveOpAction
->setData( Options::MoveOp
);
147 mResizeOpAction
= popup
->addAction( i18n("Re&size") );
148 kaction
= qobject_cast
<KAction
*>( keys
->action("Window Resize") );
150 mResizeOpAction
->setShortcut( kaction
->globalShortcut().primary() );
151 mResizeOpAction
->setData( Options::ResizeOp
);
153 mMinimizeOpAction
= popup
->addAction( i18n("Mi&nimize") );
154 kaction
= qobject_cast
<KAction
*>( keys
->action("Window Minimize") );
156 mMinimizeOpAction
->setShortcut( kaction
->globalShortcut().primary() );
157 mMinimizeOpAction
->setData( Options::MinimizeOp
);
159 mMaximizeOpAction
= popup
->addAction( i18n("Ma&ximize") );
160 kaction
= qobject_cast
<KAction
*>( keys
->action("Window Maximize") );
162 mMaximizeOpAction
->setShortcut( kaction
->globalShortcut().primary() );
163 mMaximizeOpAction
->setCheckable( true );
164 mMaximizeOpAction
->setData( Options::MaximizeOp
);
166 mShadeOpAction
= popup
->addAction( i18n("Sh&ade") );
167 kaction
= qobject_cast
<KAction
*>( keys
->action("Window Shade") );
169 mShadeOpAction
->setShortcut( kaction
->globalShortcut().primary() );
170 mShadeOpAction
->setCheckable( true );
171 mShadeOpAction
->setData( Options::ShadeOp
);
173 popup
->addSeparator();
175 if (!KGlobal::config()->isImmutable() &&
176 !KAuthorized::authorizeControlModules(Workspace::configModules(true)).isEmpty())
178 action
= popup
->addAction( i18n("Configur&e Window Behavior...") );
179 action
->setIcon( KIcon( "configure" ) );
180 connect( action
, SIGNAL( triggered() ), this, SLOT( configureWM() ) );
181 popup
->addSeparator();
184 mCloseOpAction
= popup
->addAction( i18n("&Close") );
185 mCloseOpAction
->setIcon( KIcon( "window-close" ) );
186 kaction
= qobject_cast
<KAction
*>( keys
->action("Window Close") );
188 mCloseOpAction
->setShortcut( kaction
->globalShortcut().primary() );
189 mCloseOpAction
->setData( Options::CloseOp
);
194 void Workspace::setPopupClientOpacity( QAction
* action
)
196 if( active_popup_client
== NULL
)
198 int level
= action
->data().toInt();
199 active_popup_client
->setOpacity( level
/ 100.0 );
203 The client popup menu will become visible soon.
205 Adjust the items according to the respective popup client.
207 void Workspace::clientPopupAboutToShow()
209 if ( !active_popup_client
|| !popup
)
212 if ( numberOfDesktops() == 1 )
222 mResizeOpAction
->setEnabled( active_popup_client
->isResizable() );
223 mMoveOpAction
->setEnabled( active_popup_client
->isMovable() );
224 mMaximizeOpAction
->setEnabled( active_popup_client
->isMaximizable() );
225 mMaximizeOpAction
->setChecked( active_popup_client
->maximizeMode() == Client::MaximizeFull
);
226 mShadeOpAction
->setEnabled( active_popup_client
->isShadeable() );
227 mShadeOpAction
->setChecked( active_popup_client
->shadeMode() != ShadeNone
);
228 mKeepAboveOpAction
->setChecked( active_popup_client
->keepAbove() );
229 mKeepBelowOpAction
->setChecked( active_popup_client
->keepBelow() );
230 mFullScreenOpAction
->setEnabled( active_popup_client
->userCanSetFullScreen() );
231 mFullScreenOpAction
->setChecked( active_popup_client
->isFullScreen() );
232 mNoBorderOpAction
->setEnabled( active_popup_client
->userCanSetNoBorder() );
233 mNoBorderOpAction
->setChecked( active_popup_client
->noBorder() );
234 mMinimizeOpAction
->setEnabled( active_popup_client
->isMinimizable() );
235 mCloseOpAction
->setEnabled( active_popup_client
->isCloseable() );
236 if( trans_popup
!= NULL
)
238 foreach( QAction
* action
, trans_popup
->actions())
240 if( action
->data().toInt() == qRound( active_popup_client
->opacity() * 100 ))
241 action
->setChecked( true );
243 action
->setChecked( false );
249 void Workspace::initDesktopPopup()
254 desk_popup
= new QMenu( popup
);
255 desk_popup
->setFont(KGlobalSettings::menuFont());
256 connect( desk_popup
, SIGNAL( triggered(QAction
*) ),
257 this, SLOT( slotSendToDesktop(QAction
*) ) );
258 connect( desk_popup
, SIGNAL( aboutToShow() ),
259 this, SLOT( desktopPopupAboutToShow() ) );
261 QAction
*action
= desk_popup
->menuAction();
262 popup
->insertAction(mMoveOpAction
, action
);
263 action
->setText( i18n("To &Desktop") );
267 Adjusts the desktop popup to the current values and the location of
270 void Workspace::desktopPopupAboutToShow()
276 QAction
*action
= desk_popup
->addAction( i18n("&All Desktops") );
277 action
->setData( 0 );
278 action
->setCheckable( true );
280 if ( active_popup_client
&& active_popup_client
->isOnAllDesktops() )
281 action
->setChecked( true );
282 desk_popup
->addSeparator();
285 for ( int i
= 1; i
<= numberOfDesktops(); i
++ ) {
286 QString
basic_name("%1 %2");
288 basic_name
.prepend('&');
290 action
= desk_popup
->addAction( basic_name
.arg(i
).arg( desktopName(i
).replace( '&', "&&" ) ) );
291 action
->setData( i
);
292 action
->setCheckable( true );
294 if ( active_popup_client
&&
295 !active_popup_client
->isOnAllDesktops() && active_popup_client
->desktop() == i
)
296 action
->setChecked( true );
300 void Workspace::closeActivePopup()
304 active_popup
->close();
306 active_popup_client
= NULL
;
311 Create the global accel object \c keys.
313 void Workspace::initShortcuts()
315 keys
= new KActionCollection( this );
316 KActionCollection
* actionCollection
= keys
;
319 // a separate KActionCollection is needed for the shortcut for disabling global shortcuts,
320 // otherwise it would also disable itself
321 disable_shortcuts_keys
= new KActionCollection( this );
323 #warning TODO PORT ME (KGlobalAccel related)
325 // FIXME KAccel port... needed?
326 //disable_shortcuts_keys->disableBlocking( true );
328 #include "kwinbindings.cpp"
332 void Workspace::readShortcuts()
335 #warning TODO PORT ME (KGlobalAccel related)
337 //KGlobalAccel::self()->readSettings();
339 KAction
*kaction
= qobject_cast
<KAction
*>( keys
->action("Walk Through Desktops") );
341 cutWalkThroughDesktops
= kaction
->globalShortcut();
343 kaction
= qobject_cast
<KAction
*>( keys
->action("Walk Through Desktops (Reverse)") );
345 cutWalkThroughDesktopsReverse
= kaction
->globalShortcut();
347 kaction
= qobject_cast
<KAction
*>( keys
->action("Walk Through Desktop List") );
349 cutWalkThroughDesktopList
= kaction
->globalShortcut();
351 kaction
= qobject_cast
<KAction
*>( keys
->action("Walk Through Desktop List (Reverse)") );
353 cutWalkThroughDesktopListReverse
= kaction
->globalShortcut();
355 kaction
= qobject_cast
<KAction
*>( keys
->action("Walk Through Windows") );
357 cutWalkThroughWindows
= kaction
->globalShortcut();
359 kaction
= qobject_cast
<KAction
*>( keys
->action("Walk Through Windows (Reverse)") );
361 cutWalkThroughWindowsReverse
= kaction
->globalShortcut();
364 popup
= NULL
; // so that it's recreated next time
369 void Workspace::setupWindowShortcut( Client
* c
)
371 assert( client_keys_dialog
== NULL
);
373 #warning TODO PORT ME (KGlobalAccel related)
375 // keys->setEnabled( false );
376 // disable_shortcuts_keys->setEnabled( false );
377 // client_keys->setEnabled( false );
378 client_keys_dialog
= new ShortcutDialog( c
->shortcut().primary());
379 client_keys_client
= c
;
380 connect( client_keys_dialog
, SIGNAL( dialogDone( bool )), SLOT( setupWindowShortcutDone( bool )));
381 QRect r
= clientArea( ScreenArea
, c
);
382 QSize size
= client_keys_dialog
->sizeHint();
383 QPoint pos
= c
->pos() + c
->clientPos();
384 if( pos
.x() + size
.width() >= r
.right())
385 pos
.setX( r
.right() - size
.width());
386 if( pos
.y() + size
.height() >= r
.bottom())
387 pos
.setY( r
.bottom() - size
.height());
388 client_keys_dialog
->move( pos
);
389 client_keys_dialog
->show();
390 active_popup
= client_keys_dialog
;
391 active_popup_client
= c
;
394 void Workspace::setupWindowShortcutDone( bool ok
)
396 // keys->setEnabled( true );
397 // disable_shortcuts_keys->setEnabled( true );
398 // client_keys->setEnabled( true );
400 client_keys_client
->setShortcut( KShortcut( client_keys_dialog
->shortcut()).toString());
402 delete client_keys_dialog
;
403 client_keys_dialog
= NULL
;
404 client_keys_client
= NULL
;
407 void Workspace::clientShortcutUpdated( Client
* c
)
409 QString key
= QString::number( c
->window());
410 QAction
* action
= client_keys
->action( key
.toLatin1().constData() );
411 if( !c
->shortcut().isEmpty())
413 action
->setShortcuts(c
->shortcut());
414 connect(action
, SIGNAL(triggered(bool)), c
, SLOT(shortcutActivated()));
415 action
->setEnabled( true );
423 void Workspace::clientPopupActivated( QAction
*action
)
425 if ( !action
->data().isValid() )
428 WindowOperation op
= static_cast< WindowOperation
>( action
->data().toInt() );
429 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
434 if( !c
->isFullScreen() && c
->userCanSetFullScreen())
435 type
= "fullscreenaltf3";
438 if( !c
->noBorder() && c
->userCanSetNoBorder())
439 type
= "noborderaltf3";
445 helperDialog( type
, c
);
446 performWindowOperation( c
, op
);
450 void Workspace::performWindowOperation( Client
* c
, Options::WindowOperation op
)
455 if (op
== Options::MoveOp
|| op
== Options::UnrestrictedMoveOp
)
456 QCursor::setPos( c
->geometry().center() );
457 if (op
== Options::ResizeOp
|| op
== Options::UnrestrictedResizeOp
)
458 QCursor::setPos( c
->geometry().bottomRight());
461 case Options::MoveOp
:
462 c
->performMouseCommand( Options::MouseMove
, cursorPos() );
464 case Options::UnrestrictedMoveOp
:
465 c
->performMouseCommand( Options::MouseUnrestrictedMove
, cursorPos() );
467 case Options::ResizeOp
:
468 c
->performMouseCommand( Options::MouseResize
, cursorPos() );
470 case Options::UnrestrictedResizeOp
:
471 c
->performMouseCommand( Options::MouseUnrestrictedResize
, cursorPos() );
473 case Options::CloseOp
:
476 case Options::MaximizeOp
:
477 c
->maximize( c
->maximizeMode() == Client::MaximizeFull
478 ? Client::MaximizeRestore
: Client::MaximizeFull
);
480 case Options::HMaximizeOp
:
481 c
->maximize( c
->maximizeMode() ^ Client::MaximizeHorizontal
);
483 case Options::VMaximizeOp
:
484 c
->maximize( c
->maximizeMode() ^ Client::MaximizeVertical
);
486 case Options::RestoreOp
:
487 c
->maximize( Client::MaximizeRestore
);
489 case Options::MinimizeOp
:
492 case Options::ShadeOp
:
493 c
->performMouseCommand( Options::MouseShade
, cursorPos());
495 case Options::OnAllDesktopsOp
:
496 c
->setOnAllDesktops( !c
->isOnAllDesktops() );
498 case Options::FullScreenOp
:
499 c
->setFullScreen( !c
->isFullScreen(), true );
501 case Options::NoBorderOp
:
502 c
->setUserNoBorder( !c
->isUserNoBorder());
504 case Options::KeepAboveOp
:
506 StackingUpdatesBlocker
blocker( this );
507 bool was
= c
->keepAbove();
508 c
->setKeepAbove( !c
->keepAbove() );
509 if( was
&& !c
->keepAbove())
513 case Options::KeepBelowOp
:
515 StackingUpdatesBlocker
blocker( this );
516 bool was
= c
->keepBelow();
517 c
->setKeepBelow( !c
->keepBelow() );
518 if( was
&& !c
->keepBelow())
522 case Options::OperationsOp
:
523 c
->performMouseCommand( Options::MouseShade
, cursorPos());
525 case Options::WindowRulesOp
:
526 editWindowRules( c
, false );
528 case Options::ApplicationRulesOp
:
529 editWindowRules( c
, true );
531 case Options::SetupWindowShortcutOp
:
532 setupWindowShortcut( c
);
534 case Options::LowerOp
:
543 Performs a mouse command on this client (see options.h)
545 bool Client::performMouseCommand( Options::MouseCommand command
, const QPoint
&globalPos
, bool handled
)
550 case Options::MouseRaise
:
551 workspace()->raiseClient( this );
553 case Options::MouseLower
:
554 workspace()->lowerClient( this );
556 case Options::MouseShade
:
560 case Options::MouseSetShade
:
561 setShade( ShadeNormal
);
564 case Options::MouseUnsetShade
:
565 setShade( ShadeNone
);
568 case Options::MouseOperationsMenu
:
569 if ( isActive() && options
->clickRaise
)
571 workspace()->showWindowMenu( globalPos
, this );
573 case Options::MouseToggleRaiseAndLower
:
574 workspace()->raiseOrLowerClient( this );
576 case Options::MouseActivateAndRaise
:
577 replay
= isActive(); // for clickraise mode
578 workspace()->takeActivity( this, ActivityFocus
| ActivityRaise
, handled
&& replay
);
579 workspace()->setActiveScreenMouse( globalPos
);
581 case Options::MouseActivateAndLower
:
582 workspace()->requestFocus( this );
583 workspace()->lowerClient( this );
584 workspace()->setActiveScreenMouse( globalPos
);
586 case Options::MouseActivate
:
587 replay
= isActive(); // for clickraise mode
588 workspace()->takeActivity( this, ActivityFocus
, handled
&& replay
);
589 workspace()->setActiveScreenMouse( globalPos
);
591 case Options::MouseActivateRaiseAndPassClick
:
592 workspace()->takeActivity( this, ActivityFocus
| ActivityRaise
, handled
);
593 workspace()->setActiveScreenMouse( globalPos
);
596 case Options::MouseActivateAndPassClick
:
597 workspace()->takeActivity( this, ActivityFocus
, handled
);
598 workspace()->setActiveScreenMouse( globalPos
);
601 case Options::MouseActivateRaiseAndMove
:
602 case Options::MouseActivateRaiseAndUnrestrictedMove
:
603 workspace()->raiseClient( this );
604 workspace()->requestFocus( this );
605 workspace()->setActiveScreenMouse( globalPos
);
606 if( options
->moveMode
== Options::Transparent
&& isMovable())
607 move_faked_activity
= workspace()->fakeRequestedActivity( this );
609 case Options::MouseMove
:
610 case Options::MouseUnrestrictedMove
:
615 finishMoveResize( false );
616 mode
= PositionCenter
;
618 moveOffset
= QPoint( globalPos
.x() - x(), globalPos
.y() - y()); // map from global
619 invertedMoveOffset
= rect().bottomRight() - moveOffset
;
620 unrestrictedMoveResize
= ( command
== Options::MouseActivateRaiseAndUnrestrictedMove
621 || command
== Options::MouseUnrestrictedMove
);
622 if( !startMoveResize())
627 case Options::MouseResize
:
628 case Options::MouseUnrestrictedResize
:
630 if (!isResizable() || isShade())
633 finishMoveResize( false );
635 moveOffset
= QPoint( globalPos
.x() - x(), globalPos
.y() - y()); // map from global
636 int x
= moveOffset
.x(), y
= moveOffset
.y();
637 bool left
= x
< width() / 3;
638 bool right
= x
>= 2 * width() / 3;
639 bool top
= y
< height() / 3;
640 bool bot
= y
>= 2 * height() / 3;
642 mode
= left
? PositionTopLeft
: (right
? PositionTopRight
: PositionTop
);
644 mode
= left
? PositionBottomLeft
: (right
? PositionBottomRight
: PositionBottom
);
646 mode
= (x
< width() / 2) ? PositionLeft
: PositionRight
;
647 invertedMoveOffset
= rect().bottomRight() - moveOffset
;
648 unrestrictedMoveResize
= ( command
== Options::MouseUnrestrictedResize
);
649 if( !startMoveResize())
654 case Options::MouseMaximize
:
655 maximize( Client::MaximizeFull
);
657 case Options::MouseRestore
:
658 maximize( Client::MaximizeRestore
);
660 case Options::MouseMinimize
:
663 case Options::MouseAbove
:
665 StackingUpdatesBlocker
blocker( workspace());
667 setKeepBelow( false );
669 setKeepAbove( true );
672 case Options::MouseBelow
:
674 StackingUpdatesBlocker
blocker( workspace());
676 setKeepAbove( false );
678 setKeepBelow( true );
681 case Options::MousePreviousDesktop
:
682 workspace()->windowToPreviousDesktop( this );
684 case Options::MouseNextDesktop
:
685 workspace()->windowToNextDesktop( this );
687 case Options::MouseOpacityMore
:
688 setOpacity( qMin( opacity() + 0.1, 1.0 ));
690 case Options::MouseOpacityLess
:
691 setOpacity( qMax( opacity() - 0.1, 0.0 ));
693 case Options::MouseNothing
:
701 void Workspace::showWindowMenuAt( unsigned long, int, int )
703 slotWindowOperations();
706 void Workspace::loadEffect( const QString
& name
)
709 static_cast<EffectsHandlerImpl
*>(effects
)->loadEffect( name
);
712 void Workspace::toggleEffect( const QString
& name
)
715 static_cast<EffectsHandlerImpl
*>(effects
)->toggleEffect( name
);
718 void Workspace::unloadEffect( const QString
& name
)
721 static_cast<EffectsHandlerImpl
*>(effects
)->unloadEffect( name
);
724 void Workspace::reloadEffect( const QString
& name
)
727 static_cast<EffectsHandlerImpl
*>(effects
)->reloadEffect( name
);
730 void Workspace::slotActivateAttentionWindow()
732 if( attention_chain
.count() > 0 )
733 activateClient( attention_chain
.first());
736 void Workspace::slotSwitchDesktopNext()
738 int d
= currentDesktop() + 1;
739 if ( d
> numberOfDesktops() )
741 if ( options
->rollOverDesktops
)
750 setCurrentDesktop(d
);
753 void Workspace::slotSwitchDesktopPrevious()
755 int d
= currentDesktop() - 1;
758 if ( options
->rollOverDesktops
)
759 d
= numberOfDesktops();
763 setCurrentDesktop(d
);
766 void Workspace::slotSwitchDesktopRight()
768 int desktop
= desktopToRight( currentDesktop(), options
->rollOverDesktops
);
769 if( desktop
== currentDesktop())
771 setCurrentDesktop( desktop
);
774 void Workspace::slotSwitchDesktopLeft()
776 int desktop
= desktopToLeft( currentDesktop(), options
->rollOverDesktops
);
777 if( desktop
== currentDesktop())
779 setCurrentDesktop( desktop
);
782 void Workspace::slotSwitchDesktopUp()
784 int desktop
= desktopUp( currentDesktop(), options
->rollOverDesktops
);
785 if( desktop
== currentDesktop())
787 setCurrentDesktop( desktop
);
790 void Workspace::slotSwitchDesktopDown()
792 int desktop
= desktopDown( currentDesktop(), options
->rollOverDesktops
);
793 if( desktop
== currentDesktop())
795 setCurrentDesktop( desktop
);
798 void Workspace::slotSwitchToDesktop( int i
)
800 setCurrentDesktop( i
);
804 void Workspace::slotWindowToDesktop( int i
)
806 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
807 if( i
>= 1 && i
<= numberOfDesktops() && c
811 sendClientToDesktop( c
, i
, true );
814 void Workspace::slotSwitchToScreen( int i
)
816 setCurrentScreen( i
);
819 void Workspace::slotSwitchToNextScreen()
821 slotSwitchToScreen(( activeScreen() + 1 ) % numScreens());
824 void Workspace::slotWindowToScreen( int i
)
826 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
827 if( i
>= 0 && i
<= numScreens() && c
832 sendClientToScreen( c
, i
);
836 void Workspace::slotWindowToNextScreen()
838 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
844 sendClientToScreen( c
, ( c
->screen() + 1 ) % numScreens());
849 Maximizes the popup client
851 void Workspace::slotWindowMaximize()
853 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
855 performWindowOperation( c
, Options::MaximizeOp
);
859 Maximizes the popup client vertically
861 void Workspace::slotWindowMaximizeVertical()
863 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
865 performWindowOperation( c
, Options::VMaximizeOp
);
869 Maximizes the popup client horiozontally
871 void Workspace::slotWindowMaximizeHorizontal()
873 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
875 performWindowOperation( c
, Options::HMaximizeOp
);
880 Minimizes the popup client
882 void Workspace::slotWindowMinimize()
884 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
885 performWindowOperation( c
, Options::MinimizeOp
);
889 Shades/unshades the popup client respectively
891 void Workspace::slotWindowShade()
893 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
894 performWindowOperation( c
, Options::ShadeOp
);
898 Raises the popup client
900 void Workspace::slotWindowRaise()
902 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
908 Lowers the popup client
910 void Workspace::slotWindowLower()
912 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
918 Does a toggle-raise-and-lower on the popup client;
920 void Workspace::slotWindowRaiseOrLower()
922 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
924 raiseOrLowerClient( c
);
927 void Workspace::slotWindowOnAllDesktops()
929 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
931 c
->setOnAllDesktops( !c
->isOnAllDesktops());
934 void Workspace::slotWindowFullScreen()
936 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
938 performWindowOperation( c
, Options::FullScreenOp
);
941 void Workspace::slotWindowNoBorder()
943 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
945 performWindowOperation( c
, Options::NoBorderOp
);
948 void Workspace::slotWindowAbove()
950 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
952 performWindowOperation( c
, Options::KeepAboveOp
);
955 void Workspace::slotWindowBelow()
957 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
959 performWindowOperation( c
, Options::KeepBelowOp
);
961 void Workspace::slotSetupWindowShortcut()
963 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
965 performWindowOperation( c
, Options::SetupWindowShortcutOp
);
969 Move window to next desktop
971 void Workspace::slotWindowToNextDesktop()
973 windowToNextDesktop( active_popup_client
? active_popup_client
: active_client
);
976 void Workspace::windowToNextDesktop( Client
* c
)
978 int d
= currentDesktop() + 1;
979 if ( d
> numberOfDesktops() )
981 if (c
&& !c
->isDesktop()
982 && !c
->isDock() && !c
->isTopMenu())
984 setClientIsMoving( c
);
985 setCurrentDesktop( d
);
986 setClientIsMoving( NULL
);
991 Move window to previous desktop
993 void Workspace::slotWindowToPreviousDesktop()
995 windowToPreviousDesktop( active_popup_client
? active_popup_client
: active_client
);
998 void Workspace::windowToPreviousDesktop( Client
* c
)
1000 int d
= currentDesktop() - 1;
1002 d
= numberOfDesktops();
1003 if (c
&& !c
->isDesktop()
1004 && !c
->isDock() && !c
->isTopMenu())
1006 setClientIsMoving( c
);
1007 setCurrentDesktop( d
);
1008 setClientIsMoving( NULL
);
1012 void Workspace::slotWindowToDesktopRight()
1014 int d
= desktopToRight( currentDesktop(), options
->rollOverDesktops
);
1015 if( d
== currentDesktop())
1017 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
1018 if (c
&& !c
->isDesktop()
1019 && !c
->isDock() && !c
->isTopMenu())
1021 setClientIsMoving( c
);
1022 setCurrentDesktop( d
);
1023 setClientIsMoving( NULL
);
1027 void Workspace::slotWindowToDesktopLeft()
1029 int d
= desktopToLeft( currentDesktop(), options
->rollOverDesktops
);
1030 if( d
== currentDesktop())
1032 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
1033 if (c
&& !c
->isDesktop()
1034 && !c
->isDock() && !c
->isTopMenu())
1036 setClientIsMoving( c
);
1037 setCurrentDesktop( d
);
1038 setClientIsMoving( NULL
);
1042 void Workspace::slotWindowToDesktopUp()
1044 int d
= desktopUp( currentDesktop(), options
->rollOverDesktops
);
1045 if( d
== currentDesktop())
1047 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
1048 if (c
&& !c
->isDesktop()
1049 && !c
->isDock() && !c
->isTopMenu())
1051 setClientIsMoving( c
);
1052 setCurrentDesktop( d
);
1053 setClientIsMoving( NULL
);
1057 void Workspace::slotWindowToDesktopDown()
1059 int d
= desktopDown( currentDesktop(), options
->rollOverDesktops
);
1060 if( d
== currentDesktop())
1062 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
1063 if (c
&& !c
->isDesktop()
1064 && !c
->isDock() && !c
->isTopMenu())
1066 setClientIsMoving( c
);
1067 setCurrentDesktop( d
);
1068 setClientIsMoving( NULL
);
1074 Kill Window feature, similar to xkill
1076 void Workspace::slotKillWindow()
1078 KillWindow
kill( this );
1083 Sends the popup client to desktop \a desk
1085 Internal slot for the window operation menu
1087 void Workspace::slotSendToDesktop( QAction
*action
)
1089 int desk
= action
->data().toInt();
1090 if ( !active_popup_client
)
1093 { // the 'on_all_desktops' menu entry
1094 active_popup_client
->setOnAllDesktops( !active_popup_client
->isOnAllDesktops());
1098 sendClientToDesktop( active_popup_client
, desk
, false );
1103 Shows the window operations popup menu for the activeClient()
1105 void Workspace::slotWindowOperations()
1107 if ( !active_client
)
1109 QPoint pos
= active_client
->pos() + active_client
->clientPos();
1110 showWindowMenu( pos
.x(), pos
.y(), active_client
);
1113 void Workspace::showWindowMenu( const QRect
&pos
, Client
* cl
)
1115 if (!KAuthorized::authorizeKAction("kwin_rmb"))
1119 if( active_popup_client
!= NULL
) // recursion
1121 if ( cl
->isDesktop()
1126 active_popup_client
= cl
;
1127 QMenu
* p
= clientPopup();
1130 int y
= pos
.bottom();
1132 p
->exec( QPoint( x
, y
) );
1135 QRect area
= clientArea(ScreenArea
, QPoint(x
, y
), currentDesktop());
1136 clientPopupAboutToShow(); // needed for sizeHint() to be correct :-/
1137 int popupHeight
= p
->sizeHint().height();
1138 if (y
+ popupHeight
< area
.height())
1139 p
->exec( QPoint( x
, y
) );
1141 p
->exec( QPoint( x
, pos
.top() - popupHeight
) );
1143 // active popup may be already changed (e.g. the window shortcut dialog)
1144 if( active_popup
== p
)
1149 Closes the popup client
1151 void Workspace::slotWindowClose()
1153 if ( tab_box
->isVisible())
1155 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
1156 performWindowOperation( c
, Options::CloseOp
);
1160 Starts keyboard move mode for the popup client
1162 void Workspace::slotWindowMove()
1164 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
1165 performWindowOperation( c
, Options::UnrestrictedMoveOp
);
1169 Starts keyboard resize mode for the popup client
1171 void Workspace::slotWindowResize()
1173 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
1174 performWindowOperation( c
, Options::UnrestrictedResizeOp
);
1177 void Client::setShortcut( const QString
& _cut
)
1179 QString cut
= rules()->checkShortcut( _cut
);
1181 return setShortcutInternal( KShortcut());
1183 // base+(abcdef)<space>base+(abcdef)
1184 // E.g. Alt+Ctrl+(ABCDEF) Win+X,Win+(ABCDEF)
1185 if( !cut
.contains( '(' ) && !cut
.contains( ')' ) && !cut
.contains( ' ' ))
1187 if( workspace()->shortcutAvailable( KShortcut( cut
), this ))
1188 setShortcutInternal( KShortcut( cut
));
1190 setShortcutInternal( KShortcut());
1193 QList
< KShortcut
> keys
;
1194 QStringList groups
= cut
.split( ' ');
1195 for( QStringList::ConstIterator it
= groups
.begin();
1199 QRegExp
reg( "(.*\\+)\\((.*)\\)" );
1200 if( reg
.indexIn( *it
) > -1 )
1202 QString base
= reg
.cap( 1 );
1203 QString list
= reg
.cap( 2 );
1208 KShortcut
c( base
+ list
[ i
] );
1214 for( QList
< KShortcut
>::ConstIterator it
= keys
.begin();
1218 if( _shortcut
== *it
) // current one is in the list
1221 for( QList
< KShortcut
>::ConstIterator it
= keys
.begin();
1225 if( workspace()->shortcutAvailable( *it
, this ))
1227 setShortcutInternal( *it
);
1231 setShortcutInternal( KShortcut());
1234 void Client::setShortcutInternal( const KShortcut
& cut
)
1236 if( _shortcut
== cut
)
1240 workspace()->clientShortcutUpdated( this );
1243 bool Workspace::shortcutAvailable( const KShortcut
& cut
, Client
* ignore
) const
1245 // TODO check global shortcuts etc.
1246 for( ClientList::ConstIterator it
= clients
.begin();
1247 it
!= clients
.end();
1250 if( (*it
) != ignore
&& (*it
)->shortcut() == cut
)