]> git.sur5r.net Git - i3/i3/commitdiff
xcb_drag_prepare_cb: drain events (#3193)
authorOrestis <orestisf1993@gmail.com>
Mon, 26 Mar 2018 15:59:34 +0000 (18:59 +0300)
committerMichael Stapelberg <stapelberg@users.noreply.github.com>
Mon, 26 Mar 2018 15:59:34 +0000 (17:59 +0200)
As discussed in PR #3085, X11 events can appear while
dragloop->callback() is running.

Co-authored-by: Michael Stapelberg <michael@stapelberg.de>
src/floating.c

index fc68df8e6b587482ab5043751a56bc711c23db85..1bc4996a17c407868ff4e12d6e3be16463fd5b45 100644 (file)
@@ -669,8 +669,7 @@ struct drag_x11_cb {
     const void *extra;
 };
 
-static void xcb_drag_prepare_cb(EV_P_ ev_prepare *w, int revents) {
-    struct drag_x11_cb *dragloop = (struct drag_x11_cb *)w->data;
+static bool drain_drag_events(EV_P, struct drag_x11_cb *dragloop) {
     xcb_motion_notify_event_t *last_motion_notify = NULL;
     xcb_generic_event_t *event;
 
@@ -731,12 +730,14 @@ static void xcb_drag_prepare_cb(EV_P_ ev_prepare *w, int revents) {
 
         if (dragloop->result != DRAGGING) {
             free(last_motion_notify);
-            return;
+            ev_break(EV_A_ EVBREAK_ONE);
+            return true;
         }
     }
 
-    if (last_motion_notify == NULL)
-        return;
+    if (last_motion_notify == NULL) {
+        return true;
+    }
 
     /* Ensure that we are either dragging the resize handle (con is NULL) or that the
      * container still exists. The latter might not be true, e.g., if the window closed
@@ -749,9 +750,17 @@ static void xcb_drag_prepare_cb(EV_P_ ev_prepare *w, int revents) {
             last_motion_notify->root_y,
             dragloop->extra);
     }
-    free(last_motion_notify);
+    FREE(last_motion_notify);
 
     xcb_flush(conn);
+    return false;
+}
+
+static void xcb_drag_prepare_cb(EV_P_ ev_prepare *w, int revents) {
+    struct drag_x11_cb *dragloop = (struct drag_x11_cb *)w->data;
+    while (!drain_drag_events(EV_A, dragloop)) {
+        /* repeatedly drain events: draining might produce additional ones */
+    }
 }
 
 /*
@@ -826,8 +835,7 @@ drag_result_t drag_pointer(Con *con, const xcb_button_press_event_t *event, xcb_
     main_set_x11_cb(false);
     ev_prepare_start(main_loop, prepare);
 
-    while (loop.result == DRAGGING)
-        ev_run(main_loop, EVRUN_ONCE);
+    ev_loop(main_loop, 0);
 
     ev_prepare_stop(main_loop, prepare);
     main_set_x11_cb(true);