From be9a2bb7f8ffac4c360b272cd5717bc158c0bb74 Mon Sep 17 00:00:00 2001 From: Orestis Floros Date: Fri, 22 Sep 2017 19:22:48 +0300 Subject: [PATCH 1/2] Add con_exists function Checks the all_cons queue and returns true if a given con is found. --- include/con.h | 7 +++++++ src/con.c | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/include/con.h b/include/con.h index 69292411..b88ea354 100644 --- a/include/con.h +++ b/include/con.h @@ -165,6 +165,13 @@ Con *con_by_window_id(xcb_window_t window); */ Con *con_by_con_id(long target); +/** + * Returns true if the given container (still) exists. + * This can be used, e.g., to make sure a container hasn't been closed in the meantime. + * + */ +bool con_exists(Con *con); + /** * Returns the container with the given frame ID or NULL if no such container * exists. diff --git a/src/con.c b/src/con.c index 29a326e7..e0901443 100644 --- a/src/con.c +++ b/src/con.c @@ -597,6 +597,15 @@ Con *con_by_con_id(long target) { return NULL; } +/* + * Returns true if the given container (still) exists. + * This can be used, e.g., to make sure a container hasn't been closed in the meantime. + * + */ +bool con_exists(Con *con) { + return con_by_con_id((long)con) != NULL; +} + /* * Returns the container with the given frame ID or NULL if no such container * exists. From 414d23fb7a8b09598dbf679baa56ae269e8e35a2 Mon Sep 17 00:00:00 2001 From: Orestis Floros Date: Fri, 22 Sep 2017 19:25:02 +0300 Subject: [PATCH 2/2] Check container existance during drag events This fixes a crash that occurs when disabling floating for a container while it is being moved or resized. @Deiz describes the problem: > It occurs because the command that disables floating runs before the event loop. So, the window is tiled, its floating parent is destroyed, but then a key event is handled which causes the position/size of the now-destroyed parent to be modified. Fixes #1627 --- src/floating.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/floating.c b/src/floating.c index f2994339..6a953132 100644 --- a/src/floating.c +++ b/src/floating.c @@ -531,6 +531,11 @@ void floating_drag_window(Con *con, const xcb_button_press_event_t *event) { /* Drag the window */ drag_result_t drag_result = drag_pointer(con, event, XCB_NONE, BORDER_TOP /* irrelevant */, XCURSOR_CURSOR_MOVE, drag_window_callback, event); + if (!con_exists(con)) { + DLOG("The container has been closed in the meantime.\n"); + return; + } + /* If the user cancelled, undo the changes. */ if (drag_result == DRAG_REVERT) floating_reposition(con, initial_rect); @@ -642,6 +647,11 @@ void floating_resize_window(Con *con, const bool proportional, drag_result_t drag_result = drag_pointer(con, event, XCB_NONE, BORDER_TOP /* irrelevant */, cursor, resize_window_callback, ¶ms); + if (!con_exists(con)) { + DLOG("The container has been closed in the meantime.\n"); + return; + } + /* If the user cancels, undo the resize */ if (drag_result == DRAG_REVERT) floating_reposition(con, initial_rect); @@ -739,12 +749,17 @@ static void xcb_drag_check_cb(EV_P_ ev_check *w, int revents) { if (last_motion_notify == NULL) return; - dragloop->callback( - dragloop->con, - &(dragloop->old_rect), - last_motion_notify->root_x, - last_motion_notify->root_y, - dragloop->extra); + /* 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 + * for any reason while the user was dragging it. */ + if (!dragloop->con || con_exists(dragloop->con)) { + dragloop->callback( + dragloop->con, + &(dragloop->old_rect), + last_motion_notify->root_x, + last_motion_notify->root_y, + dragloop->extra); + } free(last_motion_notify); }