xcb_drag_prepare_cb: drain events (#3193)
As discussed in PR #3085, X11 events can appear while dragloop->callback() is running. Co-authored-by: Michael Stapelberg <michael@stapelberg.de>
This commit is contained in:
parent
f560519f5c
commit
a0309cbd52
|
@ -669,8 +669,7 @@ struct drag_x11_cb {
|
||||||
const void *extra;
|
const void *extra;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void xcb_drag_prepare_cb(EV_P_ ev_prepare *w, int revents) {
|
static bool drain_drag_events(EV_P, struct drag_x11_cb *dragloop) {
|
||||||
struct drag_x11_cb *dragloop = (struct drag_x11_cb *)w->data;
|
|
||||||
xcb_motion_notify_event_t *last_motion_notify = NULL;
|
xcb_motion_notify_event_t *last_motion_notify = NULL;
|
||||||
xcb_generic_event_t *event;
|
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) {
|
if (dragloop->result != DRAGGING) {
|
||||||
free(last_motion_notify);
|
free(last_motion_notify);
|
||||||
return;
|
ev_break(EV_A_ EVBREAK_ONE);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_motion_notify == NULL)
|
if (last_motion_notify == NULL) {
|
||||||
return;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Ensure that we are either dragging the resize handle (con is NULL) or that the
|
/* 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
|
* 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,
|
last_motion_notify->root_y,
|
||||||
dragloop->extra);
|
dragloop->extra);
|
||||||
}
|
}
|
||||||
free(last_motion_notify);
|
FREE(last_motion_notify);
|
||||||
|
|
||||||
xcb_flush(conn);
|
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);
|
main_set_x11_cb(false);
|
||||||
ev_prepare_start(main_loop, prepare);
|
ev_prepare_start(main_loop, prepare);
|
||||||
|
|
||||||
while (loop.result == DRAGGING)
|
ev_loop(main_loop, 0);
|
||||||
ev_run(main_loop, EVRUN_ONCE);
|
|
||||||
|
|
||||||
ev_prepare_stop(main_loop, prepare);
|
ev_prepare_stop(main_loop, prepare);
|
||||||
main_set_x11_cb(true);
|
main_set_x11_cb(true);
|
||||||
|
|
Loading…
Reference in New Issue