Update Android port

* build-aux/makecounter.sh (curcount): Rename `counter' to
`emacs_shortlisp_counter'.
* doc/emacs/input.texi (Touchscreens): Document
`touch-screen-extend-selection'.
* doc/lispref/commands.texi (Touchscreen Events): Document
`touchscreen-restart-drag'.
* lisp/touch-screen.el (touch-screen-extend-selection): New user
option.
(touch-screen-restart-drag): New function.
(touch-screen-handle-point-update): Handle `restart-drag'
gestures.
(touch-screen-handle-touch): Check if the prerequisites for
extending a previous drag gesture are met, and generate such
events if so.
(touch-screen-translate-touch): Update doc string.
* src/Makefile.in (otherobj): Remove BUILD_COUNTER_OBJ.
($(lispsource)/international/charprop.el):
(%.elc): Don't depend on bootstrap-emacs if cross configuring
for Android.
(libemacs.so): Directly depend on and link with
BUILD_COUNTER_OBJ.
This commit is contained in:
Po Lu 2023-07-19 12:46:02 +08:00
parent 69828fba28
commit db48c88e7e
5 changed files with 160 additions and 61 deletions

View file

@ -39,5 +39,5 @@ cat > $1 <<EOF
#ifdef EXPORT
EXPORT
#endif /* EXPORT */
int counter = $curcount;
int emacs_shortlisp_counter = $curcount;
EOF

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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.