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->setEnabled( false );
00285     disable_shortcuts_keys->setEnabled( false );
00286     client_keys->setEnabled( false );
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->setEnabled( true );
00306     disable_shortcuts_keys->setEnabled( true );
00307     client_keys->setEnabled( true );
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         case Options::MinimizeOp:
00395             c->minimize();
00396             break;
00397         case Options::ShadeOp:
00398             c->performMouseCommand( Options::MouseShade, QCursor::pos());
00399             break;
00400         case Options::OnAllDesktopsOp:
00401             c->setOnAllDesktops( !c->isOnAllDesktops() );
00402             break;
00403         case Options::FullScreenOp:
00404             c->setFullScreen( !c->isFullScreen(), true );
00405             break;
00406         case Options::NoBorderOp:
00407             c->setUserNoBorder( !c->isUserNoBorder());
00408             break;
00409         case Options::KeepAboveOp:
00410             {
00411             StackingUpdatesBlocker blocker( this );
00412             bool was = c->keepAbove();
00413             c->setKeepAbove( !c->keepAbove() );
00414             if( was && !c->keepAbove())
00415                 raiseClient( c );
00416             break;
00417             }
00418         case Options::KeepBelowOp:
00419             {
00420             StackingUpdatesBlocker blocker( this );
00421             bool was = c->keepBelow();
00422             c->setKeepBelow( !c->keepBelow() );
00423             if( was && !c->keepBelow())
00424                 lowerClient( c );
00425             break;
00426             }
00427         case Options::OperationsOp:
00428             c->performMouseCommand( Options::MouseShade, QCursor::pos());
00429             break;
00430         case Options::WindowRulesOp:
00431             editWindowRules( c, false );
00432             break;
00433         case Options::ApplicationRulesOp:
00434             editWindowRules( c, true );
00435             break;
00436         case Options::SetupWindowShortcutOp:
00437             setupWindowShortcut( c );
00438             break;
00439         case Options::LowerOp:
00440             lowerClient(c);
00441             break;
00442         case Options::NoOp:
00443             break;
00444         }
00445     }
00446 
00450 bool Client::performMouseCommand( Options::MouseCommand command, QPoint globalPos, bool handled )
00451     {
00452     bool replay = FALSE;
00453     switch (command) 
00454         {
00455         case Options::MouseRaise:
00456             workspace()->raiseClient( this );
00457             break;
00458         case Options::MouseLower:
00459             workspace()->lowerClient( this );
00460             break;
00461         case Options::MouseShade :
00462             toggleShade();
00463             cancelShadeHover();
00464             break;
00465         case Options::MouseSetShade:
00466             setShade( ShadeNormal );
00467             cancelShadeHover();
00468             break;
00469         case Options::MouseUnsetShade:
00470             setShade( ShadeNone );
00471             cancelShadeHover();
00472             break;
00473         case Options::MouseOperationsMenu:
00474             if ( isActive() & options->clickRaise )
00475                 autoRaise();
00476             workspace()->showWindowMenu( globalPos, this );
00477             break;
00478         case Options::MouseToggleRaiseAndLower:
00479             workspace()->raiseOrLowerClient( this );
00480             break;
00481         case Options::MouseActivateAndRaise:
00482             replay = isActive(); // for clickraise mode
00483             workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled && replay );
00484             break;
00485         case Options::MouseActivateAndLower:
00486             workspace()->requestFocus( this );
00487             workspace()->lowerClient( this );
00488             break;
00489         case Options::MouseActivate:
00490             replay = isActive(); // for clickraise mode
00491             workspace()->takeActivity( this, ActivityFocus, handled && replay );
00492             break;
00493         case Options::MouseActivateRaiseAndPassClick:
00494             workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled );
00495             replay = TRUE;
00496             break;
00497         case Options::MouseActivateAndPassClick:
00498             workspace()->takeActivity( this, ActivityFocus, handled );
00499             replay = TRUE;
00500             break;
00501         case Options::MouseActivateRaiseAndMove:
00502         case Options::MouseActivateRaiseAndUnrestrictedMove:
00503             workspace()->raiseClient( this );
00504             workspace()->requestFocus( this );
00505             if( options->moveMode == Options::Transparent && isMovable())
00506                 move_faked_activity = workspace()->fakeRequestedActivity( this );
00507         // fallthrough
00508         case Options::MouseMove:
00509         case Options::MouseUnrestrictedMove:
00510             {
00511             if (!isMovable())
00512                 break;
00513             if( moveResizeMode )
00514                 finishMoveResize( false );
00515             mode = PositionCenter;
00516             buttonDown = TRUE;
00517             moveOffset = QPoint( globalPos.x() - x(), globalPos.y() - y()); // map from global
00518             invertedMoveOffset = rect().bottomRight() - moveOffset;
00519             unrestrictedMoveResize = ( command == Options::MouseActivateRaiseAndUnrestrictedMove
00520                                     || command == Options::MouseUnrestrictedMove );
00521             setCursor( mode );
00522             if( !startMoveResize())
00523                 {
00524                 buttonDown = false;
00525                 setCursor( mode );
00526                 }
00527             break;
00528             }
00529         case Options::MouseResize:
00530         case Options::MouseUnrestrictedResize:
00531             {
00532             if (!isResizable() || isShade())
00533                 break;
00534             if( moveResizeMode )
00535                 finishMoveResize( false );
00536             buttonDown = TRUE;
00537             moveOffset = QPoint( globalPos.x() - x(), globalPos.y() - y()); // map from global
00538             int x = moveOffset.x(), y = moveOffset.y();
00539             bool left = x < width() / 3;
00540             bool right = x >= 2 * width() / 3;
00541             bool top = y < height() / 3;
00542             bool bot = y >= 2 * height() / 3;
00543             if (top)
00544                 mode = left ? PositionTopLeft : (right ? PositionTopRight : PositionTop);
00545             else if (bot)
00546                 mode = left ? PositionBottomLeft : (right ? PositionBottomRight : PositionBottom);
00547             else
00548                 mode = (x < width() / 2) ? PositionLeft : PositionRight;
00549             invertedMoveOffset = rect().bottomRight() - moveOffset;
00550             unrestrictedMoveResize = ( command == Options::MouseUnrestrictedResize );
00551             setCursor( mode );
00552             if( !startMoveResize())
00553                 {
00554                 buttonDown = false;
00555                 setCursor( mode );
00556                 }
00557             break;
00558             }
00559         case Options::MouseMaximize:
00560             maximize( Client::MaximizeFull );
00561             break;
00562         case Options::MouseRestore:
00563             maximize( Client::MaximizeRestore );
00564             break;
00565         case Options::MouseMinimize:
00566             minimize();
00567             break;
00568         case Options::MouseAbove:
00569             {
00570             StackingUpdatesBlocker blocker( workspace());
00571             if( keepBelow())
00572                 setKeepBelow( false );
00573             else
00574                 setKeepAbove( true );
00575             break;
00576             }
00577         case Options::MouseBelow:
00578             {
00579             StackingUpdatesBlocker blocker( workspace());
00580             if( keepAbove())
00581                 setKeepAbove( false );
00582             else
00583                 setKeepBelow( true );
00584             break;
00585             }
00586         case Options::MousePreviousDesktop:
00587             workspace()->windowToPreviousDesktop( this );
00588             break;
00589         case Options::MouseNextDesktop:
00590             workspace()->windowToNextDesktop( this );
00591             break;
00592         case Options::MouseOpacityMore:
00593             if (opacity_ < 0xFFFFFFFF)
00594                 {
00595                 if (opacity_ < 0xF3333333)
00596                     {
00597                     setOpacity(TRUE, opacity_ + 0xCCCCCCC);
00598                     custom_opacity = true;
00599                     }
00600                 else
00601                     {
00602                     setOpacity(FALSE, 0xFFFFFFFF);
00603                     custom_opacity = false;
00604                     }
00605                 }
00606             break;
00607         case Options::MouseOpacityLess:
00608             if (opacity_ > 0)
00609                 {
00610                 setOpacity(TRUE, (opacity_ > 0xCCCCCCC) ? opacity_ - 0xCCCCCCC : 0);
00611                 custom_opacity = true;
00612                 }
00613             break;
00614         case Options::MouseNothing:
00615             replay = TRUE;
00616             break;
00617         }
00618     return replay;
00619     }
00620 
00621 // KDE4 remove me
00622 void Workspace::showWindowMenuAt( unsigned long, int, int )
00623     {
00624     slotWindowOperations();
00625     }
00626 
00627 void Workspace::slotActivateAttentionWindow()
00628     {
00629     if( attention_chain.count() > 0 )
00630         activateClient( attention_chain.first());
00631     }
00632 
00633 void Workspace::slotSwitchDesktopNext()
00634     {
00635     int d = currentDesktop() + 1;
00636      if ( d > numberOfDesktops() ) 
00637         {
00638         if ( options->rollOverDesktops ) 
00639             {
00640             d = 1;
00641             }
00642         else 
00643             {
00644             return;
00645             }
00646         }
00647     setCurrentDesktop(d);
00648     }
00649 
00650 void Workspace::slotSwitchDesktopPrevious()
00651     {
00652     int d = currentDesktop() - 1;
00653     if ( d <= 0 ) 
00654         {
00655         if ( options->rollOverDesktops )
00656           d = numberOfDesktops();
00657       else
00658           return;
00659         }
00660     setCurrentDesktop(d);
00661     }
00662 
00663 void Workspace::slotSwitchDesktopRight()
00664     {
00665     int desktop = desktopToRight( currentDesktop());
00666     if( desktop == currentDesktop())
00667         return;
00668     setCurrentDesktop( desktop );
00669     }
00670 
00671 void Workspace::slotSwitchDesktopLeft()
00672     {
00673     int desktop = desktopToLeft( currentDesktop());
00674     if( desktop == currentDesktop())
00675         return;
00676     setCurrentDesktop( desktop );
00677     }
00678 
00679 void Workspace::slotSwitchDesktopUp()
00680     {
00681     int desktop = desktopUp( currentDesktop());
00682     if( desktop == currentDesktop())
00683         return;
00684     setCurrentDesktop( desktop );
00685     }
00686 
00687 void Workspace::slotSwitchDesktopDown()
00688     {
00689     int desktop = desktopDown( currentDesktop());
00690     if( desktop == currentDesktop())
00691         return;
00692     setCurrentDesktop( desktop );
00693     }
00694 
00695 void Workspace::slotSwitchToDesktop( int i )
00696     {
00697     setCurrentDesktop( i );
00698     }
00699 
00700 
00701 void Workspace::slotWindowToDesktop( int i )
00702     {
00703     Client* c = active_popup_client ? active_popup_client : active_client;
00704     if( i >= 1 && i <= numberOfDesktops() && c
00705         && !c->isDesktop()
00706         && !c->isDock()
00707         && !c->isTopMenu())
00708             sendClientToDesktop( c, i, true );
00709     }
00710 
00714 void Workspace::slotWindowMaximize()
00715     {
00716     Client* c = active_popup_client ? active_popup_client : active_client;
00717     if ( c )
00718         performWindowOperation( c, Options::MaximizeOp );
00719     }
00720 
00724 void Workspace::slotWindowMaximizeVertical()
00725     {
00726     Client* c = active_popup_client ? active_popup_client : active_client;
00727     if ( c )
00728         performWindowOperation( c, Options::VMaximizeOp );
00729     }
00730 
00734 void Workspace::slotWindowMaximizeHorizontal()
00735     {
00736     Client* c = active_popup_client ? active_popup_client : active_client;
00737     if ( c )
00738         performWindowOperation( c, Options::HMaximizeOp );
00739     }
00740 
00741 
00745 void Workspace::slotWindowMinimize()
00746     {
00747     Client* c = active_popup_client ? active_popup_client : active_client;
00748     performWindowOperation( c, Options::MinimizeOp );
00749     }
00750 
00754 void Workspace::slotWindowShade()
00755     {
00756     Client* c = active_popup_client ? active_popup_client : active_client;
00757     performWindowOperation( c, Options::ShadeOp );
00758     }
00759 
00763 void Workspace::slotWindowRaise()
00764     {
00765     Client* c = active_popup_client ? active_popup_client : active_client;
00766     if ( c )
00767         raiseClient( c );
00768     }
00769 
00773 void Workspace::slotWindowLower()
00774     {
00775     Client* c = active_popup_client ? active_popup_client : active_client;
00776     if ( c )
00777         lowerClient( c );
00778     }
00779 
00783 void Workspace::slotWindowRaiseOrLower()
00784     {
00785     Client* c = active_popup_client ? active_popup_client : active_client;
00786     if  ( c )
00787         raiseOrLowerClient( c );
00788     }
00789 
00790 void Workspace::slotWindowOnAllDesktops()
00791     {
00792     Client* c = active_popup_client ? active_popup_client : active_client;
00793     if( c )
00794         c->setOnAllDesktops( !c->isOnAllDesktops());
00795     }
00796 
00797 void Workspace::slotWindowFullScreen()
00798     {
00799     Client* c = active_popup_client ? active_popup_client : active_client;
00800     if( c )
00801         performWindowOperation( c, Options::FullScreenOp );
00802     }
00803 
00804 void Workspace::slotWindowNoBorder()
00805     {
00806     Client* c = active_popup_client ? active_popup_client : active_client;
00807     if( c )
00808         performWindowOperation( c, Options::NoBorderOp );
00809     }
00810 
00811 void Workspace::slotWindowAbove()
00812     {
00813     Client* c = active_popup_client ? active_popup_client : active_client;
00814     if( c )
00815         performWindowOperation( c, Options::KeepAboveOp );
00816     }
00817 
00818 void Workspace::slotWindowBelow()
00819     {
00820     Client* c = active_popup_client ? active_popup_client : active_client;
00821     if( c )
00822         performWindowOperation( c, Options::KeepBelowOp );
00823     }
00824 void Workspace::slotSetupWindowShortcut()
00825     {
00826     Client* c = active_popup_client ? active_popup_client : active_client;
00827     if( c )
00828         performWindowOperation( c, Options::SetupWindowShortcutOp );
00829     }
00830 
00834 void Workspace::slotWindowToNextDesktop()
00835     {
00836     windowToNextDesktop( active_popup_client ? active_popup_client : active_client );
00837     }
00838     
00839 void Workspace::windowToNextDesktop( Client* c )
00840     {
00841     int d = currentDesktop() + 1;
00842     if ( d > numberOfDesktops() )
00843         d = 1;
00844     if (c && !c->isDesktop()
00845         && !c->isDock() && !c->isTopMenu())
00846         {
00847         setClientIsMoving( c );
00848         setCurrentDesktop( d );
00849         setClientIsMoving( NULL );
00850         }
00851     }
00852 
00856 void Workspace::slotWindowToPreviousDesktop()
00857     {
00858     windowToPreviousDesktop( active_popup_client ? active_popup_client : active_client );
00859     }
00860     
00861 void Workspace::windowToPreviousDesktop( Client* c )
00862     {
00863     int d = currentDesktop() - 1;
00864     if ( d <= 0 )
00865         d = numberOfDesktops();
00866     if (c && !c->isDesktop()
00867         && !c->isDock() && !c->isTopMenu())
00868         {
00869         setClientIsMoving( c );
00870         setCurrentDesktop( d );
00871         setClientIsMoving( NULL );
00872         }
00873     }
00874 
00875 void Workspace::slotWindowToDesktopRight()
00876     {
00877     int d = desktopToRight( currentDesktop());
00878     if( d == currentDesktop())
00879         return;
00880     Client* c = active_popup_client ? active_popup_client : active_client;
00881     if (c && !c->isDesktop()
00882         && !c->isDock() && !c->isTopMenu())
00883         {
00884         setClientIsMoving( c );
00885         setCurrentDesktop( d );
00886         setClientIsMoving( NULL );
00887         }
00888     }
00889 
00890 void Workspace::slotWindowToDesktopLeft()
00891     {
00892     int d = desktopToLeft( currentDesktop());
00893     if( d == currentDesktop())
00894         return;
00895     Client* c = active_popup_client ? active_popup_client : active_client;
00896     if (c && !c->isDesktop()
00897         && !c->isDock() && !c->isTopMenu())
00898         {
00899         setClientIsMoving( c );
00900         setCurrentDesktop( d );
00901         setClientIsMoving( NULL );
00902         }
00903     }
00904 
00905 void Workspace::slotWindowToDesktopUp()
00906     {
00907     int d = desktopUp( currentDesktop());
00908     if( d == currentDesktop())
00909         return;
00910     Client* c = active_popup_client ? active_popup_client : active_client;
00911     if (c && !c->isDesktop()
00912         && !c->isDock() && !c->isTopMenu())
00913         {
00914         setClientIsMoving( c );
00915         setCurrentDesktop( d );
00916         setClientIsMoving( NULL );
00917         }
00918     }
00919 
00920 void Workspace::slotWindowToDesktopDown()
00921     {
00922     int d = desktopDown( currentDesktop());
00923     if( d == currentDesktop())
00924         return;
00925     Client* c = active_popup_client ? active_popup_client : active_client;
00926     if (c && !c->isDesktop()
00927         && !c->isDock() && !c->isTopMenu())
00928         {
00929         setClientIsMoving( c );
00930         setCurrentDesktop( d );
00931         setClientIsMoving( NULL );
00932         }
00933     }
00934 
00935 
00939 void Workspace::slotKillWindow()
00940     {
00941     KillWindow kill( this );
00942     kill.start();
00943     }
00944 
00950 void Workspace::slotSendToDesktop( int desk )
00951     {
00952     if ( !active_popup_client )
00953         return;
00954     if ( desk == 0 ) 
00955         { // the 'on_all_desktops' menu entry
00956         active_popup_client->setOnAllDesktops( !active_popup_client->isOnAllDesktops());
00957         return;
00958         }
00959 
00960     sendClientToDesktop( active_popup_client, desk, false );
00961 
00962     }
00963 
00967 void Workspace::slotWindowOperations()
00968     {
00969     if ( !active_client )
00970         return;
00971     QPoint pos = active_client->pos() + active_client->clientPos();
00972     showWindowMenu( pos.x(), pos.y(), active_client );
00973     }
00974 
00975 void Workspace::showWindowMenu( const QRect &pos, Client* cl )
00976     {
00977     if (!kapp->authorizeKAction("kwin_rmb"))
00978         return;
00979     if( !cl )
00980         return;
00981     if( active_popup_client != NULL ) // recursion
00982         return;
00983     if ( cl->isDesktop()
00984         || cl->isDock()
00985         || cl->isTopMenu())
00986         return;
00987 
00988     active_popup_client = cl;
00989     QPopupMenu* p = clientPopup();
00990     active_popup = p;
00991     int x = pos.left();
00992     int y = pos.bottom();
00993     if (y == pos.top())
00994     p->exec( QPoint( x, y ) );
00995     else
00996         {
00997     QRect area = clientArea(ScreenArea, QPoint(x, y), currentDesktop());
00998         clientPopupAboutToShow(); // needed for sizeHint() to be correct :-/
00999     int popupHeight = p->sizeHint().height();
01000     if (y + popupHeight < area.height())
01001         p->exec( QPoint( x, y ) );
01002     else
01003         p->exec( QPoint( x, pos.top() - popupHeight ) );
01004         }
01005     // active popup may be already changed (e.g. the window shortcut dialog)
01006     if( active_popup == p )
01007         closeActivePopup();
01008     }
01009 
01013 void Workspace::slotWindowClose()
01014     {
01015     if ( tab_box->isVisible())
01016         return;
01017     Client* c = active_popup_client ? active_popup_client : active_client;
01018     performWindowOperation( c, Options::CloseOp );
01019     }
01020 
01024 void Workspace::slotWindowMove()
01025     {
01026     Client* c = active_popup_client ? active_popup_client : active_client;
01027     performWindowOperation( c, Options::UnrestrictedMoveOp );
01028     }
01029 
01033 void Workspace::slotWindowResize()
01034     {
01035     Client* c = active_popup_client ? active_popup_client : active_client;
01036     performWindowOperation( c, Options::UnrestrictedResizeOp );
01037     }
01038 
01039 void Client::setShortcut( const QString& _cut )
01040     {
01041     QString cut = rules()->checkShortcut( _cut );
01042     if( cut.isEmpty())
01043         return setShortcutInternal( KShortcut());
01044 // Format:
01045 // base+(abcdef)<space>base+(abcdef)
01046 // E.g. Alt+Ctrl+(ABCDEF) Win+X,Win+(ABCDEF)
01047     if( !cut.contains( '(' ) && !cut.contains( ')' ) && !cut.contains( ' ' ))
01048         {
01049         if( workspace()->shortcutAvailable( KShortcut( cut ), this ))
01050             setShortcutInternal( KShortcut( cut ));
01051         else
01052             setShortcutInternal( KShortcut());
01053         return;
01054         }
01055     QValueList< KShortcut > keys;
01056     QStringList groups = QStringList::split( ' ', cut );
01057     for( QStringList::ConstIterator it = groups.begin();
01058          it != groups.end();
01059          ++it )
01060         {
01061         QRegExp reg( "(.*\\+)\\((.*)\\)" );
01062         if( reg.search( *it ) > -1 )
01063             {
01064             QString base = reg.cap( 1 );
01065             QString list = reg.cap( 2 );
01066             for( unsigned int i = 0;
01067                  i < list.length();
01068                  ++i )
01069                 {
01070                 KShortcut c( base + list[ i ] );
01071                 if( !c.isNull())
01072                     keys.append( c );
01073                 }
01074             }
01075         }
01076     for( QValueList< KShortcut >::ConstIterator it = keys.begin();
01077          it != keys.end();
01078          ++it )
01079         {
01080         if( _shortcut == *it ) // current one is in the list
01081             return;
01082         }
01083     for( QValueList< KShortcut >::ConstIterator it = keys.begin();
01084          it != keys.end();
01085          ++it )
01086         {
01087         if( workspace()->shortcutAvailable( *it, this ))
01088             {
01089             setShortcutInternal( *it );
01090             return;
01091             }
01092         }
01093     setShortcutInternal( KShortcut());
01094     }
01095 
01096 void Client::setShortcutInternal( const KShortcut& cut )
01097     {
01098     if( _shortcut == cut )
01099         return;
01100     _shortcut = cut;
01101     updateCaption();
01102     workspace()->clientShortcutUpdated( this );
01103     }
01104 
01105 bool Workspace::shortcutAvailable( const KShortcut& cut, Client* ignore ) const
01106     {
01107     // TODO check global shortcuts etc.
01108     for( ClientList::ConstIterator it = clients.begin();
01109          it != clients.end();
01110          ++it )
01111         {
01112         if( (*it) != ignore && (*it)->shortcut() == cut )
01113             return false;    
01114         }
01115     return true;
01116     }
01117 
01118 } // namespace
KDE Home | KDE Accessibility Home | Description of Access Keys