render_con(con, false);
if (set_focus)
- con_focus(con);
+ con_activate(con);
/* Check if we need to re-assign it to a different workspace because of its
* coordinates and exit if that was done successfully. */
con_fix_percent(con->parent);
if (set_focus)
- con_focus(con);
+ con_activate(con);
floating_set_hint_atom(con, false);
ipc_send_window_event("floating", con);
Con *ws = TAILQ_FIRST(&(content->focus_head));
DLOG("Moving con %p / %s to workspace %p / %s\n", con, con->name, ws, ws->name);
con_move_to_workspace(con, ws, false, true, false);
- con_focus(con_descend_focused(con));
+ workspace_show(ws);
+ con_activate(con_descend_focused(con));
return true;
}
/* 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);
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);
/* Custom data structure used to track dragging-related events. */
struct drag_x11_cb {
- ev_check check;
+ ev_prepare prepare;
/* Whether this modal event loop should be exited and with which result. */
drag_result_t result;
const void *extra;
};
-static void xcb_drag_check_cb(EV_P_ ev_check *w, int revents) {
+static void xcb_drag_prepare_cb(EV_P_ ev_prepare *w, int revents) {
struct drag_x11_cb *dragloop = (struct drag_x11_cb *)w->data;
xcb_motion_notify_event_t *last_motion_notify = NULL;
xcb_generic_event_t *event;
if (last_motion_notify != (xcb_motion_notify_event_t *)event)
free(event);
- if (dragloop->result != DRAGGING)
+ if (dragloop->result != DRAGGING) {
+ free(last_motion_notify);
return;
+ }
}
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);
+
+ xcb_flush(conn);
}
/*
.callback = callback,
.extra = extra,
};
- ev_check *check = &loop.check;
+ ev_prepare *prepare = &loop.prepare;
if (con)
loop.old_rect = con->rect;
- ev_check_init(check, xcb_drag_check_cb);
- check->data = &loop;
+ ev_prepare_init(prepare, xcb_drag_prepare_cb);
+ prepare->data = &loop;
main_set_x11_cb(false);
- ev_check_start(main_loop, check);
+ ev_prepare_start(main_loop, prepare);
while (loop.result == DRAGGING)
ev_run(main_loop, EVRUN_ONCE);
- ev_check_stop(main_loop, check);
+ ev_prepare_stop(main_loop, prepare);
main_set_x11_cb(true);
xcb_ungrab_keyboard(conn, XCB_CURRENT_TIME);
* outputs.
*
*/
-void floating_reposition(Con *con, Rect newrect) {
+bool floating_reposition(Con *con, Rect newrect) {
/* Sanity check: Are the new coordinates on any output? If not, we
* ignore that request. */
if (!contained_by_output(newrect)) {
ELOG("No output found at destination coordinates. Not repositioning.\n");
- return;
+ return false;
}
con->rect = newrect;
con->scratchpad_state = SCRATCHPAD_CHANGED;
tree_render();
+ return true;
}
/*