From d510baf3650426a0833c89f8b61e907cd9ba37f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Mon, 7 May 2007 12:18:19 +0000 Subject: [PATCH] Option for separating focus between Xinerama screens. svn path=/trunk/KDE/kdebase/workspace/; revision=662065 --- activation.cpp | 13 ++++++++----- client.cpp | 14 ++++++++++++++ client.h | 3 +++ geometry.cpp | 15 +++++++++++---- kwin.kcfg | 2 ++ options.cpp | 3 +++ options.h | 5 +++++ popupinfo.cpp | 9 ++++----- popupinfo.h | 3 ++- tabbox.cpp | 40 +++++++++++++++++++++++++--------------- workspace.cpp | 36 +++++++++++++++++++++++++++++++++++- workspace.h | 5 +++++ 12 files changed, 117 insertions(+), 31 deletions(-) diff --git a/activation.cpp b/activation.cpp index 378bca460c..c40f15566e 100644 --- a/activation.cpp +++ b/activation.cpp @@ -411,16 +411,19 @@ bool Workspace::activateNextClient( Client* c ) i >= 0; --i ) { - if( !focus_chain[ currentDesktop() ].at( i )->isShown( false ) - || !focus_chain[ currentDesktop() ].at( i )->isOnCurrentDesktop()) + Client* ci = focus_chain[ currentDesktop() ].at( i ); + if( !ci->isShown( false ) + || !ci->isOnCurrentDesktop()) continue; - if( mainwindows.contains( focus_chain[ currentDesktop() ].at( i ) )) + if( options->separateScreenFocus && !ci->isOnScreen( c->screen())) + continue; + if( mainwindows.contains( ci )) { - get_focus = focus_chain[ currentDesktop() ].at( i ); + get_focus = ci; break; } if( get_focus == NULL ) - get_focus = focus_chain[ currentDesktop() ].at( i ); + get_focus = ci; } if( get_focus == NULL ) get_focus = findDesktop( true, currentDesktop()); diff --git a/client.cpp b/client.cpp index d692e45950..01d06c1547 100644 --- a/client.cpp +++ b/client.cpp @@ -1133,6 +1133,20 @@ void Client::setOnAllDesktops( bool b ) setDesktop( 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/client.h b/client.h index 5d614c6462..20d71f28e9 100644 --- a/client.h +++ b/client.h @@ -109,6 +109,9 @@ class Client virtual int desktop() const; void setDesktop( int ); 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/geometry.cpp b/geometry.cpp index f2bf8fefc8..487db55f32 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -218,14 +218,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 ); @@ -270,11 +267,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->isVirtualDesktop() ? desktopwidget->screenNumber( p ) : desktopwidget->primaryScreen(); + 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 diff --git a/kwin.kcfg b/kwin.kcfg index 175dc0e4aa..112f7503b8 100644 --- a/kwin.kcfg +++ b/kwin.kcfg @@ -60,6 +60,8 @@ + + diff --git a/options.cpp b/options.cpp index cee241c119..401f7a06e6 100644 --- a/options.cpp +++ b/options.cpp @@ -71,6 +71,9 @@ unsigned long Options::updateSettings() altTabStyle = KDE; // what a default :-) if ( val == "CDE" ) altTabStyle = CDE; + + separateScreenFocus = config.readEntry( "SeparateScreenFocus", true ); + activeMouseScreen = config.readEntry( "ActiveMouseScreen", focusPolicy != ClickToFocus ); rollOverDesktops = config.readEntry("RollOverDesktops", true); diff --git a/options.h b/options.h index 96ae309f10..402de43517 100644 --- a/options.h +++ b/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 diff --git a/popupinfo.cpp b/popupinfo.cpp index b6b8195278..3a806fbd66 100644 --- a/popupinfo.cpp +++ b/popupinfo.cpp @@ -25,7 +25,6 @@ License. See the file "COPYING" for the exact licensing terms. #include #include #include -#include #include #include #include @@ -36,10 +35,10 @@ License. See the file "COPYING" for the exact licensing terms. namespace KWin { -PopupInfo::PopupInfo( const char *name ) - : QWidget( 0 ) +PopupInfo::PopupInfo( Workspace* ws, const char *name ) + : QWidget( 0, name ), workspace( ws ) { - setObjectName( name ); + setObjectName( name ); m_infoString = ""; m_shown = false; @@ -66,7 +65,7 @@ PopupInfo::~PopupInfo() */ void PopupInfo::reset() { - QRect r = KGlobalSettings::desktopGeometry(cursorPos()); + QRect r = workspace->screenGeometry( workspace->activeScreen()); int w = fontMetrics().width( m_infoString ) + 30; diff --git a/popupinfo.h b/popupinfo.h index 2180950472..75ea9fd907 100644 --- a/popupinfo.h +++ b/popupinfo.h @@ -23,7 +23,7 @@ class PopupInfo : public QWidget { Q_OBJECT public: - PopupInfo( const char *name=0 ); + PopupInfo( Workspace* ws, const char *name=0 ); ~PopupInfo(); void reset(); @@ -42,6 +42,7 @@ class PopupInfo : public QWidget bool m_show; bool m_shown; QString m_infoString; + Workspace* workspace; }; } // namespace diff --git a/tabbox.cpp b/tabbox.cpp index abc27ab5e4..bf342ead7e 100644 --- a/tabbox.cpp +++ b/tabbox.cpp @@ -24,7 +24,6 @@ License. See the file "COPYING" for the exact licensing terms. #include #include #include -#include #include #include #include @@ -101,24 +100,35 @@ void TabBox::createClientList(ClientList &list, int desktop /*-1 = all*/, Client while ( c ) { + Client* add = NULL; if ( ((desktop == -1) || c->isOnDesktop(desktop)) && c->wantsTabFocus() ) - { - if ( start == c ) - { - list.removeAll( c ); - list.prepend( c ); - } + { // 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 - { // 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; + { + // nothing } } - + if( options->separateScreenFocus && options->xineramaEnabled ) + { + if( c->screen() != workspace()->activeScreen()) + add = NULL; + } + if( add != NULL ) + { + if ( start == add ) + { + list.removeAll( add ); + list.prepend( add ); + } + else + list += add; + } if ( chain ) c = workspace()->nextClientFocusChain( c ); else @@ -167,7 +177,7 @@ void TabBox::reset( bool partial_reset ) { int w, h, cw = 0, wmax = 0; - QRect r = KGlobalSettings::desktopGeometry(cursorPos()); + 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/workspace.cpp b/workspace.cpp index 111a0ce543..7eaaae8f35 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -203,7 +203,7 @@ Workspace::Workspace( bool restore ) client_keys = new KActionCollection( this ); initShortcuts(); tab_box = new TabBox( this ); - popupinfo = new PopupInfo( ); + popupinfo = new PopupInfo( this ); init(); @@ -1600,6 +1600,40 @@ 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 ) + return qApp->desktop()->screenNumber( activeClient()->geometry().center()); + return qApp->desktop()->primaryScreen(); + } + return qApp->desktop()->screenNumber( QCursor::pos()); + } + +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::setDesktopLayout(NET::Orientation o, int x, int y,NET::DesktopLayoutCorner c) { Q_UNUSED( c ); // I don't find this worth bothering, feel free to diff --git a/workspace.h b/workspace.h index 139dd92e70..341db4e42f 100644 --- a/workspace.h +++ b/workspace.h @@ -95,6 +95,7 @@ class Workspace : public QObject, public KDecorationDefines 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 @@ -171,6 +172,10 @@ class Workspace : public QObject, public KDecorationDefines void setNumberOfDesktops( int n ); void calcDesktopLayout(int* x, int* y, Qt::Orientation* orientation) const; + int activeScreen() const; + int numScreens() const; + QRect screenGeometry( int screen ) const; + int screenNumber( QPoint pos ) const; QWidget* desktopWidget(); // for TabBox