Ticket #3997: 0001-Touch-on-long-press-on-a-link-or-image-show-the-Pale.patch

File 0001-Touch-on-long-press-on-a-link-or-image-show-the-Pale.patch, 4.2 KB (added by erikos, 12 years ago)

Touch: on long-press on a link or image show the Palette

  • palettes.py

    From 89834550190d287f0e0b86a3eb4ddc0abd99158a Mon Sep 17 00:00:00 2001
    From: Simon Schampijer <simon@laptop.org>
    Date: Tue, 9 Oct 2012 10:47:10 +0200
    Subject: [PATCH] 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
    ---
     palettes.py | 46 ++++++++++++++++++++++++++++++++++++++++++++--
     1 file changed, 44 insertions(+), 2 deletions(-)
    
    diff --git a/palettes.py b/palettes.py
    index bbebce8..ffd1d80 100644
    a b from gi.repository import Gtk 
    2626from gi.repository import Gdk
    2727from gi.repository import WebKit
    2828
     29from gi.repository import SugarGestures
     30
    2931from sugar3.graphics.palette import Palette, Invoker
    3032from sugar3 import profile
    3133
    class ContentInvoker(Invoker): 
    3739        Invoker.__init__(self)
    3840        self._position_hint = self.AT_CURSOR
    3941        self._browser = browser
     42        self._recognized_long_press_event = False
    4043        self._browser.connect('button-press-event', self.__button_press_cb)
     44        self._browser.connect('button-release-event', self.__button_release_cb)
     45        self._browser.connect('realize', self.__browser_realize_cb)
    4146        self.attach(self._browser)
    4247
    4348    def get_default_position(self):
    4449        return self.AT_CURSOR
    4550
     51    def __long_pressed_cb(self, controller, x, y):
     52        self._recognized_long_press_event = True
     53
     54        event = Gdk.EventButton()
     55        event.type = Gdk.EventType._3BUTTON_PRESS
     56        gdk_window = self._browser.get_window()
     57        event.window = gdk_window
     58        event.time = Gtk.get_current_event_time()
     59        event.x = x
     60        event.y = y
     61        x_root, y_root = gdk_window.get_root_coords(x, y)
     62        event.x_root = x_root
     63        event.y_root = y_root
     64
     65        self._handle_event(event)
     66
     67        return True
     68
     69    def __button_release_cb(self, browser, event):
     70        if self._recognized_long_press_event:
     71            self._recognized_long_press_event = False
     72            return True
     73        else:
     74            return False
     75
     76    def __browser_realize_cb(self, browser):
     77        x11_window = browser.get_window()
     78        x11_window.set_events(x11_window.get_events() |
     79                              Gdk.EventMask.POINTER_MOTION_MASK |
     80                              Gdk.EventMask.TOUCH_MASK)
     81
     82        lp = SugarGestures.LongPressController(trigger_delay=100)
     83        lp.connect('pressed', self.__long_pressed_cb)
     84        lp.attach(browser, SugarGestures.EventControllerFlags.NONE)
     85
    4686    def get_rect(self):
    4787        allocation = self._browser.get_allocation()
    4888        window = self._browser.get_window()
    class ContentInvoker(Invoker): 
    73113    def __button_press_cb(self, browser, event):
    74114        if event.button != 3:
    75115            return False
     116        self._handle_event(event)
     117        return True
     118
     119    def _handle_event(self, event):
    76120        hit_test = self._browser.get_hit_test_result(event)
    77121        if hit_test.props.context & WebKit.HitTestResultContext.LINK:
    78122            link_uri = hit_test.props.link_uri
    class ContentInvoker(Invoker): 
    104148            self.palette = SelectionPalette(self._browser, title, None, None)
    105149            self.notify_right_click()
    106150
    107         return True
    108 
    109151
    110152class SelectionPalette(Palette):
    111153    def __init__(self, browser, title, url, owner_document):