static void set_curpos(KeyBindingTree *newpos)
{
- grab_keys(FALSE);
- curpos = newpos;
- grab_keys(TRUE);
+ if (curpos != newpos) {
+ grab_keys(FALSE);
+ curpos = newpos;
+ grab_keys(TRUE);
+ }
if (curpos != NULL) {
gchar *text = NULL;
g_assert(istate.active);
- alist = g_slist_append(NULL, istate.action);
- action_run_interactive(alist, istate.client, state, time, cancel, TRUE);
- g_slist_free(alist);
+ /* 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;
- if (ungrab) {
- grab_keyboard(FALSE);
- grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
- }
+ alist = g_slist_append(NULL, istate.action);
+ action_run_interactive(alist, istate.client, state, time, cancel, TRUE);
+ g_slist_free(alist);
}
static void keyboard_interactive_end_client(ObClient *client, gpointer data)
istate.client = NULL;
}
+
+void keyboard_interactive_cancel()
+{
+ keyboard_interactive_end(0, TRUE, event_curtime, TRUE);
+}
+
gboolean keyboard_interactive_grab(guint state, ObClient *client,
ObAction *action)
{
g_assert(action->data.any.interactive);
if (!istate.active) {
- grab_pointer(TRUE, FALSE, OB_CURSOR_POINTER);
- if (!grab_keyboard(TRUE)) {
- grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
+ if (!grab_keyboard())
return FALSE;
- }
} else if (action->func != istate.action->func) {
- keyboard_interactive_end(state, FALSE, action->data.any.time, FALSE);
+ keyboard_interactive_end(state, TRUE, action->data.any.time, FALSE);
}
istate.active = TRUE;
gboolean cancel = FALSE;
if (istate.active) {
- if ((e->type == KeyRelease && !(istate.state & e->xkey.state)))
+ if ((e->type == KeyRelease && !(istate.state & e->xkey.state))) {
done = TRUE;
- else if (e->type == KeyPress) {
+ handled = 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))
+ else */if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) {
cancel = done = TRUE;
- } else if (e->type == ButtonPress)
- cancel = done = TRUE;
+ handled = TRUE;
+ }
+ } else if (e->type == ButtonPress) {
+ cancel = TRUE;
+ done = TRUE;
+ handled = FALSE;
+ }
- if (done) {
+ if (done)
keyboard_interactive_end(e->xkey.state, cancel, e->xkey.time,TRUE);
- handled = TRUE;
- } else
+ if (handled)
*client = istate.client;
}
else {
keyboard_reset_chains(0);
+ /* If we don't have the keyboard grabbed, then ungrab it with
+ XUngrabKeyboard, so that there is not a passive grab left
+ on from the KeyPress. If the grab is left on, and focus
+ moves during that time, it will be NotifyWhileGrabbed, and
+ applications like to ignore those! */
+ if (!keyboard_interactively_grabbed())
+ XUngrabKeyboard(ob_display, e->xkey.time);
+
action_run_key(p->actions, client, e->xkey.state,
e->xkey.x_root, e->xkey.y_root,
e->xkey.time);
popup = popup_new(FALSE);
if (!reconfig)
- client_add_destructor(keyboard_interactive_end_client, NULL);
+ client_add_destroy_notify(keyboard_interactive_end_client, NULL);
}
void keyboard_shutdown(gboolean reconfig)
{
if (!reconfig)
- client_remove_destructor(keyboard_interactive_end_client);
+ client_remove_destroy_notify(keyboard_interactive_end_client);
- istate.active = FALSE;
+ if (istate.active)
+ keyboard_interactive_cancel();
ob_main_loop_timeout_remove(ob_main_loop, chain_timeout);