summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2003-05-22 18:14:22 +0000
committerDana Jansens <danakj@orodu.net>2003-05-22 18:14:22 +0000
commit1eef38ce75abecac64104a0a42c04924fdd77b1c (patch)
tree4da3f878726982ddeef49ed06ddc5d3a7a9d93a6
parent64c9c16c3f5a34a5addb16acb96cf4ee18594105 (diff)
async key grabs to avoid race conditions with the sync stuff. there are still possible rases (yay X) but they will be much harder to hit, i expect noone will ever hit them more than once/often enuogh to realise.
-rw-r--r--plugins/keyboard/keyboard.c76
1 files changed, 39 insertions, 37 deletions
diff --git a/plugins/keyboard/keyboard.c b/plugins/keyboard/keyboard.c
index acda951a..5edd6291 100644
--- a/plugins/keyboard/keyboard.c
+++ b/plugins/keyboard/keyboard.c
@@ -5,6 +5,7 @@
#include "kernel/grab.h"
#include "kernel/action.h"
#include "kernel/parse.h"
+#include "kernel/timer.h"
#include "tree.h"
#include "keyboard.h"
#include "keyparse.h"
@@ -20,30 +21,37 @@ KeyBindingTree *firstnode = NULL;
static KeyBindingTree *curpos;
static guint reset_key, reset_state, button_return, button_escape;
-static gboolean grabbed;
+static Timer *chain_timer;
-static void grab_keys(gboolean grab)
+static void grab_keys()
{
- if (!grab) {
- ungrab_all_keys();
- } else {
- KeyBindingTree *p = firstnode;
- while (p) {
- grab_key(p->key, p->state, GrabModeSync);
- p = p->next_sibling;
- }
+ KeyBindingTree *p;
+
+ ungrab_all_keys();
+
+ p = curpos ? curpos->first_child : firstnode;
+ while (p) {
+ grab_key(p->key, p->state, GrabModeAsync);
+ p = p->next_sibling;
}
+ grab_key(reset_key, reset_state, GrabModeAsync);
}
static void reset_chains()
{
- /* XXX kill timer */
- curpos = NULL;
- if (grabbed) {
- grabbed = FALSE;
- grab_keyboard(FALSE);
- } else
- XAllowEvents(ob_display, AsyncKeyboard, event_lasttime);
+ if (chain_timer) {
+ timer_stop(chain_timer);
+ chain_timer = NULL;
+ }
+ if (curpos) {
+ curpos = NULL;
+ grab_keys();
+ }
+}
+
+static void chain_timeout(void *data)
+{
+ reset_chains();
}
gboolean kbind(GList *keylist, Action *action)
@@ -71,19 +79,12 @@ gboolean kbind(GList *keylist, Action *action)
return FALSE;
}
- /* grab the server here to make sure no key presses go missed */
- grab_server(TRUE);
- grab_keys(FALSE);
-
/* set the action */
t->actions = g_slist_append(t->actions, action);
/* assimilate this built tree into the main tree. assimilation
destroys/uses the tree */
if (tree) tree_assimilate(tree);
- grab_keys(TRUE);
- grab_server(FALSE);
-
return TRUE;
}
@@ -115,8 +116,8 @@ static void event(ObEvent *e, void *foo)
Action *act = it->data;
act->data.cycle.final = TRUE;
act->func(&act->data);
- grab_keyboard(FALSE);
grabbed_key = NULL;
+ grab_keyboard(FALSE);
reset_chains();
return;
}
@@ -140,14 +141,12 @@ static void event(ObEvent *e, void *foo)
if (p->key == e->data.x.e->xkey.keycode &&
p->state == e->data.x.e->xkey.state) {
if (p->first_child != NULL) { /* part of a chain */
- /* XXX TIMER */
- if (!grabbed) {
- grab_keyboard(TRUE);
- grabbed = TRUE;
- XAllowEvents(ob_display, AsyncKeyboard,
- event_lasttime);
- }
+ if (chain_timer) timer_stop(chain_timer);
+ /* 5 second timeout for chains */
+ chain_timer = timer_start(5000*1000, chain_timeout,
+ NULL);
curpos = p;
+ grab_keys();
} else {
GSList *it;
for (it = p->actions; it; it = it->next) {
@@ -164,8 +163,9 @@ static void event(ObEvent *e, void *foo)
if (act->func == action_cycle_windows &&
!grabbed_key) {
- grab_keyboard(TRUE);
grabbed_key = p;
+ grab_keyboard(TRUE);
+ break;
}
}
}
@@ -184,22 +184,24 @@ void plugin_startup()
guint i;
curpos = NULL;
- grabbed = FALSE;
+ chain_timer = NULL;
- dispatch_register(Event_X_KeyPress | Event_X_KeyRelease, (EventHandler)event, NULL);
+ dispatch_register(Event_X_KeyPress | Event_X_KeyRelease,
+ (EventHandler)event, NULL);
translate_key("C-g", &reset_state, &reset_key);
translate_key("Escape", &i, &button_escape);
translate_key("Return", &i, &button_return);
+
+ grab_keys();
}
void plugin_shutdown()
{
dispatch_register(0, (EventHandler)event, NULL);
- grab_keys(FALSE);
tree_destroy(firstnode);
firstnode = NULL;
- grab_keys(TRUE);
+ ungrab_all_keys();
}