emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 203c503ff2: Minor fixes to menus on XI2


From: Po Lu
Subject: master 203c503ff2: Minor fixes to menus on XI2
Date: Thu, 14 Apr 2022 04:07:25 -0400 (EDT)

branch: master
commit 203c503ff22e6c3c7b75d0e30d1974bb0ca9e60a
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    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'.
---
 src/xfns.c  |  7 +++++++
 src/xmenu.c | 19 +++++++++++--------
 src/xterm.c | 49 +++++++++++++++++++++++++++++++++++++++----------
 src/xterm.h |  9 +++++++--
 4 files changed, 64 insertions(+), 20 deletions(-)

diff --git a/src/xfns.c b/src/xfns.c
index 5cf3eb4199..195af1381b 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 d19fe13c29..94cd9dab69 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 367659d3c1..94f8ce33bb 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 7509408268..defeaacc0d 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);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]