mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-30 04:10:54 -08:00
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.
This commit is contained in:
parent
c969b39971
commit
7e5a8cdceb
6 changed files with 62 additions and 8 deletions
3
etc/NEWS
3
etc/NEWS
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
39
src/nsfns.m
39
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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
14
src/nsterm.m
14
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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue