diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-12-11 20:21:27 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-12-11 20:21:27 +0000 |
commit | 10e41144596fc9ced40fc349d9ecd099b1c2ea19 (patch) | |
tree | 88ab04e475ff5a4cd889cb082f5760b6e0bf5e4e /kwin | |
parent | 4aed2c8219774f5d797760606b8489a92ddc5163 (diff) | |
download | tdebase-10e41144596fc9ced40fc349d9ecd099b1c2ea19.tar.gz tdebase-10e41144596fc9ced40fc349d9ecd099b1c2ea19.zip |
Initial import of Trinity 3.5.11 to kdebase
Extends krandrtray, adds iccconfig kcontrol module, adds run dialog autocomplete and lots of bugfixes
Will need to check for commit warnings and repair as encountered
Also needs full compile test
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1061475 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kwin')
-rw-r--r-- | kwin/KWinInterface.h | 1 | ||||
-rw-r--r-- | kwin/activation.cpp | 36 | ||||
-rw-r--r-- | kwin/client.cpp | 14 | ||||
-rw-r--r-- | kwin/client.h | 3 | ||||
-rw-r--r-- | kwin/geometry.cpp | 47 | ||||
-rw-r--r-- | kwin/kcmkwin/kwinoptions/windows.cpp | 51 | ||||
-rw-r--r-- | kwin/kcmkwin/kwinoptions/windows.h | 5 | ||||
-rw-r--r-- | kwin/kwin.kcfg | 3 | ||||
-rw-r--r-- | kwin/kwinbindings.cpp | 18 | ||||
-rw-r--r-- | kwin/manage.cpp | 11 | ||||
-rw-r--r-- | kwin/options.cpp | 6 | ||||
-rw-r--r-- | kwin/options.h | 8 | ||||
-rw-r--r-- | kwin/placement.cpp | 7 | ||||
-rw-r--r-- | kwin/popupinfo.cpp | 7 | ||||
-rw-r--r-- | kwin/popupinfo.h | 3 | ||||
-rw-r--r-- | kwin/tabbox.cpp | 41 | ||||
-rw-r--r-- | kwin/useractions.cpp | 40 | ||||
-rw-r--r-- | kwin/utils.cpp | 2 | ||||
-rw-r--r-- | kwin/workspace.cpp | 79 | ||||
-rw-r--r-- | kwin/workspace.h | 16 |
20 files changed, 360 insertions, 38 deletions
diff --git a/kwin/KWinInterface.h b/kwin/KWinInterface.h index d368ec368..bca7354b5 100644 --- a/kwin/KWinInterface.h +++ b/kwin/KWinInterface.h @@ -16,6 +16,7 @@ class KWinInterface : virtual public DCOPObject virtual void refresh() = 0; virtual void doNotManage(QString)= 0; virtual void showWindowMenuAt(unsigned long winId, int x, int y)= 0; + virtual void kDestopResized() = 0; virtual void setDesktopLayout(int orientation, int x, int y)= 0; virtual bool setCurrentDesktop(int)= 0; virtual int currentDesktop() const = 0; diff --git a/kwin/activation.cpp b/kwin/activation.cpp index 2551519ec..a6844b737 100644 --- a/kwin/activation.cpp +++ b/kwin/activation.cpp @@ -360,6 +360,8 @@ void Workspace::takeActivity( Client* c, int flags, bool handled ) return; } c->takeActivity( flags, handled, Allowed ); + if( !c->isOnScreen( active_screen )) + active_screen = c->screen(); } void Workspace::handleTakeActivity( Client* c, Time /*timestamp*/, int flags ) @@ -413,6 +415,13 @@ bool Workspace::activateNextClient( Client* c ) { if( !(*it)->isShown( false ) || !(*it)->isOnCurrentDesktop()) continue; + if( options->separateScreenFocus ) + { + if( c != NULL && !(*it)->isOnScreen( c->screen())) + continue; + if( c == NULL && !(*it)->isOnScreen( activeScreen())) + continue; + } if( mainwindows.contains( *it )) { get_focus = *it; @@ -438,6 +447,31 @@ bool Workspace::activateNextClient( Client* c ) return true; } +void Workspace::setCurrentScreen( int new_screen ) + { + if (new_screen < 0 || new_screen > numScreens()) + return; + if ( !options->focusPolicyIsReasonable()) + return; + closeActivePopup(); + Client* get_focus = NULL; + for( ClientList::ConstIterator it = focus_chain[currentDesktop()].fromLast(); + it != focus_chain[currentDesktop()].end(); + --it ) + { + if( !(*it)->isShown( false ) || !(*it)->isOnCurrentDesktop()) + continue; + if( !(*it)->screen() == new_screen ) + continue; + get_focus = *it; + break; + } + if( get_focus == NULL ) + get_focus = findDesktop( true, currentDesktop()); + if( get_focus != NULL && get_focus != mostRecentlyActivatedClient()) + requestFocus( get_focus ); + active_screen = new_screen; + } void Workspace::gotFocusIn( const Client* c ) { @@ -860,6 +894,8 @@ void Client::startupIdChanged() desktop = asn_data.desktop(); if( !isOnAllDesktops()) workspace()->sendClientToDesktop( this, desktop, true ); + if( asn_data.xinerama() != -1 ) + workspace()->sendClientToScreen( this, asn_data.xinerama()); Time timestamp = asn_id.timestamp(); if( timestamp == 0 && asn_data.timestamp() != -1U ) timestamp = asn_data.timestamp(); diff --git a/kwin/client.cpp b/kwin/client.cpp index fe8c59c58..9fc5353df 100644 --- a/kwin/client.cpp +++ b/kwin/client.cpp @@ -1255,6 +1255,20 @@ bool Client::isOnCurrentDesktop() const return isOnDesktop( workspace()->currentDesktop()); } +int Client::screen() const + { + if( !options->xineramaEnabled ) + return 0; + return workspace()->screenNumber( geometry().center()); + } + +bool Client::isOnScreen( int screen ) const + { + if( !options->xineramaEnabled ) + return screen == 0; + return workspace()->screenGeometry( screen ).intersects( geometry()); + } + // performs activation and/or raising of the window void Client::takeActivity( int flags, bool handled, allowed_t ) { diff --git a/kwin/client.h b/kwin/client.h index d0d8e9d54..0905b5794 100644 --- a/kwin/client.h +++ b/kwin/client.h @@ -118,6 +118,9 @@ class Client : public QObject, public KDecorationDefines bool isOnCurrentDesktop() const; bool isOnAllDesktops() const; void setOnAllDesktops( bool set ); + + bool isOnScreen( int screen ) const; // true if it's at least partially there + int screen() const; // the screen where the center is // !isMinimized() && not hidden, i.e. normally visible on some virtual desktop bool isShown( bool shaded_is_shown ) const; diff --git a/kwin/geometry.cpp b/kwin/geometry.cpp index 7c64eadcf..cff5a3a19 100644 --- a/kwin/geometry.cpp +++ b/kwin/geometry.cpp @@ -43,13 +43,30 @@ namespace KWinInternal */ void Workspace::desktopResized() { - QRect geom = QApplication::desktop()->geometry(); + printf("Workspace::desktopResized()\n\r"); + QRect geom = KApplication::desktop()->geometry(); NETSize desktop_geometry; desktop_geometry.width = geom.width(); desktop_geometry.height = geom.height(); rootInfo->setDesktopGeometry( -1, desktop_geometry ); - updateClientArea(); + updateClientArea( true ); + checkElectricBorders( true ); + } + +/*! + Resizes the workspace after kdesktop signals a desktop resize + */ +void Workspace::kDestopResized() + { + printf("Workspace::kDesktopResized()\n\r"); + QRect geom = KApplication::desktop()->geometry(); + NETSize desktop_geometry; + desktop_geometry.width = geom.width(); + desktop_geometry.height = geom.height(); + rootInfo->setDesktopGeometry( -1, desktop_geometry ); + + updateClientArea( true ); checkElectricBorders( true ); } @@ -211,14 +228,11 @@ void Workspace::updateClientArea() \sa geometry() */ -QRect Workspace::clientArea( clientAreaOption opt, const QPoint& p, int desktop ) const +QRect Workspace::clientArea( clientAreaOption opt, int screen, int desktop ) const { if( desktop == NETWinInfo::OnAllDesktops || desktop == 0 ) desktop = currentDesktop(); QDesktopWidget *desktopwidget = KApplication::desktop(); - int screen = desktopwidget->isVirtualDesktop() ? desktopwidget->screenNumber( p ) : desktopwidget->primaryScreen(); - if( screen < 0 ) - screen = desktopwidget->primaryScreen(); QRect sarea = screenarea // may be NULL during KWin initialization ? screenarea[ desktop ][ screen ] : desktopwidget->screenGeometry( screen ); @@ -263,11 +277,21 @@ QRect Workspace::clientArea( clientAreaOption opt, const QPoint& p, int desktop return QRect(); } +QRect Workspace::clientArea( clientAreaOption opt, const QPoint& p, int desktop ) const + { + QDesktopWidget *desktopwidget = KApplication::desktop(); + int screen = desktopwidget->screenNumber( p ); + if( screen < 0 ) + screen = desktopwidget->primaryScreen(); + return clientArea( opt, screen, desktop ); + } + QRect Workspace::clientArea( clientAreaOption opt, const Client* c ) const { return clientArea( opt, c->geometry().center(), c->desktop()); } + /*! Client \a c is moved around to position \a pos. This gives the workspace the opportunity to interveniate and to implement @@ -896,10 +920,6 @@ void Client::checkWorkspacePosition() setGeometry( area ); return; } - if( maximizeMode() != MaximizeRestore ) - // TODO update geom_restore? - changeMaximize( false, false, true ); // adjust size - if( isFullScreen()) { QRect area = workspace()->clientArea( FullScreenArea, this ); @@ -926,6 +946,10 @@ void Client::checkWorkspacePosition() return; } + if( maximizeMode() != MaximizeRestore ) + // TODO update geom_restore? + changeMaximize( false, false, true ); // adjust size + if( !isShade()) // TODO { int old_diff_x = workarea_diff_x; @@ -1722,6 +1746,7 @@ void Client::setGeometry( int x, int y, int w, int h, ForceGeometry_t force ) sendSyntheticConfigureNotify(); updateWindowRules(); checkMaximizeGeometry(); + workspace()->checkActiveScreen( this ); } void Client::plainResize( int w, int h, ForceGeometry_t force ) @@ -1775,6 +1800,7 @@ void Client::plainResize( int w, int h, ForceGeometry_t force ) sendSyntheticConfigureNotify(); updateWindowRules(); checkMaximizeGeometry(); + workspace()->checkActiveScreen( this ); } /*! @@ -1795,6 +1821,7 @@ void Client::move( int x, int y, ForceGeometry_t force ) sendSyntheticConfigureNotify(); updateWindowRules(); checkMaximizeGeometry(); + workspace()->checkActiveScreen( this ); } diff --git a/kwin/kcmkwin/kwinoptions/windows.cpp b/kwin/kcmkwin/kwinoptions/windows.cpp index db682b316..aa779125b 100644 --- a/kwin/kcmkwin/kwinoptions/windows.cpp +++ b/kwin/kcmkwin/kwinoptions/windows.cpp @@ -76,6 +76,8 @@ #define KWIN_SHADEHOVER_INTERVAL "ShadeHoverInterval" #define KWIN_FOCUS_STEALING "FocusStealingPreventionLevel" #define KWIN_HIDE_UTILITY "HideUtilityWindowsForInactive" +#define KWIN_SEPARATE_SCREEN_FOCUS "SeparateScreenFocus" +#define KWIN_ACTIVE_MOUSE_SCREEN "ActiveMouseScreen" // kwm config keywords #define KWM_ELECTRIC_BORDER "ElectricBorders" @@ -209,6 +211,27 @@ KFocusConfig::KFocusConfig (bool _standAlone, KConfig *_config, QWidget * parent QWhatsThis::add( delayFocus, i18n("This is the delay after which the window the mouse pointer is over" " will automatically receive focus.") ); + separateScreenFocus = new QCheckBox( i18n( "S&eparate screen focus" ), fcsBox ); + fLay->addWidget( separateScreenFocus ); + wtstr = i18n( "When this option is enabled, focus operations are limited only to the active Xinerama screen" ); + QWhatsThis::add( separateScreenFocus, wtstr ); + + activeMouseScreen = new QCheckBox( i18n( "Active &mouse screen" ), fcsBox ); + fLay->addWidget( activeMouseScreen ); + wtstr = i18n( "When this option is enabled, active Xinerama screen (where for example new windows appear)" + " is the screen with the mouse pointer. When disabled, the active Xinerama screen is the screen" + " with the focused window. This option is by default disabled for Click to focus and" + " enabled for other focus policies." ); + QWhatsThis::add( activeMouseScreen, wtstr ); + connect(focusCombo, SIGNAL(activated(int)), this, SLOT(updateActiveMouseScreen())); + + if (!QApplication::desktop()->isVirtualDesktop() || + QApplication::desktop()->numScreens() == 1) // No Ximerama + { + separateScreenFocus->hide(); + activeMouseScreen->hide(); + } + lay->addWidget(fcsBox); kbdBox = new QButtonGroup(i18n("Navigation"), this); @@ -260,6 +283,8 @@ KFocusConfig::KFocusConfig (bool _standAlone, KConfig *_config, QWidget * parent connect(fcsBox, SIGNAL(clicked(int)), SLOT(changed())); connect(autoRaise, SIGNAL(valueChanged(int)), SLOT(changed())); connect(delayFocus, SIGNAL(valueChanged(int)), SLOT(changed())); + connect(separateScreenFocus, SIGNAL(clicked()), SLOT(changed())); + connect(activeMouseScreen, SIGNAL(clicked()), SLOT(changed())); connect(altTabPopup, SIGNAL(clicked()), SLOT(changed())); connect(traverseAll, SIGNAL(clicked()), SLOT(changed())); connect(rollOverDesktops, SIGNAL(clicked()), SLOT(changed())); @@ -366,6 +391,22 @@ void KFocusConfig::delayFocusOnTog(bool a) { void KFocusConfig::clickRaiseOnTog(bool ) { } +void KFocusConfig::setSeparateScreenFocus(bool s) { + separateScreenFocus->setChecked(s); +} + +void KFocusConfig::setActiveMouseScreen(bool a) { + activeMouseScreen->setChecked(a); +} + +void KFocusConfig::updateActiveMouseScreen() +{ + // on by default for non click to focus policies + KConfigGroup cfg( config, "Windows" ); + if( !cfg.hasKey( KWIN_ACTIVE_MOUSE_SCREEN )) + setActiveMouseScreen( focusCombo->currentItem() != 0 ); +} + void KFocusConfig::setAltTabMode(bool a) { altTabPopup->setChecked(a); } @@ -412,6 +453,10 @@ void KFocusConfig::load( void ) setClickRaise(key != "off"); setAutoRaiseEnabled(); // this will disable/hide the auto raise delay widget if focus==click setDelayFocusEnabled(); + + setSeparateScreenFocus( config->readBoolEntry(KWIN_SEPARATE_SCREEN_FOCUS, false)); + // on by default for non click to focus policies + setActiveMouseScreen( config->readBoolEntry(KWIN_ACTIVE_MOUSE_SCREEN, focusCombo->currentItem() != 0 )); key = config->readEntry(KWIN_ALTTABMODE, "KDE"); setAltTabMode(key == "KDE"); @@ -467,6 +512,9 @@ void KFocusConfig::save( void ) else config->writeEntry(KWIN_CLICKRAISE, "off"); + config->writeEntry(KWIN_SEPARATE_SCREEN_FOCUS, separateScreenFocus->isChecked()); + config->writeEntry(KWIN_ACTIVE_MOUSE_SCREEN, activeMouseScreen->isChecked()); + if (altTabPopup->isChecked()) config->writeEntry(KWIN_ALTTABMODE, "KDE"); else @@ -500,6 +548,9 @@ void KFocusConfig::defaults() setAutoRaise(false); setDelayFocus(false); setClickRaise(true); + setSeparateScreenFocus( false ); + // on by default for non click to focus policies + setActiveMouseScreen( focusCombo->currentItem() != 0 ); setAltTabMode(true); setTraverseAll( false ); setRollOverDesktops(true); diff --git a/kwin/kcmkwin/kwinoptions/windows.h b/kwin/kcmkwin/kwinoptions/windows.h index 60a4d69f0..14537b922 100644 --- a/kwin/kcmkwin/kwinoptions/windows.h +++ b/kwin/kcmkwin/kwinoptions/windows.h @@ -86,6 +86,7 @@ private slots: void delayFocusOnTog(bool); void clickRaiseOnTog(bool); void updateAltTabMode(); + void updateActiveMouseScreen(); void changed() { emit KCModule::changed(true); } @@ -101,6 +102,8 @@ private: void setDelayFocusInterval(int); void setDelayFocus(bool); void setClickRaise(bool); + void setSeparateScreenFocus(bool); + void setActiveMouseScreen(bool); void setAltTabMode(bool); void setTraverseAll(bool); void setRollOverDesktops(bool); @@ -113,6 +116,8 @@ private: QCheckBox *clickRaiseOn; KIntNumInput *autoRaise; KIntNumInput *delayFocus; + QCheckBox *separateScreenFocus; + QCheckBox *activeMouseScreen; QButtonGroup *kbdBox; QCheckBox *altTabPopup; diff --git a/kwin/kwin.kcfg b/kwin/kwin.kcfg index 9865d296c..63749c1f8 100644 --- a/kwin/kwin.kcfg +++ b/kwin/kwin.kcfg @@ -60,6 +60,9 @@ <entry key="IgnorePositionClasses" type="StringList" /> <entry key="KillPingTimeout" type="Int" /> <entry key="ShowDesktopIsMinimizeAll" type="Bool" /> + <entry key="SeparateScreenFocus" type="Bool" /> + <entry key="ActiveMouseScreen" type="Bool" /> + <entry key="XineramaPlacementScreen" type="Int" /> </group> <group name="WM" > diff --git a/kwin/kwinbindings.cpp b/kwin/kwinbindings.cpp index 1fd8c572f..9dee0a071 100644 --- a/kwin/kwinbindings.cpp +++ b/kwin/kwinbindings.cpp @@ -104,6 +104,15 @@ DEF( I18N_NOOP("Window One Desktop to the Left"), 0, 0, slotWindowToDesktopLeft() ); DEF( I18N_NOOP("Window One Desktop Up"), 0, 0, slotWindowToDesktopUp() ); DEF( I18N_NOOP("Window One Desktop Down"), 0, 0, slotWindowToDesktopDown() ); + DEF( I18N_NOOP("Window to Screen 0"), 0, 0, slotWindowToScreen(int) ); + DEF( I18N_NOOP("Window to Screen 1"), 0, 0, slotWindowToScreen(int) ); + DEF( I18N_NOOP("Window to Screen 2"), 0, 0, slotWindowToScreen(int) ); + DEF( I18N_NOOP("Window to Screen 3"), 0, 0, slotWindowToScreen(int) ); + DEF( I18N_NOOP("Window to Screen 4"), 0, 0, slotWindowToScreen(int) ); + DEF( I18N_NOOP("Window to Screen 5"), 0, 0, slotWindowToScreen(int) ); + DEF( I18N_NOOP("Window to Screen 6"), 0, 0, slotWindowToScreen(int) ); + DEF( I18N_NOOP("Window to Screen 7"), 0, 0, slotWindowToScreen(int) ); + DEF( I18N_NOOP("Window to Next Screen"), 0, 0, slotWindowToNextScreen() ); keys->insert( "Group:Desktop Switching", i18n("Desktop Switching") ); DEF( I18N_NOOP("Switch to Desktop 1"), CTRL+Qt::Key_F1, WIN+Qt::Key_F1, slotSwitchToDesktop(int) ); @@ -132,6 +141,15 @@ DEF( I18N_NOOP("Switch One Desktop to the Left"), 0, 0, slotSwitchDesktopLeft() ); DEF( I18N_NOOP("Switch One Desktop Up"), 0, 0, slotSwitchDesktopUp() ); DEF( I18N_NOOP("Switch One Desktop Down"), 0, 0, slotSwitchDesktopDown() ); + DEF( I18N_NOOP("Switch to Screen 0"), 0, 0, slotSwitchToScreen(int) ); + DEF( I18N_NOOP("Switch to Screen 1"), 0, 0, slotSwitchToScreen(int) ); + DEF( I18N_NOOP("Switch to Screen 2"), 0, 0, slotSwitchToScreen(int) ); + DEF( I18N_NOOP("Switch to Screen 3"), 0, 0, slotSwitchToScreen(int) ); + DEF( I18N_NOOP("Switch to Screen 4"), 0, 0, slotSwitchToScreen(int) ); + DEF( I18N_NOOP("Switch to Screen 5"), 0, 0, slotSwitchToScreen(int) ); + DEF( I18N_NOOP("Switch to Screen 6"), 0, 0, slotSwitchToScreen(int) ); + DEF( I18N_NOOP("Switch to Screen 7"), 0, 0, slotSwitchToScreen(int) ); + DEF( I18N_NOOP("Switch to Next Screen"), 0, 0, slotSwitchToNextScreen() ); keys->insert( "Group:Miscellaneous", i18n("Miscellaneous") ); DEF( I18N_NOOP("Mouse Emulation"), ALT+Qt::Key_F12, 0, slotMouseEmulation() ); diff --git a/kwin/manage.cpp b/kwin/manage.cpp index 35dcc88ba..24398dcae 100644 --- a/kwin/manage.cpp +++ b/kwin/manage.cpp @@ -166,7 +166,7 @@ bool Client::manage( Window w, bool isMapped ) it != mainclients.end(); ++it ) { - if( (*it)->isSpecialWindow()) + if( mainclients.count() > 1 && (*it)->isSpecialWindow()) continue; // don't consider toolbars etc when placing maincl = *it; if( (*it)->isOnCurrentDesktop()) @@ -202,9 +202,14 @@ bool Client::manage( Window w, bool isMapped ) if( isMapped || session ) area = workspace()->clientArea( FullArea, geom.center(), desktop()); else if( options->xineramaPlacementEnabled ) - area = workspace()->clientArea( PlacementArea, QCursor::pos(), desktop()); + { + int screen = options->xineramaPlacementScreen; + if( screen == -1 ) // active screen + screen = asn_data.xinerama() == -1 ? workspace()->activeScreen() : asn_data.xinerama(); + area = workspace()->clientArea( PlacementArea, workspace()->screenGeometry( screen ).center(), desktop()); + } else - area = workspace()->clientArea( PlacementArea, geom.center(), desktop()); + area = workspace()->clientArea( PlacementArea, QCursor::pos(), desktop()); if( int type = checkFullScreenHack( geom )) { diff --git a/kwin/options.cpp b/kwin/options.cpp index 690266fc9..f74051bbb 100644 --- a/kwin/options.cpp +++ b/kwin/options.cpp @@ -71,6 +71,9 @@ unsigned long Options::updateSettings() altTabStyle = KDE; // what a default :-) if ( val == "CDE" ) altTabStyle = CDE; + + separateScreenFocus = config->readBoolEntry( "SeparateScreenFocus", false ); + activeMouseScreen = config->readBoolEntry( "ActiveMouseScreen", focusPolicy != ClickToFocus ); rollOverDesktops = config->readBoolEntry("RollOverDesktops", TRUE); @@ -91,9 +94,10 @@ unsigned long Options::updateSettings() delete gc; placement = Placement::policyFromString( config->readEntry("Placement"), true ); + xineramaPlacementScreen = KCLAMP( config->readNumEntry( "XineramaPlacementScreen", -1 ), + -1, qApp->desktop()->numScreens() - 1 ); animateShade = config->readBoolEntry("AnimateShade", TRUE ); - animateMinimize = config->readBoolEntry("AnimateMinimize", TRUE ); animateMinimizeSpeed = config->readNumEntry("AnimateMinimizeSpeed", 5 ); diff --git a/kwin/options.h b/kwin/options.h index 59279fe80..034c9759b 100644 --- a/kwin/options.h +++ b/kwin/options.h @@ -124,6 +124,11 @@ class Options : public KDecorationOptions */ enum AltTabStyle { KDE, CDE }; AltTabStyle altTabStyle; + + // whether to see Xinerama screens separately for focus (in Alt+Tab, when activating next client) + bool separateScreenFocus; + // whether active Xinerama screen is the one with mouse (or with the active window) + bool activeMouseScreen; /** * Xinerama options @@ -133,6 +138,9 @@ class Options : public KDecorationOptions bool xineramaMovementEnabled; bool xineramaMaximizeEnabled; bool xineramaFullscreenEnabled; + + // number, or -1 = active screen (Workspace::activeScreen()) + int xineramaPlacementScreen; /** MoveResizeMode, either Tranparent or Opaque. diff --git a/kwin/placement.cpp b/kwin/placement.cpp index 223b95c5b..e9ae1b95e 100644 --- a/kwin/placement.cpp +++ b/kwin/placement.cpp @@ -473,7 +473,7 @@ void Placement::placeOnMainWindow(Client* c, QRect& area, Policy nextPlacement ) it != mainwindows.end(); ++it ) { - if( (*it)->isSpecialWindow()) + if( mainwindows.count() > 1 && (*it)->isSpecialWindow()) continue; // don't consider toolbars etc when placing ++mains_count; place_on2 = *it; @@ -502,6 +502,11 @@ void Placement::placeOnMainWindow(Client* c, QRect& area, Policy nextPlacement ) } place_on = place_on2; // use the only window filtered together with 'mains_count' } + if( place_on->isDesktop()) + { + place( c, area, Centered ); + return; + } QRect geom = c->geometry(); geom.moveCenter( place_on->geometry().center()); c->move( geom.topLeft()); diff --git a/kwin/popupinfo.cpp b/kwin/popupinfo.cpp index aef5dbea7..906489e67 100644 --- a/kwin/popupinfo.cpp +++ b/kwin/popupinfo.cpp @@ -25,7 +25,6 @@ License. See the file "COPYING" for the exact licensing terms. #include <klocale.h> #include <qapplication.h> #include <qdesktopwidget.h> -#include <qcursor.h> #include <kstringhandler.h> #include <kglobalsettings.h> @@ -34,8 +33,8 @@ License. See the file "COPYING" for the exact licensing terms. namespace KWinInternal { -PopupInfo::PopupInfo( const char *name ) - : QWidget( 0, name ) +PopupInfo::PopupInfo( Workspace* ws, const char *name ) + : QWidget( 0, name ), workspace( ws ) { m_infoString = ""; m_shown = false; @@ -60,7 +59,7 @@ PopupInfo::~PopupInfo() */ void PopupInfo::reset() { - QRect r = KGlobalSettings::desktopGeometry(QCursor::pos()); + QRect r = workspace->screenGeometry( workspace->activeScreen()); int w = fontMetrics().width( m_infoString ) + 30; diff --git a/kwin/popupinfo.h b/kwin/popupinfo.h index 11936fcfb..0b31846ed 100644 --- a/kwin/popupinfo.h +++ b/kwin/popupinfo.h @@ -24,7 +24,7 @@ class PopupInfo : public QWidget { Q_OBJECT public: - PopupInfo( const char *name=0 ); + PopupInfo( Workspace* ws, const char *name=0 ); ~PopupInfo(); void reset(); @@ -43,6 +43,7 @@ class PopupInfo : public QWidget bool m_show; bool m_shown; QString m_infoString; + Workspace* workspace; }; } // namespace diff --git a/kwin/tabbox.cpp b/kwin/tabbox.cpp index 96440e7af..29bef47b8 100644 --- a/kwin/tabbox.cpp +++ b/kwin/tabbox.cpp @@ -23,7 +23,6 @@ License. See the file "COPYING" for the exact licensing terms. #include <klocale.h> #include <qapplication.h> #include <qdesktopwidget.h> -#include <qcursor.h> #include <kstringhandler.h> #include <stdarg.h> #include <kdebug.h> @@ -110,26 +109,36 @@ void TabBox::createClientList(ClientList &list, int desktop /*-1 = all*/, Client while ( c ) { + Client* add = NULL; if ( ((desktop == -1) || c->isOnDesktop(desktop)) && c->wantsTabFocus() ) + { // don't add windows that have modal dialogs + Client* modal = c->findModal(); + if( modal == NULL || modal == c ) + add = c; + else if( !list.contains( modal )) + add = modal; + else + { + // nothing + } + } + + if( options->separateScreenFocus && options->xineramaEnabled ) { - if ( start == c ) + if( c->screen() != workspace()->activeScreen()) + add = NULL; + } + + if( add != NULL ) + { + if ( start == add ) { - list.remove( c ); - list.prepend( c ); + list.remove( add ); + list.prepend( add ); } else - { // don't add windows that have modal dialogs - Client* modal = c->findModal(); - if( modal == NULL || modal == c ) - list += c; - else if( !list.contains( modal )) - list += modal; - else - { - // nothing - } - } + list += add; } if ( chain ) @@ -156,7 +165,7 @@ void TabBox::reset() { int w, h, cw = 0, wmax = 0; - QRect r = KGlobalSettings::desktopGeometry(QCursor::pos()); + QRect r = workspace()->screenGeometry( workspace()->activeScreen()); // calculate height of 1 line // fontheight + 1 pixel above + 1 pixel below, or 32x32 icon + 2 pixel above + below diff --git a/kwin/useractions.cpp b/kwin/useractions.cpp index b722bf1a1..4a431b339 100644 --- a/kwin/useractions.cpp +++ b/kwin/useractions.cpp @@ -482,27 +482,33 @@ bool Client::performMouseCommand( Options::MouseCommand command, QPoint globalPo case Options::MouseActivateAndRaise: replay = isActive(); // for clickraise mode workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled && replay ); + workspace()->setActiveScreenMouse( globalPos ); break; case Options::MouseActivateAndLower: workspace()->requestFocus( this ); workspace()->lowerClient( this ); + workspace()->setActiveScreenMouse( globalPos ); break; case Options::MouseActivate: replay = isActive(); // for clickraise mode workspace()->takeActivity( this, ActivityFocus, handled && replay ); + workspace()->setActiveScreenMouse( globalPos ); break; case Options::MouseActivateRaiseAndPassClick: workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled ); + workspace()->setActiveScreenMouse( globalPos ); replay = TRUE; break; case Options::MouseActivateAndPassClick: workspace()->takeActivity( this, ActivityFocus, handled ); + workspace()->setActiveScreenMouse( globalPos ); replay = TRUE; break; case Options::MouseActivateRaiseAndMove: case Options::MouseActivateRaiseAndUnrestrictedMove: workspace()->raiseClient( this ); workspace()->requestFocus( this ); + workspace()->setActiveScreenMouse( globalPos ); if( options->moveMode == Options::Transparent && isMovable()) move_faked_activity = workspace()->fakeRequestedActivity( this ); // fallthrough @@ -709,6 +715,40 @@ void Workspace::slotWindowToDesktop( int i ) sendClientToDesktop( c, i, true ); } +void Workspace::slotSwitchToScreen( int i ) + { + setCurrentScreen( i ); + } + +void Workspace::slotSwitchToNextScreen() + { + slotSwitchToScreen(( activeScreen() + 1 ) % numScreens()); + } + +void Workspace::slotWindowToScreen( int i ) + { + Client* c = active_popup_client ? active_popup_client : active_client; + if( i >= 0 && i <= numScreens() && c + && !c->isDesktop() + && !c->isDock() + && !c->isTopMenu()) + { + sendClientToScreen( c, i ); + } + } + +void Workspace::slotWindowToNextScreen() + { + Client* c = active_popup_client ? active_popup_client : active_client; + if( c + && !c->isDesktop() + && !c->isDock() + && !c->isTopMenu()) + { + sendClientToScreen( c, ( c->screen() + 1 ) % numScreens()); + } + } + /*! Maximizes the popup client */ diff --git a/kwin/utils.cpp b/kwin/utils.cpp index b0f77df37..7c4fd00eb 100644 --- a/kwin/utils.cpp +++ b/kwin/utils.cpp @@ -314,7 +314,7 @@ bool isLocalMachine( const QCString& host ) hostnamebuf[sizeof(hostnamebuf)-1] = 0; if (host == hostnamebuf) return true; - if( char *dot = strchr(hostnamebuf, '.')) + if( char *dot = (char*)strchr(hostnamebuf, '.')) { *dot = '\0'; if( host == hostnamebuf ) diff --git a/kwin/workspace.cpp b/kwin/workspace.cpp index 1335a888c..2bf94c9a5 100644 --- a/kwin/workspace.cpp +++ b/kwin/workspace.cpp @@ -71,6 +71,7 @@ Workspace::Workspace( bool restore ) QObject (0, "workspace"), current_desktop (0), number_of_desktops(0), + active_screen (0), active_popup( NULL ), active_popup_client( NULL ), desktop_widget (0), @@ -191,7 +192,7 @@ Workspace::Workspace( bool restore ) client_keys = new KGlobalAccel( this ); initShortcuts(); tab_box = new TabBox( this ); - popupinfo = new PopupInfo( ); + popupinfo = new PopupInfo( this ); init(); @@ -290,6 +291,7 @@ void Workspace::init() NET::WM2ExtendedStrut | NET::WM2KDETemporaryRules | NET::WM2ShowingDesktop | + NET::WM2FullPlacement | NET::WM2DesktopLayout | 0 , @@ -1523,6 +1525,81 @@ void Workspace::sendClientToDesktop( Client* c, int desk, bool dont_activate ) updateClientArea(); } +int Workspace::numScreens() const + { + if( !options->xineramaEnabled ) + return 0; + return qApp->desktop()->numScreens(); + } + +int Workspace::activeScreen() const + { + if( !options->xineramaEnabled ) + return 0; + if( !options->activeMouseScreen ) + { + if( activeClient() != NULL && !activeClient()->isOnScreen( active_screen )) + return qApp->desktop()->screenNumber( activeClient()->geometry().center()); + return active_screen; + } + return qApp->desktop()->screenNumber( QCursor::pos()); + } + +// check whether a client moved completely out of what's considered the active screen, +// if yes, set a new active screen +void Workspace::checkActiveScreen( const Client* c ) + { + if( !options->xineramaEnabled ) + return; + if( !c->isActive()) + return; + if( !c->isOnScreen( active_screen )) + active_screen = c->screen(); + } + +// called e.g. when a user clicks on a window, set active screen to be the screen +// where the click occured +void Workspace::setActiveScreenMouse( QPoint mousepos ) + { + if( !options->xineramaEnabled ) + return; + active_screen = qApp->desktop()->screenNumber( mousepos ); + } + +QRect Workspace::screenGeometry( int screen ) const + { + if( !options->xineramaEnabled ) + return qApp->desktop()->geometry(); + return qApp->desktop()->screenGeometry( screen ); + } + +int Workspace::screenNumber( QPoint pos ) const + { + if( !options->xineramaEnabled ) + return 0; + return qApp->desktop()->screenNumber( pos ); + } + +void Workspace::sendClientToScreen( Client* c, int screen ) + { + if( c->screen() == screen ) // don't use isOnScreen(), that's true even when only partially + return; + GeometryUpdatesPostponer blocker( c ); + QRect old_sarea = clientArea( MaximizeArea, c ); + QRect sarea = clientArea( MaximizeArea, screen, c->desktop()); + c->setGeometry( sarea.x() - old_sarea.x() + c->x(), sarea.y() - old_sarea.y() + c->y(), + c->size().width(), c->size().height()); + c->checkWorkspacePosition(); + ClientList transients_stacking_order = ensureStackingOrder( c->transients()); + for( ClientList::ConstIterator it = transients_stacking_order.begin(); + it != transients_stacking_order.end(); + ++it ) + sendClientToScreen( *it, screen ); + if( c->isActive()) + active_screen = screen; + } + + void Workspace::setDesktopLayout( int, int, int ) { // DCOP-only, unused } diff --git a/kwin/workspace.h b/kwin/workspace.h index 9ccf889b4..efb31de8a 100644 --- a/kwin/workspace.h +++ b/kwin/workspace.h @@ -91,6 +91,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine QRect clientArea( clientAreaOption, const QPoint& p, int desktop ) const; QRect clientArea( clientAreaOption, const Client* c ) const; + QRect clientArea( clientAreaOption, int screen, int desktop ) const; /** * @internal @@ -161,6 +162,13 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine */ int numberOfDesktops() const; void setNumberOfDesktops( int n ); + + int activeScreen() const; + int numScreens() const; + void checkActiveScreen( const Client* c ); + void setActiveScreenMouse( QPoint mousepos ); + QRect screenGeometry( int screen ) const; + int screenNumber( QPoint pos ) const; QWidget* desktopWidget(); @@ -186,9 +194,11 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine void sendClientToDesktop( Client* c, int desktop, bool dont_activate ); void windowToPreviousDesktop( Client* c ); void windowToNextDesktop( Client* c ); + void sendClientToScreen( Client* c, int screen ); // KDE4 remove me - and it's also in the DCOP interface :( void showWindowMenuAt( unsigned long id, int x, int y ); + void kDestopResized(); /** * Shows the menu operations menu for the client and makes it active if @@ -224,6 +234,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine void nextDesktop(); void previousDesktop(); void circulateDesktopApplications(); + void setCurrentScreen( int new_screen ); QString desktopName( int desk ) const; virtual void setDesktopLayout(int , int , int ); @@ -301,6 +312,10 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine //void slotSwitchToWindow( int ); void slotWindowToDesktop( int ); //void slotWindowToListPosition( int ); + void slotSwitchToScreen( int ); + void slotWindowToScreen( int ); + void slotSwitchToNextScreen(); + void slotWindowToNextScreen(); void slotWindowMaximize(); void slotWindowMaximizeVertical(); @@ -481,6 +496,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine int current_desktop; int number_of_desktops; QMemArray<int> desktop_focus_chain; + int active_screen; QWidget* active_popup; Client* active_popup_client; |