summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild-aux/makecounter.sh2
-rw-r--r--doc/emacs/input.texi9
-rw-r--r--doc/lispref/commands.texi15
-rw-r--r--lisp/touch-screen.el152
-rw-r--r--src/Makefile.in43
5 files changed, 160 insertions, 61 deletions
diff --git a/build-aux/makecounter.sh b/build-aux/makecounter.sh
index 13ad5f485a2..3bebd288031 100755
--- a/build-aux/makecounter.sh
+++ b/build-aux/makecounter.sh
@@ -39,5 +39,5 @@ cat > $1 <<EOF
#ifdef EXPORT
EXPORT
#endif /* EXPORT */
-int counter = $curcount;
+int emacs_shortlisp_counter = $curcount;
EOF
diff --git a/doc/emacs/input.texi b/doc/emacs/input.texi
index eccb3e5e243..f5b0d0570e1 100644
--- a/doc/emacs/input.texi
+++ b/doc/emacs/input.texi
@@ -68,6 +68,15 @@ touch screen display, to the detriment of text selection. The user
option @code{touch-screen-word-select} enables ``word selection
mode'', causing dragging to select the complete word, not only the
character containing the position of the tool.
+
+@vindex touch-screen-extend-selection
+@cindex extending the selection, touchscreens
+ Similarly, it may be difficult to select all of the text intended
+within a single gesture. If the user option
+@code{touch-screen-extend-selection} is enabled, taps on the locations
+of the point or the mark within a window will begin a new ``drag''
+gesture, where the region will be extended in the direction of any
+subsequent movement.
@end itemize
@vindex touch-screen-delay
diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index 55fecdce2d7..d53e45a73de 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -2129,9 +2129,18 @@ set to a mouse position list containing the position of the
@cindex @code{touchscreen-drag} event
@item (touchscreen-drag @var{posn})
If a ``long-press'' gesture is detected while translating the current
-touch sequence, a @code{touchscreen-drag} event is sent upon each
-subsequent @code{touchscreen-update} event, with @var{posn} set to the
-new position of the touchpoint.
+touch sequence or ``drag-to-select'' is being resumed as a result of
+the @code{touch-screen-extend-selection} user option, a
+@code{touchscreen-drag} event is sent upon each subsequent
+@code{touchscreen-update} event with @var{posn} set to the new
+position of the touchpoint.
+
+@cindex @code{touchscreen-restart-drag} event
+@item (touchscreen-restart-drag @var{posn})
+This event is sent upon the start of a touch sequence resulting in the
+continuation of a ``drag-to-select'' gesture (subject to the
+aformentioned user option) with @var{posn} set to the position list of
+the initial @code{touchscreen-begin} event within that touch sequence.
@end table
@cindex handling touch screen events
diff --git a/lisp/touch-screen.el b/lisp/touch-screen.el
index 4c43ec4b63f..a9815dfc623 100644
--- a/lisp/touch-screen.el
+++ b/lisp/touch-screen.el
@@ -86,6 +86,15 @@ by dragging will try to select entire words."
:group 'mouse
:version "30.1")
+(defcustom touch-screen-extend-selection nil
+ "If non-nil, restart drag-to-select upon a tap on point or mark.
+When enabled, tapping on the character containing the point or
+mark will resume dragging where it left off while the region is
+active."
+ :type 'boolean
+ :group 'mouse
+ :version "30.1")
+
(defvar-local touch-screen-word-select-bounds nil
"The start and end positions of the word last selected.
Normally a cons of those two positions or nil if no word was
@@ -471,8 +480,35 @@ area."
(setq touch-screen-word-select-bounds nil))
(redisplay)))))))))
+(defun touch-screen-restart-drag (event)
+ "Restart dragging to select text.
+Set point to the location of EVENT within its window while
+keeping the bounds of the region intact, and set up state for
+`touch-screen-drag'."
+ (interactive "e")
+ (let* ((posn (event-start event))
+ (window (posn-window posn))
+ (point (posn-point posn)))
+ (with-selected-window window
+ (let ((current-point (point))
+ (current-mark (mark)))
+ ;; Ensure that mark and point haven't changed since EVENT was
+ ;; generated, and the region is still active.
+ (when (or (eq point current-point)
+ (eq point current-mark)
+ (region-active-p))
+ (when (eq point current-mark)
+ ;; Exchange point and mark.
+ (exchange-point-and-mark))
+ ;; Clear the state necessary to set up dragging. Don't try
+ ;; to select entire words immediately after dragging starts,
+ ;; to allow for fine grained selection inside a word.
+ (setq touch-screen-word-select-bounds nil
+ touch-screen-word-select-initial-word nil))))))
+
(global-set-key [touchscreen-hold] #'touch-screen-hold)
(global-set-key [touchscreen-drag] #'touch-screen-drag)
+(global-set-key [touchscreen-restart-drag] #'touch-screen-restart-drag)
@@ -541,8 +577,12 @@ If the fourth element of `touch-screen-current-tool' is
If the fourth element of `touch-screen-current-tool' is `held',
then the touch has been held down for some time. If motion
-happens, cancel `touch-screen-current-timer', and set the field
-to `drag'. Then, generate a `touchscreen-drag' event.
+happens, set the field to `drag'. Then, generate a
+`touchscreen-drag' event.
+
+If the fourth element of `touch-screen-current-tool' is
+`restart-drag', set the field to `drag' and generate a
+`touchscreen-drag'.
If the fourth element of `touch-screen-current-tool' is `drag',
then move point to the position of POINT."
@@ -628,6 +668,15 @@ then move point to the position of POINT."
;; `touchscreen-hold' was generated when the timeout
;; fired.
(throw 'input-event (list 'touchscreen-drag posn))))
+ ((eq what 'restart-drag)
+ (let* ((posn (cdr point)))
+ ;; Now start dragging.
+ (setcar (nthcdr 3 touch-screen-current-tool)
+ 'drag)
+ ;; Generate a (touchscreen-drag POSN) event.
+ ;; `touchscreen-restart-drag' was generated when the
+ ;; timeout fired.
+ (throw 'input-event (list 'touchscreen-drag posn))))
((eq what 'drag)
(let* ((posn (cdr point)))
;; Generate a (touchscreen-drag POSN) event.
@@ -809,7 +858,7 @@ the place of EVENT within the key sequence being translated, or
(position (cdadr event))
(window (posn-window position))
(point (posn-point position))
- binding)
+ binding tool-list)
;; Cancel the touch screen timer, if it is still there by any
;; chance.
(when touch-screen-current-timer
@@ -817,24 +866,46 @@ the place of EVENT within the key sequence being translated, or
(setq touch-screen-current-timer nil))
;; Replace any previously ongoing gesture. If POSITION has no
;; window or position, make it nil instead.
- (setq touch-screen-current-tool (and (windowp window)
- (list touchpoint window
- (posn-x-y position)
- nil position
- nil nil nil nil)))
- ;; Determine if there is a command bound to `down-mouse-1' at
- ;; the position of the tap and that command is not a command
- ;; whose functionality is replaced by the long-press
- ;; mechanism. If so, set the fourth element of
- ;; `touch-screen-current-tool' to `mouse-drag' and generate an
- ;; emulated `mouse-1' event.
- ;;
- ;; If the command in question is a keymap, use `mouse-1-menu'
- ;; instead of `mouse-drag', and don't generate a
- ;; `down-mouse-1' event immediately. Instead, wait for the
- ;; touch point to be released.
- (if (and touch-screen-current-tool
- (with-selected-window window
+ (setq tool-list (and (windowp window)
+ (list touchpoint window
+ (posn-x-y position)
+ nil position
+ nil nil nil nil))
+ touch-screen-current-tool tool-list)
+
+ ;; Select the window underneath the event as the checks below
+ ;; will look up keymaps and markers inside its buffer.
+ (save-selected-window
+ ;; Check if `touch-screen-extend-selection' is enabled, the
+ ;; tap lies on the point or the mark, and the region is
+ ;; active. If that's the case, set the fourth element of
+ ;; `touch-screen-current-tool' to `restart-drag', then
+ ;; generate a `touchscreen-restart-drag' event.
+ (when tool-list
+ ;; tool-list is always non-nil where the selected window
+ ;; matters.
+ (select-window window)
+ (when (and touch-screen-extend-selection
+ (or (eq point (point))
+ (eq point (mark)))
+ (region-active-p))
+ ;; Indicate that a drag is about to restart.
+ (setcar (nthcdr 3 tool-list) 'restart-drag)
+ ;; Generate the `restart-drag' event.
+ (throw 'input-event (list 'touchscreen-restart-drag
+ position))))
+ ;; Determine if there is a command bound to `down-mouse-1'
+ ;; at the position of the tap and that command is not a
+ ;; command whose functionality is replaced by the long-press
+ ;; mechanism. If so, set the fourth element of
+ ;; `touch-screen-current-tool' to `mouse-drag' and generate
+ ;; an emulated `mouse-1' event.
+ ;;
+ ;; If the command in question is a keymap, set that element
+ ;; to `mouse-1-menu' instead of `mouse-drag', and don't
+ ;; generate a `down-mouse-1' event immediately. Instead,
+ ;; wait for the touch point to be released.
+ (if (and tool-list
(and (setq binding
(key-binding (if prefix
(vector prefix
@@ -842,24 +913,23 @@ the place of EVENT within the key sequence being translated, or
[down-mouse-1])
t nil position))
(not (and (symbolp binding)
- (get binding 'ignored-mouse-command))))))
- (if (or (keymapp binding)
- (and (symbolp binding)
- (get binding 'mouse-1-menu-command)))
- ;; binding is a keymap, or a command that does almost
- ;; the same thing. If a `mouse-1' event is generated
- ;; after the keyboard command loop displays it as a
- ;; menu, that event could cause unwanted commands to
- ;; be run. Set what to `mouse-1-menu' instead and
- ;; wait for the up event to display the menu.
- (setcar (nthcdr 3 touch-screen-current-tool)
- 'mouse-1-menu)
- (progn (setcar (nthcdr 3 touch-screen-current-tool)
- 'mouse-drag)
- (throw 'input-event (list 'down-mouse-1 position))))
- (and point
- ;; Start the long-press timer.
- (touch-screen-handle-timeout nil)))))
+ (get binding 'ignored-mouse-command)))))
+ (if (or (keymapp binding)
+ (and (symbolp binding)
+ (get binding 'mouse-1-menu-command)))
+ ;; binding is a keymap, or a command that does
+ ;; almost the same thing. If a `mouse-1' event is
+ ;; generated after the keyboard command loop
+ ;; displays it as a menu, that event could cause
+ ;; unwanted commands to be run. Set what to
+ ;; `mouse-1-menu' instead and wait for the up event
+ ;; to display the menu.
+ (setcar (nthcdr 3 tool-list) 'mouse-1-menu)
+ (progn (setcar (nthcdr 3 tool-list) 'mouse-drag)
+ (throw 'input-event (list 'down-mouse-1 position))))
+ (and point
+ ;; Start the long-press timer.
+ (touch-screen-handle-timeout nil))))))
((eq (car event) 'touchscreen-update)
(unless touch-screen-current-tool
;; If a stray touchscreen-update event arrives (most likely
@@ -930,6 +1000,10 @@ and vertically,
where POSN is the position of the long-press or touchpoint
motion,
+ (touchscreen-restart-drag POSN)
+
+where POSN is the position of the tap,
+
(down-mouse-1 POSN)
(drag-mouse-1 POSN)
diff --git a/src/Makefile.in b/src/Makefile.in
index 36f3876f659..e818b6c1655 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -514,22 +514,9 @@ PRE_ALLOC_OBJ=@PRE_ALLOC_OBJ@
## lastfile.o on Cygwin and MinGW, empty elsewhere.
POST_ALLOC_OBJ=@POST_ALLOC_OBJ@
-## Builds using libemacs.so (Android) don't dump Emacs within this
-## Makefile, but on device. Make sure the library hash changes for
-## each change in shortlisp by linking an object that changes
-## accordingly to it.
-BUILD_COUNTER_OBJ =
-ifeq ($(XCONFIGURE),android)
-BUILD_COUNTER_OBJ = build-counter.o
-
-# This file is then compiled into build-counter.so
-build-counter.c: $(abs_top_builddir)/src/lisp.mk $(shortlisp)
- $(AM_V_GEN) $(top_srcdir)/build-aux/makecounter.sh $@
-endif
-
## List of object files that make-docfile should not be told about.
otherobj= $(TERMCAP_OBJ) $(PRE_ALLOC_OBJ) $(GMALLOC_OBJ) $(RALLOC_OBJ) \
- $(POST_ALLOC_OBJ) $(WIDGET_OBJ) $(LIBOBJS) $(BUILD_COUNTER_OBJ)
+ $(POST_ALLOC_OBJ) $(WIDGET_OBJ) $(LIBOBJS)
## All object files linked into temacs. $(VMLIMIT_OBJ) should be first.
## (On MinGW, firstfile.o should be before vm-limit.o.)
@@ -625,9 +612,11 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(PGTK_LIBS) $(LIBX_BASE) $(LIBIMAGE
## up-to-date. Although since charprop depends on bootstrap-emacs,
## and emacs depends on charprop, in practice this rule was always run
## anyway.
+ifneq ($(XCONFIGURE),android)
$(lispsource)/international/charprop.el: \
FORCE | bootstrap-emacs$(EXEEXT) $(bootstrap_pdmp)
$(MAKE) -C ../admin/unidata all EMACS="../$(bootstrap_exe)"
+endif
## We require charprop.el to exist before ucs-normalize.el is
## byte-compiled, because ucs-normalize.el needs to load 2 uni-*.el files.
@@ -782,12 +771,22 @@ top_builddir := $(old_top_builddir)/..
include $(old_top_builddir)/ndk-build/ndk-build.mk
top_builddir := $(old_top_builddir)
-libemacs.so: $(ALLOBJS) $(LIBEGNU_ARCHIVE) $(EMACSRES) \
- $(MAKE_PDUMPER_FINGERPRINT) $(NDK_BUILD_SHARED) \
- $(NDK_BUILD_STATIC) $(etc)/DOC
+## Builds using libemacs.so (Android) don't dump Emacs within this
+## Makefile, but on device. Make sure the library hash changes for
+## each change in shortlisp by linking an object that changes
+## accordingly to it.
+BUILD_COUNTER_OBJ = build-counter.o
+
+# This file is then compiled into libemacs.so
+build-counter.c: $(abs_top_builddir)/src/lisp.mk $(lisp)
+ $(AM_V_GEN) $(top_srcdir)/build-aux/makecounter.sh $@
+
+libemacs.so: $(ALLOBJS) $(BUILD_COUNTER_OBJ) $(LIBEGNU_ARCHIVE) \
+ $(EMACSRES) $(MAKE_PDUMPER_FINGERPRINT) \
+ $(NDK_BUILD_SHARED) $(NDK_BUILD_STATIC) $(etc)/DOC
$(AM_V_CCLD)$(CC) -o $@ $(ALL_CFLAGS) $(TEMACS_LDFLAGS) \
$(ANDROID_LDFLAGS) $(LDFLAGS) -shared $(ALLOBJS) \
- $(LIBEGNU_ARCHIVE) $(LIBES)
+ $(BUILD_COUNTER_OBJ) $(LIBEGNU_ARCHIVE) $(LIBES)
$(AM_V_at)$(MAKE_PDUMPER_FINGERPRINT) $@
# There is also a binary named `android-emacs' which simply calls
@@ -918,10 +917,16 @@ tags: TAGS ../lisp/TAGS $(lwlibdir)/TAGS $(lib)/TAGS
## To solve the freshness issue, in the past we tried various clever tricks,
## but now that we require GNU make, we can simply specify
## bootstrap-emacs$(EXEEXT) as an order-only prerequisite.
+##
+## bootstrap-emacs doesn't have to be built when cross-compiling
+## libemacs.so for Android, however, as the Lisp files have already
+## been compiled by the top level `src' Makefile.
+ifneq ($(XCONFIGURE),android)
%.elc: %.el | bootstrap-emacs$(EXEEXT) $(bootstrap_pdmp)
@$(MAKE) $(AM_V_NO_PD) -C ../lisp EMACS="$(bootstrap_exe)"\
THEFILE=$< $<c
+endif
ifeq ($(HAVE_NATIVE_COMP):$(NATIVE_DISABLED),yes:)
## The following rules are used only when building a source tarball
@@ -975,8 +980,10 @@ NATIVE_COMPILATION_AOT = @NATIVE_COMPILATION_AOT@
fi
endif
+ifneq ($(XCONFIGURE),android)
$(lispsource)/loaddefs.el: | bootstrap-emacs$(EXEEXT) $(bootstrap_pdmp)
$(MAKE) -C ../lisp autoloads EMACS="$(bootstrap_exe)"
+endif
## Dump an Emacs executable named bootstrap-emacs containing the
## files from loadup.el in source form.