don't run 100 actions when doing interactive actions. keep only one interactive action at a time, no need to queue them up. when an action with a different function comes along, end the previous one. if its the same function though, you know it will clean up after itself so no need to save them both and call it twice identically.

This commit is contained in:
Dana Jansens 2007-05-03 04:21:16 +00:00
parent 9c19d7f677
commit 34b89d8f71

View file

@ -39,15 +39,15 @@
#include <glib.h> #include <glib.h>
typedef struct { typedef struct {
gboolean active;
guint state; guint state;
ObClient *client; ObClient *client;
GSList *actions; ObAction *action;
ObFrameContext context;
} ObInteractiveState; } ObInteractiveState;
KeyBindingTree *keyboard_firstnode = NULL; KeyBindingTree *keyboard_firstnode = NULL;
static ObPopup *popup = NULL; static ObPopup *popup = NULL;
static GSList *interactive_states; static ObInteractiveState istate;
static KeyBindingTree *curpos; static KeyBindingTree *curpos;
static void grab_keys(gboolean grab) static void grab_keys(gboolean grab)
@ -186,92 +186,76 @@ gboolean keyboard_bind(GList *keylist, ObAction *action)
return TRUE; return TRUE;
} }
gboolean keyboard_interactive_grab(guint state, ObClient *client, static void keyboard_interactive_end(guint state, gboolean cancel, Time time,
ObAction *action) gboolean ungrab)
{ {
ObInteractiveState *s; GSList *alist;
g_assert(action->data.any.interactive); g_assert(istate.active);
if (!interactive_states) { alist = g_slist_append(NULL, istate.action);
grab_pointer(TRUE, FALSE, OB_CURSOR_POINTER); action_run_interactive(alist, istate.client, state, time, cancel, TRUE);
if (!grab_keyboard(TRUE)) { g_slist_free(alist);
grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
return FALSE;
}
}
s = g_new(ObInteractiveState, 1); istate.active = FALSE;
s->state = state; if (ungrab) {
s->client = client;
s->actions = g_slist_append(NULL, action);
interactive_states = g_slist_append(interactive_states, s);
return TRUE;
}
void keyboard_interactive_end(ObInteractiveState *s,
guint state, gboolean cancel, Time time)
{
action_run_interactive(s->actions, s->client, state, time, cancel, TRUE);
g_slist_free(s->actions);
g_free(s);
interactive_states = g_slist_remove(interactive_states, s);
if (!interactive_states) {
grab_keyboard(FALSE); grab_keyboard(FALSE);
grab_pointer(FALSE, FALSE, OB_CURSOR_NONE); grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
} }
} }
void keyboard_interactive_end_client(ObClient *client, gpointer data) static void keyboard_interactive_end_client(ObClient *client, gpointer data)
{ {
GSList *it, *next; if (istate.active && istate.client == client)
istate.client = NULL;
}
for (it = interactive_states; it; it = next) { gboolean keyboard_interactive_grab(guint state, ObClient *client,
ObInteractiveState *s = it->data; ObAction *action)
{
g_assert(action->data.any.interactive);
next = g_slist_next(it); if (!istate.active) {
grab_pointer(TRUE, FALSE, OB_CURSOR_POINTER);
if (s->client == client) if (!grab_keyboard(TRUE)) {
s->client = NULL; grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
return FALSE;
}
} else if (action->func != istate.action->func) {
keyboard_interactive_end(state, FALSE, action->data.any.time, FALSE);
} }
istate.active = TRUE;
istate.state = state;
istate.client = client;
istate.action = action;
return TRUE;
} }
gboolean keyboard_process_interactive_grab(const XEvent *e, ObClient **client) gboolean keyboard_process_interactive_grab(const XEvent *e, ObClient **client)
{ {
GSList *it, *next;
gboolean handled = FALSE; gboolean handled = FALSE;
gboolean done = FALSE; gboolean done = FALSE;
gboolean cancel = FALSE; gboolean cancel = FALSE;
for (it = interactive_states; it; it = next) { if ((e->type == KeyRelease && !(istate.state & e->xkey.state)))
ObInteractiveState *s = it->data; done = TRUE;
else if (e->type == KeyPress) {
/*if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN))
done = TRUE;
else */if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE))
cancel = done = TRUE;
} else if (e->type == ButtonPress)
cancel = done = TRUE;
next = g_slist_next(it); if (done) {
keyboard_interactive_end(e->xkey.state, cancel, e->xkey.time, TRUE);
if ((e->type == KeyRelease &&
!(s->state & e->xkey.state)))
done = TRUE;
else if (e->type == KeyPress) {
/*if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN))
done = TRUE;
else */if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE))
cancel = done = TRUE;
} else if (e->type == ButtonPress)
cancel = done = TRUE;
if (done) { handled = TRUE;
keyboard_interactive_end(s, e->xkey.state, cancel, e->xkey.time); } else
*client = istate.client;
handled = TRUE;
} else
*client = s->client;
}
return handled; return handled;
} }
@ -326,7 +310,7 @@ void keyboard_event(ObClient *client, const XEvent *e)
gboolean keyboard_interactively_grabbed() gboolean keyboard_interactively_grabbed()
{ {
return !!interactive_states; return istate.active;
} }
void keyboard_startup(gboolean reconfig) void keyboard_startup(gboolean reconfig)
@ -345,10 +329,7 @@ void keyboard_shutdown(gboolean reconfig)
if (!reconfig) if (!reconfig)
client_remove_destructor(keyboard_interactive_end_client); client_remove_destructor(keyboard_interactive_end_client);
for (it = interactive_states; it; it = g_slist_next(it)) istate.active = FALSE;
g_free(it->data);
g_slist_free(interactive_states);
interactive_states = NULL;
ob_main_loop_timeout_remove(ob_main_loop, chain_timeout); ob_main_loop_timeout_remove(ob_main_loop, chain_timeout);