]> git.tdb.fi Git - geometrycompositor.git/blobdiff - source/main.c
React to ReparentNotify events
[geometrycompositor.git] / source / main.c
index 05b59557495cf9725cee2553db1b3cc5fa1fd2a8..c37ecc8d86f6f552a9cbe2ac481ad87a30065640 100644 (file)
@@ -310,6 +310,31 @@ void add_window(Compositor *compositor, CompositedScreen *screen, Window w)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 }
 
+void remove_window(Compositor *compositor, CompositedScreen *screen, Window w, int destroyed)
+{
+       unsigned i;
+
+       for(i=0; i<screen->nwindows; ++i)
+               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)
+                               screen->windows[i] = screen->windows[i+1];
+               }
+}
+
 CompositedScreen *find_screen_by_root(Compositor *compositor, Window root)
 {
        unsigned i;
@@ -487,6 +512,15 @@ void process_create_window_event(Compositor *compositor, XCreateWindowEvent *eve
        add_window(compositor, screen, event->window);
 }
 
+void process_destroy_window_event(Compositor *compositor, XDestroyWindowEvent *event)
+{
+       CompositedScreen *screen = find_screen_by_root(compositor, event->event);
+       if(!screen)
+               return;
+
+       remove_window(compositor, screen, event->window, 1);
+}
+
 void process_map_event(Compositor *compositor, XMapEvent *event)
 {
        CompositedScreen *screen = find_screen_by_root(compositor, event->event);
@@ -512,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);
@@ -538,12 +584,18 @@ int process_event(Compositor *compositor)
        case CreateNotify:
                process_create_window_event(compositor, &event.xcreatewindow);
                break;
+       case DestroyNotify:
+               process_destroy_window_event(compositor, &event.xdestroywindow);
+               break;
        case MapNotify:
                process_map_event(compositor, &event.xmap);
                break;
        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);