well.. it compiles..

This commit is contained in:
Dana Jansens 2007-06-22 03:05:02 +00:00
parent ae624a1487
commit 780d1b0961
12 changed files with 92 additions and 265 deletions

View file

@ -19,6 +19,7 @@
#include "actions.h" #include "actions.h"
#include "gettext.h" #include "gettext.h"
#include "grab.h" #include "grab.h"
#include "screen.h"
static void actions_definition_ref(ObActionsDefinition *def); static void actions_definition_ref(ObActionsDefinition *def);
static void actions_definition_unref(ObActionsDefinition *def); static void actions_definition_unref(ObActionsDefinition *def);
@ -54,12 +55,12 @@ static GSList *registered = NULL;
void actions_startup(gboolean reconfig) void actions_startup(gboolean reconfig)
{ {
if (reconfig) return; if (reconfig) return;
} }
void actions_shutdown(gboolean reconfig) void actions_shutdown(gboolean reconfig)
{ {
actions_interactive_cancel_act();
if (reconfig) return; if (reconfig) return;
/* free all the registered actions */ /* free all the registered actions */
@ -205,6 +206,14 @@ void actions_run_acts(GSList *acts,
{ {
GSList *it; GSList *it;
/* Don't allow saving the initial state when running things from the
menu */
if (uact == OB_USER_ACTION_MENU_SELECTION)
state = 0;
/* If x and y are < 0 then use the current pointer position */
if (x < 0 && y < 0)
screen_pointer_pos(&x, &y);
for (it = acts; it; it = g_slist_next(it)) { for (it = acts; it; it = g_slist_next(it)) {
ObActionsData data; ObActionsData data;
ObActionsAct *act = it->data; ObActionsAct *act = it->data;

View file

@ -20,7 +20,6 @@
#include "openbox.h" #include "openbox.h"
#include "menu.h" #include "menu.h"
#include "menuframe.h" #include "menuframe.h"
#include "action.h"
#include "screen.h" #include "screen.h"
#include "client.h" #include "client.h"
#include "focus.h" #include "focus.h"
@ -38,7 +37,6 @@ static gboolean self_update(ObMenuFrame *frame, gpointer data)
ObMenu *menu = frame->menu; ObMenu *menu = frame->menu;
ObMenuEntry *e; ObMenuEntry *e;
GList *it; GList *it;
gint i;
guint desktop; guint desktop;
menu_clear_entries(menu); menu_clear_entries(menu);
@ -48,33 +46,22 @@ static gboolean self_update(ObMenuFrame *frame, gpointer data)
gboolean onlyiconic = TRUE; gboolean onlyiconic = TRUE;
menu_add_separator(menu, -1, screen_desktop_names[desktop]); menu_add_separator(menu, -1, screen_desktop_names[desktop]);
for (it = focus_order, i = 0; it; it = g_list_next(it), ++i) { for (it = focus_order; it; it = g_list_next(it)) {
ObClient *c = it->data; ObClient *c = it->data;
if (client_normal(c) && (!c->skip_taskbar || c->iconic) && if (client_normal(c) && (!c->skip_taskbar || c->iconic) &&
(c->desktop == desktop || c->desktop == DESKTOP_ALL)) (c->desktop == desktop || c->desktop == DESKTOP_ALL))
{ {
GSList *acts = NULL;
ObAction* act;
const ObClientIcon *icon; const ObClientIcon *icon;
empty = FALSE; empty = FALSE;
act = action_from_string("Activate",
OB_USER_ACTION_MENU_SELECTION);
act->data.activate.any.c = c;
acts = g_slist_append(acts, act);
act = action_from_string("Desktop",
OB_USER_ACTION_MENU_SELECTION);
act->data.desktop.desk = desktop;
acts = g_slist_append(acts, act);
if (c->iconic) { if (c->iconic) {
gchar *title = g_strdup_printf("(%s)", c->icon_title); gchar *title = g_strdup_printf("(%s)", c->icon_title);
e = menu_add_normal(menu, i, title, acts, FALSE); e = menu_add_normal(menu, -1, title, NULL, FALSE);
g_free(title); g_free(title);
} else { } else {
onlyiconic = FALSE; onlyiconic = FALSE;
e = menu_add_normal(menu, i, c->title, acts, FALSE); e = menu_add_normal(menu, -1, c->title, NULL, FALSE);
} }
if (config_menu_client_list_icons if (config_menu_client_list_icons
@ -85,23 +72,20 @@ static gboolean self_update(ObMenuFrame *frame, gpointer data)
e->data.normal.icon_alpha = e->data.normal.icon_alpha =
c->iconic ? OB_ICONIC_ALPHA : 0xff; c->iconic ? OB_ICONIC_ALPHA : 0xff;
} }
e->data.normal.data = c;
} }
} }
if (empty || onlyiconic) { if (empty || onlyiconic) {
ObMenuEntry *e;
/* no entries or only iconified windows, so add a /* no entries or only iconified windows, so add a
* way to go to this desktop without uniconifying a window */ * way to go to this desktop without uniconifying a window */
if (!empty) if (!empty)
menu_add_separator(menu, -1, NULL); menu_add_separator(menu, -1, NULL);
GSList *acts = NULL; e = menu_add_normal(menu, desktop, _("Go there..."), NULL, TRUE);
ObAction* act;
ObMenuEntry *e;
act = action_from_string("Desktop", OB_USER_ACTION_MENU_SELECTION);
act->data.desktop.desk = desktop;
acts = g_slist_append(acts, act);
e = menu_add_normal(menu, 0, _("Go there..."), acts, TRUE);
if (desktop == screen_desktop) if (desktop == screen_desktop)
e->data.normal.enabled = FALSE; e->data.normal.enabled = FALSE;
} }
@ -109,18 +93,16 @@ static gboolean self_update(ObMenuFrame *frame, gpointer data)
return TRUE; /* always show the menu */ return TRUE; /* always show the menu */
} }
/* executes it using the client in the actions, since we set that
when we make the actions! */
static void menu_execute(ObMenuEntry *self, ObMenuFrame *f, static void menu_execute(ObMenuEntry *self, ObMenuFrame *f,
ObClient *c, guint state, gpointer data, ObClient *c, guint state, gpointer data,
Time time) Time time)
{ {
ObAction *a; if (self->id == -1) {
if (self->data.normal.data) /* it's set to NULL if its destroyed */
if (self->data.normal.actions) { client_activate(self->data.normal.data, FALSE, TRUE);
a = self->data.normal.actions->data;
action_run(self->data.normal.actions, a->data.any.c, state, time);
} }
else
screen_set_desktop(self->id, TRUE);
} }
static void client_dest(ObClient *client, gpointer data) static void client_dest(ObClient *client, gpointer data)
@ -132,12 +114,9 @@ static void client_dest(ObClient *client, gpointer data)
for (eit = combined_menu->entries; eit; eit = g_list_next(eit)) { for (eit = combined_menu->entries; eit; eit = g_list_next(eit)) {
ObMenuEntry *meit = eit->data; ObMenuEntry *meit = eit->data;
if (meit->type == OB_MENU_ENTRY_TYPE_NORMAL && if (meit->type == OB_MENU_ENTRY_TYPE_NORMAL &&
meit->data.normal.actions) meit->data.normal.data == client)
{ {
ObAction *a = meit->data.normal.actions->data; meit->data.normal.data = NULL;
ObClient *c = a->data.any.c;
if (c == client)
a->data.any.c = NULL;
} }
} }
} }

View file

@ -20,7 +20,6 @@
#include "openbox.h" #include "openbox.h"
#include "menu.h" #include "menu.h"
#include "menuframe.h" #include "menuframe.h"
#include "action.h"
#include "screen.h" #include "screen.h"
#include "client.h" #include "client.h"
#include "focus.h" #include "focus.h"
@ -43,40 +42,28 @@ static gboolean desk_menu_update(ObMenuFrame *frame, gpointer data)
ObMenu *menu = frame->menu; ObMenu *menu = frame->menu;
DesktopData *d = data; DesktopData *d = data;
GList *it; GList *it;
gint i;
gboolean empty = TRUE; gboolean empty = TRUE;
gboolean onlyiconic = TRUE; gboolean onlyiconic = TRUE;
menu_clear_entries(menu); menu_clear_entries(menu);
for (it = focus_order, i = 0; it; it = g_list_next(it), ++i) { for (it = focus_order; it; it = g_list_next(it)) {
ObClient *c = it->data; ObClient *c = it->data;
if (client_normal(c) && (!c->skip_taskbar || c->iconic) && if (client_normal(c) && (!c->skip_taskbar || c->iconic) &&
(c->desktop == d->desktop || c->desktop == DESKTOP_ALL)) (c->desktop == d->desktop || c->desktop == DESKTOP_ALL))
{ {
GSList *acts = NULL;
ObAction* act;
ObMenuEntry *e; ObMenuEntry *e;
const ObClientIcon *icon; const ObClientIcon *icon;
empty = FALSE; empty = FALSE;
act = action_from_string("Activate",
OB_USER_ACTION_MENU_SELECTION);
act->data.activate.any.c = c;
acts = g_slist_append(acts, act);
act = action_from_string("Desktop",
OB_USER_ACTION_MENU_SELECTION);
act->data.desktop.desk = d->desktop;
acts = g_slist_append(acts, act);
if (c->iconic) { if (c->iconic) {
gchar *title = g_strdup_printf("(%s)", c->icon_title); gchar *title = g_strdup_printf("(%s)", c->icon_title);
e = menu_add_normal(menu, i, title, acts, FALSE); e = menu_add_normal(menu, -1, title, NULL, FALSE);
g_free(title); g_free(title);
} else { } else {
onlyiconic = FALSE; onlyiconic = FALSE;
e = menu_add_normal(menu, i, c->title, acts, FALSE); e = menu_add_normal(menu, -1, c->title, NULL, FALSE);
} }
if (config_menu_client_list_icons if (config_menu_client_list_icons
@ -86,41 +73,36 @@ static gboolean desk_menu_update(ObMenuFrame *frame, gpointer data)
e->data.normal.icon_data = icon->data; e->data.normal.icon_data = icon->data;
e->data.normal.icon_alpha = c->iconic ? OB_ICONIC_ALPHA : 0xff; e->data.normal.icon_alpha = c->iconic ? OB_ICONIC_ALPHA : 0xff;
} }
e->data.normal.data = c;
} }
} }
if (empty || onlyiconic) { if (empty || onlyiconic) {
ObMenuEntry *e;
/* no entries or only iconified windows, so add a /* no entries or only iconified windows, so add a
* way to go to this desktop without uniconifying a window */ * way to go to this desktop without uniconifying a window */
if (!empty) if (!empty)
menu_add_separator(menu, -1, NULL); menu_add_separator(menu, -1, NULL);
GSList *acts = NULL; e = menu_add_normal(menu, d->desktop, _("Go there..."), NULL, TRUE);
ObAction* act;
ObMenuEntry *e;
act = action_from_string("Desktop", OB_USER_ACTION_MENU_SELECTION);
act->data.desktop.desk = d->desktop;
acts = g_slist_append(acts, act);
e = menu_add_normal(menu, 0, _("Go there..."), acts, TRUE);
if (d->desktop == screen_desktop) if (d->desktop == screen_desktop)
e->data.normal.enabled = FALSE; e->data.normal.enabled = FALSE;
} }
return TRUE; /* always show */ return TRUE; /* always show */
} }
/* executes it using the client in the actions, since we set that
when we make the actions! */
static void desk_menu_execute(ObMenuEntry *self, ObMenuFrame *f, static void desk_menu_execute(ObMenuEntry *self, ObMenuFrame *f,
ObClient *c, guint state, gpointer data, ObClient *c, guint state, gpointer data,
Time time) Time time)
{ {
ObAction *a; if (self->id == -1) {
if (self->data.normal.data) /* it's set to NULL if its destroyed */
if (self->data.normal.actions) { client_activate(self->data.normal.data, FALSE, TRUE);
a = self->data.normal.actions->data;
action_run(self->data.normal.actions, a->data.any.c, state, time);
} }
else
screen_set_desktop(self->id, TRUE);
} }
static void desk_menu_destroy(ObMenu *menu, gpointer data) static void desk_menu_destroy(ObMenu *menu, gpointer data)
@ -176,11 +158,10 @@ static void client_dest(ObClient *client, gpointer data)
GList *eit; GList *eit;
for (eit = mit->entries; eit; eit = g_list_next(eit)) { for (eit = mit->entries; eit; eit = g_list_next(eit)) {
ObMenuEntry *meit = eit->data; ObMenuEntry *meit = eit->data;
if (meit->type == OB_MENU_ENTRY_TYPE_NORMAL) { if (meit->type == OB_MENU_ENTRY_TYPE_NORMAL &&
ObAction *a = meit->data.normal.actions->data; meit->data.normal.data == client)
ObClient *c = a->data.any.c; {
if (c == client) meit->data.normal.data = NULL;
a->data.any.c = NULL;
} }
} }
} }

View file

@ -22,6 +22,7 @@
#include "window.h" #include "window.h"
#include "openbox.h" #include "openbox.h"
#include "dock.h" #include "dock.h"
#include "actions.h"
#include "client.h" #include "client.h"
#include "xerror.h" #include "xerror.h"
#include "prop.h" #include "prop.h"

View file

@ -38,16 +38,8 @@
#include <glib.h> #include <glib.h>
typedef struct {
gboolean active;
guint state;
ObClient *client;
ObActionsAct *action;
} ObInteractiveState;
KeyBindingTree *keyboard_firstnode = NULL; KeyBindingTree *keyboard_firstnode = NULL;
static ObPopup *popup = NULL; static ObPopup *popup = NULL;
static ObInteractiveState istate;
static KeyBindingTree *curpos; static KeyBindingTree *curpos;
static void grab_keys(gboolean grab) static void grab_keys(gboolean grab)
@ -178,64 +170,7 @@ gboolean keyboard_bind(GList *keylist, ObActionsAct *action)
return TRUE; return TRUE;
} }
static void keyboard_interactive_end(guint state, gboolean cancel, Time time,
gboolean ungrab)
{
#if 0 #if 0
GSList *alist;
g_assert(istate.active);
/* ungrab first so they won't be NotifyWhileGrabbed */
if (ungrab)
ungrab_keyboard();
/* set this before running the actions so they know the keyboard is not
grabbed */
istate.active = FALSE;
alist = g_slist_append(NULL, istate.action);
action_run_interactive(alist, istate.client, state, time, cancel, TRUE);
g_slist_free(alist);
keyboard_reset_chains(0);
#endif
}
static void keyboard_interactive_end_client(ObClient *client, gpointer data)
{
if (istate.active && istate.client == client)
istate.client = NULL;
}
void keyboard_interactive_cancel()
{
keyboard_interactive_end(0, TRUE, event_curtime, TRUE);
}
gboolean keyboard_interactive_grab(guint state, ObClient *client,
ObActionsAct *action)
{
#if 0
g_assert(action->data.any.interactive);
if (!istate.active) {
if (!grab_keyboard())
return FALSE;
} else if (action->func != istate.action->func) {
keyboard_interactive_end(state, TRUE, action->data.any.time, FALSE);
}
istate.active = TRUE;
istate.state = state;
istate.client = client;
istate.action = action;
#endif
return TRUE;
}
gboolean keyboard_process_interactive_grab(const XEvent *e, ObClient **client) gboolean keyboard_process_interactive_grab(const XEvent *e, ObClient **client)
{ {
gboolean handled = FALSE; gboolean handled = FALSE;
@ -268,6 +203,7 @@ gboolean keyboard_process_interactive_grab(const XEvent *e, ObClient **client)
return handled; return handled;
} }
#endif
void keyboard_event(ObClient *client, const XEvent *e) void keyboard_event(ObClient *client, const XEvent *e)
{ {
@ -312,17 +248,16 @@ void keyboard_event(ObClient *client, const XEvent *e)
set_curpos(p); set_curpos(p);
else { else {
GSList *it; GSList *it;
gboolean inter = FALSE;
for (it = p->actions; it && !inter; it = g_slist_next(it)) for (it = p->actions; it; it = g_slist_next(it))
if (((ObActionsAct*)it->data)->data.any.interactive) if (actions_act_is_interactive(it->data)) break;
inter = TRUE; if (it == NULL) /* reset if the actions are not interactive */
if (!inter) /* don't reset if the action is interactive */
keyboard_reset_chains(0); keyboard_reset_chains(0);
action_run_key(p->actions, client, e->xkey.state, actions_run_acts(p->actions, OB_USER_ACTION_KEYBOARD_KEY,
e->xkey.x_root, e->xkey.y_root, e->xkey.time, e->xkey.state,
e->xkey.time); e->xkey.x_root, e->xkey.y_root,
OB_FRAME_CONTEXT_NONE, client);
} }
break; break;
} }
@ -330,29 +265,15 @@ void keyboard_event(ObClient *client, const XEvent *e)
} }
} }
gboolean keyboard_interactively_grabbed()
{
return istate.active;
}
void keyboard_startup(gboolean reconfig) void keyboard_startup(gboolean reconfig)
{ {
grab_keys(TRUE); grab_keys(TRUE);
popup = popup_new(FALSE); popup = popup_new(FALSE);
popup_set_text_align(popup, RR_JUSTIFY_CENTER); popup_set_text_align(popup, RR_JUSTIFY_CENTER);
if (!reconfig)
client_add_destroy_notify(keyboard_interactive_end_client, NULL);
} }
void keyboard_shutdown(gboolean reconfig) void keyboard_shutdown(gboolean reconfig)
{ {
if (!reconfig)
client_remove_destroy_notify(keyboard_interactive_end_client);
if (istate.active)
keyboard_interactive_cancel();
ob_main_loop_timeout_remove(ob_main_loop, chain_timeout); ob_main_loop_timeout_remove(ob_main_loop, chain_timeout);
keyboard_unbind_all(); keyboard_unbind_all();

View file

@ -43,12 +43,4 @@ void keyboard_event(struct _ObClient *client, const XEvent *e);
*/ */
void keyboard_reset_chains(gint break_chroots); void keyboard_reset_chains(gint break_chroots);
gboolean keyboard_interactive_grab(guint state, struct _ObClient *client,
struct _ObActionsAct *action);
gboolean keyboard_process_interactive_grab(const XEvent *e,
struct _ObClient **client);
gboolean keyboard_interactively_grabbed();
void keyboard_interactive_cancel();
#endif #endif

View file

@ -19,6 +19,7 @@
#include "keyboard.h" #include "keyboard.h"
#include "translate.h" #include "translate.h"
#include "actions.h"
#include <glib.h> #include <glib.h>
void tree_destroy(KeyBindingTree *tree) void tree_destroy(KeyBindingTree *tree)
@ -35,7 +36,7 @@ void tree_destroy(KeyBindingTree *tree)
g_free(it->data); g_free(it->data);
g_list_free(tree->keylist); g_list_free(tree->keylist);
for (sit = tree->actions; sit != NULL; sit = sit->next) for (sit = tree->actions; sit != NULL; sit = sit->next)
action_unref(sit->data); actions_act_unref(sit->data);
g_slist_free(tree->actions); g_slist_free(tree->actions);
} }
g_free(tree); g_free(tree);

View file

@ -18,8 +18,6 @@
*/ */
#include "mainloop.h" #include "mainloop.h"
#include "action.h"
#include "client.h"
#include "event.h" #include "event.h"
#include <stdio.h> #include <stdio.h>
@ -90,8 +88,6 @@ struct _ObMainLoop
gboolean signal_fired; gboolean signal_fired;
guint signals_fired[NUM_SIGNALS]; guint signals_fired[NUM_SIGNALS];
GSList *signal_handlers[NUM_SIGNALS]; GSList *signal_handlers[NUM_SIGNALS];
GSList *action_queue;
}; };
struct _ObMainLoopTimer struct _ObMainLoopTimer
@ -182,8 +178,6 @@ ObMainLoop *ob_main_loop_new(Display *display)
all_loops = g_slist_prepend(all_loops, loop); all_loops = g_slist_prepend(all_loops, loop);
loop->action_queue = NULL;
return loop; return loop;
} }
@ -234,10 +228,6 @@ void ob_main_loop_destroy(ObMainLoop *loop)
} }
} }
for (it = loop->action_queue; it; it = g_slist_next(it))
action_unref(it->data);
g_slist_free(loop->action_queue);
g_free(loop); g_free(loop);
} }
} }
@ -253,37 +243,16 @@ static void fd_handle_foreach(gpointer key,
h->func(h->fd, h->data); h->func(h->fd, h->data);
} }
void ob_main_loop_queue_action(ObMainLoop *loop, ObAction *act)
{
loop->action_queue = g_slist_append(loop->action_queue, action_copy(act));
}
static void ob_main_loop_client_destroy(ObClient *client, gpointer data)
{
ObMainLoop *loop = data;
GSList *it;
for (it = loop->action_queue; it; it = g_slist_next(it)) {
ObAction *act = it->data;
if (act->data.any.c == client)
act->data.any.c = NULL;
}
}
void ob_main_loop_run(ObMainLoop *loop) void ob_main_loop_run(ObMainLoop *loop)
{ {
XEvent e; XEvent e;
struct timeval *wait; struct timeval *wait;
fd_set selset; fd_set selset;
GSList *it; GSList *it;
ObAction *act;
loop->run = TRUE; loop->run = TRUE;
loop->running = TRUE; loop->running = TRUE;
client_add_destroy_notify(ob_main_loop_client_destroy, loop);
while (loop->run) { while (loop->run) {
if (loop->signal_fired) { if (loop->signal_fired) {
guint i; guint i;
@ -315,33 +284,6 @@ void ob_main_loop_run(ObMainLoop *loop)
h->func(&e, h->data); h->func(&e, h->data);
} }
} while (XPending(loop->display) && loop->run); } while (XPending(loop->display) && loop->run);
} else if (loop->action_queue) {
/* only fire off one action at a time, then go back for more
X events, since the action might cause some X events (like
FocusIn :) */
do {
act = loop->action_queue->data;
if (act->data.any.client_action == OB_CLIENT_ACTION_ALWAYS &&
!act->data.any.c)
{
loop->action_queue =
g_slist_delete_link(loop->action_queue,
loop->action_queue);
action_unref(act);
act = NULL;
}
} while (!act && loop->action_queue && loop->run);
if (act) {
event_curtime = act->data.any.time;
act->func(&act->data);
event_curtime = CurrentTime;
loop->action_queue =
g_slist_delete_link(loop->action_queue,
loop->action_queue);
action_unref(act);
}
} else { } else {
/* this only runs if there were no x events received */ /* this only runs if there were no x events received */
@ -365,8 +307,6 @@ void ob_main_loop_run(ObMainLoop *loop)
} }
} }
client_remove_destroy_notify(ob_main_loop_client_destroy);
loop->running = FALSE; loop->running = FALSE;
} }

View file

@ -70,12 +70,6 @@ void ob_main_loop_timeout_remove_data(ObMainLoop *loop,
gpointer data, gpointer data,
gboolean cancel_dest); gboolean cancel_dest);
struct _ObAction;
/*! Queues an action, which will be run when there are no more X events
to process */
void ob_main_loop_queue_action(ObMainLoop *loop, struct _ObAction *act);
void ob_main_loop_run(ObMainLoop *loop); void ob_main_loop_run(ObMainLoop *loop);
void ob_main_loop_exit(ObMainLoop *loop); void ob_main_loop_exit(ObMainLoop *loop);

View file

@ -22,8 +22,10 @@
#include "openbox.h" #include "openbox.h"
#include "mainloop.h" #include "mainloop.h"
#include "stacking.h" #include "stacking.h"
#include "grab.h"
#include "client.h" #include "client.h"
#include "config.h" #include "config.h"
#include "actions.h"
#include "screen.h" #include "screen.h"
#include "menuframe.h" #include "menuframe.h"
#include "keyboard.h" #include "keyboard.h"
@ -263,8 +265,7 @@ static void parse_menu_item(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
for (node = node->children; node; node = node->next) for (node = node->children; node; node = node->next)
if (!xmlStrcasecmp(node->name, (const xmlChar*) "action")) { if (!xmlStrcasecmp(node->name, (const xmlChar*) "action")) {
ObAction *a = action_parse ObActionsAct *a = actions_parse(i, doc, node);
(i, doc, node, OB_USER_ACTION_MENU_SELECTION);
if (a) if (a)
acts = g_slist_append(acts, a); acts = g_slist_append(acts, a);
} }
@ -411,8 +412,8 @@ void menu_show(gchar *name, gint x, gint y, gint button, ObClient *client)
ObMenu *self; ObMenu *self;
ObMenuFrame *frame; ObMenuFrame *frame;
if (!(self = menu_from_name(name)) if (!(self = menu_from_name(name)) ||
|| keyboard_interactively_grabbed()) return; grab_on_keyboard() || grab_on_pointer()) return;
/* if the requested menu is already the top visible menu, then don't /* if the requested menu is already the top visible menu, then don't
bother */ bother */
@ -430,30 +431,33 @@ void menu_show(gchar *name, gint x, gint y, gint button, ObClient *client)
frame = menu_frame_new(self, 0, client); frame = menu_frame_new(self, 0, client);
if (!menu_frame_show_topmenu(frame, x, y, button)) if (!menu_frame_show_topmenu(frame, x, y, button))
menu_frame_free(frame); menu_frame_free(frame);
else if (!button) {
/* select the first entry if it's not a submenu and we opened
* the menu with the keyboard, and skip all headers */
GList *it = frame->entries;
while (it) {
ObMenuEntryFrame *e = it->data;
if (e->entry->type == OB_MENU_ENTRY_TYPE_NORMAL) {
menu_frame_select(frame, e, FALSE);
break;
} else if (e->entry->type == OB_MENU_ENTRY_TYPE_SEPARATOR)
it = g_list_next(it);
else
break;
}
}
if (!button)
menu_can_hide = TRUE;
else { else {
menu_can_hide = FALSE; if (!button) {
ob_main_loop_timeout_add(ob_main_loop, /* select the first entry if it's not a submenu and we opened
config_menu_hide_delay * 1000, * the menu with the keyboard, and skip all headers */
menu_hide_delay_func, GList *it = frame->entries;
NULL, g_direct_equal, NULL); while (it) {
ObMenuEntryFrame *e = it->data;
if (e->entry->type == OB_MENU_ENTRY_TYPE_NORMAL) {
menu_frame_select(frame, e, FALSE);
break;
} else if (e->entry->type == OB_MENU_ENTRY_TYPE_SEPARATOR)
it = g_list_next(it);
else
break;
}
}
/* reset the hide timer */
if (!button)
menu_can_hide = TRUE;
else {
menu_can_hide = FALSE;
ob_main_loop_timeout_add(ob_main_loop,
config_menu_hide_delay * 1000,
menu_hide_delay_func,
NULL, g_direct_equal, NULL);
}
} }
} }
@ -498,7 +502,7 @@ void menu_entry_unref(ObMenuEntry *self)
case OB_MENU_ENTRY_TYPE_NORMAL: case OB_MENU_ENTRY_TYPE_NORMAL:
g_free(self->data.normal.label); g_free(self->data.normal.label);
while (self->data.normal.actions) { while (self->data.normal.actions) {
action_unref(self->data.normal.actions->data); actions_act_unref(self->data.normal.actions->data);
self->data.normal.actions = self->data.normal.actions =
g_slist_delete_link(self->data.normal.actions, g_slist_delete_link(self->data.normal.actions,
self->data.normal.actions); self->data.normal.actions);

View file

@ -125,6 +125,8 @@ struct _ObNormalMenuEntry {
RrColor *mask_selected_color; RrColor *mask_selected_color;
RrColor *mask_disabled_color; RrColor *mask_disabled_color;
RrColor *mask_disabled_selected_color; RrColor *mask_disabled_selected_color;
gpointer data;
}; };
struct _ObSubmenuMenuEntry { struct _ObSubmenuMenuEntry {

View file

@ -21,6 +21,7 @@
#include "client.h" #include "client.h"
#include "menu.h" #include "menu.h"
#include "screen.h" #include "screen.h"
#include "actions.h"
#include "grab.h" #include "grab.h"
#include "openbox.h" #include "openbox.h"
#include "mainloop.h" #include "mainloop.h"
@ -1201,7 +1202,9 @@ void menu_entry_frame_execute(ObMenuEntryFrame *self, guint state, Time time)
if (func) if (func)
func(entry, frame, client, state, data, time); func(entry, frame, client, state, data, time);
else else
action_run(acts, client, state, time); actions_run_acts(acts, OB_USER_ACTION_MENU_SELECTION,
time, state, -1, -1, OB_FRAME_CONTEXT_NONE,
client);
} }
} }