X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;ds=inline;f=openbox%2Fmenuframe.c;h=7ca2136ca1f13ab98947be969788331ffb36e147;hb=a65b1d202f11a0e1e87b9343a9a620321e84f6cf;hp=c417c05a11df59512f0420b6a58abc0a29e08a4f;hpb=957963e272be1fba1e06dd2bdcfa9a4348121baf;p=chaz%2Fopenbox diff --git a/openbox/menuframe.c b/openbox/menuframe.c index c417c05a..7ca2136c 100644 --- a/openbox/menuframe.c +++ b/openbox/menuframe.c @@ -163,6 +163,8 @@ static ObMenuEntryFrame* menu_entry_frame_new(ObMenuEntry *entry, RrAppearanceCopy(ob_rr_theme->a_menu_text_disabled); self->a_text_selected = RrAppearanceCopy(ob_rr_theme->a_menu_text_selected); + self->a_text_title = + RrAppearanceCopy(ob_rr_theme->a_menu_text_title); return self; } @@ -172,15 +174,15 @@ static void menu_entry_frame_free(ObMenuEntryFrame *self) if (self) { XDestroyWindow(ob_display, self->text); XDestroyWindow(ob_display, self->window); - g_hash_table_insert(menu_frame_map, &self->text, self); - g_hash_table_insert(menu_frame_map, &self->window, self); + 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) { XDestroyWindow(ob_display, self->icon); - g_hash_table_insert(menu_frame_map, &self->icon, self); + g_hash_table_remove(menu_frame_map, &self->icon); } if (self->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) { XDestroyWindow(ob_display, self->bullet); - g_hash_table_insert(menu_frame_map, &self->bullet, self); + g_hash_table_remove(menu_frame_map, &self->bullet); } RrAppearanceFree(self->a_normal); @@ -193,6 +195,7 @@ static void menu_entry_frame_free(ObMenuEntryFrame *self) RrAppearanceFree(self->a_text_normal); RrAppearanceFree(self->a_text_disabled); RrAppearanceFree(self->a_text_selected); + RrAppearanceFree(self->a_text_title); RrAppearanceFree(self->a_bullet_normal); RrAppearanceFree(self->a_bullet_selected); @@ -290,9 +293,7 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) case OB_MENU_ENTRY_TYPE_SEPARATOR: if (self->entry->data.separator.label) { item_a = self->frame->a_title; - item_a->texture[0].data.text.string = - self->entry->data.separator.label; - th = self->frame->title_h; + th = ob_rr_theme->menu_title_height; } else { item_a = self->a_normal; th = SEPARATOR_HEIGHT + 2*PADDING; @@ -317,6 +318,15 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) self->a_text_selected : self->a_text_normal)); text_a->texture[0].data.text.string = self->entry->data.normal.label; + if (self->entry->data.normal.shortcut && + (self->frame->menu->show_all_shortcuts || + self->entry->data.normal.shortcut_position > 0)) + { + text_a->texture[0].data.text.shortcut = TRUE; + text_a->texture[0].data.text.shortcut_pos = + self->entry->data.normal.shortcut_position; + } else + text_a->texture[0].data.text.shortcut = FALSE; break; case OB_MENU_ENTRY_TYPE_SUBMENU: text_a = (self == self->frame->selected ? @@ -324,8 +334,19 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) self->a_text_normal); sub = self->entry->data.submenu.submenu; text_a->texture[0].data.text.string = sub ? sub->title : ""; + if (sub->shortcut && (self->frame->menu->show_all_shortcuts || + sub->shortcut_position > 0)) + { + text_a->texture[0].data.text.shortcut = TRUE; + text_a->texture[0].data.text.shortcut_pos = sub->shortcut_position; + } else + text_a->texture[0].data.text.shortcut = FALSE; break; case OB_MENU_ENTRY_TYPE_SEPARATOR: + if (self->entry->data.separator.label != NULL) + text_a = self->a_text_title; + else + text_a = self->a_text_normal; break; } @@ -353,7 +374,22 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) self->frame->item_h - 2*PADDING); break; case OB_MENU_ENTRY_TYPE_SEPARATOR: - if (self->entry->data.separator.label == NULL) { + if (self->entry->data.separator.label != NULL) { + /* labeled separator */ + XMoveResizeWindow(ob_display, self->text, + ob_rr_theme->paddingx, ob_rr_theme->paddingy, + self->area.width - 2*ob_rr_theme->paddingx, + ob_rr_theme->menu_title_height - + 2*ob_rr_theme->paddingy); + text_a->surface.parent = item_a; + text_a->surface.parentx = ob_rr_theme->paddingx; + text_a->surface.parenty = ob_rr_theme->paddingy; + RrPaint(text_a, self->text, + self->area.width - 2*ob_rr_theme->paddingx, + ob_rr_theme->menu_title_height - + 2*ob_rr_theme->paddingy); + } else { + /* unlabeled separaator */ XMoveResizeWindow(ob_display, self->text, PADDING, PADDING, self->area.width - 2*PADDING, SEPARATOR_HEIGHT); self->a_separator->surface.parent = item_a; @@ -462,6 +498,7 @@ static void menu_frame_render(ObMenuFrame *self) GList *it; gboolean has_icon = FALSE; ObMenu *sub; + ObMenuEntryFrame *e; XSetWindowBorderWidth(ob_display, self->window, ob_rr_theme->mbwidth); XSetWindowBorder(ob_display, self->window, @@ -481,12 +518,6 @@ static void menu_frame_render(ObMenuFrame *self) th += 2*PADDING; self->item_h = th; - self->a_title->texture[0].data.text.string = ""; - RrMinsize(self->a_title, &tw, &th); - tw += 2*PADDING; - th += 2*PADDING; - self->title_h = th; - RrMargins(e->a_normal, &l, &t, &r, &b); STRUT_SET(self->item_margin, MAX(self->item_margin.left, l), @@ -512,10 +543,28 @@ static void menu_frame_render(ObMenuFrame *self) for (it = self->entries; it; it = g_list_next(it)) { RrAppearance *text_a; - ObMenuEntryFrame *e = it->data; + e = it->data; + + /* if the first entry is a labeled separator, then make its border + overlap with the menu's outside border */ + if (it == self->entries && + e->entry->type == OB_MENU_ENTRY_TYPE_SEPARATOR && + e->entry->data.separator.label) + { + h -= ob_rr_theme->mbwidth; + } + + if (e->entry->type == OB_MENU_ENTRY_TYPE_SEPARATOR && + e->entry->data.separator.label) + { + e->border = ob_rr_theme->mbwidth; + } - RECT_SET_POINT(e->area, 0, h); - XMoveWindow(ob_display, e->window, 0, e->area.y); + RECT_SET_POINT(e->area, 0, h+e->border); + XMoveWindow(ob_display, e->window, e->area.x-e->border, e->area.y-e->border); + XSetWindowBorderWidth(ob_display, e->window, e->border); + XSetWindowBorder(ob_display, e->window, + RrColorPixel(ob_rr_theme->menu_b_color)); text_a = ((e->entry->type == OB_MENU_ENTRY_TYPE_NORMAL && !e->entry->data.normal.enabled) ? @@ -547,10 +596,12 @@ static void menu_frame_render(ObMenuFrame *self) break; case OB_MENU_ENTRY_TYPE_SEPARATOR: if (e->entry->data.separator.label != NULL) { - self->a_title->texture[0].data.text.string = + e->a_text_title->texture[0].data.text.string = e->entry->data.separator.label; - RrMinsize(self->a_title, &tw, &th); + RrMinsize(e->a_text_title, &tw, &th); tw = MIN(tw, MAX_MENU_WIDTH); + th = ob_rr_theme->menu_title_height + + (ob_rr_theme->mbwidth - PADDING) *2; } else { tw = 0; th = SEPARATOR_HEIGHT; @@ -563,6 +614,16 @@ static void menu_frame_render(ObMenuFrame *self) h += th; } + /* if the last entry is a labeled separator, then make its border + overlap with the menu's outside border */ + it = g_list_last(self->entries); + e = it ? it->data : NULL; + if (e && e->entry->type == OB_MENU_ENTRY_TYPE_SEPARATOR && + e->entry->data.separator.label) + { + h -= ob_rr_theme->mbwidth; + } + self->text_x = PADDING; self->text_w = w; @@ -636,10 +697,10 @@ static gboolean menu_frame_show(ObMenuFrame *self) if (menu_frame_visible == NULL) { /* no menus shown yet */ - if (!grab_pointer(TRUE, OB_CURSOR_POINTER)) + if (!grab_pointer(TRUE, TRUE, OB_CURSOR_POINTER)) return FALSE; if (!grab_keyboard(TRUE)) { - grab_pointer(FALSE, OB_CURSOR_POINTER); + grab_pointer(FALSE, TRUE, OB_CURSOR_POINTER); return FALSE; } } @@ -738,7 +799,8 @@ gboolean menu_frame_show_submenu(ObMenuFrame *self, ObMenuFrame *parent, XMapWindow(ob_display, self->window); - if (screen_pointer_pos(&dx, &dy) && (e = menu_entry_frame_under(dx, dy))) + if (screen_pointer_pos(&dx, &dy) && (e = menu_entry_frame_under(dx, dy)) && + e->frame == self) ++e->ignore_enters; return TRUE; @@ -763,7 +825,7 @@ void menu_frame_hide(ObMenuFrame *self) if (menu_frame_visible == NULL) { /* last menu shown */ - grab_pointer(FALSE, OB_CURSOR_NONE); + grab_pointer(FALSE, TRUE, OB_CURSOR_NONE); grab_keyboard(FALSE); } @@ -840,7 +902,8 @@ static gboolean menu_entry_frame_submenu_timeout(gpointer data) return FALSE; } -void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry) +void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry, + gboolean immediate) { ObMenuEntryFrame *old = self->selected; ObMenuFrame *oldchild = self->child; @@ -867,12 +930,12 @@ void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry) menu_entry_frame_render(self->selected); if (self->selected->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) { - if (config_submenu_show_delay) { + if (config_submenu_show_delay && !immediate) { /* initiate a new submenu open request */ ob_main_loop_timeout_add(ob_main_loop, config_submenu_show_delay * 1000, menu_entry_frame_submenu_timeout, - self->selected, + self->selected, g_direct_equal, NULL); } else { menu_entry_frame_show_submenu(self->selected); @@ -942,7 +1005,7 @@ void menu_frame_select_previous(ObMenuFrame *self) } } } - menu_frame_select(self, it ? it->data : NULL); + menu_frame_select(self, it ? it->data : NULL, TRUE); } void menu_frame_select_next(ObMenuFrame *self) @@ -968,5 +1031,5 @@ void menu_frame_select_next(ObMenuFrame *self) } } } - menu_frame_select(self, it ? it->data : NULL); + menu_frame_select(self, it ? it->data : NULL, TRUE); }