WidgetInvoker: add support for long-press events, part of #4127
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 Signed-off-by: Simon Schampijer <simon@laptop.org> Acked-by: Manuel Quiñones <manuq@laptop.org>
This commit is contained in:
parent
de7c5b90bd
commit
a515976dff
@ -1002,6 +1002,11 @@ class WidgetInvoker(Invoker):
|
|||||||
self._enter_hid = None
|
self._enter_hid = None
|
||||||
self._leave_hid = None
|
self._leave_hid = None
|
||||||
self._release_hid = None
|
self._release_hid = None
|
||||||
|
self._click_hid = None
|
||||||
|
self._touch_hid = None
|
||||||
|
self._long_pressed_recognized = False
|
||||||
|
self._long_pressed_hid = None
|
||||||
|
self._long_pressed_controller = SugarGestures.LongPressController()
|
||||||
|
|
||||||
if parent or widget:
|
if parent or widget:
|
||||||
self.attach_widget(parent, widget)
|
self.attach_widget(parent, widget)
|
||||||
@ -1018,9 +1023,18 @@ class WidgetInvoker(Invoker):
|
|||||||
self.__enter_notify_event_cb)
|
self.__enter_notify_event_cb)
|
||||||
self._leave_hid = self._widget.connect('leave-notify-event',
|
self._leave_hid = self._widget.connect('leave-notify-event',
|
||||||
self.__leave_notify_event_cb)
|
self.__leave_notify_event_cb)
|
||||||
|
if GObject.signal_lookup('clicked', self._widget) != 0:
|
||||||
|
self._click_hid = self._widget.connect('clicked',
|
||||||
|
self.__click_event_cb)
|
||||||
|
self._touch_hid = self._widget.connect('touch-event',
|
||||||
|
self.__touch_event_cb)
|
||||||
self._release_hid = self._widget.connect('button-release-event',
|
self._release_hid = self._widget.connect('button-release-event',
|
||||||
self.__button_release_event_cb)
|
self.__button_release_event_cb)
|
||||||
|
|
||||||
|
self._long_pressed_hid = self._long_pressed_controller.connect(
|
||||||
|
'pressed', self.__long_pressed_event_cb, self._widget)
|
||||||
|
self._long_pressed_controller.attach(self._widget,
|
||||||
|
SugarGestures.EventControllerFlags.NONE)
|
||||||
self.attach(parent)
|
self.attach(parent)
|
||||||
|
|
||||||
def detach(self):
|
def detach(self):
|
||||||
@ -1028,6 +1042,11 @@ class WidgetInvoker(Invoker):
|
|||||||
self._widget.disconnect(self._enter_hid)
|
self._widget.disconnect(self._enter_hid)
|
||||||
self._widget.disconnect(self._leave_hid)
|
self._widget.disconnect(self._leave_hid)
|
||||||
self._widget.disconnect(self._release_hid)
|
self._widget.disconnect(self._release_hid)
|
||||||
|
if self._click_hid:
|
||||||
|
self._widget.disconnect(self._click_hid)
|
||||||
|
self._widget.disconnect(self._touch_hid)
|
||||||
|
self._long_pressed_controller.detach(self._widget)
|
||||||
|
self._long_pressed_controller.disconnect(self._long_pressed_hid)
|
||||||
|
|
||||||
def get_rect(self):
|
def get_rect(self):
|
||||||
allocation = self._widget.get_allocation()
|
allocation = self._widget.get_allocation()
|
||||||
@ -1075,8 +1094,19 @@ class WidgetInvoker(Invoker):
|
|||||||
if event.mode == Gdk.CrossingMode.NORMAL:
|
if event.mode == Gdk.CrossingMode.NORMAL:
|
||||||
self.notify_mouse_leave()
|
self.notify_mouse_leave()
|
||||||
|
|
||||||
|
def __touch_event_cb(self, button, event):
|
||||||
|
if event.type == Gdk.EventType.TOUCH_END:
|
||||||
|
if self._long_pressed_recognized:
|
||||||
|
self._long_pressed_recognized = False
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __click_event_cb(self, button):
|
||||||
|
if self.props.toggle_palette:
|
||||||
|
self.notify_toggle_state()
|
||||||
|
|
||||||
def __button_release_event_cb(self, widget, event):
|
def __button_release_event_cb(self, widget, event):
|
||||||
if event.button == 1:
|
if event.button == 1 and not self._click_hid:
|
||||||
if self.props.toggle_palette:
|
if self.props.toggle_palette:
|
||||||
self.notify_toggle_state()
|
self.notify_toggle_state()
|
||||||
elif event.button == 3:
|
elif event.button == 3:
|
||||||
@ -1085,6 +1115,10 @@ class WidgetInvoker(Invoker):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def __long_pressed_event_cb(self, controller, x, y, widget):
|
||||||
|
self._long_pressed_recognized = True
|
||||||
|
self.notify_right_click()
|
||||||
|
|
||||||
def get_toplevel(self):
|
def get_toplevel(self):
|
||||||
return self._widget.get_toplevel()
|
return self._widget.get_toplevel()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user