emacs-diffs
[Top][All Lists]
Advanced

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

master 70a184b141: Improve correctness of generated xwidget events


From: Po Lu
Subject: master 70a184b141: Improve correctness of generated xwidget events
Date: Wed, 2 Feb 2022 06:07:58 -0500 (EST)

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

    Improve correctness of generated xwidget events
    
    * src/xwidget.c (xw_maybe_synthesize_crossing): Add new
    parameters for controlling the crossing mode.  Also improve the
    accuracy of generated crossing events when the mouse pointer
    moves outside the toplevel from an inferior of it.  All callers
    changed.
    (xw_notify_virtual_upwards_until):
    (xw_notify_virtual_downwards_until): New parameters for crossing
    mode.  All callers changed.
---
 src/xwidget.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 75 insertions(+), 21 deletions(-)

diff --git a/src/xwidget.c b/src/xwidget.c
index 9b08d47a8e..23031f9c93 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -265,10 +265,12 @@ xw_translate_x_modifiers (struct x_display_info *dpyinfo,
 
 static bool xw_maybe_synthesize_crossing (struct xwidget_view *,
                                          GdkWindow *, int, int, int,
-                                         Time, unsigned int);
+                                         Time, unsigned int,
+                                         GdkCrossingMode, GdkCrossingMode);
 static void xw_notify_virtual_upwards_until (struct xwidget_view *, GdkWindow 
*,
                                             GdkWindow *, GdkWindow *, unsigned 
int,
-                                            int, int, Time, GdkEventType, 
bool);
+                                            int, int, Time, GdkEventType, bool,
+                                            GdkCrossingMode);
 static void window_coords_from_toplevel (GdkWindow *, GdkWindow *, int,
                                         int, int *, int *);
 #endif
@@ -1219,7 +1221,8 @@ xwidget_button_1 (struct xwidget_view *view,
        {
          xw_maybe_synthesize_crossing (view, gtk_widget_get_window 
(ungrab_target),
                                        view_x, view_y, XW_CROSSING_NONE,
-                                       time, modifier_state);
+                                       time, modifier_state, 
GDK_CROSSING_UNGRAB,
+                                       GDK_CROSSING_UNGRAB);
        }
       else
        {
@@ -1243,7 +1246,8 @@ xwidget_button_1 (struct xwidget_view *view,
 
          xw_notify_virtual_upwards_until (view, target_window, toplevel, 
toplevel,
                                           modifier_state, view_x, view_y, time,
-                                          GDK_LEAVE_NOTIFY, false);
+                                          GDK_LEAVE_NOTIFY, false,
+                                          GDK_CROSSING_UNGRAB);
 
          if (target_window != toplevel)
            {
@@ -1370,7 +1374,11 @@ xwidget_motion_notify (struct xwidget_view *view,
     }
   else if (xw_maybe_synthesize_crossing (view, gtk_widget_get_window (target),
                                         x + view->clip_left, y + 
view->clip_top,
-                                        XW_CROSSING_NONE, time, state))
+                                        XW_CROSSING_NONE, time, state,
+                                        (view->passive_grab
+                                         ? GDK_CROSSING_GRAB
+                                         : GDK_CROSSING_NORMAL),
+                                        GDK_CROSSING_NORMAL))
     return;
 
   xg_event = gdk_event_new (GDK_MOTION_NOTIFY);
@@ -1605,7 +1613,8 @@ xw_notify_virtual_upwards_until (struct xwidget_view *xv,
                                 unsigned int state,
                                 int x, int y, Time time,
                                 GdkEventType type,
-                                bool nonlinear_p)
+                                bool nonlinear_p,
+                                GdkCrossingMode crossing)
 {
   GdkEvent *xg_event;
   GdkWindow *tem;
@@ -1626,7 +1635,7 @@ xw_notify_virtual_upwards_until (struct xwidget_view *xv,
       xg_event->crossing.detail = (nonlinear_p
                                   ? GDK_NOTIFY_NONLINEAR_VIRTUAL
                                   : GDK_NOTIFY_VIRTUAL);
-      xg_event->crossing.mode = GDK_CROSSING_NORMAL;
+      xg_event->crossing.mode = crossing;
       xg_event->crossing.window = g_object_ref (tem);
 
       gtk_main_do_event (xg_event);
@@ -1642,7 +1651,8 @@ xw_notify_virtual_downwards_until (struct xwidget_view 
*xv,
                                   unsigned int state,
                                   int x, int y, Time time,
                                   GdkEventType type,
-                                  bool nonlinear_p)
+                                  bool nonlinear_p,
+                                  GdkCrossingMode crossing)
 {
   GdkEvent *xg_event;
   GdkWindow *tem;
@@ -1671,7 +1681,7 @@ xw_notify_virtual_downwards_until (struct xwidget_view 
*xv,
       xg_event->crossing.detail = (nonlinear_p
                                   ? GDK_NOTIFY_NONLINEAR_VIRTUAL
                                   : GDK_NOTIFY_VIRTUAL);
-      xg_event->crossing.mode = GDK_CROSSING_NORMAL;
+      xg_event->crossing.mode = crossing;
       xg_event->crossing.window = g_object_ref (tem);
 
       gtk_main_do_event (xg_event);
@@ -1716,14 +1726,18 @@ static bool
 xw_maybe_synthesize_crossing (struct xwidget_view *view,
                              GdkWindow *current_window,
                              int x, int y, int crossing,
-                             Time time, unsigned int state)
+                             Time time, unsigned int state,
+                             GdkCrossingMode entry_crossing,
+                             GdkCrossingMode exit_crossing)
 {
   GdkWindow *last_crossing, *toplevel, *ancestor;
   GdkEvent *xg_event;
   int cx, cy;
   bool nonlinear_p;
+  bool retention_flag;
 
   toplevel = gtk_widget_get_window (XXWIDGET (view->model)->widgetwindow_osr);
+  retention_flag = false;
 
   if (crossing == XW_CROSSING_LEFT
       && (view->last_crossing_window
@@ -1732,13 +1746,40 @@ xw_maybe_synthesize_crossing (struct xwidget_view *view,
       xw_notify_virtual_upwards_until (view, view->last_crossing_window,
                                       toplevel, toplevel,
                                       state, x, y, time,
-                                      GDK_LEAVE_NOTIFY, false);
+                                      GDK_LEAVE_NOTIFY, false,
+                                      exit_crossing);
     }
 
   if (view->last_crossing_window
       && (gdk_window_is_destroyed (view->last_crossing_window)
          || crossing == XW_CROSSING_LEFT))
     {
+      if (!gdk_window_is_destroyed (view->last_crossing_window)
+         && view->last_crossing_window != toplevel)
+       {
+         xg_event = gdk_event_new (GDK_LEAVE_NOTIFY);
+         window_coords_from_toplevel (view->last_crossing_window,
+                                      toplevel, x, y, &cx, &cy);
+
+         xg_event->crossing.x = cx;
+         xg_event->crossing.y = cy;
+         xg_event->crossing.time = time;
+         xg_event->crossing.focus = FALSE;
+         xg_event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+         xg_event->crossing.mode = exit_crossing;
+         xg_event->crossing.window = g_object_ref (view->last_crossing_window);
+         gdk_event_set_device (xg_event, find_suitable_pointer (view->frame));
+
+         gtk_main_do_event (xg_event);
+         gdk_event_free (xg_event);
+
+         xw_notify_virtual_upwards_until (view, view->last_crossing_window,
+                                          gdk_window_get_parent (toplevel),
+                                          toplevel, state, x, y, time,
+                                          GDK_LEAVE_NOTIFY, false, 
exit_crossing);
+         retention_flag = true;
+       }
+
       g_signal_handler_disconnect (view->last_crossing_window,
                                   view->last_crossing_cursor_signal);
       g_clear_pointer (&view->last_crossing_window,
@@ -1760,9 +1801,9 @@ xw_maybe_synthesize_crossing (struct xwidget_view *view,
                                             toplevel, toplevel,
                                             state, x, y, time,
                                             GDK_ENTER_NOTIFY,
-                                            false);
+                                            false, entry_crossing);
        }
-      return false;
+      return retention_flag;
     }
 
   if (last_crossing != current_window)
@@ -1787,7 +1828,8 @@ xw_maybe_synthesize_crossing (struct xwidget_view *view,
                                         ancestor, toplevel,
                                         state, x, y, time,
                                         GDK_LEAVE_NOTIFY,
-                                        nonlinear_p);
+                                        nonlinear_p,
+                                        exit_crossing);
 
       xg_event = gdk_event_new (GDK_LEAVE_NOTIFY);
       gdk_event_set_device (xg_event, find_suitable_pointer (view->frame));
@@ -1798,13 +1840,12 @@ xw_maybe_synthesize_crossing (struct xwidget_view *view,
       xg_event->crossing.time = time;
       xg_event->crossing.focus = FALSE;
       xg_event->crossing.state = state;
-      /* TODO: actually calculate the event mode.  */
       xg_event->crossing.detail = (nonlinear_p
                                   ? GDK_NOTIFY_NONLINEAR
                                   : (last_crossing == ancestor
                                      ? GDK_NOTIFY_INFERIOR
                                      : GDK_NOTIFY_ANCESTOR));
-      xg_event->crossing.mode = GDK_CROSSING_NORMAL;
+      xg_event->crossing.mode = exit_crossing;
       xg_event->crossing.window = g_object_ref (last_crossing);
 
       gtk_main_do_event (xg_event);
@@ -1815,7 +1856,8 @@ xw_maybe_synthesize_crossing (struct xwidget_view *view,
                                           ancestor, toplevel,
                                           state, x, y, time,
                                           GDK_ENTER_NOTIFY,
-                                          nonlinear_p);
+                                          nonlinear_p,
+                                          entry_crossing);
 
       xg_event = gdk_event_new (GDK_ENTER_NOTIFY);
       gdk_event_set_device (xg_event, find_suitable_pointer (view->frame));
@@ -1831,7 +1873,7 @@ xw_maybe_synthesize_crossing (struct xwidget_view *view,
                                   : (current_window == ancestor
                                      ? GDK_NOTIFY_INFERIOR
                                      : GDK_NOTIFY_ANCESTOR));
-      xg_event->crossing.mode = GDK_CROSSING_NORMAL;
+      xg_event->crossing.mode = entry_crossing;
       xg_event->crossing.window = g_object_ref (current_window);
 
       gtk_main_do_event (xg_event);
@@ -1909,7 +1951,11 @@ xwidget_motion_or_crossing (struct xwidget_view *view, 
const XEvent *event)
       if (!xw_maybe_synthesize_crossing (view, xg_event->any.window,
                                         toplevel_x, toplevel_y,
                                         XW_CROSSING_NONE, event->xmotion.time,
-                                        event->xmotion.state))
+                                        event->xmotion.state,
+                                        (view->passive_grab
+                                         ? GDK_CROSSING_GRAB
+                                         : GDK_CROSSING_NORMAL),
+                                        GDK_CROSSING_NORMAL))
        {
          xg_event->motion.x = x;
          xg_event->motion.y = y;
@@ -1954,7 +2000,11 @@ xwidget_motion_or_crossing (struct xwidget_view *view, 
const XEvent *event)
                                           (xev->type == XI_Enter
                                            ? XW_CROSSING_ENTERED
                                            : XW_CROSSING_LEFT),
-                                          xev->time, xg_event->crossing.state))
+                                          xev->time, xg_event->crossing.state,
+                                          (view->passive_grab
+                                           ? GDK_CROSSING_GRAB
+                                           : GDK_CROSSING_NORMAL),
+                                          GDK_CROSSING_NORMAL))
        {
          gdk_event_free (xg_event);
          return;
@@ -1972,7 +2022,11 @@ xwidget_motion_or_crossing (struct xwidget_view *view, 
const XEvent *event)
                                            ? XW_CROSSING_ENTERED
                                            : XW_CROSSING_LEFT),
                                           event->xcrossing.time,
-                                          event->xcrossing.state))
+                                          event->xcrossing.state,
+                                          (view->passive_grab
+                                           ? GDK_CROSSING_GRAB
+                                           : GDK_CROSSING_NORMAL),
+                                          GDK_CROSSING_NORMAL))
        {
          gdk_event_free (xg_event);
          return;



reply via email to

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