summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md218
-rw-r--r--config.def.h43
-rw-r--r--config.mk8
-rw-r--r--patches/shiftview/README.md9
-rw-r--r--patches/shiftview/shiftview.patch76
-rw-r--r--shiftview.c30
6 files changed, 155 insertions, 229 deletions
diff --git a/README.md b/README.md
index 38211c4..07adaf3 100644
--- a/README.md
+++ b/README.md
@@ -1,219 +1,3 @@
# dwl - dwm for Wayland
-2025-08-16:
-dwl IS CURRENTLY UN-MAINTAINED.
-AT THE PRESENT TIME, I (@fauxmight) DO NOT HAVE
-THE TIME OR CAPACITY TO KEEP UP WITH [wlroots] CHANGES.
-IF YOU ARE INTERESTED IN TAKING ON LEAD DEVELOPER RESPONSIBILITIES,
-SEE ISSUE [#1166](https://codeberg.org/dwl/dwl/issues/1166).
----
-
-Join us on our IRC channel: [#dwl on Libera Chat]
-Or on the community-maintained [Discord server].
-
-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,
-primarily in terms of functionality, and secondarily in terms of
-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`
-- Tied to as few external dependencies as possible
-
-## Getting Started:
-
-### Latest semi-stable [release]
-This is probably where you want to start. This builds against the [wlroots]
-versions currently shipping in major distributions. If your
-distribution's `wlroots` version is older, use an earlier dwl [release].
-The `wlroots` version against which a given `dwl` release builds is specified
-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.
-
-### Building dwl
-dwl has the following dependencies:
-- libinput
-- wayland
-- wlroots (compiled with the libinput backend)
-- xkbcommon
-- wayland-protocols (compile-time only)
-- pkg-config (compile-time only)
-
-dwl has the following additional dependencies if XWayland support is enabled:
-- libxcb
-- libxcb-wm
-- wlroots (compiled with X11 support)
-- Xwayland (runtime only)
-
-Install these (and their `-devel` versions if your distro has separate
-development packages) and run `make`. If you wish to build against a released
-version of wlroots (*you probably do*), use a [release] or a [0.x branch]. If
-you want to use the unstable development `main` branch, you need to use the git
-version of [wlroots].
-
-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
-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
-created. Check out the [dwl-patches] repository!
-
-## Running dwl
-
-dwl can be run on any of the backends supported by wlroots. This means you can
-run it as a separate window inside either an X11 or Wayland session, as well as
-directly from a VT console. Depending on your distro's setup, you may need to
-add your user to the `video` and `input` groups before you can run dwl on a
-VT. If you are using `elogind` or `systemd-logind` you need to install polkit;
-otherwise you need to add yourself in the `seat` group and enable/start the
-seatd daemon.
-
-When dwl is run with no arguments, it will launch the server and begin handling
-any shortcuts configured in `config.h`. There is no status bar or other
-decoration initially; these are instead clients that can be run within the
-Wayland session. Do note that the default background color is grey. This can be
-modified in `config.h`.
-
-If you would like to run a script or command automatically at startup, you can
-specify the command using the `-s` option. This command will be executed as a
-shell command using `/bin/sh -c`. It serves a similar function to `.xinitrc`,
-but differs in that the display server will not shut down when this process
-terminates. Instead, dwl will send this process a SIGTERM at shutdown and wait
-for it to terminate (if it hasn't already). This makes it ideal for execing into
-a user service manager like [s6], [anopa], [runit], [dinit], or [`systemd
---user`].
-
-Note: The `-s` command is run as a *child process* of dwl, which means that it
-does not have the ability to affect the environment of dwl or of any processes
-that it spawns. If you need to set environment variables that affect the entire
-dwl session, these must be set prior to running dwl. For example, Wayland
-requires a valid `XDG_RUNTIME_DIR`, which is usually set up by a session manager
-such as `elogind` or `systemd-logind`. If your system doesn't do this
-automatically, you will need to configure it prior to launching `dwl`, e.g.:
-
- export XDG_RUNTIME_DIR=/tmp/xdg-runtime-$(id -u)
- mkdir -p $XDG_RUNTIME_DIR
- dwl
-
-### Status information
-
-Information about selected layouts, current window title, app-id, and
-selected/occupied/urgent tags is written to the stdin of the `-s` command (see
-the `STATUS INFORMATION` section in `_dwl_(1)`). This information can be used to
-populate an external status bar with a script that parses the
-information. Failing to read this information will cause dwl to block, so if you
-do want to run a startup command that does not consume the status information,
-you can close standard input with the `<&-` shell redirection, for example:
-
- dwl -s 'foot --server <&-'
-
-If your startup command is a shell script, you can achieve the same inside the
-script with the line
-
- exec <&-
-
-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
-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,
- 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.
-- Configurable multi-monitor layout support, including position and rotation
-- Configurable HiDPI/multi-DPI support
-- Idle-inhibit protocol which lets applications such as mpv disable idle
- monitoring
-- Provide information to external status bars via stdout/stdin
-- Urgency hints via xdg-activate protocol
-- Support screen lockers via ext-session-lock-v1 protocol
-- Various Wayland protocols
-- XWayland support as provided by wlroots (can be enabled in `config.mk`)
-- Zero flickering - Wayland users naturally expect that "every frame is perfect"
-- Layer shell popups (used by Waybar)
-- 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:
-
-- Protocols made trivial by wlroots
-- Implement the text-input and input-method protocols to support IME once ibus
- implements input-method v2 (see https://github.com/ibus/ibus/pull/2256 and
- https://codeberg.org/dwl/dwl/pulls/235)
-
-Feature *non-goals* for the main codebase include:
-
-- Client-side decoration (any more than is necessary to tell the clients not to)
-- Client-initiated window management, such as move, resize, and close, which can
- be done through the compositor
-- Animations and visual effects
-
-## Acknowledgements
-
-dwl began by extending the TinyWL example provided (CC0) by the sway/wlroots
-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
-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
-- Guido Cella for the layer-shell protocol implementation, patch maintenance,
- and for helping to keep the project running
-- Stivvo for output management and fullscreen support, and patch maintenance
-
-
-[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
-[0.x branch]: https://codeberg.org/dwl/dwl/branches
-[anopa]: https://jjacky.com/anopa/
-[dinit]: https://davmac.org/projects/dinit/
-[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
-[release]: https://codeberg.org/dwl/dwl/releases
-[runit]: http://smarden.org/runit/faq.html#userservices
-[s6]: https://skarnet.org/software/s6/
-[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots/
-[wiki]: https://codeberg.org/dwl/dwl/wiki/Home#compatible-status-bars
-[Discord server]: https://discord.gg/jJxZnrGPWN
-[Wayland]: https://wayland.freedesktop.org/
+Fork of [dwl](https://codeberg.org/dwl/dwl)
diff --git a/config.def.h b/config.def.h
index f490e24..6eb96ce 100644
--- a/config.def.h
+++ b/config.def.h
@@ -6,7 +6,7 @@
/* appearance */
static const int sloppyfocus = 1; /* focus follows mouse */
static const int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */
-static const unsigned int borderpx = 1; /* border pixel of windows */
+static const unsigned int borderpx = 0; /* border pixel of windows */
static const float rootcolor[] = COLOR(0x222222ff);
static const float bordercolor[] = COLOR(0x444444ff);
static const float focuscolor[] = COLOR(0x005577ff);
@@ -15,16 +15,27 @@ static const float urgentcolor[] = COLOR(0xff0000ff);
static const float fullscreen_bg[] = {0.0f, 0.0f, 0.0f, 1.0f}; /* You can also use glsl colors */
/* tagging - TAGCOUNT must be no greater than 31 */
-#define TAGCOUNT (9)
+#define TAGCOUNT (5)
/* logging */
static int log_level = WLR_ERROR;
static const Rule rules[] = {
- /* app_id title tags mask isfloating monitor */
- { "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 */
+ /* app_id title tags mask isfloating monitor */
+// { "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" */
+ { "Gimp", NULL, 0, 1, -1 },
+ { "mpv", NULL, 0, 1, -1 },
+ { "Firefox", NULL, 1, 0, -1 },
+ { "firefox", NULL, 1, 0, -1 },
+ { "LibreWolf", NULL, 1, 0, -1 },
+ { "librewolf", NULL, 1, 0, -1 },
+ { "Thunderbird", NULL, 1 << 1, 0, 0 },
+ { "Pavucontrol", NULL, 1 << 4, 0, 0 },
+ { "pavucontrol", NULL, 1 << 4, 0, 0 },
+ /* default/example rule: can be changed but cannot be eliminated; at least one rule must exist */
};
/* layout(s) */
@@ -53,11 +64,13 @@ static const struct xkb_rule_names xkb_rules = {
/* example:
.options = "ctrl:nocaps",
*/
- .options = NULL,
+ // set capslock to escape
+ // maybe can repurpose windows key here too ...
+ .options = "caps:escape",
};
static const int repeat_rate = 25;
-static const int repeat_delay = 600;
+static const int repeat_delay = 300;
/* Trackpad */
static const int tap_to_click = 1;
@@ -117,10 +130,22 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
/* commands */
static const char *termcmd[] = { "foot", NULL };
static const char *menucmd[] = { "wmenu-run", NULL };
+//static const char *passcmd[] = { "passmenu", NULL }; TO FIX WITH WAYLAND MENU
+//static const char *otpcmd[] = { "otp", NULL }; SAME AS passcmd
+static const char *webcmd[] = { "web", NULL };
+static const char *radarcmd[] = { "radar", NULL };
+
+#include "shiftview.c"
static const Key keys[] = {
/* Note that Shift changes certain key codes: 2 -> at, etc. */
/* modifier key function argument */
+ // commands
+// { MODKEY|ShiftMask, XK_p, spawn, {.v = passcmd } },
+// { MODKEY, XK_o, spawn, {.v = otpcmd } },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_a, spawn, {.v = webcmd } },
+ { MODKEY, XKB_KEY_r, spawn, {.v = radarcmd } },
+ // basic functionality
{ MODKEY, XKB_KEY_p, spawn, {.v = menucmd} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} },
{ MODKEY, XKB_KEY_j, focusstack, {.i = +1} },
@@ -133,6 +158,8 @@ 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, XKB_KEY_q, shiftview, { .i = -1 } },
+ { MODKEY, XKB_KEY_w, shiftview, { .i = 1 } },
{ 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]} },
diff --git a/config.mk b/config.mk
index eb08a05..b84ac8e 100644
--- a/config.mk
+++ b/config.mk
@@ -24,11 +24,11 @@ WLR_LIBS = `$(PKG_CONFIG) --libs wlroots-0.19`
# -I$(PWD)/wlroots/0.19/include/wlroots-0.19
#WLR_LIBS = -Wl,-rpath,$(PWD)/wlroots/0.19/lib64 -L$(PWD)/wlroots/0.19/lib64 -lwlroots-0.19
-XWAYLAND =
-XLIBS =
+#XWAYLAND =
+#XLIBS =
# Uncomment to build XWayland support
-#XWAYLAND = -DXWAYLAND
-#XLIBS = xcb xcb-icccm
+XWAYLAND = -DXWAYLAND
+XLIBS = xcb xcb-icccm
# dwl itself only uses C99 features, but wlroots' headers use anonymous unions (C11).
# To avoid warnings about them, we do not use -std=c99 and instead of using the
diff --git a/patches/shiftview/README.md b/patches/shiftview/README.md
new file mode 100644
index 0000000..8e26f4d
--- /dev/null
+++ b/patches/shiftview/README.md
@@ -0,0 +1,9 @@
+### Description
+Add keybindings to cycle through tags with visible clients.
+
+### Download
+- [git branch](https://codeberg.org/guidocella/dwl/src/branch/shiftview)
+- [2026-02-09](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/shiftview/shiftview.patch)
+
+### Authors
+- [Guido Cella](https://codeberg.org/guidocella)
diff --git a/patches/shiftview/shiftview.patch b/patches/shiftview/shiftview.patch
new file mode 100644
index 0000000..50a849b
--- /dev/null
+++ b/patches/shiftview/shiftview.patch
@@ -0,0 +1,76 @@
+From ce4217d8ee9c28ba76ca34fae7a7c3ef1aceecb0 Mon Sep 17 00:00:00 2001
+From: Guido Cella <guido@guidocella.xyz>
+Date: Sat, 27 Jan 2024 22:43:29 +0100
+Subject: [PATCH] cycle through tags
+
+---
+ config.def.h | 4 ++++
+ shiftview.c | 34 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 38 insertions(+)
+ create mode 100644 shiftview.c
+
+diff --git a/config.def.h b/config.def.h
+index 8a6eda0..fd80703 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -118,6 +118,8 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
+ static const char *termcmd[] = { "foot", NULL };
+ static const char *menucmd[] = { "wmenu-run", NULL };
+
++#include "shiftview.c"
++
+ static const Key keys[] = {
+ /* Note that Shift changes certain key codes: 2 -> at, etc. */
+ /* modifier key function argument */
+@@ -131,6 +133,8 @@ 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, XKB_KEY_a, shiftview, { .i = -1 } },
++ { MODKEY, XKB_KEY_semicolon, shiftview, { .i = 1 } },
+ { 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]} },
+diff --git a/shiftview.c b/shiftview.c
+new file mode 100644
+index 0000000..fa53db0
+--- /dev/null
++++ b/shiftview.c
+@@ -0,0 +1,34 @@
++// "arg->i" stores the number of tags to shift right (positive value)
++// or left (negative value)
++void
++shiftview(const Arg *arg)
++{
++ Arg a;
++ Client *c;
++ bool visible = false;
++ int i = arg->i;
++ int count = 0;
++ int nextseltags, curseltags = selmon->tagset[selmon->seltags];
++
++ do {
++ if (i > 0) // left circular shift
++ nextseltags = (curseltags << i) | (curseltags >> (TAGCOUNT - i));
++ else // right circular shift
++ nextseltags = curseltags >> (-i) | (curseltags << (TAGCOUNT + i));
++
++ // Check if the tag is visible
++ wl_list_for_each(c, &clients, link) {
++ if (c->mon == selmon && nextseltags & c->tags) {
++ visible = true;
++ break;
++ }
++ }
++
++ i += arg->i;
++ } while (!visible && ++count <= TAGCOUNT);
++
++ if (count <= TAGCOUNT) {
++ a.i = nextseltags;
++ view(&a);
++ }
++}
+--
+2.52.0
+
diff --git a/shiftview.c b/shiftview.c
new file mode 100644
index 0000000..ddd81ef
--- /dev/null
+++ b/shiftview.c
@@ -0,0 +1,30 @@
+// shiftview all tags regardless of tags having open windows
+void
+shiftview(const Arg *arg)
+{
+ Arg view_argument;
+ uint32_t destination_tag;
+
+ // arg->i represents the direction and distance passed from config.def.h (usually -1 and +1)
+ if(arg->i > 0){
+ // shift right (increase tag index), move the active tag bit to the left (0001) to (0010)
+ destination_tag = selmon->tagset[selmon->seltags] << arg->i;
+ }else{
+ // shift to the left
+ destination_tag = selmon->tagset[selmon->seltags] >> (-arg->i);
+ }
+
+ // TAGMASK defines the valid boundary for tags (111111111) for 9 tags
+ // if the shift pushed the active bit outside the bounds, destination_tag will become 0
+ if(!(destination_tag & TAGMASK)){
+ // If we went off to the right edge, wrap around to the first tag (000000001)
+ // If we went off to the left, wrap around to the last tag (bit 1 shifted left by TAGCOUNT - 1)
+ destination_tag = arg->i > 0 ? 1 : 1 << (TAGCOUNT - 1);
+ }
+
+ // pack the destination tag bitmask into the required dwl argument struct
+ view_argument.ui = destination_tag;
+
+ // pass the destination tag to dwl's view function
+ view(&view_argument);
+}