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
icc-effect-5.14.5
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. (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
======================

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -35,7 +35,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <X11/extensions/Xdamage.h>
#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);

View File

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