You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
952 lines
35 KiB
952 lines
35 KiB
Index: kdesktop/minicli.cpp
|
|
===================================================================
|
|
--- kdesktop/minicli.cpp.orig
|
|
+++ kdesktop/minicli.cpp
|
|
@@ -379,6 +379,17 @@ int Minicli::runCommand()
|
|
cmd = uri.path();
|
|
else
|
|
cmd = uri.url();
|
|
+
|
|
+ QCString asn;
|
|
+ if( qApp->desktop()->isVirtualDesktop())
|
|
+ {
|
|
+ asn = KStartupInfo::createNewStartupId();
|
|
+ KStartupInfoId id;
|
|
+ id.initId( asn );
|
|
+ KStartupInfoData data;
|
|
+ data.setXinerama( qApp->desktop()->screenNumber( this ));
|
|
+ KStartupInfo::sendChange( id, data );
|
|
+ }
|
|
|
|
// Determine whether the application should be run through
|
|
// the command line (terminal) interface...
|
|
@@ -514,7 +525,7 @@ int Minicli::runCommand()
|
|
case KURIFilterData::HELP:
|
|
{
|
|
// No need for kfmclient, KRun does it all (David)
|
|
- (void) new KRun( m_filterData->uri(), parentWidget());
|
|
+ (void) new KRun( m_filterData->uri(), parentWidget(), asn );
|
|
return 0;
|
|
}
|
|
case KURIFilterData::EXECUTABLE:
|
|
@@ -526,7 +537,7 @@ int Minicli::runCommand()
|
|
if (service && service->isValid() && service->type() == "Application")
|
|
{
|
|
notifyServiceStarted(service);
|
|
- KRun::run(*service, KURL::List());
|
|
+ KRun::run(*service, KURL::List(), parentWidget(), asn );
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -561,7 +572,7 @@ int Minicli::runCommand()
|
|
if (service && service->isValid() && service->type() == "Application")
|
|
{
|
|
notifyServiceStarted(service);
|
|
- KRun::run(*service, KURL::List(), this);
|
|
+ KRun::run(*service, KURL::List(), parentWidget(), asn );
|
|
return 0;
|
|
}
|
|
|
|
@@ -569,7 +580,7 @@ int Minicli::runCommand()
|
|
if (service && service->isValid() && service->type() == "Application")
|
|
{
|
|
notifyServiceStarted(service);
|
|
- KRun::run(*service, KURL::List(), this);
|
|
+ KRun::run(*service, KURL::List(), parentWidget(), asn );
|
|
return 0;
|
|
}
|
|
|
|
@@ -581,7 +592,7 @@ int Minicli::runCommand()
|
|
}
|
|
}
|
|
|
|
- if ( KRun::runCommand( cmd, exec, m_iconName ) )
|
|
+ if ( KRun::runCommand( cmd, exec, m_iconName, parentWidget(), asn ) )
|
|
return 0;
|
|
else
|
|
{
|
|
Index: kdesktop/desktop.cc
|
|
===================================================================
|
|
--- kdesktop/desktop.cc.orig
|
|
+++ kdesktop/desktop.cc
|
|
@@ -520,9 +520,12 @@ void KDesktop::popupExecuteCommand(const
|
|
if ( m_miniCli->isVisible() ) {
|
|
KWin::forceActiveWindow( m_miniCli->winId() );
|
|
} else {
|
|
- QRect rect = KGlobalSettings::desktopGeometry(QCursor::pos());
|
|
- m_miniCli->move(rect.x() + (rect.width() - m_miniCli->width())/2,
|
|
- rect.y() + (rect.height() - m_miniCli->height())/2);
|
|
+ NETRootInfo i( qt_xdisplay(), NET::Supported );
|
|
+ if( !i.isSupported( NET::WM2FullPlacement )) {
|
|
+ QRect rect = KGlobalSettings::desktopGeometry(QCursor::pos());
|
|
+ m_miniCli->move(rect.x() + (rect.width() - m_miniCli->width())/2,
|
|
+ rect.y() + (rect.height() - m_miniCli->height())/2);
|
|
+ }
|
|
m_miniCli->show(); // non-modal
|
|
}
|
|
}
|
|
Index: kwin/useractions.cpp
|
|
===================================================================
|
|
--- kwin/useractions.cpp.orig
|
|
+++ kwin/useractions.cpp
|
|
@@ -482,27 +482,33 @@ bool Client::performMouseCommand( Option
|
|
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
|
|
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
|
|
*/
|
|
Index: kwin/options.h
|
|
===================================================================
|
|
--- kwin/options.h.orig
|
|
+++ kwin/options.h
|
|
@@ -124,6 +124,11 @@ class Options : public KDecorationOption
|
|
*/
|
|
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 KDecorationOption
|
|
bool xineramaMovementEnabled;
|
|
bool xineramaMaximizeEnabled;
|
|
bool xineramaFullscreenEnabled;
|
|
+
|
|
+ // number, or -1 = active screen (Workspace::activeScreen())
|
|
+ int xineramaPlacementScreen;
|
|
|
|
/**
|
|
MoveResizeMode, either Tranparent or Opaque.
|
|
Index: kwin/workspace.h
|
|
===================================================================
|
|
--- kwin/workspace.h.orig
|
|
+++ kwin/workspace.h
|
|
@@ -91,6 +91,7 @@ class Workspace : public QObject, public
|
|
|
|
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
|
|
*/
|
|
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,6 +194,7 @@ class Workspace : public QObject, public
|
|
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 );
|
|
@@ -224,6 +233,7 @@ class Workspace : public QObject, public
|
|
void nextDesktop();
|
|
void previousDesktop();
|
|
void circulateDesktopApplications();
|
|
+ void setCurrentScreen( int new_screen );
|
|
|
|
QString desktopName( int desk ) const;
|
|
virtual void setDesktopLayout(int , int , int );
|
|
@@ -301,6 +311,10 @@ class Workspace : public QObject, public
|
|
//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 +495,7 @@ class Workspace : public QObject, public
|
|
int current_desktop;
|
|
int number_of_desktops;
|
|
QMemArray<int> desktop_focus_chain;
|
|
+ int active_screen;
|
|
|
|
QWidget* active_popup;
|
|
Client* active_popup_client;
|
|
Index: kwin/tabbox.cpp
|
|
===================================================================
|
|
--- kwin/tabbox.cpp.orig
|
|
+++ kwin/tabbox.cpp
|
|
@@ -23,7 +23,6 @@ License. See the file "COPYING" for the
|
|
#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
|
|
|
|
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
|
|
Index: kwin/kcmkwin/kwinoptions/windows.h
|
|
===================================================================
|
|
--- kwin/kcmkwin/kwinoptions/windows.h.orig
|
|
+++ 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;
|
|
Index: kwin/kcmkwin/kwinoptions/windows.cpp
|
|
===================================================================
|
|
--- kwin/kcmkwin/kwinoptions/windows.cpp.orig
|
|
+++ 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 _standA
|
|
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 _standA
|
|
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
|
|
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);
|
|
Index: kwin/popupinfo.h
|
|
===================================================================
|
|
--- kwin/popupinfo.h.orig
|
|
+++ 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
|
|
Index: kwin/options.cpp
|
|
===================================================================
|
|
--- kwin/options.cpp.orig
|
|
+++ 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 );
|
|
|
|
Index: kwin/placement.cpp
|
|
===================================================================
|
|
--- kwin/placement.cpp.orig
|
|
+++ kwin/placement.cpp
|
|
@@ -473,7 +473,7 @@ void Placement::placeOnMainWindow(Client
|
|
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
|
|
}
|
|
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());
|
|
Index: kwin/client.cpp
|
|
===================================================================
|
|
--- kwin/client.cpp.orig
|
|
+++ 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 )
|
|
{
|
|
Index: kwin/popupinfo.cpp
|
|
===================================================================
|
|
--- kwin/popupinfo.cpp.orig
|
|
+++ kwin/popupinfo.cpp
|
|
@@ -25,7 +25,6 @@ License. See the file "COPYING" for the
|
|
#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
|
|
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;
|
|
|
|
Index: kwin/geometry.cpp
|
|
===================================================================
|
|
--- kwin/geometry.cpp.orig
|
|
+++ kwin/geometry.cpp
|
|
@@ -211,14 +211,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 +260,21 @@ QRect Workspace::clientArea( clientAreaO
|
|
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 +903,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 +929,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 +1729,7 @@ void Client::setGeometry( int x, int y,
|
|
sendSyntheticConfigureNotify();
|
|
updateWindowRules();
|
|
checkMaximizeGeometry();
|
|
+ workspace()->checkActiveScreen( this );
|
|
}
|
|
|
|
void Client::plainResize( int w, int h, ForceGeometry_t force )
|
|
@@ -1775,6 +1783,7 @@ void Client::plainResize( int w, int h,
|
|
sendSyntheticConfigureNotify();
|
|
updateWindowRules();
|
|
checkMaximizeGeometry();
|
|
+ workspace()->checkActiveScreen( this );
|
|
}
|
|
|
|
/*!
|
|
@@ -1795,6 +1804,7 @@ void Client::move( int x, int y, ForceGe
|
|
sendSyntheticConfigureNotify();
|
|
updateWindowRules();
|
|
checkMaximizeGeometry();
|
|
+ workspace()->checkActiveScreen( this );
|
|
}
|
|
|
|
|
|
Index: kwin/kwin.kcfg
|
|
===================================================================
|
|
--- kwin/kwin.kcfg.orig
|
|
+++ 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" >
|
|
Index: kwin/client.h
|
|
===================================================================
|
|
--- kwin/client.h.orig
|
|
+++ kwin/client.h
|
|
@@ -118,6 +118,9 @@ class Client : public QObject, public KD
|
|
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;
|
|
Index: kwin/manage.cpp
|
|
===================================================================
|
|
--- kwin/manage.cpp.orig
|
|
+++ kwin/manage.cpp
|
|
@@ -166,7 +166,7 @@ bool Client::manage( Window w, bool isMa
|
|
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 isMa
|
|
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 ))
|
|
{
|
|
Index: kwin/workspace.cpp
|
|
===================================================================
|
|
--- kwin/workspace.cpp.orig
|
|
+++ kwin/workspace.cpp
|
|
@@ -82,6 +82,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),
|
|
@@ -202,7 +203,7 @@ Workspace::Workspace( bool restore )
|
|
client_keys = new KGlobalAccel( this );
|
|
initShortcuts();
|
|
tab_box = new TabBox( this );
|
|
- popupinfo = new PopupInfo( );
|
|
+ popupinfo = new PopupInfo( this );
|
|
|
|
init();
|
|
|
|
@@ -304,6 +305,7 @@ void Workspace::init()
|
|
NET::WM2ExtendedStrut |
|
|
NET::WM2KDETemporaryRules |
|
|
NET::WM2ShowingDesktop |
|
|
+ NET::WM2FullPlacement |
|
|
NET::WM2DesktopLayout |
|
|
0
|
|
,
|
|
@@ -1541,6 +1543,83 @@ void Workspace::setDesktopLayout( int, i
|
|
{ // DCOP-only, unused
|
|
}
|
|
|
|
+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 parti
|
|
+ // ally
|
|
+ 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::updateDesktopLayout()
|
|
{
|
|
// rootInfo->desktopLayoutCorner(); // I don't find this worth bothering, feel free to
|
|
Index: kwin/activation.cpp
|
|
===================================================================
|
|
--- kwin/activation.cpp.orig
|
|
+++ kwin/activation.cpp
|
|
@@ -360,6 +360,8 @@ void Workspace::takeActivity( Client* c,
|
|
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( Clie
|
|
{
|
|
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( Clie
|
|
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();
|
|
Index: kwin/kwinbindings.cpp
|
|
===================================================================
|
|
--- kwin/kwinbindings.cpp.orig
|
|
+++ 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() );
|