aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2020-06-04 15:04:56 -0700
committerNicholas Noll <nbnoll@eml.cc>2020-06-04 15:04:56 -0700
commitc85ebc8fe50be0ba7e87d21302337b5263052741 (patch)
treea08b6f9498018870bdff326a7b5986fda36af9d5 /sys
parent60e3cfcb5304171cb5f4f8732730d30084c730e2 (diff)
fix: issue with freeing clients
Diffstat (limited to 'sys')
-rw-r--r--sys/cmd/dway/config.h3
-rw-r--r--sys/cmd/dway/dway.c224
-rw-r--r--sys/cmd/dway/dway.h41
3 files changed, 202 insertions, 66 deletions
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 <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_cursor.h>
+#include <wlr/types/wlr_data_control_v1.h>
#include <wlr/types/wlr_data_device.h>
+#include <wlr/types/wlr_export_dmabuf_v1.h>
+#include <wlr/types/wlr_gamma_control_v1.h>
+#include <wlr/types/wlr_gtk_primary_selection.h>
+#include <wlr/types/wlr_idle.h>
#include <wlr/types/wlr_input_device.h>
#include <wlr/types/wlr_keyboard.h>
+#include <wlr/types/wlr_layer_shell_v1.h>
#include <wlr/types/wlr_matrix.h>
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_output_layout.h>
@@ -21,14 +27,19 @@
#include <wlr/types/wlr_primary_selection_v1.h>
#include <wlr/types/wlr_screencopy_v1.h>
#include <wlr/types/wlr_seat.h>
+#include <wlr/types/wlr_server_decoration.h>
#include <wlr/types/wlr_xcursor_manager.h>
+#include <wlr/types/wlr_xdg_decoration_v1.h>
#include <wlr/types/wlr_xdg_shell.h>
#include <wlr/types/wlr_xdg_output_v1.h>
#include <wlr/util/log.h>
-#include "xdg-shell-protocol.h"
-#include <xkbcommon/xkbcommon.h>
+#include "xdg-shell.h"
+#include "wlr-layer-shell.h"
+#include <signal.h>
+#include <wait.h>
+#include <xkbcommon/xkbcommon.h>
#include <linux/input-event-codes.h>
/* 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);