void merge_desktops(monitor_t *ms, desktop_t *ds, monitor_t *md, desktop_t *dd) { if (ds == NULL || dd == NULL || ds == dd) { return; } transfer_node(ms, ds, ds->root, md, dd, dd->focus); }
void client_message(xcb_generic_event_t *evt) { xcb_client_message_event_t *e = (xcb_client_message_event_t *) evt; if (e->type == ewmh->_NET_CURRENT_DESKTOP) { coordinates_t loc; if (ewmh_locate_desktop(e->data.data32[0], &loc)) { focus_node(loc.monitor, loc.desktop, loc.desktop->focus); } return; } coordinates_t loc; if (!locate_window(e->window, &loc)) { return; } if (e->type == ewmh->_NET_WM_STATE) { handle_state(loc.monitor, loc.desktop, loc.node, e->data.data32[1], e->data.data32[0]); handle_state(loc.monitor, loc.desktop, loc.node, e->data.data32[2], e->data.data32[0]); } else if (e->type == ewmh->_NET_ACTIVE_WINDOW) { if ((ignore_ewmh_focus && e->data.data32[0] == XCB_EWMH_CLIENT_SOURCE_TYPE_NORMAL) || loc.node == mon->desk->focus) { return; } focus_node(loc.monitor, loc.desktop, loc.node); } else if (e->type == ewmh->_NET_WM_DESKTOP) { coordinates_t dloc; if (ewmh_locate_desktop(e->data.data32[0], &dloc)) { transfer_node(loc.monitor, loc.desktop, loc.node, dloc.monitor, dloc.desktop, dloc.desktop->focus); } } else if (e->type == ewmh->_NET_CLOSE_WINDOW) { window_close(loc.node); } }
void merge_desktops(monitor_t *ms, desktop_t *ds, monitor_t *md, desktop_t *dd) { if (ds == NULL || dd == NULL || ds == dd) return; node_t *n = first_extrema(ds->root); while (n != NULL) { node_t *next = next_leaf(n, ds->root); transfer_node(ms, ds, n, md, dd, dd->focus); n = next; } }
void client_message(xcb_generic_event_t *evt) { xcb_client_message_event_t *e = (xcb_client_message_event_t *) evt; PRINTF("client message %X %u\n", e->window, e->type); if (e->type == ewmh->_NET_CURRENT_DESKTOP) { coordinates_t loc; if (ewmh_locate_desktop(e->data.data32[0], &loc)) focus_node(loc.monitor, loc.desktop, loc.desktop->focus); return; } coordinates_t loc; if (!locate_window(e->window, &loc)) return; if (e->type == ewmh->_NET_WM_STATE) { handle_state(loc.monitor, loc.desktop, loc.node, e->data.data32[1], e->data.data32[0]); handle_state(loc.monitor, loc.desktop, loc.node, e->data.data32[2], e->data.data32[0]); } else if (e->type == ewmh->_NET_ACTIVE_WINDOW) { if ((ignore_ewmh_focus && e->data.data32[0] == XCB_EWMH_CLIENT_SOURCE_TYPE_NORMAL) || loc.node == mon->desk->focus) return; if (loc.desktop->focus->client->fullscreen && loc.desktop->focus != loc.node) { set_fullscreen(loc.desktop->focus, false); arrange(loc.monitor, loc.desktop); } focus_node(loc.monitor, loc.desktop, loc.node); } else if (e->type == ewmh->_NET_WM_DESKTOP) { coordinates_t dloc; if (ewmh_locate_desktop(e->data.data32[0], &dloc)) transfer_node(loc.monitor, loc.desktop, loc.node, dloc.monitor, dloc.desktop, dloc.desktop->focus); } else if (e->type == ewmh->_NET_CLOSE_WINDOW) { window_close(loc.node); } }
void track_pointer(int root_x, int root_y) { 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(m, d, n, m, d, 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; } } bool focused = (n == mon->desk->focus); transfer_node(m, d, n, loc.monitor, loc.desktop, loc.desktop->focus); if (focused) focus_node(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; bool focused = (n == mon->desk->focus); transfer_node(m, d, n, pmon, pmon->desk, pmon->desk->focus); if (focused) focus_node(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; } }
bool move_client(coordinates_t *loc, int dx, int dy) { node_t *n = loc->node; if (n == NULL || n->client == NULL) { return false; } monitor_t *pm = NULL; if (IS_TILED(n->client)) { if (!grabbing) { return false; } xcb_window_t pwin = XCB_NONE; query_pointer(&pwin, NULL); if (pwin == n->id) { return false; } coordinates_t dst; bool is_managed = (pwin != XCB_NONE && locate_window(pwin, &dst)); if (is_managed && dst.monitor == loc->monitor && IS_TILED(dst.node->client)) { swap_nodes(loc->monitor, loc->desktop, n, loc->monitor, loc->desktop, dst.node); return true; } else { if (is_managed && dst.monitor == loc->monitor) { return false; } else { xcb_point_t pt = {0, 0}; query_pointer(NULL, &pt); pm = monitor_from_point(pt); } } } else { client_t *c = n->client; xcb_rectangle_t rect = c->floating_rectangle; int16_t x = rect.x + dx; int16_t y = rect.y + dy; if (focus_follows_pointer) { listen_enter_notify(loc->desktop->root, false); } window_move(n->id, x, y); if (focus_follows_pointer) { listen_enter_notify(loc->desktop->root, true); } c->floating_rectangle.x = x; c->floating_rectangle.y = y; if (!grabbing) { put_status(SBSC_MASK_NODE_GEOMETRY, "node_geometry 0x%08X 0x%08X 0x%08X %ux%u+%i+%i\n", loc->monitor->id, loc->desktop->id, loc->node->id, rect.width, rect.height, x, y); } pm = monitor_from_client(c); } if (pm == NULL || pm == loc->monitor) { return true; } bool focused = (n == mon->desk->focus); transfer_node(loc->monitor, loc->desktop, n, pm, pm->desk, pm->desk->focus); loc->monitor = pm; loc->desktop = pm->desk; if (focused) { focus_node(pm, pm->desk, n); } return true; }