• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

KWin

useractions.cpp

Go to the documentation of this file.
00001 /********************************************************************
00002  KWin - the KDE window manager
00003  This file is part of the KDE project.
00004 
00005 Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
00006 Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
00007 
00008 This program is free software; you can redistribute it and/or modify
00009 it under the terms of the GNU General Public License as published by
00010 the Free Software Foundation; either version 2 of the License, or
00011 (at your option) any later version.
00012 
00013 This program is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 GNU General Public License for more details.
00017 
00018 You should have received a copy of the GNU General Public License
00019 along with this program.  If not, see <http://www.gnu.org/licenses/>.
00020 *********************************************************************/
00021 
00022 /*
00023 
00024  This file contains things relevant to direct user actions, such as
00025  responses to global keyboard shortcuts, or selecting actions
00026  from the window operations menu.
00027 
00028 */
00029 
00030 #include "client.h"
00031 #include "workspace.h"
00032 #include "effects.h"
00033 
00034 #include <fixx11h.h>
00035 #include <QPushButton>
00036 #include <QSlider>
00037 
00038 #include <kglobalsettings.h>
00039 #include <kiconloader.h>
00040 #include <klocale.h>
00041 #include <kconfig.h>
00042 #include <kglobalaccel.h>
00043 #include <kapplication.h>
00044 #include <QRegExp>
00045 #include <QMenu>
00046 #include <QVBoxLayout>
00047 #include <kauthorized.h>
00048 #include <kactioncollection.h>
00049 #include <kaction.h>
00050 
00051 #include "killwindow.h"
00052 #include "tabbox.h"
00053 
00054 namespace KWin
00055 {
00056 
00057 //****************************************
00058 // Workspace
00059 //****************************************
00060 
00061 QMenu* Workspace::clientPopup()
00062     {
00063     if ( !popup )
00064         {
00065         popup = new QMenu;
00066         popup->setFont(KGlobalSettings::menuFont());
00067         connect( popup, SIGNAL( aboutToShow() ), this, SLOT( clientPopupAboutToShow() ) );
00068         connect( popup, SIGNAL( triggered(QAction*) ), this, SLOT( clientPopupActivated(QAction*) ) );
00069 
00070         advanced_popup = new QMenu( popup );
00071         advanced_popup->setFont(KGlobalSettings::menuFont());
00072 
00073         mKeepAboveOpAction = advanced_popup->addAction( i18n("Keep &Above Others") );
00074         mKeepAboveOpAction->setIcon( KIcon( "go-up" ) );
00075         KAction *kaction = qobject_cast<KAction*>( keys->action("Window Above Other Windows") );
00076         if ( kaction!=0 )
00077             mKeepAboveOpAction->setShortcut( kaction->globalShortcut().primary() );
00078         mKeepAboveOpAction->setCheckable( true );
00079         mKeepAboveOpAction->setData( Options::KeepAboveOp );
00080 
00081         mKeepBelowOpAction = advanced_popup->addAction( i18n("Keep &Below Others") );
00082         mKeepBelowOpAction->setIcon( KIcon( "go-down" ) );
00083         kaction = qobject_cast<KAction*>( keys->action("Window Below Other Windows") );
00084         if ( kaction!=0 )
00085             mKeepBelowOpAction->setShortcut( kaction->globalShortcut().primary() );
00086         mKeepBelowOpAction->setCheckable( true );
00087         mKeepBelowOpAction->setData( Options::KeepBelowOp );
00088 
00089         mFullScreenOpAction = advanced_popup->addAction( i18n("&Fullscreen") );
00090         mFullScreenOpAction->setIcon( KIcon( "view-fullscreen" ) );
00091         kaction = qobject_cast<KAction*>( keys->action("Window Fullscreen") );
00092         if ( kaction!=0 )
00093             mFullScreenOpAction->setShortcut( kaction->globalShortcut().primary() );
00094         mFullScreenOpAction->setCheckable( true );
00095         mFullScreenOpAction->setData( Options::FullScreenOp );
00096 
00097         mNoBorderOpAction = advanced_popup->addAction( i18n("&No Border") );
00098         kaction = qobject_cast<KAction*>( keys->action("Window No Border") );
00099         if ( kaction!=0 )
00100             mNoBorderOpAction->setShortcut( kaction->globalShortcut().primary() );
00101         mNoBorderOpAction->setCheckable( true );
00102         mNoBorderOpAction->setData( Options::NoBorderOp );
00103 
00104         QAction *action = advanced_popup->addAction( i18n("Window &Shortcut...") );
00105         action->setIcon( KIcon("configure-shortcuts") );
00106         kaction = qobject_cast<KAction*>( keys->action("Setup Window Shortcut") );
00107         if ( kaction!=0 )
00108             action->setShortcut( kaction->globalShortcut().primary() );
00109         action->setData( Options::SetupWindowShortcutOp );
00110 
00111         action = advanced_popup->addAction( i18n("&Special Window Settings...") );
00112         action->setIcon( KIcon( "wizard" ) );
00113         action->setData( Options::WindowRulesOp );
00114 
00115         action = advanced_popup->addAction( i18n("&Special Application Settings...") );
00116         action->setIcon( KIcon( "wizard" ) );
00117         action->setData( Options::ApplicationRulesOp );
00118 
00119         action = popup->addMenu( advanced_popup );
00120         action->setText( i18n("Ad&vanced") );
00121 
00122         trans_popup = 0;
00123         if (compositing()){
00124             trans_popup = new QMenu( popup );
00125             trans_popup->setFont(KGlobalSettings::menuFont());
00126             connect( trans_popup, SIGNAL( triggered(QAction*) ), this, SLOT( setPopupClientOpacity(QAction*)));
00127             const int levels[] = { 100, 90, 75, 50, 25, 10 };
00128             for( unsigned int i = 0;
00129                  i < sizeof( levels ) / sizeof( levels[ 0 ] );
00130                  ++i )
00131                 {
00132                 action = trans_popup->addAction( QString::number( levels[ i ] ) + "%" );
00133                 action->setCheckable( true );
00134                 action->setData( levels[ i ] );
00135                 }
00136             action = popup->addMenu( trans_popup );
00137             action->setText( i18n("&Opacity") );
00138         }
00139 
00140         mMoveOpAction = popup->addAction( i18n("&Move") );
00141         mMoveOpAction->setIcon( KIcon( "transform-move" ) );
00142         kaction = qobject_cast<KAction*>( keys->action("Window Move") );
00143         if ( kaction!=0 )
00144             mMoveOpAction->setShortcut( kaction->globalShortcut().primary() );
00145         mMoveOpAction->setData( Options::MoveOp );
00146 
00147         mResizeOpAction = popup->addAction( i18n("Re&size") );
00148         kaction = qobject_cast<KAction*>( keys->action("Window Resize") );
00149         if ( kaction!=0 )
00150             mResizeOpAction->setShortcut( kaction->globalShortcut().primary() );
00151         mResizeOpAction->setData( Options::ResizeOp );
00152 
00153         mMinimizeOpAction = popup->addAction( i18n("Mi&nimize") );
00154         kaction = qobject_cast<KAction*>( keys->action("Window Minimize") );
00155         if ( kaction!=0 )
00156             mMinimizeOpAction->setShortcut( kaction->globalShortcut().primary() );
00157         mMinimizeOpAction->setData( Options::MinimizeOp );
00158 
00159         mMaximizeOpAction = popup->addAction( i18n("Ma&ximize") );
00160         kaction = qobject_cast<KAction*>( keys->action("Window Maximize") );
00161         if ( kaction!=0 )
00162             mMaximizeOpAction->setShortcut( kaction->globalShortcut().primary() );
00163         mMaximizeOpAction->setCheckable( true );
00164         mMaximizeOpAction->setData( Options::MaximizeOp );
00165 
00166         mShadeOpAction = popup->addAction( i18n("Sh&ade") );
00167         kaction = qobject_cast<KAction*>( keys->action("Window Shade") );
00168         if ( kaction!=0 )
00169             mShadeOpAction->setShortcut( kaction->globalShortcut().primary() );
00170         mShadeOpAction->setCheckable( true );
00171         mShadeOpAction->setData( Options::ShadeOp );
00172 
00173         popup->addSeparator();
00174 
00175         if (!KGlobal::config()->isImmutable() &&
00176             !KAuthorized::authorizeControlModules(Workspace::configModules(true)).isEmpty())
00177             {
00178               action = popup->addAction( i18n("Configur&e Window Behavior...") );
00179               action->setIcon( KIcon( "configure" ) );
00180               connect( action, SIGNAL( triggered() ), this, SLOT( configureWM() ) );
00181               popup->addSeparator();
00182             }
00183 
00184         mCloseOpAction = popup->addAction( i18n("&Close") );
00185         mCloseOpAction->setIcon( KIcon( "window-close" ) );
00186         kaction = qobject_cast<KAction*>( keys->action("Window Close") );
00187         if ( kaction!=0 )
00188             mCloseOpAction->setShortcut( kaction->globalShortcut().primary() );
00189         mCloseOpAction->setData( Options::CloseOp );
00190         }
00191     return popup;
00192     }
00193 
00194 void Workspace::discardPopup()
00195     {
00196     delete popup;
00197     popup = NULL; 
00198     desk_popup = NULL;
00199     }
00200 
00201 void Workspace::setPopupClientOpacity( QAction* action )
00202     {
00203     if( active_popup_client == NULL )
00204         return;
00205     int level = action->data().toInt();
00206     active_popup_client->setOpacity( level / 100.0 );
00207     }
00208 
00214 void Workspace::clientPopupAboutToShow()
00215     {
00216     if ( !active_popup_client || !popup )
00217         return;
00218 
00219     if ( numberOfDesktops() == 1 )
00220         {
00221         delete desk_popup;
00222         desk_popup = 0;
00223         }
00224     else
00225         {
00226         initDesktopPopup();
00227         }
00228 
00229     mResizeOpAction->setEnabled( active_popup_client->isResizable() );
00230     mMoveOpAction->setEnabled( active_popup_client->isMovableAcrossScreens() );
00231     mMaximizeOpAction->setEnabled( active_popup_client->isMaximizable() );
00232     mMaximizeOpAction->setChecked( active_popup_client->maximizeMode() == Client::MaximizeFull );
00233     mShadeOpAction->setEnabled( active_popup_client->isShadeable() );
00234     mShadeOpAction->setChecked( active_popup_client->shadeMode() != ShadeNone );
00235     mKeepAboveOpAction->setChecked( active_popup_client->keepAbove() );
00236     mKeepBelowOpAction->setChecked( active_popup_client->keepBelow() );
00237     mFullScreenOpAction->setEnabled( active_popup_client->userCanSetFullScreen() );
00238     mFullScreenOpAction->setChecked( active_popup_client->isFullScreen() );
00239     mNoBorderOpAction->setEnabled( active_popup_client->userCanSetNoBorder() );
00240     mNoBorderOpAction->setChecked( active_popup_client->noBorder() );
00241     mMinimizeOpAction->setEnabled( active_popup_client->isMinimizable() );
00242     mCloseOpAction->setEnabled( active_popup_client->isCloseable() );
00243     if( trans_popup != NULL )
00244         {
00245         foreach( QAction* action, trans_popup->actions())
00246             {
00247             if( action->data().toInt() == qRound( active_popup_client->opacity() * 100 ))
00248                 action->setChecked( true );
00249             else
00250                 action->setChecked( false );
00251             }
00252         }
00253     }
00254 
00255 
00256 void Workspace::initDesktopPopup()
00257     {
00258     if (desk_popup)
00259         return;
00260 
00261     desk_popup = new QMenu( popup );
00262     desk_popup->setFont(KGlobalSettings::menuFont());
00263     connect( desk_popup, SIGNAL( triggered(QAction*) ),
00264              this, SLOT( slotSendToDesktop(QAction*) ) );
00265     connect( desk_popup, SIGNAL( aboutToShow() ),
00266              this, SLOT( desktopPopupAboutToShow() ) );
00267 
00268     QAction *action = desk_popup->menuAction();
00269     popup->insertAction(advanced_popup->menuAction(), action);
00270     action->setText( i18n("To &Desktop") );
00271     }
00272 
00277 void Workspace::desktopPopupAboutToShow()
00278     {
00279     if ( !desk_popup )
00280         return;
00281 
00282     desk_popup->clear();
00283     QAction *action = desk_popup->addAction( i18n("&All Desktops") );
00284     action->setData( 0 );
00285     action->setCheckable( true );
00286 
00287     if ( active_popup_client && active_popup_client->isOnAllDesktops() )
00288         action->setChecked( true );
00289     desk_popup->addSeparator();
00290 
00291     const int BASE = 10;
00292     for ( int i = 1; i <= numberOfDesktops(); i++ ) {
00293         QString basic_name("%1  %2");
00294         if (i<BASE) {
00295             basic_name.prepend('&');
00296         }
00297         action = desk_popup->addAction( basic_name.arg(i).arg( desktopName(i).replace( '&', "&&" ) ) );
00298         action->setData( i );
00299         action->setCheckable( true );
00300 
00301         if ( active_popup_client &&
00302              !active_popup_client->isOnAllDesktops() && active_popup_client->desktop()  == i )
00303             action->setChecked( true );
00304         }
00305     }
00306 
00307 void Workspace::closeActivePopup()
00308     {
00309     if( active_popup )
00310         {
00311         active_popup->close();
00312         active_popup = NULL;
00313         active_popup_client = NULL;
00314         }
00315     }
00316 
00320 void Workspace::initShortcuts()
00321     {
00322     keys = new KActionCollection( this );
00323     KActionCollection* actionCollection = keys;
00324     QAction* a = 0L;
00325 
00326     // a separate KActionCollection is needed for the shortcut for disabling global shortcuts,
00327     // otherwise it would also disable itself
00328     disable_shortcuts_keys = new KActionCollection( this );
00329 #ifdef __GNUC__
00330 #warning TODO PORT ME (KGlobalAccel related)
00331 #endif
00332     // FIXME KAccel port... needed?
00333     //disable_shortcuts_keys->disableBlocking( true );
00334 #define IN_KWIN
00335 #include "kwinbindings.cpp"
00336     readShortcuts();
00337     }
00338 
00339 void Workspace::readShortcuts()
00340     {
00341 #ifdef __GNUC__
00342 #warning TODO PORT ME (KGlobalAccel related)
00343 #endif
00344     //KGlobalAccel::self()->readSettings();
00345 
00346     KAction *kaction = qobject_cast<KAction*>( keys->action("Walk Through Desktops") );
00347     if ( kaction!=0 )
00348         cutWalkThroughDesktops = kaction->globalShortcut();
00349 
00350     kaction = qobject_cast<KAction*>( keys->action("Walk Through Desktops (Reverse)") );
00351     if ( kaction!=0 )
00352         cutWalkThroughDesktopsReverse = kaction->globalShortcut();
00353 
00354     kaction = qobject_cast<KAction*>( keys->action("Walk Through Desktop List") );
00355     if ( kaction!=0 )
00356         cutWalkThroughDesktopList = kaction->globalShortcut();
00357 
00358     kaction = qobject_cast<KAction*>( keys->action("Walk Through Desktop List (Reverse)") );
00359     if ( kaction!=0 )
00360         cutWalkThroughDesktopListReverse = kaction->globalShortcut();
00361 
00362     kaction = qobject_cast<KAction*>( keys->action("Walk Through Windows") );
00363     if ( kaction!=0 )
00364         cutWalkThroughWindows = kaction->globalShortcut();
00365 
00366     kaction = qobject_cast<KAction*>( keys->action("Walk Through Windows (Reverse)") );
00367     if ( kaction!=0 )
00368         cutWalkThroughWindowsReverse = kaction->globalShortcut();
00369     discardPopup(); // so that it's recreated next time
00370     }
00371 
00372 
00373 void Workspace::setupWindowShortcut( Client* c )
00374     {
00375     assert( client_keys_dialog == NULL );
00376 #ifdef __GNUC__
00377 #warning TODO PORT ME (KGlobalAccel related)
00378 #endif
00379 //    keys->setEnabled( false );
00380 //    disable_shortcuts_keys->setEnabled( false );
00381 //    client_keys->setEnabled( false );
00382     client_keys_dialog = new ShortcutDialog( c->shortcut().primary());
00383     client_keys_client = c;
00384     connect( client_keys_dialog, SIGNAL( dialogDone( bool )), SLOT( setupWindowShortcutDone( bool )));
00385     QRect r = clientArea( ScreenArea, c );
00386     QSize size = client_keys_dialog->sizeHint();
00387     QPoint pos = c->pos() + c->clientPos();
00388     if( pos.x() + size.width() >= r.right())
00389         pos.setX( r.right() - size.width());
00390     if( pos.y() + size.height() >= r.bottom())
00391         pos.setY( r.bottom() - size.height());
00392     client_keys_dialog->move( pos );
00393     client_keys_dialog->show();
00394     active_popup = client_keys_dialog;
00395     active_popup_client = c;
00396     }
00397 
00398 void Workspace::setupWindowShortcutDone( bool ok )
00399     {
00400 //    keys->setEnabled( true );
00401 //    disable_shortcuts_keys->setEnabled( true );
00402 //    client_keys->setEnabled( true );
00403     if( ok )
00404         client_keys_client->setShortcut( KShortcut( client_keys_dialog->shortcut()).toString());
00405     closeActivePopup();
00406     client_keys_dialog->deleteLater();
00407     client_keys_dialog = NULL;
00408     client_keys_client = NULL;
00409     }
00410 
00411 void Workspace::clientShortcutUpdated( Client* c )
00412     {
00413     QString key = QString( "_k_session:%1" ).arg(c->window());
00414     QAction* action = client_keys->action( key.toLatin1().constData() );
00415     if( !c->shortcut().isEmpty())
00416         {
00417         if( action == NULL ) // new shortcut
00418             {
00419             action = client_keys->addAction(QString( key ));
00420             action->setText( i18n("Activate Window (%1)", c->caption()) );
00421             connect( action, SIGNAL(triggered(bool)), c, SLOT(shortcutActivated()) );
00422             }
00423 
00424         KAction *kaction = qobject_cast<KAction*>( action );
00425         // no autoloading, since it's configured explicitly here and is not meant to be reused
00426         // (the key is the window id anyway, which is kind of random)
00427         kaction->setGlobalShortcut(
00428                 c->shortcut(), KAction::ActiveShortcut, KAction::NoAutoloading );
00429         kaction->setEnabled( true );
00430         }
00431     else
00432         {
00433         KAction *kaction = qobject_cast<KAction*>( action );
00434         if( kaction )
00435             {
00436             kaction->forgetGlobalShortcut();
00437             }
00438         delete action;
00439         }
00440     }
00441 
00442 void Workspace::clientPopupActivated( QAction *action )
00443     {
00444       if ( !action->data().isValid() )
00445         return;
00446 
00447     WindowOperation op = static_cast< WindowOperation >( action->data().toInt() );
00448     Client* c = active_popup_client ? active_popup_client : active_client;
00449     QString type;
00450     switch( op )
00451         {
00452         case FullScreenOp:
00453             if( !c->isFullScreen() && c->userCanSetFullScreen())
00454                 type = "fullscreenaltf3";
00455           break;
00456         case NoBorderOp:
00457             if( !c->noBorder() && c->userCanSetNoBorder())
00458                 type = "noborderaltf3";
00459           break;
00460         default:
00461             break;
00462         };
00463     if( !type.isEmpty())
00464         helperDialog( type, c );
00465     performWindowOperation( c, op );
00466     }
00467 
00468 
00469 void Workspace::performWindowOperation( Client* c, Options::WindowOperation op )
00470     {
00471     if ( !c )
00472         return;
00473 
00474     if (op == Options::MoveOp || op == Options::UnrestrictedMoveOp )
00475         QCursor::setPos( c->geometry().center() );
00476     if (op == Options::ResizeOp || op == Options::UnrestrictedResizeOp )
00477         QCursor::setPos( c->geometry().bottomRight());
00478     switch ( op )
00479         {
00480         case Options::MoveOp:
00481             c->performMouseCommand( Options::MouseMove, cursorPos() );
00482             break;
00483         case Options::UnrestrictedMoveOp:
00484             c->performMouseCommand( Options::MouseUnrestrictedMove, cursorPos() );
00485             break;
00486         case Options::ResizeOp:
00487             c->performMouseCommand( Options::MouseResize, cursorPos() );
00488             break;
00489         case Options::UnrestrictedResizeOp:
00490             c->performMouseCommand( Options::MouseUnrestrictedResize, cursorPos() );
00491             break;
00492         case Options::CloseOp:
00493             c->closeWindow();
00494             break;
00495         case Options::MaximizeOp:
00496             c->maximize( c->maximizeMode() == Client::MaximizeFull
00497                 ? Client::MaximizeRestore : Client::MaximizeFull );
00498             break;
00499         case Options::HMaximizeOp:
00500             c->maximize( c->maximizeMode() ^ Client::MaximizeHorizontal );
00501             break;
00502         case Options::VMaximizeOp:
00503             c->maximize( c->maximizeMode() ^ Client::MaximizeVertical );
00504             break;
00505         case Options::RestoreOp:
00506             c->maximize( Client::MaximizeRestore );
00507             break;
00508         case Options::MinimizeOp:
00509             c->minimize();
00510             break;
00511         case Options::ShadeOp:
00512             c->performMouseCommand( Options::MouseShade, cursorPos());
00513             break;
00514         case Options::OnAllDesktopsOp:
00515             c->setOnAllDesktops( !c->isOnAllDesktops() );
00516             break;
00517         case Options::FullScreenOp:
00518             c->setFullScreen( !c->isFullScreen(), true );
00519             break;
00520         case Options::NoBorderOp:
00521             c->setNoBorder( !c->noBorder());
00522             break;
00523         case Options::KeepAboveOp:
00524             {
00525             StackingUpdatesBlocker blocker( this );
00526             bool was = c->keepAbove();
00527             c->setKeepAbove( !c->keepAbove() );
00528             if( was && !c->keepAbove())
00529                 raiseClient( c );
00530             break;
00531             }
00532         case Options::KeepBelowOp:
00533             {
00534             StackingUpdatesBlocker blocker( this );
00535             bool was = c->keepBelow();
00536             c->setKeepBelow( !c->keepBelow() );
00537             if( was && !c->keepBelow())
00538                 lowerClient( c );
00539             break;
00540             }
00541         case Options::OperationsOp:
00542             c->performMouseCommand( Options::MouseShade, cursorPos());
00543             break;
00544         case Options::WindowRulesOp:
00545             editWindowRules( c, false );
00546             break;
00547         case Options::ApplicationRulesOp:
00548             editWindowRules( c, true );
00549             break;
00550         case Options::SetupWindowShortcutOp:
00551             setupWindowShortcut( c );
00552             break;
00553         case Options::LowerOp:
00554             lowerClient(c);
00555             break;
00556         case Options::NoOp:
00557             break;
00558         }
00559     }
00560 
00564 bool Client::performMouseCommand( Options::MouseCommand command, const QPoint &globalPos, bool handled )
00565     {
00566     bool replay = false;
00567     switch (command)
00568         {
00569         case Options::MouseRaise:
00570             workspace()->raiseClient( this );
00571             break;
00572         case Options::MouseLower:
00573             workspace()->lowerClient( this );
00574             break;
00575         case Options::MouseShade :
00576             toggleShade();
00577             cancelShadeHoverTimer();
00578             break;
00579         case Options::MouseSetShade:
00580             setShade( ShadeNormal );
00581             cancelShadeHoverTimer();
00582             break;
00583         case Options::MouseUnsetShade:
00584             setShade( ShadeNone );
00585             cancelShadeHoverTimer();
00586             break;
00587         case Options::MouseOperationsMenu:
00588             if ( isActive() && options->clickRaise )
00589                 autoRaise();
00590             workspace()->showWindowMenu( globalPos, this );
00591             break;
00592         case Options::MouseToggleRaiseAndLower:
00593             workspace()->raiseOrLowerClient( this );
00594             break;
00595         case Options::MouseActivateAndRaise:
00596             replay = isActive(); // for clickraise mode
00597             workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled && replay );
00598             workspace()->setActiveScreenMouse( globalPos );
00599             break;
00600         case Options::MouseActivateAndLower:
00601             workspace()->requestFocus( this );
00602             workspace()->lowerClient( this );
00603             workspace()->setActiveScreenMouse( globalPos );
00604             break;
00605         case Options::MouseActivate:
00606             replay = isActive(); // for clickraise mode
00607             workspace()->takeActivity( this, ActivityFocus, handled && replay );
00608             workspace()->setActiveScreenMouse( globalPos );
00609             break;
00610         case Options::MouseActivateRaiseAndPassClick:
00611             workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled );
00612             workspace()->setActiveScreenMouse( globalPos );
00613             replay = true;
00614             break;
00615         case Options::MouseActivateAndPassClick:
00616             workspace()->takeActivity( this, ActivityFocus, handled );
00617             workspace()->setActiveScreenMouse( globalPos );
00618             replay = true;
00619             break;
00620         case Options::MouseActivateRaiseAndMove:
00621         case Options::MouseActivateRaiseAndUnrestrictedMove:
00622             workspace()->raiseClient( this );
00623             workspace()->requestFocus( this );
00624             workspace()->setActiveScreenMouse( globalPos );
00625             if( options->moveMode == Options::Transparent && isMovableAcrossScreens())
00626                 move_faked_activity = workspace()->fakeRequestedActivity( this );
00627         // fallthrough
00628         case Options::MouseMove:
00629         case Options::MouseUnrestrictedMove:
00630             {
00631             if (!isMovableAcrossScreens())
00632                 break;
00633             if( moveResizeMode )
00634                 finishMoveResize( false );
00635             mode = PositionCenter;
00636             buttonDown = true;
00637             moveOffset = QPoint( globalPos.x() - x(), globalPos.y() - y()); // map from global
00638             invertedMoveOffset = rect().bottomRight() - moveOffset;
00639             unrestrictedMoveResize = ( command == Options::MouseActivateRaiseAndUnrestrictedMove
00640                                     || command == Options::MouseUnrestrictedMove );
00641             if( !startMoveResize())
00642                 buttonDown = false;
00643             updateCursor();
00644             break;
00645             }
00646         case Options::MouseResize:
00647         case Options::MouseUnrestrictedResize:
00648             {
00649             if (!isResizable() || isShade())
00650                 break;
00651             if( moveResizeMode )
00652                 finishMoveResize( false );
00653             buttonDown = true;
00654             moveOffset = QPoint( globalPos.x() - x(), globalPos.y() - y()); // map from global
00655             int x = moveOffset.x(), y = moveOffset.y();
00656             bool left = x < width() / 3;
00657             bool right = x >= 2 * width() / 3;
00658             bool top = y < height() / 3;
00659             bool bot = y >= 2 * height() / 3;
00660             if (top)
00661                 mode = left ? PositionTopLeft : (right ? PositionTopRight : PositionTop);
00662             else if (bot)
00663                 mode = left ? PositionBottomLeft : (right ? PositionBottomRight : PositionBottom);
00664             else
00665                 mode = (x < width() / 2) ? PositionLeft : PositionRight;
00666             invertedMoveOffset = rect().bottomRight() - moveOffset;
00667             unrestrictedMoveResize = ( command == Options::MouseUnrestrictedResize );
00668             if( !startMoveResize())
00669                 buttonDown = false;
00670             updateCursor();
00671             break;
00672             }
00673         case Options::MouseMaximize:
00674             maximize( Client::MaximizeFull );
00675             break;
00676         case Options::MouseRestore:
00677             maximize( Client::MaximizeRestore );
00678             break;
00679         case Options::MouseMinimize:
00680             minimize();
00681             break;
00682         case Options::MouseAbove:
00683             {
00684             StackingUpdatesBlocker blocker( workspace());
00685             if( keepBelow())
00686                 setKeepBelow( false );
00687             else
00688                 setKeepAbove( true );
00689             break;
00690             }
00691         case Options::MouseBelow:
00692             {
00693             StackingUpdatesBlocker blocker( workspace());
00694             if( keepAbove())
00695                 setKeepAbove( false );
00696             else
00697                 setKeepBelow( true );
00698             break;
00699             }
00700         case Options::MousePreviousDesktop:
00701             workspace()->windowToPreviousDesktop( this );
00702             break;
00703         case Options::MouseNextDesktop:
00704             workspace()->windowToNextDesktop( this );
00705             break;
00706         case Options::MouseOpacityMore:
00707             if( !isDesktop() ) // No point in changing the opacity of the desktop
00708                 setOpacity( qMin( opacity() + 0.1, 1.0 ));
00709             break;
00710         case Options::MouseOpacityLess:
00711             if( !isDesktop() ) // No point in changing the opacity of the desktop
00712                 setOpacity( qMax( opacity() - 0.1, 0.0 ));
00713             break;
00714         case Options::MouseNothing:
00715             replay = true;
00716             break;
00717         }
00718     return replay;
00719     }
00720 
00721 // KDE4 remove me
00722 void Workspace::showWindowMenuAt( unsigned long, int, int )
00723     {
00724     slotWindowOperations();
00725     }
00726 
00727 void Workspace::loadEffect( const QString& name )
00728     {
00729     if( effects )
00730         static_cast<EffectsHandlerImpl*>(effects)->loadEffect( name );
00731     }
00732 
00733 void Workspace::toggleEffect( const QString& name )
00734     {
00735     if( effects )
00736         static_cast<EffectsHandlerImpl*>(effects)->toggleEffect( name );
00737     }
00738 
00739 void Workspace::unloadEffect( const QString& name )
00740     {
00741     if( effects )
00742         static_cast<EffectsHandlerImpl*>(effects)->unloadEffect( name );
00743     }
00744 
00745 void Workspace::reconfigureEffect( const QString& name )
00746     {
00747     if( effects )
00748         static_cast<EffectsHandlerImpl*>(effects)->reconfigureEffect( name );
00749     }
00750 
00751 QStringList Workspace::loadedEffects() const
00752     {
00753     QStringList listModulesLoaded;
00754     if ( effects )
00755         listModulesLoaded = static_cast<EffectsHandlerImpl*>(effects)->loadedEffects();
00756     return listModulesLoaded;
00757     }
00758 
00759 QStringList Workspace::listOfEffects() const
00760     {
00761     QStringList listModules;
00762     if ( effects )
00763         listModules = static_cast<EffectsHandlerImpl*>(effects)->listOfEffects();
00764     return listModules;
00765     }
00766 
00767 void Workspace::slotActivateAttentionWindow()
00768     {
00769     if( attention_chain.count() > 0 )
00770         activateClient( attention_chain.first());
00771     }
00772 
00773 void Workspace::slotSwitchDesktopNext()
00774     {
00775     int d = currentDesktop() + 1;
00776      if ( d > numberOfDesktops() )
00777         {
00778         if ( options->rollOverDesktops )
00779             {
00780             d = 1;
00781             }
00782         else
00783             {
00784             return;
00785             }
00786         }
00787     setCurrentDesktop(d);
00788     }
00789 
00790 void Workspace::slotSwitchDesktopPrevious()
00791     {
00792     int d = currentDesktop() - 1;
00793     if ( d <= 0 )
00794         {
00795         if ( options->rollOverDesktops )
00796           d = numberOfDesktops();
00797       else
00798           return;
00799         }
00800     setCurrentDesktop(d);
00801     }
00802 
00803 void Workspace::slotSwitchDesktopRight()
00804     {
00805     int desktop = desktopToRight( currentDesktop(), options->rollOverDesktops);
00806     if( desktop == currentDesktop())
00807         return;
00808     setCurrentDesktop( desktop );
00809     }
00810 
00811 void Workspace::slotSwitchDesktopLeft()
00812     {
00813     int desktop = desktopToLeft( currentDesktop(), options->rollOverDesktops);
00814     if( desktop == currentDesktop())
00815         return;
00816     setCurrentDesktop( desktop );
00817     }
00818 
00819 void Workspace::slotSwitchDesktopUp()
00820     {
00821     int desktop = desktopUp( currentDesktop(), options->rollOverDesktops);
00822     if( desktop == currentDesktop())
00823         return;
00824     setCurrentDesktop( desktop );
00825     }
00826 
00827 void Workspace::slotSwitchDesktopDown()
00828     {
00829     int desktop = desktopDown( currentDesktop(), options->rollOverDesktops);
00830     if( desktop == currentDesktop())
00831         return;
00832     setCurrentDesktop( desktop );
00833     }
00834 
00835 void Workspace::slotSwitchToDesktop( int i )
00836     {
00837     setCurrentDesktop( i );
00838     }
00839 
00840 
00841 void Workspace::slotWindowToDesktop( int i )
00842     {
00843     Client* c = active_popup_client ? active_popup_client : active_client;
00844     if( i >= 1 && i <= numberOfDesktops() && c
00845         && !c->isDesktop()
00846         && !c->isDock()
00847         && !c->isTopMenu())
00848             sendClientToDesktop( c, i, true );
00849     }
00850 
00851 void Workspace::slotSwitchToScreen( int i )
00852     {
00853     setCurrentScreen( i );
00854     }
00855 
00856 void Workspace::slotSwitchToNextScreen()
00857     {
00858     slotSwitchToScreen(( activeScreen() + 1 ) % numScreens());
00859     }
00860 
00861 void Workspace::slotWindowToScreen( int i )
00862     {
00863     Client* c = active_popup_client ? active_popup_client : active_client;
00864     if( i >= 0 && i <= numScreens() && c
00865         && !c->isDesktop()
00866         && !c->isDock()
00867         && !c->isTopMenu())
00868         {
00869         sendClientToScreen( c, i );
00870         }
00871     }
00872 
00873 void Workspace::slotWindowToNextScreen()
00874     {
00875     Client* c = active_popup_client ? active_popup_client : active_client;
00876     if( c
00877         && !c->isDesktop()
00878         && !c->isDock()
00879         && !c->isTopMenu())
00880         {
00881         sendClientToScreen( c, ( c->screen() + 1 ) % numScreens());
00882         }
00883     }
00884 
00888 void Workspace::slotWindowMaximize()
00889     {
00890     Client* c = active_popup_client ? active_popup_client : active_client;
00891     if ( c )
00892         performWindowOperation( c, Options::MaximizeOp );
00893     }
00894 
00898 void Workspace::slotWindowMaximizeVertical()
00899     {
00900     Client* c = active_popup_client ? active_popup_client : active_client;
00901     if ( c )
00902         performWindowOperation( c, Options::VMaximizeOp );
00903     }
00904 
00908 void Workspace::slotWindowMaximizeHorizontal()
00909     {
00910     Client* c = active_popup_client ? active_popup_client : active_client;
00911     if ( c )
00912         performWindowOperation( c, Options::HMaximizeOp );
00913     }
00914 
00915 
00919 void Workspace::slotWindowMinimize()
00920     {
00921     Client* c = active_popup_client ? active_popup_client : active_client;
00922     performWindowOperation( c, Options::MinimizeOp );
00923     }
00924 
00928 void Workspace::slotWindowShade()
00929     {
00930     Client* c = active_popup_client ? active_popup_client : active_client;
00931     performWindowOperation( c, Options::ShadeOp );
00932     }
00933 
00937 void Workspace::slotWindowRaise()
00938     {
00939     Client* c = active_popup_client ? active_popup_client : active_client;
00940     if ( c )
00941         raiseClient( c );
00942     }
00943 
00947 void Workspace::slotWindowLower()
00948     {
00949     Client* c = active_popup_client ? active_popup_client : active_client;
00950     if ( c )
00951         lowerClient( c );
00952     }
00953 
00957 void Workspace::slotWindowRaiseOrLower()
00958     {
00959     Client* c = active_popup_client ? active_popup_client : active_client;
00960     if  ( c )
00961         raiseOrLowerClient( c );
00962     }
00963 
00964 void Workspace::slotWindowOnAllDesktops()
00965     {
00966     Client* c = active_popup_client ? active_popup_client : active_client;
00967     if( c )
00968         c->setOnAllDesktops( !c->isOnAllDesktops());
00969     }
00970 
00971 void Workspace::slotWindowFullScreen()
00972     {
00973     Client* c = active_popup_client ? active_popup_client : active_client;
00974     if( c )
00975         performWindowOperation( c, Options::FullScreenOp );
00976     }
00977 
00978 void Workspace::slotWindowNoBorder()
00979     {
00980     Client* c = active_popup_client ? active_popup_client : active_client;
00981     if( c )
00982         performWindowOperation( c, Options::NoBorderOp );
00983     }
00984 
00985 void Workspace::slotWindowAbove()
00986     {
00987     Client* c = active_popup_client ? active_popup_client : active_client;
00988     if( c )
00989         performWindowOperation( c, Options::KeepAboveOp );
00990     }
00991 
00992 void Workspace::slotWindowBelow()
00993     {
00994     Client* c = active_popup_client ? active_popup_client : active_client;
00995     if( c )
00996         performWindowOperation( c, Options::KeepBelowOp );
00997     }
00998 void Workspace::slotSetupWindowShortcut()
00999     {
01000     Client* c = active_popup_client ? active_popup_client : active_client;
01001     if( c )
01002         performWindowOperation( c, Options::SetupWindowShortcutOp );
01003     }
01004 
01008 void Workspace::slotWindowToNextDesktop()
01009     {
01010     windowToNextDesktop( active_popup_client ? active_popup_client : active_client );
01011     }
01012 
01013 void Workspace::windowToNextDesktop( Client* c )
01014     {
01015     int d = currentDesktop() + 1;
01016     if ( d > numberOfDesktops() )
01017         d = 1;
01018     if (c && !c->isDesktop()
01019         && !c->isDock() && !c->isTopMenu())
01020         {
01021         setClientIsMoving( c );
01022         setCurrentDesktop( d );
01023         setClientIsMoving( NULL );
01024         }
01025     }
01026 
01030 void Workspace::slotWindowToPreviousDesktop()
01031     {
01032     windowToPreviousDesktop( active_popup_client ? active_popup_client : active_client );
01033     }
01034 
01035 void Workspace::windowToPreviousDesktop( Client* c )
01036     {
01037     int d = currentDesktop() - 1;
01038     if ( d <= 0 )
01039         d = numberOfDesktops();
01040     if (c && !c->isDesktop()
01041         && !c->isDock() && !c->isTopMenu())
01042         {
01043         setClientIsMoving( c );
01044         setCurrentDesktop( d );
01045         setClientIsMoving( NULL );
01046         }
01047     }
01048 
01049 void Workspace::slotWindowToDesktopRight()
01050     {
01051     int d = desktopToRight( currentDesktop(), options->rollOverDesktops);
01052     if( d == currentDesktop())
01053         return;
01054     Client* c = active_popup_client ? active_popup_client : active_client;
01055     if (c && !c->isDesktop()
01056         && !c->isDock() && !c->isTopMenu())
01057         {
01058         setClientIsMoving( c );
01059         setCurrentDesktop( d );
01060         setClientIsMoving( NULL );
01061         }
01062     }
01063 
01064 void Workspace::slotWindowToDesktopLeft()
01065     {
01066     int d = desktopToLeft( currentDesktop(), options->rollOverDesktops);
01067     if( d == currentDesktop())
01068         return;
01069     Client* c = active_popup_client ? active_popup_client : active_client;
01070     if (c && !c->isDesktop()
01071         && !c->isDock() && !c->isTopMenu())
01072         {
01073         setClientIsMoving( c );
01074         setCurrentDesktop( d );
01075         setClientIsMoving( NULL );
01076         }
01077     }
01078 
01079 void Workspace::slotWindowToDesktopUp()
01080     {
01081     int d = desktopUp( currentDesktop(), options->rollOverDesktops);
01082     if( d == currentDesktop())
01083         return;
01084     Client* c = active_popup_client ? active_popup_client : active_client;
01085     if (c && !c->isDesktop()
01086         && !c->isDock() && !c->isTopMenu())
01087         {
01088         setClientIsMoving( c );
01089         setCurrentDesktop( d );
01090         setClientIsMoving( NULL );
01091         }
01092     }
01093 
01094 void Workspace::slotWindowToDesktopDown()
01095     {
01096     int d = desktopDown( currentDesktop(), options->rollOverDesktops);
01097     if( d == currentDesktop())
01098         return;
01099     Client* c = active_popup_client ? active_popup_client : active_client;
01100     if (c && !c->isDesktop()
01101         && !c->isDock() && !c->isTopMenu())
01102         {
01103         setClientIsMoving( c );
01104         setCurrentDesktop( d );
01105         setClientIsMoving( NULL );
01106         }
01107     }
01108 
01109 
01113 void Workspace::slotKillWindow()
01114     {
01115     KillWindow kill( this );
01116     kill.start();
01117     }
01118 
01124 void Workspace::slotSendToDesktop( QAction *action )
01125     {
01126       int desk = action->data().toInt();
01127     if ( !active_popup_client )
01128         return;
01129     if ( desk == 0 )
01130         { // the 'on_all_desktops' menu entry
01131         active_popup_client->setOnAllDesktops( !active_popup_client->isOnAllDesktops());
01132         return;
01133         }
01134 
01135     sendClientToDesktop( active_popup_client, desk, false );
01136 
01137     }
01138 
01142 void Workspace::slotWindowOperations()
01143     {
01144     if ( !active_client )
01145         return;
01146     QPoint pos = active_client->pos() + active_client->clientPos();
01147     showWindowMenu( pos.x(), pos.y(), active_client );
01148     }
01149 
01150 void Workspace::showWindowMenu( const QRect &pos, Client* cl )
01151     {
01152     if (!KAuthorized::authorizeKAction("kwin_rmb"))
01153         return;
01154     if( !cl )
01155         return;
01156     if( active_popup_client != NULL ) // recursion
01157         return;
01158     if ( cl->isDesktop()
01159         || cl->isDock()
01160         || cl->isTopMenu())
01161         return;
01162 
01163     active_popup_client = cl;
01164     QMenu* p = clientPopup();
01165     active_popup = p;
01166     int x = pos.left();
01167     int y = pos.bottom();
01168     if (y == pos.top())
01169     p->exec( QPoint( x, y ) );
01170     else
01171         {
01172     QRect area = clientArea(ScreenArea, QPoint(x, y), currentDesktop());
01173         clientPopupAboutToShow(); // needed for sizeHint() to be correct :-/
01174     int popupHeight = p->sizeHint().height();
01175     if (y + popupHeight < area.height())
01176         p->exec( QPoint( x, y ) );
01177     else
01178         p->exec( QPoint( x, pos.top() - popupHeight ) );
01179         }
01180     // active popup may be already changed (e.g. the window shortcut dialog)
01181     if( active_popup == p )
01182         closeActivePopup();
01183     }
01184 
01188 void Workspace::slotWindowClose()
01189     {
01190     if ( tab_box->isVisible())
01191         return;
01192     Client* c = active_popup_client ? active_popup_client : active_client;
01193     performWindowOperation( c, Options::CloseOp );
01194     }
01195 
01199 void Workspace::slotWindowMove()
01200     {
01201     Client* c = active_popup_client ? active_popup_client : active_client;
01202     performWindowOperation( c, Options::UnrestrictedMoveOp );
01203     }
01204 
01208 void Workspace::slotWindowResize()
01209     {
01210     Client* c = active_popup_client ? active_popup_client : active_client;
01211     performWindowOperation( c, Options::UnrestrictedResizeOp );
01212     }
01213 
01214 void Client::setShortcut( const QString& _cut )
01215     {
01216     QString cut = rules()->checkShortcut( _cut );
01217     if( cut.isEmpty())
01218         return setShortcutInternal( KShortcut());
01219 // Format:
01220 // base+(abcdef)<space>base+(abcdef)
01221 // E.g. Alt+Ctrl+(ABCDEF) Win+X,Win+(ABCDEF)
01222     if( !cut.contains( '(' ) && !cut.contains( ')' ) && !cut.contains( ' ' ))
01223         {
01224         if( workspace()->shortcutAvailable( KShortcut( cut ), this ))
01225             setShortcutInternal( KShortcut( cut ));
01226         else
01227             setShortcutInternal( KShortcut());
01228         return;
01229         }
01230     QList< KShortcut > keys;
01231     QStringList groups = cut.split( ' ');
01232     for( QStringList::ConstIterator it = groups.constBegin();
01233          it != groups.constEnd();
01234          ++it )
01235         {
01236         QRegExp reg( "(.*\\+)\\((.*)\\)" );
01237         if( reg.indexIn( *it ) > -1 )
01238             {
01239             QString base = reg.cap( 1 );
01240             QString list = reg.cap( 2 );
01241             for( int i = 0;
01242                  i < list.length();
01243                  ++i )
01244                 {
01245                 KShortcut c( base + list[ i ] );
01246                 if( !c.isEmpty())
01247                     keys.append( c );
01248                 }
01249             }
01250         }
01251     for( QList< KShortcut >::ConstIterator it = keys.constBegin();
01252          it != keys.constEnd();
01253          ++it )
01254         {
01255         if( _shortcut == *it ) // current one is in the list
01256             return;
01257         }
01258     for( QList< KShortcut >::ConstIterator it = keys.constBegin();
01259          it != keys.constEnd();
01260          ++it )
01261         {
01262         if( workspace()->shortcutAvailable( *it, this ))
01263             {
01264             setShortcutInternal( *it );
01265             return;
01266             }
01267         }
01268     setShortcutInternal( KShortcut());
01269     }
01270 
01271 void Client::setShortcutInternal( const KShortcut& cut )
01272     {
01273     if( _shortcut == cut )
01274         return;
01275     _shortcut = cut;
01276     updateCaption();
01277 #if 0
01278     workspace()->clientShortcutUpdated( this );
01279 #else
01280     // Workaround for kwin<->kglobalaccel deadlock, when KWin has X grab and the kded
01281     // kglobalaccel module tries to create the key grab. KWin should preferably grab
01282     // they keys itself anyway :(.
01283     QTimer::singleShot( 0, this, SLOT( delayedSetShortcut()));
01284 #endif
01285     }
01286 
01287 void Client::delayedSetShortcut()
01288     {
01289     workspace()->clientShortcutUpdated( this );
01290     }
01291 
01292 bool Workspace::shortcutAvailable( const KShortcut& cut, Client* ignore ) const
01293     {
01294     // TODO check global shortcuts etc.
01295     for( ClientList::ConstIterator it = clients.constBegin();
01296          it != clients.constEnd();
01297          ++it )
01298         {
01299         if( (*it) != ignore && (*it)->shortcut() == cut )
01300             return false;
01301         }
01302     return true;
01303     }
01304 
01305 } // namespace

KWin

Skip menu "KWin"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • KWin
  •   KWin Libraries
  • Libraries
  •   libkworkspace
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal