From 0a8f62d8c7116be9e344f351df679599908fb29c Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Thu, 4 Jun 2020 19:10:07 -0700 Subject: refactored --- sys/cmd/dwm/client.c | 254 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 sys/cmd/dwm/client.c (limited to 'sys/cmd/dwm/client.c') diff --git a/sys/cmd/dwm/client.c b/sys/cmd/dwm/client.c new file mode 100644 index 0000000..cc9730b --- /dev/null +++ b/sys/cmd/dwm/client.c @@ -0,0 +1,254 @@ +#include "dwm.h" + +#define WLR_EDGE_ALL WLR_EDGE_TOP|WLR_EDGE_BOTTOM|WLR_EDGE_LEFT|WLR_EDGE_RIGHT + + +/* local callbacks */ +static void map(struct wl_listener *ev, void *arg); +static void unmap(struct wl_listener *ev, void *arg); +static void delete(struct wl_listener *ev, void *arg); + +/* globals */ +static char *broken = ""; + +// ----------------------------------------------------------------------- +// methods + +void +applybounds(Client *c, struct wlr_box *bbox) +{ + c->dim.width = MAX(1, c->dim.width); + c->dim.height = MAX(1, c->dim.height); + + if (c->dim.x >= bbox->x + bbox->width) + c->dim.x = bbox->x + bbox->width - c->dim.width; + if (c->dim.y >= bbox->y + bbox->height) + c->dim.y = bbox->y + bbox->height - c->dim.height; + if (c->dim.x + c->dim.width + 2 * c->bw <= bbox->x) + c->dim.x = bbox->x; + if (c->dim.y + c->dim.height + 2 * c->bw <= bbox->y) + c->dim.y = bbox->y; +} + +void +applyrules(Client *c) +{ + char *id, *title; + uint i, newtags = 0; + const Rule *r; + Monitor *m, *it; + + m = monitor; + /* rule matching */ + c->floating = 0; + if (!(id = c->surf->toplevel->app_id)) + id = broken; + if (!(title = c->surf->toplevel->title)) + title = broken; + + for (r = apprules; r < arrend(apprules); r++) { + if ((!r->title || strstr(title, r->title)) + && (!r->id || strstr(id, r->id))) + { + c->floating = r->floating; + newtags |= r->tags; + i = 0; + wl_list_for_each(it, &dwm.odevs, link) + if (r->monitor == i++) + m = it; + } + } + setmonitor(c, m, newtags); +} + +void +resize(Client *c, int x, int y, int w, int h, int interact) +{ + struct wlr_box *bbox; + + bbox = interact ? &dwm.dim : &c->m->area.win; + c->dim.x = x; + c->dim.y = y; + c->dim.width = w; + c->dim.height = h; + + applybounds(c, bbox); + /* wlroots makes this a no-op if size hasn't changed */ + wlr_xdg_toplevel_set_size(c->surf, c->dim.width - 2*c->bw - gapwidth, c->dim.height - 2*c->bw - gapwidth); +} + +Client * +getclient(void) +{ + Client *c; + + c = wl_container_of(dwm.focus.next, c, link.focus); + if (wl_list_empty(&dwm.focus) || !VISIBLEON(c, monitor)) + return nil; + + return c; +} + +Client * +clientat(double x, double y) +{ + Client *c; + wl_list_for_each(c, &dwm.stack, link.stack) + if (VISIBLEON(c, c->m) && wlr_box_contains_point(&c->dim, x, y)) + return c; + return nil; +} + + +Client * +lastfocus(void) +{ + Client *c; + wl_list_for_each(c, &dwm.focus, link.focus) + if (VISIBLEON(c, monitor)) + return c; + + return nil; +} + +void +setfocus(Client *c, struct wlr_surface *surf, int lift) +{ + struct wlr_surface *prev_surface; + struct wlr_xdg_surface *prev; + struct wlr_keyboard *kb; + + if (c) { + if (!surf) + surf = c->surf->surface; + monitor = c->m; + } + + prev_surface = dwm.seat->keyboard_state.focused_surface; + if (prev_surface == surf) + return; + + if (prev_surface) { + prev = wlr_xdg_surface_from_wlr_surface(dwm.seat->keyboard_state.focused_surface); + wlr_xdg_toplevel_set_activated(prev, 0); + } + + kb = wlr_seat_get_keyboard(dwm.seat); + wlr_seat_keyboard_notify_enter(dwm.seat, surf, kb->keycodes, kb->num_keycodes, &kb->modifiers); + + if (c) { + wl_list_remove(&c->link.focus); + wl_list_insert(&dwm.focus, &c->link.focus); + if (lift) { + wl_list_remove(&c->link.stack); + wl_list_insert(&dwm.stack, &c->link.stack); + } + wlr_xdg_toplevel_set_activated(c->surf, 1); + } +} + +void +setfloating(Client *c, int f) +{ + if (c->floating == f) + return; + + c->floating = f; + arrange(c->m); +} + +void +pointerfocus(Client *c, struct wlr_surface *surf, double sx, double sy, uint32 time) +{ + if (c && !surf) + surf = c->surf->surface; + + if (surf && surf == dwm.seat->pointer_state.focused_surface) { + wlr_seat_pointer_notify_motion(dwm.seat, time, sx, sy); + return; + } + + wlr_seat_pointer_notify_enter(dwm.seat, surf, sx, sy); + /* If keyboard focus follows mouse, enforce that */ + if (sloppyfocus && surf) + setfocus(c, surf, 0); +} + + +// ----------------------------------------------------------------------- +// callback function implementations + +/* xdg-surfaces */ +void +ev·newclient(struct wl_listener *ev, void *arg) +{ + Client *c; + struct wlr_xdg_surface *surf; + + surf = arg; + if (surf->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) + return; + + c = surf->data = calloc(1, sizeof(*c)); + c->surf = surf; + c->bw = borderwidth; + + wlr_xdg_toplevel_set_tiled(surf, WLR_EDGE_ALL); + + /* install callbacks */ + c->ev.map.notify = map; + c->ev.unmap.notify = unmap; + c->ev.free.notify = delete; + + wl_signal_add(&surf->events.map, &c->ev.map); + wl_signal_add(&surf->events.unmap, &c->ev.unmap); + wl_signal_add(&surf->events.destroy, &c->ev.free); +} + +static +void +map(struct wl_listener *ev, void *arg) +{ + Client *c; + + c = wl_container_of(ev, c, ev.map); + + wl_list_insert(&dwm.tiles, &c->link.tiles); + wl_list_insert(&dwm.focus, &c->link.focus); + wl_list_insert(&dwm.stack, &c->link.stack); + + wlr_xdg_surface_get_geometry(c->surf, &c->dim); + + c->dim.width += 2 * c->bw; + c->dim.height += 2 * c->bw; + + applyrules(c); +} + +static +void +unmap(struct wl_listener *ev, void *arg) +{ + Monitor *m; + Client *c; + + c = wl_container_of(ev, c, ev.unmap); + m = c->m; + setmonitor(c, nil, 0); + + wl_list_remove(&c->link.tiles); + wl_list_remove(&c->link.stack); + wl_list_remove(&c->link.focus); + + c->surf = nil; + arrange(m); +} + +static +void +delete(struct wl_listener *ev, void *arg) +{ + Client *c; + c = wl_container_of(ev, c, ev.free); + free(c); +} -- cgit v1.2.1