From c85ebc8fe50be0ba7e87d21302337b5263052741 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Thu, 4 Jun 2020 15:04:56 -0700 Subject: fix: issue with freeing clients --- sys/cmd/dway/config.h | 3 +- sys/cmd/dway/dway.c | 224 +++++++++++++++++++++++++++++++++++++------------- sys/cmd/dway/dway.h | 41 +++++++-- 3 files changed, 202 insertions(+), 66 deletions(-) (limited to 'sys') diff --git a/sys/cmd/dway/config.h b/sys/cmd/dway/config.h index 5ac665a..cd27147 100644 --- a/sys/cmd/dway/config.h +++ b/sys/cmd/dway/config.h @@ -2,6 +2,7 @@ static const int sloppyfocus = 1; /* focus follows mouse */ static const uint borderwidth = 1; /* width window borders (pixel) */ +static const uint gapwidth = 4; /* width of gaps(pixel) */ static const float rootcolor[] = {0.3, 0.3, 0.3, 1.0}; static const float bordercolor[] = {0.5, 0.5, 0.5, 1.0}; @@ -24,7 +25,7 @@ static const MonitorRule monitorrules[] = { /* example of a HiDPI laptop monitor: { "eDP-1", 0.5, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL }, */ - { NULL, 0.55, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL }, + { nil, 0.55, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL }, }; /* keyboard */ diff --git a/sys/cmd/dway/dway.c b/sys/cmd/dway/dway.c index fd47ccb..3cfce9e 100644 --- a/sys/cmd/dway/dway.c +++ b/sys/cmd/dway/dway.c @@ -7,13 +7,20 @@ /* global state */ static struct { - struct wl_display *display; - struct wlr_backend *backend; - struct wlr_renderer *draw; - struct wlr_compositor *compositor; - struct wlr_xdg_shell *shell; - struct wlr_output_layout *layout; - struct wlr_seat *seat; + struct wl_display *display; + struct wlr_backend *backend; + struct wlr_renderer *draw; + struct wlr_compositor *compositor; + struct wlr_xdg_shell *xdgsh; + struct wlr_layer_shell_v1 *laysh; + struct wlr_output_layout *layout; + struct wlr_idle *idle; + struct wlr_seat *seat; + + struct { + struct wlr_server_decoration_manager *deco; + struct wlr_xdg_decoration_manager *xdeco; + } mngr; struct { struct wl_event_loop *loop; @@ -24,6 +31,9 @@ static struct struct wl_listener cursor; struct wl_listener sel; struct wl_listener psel; + /* shells */ + struct wl_listener layer; + struct wl_listener deco; } ev; struct { @@ -33,8 +43,10 @@ static struct struct wl_list stack; /* order w/in stack */ struct wl_list focus; /* order of focus */ struct wl_list keyboards; + struct wl_list decos; }; + /* geometry of union of output devices */ struct wlr_box dim; } dway = { @@ -45,6 +57,8 @@ static struct .cursor = {.notify=ev·setcursor}, .sel = {.notify=ev·setsel}, .psel = {.notify=ev·setpsel}, + .layer = {.notify=ev·newlayershell}, + .deco = {.notify=ev·newdecoration}, }, }; @@ -57,18 +71,18 @@ static struct static Mouse mouse = { .ev = { - .axis = {.notify=ev·mousescroll}, - .button = {.notify=ev·mousebutton}, - .frame = {.notify=ev·mouseframe}, - .motion = {.notify=ev·mouserelmove}, - .absmotion = {.notify=ev·mouseabsmove}, + .axis = {.notify=ev·mousescroll}, + .button = {.notify=ev·mousebutton}, + .frame = {.notify=ev·mouseframe}, + .motion = {.notify=ev·mouserelmove}, + .absmotion = {.notify=ev·mouseabsmove}, }, }; static Keyboard keyboard = { .ev = { - .modifier = {.notify=ev·modifier}, - .keypress = {.notify=ev·keypress}, + .modifier = {.notify=ev·modifier}, + .keypress = {.notify=ev·keypress}, }, }; @@ -169,7 +183,7 @@ resize(Client *c, int x, int y, int w, int h, int interact) 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, c->dim.height - 2*c->bw); + wlr_xdg_toplevel_set_size(c->surf, c->dim.width - 2*c->bw - gapwidth, c->dim.height - 2*c->bw - gapwidth); } static @@ -178,7 +192,7 @@ getclient(void) { Client *c; - c = wl_container_of(dway.focus.next, c, pos.focus); + c = wl_container_of(dway.focus.next, c, link.focus); if (wl_list_empty(&dway.focus) || !VISIBLEON(c, monitor)) return nil; @@ -190,7 +204,7 @@ Client * clientat(double x, double y) { Client *c; - wl_list_for_each(c, &dway.stack, pos.stack) + wl_list_for_each(c, &dway.stack, link.stack) if (VISIBLEON(c, c->m) && wlr_box_contains_point(&c->dim, x, y)) return c; return nil; @@ -202,7 +216,7 @@ Client * lastfocus(void) { Client *c; - wl_list_for_each(c, &dway.focus, pos.focus) + wl_list_for_each(c, &dway.focus, link.focus) if (VISIBLEON(c, monitor)) return c; @@ -236,11 +250,11 @@ setfocus(Client *c, struct wlr_surface *surf, int lift) wlr_seat_keyboard_notify_enter(dway.seat, surf, kb->keycodes, kb->num_keycodes, &kb->modifiers); if (c) { - wl_list_remove(&c->pos.focus); - wl_list_insert(&dway.focus, &c->pos.focus); + wl_list_remove(&c->link.focus); + wl_list_insert(&dway.focus, &c->link.focus); if (lift) { - wl_list_remove(&c->pos.stack); - wl_list_insert(&dway.stack, &c->pos.stack); + wl_list_remove(&c->link.stack); + wl_list_insert(&dway.stack, &c->link.stack); } wlr_xdg_toplevel_set_activated(c->surf, 1); } @@ -376,9 +390,9 @@ ev·newmonitor(struct wl_listener *ev, void *arg) /* install callbacks */ m->ev.draw.notify = ev·render; - wl_signal_add(&dev->events.frame, &m->ev.draw); - m->ev.free.notify = ev·freemonitor; + + wl_signal_add(&dev->events.frame, &m->ev.draw); wl_signal_add(&dev->events.destroy, &m->ev.free); wl_list_insert(&dway.odevs, &m->link); @@ -455,7 +469,7 @@ renderclients(Monitor *m, struct timespec *now) Payload data; struct wlr_box *borders; - wl_list_for_each_reverse(c, &dway.stack, pos.stack) { + wl_list_for_each_reverse(c, &dway.stack, link.stack) { if (!VISIBLEON(c, c->m) || !wlr_output_layout_intersects(dway.layout, m->dev, &c->dim)) continue; @@ -514,6 +528,63 @@ ev·render(struct wl_listener *ev, void *arg) wlr_output_commit(m->dev); } +/* wlr-layers */ +static +void +ev·newlayershell(struct wl_listener *ev, void *arg) +{ + struct wlr_layer_surface_v1 *layer; + + layer = arg; + + /* fill in */ +} + +/* decorations */ +static +void +ev·newdecoration(struct wl_listener *ev, void *arg) +{ + struct wlr_server_decoration *wlr; + Deco *deco; + + wlr = arg; + + deco = calloc(1, sizeof(*deco)); + if (!deco) + return; + + deco->wlr = wlr; + + wl_signal_add(&wlr->events.destroy, &deco->ev.free); + deco->ev.free.notify = ev·freedecoration; + + wl_signal_add(&wlr->events.mode, &deco->ev.mode); + deco->ev.mode.notify = ev·modedecoration; + + wl_list_insert(&dway.decos, &deco->link); +} + +static +void +ev·freedecoration(struct wl_listener *ev, void *arg) +{ + Deco *deco; + + deco = wl_container_of(ev, deco, ev.free); + + wl_list_remove(&deco->ev.free.link); + wl_list_remove(&deco->ev.mode.link); + wl_list_remove(&deco->link); + free(deco); +} +static +void +ev·modedecoration(struct wl_listener *ev, void *arg) +{ + /* no op */ +} + /* xdg-surfaces */ #define WLR_EDGE_ALL WLR_EDGE_TOP|WLR_EDGE_BOTTOM|WLR_EDGE_LEFT|WLR_EDGE_RIGHT static @@ -534,14 +605,13 @@ ev·newclient(struct wl_listener *ev, void *arg) wlr_xdg_toplevel_set_tiled(surf, WLR_EDGE_ALL); /* install callbacks */ - c->ev.map.notify = ev·mapclient; - wl_signal_add(&surf->events.map, &c->ev.map); - + c->ev.map.notify = ev·mapclient; c->ev.unmap.notify = ev·unmapclient; - wl_signal_add(&surf->events.unmap, &c->ev.unmap); + c->ev.free.notify = ev·freeclient; - c->ev.free.notify = ev·freeclient; - wl_signal_add(&surf->events.unmap, &c->ev.free); + 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 @@ -552,9 +622,9 @@ ev·mapclient(struct wl_listener *ev, void *arg) c = wl_container_of(ev, c, ev.map); - wl_list_insert(&dway.tiles, &c->pos.tiles); - wl_list_insert(&dway.focus, &c->pos.focus); - wl_list_insert(&dway.stack, &c->pos.stack); + wl_list_insert(&dway.tiles, &c->link.tiles); + wl_list_insert(&dway.focus, &c->link.focus); + wl_list_insert(&dway.stack, &c->link.stack); wlr_xdg_surface_get_geometry(c->surf, &c->dim); @@ -568,14 +638,19 @@ static void ev·unmapclient(struct wl_listener *ev, void *arg) { - Client *c; + Monitor *m; + Client *c; c = wl_container_of(ev, c, ev.unmap); + m = c->m; setmonitor(c, nil, 0); - wl_list_remove(&c->pos.tiles); - wl_list_remove(&c->pos.stack); - wl_list_remove(&c->pos.focus); + wl_list_remove(&c->link.tiles); + wl_list_remove(&c->link.stack); + wl_list_remove(&c->link.focus); + + c->surf = nil; + arrange(m); } static @@ -583,10 +658,12 @@ void ev·freeclient(struct wl_listener *ev, void *arg) { Client *c; - c = wl_container_of(ev, c, ev.unmap); + c = wl_container_of(ev, c, ev.free); free(c); } +/* server decorations */ + /* cursor images */ static @@ -795,8 +872,8 @@ mousemoved(uint32 time) mouse.cursor->y - c->dim.y - c->bw, &sx, &sy); - // if (!surf) - wlr_xcursor_manager_set_cursor_image(mouse.manager, "left_ptr", mouse.cursor); + if (!surf) + wlr_xcursor_manager_set_cursor_image(mouse.manager, "left_ptr", mouse.cursor); pointerfocus(c, surf, sx, sy, time); } @@ -933,22 +1010,22 @@ focusstack(const Arg *arg) return; if (arg->i > 0) { - wl_list_for_each(c, &sel->pos.tiles, pos.tiles) { - if (&c->pos.tiles == &dway.tiles) + wl_list_for_each(c, &sel->link.tiles, link.tiles) { + if (&c->link.tiles == &dway.tiles) continue; if (VISIBLEON(c, monitor)) break; } } else { - wl_list_for_each_reverse(c, &sel->pos.tiles, pos.tiles) { - if (&c->pos.tiles == &dway.tiles) + wl_list_for_each_reverse(c, &sel->link.tiles, link.tiles) { + if (&c->link.tiles == &dway.tiles) continue; /* wrap past the sentinel node */ if (VISIBLEON(c, monitor)) break; /* found it */ } } /* If only one client is visible on selmon, then c == sel */ - setfocus(c, NULL, 1); + setfocus(c, nil, 1); } static @@ -1014,11 +1091,18 @@ static void spawn(const Arg *arg) { - if (fork() == 0) { + pid_t pid; + if ((pid=fork()) == 0) { setsid(); + + printf("running %s\n", ((char**)arg->v)[0]); execvp(((char **)arg->v)[0], (char **)arg->v); - fatal("dwl: execvp %s", ((char **)arg->v)[0]); - } + + fprintf(stderr, "dwl: execvp %s", ((char **)arg->v)[0]); + perror(" failed"); + exit(EXIT_FAILURE); + } else if (pid < 0) + fatal("failed to fork"); } static @@ -1119,7 +1203,7 @@ tile(Monitor *m) uint i, n, h, mw, my, ty; n = 0; - wl_list_for_each(c, &dway.tiles, pos.tiles) + wl_list_for_each(c, &dway.tiles, link.tiles) if (VISIBLEON(c, m) && !c->floating) n++; @@ -1132,7 +1216,7 @@ tile(Monitor *m) mw = m->area.win.width; i = my = ty = 0; - wl_list_for_each(c, &dway.tiles, pos.tiles) { + wl_list_for_each(c, &dway.tiles, link.tiles) { if (!VISIBLEON(c, m) || c->floating) continue; if (i < m->nmaster) { @@ -1169,18 +1253,25 @@ setup(void) wlr_renderer_init_wl_display(dway.draw, dway.display); /* intialize the compositor and some automated handlers */ - wlr_compositor_create(dway.display, dway.draw); - wlr_screencopy_manager_v1_create(dway.display); + dway.compositor = wlr_compositor_create(dway.display, dway.draw); + wlr_data_device_manager_create(dway.display); - wlr_primary_selection_v1_device_manager_create(dway.display); + wlr_gamma_control_manager_v1_create(dway.display); + wlr_gtk_primary_selection_device_manager_create(dway.display); - dway.layout = wlr_output_layout_create(); - wlr_xdg_output_manager_v1_create(dway.display, dway.layout); + /* middle management */ + wlr_export_dmabuf_manager_v1_create(dway.display); + wlr_screencopy_manager_v1_create(dway.display); + wlr_data_control_manager_v1_create(dway.display); + wlr_primary_selection_v1_device_manager_create(dway.display); dway.ev.loop = wl_display_get_event_loop(dway.display); if (!dway.ev.loop) fatal("failed to initialize event loop"); + dway.layout = wlr_output_layout_create(); + wlr_xdg_output_manager_v1_create(dway.display, dway.layout); + /* grab output devices */ wl_list_init(&dway.odevs); wl_signal_add(&dway.backend->events.new_output, &dway.ev.odev); @@ -1189,9 +1280,23 @@ setup(void) wl_list_init(&dway.tiles); wl_list_init(&dway.stack); wl_list_init(&dway.focus); + wl_list_init(&dway.decos); + + /* layer shell */ + dway.laysh = wlr_layer_shell_v1_create(dway.display); + wl_signal_add(&dway.laysh->events.new_surface, &dway.ev.layer); + + /* xdg shell */ + dway.xdgsh = wlr_xdg_shell_create(dway.display); + wl_signal_add(&dway.xdgsh->events.new_surface, &dway.ev.client); - dway.shell = wlr_xdg_shell_create(dway.display); - wl_signal_add(&dway.shell->events.new_surface, &dway.ev.client); + /* decorations */ + dway.mngr.deco = wlr_server_decoration_manager_create(dway.display); + wlr_server_decoration_manager_set_default_mode(dway.mngr.deco, WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); + wl_signal_add(&dway.mngr.deco->events.new_decoration, &dway.ev.deco); + wl_list_init(&dway.decos); + + dway.mngr.deco = wlr_server_decoration_manager_create(dway.display); /* grab input devices and install callbacks */ mouse.cursor = wlr_cursor_create(); @@ -1251,8 +1356,9 @@ run(void) void cleanup(void) { - wlr_backend_destroy(dway.backend); + wl_display_destroy_clients(dway.display); wl_display_destroy(dway.display); + wlr_backend_destroy(dway.backend); } void diff --git a/sys/cmd/dway/dway.h b/sys/cmd/dway/dway.h index 4fce74b..838e035 100644 --- a/sys/cmd/dway/dway.h +++ b/sys/cmd/dway/dway.h @@ -10,9 +10,15 @@ #include #include #include +#include #include +#include +#include +#include +#include #include #include +#include #include #include #include @@ -21,14 +27,19 @@ #include #include #include +#include #include +#include #include #include #include -#include "xdg-shell-protocol.h" -#include +#include "xdg-shell.h" +#include "wlr-layer-shell.h" +#include +#include +#include #include /* main types */ @@ -41,6 +52,7 @@ typedef struct Keyboard Keyboard; typedef struct Monitor Monitor; typedef struct Layout Layout; typedef struct Client Client; +typedef struct Deco Deco; typedef struct Payload Payload; typedef struct Rule Rule; @@ -151,18 +163,29 @@ struct Client struct wl_list tiles; struct wl_list stack; struct wl_list focus; - } pos; + } link; struct { struct wl_listener map; struct wl_listener unmap; struct wl_listener free; } ev; - int bw; - uint tags; - int floating; + int bw; + uint tags; + int floating; Monitor *m; }; +struct Deco +{ + struct wl_list link; + struct wlr_server_decoration *wlr; + + struct { + struct wl_listener free; + struct wl_listener mode; + } ev; +}; + struct Payload { struct wlr_output *dev; @@ -205,6 +228,12 @@ static void ev·mapclient(struct wl_listener *ev, void *arg); static void ev·unmapclient(struct wl_listener *ev, void *arg); static void ev·freeclient(struct wl_listener *ev, void *arg); +static void ev·newdecoration(struct wl_listener *ev, void *arg); +static void ev·freedecoration(struct wl_listener *ev, void *arg); +static void ev·modedecoration(struct wl_listener *ev, void *arg); + +static void ev·newlayershell(struct wl_listener *ev, void *arg); + static void ev·setcursor(struct wl_listener *ev, void *arg); static void ev·setsel(struct wl_listener *ev, void *arg); static void ev·setpsel(struct wl_listener *ev, void *arg); -- cgit v1.2.1