Option for separating focus between Xinerama screens.

svn path=/trunk/KDE/kdebase/workspace/; revision=662065
This commit is contained in:
Luboš Luňák 2007-05-07 12:18:19 +00:00
parent 8d9f931cfd
commit d510baf365
12 changed files with 117 additions and 31 deletions

View file

@ -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());

View file

@ -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 )
{

View file

@ -110,6 +110,9 @@ class Client
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;

View file

@ -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

View file

@ -60,6 +60,8 @@
<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" />
</group>
<group name="WM" >
<entry key="frame" type="Color" />

View file

@ -72,6 +72,9 @@ unsigned long Options::updateSettings()
if ( val == "CDE" )
altTabStyle = CDE;
separateScreenFocus = config.readEntry( "SeparateScreenFocus", true );
activeMouseScreen = config.readEntry( "ActiveMouseScreen", focusPolicy != ClickToFocus );
rollOverDesktops = config.readEntry("RollOverDesktops", true);
// focusStealingPreventionLevel = config.readEntry( "FocusStealingPreventionLevel", 2 );

View file

@ -125,6 +125,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
*/

View file

@ -25,7 +25,6 @@ License. See the file "COPYING" for the exact licensing terms.
#include <klocale.h>
#include <QApplication>
#include <qdesktopwidget.h>
#include <QCursor>
#include <kstringhandler.h>
#include <kglobalsettings.h>
#include <QX11Info>
@ -36,8 +35,8 @@ 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 );
@ -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;

View file

@ -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

View file

@ -24,7 +24,6 @@ License. See the file "COPYING" for the exact licensing terms.
#include <klocale.h>
#include <QApplication>
#include <qdesktopwidget.h>
#include <QCursor>
#include <QAction>
#include <stdarg.h>
#include <kdebug.h>
@ -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 );
}
else
{ // don't add windows that have modal dialogs
Client* modal = c->findModal();
if( modal == NULL || modal == c )
list += c;
add = c;
else if( !list.contains( modal ))
list += modal;
add = modal;
else
{
// 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

View file

@ -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

View file

@ -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