From 563d7a17fd15a792e84705aab3cd1bb793c0ae5d Mon Sep 17 00:00:00 2001
From: Simon Schampijer <simon@laptop.org>
Date: Thu, 1 Nov 2012 13:35:16 +0100
Subject: [PATCH toolkit-gtk3 2/2] WidgetInvoker: add support for long-press
events
The WidgetInvoker will decide if a long press has been made
or not. We watch out for TOUCH_END events and when a long-press
event has been seen before we stop further propagation of the
event, hence there won't be any button-release or clicked
events available to the user of the widget.
There are several widgets using the WidgetInvoker, and those
handle differently touch events. The GtkButton does have a widget
implementation to handle touch events, it does stop further
propagation and emits the pressed/released signal for further
consumption [1]. We will not get a button-press/button-release
event for a touch event in this case.
The default behaviour for widgets e.g. a TreeView is to transform
the touch events into pointer events [2], for those widgets we do get
a button-press/button-release event for a touch events.
[1] http://git.gnome.org/browse/gtk+/tree/gtk/gtkbutton.c#n1809
[2] http://git.gnome.org/browse/gtk+/tree/gtk/gtkwidget.c#n5876
---
src/sugar3/graphics/palettewindow.py | 36 +++++++++++++++++++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
diff --git a/src/sugar3/graphics/palettewindow.py b/src/sugar3/graphics/palettewindow.py
index 6e33efe..e1fde4a 100644
a
|
b
|
class WidgetInvoker(Invoker): |
1002 | 1002 | self._enter_hid = None |
1003 | 1003 | self._leave_hid = None |
1004 | 1004 | self._release_hid = None |
| 1005 | self._click_hid = None |
| 1006 | self._touch_hid = None |
| 1007 | self._long_pressed_recognized = False |
| 1008 | self._long_pressed_hid = None |
| 1009 | self._long_pressed_controller = SugarGestures.LongPressController() |
1005 | 1010 | |
1006 | 1011 | if parent or widget: |
1007 | 1012 | self.attach_widget(parent, widget) |
… |
… |
class WidgetInvoker(Invoker): |
1018 | 1023 | self.__enter_notify_event_cb) |
1019 | 1024 | self._leave_hid = self._widget.connect('leave-notify-event', |
1020 | 1025 | self.__leave_notify_event_cb) |
| 1026 | if GObject.signal_lookup('clicked', self._widget) != 0: |
| 1027 | self._click_hid = self._widget.connect('clicked', |
| 1028 | self.__click_event_cb) |
| 1029 | self._touch_hid = self._widget.connect('touch-event', |
| 1030 | self.__touch_event_cb) |
1021 | 1031 | self._release_hid = self._widget.connect('button-release-event', |
1022 | 1032 | self.__button_release_event_cb) |
1023 | 1033 | |
| 1034 | self._long_pressed_hid = self._long_pressed_controller.connect( |
| 1035 | 'pressed', self.__long_pressed_event_cb, self._widget) |
| 1036 | self._long_pressed_controller.attach(self._widget, |
| 1037 | SugarGestures.EventControllerFlags.NONE) |
1024 | 1038 | self.attach(parent) |
1025 | 1039 | |
1026 | 1040 | def detach(self): |
… |
… |
class WidgetInvoker(Invoker): |
1028 | 1042 | self._widget.disconnect(self._enter_hid) |
1029 | 1043 | self._widget.disconnect(self._leave_hid) |
1030 | 1044 | self._widget.disconnect(self._release_hid) |
| 1045 | if self._click_hid: |
| 1046 | self._widget.disconnect(self._click_hid) |
| 1047 | self._widget.disconnect(self._touch_hid) |
| 1048 | self._long_pressed_controller.detach(self._widget) |
| 1049 | self._long_pressed_controller.disconnect(self._long_pressed_hid) |
1031 | 1050 | |
1032 | 1051 | def get_rect(self): |
1033 | 1052 | allocation = self._widget.get_allocation() |
… |
… |
class WidgetInvoker(Invoker): |
1075 | 1094 | if event.mode == Gdk.CrossingMode.NORMAL: |
1076 | 1095 | self.notify_mouse_leave() |
1077 | 1096 | |
| 1097 | def __touch_event_cb(self, button, event): |
| 1098 | if event.type == Gdk.EventType.TOUCH_END: |
| 1099 | if self._long_pressed_recognized: |
| 1100 | self._long_pressed_recognized = False |
| 1101 | return True |
| 1102 | return False |
| 1103 | |
| 1104 | def __click_event_cb(self, button): |
| 1105 | if self.props.toggle_palette: |
| 1106 | self.notify_toggle_state() |
| 1107 | |
1078 | 1108 | def __button_release_event_cb(self, widget, event): |
1079 | | if event.button == 1: |
| 1109 | if event.button == 1 and not self._click_hid: |
1080 | 1110 | if self.props.toggle_palette: |
1081 | 1111 | self.notify_toggle_state() |
1082 | 1112 | elif event.button == 3: |
… |
… |
class WidgetInvoker(Invoker): |
1085 | 1115 | else: |
1086 | 1116 | return False |
1087 | 1117 | |
| 1118 | def __long_pressed_event_cb(self, controller, x, y, widget): |
| 1119 | self._long_pressed_recognized = True |
| 1120 | self.notify_right_click() |
| 1121 | |
1088 | 1122 | def get_toplevel(self): |
1089 | 1123 | return self._widget.get_toplevel() |
1090 | 1124 | |