diff --git a/COMPLIANCE b/COMPLIANCE
index e63455e4f6..e3f01a4781 100644
--- a/COMPLIANCE
+++ b/COMPLIANCE
@@ -151,6 +151,17 @@ version 1.2
? 7.7.
+ 7. (rest of the section)
+
++ _NET_WM_FULLSCREEN_MONITORS Status: Done.
+ +----------------------------------------------------------------+
+ | The Window Manager MUST keep this list updated to reflect the |
+ | current state of the window. The application window sends this |
+ | in a ClientMessage to the root window. KWin persists this info |
+ | both internally as well as against the application window. |
+ | This data is used to spread the fullscreen application window |
+ | across the requested topology, if valid. |
+ +----------------------------------------------------------------+
+
ICCCM spec compliance (whole document):
version 2.0
======================
diff --git a/client.h b/client.h
index b05e29fc8a..fade99c2c1 100644
--- a/client.h
+++ b/client.h
@@ -86,6 +86,7 @@ class Client
void setupWindowRules( bool ignore_temporary );
void applyWindowRules();
void updateWindowRules();
+ void updateFullscreenMonitors( NETFullscreenMonitors topology );
// returns true for "special" windows and false for windows which are "normal"
// (normal=window which has a border, can be moved by the user, can be closed, etc.)
@@ -349,6 +350,7 @@ class Client
bool isManaged() const; // returns false if this client is not yet managed
void updateAllowedActions( bool force = false );
QSize sizeForClientSize( const QSize&, Sizemode mode = SizemodeAny, bool noframe = false ) const;
+ QRect fullscreenMonitorsArea( NETFullscreenMonitors topology ) const;
void changeMaximize( bool horizontal, bool vertical, bool adjust );
void checkMaximizeGeometry();
int checkFullScreenHack( const QRect& geom ) const; // 0 - none, 1 - one xinerama screen, 2 - full area
@@ -547,7 +549,7 @@ class GeometryUpdatesBlocker
// NET WM Protocol handler class
-class WinInfo : public NETWinInfo
+class WinInfo : public NETWinInfo2
{
private:
typedef KWin::Client Client; // because of NET::Client
@@ -555,6 +557,7 @@ class WinInfo : public NETWinInfo
WinInfo( Client* c, Display * display, Window window,
Window rwin, const unsigned long pr[], int pr_size );
virtual void changeDesktop(int desktop);
+ virtual void changeFullscreenMonitors(NETFullscreenMonitors topology);
virtual void changeState( unsigned long state, unsigned long mask );
void disable();
private:
diff --git a/composite.cpp b/composite.cpp
index d5c9558c0c..7b797b278e 100644
--- a/composite.cpp
+++ b/composite.cpp
@@ -254,7 +254,7 @@ void Workspace::finishCompositing()
{ // forward all opacity values to the frame in case there'll be other CM running
if( (*it)->opacity() != 1.0 )
{
- NETWinInfo i( display(), (*it)->frameId(), rootWindow(), 0 );
+ NETWinInfo2 i( display(), (*it)->frameId(), rootWindow(), 0 );
i.setOpacity( static_cast< unsigned long >((*it)->opacity() * 0xffffffff ));
}
}
diff --git a/events.cpp b/events.cpp
index 2bfff7f33f..35ed98447b 100644
--- a/events.cpp
+++ b/events.cpp
@@ -59,7 +59,7 @@ namespace KWin
WinInfo::WinInfo( Client * c, Display * display, Window window,
Window rwin, const unsigned long pr[], int pr_size )
- : NETWinInfo( display, window, rwin, pr, pr_size, NET::WindowManager ), m_client( c )
+ : NETWinInfo2( display, window, rwin, pr, pr_size, NET::WindowManager ), m_client( c )
{
}
@@ -68,6 +68,11 @@ void WinInfo::changeDesktop(int desktop)
m_client->workspace()->sendClientToDesktop( m_client, desktop, true );
}
+void WinInfo::changeFullscreenMonitors( NETFullscreenMonitors topology )
+ {
+ m_client->updateFullscreenMonitors( topology );
+ }
+
void WinInfo::changeState( unsigned long state, unsigned long mask )
{
mask &= ~NET::Sticky; // KWin doesn't support large desktops, ignore
@@ -622,7 +627,7 @@ bool Client::windowEvent( XEvent* e )
}
else
{ // forward to the frame if there's possibly another compositing manager running
- NETWinInfo i( display(), frameId(), rootWindow(), 0 );
+ NETWinInfo2 i( display(), frameId(), rootWindow(), 0 );
i.setOpacity( info->opacity());
}
}
diff --git a/geometry.cpp b/geometry.cpp
index b45f51cad5..741fd47abb 100644
--- a/geometry.cpp
+++ b/geometry.cpp
@@ -2305,7 +2305,10 @@ void Client::setFullScreen( bool set, bool user )
info->setState( isFullScreen() ? NET::FullScreen : 0, NET::FullScreen );
updateDecoration( false, false );
if( isFullScreen())
- setGeometry( workspace()->clientArea( FullScreenArea, this ));
+ if( info->fullscreenMonitors().isSet())
+ setGeometry( fullscreenMonitorsArea( info->fullscreenMonitors()));
+ else
+ setGeometry( workspace()->clientArea( FullScreenArea, this ));
else
{
if( !geom_fs_restore.isNull())
@@ -2320,6 +2323,51 @@ void Client::setFullScreen( bool set, bool user )
workspace()->checkUnredirect();
}
+
+void Client::updateFullscreenMonitors( NETFullscreenMonitors topology )
+ {
+ int nscreens = Kephal::ScreenUtils::numScreens();
+
+// kDebug( 1212 ) << "incoming request with top: " << topology.top << " bottom: " << topology.bottom
+// << " left: " << topology.left << " right: " << topology.right
+// << ", we have: " << nscreens << " screens.";
+
+ if( topology.top >= nscreens ||
+ topology.bottom >= nscreens ||
+ topology.left >= nscreens ||
+ topology.right >= nscreens )
+ {
+ kWarning( 1212 ) << "fullscreenMonitors update failed. request higher than number of screens.";
+ return;
+ }
+
+ info->setFullscreenMonitors( topology );
+ if( isFullScreen())
+ setGeometry( fullscreenMonitorsArea( topology ));
+ }
+
+
+/*!
+ Calculates the bounding rectangle defined by the 4 monitor indices indicating the
+ top, bottom, left, and right edges of the window when the fullscreen state is enabled.
+ */
+QRect Client::fullscreenMonitorsArea(NETFullscreenMonitors requestedTopology) const
+ {
+ QRect top, bottom, left, right, total;
+
+ top = Kephal::ScreenUtils::screenGeometry( requestedTopology.top );
+ bottom = Kephal::ScreenUtils::screenGeometry(requestedTopology.bottom );
+ left = Kephal::ScreenUtils::screenGeometry(requestedTopology.left );
+ right = Kephal::ScreenUtils::screenGeometry(requestedTopology.right );
+ total = top.united( bottom.united( left.united( right ) ) );
+
+// kDebug( 1212 ) << "top: " << top << " bottom: " << bottom
+// << " left: " << left << " right: " << right;
+// kDebug( 1212 ) << "returning rect: " << total;
+ return total;
+ }
+
+
int Client::checkFullScreenHack( const QRect& geom ) const
{
// if it's noborder window, and has size of one screen or the whole desktop geometry, it's fullscreen hack
diff --git a/group.cpp b/group.cpp
index e7cf5628c9..a6303eaa52 100644
--- a/group.cpp
+++ b/group.cpp
@@ -221,7 +221,7 @@ Group::Group( Window leader_P, Workspace* workspace_P )
{
leader_client = workspace_P->findClient( WindowMatchPredicate( leader_P ));
unsigned long properties[ 2 ] = { 0, NET::WM2StartupId };
- leader_info = new NETWinInfo( display(), leader_P, rootWindow(),
+ leader_info = new NETWinInfo2( display(), leader_P, rootWindow(),
properties, 2 );
}
effect_group = new EffectWindowGroupImpl( this );
diff --git a/group.h b/group.h
index 268f3c1f57..5776183cf4 100644
--- a/group.h
+++ b/group.h
@@ -62,7 +62,7 @@ class Group
Client* leader_client;
Window leader_wid;
Workspace* _workspace;
- NETWinInfo* leader_info;
+ NETWinInfo2* leader_info;
Time user_time;
int refcount;
EffectWindowGroupImpl* effect_group;
diff --git a/manage.cpp b/manage.cpp
index 8661d8e9df..a0a6fd008e 100644
--- a/manage.cpp
+++ b/manage.cpp
@@ -94,6 +94,7 @@ bool Client::manage( Window w, bool isMapped )
NET::WM2StartupId |
NET::WM2ExtendedStrut |
NET::WM2Opacity |
+ NET::WM2FullscreenMonitors |
0;
info = new WinInfo( this, display(), client, rootWindow(), properties, 2 );
diff --git a/toplevel.h b/toplevel.h
index 99476a9b2c..f0cdfb0441 100644
--- a/toplevel.h
+++ b/toplevel.h
@@ -35,7 +35,7 @@ along with this program. If not, see .
#include
#endif
-class NETWinInfo;
+class NETWinInfo2;
namespace KWin
{
@@ -151,7 +151,7 @@ class Toplevel
QRect geom;
Visual* vis;
int bit_depth;
- NETWinInfo* info;
+ NETWinInfo2* info;
bool ready_for_painting;
private:
static QByteArray staticWindowRole(WId);
diff --git a/unmanaged.cpp b/unmanaged.cpp
index 0a703de516..083f9c265c 100644
--- a/unmanaged.cpp
+++ b/unmanaged.cpp
@@ -65,7 +65,7 @@ bool Unmanaged::track( Window w )
properties[ NETWinInfo::PROTOCOLS2 ] =
NET::WM2Opacity |
0;
- info = new NETWinInfo( display(), w, rootWindow(), properties, 2 );
+ info = new NETWinInfo2( display(), w, rootWindow(), properties, 2 );
getResourceClass();
getWindowRole();
getWmClientLeader();