diff options
author | Alan Third <alan@idiocy.org> | 2017-06-24 09:36:03 +0100 |
---|---|---|
committer | Alan Third <alan@idiocy.org> | 2017-06-25 23:12:50 +0100 |
commit | b39042174d581dadef95cadd6ae28640f5cafc07 (patch) | |
tree | 45ae9cc1d511302cb108d52eeef6f2bd4c909cd4 | |
parent | 1886246f6f40b8c376467f71605141035959cae0 (diff) | |
download | emacs-b39042174d581dadef95cadd6ae28640f5cafc07.tar.gz |
Add touch events
* src/keyboard.c (syms_of_keyboard): Add `Qtouch_gesture' and
initialize `touch_syms'.
(touch_names): New variable containing touch gesture names.
(make_lispy_event): Handle new touch gestures.
* src/nsterm.m (EmacsView::mouseDown) [NS_IMPL_COCOA]: Use
touch-based scrolling instead of using mousewheel compatibility.
(EmacsView::magnifyWithEvent) [NS_IMPL_COCOA]: New function.
(EmacsView::swipeWithEvent) [NS_IMPL_COCOA]: New function.
(EmacsView::rotateWithEvent) [NS_IMPL_COCOA]: New function.
src/termhooks.h (event_kind): New touch event types.
-rw-r--r-- | src/keyboard.c | 109 | ||||
-rw-r--r-- | src/nsterm.m | 132 | ||||
-rw-r--r-- | src/termhooks.h | 31 |
3 files changed, 259 insertions, 13 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index 9e90899c569..747776f73dd 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -4557,6 +4557,7 @@ static Lisp_Object accent_key_syms; static Lisp_Object func_key_syms; static Lisp_Object mouse_syms; static Lisp_Object wheel_syms; +static Lisp_Object touch_syms; static Lisp_Object drag_n_drop_syms; /* This is a list of keysym codes for special "accent" characters. @@ -5107,6 +5108,12 @@ static const char *const lispy_wheel_names[] = "wheel-up", "wheel-down", "wheel-left", "wheel-right" }; +static const char *const touch_names[] = +{ + "touch-scroll", "touch-pinch", "touch-rotate", "touch-swipe-up", + "touch-swipe-down", "touch-swipe-left", "touch-swipe-right" +}; + /* drag-n-drop events are generated when a set of selected files are dragged from another application and dropped onto an Emacs window. */ static const char *const lispy_drag_n_drop_names[] = @@ -6025,6 +6032,105 @@ make_lispy_event (struct input_event *event) return list3 (head, position, files); } + case TOUCH_SCROLL_EVENT: + { + Lisp_Object position; + Lisp_Object head; + Lisp_Object deltas = event->arg; + struct frame *f = XFRAME (event->frame_or_window); + + /* Ignore touch events that were made on frame that have + been deleted. */ + if (! FRAME_LIVE_P (f)) + return Qnil; + + position = make_lispy_position (f, event->x, event->y, + event->timestamp); + + head = modify_event_symbol (0, event->modifiers, Qtouch_gesture, Qnil, + touch_names, &touch_syms, ASIZE (touch_syms)); + + return list3 (head, position, deltas); + } + + case TOUCH_PINCH_EVENT: + { + Lisp_Object position; + Lisp_Object head; + Lisp_Object delta = event->arg; + struct frame *f = XFRAME (event->frame_or_window); + + /* Ignore touch events that were made on frame that have + been deleted. */ + if (! FRAME_LIVE_P (f)) + return Qnil; + + position = make_lispy_position (f, event->x, event->y, + event->timestamp); + + head = modify_event_symbol (1, event->modifiers, Qtouch_gesture, Qnil, + touch_names, &touch_syms, ASIZE (touch_syms)); + + return list3 (head, position, delta); + } + + case TOUCH_SWIPE_UP_EVENT: + case TOUCH_SWIPE_DOWN_EVENT: + case TOUCH_SWIPE_LEFT_EVENT: + case TOUCH_SWIPE_RIGHT_EVENT: + { + Lisp_Object position; + Lisp_Object head; + struct frame *f = XFRAME (event->frame_or_window); + int symbol_num; + + /* Ignore touch events that were made on frame that have + been deleted. */ + if (! FRAME_LIVE_P (f)) + return Qnil; + + position = make_lispy_position (f, event->x, event->y, + event->timestamp); + + switch (event->kind) + { + case TOUCH_SWIPE_UP_EVENT: + symbol_num = 3; + case TOUCH_SWIPE_DOWN_EVENT: + symbol_num = 4; + case TOUCH_SWIPE_LEFT_EVENT: + symbol_num = 5; + case TOUCH_SWIPE_RIGHT_EVENT: + symbol_num = 6; + } + + head = modify_event_symbol (symbol_num, event->modifiers, Qtouch_gesture, Qnil, + touch_names, &touch_syms, ASIZE (touch_syms)); + + return list2 (head, position); + } + + case TOUCH_ROTATE_EVENT: + { + Lisp_Object position; + Lisp_Object head; + Lisp_Object rotation = event->arg; + struct frame *f = XFRAME (event->frame_or_window); + + /* Ignore touch events that were made on frame that have + been deleted. */ + if (! FRAME_LIVE_P (f)) + return Qnil; + + position = make_lispy_position (f, event->x, event->y, + event->timestamp); + + head = modify_event_symbol (2, event->modifiers, Qtouch_gesture, Qnil, + touch_names, &touch_syms, ASIZE (touch_syms)); + + return list3 (head, position, rotation); + } + #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \ || defined (HAVE_NS) || defined (USE_GTK) case MENU_BAR_EVENT: @@ -11079,6 +11185,7 @@ syms_of_keyboard (void) /* The values of Qevent_kind properties. */ DEFSYM (Qmouse_click, "mouse-click"); + DEFSYM (Qtouch_gesture, "touch-gesture"); DEFSYM (Qdrag_n_drop, "drag-n-drop"); DEFSYM (Qsave_session, "save-session"); @@ -11227,6 +11334,8 @@ syms_of_keyboard (void) wheel_syms = Fmake_vector (make_number (ARRAYELTS (lispy_wheel_names)), Qnil); staticpro (&wheel_syms); + touch_syms = Fmake_vector (make_number (7), Qnil); + staticpro (&touch_syms); { int i; diff --git a/src/nsterm.m b/src/nsterm.m index e05dbf45fbc..f9710d573d6 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -6374,24 +6374,41 @@ not_in_argv (NSString *arg) if ([theEvent type] == NSEventTypeScrollWheel) { - CGFloat delta = [theEvent deltaY]; - /* Mac notebooks send wheel events w/delta =0 when trackpad scrolling */ - if (delta == 0) +#ifdef NS_IMPL_COCOA + if ([theEvent respondsToSelector: @selector(hasPreciseScrollingDeltas)] + && [theEvent hasPreciseScrollingDeltas]) + { + Lisp_Object dx, dy; + dx = make_float ([theEvent scrollingDeltaX]); + dy = make_float ([theEvent scrollingDeltaY]); + + emacs_event->kind = TOUCH_SCROLL_EVENT; + emacs_event->arg = list2 (dx, dy); + } + else { - delta = [theEvent deltaX]; +#endif + CGFloat delta = [theEvent deltaY]; + /* Mac notebooks send wheel events w/delta =0 when trackpad scrolling */ if (delta == 0) { - NSTRACE_MSG ("deltaIsZero"); - return; + delta = [theEvent deltaX]; + if (delta == 0) + { + NSTRACE_MSG ("deltaIsZero"); + return; + } + emacs_event->kind = HORIZ_WHEEL_EVENT; } - emacs_event->kind = HORIZ_WHEEL_EVENT; - } - else - emacs_event->kind = WHEEL_EVENT; + else + emacs_event->kind = WHEEL_EVENT; - emacs_event->code = 0; - emacs_event->modifiers = EV_MODIFIERS (theEvent) | - ((delta > 0) ? up_modifier : down_modifier); + emacs_event->code = 0; + emacs_event->modifiers = EV_MODIFIERS (theEvent) | + ((delta > 0) ? up_modifier : down_modifier); +#ifdef NS_IMPL_COCOA + } +#endif } else { @@ -6537,6 +6554,95 @@ not_in_argv (NSString *arg) } +#ifdef NS_IMPL_COCOA +/* GNUstep doesn't support touch gestures yet. */ + +- (void)magnifyWithEvent: (NSEvent *) e +{ + struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe); + NSPoint p = [self convertPoint: [e locationInWindow] fromView: nil]; + Lisp_Object delta; + + NSTRACE ("[EmacsView magnifyWithEvent:]"); + + [self deleteWorkingText]; + + if (!emacs_event) + return; + + dpyinfo->last_mouse_frame = emacsframe; + + delta = make_float ([e magnification] * 25); + + emacs_event->kind = TOUCH_PINCH_EVENT; + emacs_event->arg = delta; + emacs_event->modifiers = EV_MODIFIERS (e) + | EV_UDMODIFIERS (e); + + XSETINT (emacs_event->x, lrint (p.x)); + XSETINT (emacs_event->y, lrint (p.y)); + EV_TRAILER (e); +} + + +- (void)swipeWithEvent: (NSEvent *) e +{ + struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe); + NSPoint p = [self convertPoint: [e locationInWindow] fromView: nil]; + CGFloat dx = [e deltaX]; + CGFloat dy = [e deltaY]; + + NSTRACE ("[EmacsView swipeWithEvent:]"); + + [self deleteWorkingText]; + + if (!emacs_event) + return; + + dpyinfo->last_mouse_frame = emacsframe; + + if (dx != 0) + emacs_event->kind = (dx > 0) ? TOUCH_SWIPE_LEFT_EVENT : TOUCH_SWIPE_RIGHT_EVENT; + else if (dy != 0) + emacs_event->kind = (dy > 0) ? TOUCH_SWIPE_UP_EVENT : TOUCH_SWIPE_DOWN_EVENT; + else + return; /* No swipe direction detected. */ + + emacs_event->modifiers = EV_MODIFIERS (e) + | EV_UDMODIFIERS (e); + + XSETINT (emacs_event->x, lrint (p.x)); + XSETINT (emacs_event->y, lrint (p.y)); + EV_TRAILER (e); +} + + +- (void)rotateWithEvent: (NSEvent *) e +{ + struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe); + NSPoint p = [self convertPoint: [e locationInWindow] fromView: nil]; + + NSTRACE ("[EmacsView rotateWithEvent:]"); + + [self deleteWorkingText]; + + if (!emacs_event) + return; + + dpyinfo->last_mouse_frame = emacsframe; + + emacs_event->kind = TOUCH_ROTATE_EVENT; + emacs_event->arg = make_float([e rotation]);; + emacs_event->modifiers = EV_MODIFIERS (e) + | EV_UDMODIFIERS (e); + + XSETINT (emacs_event->x, lrint (p.x)); + XSETINT (emacs_event->y, lrint (p.y)); + EV_TRAILER (e); +} +#endif /* NS_IMPL_COCOA */ + + - (BOOL)windowShouldClose: (id)sender { NSEvent *e =[[self window] currentEvent]; diff --git a/src/termhooks.h b/src/termhooks.h index 14ec397346a..08f6884da44 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -120,6 +120,37 @@ enum event_kind HORIZ_WHEEL_EVENT, /* A wheel event generated by a second horizontal wheel that is present on some mice. See WHEEL_EVENT. */ + TOUCH_SCROLL_EVENT, /* Touch scroll event generated by a + touchpad or touch screen. + .modifiers holds the state of any + modifier keys. + .x and .y contain the mouse + position. + .arg holds a list in the form: + (delta-x delta-y). */ + TOUCH_PINCH_EVENT, /* Touch pinch event generated by a + touchpad or touch screen. + .modifiers holds the state of any + modifier keys. + .x and .y contain the mouse + position. + .arg holds the pinch delta as a float. */ + TOUCH_ROTATE_EVENT, /* Touch rotate event generated by a + touchpad or touch screen. + .modifiers holds the state of any + modifier keys. + .x and .y contain the mouse + position. + .arg holds the rotation delta as a + float. */ + /* The following four events are touch swipe events generated by a + touchpad or touchscreen. + .modifiers holds the state of any modifier keys. + .x and .y contain the mouse position. */ + TOUCH_SWIPE_UP_EVENT, + TOUCH_SWIPE_DOWN_EVENT, + TOUCH_SWIPE_LEFT_EVENT, + TOUCH_SWIPE_RIGHT_EVENT, #ifdef HAVE_NTGUI LANGUAGE_CHANGE_EVENT, /* A LANGUAGE_CHANGE_EVENT is generated when HAVE_NTGUI or on Mac OS |