aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--etc/NEWS3
-rw-r--r--lisp/frame.el3
-rw-r--r--src/nsfns.m39
-rw-r--r--src/nsterm.h2
-rw-r--r--src/nsterm.m14
-rw-r--r--test/lisp/mouse-tests.el9
6 files changed, 62 insertions, 8 deletions
diff --git a/etc/NEWS b/etc/NEWS
index eeb7c773acc..1b1fec3e914 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1321,6 +1321,9 @@ This is in contrast to the default action on POSIX Systems, where it
1321causes the receiving process to terminate with a core dump if no 1321causes the receiving process to terminate with a core dump if no
1322debugger has been attached to it. 1322debugger has been attached to it.
1323 1323
1324** `set-mouse-position' and `set-mouse-absolute-pixel-position' work
1325on macOS.
1326
1324 1327
1325---------------------------------------------------------------------- 1328----------------------------------------------------------------------
1326This file is part of GNU Emacs. 1329This 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."
1465 (t 1465 (t
1466 (cons 0 0))))) 1466 (cons 0 0)))))
1467 1467
1468(declare-function ns-set-mouse-absolute-pixel-position "nsfns.m" (x y))
1468(declare-function w32-set-mouse-absolute-pixel-position "w32fns.c" (x y)) 1469(declare-function w32-set-mouse-absolute-pixel-position "w32fns.c" (x y))
1469(declare-function x-set-mouse-absolute-pixel-position "xfns.c" (x y)) 1470(declare-function x-set-mouse-absolute-pixel-position "xfns.c" (x y))
1470 1471
@@ -1474,6 +1475,8 @@ The coordinates X and Y are interpreted in pixels relative to a
1474position (0, 0) of the selected frame's terminal." 1475position (0, 0) of the selected frame's terminal."
1475 (let ((frame-type (framep-on-display))) 1476 (let ((frame-type (framep-on-display)))
1476 (cond 1477 (cond
1478 ((eq frame-type 'ns)
1479 (ns-set-mouse-absolute-pixel-position x y))
1477 ((eq frame-type 'x) 1480 ((eq frame-type 'x)
1478 (x-set-mouse-absolute-pixel-position x y)) 1481 (x-set-mouse-absolute-pixel-position x y))
1479 ((eq frame-type 'w32) 1482 ((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. */)
3066 : Qnative_edges)); 3066 : Qnative_edges));
3067} 3067}
3068 3068
3069DEFUN ("ns-set-mouse-absolute-pixel-position",
3070 Fns_set_mouse_absolute_pixel_position,
3071 Sns_set_mouse_absolute_pixel_position, 2, 2, 0,
3072 doc: /* Move mouse pointer to absolute pixel position (X, Y).
3073The coordinates X and Y are interpreted in pixels relative to a position
3074\(0, 0) of the selected frame's display. */)
3075 (Lisp_Object x, Lisp_Object y)
3076{
3077 struct frame *f = SELECTED_FRAME ();
3078 EmacsView *view = FRAME_NS_VIEW (f);
3079 NSScreen *screen = [[view window] screen];
3080 NSRect screen_frame = [screen frame];
3081 int mouse_x, mouse_y;
3082
3083 NSScreen *primary_screen = [[NSScreen screens] objectAtIndex:0];
3084 NSRect primary_screen_frame = [primary_screen frame];
3085 CGFloat primary_screen_height = primary_screen_frame.size.height;
3086
3087 if (FRAME_INITIAL_P (f) || !FRAME_NS_P (f))
3088 return Qnil;
3089
3090 CHECK_TYPE_RANGED_INTEGER (int, x);
3091 CHECK_TYPE_RANGED_INTEGER (int, y);
3092
3093 mouse_x = screen_frame.origin.x + XINT (x);
3094
3095 if (screen == primary_screen)
3096 mouse_y = screen_frame.origin.y + XINT (y);
3097 else
3098 mouse_y = (primary_screen_height - screen_frame.size.height
3099 - screen_frame.origin.y) + XINT (y);
3100
3101 CGPoint mouse_pos = CGPointMake(mouse_x, mouse_y);
3102 CGWarpMouseCursorPosition (mouse_pos);
3103
3104 return Qnil;
3105}
3106
3069/* ========================================================================== 3107/* ==========================================================================
3070 3108
3071 Class implementations 3109 Class implementations
@@ -3254,6 +3292,7 @@ be used as the image of the icon representing the frame. */);
3254 defsubr (&Sns_frame_edges); 3292 defsubr (&Sns_frame_edges);
3255 defsubr (&Sns_frame_list_z_order); 3293 defsubr (&Sns_frame_list_z_order);
3256 defsubr (&Sns_frame_restack); 3294 defsubr (&Sns_frame_restack);
3295 defsubr (&Sns_set_mouse_absolute_pixel_position);
3257 defsubr (&Sx_display_mm_width); 3296 defsubr (&Sx_display_mm_width);
3258 defsubr (&Sx_display_mm_height); 3297 defsubr (&Sx_display_mm_height);
3259 defsubr (&Sx_display_screens); 3298 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
1087 ? ([[FRAME_NS_VIEW (f) window] parentWindow].frame.origin.y \ 1087 ? ([[FRAME_NS_VIEW (f) window] parentWindow].frame.origin.y \
1088 + [[FRAME_NS_VIEW (f) window] parentWindow].frame.size.height \ 1088 + [[FRAME_NS_VIEW (f) window] parentWindow].frame.size.height \
1089 - FRAME_NS_TITLEBAR_HEIGHT (FRAME_PARENT_FRAME (f))) \ 1089 - FRAME_NS_TITLEBAR_HEIGHT (FRAME_PARENT_FRAME (f))) \
1090 : [[[FRAME_NS_VIEW (f) window] screen] frame].size.height) 1090 : [[[NSScreen screens] objectAtIndex: 0] frame].size.height)
1091 1091
1092#define FRAME_NS_FONT_TABLE(f) (FRAME_DISPLAY_INFO (f)->font_table) 1092#define FRAME_NS_FONT_TABLE(f) (FRAME_DISPLAY_INFO (f)->font_table)
1093 1093
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)
2321 -------------------------------------------------------------------------- */ 2321 -------------------------------------------------------------------------- */
2322{ 2322{
2323 NSTRACE ("frame_set_mouse_pixel_position"); 2323 NSTRACE ("frame_set_mouse_pixel_position");
2324 ns_raise_frame (f); 2324
2325#if 0 2325 /* FIXME: what about GNUstep? */
2326 /* FIXME: this does not work, and what about GNUstep? */
2327#ifdef NS_IMPL_COCOA 2326#ifdef NS_IMPL_COCOA
2328 [FRAME_NS_VIEW (f) lockFocus]; 2327 CGPoint mouse_pos =
2329 PSsetmouse ((float)pix_x, (float)pix_y); 2328 CGPointMake(f->left_pos + pix_x,
2330 [FRAME_NS_VIEW (f) unlockFocus]; 2329 f->top_pos + pix_y +
2331#endif 2330 FRAME_NS_TITLEBAR_HEIGHT(f) + FRAME_TOOLBAR_HEIGHT(f));
2331 CGWarpMouseCursorPosition (mouse_pos);
2332#endif 2332#endif
2333} 2333}
2334 2334
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."
47 (should-not (mouse--down-1-maybe-follows-link)) 47 (should-not (mouse--down-1-maybe-follows-link))
48 (should (equal unread-command-events '((mouse-2 nil 1)))))) 48 (should (equal unread-command-events '((mouse-2 nil 1))))))
49 49
50(ert-deftest bug26816-mouse-frame-movement ()
51 "Mouse moves relative to frame."
52 (skip-unless (display-graphic-p))
53 (let ((frame (selected-frame)))
54 (set-mouse-position frame 0 0)
55 (should (equal (mouse-position)
56 (cons frame (cons 0 0))))))
57
58
50;;; mouse-tests.el ends here 59;;; mouse-tests.el ends here