#include "openbox.h"
#include "config.h"
#include "obt/prop.h"
+#include "obt/keyboard.h"
#include "obrender/theme.h"
#define PADDING 2
GHashTable *menu_frame_map;
static RrAppearance *a_sep;
+static guint submenu_show_timer = 0;
+static guint submenu_hide_timer = 0;
static ObMenuEntryFrame* menu_entry_frame_new(ObMenuEntry *entry,
ObMenuFrame *frame);
ObMenuFrame *self;
XSetWindowAttributes attr;
- self = g_new0(ObMenuFrame, 1);
+ self = g_slice_new0(ObMenuFrame);
self->obwin.type = OB_WINDOW_CLASS_MENUFRAME;
self->menu = menu;
self->selected = NULL;
XDestroyWindow(obt_display, self->window);
- g_free(self);
+ g_slice_free(ObMenuFrame, self);
}
}
+ObtIC* menu_frame_ic(ObMenuFrame *self)
+{
+ /* menus are always used through a grab right now, so they can always use
+ the grab input context */
+ return grab_input_context();
+}
+
static ObMenuEntryFrame* menu_entry_frame_new(ObMenuEntry *entry,
ObMenuFrame *frame)
{
ObMenuEntryFrame *self;
XSetWindowAttributes attr;
- self = g_new0(ObMenuEntryFrame, 1);
+ self = g_slice_new0(ObMenuEntryFrame);
self->entry = entry;
self->frame = frame;
g_hash_table_remove(menu_frame_map, &self->bullet);
}
- g_free(self);
+ g_slice_free(ObMenuEntryFrame, self);
}
}
void menu_frame_move_on_screen(ObMenuFrame *self, gint x, gint y,
gint *dx, gint *dy)
{
- Rect *a = NULL;
+ const Rect *a = NULL;
gint pos, half;
*dx = *dy = 0;
*dx = MAX(*dx, a->x - x);
*dy = MAX(*dy, a->y - y);
}
-
- g_free(a);
}
static void menu_entry_frame_render(ObMenuEntryFrame *self)
static void menu_frame_update(ObMenuFrame *self)
{
GList *mit, *fit;
- Rect *a;
+ const Rect *a;
gint h;
menu_pipe_execute(self->menu);
}
}
- g_free(a);
-
menu_frame_render(self);
}
*/
static void remove_submenu_hide_timeout(ObMenuFrame *child)
{
- obt_main_loop_timeout_remove_data(ob_main_loop, submenu_hide_timeout,
- child, FALSE);
+ if (submenu_hide_timer) g_source_remove(submenu_hide_timer);
+ submenu_hide_timer = 0;
}
gboolean menu_frame_show_submenu(ObMenuFrame *self, ObMenuFrame *parent,
static void menu_frame_hide(ObMenuFrame *self)
{
+ ObMenu *const menu = self->menu;
GList *it = g_list_find(menu_frame_visible, self);
gulong ignore_start;
if (!it)
return;
- if (self->menu->hide_func)
- self->menu->hide_func(self, self->menu->data);
+ if (menu->hide_func)
+ menu->hide_func(self, menu->data);
if (self->child)
menu_frame_hide(self->child);
event_end_ignore_all_enters(ignore_start);
menu_frame_free(self);
+
+ if (menu->cleanup_func)
+ menu->cleanup_func(menu, menu->data);
}
void menu_frame_hide_all(void)
if (config_submenu_show_delay) {
/* remove any submenu open requests */
- obt_main_loop_timeout_remove(ob_main_loop, submenu_show_timeout);
+ if (submenu_show_timer) g_source_remove(submenu_show_timer);
+ submenu_show_timer = 0;
}
if ((it = g_list_last(menu_frame_visible)))
menu_frame_hide(it->data);
if (config_submenu_show_delay) {
/* remove any submenu open requests */
- obt_main_loop_timeout_remove(ob_main_loop, submenu_show_timeout);
+ if (submenu_show_timer) g_source_remove(submenu_show_timer);
+ submenu_show_timer = 0;
}
self->selected = entry;
submenu */
if (immediate || config_submenu_hide_delay == 0)
menu_frame_hide(oldchild);
- else if (config_submenu_hide_delay > 0)
- obt_main_loop_timeout_add(ob_main_loop,
- config_submenu_hide_delay * 1000,
- submenu_hide_timeout,
- oldchild, g_direct_equal,
- NULL);
+ else if (config_submenu_hide_delay > 0) {
+ if (submenu_hide_timer) g_source_remove(submenu_hide_timer);
+ submenu_hide_timer =
+ g_timeout_add_full(G_PRIORITY_DEFAULT,
+ config_submenu_hide_delay,
+ submenu_hide_timeout, oldchild, NULL);
+ }
}
}
if (oldchild_entry != self->selected) {
if (immediate || config_submenu_hide_delay == 0)
menu_entry_frame_show_submenu(self->selected);
- else if (config_submenu_hide_delay > 0)
- obt_main_loop_timeout_add(ob_main_loop,
- config_submenu_show_delay * 1000,
- submenu_show_timeout,
- self->selected, g_direct_equal,
- NULL);
+ else if (config_submenu_hide_delay > 0) {
+ if (submenu_show_timer)
+ g_source_remove(submenu_show_timer);
+ submenu_show_timer =
+ g_timeout_add_full(G_PRIORITY_DEFAULT,
+ config_submenu_show_delay,
+ submenu_show_timeout,
+ self->selected, NULL);
+ }
}
/* hide the grandchildren of this menu. and move the cursor to
the current menu */
GSList *acts = self->entry->data.normal.actions;
ObClient *client = self->frame->client;
ObMenuFrame *frame = self->frame;
+ guint mods = obt_keyboard_only_modmasks(state);
/* release grabs before executing the shit */
- if (!(state & ControlMask)) {
+ if (!(mods & ControlMask)) {
event_cancel_all_key_grabs();
frame = NULL;
}