]> Dogcows Code - chaz/openbox/blobdiff - openbox/menuframe.c
80 cols everywhere
[chaz/openbox] / openbox / menuframe.c
index b04fda55a746579a7f75fbf1047fdcf2b63890ce..7fff8b691263d16c8adb9ad7822c2be9aefae372 100644 (file)
@@ -21,6 +21,7 @@
 #include "client.h"
 #include "menu.h"
 #include "screen.h"
+#include "actions.h"
 #include "grab.h"
 #include "openbox.h"
 #include "mainloop.h"
@@ -43,9 +44,9 @@ GList *menu_frame_visible;
 static ObMenuEntryFrame* menu_entry_frame_new(ObMenuEntry *entry,
                                               ObMenuFrame *frame);
 static void menu_entry_frame_free(ObMenuEntryFrame *self);
-static void menu_frame_render(ObMenuFrame *self);
 static void menu_frame_update(ObMenuFrame *self);
 static gboolean menu_entry_frame_submenu_timeout(gpointer data);
+static void menu_frame_hide(ObMenuFrame *self);
 
 static Window createWindow(Window parent, gulong mask,
                            XSetWindowAttributes *attrib)
@@ -90,7 +91,7 @@ ObMenuFrame* menu_frame_new(ObMenu *menu, guint show_from, ObClient *client)
 
     XSetWindowBorderWidth(ob_display, self->window, ob_rr_theme->mbwidth);
     XSetWindowBorder(ob_display, self->window,
-                     RrColorPixel(ob_rr_theme->menu_b_color));
+                     RrColorPixel(ob_rr_theme->menu_border_color));
 
     self->a_title = RrAppearanceCopy(ob_rr_theme->a_menu_title);
     self->a_items = RrAppearanceCopy(ob_rr_theme->a_menu);
@@ -343,6 +344,8 @@ void menu_frame_move_on_screen(ObMenuFrame *self, gint x, gint y,
         *dx = MAX(*dx, a->x - x);
         *dy = MAX(*dy, a->y - y);
     }
+
+    g_free(a);
 }
 
 static void menu_entry_frame_render(ObMenuEntryFrame *self)
@@ -398,6 +401,7 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
         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_always_show ||
              self->entry->data.normal.shortcut_position > 0))
         {
             text_a->texture[0].data.text.shortcut = TRUE;
@@ -413,6 +417,7 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
         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_always_show ||
                               sub->shortcut_position > 0))
         {
             text_a->texture[0].data.text.shortcut = TRUE;
@@ -499,6 +504,8 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
             self->entry->data.normal.icon_width;
         self->a_icon->texture[0].data.rgba.height =
             self->entry->data.normal.icon_height;
+        self->a_icon->texture[0].data.rgba.alpha =
+            self->entry->data.normal.icon_alpha;
         self->a_icon->texture[0].data.rgba.data =
             self->entry->data.normal.icon_data;
         self->a_icon->surface.parent = item_a;
@@ -616,7 +623,7 @@ static gint menu_entry_frame_get_height(ObMenuEntryFrame *self,
     return h;
 }
 
-static void menu_frame_render(ObMenuFrame *self)
+void menu_frame_render(ObMenuFrame *self)
 {
     gint w = 0, h = 0;
     gint tw, th; /* temps */
@@ -687,10 +694,11 @@ static void menu_frame_render(ObMenuFrame *self)
         }
 
         RECT_SET_POINT(e->area, 0, h+e->border);
-        XMoveWindow(ob_display, e->window, e->area.x-e->border, e->area.y-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));
+                         RrColorPixel(ob_rr_theme->menu_border_color));
 
 
         text_a = (e->entry->type == OB_MENU_ENTRY_TYPE_NORMAL &&
@@ -729,7 +737,7 @@ static void menu_frame_render(ObMenuFrame *self)
             if (e->entry->data.separator.label != NULL) {
                 e->a_text_title->texture[0].data.text.string =
                     e->entry->data.separator.label;
-                tw = RrMinWidth(text_a);
+                tw = RrMinWidth(e->a_text_title) + 2*ob_rr_theme->paddingx;
                 tw = MIN(tw, MAX_MENU_WIDTH);
                 th = ob_rr_theme->menu_title_height +
                     (ob_rr_theme->mbwidth - PADDING) *2;
@@ -824,13 +832,18 @@ static void menu_frame_update(ObMenuFrame *self)
         fit = n;
     }
 
-    menu_frame_render(self);
+    /* * make the menu fit on the screen */
 
-    /* make the menu fit on the screen. at most we call render twice, at least
-       not like n times or sometime */
+    /* calculate the height of the menu */
+    h = 0;
+    for (fit = self->entries; fit; fit = g_list_next(fit))
+        h += menu_entry_frame_get_height(fit->data,
+                                         fit == self->entries,
+                                         g_list_next(fit) == NULL);
+    /* add the border at the top and bottom */
+    h += ob_rr_theme->mbwidth * 2;
 
     a = screen_physical_area_monitor(self->monitor);
-    h = self->area.height;
 
     if (h > a->height) {
         GList *flast, *tmp;
@@ -854,8 +867,6 @@ static void menu_frame_update(ObMenuFrame *self)
             menu_entry_frame_free(tmp->data);
             self->entries = g_list_delete_link(self->entries, tmp);
 
-            menu_frame_render(self);
-
             /* only the first one that we see is the last entry in the menu */
             last_entry = FALSE;
         };
@@ -881,10 +892,11 @@ static void menu_frame_update(ObMenuFrame *self)
             /* add our More... entry to the frame */
             self->entries = g_list_append(self->entries, more_frame);
         }
-
-        /* render again */
-        menu_frame_render(self);
     }
+
+    g_free(a);
+
+    menu_frame_render(self);
 }
 
 static gboolean menu_frame_is_visible(ObMenuFrame *self)
@@ -910,10 +922,13 @@ static gboolean menu_frame_show(ObMenuFrame *self)
 
     if (menu_frame_visible == NULL) {
         /* no menus shown yet */
-        if (!grab_pointer(TRUE, TRUE, OB_CURSOR_POINTER))
+
+        /* grab the pointer in such a way as to pass through "owner events"
+           so that we can get enter/leave notifies in the menu. */
+        if (!grab_pointer(TRUE, FALSE, OB_CURSOR_POINTER))
             return FALSE;
-        if (!grab_keyboard(TRUE)) {
-            grab_pointer(FALSE, TRUE, OB_CURSOR_POINTER);
+        if (!grab_keyboard()) {
+            ungrab_pointer();
             return FALSE;
         }
     }
@@ -922,12 +937,16 @@ static gboolean menu_frame_show(ObMenuFrame *self)
 
     menu_frame_visible = g_list_prepend(menu_frame_visible, self);
 
+    if (self->menu->show_func)
+        self->menu->show_func(self, self->menu->data);
+
     return TRUE;
 }
 
 gboolean menu_frame_show_topmenu(ObMenuFrame *self, gint x, gint y,
-                                 gint button)
+                                 gboolean mouse)
 {
+    gint px, py;
     guint i;
 
     if (menu_frame_is_visible(self))
@@ -938,14 +957,16 @@ gboolean menu_frame_show_topmenu(ObMenuFrame *self, gint x, gint y,
     /* find the monitor the menu is on */
     for (i = 0; i < screen_num_monitors; ++i) {
         Rect *a = screen_physical_area_monitor(i);
-        if (RECT_CONTAINS(*a, x, y)) {
+        gboolean contains = RECT_CONTAINS(*a, x, y);
+        g_free(a);
+        if (contains) {
             self->monitor = i;
             break;
         }
     }
 
     if (self->menu->place_func)
-        self->menu->place_func(self, &x, &y, button, self->menu->data);
+        self->menu->place_func(self, &x, &y, mouse, self->menu->data);
     else
         menu_frame_place_topmenu(self, &x, &y);
 
@@ -953,14 +974,20 @@ gboolean menu_frame_show_topmenu(ObMenuFrame *self, gint x, gint y,
 
     XMapWindow(ob_display, self->window);
 
+    if (screen_pointer_pos(&px, &py)) {
+        ObMenuEntryFrame *e = menu_entry_frame_under(px, py);
+        if (e && e->frame == self)
+            e->ignore_enters++;
+    }
+
     return TRUE;
 }
 
 gboolean menu_frame_show_submenu(ObMenuFrame *self, ObMenuFrame *parent,
                                  ObMenuEntryFrame *parent_entry)
 {
-    ObMenuEntryFrame *e;
     gint x, y, dx, dy;
+    gint px, py;
 
     if (menu_frame_is_visible(self))
         return TRUE;
@@ -990,20 +1017,25 @@ 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)) &&
-        e->frame == self)
-        ++e->ignore_enters;
+    if (screen_pointer_pos(&px, &py)) {
+        ObMenuEntryFrame *e = menu_entry_frame_under(px, py);
+        if (e && e->frame == self)
+            e->ignore_enters++;
+    }
 
     return TRUE;
 }
 
-void menu_frame_hide(ObMenuFrame *self)
+static void menu_frame_hide(ObMenuFrame *self)
 {
     GList *it = g_list_find(menu_frame_visible, self);
 
     if (!it)
         return;
 
+    if (self->menu->hide_func)
+        self->menu->hide_func(self, self->menu->data);
+
     if (self->child)
         menu_frame_hide(self->child);
 
@@ -1016,8 +1048,8 @@ void menu_frame_hide(ObMenuFrame *self)
 
     if (menu_frame_visible == NULL) {
         /* last menu shown */
-        grab_pointer(FALSE, TRUE, OB_CURSOR_NONE);
-        grab_keyboard(FALSE);
+        ungrab_pointer();
+        ungrab_keyboard();
     }
 
     XUnmapWindow(ob_display, self->window);
@@ -1079,7 +1111,7 @@ ObMenuEntryFrame* menu_entry_frame_under(gint x, gint y)
             ObMenuEntryFrame *e = it->data;
 
             if (RECT_CONTAINS(e->area, x, y)) {
-                ret = e;            
+                ret = e;
                 break;
             }
         }
@@ -1150,7 +1182,7 @@ void menu_entry_frame_show_submenu(ObMenuEntryFrame *self)
     menu_frame_show_submenu(f, self->frame, self);
 }
 
-void menu_entry_frame_execute(ObMenuEntryFrame *self, guint state, Time time)
+void menu_entry_frame_execute(ObMenuEntryFrame *self, guint state)
 {
     if (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL &&
         self->entry->data.normal.enabled)
@@ -1162,15 +1194,19 @@ void menu_entry_frame_execute(ObMenuEntryFrame *self, guint state, Time time)
         gpointer data = self->frame->menu->data;
         GSList *acts = self->entry->data.normal.actions;
         ObClient *client = self->frame->client;
+        ObMenuFrame *frame = self->frame;
 
         /* release grabs before executing the shit */
-        if (!(state & ControlMask))
+        if (!(state & ControlMask)) {
             menu_frame_hide_all();
+            frame = NULL;
+        }
 
         if (func)
-            func(entry, state, data, time);
+            func(entry, frame, client, state, data);
         else
-            action_run(acts, client, state, time);
+            actions_run_acts(acts, OB_USER_ACTION_MENU_SELECTION,
+                             state, -1, -1, 0, OB_FRAME_CONTEXT_NONE, client);
     }
 }
 
This page took 0.035285 seconds and 4 git commands to generate.