From ebe043a4d20d408f04fb1a520fd5e707bbbf68db Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Sat, 17 Mar 2007 13:30:23 +0000 Subject: Refactored global key handling and frame logic. --- (limited to 'shell') diff --git a/shell/view/frame/frame.py b/shell/view/frame/frame.py index 11aea67..aa152ef 100644 --- a/shell/view/frame/frame.py +++ b/shell/view/frame/frame.py @@ -13,6 +13,7 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +import logging import gtk import gobject @@ -77,38 +78,36 @@ class _MouseListener(object): _FRAME_HIDING_DELAY, self._hide_frame_timeout_cb) class _KeyListener(object): + _HIDDEN = 1 + _SHOWN_PRESSED = 2 + _SHOWN_REPEAT = 3 + _SHOWN_RELEASED = 4 + def __init__(self, frame): self._frame = frame - self._hide_sid = 0 + self._state = _KeyListener._HIDDEN def key_press(self): if self._frame.mode != MODE_NONE and \ self._frame.mode != MODE_KEYBOARD: return - if self._frame.visible: - self._hide_frame() - else: - self._show_frame() + if self._state == _KeyListener._HIDDEN: + self._frame.show() + self._frame.mode = MODE_KEYBOARD + self._state = _KeyListener._SHOWN_PRESSED + elif self._state == _KeyListener._SHOWN_PRESSED: + self._state = _KeyListener._SHOWN_REPEAT + elif self._state == _KeyListener._SHOWN_RELEASED: + self._frame.hide() + self._state = _KeyListener._HIDDEN def key_release(self): - self._hide_frame() - - def _hide_frame_timeout_cb(self): - self._frame.hide() - return False - - def _show_frame(self): - if self._hide_sid != 0: - gobject.source_remove(self._hide_sid) - self._frame.show() - self._frame.mode = MODE_KEYBOARD - - def _hide_frame(self): - if self._hide_sid != 0: - gobject.source_remove(self._hide_sid) - self._hide_sid = gobject.timeout_add( - 100, self._hide_frame_timeout_cb) + if self._state == _KeyListener._SHOWN_PRESSED: + self._state = _KeyListener._SHOWN_RELEASED + elif self._state == _KeyListener._SHOWN_REPEAT: + self._frame.hide() + self._state = _KeyListener._HIDDEN class Frame(object): def __init__(self, shell): diff --git a/shell/view/keyhandler.py b/shell/view/keyhandler.py index ac3e7dd..645f5d6 100644 --- a/shell/view/keyhandler.py +++ b/shell/view/keyhandler.py @@ -1,8 +1,10 @@ import os import signal +import logging import dbus import gobject +import gtk from sugar import env from hardware import hardwaremanager @@ -46,6 +48,9 @@ class KeyHandler(object): self._shell = shell self._audio_manager = hardwaremanager.get_audio_manager() self._screen_rotation = 0 + self._key_pressed = None + self._keycode_pressed = 0 + self._keystate_pressed = 0 self._key_grabber = KeyGrabber() self._key_grabber.connect('key-pressed', @@ -166,16 +171,42 @@ class KeyHandler(object): # FIXME: finish alt+tab support pass - def _key_pressed_cb(self, grabber, key): - action = _actions_table[key] - method = getattr(self, 'handle_' + action) - method() + def _key_pressed_cb(self, grabber, keycode, state): + key = grabber.get_key(keycode, state) + if key: + self._key_pressed = key + self._keycode_pressed = keycode + self._keystate_pressed = state + gtk.gdk.keyboard_grab(gtk.gdk.get_default_root_window(), + owner_events=False, time=0L) - def _key_released_cb(self, grabber, key): - if key == 'F9': - self._shell.get_frame().notify_key_release() - elif key == '0x93': - self._shell.get_frame().notify_key_release() + action = _actions_table[key] + method = getattr(self, 'handle_' + action) + method() + + return True + + return False + + def _key_released_cb(self, grabber, keycode, state): + if self._keycode_pressed == keycode: + self._keycode_pressed = 0 + + if self._keystate_pressed == state: + self._keystate_pressed = 0 + + if not self._keycode_pressed and not self._keystate_pressed and \ + self._key_pressed: + gtk.gdk.keyboard_ungrab(time=0L) + + if self._key_pressed == 'f': + self._shell.get_frame().notify_key_release() + elif self._key_pressed == '0x93': + self._shell.get_frame().notify_key_release() + + return True + + return False def _toggle_console_visibility_cb(self): bus = dbus.SessionBus() -- cgit v0.9.1