summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2022-04-14 16:02:12 +0800
committerPo Lu <luangruo@yahoo.com>2022-04-14 16:04:59 +0800
commit203c503ff22e6c3c7b75d0e30d1974bb0ca9e60a (patch)
treeea558353a347de0844bcecfcc6e3a6bcb7a30712 /src
parentc10024911d6c225645c22e87a7326c13c0116ac6 (diff)
downloademacs-203c503ff22e6c3c7b75d0e30d1974bb0ca9e60a.tar.gz
emacs-203c503ff22e6c3c7b75d0e30d1974bb0ca9e60a.tar.bz2
emacs-203c503ff22e6c3c7b75d0e30d1974bb0ca9e60a.zip
Minor fixes to menus on XI2
* src/xfns.c (Fx_create_frame): Populate `xi_masks'. * src/xmenu.c (x_activate_menubar) (create_and_show_popup_menu, x_menu_show): Only clear input extension grabs if we (or the toolkit) actually selected for XI_ButtonPress events. * src/xterm.c (xi_frame_selected_for): New function. (xi_populate_device_from_info, handle_one_xevent): Store device use instead of just whether or not it's a master device. (x_dnd_begin_drag_and_drop): Clean up block_input stuff. * src/xterm.h: Update prototypes. (struct xi_device_t): Rename `master_p' to `use'.
Diffstat (limited to 'src')
-rw-r--r--src/xfns.c7
-rw-r--r--src/xmenu.c19
-rw-r--r--src/xterm.c49
-rw-r--r--src/xterm.h9
4 files changed, 64 insertions, 20 deletions
diff --git a/src/xfns.c b/src/xfns.c
index 5cf3eb41996..195af1381b9 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -4845,6 +4845,13 @@ This function is an internal primitive--use `make-frame' instead. */)
x_icon (f, parms);
x_make_gc (f);
+#ifdef HAVE_XINPUT2
+ if (dpyinfo->supports_xi2)
+ FRAME_X_OUTPUT (f)->xi_masks
+ = XIGetSelectedEvents (dpyinfo->display, FRAME_X_WINDOW (f),
+ &FRAME_X_OUTPUT (f)->num_xi_masks);
+#endif
+
/* Now consider the frame official. */
f->terminal->reference_count++;
FRAME_DISPLAY_INFO (f)->reference_count++;
diff --git a/src/xmenu.c b/src/xmenu.c
index d19fe13c295..94cd9dab69b 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -634,15 +634,15 @@ x_activate_menubar (struct frame *f)
Otherwise some versions of Motif will emit a warning and hang,
and lwlib will fail to destroy the menu window. */
- if (dpyinfo->num_devices)
+ if (dpyinfo->supports_xi2
+ && xi_frame_selected_for (f, XI_ButtonPress))
{
for (int i = 0; i < dpyinfo->num_devices; ++i)
{
if (dpyinfo->devices[i].grab)
- {
- XIUngrabDevice (dpyinfo->display, dpyinfo->devices[i].device_id,
- CurrentTime);
- }
+ XIUngrabDevice (dpyinfo->display,
+ dpyinfo->devices[i].device_id,
+ CurrentTime);
}
}
#endif
@@ -1528,7 +1528,8 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv,
}
#if !defined HAVE_GTK3 && defined HAVE_XINPUT2
- if (FRAME_DISPLAY_INFO (f)->num_devices)
+ if (FRAME_DISPLAY_INFO (f)->supports_xi2
+ && xi_frame_selected_for (f, XI_ButtonPress))
{
for (int i = 0; i < FRAME_DISPLAY_INFO (f)->num_devices; ++i)
{
@@ -1696,7 +1697,8 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv,
if (dpyinfo->supports_xi2)
XGrabServer (dpyinfo->display);
- if (dpyinfo->num_devices)
+ if (dpyinfo->supports_xi2
+ && xi_frame_selected_for (f, XI_ButtonPress))
{
for (int i = 0; i < dpyinfo->num_devices; ++i)
{
@@ -2677,7 +2679,8 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
/* Clear the XI2 grab so a core grab can be set. */
- if (dpyinfo->num_devices)
+ if (dpyinfo->supports_xi2
+ && xi_frame_selected_for (f, XI_ButtonPress))
{
for (int i = 0; i < dpyinfo->num_devices; ++i)
{
diff --git a/src/xterm.c b/src/xterm.c
index 367659d3c1c..94f8ce33bb0 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -3704,6 +3704,29 @@ record_event (char *locus, int type)
#endif
+#ifdef HAVE_XINPUT2
+bool
+xi_frame_selected_for (struct frame *f, unsigned long event)
+{
+ XIEventMask *masks;
+ int i;
+
+ masks = FRAME_X_OUTPUT (f)->xi_masks;
+
+ if (!masks)
+ return false;
+
+ for (i = 0; i < FRAME_X_OUTPUT (f)->num_xi_masks; ++i)
+ {
+ if (masks[i].mask_len >= XIMaskLen (event)
+ && XIMaskIsSet (masks[i].mask, event))
+ return true;
+ }
+
+ return false;
+}
+#endif
+
static void
x_toolkit_position (struct frame *f, int x, int y,
bool *menu_bar_p, bool *tool_bar_p)
@@ -3886,8 +3909,7 @@ xi_populate_device_from_info (struct xi_device_t *xi_device,
xi_device->touchpoints = NULL;
#endif
- xi_device->master_p = (device->use == XIMasterKeyboard
- || device->use == XIMasterPointer);
+ xi_device->use = device->use;
#ifdef HAVE_XINPUT2_2
xi_device->direct_p = false;
#endif
@@ -9559,7 +9581,6 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
the root window, so we can get notified when window stacking
changes, a common operation during drag-and-drop. */
- block_input ();
XGetWindowAttributes (FRAME_X_DISPLAY (f),
FRAME_DISPLAY_INFO (f)->root_window,
&root_window_attrs);
@@ -9581,6 +9602,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
current_hold_quit = &hold_quit;
#endif
+ block_input ();
#ifdef USE_GTK
gtk_main_iteration ();
#else
@@ -9612,6 +9634,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
&next_event, &finish, &hold_quit);
#endif
#endif
+ unblock_input ();
if (x_dnd_movement_frame)
{
@@ -9712,7 +9735,6 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
XSelectInput (FRAME_X_DISPLAY (f),
FRAME_DISPLAY_INFO (f)->root_window,
root_window_attrs.your_event_mask);
- unblock_input ();
quit ();
}
}
@@ -9725,11 +9747,11 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
#endif
x_dnd_movement_frame = NULL;
+ block_input ();
/* Restore the old event mask. */
XSelectInput (FRAME_X_DISPLAY (f),
FRAME_DISPLAY_INFO (f)->root_window,
root_window_attrs.your_event_mask);
-
unblock_input ();
if (x_dnd_return_frame == 3
@@ -18024,8 +18046,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (info)
{
if (device && info->enabled)
- device->master_p = (info->use == XIMasterKeyboard
- || info->use == XIMasterPointer);
+ device->use = info->use;
else if (device)
disabled[n_disabled++] = hev->info[i].deviceid;
@@ -21666,9 +21687,6 @@ x_free_frame_resources (struct frame *f)
#ifdef HAVE_X_I18N
if (FRAME_XIC (f))
free_frame_xic (f);
-
- if (f->output_data.x->preedit_chars)
- xfree (f->output_data.x->preedit_chars);
#endif
#ifdef USE_CAIRO
@@ -21821,6 +21839,17 @@ x_destroy_window (struct frame *f)
xfree (f->output_data.x->saved_menu_event);
xfree (f->output_data.x);
+
+#ifdef HAVE_X_I18N
+ if (f->output_data.x->preedit_chars)
+ xfree (f->output_data.x->preedit_chars);
+#endif
+
+#ifdef HAVE_XINPUT2
+ if (f->output_data.x->xi_masks)
+ XFree (f->output_data.x->xi_masks);
+#endif
+
f->output_data.x = NULL;
dpyinfo->reference_count--;
diff --git a/src/xterm.h b/src/xterm.h
index 75094082683..defeaacc0d7 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -232,8 +232,7 @@ struct xi_device_t
#ifdef HAVE_XINPUT2_1
int scroll_valuator_count;
#endif
- int grab;
- bool master_p;
+ int grab, use;
#ifdef HAVE_XINPUT2_2
bool direct_p;
#endif
@@ -977,6 +976,11 @@ struct x_output
bool preedit_active;
int preedit_caret;
#endif
+
+#ifdef HAVE_XINPUT2
+ XIEventMask *xi_masks;
+ int num_xi_masks;
+#endif
};
enum
@@ -1571,6 +1575,7 @@ extern struct frame *x_dnd_frame;
#ifdef HAVE_XINPUT2
struct xi_device_t *xi_device_from_id (struct x_display_info *, int);
+bool xi_frame_selected_for (struct frame *, unsigned long);
#endif
extern void mark_xterm (void);