#include "wm.h" void focus(Client *client, struct wlr_surface *new) { struct wlr_seat *seat; struct wlr_surface *old; struct wlr_xdg_surface *xdg; struct wlr_keyboard *keyboard; if(client) { wl_list_remove(&client->stack); wl_list_insert(&server.client.stack, &client->stack); } seat = server.input.seat; old = seat->keyboard_state.focused_surface; if(old==new) return; if(old) { xdg = wlr_xdg_surface_from_wlr_surface(seat->keyboard_state.focused_surface); wlr_xdg_toplevel_set_activated(xdg, false); } if(!client) { wlr_seat_keyboard_notify_clear_focus(seat); return; } keyboard = wlr_seat_get_keyboard(seat); wlr_seat_keyboard_notify_enter(seat, client->xdg->surface, keyboard->keycodes, keyboard->num_keycodes, &keyboard->modifiers ); wlr_xdg_toplevel_set_activated(client->xdg, true); } int client_has(Client *client, double lx, double ly, struct wlr_surface **surface, double *sx, double *sy) { double x, y, vsx = lx - client->geo.x, vsy = ly - client->geo.y; struct wlr_surface *find = nil; find = wlr_xdg_surface_surface_at(client->xdg, vsx, vsy, &x, &y); if(find) { *sx = x; *sy = y; *surface = find; return true; } return false; } Client* client_at(double lx, double ly, struct wlr_surface **surface, double *sx, double *sy) { Client *it; wl_list_for_each(it, &server.client.list, link) { if(client_has(it, lx, ly, surface, sx, sy)) return it; } return nil; } void setinteractive(Client *client, int mode, uint32 edges) { double bx, by; struct wlr_box box; struct wlr_surface *focused = server.input.seat->pointer_state.focused_surface; if(client->xdg->surface != focused) return; server.grab.client = client; server.cursor.mode = mode; if(mode == CursorMove) { server.grab.x = server.cursor.dot->x - client->geo.x; server.grab.y = server.cursor.dot->y - client->geo.y; } else { wlr_xdg_surface_get_geometry(client->xdg, &box); bx = (client->geo.x + box.x) + ((edges & WLR_EDGE_RIGHT) ? box.width : 0); by = (client->geo.y + box.y) + ((edges & WLR_EDGE_BOTTOM) ? box.height : 0); server.grab.x = server.cursor.dot->x - bx; server.grab.y = server.cursor.dot->y - by; server.grab.box = box; server.grab.box.x += client->geo.x; server.grab.box.y += client->geo.y; server.resize = edges; } } static void apply_bounds(Client *client, struct wlr_box *box) { client->geo.width = MAX(1, client->geo.width); client->geo.height = MAX(1, client->geo.height); if(client->geo.x >= box->x + box->width) client->geo.x = box->x + box->width - client->geo.width; if(client->geo.y >= box->y + box->height) client->geo.y = box->y + box->height - client->geo.height; if(client->geo.x + client->geo.width + 2*client->border <= box->x) client->geo.x = box->x; if(client->geo.y + client->geo.height + 2*client->border <= box->y) client->geo.y = box->y; } void resize(Client *client, int x, int y, int w, int h, int interact) { struct wlr_box *box = interact ? &server.monitor.geometry : &client->monitor->window; client->geo.x = x; client->geo.y = y; client->geo.width = w; client->geo.height = h; apply_bounds(client, box); client->resize = wlr_xdg_toplevel_set_size(client->xdg, client->geo.width - 2*client->border, client->geo.height - 2*client->border ); }