From f13c078df3041afbf1b9d4fdbb502b426c46640c Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 11 Dec 2015 18:56:04 +0200 Subject: [PATCH] React to ReparentNotify events When a reparenting window manager is in use, new windows appear on the root window first and immediately get reparented. We must unredirect them so the contents appear in the window manager frame. --- source/main.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/source/main.c b/source/main.c index 9865eb9..c37ecc8 100644 --- a/source/main.c +++ b/source/main.c @@ -310,7 +310,7 @@ void add_window(Compositor *compositor, CompositedScreen *screen, Window w) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } -void remove_window(CompositedScreen *screen, Window w) +void remove_window(Compositor *compositor, CompositedScreen *screen, Window w, int destroyed) { unsigned i; @@ -318,6 +318,16 @@ void remove_window(CompositedScreen *screen, Window w) if(screen->windows[i].window==w) { glDeleteTextures(1, &screen->windows[i].texture); + if(!destroyed) + { + XDamageDestroy(compositor->display, screen->windows[i].damage); + if(screen->windows[i].pixmap) + { + glXDestroyPixmap(compositor->display, screen->windows[i].glx_pixmap); + XFreePixmap(compositor->display, screen->windows[i].pixmap); + } + XCompositeUnredirectWindow(compositor->display, screen->windows[i].window, CompositeRedirectManual); + } --screen->nwindows; for(; inwindows; ++i) @@ -508,7 +518,7 @@ void process_destroy_window_event(Compositor *compositor, XDestroyWindowEvent *e if(!screen) return; - remove_window(screen, event->window); + remove_window(compositor, screen, event->window, 1); } void process_map_event(Compositor *compositor, XMapEvent *event) @@ -536,6 +546,18 @@ void process_unmap_event(Compositor *compositor, XUnmapEvent *event) window->map_state = IsUnviewable; } +void process_reparent_event(Compositor *compositor, XReparentEvent *event) +{ + CompositedScreen *screen = find_screen_by_root(compositor, event->event); + if(!screen) + return; + + if(event->parent==screen->root) + add_window(compositor, screen, event->window); + else + remove_window(compositor, screen, event->window, 0); +} + void process_damage_event(Compositor *compositor, XDamageNotifyEvent *event) { CompositedScreen *screen = find_screen_by_window(compositor, event->drawable); @@ -571,6 +593,9 @@ int process_event(Compositor *compositor) case UnmapNotify: process_unmap_event(compositor, &event.xunmap); break; + case ReparentNotify: + process_reparent_event(compositor, &event.xreparent); + break; default: if(event.type==compositor->damage_event+XDamageNotify) process_damage_event(compositor, (XDamageNotifyEvent *)&event); -- 2.45.2