From 2e2d481748eb77a72e641df559c945439a794595 Mon Sep 17 00:00:00 2001 From: Simon Schampijer Date: Tue, 09 Oct 2012 08:47:10 +0000 Subject: Touch: on long-press on a link or image show the Palette Show the same Palette as we show when a learner does a right click on a canvas element. We use the LongPress event controller from the toolkit for that. We can only hook this up to the browser widget once it is realized because we need to enable the touch events on the x11 window. When we recognized a long-press event we need to get the information about that canvas element from WebKit. The webkit_web_view_get_hit_test_result API [1] which we use when a right click is recognized does expect an event of type GdkEventButton to be passed. From the x, y coordinates we get with the pressed signal we can construct such an event and and pass that fake event to WebKit. In order to differentiate between a tap and a tap&hold event, we need to inhibit the release event to be further propagated if a long-press occurred before. We use a boolean to differentiate those two cases. [1] http://webkitgtk.org/reference/webkitgtk/stable/webkitgtk-webkitwebview.html#webkit-web-view-get-hit-test-result Signed-off-by: Simon Schampijer Acked-by: Manuel QuiƱones --- diff --git a/palettes.py b/palettes.py index bbebce8..e97fd4c 100644 --- a/palettes.py +++ b/palettes.py @@ -26,6 +26,8 @@ from gi.repository import Gtk from gi.repository import Gdk from gi.repository import WebKit +from gi.repository import SugarGestures + from sugar3.graphics.palette import Palette, Invoker from sugar3 import profile @@ -37,12 +39,50 @@ class ContentInvoker(Invoker): Invoker.__init__(self) self._position_hint = self.AT_CURSOR self._browser = browser + self._recognized_long_press_event = False self._browser.connect('button-press-event', self.__button_press_cb) + self._browser.connect('button-release-event', self.__button_release_cb) + self._browser.connect('realize', self.__browser_realize_cb) self.attach(self._browser) def get_default_position(self): return self.AT_CURSOR + def __long_pressed_cb(self, controller, x, y): + self._recognized_long_press_event = True + + event = Gdk.EventButton() + event.type = Gdk.EventType._3BUTTON_PRESS + gdk_window = self._browser.get_window() + event.window = gdk_window + event.time = Gtk.get_current_event_time() + event.x = x + event.y = y + x_root, y_root = gdk_window.get_root_coords(x, y) + event.x_root = x_root + event.y_root = y_root + + self._handle_event(event) + + return True + + def __button_release_cb(self, browser, event): + if self._recognized_long_press_event: + self._recognized_long_press_event = False + return True + else: + return False + + def __browser_realize_cb(self, browser): + x11_window = browser.get_window() + x11_window.set_events(x11_window.get_events() | + Gdk.EventMask.POINTER_MOTION_MASK | + Gdk.EventMask.TOUCH_MASK) + + lp = SugarGestures.LongPressController(trigger_delay=500) + lp.connect('pressed', self.__long_pressed_cb) + lp.attach(browser, SugarGestures.EventControllerFlags.NONE) + def get_rect(self): allocation = self._browser.get_allocation() window = self._browser.get_window() @@ -73,6 +113,10 @@ class ContentInvoker(Invoker): def __button_press_cb(self, browser, event): if event.button != 3: return False + self._handle_event(event) + return True + + def _handle_event(self, event): hit_test = self._browser.get_hit_test_result(event) if hit_test.props.context & WebKit.HitTestResultContext.LINK: link_uri = hit_test.props.link_uri @@ -104,8 +148,6 @@ class ContentInvoker(Invoker): self.palette = SelectionPalette(self._browser, title, None, None) self.notify_right_click() - return True - class SelectionPalette(Palette): def __init__(self, browser, title, url, owner_document): -- cgit v0.9.1