]> Dogcows Code - chaz/openbox/blobdiff - openbox/menuframe.c
add keyboard shortcuts to the menus. you can specify the shortcut key with & even...
[chaz/openbox] / openbox / menuframe.c
index a5c301ed6f1617ab18a0169696c2fea1b0519fe1..d92f47df686cc756dc7ae635dafe23e0d522cee6 100644 (file)
@@ -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,13 @@ 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->frame->menu->show_all_shortcuts ||
+            self->entry->data.normal.shortcut_position > 0)
+        {
+            text_a->texture[0].data.text.shortcut =
+                self->entry->data.normal.shortcut;
+        } else
+            text_a->texture[0].data.text.shortcut = 0;
         break;
     case OB_MENU_ENTRY_TYPE_SUBMENU:
         text_a = (self == self->frame->selected ?
@@ -324,8 +332,17 @@ 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 (self->frame->menu->show_all_shortcuts ||
+            sub->shortcut_position > 0) {
+            text_a->texture[0].data.text.shortcut = sub->shortcut;
+        } else
+            text_a->texture[0].data.text.shortcut = 0;
         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 +370,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 +494,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 +514,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 +539,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 +592,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 +610,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 +693,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;
         }
     }
@@ -764,7 +821,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);
     }
 
@@ -841,7 +898,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;
@@ -868,12 +926,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);
@@ -943,7 +1001,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)
@@ -969,5 +1027,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);
 }
This page took 0.030402 seconds and 4 git commands to generate.