aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/wm/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cmd/wm/client.c')
-rw-r--r--sys/cmd/wm/client.c118
1 files changed, 92 insertions, 26 deletions
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);
+}