From 95717db1e8045f14ca427243a86a0cd433e07273 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Wed, 11 May 2022 16:01:32 +0800 Subject: [PATCH] Fix mouse pointer avoidance in some configurations * lisp/avoid.el (mouse-avoidance-random-shape): Ignore invisible pointer. (mouse-avoidance-ignore-p): Adjust for interprogram DND. * lisp/term/x-win.el (x-pointer-invisible): Make value larger than the maximum possible glyph. * src/xfns.c (x_set_mouse_color): Use function that handles `x-pointer-invisible' too. * src/xterm.c (x_create_font_cursor): New function. Handle invisible cursors. * src/xterm.h: Update prototypes. --- lisp/avoid.el | 17 ++++++++++------- lisp/term/x-win.el | 4 +++- src/xfns.c | 44 ++++++++++++++++++++++++-------------------- src/xterm.c | 12 ++++++++++++ src/xterm.h | 3 ++- 5 files changed, 51 insertions(+), 29 deletions(-) diff --git a/lisp/avoid.el b/lisp/avoid.el index b53d84d2e8d..c97e51a6f7d 100644 --- a/lisp/avoid.el +++ b/lisp/avoid.el @@ -300,12 +300,14 @@ has an integer value is a valid cursor shape. You might want to redefine this function to suit your own tastes." (if (null mouse-avoidance-pointer-shapes) (progn - (setq mouse-avoidance-pointer-shapes - (mapcar (lambda (x) (symbol-value (intern x))) - (all-completions "x-pointer-" obarray - (lambda (x) - (and (boundp x) - (integerp (symbol-value x))))))))) + (dolist (i (all-completions "x-pointer-" obarray + (lambda (x) + (and (boundp x) + (integerp (symbol-value x)))))) + (ignore-errors + (let ((value (symbol-value (intern i)))) + (when (< value x-pointer-invisible) + (push value mouse-avoidance-pointer-shapes))))))) (seq-random-elt mouse-avoidance-pointer-shapes)) (defun mouse-avoidance-ignore-p () @@ -317,7 +319,8 @@ redefine this function to suit your own tastes." (not (eq (car mp) (selected-frame))) ;; Don't interfere with ongoing `mouse-drag-and-drop-region' ;; (Bug#36269). - (eq track-mouse 'dropping) + (or (eq track-mouse 'dropping) + (eq track-mouse 'drag-source)) ;; Don't do anything if last event was a mouse event. ;; FIXME: this code fails in the case where the mouse was moved ;; since the last key-press but without generating any event. diff --git a/lisp/term/x-win.el b/lisp/term/x-win.el index ca38a0a8c92..08a8bf88e5d 100644 --- a/lisp/term/x-win.el +++ b/lisp/term/x-win.el @@ -241,7 +241,9 @@ exists." (defconst x-pointer-ur-angle 148) (defconst x-pointer-watch 150) (defconst x-pointer-xterm 152) -(defconst x-pointer-invisible 255) +(defconst x-pointer-invisible 65536) ;; This value is larger than a + ;; CARD16, so it cannot be a + ;; valid cursor. ;;;; Keysyms diff --git a/src/xfns.c b/src/xfns.c index 5522684170f..6eddf3a4949 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -1261,25 +1261,27 @@ struct mouse_cursor_types { }; /* This array must stay in sync with enum mouse_cursor above! */ -static const struct mouse_cursor_types mouse_cursor_types[] = { - { "text", &Vx_pointer_shape, XC_xterm }, - { "nontext", &Vx_nontext_pointer_shape, XC_left_ptr }, - { "hourglass", &Vx_hourglass_pointer_shape, XC_watch }, - { "modeline", &Vx_mode_pointer_shape, XC_xterm }, - { NULL, &Vx_sensitive_text_pointer_shape, XC_hand2 }, - { NULL, &Vx_window_horizontal_drag_shape, XC_sb_h_double_arrow }, - { NULL, &Vx_window_vertical_drag_shape, XC_sb_v_double_arrow }, - { NULL, &Vx_window_left_edge_shape, XC_left_side }, - { NULL, &Vx_window_top_left_corner_shape, XC_top_left_corner }, - { NULL, &Vx_window_top_edge_shape, XC_top_side }, - { NULL, &Vx_window_top_right_corner_shape, XC_top_right_corner }, - { NULL, &Vx_window_right_edge_shape, XC_right_side }, - { NULL, &Vx_window_bottom_right_corner_shape, XC_bottom_right_corner }, - { NULL, &Vx_window_bottom_edge_shape, XC_bottom_side }, - { NULL, &Vx_window_bottom_left_corner_shape, XC_bottom_left_corner }, -}; +static const struct mouse_cursor_types mouse_cursor_types[] = + { + { "text", &Vx_pointer_shape, XC_xterm }, + { "nontext", &Vx_nontext_pointer_shape, XC_left_ptr }, + { "hourglass", &Vx_hourglass_pointer_shape, XC_watch }, + { "modeline", &Vx_mode_pointer_shape, XC_xterm }, + { NULL, &Vx_sensitive_text_pointer_shape, XC_hand2 }, + { NULL, &Vx_window_horizontal_drag_shape, XC_sb_h_double_arrow }, + { NULL, &Vx_window_vertical_drag_shape, XC_sb_v_double_arrow }, + { NULL, &Vx_window_left_edge_shape, XC_left_side }, + { NULL, &Vx_window_top_left_corner_shape, XC_top_left_corner }, + { NULL, &Vx_window_top_edge_shape, XC_top_side }, + { NULL, &Vx_window_top_right_corner_shape, XC_top_right_corner }, + { NULL, &Vx_window_right_edge_shape, XC_right_side }, + { NULL, &Vx_window_bottom_right_corner_shape, XC_bottom_right_corner }, + { NULL, &Vx_window_bottom_edge_shape, XC_bottom_side }, + { NULL, &Vx_window_bottom_left_corner_shape, XC_bottom_left_corner }, + }; -struct mouse_cursor_data { +struct mouse_cursor_data +{ /* Last index for which XCreateFontCursor has been called, and thus the last index for which x_request_serial[] is valid. */ int last_cursor_create_request; @@ -1360,8 +1362,10 @@ x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { cursor_data.x_request_serial[i] = XNextRequest (dpy); cursor_data.last_cursor_create_request = i; - cursor_data.cursor[i] = XCreateFontCursor (dpy, - cursor_data.cursor_num[i]); + + cursor_data.cursor[i] + = x_create_font_cursor (FRAME_DISPLAY_INFO (f), + cursor_data.cursor_num[i]); } /* Now sync up and process all received errors from cursor diff --git a/src/xterm.c b/src/xterm.c index 4c1720ca94f..a250fce9b09 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -22639,6 +22639,18 @@ x_make_frame_visible_invisible (struct frame *f, bool visible) x_make_frame_invisible (f); } +Cursor +x_create_font_cursor (struct x_display_info *dpyinfo, int glyph) +{ + if (glyph <= 65535) + return XCreateFontCursor (dpyinfo->display, glyph); + + /* x-pointer-invisible cannot fit in CARD16, and thus cannot be any + existing cursor. */ + return make_invisible_cursor (dpyinfo); +} + + /* Change window state from mapped to iconified. */ void diff --git a/src/xterm.h b/src/xterm.h index 98c4c5f01c6..3437037e674 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -1383,7 +1383,8 @@ extern void x_iconify_frame (struct frame *f); extern void x_free_frame_resources (struct frame *); extern void x_wm_set_size_hint (struct frame *, long, bool); -extern void x_delete_terminal (struct terminal *terminal); +extern void x_delete_terminal (struct terminal *); +extern Cursor x_create_font_cursor (struct x_display_info *, int); extern unsigned long x_copy_color (struct frame *, unsigned long); #ifdef USE_X_TOOLKIT extern XtAppContext Xt_app_con; -- 2.39.2