Rework ObWindow for better inheritence.
authorDana Jansens <danakj@orodu.net>
Wed, 9 Jun 2010 23:08:31 +0000 (19:08 -0400)
committerDana Jansens <danakj@orodu.net>
Sat, 26 Jun 2010 23:30:47 +0000 (01:30 +0200)
add window_new() that allocates an ObWindow (also works for a subclass)
add window_free() that frees it.
add window_set_abstract() that a subclass must call to set up the ObWindow's
  "abstract class" functionality
add abstract properties in ObWindow: depth, top, layer.
make all the existing ObWindows use the new window_foo() functions.

15 files changed:
openbox/client.c
openbox/client.h
openbox/composite.c
openbox/dock.c
openbox/dock.h
openbox/focus_cycle_indicator.c
openbox/focus_cycle_popup.c
openbox/frame.c
openbox/frame.h
openbox/menuframe.c
openbox/menuframe.h
openbox/popup.c
openbox/popup.h
openbox/window.c
openbox/window.h

index 28cf99d3649109bbd4b6922baed44fd5434edbfe..79ca23424abc4082b1d3c3de9feb3aef037a439f 100644 (file)
@@ -221,8 +221,7 @@ void client_manage(Window window, ObPrompt *prompt)
 
     /* create the ObClient struct, and populate it from the hints on the
        window */
-    self = g_slice_new0(ObClient);
-    self->obwin.type = OB_WINDOW_CLASS_CLIENT;
+    self = window_new(OB_WINDOW_CLASS_CLIENT, ObClient);
     self->window = window;
     self->prompt = prompt;
     self->managed = TRUE;
@@ -254,6 +253,11 @@ void client_manage(Window window, ObPrompt *prompt)
     /* create the decoration frame for the client window */
     self->frame = frame_new(self);
 
+    window_set_abstract(CLIENT_AS_WINDOW(self),
+                        &self->frame->window, /* top level window */
+                        &self->layer,         /* stacking layer */
+                        &self->frame->depth); /* window depth */
+
     frame_grab_client(self->frame);
 
     /* we've grabbed everything and set everything that we need to at mapping
@@ -507,7 +511,7 @@ ObClient *client_fake_manage(Window window)
 
     /* do this minimal stuff to figure out the client's decorations */
 
-    self = g_slice_new0(ObClient);
+    self = window_new(OB_WINDOW_CLASS_CLIENT, ObClient);
     self->window = window;
 
     client_get_all(self, FALSE);
@@ -521,6 +525,13 @@ ObClient *client_fake_manage(Window window)
     client_apply_startup_state(self, self->area.x, self->area.y,
                                self->area.width, self->area.height);
 
+    window_set_abstract(CLIENT_AS_WINDOW(self),
+                        &self->frame->window, /* top level window */
+                        &self->layer,         /* stacking layer */
+                        &self->frame->depth); /* window depth */
+
+    frame_adjust_area(self->frame, FALSE, TRUE, TRUE);
+
     ob_debug("gave extents left %d right %d top %d bottom %d",
              self->frame->size.left, self->frame->size.right,
              self->frame->size.top, self->frame->size.bottom);
@@ -684,7 +695,7 @@ void client_unmanage(ObClient *self)
     g_free(self->role);
     g_free(self->client_machine);
     g_free(self->sm_client_id);
-    g_slice_free(ObClient, self);
+    window_free(CLIENT_AS_WINDOW(self));
 }
 
 void client_fake_unmanage(ObClient *self)
@@ -692,7 +703,7 @@ void client_fake_unmanage(ObClient *self)
     /* this is all that got allocated to get the decorations */
 
     frame_free(self->frame);
-    g_slice_free(ObClient, self);
+    window_free(CLIENT_AS_WINDOW(self));
 }
 
 static gboolean client_can_steal_focus(ObClient *self,
index 47da397ada526e98aed8613580eda41a9a9a3010..6f2aad5420301213dedf5c448e069f720ca6d3ee 100644 (file)
@@ -71,7 +71,7 @@ typedef enum
 
 struct _ObClient
 {
-    ObWindow obwin;
+    ObWindow super;
     Window  window;
     gboolean managed;
 
index af24f2f2a8153c4fb1c52d2ab8f60f4d6a8524e0..69b7f37b6536447df2924c02d3197a4c7c8d7bd6 100644 (file)
@@ -302,7 +302,7 @@ static gboolean composite(gpointer data)
                 continue;
         }
 
-        if (win->depth == 32)
+        if (window_depth(win) == 32)
             attribs[1] = GLX_TEXTURE_FORMAT_RGBA_EXT;
         else
             attribs[1] = GLX_TEXTURE_FORMAT_RGB_EXT;
@@ -311,7 +311,10 @@ static gboolean composite(gpointer data)
             win->pixmap = XCompositeNameWindowPixmap(obt_display, window_top(win));
 
         if (win->gpixmap == None)
-            win->gpixmap = obcomp.CreatePixmap(obt_display, obcomp.PixmapConfig[win->depth], win->pixmap, attribs);
+            win->gpixmap =
+                obcomp.CreatePixmap(obt_display,
+                                    obcomp.PixmapConfig[window_depth(win)],
+                                    win->pixmap, attribs);
 
         glBindTexture(GL_TEXTURE_2D, win->texture);
 gettimeofday(&start, NULL);
index b8a5ff5668d42f39b9b05dca00142582436ba95a..068c65d504f37de1104ba1588f7e99910a90c7de 100644 (file)
@@ -82,8 +82,7 @@ void dock_startup(gboolean reconfig)
     STRUT_PARTIAL_SET(dock_strut, 0, 0, 0, 0,
                       0, 0, 0, 0, 0, 0, 0, 0);
 
-    dock = g_slice_new0(ObDock);
-    dock->obwin.type = OB_WINDOW_CLASS_DOCK;
+    dock = window_new(OB_WINDOW_CLASS_DOCK, ObDock);
 
     dock->hidden = TRUE;
 
@@ -93,9 +92,10 @@ void dock_startup(gboolean reconfig)
     attrib.event_mask = DOCK_EVENT_MASK;
     attrib.override_redirect = True;
     attrib.do_not_propagate_mask = DOCK_NOPROPAGATEMASK;
+    dock->depth = RrDepth(ob_rr_inst);
     dock->frame = XCreateWindow(obt_display, obt_root(ob_screen),
                                 0, 0, 1, 1, 0,
-                                RrDepth(ob_rr_inst), InputOutput,
+                                dock->depth, InputOutput,
                                 RrVisual(ob_rr_inst),
                                 CWOverrideRedirect | CWEventMask |
                                 CWDontPropagate,
@@ -109,6 +109,11 @@ void dock_startup(gboolean reconfig)
     OBT_PROP_SET32(dock->frame, NET_WM_WINDOW_TYPE, ATOM,
                    OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_DOCK));
 
+    window_set_abstract(DOCK_AS_WINDOW(dock),
+                        &dock->frame,         /* top level window */
+                        &config_dock_layer,   /* stacking layer */
+                        &dock->depth);        /* window depth */
+
     window_add(&dock->frame, DOCK_AS_WINDOW(dock));
     stacking_add(DOCK_AS_WINDOW(dock));
 }
@@ -131,7 +136,7 @@ void dock_shutdown(gboolean reconfig)
     RrAppearanceFree(dock->a_frame);
     window_remove(dock->frame);
     stacking_remove(dock);
-    g_slice_free(ObDock, dock);
+    window_free(DOCK_AS_WINDOW(dock));
     dock = NULL;
 }
 
index cb4fd6cada01524b9f368b9e1d4951004aff8b4b..c202c664315cd9f534c923a9633a964ec8dae3a5 100644 (file)
@@ -33,9 +33,10 @@ typedef struct _ObDockApp ObDockApp;
 
 struct _ObDock
 {
-    ObWindow obwin;
+    ObWindow super;
 
     Window frame;
+    int depth;
     RrAppearance *a_frame;
 
     /* actual position (when not auto-hidden) */
index c467c3bc16f3a2a47c696eebe788adae21097001..655b87f8b70b741dd994d3b20969cfc5ba79a127 100644 (file)
 
 static struct
 {
-    ObInternalWindow top;
-    ObInternalWindow left;
-    ObInternalWindow right;
-    ObInternalWindow bottom;
+    ObInternalWindow *top;
+    ObInternalWindow *left;
+    ObInternalWindow *right;
+    ObInternalWindow *bottom;
 } focus_indicator;
 
 static RrAppearance *a_focus_indicator;
 static RrColor      *color_white;
 static gboolean      visible;
 
-static Window create_window(Window parent, gulong mask,
+static Window create_window(Window parent, gint depth, gulong mask,
                             XSetWindowAttributes *attrib)
 {
     return XCreateWindow(obt_display, parent, 0, 0, 1, 1, 0,
-                         RrDepth(ob_rr_inst), InputOutput,
-                         RrVisual(ob_rr_inst), mask, attrib);
+                         depth, InputOutput,
+                         0, mask, attrib);
 
 }
 
 void focus_cycle_indicator_startup(gboolean reconfig)
 {
+    Window w;
+    gint depth;
     XSetWindowAttributes attr;
 
     visible = FALSE;
 
     if (reconfig) return;
 
-    focus_indicator.top.super.type = OB_WINDOW_CLASS_INTERNAL;
-    focus_indicator.left.super.type = OB_WINDOW_CLASS_INTERNAL;
-    focus_indicator.right.super.type = OB_WINDOW_CLASS_INTERNAL;
-    focus_indicator.bottom.super.type = OB_WINDOW_CLASS_INTERNAL;
-
+    depth = RrDepth(ob_rr_inst);
     attr.override_redirect = True;
     attr.background_pixel = BlackPixel(obt_display, ob_screen);
-    focus_indicator.top.window =
-        create_window(obt_root(ob_screen),
+
+    w = create_window(obt_root(ob_screen), depth,
                       CWOverrideRedirect | CWBackPixel, &attr);
-    focus_indicator.left.window =
-        create_window(obt_root(ob_screen),
+    focus_indicator.top = window_internal_new(w, depth);
+    w = create_window(obt_root(ob_screen), depth,
                       CWOverrideRedirect | CWBackPixel, &attr);
-    focus_indicator.right.window =
-        create_window(obt_root(ob_screen),
+    focus_indicator.left = window_internal_new(w, depth);
+    w = create_window(obt_root(ob_screen), depth,
                       CWOverrideRedirect | CWBackPixel, &attr);
-    focus_indicator.bottom.window =
-        create_window(obt_root(ob_screen),
+    focus_indicator.right = window_internal_new(w, depth);
+    w = create_window(obt_root(ob_screen), depth,
                       CWOverrideRedirect | CWBackPixel, &attr);
-
-    stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.top));
-    stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.left));
-    stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.right));
-    stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.bottom));
-    window_add(&focus_indicator.top.window,
-               INTERNAL_AS_WINDOW(&focus_indicator.top));
-    window_add(&focus_indicator.left.window,
-               INTERNAL_AS_WINDOW(&focus_indicator.left));
-    window_add(&focus_indicator.right.window,
-               INTERNAL_AS_WINDOW(&focus_indicator.right));
-    window_add(&focus_indicator.bottom.window,
-               INTERNAL_AS_WINDOW(&focus_indicator.bottom));
+    focus_indicator.bottom = window_internal_new(w, depth);
+
+    stacking_add(INTERNAL_AS_WINDOW(focus_indicator.top));
+    stacking_add(INTERNAL_AS_WINDOW(focus_indicator.left));
+    stacking_add(INTERNAL_AS_WINDOW(focus_indicator.right));
+    stacking_add(INTERNAL_AS_WINDOW(focus_indicator.bottom));
+    window_add(&focus_indicator.top->window,
+               INTERNAL_AS_WINDOW(focus_indicator.top));
+    window_add(&focus_indicator.left->window,
+               INTERNAL_AS_WINDOW(focus_indicator.left));
+    window_add(&focus_indicator.right->window,
+               INTERNAL_AS_WINDOW(focus_indicator.right));
+    window_add(&focus_indicator.bottom->window,
+               INTERNAL_AS_WINDOW(focus_indicator.bottom));
 
     color_white = RrColorNew(ob_rr_inst, 0xff, 0xff, 0xff);
 
@@ -117,20 +116,25 @@ void focus_cycle_indicator_shutdown(gboolean reconfig)
 
     RrAppearanceFree(a_focus_indicator);
 
-    window_remove(focus_indicator.top.window);
-    window_remove(focus_indicator.left.window);
-    window_remove(focus_indicator.right.window);
-    window_remove(focus_indicator.bottom.window);
-
-    stacking_remove(INTERNAL_AS_WINDOW(&focus_indicator.top));
-    stacking_remove(INTERNAL_AS_WINDOW(&focus_indicator.left));
-    stacking_remove(INTERNAL_AS_WINDOW(&focus_indicator.right));
-    stacking_remove(INTERNAL_AS_WINDOW(&focus_indicator.bottom));
-
-    XDestroyWindow(obt_display, focus_indicator.top.window);
-    XDestroyWindow(obt_display, focus_indicator.left.window);
-    XDestroyWindow(obt_display, focus_indicator.right.window);
-    XDestroyWindow(obt_display, focus_indicator.bottom.window);
+    window_remove(focus_indicator.top->window);
+    window_remove(focus_indicator.left->window);
+    window_remove(focus_indicator.right->window);
+    window_remove(focus_indicator.bottom->window);
+
+    stacking_remove(INTERNAL_AS_WINDOW(focus_indicator.top));
+    stacking_remove(INTERNAL_AS_WINDOW(focus_indicator.left));
+    stacking_remove(INTERNAL_AS_WINDOW(focus_indicator.right));
+    stacking_remove(INTERNAL_AS_WINDOW(focus_indicator.bottom));
+
+    XDestroyWindow(obt_display, focus_indicator.top->window);
+    XDestroyWindow(obt_display, focus_indicator.left->window);
+    XDestroyWindow(obt_display, focus_indicator.right->window);
+    XDestroyWindow(obt_display, focus_indicator.bottom->window);
+
+    window_free(INTERNAL_AS_WINDOW(focus_indicator.top));
+    window_free(INTERNAL_AS_WINDOW(focus_indicator.left));
+    window_free(INTERNAL_AS_WINDOW(focus_indicator.right));
+    window_free(INTERNAL_AS_WINDOW(focus_indicator.bottom));
 }
 
 void focus_cycle_update_indicator(ObClient *c)
@@ -147,10 +151,10 @@ void focus_cycle_draw_indicator(ObClient *c)
         /* kill enter events cause by this unmapping */
         ignore_start = event_start_ignore_all_enters();
 
-        XUnmapWindow(obt_display, focus_indicator.top.window);
-        XUnmapWindow(obt_display, focus_indicator.left.window);
-        XUnmapWindow(obt_display, focus_indicator.right.window);
-        XUnmapWindow(obt_display, focus_indicator.bottom.window);
+        XUnmapWindow(obt_display, focus_indicator.top->window);
+        XUnmapWindow(obt_display, focus_indicator.left->window);
+        XUnmapWindow(obt_display, focus_indicator.right->window);
+        XUnmapWindow(obt_display, focus_indicator.bottom->window);
 
         event_end_ignore_all_enters(ignore_start);
 
@@ -176,7 +180,7 @@ void focus_cycle_draw_indicator(ObClient *c)
         /* kill enter events cause by this moving */
         ignore_start = event_start_ignore_all_enters();
 
-        XMoveResizeWindow(obt_display, focus_indicator.top.window,
+        XMoveResizeWindow(obt_display, focus_indicator.top->window,
                           x, y, w, h);
         a_focus_indicator->texture[0].data.lineart.x1 = 0;
         a_focus_indicator->texture[0].data.lineart.y1 = h-1;
@@ -194,7 +198,7 @@ void focus_cycle_draw_indicator(ObClient *c)
         a_focus_indicator->texture[3].data.lineart.y1 = h-1;
         a_focus_indicator->texture[3].data.lineart.x2 = w - wr;
         a_focus_indicator->texture[3].data.lineart.y2 = h-1;
-        RrPaint(a_focus_indicator, focus_indicator.top.window,
+        RrPaint(a_focus_indicator, focus_indicator.top->window,
                 w, h);
 
         x = c->frame->area.x;
@@ -202,7 +206,7 @@ void focus_cycle_draw_indicator(ObClient *c)
         w = wl;
         h = c->frame->area.height;
 
-        XMoveResizeWindow(obt_display, focus_indicator.left.window,
+        XMoveResizeWindow(obt_display, focus_indicator.left->window,
                           x, y, w, h);
         a_focus_indicator->texture[0].data.lineart.x1 = w-1;
         a_focus_indicator->texture[0].data.lineart.y1 = 0;
@@ -220,7 +224,7 @@ void focus_cycle_draw_indicator(ObClient *c)
         a_focus_indicator->texture[3].data.lineart.y1 = wt-1;
         a_focus_indicator->texture[3].data.lineart.x2 = w-1;
         a_focus_indicator->texture[3].data.lineart.y2 = h - wb;
-        RrPaint(a_focus_indicator, focus_indicator.left.window,
+        RrPaint(a_focus_indicator, focus_indicator.left->window,
                 w, h);
 
         x = c->frame->area.x + c->frame->area.width - wr;
@@ -228,7 +232,7 @@ void focus_cycle_draw_indicator(ObClient *c)
         w = wr;
         h = c->frame->area.height ;
 
-        XMoveResizeWindow(obt_display, focus_indicator.right.window,
+        XMoveResizeWindow(obt_display, focus_indicator.right->window,
                           x, y, w, h);
         a_focus_indicator->texture[0].data.lineart.x1 = 0;
         a_focus_indicator->texture[0].data.lineart.y1 = 0;
@@ -246,7 +250,7 @@ void focus_cycle_draw_indicator(ObClient *c)
         a_focus_indicator->texture[3].data.lineart.y1 = wt-1;
         a_focus_indicator->texture[3].data.lineart.x2 = 0;
         a_focus_indicator->texture[3].data.lineart.y2 = h - wb;
-        RrPaint(a_focus_indicator, focus_indicator.right.window,
+        RrPaint(a_focus_indicator, focus_indicator.right->window,
                 w, h);
 
         x = c->frame->area.x;
@@ -254,7 +258,7 @@ void focus_cycle_draw_indicator(ObClient *c)
         w = c->frame->area.width;
         h = wb;
 
-        XMoveResizeWindow(obt_display, focus_indicator.bottom.window,
+        XMoveResizeWindow(obt_display, focus_indicator.bottom->window,
                           x, y, w, h);
         a_focus_indicator->texture[0].data.lineart.x1 = 0;
         a_focus_indicator->texture[0].data.lineart.y1 = 0;
@@ -272,13 +276,13 @@ void focus_cycle_draw_indicator(ObClient *c)
         a_focus_indicator->texture[3].data.lineart.y1 = 0;
         a_focus_indicator->texture[3].data.lineart.x2 = w - wr;
         a_focus_indicator->texture[3].data.lineart.y2 = 0;
-        RrPaint(a_focus_indicator, focus_indicator.bottom.window,
+        RrPaint(a_focus_indicator, focus_indicator.bottom->window,
                 w, h);
 
-        XMapWindow(obt_display, focus_indicator.top.window);
-        XMapWindow(obt_display, focus_indicator.left.window);
-        XMapWindow(obt_display, focus_indicator.right.window);
-        XMapWindow(obt_display, focus_indicator.bottom.window);
+        XMapWindow(obt_display, focus_indicator.top->window);
+        XMapWindow(obt_display, focus_indicator.left->window);
+        XMapWindow(obt_display, focus_indicator.right->window);
+        XMapWindow(obt_display, focus_indicator.bottom->window);
 
         event_end_ignore_all_enters(ignore_start);
 
index e1ea8488874fbc159d75f3423bf894b21505e95e..f30ba8b7c54605e9a96db965dfca9ec646b97a9e 100644 (file)
@@ -65,8 +65,10 @@ struct _ObFocusCyclePopupTarget
 
 struct _ObFocusCyclePopup
 {
-    ObWindow obwin;
+    ObWindow super;
     Window bg;
+    gint depth;
+    ObStackingLayer layer;
 
     /* This is used when the popup is in icon mode */
     Window icon_mode_text;
@@ -95,7 +97,7 @@ struct _ObFocusCyclePopup
 };
 
 /*! This popup shows all possible windows */
-static ObFocusCyclePopup popup;
+static ObFocusCyclePopup *popup;
 /*! This popup shows a single window */
 static ObIconPopup *single_popup;
 
@@ -107,11 +109,12 @@ static gboolean popup_setup    (ObFocusCyclePopup *p,
 static void     popup_render   (ObFocusCyclePopup *p,
                                 const ObClient *c);
 
-static Window create_window(Window parent, guint bwidth, gulong mask,
+static Window create_window(Window parent, guint bwidth, gint depth,
+                            gulong mask,
                             XSetWindowAttributes *attr)
 {
     return XCreateWindow(obt_display, parent, 0, 0, 1, 1, bwidth,
-                         RrDepth(ob_rr_inst), InputOutput,
+                         (depth ? depth : RrDepth(ob_rr_inst)), InputOutput,
                          RrVisual(ob_rr_inst), mask, attr);
 }
 
@@ -122,54 +125,57 @@ void focus_cycle_popup_startup(gboolean reconfig)
 
     single_popup = icon_popup_new();
 
-    popup.obwin.type = OB_WINDOW_CLASS_INTERNAL;
-    popup.a_bg = RrAppearanceCopy(ob_rr_theme->osd_bg);
-    popup.a_hilite_text = RrAppearanceCopy(ob_rr_theme->osd_hilite_label);
-    popup.a_text = RrAppearanceCopy(ob_rr_theme->osd_unhilite_label);
-    popup.a_icon = RrAppearanceCopy(ob_rr_theme->a_clear);
-    popup.a_arrow = RrAppearanceCopy(ob_rr_theme->a_clear_tex);
+    popup = window_new(OB_WINDOW_CLASS_INTERNAL, ObFocusCyclePopup);
+    popup->a_bg = RrAppearanceCopy(ob_rr_theme->osd_bg);
+    popup->a_hilite_text = RrAppearanceCopy(ob_rr_theme->osd_hilite_label);
+    popup->a_text = RrAppearanceCopy(ob_rr_theme->osd_unhilite_label);
+    popup->a_icon = RrAppearanceCopy(ob_rr_theme->a_clear);
+    popup->a_arrow = RrAppearanceCopy(ob_rr_theme->a_clear_tex);
 
-    popup.a_hilite_text->surface.parent = popup.a_bg;
-    popup.a_text->surface.parent = popup.a_bg;
-    popup.a_icon->surface.parent = popup.a_bg;
+    popup->a_hilite_text->surface.parent = popup->a_bg;
+    popup->a_text->surface.parent = popup->a_bg;
+    popup->a_icon->surface.parent = popup->a_bg;
 
-    popup.a_text->texture[0].data.text.justify = RR_JUSTIFY_LEFT;
-    popup.a_hilite_text->texture[0].data.text.justify = RR_JUSTIFY_LEFT;
+    popup->a_text->texture[0].data.text.justify = RR_JUSTIFY_LEFT;
+    popup->a_hilite_text->texture[0].data.text.justify = RR_JUSTIFY_LEFT;
 
     /* 2 textures. texture[0] is the icon.  texture[1] is the hilight, and
        may or may not be used */
-    RrAppearanceAddTextures(popup.a_icon, 2);
+    RrAppearanceAddTextures(popup->a_icon, 2);
 
-    RrAppearanceClearTextures(popup.a_icon);
-    popup.a_icon->texture[0].type = RR_TEXTURE_IMAGE;
+    RrAppearanceClearTextures(popup->a_icon);
+    popup->a_icon->texture[0].type = RR_TEXTURE_IMAGE;
 
-    RrAppearanceClearTextures(popup.a_arrow);
-    popup.a_arrow->texture[0].type = RR_TEXTURE_MASK;
-    popup.a_arrow->texture[0].data.mask.color =
+    RrAppearanceClearTextures(popup->a_arrow);
+    popup->a_arrow->texture[0].type = RR_TEXTURE_MASK;
+    popup->a_arrow->texture[0].data.mask.color =
         ob_rr_theme->osd_text_active_color;
 
     attrib.override_redirect = True;
     attrib.border_pixel=RrColorPixel(ob_rr_theme->osd_border_color);
-    popup.bg = create_window(obt_root(ob_screen), ob_rr_theme->obwidth,
-                             CWOverrideRedirect | CWBorderPixel, &attrib);
+    popup->depth = RrDepth(ob_rr_inst);
+    popup->bg = create_window(obt_root(ob_screen), ob_rr_theme->obwidth,
+                              popup->depth,
+                              CWOverrideRedirect | CWBorderPixel, &attrib);
+    popup->layer = OB_STACKING_LAYER_INTERNAL;
 
     /* create the text window used for the icon-mode popup */
-    popup.icon_mode_text = create_window(popup.bg, 0, 0, NULL);
+    popup->icon_mode_text = create_window(popup->bg, 0, 0, 0, NULL);
 
     /* create the windows for the up and down arrows */
-    popup.list_mode_up = create_window(popup.bg, 0, 0, NULL);
-    popup.list_mode_down = create_window(popup.bg, 0, 0, NULL);
+    popup->list_mode_up = create_window(popup->bg, 0, 0, 0, NULL);
+    popup->list_mode_down = create_window(popup->bg, 0, 0, 0, NULL);
 
-    popup.targets = NULL;
-    popup.n_targets = 0;
-    popup.last_target = NULL;
+    popup->targets = NULL;
+    popup->n_targets = 0;
+    popup->last_target = NULL;
 
     /* set up the hilite texture for the icon */
-    popup.a_icon->texture[1].data.rgba.width = HILITE_SIZE;
-    popup.a_icon->texture[1].data.rgba.height = HILITE_SIZE;
-    popup.a_icon->texture[1].data.rgba.alpha = 0xff;
+    popup->a_icon->texture[1].data.rgba.width = HILITE_SIZE;
+    popup->a_icon->texture[1].data.rgba.height = HILITE_SIZE;
+    popup->a_icon->texture[1].data.rgba.alpha = 0xff;
     p = g_new(RrPixel32, HILITE_SIZE * HILITE_SIZE);
-    popup.a_icon->texture[1].data.rgba.data = p;
+    popup->a_icon->texture[1].data.rgba.data = p;
 
     /* create the hilite under the target icon */
     {
@@ -203,19 +209,24 @@ void focus_cycle_popup_startup(gboolean reconfig)
             }
     }
 
-    stacking_add(INTERNAL_AS_WINDOW(&popup));
-    window_add(&popup.bg, INTERNAL_AS_WINDOW(&popup));
+    window_set_abstract(INTERNAL_AS_WINDOW(popup),
+                        &popup->bg,
+                        &popup->layer,
+                        &popup->depth);
+
+    stacking_add(INTERNAL_AS_WINDOW(popup));
+    window_add(&popup->bg, INTERNAL_AS_WINDOW(popup));
 }
 
 void focus_cycle_popup_shutdown(gboolean reconfig)
 {
     icon_popup_free(single_popup);
 
-    window_remove(popup.bg);
+    window_remove(popup->bg);
     stacking_remove(INTERNAL_AS_WINDOW(&popup));
 
-    while(popup.targets) {
-        ObFocusCyclePopupTarget *t = popup.targets->data;
+    while(popup->targets) {
+        ObFocusCyclePopupTarget *t = popup->targets->data;
 
         RrImageUnref(t->icon);
         g_free(t->text);
@@ -223,22 +234,24 @@ void focus_cycle_popup_shutdown(gboolean reconfig)
         XDestroyWindow(obt_display, t->textwin);
         g_slice_free(ObFocusCyclePopupTarget, t);
 
-        popup.targets = g_list_delete_link(popup.targets, popup.targets);
+        popup->targets = g_list_delete_link(popup->targets, popup->targets);
     }
 
-    g_free(popup.a_icon->texture[1].data.rgba.data);
-    popup.a_icon->texture[1].data.rgba.data = NULL;
+    g_free(popup->a_icon->texture[1].data.rgba.data);
+    popup->a_icon->texture[1].data.rgba.data = NULL;
+
+    XDestroyWindow(obt_display, popup->list_mode_up);
+    XDestroyWindow(obt_display, popup->list_mode_down);
+    XDestroyWindow(obt_display, popup->icon_mode_text);
+    XDestroyWindow(obt_display, popup->bg);
 
-    XDestroyWindow(obt_display, popup.list_mode_up);
-    XDestroyWindow(obt_display, popup.list_mode_down);
-    XDestroyWindow(obt_display, popup.icon_mode_text);
-    XDestroyWindow(obt_display, popup.bg);
+    RrAppearanceFree(popup->a_arrow);
+    RrAppearanceFree(popup->a_icon);
+    RrAppearanceFree(popup->a_hilite_text);
+    RrAppearanceFree(popup->a_text);
+    RrAppearanceFree(popup->a_bg);
 
-    RrAppearanceFree(popup.a_arrow);
-    RrAppearanceFree(popup.a_icon);
-    RrAppearanceFree(popup.a_hilite_text);
-    RrAppearanceFree(popup.a_text);
-    RrAppearanceFree(popup.a_bg);
+    window_free(INTERNAL_AS_WINDOW(popup));
 }
 
 static void popup_target_free(ObFocusCyclePopupTarget *t)
@@ -323,8 +336,8 @@ static gboolean popup_setup(ObFocusCyclePopup *p, gboolean create_targets,
                     t->text = text;
                     t->icon = client_icon(t->client);
                     RrImageRef(t->icon); /* own the icon so it won't go away */
-                    t->iconwin = create_window(p->bg, 0, 0, NULL);
-                    t->textwin = create_window(p->bg, 0, 0, NULL);
+                    t->iconwin = create_window(p->bg, 0, 0, 0, NULL);
+                    t->textwin = create_window(p->bg, 0, 0, 0, NULL);
 
                     p->targets = g_list_prepend(p->targets, t);
                     ++n;
@@ -356,12 +369,12 @@ static gboolean popup_setup(ObFocusCyclePopup *p, gboolean create_targets,
 
 static void popup_cleanup(void)
 {
-    while(popup.targets) {
-        popup_target_free(popup.targets->data);
-        popup.targets = g_list_delete_link(popup.targets, popup.targets);
+    while(popup->targets) {
+        popup_target_free(popup->targets->data);
+        popup->targets = g_list_delete_link(popup->targets, popup->targets);
     }
-    popup.n_targets = 0;
-    popup.last_target = NULL;
+    popup->n_targets = 0;
+    popup->last_target = NULL;
 }
 
 static gchar *popup_get_name(ObClient *c)
@@ -559,9 +572,9 @@ static void popup_render(ObFocusCyclePopup *p, const ObClient *c)
             /* position the text */
             XMoveResizeWindow(obt_display, p->icon_mode_text,
                               icon_mode_textx, icon_mode_texty, textw, texth);
-            XMapWindow(obt_display, popup.icon_mode_text);
+            XMapWindow(obt_display, popup->icon_mode_text);
         } else {
-            XUnmapWindow(obt_display, popup.icon_mode_text);
+            XUnmapWindow(obt_display, popup->icon_mode_text);
 
             up_arrow_x = (w - ob_rr_theme->up_arrow_mask->width) / 2;
             up_arrow_y = t;
@@ -715,20 +728,20 @@ void focus_cycle_popup_show(ObClient *c, ObFocusCyclePopupMode mode,
     }
 
     /* do this stuff only when the dialog is first showing */
-    if (!popup.mapped) {
-        popup_setup(&popup, TRUE, FALSE, linear);
+    if (!popup->mapped) {
+        popup_setup(popup, TRUE, FALSE, linear);
         /* this is fixed once the dialog is shown */
-        popup.mode = mode;
+        popup->mode = mode;
     }
-    g_assert(popup.targets != NULL);
+    g_assert(popup->targets != NULL);
 
-    popup_render(&popup, c);
+    popup_render(popup, c);
 
-    if (!popup.mapped) {
+    if (!popup->mapped) {
         /* show the dialog */
-        XMapWindow(obt_display, popup.bg);
+        XMapWindow(obt_display, popup->bg);
         XFlush(obt_display);
-        popup.mapped = TRUE;
+        popup->mapped = TRUE;
         screen_hide_desktop_popup();
     }
 }
@@ -739,12 +752,12 @@ void focus_cycle_popup_hide(void)
 
     ignore_start = event_start_ignore_all_enters();
 
-    XUnmapWindow(obt_display, popup.bg);
+    XUnmapWindow(obt_display, popup->bg);
     XFlush(obt_display);
 
     event_end_ignore_all_enters(ignore_start);
 
-    popup.mapped = FALSE;
+    popup->mapped = FALSE;
 
     popup_cleanup();
 }
@@ -766,7 +779,7 @@ void focus_cycle_popup_single_show(struct _ObClient *c)
         icon_popup_height(single_popup, POPUP_HEIGHT);
         icon_popup_min_width(single_popup, POPUP_WIDTH);
         icon_popup_max_width(single_popup, MAX(a->width/3, POPUP_WIDTH));
-        icon_popup_text_width(single_popup, popup.maxtextw);
+        icon_popup_text_width(single_popup, popup->maxtextw);
     }
 
     text = popup_get_name(c);
@@ -782,10 +795,10 @@ void focus_cycle_popup_single_hide(void)
 
 gboolean focus_cycle_popup_is_showing(ObClient *c)
 {
-    if (popup.mapped) {
+    if (popup->mapped) {
         GList *it;
 
-        for (it = popup.targets; it; it = g_list_next(it)) {
+        for (it = popup->targets; it; it = g_list_next(it)) {
             ObFocusCyclePopupTarget *t = it->data;
             if (t->client == c)
                 return TRUE;
@@ -798,7 +811,7 @@ static ObClient* popup_revert(ObClient *target)
 {
     GList *it, *itt;
 
-    for (it = popup.targets; it; it = g_list_next(it)) {
+    for (it = popup->targets; it; it = g_list_next(it)) {
         ObFocusCyclePopupTarget *t = it->data;
         if (t->client == target) {
             /* move to a previous window if possible */
@@ -826,21 +839,21 @@ ObClient* focus_cycle_popup_refresh(ObClient *target,
                                     gboolean redraw,
                                     gboolean linear)
 {
-    if (!popup.mapped) return NULL;
+    if (!popup->mapped) return NULL;
 
     if (!focus_cycle_valid(target))
         target = popup_revert(target);
 
-    redraw = popup_setup(&popup, TRUE, TRUE, linear) && redraw;
+    redraw = popup_setup(popup, TRUE, TRUE, linear) && redraw;
 
-    if (!target && popup.targets)
-        target = ((ObFocusCyclePopupTarget*)popup.targets->data)->client;
+    if (!target && popup->targets)
+        target = ((ObFocusCyclePopupTarget*)popup->targets->data)->client;
 
     if (target && redraw) {
-        popup.mapped = FALSE;
-        popup_render(&popup, target);
+        popup->mapped = FALSE;
+        popup_render(popup, target);
         XFlush(obt_display);
-        popup.mapped = TRUE;
+        popup->mapped = TRUE;
     }
 
     return target;
index 5313fdfc2f62e1d76ee1f47e48b3d9e486c94a52..731c18d8a41159a582199f36eecf25aaef1911ad 100644 (file)
@@ -53,11 +53,11 @@ static void free_theme_statics(ObFrame *self);
 static gboolean frame_animate_iconify(gpointer self);
 static void frame_adjust_cursors(ObFrame *self);
 
-static Window createWindow(Window parent, Visual *visual,
+static Window createWindow(Window parent, Visual *visual, int depth,
                            gulong mask, XSetWindowAttributes *attrib)
 {
     return XCreateWindow(obt_display, parent, 0, 0, 1, 1, 0,
-                         (visual ? 32 : RrDepth(ob_rr_inst)), InputOutput,
+                         (depth ? depth : RrDepth(ob_rr_inst)), InputOutput,
                          (visual ? visual : RrVisual(ob_rr_inst)),
                          mask, attrib);
 
@@ -107,7 +107,8 @@ ObFrame *frame_new(ObClient *client)
         attrib.background_pixel = BlackPixel(obt_display, ob_screen);
         attrib.border_pixel = BlackPixel(obt_display, ob_screen);
     }
-    self->window = createWindow(obt_root(ob_screen), visual,
+    self->depth = visual ? 32 : RrDepth(ob_rr_inst);
+    self->window = createWindow(obt_root(ob_screen), visual, self->depth,
                                 mask, &attrib);
 
     /* create the visible decor windows */
@@ -119,8 +120,8 @@ ObFrame *frame_new(ObClient *client)
         attrib.colormap = RrColormap(ob_rr_inst);
     }
 
-    self->backback = createWindow(self->window, NULL, mask, &attrib);
-    self->backfront = createWindow(self->backback, NULL, mask, &attrib);
+    self->backback = createWindow(self->window, NULL, 0, mask, &attrib);
+    self->backfront = createWindow(self->backback, NULL, 0, mask, &attrib);
     XMapWindow(obt_display, self->backback);
     XMapWindow(obt_display, self->backfront);
 
index 11880e738ecc58f4d4f4b6148b88b5f44fc419d2..b403e4d5ef3b5d19969ba68d7b341724b9d0285d 100644 (file)
@@ -84,6 +84,7 @@ struct _ObFrame
     struct _ObClient *client;
 
     Window    window;
+    gint      depth;
 
     /* These are used to prevent flashing when the client window unmaps? */
     Window    backback;
index fafc0f790c0185bc045ec0ff862019043d6d0e13..10e7ca9b3e3e843c9f0b8a5e5a2fbebbcb32ddc1 100644 (file)
@@ -56,11 +56,11 @@ static void menu_frame_hide(ObMenuFrame *self);
 
 static gboolean submenu_hide_timeout(gpointer data);
 
-static Window createWindow(Window parent, gulong mask,
+static Window createWindow(Window parent, gint depth, gulong mask,
                            XSetWindowAttributes *attrib)
 {
     return XCreateWindow(obt_display, parent, 0, 0, 1, 1, 0,
-                         RrDepth(ob_rr_inst), InputOutput,
+                         (depth ? depth : RrDepth(ob_rr_inst)), InputOutput,
                          RrVisual(ob_rr_inst), mask, attrib);
 }
 
@@ -110,8 +110,7 @@ ObMenuFrame* menu_frame_new(ObMenu *menu, guint show_from, ObClient *client)
     ObMenuFrame *self;
     XSetWindowAttributes attr;
 
-    self = g_slice_new0(ObMenuFrame);
-    self->obwin.type = OB_WINDOW_CLASS_MENUFRAME;
+    self = window_new(OB_WINDOW_CLASS_MENUFRAME, ObMenuFrame);
     self->menu = menu;
     self->selected = NULL;
     self->client = client;
@@ -119,8 +118,10 @@ ObMenuFrame* menu_frame_new(ObMenu *menu, guint show_from, ObClient *client)
     self->show_from = show_from;
 
     attr.event_mask = FRAME_EVENTMASK;
-    self->window = createWindow(obt_root(ob_screen),
+    self->depth = RrDepth(ob_rr_inst);
+    self->window = createWindow(obt_root(ob_screen), self->depth,
                                 CWEventMask, &attr);
+    self->layer =  OB_STACKING_LAYER_INTERNAL;
 
     /* make it a popup menu type window */
     OBT_PROP_SET32(self->window, NET_WM_WINDOW_TYPE, ATOM,
@@ -132,6 +133,11 @@ ObMenuFrame* menu_frame_new(ObMenu *menu, guint show_from, ObClient *client)
 
     self->a_items = RrAppearanceCopy(ob_rr_theme->a_menu);
 
+    window_set_abstract(MENUFRAME_AS_WINDOW(self),
+                        &self->window,        /* top level window */
+                        &self->layer,         /* stacking layer */
+                        &self->depth);        /* window depth */
+
     window_add(&self->window, MENUFRAME_AS_WINDOW(self));
     stacking_add(MENUFRAME_AS_WINDOW(self));
 
@@ -153,7 +159,7 @@ void menu_frame_free(ObMenuFrame *self)
 
         XDestroyWindow(obt_display, self->window);
 
-        g_slice_free(ObMenuFrame, self);
+        window_free(MENUFRAME_AS_WINDOW(self));
     }
 }
 
@@ -177,16 +183,16 @@ static ObMenuEntryFrame* menu_entry_frame_new(ObMenuEntry *entry,
     menu_entry_ref(entry);
 
     attr.event_mask = ENTRY_EVENTMASK;
-    self->window = createWindow(self->frame->window, CWEventMask, &attr);
-    self->text = createWindow(self->window, 0, NULL);
+    self->window = createWindow(self->frame->window, 0, CWEventMask, &attr);
+    self->text = createWindow(self->window, 0, 0, NULL);
     g_hash_table_insert(menu_frame_map, &self->window, self);
     g_hash_table_insert(menu_frame_map, &self->text, self);
     if (entry->type == OB_MENU_ENTRY_TYPE_NORMAL) {
-        self->icon = createWindow(self->window, 0, NULL);
+        self->icon = createWindow(self->window, 0, 0, NULL);
         g_hash_table_insert(menu_frame_map, &self->icon, self);
     }
     if (entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) {
-        self->bullet = createWindow(self->window, 0, NULL);
+        self->bullet = createWindow(self->window, 0, 0, NULL);
         g_hash_table_insert(menu_frame_map, &self->bullet, self);
     }
 
index 44c02562220a983128b6fe2d36dcec3f7cb06510..9c33df1702084912a2c06daadb837f2397dde7a1 100644 (file)
@@ -38,9 +38,10 @@ extern GList *menu_frame_visible;
 
 struct _ObMenuFrame
 {
-    /* stuff to be an ObWindow */
-    ObWindow obwin;
+    ObWindow super;
     Window window;
+    ObStackingLayer layer;
+    gint depth;
 
     struct _ObMenu *menu;
 
index 6dd0e30ddd1ceb38283258792b9544560a29664f..b87a4ad83598b980be95ff0a24529260f3a60b91 100644 (file)
@@ -31,9 +31,9 @@
 ObPopup *popup_new(void)
 {
     XSetWindowAttributes attrib;
-    ObPopup *self = g_slice_new0(ObPopup);
+    ObPopup *self;
 
-    self->obwin.type = OB_WINDOW_CLASS_INTERNAL;
+    self = window_new(OB_WINDOW_CLASS_INTERNAL, ObPopup);
     self->gravity = NorthWestGravity;
     self->x = self->y = self->textw = self->h = 0;
     self->a_bg = RrAppearanceCopy(ob_rr_theme->osd_bg);
@@ -41,10 +41,12 @@ ObPopup *popup_new(void)
     self->iconwm = self->iconhm = 1;
 
     attrib.override_redirect = True;
+    self->depth = RrDepth(ob_rr_inst);
     self->bg = XCreateWindow(obt_display, obt_root(ob_screen),
-                             0, 0, 1, 1, 0, RrDepth(ob_rr_inst),
+                             0, 0, 1, 1, 0, self->depth,
                              InputOutput, RrVisual(ob_rr_inst),
                              CWOverrideRedirect, &attrib);
+    self->layer = OB_STACKING_LAYER_INTERNAL;
 
     self->text = XCreateWindow(obt_display, self->bg,
                                0, 0, 1, 1, 0, RrDepth(ob_rr_inst),
@@ -56,6 +58,11 @@ ObPopup *popup_new(void)
 
     XMapWindow(obt_display, self->text);
 
+    window_set_abstract(INTERNAL_AS_WINDOW(self),
+                        &self->bg,      /* top level window */
+                        &self->layer,   /* stacking layer */
+                        &self->depth);  /* window depth */
+
     stacking_add(INTERNAL_AS_WINDOW(self));
     window_add(&self->bg, INTERNAL_AS_WINDOW(self));
     return self;
@@ -72,7 +79,7 @@ void popup_free(ObPopup *self)
         RrAppearanceFree(self->a_text);
         window_remove(self->bg);
         stacking_remove(self);
-        g_slice_free(ObPopup, self);
+        window_free(INTERNAL_AS_WINDOW(self));
     }
 }
 
index 6de9d184cdaf08109debda8989a2ca07a786b292..c9563eba5fab579a86ef0ba7e828e25050330c1f 100644 (file)
@@ -34,8 +34,10 @@ typedef struct _ObPagerPopup ObPagerPopup;
 
 struct _ObPopup
 {
-    ObWindow obwin;
+    ObWindow super;
     Window bg;
+    ObStackingLayer layer;
+    gint depth;
 
     Window text;
 
index bb5ed08e7981c522a7d0b9adf65bad1f9ff15098..b139af5684887497f5a97827e7d8dc97cf0eb1d4 100644 (file)
@@ -48,41 +48,64 @@ void window_shutdown(gboolean reconfig)
     g_hash_table_destroy(window_map);
 }
 
-Window window_top(ObWindow *self)
+ObWindow* window_new_size(ObWindowClass type, gsize size)
 {
-    switch (self->type) {
-    case OB_WINDOW_CLASS_MENUFRAME:
-        return WINDOW_AS_MENUFRAME(self)->window;
-    case OB_WINDOW_CLASS_DOCK:
-        return WINDOW_AS_DOCK(self)->frame;
-    case OB_WINDOW_CLASS_CLIENT:
-        return WINDOW_AS_CLIENT(self)->frame->window;
-    case OB_WINDOW_CLASS_INTERNAL:
-        return WINDOW_AS_INTERNAL(self)->window;
-    case OB_WINDOW_CLASS_PROMPT:
-        return WINDOW_AS_PROMPT(self)->super.window;
+    ObWindow *self;
+
+    g_assert(size >= sizeof(ObWindow));
+    self = g_slice_alloc0(size);
+    self->size = size;
+    self->type = type;
+
+#ifdef USE_COMPOSITING
+    glGenTextures(1, &self->texture);
+#endif
+
+    return self;
+}
+
+void window_set_abstract(ObWindow *self,
+                         const Window *top,
+                         const ObStackingLayer *layer,
+                         const int *depth)
+{
+    self->top = top;
+    self->layer = layer;
+    self->depth = depth;
+
+    /* set up any things in ObWindow that require use of the abstract pointers
+       now */
+
+#ifdef USE_COMPOSITING
+    if (self->type != OB_WINDOW_CLASS_PROMPT) {
+        self->damage = XDamageCreate(obt_display, *self->top,
+                                     XDamageReportNonEmpty);
+
+        XCompositeRedirectWindow(obt_display, *self->top,
+                                 CompositeRedirectManual);
     }
-    g_assert_not_reached();
-    return None;
+#endif
 }
 
-ObStackingLayer window_layer(ObWindow *self)
+void window_free(ObWindow *self)
 {
-    switch (self->type) {
-    case OB_WINDOW_CLASS_DOCK:
-        return config_dock_layer;
-    case OB_WINDOW_CLASS_CLIENT:
-        return ((ObClient*)self)->layer;
-    case OB_WINDOW_CLASS_MENUFRAME:
-    case OB_WINDOW_CLASS_INTERNAL:
-        return OB_STACKING_LAYER_INTERNAL;
-    case OB_WINDOW_CLASS_PROMPT:
-        /* not used directly for stacking, prompts are managed as clients */
-        g_assert_not_reached();
-        break;
+    /* The abstract pointers must not be used here, they are likely invalid
+       by now ! */
+
+#ifdef USE_COMPOSITING
+    if (self->type != OB_WINDOW_CLASS_PROMPT) {
+        if (self->damage)
+            XDamageDestroy(obt_display, self->damage);
+        if (self->gpixmap)
+            glXDestroyPixmap(obt_display, self->gpixmap);
+        if (self->pixmap)
+            XFreePixmap(obt_display, self->pixmap);
+        if (self->texture)
+            glDeleteTextures(1, &self->texture);
     }
-    g_assert_not_reached();
-    return None;
+#endif
+
+    g_slice_free1(self->size, self);
 }
 
 ObWindow* window_find(Window xwin)
@@ -94,51 +117,30 @@ void window_add(Window *xwin, ObWindow *win)
 {
     g_assert(xwin != NULL);
     g_assert(win != NULL);
-#ifdef USE_COMPOSITING
-    XWindowAttributes wattrib;
-    Status ret;
-
-    if (win->type != OB_WINDOW_CLASS_PROMPT) {
-        win->damage = XDamageCreate(obt_display, window_top(win), XDamageReportNonEmpty);
-
-        XCompositeRedirectWindow(obt_display, window_top(win), CompositeRedirectManual);
-
-        win->pixmap = None;
-        glGenTextures(1, &win->texture);
-        ret = XGetWindowAttributes(obt_display, window_top(win), &wattrib);
-        g_assert(ret != BadDrawable);
-        g_assert(ret != BadWindow);
-
-        win->depth = wattrib.depth;
-    }
-#endif
     g_hash_table_insert(window_map, xwin, win);
 }
 
 void window_remove(Window xwin)
 {
     g_assert(xwin != None);
-#ifdef USE_COMPOSITING
-    ObWindow *win;
-    win = window_find(xwin);
-    if (!win) {
-        printf("Compositor tried to clean up a window, but it was not there.\n");
-        return;
-    }
-    if (win->type != OB_WINDOW_CLASS_PROMPT) {
-        if (win->damage)
-            XDamageDestroy(obt_display, win->damage);
-        if (win->gpixmap)
-            glXDestroyGLXPixmap(obt_display, win->gpixmap);
-        if (win->pixmap)
-            XFreePixmap(obt_display, win->pixmap);
-        if (win->texture)
-            glDeleteTextures(1, &win->texture);
-    }
-#endif
     g_hash_table_remove(window_map, &xwin);
 }
 
+ObInternalWindow* window_internal_new(Window window, int depth)
+{
+    ObInternalWindow *self;
+
+    self = window_new(OB_WINDOW_CLASS_INTERNAL, ObInternalWindow);
+    self->window = window;
+    self->layer = OB_STACKING_LAYER_INTERNAL;
+    self->depth = depth;
+    window_set_abstract(INTERNAL_AS_WINDOW(self),
+                        &self->window,
+                        &self->layer,
+                        &self->depth);
+    return self;
+}
+
 void window_manage_all(void)
 {
     guint i, j, nchild;
index df3733226df5f39bd076b23552a8ab572188fef8..27600c6b4f672e96e31ef8e10e1571da276b4205 100644 (file)
@@ -46,12 +46,23 @@ typedef enum {
    struct */
 struct _ObWindow {
     ObWindowClass type;
+    gsize size;
+
+    /* abstract values implemented by subclasses */
+
+    /*! Points to the top level Xwindow for the ObWindow */
+    const Window *top;
+    /*! Points to the stacking layer for the ObWindow */
+    const ObStackingLayer *layer;
+    /*! Points to the position and size occupied by the ObWindow */
+    /*! Points to the depth of the ObWindow */
+    const int *depth;
+
 #ifdef USE_COMPOSITING
     GLuint texture;
     Pixmap pixmap;
     GLXPixmap gpixmap;
     Damage damage;
-    int depth;
     Rect comp_area;
     gboolean mapped;
 #endif
@@ -89,19 +100,35 @@ struct _ObPrompt;
 void window_startup (gboolean reconfig);
 void window_shutdown(gboolean reconfig);
 
-Window          window_top  (ObWindow *self);
-ObStackingLayer window_layer(ObWindow *self);
+#define window_new(c, t) ((t*)window_new_size((c), sizeof(t)))
+ObWindow* window_new_size(ObWindowClass type, gsize size);
+/*! A subclass of ObWindow must call this to set these pointers during the
+  initialization/creation phase, so that the ObWindow can be used */
+void      window_set_abstract(ObWindow *self,
+                              const Window *top,
+                              const ObStackingLayer *layer,
+                              const int *depth);
+void      window_free(ObWindow *self);
 
 ObWindow* window_find  (Window xwin);
 void      window_add   (Window *xwin, ObWindow *win);
 void      window_remove(Window xwin);
 
+#define window_top(w) (*((ObWindow*)w)->top)
+#define window_layer(w) (*((ObWindow*)w)->layer)
+#define window_area(w) (*((ObWindow*)w)->area)
+#define window_depth(w) (*((ObWindow*)w)->depth)
+
 /* Internal openbox-owned windows like the alt-tab popup */
 struct _ObInternalWindow {
     ObWindow super;
     Window window;
+    ObStackingLayer layer;
+    int depth;
 };
 
+ObInternalWindow* window_internal_new(Window window, int depth);
+
 void window_manage_all(void);
 void window_manage(Window win);
 void window_unmanage_all(void);