+ if (frozen_pointer->action == ACTION_NONE)
+ return;
+
+ int16_t delta_x, delta_y, x = 0, y = 0, w = 1, h = 1;
+ uint16_t width, height;
+
+ pointer_action_t pac = frozen_pointer->action;
+ monitor_t *m = frozen_pointer->monitor;
+ desktop_t *d = frozen_pointer->desktop;
+ node_t *n = frozen_pointer->node;
+ client_t *c = frozen_pointer->client;
+ xcb_window_t win = frozen_pointer->window;
+ xcb_rectangle_t rect = frozen_pointer->rectangle;
+ node_t *vertical_fence = frozen_pointer->vertical_fence;
+ node_t *horizontal_fence = frozen_pointer->horizontal_fence;
+
+ delta_x = root_x - frozen_pointer->position.x;
+ delta_y = root_y - frozen_pointer->position.y;
+
+ switch (pac) {
+ case ACTION_MOVE:
+ if (frozen_pointer->is_tiled) {
+ xcb_window_t pwin = XCB_NONE;
+ query_pointer(&pwin, NULL);
+ if (pwin == win)
+ return;
+ coordinates_t loc;
+ bool is_managed = (pwin == XCB_NONE ? false : locate_window(pwin, &loc));
+ if (is_managed && is_tiled(loc.node->client) && loc.monitor == m) {
+ swap_nodes(n, loc.node);
+ arrange(m, d);
+ } else {
+ if (is_managed && loc.monitor == m) {
+ return;
+ } else if (!is_managed) {
+ xcb_point_t pt = (xcb_point_t) {root_x, root_y};
+ monitor_t *pmon = monitor_from_point(pt);
+ if (pmon == NULL || pmon == m) {
+ return;
+ } else {
+ loc.monitor = pmon;
+ loc.desktop = pmon->desk;
+ }
+ }
+ transfer_node(m, d, loc.monitor, loc.desktop, n);
+ frozen_pointer->monitor = loc.monitor;
+ frozen_pointer->desktop = loc.desktop;
+ }
+ } else {
+ x = rect.x + delta_x;
+ y = rect.y + delta_y;
+ window_move(win, x, y);
+ c->floating_rectangle.x = x;
+ c->floating_rectangle.y = y;
+ xcb_point_t pt = (xcb_point_t) {root_x, root_y};
+ monitor_t *pmon = monitor_from_point(pt);
+ if (pmon == NULL || pmon == m)
+ return;
+ transfer_node(m, d, pmon, pmon->desk, n);
+ frozen_pointer->monitor = pmon;
+ frozen_pointer->desktop = pmon->desk;
+ }
+ break;
+ case ACTION_RESIZE_SIDE:
+ case ACTION_RESIZE_CORNER:
+ if (frozen_pointer->is_tiled) {
+ if (vertical_fence != NULL) {
+ double sr = frozen_pointer->vertical_ratio + (double) delta_x / vertical_fence->rectangle.width;
+ sr = MAX(0, sr);
+ sr = MIN(1, sr);
+ vertical_fence->split_ratio = sr;
+ }
+ if (horizontal_fence != NULL) {
+ double sr = frozen_pointer->horizontal_ratio + (double) delta_y / horizontal_fence->rectangle.height;
+ sr = MAX(0, sr);
+ sr = MIN(1, sr);
+ horizontal_fence->split_ratio = sr;
+ }
+ arrange(mon, mon->desk);
+ } else {
+ if (pac == ACTION_RESIZE_SIDE) {
+ switch (frozen_pointer->side) {
+ case SIDE_TOP:
+ x = rect.x;
+ y = rect.y + delta_y;
+ w = rect.width;
+ h = rect.height - delta_y;
+ break;
+ case SIDE_RIGHT:
+ x = rect.x;
+ y = rect.y;
+ w = rect.width + delta_x;
+ h = rect.height;
+ break;
+ case SIDE_BOTTOM:
+ x = rect.x;
+ y = rect.y;
+ w = rect.width;
+ h = rect.height + delta_y;
+ break;
+ case SIDE_LEFT:
+ x = rect.x + delta_x;
+ y = rect.y;
+ w = rect.width - delta_x;
+ h = rect.height;
+ break;
+ }
+ width = MAX(1, w);
+ height = MAX(1, h);
+ window_move_resize(win, x, y, width, height);
+ c->floating_rectangle = (xcb_rectangle_t) {x, y, width, height};
+ window_draw_border(n, d->focus == n, mon == m);
+ } else if (pac == ACTION_RESIZE_CORNER) {
+ switch (frozen_pointer->corner) {
+ case CORNER_TOP_LEFT:
+ x = rect.x + delta_x;
+ y = rect.y + delta_y;
+ w = rect.width - delta_x;
+ h = rect.height - delta_y;
+ break;
+ case CORNER_TOP_RIGHT:
+ x = rect.x;
+ y = rect.y + delta_y;
+ w = rect.width + delta_x;
+ h = rect.height - delta_y;
+ break;
+ case CORNER_BOTTOM_LEFT:
+ x = rect.x + delta_x;
+ y = rect.y;
+ w = rect.width - delta_x;
+ h = rect.height + delta_y;
+ break;
+ case CORNER_BOTTOM_RIGHT:
+ x = rect.x;
+ y = rect.y;
+ w = rect.width + delta_x;
+ h = rect.height + delta_y;
+ break;
+ }
+ width = MAX(1, w);
+ height = MAX(1, h);
+ window_move_resize(win, x, y, width, height);
+ c->floating_rectangle = (xcb_rectangle_t) {x, y, width, height};
+ window_draw_border(n, d->focus == n, mon == m);
+ }
+ }
+ break;
+ case ACTION_FOCUS:
+ case ACTION_NONE:
+ break;