diff options
author | Charles A. Roelli <charles@aurox.ch> | 2017-05-18 21:31:46 +0200 |
---|---|---|
committer | Alan Third <alan@idiocy.org> | 2017-05-21 00:09:41 +0100 |
commit | 7e5a8cdceb408077df78b1ea810b1f5d4657303d (patch) | |
tree | 0b8ec76811bc1e66aa3fbfa5ad594a3e6cbb302a | |
parent | c969b3997168de2bbe781fbcb08b67b15eddc02d (diff) | |
download | emacs-7e5a8cdceb408077df78b1ea810b1f5d4657303d.tar.gz |
Fix macOS mouse movement
* lisp/frame.el (ns-set-mouse-absolute-pixel-position): New
function (Lisp).
(set-mouse-absolute-pixel-position): Change it to call
`ns-set-mouse-absolute-pixel-position' on macOS.
* src/nsfns.m (Fns_set_mouse_absolute_pixel_position): New
function.
* src/nsterm.h (NS_PARENT_WINDOW_TOP_POS): Use the primary
screen's height as a base for calculating global coordinates.
* src/nsterm.m (frame_set_mouse_pixel_position): Fix it in macOS.
* test/lisp/mouse-tests.el (bug26816-mouse-frame-movement): Test
movement of mouse relative to frame.
-rw-r--r-- | etc/NEWS | 3 | ||||
-rw-r--r-- | lisp/frame.el | 3 | ||||
-rw-r--r-- | src/nsfns.m | 39 | ||||
-rw-r--r-- | src/nsterm.h | 2 | ||||
-rw-r--r-- | src/nsterm.m | 14 | ||||
-rw-r--r-- | test/lisp/mouse-tests.el | 9 |
6 files changed, 62 insertions, 8 deletions
@@ -1321,6 +1321,9 @@ This is in contrast to the default action on POSIX Systems, where it causes the receiving process to terminate with a core dump if no debugger has been attached to it. +** `set-mouse-position' and `set-mouse-absolute-pixel-position' work +on macOS. + ---------------------------------------------------------------------- This file is part of GNU Emacs. diff --git a/lisp/frame.el b/lisp/frame.el index 05db8cf6fd4..02871e0551d 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -1465,6 +1465,7 @@ position (0, 0) of the selected frame's terminal." (t (cons 0 0))))) +(declare-function ns-set-mouse-absolute-pixel-position "nsfns.m" (x y)) (declare-function w32-set-mouse-absolute-pixel-position "w32fns.c" (x y)) (declare-function x-set-mouse-absolute-pixel-position "xfns.c" (x y)) @@ -1474,6 +1475,8 @@ The coordinates X and Y are interpreted in pixels relative to a position (0, 0) of the selected frame's terminal." (let ((frame-type (framep-on-display))) (cond + ((eq frame-type 'ns) + (ns-set-mouse-absolute-pixel-position x y)) ((eq frame-type 'x) (x-set-mouse-absolute-pixel-position x y)) ((eq frame-type 'w32) diff --git a/src/nsfns.m b/src/nsfns.m index 04565a99bb7..a815ce656cb 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -3066,6 +3066,44 @@ menu bar or tool bar of FRAME. */) : Qnative_edges)); } +DEFUN ("ns-set-mouse-absolute-pixel-position", + Fns_set_mouse_absolute_pixel_position, + Sns_set_mouse_absolute_pixel_position, 2, 2, 0, + doc: /* Move mouse pointer to absolute pixel position (X, Y). +The coordinates X and Y are interpreted in pixels relative to a position +\(0, 0) of the selected frame's display. */) + (Lisp_Object x, Lisp_Object y) +{ + struct frame *f = SELECTED_FRAME (); + EmacsView *view = FRAME_NS_VIEW (f); + NSScreen *screen = [[view window] screen]; + NSRect screen_frame = [screen frame]; + int mouse_x, mouse_y; + + NSScreen *primary_screen = [[NSScreen screens] objectAtIndex:0]; + NSRect primary_screen_frame = [primary_screen frame]; + CGFloat primary_screen_height = primary_screen_frame.size.height; + + if (FRAME_INITIAL_P (f) || !FRAME_NS_P (f)) + return Qnil; + + CHECK_TYPE_RANGED_INTEGER (int, x); + CHECK_TYPE_RANGED_INTEGER (int, y); + + mouse_x = screen_frame.origin.x + XINT (x); + + if (screen == primary_screen) + mouse_y = screen_frame.origin.y + XINT (y); + else + mouse_y = (primary_screen_height - screen_frame.size.height + - screen_frame.origin.y) + XINT (y); + + CGPoint mouse_pos = CGPointMake(mouse_x, mouse_y); + CGWarpMouseCursorPosition (mouse_pos); + + return Qnil; +} + /* ========================================================================== Class implementations @@ -3254,6 +3292,7 @@ be used as the image of the icon representing the frame. */); defsubr (&Sns_frame_edges); defsubr (&Sns_frame_list_z_order); defsubr (&Sns_frame_restack); + defsubr (&Sns_set_mouse_absolute_pixel_position); defsubr (&Sx_display_mm_width); defsubr (&Sx_display_mm_height); defsubr (&Sx_display_screens); diff --git a/src/nsterm.h b/src/nsterm.h index 9285178d190..ac339bf4792 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -1087,7 +1087,7 @@ struct x_output ? ([[FRAME_NS_VIEW (f) window] parentWindow].frame.origin.y \ + [[FRAME_NS_VIEW (f) window] parentWindow].frame.size.height \ - FRAME_NS_TITLEBAR_HEIGHT (FRAME_PARENT_FRAME (f))) \ - : [[[FRAME_NS_VIEW (f) window] screen] frame].size.height) + : [[[NSScreen screens] objectAtIndex: 0] frame].size.height) #define FRAME_NS_FONT_TABLE(f) (FRAME_DISPLAY_INFO (f)->font_table) diff --git a/src/nsterm.m b/src/nsterm.m index c22c5a70baa..a7ab73b63e3 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -2321,14 +2321,14 @@ frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y) -------------------------------------------------------------------------- */ { NSTRACE ("frame_set_mouse_pixel_position"); - ns_raise_frame (f); -#if 0 - /* FIXME: this does not work, and what about GNUstep? */ + + /* FIXME: what about GNUstep? */ #ifdef NS_IMPL_COCOA - [FRAME_NS_VIEW (f) lockFocus]; - PSsetmouse ((float)pix_x, (float)pix_y); - [FRAME_NS_VIEW (f) unlockFocus]; -#endif + CGPoint mouse_pos = + CGPointMake(f->left_pos + pix_x, + f->top_pos + pix_y + + FRAME_NS_TITLEBAR_HEIGHT(f) + FRAME_TOOLBAR_HEIGHT(f)); + CGWarpMouseCursorPosition (mouse_pos); #endif } diff --git a/test/lisp/mouse-tests.el b/test/lisp/mouse-tests.el index fffaa2fa53d..a8eca28365e 100644 --- a/test/lisp/mouse-tests.el +++ b/test/lisp/mouse-tests.el @@ -47,4 +47,13 @@ translate ‘mouse-1’ events into ‘mouse-2’ events." (should-not (mouse--down-1-maybe-follows-link)) (should (equal unread-command-events '((mouse-2 nil 1)))))) +(ert-deftest bug26816-mouse-frame-movement () + "Mouse moves relative to frame." + (skip-unless (display-graphic-p)) + (let ((frame (selected-frame))) + (set-mouse-position frame 0 0) + (should (equal (mouse-position) + (cons frame (cons 0 0)))))) + + ;;; mouse-tests.el ends here |