diff --git a/useractions.cpp b/useractions.cpp index 5c665ae5e2..6a44a32d5b 100644 --- a/useractions.cpp +++ b/useractions.cpp @@ -19,12 +19,11 @@ License. See the file "COPYING" for the exact licensing terms. #include "client.h" #include "workspace.h" -#include "effects.h" #include #include #include - +#include #include #include #include @@ -61,7 +60,7 @@ QMenu* Workspace::clientPopup() advanced_popup->setFont(KGlobalSettings::menuFont()); mKeepAboveOpAction = advanced_popup->addAction( i18n("Keep &Above Others") ); - mKeepAboveOpAction->setIcon( KIcon( "up" ) ); + mKeepAboveOpAction->setIcon( KIcon( "go-up" ) ); KAction *kaction = qobject_cast( keys->action("Window Above Other Windows") ); if ( kaction!=0 ) mKeepAboveOpAction->setShortcut( kaction->globalShortcut().primary() ); @@ -69,7 +68,7 @@ QMenu* Workspace::clientPopup() mKeepAboveOpAction->setData( Options::KeepAboveOp ); mKeepBelowOpAction = advanced_popup->addAction( i18n("Keep &Below Others") ); - mKeepBelowOpAction->setIcon( KIcon( "down" ) ); + mKeepBelowOpAction->setIcon( KIcon( "go-down" ) ); kaction = qobject_cast( keys->action("Window Below Other Windows") ); if ( kaction!=0 ) mKeepBelowOpAction->setShortcut( kaction->globalShortcut().primary() ); @@ -77,7 +76,7 @@ QMenu* Workspace::clientPopup() mKeepBelowOpAction->setData( Options::KeepBelowOp ); mFullScreenOpAction = advanced_popup->addAction( i18n("&Fullscreen") ); - mFullScreenOpAction->setIcon( KIcon( "window_fullscreen" ) ); + mFullScreenOpAction->setIcon( KIcon( "view-fullscreen" ) ); kaction = qobject_cast( keys->action("Window Fullscreen") ); if ( kaction!=0 ) mFullScreenOpAction->setShortcut( kaction->globalShortcut().primary() ); @@ -109,21 +108,23 @@ QMenu* Workspace::clientPopup() action = popup->addMenu( advanced_popup ); action->setText( i18n("Ad&vanced") ); - desk_popup_index = popup->actions().count(); - if (options->useTranslucency){ - trans_popup = new QMenu( popup ); - trans_popup->setFont(KGlobalSettings::menuFont()); - connect( trans_popup, SIGNAL( triggered(QAction*) ), this, SLOT( setPopupClientOpacity(QAction*))); - const int levels[] = { 100, 90, 75, 50, 25, 10 }; - for( unsigned int i = 0; - i < sizeof( levels ) / sizeof( levels[ 0 ] ); - ++i ) - { - action = trans_popup->addAction( QString::number( levels[ i ] ) + "%" ); - action->setCheckable( true ); - action->setData( levels[ i ] ); - } + QMenu *trans_popup = new QMenu( popup ); + QVBoxLayout *transLayout = new QVBoxLayout(trans_popup); + trans_popup->setLayout( transLayout ); + transButton = new QPushButton(trans_popup); + transButton->setObjectName("transButton"); + transButton->setToolTip( i18n("Reset opacity to default value")); + transSlider = new QSlider(trans_popup); + transSlider->setObjectName( "transSlider" ); + transSlider->setRange( 0, 100 ); + transSlider->setValue( 100 ); + transSlider->setOrientation( Qt::Vertical ); + transSlider->setToolTip( i18n("Slide this to set the window's opacity")); + connect(transButton, SIGNAL(clicked()), SLOT(resetClientOpacity())); + connect(transButton, SIGNAL(clicked()), trans_popup, SLOT(hide())); + connect(transSlider, SIGNAL(valueChanged(int)), SLOT(setTransButtonText(int))); + connect(transSlider, SIGNAL(valueChanged(int)), this, SLOT(setPopupClientOpacity(int))); action = popup->addMenu( trans_popup ); action->setText( i18n("&Opacity") ); } @@ -173,7 +174,7 @@ QMenu* Workspace::clientPopup() } mCloseOpAction = popup->addAction( i18n("&Close") ); - mCloseOpAction->setIcon( KIcon( "fileclose" ) ); + mCloseOpAction->setIcon( KIcon( "window-close" ) ); kaction = qobject_cast( keys->action("Window Close") ); if ( kaction!=0 ) mCloseOpAction->setShortcut( kaction->globalShortcut().primary() ); @@ -182,14 +183,31 @@ QMenu* Workspace::clientPopup() return popup; } -void Workspace::setPopupClientOpacity( QAction* action ) +//sets the transparency of the client to given value(given by slider) +void Workspace::setPopupClientOpacity(int value) { - if( active_popup_client == NULL ) - return; - int level = action->data().toInt(); - active_popup_client->setOpacity( level / 100.0 ); + // TODO } +void Workspace::setTransButtonText(int value) + { + value = 100 - value; + if(value < 0) + transButton->setText("000 %"); + else if (value >= 100 ) + transButton->setText("100 %"); + else if(value < 10) + transButton->setText("00"+QString::number(value)+" %"); + else if(value < 100) + transButton->setText('0'+QString::number(value)+" %"); + } + +void Workspace::resetClientOpacity() + { + // TODO + } + + /*! The client popup menu will become visible soon. @@ -224,16 +242,6 @@ void Workspace::clientPopupAboutToShow() mNoBorderOpAction->setChecked( active_popup_client->noBorder() ); mMinimizeOpAction->setEnabled( active_popup_client->isMinimizable() ); mCloseOpAction->setEnabled( active_popup_client->isCloseable() ); - if (options->useTranslucency) - { - foreach( QAction* action, trans_popup->actions()) - { - if( action->data().toInt() == qRound( active_popup_client->opacity() * 100 )) - action->setChecked( true ); - else - action->setChecked( false ); - } - } } @@ -249,9 +257,9 @@ void Workspace::initDesktopPopup() connect( desk_popup, SIGNAL( aboutToShow() ), this, SLOT( desktopPopupAboutToShow() ) ); - QAction *action = popup->addMenu( desk_popup ); + QAction *action = desk_popup->menuAction(); + popup->insertAction(mMoveOpAction, action); action->setText( i18n("To &Desktop") ); - action->setData( desk_popup_index ); } /*! @@ -438,7 +446,7 @@ void Workspace::clientPopupActivated( QAction *action ) } -void Workspace::performWindowOperation( Client* c, Options::WindowOperation op ) +void Workspace::performWindowOperation( Client* c, Options::WindowOperation op ) { if ( !c ) return; @@ -447,19 +455,19 @@ void Workspace::performWindowOperation( Client* c, Options::WindowOperation op ) QCursor::setPos( c->geometry().center() ); if (op == Options::ResizeOp || op == Options::UnrestrictedResizeOp ) QCursor::setPos( c->geometry().bottomRight()); - switch ( op ) + switch ( op ) { case Options::MoveOp: - c->performMouseCommand( Options::MouseMove, cursorPos() ); + c->performMouseCommand( Options::MouseMove, QCursor::pos() ); break; case Options::UnrestrictedMoveOp: - c->performMouseCommand( Options::MouseUnrestrictedMove, cursorPos() ); + c->performMouseCommand( Options::MouseUnrestrictedMove, QCursor::pos() ); break; case Options::ResizeOp: - c->performMouseCommand( Options::MouseResize, cursorPos() ); + c->performMouseCommand( Options::MouseResize, QCursor::pos() ); break; case Options::UnrestrictedResizeOp: - c->performMouseCommand( Options::MouseUnrestrictedResize, cursorPos() ); + c->performMouseCommand( Options::MouseUnrestrictedResize, QCursor::pos() ); break; case Options::CloseOp: c->closeWindow(); @@ -481,7 +489,7 @@ void Workspace::performWindowOperation( Client* c, Options::WindowOperation op ) c->minimize(); break; case Options::ShadeOp: - c->performMouseCommand( Options::MouseShade, cursorPos()); + c->performMouseCommand( Options::MouseShade, QCursor::pos()); break; case Options::OnAllDesktopsOp: c->setOnAllDesktops( !c->isOnAllDesktops() ); @@ -511,7 +519,7 @@ void Workspace::performWindowOperation( Client* c, Options::WindowOperation op ) break; } case Options::OperationsOp: - c->performMouseCommand( Options::MouseShade, cursorPos()); + c->performMouseCommand( Options::MouseShade, QCursor::pos()); break; case Options::WindowRulesOp: editWindowRules( c, false ); @@ -536,7 +544,7 @@ void Workspace::performWindowOperation( Client* c, Options::WindowOperation op ) bool Client::performMouseCommand( Options::MouseCommand command, QPoint globalPos, bool handled ) { bool replay = false; - switch (command) + switch (command) { case Options::MouseRaise: workspace()->raiseClient( this ); @@ -676,10 +684,10 @@ bool Client::performMouseCommand( Options::MouseCommand command, QPoint globalPo workspace()->windowToNextDesktop( this ); break; case Options::MouseOpacityMore: - setOpacity( qMin( opacity() + 0.1, 1.0 )); + // TODO break; case Options::MouseOpacityLess: - setOpacity( qMax( opacity() - 0.1, 0.0 )); + // TODO break; case Options::MouseNothing: replay = true; @@ -694,24 +702,6 @@ void Workspace::showWindowMenuAt( unsigned long, int, int ) slotWindowOperations(); } -void Workspace::loadEffect( const QString& name ) - { - if( effects ) - static_cast(effects)->loadEffect( name ); - } - -void Workspace::toggleEffect( const QString& name ) - { - if( effects ) - static_cast(effects)->toggleEffect( name ); - } - -void Workspace::unloadEffect( const QString& name ) - { - if( effects ) - static_cast(effects)->unloadEffect( name ); - } - void Workspace::slotActivateAttentionWindow() { if( attention_chain.count() > 0 ) @@ -721,13 +711,13 @@ void Workspace::slotActivateAttentionWindow() void Workspace::slotSwitchDesktopNext() { int d = currentDesktop() + 1; - if ( d > numberOfDesktops() ) + if ( d > numberOfDesktops() ) { - if ( options->rollOverDesktops ) + if ( options->rollOverDesktops ) { d = 1; } - else + else { return; } @@ -738,7 +728,7 @@ void Workspace::slotSwitchDesktopNext() void Workspace::slotSwitchDesktopPrevious() { int d = currentDesktop() - 1; - if ( d <= 0 ) + if ( d <= 0 ) { if ( options->rollOverDesktops ) d = numberOfDesktops(); @@ -923,7 +913,7 @@ void Workspace::slotWindowToNextDesktop() { windowToNextDesktop( active_popup_client ? active_popup_client : active_client ); } - + void Workspace::windowToNextDesktop( Client* c ) { int d = currentDesktop() + 1; @@ -945,7 +935,7 @@ void Workspace::slotWindowToPreviousDesktop() { windowToPreviousDesktop( active_popup_client ? active_popup_client : active_client ); } - + void Workspace::windowToPreviousDesktop( Client* c ) { int d = currentDesktop() - 1; @@ -1040,7 +1030,7 @@ void Workspace::slotSendToDesktop( QAction *action ) int desk = action->data().toInt(); if ( !active_popup_client ) return; - if ( desk == 0 ) + if ( desk == 0 ) { // the 'on_all_desktops' menu entry active_popup_client->setOnAllDesktops( !active_popup_client->isOnAllDesktops()); return; @@ -1199,7 +1189,7 @@ bool Workspace::shortcutAvailable( const KShortcut& cut, Client* ignore ) const ++it ) { if( (*it) != ignore && (*it)->shortcut() == cut ) - return false; + return false; } return true; } diff --git a/workspace.cpp b/workspace.cpp index a60d660180..9a61e07e3f 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -43,10 +43,6 @@ License. See the file "COPYING" for the exact licensing terms. #include "group.h" #include "rules.h" #include "kwinadaptor.h" -#include "unmanaged.h" -#include "scene.h" -#include "deleted.h" -#include "effects.h" #include #include @@ -80,6 +76,7 @@ Workspace::Workspace( bool restore ) active_popup_client( NULL ), desktop_widget (0), temporaryRulesMessages( "_KDE_NET_WM_TEMPORARY_RULES", NULL, false ), + rules_updates_disabled( false ), active_client (0), last_active_client (0), most_recently_raised (0), @@ -98,9 +95,7 @@ Workspace::Workspace( bool restore ) popupinfo (0), popup (0), advanced_popup (0), - trans_popup (0), desk_popup (0), - desk_popup_index (0), keys (0), client_keys ( NULL ), // client_keys_dialog ( NULL ), @@ -110,7 +105,12 @@ Workspace::Workspace( bool restore ) global_shortcuts_disabled_for_client( false ), root (0), workspaceInit (true), - startup(0), + startup(0), electric_have_borders(false), + electric_current_border(0), + electric_top_border(None), + electric_bottom_border(None), + electric_left_border(None), + electric_right_border(None), layoutOrientation(Qt::Vertical), layoutX(-1), layoutY(2), @@ -123,16 +123,12 @@ Workspace::Workspace( bool restore ) topmenu_space( NULL ), set_active_client_recursion( 0 ), block_stacking_updates( 0 ), - forced_global_mouse_grab( false ), - cm_selection( NULL ), - compositeRate( 0 ), - overlay( None ), - transSlider( NULL ), - transButton( NULL ) + forced_global_mouse_grab( false ) { (void) new KWinAdaptor( this ); - QDBusConnection::sessionBus().registerObject("/KWin", this); - + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.registerObject("/KWin", this); + dbus.connect(QString(), "/KWin", "org.kde.KWin", "reloadConfig", this, SLOT(slotReloadConfig())); _self = this; mgr = new PluginMgr; root = rootWindow(); @@ -140,14 +136,6 @@ Workspace::Workspace( bool restore ) default_colormap = DefaultColormap(display(), info.screen() ); installed_colormap = default_colormap; - for( int i = 0; - i < ELECTRIC_COUNT; - ++i ) - { - electric_reserved[ i ] = 0; - electric_windows[ i ] = None; - } - connect( &temporaryRulesMessages, SIGNAL( gotMessage( const QString& )), this, SLOT( gotTemporaryRulesMessage( const QString& ))); connect( &rulesUpdatedTimer, SIGNAL( timeout()), this, SLOT( writeWindowRules())); @@ -156,6 +144,9 @@ Workspace::Workspace( bool restore ) delayFocusTimer = 0; + electric_time_first = xTime(); + electric_time_last = xTime(); + if ( restore ) loadSessionInfo(); @@ -178,12 +169,10 @@ Workspace::Workspace( bool restore ) ColormapChangeMask | SubstructureRedirectMask | SubstructureNotifyMask | - FocusChangeMask | // for NotifyDetailNone - ExposureMask + FocusChangeMask // for NotifyDetailNone ); - Extensions::init(); - setupCompositing(); + Shape::init(); // compatibility long data = 1; @@ -211,9 +200,7 @@ Workspace::Workspace( bool restore ) void Workspace::init() { - if( options->electricBorders() == Options::ElectricAlways ) - reserveElectricBorderSwitching( true ); - updateElectricBorders(); + checkElectricBorders(); // not used yet // topDock = 0L; @@ -291,6 +278,7 @@ void Workspace::init() NET::WM2ExtendedStrut | NET::WM2KDETemporaryRules | NET::WM2ShowingDesktop | + NET::WM2DesktopLayout | 0 , NET::ActionMove | @@ -334,7 +322,6 @@ void Workspace::init() connect(&reconfigureTimer, SIGNAL(timeout()), this, SLOT(slotReconfigure())); connect( &updateToolWindowsTimer, SIGNAL( timeout()), this, SLOT( slotUpdateToolWindows())); - connect( &compositeTimer, SIGNAL( timeout()), SLOT( performCompositing())); connect(KGlobalSettings::self(), SIGNAL(appearanceChanged()), this, SLOT(slotReconfigure())); @@ -372,10 +359,7 @@ void Workspace::init() XWindowAttributes attr; XGetWindowAttributes(display(), wins[i], &attr); if (attr.override_redirect ) - { - createUnmanaged( wins[ i ] ); continue; - } if( topmenu_space && topmenu_space->winId() == wins[ i ] ) continue; if (attr.map_state != IsUnmapped) @@ -397,6 +381,7 @@ void Workspace::init() updateStackingOrder( true ); updateClientArea(); + raiseElectricBorders(); // NETWM spec says we have to set it to (0,0) if we don't support it NETPoint* viewports = new NETPoint[ number_of_desktops ]; @@ -436,7 +421,6 @@ void Workspace::init() Workspace::~Workspace() { - finishCompositing(); blockStackingUpdates( true ); // TODO grabXServer(); // use stacking_order, so that kwin --replace keeps stacking order @@ -446,12 +430,12 @@ Workspace::~Workspace() { // only release the window (*it)->releaseWindow( true ); - // no removeClient() is called ! + // No removeClient() is called, it does more than just removing. + // However, remove from some lists to e.g. prevent performTransiencyCheck() + // from crashing. + clients.remove( *it ); + desktops.remove( *it ); } - for( UnmanagedList::ConstIterator it = unmanaged.begin(); - it != unmanaged.end(); - ++it ) - (*it)->release(); delete desktop_widget; delete tab_box; delete popupinfo; @@ -495,28 +479,6 @@ Client* Workspace::createClient( Window w, bool is_mapped ) return NULL; } addClient( c, Allowed ); - if( scene ) - scene->windowAdded( c ); - if( effects ) - static_cast(effects)->windowAdded( c->effectWindow()); - return c; - } - -Unmanaged* Workspace::createUnmanaged( Window w ) - { - if( w == overlay ) - return NULL; - Unmanaged* c = new Unmanaged( this ); - if( !c->track( w )) - { - Unmanaged::deleteUnmanaged( c, Allowed ); - return NULL; - } - addUnmanaged( c, Allowed ); - if( scene ) - scene->windowAdded( c ); - if( effects ) - static_cast(effects)->windowAdded( c->effectWindow()); return c; } @@ -557,13 +519,7 @@ void Workspace::addClient( Client* c, allowed_t ) updateStackingOrder( true ); // propagate new client if( c->isUtility() || c->isMenu() || c->isToolbar()) updateToolWindows( true ); - if( tab_grab ) - tab_box->reset( true ); - } - -void Workspace::addUnmanaged( Unmanaged* c, allowed_t ) - { - unmanaged.append( c ); + checkNonExistentClients(); } /* @@ -584,12 +540,6 @@ void Workspace::removeClient( Client* c, allowed_t ) if( c->isNormalWindow()) Notify::raise( Notify::Delete ); - if( tab_grab ) - { - if( tab_box->currentClient() == c ) - tab_box->nextPrev( true ); - } - Q_ASSERT( clients.contains( c ) || desktops.contains( c )); clients.removeAll( c ); desktops.removeAll( c ); @@ -620,34 +570,12 @@ void Workspace::removeClient( Client* c, allowed_t ) updateStackingOrder( true ); - if( tab_grab ) - tab_box->reset( true ); + if (tab_grab) + tab_box->repaint(); updateClientArea(); } -void Workspace::removeUnmanaged( Unmanaged* c, allowed_t ) - { - assert( unmanaged.contains( c )); - unmanaged.removeAll( c ); - } - -void Workspace::addDeleted( Deleted* c, allowed_t ) - { - assert( !deleted.contains( c )); - deleted.append( c ); - } - -void Workspace::removeDeleted( Deleted* c, allowed_t ) - { - assert( deleted.contains( c )); - if( scene ) - scene->windowDeleted( c ); - if( effects ) - static_cast(effects)->windowDeleted( c->effectWindow()); - deleted.removeAll( c ); - } - void Workspace::updateFocusChains( Client* c, FocusChainChange change ) { if( !c->wantsTabFocus()) // doesn't want tab focus, remove @@ -673,7 +601,13 @@ void Workspace::updateFocusChains( Client* c, FocusChainChange change ) focus_chain[ i ].prepend( c ); } else if( !focus_chain[ i ].contains( c )) - focus_chain[ i ].prepend( c ); // otherwise add as the last one + { // add it after the active one + if( active_client != NULL && active_client != c + && !focus_chain[ i ].isEmpty() && focus_chain[ i ].last() == active_client ) + focus_chain[ i ].insert( focus_chain[ i ].size() - 1, c ); + else + focus_chain[ i ].append( c ); // otherwise add as the first one + } } } else //now only on desktop, remove it anywhere else @@ -693,7 +627,13 @@ void Workspace::updateFocusChains( Client* c, FocusChainChange change ) focus_chain[ i ].prepend( c ); } else if( !focus_chain[ i ].contains( c )) - focus_chain[ i ].prepend( c ); + { // add it after the active one + if( active_client != NULL && active_client != c + && !focus_chain[ i ].isEmpty() && focus_chain[ i ].last() == active_client ) + focus_chain[ i ].insert( focus_chain[ i ].size() - 1, c ); + else + focus_chain[ i ].append( c ); // otherwise add as the first one + } } else focus_chain[ i ].removeAll( c ); @@ -710,7 +650,13 @@ void Workspace::updateFocusChains( Client* c, FocusChainChange change ) global_focus_chain.prepend( c ); } else if( !global_focus_chain.contains( c )) - global_focus_chain.prepend( c ); + { // add it after the active one + if( active_client != NULL && active_client != c + && !global_focus_chain.isEmpty() && global_focus_chain.last() == active_client ) + global_focus_chain.insert( global_focus_chain.size() - 1, c ); + else + global_focus_chain.append( c ); // otherwise add as the first one + } } void Workspace::updateCurrentTopMenu() @@ -928,6 +874,13 @@ void Workspace::updateColormap() } } +void Workspace::slotReloadConfig() +{ + kDebug()<<"void Workspace::slotReloadConfig()\n"; + + reconfigure(); +} + void Workspace::reconfigure() { reconfigureTimer.start( 200 ); @@ -944,16 +897,13 @@ void Workspace::slotSettingsChanged(int category) /*! Reread settings */ -KWIN_PROCEDURE( CheckBorderSizesProcedure, Client, cl->checkBorderSizes() ); +KWIN_PROCEDURE( CheckBorderSizesProcedure, cl->checkBorderSizes() ); void Workspace::slotReconfigure() { kDebug(1212) << "Workspace::slotReconfigure()" << endl; reconfigureTimer.stop(); - if( options->electricBorders() == Options::ElectricAlways ) - reserveElectricBorderSwitching( false ); - KGlobal::config()->reparseConfiguration(); unsigned long changed = options->updateSettings(); tab_box->reconfigure(); @@ -984,9 +934,7 @@ void Workspace::slotReconfigure() forEachClient( CheckBorderSizesProcedure()); } - if( options->electricBorders() == Options::ElectricAlways ) - reserveElectricBorderSwitching( true ); - updateElectricBorders(); + checkElectricBorders(); if( options->topMenuEnabled() && !managingTopMenus()) { @@ -1006,11 +954,6 @@ void Workspace::slotReconfigure() updateTopMenuGeometry(); updateCurrentTopMenu(); } - - if( options->useTranslucency ) - setupCompositing(); - else - finishCompositing(); loadWindowRules(); for( ClientList::Iterator it = clients.begin(); @@ -1162,8 +1105,6 @@ unsigned int ObscuringWindows::max_cache_size = 0; void ObscuringWindows::create( Client* c ) { - if( compositing()) // not needed with compositing - return; if( cached == 0 ) cached = new QList; Window obs_win; @@ -1295,15 +1236,16 @@ bool Workspace::setCurrentDesktop( int new_desktop ) // and active_client is on_all_desktops and under mouse (hence == old_active_client), // conserve focus (thanks to Volker Schatz ) else if( active_client && active_client->isShown( true ) && active_client->isOnCurrentDesktop()) - c= active_client; + c = active_client; + + if( c == NULL && !desktops.isEmpty()) + c = findDesktop( true, currentDesktop()); if( c != active_client ) setActiveClient( NULL, Allowed ); if ( c ) requestFocus( c ); - else if( !desktops.isEmpty() ) - requestFocus( findDesktop( true, currentDesktop())); else focusToNull(); @@ -1325,12 +1267,6 @@ bool Workspace::setCurrentDesktop( int new_desktop ) if( old_desktop != 0 ) // not for the very first time popupinfo->showInfo( desktopName(currentDesktop()) ); - - if( effects != NULL && old_desktop != 0 && old_desktop != new_desktop ) - static_cast(effects)->desktopChanged( old_desktop ); - if( compositing()) - addRepaintFull(); - return true; } @@ -1351,10 +1287,9 @@ void Workspace::previousDesktop() int Workspace::desktopToRight( int desktop ) const { int x,y; - Qt::Orientation orientation; - calcDesktopLayout( &x, &y, &orientation ); + calcDesktopLayout(x,y); int dt = desktop-1; - if (orientation == Qt::Vertical) + if (layoutOrientation == Qt::Vertical) { dt += y; if ( dt >= numberOfDesktops() ) @@ -1383,10 +1318,9 @@ int Workspace::desktopToRight( int desktop ) const int Workspace::desktopToLeft( int desktop ) const { int x,y; - Qt::Orientation orientation; - calcDesktopLayout( &x, &y, &orientation ); + calcDesktopLayout(x,y); int dt = desktop-1; - if (orientation == Qt::Vertical) + if (layoutOrientation == Qt::Vertical) { dt -= y; if ( dt < 0 ) @@ -1415,10 +1349,9 @@ int Workspace::desktopToLeft( int desktop ) const int Workspace::desktopUp( int desktop ) const { int x,y; - Qt::Orientation orientation; - calcDesktopLayout( &x, &y, &orientation); + calcDesktopLayout(x,y); int dt = desktop-1; - if (orientation == Qt::Horizontal) + if (layoutOrientation == Qt::Horizontal) { dt -= x; if ( dt < 0 ) @@ -1447,10 +1380,9 @@ int Workspace::desktopUp( int desktop ) const int Workspace::desktopDown( int desktop ) const { int x,y; - Qt::Orientation orientation; - calcDesktopLayout( &x, &y, &orientation); + calcDesktopLayout(x,y); int dt = desktop-1; - if (orientation == Qt::Horizontal) + if (layoutOrientation == Qt::Horizontal) { dt += x; if ( dt >= numberOfDesktops() ) @@ -1567,29 +1499,27 @@ void Workspace::sendClientToDesktop( Client* c, int desk, bool dont_activate ) updateClientArea(); } -void Workspace::setDesktopLayout(int o, int x, int y) +void Workspace::setDesktopLayout(NET::Orientation o, int x, int y,NET::DesktopLayoutCorner c) { - layoutOrientation = (Qt::Orientation) o; + Q_UNUSED( c ); // I don't find this worth bothering, feel free to + layoutOrientation = ( o == NET::OrientationHorizontal ? Qt::Horizontal : Qt::Vertical ); layoutX = x; layoutY = y; } -void Workspace::calcDesktopLayout(int* xp, int* yp, Qt::Orientation* orientation) const +void Workspace::calcDesktopLayout(int &x, int &y) const { - int x = layoutX; - int y = layoutY; - if ((x == -1) && (y > 0)) + x = layoutX; // <= 0 means compute it from the other and total number of desktops + y = layoutY; + if((x <= 0) && (y > 0)) x = (numberOfDesktops()+y-1) / y; - else if ((y == -1) && (x > 0)) + else if((y <=0) && (x > 0)) y = (numberOfDesktops()+x-1) / x; - if (x == -1) + if(x <=0) x = 1; - if (y == -1) + if (y <= 0) y = 1; - *xp = x; - *yp = y; - *orientation = layoutOrientation; } /*! @@ -1720,7 +1650,7 @@ void Workspace::slotGrabWindow() QPixmap snapshot = QPixmap::grabWindow( active_client->frameId() ); //No XShape - no work. - if( Extensions::shapeAvailable()) + if( Shape::available()) { //As the first step, get the mask from XShape. int count, order; @@ -1780,14 +1710,18 @@ void Workspace::slotGrabDesktop() */ void Workspace::slotMouseEmulation() { + if ( mouse_emulation ) { - ungrabXKeyboard(); + XUngrabKeyboard(display(), xTime()); mouse_emulation = false; return; } - if( grabXKeyboard()) + if ( XGrabKeyboard(display(), + root, false, + GrabModeAsync, GrabModeAsync, + xTime()) == GrabSuccess ) { mouse_emulation = true; mouse_emulation_state = 0; @@ -1917,7 +1851,7 @@ bool Workspace::keyPressMouseEmulation( XKeyEvent& ev ) bool is_alt = km & Mod1Mask; bool is_shift = km & ShiftMask; int delta = is_control?1:is_alt?32:8; - QPoint pos = cursorPos(); + QPoint pos = QCursor::pos(); switch ( kc ) { @@ -1985,7 +1919,7 @@ bool Workspace::keyPressMouseEmulation( XKeyEvent& ev ) } // fall through case XK_Escape: - ungrabXKeyboard(); + XUngrabKeyboard(display(), xTime()); mouse_emulation = false; return true; default: @@ -2035,146 +1969,149 @@ void Workspace::cancelDelayFocus() // Electric Borders //========================================================================// // Electric Border Window management. Electric borders allow a user -// to change the virtual desktop or activate another features -// by moving the mouse pointer to the borders or corners. -// Technically this is done with input only windows. -void Workspace::updateElectricBorders() +// to change the virtual desktop by moving the mouse pointer to the +// borders. Technically this is done with input only windows. Since +// electric borders can be switched on and off, we have these two +// functions to create and destroy them. +void Workspace::checkElectricBorders( bool force ) { - electric_time_first = xTime(); - electric_time_last = xTime(); - electric_current_border = ElectricNone; + if( force ) + destroyBorderWindows(); + + electric_current_border = 0; + QRect r = QApplication::desktop()->geometry(); electricTop = r.top(); electricBottom = r.bottom(); electricLeft = r.left(); electricRight = r.right(); - for( int pos = 0; - pos < ELECTRIC_COUNT; - ++pos ) - { - if( electric_reserved[ pos ] == 0 ) - { - if( electric_windows[ pos ] != None ) - XDestroyWindow( display(), electric_windows[ pos ] ); - electric_windows[ pos ] = None; - continue; - } - if( electric_windows[ pos ] != None ) - continue; - XSetWindowAttributes attributes; - attributes.override_redirect = True; - attributes.event_mask = EnterWindowMask | LeaveWindowMask; - unsigned long valuemask = CWOverrideRedirect | CWEventMask; - int xywh[ ELECTRIC_COUNT ][ 4 ] = - { - { r.left() + 1, r.top(), r.width() - 2, 1 }, // top - { r.right(), r.top(), 1, 1 }, // topright - { r.right(), r.top() + 1, 1, r.height() - 2 }, // etc. - { r.right(), r.bottom(), 1, 1 }, - { r.left() + 1, r.bottom(), r.width() - 2, 1 }, - { r.left(), r.bottom(), 1, 1 }, - { r.left(), r.top() + 1, 1, r.height() - 2 }, - { r.left(), r.top(), 1, 1 } - }; - electric_windows[ pos ] = XCreateWindow( display(), rootWindow(), - xywh[ pos ][ 0 ], xywh[ pos ][ 1 ], xywh[ pos ][ 2 ], xywh[ pos ][ 3 ], - 0, CopyFromParent, InputOnly, CopyFromParent, valuemask, &attributes ); - XMapWindow( display(), electric_windows[ pos ]); - // Set XdndAware on the windows, so that DND enter events are received (#86998) - Atom version = 4; // XDND version - XChangeProperty( display(), electric_windows[ pos ], atoms->xdnd_aware, XA_ATOM, - 32, PropModeReplace, ( unsigned char* )&version, 1 ); - } - } - -void Workspace::destroyElectricBorders() - { - for( int pos = 0; - pos < ELECTRIC_COUNT; - ++pos ) - { - if( electric_windows[ pos ] != None ) - XDestroyWindow( display(), electric_windows[ pos ] ); - electric_windows[ pos ] = None; - } - } - -void Workspace::reserveElectricBorderSwitching( bool reserve ) - { - if( reserve ) - { - reserveElectricBorder( ElectricTop ); - reserveElectricBorder( ElectricBottom ); - reserveElectricBorder( ElectricLeft ); - reserveElectricBorder( ElectricRight ); - } + if (options->electricBorders() == Options::ElectricAlways) + createBorderWindows(); else - { - unreserveElectricBorder( ElectricTop ); - unreserveElectricBorder( ElectricBottom ); - unreserveElectricBorder( ElectricLeft ); - unreserveElectricBorder( ElectricRight ); - } + destroyBorderWindows(); } -void Workspace::reserveElectricBorder( ElectricBorder border ) +void Workspace::createBorderWindows() { - if( border == ElectricNone ) + if ( electric_have_borders ) return; - if( electric_reserved[ border ]++ == 0 ) - QTimer::singleShot( 0, this, SLOT( updateElectricBorders())); + + electric_have_borders = true; + + QRect r = QApplication::desktop()->geometry(); + XSetWindowAttributes attributes; + unsigned long valuemask; + attributes.override_redirect = True; + attributes.event_mask = ( EnterWindowMask | LeaveWindowMask ); + valuemask= (CWOverrideRedirect | CWEventMask | CWCursor ); + attributes.cursor = XCreateFontCursor(display(), + XC_sb_up_arrow); + electric_top_border = XCreateWindow (display(), rootWindow(), + 0,0, + r.width(),1, + 0, + CopyFromParent, InputOnly, + CopyFromParent, + valuemask, &attributes); + XMapWindow(display(), electric_top_border); + + attributes.cursor = XCreateFontCursor(display(), + XC_sb_down_arrow); + electric_bottom_border = XCreateWindow (display(), rootWindow(), + 0,r.height()-1, + r.width(),1, + 0, + CopyFromParent, InputOnly, + CopyFromParent, + valuemask, &attributes); + XMapWindow(display(), electric_bottom_border); + + attributes.cursor = XCreateFontCursor(display(), + XC_sb_left_arrow); + electric_left_border = XCreateWindow (display(), rootWindow(), + 0,0, + 1,r.height(), + 0, + CopyFromParent, InputOnly, + CopyFromParent, + valuemask, &attributes); + XMapWindow(display(), electric_left_border); + + attributes.cursor = XCreateFontCursor(display(), + XC_sb_right_arrow); + electric_right_border = XCreateWindow (display(), rootWindow(), + r.width()-1,0, + 1,r.height(), + 0, + CopyFromParent, InputOnly, + CopyFromParent, + valuemask, &attributes); + XMapWindow(display(), electric_right_border); + // Set XdndAware on the windows, so that DND enter events are received (#86998) + Atom version = 4; // XDND version + XChangeProperty( display(), electric_top_border, atoms->xdnd_aware, XA_ATOM, + 32, PropModeReplace, ( unsigned char* )&version, 1 ); + XChangeProperty( display(), electric_bottom_border, atoms->xdnd_aware, XA_ATOM, + 32, PropModeReplace, ( unsigned char* )&version, 1 ); + XChangeProperty( display(), electric_left_border, atoms->xdnd_aware, XA_ATOM, + 32, PropModeReplace, ( unsigned char* )&version, 1 ); + XChangeProperty( display(), electric_right_border, atoms->xdnd_aware, XA_ATOM, + 32, PropModeReplace, ( unsigned char* )&version, 1 ); } -void Workspace::unreserveElectricBorder( ElectricBorder border ) + +// Electric Border Window management. Electric borders allow a user +// to change the virtual desktop by moving the mouse pointer to the +// borders. Technically this is done with input only windows. Since +// electric borders can be switched on and off, we have these two +// functions to create and destroy them. +void Workspace::destroyBorderWindows() { - if( border == ElectricNone ) - return; - assert( electric_reserved[ border ] > 0 ); - if( --electric_reserved[ border ] == 0 ) - QTimer::singleShot( 0, this, SLOT( updateElectricBorders())); + if( !electric_have_borders) + return; + + electric_have_borders = false; + + if(electric_top_border) + XDestroyWindow(display(),electric_top_border); + if(electric_bottom_border) + XDestroyWindow(display(),electric_bottom_border); + if(electric_left_border) + XDestroyWindow(display(),electric_left_border); + if(electric_right_border) + XDestroyWindow(display(),electric_right_border); + + electric_top_border = None; + electric_bottom_border = None; + electric_left_border = None; + electric_right_border = None; } -void Workspace::checkElectricBorder(const QPoint &pos, Time now) +void Workspace::clientMoved(const QPoint &pos, Time now) { + if (options->electricBorders() == Options::ElectricDisabled) + return; + if ((pos.x() != electricLeft) && (pos.x() != electricRight) && (pos.y() != electricTop) && (pos.y() != electricBottom)) return; - bool have_borders = false; - for( int i = 0; - i < ELECTRIC_COUNT; - ++i ) - if( electric_windows[ i ] != None ) - have_borders = true; - if( !have_borders ) - return; - Time treshold_set = options->electricBorderDelay(); // set timeout Time treshold_reset = 250; // reset timeout int distance_reset = 30; // Mouse should not move more than this many pixels - ElectricBorder border; - if( pos.x() == electricLeft && pos.y() == electricTop ) - border = ElectricTopLeft; - else if( pos.x() == electricRight && pos.y() == electricTop ) - border = ElectricTopRight; - else if( pos.x() == electricLeft && pos.y() == electricBottom ) - border = ElectricBottomLeft; - else if( pos.x() == electricRight && pos.y() == electricBottom ) - border = ElectricBottomRight; - else if( pos.x() == electricLeft ) - border = ElectricLeft; - else if( pos.x() == electricRight ) - border = ElectricRight; - else if( pos.y() == electricTop ) - border = ElectricTop; - else if( pos.y() == electricBottom ) - border = ElectricBottom; - else - abort(); + int border = 0; + if (pos.x() == electricLeft) + border = 1; + else if (pos.x() == electricRight) + border = 2; + else if (pos.y() == electricTop) + border = 3; + else if (pos.y() == electricBottom) + border = 4; if ((electric_current_border == border) && (timestampDiff(electric_time_last, now) < treshold_reset) && @@ -2184,11 +2121,50 @@ void Workspace::checkElectricBorder(const QPoint &pos, Time now) if (timestampDiff(electric_time_first, now) > treshold_set) { - electric_current_border = ElectricNone; - if( effects && static_cast(effects)->borderActivated( border )) - {} // handled by effects - else - electricBorderSwitchDesktop( border, pos ); + electric_current_border = 0; + + QRect r = QApplication::desktop()->geometry(); + int offset; + + int desk_before = currentDesktop(); + switch(border) + { + case 1: + slotSwitchDesktopLeft(); + if (currentDesktop() != desk_before) + { + offset = r.width() / 5; + QCursor::setPos(r.width() - offset, pos.y()); + } + break; + + case 2: + slotSwitchDesktopRight(); + if (currentDesktop() != desk_before) + { + offset = r.width() / 5; + QCursor::setPos(offset, pos.y()); + } + break; + + case 3: + slotSwitchDesktopUp(); + if (currentDesktop() != desk_before) + { + offset = r.height() / 5; + QCursor::setPos(pos.x(), r.height() - offset); + } + break; + + case 4: + slotSwitchDesktopDown(); + if (currentDesktop() != desk_before) + { + offset = r.height() / 5; + QCursor::setPos(pos.x(), offset); + } + break; + } return; } } @@ -2200,91 +2176,67 @@ void Workspace::checkElectricBorder(const QPoint &pos, Time now) electric_push_point = pos; } - // reset the pointer to find out wether the user is really pushing - // (the direction back from which it came, starting from top clockwise) - static int xdiff[ ELECTRIC_COUNT ] = { 0, -1, -1, -1, 0, 1, 1, 1 }; - static int ydiff[ ELECTRIC_COUNT ] = { 1, 1, 0, -1, -1, -1, 0, 1 }; - QCursor::setPos( pos.x() + xdiff[ border ], pos.y() + ydiff[ border ] ); - } + int mouse_warp = 1; -void Workspace::electricBorderSwitchDesktop( ElectricBorder border, const QPoint& pos ) - { - QRect r = QApplication::desktop()->geometry(); - int offset; - - int desk_before = currentDesktop(); - switch(border) + // reset the pointer to find out wether the user is really pushing + switch( border) { - case ElectricLeft: - slotSwitchDesktopLeft(); - if (currentDesktop() != desk_before) - { - offset = r.width() / 5; - QCursor::setPos(r.width() - offset, pos.y()); - } - break; - case ElectricRight: - slotSwitchDesktopRight(); - if (currentDesktop() != desk_before) - { - offset = r.width() / 5; - QCursor::setPos(offset, pos.y()); - } - break; - case ElectricTop: - slotSwitchDesktopUp(); - if (currentDesktop() != desk_before) - { - offset = r.height() / 5; - QCursor::setPos(pos.x(), r.height() - offset); - } - break; - case ElectricBottom: - slotSwitchDesktopDown(); - if (currentDesktop() != desk_before) - { - offset = r.height() / 5; - QCursor::setPos(pos.x(), offset); - } - break; - default: - break; + case 1: QCursor::setPos(pos.x()+mouse_warp, pos.y()); break; + case 2: QCursor::setPos(pos.x()-mouse_warp, pos.y()); break; + case 3: QCursor::setPos(pos.x(), pos.y()+mouse_warp); break; + case 4: QCursor::setPos(pos.x(), pos.y()-mouse_warp); break; } } // this function is called when the user entered an electric border // with the mouse. It may switch to another virtual desktop -bool Workspace::electricBorderEvent(XEvent *e) +bool Workspace::electricBorder(XEvent *e) { + if( !electric_have_borders ) + return false; if( e->type == EnterNotify ) { - for( int i = 0; - i < ELECTRIC_COUNT; - ++i ) - if( electric_windows[ i ] != None && e->xcrossing.window == electric_windows[ i ] ) - { // the user entered an electric border - checkElectricBorder( QPoint( e->xcrossing.x_root, e->xcrossing.y_root ), e->xcrossing.time ); - return true; - } + if( e->xcrossing.window == electric_top_border || + e->xcrossing.window == electric_left_border || + e->xcrossing.window == electric_bottom_border || + e->xcrossing.window == electric_right_border) + // the user entered an electric border + { + clientMoved( QPoint( e->xcrossing.x_root, e->xcrossing.y_root ), e->xcrossing.time ); + return true; + } } if( e->type == ClientMessage ) { - if( e->xclient.message_type == atoms->xdnd_position ) + if( e->xclient.message_type == atoms->xdnd_position + && ( e->xclient.window == electric_top_border + || e->xclient.window == electric_bottom_border + || e->xclient.window == electric_left_border + || e->xclient.window == electric_right_border )) { - for( int i = 0; - i < ELECTRIC_COUNT; - ++i ) - if( electric_windows[ i ] != None && e->xclient.window == electric_windows[ i ] ) - { - updateXTime(); - checkElectricBorder( QPoint( e->xclient.data.l[2]>>16, e->xclient.data.l[2]&0xffff), xTime() ); - return true; - } + updateXTime(); + clientMoved( QPoint( e->xclient.data.l[2]>>16, e->xclient.data.l[2]&0xffff), xTime() ); + return true; } } return false; } +// electric borders (input only windows) have to be always on the +// top. For that reason kwm calls this function always after some +// windows have been raised. +void Workspace::raiseElectricBorders() + { + + if(electric_have_borders) + { + XRaiseWindow(display(), electric_top_border); + XRaiseWindow(display(), electric_left_border); + XRaiseWindow(display(), electric_bottom_border); + XRaiseWindow(display(), electric_right_border); + } + } + void Workspace::addTopMenu( Client* c ) { assert( c->isTopMenu()); @@ -2443,7 +2395,7 @@ void Workspace::helperDialog( const QString& message, const Client* c ) { KConfig cfg( "kwin_dialogsrc" ); KConfigGroup cg(&cfg, "Notification Messages" ); // this depends on KMessageBox - if( !cg.readEntry( type, QVariant(true )).toBool()) // has don't show again checked + if( !cg.readEntry( type, true )) // has don't show again checked return; // save launching kdialog proc << "--dontagain" << "kwin_dialogsrc:" + type; } @@ -2574,49 +2526,6 @@ void Workspace::slotBlockShortcuts( int data ) (*it)->updateMouseGrab(); } -// Optimized version of QCursor::pos() that tries to avoid X roundtrips -// by updating the value only when the X timestamp changes. -static QPoint last_cursor_pos; -static int last_buttons = 0; -static Time last_cursor_timestamp = CurrentTime; - -QPoint Workspace::cursorPos() - { - if( last_cursor_timestamp == CurrentTime - || last_cursor_timestamp != QX11Info::appTime()) - { - last_cursor_timestamp = QX11Info::appTime(); - Window root; - Window child; - int root_x, root_y, win_x, win_y; - uint state; - XQueryPointer( display(), rootWindow(), &root, &child, - &root_x, &root_y, &win_x, &win_y, &state ); - last_cursor_pos = QPoint( root_x, root_y ); - last_buttons = state; - QTimer::singleShot( 0, this, SLOT( resetCursorPosTime())); - } - return last_cursor_pos; - } - -// Because of QTimer's and the impossibility to get events for all mouse -// movements (at least I haven't figured out how) the position needs -// to be also refetched after each return to the event loop. -void Workspace::resetCursorPosTime() - { - last_cursor_timestamp = CurrentTime; - } - -void Workspace::checkCursorPos() - { - QPoint last = last_cursor_pos; - int lastb = last_buttons; - cursorPos(); // update if needed - if( last != last_cursor_pos || lastb != last_buttons ) - static_cast< EffectsHandlerImpl* >( effects )->mouseChanged( cursorPos(), last, - x11ToQtMouseButtons( last_buttons ), x11ToQtKeyboardModifiers( last_buttons )); - } - } // namespace #include "workspace.moc" diff --git a/workspace.h b/workspace.h index 5f5d3c46f3..e2351bf1dc 100644 --- a/workspace.h +++ b/workspace.h @@ -18,8 +18,6 @@ License. See the file "COPYING" for the exact licensing terms. #include #include #include -#include -#include #include "utils.h" #include "kdecoration.h" @@ -36,6 +34,7 @@ class KStartupInfoId; class KStartupInfoData; class QSlider; class QPushButton; +class K3Process; namespace KWin { @@ -78,9 +77,8 @@ class Workspace : public QObject, public KDecorationDefines virtual ~Workspace(); static Workspace * self() { return _self; } - + bool workspaceEvent( XEvent * ); - bool workspaceEvent( QEvent * ); KDecoration* createDecoration( KDecorationBridge* bridge ); @@ -89,9 +87,6 @@ class Workspace : public QObject, public KDecorationDefines template< typename T > Client* findClient( T predicate ); template< typename T1, typename T2 > void forEachClient( T1 procedure, T2 predicate ); template< typename T > void forEachClient( T procedure ); - template< typename T > Unmanaged* findUnmanaged( T predicate ); - template< typename T1, typename T2 > void forEachUnmanaged( T1 procedure, T2 predicate ); - template< typename T > void forEachUnmanaged( T procedure ); QRect clientArea( clientAreaOption, const QPoint& p, int desktop ) const; QRect clientArea( clientAreaOption, const Client* c ) const; @@ -155,10 +150,7 @@ class Workspace : public QObject, public KDecorationDefines void clientHidden( Client* ); void clientAttentionChanged( Client* c, bool set ); - void checkElectricBorder(const QPoint &pos, Time time); - void reserveElectricBorder( ElectricBorder border ); - void unreserveElectricBorder( ElectricBorder border ); - void reserveElectricBorderSwitching( bool reserve ); + void clientMoved(const QPoint &pos, Time time); /** * Returns the current virtual desktop of this workspace @@ -169,27 +161,16 @@ class Workspace : public QObject, public KDecorationDefines */ int numberOfDesktops() const; void setNumberOfDesktops( int n ); - void calcDesktopLayout(int* x, int* y, Qt::Orientation* orientation) const; QWidget* desktopWidget(); // for TabBox - Client* currentTabBoxClient() const; - ClientList currentTabBoxClientList() const; - int currentTabBoxDesktop() const; - QList< int > currentTabBoxDesktopList() const; - void setTabBoxClient(Client*); - void setTabBoxDesktop(int); - Client* nextClientFocusChain(Client*) const; - Client* previousClientFocusChain(Client*) const; - Client* nextClientStatic(Client*) const; - Client* previousClientStatic(Client*) const; + Client* nextFocusChainClient(Client*) const; + Client* previousFocusChainClient(Client*) const; + Client* nextStaticClient(Client*) const; + Client* previousStaticClient(Client*) const; int nextDesktopFocusChain( int iDesktop ) const; int previousDesktopFocusChain( int iDesktop ) const; - int nextDesktopStatic( int iDesktop ) const; - int previousDesktopStatic( int iDesktop ) const; - void refTabBox(); - void unrefTabBox(); void closeTabBox(); /** @@ -200,7 +181,7 @@ class Workspace : public QObject, public KDecorationDefines ClientList ensureStackingOrder( const ClientList& clients ) const; - Client* topClientOnDesktop( int desktop, bool unconstrained = false ) const; + Client* topClientOnDesktop( int desktop, bool unconstrained = false, bool only_normal = true ) const; Client* findDesktop( bool topmost, int desktop ) const; void sendClientToDesktop( Client* c, int desktop, bool dont_activate ); void windowToPreviousDesktop( Client* c ); @@ -209,11 +190,6 @@ class Workspace : public QObject, public KDecorationDefines // KDE4 remove me - and it's also in the DCOP interface :( void showWindowMenuAt( unsigned long id, int x, int y ); - void loadEffect( const QString& name ); - void toggleEffect( const QString& name ); - - void unloadEffect( const QString& name ); - /** * Shows the menu operations menu for the client and makes it active if * it's not already. @@ -237,6 +213,8 @@ class Workspace : public QObject, public KDecorationDefines WindowRules findWindowRules( const Client*, bool ); void rulesUpdated(); void discardUsedWindowRules( Client* c, bool withdraw ); + void disableRulesUpdates( bool disable ); + bool rulesUpdatesDisabled() const; // dcop interface void cascadeDesktop(); @@ -248,7 +226,7 @@ class Workspace : public QObject, public KDecorationDefines void circulateDesktopApplications(); QString desktopName( int desk ) const; - void setDesktopLayout(int o, int x, int y); + void setDesktopLayout(NET::Orientation o, int x, int y, NET::DesktopLayoutCorner c); void setShowingDesktop( bool showing ); void resetShowingDesktop( bool keep_hidden ); bool showingDesktop() const; @@ -258,17 +236,14 @@ class Workspace : public QObject, public KDecorationDefines void sendPingToWindow( Window w, Time timestamp ); // called from Client::pingWindow() void sendTakeActivity( Client* c, Time timestamp, long flags ); // called from Client::takeActivity() - void removeClient( Client*, allowed_t ); // only called from Client::destroyClient() or Client::releaseWindow() + // only called from Client::destroyClient() or Client::releaseWindow() + void removeClient( Client*, allowed_t ); void setActiveClient( Client*, allowed_t ); Group* findGroup( Window leader ) const; void addGroup( Group* group, allowed_t ); void removeGroup( Group* group, allowed_t ); Group* findClientLeaderGroup( const Client* c ) const; - void removeUnmanaged( Unmanaged*, allowed_t ); // only called from Unmanaged::release() - void removeDeleted( Deleted*, allowed_t ); - void addDeleted( Deleted*, allowed_t ); - bool checkStartupNotification( Window w, KStartupInfoId& id, KStartupInfoData& data ); void focusToNull(); // SELI public? @@ -281,7 +256,6 @@ class Workspace : public QObject, public KDecorationDefines bool globalShortcutsDisabled() const; void disableGlobalShortcuts( bool disable ); void disableGlobalShortcutsForClient( bool disable ); - QPoint cursorPos(); void sessionSaveStarted(); void sessionSaveDone(); @@ -305,19 +279,6 @@ class Workspace : public QObject, public KDecorationDefines void toggleTopDockShadows(bool on); - // when adding repaints caused by a window, you probably want to use - // either Toplevel::addRepaint() or Toplevel::addWorkspaceRepaint() - void addRepaint( const QRect& r ); - void addRepaint( int x, int y, int w, int h ); - void addRepaintFull(); - // creates XComposite overlay window, call initOverlay() afterwards - bool createOverlay(); - // init overlay and the destination window in it - void setupOverlay( Window window ); - // destroys XComposite overlay window - void destroyOverlay(); - Window overlayWindow(); - public slots: void refresh(); // keybindings @@ -447,16 +408,15 @@ class Workspace : public QObject, public KDecorationDefines void cleanupTemporaryRules(); void writeWindowRules(); void slotBlockShortcuts(int data); - void setPopupClientOpacity( QAction* action ); - void setupCompositing(); - void performCompositing(); - void lostCMSelection(); - void updateElectricBorders(); - void resetCursorPosTime(); + void slotReloadConfig(); + // kompmgr + void setPopupClientOpacity(int v); + void resetClientOpacity(); + void setTransButtonText(int value); + // end protected: bool keyPressMouseEmulation( XKeyEvent& ev ); - bool netCheck( XEvent* e ); private: void init(); @@ -464,17 +424,16 @@ class Workspace : public QObject, public KDecorationDefines void readShortcuts(); void initDesktopPopup(); void setupWindowShortcut( Client* c ); - void checkCursorPos(); bool startKDEWalkThroughWindows(); - bool startWalkThroughDesktops( TabBoxMode mode ); // TabBoxDesktopMode | TabBoxDesktopListMode + bool startWalkThroughDesktops( int mode ); // TabBox::Mode::DesktopMode | DesktopListMode bool startWalkThroughDesktops(); bool startWalkThroughDesktopList(); void KDEWalkThroughWindows( bool forward ); void CDEWalkThroughWindows( bool forward ); void walkThroughDesktops( bool forward ); void KDEOneStepThroughWindows( bool forward ); - void oneStepThroughDesktops( bool forward, TabBoxMode mode ); // TabBoxDesktopMode | TabBoxDesktopListMode + void oneStepThroughDesktops( bool forward, int mode ); // TabBox::Mode::DesktopMode | DesktopListMode void oneStepThroughDesktops( bool forward ); void oneStepThroughDesktopList( bool forward ); bool establishTabBoxGrab(); @@ -501,8 +460,6 @@ class Workspace : public QObject, public KDecorationDefines // this is the right way to create a new client Client* createClient( Window w, bool is_mapped ); void addClient( Client* c, allowed_t ); - Unmanaged* createUnmanaged( Window w ); - void addUnmanaged( Unmanaged* c, allowed_t ); Window findSpecialEventWindow( XEvent* e ); @@ -528,21 +485,22 @@ class Workspace : public QObject, public KDecorationDefines void tabBoxKeyRelease( const XKeyEvent& ev ); // electric borders - void destroyElectricBorders(); - bool electricBorderEvent(XEvent * e); - void electricBorderSwitchDesktop( ElectricBorder border, const QPoint& pos ); + void checkElectricBorders( bool force = false ); + void createBorderWindows(); + void destroyBorderWindows(); + bool electricBorder(XEvent * e); + void raiseElectricBorders(); // ------------------ void helperDialog( const QString& message, const Client* c ); + void calcDesktopLayout(int &x, int &y) const; + QMenu* clientPopup(); void closeActivePopup(); void updateClientArea( bool force ); - - void finishCompositing(); - bool windowRepaintsPending() const; SystemTrayWindowList systemTrayWins; @@ -563,6 +521,7 @@ class Workspace : public QObject, public KDecorationDefines QList rules; KXMessages temporaryRulesMessages; QTimer rulesUpdatedTimer; + bool rules_updates_disabled; static const char* windowTypeToTxt( NET::WindowType type ); static NET::WindowType txtToWindowType( const char* txt ); static bool sessionInfoWindowTypeMatch( Client* c, SessionInfo* info ); @@ -579,12 +538,10 @@ class Workspace : public QObject, public KDecorationDefines ClientList clients; ClientList desktops; - UnmanagedList unmanaged; - DeletedList deleted; - ClientList unconstrained_stacking_order; - ClientList stacking_order; - QVector< ClientList > focus_chain; + ClientList unconstrained_stacking_order; // topmost last + ClientList stacking_order; // topmost last + QVector< ClientList > focus_chain; // currently ative last ClientList global_focus_chain; // this one is only for things like tabbox's MRU ClientList should_get_focus; // last is most recent ClientList attention_chain; @@ -618,9 +575,7 @@ class Workspace : public QObject, public KDecorationDefines QMenu *popup; QMenu *advanced_popup; - QMenu *trans_popup; QMenu *desk_popup; - int desk_popup_index; KActionCollection *keys; KActionCollection *client_keys; @@ -665,8 +620,12 @@ class Workspace : public QObject, public KDecorationDefines KStartupInfo* startup; - ElectricBorder electric_current_border; - Window electric_windows[ ELECTRIC_COUNT ]; + bool electric_have_borders; + int electric_current_border; + WId electric_top_border; + WId electric_bottom_border; + WId electric_left_border; + WId electric_right_border; int electricLeft; int electricRight; int electricTop; @@ -674,7 +633,6 @@ class Workspace : public QObject, public KDecorationDefines Time electric_time_first; Time electric_time_last; QPoint electric_push_point; - int electric_reserved[ ELECTRIC_COUNT ]; // corners/edges used by something Qt::Orientation layoutOrientation; int layoutX; @@ -699,14 +657,12 @@ class Workspace : public QObject, public KDecorationDefines bool forced_global_mouse_grab; friend class StackingUpdatesBlocker; - KSelectionOwner* cm_selection; - QTimer compositeTimer; - QTime lastCompositePaint; - int compositeRate; - QRegion repaints_region; - Window overlay; // XComposite overlay window + //kompmgr QSlider *transSlider; QPushButton *transButton; + + private: + friend bool performTransiencyCheck(); }; // helper for Workspace::blockStackingUpdates() being called in pairs (true/false) @@ -731,7 +687,6 @@ class RootInfo : public NETRootInfo protected: virtual void changeNumberOfDesktops(int n); virtual void changeCurrentDesktop(int d); -// virtual void changeActiveWindow(Window w); the extended version is used virtual void changeActiveWindow(Window w,NET::RequestSource src, Time timestamp, Window active_window); virtual void closeWindow(Window w); virtual void moveResize(Window w, int x_root, int y_root, unsigned long direction); @@ -849,9 +804,10 @@ inline bool Workspace::globalShortcutsDisabled() const return global_shortcuts_disabled || global_shortcuts_disabled_for_client; } -inline Window Workspace::overlayWindow() +inline +bool Workspace::rulesUpdatesDisabled() const { - return overlay; + return rules_updates_disabled; } template< typename T > @@ -881,27 +837,7 @@ inline void Workspace::forEachClient( T procedure ) return forEachClient( procedure, TruePredicate()); } -template< typename T > -inline Unmanaged* Workspace::findUnmanaged( T predicate ) - { - return findUnmanagedInList( unmanaged, predicate ); - } - -template< typename T1, typename T2 > -inline void Workspace::forEachUnmanaged( T1 procedure, T2 predicate ) - { - for ( UnmanagedList::ConstIterator it = unmanaged.begin(); it != unmanaged.end(); ++it) - if ( predicate( const_cast< const Unmanaged* >( *it))) - procedure( *it ); - } - -template< typename T > -inline void Workspace::forEachUnmanaged( T procedure ) - { - return forEachUnmanaged( procedure, TruePredicate()); - } - -KWIN_COMPARE_PREDICATE( ClientMatchPredicate, Client, const Client*, cl == value ); +KWIN_COMPARE_PREDICATE( ClientMatchPredicate, const Client*, cl == value ); inline bool Workspace::hasClient( const Client* c ) { return findClient( ClientMatchPredicate( c ));