diff options
-rwxr-xr-x | build-aux/makecounter.sh | 2 | ||||
-rw-r--r-- | doc/emacs/input.texi | 9 | ||||
-rw-r--r-- | doc/lispref/commands.texi | 15 | ||||
-rw-r--r-- | lisp/touch-screen.el | 152 | ||||
-rw-r--r-- | src/Makefile.in | 43 |
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. |