This change allows KWin to use the new NETWinInfo2 class (binary

compatibility class) and subsequently properly handle the
_NET_WM_FULLSCREEN_MONITORS EWMH spec hint.

svn path=/trunk/KDE/kdebase/workspace/; revision=885362
This commit is contained in:
Jason vanRijn Kasper 2008-11-17 08:03:39 +00:00
parent 0eb042c984
commit fb0a01228f
10 changed files with 78 additions and 10 deletions

View file

@ -151,6 +151,17 @@ version 1.2
? 7.7. ? 7.7.
+ 7. (rest of the section) + 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): ICCCM spec compliance (whole document):
version 2.0 version 2.0
====================== ======================

View file

@ -86,6 +86,7 @@ class Client
void setupWindowRules( bool ignore_temporary ); void setupWindowRules( bool ignore_temporary );
void applyWindowRules(); void applyWindowRules();
void updateWindowRules(); void updateWindowRules();
void updateFullscreenMonitors( NETFullscreenMonitors topology );
// returns true for "special" windows and false for windows which are "normal" // 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.) // (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 bool isManaged() const; // returns false if this client is not yet managed
void updateAllowedActions( bool force = false ); void updateAllowedActions( bool force = false );
QSize sizeForClientSize( const QSize&, Sizemode mode = SizemodeAny, bool noframe = false ) const; 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 changeMaximize( bool horizontal, bool vertical, bool adjust );
void checkMaximizeGeometry(); void checkMaximizeGeometry();
int checkFullScreenHack( const QRect& geom ) const; // 0 - none, 1 - one xinerama screen, 2 - full area 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 // NET WM Protocol handler class
class WinInfo : public NETWinInfo class WinInfo : public NETWinInfo2
{ {
private: private:
typedef KWin::Client Client; // because of NET::Client typedef KWin::Client Client; // because of NET::Client
@ -555,6 +557,7 @@ class WinInfo : public NETWinInfo
WinInfo( Client* c, Display * display, Window window, WinInfo( Client* c, Display * display, Window window,
Window rwin, const unsigned long pr[], int pr_size ); Window rwin, const unsigned long pr[], int pr_size );
virtual void changeDesktop(int desktop); virtual void changeDesktop(int desktop);
virtual void changeFullscreenMonitors(NETFullscreenMonitors topology);
virtual void changeState( unsigned long state, unsigned long mask ); virtual void changeState( unsigned long state, unsigned long mask );
void disable(); void disable();
private: private:

View file

@ -254,7 +254,7 @@ void Workspace::finishCompositing()
{ // forward all opacity values to the frame in case there'll be other CM running { // forward all opacity values to the frame in case there'll be other CM running
if( (*it)->opacity() != 1.0 ) 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 )); i.setOpacity( static_cast< unsigned long >((*it)->opacity() * 0xffffffff ));
} }
} }

View file

@ -59,7 +59,7 @@ namespace KWin
WinInfo::WinInfo( Client * c, Display * display, Window window, WinInfo::WinInfo( Client * c, Display * display, Window window,
Window rwin, const unsigned long pr[], int pr_size ) 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 ); 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 ) void WinInfo::changeState( unsigned long state, unsigned long mask )
{ {
mask &= ~NET::Sticky; // KWin doesn't support large desktops, ignore mask &= ~NET::Sticky; // KWin doesn't support large desktops, ignore
@ -622,7 +627,7 @@ bool Client::windowEvent( XEvent* e )
} }
else else
{ // forward to the frame if there's possibly another compositing manager running { // 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()); i.setOpacity( info->opacity());
} }
} }

View file

@ -2305,7 +2305,10 @@ void Client::setFullScreen( bool set, bool user )
info->setState( isFullScreen() ? NET::FullScreen : 0, NET::FullScreen ); info->setState( isFullScreen() ? NET::FullScreen : 0, NET::FullScreen );
updateDecoration( false, false ); updateDecoration( false, false );
if( isFullScreen()) if( isFullScreen())
setGeometry( workspace()->clientArea( FullScreenArea, this )); if( info->fullscreenMonitors().isSet())
setGeometry( fullscreenMonitorsArea( info->fullscreenMonitors()));
else
setGeometry( workspace()->clientArea( FullScreenArea, this ));
else else
{ {
if( !geom_fs_restore.isNull()) if( !geom_fs_restore.isNull())
@ -2320,6 +2323,51 @@ void Client::setFullScreen( bool set, bool user )
workspace()->checkUnredirect(); 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 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 // if it's noborder window, and has size of one screen or the whole desktop geometry, it's fullscreen hack

View file

@ -221,7 +221,7 @@ Group::Group( Window leader_P, Workspace* workspace_P )
{ {
leader_client = workspace_P->findClient( WindowMatchPredicate( leader_P )); leader_client = workspace_P->findClient( WindowMatchPredicate( leader_P ));
unsigned long properties[ 2 ] = { 0, NET::WM2StartupId }; 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 ); properties, 2 );
} }
effect_group = new EffectWindowGroupImpl( this ); effect_group = new EffectWindowGroupImpl( this );

View file

@ -62,7 +62,7 @@ class Group
Client* leader_client; Client* leader_client;
Window leader_wid; Window leader_wid;
Workspace* _workspace; Workspace* _workspace;
NETWinInfo* leader_info; NETWinInfo2* leader_info;
Time user_time; Time user_time;
int refcount; int refcount;
EffectWindowGroupImpl* effect_group; EffectWindowGroupImpl* effect_group;

View file

@ -94,6 +94,7 @@ bool Client::manage( Window w, bool isMapped )
NET::WM2StartupId | NET::WM2StartupId |
NET::WM2ExtendedStrut | NET::WM2ExtendedStrut |
NET::WM2Opacity | NET::WM2Opacity |
NET::WM2FullscreenMonitors |
0; 0;
info = new WinInfo( this, display(), client, rootWindow(), properties, 2 ); info = new WinInfo( this, display(), client, rootWindow(), properties, 2 );

View file

@ -35,7 +35,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <X11/extensions/Xdamage.h> #include <X11/extensions/Xdamage.h>
#endif #endif
class NETWinInfo; class NETWinInfo2;
namespace KWin namespace KWin
{ {
@ -151,7 +151,7 @@ class Toplevel
QRect geom; QRect geom;
Visual* vis; Visual* vis;
int bit_depth; int bit_depth;
NETWinInfo* info; NETWinInfo2* info;
bool ready_for_painting; bool ready_for_painting;
private: private:
static QByteArray staticWindowRole(WId); static QByteArray staticWindowRole(WId);

View file

@ -65,7 +65,7 @@ bool Unmanaged::track( Window w )
properties[ NETWinInfo::PROTOCOLS2 ] = properties[ NETWinInfo::PROTOCOLS2 ] =
NET::WM2Opacity | NET::WM2Opacity |
0; 0;
info = new NETWinInfo( display(), w, rootWindow(), properties, 2 ); info = new NETWinInfo2( display(), w, rootWindow(), properties, 2 );
getResourceClass(); getResourceClass();
getWindowRole(); getWindowRole();
getWmClientLeader(); getWmClientLeader();