From 31359b8bcc7cda35cd675bab34ccb785fb57fb9b Mon Sep 17 00:00:00 2001
From: Aleksandar Krsteski <alekrsteski@gmail.com>
Date: Wed, 18 Mar 2009 22:03:28 +0100
Subject: [PATCH 2/2] Try a better fix for losefocus race condition.
Try to fix the race condition between window losefocus event and
keybinding event from globalhotkeys in a better way, by comparing event
times of the keybinding event and losefocus event. To achive this add a
python binding for keybinder_get_current_event_time funcion and use it
to compare keybinding timestamp with losefocus timestamp.
---
src/globalhotkeys/globalhotkeys.c | 10 ++++++++++
src/guake.py | 23 ++++++++++++-----------
2 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/src/globalhotkeys/globalhotkeys.c b/src/globalhotkeys/globalhotkeys.c
index 99d19ac..f00cf24 100644
|
a
|
b
|
|
| 196 | 196 | return NULL; |
| 197 | 197 | } |
| 198 | 198 | |
| | 199 | static PyObject * |
| | 200 | GlobalHotkey_get_current_event_time (GlobalHotkey *self) |
| | 201 | { |
| | 202 | guint32 ret = keybinder_get_current_event_time (); |
| | 203 | return Py_BuildValue ("i", ret); |
| | 204 | } |
| | 205 | |
| 199 | 206 | static struct PyMemberDef GlobalHotkey_members[] = { |
| 200 | 207 | {"binded", T_OBJECT_EX, offsetof (GlobalHotkey, binded), 0, |
| 201 | 208 | "Already binded hotkeys"}, |
| … |
… |
|
| 216 | 223 | {"bind", (PyCFunction) GlobalHotkey_bind, |
| 217 | 224 | METH_VARARGS, "Bind a key to a callable object"}, |
| 218 | 225 | |
| | 226 | {"get_current_event_time", (PyCFunction) GlobalHotkey_get_current_event_time, |
| | 227 | METH_NOARGS, "Returns the timestamp of the current event"}, |
| | 228 | |
| 219 | 229 | {NULL} /* sentinel */ |
| 220 | 230 | }; |
| 221 | 231 | |
diff --git a/src/guake.py b/src/guake.py
index 1ebc6f4..cbf400a 100644
|
a
|
b
|
|
| 524 | 524 | # holds fullscreen status |
| 525 | 525 | self.fullscreen = False |
| 526 | 526 | |
| | 527 | # holds the timestamp of the losefocus event |
| | 528 | self.losefocus_time = 0 |
| | 529 | |
| 527 | 530 | # double click stuff |
| 528 | 531 | def double_click(hbox, event): |
| 529 | 532 | """Handles double clicks on tabs area and when receive |
| … |
… |
|
| 606 | 609 | value = self.client.get_bool(KEY('/general/window_losefocus')) |
| 607 | 610 | visible = window.get_property('visible') |
| 608 | 611 | if value and visible and not self.showing_context_menu: |
| | 612 | self.losefocus_time = gtk.gdk.x11_get_server_time(self.window.window) |
| 609 | 613 | self.hide() |
| 610 | 614 | |
| 611 | | # There is a race condition between the focus-out-event and |
| 612 | | # the global keybind that calls the self.show_hide method. I |
| 613 | | # didn't investigate but this callback is allways called |
| 614 | | # before the X keyboard event. So, to fix it temporarely, I |
| 615 | | # did the following hammer: |
| 616 | | def hack(): |
| 617 | | sleep(0.1) |
| 618 | | self.client.notify(GKEY('show_hide')) |
| 619 | | self.hotkeys.unbind_all() |
| 620 | | start_new_thread(hack, ()) |
| 621 | | |
| 622 | 615 | def show_menu(self, *args): |
| 623 | 616 | """Show the tray icon menu. |
| 624 | 617 | """ |
| … |
… |
|
| 671 | 664 | def show_hide(self, *args): |
| 672 | 665 | """Toggles the main window visibility |
| 673 | 666 | """ |
| | 667 | event_time = self.hotkeys.get_current_event_time() |
| | 668 | |
| | 669 | if self.losefocus_time and \ |
| | 670 | self.losefocus_time >= event_time and \ |
| | 671 | (self.losefocus_time - event_time) < 10: |
| | 672 | self.losefocus_time = 0 |
| | 673 | return |
| | 674 | |
| 674 | 675 | if not self.window.get_property('visible'): |
| 675 | 676 | self.show() |
| 676 | 677 | self.set_terminal_focus() |