summaryrefslogtreecommitdiff
path: root/openbox
diff options
context:
space:
mode:
Diffstat (limited to 'openbox')
-rw-r--r--openbox/client.c266
-rw-r--r--openbox/client.h20
-rw-r--r--openbox/client_list_combined_menu.c10
-rw-r--r--openbox/client_list_menu.c9
-rw-r--r--openbox/focus_cycle_popup.c29
-rw-r--r--openbox/framerender.c20
-rw-r--r--openbox/menu.c1
-rw-r--r--openbox/menu.h8
-rw-r--r--openbox/menuframe.c22
-rw-r--r--openbox/openbox.c23
-rw-r--r--openbox/openbox.h1
-rw-r--r--openbox/popup.c15
-rw-r--r--openbox/popup.h2
13 files changed, 195 insertions, 231 deletions
diff --git a/openbox/client.c b/openbox/client.c
index e65ed07c..c7a82d16 100644
--- a/openbox/client.c
+++ b/openbox/client.c
@@ -67,9 +67,10 @@ typedef struct
gpointer data;
} ClientCallback;
-GList *client_list = NULL;
+GList *client_list = NULL;
-static GSList *client_destroy_notifies = NULL;
+static GSList *client_destroy_notifies = NULL;
+static RrImage *client_default_icon = NULL;
static void client_get_all(ObClient *self, gboolean real);
static void client_get_startup_id(ObClient *self);
@@ -109,6 +110,19 @@ static void client_prompt_kill(ObClient *self);
void client_startup(gboolean reconfig)
{
+ if ((client_default_icon = RrImageCacheFind(ob_rr_icons,
+ ob_rr_theme->def_win_icon,
+ ob_rr_theme->def_win_icon_w,
+ ob_rr_theme->def_win_icon_h)))
+ RrImageRef(client_default_icon);
+ else {
+ client_default_icon = RrImageNew(ob_rr_icons);
+ RrImageAddPicture(client_default_icon,
+ ob_rr_theme->def_win_icon,
+ ob_rr_theme->def_win_icon_w,
+ ob_rr_theme->def_win_icon_h);
+ }
+
if (reconfig) return;
client_set_list();
@@ -116,6 +130,9 @@ void client_startup(gboolean reconfig)
void client_shutdown(gboolean reconfig)
{
+ RrImageUnref(client_default_icon);
+ client_default_icon = NULL;
+
if (reconfig) return;
}
@@ -587,7 +604,6 @@ void client_unmanage_all(void)
void client_unmanage(ObClient *self)
{
- guint j;
GSList *it;
gulong ignore_start;
@@ -719,11 +735,8 @@ void client_unmanage(ObClient *self)
ob_debug("Unmanaged window 0x%lx", self->window);
/* free all data allocated in the client struct */
+ RrImageUnref(self->icon_set);
g_slist_free(self->transients);
- for (j = 0; j < self->nicons; ++j)
- g_free(self->icons[j].data);
- if (self->nicons > 0)
- g_free(self->icons);
g_free(self->startup_id);
g_free(self->wm_command);
g_free(self->title);
@@ -2009,143 +2022,134 @@ void client_update_strut(ObClient *self)
}
}
-/* Avoid storing icons above this size if possible */
-#define AVOID_ABOVE 64
-
void client_update_icons(ObClient *self)
{
guint num;
guint32 *data;
guint w, h, i, j;
guint num_seen; /* number of icons present */
- guint num_small_seen; /* number of icons small enough present */
- guint smallest, smallest_area;
+ RrImage *img;
+
+ img = NULL;
- for (i = 0; i < self->nicons; ++i)
- g_free(self->icons[i].data);
- if (self->nicons > 0)
- g_free(self->icons);
- self->nicons = 0;
+ /* grab the server, because we might be setting the window's icon and
+ we don't want them to set it in between and we overwrite their own
+ icon */
+ grab_server(TRUE);
if (OBT_PROP_GETA32(self->window, NET_WM_ICON, CARDINAL, &data, &num)) {
/* figure out how many valid icons are in here */
i = 0;
- num_seen = num_small_seen = 0;
- smallest = smallest_area = 0;
- if (num > 2)
- while (i < num) {
+ num_seen = 0;
+ while (i + 2 < num) { /* +2 is to make sure there is a w and h */
+ w = data[i++];
+ h = data[i++];
+ /* watch for the data being too small for the specified size,
+ or for zero sized icons. */
+ if (i + w*h > num || w == 0 || h == 0) break;
+
+ /* convert it to the right bit order for ObRender */
+ for (j = 0; j < w*h; ++j)
+ data[i+j] =
+ (((data[i+j] >> 24) & 0xff) << RrDefaultAlphaOffset) +
+ (((data[i+j] >> 16) & 0xff) << RrDefaultRedOffset) +
+ (((data[i+j] >> 8) & 0xff) << RrDefaultGreenOffset) +
+ (((data[i+j] >> 0) & 0xff) << RrDefaultBlueOffset);
+
+ /* is it in the cache? */
+ img = RrImageCacheFind(ob_rr_icons, &data[i], w, h);
+ if (img) RrImageRef(img); /* own it */
+
+ i += w*h;
+ ++num_seen;
+
+ /* don't bother looping anymore if we already found it in the cache
+ since we'll just use that! */
+ if (img) break;
+ }
+
+ /* if it's not in the cache yet, then add it to the cache now.
+ we have already converted it to the correct bit order above */
+ if (!img && num_seen > 0) {
+ img = RrImageNew(ob_rr_icons);
+ i = 0;
+ for (j = 0; j < num_seen; ++j) {
w = data[i++];
h = data[i++];
- i += w * h;
- /* watch for it being too small for the specified size, or for
- zero sized icons. */
- if (i > num || w == 0 || h == 0) break;
-
- if (!smallest_area || w*h < smallest_area) {
- smallest = num_seen;
- smallest_area = w*h;
- }
- ++num_seen;
- if (w <= AVOID_ABOVE && h <= AVOID_ABOVE)
- ++num_small_seen;
- }
- if (num_small_seen > 0)
- self->nicons = num_small_seen;
- else if (num_seen)
- self->nicons = 1;
-
- self->icons = g_new(ObClientIcon, self->nicons);
-
- /* store the icons */
- i = 0;
- for (j = 0; j < self->nicons;) {
- guint x, y, t;
-
- w = self->icons[j].width = data[i++];
- h = self->icons[j].height = data[i++];
-
- /* if there are some icons smaller than the threshold, we're
- skipping all the ones above */
- if (num_small_seen > 0) {
- if (w > AVOID_ABOVE || h > AVOID_ABOVE) {
- i += w*h;
- continue;
- }
- }
- /* if there were no icons smaller than the threshold, then we are
- only taking the smallest available one we saw */
- else if (j != smallest) {
+ RrImageAddPicture(img, &data[i], w, h);
i += w*h;
- continue;
}
-
- self->icons[j].data = g_new(RrPixel32, w * h);
- for (x = 0, y = 0, t = 0; t < w * h; ++t, ++x, ++i) {
- if (x >= w) {
- x = 0;
- ++y;
- }
- self->icons[j].data[t] =
- (((data[i] >> 24) & 0xff) << RrDefaultAlphaOffset) +
- (((data[i] >> 16) & 0xff) << RrDefaultRedOffset) +
- (((data[i] >> 8) & 0xff) << RrDefaultGreenOffset) +
- (((data[i] >> 0) & 0xff) << RrDefaultBlueOffset);
- }
- g_assert(i <= num);
-
- ++j;
}
g_free(data);
- } else {
+ }
+
+ /* if we didn't find an image from the NET_WM_ICON stuff, then try the
+ legacy X hints */
+ if (!img) {
XWMHints *hints;
if ((hints = XGetWMHints(obt_display, self->window))) {
if (hints->flags & IconPixmapHint) {
- self->nicons = 1;
- self->icons = g_new(ObClientIcon, self->nicons);
+ gboolean xicon;
obt_display_ignore_errors(TRUE);
- if (!RrPixmapToRGBA(ob_rr_inst,
- hints->icon_pixmap,
- (hints->flags & IconMaskHint ?
- hints->icon_mask : None),
- &self->icons[0].width,
- &self->icons[0].height,
- &self->icons[0].data))
- {
- g_free(self->icons);
- self->nicons = 0;
- }
+ xicon = RrPixmapToRGBA(ob_rr_inst,
+ hints->icon_pixmap,
+ (hints->flags & IconMaskHint ?
+ hints->icon_mask : None),
+ (gint*)&w, (gint*)&h, &data);
obt_display_ignore_errors(FALSE);
+
+
+ if (xicon) {
+ if (w > 0 && h > 0) {
+ /* is this icon in the cache yet? */
+ img = RrImageCacheFind(ob_rr_icons, data, w, h);
+ if (img) RrImageRef(img); /* own it */
+
+ /* if not, then add it */
+ if (!img) {
+ img = RrImageNew(ob_rr_icons);
+ RrImageAddPicture(img, data, w, h);
+ }
+ }
+
+ g_free(data);
+ }
}
XFree(hints);
}
}
- /* set the default icon onto the window
- in theory, this could be a race, but if a window doesn't set an icon
- or removes it entirely, it's not very likely it is going to set one
- right away afterwards
+ /* set the client's icons to be whatever we found */
+ RrImageUnref(self->icon_set);
+ self->icon_set = img;
- if it has parents, then one of them will have an icon already
+ /* if the client has no icon at all, then we set a default icon onto it.
+ but, if it has parents, then one of them will have an icon already
*/
- if (self->nicons == 0 && !self->parents) {
+ if (!self->icon_set && !self->parents) {
RrPixel32 *icon = ob_rr_theme->def_win_icon;
- gulong *data;
-
- data = g_new(gulong, 48*48+2);
- data[0] = data[1] = 48;
- for (i = 0; i < 48*48; ++i)
- data[i+2] = (((icon[i] >> RrDefaultAlphaOffset) & 0xff) << 24) +
+ gulong *ldata; /* use a long here to satisfy OBT_PROP_SETA32 */
+
+ w = ob_rr_theme->def_win_icon_w;
+ h = ob_rr_theme->def_win_icon_h;
+ ldata = g_new(gulong, w*h+2);
+ ldata[0] = w;
+ ldata[1] = h;
+ for (i = 0; i < w*h; ++i)
+ ldata[i+2] = (((icon[i] >> RrDefaultAlphaOffset) & 0xff) << 24) +
(((icon[i] >> RrDefaultRedOffset) & 0xff) << 16) +
(((icon[i] >> RrDefaultGreenOffset) & 0xff) << 8) +
(((icon[i] >> RrDefaultBlueOffset) & 0xff) << 0);
- OBT_PROP_SETA32(self->window, NET_WM_ICON, CARDINAL, data, 48*48+2);
- g_free(data);
+ OBT_PROP_SETA32(self->window, NET_WM_ICON, CARDINAL, ldata, w*h+2);
+ g_free(ldata);
} else if (self->frame)
/* don't draw the icon empty if we're just setting one now anyways,
we'll get the property change any second */
frame_adjust_icon(self->frame);
+
+ grab_server(FALSE);
}
void client_update_icon_geometry(ObClient *self)
@@ -3840,53 +3844,21 @@ gboolean client_focused(ObClient *self)
return self == focus_client;
}
-static ObClientIcon* client_icon_recursive(ObClient *self, gint w, gint h)
-{
- guint i;
- gulong min_diff, min_i;
- if (!self->nicons) {
- ObClientIcon *parent = NULL;
- GSList *it;
- for (it = self->parents; it; it = g_slist_next(it)) {
- ObClient *c = it->data;
- if ((parent = client_icon_recursive(c, w, h)))
- break;
- }
-
- return parent;
- }
-
- /* some kind of crappy approximation to find the icon closest in size to
- what we requested, but icons are generally all the same ratio as
- eachother so it's good enough. */
-
- min_diff = ABS(self->icons[0].width - w) + ABS(self->icons[0].height - h);
- min_i = 0;
-
- for (i = 1; i < self->nicons; ++i) {
- gulong diff;
-
- diff = ABS(self->icons[i].width - w) + ABS(self->icons[i].height - h);
- if (diff < min_diff) {
- min_diff = diff;
- min_i = i;
- }
- }
- return &self->icons[min_i];
-}
-
-const ObClientIcon* client_icon(ObClient *self, gint w, gint h)
+RrImage* client_icon(ObClient *self)
{
- ObClientIcon *ret;
- static ObClientIcon deficon;
+ RrImage *ret = NULL;
- if (!(ret = client_icon_recursive(self, w, h))) {
- deficon.width = deficon.height = 48;
- deficon.data = ob_rr_theme->def_win_icon;
- ret = &deficon;
+ if (self->icon_set)
+ ret = self->icon_set;
+ else if (self->parents) {
+ GSList *it;
+ for (it = self->parents; it && !ret; it = g_slist_next(it))
+ ret = client_icon(it->data);
}
+ if (!ret)
+ ret = client_default_icon;
return ret;
}
diff --git a/openbox/client.h b/openbox/client.h
index bb63137f..c24fcb20 100644
--- a/openbox/client.h
+++ b/openbox/client.h
@@ -40,15 +40,6 @@ struct _ObSessionState;
struct _ObPrompt;
typedef struct _ObClient ObClient;
-typedef struct _ObClientIcon ObClientIcon;
-
-/*! Holds an icon in ARGB format */
-struct _ObClientIcon
-{
- gint width;
- gint height;
- RrPixel32 *data;
-};
/*! Possible window types */
typedef enum
@@ -307,10 +298,8 @@ struct _ObClient
*/
guint functions;
- /*! Icons for the client as specified on the client window */
- ObClientIcon *icons;
- /*! The number of icons in icons */
- guint nicons;
+ /* The window's icon, in a variety of shapes and sizes */
+ RrImage *icon_set;
/*! Where the window should iconify to/from */
Rect icon_geometry;
@@ -642,7 +631,10 @@ void client_setup_decor_and_functions(ObClient *self, gboolean reconfig);
/*! Sets the window's type and transient flag */
void client_get_type_and_transientness(ObClient *self);
-const ObClientIcon *client_icon(ObClient *self, gint w, gint h);
+/*! Returns a client's icon set, or its parents (recursively) if it doesn't
+ have one
+*/
+RrImage* client_icon(ObClient *self);
/*! Return TRUE if the client is transient for some other window. Return
FALSE if it's not transient or there is no window for it to be
diff --git a/openbox/client_list_combined_menu.c b/openbox/client_list_combined_menu.c
index 76a819fc..a04d07d6 100644
--- a/openbox/client_list_combined_menu.c
+++ b/openbox/client_list_combined_menu.c
@@ -56,8 +56,6 @@ static gboolean self_update(ObMenuFrame *frame, gpointer data)
if (client_normal(c) && (!c->skip_taskbar || c->iconic) &&
(c->desktop == desktop || c->desktop == DESKTOP_ALL))
{
- const ObClientIcon *icon;
-
empty = FALSE;
if (c->iconic) {
@@ -69,11 +67,9 @@ static gboolean self_update(ObMenuFrame *frame, gpointer data)
e = menu_add_normal(menu, desktop, c->title, NULL, FALSE);
}
- if (config_menu_client_list_icons
- && (icon = client_icon(c, 32, 32))) {
- e->data.normal.icon_width = icon->width;
- e->data.normal.icon_height = icon->height;
- e->data.normal.icon_data = icon->data;
+ if (config_menu_client_list_icons) {
+ e->data.normal.icon = client_icon(c);
+ RrImageRef(e->data.normal.icon);
e->data.normal.icon_alpha =
c->iconic ? OB_ICONIC_ALPHA : 0xff;
}
diff --git a/openbox/client_list_menu.c b/openbox/client_list_menu.c
index e6521a0a..4ec6e785 100644
--- a/openbox/client_list_menu.c
+++ b/openbox/client_list_menu.c
@@ -58,7 +58,6 @@ static gboolean desk_menu_update(ObMenuFrame *frame, gpointer data)
(c->desktop == d->desktop || c->desktop == DESKTOP_ALL))
{
ObMenuEntry *e;
- const ObClientIcon *icon;
empty = FALSE;
@@ -71,11 +70,9 @@ static gboolean desk_menu_update(ObMenuFrame *frame, gpointer data)
e = menu_add_normal(menu, d->desktop, c->title, NULL, FALSE);
}
- if (config_menu_client_list_icons
- && (icon = client_icon(c, 32, 32))) {
- e->data.normal.icon_width = icon->width;
- e->data.normal.icon_height = icon->height;
- e->data.normal.icon_data = icon->data;
+ if (config_menu_client_list_icons) {
+ e->data.normal.icon = client_icon(c);
+ RrImageRef(e->data.normal.icon);
e->data.normal.icon_alpha = c->iconic ? OB_ICONIC_ALPHA : 0xff;
}
diff --git a/openbox/focus_cycle_popup.c b/openbox/focus_cycle_popup.c
index 4d1dfaa3..3feac6ab 100644
--- a/openbox/focus_cycle_popup.c
+++ b/openbox/focus_cycle_popup.c
@@ -54,6 +54,7 @@ typedef struct _ObFocusCyclePopupTarget ObFocusCyclePopupTarget;
struct _ObFocusCyclePopupTarget
{
ObClient *client;
+ RrImage *icon;
gchar *text;
Window iconwin;
/* This is used when the popup is in list mode */
@@ -139,8 +140,10 @@ void focus_cycle_popup_startup(gboolean reconfig)
may or may not be used */
RrAppearanceAddTextures(popup.a_icon, 2);
- popup.a_icon->texture[0].type = RR_TEXTURE_RGBA;
+ 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 =
ob_rr_theme->osd_color;
@@ -212,9 +215,11 @@ void focus_cycle_popup_shutdown(gboolean reconfig)
while(popup.targets) {
ObFocusCyclePopupTarget *t = popup.targets->data;
+ RrImageUnref(t->icon);
g_free(t->text);
XDestroyWindow(obt_display, t->iconwin);
XDestroyWindow(obt_display, t->textwin);
+ g_free(t);
popup.targets = g_list_delete_link(popup.targets, popup.targets);
}
@@ -272,6 +277,8 @@ static void popup_setup(ObFocusCyclePopup *p, gboolean create_targets,
t->client = ft;
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);
@@ -547,7 +554,6 @@ static void popup_render(ObFocusCyclePopup *p, const ObClient *c)
/* row and column start from 0 */
const gint row = i / icons_per_row - p->scroll;
const gint col = i % icons_per_row;
- const ObClientIcon *icon;
gint iconx, icony;
gint list_mode_textx, list_mode_texty;
RrAppearance *text;
@@ -590,16 +596,13 @@ static void popup_render(ObFocusCyclePopup *p, const ObClient *c)
}
/* get the icon from the client */
- icon = client_icon(target->client, ICON_SIZE, ICON_SIZE);
- p->a_icon->texture[0].data.rgba.width = icon->width;
- p->a_icon->texture[0].data.rgba.height = icon->height;
- p->a_icon->texture[0].data.rgba.twidth = ICON_SIZE;
- p->a_icon->texture[0].data.rgba.theight = ICON_SIZE;
- p->a_icon->texture[0].data.rgba.tx = HILITE_OFFSET;
- p->a_icon->texture[0].data.rgba.ty = HILITE_OFFSET;
- p->a_icon->texture[0].data.rgba.alpha =
+ p->a_icon->texture[0].data.image.twidth = ICON_SIZE;
+ p->a_icon->texture[0].data.image.theight = ICON_SIZE;
+ p->a_icon->texture[0].data.image.tx = HILITE_OFFSET;
+ p->a_icon->texture[0].data.image.ty = HILITE_OFFSET;
+ p->a_icon->texture[0].data.image.alpha =
target->client->iconic ? OB_ICONIC_ALPHA : 0xff;
- p->a_icon->texture[0].data.rgba.data = icon->data;
+ p->a_icon->texture[0].data.image.image = target->icon;
/* Draw the hilite? */
p->a_icon->texture[1].type = (target == newtarget) ?
@@ -685,6 +688,7 @@ void focus_cycle_popup_hide(void)
while(popup.targets) {
ObFocusCyclePopupTarget *t = popup.targets->data;
+ RrImageUnref(t->icon);
g_free(t->text);
XDestroyWindow(obt_display, t->iconwin);
XDestroyWindow(obt_display, t->textwin);
@@ -726,8 +730,7 @@ void focus_cycle_popup_single_show(struct _ObClient *c,
}
text = popup_get_name(c);
- icon_popup_show(single_popup, text, client_icon(c, HILITE_SIZE,
- HILITE_SIZE));
+ icon_popup_show(single_popup, text, client_icon(c));
g_free(text);
screen_hide_desktop_popup();
}
diff --git a/openbox/framerender.c b/openbox/framerender.c
index 87706b2b..bf71d2c3 100644
--- a/openbox/framerender.c
+++ b/openbox/framerender.c
@@ -354,21 +354,21 @@ static void framerender_label(ObFrame *self, RrAppearance *a)
static void framerender_icon(ObFrame *self, RrAppearance *a)
{
- const ObClientIcon *icon;
+ RrImage *icon;
if (!self->icon_on) return;
- icon = client_icon(self->client,
- ob_rr_theme->button_size + 2,
- ob_rr_theme->button_size + 2);
+ icon = client_icon(self->client);
+
if (icon) {
- a->texture[0].type = RR_TEXTURE_RGBA;
- a->texture[0].data.rgba.width = icon->width;
- a->texture[0].data.rgba.height = icon->height;
- a->texture[0].data.rgba.alpha = 0xff;
- a->texture[0].data.rgba.data = icon->data;
- } else
+ RrAppearanceClearTextures(a);
+ a->texture[0].type = RR_TEXTURE_IMAGE;
+ a->texture[0].data.image.alpha = 0xff;
+ a->texture[0].data.image.image = icon;
+ } else {
+ RrAppearanceClearTextures(a);
a->texture[0].type = RR_TEXTURE_NONE;
+ }
RrPaint(a, self->icon,
ob_rr_theme->button_size + 2, ob_rr_theme->button_size + 2);
diff --git a/openbox/menu.c b/openbox/menu.c
index 768630bd..63b74b95 100644
--- a/openbox/menu.c
+++ b/openbox/menu.c
@@ -500,6 +500,7 @@ void menu_entry_unref(ObMenuEntry *self)
if (self && --self->ref == 0) {
switch (self->type) {
case OB_MENU_ENTRY_TYPE_NORMAL:
+ RrImageUnref(self->data.normal.icon);
g_free(self->data.normal.label);
while (self->data.normal.actions) {
actions_act_unref(self->data.normal.actions->data);
diff --git a/openbox/menu.h b/openbox/menu.h
index 752a6771..c488f67d 100644
--- a/openbox/menu.h
+++ b/openbox/menu.h
@@ -115,11 +115,9 @@ struct _ObNormalMenuEntry {
/* List of ObActions */
GSList *actions;
- /* Icon shit */
- gint icon_width;
- gint icon_height;
- gint icon_alpha;
- RrPixel32 *icon_data;
+ /* Icon stuff. If you set this, make sure you RrImageRef() it too. */
+ RrImage *icon;
+ gint icon_alpha;
/* Mask icon */
RrPixmapMask *mask;
diff --git a/openbox/menuframe.c b/openbox/menuframe.c
index 598bc005..c25e485f 100644
--- a/openbox/menuframe.c
+++ b/openbox/menuframe.c
@@ -338,6 +338,7 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
default:
g_assert_not_reached();
}
+
RECT_SET_SIZE(self->area, self->frame->inner_w, th);
XResizeWindow(obt_display, self->window,
self->area.width, self->area.height);
@@ -442,6 +443,7 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
self->area.width - 2*PADDING, SEPARATOR_HEIGHT);
clear = ob_rr_theme->a_clear_tex;
+ RrAppearanceClearTextures(clear);
clear->texture[0].type = RR_TEXTURE_LINE_ART;
clear->surface.parent = item_a;
clear->surface.parentx = PADDING;
@@ -459,7 +461,7 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
}
if (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL &&
- self->entry->data.normal.icon_data)
+ self->entry->data.normal.icon)
{
RrAppearance *clear;
@@ -471,15 +473,12 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
- frame->item_margin.bottom);
clear = ob_rr_theme->a_clear_tex;
- clear->texture[0].type = RR_TEXTURE_RGBA;
- clear->texture[0].data.rgba.width =
- self->entry->data.normal.icon_width;
- clear->texture[0].data.rgba.height =
- self->entry->data.normal.icon_height;
- clear->texture[0].data.rgba.alpha =
+ RrAppearanceClearTextures(clear);
+ clear->texture[0].type = RR_TEXTURE_IMAGE;
+ clear->texture[0].data.image.image =
+ self->entry->data.normal.icon;
+ clear->texture[0].data.image.alpha =
self->entry->data.normal.icon_alpha;
- clear->texture[0].data.rgba.data =
- self->entry->data.normal.icon_data;
clear->surface.parent = item_a;
clear->surface.parentx = PADDING;
clear->surface.parenty = frame->item_margin.top;
@@ -503,6 +502,7 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
- frame->item_margin.bottom);
clear = ob_rr_theme->a_clear_tex;
+ RrAppearanceClearTextures(clear);
clear->texture[0].type = RR_TEXTURE_MASK;
clear->texture[0].data.mask.mask =
self->entry->data.normal.mask;
@@ -694,7 +694,7 @@ void menu_frame_render(ObMenuFrame *self)
tw = MIN(tw, MAX_MENU_WIDTH);
th = ob_rr_theme->menu_font_height;
- if (e->entry->data.normal.icon_data ||
+ if (e->entry->data.normal.icon ||
e->entry->data.normal.mask)
has_icon = TRUE;
break;
@@ -705,7 +705,7 @@ void menu_frame_render(ObMenuFrame *self)
tw = MIN(tw, MAX_MENU_WIDTH);
th = ob_rr_theme->menu_font_height;
- if (e->entry->data.normal.icon_data ||
+ if (e->entry->data.normal.icon ||
e->entry->data.normal.mask)
has_icon = TRUE;
diff --git a/openbox/openbox.c b/openbox/openbox.c
index a6a81cef..ec6cc44c 100644
--- a/openbox/openbox.c
+++ b/openbox/openbox.c
@@ -83,16 +83,17 @@
#include <X11/Xlib.h>
#include <X11/keysym.h>
-RrInstance *ob_rr_inst;
-RrTheme *ob_rr_theme;
-ObtMainLoop *ob_main_loop;
-gint ob_screen;
-gboolean ob_replace_wm = FALSE;
-gboolean ob_sm_use = TRUE;
-gchar *ob_sm_id = NULL;
-gchar *ob_sm_save_file = NULL;
-gboolean ob_sm_restore = TRUE;
-gboolean ob_debug_xinerama = FALSE;
+RrInstance *ob_rr_inst;
+RrImageCache *ob_rr_icons;
+RrTheme *ob_rr_theme;
+ObtMainLoop *ob_main_loop;
+gint ob_screen;
+gboolean ob_replace_wm = FALSE;
+gboolean ob_sm_use = TRUE;
+gchar *ob_sm_id = NULL;
+gchar *ob_sm_save_file = NULL;
+gboolean ob_sm_restore = TRUE;
+gboolean ob_debug_xinerama = FALSE;
static ObState state;
static gboolean xsync = FALSE;
@@ -167,6 +168,7 @@ gint main(gint argc, gchar **argv)
ob_rr_inst = RrInstanceNew(obt_display, ob_screen);
if (ob_rr_inst == NULL)
ob_exit_with_error(_("Failed to initialize the obrender library."));
+ ob_rr_icons = RrImageCacheNew();
XSynchronize(obt_display, xsync);
@@ -373,6 +375,7 @@ gint main(gint argc, gchar **argv)
XSync(obt_display, FALSE);
RrThemeFree(ob_rr_theme);
+ RrImageCacheUnref(ob_rr_icons);
RrInstanceFree(ob_rr_inst);
session_shutdown(being_replaced);
diff --git a/openbox/openbox.h b/openbox/openbox.h
index 47d92042..471aa779 100644
--- a/openbox/openbox.h
+++ b/openbox/openbox.h
@@ -30,6 +30,7 @@
#include <X11/Xlib.h>
extern RrInstance *ob_rr_inst;
+extern RrImageCache *ob_rr_icons;
extern RrTheme *ob_rr_theme;
extern ObtMainLoop *ob_main_loop;
diff --git a/openbox/popup.c b/openbox/popup.c
index 02c87848..fd31846e 100644
--- a/openbox/popup.c
+++ b/openbox/popup.c
@@ -366,16 +366,17 @@ void icon_popup_free(ObIconPopup *self)
}
void icon_popup_delay_show(ObIconPopup *self, gulong usec,
- gchar *text, const ObClientIcon *icon)
+ gchar *text, RrImage *icon)
{
if (icon) {
- self->a_icon->texture[0].type = RR_TEXTURE_RGBA;
- self->a_icon->texture[0].data.rgba.width = icon->width;
- self->a_icon->texture[0].data.rgba.height = icon->height;
- self->a_icon->texture[0].data.rgba.alpha = 0xff;
- self->a_icon->texture[0].data.rgba.data = icon->data;
- } else
+ RrAppearanceClearTextures(self->a_icon);
+ self->a_icon->texture[0].type = RR_TEXTURE_IMAGE;
+ self->a_icon->texture[0].data.image.alpha = 0xff;
+ self->a_icon->texture[0].data.image.image = icon;
+ } else {
+ RrAppearanceClearTextures(self->a_icon);
self->a_icon->texture[0].type = RR_TEXTURE_NONE;
+ }
popup_delay_show(self->popup, usec, text);
}
diff --git a/openbox/popup.h b/openbox/popup.h
index 0072f53e..2b01ce24 100644
--- a/openbox/popup.h
+++ b/openbox/popup.h
@@ -110,7 +110,7 @@ void icon_popup_free(ObIconPopup *self);
#define icon_popup_show(s, t, i) icon_popup_delay_show((s),0,(t),(i))
void icon_popup_delay_show(ObIconPopup *self, gulong usec,
- gchar *text, const struct _ObClientIcon *icon);
+ gchar *text, RrImage *icon);
#define icon_popup_hide(p) popup_hide((p)->popup)
#define icon_popup_position(p, g, x, y) popup_position((p)->popup,(g),(x),(y))
#define icon_popup_text_width(p, w) popup_text_width((p)->popup,(w))