let's not alienate the dwm folks

Fix style.
main
Devin J. Pohly 2020-12-24 22:21:00 -05:00
parent 206427537a
commit 57d0760635
2 changed files with 128 additions and 116 deletions

View File

@ -2,7 +2,7 @@
PREFIX = /usr/local PREFIX = /usr/local
# Default compile flags (overridable by environment) # Default compile flags (overridable by environment)
CFLAGS ?= -g -Wall -Wextra -Werror -Wno-unused-parameter -Wno-sign-compare -Wno-error=unused-function CFLAGS ?= -g -Wall -Wextra -Werror -Wno-unused-parameter -Wno-sign-compare -Wno-error=unused-function -Wdeclaration-after-statement
# Uncomment to build XWayland support # Uncomment to build XWayland support
#CFLAGS += -DXWAYLAND #CFLAGS += -DXWAYLAND

242
dwl.c
View File

@ -156,6 +156,14 @@ typedef struct {
enum zwlr_layer_shell_v1_layer layer; enum zwlr_layer_shell_v1_layer layer;
} LayerSurface; } LayerSurface;
typedef struct {
uint32_t singular_anchor;
uint32_t anchor_triplet;
int *positive_axis;
int *negative_axis;
int margin;
} Edge;
typedef struct { typedef struct {
const char *symbol; const char *symbol;
void (*arrange)(Monitor *); void (*arrange)(Monitor *);
@ -396,61 +404,46 @@ applyexclusive(struct wlr_box *usable_area,
uint32_t anchor, int32_t exclusive, uint32_t anchor, int32_t exclusive,
int32_t margin_top, int32_t margin_right, int32_t margin_top, int32_t margin_right,
int32_t margin_bottom, int32_t margin_left) { int32_t margin_bottom, int32_t margin_left) {
Edge edges[4];
if (exclusive <= 0) if (exclusive <= 0)
return; return;
struct { // Top
uint32_t singular_anchor; edges[0].singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
uint32_t anchor_triplet; edges[0].anchor_triplet = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
int *positive_axis; ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
int *negative_axis; ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
int margin; edges[0].positive_axis = &usable_area->y;
} edges[] = { edges[0].negative_axis = &usable_area->height;
// Top edges[0].margin = margin_top;
{
.singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP, // Bottom
.anchor_triplet = edges[1].singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | edges[1].anchor_triplet = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP, ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
.positive_axis = &usable_area->y, edges[1].positive_axis = NULL;
.negative_axis = &usable_area->height, edges[1].negative_axis = &usable_area->height;
.margin = margin_top, edges[1].margin = margin_bottom;
},
// Bottom // Left
{ edges[2].singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
.singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM, edges[2].anchor_triplet = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
.anchor_triplet = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | edges[2].positive_axis = &usable_area->x;
ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM, edges[2].negative_axis = &usable_area->width;
.positive_axis = NULL, edges[2].margin = margin_left;
.negative_axis = &usable_area->height,
.margin = margin_bottom, // Right
}, edges[3].singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
// Left edges[3].anchor_triplet = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
{ ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
.singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT, ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
.anchor_triplet = edges[3].positive_axis = NULL;
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | edges[3].negative_axis = &usable_area->width;
ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | edges[3].margin = margin_right;
ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM,
.positive_axis = &usable_area->x,
.negative_axis = &usable_area->width,
.margin = margin_left,
},
// Right
{
.singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT,
.anchor_triplet =
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM,
.positive_axis = NULL,
.negative_axis = &usable_area->width,
.margin = margin_right,
},
};
for (size_t i = 0; i < LENGTH(edges); ++i) { for (size_t i = 0; i < LENGTH(edges); ++i) {
if ((anchor == edges[i].singular_anchor || anchor == edges[i].anchor_triplet) if ((anchor == edges[i].singular_anchor || anchor == edges[i].anchor_triplet)
@ -469,6 +462,9 @@ applyrules(Client *c)
{ {
/* rule matching */ /* rule matching */
const char *appid, *title; const char *appid, *title;
unsigned int i, newtags = 0;
const Rule *r;
Monitor *mon = selmon, *m;
#ifdef XWAYLAND #ifdef XWAYLAND
if (c->type != XDGShell) { if (c->type != XDGShell) {
updatewindowtype(c); updatewindowtype(c);
@ -485,9 +481,6 @@ applyrules(Client *c)
if (!title) if (!title)
title = broken; title = broken;
unsigned int i, newtags = 0;
const Rule *r;
Monitor *mon = selmon, *m;
for (r = rules; r < END(rules); r++) { for (r = rules; r < END(rules); r++) {
if ((!r->title || strstr(title, r->title)) if ((!r->title || strstr(title, r->title))
&& (!r->id || strstr(appid, r->id))) { && (!r->id || strstr(appid, r->id))) {
@ -521,20 +514,22 @@ arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int
wl_list_for_each(layersurface, list, link) { wl_list_for_each(layersurface, list, link) {
struct wlr_layer_surface_v1 *wlr_layer_surface = layersurface->layer_surface; struct wlr_layer_surface_v1 *wlr_layer_surface = layersurface->layer_surface;
struct wlr_layer_surface_v1_state *state = &wlr_layer_surface->current; struct wlr_layer_surface_v1_state *state = &wlr_layer_surface->current;
struct wlr_box bounds;
struct wlr_box box = { struct wlr_box box = {
.width = state->desired_width, .width = state->desired_width,
.height = state->desired_height .height = state->desired_height
}; };
const uint32_t both_horiz = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
| ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
const uint32_t both_vert = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP
| ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
if (exclusive != (state->exclusive_zone > 0)) if (exclusive != (state->exclusive_zone > 0))
continue; continue;
struct wlr_box bounds = state->exclusive_zone == -1 ? bounds = state->exclusive_zone == -1 ? full_area : *usable_area;
full_area : *usable_area;
// Horizontal axis // Horizontal axis
const uint32_t both_horiz = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
| ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
if ((state->anchor & both_horiz) && box.width == 0) { if ((state->anchor & both_horiz) && box.width == 0) {
box.x = bounds.x; box.x = bounds.x;
box.width = bounds.width; box.width = bounds.width;
@ -546,8 +541,6 @@ arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int
box.x = bounds.x + ((bounds.width / 2) - (box.width / 2)); box.x = bounds.x + ((bounds.width / 2) - (box.width / 2));
} }
// Vertical axis // Vertical axis
const uint32_t both_vert = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP
| ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
if ((state->anchor & both_vert) && box.height == 0) { if ((state->anchor & both_vert) && box.height == 0) {
box.y = bounds.y; box.y = bounds.y;
box.height = bounds.height; box.height = bounds.height;
@ -592,6 +585,13 @@ void
arrangelayers(Monitor *m) arrangelayers(Monitor *m)
{ {
struct wlr_box usable_area = m->m; struct wlr_box usable_area = m->m;
uint32_t layers_above_shell[] = {
ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
ZWLR_LAYER_SHELL_V1_LAYER_TOP,
};
size_t nlayers = LENGTH(layers_above_shell);
LayerSurface *layersurface;
struct wlr_keyboard *kb = wlr_seat_get_keyboard(seat);
// Arrange exclusive surfaces from top->bottom // Arrange exclusive surfaces from top->bottom
arrangelayer(m, &m->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], arrangelayer(m, &m->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
@ -619,13 +619,6 @@ arrangelayers(Monitor *m)
&usable_area, 0); &usable_area, 0);
// Find topmost keyboard interactive layer, if such a layer exists // Find topmost keyboard interactive layer, if such a layer exists
uint32_t layers_above_shell[] = {
ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
ZWLR_LAYER_SHELL_V1_LAYER_TOP,
};
size_t nlayers = LENGTH(layers_above_shell);
LayerSurface *layersurface;
struct wlr_keyboard *kb = wlr_seat_get_keyboard(seat);
for (size_t i = 0; i < nlayers; ++i) { for (size_t i = 0; i < nlayers; ++i) {
wl_list_for_each_reverse(layersurface, wl_list_for_each_reverse(layersurface,
&m->layers[layers_above_shell[i]], link) { &m->layers[layers_above_shell[i]], link) {
@ -658,19 +651,21 @@ void
buttonpress(struct wl_listener *listener, void *data) buttonpress(struct wl_listener *listener, void *data)
{ {
struct wlr_event_pointer_button *event = data; struct wlr_event_pointer_button *event = data;
struct wlr_keyboard *keyboard;
uint32_t mods;
Client *c;
const Button *b;
wlr_idle_notify_activity(idle, seat); wlr_idle_notify_activity(idle, seat);
switch (event->state) { switch (event->state) {
case WLR_BUTTON_PRESSED:; case WLR_BUTTON_PRESSED:;
/* Change focus if the button was _pressed_ over a client */ /* Change focus if the button was _pressed_ over a client */
Client *c;
if ((c = xytoclient(cursor->x, cursor->y))) if ((c = xytoclient(cursor->x, cursor->y)))
focusclient(c, 1); focusclient(c, 1);
struct wlr_keyboard* keyboard = wlr_seat_get_keyboard(seat); keyboard = wlr_seat_get_keyboard(seat);
uint32_t mods = wlr_keyboard_get_modifiers(keyboard); mods = wlr_keyboard_get_modifiers(keyboard);
const Button *b;
for (b = buttons; b < END(buttons); b++) { for (b = buttons; b < END(buttons); b++) {
if (CLEANMASK(mods) == CLEANMASK(b->mod) && if (CLEANMASK(mods) == CLEANMASK(b->mod) &&
event->button == b->button && b->func) { event->button == b->button && b->func) {
@ -737,6 +732,7 @@ cleanupmon(struct wl_listener *listener, void *data)
{ {
struct wlr_output *wlr_output = data; struct wlr_output *wlr_output = data;
Monitor *m = wlr_output->data; Monitor *m = wlr_output->data;
int nmons, i = 0;
wl_list_remove(&m->destroy.link); wl_list_remove(&m->destroy.link);
wl_list_remove(&m->frame.link); wl_list_remove(&m->frame.link);
@ -744,7 +740,7 @@ cleanupmon(struct wl_listener *listener, void *data)
wlr_output_layout_remove(output_layout, m->wlr_output); wlr_output_layout_remove(output_layout, m->wlr_output);
updatemons(); updatemons();
int nmons = wl_list_length(&mons), i = 0; nmons = wl_list_length(&mons);
do // don't switch to disabled mons do // don't switch to disabled mons
selmon = wl_container_of(mons.prev, selmon, link); selmon = wl_container_of(mons.prev, selmon, link);
while (!selmon->wlr_output->enabled && i++ < nmons); while (!selmon->wlr_output->enabled && i++ < nmons);
@ -774,11 +770,12 @@ commitlayersurfacenotify(struct wl_listener *listener, void *data)
LayerSurface *layersurface = wl_container_of(listener, layersurface, surface_commit); LayerSurface *layersurface = wl_container_of(listener, layersurface, surface_commit);
struct wlr_layer_surface_v1 *wlr_layer_surface = layersurface->layer_surface; struct wlr_layer_surface_v1 *wlr_layer_surface = layersurface->layer_surface;
struct wlr_output *wlr_output = wlr_layer_surface->output; struct wlr_output *wlr_output = wlr_layer_surface->output;
Monitor *m;
if (!wlr_output) if (!wlr_output)
return; return;
Monitor *m = wlr_output->data; m = wlr_output->data;
arrangelayers(m); arrangelayers(m);
if (layersurface->layer != wlr_layer_surface->current.layer) { if (layersurface->layer != wlr_layer_surface->current.layer) {
@ -802,12 +799,14 @@ commitnotify(struct wl_listener *listener, void *data)
void void
createkeyboard(struct wlr_input_device *device) createkeyboard(struct wlr_input_device *device)
{ {
struct xkb_context *context;
struct xkb_keymap *keymap;
Keyboard *kb = device->data = calloc(1, sizeof(*kb)); Keyboard *kb = device->data = calloc(1, sizeof(*kb));
kb->device = device; kb->device = device;
/* Prepare an XKB keymap and assign it to the keyboard. */ /* Prepare an XKB keymap and assign it to the keyboard. */
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
struct xkb_keymap *keymap = xkb_map_new_from_names(context, &xkb_rules, keymap = xkb_map_new_from_names(context, &xkb_rules,
XKB_KEYMAP_COMPILE_NO_FLAGS); XKB_KEYMAP_COMPILE_NO_FLAGS);
wlr_keyboard_set_keymap(device->keyboard, keymap); wlr_keyboard_set_keymap(device->keyboard, keymap);
@ -835,6 +834,11 @@ createmon(struct wl_listener *listener, void *data)
/* This event is raised by the backend when a new output (aka a display or /* This event is raised by the backend when a new output (aka a display or
* monitor) becomes available. */ * monitor) becomes available. */
struct wlr_output *wlr_output = data; struct wlr_output *wlr_output = data;
Monitor *m;
const MonitorRule *r;
size_t nlayers;
Monitor *moni, *insertmon = NULL;
int x = 0;
/* The mode is a tuple of (width, height, refresh rate), and each /* The mode is a tuple of (width, height, refresh rate), and each
* monitor supports only a specific set of modes. We just pick the * monitor supports only a specific set of modes. We just pick the
@ -843,11 +847,11 @@ createmon(struct wl_listener *listener, void *data)
wlr_output_set_mode(wlr_output, wlr_output_preferred_mode(wlr_output)); wlr_output_set_mode(wlr_output, wlr_output_preferred_mode(wlr_output));
/* Allocates and configures monitor state using configured rules */ /* Allocates and configures monitor state using configured rules */
Monitor *m = wlr_output->data = calloc(1, sizeof(*m)); m = wlr_output->data = calloc(1, sizeof(*m));
m->wlr_output = wlr_output; m->wlr_output = wlr_output;
m->tagset[0] = m->tagset[1] = 1; m->tagset[0] = m->tagset[1] = 1;
m->position = -1; m->position = -1;
for (const MonitorRule *r = monrules; r < END(monrules); r++) { for (r = monrules; r < END(monrules); r++) {
if (!r->name || strstr(wlr_output->name, r->name)) { if (!r->name || strstr(wlr_output->name, r->name)) {
m->mfact = r->mfact; m->mfact = r->mfact;
m->nmaster = r->nmaster; m->nmaster = r->nmaster;
@ -867,8 +871,6 @@ createmon(struct wl_listener *listener, void *data)
m->destroy.notify = cleanupmon; m->destroy.notify = cleanupmon;
wl_signal_add(&wlr_output->events.destroy, &m->destroy); wl_signal_add(&wlr_output->events.destroy, &m->destroy);
Monitor *moni, *insertmon = NULL;
int x = 0;
wl_list_for_each(moni, &mons, link) wl_list_for_each(moni, &mons, link)
if (m->position > moni->position) if (m->position > moni->position)
insertmon = moni; insertmon = moni;
@ -898,7 +900,7 @@ createmon(struct wl_listener *listener, void *data)
} }
sgeom = *wlr_output_layout_get_box(output_layout, NULL); sgeom = *wlr_output_layout_get_box(output_layout, NULL);
size_t nlayers = LENGTH(m->layers); nlayers = LENGTH(m->layers);
for (size_t i = 0; i < nlayers; ++i) for (size_t i = 0; i < nlayers; ++i)
wl_list_init(&m->layers[i]); wl_list_init(&m->layers[i]);
@ -958,13 +960,15 @@ void
createlayersurface(struct wl_listener *listener, void *data) createlayersurface(struct wl_listener *listener, void *data)
{ {
struct wlr_layer_surface_v1 *wlr_layer_surface = data; struct wlr_layer_surface_v1 *wlr_layer_surface = data;
LayerSurface *layersurface;
Monitor *m;
struct wlr_layer_surface_v1_state old_state;
if (!wlr_layer_surface->output) { if (!wlr_layer_surface->output) {
wlr_layer_surface->output = selmon->wlr_output; wlr_layer_surface->output = selmon->wlr_output;
} }
LayerSurface *layersurface = calloc(1, sizeof(LayerSurface)); layersurface = calloc(1, sizeof(LayerSurface));
layersurface->surface_commit.notify = commitlayersurfacenotify; layersurface->surface_commit.notify = commitlayersurfacenotify;
wl_signal_add(&wlr_layer_surface->surface->events.commit, wl_signal_add(&wlr_layer_surface->surface->events.commit,
&layersurface->surface_commit); &layersurface->surface_commit);
@ -978,14 +982,13 @@ createlayersurface(struct wl_listener *listener, void *data)
layersurface->layer_surface = wlr_layer_surface; layersurface->layer_surface = wlr_layer_surface;
wlr_layer_surface->data = layersurface; wlr_layer_surface->data = layersurface;
Monitor *m = wlr_layer_surface->output->data; m = wlr_layer_surface->output->data;
wl_list_insert(&m->layers[wlr_layer_surface->client_pending.layer], wl_list_insert(&m->layers[wlr_layer_surface->client_pending.layer],
&layersurface->link); &layersurface->link);
// Temporarily set the layer's current state to client_pending // Temporarily set the layer's current state to client_pending
// so that we can easily arrange it // so that we can easily arrange it
struct wlr_layer_surface_v1_state old_state = wlr_layer_surface->current; old_state = wlr_layer_surface->current;
wlr_layer_surface->current = wlr_layer_surface->client_pending; wlr_layer_surface->current = wlr_layer_surface->client_pending;
arrangelayers(m); arrangelayers(m);
wlr_layer_surface->current = old_state; wlr_layer_surface->current = old_state;
@ -1156,14 +1159,15 @@ dirtomon(int dir)
void void
focusclient(Client *c, int lift) focusclient(Client *c, int lift)
{ {
struct wlr_surface *old = seat->keyboard_state.focused_surface;
struct wlr_keyboard *kb;
/* Raise client in stacking order if requested */ /* Raise client in stacking order if requested */
if (c && lift) { if (c && lift) {
wl_list_remove(&c->slink); wl_list_remove(&c->slink);
wl_list_insert(&stack, &c->slink); wl_list_insert(&stack, &c->slink);
} }
struct wlr_surface *old = seat->keyboard_state.focused_surface;
if (c && WLR_SURFACE(c) == old) if (c && WLR_SURFACE(c) == old)
return; return;
@ -1208,7 +1212,7 @@ focusclient(Client *c, int lift)
} }
/* Have a client, so focus its top-level wlr_surface */ /* Have a client, so focus its top-level wlr_surface */
struct wlr_keyboard *kb = wlr_seat_get_keyboard(seat); kb = wlr_seat_get_keyboard(seat);
wlr_seat_keyboard_notify_enter(seat, WLR_SURFACE(c), wlr_seat_keyboard_notify_enter(seat, WLR_SURFACE(c),
kb->keycodes, kb->num_keycodes, &kb->modifiers); kb->keycodes, kb->num_keycodes, &kb->modifiers);
@ -1287,6 +1291,8 @@ inputdevice(struct wl_listener *listener, void *data)
/* This event is raised by the backend when a new input device becomes /* This event is raised by the backend when a new input device becomes
* available. */ * available. */
struct wlr_input_device *device = data; struct wlr_input_device *device = data;
uint32_t caps;
switch (device->type) { switch (device->type) {
case WLR_INPUT_DEVICE_KEYBOARD: case WLR_INPUT_DEVICE_KEYBOARD:
createkeyboard(device); createkeyboard(device);
@ -1298,11 +1304,12 @@ inputdevice(struct wl_listener *listener, void *data)
/* TODO handle other input device types */ /* TODO handle other input device types */
break; break;
} }
/* We need to let the wlr_seat know what our capabilities are, which is /* We need to let the wlr_seat know what our capabilities are, which is
* communiciated to the client. In dwl we always have a cursor, even if * communiciated to the client. In dwl we always have a cursor, even if
* there are no pointer devices, so we always include that capability. */ * there are no pointer devices, so we always include that capability. */
/* TODO do we actually require a cursor? */ /* TODO do we actually require a cursor? */
uint32_t caps = WL_SEAT_CAPABILITY_POINTER; caps = WL_SEAT_CAPABILITY_POINTER;
if (!wl_list_empty(&keyboards)) if (!wl_list_empty(&keyboards))
caps |= WL_SEAT_CAPABILITY_KEYBOARD; caps |= WL_SEAT_CAPABILITY_KEYBOARD;
wlr_seat_set_capabilities(seat, caps); wlr_seat_set_capabilities(seat, caps);
@ -1479,6 +1486,10 @@ motionabsolute(struct wl_listener *listener, void *data)
void void
motionnotify(uint32_t time) motionnotify(uint32_t time)
{ {
double sx = 0, sy = 0;
struct wlr_surface *surface = NULL;
Client *c = NULL;
// time is 0 in internal calls meant to restore pointer focus. // time is 0 in internal calls meant to restore pointer focus.
if (time) { if (time) {
wlr_idle_notify_activity(idle, seat); wlr_idle_notify_activity(idle, seat);
@ -1501,9 +1512,6 @@ motionnotify(uint32_t time)
return; return;
} }
struct wlr_surface *surface = NULL;
double sx = 0, sy = 0;
Client *c = NULL;
if ((surface = xytolayersurface(&selmon->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], if ((surface = xytolayersurface(&selmon->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
cursor->x, cursor->y, &sx, &sy))) cursor->x, cursor->y, &sx, &sy)))
; ;
@ -1628,8 +1636,7 @@ outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test)
if (m->wlr_output->name == wlr_output->name) { if (m->wlr_output->name == wlr_output->name) {
// focus the left monitor (relative to the current focus) // focus the left monitor (relative to the current focus)
m->wlr_output->enabled = !m->wlr_output->enabled; m->wlr_output->enabled = !m->wlr_output->enabled;
Arg ar = {.i = -1}; focusmon(&(Arg) {.i = -1});
focusmon(&ar);
closemon(m); closemon(m);
m->wlr_output->enabled = !m->wlr_output->enabled; m->wlr_output->enabled = !m->wlr_output->enabled;
} }
@ -1662,6 +1669,9 @@ void
pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy,
uint32_t time) uint32_t time)
{ {
struct timespec now;
int internal_call = !time;
/* Use top level surface if nothing more specific given */ /* Use top level surface if nothing more specific given */
if (c && !surface) if (c && !surface)
surface = WLR_SURFACE(c); surface = WLR_SURFACE(c);
@ -1672,9 +1682,7 @@ pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy,
return; return;
} }
int internal_call = !time; if (internal_call) {
if (!time) {
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
time = now.tv_sec * 1000 + now.tv_nsec / 1000000; time = now.tv_sec * 1000 + now.tv_nsec / 1000000;
} }
@ -1713,6 +1721,10 @@ render(struct wlr_surface *surface, int sx, int sy, void *data)
/* This function is called for every surface that needs to be rendered. */ /* This function is called for every surface that needs to be rendered. */
struct render_data *rdata = data; struct render_data *rdata = data;
struct wlr_output *output = rdata->output; struct wlr_output *output = rdata->output;
double ox = 0, oy = 0;
struct wlr_box obox;
float matrix[9];
enum wl_output_transform transform;
/* We first obtain a wlr_texture, which is a GPU resource. wlroots /* We first obtain a wlr_texture, which is a GPU resource. wlroots
* automatically handles negotiating these with the client. The underlying * automatically handles negotiating these with the client. The underlying
@ -1727,17 +1739,14 @@ render(struct wlr_surface *surface, int sx, int sy, void *data)
* one next to the other, both 1080p, a client on the rightmost display might * one next to the other, both 1080p, a client on the rightmost display might
* have layout coordinates of 2000,100. We need to translate that to * have layout coordinates of 2000,100. We need to translate that to
* output-local coordinates, or (2000 - 1920). */ * output-local coordinates, or (2000 - 1920). */
double ox = 0, oy = 0;
wlr_output_layout_output_coords(output_layout, output, &ox, &oy); wlr_output_layout_output_coords(output_layout, output, &ox, &oy);
/* We also have to apply the scale factor for HiDPI outputs. This is only /* We also have to apply the scale factor for HiDPI outputs. This is only
* part of the puzzle, dwl does not fully support HiDPI. */ * part of the puzzle, dwl does not fully support HiDPI. */
struct wlr_box obox = { obox.x = ox + rdata->x + sx;
.x = ox + rdata->x + sx, obox.y = oy + rdata->y + sy;
.y = oy + rdata->y + sy, obox.width = surface->current.width;
.width = surface->current.width, obox.height = surface->current.height;
.height = surface->current.height,
};
scalebox(&obox, output->scale); scalebox(&obox, output->scale);
/* /*
@ -1751,9 +1760,7 @@ render(struct wlr_surface *surface, int sx, int sy, void *data)
* Naturally you can do this any way you like, for example to make a 3D * Naturally you can do this any way you like, for example to make a 3D
* compositor. * compositor.
*/ */
float matrix[9]; transform = wlr_output_transform_invert(surface->current.transform);
enum wl_output_transform transform = wlr_output_transform_invert(
surface->current.transform);
wlr_matrix_project_box(matrix, &obox, transform, 0, wlr_matrix_project_box(matrix, &obox, transform, 0,
output->transform_matrix); output->transform_matrix);
@ -1843,6 +1850,9 @@ renderlayer(struct wl_list *layer_surfaces, struct timespec *now)
void void
rendermon(struct wl_listener *listener, void *data) rendermon(struct wl_listener *listener, void *data)
{ {
Client *c;
int render = 1;
/* This function is called every time an output is ready to display a frame, /* This function is called every time an output is ready to display a frame,
* generally at the output's refresh rate (e.g. 60Hz). */ * generally at the output's refresh rate (e.g. 60Hz). */
Monitor *m = wl_container_of(listener, m, frame); Monitor *m = wl_container_of(listener, m, frame);
@ -1851,8 +1861,6 @@ rendermon(struct wl_listener *listener, void *data)
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
/* Do not render if any XDG clients have an outstanding resize. */ /* Do not render if any XDG clients have an outstanding resize. */
Client *c;
int render = 1;
wl_list_for_each(c, &stack, slink) { wl_list_for_each(c, &stack, slink) {
if (c->resize) { if (c->resize) {
wlr_surface_send_frame_done(WLR_SURFACE(c), &now); wlr_surface_send_frame_done(WLR_SURFACE(c), &now);
@ -1902,11 +1910,11 @@ resize(Client *c, int x, int y, int w, int h, int interact)
* compositor, you'd wait for the client to prepare a buffer at * compositor, you'd wait for the client to prepare a buffer at
* the new size, then commit any movement that was prepared. * the new size, then commit any movement that was prepared.
*/ */
struct wlr_box *bbox = interact ? &sgeom : &c->mon->w;
c->geom.x = x; c->geom.x = x;
c->geom.y = y; c->geom.y = y;
c->geom.width = w; c->geom.width = w;
c->geom.height = h; c->geom.height = h;
struct wlr_box *bbox = interact ? &sgeom : &c->mon->w;
applybounds(c, bbox); applybounds(c, bbox);
/* wlroots makes this a no-op if size hasn't changed */ /* wlroots makes this a no-op if size hasn't changed */
#ifdef XWAYLAND #ifdef XWAYLAND
@ -1923,6 +1931,8 @@ resize(Client *c, int x, int y, int w, int h, int interact)
void void
run(char *startup_cmd) run(char *startup_cmd)
{ {
pid_t startup_pid = -1;
/* Add a Unix socket to the Wayland display. */ /* Add a Unix socket to the Wayland display. */
const char *socket = wl_display_add_socket_auto(dpy); const char *socket = wl_display_add_socket_auto(dpy);
if (!socket) if (!socket)
@ -1948,9 +1958,8 @@ run(char *startup_cmd)
* startup command if requested. */ * startup command if requested. */
setenv("WAYLAND_DISPLAY", socket, 1); setenv("WAYLAND_DISPLAY", socket, 1);
pid_t startup_pid = -1;
if (startup_cmd) { if (startup_cmd) {
pid_t startup_pid = fork(); startup_pid = fork();
if (startup_pid < 0) if (startup_pid < 0)
EBARF("startup: fork"); EBARF("startup: fork");
if (startup_pid == 0) { if (startup_pid == 0) {
@ -2030,9 +2039,11 @@ setlayout(const Arg *arg)
void void
setmfact(const Arg *arg) setmfact(const Arg *arg)
{ {
float f;
if (!arg || !selmon->lt[selmon->sellt]->arrange) if (!arg || !selmon->lt[selmon->sellt]->arrange)
return; return;
float f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
if (f < 0.1 || f > 0.9) if (f < 0.1 || f > 0.9)
return; return;
selmon->mfact = f; selmon->mfact = f;
@ -2333,10 +2344,11 @@ togglefloating(const Arg *arg)
void void
toggletag(const Arg *arg) toggletag(const Arg *arg)
{ {
unsigned int newtags;
Client *sel = selclient(); Client *sel = selclient();
if (!sel) if (!sel)
return; return;
unsigned int newtags = sel->tags ^ (arg->ui & TAGMASK); newtags = sel->tags ^ (arg->ui & TAGMASK);
if (newtags) { if (newtags) {
sel->tags = newtags; sel->tags = newtags;
focusclient(focustop(selmon), 1); focusclient(focustop(selmon), 1);