-void keyboard_interactive_grab(guint state, ObClient *client,
- ObFrameContext context, ObAction *action)
+gboolean keyboard_interactive_grab(guint state, ObClient *client,
+ ObAction *action)
+{
+ ObInteractiveState *s;
+
+ g_assert(action->data.any.interactive);
+
+ if (!interactive_states) {
+ if (!grab_keyboard(TRUE))
+ return FALSE;
+ if (!grab_pointer(TRUE, OB_CURSOR_NONE)) {
+ grab_keyboard(FALSE);
+ return FALSE;
+ }
+ }
+
+ s = g_new(ObInteractiveState, 1);
+
+ s->state = state;
+ 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)
+{
+ action_run_interactive(s->actions, s->client, state, 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_pointer(FALSE, OB_CURSOR_NONE);
+ keyboard_reset_chains();
+ }
+}
+
+void keyboard_interactive_end_client(ObClient *client, gpointer data)