summaryrefslogtreecommitdiffstats
path: root/kwin
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-12-11 20:21:27 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-12-11 20:21:27 +0000
commit10e41144596fc9ced40fc349d9ecd099b1c2ea19 (patch)
tree88ab04e475ff5a4cd889cb082f5760b6e0bf5e4e /kwin
parent4aed2c8219774f5d797760606b8489a92ddc5163 (diff)
downloadtdebase-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.h1
-rw-r--r--kwin/activation.cpp36
-rw-r--r--kwin/client.cpp14
-rw-r--r--kwin/client.h3
-rw-r--r--kwin/geometry.cpp47
-rw-r--r--kwin/kcmkwin/kwinoptions/windows.cpp51
-rw-r--r--kwin/kcmkwin/kwinoptions/windows.h5
-rw-r--r--kwin/kwin.kcfg3
-rw-r--r--kwin/kwinbindings.cpp18
-rw-r--r--kwin/manage.cpp11
-rw-r--r--kwin/options.cpp6
-rw-r--r--kwin/options.h8
-rw-r--r--kwin/placement.cpp7
-rw-r--r--kwin/popupinfo.cpp7
-rw-r--r--kwin/popupinfo.h3
-rw-r--r--kwin/tabbox.cpp41
-rw-r--r--kwin/useractions.cpp40
-rw-r--r--kwin/utils.cpp2
-rw-r--r--kwin/workspace.cpp79
-rw-r--r--kwin/workspace.h16
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;