diff options
| -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 | |||
| 1321 | causes the receiving process to terminate with a core dump if no | 1321 | causes the receiving process to terminate with a core dump if no |
| 1322 | debugger has been attached to it. | 1322 | debugger has been attached to it. |
| 1323 | 1323 | ||
| 1324 | ** `set-mouse-position' and `set-mouse-absolute-pixel-position' work | ||
| 1325 | on macOS. | ||
| 1326 | |||
| 1324 | 1327 | ||
| 1325 | ---------------------------------------------------------------------- | 1328 | ---------------------------------------------------------------------- |
| 1326 | This file is part of GNU Emacs. | 1329 | 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." | |||
| 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 | |||
| 1474 | position (0, 0) of the selected frame's terminal." | 1475 | position (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 | ||
| 3069 | DEFUN ("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). | ||
| 3073 | The 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 |