useractions.cpp

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 You can Freely distribute this program under the GNU General Public
00009 License. See the file "COPYING" for the exact licensing terms.
00010 ******************************************************************/
00011 
00012 /*
00013 
00014  This file contains things relevant to direct user actions, such as
00015  responses to global keyboard shortcuts, or selecting actions
00016  from the window operations menu.
00017 
00018 */
00019 
00020 #include "client.h"
00021 #include "workspace.h"
00022 
00023 #include <fixx11h.h>
00024 #include <qhbox.h>
00025 #include <qpushbutton.h>
00026 #include <qslider.h>
00027 #include <qtooltip.h>
00028 #include <qpopupmenu.h>
00029 #include <kglobalsettings.h>
00030 #include <kiconloader.h>
00031 #include <klocale.h>
00032 #include <kconfig.h>
00033 #include <kglobalaccel.h>
00034 #include <kapplication.h>
00035 #include <qregexp.h>
00036 
00037 #include "killwindow.h"
00038 #include "tabbox.h"
00039 
00040 namespace KWinInternal
00041 {
00042 
00043 //****************************************
00044 // Workspace
00045 //****************************************
00046 
00047 QPopupMenu* Workspace::clientPopup()
00048     {
00049     if ( !popup )
00050         {
00051         popup = new QPopupMenu;
00052         popup->setCheckable( TRUE );
00053         popup->setFont(KGlobalSettings::menuFont());
00054         connect( popup, SIGNAL( aboutToShow() ), this, SLOT( clientPopupAboutToShow() ) );
00055         connect( popup, SIGNAL( activated(int) ), this, SLOT( clientPopupActivated(int) ) );
00056       
00057         advanced_popup = new QPopupMenu( popup );
00058         advanced_popup->setCheckable( TRUE );
00059         advanced_popup->setFont(KGlobalSettings::menuFont());
00060         connect( advanced_popup, SIGNAL( activated(int) ), this, SLOT( clientPopupActivated(int) ) );
00061         advanced_popup->insertItem( SmallIconSet( "up" ),
00062             i18n("Keep &Above Others")+'\t'+keys->shortcut("Window Above Other Windows").seq(0).toString(), Options::KeepAboveOp );
00063         advanced_popup->insertItem( SmallIconSet( "down" ),
00064             i18n("Keep &Below Others")+'\t'+keys->shortcut("Window Below Other Windows").seq(0).toString(), Options::KeepBelowOp );
00065         advanced_popup->insertItem( SmallIconSet( "window_fullscreen" ),
00066             i18n("&Fullscreen")+'\t'+keys->shortcut("Window Fullscreen").seq(0).toString(), Options::FullScreenOp );
00067         advanced_popup->insertItem( i18n("&No Border")+'\t'+keys->shortcut("Window No Border").seq(0).toString(), Options::NoBorderOp );
00068         advanced_popup->insertItem( SmallIconSet("key_bindings"),
00069             i18n("Window &Shortcut...")+'\t'+keys->shortcut("Setup Window Shortcut").seq(0).toString(), Options::SetupWindowShortcutOp );
00070         advanced_popup->insertItem( SmallIconSet( "wizard" ), i18n("&Special Window Settings..."), Options::WindowRulesOp );
00071         advanced_popup->insertItem( SmallIconSet( "wizard" ), i18n("&Special Application Settings..."), Options::ApplicationRulesOp );
00072 
00073         popup->insertItem(i18n("Ad&vanced"), advanced_popup );
00074         desk_popup_index = popup->count();
00075         
00076         if (options->useTranslucency){
00077             QPopupMenu *trans_popup = new QPopupMenu( popup );
00078             QVBox *transBox = new QVBox(trans_popup);
00079             transButton = new QPushButton(transBox, "transButton");
00080             QToolTip::add(transButton, i18n("Reset opacity to default value"));
00081             transSlider = new QSlider(0, 100, 1, 100, Qt::Vertical, transBox, "transSlider");
00082             QToolTip::add(transSlider, i18n("Slide this to set the window's opacity"));
00083             connect(transButton, SIGNAL(clicked()), SLOT(resetClientOpacity()));
00084             connect(transButton, SIGNAL(clicked()), trans_popup, SLOT(hide()));
00085             connect(transSlider, SIGNAL(valueChanged(int)), SLOT(setTransButtonText(int)));
00086             connect(transSlider, SIGNAL(valueChanged(int)), this, SLOT(setPopupClientOpacity(int)));
00087 //             connect(transSlider, SIGNAL(sliderReleased()), trans_popup, SLOT(hide()));
00088             trans_popup->insertItem(transBox);
00089             popup->insertItem(i18n("&Opacity"), trans_popup );
00090         }
00091         
00092         popup->insertItem( SmallIconSet( "move" ), i18n("&Move")+'\t'+keys->shortcut("Window Move").seq(0).toString(), Options::MoveOp );
00093         popup->insertItem( i18n("Re&size")+'\t'+keys->shortcut("Window Resize").seq(0).toString(), Options::ResizeOp );
00094         popup->insertItem( i18n("Mi&nimize")+'\t'+keys->shortcut("Window Minimize").seq(0).toString(), Options::MinimizeOp );
00095         popup->insertItem( i18n("Ma&ximize")+'\t'+keys->shortcut("Window Maximize").seq(0).toString(), Options::MaximizeOp );
00096         popup->insertItem( i18n("Sh&ade")+'\t'+keys->shortcut("Window Shade").seq(0).toString(), Options::ShadeOp );
00097 
00098         popup->insertSeparator();
00099 
00100         if (!KGlobal::config()->isImmutable() && 
00101             !kapp->authorizeControlModules(Workspace::configModules(true)).isEmpty())
00102             {
00103             popup->insertItem(SmallIconSet( "configure" ), i18n("Configur&e Window Behavior..."), this, SLOT( configureWM() ));
00104             popup->insertSeparator();
00105             }
00106 
00107         popup->insertItem( SmallIconSet( "fileclose" ), i18n("&Close")+'\t'+keys->shortcut("Window Close").seq(0).toString(), Options::CloseOp );
00108         }
00109     return popup;
00110     }
00111     
00112 //sets the transparency of the client to given value(given by slider)
00113 void Workspace::setPopupClientOpacity(int value)
00114     {
00115     active_popup_client->setCustomOpacityFlag(true);
00116     value = 100 - value;
00117     value<100?active_popup_client->setOpacity(true, (uint)((value/100.0)*0xffffffff)):active_popup_client->setOpacity(false,0xffffffff);
00118     }
00119 
00120 void Workspace::setTransButtonText(int value)
00121     {
00122     value = 100 - value;
00123     if(value < 0)
00124         transButton->setText("000 %");
00125     else if (value >= 100 )
00126         transButton->setText("100 %");
00127     else if(value < 10)
00128         transButton->setText("00"+QString::number(value)+" %");
00129     else if(value < 100)
00130         transButton->setText("0"+QString::number(value)+" %");
00131     }
00132 
00133 void Workspace::resetClientOpacity()
00134     {
00135     active_popup_client->setCustomOpacityFlag(false);
00136     active_popup_client->updateOpacity();
00137     transSlider->setValue(100-active_popup_client->opacityPercentage());
00138     setTransButtonText(100-active_popup_client->opacityPercentage());
00139     }
00140 
00141 
00147 void Workspace::clientPopupAboutToShow()
00148     {
00149     if ( !active_popup_client || !popup )
00150         return;
00151 
00152     if ( numberOfDesktops() == 1 )
00153         {
00154         delete desk_popup;
00155         desk_popup = 0;
00156         }
00157     else
00158         {
00159         initDesktopPopup();
00160         }
00161 
00162     popup->setItemEnabled( Options::ResizeOp, active_popup_client->isResizable() );
00163     popup->setItemEnabled( Options::MoveOp, active_popup_client->isMovable() );
00164     popup->setItemEnabled( Options::MaximizeOp, active_popup_client->isMaximizable() );
00165     popup->setItemChecked( Options::MaximizeOp, active_popup_client->maximizeMode() == Client::MaximizeFull );
00166     // This should be checked also when hover unshaded
00167     popup->setItemChecked( Options::ShadeOp, active_popup_client->shadeMode() != ShadeNone );
00168     popup->setItemEnabled( Options::ShadeOp, active_popup_client->isShadeable());
00169     advanced_popup->setItemChecked( Options::KeepAboveOp, active_popup_client->keepAbove() );
00170     advanced_popup->setItemChecked( Options::KeepBelowOp, active_popup_client->keepBelow() );
00171     advanced_popup->setItemChecked( Options::FullScreenOp, active_popup_client->isFullScreen() );
00172     advanced_popup->setItemEnabled( Options::FullScreenOp, active_popup_client->userCanSetFullScreen() );
00173     advanced_popup->setItemChecked( Options::NoBorderOp, active_popup_client->noBorder() );
00174     advanced_popup->setItemEnabled( Options::NoBorderOp, active_popup_client->userCanSetNoBorder() );
00175     popup->setItemEnabled( Options::MinimizeOp, active_popup_client->isMinimizable() );
00176     popup->setItemEnabled( Options::CloseOp, active_popup_client->isCloseable() );
00177     if (options->useTranslucency)
00178         {
00179         transSlider->setValue(100-active_popup_client->opacityPercentage());
00180         setTransButtonText(100-active_popup_client->opacityPercentage());
00181         }
00182     }
00183 
00184 
00185 void Workspace::initDesktopPopup()
00186     {
00187     if (desk_popup)
00188         return;
00189 
00190     desk_popup = new QPopupMenu( popup );
00191     desk_popup->setCheckable( TRUE );
00192     desk_popup->setFont(KGlobalSettings::menuFont());
00193     connect( desk_popup, SIGNAL( activated(int) ),
00194              this, SLOT( slotSendToDesktop(int) ) );
00195     connect( desk_popup, SIGNAL( aboutToShow() ),
00196              this, SLOT( desktopPopupAboutToShow() ) );
00197 
00198     popup->insertItem(i18n("To &Desktop"), desk_popup, -1, desk_popup_index );
00199     }
00200 
00205 void Workspace::desktopPopupAboutToShow()
00206     {
00207     if ( !desk_popup )
00208         return;
00209 
00210     desk_popup->clear();
00211     desk_popup->insertItem( i18n("&All Desktops"), 0 );
00212     if ( active_popup_client && active_popup_client->isOnAllDesktops() )
00213         desk_popup->setItemChecked( 0, TRUE );
00214     desk_popup->insertSeparator( -1 );
00215     int id;
00216     const int BASE = 10;
00217     for ( int i = 1; i <= numberOfDesktops(); i++ ) 
00218         {
00219         QString basic_name("%1  %2");
00220         if (i<BASE)
00221             {
00222             basic_name.prepend('&');
00223             }
00224         id = desk_popup->insertItem(
00225                 basic_name
00226                     .arg(i)
00227                     .arg( desktopName(i).replace( '&', "&&" )),
00228                 i );
00229         if ( active_popup_client &&
00230              !active_popup_client->isOnAllDesktops() && active_popup_client->desktop()  == i )
00231             desk_popup->setItemChecked( id, TRUE );
00232         }
00233     }
00234 
00235 void Workspace::closeActivePopup()
00236     {
00237     if( active_popup )
00238         {
00239         active_popup->close();
00240         active_popup = NULL;
00241         active_popup_client = NULL;
00242         }
00243     }
00244 
00248 void Workspace::initShortcuts()
00249     {
00250     keys = new KGlobalAccel( this );
00251     // a separate KGlobalAccel is needed for the shortcut for disabling global shortcuts,
00252     // otherwise it would also disable itself
00253     disable_shortcuts_keys = new KGlobalAccel( this );
00254     disable_shortcuts_keys->disableBlocking( true );
00255 #define IN_KWIN
00256 #include "kwinbindings.cpp"
00257     readShortcuts();
00258     }
00259 
00260 void Workspace::readShortcuts()
00261     {
00262     keys->readSettings();
00263     disable_shortcuts_keys->readSettings();
00264 
00265     cutWalkThroughDesktops = keys->shortcut("Walk Through Desktops");
00266     cutWalkThroughDesktopsReverse = keys->shortcut("Walk Through Desktops (Reverse)");
00267     cutWalkThroughDesktopList = keys->shortcut("Walk Through Desktop List");
00268     cutWalkThroughDesktopListReverse = keys->shortcut("Walk Through Desktop List (Reverse)");
00269     cutWalkThroughWindows = keys->shortcut("Walk Through Windows");
00270     cutWalkThroughWindowsReverse = keys->shortcut("Walk Through Windows (Reverse)");
00271 
00272     keys->updateConnections();
00273     disable_shortcuts_keys->updateConnections();
00274     
00275     delete popup;
00276     popup = NULL; // so that it's recreated next time
00277     desk_popup = NULL;
00278     }
00279 
00280 
00281 void Workspace::setupWindowShortcut( Client* c )
00282     {
00283     assert( client_keys_dialog == NULL );
00284     keys->suspend( true );
00285     disable_shortcuts_keys->suspend( true );
00286     client_keys->suspend( true );
00287     client_keys_dialog = new ShortcutDialog( c->shortcut());
00288     client_keys_client = c;
00289     connect( client_keys_dialog, SIGNAL( dialogDone( bool )), SLOT( setupWindowShortcutDone( bool )));
00290     QRect r = clientArea( ScreenArea, c );
00291     QSize size = client_keys_dialog->sizeHint();
00292     QPoint pos = c->pos() + c->clientPos();
00293     if( pos.x() + size.width() >= r.right())
00294         pos.setX( r.right() - size.width());
00295     if( pos.y() + size.height() >= r.bottom())
00296         pos.setY( r.bottom() - size.height());
00297     client_keys_dialog->move( pos );
00298     client_keys_dialog->show();
00299     active_popup = client_keys_dialog;
00300     active_popup_client = c;
00301     }
00302 
00303 void Workspace::setupWindowShortcutDone( bool ok )
00304     {
00305     keys->suspend( false );
00306     disable_shortcuts_keys->suspend( false );
00307     client_keys->suspend( false );
00308     if( ok )
00309         {
00310         client_keys_client->setShortcut( KShortcut( client_keys_dialog->shortcut()).toString());
00311         }
00312     closeActivePopup();
00313     delete client_keys_dialog;
00314     client_keys_dialog = NULL;
00315     client_keys_client = NULL;
00316     }
00317 
00318 void Workspace::clientShortcutUpdated( Client* c )
00319     {
00320     QString key = QString::number( c->window());
00321     client_keys->remove( key );
00322     if( !c->shortcut().isNull())
00323         {
00324         client_keys->insert( key, key );
00325         client_keys->setShortcut( key, c->shortcut());
00326         client_keys->setSlot( key, c, SLOT( shortcutActivated()));
00327         client_keys->setActionEnabled( key, true );
00328         }
00329     client_keys->updateConnections();
00330     }
00331 
00332 void Workspace::clientPopupActivated( int id )
00333     {
00334     WindowOperation op = static_cast< WindowOperation >( id );
00335     Client* c = active_popup_client ? active_popup_client : active_client;
00336     QString type;
00337     switch( op )
00338         {
00339         case FullScreenOp:
00340             if( !c->isFullScreen() && c->userCanSetFullScreen())
00341                 type = "fullscreenaltf3";
00342           break;
00343         case NoBorderOp:
00344             if( !c->noBorder() && c->userCanSetNoBorder())
00345                 type = "noborderaltf3";
00346           break;
00347         default:
00348             break;
00349         };
00350     if( !type.isEmpty())
00351         helperDialog( type, c );
00352     performWindowOperation( c, op );
00353     }
00354 
00355 
00356 void Workspace::performWindowOperation( Client* c, Options::WindowOperation op ) 
00357     {
00358     if ( !c )
00359         return;
00360 
00361     if (op == Options::MoveOp || op == Options::UnrestrictedMoveOp )
00362         QCursor::setPos( c->geometry().center() );
00363     if (op == Options::ResizeOp || op == Options::UnrestrictedResizeOp )
00364         QCursor::setPos( c->geometry().bottomRight());
00365     switch ( op ) 
00366         {
00367         case Options::MoveOp:
00368             c->performMouseCommand( Options::MouseMove, QCursor::pos() );
00369             break;
00370         case Options::UnrestrictedMoveOp:
00371             c->performMouseCommand( Options::MouseUnrestrictedMove, QCursor::pos() );
00372             break;
00373         case Options::ResizeOp:
00374             c->performMouseCommand( Options::MouseResize, QCursor::pos() );
00375             break;
00376         case Options::UnrestrictedResizeOp:
00377             c->performMouseCommand( Options::MouseUnrestrictedResize, QCursor::pos() );
00378             break;
00379         case Options::CloseOp:
00380             c->closeWindow();
00381             break;
00382         case Options::MaximizeOp:
00383             c->maximize( c->maximizeMode() == Client::MaximizeFull
00384                 ? Client::MaximizeRestore : Client::MaximizeFull );
00385             break;
00386         case Options::HMaximizeOp:
00387             c->maximize( c->maximizeMode() ^ Client::MaximizeHorizontal );
00388             break;
00389         case Options::VMaximizeOp:
00390             c->maximize( c->maximizeMode() ^ Client::MaximizeVertical );
00391             break;
00392         case Options::RestoreOp:
00393             c->maximize( Client::MaximizeRestore );
00394             break;
00395         case Options::MinimizeOp:
00396             c->minimize();
00397             break;
00398         case Options::ShadeOp:
00399             c->performMouseCommand( Options::MouseShade, QCursor::pos());
00400             break;
00401         case Options::OnAllDesktopsOp:
00402             c->setOnAllDesktops( !c->isOnAllDesktops() );
00403             break;
00404         case Options::FullScreenOp:
00405             c->setFullScreen( !c->isFullScreen(), true );
00406             break;
00407         case Options::NoBorderOp:
00408             c->setUserNoBorder( !c->isUserNoBorder());
00409             break;
00410         case Options::KeepAboveOp:
00411             {
00412             StackingUpdatesBlocker blocker( this );
00413             bool was = c->keepAbove();
00414             c->setKeepAbove( !c->keepAbove() );
00415             if( was && !c->keepAbove())
00416                 raiseClient( c );
00417             break;
00418             }
00419         case Options::KeepBelowOp:
00420             {
00421             StackingUpdatesBlocker blocker( this );
00422             bool was = c->keepBelow();
00423             c->setKeepBelow( !c->keepBelow() );
00424             if( was && !c->keepBelow())
00425                 lowerClient( c );
00426             break;
00427             }
00428         case Options::OperationsOp:
00429             c->performMouseCommand( Options::MouseShade, QCursor::pos());
00430             break;
00431         case Options::WindowRulesOp:
00432             editWindowRules( c, false );
00433             break;
00434         case Options::ApplicationRulesOp:
00435             editWindowRules( c, true );
00436             break;
00437         case Options::SetupWindowShortcutOp:
00438             setupWindowShortcut( c );
00439             break;
00440         case Options::LowerOp:
00441             lowerClient(c);
00442             break;
00443         case Options::NoOp:
00444             break;
00445         }
00446     }
00447 
00451 bool Client::performMouseCommand( Options::MouseCommand command, QPoint globalPos, bool handled )
00452     {
00453     bool replay = FALSE;
00454     switch (command) 
00455         {
00456         case Options::MouseRaise:
00457             workspace()->raiseClient( this );
00458             break;
00459         case Options::MouseLower:
00460             workspace()->lowerClient( this );
00461             break;
00462         case Options::MouseShade :
00463             toggleShade();
00464             cancelShadeHover();
00465             break;
00466         case Options::MouseSetShade:
00467             setShade( ShadeNormal );
00468             cancelShadeHover();
00469             break;
00470         case Options::MouseUnsetShade:
00471             setShade( ShadeNone );
00472             cancelShadeHover();
00473             break;
00474         case Options::MouseOperationsMenu:
00475             if ( isActive() && options->clickRaise )
00476                 autoRaise();
00477             workspace()->showWindowMenu( globalPos, this );
00478             break;
00479         case Options::MouseToggleRaiseAndLower:
00480             workspace()->raiseOrLowerClient( this );
00481             break;
00482         case Options::MouseActivateAndRaise:
00483             replay = isActive(); // for clickraise mode
00484             workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled && replay );
00485             break;
00486         case Options::MouseActivateAndLower:
00487             workspace()->requestFocus( this );
00488             workspace()->lowerClient( this );
00489             break;
00490         case Options::MouseActivate:
00491             replay = isActive(); // for clickraise mode
00492             workspace()->takeActivity( this, ActivityFocus, handled && replay );
00493             break;
00494         case Options::MouseActivateRaiseAndPassClick:
00495             workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled );
00496             replay = TRUE;
00497             break;
00498         case Options::MouseActivateAndPassClick:
00499             workspace()->takeActivity( this, ActivityFocus, handled );
00500             replay = TRUE;
00501             break;
00502         case Options::MouseActivateRaiseAndMove:
00503         case Options::MouseActivateRaiseAndUnrestrictedMove:
00504             workspace()->raiseClient( this );
00505             workspace()->requestFocus( this );
00506             if( options->moveMode == Options::Transparent && isMovable())
00507                 move_faked_activity = workspace()->fakeRequestedActivity( this );
00508         // fallthrough
00509         case Options::MouseMove:
00510         case Options::MouseUnrestrictedMove:
00511             {
00512             if (!isMovable())
00513                 break;
00514             if( moveResizeMode )
00515                 finishMoveResize( false );
00516             mode = PositionCenter;
00517             buttonDown = TRUE;
00518             moveOffset = QPoint( globalPos.x() - x(), globalPos.y() - y()); // map from global
00519             invertedMoveOffset = rect().bottomRight() - moveOffset;
00520             unrestrictedMoveResize = ( command == Options::MouseActivateRaiseAndUnrestrictedMove
00521                                     || command == Options::MouseUnrestrictedMove );
00522             setCursor( mode );
00523             if( !startMoveResize())
00524                 {
00525                 buttonDown = false;
00526                 setCursor( mode );
00527                 }
00528             break;
00529             }
00530         case Options::MouseResize:
00531         case Options::MouseUnrestrictedResize:
00532             {
00533             if (!isResizable() || isShade())
00534                 break;
00535             if( moveResizeMode )
00536                 finishMoveResize( false );
00537             buttonDown = TRUE;
00538             moveOffset = QPoint( globalPos.x() - x(), globalPos.y() - y()); // map from global
00539             int x = moveOffset.x(), y = moveOffset.y();
00540             bool left = x < width() / 3;
00541             bool right = x >= 2 * width() / 3;
00542             bool top = y < height() / 3;
00543             bool bot = y >= 2 * height() / 3;
00544             if (top)
00545                 mode = left ? PositionTopLeft : (right ? PositionTopRight : PositionTop);
00546             else if (bot)
00547                 mode = left ? PositionBottomLeft : (right ? PositionBottomRight : PositionBottom);
00548             else
00549                 mode = (x < width() / 2) ? PositionLeft : PositionRight;
00550             invertedMoveOffset = rect().bottomRight() - moveOffset;
00551             unrestrictedMoveResize = ( command == Options::MouseUnrestrictedResize );
00552             setCursor( mode );
00553             if( !startMoveResize())
00554                 {
00555                 buttonDown = false;
00556                 setCursor( mode );
00557                 }
00558             break;
00559             }
00560         case Options::MouseMaximize:
00561             maximize( Client::MaximizeFull );
00562             break;
00563         case Options::MouseRestore:
00564             maximize( Client::MaximizeRestore );
00565             break;
00566         case Options::MouseMinimize:
00567             minimize();
00568             break;
00569         case Options::MouseAbove:
00570             {
00571             StackingUpdatesBlocker blocker( workspace());
00572             if( keepBelow())
00573                 setKeepBelow( false );
00574             else
00575                 setKeepAbove( true );
00576             break;
00577             }
00578         case Options::MouseBelow:
00579             {
00580             StackingUpdatesBlocker blocker( workspace());
00581             if( keepAbove())
00582                 setKeepAbove( false );
00583             else
00584                 setKeepBelow( true );
00585             break;
00586             }
00587         case Options::MousePreviousDesktop:
00588             workspace()->windowToPreviousDesktop( this );
00589             break;
00590         case Options::MouseNextDesktop:
00591             workspace()->windowToNextDesktop( this );
00592             break;
00593         case Options::MouseOpacityMore:
00594             if (opacity_ < 0xFFFFFFFF)
00595                 {
00596                 if (opacity_ < 0xF3333333)
00597                     {
00598                     setOpacity(TRUE, opacity_ + 0xCCCCCCC);
00599                     custom_opacity = true;
00600                     }
00601                 else
00602                     {
00603                     setOpacity(FALSE, 0xFFFFFFFF);
00604                     custom_opacity = false;
00605                     }
00606                 }
00607             break;
00608         case Options::MouseOpacityLess:
00609             if (opacity_ > 0)
00610                 {
00611                 setOpacity(TRUE, (opacity_ > 0xCCCCCCC) ? opacity_ - 0xCCCCCCC : 0);
00612                 custom_opacity = true;
00613                 }
00614             break;
00615         case Options::MouseNothing:
00616             replay = TRUE;
00617             break;
00618         }
00619     return replay;
00620     }
00621 
00622 // KDE4 remove me
00623 void Workspace::showWindowMenuAt( unsigned long, int, int )
00624     {
00625     slotWindowOperations();
00626     }
00627 
00628 void Workspace::slotActivateAttentionWindow()
00629     {
00630     if( attention_chain.count() > 0 )
00631         activateClient( attention_chain.first());
00632     }
00633 
00634 void Workspace::slotSwitchDesktopNext()
00635     {
00636     int d = currentDesktop() + 1;
00637      if ( d > numberOfDesktops() ) 
00638         {
00639         if ( options->rollOverDesktops ) 
00640             {
00641             d = 1;
00642             }
00643         else 
00644             {
00645             return;
00646             }
00647         }
00648     setCurrentDesktop(d);
00649     }
00650 
00651 void Workspace::slotSwitchDesktopPrevious()
00652     {
00653     int d = currentDesktop() - 1;
00654     if ( d <= 0 ) 
00655         {
00656         if ( options->rollOverDesktops )
00657           d = numberOfDesktops();
00658       else
00659           return;
00660         }
00661     setCurrentDesktop(d);
00662     }
00663 
00664 void Workspace::slotSwitchDesktopRight()
00665     {
00666     int desktop = desktopToRight( currentDesktop());
00667     if( desktop == currentDesktop())
00668         return;
00669     setCurrentDesktop( desktop );
00670     }
00671 
00672 void Workspace::slotSwitchDesktopLeft()
00673     {
00674     int desktop = desktopToLeft( currentDesktop());
00675     if( desktop == currentDesktop())
00676         return;
00677     setCurrentDesktop( desktop );
00678     }
00679 
00680 void Workspace::slotSwitchDesktopUp()
00681     {
00682     int desktop = desktopUp( currentDesktop());
00683     if( desktop == currentDesktop())
00684         return;
00685     setCurrentDesktop( desktop );
00686     }
00687 
00688 void Workspace::slotSwitchDesktopDown()
00689     {
00690     int desktop = desktopDown( currentDesktop());
00691     if( desktop == currentDesktop())
00692         return;
00693     setCurrentDesktop( desktop );
00694     }
00695 
00696 void Workspace::slotSwitchToDesktop( int i )
00697     {
00698     setCurrentDesktop( i );
00699     }
00700 
00701 
00702 void Workspace::slotWindowToDesktop( int i )
00703     {
00704     Client* c = active_popup_client ? active_popup_client : active_client;
00705     if( i >= 1 && i <= numberOfDesktops() && c
00706         && !c->isDesktop()
00707         && !c->isDock()
00708         && !c->isTopMenu())
00709             sendClientToDesktop( c, i, true );
00710     }
00711 
00715 void Workspace::slotWindowMaximize()
00716     {
00717     Client* c = active_popup_client ? active_popup_client : active_client;
00718     if ( c )
00719         performWindowOperation( c, Options::MaximizeOp );
00720     }
00721 
00725 void Workspace::slotWindowMaximizeVertical()
00726     {
00727     Client* c = active_popup_client ? active_popup_client : active_client;
00728     if ( c )
00729         performWindowOperation( c, Options::VMaximizeOp );
00730     }
00731 
00735 void Workspace::slotWindowMaximizeHorizontal()
00736     {
00737     Client* c = active_popup_client ? active_popup_client : active_client;
00738     if ( c )
00739         performWindowOperation( c, Options::HMaximizeOp );
00740     }
00741 
00742 
00746 void Workspace::slotWindowMinimize()
00747     {
00748     Client* c = active_popup_client ? active_popup_client : active_client;
00749     performWindowOperation( c, Options::MinimizeOp );
00750     }
00751 
00755 void Workspace::slotWindowShade()
00756     {
00757     Client* c = active_popup_client ? active_popup_client : active_client;
00758     performWindowOperation( c, Options::ShadeOp );
00759     }
00760 
00764 void Workspace::slotWindowRaise()
00765     {
00766     Client* c = active_popup_client ? active_popup_client : active_client;
00767     if ( c )
00768         raiseClient( c );
00769     }
00770 
00774 void Workspace::slotWindowLower()
00775     {
00776     Client* c = active_popup_client ? active_popup_client : active_client;
00777     if ( c )
00778         lowerClient( c );
00779     }
00780 
00784 void Workspace::slotWindowRaiseOrLower()
00785     {
00786     Client* c = active_popup_client ? active_popup_client : active_client;
00787     if  ( c )
00788         raiseOrLowerClient( c );
00789     }
00790 
00791 void Workspace::slotWindowOnAllDesktops()
00792     {
00793     Client* c = active_popup_client ? active_popup_client : active_client;
00794     if( c )
00795         c->setOnAllDesktops( !c->isOnAllDesktops());
00796     }
00797 
00798 void Workspace::slotWindowFullScreen()
00799     {
00800     Client* c = active_popup_client ? active_popup_client : active_client;
00801     if( c )
00802         performWindowOperation( c, Options::FullScreenOp );
00803     }
00804 
00805 void Workspace::slotWindowNoBorder()
00806     {
00807     Client* c = active_popup_client ? active_popup_client : active_client;
00808     if( c )
00809         performWindowOperation( c, Options::NoBorderOp );
00810     }
00811 
00812 void Workspace::slotWindowAbove()
00813     {
00814     Client* c = active_popup_client ? active_popup_client : active_client;
00815     if( c )
00816         performWindowOperation( c, Options::KeepAboveOp );
00817     }
00818 
00819 void Workspace::slotWindowBelow()
00820     {
00821     Client* c = active_popup_client ? active_popup_client : active_client;
00822     if( c )
00823         performWindowOperation( c, Options::KeepBelowOp );
00824     }
00825 void Workspace::slotSetupWindowShortcut()
00826     {
00827     Client* c = active_popup_client ? active_popup_client : active_client;
00828     if( c )
00829         performWindowOperation( c, Options::SetupWindowShortcutOp );
00830     }
00831 
00835 void Workspace::slotWindowToNextDesktop()
00836     {
00837     windowToNextDesktop( active_popup_client ? active_popup_client : active_client );
00838     }
00839     
00840 void Workspace::windowToNextDesktop( Client* c )
00841     {
00842     int d = currentDesktop() + 1;
00843     if ( d > numberOfDesktops() )
00844         d = 1;
00845     if (c && !c->isDesktop()
00846         && !c->isDock() && !c->isTopMenu())
00847         {
00848         setClientIsMoving( c );
00849         setCurrentDesktop( d );
00850         setClientIsMoving( NULL );
00851         }
00852     }
00853 
00857 void Workspace::slotWindowToPreviousDesktop()
00858     {
00859     windowToPreviousDesktop( active_popup_client ? active_popup_client : active_client );
00860     }
00861     
00862 void Workspace::windowToPreviousDesktop( Client* c )
00863     {
00864     int d = currentDesktop() - 1;
00865     if ( d <= 0 )
00866         d = numberOfDesktops();
00867     if (c && !c->isDesktop()
00868         && !c->isDock() && !c->isTopMenu())
00869         {
00870         setClientIsMoving( c );
00871         setCurrentDesktop( d );
00872         setClientIsMoving( NULL );
00873         }
00874     }
00875 
00876 void Workspace::slotWindowToDesktopRight()
00877     {
00878     int d = desktopToRight( currentDesktop());
00879     if( d == currentDesktop())
00880         return;
00881     Client* c = active_popup_client ? active_popup_client : active_client;
00882     if (c && !c->isDesktop()
00883         && !c->isDock() && !c->isTopMenu())
00884         {
00885         setClientIsMoving( c );
00886         setCurrentDesktop( d );
00887         setClientIsMoving( NULL );
00888         }
00889     }
00890 
00891 void Workspace::slotWindowToDesktopLeft()
00892     {
00893     int d = desktopToLeft( currentDesktop());
00894     if( d == currentDesktop())
00895         return;
00896     Client* c = active_popup_client ? active_popup_client : active_client;
00897     if (c && !c->isDesktop()
00898         && !c->isDock() && !c->isTopMenu())
00899         {
00900         setClientIsMoving( c );
00901         setCurrentDesktop( d );
00902         setClientIsMoving( NULL );
00903         }
00904     }
00905 
00906 void Workspace::slotWindowToDesktopUp()
00907     {
00908     int d = desktopUp( currentDesktop());
00909     if( d == currentDesktop())
00910         return;
00911     Client* c = active_popup_client ? active_popup_client : active_client;
00912     if (c && !c->isDesktop()
00913         && !c->isDock() && !c->isTopMenu())
00914         {
00915         setClientIsMoving( c );
00916         setCurrentDesktop( d );
00917         setClientIsMoving( NULL );
00918         }
00919     }
00920 
00921 void Workspace::slotWindowToDesktopDown()
00922     {
00923     int d = desktopDown( currentDesktop());
00924     if( d == currentDesktop())
00925         return;
00926     Client* c = active_popup_client ? active_popup_client : active_client;
00927     if (c && !c->isDesktop()
00928         && !c->isDock() && !c->isTopMenu())
00929         {
00930         setClientIsMoving( c );
00931         setCurrentDesktop( d );
00932         setClientIsMoving( NULL );
00933         }
00934     }
00935 
00936 
00940 void Workspace::slotKillWindow()
00941     {
00942     KillWindow kill( this );
00943     kill.start();
00944     }
00945 
00951 void Workspace::slotSendToDesktop( int desk )
00952     {
00953     if ( !active_popup_client )
00954         return;
00955     if ( desk == 0 ) 
00956         { // the 'on_all_desktops' menu entry
00957         active_popup_client->setOnAllDesktops( !active_popup_client->isOnAllDesktops());
00958         return;
00959         }
00960 
00961     sendClientToDesktop( active_popup_client, desk, false );
00962 
00963     }
00964 
00968 void Workspace::slotWindowOperations()
00969     {
00970     if ( !active_client )
00971         return;
00972     QPoint pos = active_client->pos() + active_client->clientPos();
00973     showWindowMenu( pos.x(), pos.y(), active_client );
00974     }
00975 
00976 void Workspace::showWindowMenu( const QRect &pos, Client* cl )
00977     {
00978     if (!kapp->authorizeKAction("kwin_rmb"))
00979         return;
00980     if( !cl )
00981         return;
00982     if( active_popup_client != NULL ) // recursion
00983         return;
00984     if ( cl->isDesktop()
00985         || cl->isDock()
00986         || cl->isTopMenu())
00987         return;
00988 
00989     active_popup_client = cl;
00990     QPopupMenu* p = clientPopup();
00991     active_popup = p;
00992     int x = pos.left();
00993     int y = pos.bottom();
00994     if (y == pos.top())
00995     p->exec( QPoint( x, y ) );
00996     else
00997         {
00998     QRect area = clientArea(ScreenArea, QPoint(x, y), currentDesktop());
00999         clientPopupAboutToShow(); // needed for sizeHint() to be correct :-/
01000     int popupHeight = p->sizeHint().height();
01001     if (y + popupHeight < area.height())
01002         p->exec( QPoint( x, y ) );
01003     else
01004         p->exec( QPoint( x, pos.top() - popupHeight ) );
01005         }
01006     // active popup may be already changed (e.g. the window shortcut dialog)
01007     if( active_popup == p )
01008         closeActivePopup();
01009     }
01010 
01014 void Workspace::slotWindowClose()
01015     {
01016     if ( tab_box->isVisible())
01017         return;
01018     Client* c = active_popup_client ? active_popup_client : active_client;
01019     performWindowOperation( c, Options::CloseOp );
01020     }
01021 
01025 void Workspace::slotWindowMove()
01026     {
01027     Client* c = active_popup_client ? active_popup_client : active_client;
01028     performWindowOperation( c, Options::UnrestrictedMoveOp );
01029     }
01030 
01034 void Workspace::slotWindowResize()
01035     {
01036     Client* c = active_popup_client ? active_popup_client : active_client;
01037     performWindowOperation( c, Options::UnrestrictedResizeOp );
01038     }
01039 
01040 void Client::setShortcut( const QString& _cut )
01041     {
01042     QString cut = rules()->checkShortcut( _cut );
01043     if( cut.isEmpty())
01044         return setShortcutInternal( KShortcut());
01045 // Format:
01046 // base+(abcdef)<space>base+(abcdef)
01047 // E.g. Alt+Ctrl+(ABCDEF) Win+X,Win+(ABCDEF)
01048     if( !cut.contains( '(' ) && !cut.contains( ')' ) && !cut.contains( ' ' ))
01049         {
01050         if( workspace()->shortcutAvailable( KShortcut( cut ), this ))
01051             setShortcutInternal( KShortcut( cut ));
01052         else
01053             setShortcutInternal( KShortcut());
01054         return;
01055         }
01056     QValueList< KShortcut > keys;
01057     QStringList groups = QStringList::split( ' ', cut );
01058     for( QStringList::ConstIterator it = groups.begin();
01059          it != groups.end();
01060          ++it )
01061         {
01062         QRegExp reg( "(.*\\+)\\((.*)\\)" );
01063         if( reg.search( *it ) > -1 )
01064             {
01065             QString base = reg.cap( 1 );
01066             QString list = reg.cap( 2 );
01067             for( unsigned int i = 0;
01068                  i < list.length();
01069                  ++i )
01070                 {
01071                 KShortcut c( base + list[ i ] );
01072                 if( !c.isNull())
01073                     keys.append( c );
01074                 }
01075             }
01076         }
01077     for( QValueList< KShortcut >::ConstIterator it = keys.begin();
01078          it != keys.end();
01079          ++it )
01080         {
01081         if( _shortcut == *it ) // current one is in the list
01082             return;
01083         }
01084     for( QValueList< KShortcut >::ConstIterator it = keys.begin();
01085          it != keys.end();
01086          ++it )
01087         {
01088         if( workspace()->shortcutAvailable( *it, this ))
01089             {
01090             setShortcutInternal( *it );
01091             return;
01092             }
01093         }
01094     setShortcutInternal( KShortcut());
01095     }
01096 
01097 void Client::setShortcutInternal( const KShortcut& cut )
01098     {
01099     if( _shortcut == cut )
01100         return;
01101     _shortcut = cut;
01102     updateCaption();
01103     workspace()->clientShortcutUpdated( this );
01104     }
01105 
01106 bool Workspace::shortcutAvailable( const KShortcut& cut, Client* ignore ) const
01107     {
01108     // TODO check global shortcuts etc.
01109     for( ClientList::ConstIterator it = clients.begin();
01110          it != clients.end();
01111          ++it )
01112         {
01113         if( (*it) != ignore && (*it)->shortcut() == cut )
01114             return false;    
01115         }
01116     return true;
01117     }
01118 
01119 } // namespace
KDE Home | KDE Accessibility Home | Description of Access Keys