shape windows support, some fixes for configure-request handling

svn path=/trunk/kdebase/kwin/; revision=33553
This commit is contained in:
Matthias Ettrich 1999-11-12 03:11:19 +00:00
parent d94de9b5b6
commit a30c061abb
4 changed files with 86 additions and 31 deletions

View file

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

View file

@ -119,6 +119,11 @@ public:
virtual void drawbound( const QRect& geom );
virtual void clearbound();
// shape extensions
bool shape() const;
void updateShape();
public slots:
void iconify();
void closeWindow();
@ -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

View file

@ -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 )
@ -38,16 +63,20 @@ static Client* clientFactory( Workspace *ws, WId w )
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;
@ -240,28 +275,8 @@ bool Workspace::workspaceEvent( XEvent * e )
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;

View file

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