From d69354eedb0b25767293b7aac9ab32def01005f3 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Mon, 4 Oct 2021 07:18:56 -0700 Subject: checkin(wm) --- sys/cmd/wm/client.c | 118 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 92 insertions(+), 26 deletions(-) (limited to 'sys/cmd/wm/client.c') diff --git a/sys/cmd/wm/client.c b/sys/cmd/wm/client.c index 2a8c0c0..4132468 100644 --- a/sys/cmd/wm/client.c +++ b/sys/cmd/wm/client.c @@ -1,14 +1,16 @@ #include "wm.h" +static char broken[] = "broken"; + void -focus(Client *client, struct wlr_surface *new) +focus(Client *client, struct wlr_surface *new, int lift) { struct wlr_seat *seat; struct wlr_surface *old; struct wlr_xdg_surface *xdg; struct wlr_keyboard *keyboard; - if(client) { + if(client && lift) { wl_list_remove(&client->stack); wl_list_insert(&server.client.stack, &client->stack); } @@ -19,6 +21,13 @@ focus(Client *client, struct wlr_surface *new) if(old==new) return; + if(client) { + wl_list_remove(&client->focus); + wl_list_insert(&server.client.focus, &client->focus); + server.monitor.selected = client->monitor; + client->isurgent = 0; + } + if(old) { xdg = wlr_xdg_surface_from_wlr_surface(seat->keyboard_state.focused_surface); wlr_xdg_toplevel_set_activated(xdg, false); @@ -43,7 +52,7 @@ focus(Client *client, struct wlr_surface *new) 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; + double x, y, vsx = lx - client->geometry.x, vsy = ly - client->geometry.y; struct wlr_surface *find = nil; find = wlr_xdg_surface_surface_at(client->xdg, vsx, vsy, &x, &y); @@ -82,20 +91,20 @@ setinteractive(Client *client, int mode, uint32 edges) { 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; + server.grab.x = server.cursor.dot->x - client->geometry.x; + server.grab.y = server.cursor.dot->y - client->geometry.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); + bx = (client->geometry.x + box.x) + ((edges & WLR_EDGE_RIGHT) ? box.width : 0); + by = (client->geometry.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.grab.box.x += client->geometry.x; + server.grab.box.y += client->geometry.y; server.resize = edges; } @@ -105,17 +114,17 @@ 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; + client->geometry.width = MAX(1, client->geometry.width); + client->geometry.height = MAX(1, client->geometry.height); + + if(client->geometry.x >= box->x + box->width) + client->geometry.x = box->x + box->width - client->geometry.width; + if(client->geometry.y >= box->y + box->height) + client->geometry.y = box->y + box->height - client->geometry.height; + if(client->geometry.x + client->geometry.width + 2*client->border <= box->x) + client->geometry.x = box->x; + if(client->geometry.y + client->geometry.height + 2*client->border <= box->y) + client->geometry.y = box->y; } void @@ -123,15 +132,72 @@ 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; + client->geometry.x = x; + client->geometry.y = y; + client->geometry.width = w; + client->geometry.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 + client->geometry.width - 2*client->border, + client->geometry.height - 2*client->border ); } + +void +attach_to(Client *client, Monitor *monitor, uint tags) +{ + struct wlr_surface *surface; + Monitor *old = client->monitor; + + if(old == monitor) + return; + client->monitor = monitor; + + if(old) { + wlr_surface_send_leave(client->xdg->surface, old->output); + arrange(old); + } + + if(monitor) { + /* make sure window actually overlaps with the monitor */ + apply_bounds(client, &monitor->geometry); + wlr_surface_send_enter(client->xdg->surface, monitor->output); + client->tags = tags ? tags : monitor->tag.set[monitor->tag.selected]; + arrange(monitor); + } + + surface = server.input.seat->keyboard_state.focused_surface; + focus(focused_client(server.monitor.selected), surface, 1); +} + +void +apply_rules(Client *client) +{ + /* rule matching */ + char *id, *title; + uint i, tags; + Rule *rule; + Monitor *monitor, *it; + + monitor = server.monitor.selected; + + if (!(id=client->xdg->toplevel->app_id)) + id = broken; + if (!(title=client->xdg->toplevel->title)) + title = broken; + + for(tags=0, rule=cfg·rule; rule != cfg·endrule; ++rule) { + if ((!rule->title || strstr(title, rule->title)) + && (!rule->id || strstr(id, rule->id))) { + client->isfloating = rule->isfloating; + tags |= rule->tags; + i = 0; + wl_list_for_each(it, &server.monitor.list, link) + if(rule->monitor == i++) + monitor = it; + } + } + attach_to(client, monitor, tags); +} -- cgit v1.2.1