shape windows support, some fixes for configure-request handling
svn path=/trunk/kdebase/kwin/; revision=33553
This commit is contained in:
parent
d94de9b5b6
commit
a30c061abb
4 changed files with 86 additions and 31 deletions
24
client.cpp
24
client.cpp
|
@ -13,6 +13,7 @@
|
|||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/extensions/shape.h>
|
||||
|
||||
extern Atom qt_wm_state;
|
||||
|
||||
|
@ -30,6 +31,7 @@ void Client::drawbound( const QRect& geom )
|
|||
p.setRasterOp( Qt::XorROP );
|
||||
p.drawRect( geom );
|
||||
}
|
||||
|
||||
void Client::clearbound()
|
||||
{
|
||||
if ( !visible_bound )
|
||||
|
@ -39,6 +41,16 @@ void Client::clearbound()
|
|||
visible_bound = 0;
|
||||
}
|
||||
|
||||
void Client::updateShape()
|
||||
{
|
||||
if ( shape() )
|
||||
XShapeCombineShape(qt_xdisplay(), winId(), ShapeBounding,
|
||||
windowWrapper()->x(), windowWrapper()->y(),
|
||||
window(), ShapeBounding, ShapeSet);
|
||||
else
|
||||
XShapeCombineMask( qt_xdisplay(), winId(), ShapeBounding, 0, 0,
|
||||
None, ShapeSet);
|
||||
}
|
||||
|
||||
static void sendClientMessage(Window w, Atom a, long x){
|
||||
XEvent ev;
|
||||
|
@ -116,7 +128,6 @@ WindowWrapper::WindowWrapper( WId w, Client *parent, const char* name)
|
|||
StructureNotifyMask
|
||||
);
|
||||
|
||||
|
||||
// install a passive grab to catch mouse button events
|
||||
XGrabButton(qt_xdisplay(), AnyButton, AnyModifier, winId(), FALSE,
|
||||
ButtonPressMask, GrabModeSync, GrabModeSync,
|
||||
|
@ -145,7 +156,9 @@ void WindowWrapper::resizeEvent( QResizeEvent * )
|
|||
if ( win ) {
|
||||
XMoveResizeWindow( qt_xdisplay(), win,
|
||||
0, 0, width(), height() );
|
||||
}
|
||||
if ( ((Client*)parentWidget())->shape() )
|
||||
((Client*)parentWidget())->updateShape();
|
||||
}
|
||||
}
|
||||
|
||||
void WindowWrapper::showEvent( QShowEvent* )
|
||||
|
@ -262,7 +275,7 @@ Client::Client( Workspace *ws, WId w, QWidget *parent, const char *name, WFlags
|
|||
active = FALSE;
|
||||
shaded = FALSE;
|
||||
transient_for = None;
|
||||
is_sticky = FALSE;
|
||||
is_shape = FALSE;
|
||||
|
||||
getIcons();
|
||||
getWindowProtocols();
|
||||
|
@ -325,6 +338,11 @@ void Client::manage( bool isMapped )
|
|||
placementDone = TRUE;
|
||||
}
|
||||
|
||||
if ( (is_shape = Shape::hasShape( win )) ) {
|
||||
updateShape();
|
||||
}
|
||||
|
||||
|
||||
// ### TODO check XGetWMHints() for initial mapping state, icon, etc. pp.
|
||||
// assume window wants to be visible on the current desktop
|
||||
desk = KWM::desktop( win ); //workspace()->currentDesktop();
|
||||
|
|
11
client.h
11
client.h
|
@ -118,6 +118,11 @@ public:
|
|||
// transparent stuff
|
||||
virtual void drawbound( const QRect& geom );
|
||||
virtual void clearbound();
|
||||
|
||||
|
||||
// shape extensions
|
||||
bool shape() const;
|
||||
void updateShape();
|
||||
|
||||
public slots:
|
||||
void iconify();
|
||||
|
@ -196,6 +201,7 @@ private:
|
|||
bool shaded;
|
||||
WId transient_for;
|
||||
bool is_sticky;
|
||||
bool is_shape;
|
||||
void getIcons();
|
||||
void getWindowProtocols();
|
||||
uint Pdeletewindow :1; // does the window understand the DeleteWindow protocol?
|
||||
|
@ -283,6 +289,11 @@ inline bool Client::isSticky() const
|
|||
}
|
||||
|
||||
|
||||
inline bool Client::shape() const
|
||||
{
|
||||
return is_shape;
|
||||
}
|
||||
|
||||
class NoBorderClient : public Client
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
|
@ -14,6 +14,31 @@
|
|||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/extensions/shape.h>
|
||||
|
||||
// used to store the return values of
|
||||
// XShapeQueryExtension.
|
||||
// Necessary since shaped window are an extension to X
|
||||
static int kwin_has_shape = 0;
|
||||
static int kwin_shape_event = 0;
|
||||
|
||||
// does the window w need a shape combine mask around it?
|
||||
bool Shape::hasShape( WId w){
|
||||
int xws, yws, xbs, ybs;
|
||||
unsigned wws, hws, wbs, hbs;
|
||||
int boundingShaped, clipShaped;
|
||||
if (!kwin_has_shape)
|
||||
return FALSE;
|
||||
XShapeQueryExtents(qt_xdisplay(), w,
|
||||
&boundingShaped, &xws, &yws, &wws, &hws,
|
||||
&clipShaped, &xbs, &ybs, &wbs, &hbs);
|
||||
return boundingShaped != 0;
|
||||
}
|
||||
|
||||
int Shape::shapeEvent()
|
||||
{
|
||||
return kwin_shape_event;
|
||||
}
|
||||
|
||||
|
||||
static Client* clientFactory( Workspace *ws, WId w )
|
||||
|
@ -37,17 +62,21 @@ static Client* clientFactory( Workspace *ws, WId w )
|
|||
c->setSticky( TRUE );
|
||||
return c;
|
||||
}
|
||||
|
||||
if ( Shape::hasShape( w ) ){
|
||||
return new NoBorderClient( ws, w );
|
||||
}
|
||||
|
||||
KConfig *config = KGlobal::config();
|
||||
config->setGroup("style");
|
||||
// well, it will be soon ;-)
|
||||
QString tmpStr = config->readEntry("Plugin", "standard");
|
||||
if(tmpStr == "standard")
|
||||
return new StdClient( ws, w );
|
||||
else if(tmpStr == "system")
|
||||
return new SystemClient( ws, w );
|
||||
if(tmpStr == "system")
|
||||
return new SystemClient( ws, w );
|
||||
else if(tmpStr == "be")
|
||||
return new BeClient( ws, w );
|
||||
return new BeClient( ws, w );
|
||||
else
|
||||
return new StdClient( ws, w );
|
||||
}
|
||||
|
||||
Workspace::Workspace()
|
||||
|
@ -66,6 +95,9 @@ Workspace::Workspace()
|
|||
SubstructureNotifyMask
|
||||
);
|
||||
|
||||
int dummy;
|
||||
kwin_has_shape = XShapeQueryExtension(qt_xdisplay(), &kwin_shape_event, &dummy);
|
||||
|
||||
init();
|
||||
control_grab = FALSE;
|
||||
tab_grab = FALSE;
|
||||
|
@ -227,7 +259,10 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
}
|
||||
break;
|
||||
case ConfigureRequest:
|
||||
if ( e->xconfigurerequest.parent == root ) {
|
||||
c = findClient( e->xconfigurerequest.window );
|
||||
if ( c )
|
||||
return c->windowEvent( e );
|
||||
else if ( e->xconfigurerequest.parent == root ) {
|
||||
XWindowChanges wc;
|
||||
unsigned int value_mask = 0;
|
||||
wc.border_width = 0;
|
||||
|
@ -239,29 +274,9 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
wc.stack_mode = Above;
|
||||
value_mask = e->xconfigurerequest.value_mask | CWBorderWidth;
|
||||
XConfigureWindow( qt_xdisplay(), e->xconfigurerequest.window, value_mask, & wc );
|
||||
|
||||
XWindowAttributes attr;
|
||||
if (XGetWindowAttributes(qt_xdisplay(), e->xconfigurerequest.window, &attr)){
|
||||
// send a synthetic configure notify in any case (even if we didn't change anything)
|
||||
XConfigureEvent c;
|
||||
c.type = ConfigureNotify;
|
||||
c.event = e->xconfigurerequest.window;
|
||||
c.window = e->xconfigurerequest.window;
|
||||
c.x = attr.x;
|
||||
c.y = attr.y;
|
||||
c.width = attr.width;
|
||||
c.height = attr.height;
|
||||
c.border_width = 0;
|
||||
XSendEvent( qt_xdisplay(), c.event, TRUE, NoEventMask, (XEvent*)&c );
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
c = findClient( e->xconfigurerequest.window );
|
||||
if ( c )
|
||||
return c->windowEvent( e );
|
||||
}
|
||||
|
||||
break;
|
||||
case KeyPress:
|
||||
return keyPress(e->xkey);
|
||||
|
@ -277,6 +292,11 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
return clientMessage(e->xclient);
|
||||
break;
|
||||
default:
|
||||
if ( e->type == Shape::shapeEvent() ) {
|
||||
c = findClient( ((XShapeEvent *)e)->window );
|
||||
if ( c )
|
||||
c->updateShape();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
|
|
|
@ -15,6 +15,12 @@ class KGlobalAccel;
|
|||
typedef QValueList<Client*> ClientList;
|
||||
typedef QValueList<WId> WIdList;
|
||||
|
||||
class Shape {
|
||||
public:
|
||||
static bool hasShape( WId w);
|
||||
static int shapeEvent();
|
||||
};
|
||||
|
||||
class Workspace : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -105,7 +111,7 @@ private:
|
|||
void setDecoration( int deco );
|
||||
|
||||
void propagateClients( bool onlyStacking = FALSE);
|
||||
|
||||
|
||||
WIdList dockwins;
|
||||
bool addDockwin( WId w );
|
||||
bool removeDockwin( WId w );
|
||||
|
|
Loading…
Reference in a new issue