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::discardPopup()
201 void Workspace::setPopupClientOpacity( QAction
* action
)
203 if( active_popup_client
== NULL
)
205 int level
= action
->data().toInt();
206 active_popup_client
->setOpacity( level
/ 100.0 );
210 The client popup menu will become visible soon.
212 Adjust the items according to the respective popup client.
214 void Workspace::clientPopupAboutToShow()
216 if ( !active_popup_client
|| !popup
)
219 if ( numberOfDesktops() == 1 )
229 mResizeOpAction
->setEnabled( active_popup_client
->isResizable() );
230 mMoveOpAction
->setEnabled( active_popup_client
->isMovableAcrossScreens() );
231 mMaximizeOpAction
->setEnabled( active_popup_client
->isMaximizable() );
232 mMaximizeOpAction
->setChecked( active_popup_client
->maximizeMode() == Client::MaximizeFull
);
233 mShadeOpAction
->setEnabled( active_popup_client
->isShadeable() );
234 mShadeOpAction
->setChecked( active_popup_client
->shadeMode() != ShadeNone
);
235 mKeepAboveOpAction
->setChecked( active_popup_client
->keepAbove() );
236 mKeepBelowOpAction
->setChecked( active_popup_client
->keepBelow() );
237 mFullScreenOpAction
->setEnabled( active_popup_client
->userCanSetFullScreen() );
238 mFullScreenOpAction
->setChecked( active_popup_client
->isFullScreen() );
239 mNoBorderOpAction
->setEnabled( active_popup_client
->userCanSetNoBorder() );
240 mNoBorderOpAction
->setChecked( active_popup_client
->noBorder() );
241 mMinimizeOpAction
->setEnabled( active_popup_client
->isMinimizable() );
242 mCloseOpAction
->setEnabled( active_popup_client
->isCloseable() );
243 if( trans_popup
!= NULL
)
245 foreach( QAction
* action
, trans_popup
->actions())
247 if( action
->data().toInt() == qRound( active_popup_client
->opacity() * 100 ))
248 action
->setChecked( true );
250 action
->setChecked( false );
256 void Workspace::initDesktopPopup()
261 desk_popup
= new QMenu( popup
);
262 desk_popup
->setFont(KGlobalSettings::menuFont());
263 connect( desk_popup
, SIGNAL( triggered(QAction
*) ),
264 this, SLOT( slotSendToDesktop(QAction
*) ) );
265 connect( desk_popup
, SIGNAL( aboutToShow() ),
266 this, SLOT( desktopPopupAboutToShow() ) );
268 QAction
*action
= desk_popup
->menuAction();
269 popup
->insertAction(advanced_popup
->menuAction(), action
);
270 action
->setText( i18n("To &Desktop") );
274 Adjusts the desktop popup to the current values and the location of
277 void Workspace::desktopPopupAboutToShow()
283 QAction
*action
= desk_popup
->addAction( i18n("&All Desktops") );
284 action
->setData( 0 );
285 action
->setCheckable( true );
287 if ( active_popup_client
&& active_popup_client
->isOnAllDesktops() )
288 action
->setChecked( true );
289 desk_popup
->addSeparator();
292 for ( int i
= 1; i
<= numberOfDesktops(); i
++ ) {
293 QString
basic_name("%1 %2");
295 basic_name
.prepend('&');
297 action
= desk_popup
->addAction( basic_name
.arg(i
).arg( desktopName(i
).replace( '&', "&&" ) ) );
298 action
->setData( i
);
299 action
->setCheckable( true );
301 if ( active_popup_client
&&
302 !active_popup_client
->isOnAllDesktops() && active_popup_client
->desktop() == i
)
303 action
->setChecked( true );
307 void Workspace::closeActivePopup()
311 active_popup
->close();
313 active_popup_client
= NULL
;
318 Create the global accel object \c keys.
320 void Workspace::initShortcuts()
322 keys
= new KActionCollection( this );
323 KActionCollection
* actionCollection
= keys
;
326 // a separate KActionCollection is needed for the shortcut for disabling global shortcuts,
327 // otherwise it would also disable itself
328 disable_shortcuts_keys
= new KActionCollection( this );
330 #warning TODO PORT ME (KGlobalAccel related)
332 // FIXME KAccel port... needed?
333 //disable_shortcuts_keys->disableBlocking( true );
335 #include "kwinbindings.cpp"
339 void Workspace::readShortcuts()
342 #warning TODO PORT ME (KGlobalAccel related)
344 //KGlobalAccel::self()->readSettings();
346 KAction
*kaction
= qobject_cast
<KAction
*>( keys
->action("Walk Through Desktops") );
348 cutWalkThroughDesktops
= kaction
->globalShortcut();
350 kaction
= qobject_cast
<KAction
*>( keys
->action("Walk Through Desktops (Reverse)") );
352 cutWalkThroughDesktopsReverse
= kaction
->globalShortcut();
354 kaction
= qobject_cast
<KAction
*>( keys
->action("Walk Through Desktop List") );
356 cutWalkThroughDesktopList
= kaction
->globalShortcut();
358 kaction
= qobject_cast
<KAction
*>( keys
->action("Walk Through Desktop List (Reverse)") );
360 cutWalkThroughDesktopListReverse
= kaction
->globalShortcut();
362 kaction
= qobject_cast
<KAction
*>( keys
->action("Walk Through Windows") );
364 cutWalkThroughWindows
= kaction
->globalShortcut();
366 kaction
= qobject_cast
<KAction
*>( keys
->action("Walk Through Windows (Reverse)") );
368 cutWalkThroughWindowsReverse
= kaction
->globalShortcut();
369 discardPopup(); // so that it's recreated next time
373 void Workspace::setupWindowShortcut( Client
* c
)
375 assert( client_keys_dialog
== NULL
);
377 #warning TODO PORT ME (KGlobalAccel related)
379 // keys->setEnabled( false );
380 // disable_shortcuts_keys->setEnabled( false );
381 // client_keys->setEnabled( false );
382 client_keys_dialog
= new ShortcutDialog( c
->shortcut().primary());
383 client_keys_client
= c
;
384 connect( client_keys_dialog
, SIGNAL( dialogDone( bool )), SLOT( setupWindowShortcutDone( bool )));
385 QRect r
= clientArea( ScreenArea
, c
);
386 QSize size
= client_keys_dialog
->sizeHint();
387 QPoint pos
= c
->pos() + c
->clientPos();
388 if( pos
.x() + size
.width() >= r
.right())
389 pos
.setX( r
.right() - size
.width());
390 if( pos
.y() + size
.height() >= r
.bottom())
391 pos
.setY( r
.bottom() - size
.height());
392 client_keys_dialog
->move( pos
);
393 client_keys_dialog
->show();
394 active_popup
= client_keys_dialog
;
395 active_popup_client
= c
;
398 void Workspace::setupWindowShortcutDone( bool ok
)
400 // keys->setEnabled( true );
401 // disable_shortcuts_keys->setEnabled( true );
402 // client_keys->setEnabled( true );
404 client_keys_client
->setShortcut( KShortcut( client_keys_dialog
->shortcut()).toString());
406 client_keys_dialog
->deleteLater();
407 client_keys_dialog
= NULL
;
408 client_keys_client
= NULL
;
411 void Workspace::clientShortcutUpdated( Client
* c
)
413 QString key
= QString( "_k_session:%1" ).arg(c
->window());
414 QAction
* action
= client_keys
->action( key
.toLatin1().constData() );
415 if( !c
->shortcut().isEmpty())
417 if( action
== NULL
) // new shortcut
419 action
= client_keys
->addAction(QString( key
));
420 action
->setText( i18n("Activate Window (%1)", c
->caption()) );
421 connect( action
, SIGNAL(triggered(bool)), c
, SLOT(shortcutActivated()) );
424 KAction
*kaction
= qobject_cast
<KAction
*>( action
);
425 // no autoloading, since it's configured explicitly here and is not meant to be reused
426 // (the key is the window id anyway, which is kind of random)
427 kaction
->setGlobalShortcut(
428 c
->shortcut(), KAction::ActiveShortcut
, KAction::NoAutoloading
);
429 kaction
->setEnabled( true );
433 KAction
*kaction
= qobject_cast
<KAction
*>( action
);
436 kaction
->forgetGlobalShortcut();
442 void Workspace::clientPopupActivated( QAction
*action
)
444 if ( !action
->data().isValid() )
447 WindowOperation op
= static_cast< WindowOperation
>( action
->data().toInt() );
448 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
453 if( !c
->isFullScreen() && c
->userCanSetFullScreen())
454 type
= "fullscreenaltf3";
457 if( !c
->noBorder() && c
->userCanSetNoBorder())
458 type
= "noborderaltf3";
464 helperDialog( type
, c
);
465 performWindowOperation( c
, op
);
469 void Workspace::performWindowOperation( Client
* c
, Options::WindowOperation op
)
474 if (op
== Options::MoveOp
|| op
== Options::UnrestrictedMoveOp
)
475 QCursor::setPos( c
->geometry().center() );
476 if (op
== Options::ResizeOp
|| op
== Options::UnrestrictedResizeOp
)
477 QCursor::setPos( c
->geometry().bottomRight());
480 case Options::MoveOp
:
481 c
->performMouseCommand( Options::MouseMove
, cursorPos() );
483 case Options::UnrestrictedMoveOp
:
484 c
->performMouseCommand( Options::MouseUnrestrictedMove
, cursorPos() );
486 case Options::ResizeOp
:
487 c
->performMouseCommand( Options::MouseResize
, cursorPos() );
489 case Options::UnrestrictedResizeOp
:
490 c
->performMouseCommand( Options::MouseUnrestrictedResize
, cursorPos() );
492 case Options::CloseOp
:
495 case Options::MaximizeOp
:
496 c
->maximize( c
->maximizeMode() == Client::MaximizeFull
497 ? Client::MaximizeRestore
: Client::MaximizeFull
);
499 case Options::HMaximizeOp
:
500 c
->maximize( c
->maximizeMode() ^ Client::MaximizeHorizontal
);
502 case Options::VMaximizeOp
:
503 c
->maximize( c
->maximizeMode() ^ Client::MaximizeVertical
);
505 case Options::RestoreOp
:
506 c
->maximize( Client::MaximizeRestore
);
508 case Options::MinimizeOp
:
511 case Options::ShadeOp
:
512 c
->performMouseCommand( Options::MouseShade
, cursorPos());
514 case Options::OnAllDesktopsOp
:
515 c
->setOnAllDesktops( !c
->isOnAllDesktops() );
517 case Options::FullScreenOp
:
518 c
->setFullScreen( !c
->isFullScreen(), true );
520 case Options::NoBorderOp
:
521 c
->setNoBorder( !c
->noBorder());
523 case Options::KeepAboveOp
:
525 StackingUpdatesBlocker
blocker( this );
526 bool was
= c
->keepAbove();
527 c
->setKeepAbove( !c
->keepAbove() );
528 if( was
&& !c
->keepAbove())
532 case Options::KeepBelowOp
:
534 StackingUpdatesBlocker
blocker( this );
535 bool was
= c
->keepBelow();
536 c
->setKeepBelow( !c
->keepBelow() );
537 if( was
&& !c
->keepBelow())
541 case Options::OperationsOp
:
542 c
->performMouseCommand( Options::MouseShade
, cursorPos());
544 case Options::WindowRulesOp
:
545 editWindowRules( c
, false );
547 case Options::ApplicationRulesOp
:
548 editWindowRules( c
, true );
550 case Options::SetupWindowShortcutOp
:
551 setupWindowShortcut( c
);
553 case Options::LowerOp
:
562 Performs a mouse command on this client (see options.h)
564 bool Client::performMouseCommand( Options::MouseCommand command
, const QPoint
&globalPos
, bool handled
)
569 case Options::MouseRaise
:
570 workspace()->raiseClient( this );
572 case Options::MouseLower
:
573 workspace()->lowerClient( this );
575 case Options::MouseShade
:
577 cancelShadeHoverTimer();
579 case Options::MouseSetShade
:
580 setShade( ShadeNormal
);
581 cancelShadeHoverTimer();
583 case Options::MouseUnsetShade
:
584 setShade( ShadeNone
);
585 cancelShadeHoverTimer();
587 case Options::MouseOperationsMenu
:
588 if ( isActive() && options
->clickRaise
)
590 workspace()->showWindowMenu( globalPos
, this );
592 case Options::MouseToggleRaiseAndLower
:
593 workspace()->raiseOrLowerClient( this );
595 case Options::MouseActivateAndRaise
:
596 replay
= isActive(); // for clickraise mode
597 workspace()->takeActivity( this, ActivityFocus
| ActivityRaise
, handled
&& replay
);
598 workspace()->setActiveScreenMouse( globalPos
);
600 case Options::MouseActivateAndLower
:
601 workspace()->requestFocus( this );
602 workspace()->lowerClient( this );
603 workspace()->setActiveScreenMouse( globalPos
);
605 case Options::MouseActivate
:
606 replay
= isActive(); // for clickraise mode
607 workspace()->takeActivity( this, ActivityFocus
, handled
&& replay
);
608 workspace()->setActiveScreenMouse( globalPos
);
610 case Options::MouseActivateRaiseAndPassClick
:
611 workspace()->takeActivity( this, ActivityFocus
| ActivityRaise
, handled
);
612 workspace()->setActiveScreenMouse( globalPos
);
615 case Options::MouseActivateAndPassClick
:
616 workspace()->takeActivity( this, ActivityFocus
, handled
);
617 workspace()->setActiveScreenMouse( globalPos
);
620 case Options::MouseActivateRaiseAndMove
:
621 case Options::MouseActivateRaiseAndUnrestrictedMove
:
622 workspace()->raiseClient( this );
623 workspace()->requestFocus( this );
624 workspace()->setActiveScreenMouse( globalPos
);
625 if( options
->moveMode
== Options::Transparent
&& isMovableAcrossScreens())
626 move_faked_activity
= workspace()->fakeRequestedActivity( this );
628 case Options::MouseMove
:
629 case Options::MouseUnrestrictedMove
:
631 if (!isMovableAcrossScreens())
634 finishMoveResize( false );
635 mode
= PositionCenter
;
637 moveOffset
= QPoint( globalPos
.x() - x(), globalPos
.y() - y()); // map from global
638 invertedMoveOffset
= rect().bottomRight() - moveOffset
;
639 unrestrictedMoveResize
= ( command
== Options::MouseActivateRaiseAndUnrestrictedMove
640 || command
== Options::MouseUnrestrictedMove
);
641 if( !startMoveResize())
646 case Options::MouseResize
:
647 case Options::MouseUnrestrictedResize
:
649 if (!isResizable() || isShade())
652 finishMoveResize( false );
654 moveOffset
= QPoint( globalPos
.x() - x(), globalPos
.y() - y()); // map from global
655 int x
= moveOffset
.x(), y
= moveOffset
.y();
656 bool left
= x
< width() / 3;
657 bool right
= x
>= 2 * width() / 3;
658 bool top
= y
< height() / 3;
659 bool bot
= y
>= 2 * height() / 3;
661 mode
= left
? PositionTopLeft
: (right
? PositionTopRight
: PositionTop
);
663 mode
= left
? PositionBottomLeft
: (right
? PositionBottomRight
: PositionBottom
);
665 mode
= (x
< width() / 2) ? PositionLeft
: PositionRight
;
666 invertedMoveOffset
= rect().bottomRight() - moveOffset
;
667 unrestrictedMoveResize
= ( command
== Options::MouseUnrestrictedResize
);
668 if( !startMoveResize())
673 case Options::MouseMaximize
:
674 maximize( Client::MaximizeFull
);
676 case Options::MouseRestore
:
677 maximize( Client::MaximizeRestore
);
679 case Options::MouseMinimize
:
682 case Options::MouseAbove
:
684 StackingUpdatesBlocker
blocker( workspace());
686 setKeepBelow( false );
688 setKeepAbove( true );
691 case Options::MouseBelow
:
693 StackingUpdatesBlocker
blocker( workspace());
695 setKeepAbove( false );
697 setKeepBelow( true );
700 case Options::MousePreviousDesktop
:
701 workspace()->windowToPreviousDesktop( this );
703 case Options::MouseNextDesktop
:
704 workspace()->windowToNextDesktop( this );
706 case Options::MouseOpacityMore
:
707 if( !isDesktop() ) // No point in changing the opacity of the desktop
708 setOpacity( qMin( opacity() + 0.1, 1.0 ));
710 case Options::MouseOpacityLess
:
711 if( !isDesktop() ) // No point in changing the opacity of the desktop
712 setOpacity( qMax( opacity() - 0.1, 0.0 ));
714 case Options::MouseNothing
:
722 void Workspace::showWindowMenuAt( unsigned long, int, int )
724 slotWindowOperations();
727 void Workspace::loadEffect( const QString
& name
)
730 static_cast<EffectsHandlerImpl
*>(effects
)->loadEffect( name
);
733 void Workspace::toggleEffect( const QString
& name
)
736 static_cast<EffectsHandlerImpl
*>(effects
)->toggleEffect( name
);
739 void Workspace::unloadEffect( const QString
& name
)
742 static_cast<EffectsHandlerImpl
*>(effects
)->unloadEffect( name
);
745 void Workspace::reconfigureEffect( const QString
& name
)
748 static_cast<EffectsHandlerImpl
*>(effects
)->reconfigureEffect( name
);
751 QStringList
Workspace::loadedEffects() const
753 QStringList listModulesLoaded
;
755 listModulesLoaded
= static_cast<EffectsHandlerImpl
*>(effects
)->loadedEffects();
756 return listModulesLoaded
;
759 QStringList
Workspace::listOfEffects() const
761 QStringList listModules
;
763 listModules
= static_cast<EffectsHandlerImpl
*>(effects
)->listOfEffects();
767 void Workspace::slotActivateAttentionWindow()
769 if( attention_chain
.count() > 0 )
770 activateClient( attention_chain
.first());
773 void Workspace::slotSwitchDesktopNext()
775 int d
= currentDesktop() + 1;
776 if ( d
> numberOfDesktops() )
778 if ( options
->rollOverDesktops
)
787 setCurrentDesktop(d
);
790 void Workspace::slotSwitchDesktopPrevious()
792 int d
= currentDesktop() - 1;
795 if ( options
->rollOverDesktops
)
796 d
= numberOfDesktops();
800 setCurrentDesktop(d
);
803 void Workspace::slotSwitchDesktopRight()
805 int desktop
= desktopToRight( currentDesktop(), options
->rollOverDesktops
);
806 if( desktop
== currentDesktop())
808 setCurrentDesktop( desktop
);
811 void Workspace::slotSwitchDesktopLeft()
813 int desktop
= desktopToLeft( currentDesktop(), options
->rollOverDesktops
);
814 if( desktop
== currentDesktop())
816 setCurrentDesktop( desktop
);
819 void Workspace::slotSwitchDesktopUp()
821 int desktop
= desktopUp( currentDesktop(), options
->rollOverDesktops
);
822 if( desktop
== currentDesktop())
824 setCurrentDesktop( desktop
);
827 void Workspace::slotSwitchDesktopDown()
829 int desktop
= desktopDown( currentDesktop(), options
->rollOverDesktops
);
830 if( desktop
== currentDesktop())
832 setCurrentDesktop( desktop
);
835 void Workspace::slotSwitchToDesktop( int i
)
837 setCurrentDesktop( i
);
841 void Workspace::slotWindowToDesktop( int i
)
843 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
844 if( i
>= 1 && i
<= numberOfDesktops() && c
848 sendClientToDesktop( c
, i
, true );
851 void Workspace::slotSwitchToScreen( int i
)
853 setCurrentScreen( i
);
856 void Workspace::slotSwitchToNextScreen()
858 slotSwitchToScreen(( activeScreen() + 1 ) % numScreens());
861 void Workspace::slotWindowToScreen( int i
)
863 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
864 if( i
>= 0 && i
<= numScreens() && c
869 sendClientToScreen( c
, i
);
873 void Workspace::slotWindowToNextScreen()
875 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
881 sendClientToScreen( c
, ( c
->screen() + 1 ) % numScreens());
886 Maximizes the popup client
888 void Workspace::slotWindowMaximize()
890 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
892 performWindowOperation( c
, Options::MaximizeOp
);
896 Maximizes the popup client vertically
898 void Workspace::slotWindowMaximizeVertical()
900 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
902 performWindowOperation( c
, Options::VMaximizeOp
);
906 Maximizes the popup client horiozontally
908 void Workspace::slotWindowMaximizeHorizontal()
910 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
912 performWindowOperation( c
, Options::HMaximizeOp
);
917 Minimizes the popup client
919 void Workspace::slotWindowMinimize()
921 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
922 performWindowOperation( c
, Options::MinimizeOp
);
926 Shades/unshades the popup client respectively
928 void Workspace::slotWindowShade()
930 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
931 performWindowOperation( c
, Options::ShadeOp
);
935 Raises the popup client
937 void Workspace::slotWindowRaise()
939 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
945 Lowers the popup client
947 void Workspace::slotWindowLower()
949 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
955 Does a toggle-raise-and-lower on the popup client;
957 void Workspace::slotWindowRaiseOrLower()
959 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
961 raiseOrLowerClient( c
);
964 void Workspace::slotWindowOnAllDesktops()
966 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
968 c
->setOnAllDesktops( !c
->isOnAllDesktops());
971 void Workspace::slotWindowFullScreen()
973 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
975 performWindowOperation( c
, Options::FullScreenOp
);
978 void Workspace::slotWindowNoBorder()
980 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
982 performWindowOperation( c
, Options::NoBorderOp
);
985 void Workspace::slotWindowAbove()
987 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
989 performWindowOperation( c
, Options::KeepAboveOp
);
992 void Workspace::slotWindowBelow()
994 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
996 performWindowOperation( c
, Options::KeepBelowOp
);
998 void Workspace::slotSetupWindowShortcut()
1000 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
1002 performWindowOperation( c
, Options::SetupWindowShortcutOp
);
1006 Move window to next desktop
1008 void Workspace::slotWindowToNextDesktop()
1010 windowToNextDesktop( active_popup_client
? active_popup_client
: active_client
);
1013 void Workspace::windowToNextDesktop( Client
* c
)
1015 int d
= currentDesktop() + 1;
1016 if ( d
> numberOfDesktops() )
1018 if (c
&& !c
->isDesktop()
1019 && !c
->isDock() && !c
->isTopMenu())
1021 setClientIsMoving( c
);
1022 setCurrentDesktop( d
);
1023 setClientIsMoving( NULL
);
1028 Move window to previous desktop
1030 void Workspace::slotWindowToPreviousDesktop()
1032 windowToPreviousDesktop( active_popup_client
? active_popup_client
: active_client
);
1035 void Workspace::windowToPreviousDesktop( Client
* c
)
1037 int d
= currentDesktop() - 1;
1039 d
= numberOfDesktops();
1040 if (c
&& !c
->isDesktop()
1041 && !c
->isDock() && !c
->isTopMenu())
1043 setClientIsMoving( c
);
1044 setCurrentDesktop( d
);
1045 setClientIsMoving( NULL
);
1049 void Workspace::slotWindowToDesktopRight()
1051 int d
= desktopToRight( currentDesktop(), options
->rollOverDesktops
);
1052 if( d
== currentDesktop())
1054 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
1055 if (c
&& !c
->isDesktop()
1056 && !c
->isDock() && !c
->isTopMenu())
1058 setClientIsMoving( c
);
1059 setCurrentDesktop( d
);
1060 setClientIsMoving( NULL
);
1064 void Workspace::slotWindowToDesktopLeft()
1066 int d
= desktopToLeft( currentDesktop(), options
->rollOverDesktops
);
1067 if( d
== currentDesktop())
1069 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
1070 if (c
&& !c
->isDesktop()
1071 && !c
->isDock() && !c
->isTopMenu())
1073 setClientIsMoving( c
);
1074 setCurrentDesktop( d
);
1075 setClientIsMoving( NULL
);
1079 void Workspace::slotWindowToDesktopUp()
1081 int d
= desktopUp( currentDesktop(), options
->rollOverDesktops
);
1082 if( d
== currentDesktop())
1084 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
1085 if (c
&& !c
->isDesktop()
1086 && !c
->isDock() && !c
->isTopMenu())
1088 setClientIsMoving( c
);
1089 setCurrentDesktop( d
);
1090 setClientIsMoving( NULL
);
1094 void Workspace::slotWindowToDesktopDown()
1096 int d
= desktopDown( currentDesktop(), options
->rollOverDesktops
);
1097 if( d
== currentDesktop())
1099 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
1100 if (c
&& !c
->isDesktop()
1101 && !c
->isDock() && !c
->isTopMenu())
1103 setClientIsMoving( c
);
1104 setCurrentDesktop( d
);
1105 setClientIsMoving( NULL
);
1111 Kill Window feature, similar to xkill
1113 void Workspace::slotKillWindow()
1115 KillWindow
kill( this );
1120 Sends the popup client to desktop \a desk
1122 Internal slot for the window operation menu
1124 void Workspace::slotSendToDesktop( QAction
*action
)
1126 int desk
= action
->data().toInt();
1127 if ( !active_popup_client
)
1130 { // the 'on_all_desktops' menu entry
1131 active_popup_client
->setOnAllDesktops( !active_popup_client
->isOnAllDesktops());
1135 sendClientToDesktop( active_popup_client
, desk
, false );
1140 Shows the window operations popup menu for the activeClient()
1142 void Workspace::slotWindowOperations()
1144 if ( !active_client
)
1146 QPoint pos
= active_client
->pos() + active_client
->clientPos();
1147 showWindowMenu( pos
.x(), pos
.y(), active_client
);
1150 void Workspace::showWindowMenu( const QRect
&pos
, Client
* cl
)
1152 if (!KAuthorized::authorizeKAction("kwin_rmb"))
1156 if( active_popup_client
!= NULL
) // recursion
1158 if ( cl
->isDesktop()
1163 active_popup_client
= cl
;
1164 QMenu
* p
= clientPopup();
1167 int y
= pos
.bottom();
1169 p
->exec( QPoint( x
, y
) );
1172 QRect area
= clientArea(ScreenArea
, QPoint(x
, y
), currentDesktop());
1173 clientPopupAboutToShow(); // needed for sizeHint() to be correct :-/
1174 int popupHeight
= p
->sizeHint().height();
1175 if (y
+ popupHeight
< area
.height())
1176 p
->exec( QPoint( x
, y
) );
1178 p
->exec( QPoint( x
, pos
.top() - popupHeight
) );
1180 // active popup may be already changed (e.g. the window shortcut dialog)
1181 if( active_popup
== p
)
1186 Closes the popup client
1188 void Workspace::slotWindowClose()
1190 if ( tab_box
->isVisible())
1192 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
1193 performWindowOperation( c
, Options::CloseOp
);
1197 Starts keyboard move mode for the popup client
1199 void Workspace::slotWindowMove()
1201 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
1202 performWindowOperation( c
, Options::UnrestrictedMoveOp
);
1206 Starts keyboard resize mode for the popup client
1208 void Workspace::slotWindowResize()
1210 Client
* c
= active_popup_client
? active_popup_client
: active_client
;
1211 performWindowOperation( c
, Options::UnrestrictedResizeOp
);
1214 void Client::setShortcut( const QString
& _cut
)
1216 QString cut
= rules()->checkShortcut( _cut
);
1218 return setShortcutInternal( KShortcut());
1220 // base+(abcdef)<space>base+(abcdef)
1221 // E.g. Alt+Ctrl+(ABCDEF) Win+X,Win+(ABCDEF)
1222 if( !cut
.contains( '(' ) && !cut
.contains( ')' ) && !cut
.contains( ' ' ))
1224 if( workspace()->shortcutAvailable( KShortcut( cut
), this ))
1225 setShortcutInternal( KShortcut( cut
));
1227 setShortcutInternal( KShortcut());
1230 QList
< KShortcut
> keys
;
1231 QStringList groups
= cut
.split( ' ');
1232 for( QStringList::ConstIterator it
= groups
.constBegin();
1233 it
!= groups
.constEnd();
1236 QRegExp
reg( "(.*\\+)\\((.*)\\)" );
1237 if( reg
.indexIn( *it
) > -1 )
1239 QString base
= reg
.cap( 1 );
1240 QString list
= reg
.cap( 2 );
1245 KShortcut
c( base
+ list
[ i
] );
1251 for( QList
< KShortcut
>::ConstIterator it
= keys
.constBegin();
1252 it
!= keys
.constEnd();
1255 if( _shortcut
== *it
) // current one is in the list
1258 for( QList
< KShortcut
>::ConstIterator it
= keys
.constBegin();
1259 it
!= keys
.constEnd();
1262 if( workspace()->shortcutAvailable( *it
, this ))
1264 setShortcutInternal( *it
);
1268 setShortcutInternal( KShortcut());
1271 void Client::setShortcutInternal( const KShortcut
& cut
)
1273 if( _shortcut
== cut
)
1278 workspace()->clientShortcutUpdated( this );
1280 // Workaround for kwin<->kglobalaccel deadlock, when KWin has X grab and the kded
1281 // kglobalaccel module tries to create the key grab. KWin should preferably grab
1282 // they keys itself anyway :(.
1283 QTimer::singleShot( 0, this, SLOT( delayedSetShortcut()));
1287 void Client::delayedSetShortcut()
1289 workspace()->clientShortcutUpdated( this );
1292 bool Workspace::shortcutAvailable( const KShortcut
& cut
, Client
* ignore
) const
1294 // TODO check global shortcuts etc.
1295 for( ClientList::ConstIterator it
= clients
.constBegin();
1296 it
!= clients
.constEnd();
1299 if( (*it
) != ignore
&& (*it
)->shortcut() == cut
)