From ff404156032b2ed8f7fdd95b091aa2df169b5219 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan <fourdan.olivier@wanadoo.fr> Date: Tue, 5 Oct 2004 21:37:29 +0000 Subject: [PATCH] Fix XShape bug, now gkrellm and other shaped windows work. (Old svn revision: 12035) --- src/client.c | 8 +++-- src/compositor.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ src/compositor.h | 3 +- src/events.c | 3 +- 4 files changed, 94 insertions(+), 5 deletions(-) diff --git a/src/client.c b/src/client.c index b886e38b9..c52f72af4 100644 --- a/src/client.c +++ b/src/client.c @@ -1359,6 +1359,7 @@ clientFrame (DisplayInfo *display_info, Window w, gboolean recapture) XWindowChanges wc; XSetWindowAttributes attributes; Client *c = NULL; + gboolean shaped; unsigned long valuemask; int i; @@ -1457,8 +1458,9 @@ clientFrame (DisplayInfo *display_info, Window w, gboolean recapture) c->fullscreen_old_height = c->height; c->border_width = attr.border_width; c->cmap = attr.colormap; - - if (clientCheckShape(c)) + + shaped = clientCheckShape(c); + if (shaped) { FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_HAS_BORDER); } @@ -1593,7 +1595,7 @@ clientFrame (DisplayInfo *display_info, Window w, gboolean recapture) valuemask = CWEventMask; attributes.event_mask = (CLIENT_EVENT_MASK); XChangeWindowAttributes (display_info->dpy, c->window, valuemask, &attributes); - if (display_info->shape) + if ((shaped) && (display_info->shape)) { XShapeSelectInput (display_info->dpy, c->window, ShapeNotifyMask); } diff --git a/src/compositor.c b/src/compositor.c index 64ad12393..cb2cdefc8 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -1473,6 +1473,58 @@ restack_win (CWindow *cw, Window above) } } +void +resize_win (CWindow *cw, gint width, gint height) +{ + XserverRegion damage = None; + + g_return_if_fail (cw != NULL); + TRACE ("entering resize_win"); + + damage = XFixesCreateRegion (myScreenGetXDisplay (cw->screen_info), NULL, 0); + if ((damage != None) && (cw->extents != None)) + { + XFixesCopyRegion (myScreenGetXDisplay (cw->screen_info), damage, cw->extents); + } + + if ((cw->attr.width != width) || (cw->attr.height != height)) + { +#if HAVE_NAME_WINDOW_PIXMAP + if (cw->name_window_pixmap) + { + XFreePixmap (myScreenGetXDisplay (cw->screen_info), cw->name_window_pixmap); + cw->name_window_pixmap = None; + } +#endif + if (cw->picture) + { + XRenderFreePicture (myScreenGetXDisplay (cw->screen_info), cw->picture); + cw->picture = None; + } + + if (cw->shadow) + { + XRenderFreePicture (myScreenGetXDisplay (cw->screen_info), cw->shadow); + cw->shadow = None; + } + } + cw->attr.width = width; + cw->attr.height = height; + + if (damage) + { + XserverRegion extents = win_extents (cw); + if (extents) + { + XFixesUnionRegion (myScreenGetXDisplay (cw->screen_info), damage, damage, extents); + XFixesDestroyRegion (myScreenGetXDisplay (cw->screen_info), extents); + add_damage (cw->screen_info, damage); + } + } + cw->screen_info->clipChanged = TRUE; + repair_screen (cw->screen_info); +} + static void destroy_win (ScreenInfo *screen_info, Window id, gboolean gone) { @@ -1659,6 +1711,15 @@ compositorHandleConfigureNotify (DisplayInfo *display_info, XConfigureEvent *ev) return; } + if ((cw->attr.x == ev->x) && (cw->attr.y == ev->y) && + (cw->attr.width == ev->width) && (cw->attr.height == ev->height) && + (cw->attr.border_width == ev->border_width)) + { + /* Nothing has changed, just adjust stack */ + restack_win (cw, ev->above); + return; + } + damage = XFixesCreateRegion (display_info->dpy, NULL, 0); if ((damage != None) && (cw->extents != None)) { @@ -2123,3 +2184,27 @@ compositorDamageWindow (DisplayInfo *display_info, Window id) } #endif /* HAVE_COMPOSITOR */ } + +void +compositorResizeWindow (DisplayInfo *display_info, Window id, gint new_width, gint new_height) +{ +#ifdef HAVE_COMPOSITOR + CWindow *cw; + + g_return_if_fail (display_info != NULL); + g_return_if_fail (id != None); + TRACE ("entering compositorResizeWindow: 0x%lx", id); + + if (!(display_info->enable_compositor)) + { + TRACE ("compositor disabled"); + return; + } + + cw = find_cwindow_in_display (display_info, id); + if (cw) + { + resize_win (cw, new_width, new_height); + } +#endif /* HAVE_COMPOSITOR */ +} diff --git a/src/compositor.h b/src/compositor.h index 0a7d2a39c..9f507dfd7 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -36,7 +36,6 @@ void compositorWindowMap (DisplayInfo *, Window); void compositorWindowUnmap (DisplayInfo *, Window); void compositorAddWindow (DisplayInfo *, Window, Client *c); void compositorRemoveWindow (DisplayInfo *, Window); -void compositorWindowSetOpacity (DisplayInfo *, Window, guint); void compositorHandleEvent (DisplayInfo *, XEvent *); void compositorInitDisplay (DisplayInfo *); @@ -44,6 +43,8 @@ void compositorInitDisplay (DisplayInfo *); void compositorManageScreen (ScreenInfo *); void compositorUnmanageScreen (ScreenInfo *); +void compositorWindowSetOpacity (DisplayInfo *, Window, guint); void compositorDamageWindow (DisplayInfo *, Window); +void compositorResizeWindow (DisplayInfo *, Window, gint, gint); #endif /* INC_COMPOSITOR_H */ diff --git a/src/events.c b/src/events.c index bd5338d7f..941a648b8 100644 --- a/src/events.c +++ b/src/events.c @@ -1775,10 +1775,11 @@ handleShape (DisplayInfo *display_info, XShapeEvent * ev) if (c) { frameDraw (c, FALSE, TRUE); + compositorResizeWindow (display_info, c->frame, ev->width + ev->x, ev->height + ev->y); } else { - compositorDamageWindow (display_info, ev->window); + compositorResizeWindow (display_info, ev->window, ev->width + ev->x, ev->height + ev->y); } } -- GitLab