16 Commits

Author SHA1 Message Date
Diego Viola a2d03cf618 Remove trailing whitespace from README 2026-03-02 02:13:43 +01:00
Diego Viola cb4cc3ae8f Fix typos 2026-02-25 02:38:09 -03:00
thanatos 9b76ee8e90 Updated README to clarify branch roles
This change effectively reverts DWL to the prior development model, where development of DWL itself happens against the current wlroots release, and changes in anticipation of the next wlroots release are made on a separate branch.
2026-02-21 19:50:17 +01:00
thanatos 908a73da82 Corrected README 2026-02-21 16:53:19 +01:00
thanatos 227cdf0128 Added Matrix to README 2026-02-21 16:46:08 +01:00
Guido Cella ca4123072d add support for the data control protocol
Enables the protocol documented at
https://wayland.app/protocols/ext-data-control-v1

It is the upstreamed version of the old wlr_data_control.

It is used e.g. by mpv to read and write the clipboard.
2026-02-12 01:47:40 +01:00
fauxmight a8915224e8 Remove "unmaintained" notice from README
User @thanatos has offered to take on the lead developer role for dwl.
2026-02-09 08:06:25 +01:00
A Frederick Christensen 9b11a49cb7 config.def.h clarify Rule and MonitorRule comments closes #660 2025-12-27 17:08:32 -06:00
A Frederick Christensen 53e3e60d4d config.def.h whitespace cleanup 2025-12-27 16:47:38 -06:00
jackinfurs 9837ea5729 fix: ignore case of keysyms in keybindings 2025-12-27 21:26:26 +00:00
fauxmight 9ba7461f4d Update README.md 2025-12-19 06:12:24 +01:00
fauxmight aca61738a2 Note unmaintained status in README 2025-12-19 06:12:03 +01:00
fauxmight 6cd26568d5 Update README.md
Document Java nonreparenting WM issue

Closes #722
2025-09-29 05:56:22 +02:00
fauxmight ed2e1efda8 Update README.md
Make "dwl" references in README.md links to dwm main site.

Closes #1168
2025-09-29 05:39:54 +02:00
A Frederick Christensen ab4cb6e283 Revert "add support for ext-image-copy-capture-v1 and ext-image-capture-source-v1 (wlroots!4545)"
This reverts commit b28674e0ca.

This PR is not yet finalized. (Screen freezes).
2025-08-04 16:27:34 -05:00
Leonardo Hernández Hernández b28674e0ca add support for ext-image-copy-capture-v1 and ext-image-capture-source-v1 (wlroots!4545)
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4545
2025-08-04 23:08:53 +02:00
4 changed files with 81 additions and 130 deletions
-4
View File
@@ -20,7 +20,6 @@ all: dwl
dwl: dwl.o util.o
$(CC) dwl.o util.o $(DWLCFLAGS) $(LDFLAGS) $(LDLIBS) -o $@
dwl.o: dwl.c client.h config.h config.mk cursor-shape-v1-protocol.h \
ext-image-copy-capture-v1-protocol.h \
pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h \
wlr-output-power-management-unstable-v1-protocol.h xdg-shell-protocol.h
util.o: util.c util.h
@@ -34,9 +33,6 @@ WAYLAND_PROTOCOLS = `$(PKG_CONFIG) --variable=pkgdatadir wayland-protocols`
cursor-shape-v1-protocol.h:
$(WAYLAND_SCANNER) enum-header \
$(WAYLAND_PROTOCOLS)/staging/cursor-shape/cursor-shape-v1.xml $@
ext-image-copy-capture-v1-protocol.h:
$(WAYLAND_SCANNER) enum-header \
$(WAYLAND_PROTOCOLS)/staging/ext-image-copy-capture/ext-image-copy-capture-v1.xml $@
pointer-constraints-unstable-v1-protocol.h:
$(WAYLAND_SCANNER) enum-header \
$(WAYLAND_PROTOCOLS)/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml $@
+31 -16
View File
@@ -1,12 +1,13 @@
# dwl - dwm for Wayland
Join us on our IRC channel: [#dwl on Libera Chat]
Or on the community-maintained [Discord server].
Join us on our [Discord server]
Or Matrix: [#dwl-official:matrix.org]
Or on our IRC channel: [#dwl on Libera Chat]
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 functionality, and secondarily in terms of
philosophy. Like dwm, dwl is:
philosophy. Like [dwm], dwl is:
- Easy to understand, hack on, and extend with patches
- One C source file (or a very small number) configurable via `config.h`
@@ -23,11 +24,13 @@ with each release on the [release] page
### Development branch [main]
Active development progresses on the `main` branch. The `main` branch is built
against a late (and often changing) git commit of wlroots. While the adventurous
are welcome to use `main`, it is a rocky road. Using `main` requires that the
user be willing to chase git commits of wlroots. Testing development pull
requests may involve merging unmerged pull requests in [wlroots]' git repository
and/or git commits of wayland.
against the latest release of [wlroots]. PRs should target this branch unless they
depend on functionality that is not in the current release of `wlroots`.
### Preview branch [wlroots-next]
The `wlroots-next` branch is built against the git version of [wlroots], which
is unstable and changes frequently. PRs requiring functionality from the git
version of `wlroots` should target this branch.
### Building dwl
dwl has the following dependencies:
@@ -55,11 +58,11 @@ To enable XWayland, you should uncomment its flags in `config.mk`.
## Configuration
All configuration is done by editing `config.h` and recompiling, in the same
manner as dwm. There is no way to separately restart the window manager in
manner as [dwm]. There is no way to separately restart the window manager in
Wayland without restarting the entire display server, so any changes will take
effect the next time dwl is executed.
As in the dwm community, we encourage users to share patches they have
As in the [dwm] community, we encourage users to share patches they have
created. Check out the [dwl-patches] repository!
## Running dwl
@@ -118,17 +121,26 @@ script with the line
To get a list of status bars that work with dwl consult our [wiki].
### (Known) Java nonreparenting WM issue
Certain IDEs don't display correctly unless an environmental variable for Java AWT
indicates that the WM is nonreparenting.
For some Java AWT-based IDEs, such as Xilinx Vivado and Microchip MPLAB X, the
following environment variable needs to be set before running the IDE or dwl:
export _JAVA_AWT_WM_NONREPARENTING=1
## Replacements for X applications
You can find a [list of useful resources on our wiki].
## Background
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
sticks to features which are necessary, simple, and straightforward to implement
given the base on which it is built. Implemented default features are:
- Any features provided by dwm/Xlib: simple window borders, tags, keybindings,
- Any features provided by [dwm]/Xlib: simple window borders, tags, keybindings,
client rules, mouse move/resize. Providing a built-in status bar is an
exception to this goal, to avoid dependencies on font rendering and/or drawing
libraries when an external bar could work well.
@@ -145,10 +157,10 @@ given the base on which it is built. Implemented default features are:
- Layer shell popups (used by Waybar)
- Damage tracking provided by scenegraph API
Given the Wayland architecture, dwl has to implement features from dwm **and**
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
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:
@@ -172,7 +184,7 @@ developers. This was made possible in many cases by looking at how sway
accomplished something, then trying to do the same in as suckless a way as
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:
- **Devin J. Pohly for creating and nurturing the fledgling project**
@@ -183,6 +195,7 @@ inspiration, and to the various contributors to the project, including:
[wlroots]: https://gitlab.freedesktop.org/wlroots
[dwm]: https://dwm.suckless.org/
[`systemd --user`]: https://wiki.archlinux.org/title/Systemd/User
[#dwl on Libera Chat]: https://web.libera.chat/?channels=#dwl
[0.7-rc1]: https://codeberg.org/dwl/dwl/releases/tag/v0.7-rc1
@@ -192,6 +205,7 @@ inspiration, and to the various contributors to the project, including:
[dwl-patches]: https://codeberg.org/dwl/dwl-patches
[list of useful resources on our wiki]: https://codeberg.org/dwl/dwl/wiki/Home#migrating-from-x
[main]: https://codeberg.org/dwl/dwl/src/branch/main
[wlroots-next]: https://codeberg.org/dwl/dwl/src/branch/wlroots-next
[release]: https://codeberg.org/dwl/dwl/releases
[runit]: http://smarden.org/runit/faq.html#userservices
[s6]: https://skarnet.org/software/s6/
@@ -199,3 +213,4 @@ inspiration, and to the various contributors to the project, including:
[wiki]: https://codeberg.org/dwl/dwl/wiki/Home#compatible-status-bars
[Discord server]: https://discord.gg/jJxZnrGPWN
[Wayland]: https://wayland.freedesktop.org/
[#dwl-official:matrix.org]: https://matrix.to/#/#dwl-official:matrix.org
+10 -14
View File
@@ -20,12 +20,11 @@ static const float fullscreen_bg[] = {0.0f, 0.0f, 0.0f, 1.0f}; /* You ca
/* logging */
static int log_level = WLR_ERROR;
/* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */
static const Rule rules[] = {
/* app_id title tags mask isfloating monitor */
/* examples: */
{ "Gimp_EXAMPLE", NULL, 0, 1, -1 }, /* Start on currently visible tags floating, not tiled */
{ "firefox_EXAMPLE", NULL, 1 << 8, 0, -1 }, /* Start on ONLY tag "9" */
/* default/example rule: can be changed but cannot be eliminated; at least one rule must exist */
};
/* layout(s) */
@@ -38,17 +37,14 @@ static const Layout layouts[] = {
/* monitors */
/* (x=-1, y=-1) is reserved as an "autoconfigure" monitor position indicator
* WARNING: negative values other than (-1, -1) cause problems with Xwayland clients
* https://gitlab.freedesktop.org/xorg/xserver/-/issues/899
*/
/* NOTE: ALWAYS add a fallback rule, even if you are completely sure it won't be used */
* WARNING: negative values other than (-1, -1) cause problems with Xwayland clients due to
* https://gitlab.freedesktop.org/xorg/xserver/-/issues/899 */
static const MonitorRule monrules[] = {
/* name mfact nmaster scale layout rotate/reflect x y */
/* example of a HiDPI laptop monitor:
{ "eDP-1", 0.5f, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
*/
/* defaults */
/* name mfact nmaster scale layout rotate/reflect x y
* example of a HiDPI laptop monitor:
{ "eDP-1", 0.5f, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 }, */
{ NULL, 0.55f, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
/* default monitor rule: can be changed but cannot be eliminated; at least one monitor rule must exist */
};
/* keyboard */
@@ -123,7 +119,7 @@ static const char *termcmd[] = { "foot", NULL };
static const char *menucmd[] = { "wmenu-run", NULL };
static const Key keys[] = {
/* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
/* Note that Shift changes certain key codes: 2 -> at, etc. */
/* modifier key function argument */
{ MODKEY, XKB_KEY_p, spawn, {.v = menucmd} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} },
@@ -135,7 +131,7 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_l, setmfact, {.f = +0.05f} },
{ MODKEY, XKB_KEY_Return, zoom, {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} },
{ MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
@@ -157,7 +153,7 @@ static const Key keys[] = {
TAGKEYS( XKB_KEY_7, XKB_KEY_ampersand, 6),
TAGKEYS( XKB_KEY_8, XKB_KEY_asterisk, 7),
TAGKEYS( XKB_KEY_9, XKB_KEY_parenleft, 8),
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, quit, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_q, quit, {0} },
/* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} },
+7 -63
View File
@@ -24,8 +24,7 @@
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_drm.h>
#include <wlr/types/wlr_export_dmabuf_v1.h>
#include <wlr/types/wlr_ext_image_capture_source_v1.h>
#include <wlr/types/wlr_ext_image_copy_capture_v1.h>
#include <wlr/types/wlr_ext_data_control_v1.h>
#include <wlr/types/wlr_fractional_scale_v1.h>
#include <wlr/types/wlr_gamma_control_v1.h>
#include <wlr/types/wlr_idle_inhibit_v1.h>
@@ -61,8 +60,6 @@
#include <wlr/types/wlr_xdg_decoration_v1.h>
#include <wlr/types/wlr_xdg_output_v1.h>
#include <wlr/types/wlr_xdg_shell.h>
#include <wlr/types/wlr_ext_image_capture_source_v1.h>
#include <wlr/types/wlr_ext_foreign_toplevel_list_v1.h>
#include <wlr/util/log.h>
#include <wlr/util/region.h>
#include <xkbcommon/xkbcommon.h>
@@ -124,9 +121,6 @@ typedef struct {
} surface;
struct wlr_xdg_toplevel_decoration_v1 *decoration;
struct wl_listener commit;
struct wlr_scene *image_capture_scene;
struct wlr_ext_image_capture_source_v1 *image_capture_source;
struct wlr_scene_tree *image_capture_tree;
struct wl_listener map;
struct wl_listener maximize;
struct wl_listener unmap;
@@ -136,7 +130,6 @@ typedef struct {
struct wl_listener set_decoration_mode;
struct wl_listener destroy_decoration;
#ifdef XWAYLAND
struct wlr_scene_surface *image_capture_scene_surface;
struct wl_listener activate;
struct wl_listener associate;
struct wl_listener dissociate;
@@ -147,7 +140,6 @@ typedef struct {
uint32_t tags;
int isfloating, isurgent, isfullscreen;
uint32_t resize; /* configure serial of a pending resize */
struct wlr_ext_foreign_toplevel_handle_v1 *ext_foreign_toplevel;
} Client;
typedef struct {
@@ -380,8 +372,6 @@ static struct wlr_session *session;
static struct wlr_xdg_shell *xdg_shell;
static struct wlr_xdg_activation_v1 *activation;
static struct wlr_ext_foreign_toplevel_image_capture_source_manager_v1 *ext_foreign_toplevel_image_capture_source_manager_v1;
static struct wl_listener new_foreign_toplevel_capture_request;
static struct wlr_xdg_decoration_manager_v1 *xdg_decoration_mgr;
static struct wl_list clients; /* tiling order */
static struct wl_list fstack; /* focus order */
@@ -393,7 +383,6 @@ static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr;
static struct wlr_virtual_pointer_manager_v1 *virtual_pointer_mgr;
static struct wlr_cursor_shape_manager_v1 *cursor_shape_mgr;
static struct wlr_output_power_manager_v1 *power_mgr;
static struct wlr_ext_foreign_toplevel_list_v1 *foreign_toplevel_list;
static struct wlr_pointer_constraints_v1 *pointer_constraints;
static struct wlr_relative_pointer_manager_v1 *relative_pointer_mgr;
@@ -597,7 +586,7 @@ arrangelayers(Monitor *m)
arrange(m);
}
/* Arrange non-exlusive surfaces from top->bottom */
/* Arrange non-exclusive surfaces from top->bottom */
for (i = 3; i >= 0; i--)
arrangelayer(m, &m->layers[i], &usable_area, 0);
@@ -794,7 +783,6 @@ cleanuplisteners(void)
wl_list_remove(&request_start_drag.link);
wl_list_remove(&start_drag.link);
wl_list_remove(&new_session_lock.link);
wl_list_remove(&new_foreign_toplevel_capture_request.link);
#ifdef XWAYLAND
wl_list_remove(&new_xwayland_surface.link);
wl_list_remove(&xwayland_ready.link);
@@ -1136,7 +1124,6 @@ createnotify(struct wl_listener *listener, void *data)
struct wlr_xdg_toplevel *toplevel = data;
Client *c = NULL;
/* Allocate a Client for this surface */
c = toplevel->base->data = ecalloc(1, sizeof(*c));
c->surface.xdg = toplevel->base;
@@ -1630,7 +1617,8 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
const Key *k;
for (k = keys; k < END(keys); k++) {
if (CLEANMASK(mods) == CLEANMASK(k->mod)
&& sym == k->keysym && k->func) {
&& xkb_keysym_to_lower(sym) == xkb_keysym_to_lower(k->keysym)
&& k->func) {
k->func(&k->arg);
return 1;
}
@@ -1756,12 +1744,6 @@ mapnotify(struct wl_listener *listener, void *data)
Monitor *m;
int i;
struct wlr_ext_foreign_toplevel_handle_v1_state foreign_toplevel_state = {
.app_id = client_get_appid(c),
.title = client_get_title(c),
};
/* Create scene tree for this client and its border */
c->scene = client_surface(c)->data = wlr_scene_tree_create(layers[LyrTile]);
/* Enabled later by a call to arrange() */
@@ -1770,16 +1752,6 @@ mapnotify(struct wl_listener *listener, void *data)
? wlr_scene_xdg_surface_create(c->scene, c->surface.xdg)
: wlr_scene_subsurface_tree_create(c->scene, client_surface(c));
c->scene->node.data = c->scene_surface->node.data = c;
printf("image capture tree\n");
c->image_capture_scene = wlr_scene_create();
c->ext_foreign_toplevel = wlr_ext_foreign_toplevel_handle_v1_create(foreign_toplevel_list,&foreign_toplevel_state);
c->ext_foreign_toplevel->data = c;
if (c->type == XDGShell) {
c->image_capture_tree = wlr_scene_xdg_surface_create(&c->image_capture_scene->tree, c->surface.xdg);
} else { /* xwayland */
c->image_capture_scene_surface = wlr_scene_surface_create(&c->image_capture_scene->tree, c->surface.xwayland->surface);
}
client_get_geometry(c, &c->geom);
@@ -2162,7 +2134,7 @@ powermgrsetmode(struct wl_listener *listener, void *data)
if (!m)
return;
m->gamma_lut_changed = 1; /* Reapply gamma LUT when re-enabling the ouput */
m->gamma_lut_changed = 1; /* Reapply gamma LUT when re-enabling the output */
wlr_output_state_set_enabled(&state, event->mode);
wlr_output_commit_state(m->wlr_output, &state);
@@ -2470,20 +2442,6 @@ setsel(struct wl_listener *listener, void *data)
struct wlr_seat_request_set_selection_event *event = data;
wlr_seat_set_selection(seat, event->source, event->serial);
}
static void handle_new_foreign_toplevel_capture_request(struct wl_listener *listener, void *data) {
struct wlr_ext_foreign_toplevel_image_capture_source_manager_v1_request *request = data;
Client *view = request->toplevel_handle->data;
if (view->image_capture_source == NULL) {
view->image_capture_source = wlr_ext_image_capture_source_v1_create_with_scene_node(
&view->image_capture_scene->tree.node, event_loop, alloc, drw);
if (view->image_capture_source == NULL) {
return;
}
}
wlr_ext_foreign_toplevel_image_capture_source_manager_v1_request_accept(request, view->image_capture_source);
}
void
setup(void)
@@ -2498,7 +2456,7 @@ setup(void)
wlr_log_init(log_level, NULL);
/* The Wayland display is managed by libwayland. It handles accepting
* clients from the Unix socket, manging Wayland globals, and so on. */
* clients from the Unix socket, managing Wayland globals, and so on. */
dpy = wl_display_create();
event_loop = wl_display_get_event_loop(dpy);
@@ -2560,9 +2518,8 @@ setup(void)
wlr_data_device_manager_create(dpy);
wlr_export_dmabuf_manager_v1_create(dpy);
wlr_screencopy_manager_v1_create(dpy);
wlr_ext_image_copy_capture_manager_v1_create(dpy, 1);
wlr_ext_output_image_capture_source_manager_v1_create(dpy, 1);
wlr_data_control_manager_v1_create(dpy);
wlr_ext_data_control_manager_v1_create(dpy, 1);
wlr_primary_selection_v1_device_manager_create(dpy);
wlr_viewporter_create(dpy);
wlr_single_pixel_buffer_manager_v1_create(dpy);
@@ -2618,11 +2575,6 @@ setup(void)
(float [4]){0.1f, 0.1f, 0.1f, 1.0f});
wlr_scene_node_set_enabled(&locked_bg->node, 0);
foreign_toplevel_list = wlr_ext_foreign_toplevel_list_v1_create(dpy,1);
ext_foreign_toplevel_image_capture_source_manager_v1 = wlr_ext_foreign_toplevel_image_capture_source_manager_v1_create(dpy, 1);
new_foreign_toplevel_capture_request.notify = handle_new_foreign_toplevel_capture_request;
wl_signal_add(&ext_foreign_toplevel_image_capture_source_manager_v1->events.new_request,&new_foreign_toplevel_capture_request);
/* Use decoration protocols to negotiate server-side decorations */
wlr_server_decoration_manager_set_default_mode(
wlr_server_decoration_manager_create(dpy),
@@ -2880,15 +2832,7 @@ unmapnotify(struct wl_listener *listener, void *data)
setmon(c, NULL, 0);
wl_list_remove(&c->flink);
}
if (c->ext_foreign_toplevel) {
wlr_ext_foreign_toplevel_handle_v1_destroy(c->ext_foreign_toplevel);
}
if (c->image_capture_scene_surface) {
wlr_scene_node_destroy(&c->image_capture_scene_surface->buffer->node);
c->image_capture_scene_surface = NULL;
}
wlr_scene_node_destroy(&c->image_capture_scene->tree.node);
wlr_scene_node_destroy(&c->scene->node);
printstatus();
motionnotify(0, NULL, 0, 0, 0, 0);