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