emacs-diffs
[Top][All Lists]
Advanced

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

master 693443bbf7: Fix various menu problems


From: Po Lu
Subject: master 693443bbf7: Fix various menu problems
Date: Fri, 21 Oct 2022 09:32:44 -0400 (EDT)

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

    Fix various menu problems
    
    * src/menu.c (x_popup_menu_1): Cancel hourglass timer before
    displaying popup.
    * src/xterm.c (x_show_hourglass): Avoid displaying hourglass
    cursor during a popup.
    (handle_one_xevent): Under X Toolkit and GTK+ 2.x builds with
    XInput 2, clear the mouse face upon a core LeaveNotify; these
    can be generated by menu grabs.
    (x_wm_set_size_hint): Fix Motif build warning.
---
 src/menu.c  |  9 +++++++++
 src/xterm.c | 44 +++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/src/menu.c b/src/menu.c
index c52e9258a1..87c5536bad 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -1391,6 +1391,15 @@ x_popup_menu_1 (Lisp_Object position, Lisp_Object menu)
 
   run_hook (Qx_pre_popup_menu_hook);
 
+  /* Cancel the hourglass timer.  Depending on how the show_menu_hook
+     is implemented, the hourglass window can either be mapped (or on
+     non-X systems, the hourglass cursor can be defined) either while
+     the menu is active, or while it is deactivated.  Both situations
+     lead to annoying cursor and/or screen flicker and a failure to
+     detect input immediately after a popup menu generated by Custom
+     is unmapped.  */
+  cancel_hourglass ();
+
   /* Display them in a menu, but not if F is the initial frame that
      doesn't have its hooks set (e.g., in a batch session), because
      such a frame cannot display menus.  */
diff --git a/src/xterm.c b/src/xterm.c
index 8b3d6f77a6..fecfc50ab5 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -10834,6 +10834,16 @@ x_show_hourglass (struct frame *f)
   if (dpy)
     {
       struct x_output *x = FRAME_X_OUTPUT (f);
+
+      /* If the hourglass window is mapped inside a popup menu, input
+        could be lost if the menu is popped down and the grab is
+        relinquished, but the hourglass window is still up.  Just
+        avoid displaying the hourglass at all while popups are
+        active.  */
+
+      if (popup_activated ())
+       return;
+
 #ifdef USE_X_TOOLKIT
       if (x->widget)
 #else
@@ -19838,7 +19848,20 @@ handle_one_xevent (struct x_display_info *dpyinfo,
         the input extension is enabled.  (bug#57468) */
 
       if (dpyinfo->supports_xi2)
-       goto OTHER;
+       {
+#if !defined USE_X_TOOLKIT && (!defined USE_GTK || defined HAVE_GTK3)
+         goto OTHER;
+#else
+         /* 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
+            face persisting if a popup is activated by clicking on a
+            button, and then dismissed by releasing the mouse button
+            outside the frame, in which case no XI_Enter event is
+            generated for the grab.  */
+         goto just_clear_mouse_face;
+#endif
+       }
 #endif
 
 #ifdef HAVE_XWIDGETS
@@ -19856,6 +19879,11 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       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:
+#endif
+
 #if defined USE_X_TOOLKIT
       /* If the mouse leaves the edit widget, then any mouse highlight
         should be cleared.  */
@@ -24250,7 +24278,12 @@ x_dispatch_event (XEvent *event, Display *display)
   dpyinfo = x_display_info_for_display (display);
 
   if (dpyinfo)
-    handle_one_xevent (dpyinfo, event, &finish, 0);
+    {
+      /* Block input before calling x_dispatch_event.  */
+      block_input ();
+      handle_one_xevent (dpyinfo, event, &finish, 0);
+      unblock_input ();
+    }
 
   return finish;
 }
@@ -28273,7 +28306,9 @@ x_wm_set_size_hint (struct frame *f, long flags, bool 
user_position)
   Window window = FRAME_OUTER_WINDOW (f);
 #ifdef USE_X_TOOLKIT
   WMShellWidget shell;
+#ifndef USE_MOTIF
   bool hints_changed;
+#endif
 #endif
 
   if (!window)
@@ -28300,11 +28335,14 @@ x_wm_set_size_hint (struct frame *f, long flags, bool 
user_position)
          shell->wm.size_hints.flags |= USPosition;
        }
 
+#ifndef USE_MOTIF
       hints_changed
        = widget_update_wm_size_hints (f->output_data.x->widget,
                                       f->output_data.x->edit_widget);
+#else
+      widget_update_wm_size_hints (f->output_data.x->widget,
+                                  f->output_data.x->edit_widget);
 
-#ifdef USE_MOTIF
       /* Do this all over again for the benefit of Motif, which always
         knows better than the programmer.  */
       shell->wm.size_hints.flags &= ~(PPosition | USPosition);



reply via email to

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