From 60e3cfcb5304171cb5f4f8732730d30084c730e2 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Wed, 3 Jun 2020 22:23:46 -0700 Subject: fixed many segfaults --- sys/cmd/dway/config.h | 13 ++- sys/cmd/dway/dway.c | 255 +++++++++++++++++++++++++++++++++++--------------- sys/cmd/dway/dway.h | 22 ++++- 3 files changed, 212 insertions(+), 78 deletions(-) (limited to 'sys/cmd') 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 = ""; + // ----------------------------------------------------------------------- // 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 #include #include +#include #include #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); -- cgit v1.2.1