void draw_presel_feedback(monitor_t *m, desktop_t *d, node_t *n) { if (n == NULL || n->presel == NULL || d->layout == LAYOUT_MONOCLE) { return; } if (focus_follows_pointer) { listen_enter_notify(d->root, false); } bool exists = (n->presel->feedback != XCB_NONE); if (!exists) { initialize_presel_feedback(n); } int gap = gapless_monocle && IS_MONOCLE(d) ? 0 : d->window_gap; presel_t *p = n->presel; xcb_rectangle_t rect = n->rectangle; rect.x = rect.y = 0; rect.width -= gap; rect.height -= gap; xcb_rectangle_t presel_rect = rect; switch (p->split_dir) { case DIR_NORTH: presel_rect.height = p->split_ratio * rect.height; break; case DIR_EAST: presel_rect.width = (1 - p->split_ratio) * rect.width; presel_rect.x = rect.width - presel_rect.width; break; case DIR_SOUTH: presel_rect.height = (1 - p->split_ratio) * rect.height; presel_rect.y = rect.height - presel_rect.height; break; case DIR_WEST: presel_rect.width = p->split_ratio * rect.width; break; } window_move_resize(p->feedback, n->rectangle.x + presel_rect.x, n->rectangle.y + presel_rect.y, presel_rect.width, presel_rect.height); if (!exists && m->desk == d) { window_show(p->feedback); } if (focus_follows_pointer) { listen_enter_notify(d->root, true); } }
void handle_presel_feedbacks(monitor_t *m, desktop_t *d) { if (m->desk != d) { return; } if (focus_follows_pointer) { listen_enter_notify(d->root, false); } if (d->layout == LAYOUT_MONOCLE) { hide_presel_feedbacks(m, d, d->root); } else { show_presel_feedbacks(m, d, d->root); } if (focus_follows_pointer) { listen_enter_notify(d->root, true); } }
void focus_desktop(monitor_t *m, desktop_t *d) { bool changed = (m != mon || m->desk != d); focus_monitor(m); if (m->desk != d) { if (focus_follows_pointer) { listen_enter_notify(d->root, false); } show_desktop(d); hide_desktop(m->desk); if (focus_follows_pointer) { listen_enter_notify(d->root, true); } m->desk = d; } if (changed) { ewmh_update_current_desktop(); put_status(SBSC_MASK_DESKTOP_FOCUS, "desktop_focus 0x%08X 0x%08X\n", m->id, d->id); } }
bool resize_client(coordinates_t *loc, resize_handle_t rh, int dx, int dy) { node_t *n = loc->node; if (n == NULL || n->client == NULL || n->client->state == STATE_FULLSCREEN) { return false; } node_t *horizontal_fence = NULL, *vertical_fence = NULL; xcb_rectangle_t rect = get_rectangle(NULL, n); uint16_t width = rect.width, height = rect.height; int16_t x = rect.x, y = rect.y; if (n->client->state == STATE_TILED) { if (rh & HANDLE_LEFT) { vertical_fence = find_fence(n, DIR_WEST); } else if (rh & HANDLE_RIGHT) { vertical_fence = find_fence(n, DIR_EAST); } if (rh & HANDLE_TOP) { horizontal_fence = find_fence(n, DIR_NORTH); } else if (rh & HANDLE_BOTTOM) { horizontal_fence = find_fence(n, DIR_SOUTH); } if (vertical_fence == NULL && horizontal_fence == NULL) { return false; } if (vertical_fence != NULL) { double sr = vertical_fence->split_ratio + (double) dx / vertical_fence->rectangle.width; sr = MAX(0, sr); sr = MIN(1, sr); vertical_fence->split_ratio = sr; } if (horizontal_fence != NULL) { double sr = horizontal_fence->split_ratio + (double) dy / horizontal_fence->rectangle.height; sr = MAX(0, sr); sr = MIN(1, sr); horizontal_fence->split_ratio = sr; } arrange(loc->monitor, loc->desktop); } else { int w = width + dx * (rh & HANDLE_LEFT ? -1 : (rh & HANDLE_RIGHT ? 1 : 0)); int h = height + dy * (rh & HANDLE_TOP ? -1 : (rh & HANDLE_BOTTOM ? 1 : 0)); width = MAX(1, w); height = MAX(1, h); apply_size_hints(n->client, &width, &height); if (rh & HANDLE_LEFT) { x += rect.width - width; } if (rh & HANDLE_TOP) { y += rect.height - height; } n->client->floating_rectangle = (xcb_rectangle_t) {x, y, width, height}; if (n->client->state == STATE_FLOATING) { if (focus_follows_pointer) { listen_enter_notify(loc->desktop->root, false); } window_move_resize(n->id, x, y, width, height); if (focus_follows_pointer) { listen_enter_notify(loc->desktop->root, true); } 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, width, height, x, y); } } else { arrange(loc->monitor, loc->desktop); } } return true; }
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; }