summarylogtreecommitdiffstats
path: root/menu_w_def9.patch
diff options
context:
space:
mode:
Diffstat (limited to 'menu_w_def9.patch')
-rw-r--r--menu_w_def9.patch754
1 files changed, 754 insertions, 0 deletions
diff --git a/menu_w_def9.patch b/menu_w_def9.patch
new file mode 100644
index 000000000000..dd2f59dfdab2
--- /dev/null
+++ b/menu_w_def9.patch
@@ -0,0 +1,754 @@
+commit 36f80459b6b8f947023ed551dd61cdd3d8d16d0d
+Author: Alexey Korop <avkorop@i.ua>
+Date: Sat Mar 14 21:07:58 2015 +0200
+
+ menu_w_def8.patch
+
+diff --git a/obrender/theme.c b/obrender/theme.c
+index 2a4f6e1..7b1969f 100644
+--- a/obrender/theme.c
++++ b/obrender/theme.c
+@@ -215,6 +215,8 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
+ theme->a_menu_text_disabled_selected = RrAppearanceNew(inst, 1);
+ theme->a_menu_bullet_normal = RrAppearanceNew(inst, 1);
+ theme->a_menu_bullet_selected = RrAppearanceNew(inst, 1);
++ theme->a_menu_bullet_def_normal = RrAppearanceNew(inst, 1);
++ theme->a_menu_bullet_def_selected = RrAppearanceNew(inst, 1);
+ theme->a_clear = RrAppearanceNew(inst, 0);
+ theme->a_clear_tex = RrAppearanceNew(inst, 1);
+ theme->osd_bg = RrAppearanceNew(inst, 0);
+@@ -527,6 +529,13 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
+ theme->menu_bullet_mask = RrPixmapMaskNew(inst, 4, 7, (gchar*)data);
+ }
+
++ /* submenu with default bullet mask */
++ if (!read_mask(inst, path, "bullet_def.xbm", &theme->menu_bullet_def_mask))
++ {
++ guchar data[] = { 0xFF, 0x85, 0x8D, 0x9D, 0xBD, 0x9D, 0x8D, 0x85, 0xFF };
++ theme->menu_bullet_def_mask = RrPixmapMaskNew(inst, 8, 9, (gchar*)data);
++ }
++
+ /* up and down arrows */
+ {
+ guchar data[] = { 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00, 0x10, 0x00 };
+@@ -618,6 +627,8 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
+ theme->a_menu_text_disabled_selected->surface.grad =
+ theme->a_menu_bullet_normal->surface.grad =
+ theme->a_menu_bullet_selected->surface.grad = RR_SURFACE_PARENTREL;
++ theme->a_menu_bullet_def_normal->surface.grad =
++ theme->a_menu_bullet_def_selected->surface.grad = RR_SURFACE_PARENTREL;
+
+ /* set up the textures */
+ theme->a_focused_label->texture[0].type = RR_TEXTURE_TEXT;
+@@ -932,13 +943,26 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
+
+ theme->a_menu_bullet_normal->texture[0].type =
+ theme->a_menu_bullet_selected->texture[0].type = RR_TEXTURE_MASK;
++ theme->a_menu_bullet_def_normal->texture[0].type =
++ theme->a_menu_bullet_def_selected->texture[0].type = RR_TEXTURE_MASK;
+ theme->a_menu_bullet_normal->texture[0].data.mask.mask =
+ theme->a_menu_bullet_selected->texture[0].data.mask.mask =
+ theme->menu_bullet_mask;
++ theme->a_menu_bullet_def_normal->texture[0].data.mask.mask =
++ theme->a_menu_bullet_def_selected->texture[0].data.mask.mask =
++ theme->menu_bullet_def_mask;
+ theme->a_menu_bullet_normal->texture[0].data.mask.color =
+ theme->menu_bullet_color;
+ theme->a_menu_bullet_selected->texture[0].data.mask.color =
+ theme->menu_bullet_selected_color;
++ theme->a_menu_bullet_def_normal->texture[0].data.mask.color =
++ theme->menu_bullet_color;
++ theme->a_menu_bullet_def_selected->texture[0].data.mask.color =
++ theme->menu_bullet_selected_color;
++ theme->a_menu_bullet_def_normal->texture[0].data.mask.color =
++ theme->menu_bullet_color;
++ theme->a_menu_bullet_def_selected->texture[0].data.mask.color =
++ theme->menu_bullet_selected_color;
+
+ g_free(path);
+ XrmDestroyDatabase(db);
+@@ -1065,6 +1089,7 @@ void RrThemeFree(RrTheme *theme)
+ g_free(theme->def_win_icon);
+
+ RrPixmapMaskFree(theme->menu_bullet_mask);
++ RrPixmapMaskFree(theme->menu_bullet_def_mask);
+ RrPixmapMaskFree(theme->down_arrow_mask);
+ RrPixmapMaskFree(theme->up_arrow_mask);
+
+@@ -1097,6 +1122,8 @@ void RrThemeFree(RrTheme *theme)
+ RrAppearanceFree(theme->a_menu_text_disabled_selected);
+ RrAppearanceFree(theme->a_menu_bullet_normal);
+ RrAppearanceFree(theme->a_menu_bullet_selected);
++ RrAppearanceFree(theme->a_menu_bullet_def_normal);
++ RrAppearanceFree(theme->a_menu_bullet_def_selected);
+ RrAppearanceFree(theme->a_clear);
+ RrAppearanceFree(theme->a_clear_tex);
+ RrAppearanceFree(theme->osd_bg);
+diff --git a/obrender/theme.h b/obrender/theme.h
+index 8797f0b..2c732fc 100644
+--- a/obrender/theme.h
++++ b/obrender/theme.h
+@@ -123,6 +123,7 @@ struct _RrTheme {
+
+ /* style settings - masks */
+ RrPixmapMask *menu_bullet_mask; /* submenu pointer */
++ RrPixmapMask *menu_bullet_def_mask; /* submenu with default pointer */
+ #if 0
+ RrPixmapMask *menu_toggle_mask; /* menu boolean */
+ #endif
+@@ -161,6 +162,8 @@ struct _RrTheme {
+ RrAppearance *a_menu_text_selected;
+ RrAppearance *a_menu_bullet_normal;
+ RrAppearance *a_menu_bullet_selected;
++ RrAppearance *a_menu_bullet_def_normal;
++ RrAppearance *a_menu_bullet_def_selected;
+ RrAppearance *a_clear; /* clear with no texture */
+ RrAppearance *a_clear_tex; /* clear with a texture */
+
+diff --git a/openbox/client_list_combined_menu.c b/openbox/client_list_combined_menu.c
+index c26b6fa..84eb506 100644
+--- a/openbox/client_list_combined_menu.c
++++ b/openbox/client_list_combined_menu.c
+@@ -74,9 +74,9 @@ static gboolean self_update(ObMenuFrame *frame, gpointer data)
+ }
+
+ if (config_menu_show_icons) {
+- e->data.normal.icon = client_icon(c);
+- RrImageRef(e->data.normal.icon);
+- e->data.normal.icon_alpha =
++ e->icon = client_icon(c);
++ RrImageRef(e->icon);
++ e->icon_alpha =
+ c->iconic ? OB_ICONIC_ALPHA : 0xff;
+ }
+
+diff --git a/openbox/client_list_menu.c b/openbox/client_list_menu.c
+index f3df2a5..4f85935 100644
+--- a/openbox/client_list_menu.c
++++ b/openbox/client_list_menu.c
+@@ -70,9 +70,9 @@ static gboolean desk_menu_update(ObMenuFrame *frame, gpointer data)
+ }
+
+ if (config_menu_show_icons) {
+- e->data.normal.icon = client_icon(c);
+- RrImageRef(e->data.normal.icon);
+- e->data.normal.icon_alpha = c->iconic ? OB_ICONIC_ALPHA : 0xff;
++ e->icon = client_icon(c);
++ RrImageRef(e->icon);
++ e->icon_alpha = c->iconic ? OB_ICONIC_ALPHA : 0xff;
+ }
+
+ e->data.normal.data = c;
+diff --git a/openbox/client_menu.c b/openbox/client_menu.c
+index 4a3b286..6d5c4c7 100644
+--- a/openbox/client_menu.c
++++ b/openbox/client_menu.c
+@@ -57,10 +57,10 @@ enum {
+
+ static void set_icon_color(ObMenuEntry *e)
+ {
+- e->data.normal.mask_normal_color = ob_rr_theme->menu_color;
+- e->data.normal.mask_selected_color = ob_rr_theme->menu_selected_color;
+- e->data.normal.mask_disabled_color = ob_rr_theme->menu_disabled_color;
+- e->data.normal.mask_disabled_selected_color =
++ e->mask_normal_color = ob_rr_theme->menu_color;
++ e->mask_selected_color = ob_rr_theme->menu_selected_color;
++ e->mask_disabled_color = ob_rr_theme->menu_disabled_color;
++ e->mask_disabled_selected_color =
+ ob_rr_theme->menu_disabled_selected_color;
+ }
+
+@@ -276,10 +276,10 @@ static gboolean send_to_menu_update(ObMenuFrame *frame, gpointer data)
+ if ((desk == DESKTOP_ALL && c->desktop != DESKTOP_ALL) ||
+ (c->desktop == DESKTOP_ALL && desk == screen_desktop))
+ {
+- e->data.normal.mask = ob_rr_theme->btn_desk->unpressed_mask;
++ e->mask = ob_rr_theme->btn_desk->unpressed_mask;
+ set_icon_color(e);
+ } else
+- e->data.normal.mask = NULL;
++ e->mask = NULL;
+ }
+
+ return TRUE; /* show the menu */
+@@ -392,7 +392,7 @@ void client_menu_startup(void)
+ menu_add_submenu(menu, CLIENT_LAYER, LAYER_MENU_NAME);
+
+ e = menu_add_normal(menu, CLIENT_RESTORE, _("R_estore"), NULL, TRUE);
+- e->data.normal.mask = ob_rr_theme->btn_max->unpressed_toggled_mask;
++ e->mask = ob_rr_theme->btn_max->unpressed_toggled_mask;
+ set_icon_color(e);
+
+ menu_add_normal(menu, CLIENT_MOVE, _("_Move"), NULL, TRUE);
+@@ -400,15 +400,15 @@ void client_menu_startup(void)
+ menu_add_normal(menu, CLIENT_RESIZE, _("Resi_ze"), NULL, TRUE);
+
+ e = menu_add_normal(menu, CLIENT_ICONIFY, _("Ico_nify"), NULL, TRUE);
+- e->data.normal.mask = ob_rr_theme->btn_iconify->unpressed_mask;
++ e->mask = ob_rr_theme->btn_iconify->unpressed_mask;
+ set_icon_color(e);
+
+ e = menu_add_normal(menu, CLIENT_MAXIMIZE, _("Ma_ximize"), NULL, TRUE);
+- e->data.normal.mask = ob_rr_theme->btn_max->unpressed_mask;
++ e->mask = ob_rr_theme->btn_max->unpressed_mask;
+ set_icon_color(e);
+
+ e = menu_add_normal(menu, CLIENT_SHADE, _("_Roll up/down"), NULL, TRUE);
+- e->data.normal.mask = ob_rr_theme->btn_shade->unpressed_mask;
++ e->mask = ob_rr_theme->btn_shade->unpressed_mask;
+ set_icon_color(e);
+
+ menu_add_normal(menu, CLIENT_DECORATE, _("Un/_Decorate"), NULL, TRUE);
+@@ -416,6 +416,6 @@ void client_menu_startup(void)
+ menu_add_separator(menu, -1, NULL);
+
+ e = menu_add_normal(menu, CLIENT_CLOSE, _("_Close"), NULL, TRUE);
+- e->data.normal.mask = ob_rr_theme->btn_close->unpressed_mask;
++ e->mask = ob_rr_theme->btn_close->unpressed_mask;
+ set_icon_color(e);
+ }
+diff --git a/openbox/event.c b/openbox/event.c
+index 5774f67..fd3ecb5 100644
+--- a/openbox/event.c
++++ b/openbox/event.c
+@@ -1845,9 +1845,17 @@ static gboolean event_handle_menu_input(XEvent *ev)
+ menu_frame_select(e->frame->child, NULL, TRUE);
+ }
+ menu_frame_select(e->frame, e, TRUE);
+- if (ev->type == ButtonRelease)
++ if ((ev->type == ButtonRelease) && (ev->xbutton.button==1)
++ && (menu_entry_frame_x_not_in_bullet(e->frame, ev->xbutton.x)))
++ {
++ /* execute clicked entry or it's default entry */
++ if (e->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) {
++ if (e->frame->child && e->frame->child->default_entry)
++ e = e->frame->child->default_entry;
++ }
+ menu_entry_frame_execute(e, ev->xbutton.state);
+ }
++ }
+ else
+ menu_frame_hide_all();
+ }
+@@ -1892,24 +1900,15 @@ static gboolean event_handle_menu_input(XEvent *ev)
+ ret = TRUE;
+ }
+
+- else if (sym == XK_Right || sym == XK_Return || sym == XK_KP_Enter)
++ else if (sym == XK_Right) {
++ /* Right goes to the selected submenu */
++ if (frame->selected &&
++ frame->selected->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU)
+ {
+- /* Right and enter goes to the selected submenu.
+- Enter executes instead if it's not on a submenu. */
+-
+- if (frame->selected) {
+- const ObMenuEntryType t = frame->selected->entry->type;
+-
+- if (t == OB_MENU_ENTRY_TYPE_SUBMENU) {
+ /* make sure it is visible */
+ menu_frame_select(frame, frame->selected, TRUE);
+- /* move focus to the child menu */
+ menu_frame_select_next(frame->child);
+ }
+- else if (sym != XK_Right) {
+- frame->press_doexec = TRUE;
+- }
+- }
+ ret = TRUE;
+ }
+
+@@ -1933,6 +1932,14 @@ static gboolean event_handle_menu_input(XEvent *ev)
+ ret = TRUE;
+ }
+
++ else if (sym == XK_Return || sym == XK_KP_Enter) {
++ if (frame->selected &&
++ frame->selected->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU)
++ menu_frame_select(frame, frame->selected, TRUE);
++ frame->press_doexec = TRUE;
++ ret = TRUE;
++ }
++
+ /* keyboard accelerator shortcuts. (if it was a valid key) */
+ else if (frame->entries &&
+ (unikey =
+@@ -1979,13 +1986,14 @@ static gboolean event_handle_menu_input(XEvent *ev)
+ menu_frame_select(frame, found, TRUE);
+
+ if (num_found == 1) {
+- if (found->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) {
++ if (found->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU &&
++ ! frame->child->default_entry)
++ {
+ /* move focus to the child menu */
+ menu_frame_select_next(frame->child);
+ }
+- else {
++ else
+ frame->press_doexec = TRUE;
+- }
+ }
+ ret = TRUE;
+ }
+@@ -1995,14 +2003,22 @@ static gboolean event_handle_menu_input(XEvent *ev)
+ /* Use KeyRelease events for running things so that the key release
+ doesn't get sent to the focused application.
+
+- Allow ControlMask only, and don't bother if the menu is empty */
+- else if (ev->type == KeyRelease && (mods & ~ControlMask) == 0) {
+- if (frame->press_keycode == ev->xkey.keycode &&
++ Allow all modifiers, and don't bother if the menu is empty */
++ else if (ev->type == KeyRelease) {
++ if ((frame->press_keycode == ev->xkey.keycode) &&
+ frame->got_press &&
+ frame->press_doexec)
+ {
+- if (frame->selected)
+- menu_entry_frame_execute(frame->selected, ev->xkey.state);
++ if (frame->selected){
++ ObMenuEntryFrame *e = frame->selected;
++
++ /* execute selected entry or it's default entry */
++ if (e->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) {
++ if (e->frame->child && e->frame->child->default_entry)
++ e = e->frame->child->default_entry;
++ }
++ menu_entry_frame_execute(e, ev->xkey.state);
++ }
+ }
+ }
+ }
+diff --git a/openbox/menu.c b/openbox/menu.c
+index 8804e12..6c0cf7e 100644
+--- a/openbox/menu.c
++++ b/openbox/menu.c
+@@ -281,6 +281,7 @@ static void parse_menu_item(xmlNodePtr node, gpointer data)
+ {
+ ObMenuParseState *state = data;
+ gchar *label;
++ gboolean is_default = FALSE;
+ gchar *icon;
+ ObMenuEntry *e;
+
+@@ -288,6 +289,7 @@ static void parse_menu_item(xmlNodePtr node, gpointer data)
+ /* Don't try to extract "icon" attribute if icons in user-defined
+ menus are not enabled. */
+
++ obt_xml_attr_bool(node, "default", &is_default);
+ if (obt_xml_attr_string_unstripped(node, "label", &label)) {
+ xmlNodePtr c;
+ GSList *acts = NULL;
+@@ -300,14 +302,15 @@ static void parse_menu_item(xmlNodePtr node, gpointer data)
+ c = obt_xml_find_node(c->next, "action");
+ }
+ e = menu_add_normal(state->parent, -1, label, acts, TRUE);
+-
++ if (is_default && !state->parent->default_entry)
++ state->parent->default_entry = e;
+ if (config_menu_show_icons &&
+ obt_xml_attr_string(node, "icon", &icon))
+ {
+- e->data.normal.icon = RrImageNewFromName(ob_rr_icons, icon);
++ e->icon = RrImageNewFromName(ob_rr_icons, icon);
+
+- if (e->data.normal.icon)
+- e->data.normal.icon_alpha = 0xff;
++ if (e->icon)
++ e->icon_alpha = 0xff;
+
+ g_free(icon);
+ }
+@@ -367,10 +370,10 @@ static void parse_menu(xmlNodePtr node, gpointer data)
+ if (config_menu_show_icons &&
+ obt_xml_attr_string(node, "icon", &icon))
+ {
+- e->data.submenu.icon = RrImageNewFromName(ob_rr_icons, icon);
++ e->icon = RrImageNewFromName(ob_rr_icons, icon);
+
+- if (e->data.submenu.icon)
+- e->data.submenu.icon_alpha = 0xff;
++ if (e->icon)
++ e->icon_alpha = 0xff;
+
+ g_free(icon);
+ }
+@@ -559,7 +562,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);
++ RrImageUnref(self->icon);
+ g_free(self->data.normal.label);
+ g_free(self->data.normal.collate_key);
+ while (self->data.normal.actions) {
+@@ -570,7 +573,7 @@ void menu_entry_unref(ObMenuEntry *self)
+ }
+ break;
+ case OB_MENU_ENTRY_TYPE_SUBMENU:
+- RrImageUnref(self->data.submenu.icon);
++ RrImageUnref(self->icon);
+ g_free(self->data.submenu.name);
+ break;
+ case OB_MENU_ENTRY_TYPE_SEPARATOR:
+diff --git a/openbox/menu.h b/openbox/menu.h
+index 8c2ecd7..04dcf10 100644
+--- a/openbox/menu.h
++++ b/openbox/menu.h
+@@ -78,6 +78,9 @@ struct _ObMenu
+ /* ObMenuEntry list */
+ GList *entries;
+
++ /* default entry */
++ ObMenuEntry *default_entry;
++
+ /* plugin data */
+ gpointer data;
+
+@@ -104,10 +107,6 @@ typedef enum
+ } ObMenuEntryType;
+
+ struct _ObNormalMenuEntry {
+- /* Icon stuff. If you set this, make sure you RrImageRef() it too. */
+- RrImage *icon;
+- gint icon_alpha;
+-
+ gchar *label;
+ gchar *collate_key;
+ /*! The shortcut key that would be used to activate this menu entry */
+@@ -123,21 +122,10 @@ struct _ObNormalMenuEntry {
+ /* List of ObActions */
+ GSList *actions;
+
+- /* Mask icon */
+- RrPixmapMask *mask;
+- RrColor *mask_normal_color;
+- RrColor *mask_selected_color;
+- RrColor *mask_disabled_color;
+- RrColor *mask_disabled_selected_color;
+-
+ gpointer data;
+ };
+
+ struct _ObSubmenuMenuEntry {
+- /* Icon stuff. If you set this, make sure you RrImageRef() it too. */
+- RrImage *icon;
+- gint icon_alpha;
+-
+ gchar *name;
+ ObMenu *submenu;
+
+@@ -157,6 +145,17 @@ struct _ObMenuEntry
+
+ gint id;
+
++ /* Icon stuff. If you set this, make sure you RrImageRef() it too. */
++ RrImage *icon;
++ gint icon_alpha;
++
++ /* Mask icon */
++ RrPixmapMask *mask;
++ RrColor *mask_normal_color;
++ RrColor *mask_selected_color;
++ RrColor *mask_disabled_color;
++ RrColor *mask_disabled_selected_color;
++
+ union u {
+ ObNormalMenuEntry normal;
+ ObSubmenuMenuEntry submenu;
+diff --git a/openbox/menuframe.c b/openbox/menuframe.c
+index 2398031..943ff69 100644
+--- a/openbox/menuframe.c
++++ b/openbox/menuframe.c
+@@ -35,6 +35,9 @@
+
+ #define ITEM_HEIGHT (ob_rr_theme->menu_font_height + 2*PADDING)
+
++ /* offset at which the submenu bullet appears in the items */
++#define BULLET_X (frame->text_x + frame->text_w - ITEM_HEIGHT + PADDING)
++
+ #define FRAME_EVENTMASK (ButtonPressMask |ButtonMotionMask | EnterWindowMask |\
+ LeaveWindowMask)
+ #define ENTRY_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
+@@ -187,7 +190,10 @@ static ObMenuEntryFrame* menu_entry_frame_new(ObMenuEntry *entry,
+ self->icon = createWindow(self->window, 0, NULL);
+ g_hash_table_insert(menu_frame_map, &self->icon, self);
+ }
+- if (entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) {
++ if (entry->type == OB_MENU_ENTRY_TYPE_SUBMENU
++ || (entry->type == OB_MENU_ENTRY_TYPE_NORMAL
++ && entry == entry->menu->default_entry))
++ {
+ self->bullet = createWindow(self->window, 0, NULL);
+ g_hash_table_insert(menu_frame_map, &self->bullet, self);
+ }
+@@ -209,12 +215,11 @@ static void menu_entry_frame_free(ObMenuEntryFrame *self)
+ XDestroyWindow(obt_display, self->window);
+ g_hash_table_remove(menu_frame_map, &self->text);
+ g_hash_table_remove(menu_frame_map, &self->window);
+- if ((self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL) ||
+- (self->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU)) {
++ if (self->icon) {
+ XDestroyWindow(obt_display, self->icon);
+ g_hash_table_remove(menu_frame_map, &self->icon);
+ }
+- if (self->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) {
++ if (self->bullet) {
+ XDestroyWindow(obt_display, self->bullet);
+ g_hash_table_remove(menu_frame_map, &self->bullet);
+ }
+@@ -372,6 +377,7 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
+ gint th; /* temp */
+ ObMenu *sub;
+ ObMenuFrame *frame = self->frame;
++ gboolean has_bullet;
+
+ switch (self->entry->type) {
+ case OB_MENU_ENTRY_TYPE_NORMAL:
+@@ -532,14 +538,34 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
+ g_assert_not_reached();
+ }
+
+- if (((self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL) ||
+- (self->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU)) &&
+- self->entry->data.normal.icon)
++ has_bullet = FALSE;
++ if ((self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL) &&
++ frame->parent &&
++ (self == self->frame->default_entry))
+ {
++ // show the mark of the default item
++ RrAppearance *bullet_a;
++
++ XMoveResizeWindow(obt_display, self->bullet,
++ PADDING, PADDING,
++ ITEM_HEIGHT - 2*PADDING,
++ ITEM_HEIGHT - 2*PADDING);
++ bullet_a = ((self == self->frame->selected) ?
++ ob_rr_theme->a_menu_bullet_def_selected :
++ ob_rr_theme->a_menu_bullet_def_normal);
++ bullet_a->surface.parent = item_a;
++ bullet_a->surface.parentx = 0;
++ bullet_a->surface.parenty = PADDING;
++ RrPaint(bullet_a, self->bullet,
++ self->frame->icon_x,
++ ITEM_HEIGHT - 2*PADDING);
++ has_bullet = TRUE;
++ }
++ if (self->entry->icon){
+ RrAppearance *clear;
+
+ XMoveResizeWindow(obt_display, self->icon,
+- PADDING, frame->item_margin.top,
++ self->frame->icon_x, frame->item_margin.top,
+ ITEM_HEIGHT - frame->item_margin.top
+ - frame->item_margin.bottom,
+ ITEM_HEIGHT - frame->item_margin.top
+@@ -549,9 +575,9 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
+ RrAppearanceClearTextures(clear);
+ clear->texture[0].type = RR_TEXTURE_IMAGE;
+ clear->texture[0].data.image.image =
+- self->entry->data.normal.icon;
++ self->entry->icon;
+ clear->texture[0].data.image.alpha =
+- self->entry->data.normal.icon_alpha;
++ self->entry->icon_alpha;
+ clear->surface.parent = item_a;
+ clear->surface.parentx = PADDING;
+ clear->surface.parenty = frame->item_margin.top;
+@@ -562,13 +588,13 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
+ - frame->item_margin.bottom);
+ XMapWindow(obt_display, self->icon);
+ } else if (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL &&
+- self->entry->data.normal.mask)
++ self->entry->mask)
+ {
+ RrColor *c;
+ RrAppearance *clear;
+
+ XMoveResizeWindow(obt_display, self->icon,
+- PADDING, frame->item_margin.top,
++ self->frame->icon_x, frame->item_margin.top,
+ ITEM_HEIGHT - frame->item_margin.top
+ - frame->item_margin.bottom,
+ ITEM_HEIGHT - frame->item_margin.top
+@@ -578,22 +604,22 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
+ RrAppearanceClearTextures(clear);
+ clear->texture[0].type = RR_TEXTURE_MASK;
+ clear->texture[0].data.mask.mask =
+- self->entry->data.normal.mask;
++ self->entry->mask;
+
+ c = (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL &&
+ !self->entry->data.normal.enabled ?
+ /* disabled */
+ (self == self->frame->selected ?
+- self->entry->data.normal.mask_disabled_selected_color :
+- self->entry->data.normal.mask_disabled_color) :
++ self->entry->mask_disabled_selected_color :
++ self->entry->mask_disabled_color) :
+ /* enabled */
+ (self == self->frame->selected ?
+- self->entry->data.normal.mask_selected_color :
+- self->entry->data.normal.mask_normal_color));
++ self->entry->mask_selected_color :
++ self->entry->mask_normal_color));
+ clear->texture[0].data.mask.color = c;
+
+ clear->surface.parent = item_a;
+- clear->surface.parentx = PADDING;
++ clear->surface.parentx = self->frame->icon_x;
+ clear->surface.parenty = frame->item_margin.top;
+ RrPaint(clear, self->icon,
+ ITEM_HEIGHT - frame->item_margin.top
+@@ -607,13 +633,17 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
+ if (self->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) {
+ RrAppearance *bullet_a;
+ XMoveResizeWindow(obt_display, self->bullet,
+- self->frame->text_x + self->frame->text_w -
+- ITEM_HEIGHT + PADDING, PADDING,
++ BULLET_X, PADDING,
+ ITEM_HEIGHT - 2*PADDING,
+ ITEM_HEIGHT - 2*PADDING);
+- bullet_a = (self == self->frame->selected ?
+- ob_rr_theme->a_menu_bullet_selected :
+- ob_rr_theme->a_menu_bullet_normal);
++ if (sub->default_entry)
++ bullet_a = ((self == self->frame->selected) ?
++ ob_rr_theme->a_menu_bullet_def_selected :
++ ob_rr_theme->a_menu_bullet_def_normal);
++ else
++ bullet_a = ((self == self->frame->selected) ?
++ ob_rr_theme->a_menu_bullet_selected :
++ ob_rr_theme->a_menu_bullet_normal);
+ bullet_a->surface.parent = item_a;
+ bullet_a->surface.parentx =
+ self->frame->text_x + self->frame->text_w - ITEM_HEIGHT + PADDING;
+@@ -621,8 +651,11 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
+ RrPaint(bullet_a, self->bullet,
+ ITEM_HEIGHT - 2*PADDING,
+ ITEM_HEIGHT - 2*PADDING);
++ has_bullet = TRUE;
++ }
++ if (has_bullet)
+ XMapWindow(obt_display, self->bullet);
+- } else
++ else
+ XUnmapWindow(obt_display, self->bullet);
+
+ XFlush(obt_display);
+@@ -767,8 +800,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 ||
+- e->entry->data.normal.mask)
++ if (e->entry->icon || e->entry->mask)
+ has_icon = TRUE;
+ break;
+ case OB_MENU_ENTRY_TYPE_SUBMENU:
+@@ -778,8 +810,8 @@ 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 ||
+- e->entry->data.normal.mask)
++ if (e->entry->icon ||
++ e->entry->mask)
+ has_icon = TRUE;
+
+ tw += ITEM_HEIGHT - PADDING;
+@@ -818,10 +850,17 @@ void menu_frame_render(ObMenuFrame *self)
+ h -= ob_rr_theme->mbwidth;
+ }
+
++ self->icon_x = PADDING;
+ self->text_x = PADDING;
+ self->text_w = w;
+
+ if (self->entries) {
++ gint def_w = ITEM_HEIGHT-2*PADDING;
++ if (self->parent && self->menu->default_entry) {
++ w += def_w;
++ self->icon_x += def_w;
++ self->text_x += def_w;
++ }
+ if (has_icon) {
+ w += ITEM_HEIGHT + PADDING;
+ self->text_x += ITEM_HEIGHT + PADDING;
+@@ -852,6 +891,7 @@ static void menu_frame_update(ObMenuFrame *self)
+ {
+ GList *mit, *fit;
+ const Rect *a;
++ ObMenuEntry *menu_default_entry;
+ gint h;
+
+ menu_pipe_execute(self->menu);
+@@ -871,10 +911,13 @@ static void menu_frame_update(ObMenuFrame *self)
+ f->entry = mit->data;
+ }
+
++ menu_default_entry = self->menu->default_entry;
+ /* if there are more menu entries than in the frame, add them */
+ while (mit) {
+ ObMenuEntryFrame *e = menu_entry_frame_new(mit->data, self);
+ self->entries = g_list_append(self->entries, e);
++ if (menu_default_entry == e->entry)
++ self->default_entry = e;
+ mit = g_list_next(mit);
+ }
+
+@@ -957,7 +1000,7 @@ static gboolean menu_frame_is_visible(ObMenuFrame *self)
+ return !!(g_list_find(menu_frame_visible, self));
+ }
+
+-static gboolean menu_frame_show(ObMenuFrame *self)
++gboolean menu_frame_show(ObMenuFrame *self)
+ {
+ GList *it;
+
+@@ -1178,6 +1221,11 @@ ObMenuEntryFrame* menu_entry_frame_under(gint x, gint y)
+ return ret;
+ }
+
++gboolean menu_entry_frame_x_not_in_bullet(ObMenuFrame* frame, gint x /* local */)
++{
++ return(x <= BULLET_X);
++}
++
+ static gboolean submenu_show_timeout(gpointer data)
+ {
+ g_assert(menu_frame_visible);
+diff --git a/openbox/menuframe.h b/openbox/menuframe.h
+index 7b295b6..ffcedf6 100644
+--- a/openbox/menuframe.h
++++ b/openbox/menuframe.h
+@@ -55,6 +55,8 @@ struct _ObMenuFrame
+
+ GList *entries;
+ ObMenuEntryFrame *selected;
++ /* default entry */
++ ObMenuEntryFrame *default_entry;
+
+ /* show entries from the menu starting at this index */
+ guint show_from;
+@@ -67,6 +69,7 @@ struct _ObMenuFrame
+ Strut item_margin;
+ gint inner_w; /* inside the borders */
+ gint item_h; /* height of all normal items */
++ gint icon_x; /* offset at which the icon or mask appears in the items */
+ gint text_x; /* offset at which the text appears in the items */
+ gint text_w; /* width of the text area in the items */
+ gint text_h; /* height of the items */
+@@ -140,8 +143,10 @@ void menu_frame_select_last(ObMenuFrame *self);
+
+ ObMenuFrame* menu_frame_under(gint x, gint y);
+ ObMenuEntryFrame* menu_entry_frame_under(gint x, gint y);
++gboolean menu_entry_frame_x_not_in_bullet(ObMenuFrame* frame, gint x /* local */);
+
+ void menu_entry_frame_show_submenu(ObMenuEntryFrame *self);
++gboolean menu_frame_show(ObMenuFrame *self);
+
+ void menu_entry_frame_execute(ObMenuEntryFrame *self, guint state);
+