#endif
/**
- * This is the return value of a drag operation like drag_pointer. DRAG_CANCEL
- * will indicate the intention of the drag should not be carried out, or that
- * the drag actions should be undone.
+ * This is the return value of a drag operation like drag_pointer.
+ *
+ * DRAGGING will indicate the drag action is still in progress and can be
+ * continued or resolved.
+ *
+ * DRAG_SUCCESS will indicate the intention of the drag action should be
+ * carried out.
+ *
+ * DRAG_REVERT will indicate an attempt should be made to restore the state of
+ * the involved windows to their condition before the drag.
+ *
+ * DRAG_ABORT will indicate that the intention of the drag action cannot be
+ * carried out (e.g. because the window has been unmapped).
*
*/
-typedef enum { DRAG_SUCCESS = 0, DRAG_CANCEL } drag_result_t;
+typedef enum {
+ DRAGGING = 0,
+ DRAG_SUCCESS,
+ DRAG_REVERT,
+ DRAG_ABORT
+} drag_result_t;
/**
* This function grabs your pointer and keyboard and lets you drag stuff around
* after the user releases the mouse button */
tree_render();
- /* Store the initial rect in case of user cancel */
+ /* Store the initial rect in case of user revert/cancel */
Rect initial_rect = con->rect;
/* 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 the user cancelled, undo the changes. */
- if (drag_result == DRAG_CANCEL)
+ if (drag_result == DRAG_REVERT)
floating_reposition(con, initial_rect);
/* If this is a scratchpad window, don't auto center it from now on. */
struct resize_window_callback_params params = { corner, proportional, event };
- /* get the initial rect in case of cancel */
+ /* get the initial rect in case of revert/cancel */
Rect initial_rect = con->rect;
drag_result_t drag_result = drag_pointer(con, event, XCB_NONE, BORDER_TOP /* irrelevant */, cursor, resize_window_callback, ¶ms);
/* If the user cancels, undo the resize */
- if (drag_result == DRAG_CANCEL)
+ if (drag_result == DRAG_REVERT)
floating_reposition(con, initial_rect);
/* If this is a scratchpad window, don't auto center it from now on. */
if ((reply = xcb_grab_pointer_reply(conn, cookie, NULL)) == NULL) {
ELOG("Could not grab pointer\n");
- return DRAG_CANCEL;
+ return DRAG_ABORT;
}
free(reply);
if ((keyb_reply = xcb_grab_keyboard_reply(conn, keyb_cookie, NULL)) == NULL) {
ELOG("Could not grab keyboard\n");
- return DRAG_CANCEL;
+ return DRAG_ABORT;
}
free(keyb_reply);
xcb_flush(conn);
xcb_generic_event_t *inside_event, *last_motion_notify = NULL;
- bool loop_done = false;
- /* The return value, set to DRAG_CANCEL on user cancel */
- drag_result_t drag_result = DRAG_SUCCESS;
+ drag_result_t drag_result = DRAGGING;
/* I’ve always wanted to have my own eventhandler… */
- while (!loop_done && (inside_event = xcb_wait_for_event(conn))) {
+ while (drag_result == DRAGGING && (inside_event = xcb_wait_for_event(conn))) {
/* We now handle all events we can get using xcb_poll_for_event */
do {
/* skip x11 errors */
switch (type) {
case XCB_BUTTON_RELEASE:
- loop_done = true;
+ drag_result = DRAG_SUCCESS;
break;
case XCB_MOTION_NOTIFY:
case XCB_UNMAP_NOTIFY:
DLOG("Unmap-notify, aborting\n");
+ drag_result = DRAG_ABORT;
+
handle_event(type, inside_event);
- loop_done = true;
- drag_result = DRAG_CANCEL;
break;
case XCB_KEY_PRESS:
/* Cancel the drag if a key was pressed */
- DLOG("A key was pressed during drag, canceling.");
- loop_done = true;
- drag_result = DRAG_CANCEL;
+ DLOG("A key was pressed during drag, reverting changes.");
+ drag_result = DRAG_REVERT;
handle_event(type, inside_event);
break;
free(inside_event);
} while ((inside_event = xcb_poll_for_event(conn)) != NULL);
- if (last_motion_notify == NULL || loop_done)
+ if (last_motion_notify == NULL || drag_result != DRAGGING)
continue;
new_x = ((xcb_motion_notify_event_t*)last_motion_notify)->root_x;