emacs-diffs
[Top][All Lists]
Advanced

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

master e1a730017d6 1/2: Correct bug#65919


From: Po Lu
Subject: master e1a730017d6 1/2: Correct bug#65919
Date: Thu, 14 Sep 2023 22:38:52 -0400 (EDT)

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

    Correct bug#65919
    
    * src/process.c (child_signal_notify): Expunge call to
    non-reentrant function from signal handler.
    
    * src/xfns.c (setup_xi_event_mask): Cease selecting for
    XI_FocusIn and XI_FocusOut under X toolkit builds.
    
    * src/xterm.c (xi_handle_interaction, xi_handle_focus_change)
    (xi_handle_focus_change): Make conditional on GTK 3 or no
    toolkit builds.
    (xi_handle_delete_frame, x_free_frame_resources): Adjust
    correspondingly.
    (handle_one_xevent) <EnterNotify, LeaveNotify>: Examine
    EnterNotify and LeaveNotify events for focus changes
    irrespective of whether XI2 is enabled under the X toolkit and
    GTK 2.x.
---
 src/process.c | 19 ++++++++++++++++-
 src/xfns.c    | 10 ++++-----
 src/xterm.c   | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 82 insertions(+), 15 deletions(-)

diff --git a/src/process.c b/src/process.c
index dbd677e59d7..7410256dae9 100644
--- a/src/process.c
+++ b/src/process.c
@@ -7416,7 +7416,24 @@ child_signal_notify (void)
   eassert (0 <= fd);
   char dummy = 0;
   if (emacs_write (fd, &dummy, 1) != 1)
-    emacs_perror ("writing to child signal FD");
+    /* This call is commented out.  It calls `emacs_perror', which in
+       turn invokes a localized version of strerror that is not
+       reentrant and must not be called within a signal handler:
+
+       __lll_lock_wait_private () at /lib64/libc.so.6
+       malloc () at /lib64/libc.so.6
+       _nl_make_l10nflist.localalias () at /lib64/libc.so.6
+       _nl_find_domain () at /lib64/libc.so.6
+       __dcigettext () at /lib64/libc.so.6
+       strerror_l () at /lib64/libc.so.6
+       emacs_perror (message=message@entry=0x6babc2)
+       child_signal_notify () at process.c:7419
+       handle_child_signal (sig=17) at process.c:7533
+       deliver_process_signal (sig=17, handler=0x6186b0>)
+       <signal handler called> () at /lib64/libc.so.6
+       _int_malloc () at /lib64/libc.so.6
+       in malloc () at /lib64/libc.so.6.  */
+    /* emacs_perror ("writing to child signal FD") */;
 #endif
 }
 
diff --git a/src/xfns.c b/src/xfns.c
index aea2f4b880e..0b1e94af9f0 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -4021,6 +4021,7 @@ initial_set_up_x_back_buffer (struct frame *f)
 }
 
 #if defined HAVE_XINPUT2
+
 static void
 setup_xi_event_mask (struct frame *f)
 {
@@ -4069,8 +4070,7 @@ setup_xi_event_mask (struct frame *f)
       XISetMask (m, XI_GesturePinchEnd);
     }
 #endif /* HAVE_XINPUT2_4 */
-  XISelectEvents (FRAME_X_DISPLAY (f),
-                 FRAME_X_WINDOW (f),
+  XISelectEvents (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                  &mask, 1);
 
   /* Fortunately `xi_masks' isn't used on GTK 3, where we really have
@@ -4085,11 +4085,8 @@ setup_xi_event_mask (struct frame *f)
 #ifdef USE_X_TOOLKIT
   XISetMask (m, XI_KeyPress);
   XISetMask (m, XI_KeyRelease);
-  XISetMask (m, XI_FocusIn);
-  XISetMask (m, XI_FocusOut);
 
-  XISelectEvents (FRAME_X_DISPLAY (f),
-                 FRAME_OUTER_WINDOW (f),
+  XISelectEvents (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
                  &mask, 1);
   memset (m, 0, l);
 #endif /* USE_X_TOOLKIT */
@@ -4135,6 +4132,7 @@ setup_xi_event_mask (struct frame *f)
 
   unblock_input ();
 }
+
 #endif
 
 #ifdef USE_X_TOOLKIT
diff --git a/src/xterm.c b/src/xterm.c
index 11ccd5ebdb3..9ca7817b8db 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -13170,6 +13170,12 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, 
Atom xaction,
 
 #ifdef HAVE_XINPUT2
 
+/* Disable per-device keyboard focus tracking within X toolkit and GTK
+   2.x builds, given that these builds receive updates to the keyboard
+   input focus as core events.  */
+
+#if !defined USE_X_TOOLKIT && (!defined USE_GTK || defined HAVE_GTK3)
+
 /* Since the input extension assigns a keyboard focus to each master
    device, there is no longer a 1:1 correspondence between the
    selected frame and the focus frame immediately after the keyboard
@@ -13381,6 +13387,8 @@ xi_focus_handle_for_device (struct x_display_info 
*dpyinfo,
   xi_handle_focus_change (dpyinfo);
 }
 
+#endif /* !USE_X_TOOLKIT && (!USE_GTK || HAVE_GTK3) */
+
 static void
 xi_handle_delete_frame (struct x_display_info *dpyinfo,
                        struct frame *f)
@@ -13409,6 +13417,7 @@ xi_handle_interaction (struct x_display_info *dpyinfo,
                       struct frame *f, struct xi_device_t *device,
                       Time time)
 {
+#if !defined USE_X_TOOLKIT && (!defined USE_GTK || defined HAVE_GTK3)
   bool change;
 
   /* If DEVICE is a pointer, use its attached keyboard device.  */
@@ -13435,6 +13444,7 @@ xi_handle_interaction (struct x_display_info *dpyinfo,
   /* If F isn't currently focused, update the focus state.  */
   if (change && f != dpyinfo->x_focus_frame)
     xi_handle_focus_change (dpyinfo);
+#endif /* !USE_X_TOOLKIT && (!USE_GTK || HAVE_GTK3) */
 }
 
 /* Return whether or not XEV actually represents a change in the
@@ -20575,6 +20585,14 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       }
 #endif
 
+      /* Apply the fix for bug#57468 on GTK 3.x and no toolkit builds,
+        but not GTK+ 2.x and X toolkit builds, where it is required
+        to treat implicit focus correctly.  */
+#if defined USE_X_TOOLKIT || (defined USE_GTK && !defined HAVE_GTK3)
+      if (x_top_window_to_frame (dpyinfo, event->xcrossing.window))
+       x_detect_focus_change (dpyinfo, any, event, &inev.ie);
+#endif /* defined USE_X_TOOLKIT || (defined USE_GTK && !defined HAVE_GTK3) */
+
 #ifdef HAVE_XINPUT2
       /* For whatever reason, the X server continues to deliver
         EnterNotify and LeaveNotify events despite us selecting for
@@ -20585,10 +20603,14 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 
       if (dpyinfo->supports_xi2)
        goto OTHER;
-#endif
+#endif /* HAVE_XINPUT2 */
 
+      /* Apply the fix for bug#57468 on GTK 3.x and no toolkit
+        builds.  */
+#if !defined USE_X_TOOLKIT || (!defined USE_GTK || defined HAVE_GTK3)
       if (x_top_window_to_frame (dpyinfo, event->xcrossing.window))
        x_detect_focus_change (dpyinfo, any, event, &inev.ie);
+#endif /* !defined USE_X_TOOLKIT || (!defined USE_GTK || defined HAVE_GTK3) */
 
       f = any;
 
@@ -20673,6 +20695,14 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       x_display_set_last_user_time (dpyinfo, event->xcrossing.time,
                                    event->xcrossing.send_event, false);
 
+      /* Apply the fix for bug#57468 on GTK 3.x and no toolkit builds,
+        but not GTK+ 2.x and X toolkit builds, where it is required
+        to treat implicit focus correctly.  */
+#if defined USE_X_TOOLKIT || (defined USE_GTK && !defined HAVE_GTK3)
+      if (x_top_window_to_frame (dpyinfo, event->xcrossing.window))
+       x_detect_focus_change (dpyinfo, any, event, &inev.ie);
+#endif /* defined USE_X_TOOLKIT || (defined USE_GTK && !defined HAVE_GTK3) */
+
 #ifdef HAVE_XINPUT2
       /* For whatever reason, the X server continues to deliver
         EnterNotify and LeaveNotify events despite us selecting for
@@ -20685,7 +20715,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
        {
 #if !defined USE_X_TOOLKIT && (!defined USE_GTK || defined HAVE_GTK3)
          goto OTHER;
-#else
+#else /* USE_X_TOOLKIT || (USE_GTK && !HAVE_GTK3) */
          /* Unfortunately, X toolkit popups generate LeaveNotify
             events due to the core grabs they acquire (and our
             releasing of the device grab).  This leads to the mouse
@@ -20694,9 +20724,16 @@ handle_one_xevent (struct x_display_info *dpyinfo,
             outside the frame, in which case no XI_Enter event is
             generated for the grab.  */
          goto just_clear_mouse_face;
-#endif
+#endif /* !USE_X_TOOLKIT && (!USE_GTK || HAVE_GTK3) */
        }
-#endif
+#endif /* HAVE_XINPUT2 */
+
+      /* Apply the fix for bug#57468 on GTK 3.x and no toolkit
+        builds.  */
+#if !defined USE_X_TOOLKIT || (!defined USE_GTK || defined HAVE_GTK3)
+      if (x_top_window_to_frame (dpyinfo, event->xcrossing.window))
+       x_detect_focus_change (dpyinfo, any, event, &inev.ie);
+#endif /* !defined USE_X_TOOLKIT || (!defined USE_GTK || defined HAVE_GTK3) */
 
 #ifdef HAVE_XWIDGETS
       {
@@ -20712,9 +20749,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       }
 #endif
 
-      if (x_top_window_to_frame (dpyinfo, event->xcrossing.window))
-       x_detect_focus_change (dpyinfo, any, event, &inev.ie);
-
 #if defined HAVE_XINPUT2                                               \
   && (defined USE_X_TOOLKIT || (defined USE_GTK && !defined HAVE_GTK3))
     just_clear_mouse_face:
@@ -22082,6 +22116,10 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 
        switch (event->xcookie.evtype)
          {
+           /* XI focus events aren't employed under X toolkit or GTK+
+              2.x because windows created by these two toolkits are
+              incompatible with input extension focus events.  */
+#if !defined USE_X_TOOLKIT && (!defined USE_GTK || defined HAVE_GTK3)
          case XI_FocusIn:
            {
              XIFocusInEvent *focusin;
@@ -22134,6 +22172,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 
              goto XI_OTHER;
            }
+#endif /* !USE_X_TOOLKIT && (!USE_GTK || HAVE_GTK3) */
 
          case XI_Enter:
            {
@@ -22179,8 +22218,11 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                 passive focus from non-top windows at all, since they
                 are an inferiors of the frame's top window, which will
                 get virtual events.  */
+
+#if !defined USE_X_TOOLKIT && (!defined USE_GTK || defined HAVE_GTK3)
              if (any)
                xi_focus_handle_for_device (dpyinfo, any, xi_event);
+#endif /* !USE_X_TOOLKIT && (!USE_GTK || HAVE_GTK3) */
 
              if (!any)
                any = x_any_window_to_frame (dpyinfo, enter->event);
@@ -22360,8 +22402,10 @@ handle_one_xevent (struct x_display_info *dpyinfo,
              }
 #endif
 
+#if !defined USE_X_TOOLKIT && (!defined USE_GTK || defined HAVE_GTK3)
              if (any)
                xi_focus_handle_for_device (dpyinfo, any, xi_event);
+#endif /* !USE_X_TOOLKIT && (!USE_GTK || HAVE_GTK3) */
 
 #ifndef USE_X_TOOLKIT
              f = x_top_window_to_frame (dpyinfo, leave->event);
@@ -24432,9 +24476,11 @@ handle_one_xevent (struct x_display_info *dpyinfo,
              XIDeviceInfo *info;
              int i, ndevices, n_disabled, *disabled;
              struct xi_device_t *device;
+#if !defined USE_X_TOOLKIT && (!defined USE_GTK || defined HAVE_GTK3)
              bool any_changed;
 
              any_changed = false;
+#endif /* !USE_X_TOOLKIT && (!USE_GTK || HAVE_GTK3) */
              hev = (XIHierarchyEvent *) xi_event;
              disabled = SAFE_ALLOCA (sizeof *disabled * hev->num_info);
              n_disabled = 0;
@@ -24451,10 +24497,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                          xi_disable_devices (dpyinfo, disabled, n_disabled);
                          n_disabled = 0;
 
+#if !defined USE_X_TOOLKIT && (!defined USE_GTK || defined HAVE_GTK3)
                          /* This flag really just means that disabled
                             devices were handled early and should be
                             used in conjunction with n_disabled.  */
                          any_changed = true;
+#endif /* !USE_X_TOOLKIT && (!USE_GTK || HAVE_GTK3) */
                        }
 
                      /* Under unknown circumstances, multiple
@@ -24521,12 +24569,14 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                 event.  */
              xi_disable_devices (dpyinfo, disabled, n_disabled);
 
+#if !defined USE_X_TOOLKIT && (!defined USE_GTK || defined HAVE_GTK3)
              /* If the device hierarchy has been changed, recompute
                 focus.  This might seem like a micro-optimization but
                 it actually keeps the focus from changing in some
                 cases where it would be undesierable.  */
              if (any_changed || n_disabled)
                xi_handle_focus_change (dpyinfo);
+#endif /* !USE_X_TOOLKIT && (!USE_GTK || HAVE_GTK3) */
 
              goto XI_OTHER;
            }
@@ -29454,6 +29504,7 @@ x_free_frame_resources (struct frame *f)
     dpyinfo->last_mouse_frame = NULL;
 
 #ifdef HAVE_XINPUT2
+#if !defined USE_X_TOOLKIT && (!defined USE_GTK || defined HAVE_GTK3)
   /* Consider a frame being unfocused with no following FocusIn event
      while an older focus from another seat exists.  The client
      pointer should then revert to the other seat, so handle potential
@@ -29461,7 +29512,8 @@ x_free_frame_resources (struct frame *f)
 
   if (dpyinfo->supports_xi2)
     xi_handle_focus_change (dpyinfo);
-#endif
+#endif /* !USE_X_TOOLKIT && (!USE_GTK || HAVE_GTK3) */
+#endif /* HAVE_XINPUT2 */
 
   unblock_input ();
 }



reply via email to

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