Implement support for _KDE_NET_WM_FRAME_OVERLAP.

svn path=/trunk/KDE/kdebase/workspace/; revision=1054393
icc-effect-5.14.5
Fredrik Höglund 2009-11-25 23:32:35 +00:00
parent ffdadc4844
commit 0a8c06b054
20 changed files with 111 additions and 8 deletions

View File

@ -208,6 +208,11 @@ bool Bridge::compositingActive() const
return c->workspace()->compositingActive();
}
QRect Bridge::transparentRect() const
{
return c->transparentRect().translated(-c->decorationRect().topLeft());
}
bool Bridge::isClientGroupActive()
{
return c->clientGroup()->containsActiveClient();

View File

@ -76,6 +76,7 @@ class Bridge : public KDecorationBridgeUnstable
virtual void grabXServer( bool grab );
virtual bool compositingActive() const;
virtual QRect transparentRect() const;
// Window tabbing
virtual bool isClientGroupActive();

View File

@ -445,13 +445,23 @@ void Client::layoutDecorationRects(QRect &left, QRect &top, QRect &right, QRect
if (mode == WindowRelative)
r.translate(-padding_left, -padding_top);
top = QRect(r.x(), r.y(), r.width(), padding_top + border_top);
bottom = QRect(r.x(), r.y() + r.height() - padding_bottom - border_bottom,
r.width(), padding_bottom + border_bottom);
NETStrut strut = info->frameOverlap();
if (strut.left == -1 && strut.top == -1 && strut.right == -1 && strut.bottom == -1)
{
top = QRect(r.x(), r.y(), r.width(), r.height() / 3);
left = QRect(r.x(), r.y() + top.height(), width() / 2, r.height() / 3);
right = QRect(r.x() + left.width(), r.y() + top.height(), r.width() - left.width(), left.height());
bottom = QRect(r.x(), r.y() + top.height() + left.height(), r.width(), r.height() - left.height() - top.height());
return;
}
top = QRect(r.x(), r.y(), r.width(), padding_top + border_top + strut.top);
bottom = QRect(r.x(), r.y() + r.height() - padding_bottom - border_bottom - strut.bottom,
r.width(), padding_bottom + border_bottom + strut.bottom);
left = QRect(r.x(), r.y() + top.height(),
padding_left + border_left, r.height() - top.height() - bottom.height());
right = QRect(r.x() + r.width() - padding_right - border_right, r.y() + top.height(),
padding_right + border_right, r.height() - top.height() - bottom.height());
padding_left + border_left + strut.left, r.height() - top.height() - bottom.height());
right = QRect(r.x() + r.width() - padding_right - border_right - strut.right, r.y() + top.height(),
padding_right + border_right + strut.right, r.height() - top.height() - bottom.height());
}
QRegion Client::decorationPendingRegion() const
@ -581,6 +591,20 @@ void Client::resizeDecorationPixmaps()
triggerDecorationRepaint();
}
QRect Client::transparentRect() const
{
NETStrut strut = info->frameOverlap();
if (strut.left == -1 && strut.top == -1 && strut.right == -1 && strut.bottom == -1)
return QRect();
const QRect r = QRect(clientPos(), clientSize())
.adjusted(strut.left, strut.top, -strut.right, -strut.bottom);
if (r.isValid())
return r;
return QRect();
}
void Client::detectNoBorder()
{
if( shape())

View File

@ -358,6 +358,8 @@ class Client
QRect(0, 0, width(), height());
}
QRect transparentRect() const;
QRegion decorationPendingRegion() const;
enum CoordinateMode {

View File

@ -68,6 +68,7 @@ void Deleted::copyToDeleted( Toplevel* c )
Toplevel::copyToDeleted( c );
desk = c->desktop();
contentsRect = QRect( c->clientPos(), c->clientSize());
transparent_rect = c->transparentRect();
if( WinInfo* cinfo = dynamic_cast< WinInfo* >( info ))
cinfo->disable();
Client* client = dynamic_cast<Client*>(c);
@ -138,6 +139,11 @@ QRect Deleted::decorationRect() const
return rect().adjusted(-padding_left, -padding_top, padding_top, padding_bottom);
}
QRect Deleted::transparentRect() const
{
return transparent_rect;
}
} // namespace
#include "deleted.moc"

View File

@ -39,6 +39,7 @@ class Deleted
virtual int desktop() const;
virtual QPoint clientPos() const;
virtual QSize clientSize() const;
virtual QRect transparentRect() const;
const QPixmap *topDecoPixmap() const { return &decorationPixmapTop; }
const QPixmap *leftDecoPixmap() const { return &decorationPixmapLeft; }
const QPixmap *bottomDecoPixmap() const { return &decorationPixmapBottom; }
@ -58,6 +59,7 @@ class Deleted
double window_opacity;
int desk;
QRect contentsRect; // for clientPos()/clientSize()
QRect transparent_rect;
QPixmap decorationPixmapLeft;
QPixmap decorationPixmapRight;

View File

@ -634,6 +634,10 @@ bool Client::windowEvent( XEvent* e )
i.setOpacity( info->opacity());
}
}
if( dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2FrameOverlap )
{
// ### Inform the decoration
}
}
switch (e->type)

View File

@ -467,6 +467,11 @@ bool KDecorationPreviewBridge::compositingActive() const
return KWindowSystem::compositingActive();
}
QRect KDecorationPreviewBridge::transparentRect() const
{
return QRect();
}
// Window tabbing
bool KDecorationPreviewBridge::isClientGroupActive()

View File

@ -115,6 +115,7 @@ class KDecorationPreviewBridge
virtual void grabXServer( bool grab );
virtual bool compositingActive() const;
virtual QRect transparentRect() const;
// Window tabbing
virtual bool isClientGroupActive();

View File

@ -932,6 +932,10 @@ QRect KCommonDecoration::titleRect() const
titleEdgeBottomBottom-(r_y+titleEdgeTop) );
}
QRect KCommonDecoration::transparentRect() const
{
return wrapper->transparentRect();
}
KCommonDecorationButton::KCommonDecorationButton(ButtonType type, KCommonDecoration *parent)
: QAbstractButton(parent?parent->widget():0 ),

View File

@ -233,6 +233,22 @@ class KWIN_EXPORT KCommonDecoration : public QObject, public KDecorationDefines
*/
QRect titleRect() const;
/**
* Returns the rectangle within the decoration that should be transparent.
*
* Usually this is the rectangle occupied by the client window,
* but a smaller rectangle may be returned if the client has specified
* that the window decoration should extend below the client area.
*
* If the client has requested that the decoration should cover the whole
* client area, a null rectangle is returned.
*
* The returned rectangle is never larger than the client area.
*
* @since 4.4
*/
QRect transparentRect() const;
public:
/**
* Handles widget and layout creation, call the base implementation when subclassing this member.

View File

@ -382,6 +382,14 @@ KDecoration::Position KDecoration::mousePosition( const QPoint& p ) const
return m;
}
QRect KDecoration::transparentRect() const
{
if (KDecorationBridgeUnstable *bridge2 = dynamic_cast<KDecorationBridgeUnstable*>(bridge_))
return bridge2->transparentRect();
else
return QRect();
}
KDecorationUnstable::KDecorationUnstable( KDecorationBridge* bridge, KDecorationFactory* factory )
: KDecoration( bridge, factory )

View File

@ -628,6 +628,20 @@ class KWIN_EXPORT KDecoration
* Convenience function that returns the height of the decoration.
*/
int height() const; // convenience
/**
* Returns the rectangle within the window frame that should be transparent.
* Usually this rectangle is the same as the client area, and it is never
* larger.
*
* If the client has requested that the window frame is extended into the
* client area, this rectangle is smaller than the client area.
*
* If the window frame should cover the whole client area, a null rectangle
* is returned.
*
* @since 4.4
*/
QRect transparentRect() const;
/**
* This function is the default handler for mouse events. All mouse events
* that are not handled by the decoration itself should be passed to it

View File

@ -94,6 +94,7 @@ class KWIN_EXPORT KDecorationBridgeUnstable
{
public:
virtual bool compositingActive() const = 0;
virtual QRect transparentRect() const = 0;
// Window tabbing
virtual bool isClientGroupActive() = 0;

View File

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

View File

@ -482,10 +482,11 @@ WindowQuadList Scene::Window::buildQuads( bool force ) const
{
Client *client = dynamic_cast<Client*>( toplevel );
QRegion contents = clientShape();
QRegion center = client->transparentRect();
QRegion decoration = (client && Workspace::self()->decorationHasAlpha() ?
QRegion(client->decorationRect()) : shape()) - contents;
QRegion(client->decorationRect()) : shape()) - center;
ret = makeQuads( WindowQuadContents, contents );
if( (client && !client->isShade()) || !client )
if( !client || !(center.isEmpty() || client->isShade()) )
ret += makeQuads( WindowQuadDecoration, decoration );
else
{

View File

@ -66,6 +66,7 @@ class Toplevel
virtual QSize clientSize() const = 0;
virtual QRect visibleRect() const; // the area the window occupies on the screen
virtual QRect decorationRect() const; // rect including the decoration shadows
virtual QRect transparentRect() const = 0;
virtual QRegion decorationPendingRegion() const; // decoration region that needs to be repainted
// prefer isXXX() instead

View File

@ -122,6 +122,11 @@ QSize Unmanaged::clientSize() const
return size();
}
QRect Unmanaged::transparentRect() const
{
return QRect(clientPos(), clientSize());
}
void Unmanaged::debug( kdbgstream& stream ) const
{
stream << "\'ID:" << window() << "\'";

View File

@ -41,6 +41,7 @@ class Unmanaged
virtual int desktop() const;
virtual QPoint clientPos() const;
virtual QSize clientSize() const;
virtual QRect transparentRect() const;
protected:
virtual void debug( kdbgstream& stream ) const;
virtual bool shouldUnredirect() const;

View File

@ -324,6 +324,7 @@ void Workspace::init()
NET::WM2DesktopLayout |
NET::WM2FullPlacement |
NET::WM2FullscreenMonitors |
NET::WM2FrameOverlap |
0
,
NET::ActionMove |