From 356618ca6a649979256552de8f2fa2a5ab6a0161 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 18 Jul 2022 09:20:05 +0800 Subject: [PATCH] Handle virtual modifiers in the DND scrolling code * lisp/x-dnd.el (x-dnd-modifier-mask): Handle virtual modifiers. * src/xfns.c (Fx_get_modifier_masks): New function. (syms_of_xfns): Define new subr. * src/xterm.c (x_get_keyboard_modifiers): New function. * src/xterm.h: Update prototypes. --- lisp/x-dnd.el | 17 ++++++++++++++--- src/xfns.c | 19 +++++++++++++++++++ src/xterm.c | 21 +++++++++++++++++++++ src/xterm.h | 1 + 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/lisp/x-dnd.el b/lisp/x-dnd.el index 6adfb8d773d..ffb94c18bb4 100644 --- a/lisp/x-dnd.el +++ b/lisp/x-dnd.el @@ -696,19 +696,30 @@ with coordinates relative to the root window." "Return the nmore-than3 bit from the 32 bit FLAGS in an XDndEnter message." (logand flags 1)) +(declare-function x-get-modifier-masks "xfns.c") + (defun x-dnd-modifier-mask (mods) "Return the X modifier mask for the Emacs modifier state MODS. MODS is a single symbol, or a list of symbols such as `shift' or `control'." - (let ((mask 0)) + (let ((virtual-modifiers (x-get-modifier-masks)) + (mask 0)) (unless (consp mods) (setq mods (list mods))) (dolist (modifier mods) ;; TODO: handle virtual modifiers such as Meta and Hyper. (cond ((eq modifier 'shift) - (setq mask (logior mask 1))) ; ShiftMask + (setq mask (logior mask 1))) ; ShiftMask ((eq modifier 'control) - (setq mask (logior mask 4))))) ; ControlMask + (setq mask (logior mask 4))) ; ControlMask + ((eq modifier 'meta) + (setq mask (logior mask (nth 4 virtual-modifiers)))) + ((eq modifier 'hyper) + (setq mask (car virtual-modifiers))) + ((eq modifier 'super) + (setq mask (cadr virtual-modifiers))) + ((eq modifier 'alt) + (setq mask (nth 2 virtual-modifiers))))) mask)) (defun x-dnd-hscroll-flags () diff --git a/src/xfns.c b/src/xfns.c index 1a65698f490..44208ffd515 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -9426,6 +9426,24 @@ present and mapped to the usual X keysyms. */) #endif } +DEFUN ("x-get-modifier-masks", Fx_get_modifier_masks, Sx_get_modifier_masks, + 0, 1, 0, + doc: /* Return the X modifier masks corresponding to keyboard modifiers. +The optional second argument TERMINAL specifies which display to fetch +modifier masks from. TERMINAL should be a terminal object, a frame or +a display name (a string). If TERMINAL is omitted or nil, that stands +for the selected frame's display. + +Return a list of (HYPER SUPER ALT SHIFT-LOCK META), each element being +a number describing the modifier mask for the corresponding Emacs +modifier. */) + (Lisp_Object terminal) +{ + struct x_display_info *dpyinfo; + + dpyinfo = check_x_display_info (terminal); + return x_get_keyboard_modifiers (dpyinfo); +} /*********************************************************************** @@ -10090,6 +10108,7 @@ eliminated in future versions of Emacs. */); defsubr (&Sx_begin_drag); defsubr (&Sx_display_set_last_user_time); defsubr (&Sx_translate_coordinates); + defsubr (&Sx_get_modifier_masks); tip_timer = Qnil; staticpro (&tip_timer); diff --git a/src/xterm.c b/src/xterm.c index bd142cf9f74..53c640ca6c2 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -28187,6 +28187,27 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost, } } +/* Return a list of the keyboard modifier masks in DPYINFO. + + Value is a list of (HYPER SUPER ALT SHIFT-LOCK META), each element + being the appropriate modifier mask. */ + +Lisp_Object +x_get_keyboard_modifiers (struct x_display_info *dpyinfo) +{ + /* This sometimes happens when the function is called during display + initialization, which can happen while obtaining vendor specific + keysyms. */ + if (!dpyinfo->xkb_desc && !dpyinfo->modmap) + x_find_modifier_meanings (dpyinfo); + + return list5 (make_uint (dpyinfo->hyper_mod_mask), + make_uint (dpyinfo->super_mod_mask), + make_uint (dpyinfo->alt_mod_mask), + make_uint (dpyinfo->shift_lock_mask), + make_uint (dpyinfo->meta_mod_mask)); +} + void syms_of_xterm (void) { diff --git a/src/xterm.h b/src/xterm.h index 6afd08eab2b..b9e7b094e31 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -1645,6 +1645,7 @@ extern bool x_defined_color (struct frame *, const char *, Emacs_Color *, bool, bool); extern void x_preserve_selections (struct x_display_info *, Lisp_Object, Lisp_Object); +extern Lisp_Object x_get_keyboard_modifiers (struct x_display_info *); #ifdef HAVE_X_I18N extern void free_frame_xic (struct frame *); # if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT