]> git.tdb.fi Git - geometrycompositor.git/commitdiff
React to ReparentNotify events
authorMikko Rasa <tdb@tdb.fi>
Fri, 11 Dec 2015 16:56:04 +0000 (18:56 +0200)
committerMikko Rasa <tdb@tdb.fi>
Fri, 11 Dec 2015 16:56:04 +0000 (18:56 +0200)
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

index 9865eb9ac7c7f84d2104c423e41f31614b4ab6fb..c37ecc8d86f6f552a9cbe2ac481ad87a30065640 100644 (file)
@@ -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(; i<screen->nwindows; ++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);