Update Android port
* doc/lispref/commands.texi (Touchscreen Events): Describe treatment of canceled touch sequences during touch event translation. * java/org/gnu/emacs/EmacsNative.java (EmacsNative): Update JNI prototypes. * java/org/gnu/emacs/EmacsWindow.java (motionEvent): Set cancelation flag in events sent where appropriate. * lisp/touch-screen.el (touch-screen-handle-point-update): Improve treatment of horizontal scrolling near window edges. (touch-screen-handle-touch): Don't handle point up if the touch sequence has been canceled. * src/android.c (sendTouchDown, sendTouchUp, sendTouchMove): New argument `flags'. * src/androidgui.h (enum android_touch_event_flags): New enum. (struct android_touch_event): New field `flags'. * src/androidterm.c (handle_one_android_event): Report cancelation in TOUCHSCREEN_END_EVENTs. * src/keyboard.c (make_lispy_event): Fix botched merge.
This commit is contained in:
parent
46fd03a496
commit
5ff31bf36c
8 changed files with 186 additions and 90 deletions
|
@ -2061,9 +2061,11 @@ keymaps that are active at the location of the
|
|||
of a single @code{down-mouse-1} event, with subsequent
|
||||
@code{touchscreen-update} events translated to mouse motion events
|
||||
(@pxref{Motion Events}), and a final @code{touchscreen-end} event
|
||||
translated to a @code{mouse-1} or @code{drag-mouse-1} event. This is
|
||||
referred to ``simple translation'', and produces a simple
|
||||
correspondence between touchpoint motion and mouse motion.
|
||||
translated to a @code{mouse-1} or @code{drag-mouse-1} event (unless
|
||||
the @code{touchscreen-end} event indicates that the touch sequence has
|
||||
been intercepted by another program.) This is referred to ``simple
|
||||
translation'', and produces a simple correspondence between touchpoint
|
||||
motion and mouse motion.
|
||||
|
||||
@cindex @code{ignored-mouse-command}, a symbol property
|
||||
However, some commands bound to
|
||||
|
@ -2078,13 +2080,14 @@ takes place: here, Emacs processes touch screen gestures
|
|||
(@pxref{Touchscreens,,, emacs, The GNU Emacs Manual}) first, and
|
||||
finally attempts to translate touch screen events into mouse events if
|
||||
no gesture was detected prior to a closing @code{touchscreen-end}
|
||||
event and a command is bound to @code{mouse-1} at the location of that
|
||||
event. Before generating the @code{mouse-1} event, point is also set
|
||||
to the location of the @code{touchscreen-end} event, and the window
|
||||
containing the position of that event is selected, as a compromise for
|
||||
packages which assume @code{mouse-drag-region} has already set point
|
||||
to the location of any mouse click and selected the window where it
|
||||
took place.
|
||||
event (with its @var{canceled} parameter @code{nil}, as with simple
|
||||
translation) and a command is bound to @code{mouse-1} at the location
|
||||
of that event. Before generating the @code{mouse-1} event, point is
|
||||
also set to the location of the @code{touchscreen-end} event, and the
|
||||
window containing the position of that event is selected, as a
|
||||
compromise for packages which assume @code{mouse-drag-region} has
|
||||
already set point to the location of any mouse click and selected the
|
||||
window where it took place.
|
||||
|
||||
To prevent unwanted @code{mouse-1} events arriving after a mouse menu
|
||||
is dismissed (@pxref{Mouse Menus}), Emacs also avoids simple
|
||||
|
|
|
@ -142,15 +142,18 @@ public static native long sendButtonRelease (short window, int x, int y,
|
|||
|
||||
/* Send an ANDROID_TOUCH_DOWN event. */
|
||||
public static native long sendTouchDown (short window, int x, int y,
|
||||
long time, int pointerID);
|
||||
long time, int pointerID,
|
||||
int flags);
|
||||
|
||||
/* Send an ANDROID_TOUCH_UP event. */
|
||||
public static native long sendTouchUp (short window, int x, int y,
|
||||
long time, int pointerID);
|
||||
long time, int pointerID,
|
||||
int flags);
|
||||
|
||||
/* Send an ANDROID_TOUCH_MOVE event. */
|
||||
public static native long sendTouchMove (short window, int x, int y,
|
||||
long time, int pointerID);
|
||||
long time, int pointerID,
|
||||
int flags);
|
||||
|
||||
/* Send an ANDROID_WHEEL event. */
|
||||
public static native long sendWheel (short window, int x, int y,
|
||||
|
|
|
@ -1025,23 +1025,30 @@ private static class Coordinate
|
|||
/* Touch down event. */
|
||||
EmacsNative.sendTouchDown (this.handle, coordinate.x,
|
||||
coordinate.y, time,
|
||||
coordinate.id);
|
||||
coordinate.id, 0);
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
/* Touch up event. Android documentation says ACTION_CANCEL
|
||||
should be treated as more or less equivalent to ACTION_UP,
|
||||
so that is what is done here. */
|
||||
/* Touch up event. */
|
||||
EmacsNative.sendTouchUp (this.handle, coordinate.x,
|
||||
coordinate.y, time, coordinate.id);
|
||||
coordinate.y, time,
|
||||
coordinate.id, 0);
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
/* Touch sequence cancellation event. */
|
||||
EmacsNative.sendTouchUp (this.handle, coordinate.x,
|
||||
coordinate.y, time,
|
||||
coordinate.id,
|
||||
1 /* ANDROID_TOUCH_SEQUENCE_CANCELED */);
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
/* Pointer motion event. */
|
||||
EmacsNative.sendTouchMove (this.handle, coordinate.x,
|
||||
coordinate.y, time, coordinate.id);
|
||||
coordinate.y, time,
|
||||
coordinate.id, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -548,11 +548,26 @@ then move point to the position of POINT."
|
|||
;; WINDOW.
|
||||
(relative-xy
|
||||
(touch-screen-relative-xy posn window))
|
||||
(col (and (eq (posn-area posn) 'text-area)
|
||||
(car (posn-col-row posn
|
||||
(posn-window posn)))))
|
||||
;; Don't start horizontal scrolling if the touch
|
||||
;; point originated within two columns of the window
|
||||
;; edges, as systems like Android use those two
|
||||
;; columns to implement gesture navigation.
|
||||
(diff-x-eligible
|
||||
(and col (> (car col) 2)
|
||||
(< (car col) (- (window-width window) 2))))
|
||||
(diff-x (- (car last-posn) (car relative-xy)))
|
||||
(diff-y (- (cdr last-posn) (cdr relative-xy))))
|
||||
;; Decide whether or not to start scrolling.
|
||||
(when (or (> diff-y 10) (> diff-x 10)
|
||||
(< diff-y -10) (< diff-x -10))
|
||||
;; Decide whether or not to start scrolling. Make the
|
||||
;; hscrolling threshold slightly larger than the vertical
|
||||
;; scrolling threshold, to compensate better for
|
||||
;; Android-style gesture navigation.
|
||||
(when (or (> diff-y 10) (and diff-x-eligible
|
||||
(> diff-x 20))
|
||||
(< diff-y -10) (and diff-x-eligible
|
||||
(< diff-x -20)))
|
||||
(setcar (nthcdr 3 touch-screen-current-tool)
|
||||
'scroll)
|
||||
(setcar (nthcdr 2 touch-screen-current-tool)
|
||||
|
@ -852,7 +867,11 @@ the place of EVENT within the key sequence being translated, or
|
|||
(cancel-timer touch-screen-current-timer)
|
||||
(setq touch-screen-current-timer nil))
|
||||
(unwind-protect
|
||||
(touch-screen-handle-point-up (cadr event) prefix)
|
||||
;; Don't perform any actions associated with releasing the
|
||||
;; tool if the touch sequence was intercepted by another
|
||||
;; program.
|
||||
(unless (caddr event)
|
||||
(touch-screen-handle-point-up (cadr event) prefix))
|
||||
;; Make sure the tool list is cleared even if
|
||||
;; `touch-screen-handle-point-up' throws.
|
||||
(setq touch-screen-current-tool nil)))
|
||||
|
|
|
@ -2870,7 +2870,8 @@ NATIVE_NAME (sendButtonRelease) (JNIEnv *env, jobject object,
|
|||
JNIEXPORT jlong JNICALL
|
||||
NATIVE_NAME (sendTouchDown) (JNIEnv *env, jobject object,
|
||||
jshort window, jint x, jint y,
|
||||
jlong time, jint pointer_id)
|
||||
jlong time, jint pointer_id,
|
||||
jint flags)
|
||||
{
|
||||
JNI_STACK_ALIGNMENT_PROLOGUE;
|
||||
|
||||
|
@ -2883,6 +2884,7 @@ NATIVE_NAME (sendTouchDown) (JNIEnv *env, jobject object,
|
|||
event.touch.y = y;
|
||||
event.touch.time = time;
|
||||
event.touch.pointer_id = pointer_id;
|
||||
event.touch.flags = flags;
|
||||
|
||||
android_write_event (&event);
|
||||
return event_serial;
|
||||
|
@ -2891,7 +2893,8 @@ NATIVE_NAME (sendTouchDown) (JNIEnv *env, jobject object,
|
|||
JNIEXPORT jlong JNICALL
|
||||
NATIVE_NAME (sendTouchUp) (JNIEnv *env, jobject object,
|
||||
jshort window, jint x, jint y,
|
||||
jlong time, jint pointer_id)
|
||||
jlong time, jint pointer_id,
|
||||
jint flags)
|
||||
{
|
||||
JNI_STACK_ALIGNMENT_PROLOGUE;
|
||||
|
||||
|
@ -2904,6 +2907,7 @@ NATIVE_NAME (sendTouchUp) (JNIEnv *env, jobject object,
|
|||
event.touch.y = y;
|
||||
event.touch.time = time;
|
||||
event.touch.pointer_id = pointer_id;
|
||||
event.touch.flags = flags;
|
||||
|
||||
android_write_event (&event);
|
||||
return event_serial;
|
||||
|
@ -2912,7 +2916,8 @@ NATIVE_NAME (sendTouchUp) (JNIEnv *env, jobject object,
|
|||
JNIEXPORT jlong JNICALL
|
||||
NATIVE_NAME (sendTouchMove) (JNIEnv *env, jobject object,
|
||||
jshort window, jint x, jint y,
|
||||
jlong time, jint pointer_id)
|
||||
jlong time, jint pointer_id,
|
||||
jint flags)
|
||||
{
|
||||
JNI_STACK_ALIGNMENT_PROLOGUE;
|
||||
|
||||
|
@ -2925,6 +2930,7 @@ NATIVE_NAME (sendTouchMove) (JNIEnv *env, jobject object,
|
|||
event.touch.y = y;
|
||||
event.touch.time = time;
|
||||
event.touch.pointer_id = pointer_id;
|
||||
event.touch.flags = flags;
|
||||
|
||||
android_write_event (&event);
|
||||
return event_serial;
|
||||
|
|
|
@ -365,6 +365,13 @@ struct android_expose_event
|
|||
int width, height;
|
||||
};
|
||||
|
||||
enum android_touch_event_flags
|
||||
{
|
||||
/* This touch sequence has been intercepted by the WM (probably
|
||||
for back gesture navigation or some such.) */
|
||||
ANDROID_TOUCH_SEQUENCE_CANCELED = 1,
|
||||
};
|
||||
|
||||
struct android_touch_event
|
||||
{
|
||||
/* Type of the event. */
|
||||
|
@ -384,6 +391,9 @@ struct android_touch_event
|
|||
|
||||
/* Index of the pointer being tracked. */
|
||||
unsigned int pointer_id;
|
||||
|
||||
/* Flags associated with this event. */
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct android_wheel_event
|
||||
|
|
|
@ -1511,6 +1511,11 @@ handle_one_android_event (struct android_display_info *dpyinfo,
|
|||
inev.ie.kind = TOUCHSCREEN_END_EVENT;
|
||||
inev.ie.timestamp = event->touch.time;
|
||||
|
||||
/* Report whether the sequence has been canceled. */
|
||||
|
||||
if (event->touch.flags & ANDROID_TOUCH_SEQUENCE_CANCELED)
|
||||
inev.ie.modifiers = 1;
|
||||
|
||||
XSETFRAME (inev.ie.frame_or_window, any);
|
||||
XSETINT (inev.ie.x, event->touch.x);
|
||||
XSETINT (inev.ie.y, event->touch.y);
|
||||
|
|
169
src/keyboard.c
169
src/keyboard.c
|
@ -6560,11 +6560,10 @@ make_lispy_event (struct input_event *event)
|
|||
{
|
||||
Lisp_Object x, y, id, position;
|
||||
struct frame *f;
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
int tab_bar_item;
|
||||
bool close;
|
||||
#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
|
||||
int column, row, dummy;
|
||||
#endif /* defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR */
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
|
||||
f = XFRAME (event->frame_or_window);
|
||||
id = event->arg;
|
||||
|
@ -6572,63 +6571,13 @@ make_lispy_event (struct input_event *event)
|
|||
y = event->y;
|
||||
|
||||
#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
|
||||
if (event->kind == TOUCHSCREEN_BEGIN_EVENT
|
||||
&& coords_in_menu_bar_window (f, XFIXNUM (x), XFIXNUM (y)))
|
||||
if (coords_in_menu_bar_window (f, XFIXNUM (x), XFIXNUM (y)))
|
||||
{
|
||||
/* If the tap began in the menu bar window, then save the
|
||||
id. */
|
||||
menu_bar_touch_id = id;
|
||||
return Qnil;
|
||||
}
|
||||
else if (event->kind == TOUCHSCREEN_END_EVENT
|
||||
&& EQ (menu_bar_touch_id, id))
|
||||
{
|
||||
/* This touch should activate the menu bar. Generate the
|
||||
menu bar event. */
|
||||
menu_bar_touch_id = Qnil;
|
||||
|
||||
if (!NILP (f->menu_bar_window))
|
||||
{
|
||||
x_y_to_hpos_vpos (XWINDOW (f->menu_bar_window), XFIXNUM (x),
|
||||
XFIXNUM (y), &column, &row, NULL, NULL,
|
||||
&dummy);
|
||||
|
||||
if (row >= 0 && row < FRAME_MENU_BAR_LINES (f))
|
||||
{
|
||||
Lisp_Object items, item;
|
||||
|
||||
/* Find the menu bar item under `column'. */
|
||||
item = Qnil;
|
||||
items = FRAME_MENU_BAR_ITEMS (f);
|
||||
for (i = 0; i < ASIZE (items); i += 4)
|
||||
{
|
||||
Lisp_Object pos, string;
|
||||
string = AREF (items, i + 1);
|
||||
pos = AREF (items, i + 3);
|
||||
if (NILP (string))
|
||||
break;
|
||||
if (column >= XFIXNUM (pos)
|
||||
&& column < XFIXNUM (pos) + SCHARS (string))
|
||||
{
|
||||
item = AREF (items, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* ELisp manual 2.4b says (x y) are window
|
||||
relative but code says they are
|
||||
frame-relative. */
|
||||
position = list4 (event->frame_or_window,
|
||||
Qmenu_bar,
|
||||
Fcons (event->x, event->y),
|
||||
INT_TO_INTEGER (event->timestamp));
|
||||
|
||||
return list2 (item, position);
|
||||
}
|
||||
}
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
#endif /* defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR */
|
||||
|
||||
position = make_lispy_position (f, x, y, event->timestamp);
|
||||
|
@ -6676,10 +6625,7 @@ make_lispy_event (struct input_event *event)
|
|||
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
|
||||
return list2 (((event->kind
|
||||
== TOUCHSCREEN_BEGIN_EVENT)
|
||||
? Qtouchscreen_begin
|
||||
: Qtouchscreen_end),
|
||||
return list2 (Qtouchscreen_begin,
|
||||
Fcons (id, position));
|
||||
}
|
||||
|
||||
|
@ -6687,18 +6633,115 @@ make_lispy_event (struct input_event *event)
|
|||
{
|
||||
Lisp_Object x, y, id, position;
|
||||
struct frame *f = XFRAME (event->frame_or_window);
|
||||
#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
|
||||
int column, row, dummy;
|
||||
#endif /* defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR */
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
int tab_bar_item;
|
||||
bool close;
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
|
||||
id = event->arg;
|
||||
x = event->x;
|
||||
y = event->y;
|
||||
|
||||
#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
|
||||
if (EQ (menu_bar_touch_id, id))
|
||||
{
|
||||
/* This touch should activate the menu bar. Generate the
|
||||
menu bar event. */
|
||||
menu_bar_touch_id = Qnil;
|
||||
|
||||
if (!NILP (f->menu_bar_window))
|
||||
{
|
||||
x_y_to_hpos_vpos (XWINDOW (f->menu_bar_window), XFIXNUM (x),
|
||||
XFIXNUM (y), &column, &row, NULL, NULL,
|
||||
&dummy);
|
||||
|
||||
if (row >= 0 && row < FRAME_MENU_BAR_LINES (f))
|
||||
{
|
||||
Lisp_Object items, item;
|
||||
|
||||
/* Find the menu bar item under `column'. */
|
||||
item = Qnil;
|
||||
items = FRAME_MENU_BAR_ITEMS (f);
|
||||
for (i = 0; i < ASIZE (items); i += 4)
|
||||
{
|
||||
Lisp_Object pos, string;
|
||||
string = AREF (items, i + 1);
|
||||
pos = AREF (items, i + 3);
|
||||
if (NILP (string))
|
||||
break;
|
||||
if (column >= XFIXNUM (pos)
|
||||
&& column < XFIXNUM (pos) + SCHARS (string))
|
||||
{
|
||||
item = AREF (items, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* ELisp manual 2.4b says (x y) are window
|
||||
relative but code says they are
|
||||
frame-relative. */
|
||||
position = list4 (event->frame_or_window,
|
||||
Qmenu_bar,
|
||||
Fcons (event->x, event->y),
|
||||
INT_TO_INTEGER (event->timestamp));
|
||||
|
||||
return list2 (item, position);
|
||||
}
|
||||
}
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
#endif /* defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR */
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
|
||||
/* Now check if POSITION lies on the tab bar. If so, look up
|
||||
the corresponding tab bar item's propertized string as the
|
||||
OBJECT. */
|
||||
|
||||
if (coords_in_tab_bar_window (f, XFIXNUM (event->x),
|
||||
XFIXNUM (event->y))
|
||||
/* `get_tab_bar_item_kbd' returns 0 if the item was
|
||||
previously highlighted, 1 otherwise, and -1 if there is
|
||||
no tab bar item. */
|
||||
&& get_tab_bar_item_kbd (f, XFIXNUM (event->x),
|
||||
XFIXNUM (event->y), &tab_bar_item,
|
||||
&close) >= 0)
|
||||
{
|
||||
/* First, obtain the propertized string. */
|
||||
x = Fcopy_sequence (AREF (f->tab_bar_items,
|
||||
(tab_bar_item
|
||||
+ TAB_BAR_ITEM_CAPTION)));
|
||||
|
||||
/* Next, add the key binding. */
|
||||
AUTO_LIST2 (y, Qmenu_item, list3 (AREF (f->tab_bar_items,
|
||||
(tab_bar_item
|
||||
+ TAB_BAR_ITEM_KEY)),
|
||||
AREF (f->tab_bar_items,
|
||||
(tab_bar_item
|
||||
+ TAB_BAR_ITEM_BINDING)),
|
||||
close ? Qt : Qnil));
|
||||
|
||||
/* And add the new properties to the propertized string. */
|
||||
Fadd_text_properties (make_fixnum (0),
|
||||
make_fixnum (SCHARS (x)),
|
||||
y, x);
|
||||
|
||||
/* Set the position to 0. */
|
||||
x = Fcons (x, make_fixnum (0));
|
||||
|
||||
/* Finally, add the OBJECT. */
|
||||
position = nconc2 (position, Fcons (x, Qnil));
|
||||
}
|
||||
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
|
||||
position = make_lispy_position (f, x, y, event->timestamp);
|
||||
|
||||
return list3 (((event->kind
|
||||
== TOUCHSCREEN_BEGIN_EVENT)
|
||||
? Qtouchscreen_begin
|
||||
: Qtouchscreen_end),
|
||||
Fcons (id, position),
|
||||
return list3 (Qtouchscreen_end, Fcons (id, position),
|
||||
event->modifiers ? Qt : Qnil);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue