From: Dana Jansens Date: Wed, 9 Jun 2010 23:08:31 +0000 (-0400) Subject: Rework ObWindow for better inheritence. X-Git-Tag: cgl~61 X-Git-Url: http://git.openbox.org/?a=commitdiff_plain;h=95f70078c4e28ca79546077a7841367a825372e0;p=dana%2Fopenbox.git Rework ObWindow for better inheritence. 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. --- diff --git a/openbox/client.c b/openbox/client.c index 28cf99d3..79ca2342 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -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, diff --git a/openbox/client.h b/openbox/client.h index 47da397a..6f2aad54 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -71,7 +71,7 @@ typedef enum struct _ObClient { - ObWindow obwin; + ObWindow super; Window window; gboolean managed; diff --git a/openbox/composite.c b/openbox/composite.c index af24f2f2..69b7f37b 100644 --- a/openbox/composite.c +++ b/openbox/composite.c @@ -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); diff --git a/openbox/dock.c b/openbox/dock.c index b8a5ff56..068c65d5 100644 --- a/openbox/dock.c +++ b/openbox/dock.c @@ -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; } diff --git a/openbox/dock.h b/openbox/dock.h index cb4fd6ca..c202c664 100644 --- a/openbox/dock.h +++ b/openbox/dock.h @@ -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) */ diff --git a/openbox/focus_cycle_indicator.c b/openbox/focus_cycle_indicator.c index c467c3bc..655b87f8 100644 --- a/openbox/focus_cycle_indicator.c +++ b/openbox/focus_cycle_indicator.c @@ -32,65 +32,64 @@ 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); diff --git a/openbox/focus_cycle_popup.c b/openbox/focus_cycle_popup.c index e1ea8488..f30ba8b7 100644 --- a/openbox/focus_cycle_popup.c +++ b/openbox/focus_cycle_popup.c @@ -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; diff --git a/openbox/frame.c b/openbox/frame.c index 5313fdfc..731c18d8 100644 --- a/openbox/frame.c +++ b/openbox/frame.c @@ -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); diff --git a/openbox/frame.h b/openbox/frame.h index 11880e73..b403e4d5 100644 --- a/openbox/frame.h +++ b/openbox/frame.h @@ -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; diff --git a/openbox/menuframe.c b/openbox/menuframe.c index fafc0f79..10e7ca9b 100644 --- a/openbox/menuframe.c +++ b/openbox/menuframe.c @@ -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); } diff --git a/openbox/menuframe.h b/openbox/menuframe.h index 44c02562..9c33df17 100644 --- a/openbox/menuframe.h +++ b/openbox/menuframe.h @@ -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; diff --git a/openbox/popup.c b/openbox/popup.c index 6dd0e30d..b87a4ad8 100644 --- a/openbox/popup.c +++ b/openbox/popup.c @@ -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)); } } diff --git a/openbox/popup.h b/openbox/popup.h index 6de9d184..c9563eba 100644 --- a/openbox/popup.h +++ b/openbox/popup.h @@ -34,8 +34,10 @@ typedef struct _ObPagerPopup ObPagerPopup; struct _ObPopup { - ObWindow obwin; + ObWindow super; Window bg; + ObStackingLayer layer; + gint depth; Window text; diff --git a/openbox/window.c b/openbox/window.c index bb5ed08e..b139af56 100644 --- a/openbox/window.c +++ b/openbox/window.c @@ -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; diff --git a/openbox/window.h b/openbox/window.h index df373322..27600c6b 100644 --- a/openbox/window.h +++ b/openbox/window.h @@ -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);