aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2020-06-03 22:23:46 -0700
committerNicholas Noll <nbnoll@eml.cc>2020-06-03 22:23:46 -0700
commit60e3cfcb5304171cb5f4f8732730d30084c730e2 (patch)
treec3e877e8e7b5abcbea9cc84785a87a52d008d7a6 /sys/cmd
parentc5d4b505e27520a8373894a3382d529a00b6791f (diff)
fixed many segfaults
Diffstat (limited to 'sys/cmd')
-rw-r--r--sys/cmd/dway/config.h13
-rw-r--r--sys/cmd/dway/dway.c255
-rw-r--r--sys/cmd/dway/dway.h22
3 files changed, 212 insertions, 78 deletions
diff --git a/sys/cmd/dway/config.h b/sys/cmd/dway/config.h
index b3f7c83..5ac665a 100644
--- a/sys/cmd/dway/config.h
+++ b/sys/cmd/dway/config.h
@@ -1,13 +1,17 @@
/* global appearance */
static const int sloppyfocus = 1; /* focus follows mouse */
-static const uint borderpixel = 1; /* border pixel of windows */
+static const uint borderwidth = 1; /* width window borders (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};
/* tagging */
static const byte *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
+static const Rule apprules[] = {
+ /* app_id title tags mask isfloating monitor */
+};
+
static const Layout layouts[] = {
/* symbol arrange function */
{ "[]=", tile },
@@ -15,6 +19,13 @@ static const Layout layouts[] = {
};
/* monitors */
+static const MonitorRule monitorrules[] = {
+ /* name mfact nmaster scale layout rotate/reflect */
+ /* 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 },
+};
/* keyboard */
static const struct xkb_rule_names xkb_rules = {
diff --git a/sys/cmd/dway/dway.c b/sys/cmd/dway/dway.c
index aff47b6..fd47ccb 100644
--- a/sys/cmd/dway/dway.c
+++ b/sys/cmd/dway/dway.c
@@ -58,7 +58,7 @@ static struct
static Mouse mouse = {
.ev = {
.axis = {.notify=ev·mousescroll},
- .button = {.notify=ev·mouseclick},
+ .button = {.notify=ev·mousebutton},
.frame = {.notify=ev·mouseframe},
.motion = {.notify=ev·mouserelmove},
.absmotion = {.notify=ev·mouseabsmove},
@@ -72,6 +72,8 @@ static Keyboard keyboard = {
},
};
+static char *broken = "<broken>";
+
// -----------------------------------------------------------------------
// utility functions
@@ -119,6 +121,40 @@ applybounds(Client *c, struct wlr_box *bbox)
c->dim.y = bbox->y;
}
+static void setmonitor(Client *c, Monitor *m, uint newtags);
+
+static
+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, &dway.odevs, link)
+ if (r->monitor == i++)
+ m = it;
+ }
+ }
+ setmonitor(c, m, newtags);
+}
+
static
void
resize(Client *c, int x, int y, int w, int h, int interact)
@@ -133,7 +169,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, c->dim.height - 2*c->bw);
}
static
@@ -151,7 +187,7 @@ getclient(void)
static
Client *
-getclientat(double x, double y)
+clientat(double x, double y)
{
Client *c;
wl_list_for_each(c, &dway.stack, pos.stack)
@@ -178,7 +214,7 @@ void
setfocus(Client *c, struct wlr_surface *surf, int lift)
{
struct wlr_surface *prev_surface;
- struct wlr_xdg_surface *previous;
+ struct wlr_xdg_surface *prev;
struct wlr_keyboard *kb;
if (c) {
@@ -192,12 +228,13 @@ setfocus(Client *c, struct wlr_surface *surf, int lift)
return;
if (prev_surface) {
- previous = wlr_xdg_surface_from_wlr_surface(dway.seat->keyboard_state.focused_surface);
- wlr_xdg_toplevel_set_activated(previous, 0);
+ prev = wlr_xdg_surface_from_wlr_surface(dway.seat->keyboard_state.focused_surface);
+ wlr_xdg_toplevel_set_activated(prev, 0);
}
kb = wlr_seat_get_keyboard(dway.seat);
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);
@@ -297,7 +334,7 @@ getmonitor(int dir)
static
Monitor *
-getmonitorat(double x, double y)
+monitorat(double x, double y)
{
struct wlr_output *dev;
@@ -314,29 +351,44 @@ void
ev·newmonitor(struct wl_listener *ev, void *arg)
{
Monitor *m;
- struct wlr_output *odev;
+ const MonitorRule *r;
+ struct wlr_output *dev;
struct wlr_output_mode *mode;
- odev = arg;
- if (!wl_list_empty(&odev->modes)) {
- mode = wl_container_of(odev->modes.prev, mode, link);
+ dev = arg;
+ wlr_output_set_mode(dev, wlr_output_preferred_mode(dev));
+
+ m = dev->data = calloc(1, sizeof(*m));
+ m->dev = dev;
+ m->tagset[0] = m->tagset[1] = 1;
+ /* look for rules to apply */
+ for (r = monitorrules; r < arrend(monitorrules); r++) {
+ if (!r->name || strstr(dev->name, r->name)) {
+ m->mfact = r->mfact;
+ m->nmaster = r->nmaster;
+ wlr_output_set_scale(dev, r->scale);
+ wlr_xcursor_manager_load(mouse.manager, r->scale);
+ m->lt[0] = m->lt[1] = r->lt;
+ wlr_output_set_transform(dev, r->rr);
+ break;
+ }
+ }
- wlr_output_set_mode(odev, mode);
- wlr_output_enable(odev, true);
- if (!wlr_output_commit(odev))
- return;
- }
+ /* 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.destroy, &m->ev.free);
- m = calloc(1, sizeof(*m));
- m->dev = odev;
wl_list_insert(&dway.odevs, &m->link);
- /* install callbacks */
- m->ev.free.notify = ev·freemonitor;
- wl_signal_add(&odev->events.destroy, &m->ev.free);
+ wlr_output_enable(dev, 1);
+ if (!wlr_output_commit(dev))
+ return;
- m->ev.draw.notify = ev·render;
- wl_signal_add(&odev->events.frame, &m->ev.draw);
+ wlr_output_layout_add_auto(dway.layout, dev);
+ dway.dim = *wlr_output_layout_get_box(dway.layout, nil);
}
static
@@ -361,8 +413,8 @@ render(struct wlr_surface *surf, int sx, int sy, void *arg)
Payload *data;
double x, y;
float mtx[9];
- struct wlr_box box;
- struct wlr_output *dev;
+ struct wlr_box box;
+ struct wlr_output *dev;
struct wlr_texture *tex;
enum wl_output_transform transform;
@@ -414,6 +466,7 @@ renderclients(Monitor *m, struct timespec *now)
w = c->surf->surface->current.width;
h = c->surf->surface->current.height;
+
borders = (struct wlr_box[4]) {
{x, y, w + 2 * c->bw, c->bw}, /* top */
{x, y + c->bw, c->bw, h}, /* left */
@@ -440,11 +493,9 @@ ev·render(struct wl_listener *ev, void *arg)
{
int w, h;
Monitor *m;
- struct wlr_output *odev;
struct timespec now;
- odev = arg;
- m = wl_container_of(ev, m, ev.draw);
+ m = wl_container_of(ev, m, ev.draw);
if (!wlr_output_attach_render(m->dev, nil))
return;
@@ -478,6 +529,7 @@ ev·newclient(struct wl_listener *ev, void *arg)
c = surf->data = calloc(1, sizeof(*c));
c->surf = surf;
+ c->bw = borderwidth;
wlr_xdg_toplevel_set_tiled(surf, WLR_EDGE_ALL);
@@ -501,10 +553,15 @@ 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.stack, &c->pos.stack);
wl_list_insert(&dway.focus, &c->pos.focus);
+ wl_list_insert(&dway.stack, &c->pos.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
@@ -514,6 +571,8 @@ ev·unmapclient(struct wl_listener *ev, void *arg)
Client *c;
c = wl_container_of(ev, c, ev.unmap);
+ setmonitor(c, nil, 0);
+
wl_list_remove(&c->pos.tiles);
wl_list_remove(&c->pos.stack);
wl_list_remove(&c->pos.focus);
@@ -637,25 +696,58 @@ ev·mousescroll(struct wl_listener *ev, void *arg)
struct wlr_event_pointer_axis *axis;
axis = arg;
- wlr_seat_pointer_notify_axis(
- dway.seat,
- axis->time_msec,
- axis->orientation,
- axis->delta,
- axis->delta_discrete,
- axis->source
- );
+ wlr_seat_pointer_notify_axis(dway.seat,
+ axis->time_msec,
+ axis->orientation,
+ axis->delta,
+ axis->delta_discrete,
+ axis->source);
}
static
void
-ev·mouseclick(struct wl_listener *ev, void *arg)
+ev·mousebutton(struct wl_listener *ev, void *arg)
{
+ uint32 mods;
+ Client *c;
+ const Button *b;
struct wlr_surface *surf;
- struct wlr_keyboard *keyboard;
+ struct wlr_keyboard *keyb;
struct wlr_event_pointer_button *button;
button = arg;
+ switch (button->state) {
+ case WLR_BUTTON_PRESSED:
+ if ((c = clientat(mouse.cursor->x, mouse.cursor->y))) {
+ surf = wlr_xdg_surface_surface_at(c->surf,
+ mouse.cursor->x - c->dim.x - c->bw,
+ mouse.cursor->y - c->dim.y - c->bw,
+ nil, nil
+ );
+ setfocus(c, surf, 1);
+ }
+
+ keyb = wlr_seat_get_keyboard(dway.seat);
+ mods = wlr_keyboard_get_modifiers(keyb);
+ for (b = buttons; b < arrend(buttons); b++) {
+ if (CLEANMASK(mods) == CLEANMASK(b->mod) &&
+ button->button == b->kind && b->func) {
+ b->func(&b->arg);
+ return;
+ }
+ }
+ break;
+
+ case WLR_BUTTON_RELEASED:
+ if (mouse.mode != MouseNormal) {
+ wlr_xcursor_manager_set_cursor_image(mouse.manager, "left_ptr", mouse.cursor);
+ mouse.mode = MouseNormal;
+ monitor = monitorat(mouse.cursor->x, mouse.cursor->y);
+ setmonitor(grab.c, monitor, 0);
+ }
+ }
+
+ wlr_seat_pointer_notify_button(dway.seat, button->time_msec, button->button, button->state);
}
static
@@ -673,13 +765,22 @@ mousemoved(uint32 time)
double sx, sy;
struct wlr_surface *surf;
+ if (sloppyfocus)
+ monitor = monitorat(mouse.cursor->x, mouse.cursor->y);
+
switch (mouse.mode) {
case MouseMove:
- resize(grab.c, mouse.cursor->x - grab.x, mouse.cursor->y - grab.y, grab.c->dim.width, grab.c->dim.height, 1);
+ resize(grab.c,
+ mouse.cursor->x - grab.x,
+ mouse.cursor->y - grab.y,
+ grab.c->dim.width, grab.c->dim.height, 1);
return;
case MouseResize:
- resize(grab.c, grab.c->dim.x, grab.c->dim.y, mouse.cursor->x - grab.c->dim.x, mouse.cursor->y - grab.c->dim.y, 1);
+ resize(grab.c,
+ grab.c->dim.x, grab.c->dim.y,
+ mouse.cursor->x - grab.c->dim.x,
+ mouse.cursor->y - grab.c->dim.y, 1);
return;
case MouseNormal:
@@ -688,12 +789,14 @@ mousemoved(uint32 time)
}
surf = nil;
- if ((c = getclientat(mouse.cursor->x, mouse.cursor->y)))
- surf = wlr_xdg_surface_surface_at(c->surf, mouse.cursor->x - c->dim.x - c->bw,
- mouse.cursor->y - c->dim.y - c->bw, &sx, &sy);
+ if ((c = clientat(mouse.cursor->x, mouse.cursor->y)))
+ surf = wlr_xdg_surface_surface_at(c->surf,
+ mouse.cursor->x - c->dim.x - c->bw,
+ 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);
}
@@ -713,10 +816,10 @@ static
void
ev·mouseabsmove(struct wl_listener *ev, void *arg)
{
- struct wlr_event_pointer_motion *mv;
+ struct wlr_event_pointer_motion_absolute *mv;
mv = arg;
- wlr_cursor_warp_absolute(mouse.cursor, mv->device, mv->delta_x, mv->delta_y);
+ wlr_cursor_warp_absolute(mouse.cursor, mv->device, mv->x, mv->y);
mousemoved(mv->time_msec);
}
@@ -852,7 +955,7 @@ static
void
moveresize(const Arg *arg)
{
- grab.c = getclientat(mouse.cursor->x, mouse.cursor->y);
+ grab.c = clientat(mouse.cursor->x, mouse.cursor->y);
if (!grab.c)
return;
@@ -1056,10 +1159,6 @@ setup(void)
if (!dway.display)
fatal("failed to initialize display");
- dway.ev.loop = wl_display_get_event_loop(dway.display);
- if (!dway.ev.loop)
- fatal("failed to initialize event loop");
-
dway.backend = wlr_backend_autocreate(dway.display, nil);
if (!dway.backend)
fatal("failed to create backend");
@@ -1069,50 +1168,53 @@ setup(void)
fatal("failed to initialize renderer");
wlr_renderer_init_wl_display(dway.draw, dway.display);
- /* intialize the compositor & layout */
- dway.compositor = wlr_compositor_create(dway.display, dway.draw);
- if (!dway.compositor)
- fatal("failed to initialize compositor");
+ /* intialize the compositor and some automated handlers */
+ wlr_compositor_create(dway.display, dway.draw);
+ wlr_screencopy_manager_v1_create(dway.display);
wlr_data_device_manager_create(dway.display);
+ wlr_primary_selection_v1_device_manager_create(dway.display);
dway.layout = wlr_output_layout_create();
+ wlr_xdg_output_manager_v1_create(dway.display, dway.layout);
+
+ dway.ev.loop = wl_display_get_event_loop(dway.display);
+ if (!dway.ev.loop)
+ fatal("failed to initialize event loop");
/* grab output devices */
wl_list_init(&dway.odevs);
wl_signal_add(&dway.backend->events.new_output, &dway.ev.odev);
- dway.shell = wlr_xdg_shell_create(dway.display);
- wl_signal_add(&dway.shell->events.new_surface, &dway.ev.client);
-
/* initialize window structures */
wl_list_init(&dway.tiles);
wl_list_init(&dway.stack);
wl_list_init(&dway.focus);
- /* grab input devices and install callbacks */
- wl_list_init(&dway.idevs);
- wl_list_init(&dway.keyboards);
- wl_signal_add(&dway.backend->events.new_input, &dway.ev.idev);
-
- dway.seat = wlr_seat_create(dway.display, "seat0");
- wl_signal_add(&dway.seat->events.request_set_cursor, &dway.ev.cursor);
- wl_signal_add(&dway.seat->events.request_set_selection, &dway.ev.sel);
- wl_signal_add(&dway.seat->events.request_set_primary_selection, &dway.ev.psel);
+ dway.shell = wlr_xdg_shell_create(dway.display);
+ wl_signal_add(&dway.shell->events.new_surface, &dway.ev.client);
+ /* grab input devices and install callbacks */
mouse.cursor = wlr_cursor_create();
if (!mouse.cursor)
fatal("no mouse found");
-
wlr_cursor_attach_output_layout(mouse.cursor, dway.layout);
mouse.manager = wlr_xcursor_manager_create(nil, 24);
- wlr_xcursor_manager_load(mouse.manager, 1);
/* attach the static cursor object to event handlers */
- wl_signal_add(&mouse.cursor->events.axis, &mouse.ev.axis);
- wl_signal_add(&mouse.cursor->events.frame, &mouse.ev.frame);
+ wl_signal_add(&mouse.cursor->events.axis, &mouse.ev.axis);
+ wl_signal_add(&mouse.cursor->events.frame, &mouse.ev.frame);
wl_signal_add(&mouse.cursor->events.button, &mouse.ev.button);
wl_signal_add(&mouse.cursor->events.motion, &mouse.ev.motion);
wl_signal_add(&mouse.cursor->events.motion_absolute, &mouse.ev.absmotion);
+
+ wl_list_init(&dway.idevs);
+ wl_list_init(&dway.keyboards);
+ wl_signal_add(&dway.backend->events.new_input, &dway.ev.idev);
+
+ dway.seat = wlr_seat_create(dway.display, "seat0");
+ wl_signal_add(&dway.seat->events.request_set_cursor, &dway.ev.cursor);
+ wl_signal_add(&dway.seat->events.request_set_selection, &dway.ev.sel);
+ wl_signal_add(&dway.seat->events.request_set_primary_selection, &dway.ev.psel);
}
void
@@ -1133,11 +1235,14 @@ run(void)
fatal("failed to start backend");
}
- monitor = getmonitorat(mouse.cursor->x, mouse.cursor->y);
+ monitor = monitorat(mouse.cursor->x, mouse.cursor->y);
+ if (!monitor)
+ fatal("no monitor found");
+
wlr_cursor_warp_closest(mouse.cursor, nil, mouse.cursor->x, mouse.cursor->y);
wlr_xcursor_manager_set_cursor_image(mouse.manager, "left_ptr", mouse.cursor);
- setenv("WAYLAND_DISPLAY", socket, true);
+ setenv("WAYLAND_DISPLAY", socket, 1);
wlr_log(WLR_INFO, "running dway on WAYLAND_DISPLAY\n");
wl_display_run(dway.display);
diff --git a/sys/cmd/dway/dway.h b/sys/cmd/dway/dway.h
index 9c1450c..4fce74b 100644
--- a/sys/cmd/dway/dway.h
+++ b/sys/cmd/dway/dway.h
@@ -23,6 +23,7 @@
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_xcursor_manager.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"
@@ -63,7 +64,7 @@ struct Button
enum
{
- MouseNormal, MouseMove, MouseResize,
+ MouseNormal=0, MouseMove, MouseResize,
};
struct Mouse
@@ -125,6 +126,23 @@ struct Layout
void (*arrange)(Monitor *);
};
+struct MonitorRule {
+ char *name;
+ float mfact;
+ int nmaster;
+ float scale;
+ const Layout *lt;
+ enum wl_output_transform rr;
+};
+
+struct Rule {
+ char *id;
+ char *title;
+ uint tags;
+ int floating;
+ int monitor;
+};
+
struct Client
{
struct wlr_xdg_surface *surf;
@@ -193,7 +211,7 @@ static void ev·setpsel(struct wl_listener *ev, void *arg);
static void ev·mousescroll(struct wl_listener *ev, void *arg);
static void ev·mouseframe(struct wl_listener *ev, void *arg);
-static void ev·mouseclick(struct wl_listener *ev, void *arg);
+static void ev·mousebutton(struct wl_listener *ev, void *arg);
static void ev·mouserelmove(struct wl_listener *ev, void *arg);
static void ev·mouseabsmove(struct wl_listener *ev, void *arg);