emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/android 62da1e57426 2/2: Improve touch-screen support


From: Po Lu
Subject: feature/android 62da1e57426 2/2: Improve touch-screen support
Date: Sat, 21 Jan 2023 08:46:55 -0500 (EST)

branch: feature/android
commit 62da1e574269fd22b5bae78361a791bedf01a0ca
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Improve touch-screen support
    
    * doc/lispref/commands.texi (Touchscreen Events): Document
    changes.
    * lisp/touch-screen.el (touch-screen-current-tool): Update doc
    string.
    (touch-screen-precision-scroll): New user option.
    (touch-screen-handle-scroll): Use traditional scrolling by
    default.
    (touch-screen-handle-touch): Adust format of
    touch-screen-current-tool.
    (touch-screen-track-tap): Don't print waiting for events.
    (touch-screen-track-drag): Likewise.  Also, don't call UPDATE
    until threshold is reached.
    (touch-screen-drag-mode-line-1, touch-screen-drag-mode-line):
    Improve window dragging.
---
 doc/lispref/commands.texi |  6 ++--
 lisp/touch-screen.el      | 77 ++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 64 insertions(+), 19 deletions(-)

diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index 484c7dc2a06..2c0787521a5 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -2058,8 +2058,10 @@ This function is used to track a single ``drag'' gesture 
originating
 from the @code{touchscreen-begin} event @code{event}.
 
 It behaves like @code{touch-screen-track-tap}, except that it returns
-@code{no-drag} if the touchpoint in @code{event} did not move far
-enough to qualify as an actual drag.
+@code{no-drag} and refrains from calling @var{update} if the
+touchpoint in @code{event} did not move far enough (by default, 5
+pixels from its position in @code{event}) to qualify as an actual
+drag.
 @end defun
 
 @node Focus Events
diff --git a/lisp/touch-screen.el b/lisp/touch-screen.el
index a1c9e0b4afd..855eebcc43f 100644
--- a/lisp/touch-screen.el
+++ b/lisp/touch-screen.el
@@ -30,11 +30,12 @@
 
 (defvar touch-screen-current-tool nil
   "The touch point currently being tracked, or nil.
-If non-nil, this is a list of five elements: the ID of the touch
+If non-nil, this is a list of six elements: the ID of the touch
 point being tracked, the window where the touch began, a cons
 containing the last known position of the touch point, relative
 to that window, a field used to store data while tracking the
-touch point, and the initial position of the touchpoint.  See
+touch point, the initial position of the touchpoint, and another
+field to used store data while tracking the touch point.  See
 `touch-screen-handle-point-update' for the meanings of the fourth
 element.")
 
@@ -54,6 +55,13 @@ This is always cleared upon any significant state change.")
   :group 'mouse
   :version "30.1")
 
+(defcustom touch-screen-precision-scroll nil
+  "Whether or not to use precision scrolling for touch screens.
+See `pixel-scroll-precision-mode' for more details."
+  :type 'boolean
+  :group 'mouse
+  :version "30.1")
+
 (defun touch-screen-relative-xy (posn window)
   "Return the coordinates of POSN, a mouse position list.
 However, return the coordinates relative to WINDOW.
@@ -86,10 +94,41 @@ to the frame that they belong in."
 (defun touch-screen-handle-scroll (dx dy)
   "Scroll the display assuming that a touch point has moved by DX and DY."
   (ignore dx)
-  ;; This only looks good with precision pixel scrolling.
-  (if (> dy 0)
-      (pixel-scroll-precision-scroll-down-page dy)
-    (pixel-scroll-precision-scroll-up-page (- dy))))
+  (if touch-screen-precision-scroll
+      (if (> dy 0)
+          (pixel-scroll-precision-scroll-down-page dy)
+        (pixel-scroll-precision-scroll-up-page (- dy)))
+    ;; Start conventional scrolling.  First, determine the direction
+    ;; in which the scrolling is taking place.  Load the accumulator
+    ;; value.
+    (let ((accumulator (or (nth 5 touch-screen-current-tool) 0))
+          (window (cadr touch-screen-current-tool)))
+      (setq accumulator (+ accumulator dy)) ; Add dy.
+      ;; Figure out how much it has scrolled and how much remains on
+      ;; the top or bottom of the window.
+      (while (catch 'again
+               (let* ((line-height (window-default-line-height window)))
+                 (if (and (< accumulator 0)
+                          (>= (- accumulator) line-height))
+                     (progn
+                       (setq accumulator (+ accumulator line-height))
+                       (scroll-down 1)
+                       (when (not (zerop accumulator))
+                         ;; If there is still an outstanding amount to
+                         ;; scroll, do this again.
+                         (throw 'again t)))
+                   (when (and (> accumulator 0)
+                              (>= accumulator line-height))
+                     (setq accumulator (- accumulator line-height))
+                       (scroll-up 1)
+                       (when (not (zerop accumulator))
+                         ;; If there is still an outstanding amount to
+                         ;; scroll, do this again.
+                         (throw 'again t)))))
+               ;; Scrolling is done.  Move the accumulator back to
+               ;; touch-screen-current-tool and break out of the loop.
+               (setcar (nthcdr 5 touch-screen-current-tool) accumulator)
+               nil)))))
 
 (defun touch-screen-handle-timeout (arg)
   "Start the touch screen timeout or handle it depending on ARG.
@@ -338,7 +377,7 @@ touchscreen-end event."
                                            (list touchpoint
                                                  (posn-window position)
                                                  (posn-x-y position)
-                                                 nil position)))
+                                                 nil position nil)))
       ;; Start the long-press timer.
       (touch-screen-handle-timeout nil)))
    ((eq (car event) 'touchscreen-update)
@@ -382,7 +421,7 @@ Return nil immediately if any other kind of event is 
received;
 otherwise, return t once the `touchscreen-end' event arrives."
   (catch 'finish
     (while t
-      (let ((new-event (read-event)))
+      (let ((new-event (read-event nil)))
         (cond
          ((eq (car-safe new-event) 'touchscreen-update)
           (when (and update (assq (caadr event) (cadr new-event)))
@@ -403,7 +442,8 @@ Read touch screen events until a `touchscreen-end' event is
 received with the same ID as in EVENT.  For each
 `touchscreen-update' event received in the mean time containing a
 touch point with the same ID as in EVENT, call UPDATE with the
-touch point in event and DATA.
+touch point in event and DATA, once the touch point has moved
+significantly by at least 5 pixels from where it was in EVENT.
 
 Return nil immediately if any other kind of event is received;
 otherwise, return either t or `no-drag' once the
@@ -414,7 +454,7 @@ touch point in EVENT did not move significantly, and t 
otherwise."
                                             'frame)))
     (catch 'finish
       (while t
-        (let ((new-event (read-event)))
+        (let ((new-event (read-event nil)))
           (cond
            ((eq (car-safe new-event) 'touchscreen-update)
             (when-let* ((tool (assq (caadr event) (nth 1 new-event)))
@@ -424,7 +464,7 @@ touch point in EVENT did not move significantly, and t 
otherwise."
                         (> (- (cdr xy) (cdr start-xy)) 5)
                         (< (- (cdr xy) (cdr start-xy)) -5))
                 (setq return-value t))
-              (when (and update tool)
+              (when (and update tool (eq return-value t))
                 (funcall update new-event data))))
            ((eq (car-safe new-event) 'touchscreen-end)
             (throw 'finish
@@ -447,6 +487,8 @@ happened.  EVENT is the same as in 
`touch-screen-drag-mode-line'."
   ;; to [down-mouse-1] or a command bound to [mouse-1].  Then, if a
   ;; keymap was found, pop it up as a menu.  Otherwise, wait for a tap
   ;; to complete and run the command found.
+  ;; Also, select the window in EVENT.
+  (select-window (posn-window (cdadr event)))
   (let* ((object (posn-object (cdadr event)))
          (object-keymap (and (consp object)
                              (stringp (car object))
@@ -483,8 +525,8 @@ bound, run that command instead."
   (interactive "e")
   ;; Find the window that should be dragged and the starting position.
   (let* ((window (posn-window (cdadr event)))
-         (relative-xy (touch-screen-relative-xy
-                       (cdadr event) window))
+         (relative-xy (touch-screen-relative-xy (cdadr event)
+                                                'frame))
          (last-position (cdr relative-xy)))
     (when (window-resizable window 0)
       (when (eq
@@ -495,9 +537,9 @@ bound, run that command instead."
                       (let* ((touchpoint (assq (caadr event)
                                                (cadr new-event)))
                              (new-relative-xy
-                              (touch-screen-relative-xy (cdr touchpoint)
-                                                        window))
+                              (touch-screen-relative-xy (cdr touchpoint) 
'frame))
                              (position (cdr new-relative-xy))
+                             (window-resize-pixelwise t)
                              growth)
                         ;; Now set the new height of the window.  If
                         ;; new-relative-y is above relative-xy, then
@@ -513,8 +555,9 @@ bound, run that command instead."
                                          (> position
                                             (+ (window-pixel-top window)
                                                (window-pixel-height window)))))
-                          (adjust-window-trailing-edge window growth nil t))
-                        (setq last-position position))))
+                          (when (ignore-errors
+                                  (adjust-window-trailing-edge window growth 
nil t) t)
+                            (setq last-position position))))))
              'no-drag)
         ;; Dragging did not actually happen, so try to run any command
         ;; necessary.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]