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