Merge remote-tracking branch 'upstream/main' into wlroots-next

This commit is contained in:
Leonardo Hernández Hernández 2024-01-24 12:09:42 -06:00
commit 1c3aaa70ba
No known key found for this signature in database
GPG key ID: E538897EE11B9624
6 changed files with 50 additions and 42 deletions

View file

@ -33,6 +33,14 @@ body:
validations: validations:
required: false required: false
- type: textarea
attributes:
label: Description
value: |
The steps you took to reproduce the problem.
validations:
required: false
- type: textarea - type: textarea
id: debug_log id: debug_log
attributes: attributes:
@ -52,11 +60,3 @@ body:
- If the lines mentioning dwl or wlroots have `??`. Please compile both dwl and wlroots from source (enabling debug symbols) and try to reproduce. - If the lines mentioning dwl or wlroots have `??`. Please compile both dwl and wlroots from source (enabling debug symbols) and try to reproduce.
validations: validations:
required: false required: false
- type: textarea
attributes:
label: Description
value: |
The steps you took to reproduce the problem.
validations:
required: false

View file

@ -5,8 +5,8 @@ include config.mk
# flags for compiling # flags for compiling
DWLCPPFLAGS = -I. -DWLR_USE_UNSTABLE -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XWAYLAND) DWLCPPFLAGS = -I. -DWLR_USE_UNSTABLE -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XWAYLAND)
DWLDEVCFLAGS = -g -pedantic -Wall -Wextra -Wdeclaration-after-statement -Wno-unused-parameter -Wno-sign-compare -Wshadow -Wunused-macros\ DWLDEVCFLAGS = -g -pedantic -Wall -Wextra -Wdeclaration-after-statement -Wno-unused-parameter -Wshadow -Wunused-macros\
-Werror=strict-prototypes -Werror=implicit -Werror=return-type -Werror=incompatible-pointer-types -Werror=strict-prototypes -Werror=implicit -Werror=return-type -Werror=incompatible-pointer-types -Wfloat-conversion
# CFLAGS / LDFLAGS # CFLAGS / LDFLAGS
PKGS = wlroots wayland-server xkbcommon libinput $(XLIBS) PKGS = wlroots wayland-server xkbcommon libinput $(XLIBS)

View file

@ -5,12 +5,11 @@ Or on our [Discord server].
dwl is a compact, hackable compositor for [Wayland] based on [wlroots]. It is dwl is a compact, hackable compositor for [Wayland] based on [wlroots]. It is
intended to fill the same space in the Wayland world that dwm does in X11, intended to fill the same space in the Wayland world that dwm does in X11,
primarily in terms of philosophy, and secondarily in terms of functionality. primarily in terms of functionality, and secondarily in terms of philosophy.
Like dwm, dwl is: Like dwm, dwl is:
- Easy to understand, hack on, and extend with patches - Easy to understand, hack on, and extend with patches
- One C source file (or a very small number) configurable via `config.h` - One C source file (or a very small number) configurable via `config.h`
- Limited to 2200 SLOC to promote hackability
- Tied to as few external dependencies as possible - Tied to as few external dependencies as possible
dwl is not meant to provide every feature under the sun. Instead, like dwm, it dwl is not meant to provide every feature under the sun. Instead, like dwm, it
@ -34,6 +33,12 @@ given the base on which it is built. Implemented default features are:
- Layer shell popups (used by Waybar) - Layer shell popups (used by Waybar)
- Damage tracking provided by scenegraph API - Damage tracking provided by scenegraph API
Given the Wayland architecture, dwl has to implement features from dwm **and**
the xorg-server. Because of this, it is impossible to maintain the original
project goal of 2000 SLOC and have a reasonably complete compositor with
features comparable to dwm. However, this does not mean that the code will grow
indiscriminately. We will try to keep the code as small as possible.
Features under consideration (possibly as patches) are: Features under consideration (possibly as patches) are:
- Protocols made trivial by wlroots - Protocols made trivial by wlroots
@ -152,6 +157,7 @@ possible.
Many thanks to suckless.org and the dwm developers and community for the Many thanks to suckless.org and the dwm developers and community for the
inspiration, and to the various contributors to the project, including: inspiration, and to the various contributors to the project, including:
- **Devin J. Pohly for creating and nurturing the fledgling project**
- Alexander Courtis for the XWayland implementation - Alexander Courtis for the XWayland implementation
- Guido Cella for the layer-shell protocol implementation, patch maintenance, - Guido Cella for the layer-shell protocol implementation, patch maintenance,
and for helping to keep the project running and for helping to keep the project running

View file

@ -339,10 +339,10 @@ client_set_size(Client *c, uint32_t width, uint32_t height)
return 0; return 0;
} }
#endif #endif
if (width == c->surface.xdg->toplevel->current.width if ((int32_t)width == c->surface.xdg->toplevel->current.width
&& height ==c->surface.xdg->toplevel->current.height) && (int32_t)height == c->surface.xdg->toplevel->current.height)
return 0; return 0;
return wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, width, height); return wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, (int32_t)width, (int32_t)height);
} }
static inline void static inline void

View file

@ -12,7 +12,7 @@ static const float bordercolor[] = COLOR(0x444444ff);
static const float focuscolor[] = COLOR(0x005577ff); static const float focuscolor[] = COLOR(0x005577ff);
static const float urgentcolor[] = COLOR(0xff0000ff); static const float urgentcolor[] = COLOR(0xff0000ff);
/* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */ /* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */
static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0}; /* You can also use glsl colors */ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */
/* tagging - TAGCOUNT must be no greater than 31 */ /* tagging - TAGCOUNT must be no greater than 31 */
#define TAGCOUNT (9) #define TAGCOUNT (9)
@ -39,12 +39,12 @@ static const Layout layouts[] = {
/* monitors */ /* monitors */
/* NOTE: ALWAYS add a fallback rule, even if you are completely sure it won't be used */ /* NOTE: ALWAYS add a fallback rule, even if you are completely sure it won't be used */
static const MonitorRule monrules[] = { static const MonitorRule monrules[] = {
/* name mfact nmaster scale layout rotate/reflect x y */ /* name mfact nmaster scale layout rotate/reflect x y */
/* example of a HiDPI laptop monitor: /* example of a HiDPI laptop monitor:
{ "eDP-1", 0.5, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 }, { "eDP-1", 0.5f, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
*/ */
/* defaults */ /* defaults */
{ NULL, 0.55, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 }, { NULL, 0.55f, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
}; };
/* keyboard */ /* keyboard */
@ -126,8 +126,8 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} }, { MODKEY, XKB_KEY_k, focusstack, {.i = -1} },
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} }, { MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
{ MODKEY, XKB_KEY_d, incnmaster, {.i = -1} }, { MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
{ MODKEY, XKB_KEY_h, setmfact, {.f = -0.05} }, { MODKEY, XKB_KEY_h, setmfact, {.f = -0.05f} },
{ MODKEY, XKB_KEY_l, setmfact, {.f = +0.05} }, { MODKEY, XKB_KEY_l, setmfact, {.f = +0.05f} },
{ MODKEY, XKB_KEY_Return, zoom, {0} }, { MODKEY, XKB_KEY_Return, zoom, {0} },
{ MODKEY, XKB_KEY_Tab, view, {0} }, { MODKEY, XKB_KEY_Tab, view, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} },

44
dwl.c
View file

@ -64,6 +64,7 @@
/* macros */ /* macros */
#define MAX(A, B) ((A) > (B) ? (A) : (B)) #define MAX(A, B) ((A) > (B) ? (A) : (B))
#define MIN(A, B) ((A) < (B) ? (A) : (B)) #define MIN(A, B) ((A) < (B) ? (A) : (B))
#define ROUND(X) ((int)((X < 0) ? (X - 0.5) : (X + 0.5)))
#define CLEANMASK(mask) (mask & ~WLR_MODIFIER_CAPS) #define CLEANMASK(mask) (mask & ~WLR_MODIFIER_CAPS)
#define VISIBLEON(C, M) ((M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags])) #define VISIBLEON(C, M) ((M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags]))
#define LENGTH(X) (sizeof X / sizeof X[0]) #define LENGTH(X) (sizeof X / sizeof X[0])
@ -195,7 +196,7 @@ struct Monitor {
unsigned int seltags; unsigned int seltags;
unsigned int sellt; unsigned int sellt;
uint32_t tagset[2]; uint32_t tagset[2];
double mfact; float mfact;
int gamma_lut_changed; int gamma_lut_changed;
int nmaster; int nmaster;
char ltsymbol[16]; char ltsymbol[16];
@ -416,9 +417,9 @@ applybounds(Client *c, struct wlr_box *bbox)
c->geom.x = bbox->x + bbox->width - c->geom.width; c->geom.x = bbox->x + bbox->width - c->geom.width;
if (c->geom.y >= bbox->y + bbox->height) if (c->geom.y >= bbox->y + bbox->height)
c->geom.y = bbox->y + bbox->height - c->geom.height; c->geom.y = bbox->y + bbox->height - c->geom.height;
if (c->geom.x + c->geom.width + 2 * c->bw <= bbox->x) if (c->geom.x + c->geom.width + 2 * (int)c->bw <= bbox->x)
c->geom.x = bbox->x; c->geom.x = bbox->x;
if (c->geom.y + c->geom.height + 2 * c->bw <= bbox->y) if (c->geom.y + c->geom.height + 2 * (int)c->bw <= bbox->y)
c->geom.y = bbox->y; c->geom.y = bbox->y;
} }
@ -427,7 +428,8 @@ applyrules(Client *c)
{ {
/* rule matching */ /* rule matching */
const char *appid, *title; const char *appid, *title;
uint32_t i, newtags = 0; uint32_t newtags = 0;
int i;
const Rule *r; const Rule *r;
Monitor *mon = selmon, *m; Monitor *mon = selmon, *m;
@ -521,7 +523,7 @@ arrangelayers(Monitor *m)
arrangelayer(m, &m->layers[i], &usable_area, 0); arrangelayer(m, &m->layers[i], &usable_area, 0);
/* Find topmost keyboard interactive layer, if such a layer exists */ /* Find topmost keyboard interactive layer, if such a layer exists */
for (i = 0; i < LENGTH(layers_above_shell); i++) { for (i = 0; i < (int)LENGTH(layers_above_shell); i++) {
wl_list_for_each_reverse(l, &m->layers[layers_above_shell[i]], link) { wl_list_for_each_reverse(l, &m->layers[layers_above_shell[i]], link) {
if (locked || !l->layer_surface->current.keyboard_interactive || !l->mapped) if (locked || !l->layer_surface->current.keyboard_interactive || !l->mapped)
continue; continue;
@ -657,7 +659,7 @@ cleanupmon(struct wl_listener *listener, void *data)
{ {
Monitor *m = wl_container_of(listener, m, destroy); Monitor *m = wl_container_of(listener, m, destroy);
LayerSurface *l, *tmp; LayerSurface *l, *tmp;
int i; size_t i;
/* m->layers[i] are intentionally not unlinked */ /* m->layers[i] are intentionally not unlinked */
for (i = 0; i < LENGTH(m->layers); i++) { for (i = 0; i < LENGTH(m->layers); i++) {
@ -672,9 +674,9 @@ cleanupmon(struct wl_listener *listener, void *data)
m->wlr_output->data = NULL; m->wlr_output->data = NULL;
wlr_output_layout_remove(output_layout, m->wlr_output); wlr_output_layout_remove(output_layout, m->wlr_output);
wlr_scene_output_destroy(m->scene_output); wlr_scene_output_destroy(m->scene_output);
wlr_scene_node_destroy(&m->fullscreen_bg->node);
closemon(m); closemon(m);
wlr_scene_node_destroy(&m->fullscreen_bg->node);
free(m); free(m);
} }
@ -745,7 +747,7 @@ commitnotify(struct wl_listener *listener, void *data)
if (c->surface.xdg->initial_commit) if (c->surface.xdg->initial_commit)
wlr_xdg_toplevel_set_wm_capabilities(c->surface.xdg->toplevel, WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); wlr_xdg_toplevel_set_wm_capabilities(c->surface.xdg->toplevel, WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
if (client_surface(c)->mapped) if (client_surface(c)->mapped && c->mon)
resize(c, c->geom, (c->isfloating && !c->isfullscreen)); resize(c, c->geom, (c->isfloating && !c->isfullscreen));
/* mark a pending resize as completed */ /* mark a pending resize as completed */
@ -1633,17 +1635,17 @@ motionnotify(uint32_t time)
} }
/* Update drag icon's position */ /* Update drag icon's position */
wlr_scene_node_set_position(&drag_icon->node, cursor->x, cursor->y); wlr_scene_node_set_position(&drag_icon->node, ROUND(cursor->x), ROUND(cursor->y));
/* If we are currently grabbing the mouse, handle and return */ /* If we are currently grabbing the mouse, handle and return */
if (cursor_mode == CurMove) { if (cursor_mode == CurMove) {
/* Move the grabbed client to the new position. */ /* Move the grabbed client to the new position. */
resize(grabc, (struct wlr_box){.x = cursor->x - grabcx, .y = cursor->y - grabcy, resize(grabc, (struct wlr_box){.x = ROUND(cursor->x) - grabcx, .y = ROUND(cursor->y) - grabcy,
.width = grabc->geom.width, .height = grabc->geom.height}, 1); .width = grabc->geom.width, .height = grabc->geom.height}, 1);
return; return;
} else if (cursor_mode == CurResize) { } else if (cursor_mode == CurResize) {
resize(grabc, (struct wlr_box){.x = grabc->geom.x, .y = grabc->geom.y, resize(grabc, (struct wlr_box){.x = grabc->geom.x, .y = grabc->geom.y,
.width = cursor->x - grabc->geom.x, .height = cursor->y - grabc->geom.y}, 1); .width = ROUND(cursor->x) - grabc->geom.x, .height = ROUND(cursor->y) - grabc->geom.y}, 1);
return; return;
} }
@ -1695,8 +1697,8 @@ moveresize(const Arg *arg)
setfloating(grabc, 1); setfloating(grabc, 1);
switch (cursor_mode = arg->ui) { switch (cursor_mode = arg->ui) {
case CurMove: case CurMove:
grabcx = cursor->x - grabc->geom.x; grabcx = ROUND(cursor->x) - grabc->geom.x;
grabcy = cursor->y - grabc->geom.y; grabcy = ROUND(cursor->y) - grabc->geom.y;
wlr_cursor_set_xcursor(cursor, cursor_mgr, "fleur"); wlr_cursor_set_xcursor(cursor, cursor_mgr, "fleur");
break; break;
case CurResize: case CurResize:
@ -1769,9 +1771,6 @@ apply_or_test:
else else
wlr_output_configuration_v1_send_failed(config); wlr_output_configuration_v1_send_failed(config);
wlr_output_configuration_v1_destroy(config); wlr_output_configuration_v1_destroy(config);
/* TODO: use a wrapper function? */
updatemons(NULL, NULL);
} }
void void
@ -2089,6 +2088,8 @@ setgamma(struct wl_listener *listener, void *data)
{ {
struct wlr_gamma_control_manager_v1_set_gamma_event *event = data; struct wlr_gamma_control_manager_v1_set_gamma_event *event = data;
Monitor *m = event->output->data; Monitor *m = event->output->data;
if (!m)
return;
m->gamma_lut_changed = 1; m->gamma_lut_changed = 1;
wlr_output_schedule_frame(m->wlr_output); wlr_output_schedule_frame(m->wlr_output);
} }
@ -2115,7 +2116,7 @@ setmfact(const Arg *arg)
if (!arg || !selmon || !selmon->lt[selmon->sellt]->arrange) if (!arg || !selmon || !selmon->lt[selmon->sellt]->arrange)
return; return;
f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; f = arg->f < 1.0f ? arg->f + selmon->mfact : arg->f - 1.0f;
if (f < 0.1 || f > 0.9) if (f < 0.1 || f > 0.9)
return; return;
selmon->mfact = f; selmon->mfact = f;
@ -2177,7 +2178,7 @@ setup(void)
struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig}; struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig};
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
for (i = 0; i < LENGTH(sig); i++) for (i = 0; i < (int)LENGTH(sig); i++)
sigaction(sig[i], &sa, NULL); sigaction(sig[i], &sa, NULL);
wlr_log_init(log_level, NULL); wlr_log_init(log_level, NULL);
@ -2287,7 +2288,7 @@ setup(void)
wl_signal_add(&session_lock_mgr->events.new_lock, &lock_listener); wl_signal_add(&session_lock_mgr->events.new_lock, &lock_listener);
LISTEN_STATIC(&session_lock_mgr->events.destroy, destroysessionmgr); LISTEN_STATIC(&session_lock_mgr->events.destroy, destroysessionmgr);
locked_bg = wlr_scene_rect_create(layers[LyrBlock], sgeom.width, sgeom.height, locked_bg = wlr_scene_rect_create(layers[LyrBlock], sgeom.width, sgeom.height,
(float [4]){0.1, 0.1, 0.1, 1.0}); (float [4]){0.1f, 0.1f, 0.1f, 1.0f});
wlr_scene_node_set_enabled(&locked_bg->node, 0); wlr_scene_node_set_enabled(&locked_bg->node, 0);
/* Use decoration protocols to negotiate server-side decorations */ /* Use decoration protocols to negotiate server-side decorations */
@ -2463,7 +2464,8 @@ tagmon(const Arg *arg)
void void
tile(Monitor *m) tile(Monitor *m)
{ {
unsigned int i, n = 0, mw, my, ty; unsigned int mw, my, ty;
int i, n = 0;
Client *c; Client *c;
wl_list_for_each(c, &clients, link) wl_list_for_each(c, &clients, link)
@ -2473,7 +2475,7 @@ tile(Monitor *m)
return; return;
if (n > m->nmaster) if (n > m->nmaster)
mw = m->nmaster ? m->w.width * m->mfact : 0; mw = m->nmaster ? ROUND(m->w.width * m->mfact) : 0;
else else
mw = m->w.width; mw = m->w.width;
i = my = ty = 0; i = my = ty = 0;