diff options
author | Leonard Kugis <leonard@kug.is> | 2025-05-23 11:41:09 +0000 |
---|---|---|
committer | Leonard Kugis <leonard@kug.is> | 2025-05-23 11:41:09 +0000 |
commit | c70505d7c7b7b48600f273357694b56ccf5d2a15 (patch) | |
tree | 21c27ac6ffced8d6d904e35bdb39baa5d685d829 /dwl-patches/stale-patches | |
download | dotfiles-master.tar.gz dotfiles-master.tar.bz2 dotfiles-master.zip |
Diffstat (limited to 'dwl-patches/stale-patches')
-rw-r--r-- | dwl-patches/stale-patches/bar-systray-old/README.md | 33 | ||||
-rw-r--r-- | dwl-patches/stale-patches/bar-systray-old/bar-systray-0.7.patch | 398 | ||||
-rw-r--r-- | dwl-patches/stale-patches/bar-systray-old/systray.png | bin | 0 -> 22944 bytes | |||
-rw-r--r-- | dwl-patches/stale-patches/master-right/README.md | 13 | ||||
-rw-r--r-- | dwl-patches/stale-patches/master-right/master-right-0.7.patch | 35 | ||||
-rw-r--r-- | dwl-patches/stale-patches/master-right/master-right.patch | 35 | ||||
-rw-r--r-- | dwl-patches/stale-patches/press_repeat_release/README.md | 15 | ||||
-rw-r--r-- | dwl-patches/stale-patches/press_repeat_release/press_repeat_release.patch | 108 | ||||
-rw-r--r-- | dwl-patches/stale-patches/remembertags/README.md | 16 | ||||
-rw-r--r-- | dwl-patches/stale-patches/remembertags/remembertags.patch | 105 | ||||
-rw-r--r-- | dwl-patches/stale-patches/tab-pango/README.md | 10 | ||||
-rw-r--r-- | dwl-patches/stale-patches/tab-pango/tab.patch | 461 | ||||
-rw-r--r-- | dwl-patches/stale-patches/togglekblayout/README.md | 14 | ||||
-rw-r--r-- | dwl-patches/stale-patches/togglekblayout/togglekblayout.patch | 107 |
14 files changed, 1350 insertions, 0 deletions
diff --git a/dwl-patches/stale-patches/bar-systray-old/README.md b/dwl-patches/stale-patches/bar-systray-old/README.md new file mode 100644 index 0000000..9c8b94e --- /dev/null +++ b/dwl-patches/stale-patches/bar-systray-old/README.md @@ -0,0 +1,33 @@ +### Description +Add a system tray next to the [bar](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/bar). Heed the warning, this is far from suckless ^^ + + + +**Superseded by [bar-systray](/dwl/dwl-patches/src/branch/main/patches/bar-systray).** + +### Dependencies +- GTK4 +- [bar.patch](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/bar) as mentioned. +- [gtk4-layer-shell](https://github.com/wmww/gtk4-layer-shell) +- [statusnotifier-systray-gtk4](https://codeberg.org/janetski/statusnotifier-systray-gtk4) built as a static library. + +### Applying the patch +The patch applies on top of the bar patch. That needs to be applied first. + +The patch creates subdirectories `lib` and `include`. After patching, but before `make`, install +`libstatusnotifier-systray-gtk4.a` and `snsystray.h` from statusnotifier-systray-gtk4 in the +directories. One possible way to do that: + +1. Clone [https://codeberg.org/janetski/statusnotifier-systray-gtk4](https://codeberg.org/janetski/statusnotifier-systray-gtk4). Can clone to any location. +2. From statusnotifier-systray-gtk4 root: + 1. `$ meson setup --default-library=static --prefix=/ -Dgir=false -Dvala=false -Ddocs=false build` + 2. `$ meson compile -C build` + 3. `$ DESTDIR=$DWLDIR meson install -C build`, where $DWLDIR is the path to dwl root. +3. Finally, from dwl root, run `make`. + +### Download +- [git branch](/janetski/dwl/src/branch/0.7-systray) +- [0.7](/dwl/dwl-patches/raw/branch/main/patches/bar-systray/bar-systray-0.7.patch) + +### Authors +- [janetski](https://codeberg.org/janetski) ([.vetu](https://discordapp.com/users/355488216469471242) on discord) diff --git a/dwl-patches/stale-patches/bar-systray-old/bar-systray-0.7.patch b/dwl-patches/stale-patches/bar-systray-old/bar-systray-0.7.patch new file mode 100644 index 0000000..eae4561 --- /dev/null +++ b/dwl-patches/stale-patches/bar-systray-old/bar-systray-0.7.patch @@ -0,0 +1,398 @@ +From 71f7b97dca2d781668e826aae7e06544958534f6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Janne=20Vetel=C3=A4inen?= <janne.vetelainen@elisanet.fi> +Date: Fri, 23 Aug 2024 18:39:17 +0300 +Subject: [PATCH 1/1] Add a system tray next to the sewn's bar + +--- + Makefile | 8 +- + config.def.h | 2 + + dwl.c | 222 ++++++++++++++++++++++++++++++++++++++++++++- + include/.gitignore | 1 + + lib/.gitignore | 1 + + 5 files changed, 225 insertions(+), 9 deletions(-) + create mode 100644 include/.gitignore + create mode 100644 lib/.gitignore + +diff --git a/Makefile b/Makefile +index 9bc67db..853b04c 100644 +--- a/Makefile ++++ b/Makefile +@@ -7,14 +7,14 @@ include config.mk + DWLCPPFLAGS = -I. -DWLR_USE_UNSTABLE -D_POSIX_C_SOURCE=200809L \ + -DVERSION=\"$(VERSION)\" $(XWAYLAND) + DWLDEVCFLAGS = -g -pedantic -Wall -Wextra -Wdeclaration-after-statement \ +- -Wno-unused-parameter -Wshadow -Wunused-macros -Werror=strict-prototypes \ ++ -Wno-unused-parameter -Wshadow -Wunused-macros \ + -Werror=implicit -Werror=return-type -Werror=incompatible-pointer-types \ + -Wfloat-conversion + + # CFLAGS / LDFLAGS +-PKGS = wlroots-0.18 wayland-server xkbcommon libinput pixman-1 fcft $(XLIBS) +-DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS) +-LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` -lm $(LIBS) ++PKGS = wlroots-0.18 wayland-server xkbcommon libinput pixman-1 fcft $(XLIBS) gtk4 gtk4-layer-shell-0 ++DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS) -Iinclude ++LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` -lm $(LIBS) -Llib -lstatusnotifier-systray-gtk4 + + all: dwl + dwl: dwl.o util.o +diff --git a/config.def.h b/config.def.h +index 5d1dc2b..bb9366f 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -11,6 +11,8 @@ static const int showbar = 1; /* 0 means no bar */ + static const int topbar = 1; /* 0 means bottom bar */ + static const char *fonts[] = {"monospace:size=10"}; + static const float rootcolor[] = COLOR(0x000000ff); ++static const int trayspacing = 4; /* Spacing between icons in system tray */ ++static const int traymargins = 4; /* System tray inner margins */ + /* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */ + static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */ + static uint32_t colors[][3] = { +diff --git a/dwl.c b/dwl.c +index ece537a..24f550a 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -72,9 +72,22 @@ + #include "util.h" + #include "drwl.h" + ++#include <snsystray.h> ++#include <gdk/gdk.h> ++#include <gio/gio.h> ++#include <glib-object.h> ++#include <glib.h> ++#include <gtk/gtk.h> ++#include <gtk4-layer-shell.h> ++#include <pthread.h> ++ + /* macros */ ++#ifndef MAX + #define MAX(A, B) ((A) > (B) ? (A) : (B)) ++#endif /* MAX */ ++#ifndef MIN + #define MIN(A, B) ((A) < (B) ? (A) : (B)) ++#endif /* MIN */ + #define CLEANMASK(mask) (mask & ~WLR_MODIFIER_CAPS) + #define VISIBLEON(C, M) ((M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags])) + #define LENGTH(X) (sizeof X / sizeof X[0]) +@@ -324,6 +337,15 @@ static void focusstack(const Arg *arg); + static Client *focustop(Monitor *m); + static void fullscreennotify(struct wl_listener *listener, void *data); + static void gpureset(struct wl_listener *listener, void *data); ++static void gtkactivate(GtkApplication *app, void *data); ++static void gtkclosewindows(void *data, void *udata); ++static void gtkhandletogglebarmsg(void *data); ++static void gtkhandlewidthnotify(SnSystray *systray, GParamSpec *pspec, void *data); ++static void* gtkinit(void *data); ++static void gtkspawnstray(Monitor *m, GtkApplication *app); ++static void gtkterminate(void *data); ++static void gtktoggletray(void *data, void *udata); ++static GdkMonitor* gtkwlrtogdkmon(Monitor *wlrmon); + static void handlesig(int signo); + static void incnmaster(const Arg *arg); + static void inputdevice(struct wl_listener *listener, void *data); +@@ -380,7 +402,7 @@ static void unlocksession(struct wl_listener *listener, void *data); + static void unmaplayersurfacenotify(struct wl_listener *listener, void *data); + static void unmapnotify(struct wl_listener *listener, void *data); + static void updatemons(struct wl_listener *listener, void *data); +-static void updatebar(Monitor *m); ++static void updatebar(Monitor *m, int traywidth); + static void updatetitle(struct wl_listener *listener, void *data); + static void urgent(struct wl_listener *listener, void *data); + static void view(const Arg *arg); +@@ -394,6 +416,8 @@ static void zoom(const Arg *arg); + /* variables */ + static const char broken[] = "broken"; + static pid_t child_pid = -1; ++static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ++static pthread_t gtkthread; /* Gtk functions are only allowed to be called from this thread */ + static int locked; + static void *exclusive_focus; + static struct wl_display *dpy; +@@ -1187,7 +1211,7 @@ createmon(struct wl_listener *listener, void *data) + + m->scene_buffer = wlr_scene_buffer_create(layers[LyrBottom], NULL); + m->scene_buffer->point_accepts_input = baracceptsinput; +- updatebar(m); ++ updatebar(m, 0); + + wl_list_insert(&mons, &m->link); + drawbars(); +@@ -1518,6 +1542,8 @@ drawbar(Monitor *m) + if (!(buf = bufmon(m))) + return; + ++ pthread_mutex_lock(&mutex); ++ + /* draw status first so it can be overdrawn by tags later */ + if (m == selmon) { /* status is only drawn on selected monitor */ + drwl_setscheme(m->drw, colors[SchemeNorm]); +@@ -1566,6 +1592,7 @@ drawbar(Monitor *m) + m->m.y + (topbar ? 0 : m->m.height - m->b.real_height)); + wlr_scene_buffer_set_buffer(m->scene_buffer, &buf->base); + wlr_buffer_unlock(&buf->base); ++ pthread_mutex_unlock(&mutex); + } + + void +@@ -1710,6 +1737,174 @@ fullscreennotify(struct wl_listener *listener, void *data) + setfullscreen(c, client_wants_fullscreen(c)); + } + ++void ++gtkactivate(GtkApplication *app, void *data) ++{ ++ GdkDisplay *display; ++ GtkCssProvider *cssp; ++ char csss[64]; ++ Monitor *m; ++ uint32_t bgcolor; ++ ++ bgcolor = colors[SchemeNorm][1] >> 8; ++ display = gdk_display_get_default(); ++ cssp = gtk_css_provider_new(); ++ sprintf(csss, "window{background-color:#%06x;}", bgcolor); ++ gtk_css_provider_load_from_string(cssp, csss); ++ gtk_style_context_add_provider_for_display(display, ++ GTK_STYLE_PROVIDER(cssp), ++ GTK_STYLE_PROVIDER_PRIORITY_USER); ++ ++ wl_list_for_each(m, &mons, link) ++ gtkspawnstray(m, app); ++ ++ g_object_unref(cssp); ++} ++ ++void ++gtkclosewindows(void *data, void *udata) ++{ ++ GtkWindow *window = GTK_WINDOW(data); ++ ++ gtk_window_close(window); ++} ++ ++void ++gtkhandletogglebarmsg(void *data) ++{ ++ GtkApplication *app; ++ GList *windows; ++ ++ app = GTK_APPLICATION(g_application_get_default()); ++ windows = gtk_application_get_windows(app); ++ g_list_foreach(windows, gtktoggletray, data); ++} ++ ++void ++gtkhandlewidthnotify(SnSystray *systray, GParamSpec *pspec, void *data) ++{ ++ Monitor *m = (Monitor *)data; ++ int traywidth; ++ ++ traywidth = sn_systray_get_width(systray); ++ ++ updatebar(m, traywidth); ++ drawbar(m); ++} ++ ++void* ++gtkinit(void *data) ++{ ++ GtkApplication *app = gtk_application_new("org.dwl.systray", ++ G_APPLICATION_NON_UNIQUE); ++ g_signal_connect(app, "activate", G_CALLBACK(gtkactivate), NULL); ++ g_application_run(G_APPLICATION(app), 0, NULL); ++ ++ g_object_unref(app); ++ ++ return NULL; ++} ++ ++void ++gtkspawnstray(Monitor *m, GtkApplication *app) ++{ ++ GdkMonitor *gdkmon; ++ GtkWindow *window; ++ SnSystray *systray; ++ const char *conn; ++ gboolean anchors[4]; ++ int iconsize, tray_init_width, tray_height; ++ ++ gdkmon = gtkwlrtogdkmon(m); ++ if (gdkmon == NULL) ++ die("Failed to get gdkmon"); ++ ++ conn = gdk_monitor_get_connector(gdkmon); ++ iconsize = m->b.real_height - 2 * traymargins; ++ tray_height = m->b.real_height; ++ tray_init_width = m->b.real_height; ++ ++ if (topbar) { ++ anchors[GTK_LAYER_SHELL_EDGE_LEFT] = false; ++ anchors[GTK_LAYER_SHELL_EDGE_RIGHT] = true; ++ anchors[GTK_LAYER_SHELL_EDGE_TOP] = true; ++ anchors[GTK_LAYER_SHELL_EDGE_BOTTOM] = false; ++ } else { ++ anchors[GTK_LAYER_SHELL_EDGE_LEFT] = false; ++ anchors[GTK_LAYER_SHELL_EDGE_RIGHT] = true; ++ anchors[GTK_LAYER_SHELL_EDGE_TOP] = false; ++ anchors[GTK_LAYER_SHELL_EDGE_BOTTOM] = true; ++ } ++ ++ systray = sn_systray_new(iconsize, ++ traymargins, ++ trayspacing, ++ conn); ++ window = GTK_WINDOW(gtk_window_new()); ++ ++ gtk_window_set_default_size(window, tray_init_width, tray_height); ++ gtk_window_set_child(window, GTK_WIDGET(systray)); ++ gtk_window_set_application(window, app); ++ gtk_layer_init_for_window(window); ++ gtk_layer_set_layer(window, GTK_LAYER_SHELL_LAYER_BOTTOM); ++ gtk_layer_set_exclusive_zone(window, -1); ++ gtk_layer_set_monitor(window, gdkmon); ++ ++ for (int j = 0; j < GTK_LAYER_SHELL_EDGE_ENTRY_NUMBER; j++) { ++ gtk_layer_set_anchor(window, j, anchors[j]); ++ } ++ ++ updatebar(m, tray_init_width); ++ g_signal_connect(systray, "notify::curwidth", G_CALLBACK(gtkhandlewidthnotify), m); ++ gtk_window_present(window); ++} ++ ++void ++gtkterminate(void *data) ++{ ++ GtkApplication *app; ++ GList *windows; ++ ++ app = GTK_APPLICATION(g_application_get_default()); ++ windows = gtk_application_get_windows(app); ++ g_list_foreach(windows, gtkclosewindows, NULL); ++} ++ ++GdkMonitor* ++gtkwlrtogdkmon(Monitor *wlrmon) ++{ ++ GdkMonitor *gdkmon = NULL; ++ ++ GListModel *gdkmons; ++ GdkDisplay *display; ++ const char *gdkname; ++ const char *wlrname; ++ unsigned int i; ++ ++ wlrname = wlrmon->wlr_output->name; ++ display = gdk_display_get_default(); ++ gdkmons = gdk_display_get_monitors(display); ++ ++ for (i = 0; i < g_list_model_get_n_items(gdkmons); i++) { ++ GdkMonitor *mon = g_list_model_get_item(gdkmons, i); ++ gdkname = gdk_monitor_get_connector(mon); ++ if (strcmp(wlrname, gdkname) == 0) ++ gdkmon = mon; ++ } ++ ++ return gdkmon; ++} ++ ++void ++gtktoggletray(void *data, void *udata) ++{ ++ GtkWidget *widget = GTK_WIDGET(data); ++ int *pbarvisible = (int *)udata; ++ int barvisible = GPOINTER_TO_INT(pbarvisible); ++ ++ gtk_widget_set_visible(widget, barvisible); ++} ++ + void + gpureset(struct wl_listener *listener, void *data) + { +@@ -2293,6 +2488,8 @@ powermgrsetmode(struct wl_listener *listener, void *data) + void + quit(const Arg *arg) + { ++ g_idle_add_once(gtkterminate, NULL); ++ pthread_join(gtkthread, NULL); + wl_display_terminate(dpy); + } + +@@ -2836,6 +3033,9 @@ setup(void) + fprintf(stderr, "failed to setup XWayland X server, continuing without it\n"); + } + #endif ++ ++ // Gtk functions are only allowed to be called from this thread. ++ pthread_create(>kthread, NULL, >kinit, NULL); + } + + void +@@ -2943,9 +3143,21 @@ tile(Monitor *m) + void + togglebar(const Arg *arg) + { ++ int barvisible; ++ int *pbarvisible; ++ + wlr_scene_node_set_enabled(&selmon->scene_buffer->node, + !selmon->scene_buffer->node.enabled); + arrangelayers(selmon); ++ ++ // Notify gtkthread ++ if (selmon->scene_buffer->node.enabled) ++ barvisible = 1; ++ else ++ barvisible = 0; ++ ++ pbarvisible = GINT_TO_POINTER(barvisible); ++ g_idle_add_once(gtkhandletogglebarmsg, pbarvisible); + } + + void +@@ -3140,7 +3352,7 @@ updatemons(struct wl_listener *listener, void *data) + if (stext[0] == '\0') + strncpy(stext, "dwl-"VERSION, sizeof(stext)); + wl_list_for_each(m, &mons, link) { +- updatebar(m); ++ updatebar(m, 0); + drawbar(m); + } + +@@ -3155,7 +3367,7 @@ updatemons(struct wl_listener *listener, void *data) + } + + void +-updatebar(Monitor *m) ++updatebar(Monitor *m, int traywidth) + { + size_t i; + int rw, rh; +@@ -3163,7 +3375,7 @@ updatebar(Monitor *m) + + wlr_output_transformed_resolution(m->wlr_output, &rw, &rh); + m->b.width = rw; +- m->b.real_width = (int)((float)m->b.width / m->wlr_output->scale); ++ m->b.real_width = (int)((float)m->b.width / m->wlr_output->scale) - traywidth; + + wlr_scene_node_set_enabled(&m->scene_buffer->node, m->wlr_output->enabled ? showbar : 0); + +diff --git a/include/.gitignore b/include/.gitignore +new file mode 100644 +index 0000000..424c745 +--- /dev/null ++++ b/include/.gitignore +@@ -0,0 +1 @@ ++*.h +diff --git a/lib/.gitignore b/lib/.gitignore +new file mode 100644 +index 0000000..10301e2 +--- /dev/null ++++ b/lib/.gitignore +@@ -0,0 +1 @@ ++*.a +-- +2.46.0 + diff --git a/dwl-patches/stale-patches/bar-systray-old/systray.png b/dwl-patches/stale-patches/bar-systray-old/systray.png Binary files differnew file mode 100644 index 0000000..54f9f98 --- /dev/null +++ b/dwl-patches/stale-patches/bar-systray-old/systray.png diff --git a/dwl-patches/stale-patches/master-right/README.md b/dwl-patches/stale-patches/master-right/README.md new file mode 100644 index 0000000..0f69bbc --- /dev/null +++ b/dwl-patches/stale-patches/master-right/README.md @@ -0,0 +1,13 @@ +### Description +Show the master area to the right. + +### Reason for deprecation +I created this patch for a user on Discord and I have never used it. + +### Download +- [git branch](https://codeberg.org/sevz/dwl/src/branch/master-right) +- [main 2024-09-01](/dwl/dwl-patches/raw/branch/main/patches/master-right/master-right.patch) +- [master-right-0.7.patch](/dwl/dwl-patches/raw/branch/main/patches/master-right/master-right-0.7.patch) + +### Authors +- [sevz](https://codeberg.org/sevz) diff --git a/dwl-patches/stale-patches/master-right/master-right-0.7.patch b/dwl-patches/stale-patches/master-right/master-right-0.7.patch new file mode 100644 index 0000000..e4845f4 --- /dev/null +++ b/dwl-patches/stale-patches/master-right/master-right-0.7.patch @@ -0,0 +1,35 @@ +From f72236247e5e7cb23c3cac86b496cdd2c523f7ff Mon Sep 17 00:00:00 2001 +From: Sevz17 <leohdz172@outlook.com> +Date: Fri, 25 Jun 2021 19:50:56 -0500 +Subject: [PATCH] show master area to the right +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Leonardo Hernández Hernández <leohdz172@proton.me> +--- + dwl.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/dwl.c b/dwl.c +index a2711f67..50b057a7 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -2710,11 +2710,12 @@ tile(Monitor *m) + if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) + continue; + if (i < m->nmaster) { +- resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw, ++ resize(c, (struct wlr_box){.x = m->w.x + m->w.width - mw, ++ .y = m->w.y + my, .width = mw, + .height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0); + my += c->geom.height; + } else { +- resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y + ty, ++ resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + ty, + .width = m->w.width - mw, .height = (m->w.height - ty) / (n - i)}, 0); + ty += c->geom.height; + } +-- +2.46.0 + diff --git a/dwl-patches/stale-patches/master-right/master-right.patch b/dwl-patches/stale-patches/master-right/master-right.patch new file mode 100644 index 0000000..70c80a1 --- /dev/null +++ b/dwl-patches/stale-patches/master-right/master-right.patch @@ -0,0 +1,35 @@ +From 0afd0a98998dda20e4fe4f4d2b5fcdec49c448c3 Mon Sep 17 00:00:00 2001 +From: Sevz17 <leohdz172@outlook.com> +Date: Fri, 25 Jun 2021 19:50:56 -0500 +Subject: [PATCH] show master area to the right +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Leonardo Hernández Hernández <leohdz172@proton.me> +--- + dwl.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/dwl.c b/dwl.c +index 9021e442..2bd354a3 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -2670,11 +2670,12 @@ tile(Monitor *m) + if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) + continue; + if (i < m->nmaster) { +- resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw, ++ resize(c, (struct wlr_box){.x = m->w.x + m->w.width - mw, ++ .y = m->w.y + my, .width = mw, + .height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0); + my += c->geom.height; + } else { +- resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y + ty, ++ resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + ty, + .width = m->w.width - mw, .height = (m->w.height - ty) / (n - i)}, 0); + ty += c->geom.height; + } +-- +2.46.0 + diff --git a/dwl-patches/stale-patches/press_repeat_release/README.md b/dwl-patches/stale-patches/press_repeat_release/README.md new file mode 100644 index 0000000..b9b4ff3 --- /dev/null +++ b/dwl-patches/stale-patches/press_repeat_release/README.md @@ -0,0 +1,15 @@ +### Description
+This patch adds 3 additional options to the `Key` struct, `on_press`, `on_repeat` and `on_release` which can be used to control which events a key binding should be triggered on.
+
+NOTE: Due to concerns about patching difficulties this patch does NOT include any changes to `config.def.h`. After applying you will need to add the 3 additional initializers to each key binding that you would like to modify. Any key binding that is not updated will cause a build warning but should function as it does in vanilla.
+
+2025-01-04 Moved to stale patches.
+Outstanding issues with this patch: https://codeberg.org/dwl/dwl-patches/issues/98
+Patch maintainer notes he is no longer maintaining dwl patches: https://codeberg.org/dwl/dwl-patches/pulls/102
+
+### Download
+- [git branch](https://codeberg.org/USERNAME/dwl/src/branch/press_repeat_release)
+- [2024-03-27](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/press_repeat_release/press_repeat_release.patch)
+
+### Authors
+- [minego](https://codeberg.org/minego)
diff --git a/dwl-patches/stale-patches/press_repeat_release/press_repeat_release.patch b/dwl-patches/stale-patches/press_repeat_release/press_repeat_release.patch new file mode 100644 index 0000000..b86666d --- /dev/null +++ b/dwl-patches/stale-patches/press_repeat_release/press_repeat_release.patch @@ -0,0 +1,108 @@ +From aee1dc3e9ca4d8deec5432d0c64921af6e301ecd Mon Sep 17 00:00:00 2001 +From: Micah N Gorrell <m@minego.net> +Date: Wed, 27 Mar 2024 15:59:50 -0600 +Subject: [PATCH 1/2] onpress, onrepeat, onrelease + +--- + dwl.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/dwl.c b/dwl.c +index 5867b0c..43bbf0c 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -146,6 +146,10 @@ typedef struct { + xkb_keysym_t keysym; + void (*func)(const Arg *); + const Arg arg; ++ ++ int on_press; ++ int on_repeat; ++ int on_release; + } Key; + + typedef struct { +@@ -286,7 +290,7 @@ static void fullscreennotify(struct wl_listener *listener, void *data); + static void handlesig(int signo); + static void incnmaster(const Arg *arg); + static void inputdevice(struct wl_listener *listener, void *data); +-static int keybinding(uint32_t mods, xkb_keysym_t sym); ++static int keybinding(uint32_t mods, xkb_keysym_t sym, int on_press, int on_repeat, int on_release); + static void keypress(struct wl_listener *listener, void *data); + static void keypressmod(struct wl_listener *listener, void *data); + static int keyrepeat(void *data); +@@ -1428,7 +1432,7 @@ inputdevice(struct wl_listener *listener, void *data) + } + + int +-keybinding(uint32_t mods, xkb_keysym_t sym) ++keybinding(uint32_t mods, xkb_keysym_t sym, int on_press, int on_repeat, int on_release) + { + /* + * Here we handle compositor keybindings. This is when the compositor is +@@ -1439,8 +1443,10 @@ keybinding(uint32_t mods, xkb_keysym_t sym) + for (k = keys; k < END(keys); k++) { + if (CLEANMASK(mods) == CLEANMASK(k->mod) + && sym == k->keysym && k->func) { +- k->func(&k->arg); +- return 1; ++ if ((on_press && k->on_press) || (on_repeat && k->on_repeat) || (on_release && k->on_release)) { ++ k->func(&k->arg); ++ return 1; ++ } + } + } + return 0; +@@ -1470,7 +1476,7 @@ keypress(struct wl_listener *listener, void *data) + * attempt to process a compositor keybinding. */ + if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { + for (i = 0; i < nsyms; i++) +- handled = keybinding(mods, syms[i]) || handled; ++ handled = keybinding(mods, syms[i], event->state == WL_KEYBOARD_KEY_STATE_PRESSED, 0, event->state == WL_KEYBOARD_KEY_STATE_RELEASED) || handled; + } + + if (handled && group->wlr_group->keyboard.repeat_info.delay > 0) { +@@ -1518,7 +1524,7 @@ keyrepeat(void *data) + 1000 / group->wlr_group->keyboard.repeat_info.rate); + + for (i = 0; i < group->nsyms; i++) +- keybinding(group->mods, group->keysyms[i]); ++ keybinding(group->mods, group->keysyms[i], 0, 1, 0); + + return 0; + } +-- +2.44.0 + + +From 1875bb171c9b0cd2fb03bb7e6c3fb400e33eeaf1 Mon Sep 17 00:00:00 2001 +From: Micah N Gorrell <m@minego.net> +Date: Wed, 27 Mar 2024 16:26:52 -0600 +Subject: [PATCH 2/2] Modified logic so that an unmodified keybinding with + default values for the new flags will behave as it does in vanilla, while + keybindings with customized flags will function as expected + +--- + dwl.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/dwl.c b/dwl.c +index 43bbf0c..55e7a40 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -1443,7 +1443,11 @@ keybinding(uint32_t mods, xkb_keysym_t sym, int on_press, int on_repeat, int on_ + for (k = keys; k < END(keys); k++) { + if (CLEANMASK(mods) == CLEANMASK(k->mod) + && sym == k->keysym && k->func) { +- if ((on_press && k->on_press) || (on_repeat && k->on_repeat) || (on_release && k->on_release)) { ++ if ((k->on_press == 0 && k->on_repeat == 0 && k->on_release == 0) || ++ (on_press && k->on_press) || ++ (on_repeat && k->on_repeat) || ++ (on_release && k->on_release) ++ ) { + k->func(&k->arg); + return 1; + } +-- +2.44.0 + diff --git a/dwl-patches/stale-patches/remembertags/README.md b/dwl-patches/stale-patches/remembertags/README.md new file mode 100644 index 0000000..b45e87c --- /dev/null +++ b/dwl-patches/stale-patches/remembertags/README.md @@ -0,0 +1,16 @@ +### Description
+This patch modifies the behavior when selecting tags so that selecting a tag will also enable any other tags that were previously visible.
+
+For example:
+1. Select tag 5, with mod+5
+2. Toggle tag 8, with ctrl+mod+8
+3. Select tag 1, with mod+1. Tags 5 and 8 should no longer be visible.
+4. Select tag 5 again, with mod+5. Tag 8 should be visible since it was remembered.
+5. Select tag 5 again, with mod_5. Selecting the already selected tag resets any remembered tags, so now tag 5 should be the only one visible.
+
+### Download
+- [git branch](https://codeberg.org/minego/dwl/src/branch/remembertags)
+- [2024-03-27](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/remembertags/remembertags.patch)
+
+### Authors
+- [minego](https://codeberg.org/minego)
\ No newline at end of file diff --git a/dwl-patches/stale-patches/remembertags/remembertags.patch b/dwl-patches/stale-patches/remembertags/remembertags.patch new file mode 100644 index 0000000..fd6135e --- /dev/null +++ b/dwl-patches/stale-patches/remembertags/remembertags.patch @@ -0,0 +1,105 @@ +From fea6eb3cfc84ede8403c89a3230f5c658a6c7bd1 Mon Sep 17 00:00:00 2001 +From: Micah N Gorrell <m@minego.net> +Date: Wed, 27 Mar 2024 13:05:09 -0600 +Subject: [PATCH] remembertags + +--- + config.def.h | 8 ++++---- + dwl.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 52 insertions(+), 4 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 9009517..2312802 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -105,10 +105,10 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA + #define MODKEY WLR_MODIFIER_ALT + + #define TAGKEYS(KEY,SKEY,TAG) \ +- { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ +- { MODKEY|WLR_MODIFIER_CTRL, KEY, toggleview, {.ui = 1 << TAG} }, \ +- { MODKEY|WLR_MODIFIER_SHIFT, SKEY, tag, {.ui = 1 << TAG} }, \ +- { MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,SKEY,toggletag, {.ui = 1 << TAG} } ++ { MODKEY, KEY, remembertagsview, {.i = TAG} }, \ ++ { MODKEY|WLR_MODIFIER_CTRL, KEY, toggleview, {.ui = 1 << TAG} }, \ ++ { MODKEY|WLR_MODIFIER_SHIFT, SKEY, tag, {.ui = 1 << TAG} }, \ ++ { MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT, SKEY, toggletag, {.ui = 1 << TAG} } + + /* helper for spawning shell commands in the pre dwm-5.0 fashion */ + #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } +diff --git a/dwl.c b/dwl.c +index 5867b0c..31a81aa 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -205,6 +205,11 @@ struct Monitor { + int gamma_lut_changed; + int nmaster; + char ltsymbol[16]; ++ unsigned int createtag[2]; /* Create windows on the last tag directly selected, not all selected */ ++ struct { ++ unsigned int tagset; ++ Client *zoomed; ++ } remembered[31]; + }; + + typedef struct { +@@ -308,6 +313,7 @@ static void pointerfocus(Client *c, struct wlr_surface *surface, + double sx, double sy, uint32_t time); + static void printstatus(void); + static void quit(const Arg *arg); ++static void remembertagsview(const Arg *arg); + static void rendermon(struct wl_listener *listener, void *data); + static void requestdecorationmode(struct wl_listener *listener, void *data); + static void requeststartdrag(struct wl_listener *listener, void *data); +@@ -1951,6 +1957,48 @@ quit(const Arg *arg) + wl_display_terminate(dpy); + } + ++void ++remembertagsview(const Arg *arg) { ++ unsigned newtags = (1 << arg->i) & TAGMASK; ++ int oldtag; ++ int active; ++ unsigned int newcreate; ++ ++ if (selmon == NULL) { ++ return; ++ } ++ ++ oldtag = selmon->createtag[selmon->seltags]; ++ active = (oldtag == arg->i); ++ ++ if (oldtag < TAGCOUNT) { ++ selmon->remembered[oldtag].tagset = selmon->tagset[selmon->seltags]; ++ } ++ ++ selmon->seltags ^= 1; /*toggle tagset*/ ++ ++ if (-1 == arg->i) { ++ /* A specific tag was not specified */ ++ active = 0; ++ newcreate = selmon->createtag[selmon->seltags]; ++ } else { ++ newcreate = arg->i; ++ } ++ ++ if (active) { ++ /* Select twice to isolate the tag */ ++ selmon->tagset[selmon->seltags] = newtags; ++ } else if (arg->i < TAGCOUNT) { ++ /* Restore whatever was previously on this tag */ ++ selmon->tagset[selmon->seltags] = newtags | selmon->remembered[newcreate].tagset; ++ } ++ ++ selmon->createtag[selmon->seltags] = newcreate; ++ focusclient(focustop(selmon), 1); ++ arrange(selmon); ++ printstatus(); ++} ++ + void + rendermon(struct wl_listener *listener, void *data) + { +-- +2.44.0 + diff --git a/dwl-patches/stale-patches/tab-pango/README.md b/dwl-patches/stale-patches/tab-pango/README.md new file mode 100644 index 0000000..c7e4a1c --- /dev/null +++ b/dwl-patches/stale-patches/tab-pango/README.md @@ -0,0 +1,10 @@ +### Description
+Add a tab bar or window title to the top or bottom of windows.
+
+**This is the old version of the `tab` patch. Deprecated because the [new version](https://codeberg.org/dwl/dwl-patches/raw/branch-main/patches/tab) is significantly more efficient and well-written than this, and it better adheres to the suckless philosophy.**
+
+### Download
+- [2024-03-15](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/tab/tab.patch)
+
+### Authors
+- [dev-gm](https://codeberg.org/dev-gm)
diff --git a/dwl-patches/stale-patches/tab-pango/tab.patch b/dwl-patches/stale-patches/tab-pango/tab.patch new file mode 100644 index 0000000..5b7b8a0 --- /dev/null +++ b/dwl-patches/stale-patches/tab-pango/tab.patch @@ -0,0 +1,461 @@ +From b624206781513cdff1b9609fc5ac4b848094e1b4 Mon Sep 17 00:00:00 2001 +From: Gavin M <github@gavinm.us> +Date: Fri, 15 Mar 2024 16:37:23 -0500 +Subject: [PATCH] Tabbed patch + +--- + Makefile | 2 +- + config.def.h | 18 +++- + dwl.c | 276 +++++++++++++++++++++++++++++++++++++++++++++++++-- + 3 files changed, 281 insertions(+), 15 deletions(-) + +diff --git a/Makefile b/Makefile +index a67fdd3..182eb87 100644 +--- a/Makefile ++++ b/Makefile +@@ -9,7 +9,7 @@ DWLDEVCFLAGS = -g -pedantic -Wall -Wextra -Wdeclaration-after-statement -Wno-unu + -Werror=strict-prototypes -Werror=implicit -Werror=return-type -Werror=incompatible-pointer-types -Wfloat-conversion + + # CFLAGS / LDFLAGS +-PKGS = wlroots wayland-server xkbcommon libinput $(XLIBS) ++PKGS = wlroots wayland-server xkbcommon libinput cairo pangocairo $(XLIBS) + DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS) + LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS) + +diff --git a/config.def.h b/config.def.h +index 9009517..1ca270f 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -7,6 +7,16 @@ + 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 double title_border_width = 0.75; ++static const unsigned int title_padding = 11; ++static const int title_top = 0; ++static const LayoutType floating_title_type = LAYOUT_TYPE_LABEL; ++static const char title_font[] = "Dejavu Sans Mono 10.5"; ++static const float title_font_color[] = COLOR(0xffffffff); ++static const float title_focus_bg[] = COLOR(0x3b3b3bff); ++static const float title_root_bg[] = COLOR(0x131313ff); ++static const float title_urgent_bg[] = COLOR(0x00ff00ff); ++static const float title_border_color[] = COLOR(0x3b3b3bff); + static const float rootcolor[] = COLOR(0x222222ff); + static const float bordercolor[] = COLOR(0x444444ff); + static const float focuscolor[] = COLOR(0x005577ff); +@@ -30,10 +40,10 @@ static const Rule rules[] = { + + /* layout(s) */ + static const Layout layouts[] = { +- /* symbol arrange function */ +- { "[]=", tile }, +- { "><>", NULL }, /* no layout function means floating behavior */ +- { "[M]", monocle }, ++ /* symbol type render_only_top arrange function */ ++ { "[]=", LAYOUT_TYPE_NONE, 0, tile }, ++ { "><>", LAYOUT_TYPE_LABEL, 0, NULL }, /* no layout function means floating behavior */ ++ { "[M]", LAYOUT_TYPE_TABS_ONLY_MULTIPLE_CLIENTS, 1, monocle }, + }; + + /* monitors */ +diff --git a/dwl.c b/dwl.c +index 5867b0c..e613d17 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -2,6 +2,11 @@ + * See LICENSE file for copyright and license details. + */ + #include <getopt.h> ++#include <cairo/cairo.h> ++#include <pango/pangocairo.h> ++#include <pango/pango-font.h> ++#include <pango/pango-layout.h> ++#include <libdrm/drm_fourcc.h> + #include <libinput.h> + #include <linux/input-event-codes.h> + #include <signal.h> +@@ -13,8 +18,10 @@ + #include <wayland-server-core.h> + #include <wlr/backend.h> + #include <wlr/backend/libinput.h> ++#include <wlr/interfaces/wlr_buffer.h> + #include <wlr/render/allocator.h> + #include <wlr/render/wlr_renderer.h> ++#include <wlr/types/wlr_buffer.h> + #include <wlr/types/wlr_compositor.h> + #include <wlr/types/wlr_cursor.h> + #include <wlr/types/wlr_cursor_shape_v1.h> +@@ -110,6 +117,7 @@ typedef struct { + struct wlr_scene_tree *scene; + struct wlr_scene_rect *border[4]; /* top, bottom, left, right */ + struct wlr_scene_tree *scene_surface; ++ struct wlr_scene_buffer *titlebar; + struct wl_list link; + struct wl_list flink; + union { +@@ -137,7 +145,7 @@ typedef struct { + #endif + unsigned int bw; + uint32_t tags; +- int isfloating, isurgent, isfullscreen; ++ int isfloating, isurgent, isfullscreen, titleisinit, istabbed; + uint32_t resize; /* configure serial of a pending resize */ + } Client; + +@@ -179,8 +187,17 @@ typedef struct { + struct wl_listener surface_commit; + } LayerSurface; + ++typedef enum { ++ LAYOUT_TYPE_NONE, ++ LAYOUT_TYPE_LABEL, ++ LAYOUT_TYPE_TABS_ONLY_MULTIPLE_CLIENTS, ++ LAYOUT_TYPE_TABS_ALWAYS ++} LayoutType; ++ + typedef struct { + const char *symbol; ++ LayoutType type; ++ int render_top_only; + void (*arrange)(Monitor *); + } Layout; + +@@ -282,6 +299,7 @@ static void focusclient(Client *c, int lift); + static void focusmon(const Arg *arg); + static void focusstack(const Arg *arg); + static Client *focustop(Monitor *m); ++static Client *focustop_onlytiled(Monitor *m, int onlytiled); + static void fullscreennotify(struct wl_listener *listener, void *data); + static void handlesig(int signo); + static void incnmaster(const Arg *arg); +@@ -309,6 +327,7 @@ static void pointerfocus(Client *c, struct wlr_surface *surface, + static void printstatus(void); + static void quit(const Arg *arg); + static void rendermon(struct wl_listener *listener, void *data); ++static void rendertitlebar(Client *client); + static void requestdecorationmode(struct wl_listener *listener, void *data); + static void requeststartdrag(struct wl_listener *listener, void *data); + static void requestmonstate(struct wl_listener *listener, void *data); +@@ -349,6 +368,7 @@ static void xytonode(double x, double y, struct wlr_surface **psurface, + static void zoom(const Arg *arg); + + /* variables */ ++static int title_height; + static const char broken[] = "broken"; + static pid_t child_pid = -1; + static int locked; +@@ -973,6 +993,7 @@ createnotify(struct wl_listener *listener, void *data) + c = xdg_surface->data = ecalloc(1, sizeof(*c)); + c->surface.xdg = xdg_surface; + c->bw = borderpx; ++ c->titleisinit = c->istabbed = 0; + + wlr_xdg_toplevel_set_wm_capabilities(xdg_surface->toplevel, + WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); +@@ -1360,6 +1381,22 @@ focustop(Monitor *m) + return NULL; + } + ++Client * ++focustop_onlytiled(Monitor *m, int onlytiled) ++{ ++ Client *c; ++ if (!m) ++ return NULL; ++ wl_list_for_each(c, &fstack, flink) { ++ if (VISIBLEON(c, m)) { ++ if ((onlytiled == 1 && c->isfloating) || (onlytiled == 2 && (!c->isfloating || !m->lt[m->sellt]->arrange))) ++ continue; ++ return c; ++ } ++ } ++ return NULL; ++} ++ + void + fullscreennotify(struct wl_listener *listener, void *data) + { +@@ -2003,6 +2040,195 @@ skip: + wlr_output_state_finish(&pending); + } + ++struct text_buffer { ++ struct wlr_buffer base; ++ void *data; ++ uint32_t format; ++ size_t stride; ++}; ++ ++static void text_buffer_destroy(struct wlr_buffer *wlr_buffer) { ++ struct text_buffer *buffer = wl_container_of(wlr_buffer, buffer, base); ++ free(buffer->data); ++ free(buffer); ++} ++ ++static bool text_buffer_begin_data_ptr_access(struct wlr_buffer *wlr_buffer, ++ uint32_t flags, void **data, uint32_t *format, size_t *stride) { ++ struct text_buffer *buffer = wl_container_of(wlr_buffer, buffer, base); ++ if(data != NULL) { ++ *data = (void *)buffer->data; ++ } ++ if(format != NULL) { ++ *format = buffer->format; ++ } ++ if(stride != NULL) { ++ *stride = buffer->stride; ++ } ++ return true; ++} ++ ++static void text_buffer_end_data_ptr_access(struct wlr_buffer *wlr_buffer) { ++ // This space is intentionally left blank ++} ++ ++static const struct wlr_buffer_impl text_buffer_impl = { ++ .destroy = text_buffer_destroy, ++ .begin_data_ptr_access = text_buffer_begin_data_ptr_access, ++ .end_data_ptr_access = text_buffer_end_data_ptr_access, ++}; ++ ++static struct text_buffer *text_buffer_create(uint32_t width, uint32_t height, uint32_t stride) { ++ struct text_buffer *buffer = calloc(1, sizeof(*buffer)); ++ if (buffer == NULL) { ++ return NULL; ++ } ++ ++ wlr_buffer_init(&buffer->base, &text_buffer_impl, width, height); ++ buffer->format = DRM_FORMAT_ARGB8888; ++ buffer->stride = stride; ++ ++ buffer->data = malloc(buffer->stride * height); ++ if (buffer->data == NULL) { ++ free(buffer); ++ return NULL; ++ } ++ ++ return buffer; ++} ++ ++void ++rendertitlebar(Client *c) ++{ ++ struct wl_list *init_destroy, *cursor_destroy; ++ cairo_surface_t *surface; ++ cairo_status_t status; ++ cairo_t *cr; ++ PangoFontDescription *desc; ++ PangoLayout *layout; ++ LayoutType title_type; ++ Client *l, *sel; ++ unsigned int len, tabsize, i; ++ const char *title; ++ const float *color; ++ unsigned char *data; ++ int stride; ++ struct text_buffer *text_buffer; ++ void *data_ptr; ++ ++ if (!c || !c->scene || !c->mon || !selmon || (!VISIBLEON(c, selmon) && c->mon == selmon)) ++ return; ++ ++ if (c->titleisinit) { ++ init_destroy = cursor_destroy = &c->titlebar->node.events.destroy.listener_list; ++ do { ++ cursor_destroy = cursor_destroy->next; ++ } while (cursor_destroy && cursor_destroy != init_destroy); ++ if (!cursor_destroy) { ++ return; ++ } ++ wlr_scene_node_destroy(&c->titlebar->node); ++ } ++ c->titleisinit = c->istabbed = 0; ++ ++ sel = focustop_onlytiled(c->mon, c->isfloating + 1); ++ ++ if (c->isfullscreen) ++ return; ++ title_type = c->isfloating ? floating_title_type : c->mon->lt[c->mon->sellt]->type; ++ ++ if (title_type == LAYOUT_TYPE_TABS_ONLY_MULTIPLE_CLIENTS || title_type == LAYOUT_TYPE_TABS_ALWAYS) { ++ len = 0; ++ wl_list_for_each(l, &clients, link) { ++ if (VISIBLEON(l, c->mon) && l->isfloating == c->isfloating) ++ len++; ++ } ++ if (title_type == LAYOUT_TYPE_TABS_ONLY_MULTIPLE_CLIENTS && len <= 1) ++ return; ++ } ++ ++ if (c->mon->lt[c->mon->sellt]->render_top_only == 1 && !c->isfloating && c != sel) { ++ c->istabbed = 1; ++ return; ++ } /*else if (c->mon->lt[c->mon->sellt]->render_top_only == 2 && c != sel) { ++ c->istabbed = 1; ++ return; ++ }*/ ++ ++ if (title_type == LAYOUT_TYPE_NONE) ++ return; ++ ++ surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, c->geom.width, title_height); ++ if ((status = cairo_surface_status(surface)) != CAIRO_STATUS_SUCCESS) { ++ wlr_log(WLR_ERROR, "cairo_image_surface_create failed: %s", ++ cairo_status_to_string(status)); ++ return; ++ } ++ cr = cairo_create(surface); ++ desc = pango_font_description_from_string(title_font); ++ layout = pango_cairo_create_layout(cr); ++ pango_layout_set_font_description(layout, desc); ++ pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE); ++ ++ cairo_set_line_width(cr, title_border_width); ++ ++ if (title_type == LAYOUT_TYPE_LABEL) { ++ cairo_rectangle(cr, 0, 0, c->geom.width, title_height); ++ cairo_set_source_rgba(cr, title_focus_bg[0], title_focus_bg[1], title_focus_bg[2], title_focus_bg[3]); ++ cairo_fill_preserve(cr); ++ cairo_set_source_rgba(cr, title_border_color[0], title_border_color[1], title_border_color[2], title_border_color[3]); ++ cairo_stroke(cr); ++ cairo_set_source_rgba(cr, title_font_color[0], title_font_color[1], title_font_color[2], title_font_color[3]); ++ title = client_get_title(c); ++ pango_layout_set_text(layout, title ? title : " ", (c->geom.width - title_padding) * PANGO_SCALE); ++ cairo_move_to(cr, title_padding, 0); ++ pango_cairo_show_layout(cr, layout); ++ } else { ++ tabsize = c->geom.width / len; ++ i = 0; ++ wl_list_for_each(l, &clients, link) { ++ if (VISIBLEON(l, c->mon) && l->isfloating == c->isfloating) { ++ cairo_rectangle(cr, i * tabsize, 0, (i + 1) * tabsize, title_height); ++ color = (l == sel) ? title_focus_bg ++ : (c->isurgent ? title_urgent_bg : title_root_bg); ++ cairo_set_source_rgba(cr, color[0], color[1], color[2], color[3]); ++ cairo_fill_preserve(cr); ++ cairo_set_source_rgba(cr, title_border_color[0], title_border_color[1], title_border_color[2], title_border_color[3]); ++ cairo_stroke(cr); ++ cairo_set_source_rgba(cr, title_font_color[0], title_font_color[1], title_font_color[2], title_font_color[3]); ++ title = client_get_title(l); ++ pango_layout_set_text(layout, title ? title : " ", (tabsize - title_padding) * PANGO_SCALE); ++ cairo_move_to(cr, (i * tabsize) + title_padding, 0); ++ pango_cairo_show_layout(cr, layout); ++ i++; ++ } ++ } ++ } ++ ++ data = cairo_image_surface_get_data(surface); ++ stride = cairo_image_surface_get_stride(surface); ++ text_buffer = text_buffer_create(c->geom.width, title_height, stride); ++ ++ if(!wlr_buffer_begin_data_ptr_access(&text_buffer->base, ++ WLR_BUFFER_DATA_PTR_ACCESS_WRITE, &data_ptr, NULL, NULL)) { ++ wlr_log(WLR_ERROR, "%s", "Failed to get pointer access to text buffer"); ++ return; ++ } ++ memcpy(data_ptr, data, stride * title_height); ++ wlr_buffer_end_data_ptr_access(&text_buffer->base); ++ cairo_surface_destroy(surface); ++ ++ c->titlebar = wlr_scene_buffer_create(c->scene, &text_buffer->base); ++ c->titleisinit = c->istabbed = 1; ++ ++ wlr_scene_node_set_position(&c->titlebar->node, 0, !title_top ? c->geom.height - title_height : 0); ++ wlr_scene_node_raise_to_top(&c->titlebar->node); ++ ++ pango_font_description_free(desc); ++ g_object_unref(layout); ++ cairo_destroy(cr); ++} ++ + void + requestdecorationmode(struct wl_listener *listener, void *data) + { +@@ -2036,24 +2262,30 @@ resize(Client *c, struct wlr_box geo, int interact) + { + struct wlr_box *bbox = interact ? &sgeom : &c->mon->w; + struct wlr_box clip; ++ unsigned int th; ++ int draw_borders = 1; + client_set_bounds(c, geo.width, geo.height); + c->geom = geo; ++ c->bw = draw_borders ? borderpx : 0; + applybounds(c, bbox); + ++ rendertitlebar(c); ++ th = c->istabbed ? title_height : c->bw; ++ + /* Update scene-graph, including borders */ + wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y); +- wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw); +- wlr_scene_rect_set_size(c->border[0], c->geom.width, c->bw); +- wlr_scene_rect_set_size(c->border[1], c->geom.width, c->bw); +- wlr_scene_rect_set_size(c->border[2], c->bw, c->geom.height - 2 * c->bw); +- wlr_scene_rect_set_size(c->border[3], c->bw, c->geom.height - 2 * c->bw); +- wlr_scene_node_set_position(&c->border[1]->node, 0, c->geom.height - c->bw); +- wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw); +- wlr_scene_node_set_position(&c->border[3]->node, c->geom.width - c->bw, c->bw); ++ wlr_scene_node_set_position(&c->scene_surface->node, c->bw, title_top ? th : c->bw); ++ wlr_scene_rect_set_size(c->border[0], c->geom.width, (title_top && c->istabbed) ? 0 : c->bw); ++ wlr_scene_rect_set_size(c->border[1], c->geom.width, (!title_top && c->istabbed) ? 0 : c->bw); ++ wlr_scene_rect_set_size(c->border[2], c->bw, c->geom.height - (c->bw + th)); ++ wlr_scene_rect_set_size(c->border[3], c->bw, c->geom.height - (c->bw + th)); ++ wlr_scene_node_set_position(&c->border[1]->node, 0, c->geom.height - (title_top ? c->bw : th)); ++ wlr_scene_node_set_position(&c->border[2]->node, 0, title_top ? th : c->bw); ++ wlr_scene_node_set_position(&c->border[3]->node, c->geom.width - c->bw, title_top ? th : c->bw); + + /* this is a no-op if size hasn't changed */ + c->resize = client_set_size(c, c->geom.width - 2 * c->bw, +- c->geom.height - 2 * c->bw); ++ c->geom.height - (c->bw + th)); + client_get_clip(c, &clip); + wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip); + } +@@ -2274,6 +2506,11 @@ setup(void) + + int i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE}; + struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig}; ++ cairo_surface_t *surface; ++ cairo_t *cr; ++ PangoFontDescription *desc; ++ PangoLayout *layout; ++ + sigemptyset(&sa.sa_mask); + + for (i = 0; i < (int)LENGTH(sig); i++) +@@ -2506,6 +2743,24 @@ setup(void) + + wlr_scene_set_presentation(scene, wlr_presentation_create(dpy, backend)); + ++ surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0); ++ ++ cr = cairo_create(surface); ++ ++ desc = pango_font_description_from_string(title_font); ++ /* Create Pango layout. */ ++ layout = pango_cairo_create_layout(cr); ++ pango_layout_set_font_description(layout, desc); ++ pango_layout_set_text(layout, " ", -1); ++ /* Set width and height to text size */ ++ pango_layout_get_pixel_size(layout, NULL, &title_height); ++ ++ /* Cleanup */ ++ pango_font_description_free (desc); ++ cairo_surface_destroy(surface); ++ g_object_unref (layout); ++ cairo_destroy(cr); ++ + /* Make sure XWayland clients don't connect to the parent X server, + * e.g when running in the x11 backend or the wayland backend and the + * compositor has Xwayland support */ +@@ -2978,6 +3233,7 @@ createnotifyx11(struct wl_listener *listener, void *data) + c->surface.xwayland = xsurface; + c->type = X11; + c->bw = borderpx; ++ c->titleisinit = c->istabbed = 0; + + /* Listen to the various events it can emit */ + LISTEN(&xsurface->events.associate, &c->associate, associatex11); +-- +2.44.0 + diff --git a/dwl-patches/stale-patches/togglekblayout/README.md b/dwl-patches/stale-patches/togglekblayout/README.md new file mode 100644 index 0000000..366a6d8 --- /dev/null +++ b/dwl-patches/stale-patches/togglekblayout/README.md @@ -0,0 +1,14 @@ +### Description + +> This patch is no longer being maintained by me [wochap](https://codeberg.org/wochap), since I'm now using a different patch specific to my use case: https://codeberg.org/wochap/dwl/src/branch/v0.6-b/xkb-rules-switcher/xkb-rules-switcher.patch + +Switch between multiple keyboard layouts at runtime. + +### Download +- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.5/togglekblayout) +- [v0.5](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/togglekblayout/togglekblayout.patch) + +### Authors +- [wochap](https://codeberg.org/wochap) +- [Stivvo](https://github.com/Stivvo) + diff --git a/dwl-patches/stale-patches/togglekblayout/togglekblayout.patch b/dwl-patches/stale-patches/togglekblayout/togglekblayout.patch new file mode 100644 index 0000000..4ef802a --- /dev/null +++ b/dwl-patches/stale-patches/togglekblayout/togglekblayout.patch @@ -0,0 +1,107 @@ +From 1bb99c78da484ce6036dc997962ed2f4c0d11208 Mon Sep 17 00:00:00 2001 +From: wochap <gean.marroquin@gmail.com> +Date: Thu, 19 Oct 2023 23:21:49 -0500 +Subject: [PATCH 1/2] apply main...Stivvo:toggleKbLayout.patch + +--- + config.def.h | 6 ++++++ + dwl.c | 20 ++++++++++++++++++++ + 2 files changed, 26 insertions(+) + +diff --git a/config.def.h b/config.def.h +index db0babc..caa09ea 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -57,6 +57,11 @@ static const struct xkb_rule_names xkb_rules = { + static const int repeat_rate = 25; + static const int repeat_delay = 600; + ++/* gb will be set the first time togglekblayout is called, then us.. it is ++ * recommended to set the same layout in position 0 of kblayouts and in ++ * xkb_rules */ ++static const char *kblayouts[] = {"us", "gb"}; ++ + /* Trackpad */ + static const int tap_to_click = 1; + static const int tap_and_drag = 1; +@@ -141,6 +146,7 @@ static const Key keys[] = { + { MODKEY, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_LEFT} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater, tagmon, {.i = WLR_DIRECTION_RIGHT} }, ++ { MODKEY, XKB_KEY_w, togglekblayout, {0} }, + TAGKEYS( XKB_KEY_1, XKB_KEY_exclam, 0), + TAGKEYS( XKB_KEY_2, XKB_KEY_at, 1), + TAGKEYS( XKB_KEY_3, XKB_KEY_numbersign, 2), +diff --git a/dwl.c b/dwl.c +index ef27a1d..25458e6 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -312,6 +312,7 @@ static void tag(const Arg *arg); + static void tagmon(const Arg *arg); + static void tile(Monitor *m); + static void togglefloating(const Arg *arg); ++static void togglekblayout(const Arg *arg); + static void togglefullscreen(const Arg *arg); + static void toggletag(const Arg *arg); + static void toggleview(const Arg *arg); +@@ -368,6 +369,7 @@ static struct wl_listener lock_listener = {.notify = locksession}; + + static struct wlr_seat *seat; + static struct wl_list keyboards; ++static unsigned int kblayout = 0; /* index of kblayouts */ + static unsigned int cursor_mode; + static Client *grabc; + static int grabcx, grabcy; /* client-relative */ +@@ -2454,6 +2456,24 @@ togglefullscreen(const Arg *arg) + setfullscreen(sel, !sel->isfullscreen); + } + ++void ++togglekblayout(const Arg *arg) ++{ ++ Keyboard *kb; ++ struct xkb_rule_names newrule = xkb_rules; ++ ++ kblayout = (kblayout + 1) % LENGTH(kblayouts); ++ newrule.layout = kblayouts[kblayout]; ++ wl_list_for_each(kb, &keyboards, link) { ++ struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); ++ struct xkb_keymap *keymap = xkb_map_new_from_names(context, &newrule, ++ XKB_KEYMAP_COMPILE_NO_FLAGS); ++ wlr_keyboard_set_keymap(kb->device->keyboard, keymap); ++ xkb_keymap_unref(keymap); ++ xkb_context_unref(context); ++ } ++} ++ + void + toggletag(const Arg *arg) + { +-- +2.42.0 + + +From 3428168a686e2da8ba8a9dc1473350610afaef19 Mon Sep 17 00:00:00 2001 +From: wochap <gean.marroquin@gmail.com> +Date: Thu, 19 Oct 2023 23:46:06 -0500 +Subject: [PATCH 2/2] fix build + +--- + dwl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dwl.c b/dwl.c +index 25458e6..090280f 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -2468,7 +2468,7 @@ togglekblayout(const Arg *arg) + struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + struct xkb_keymap *keymap = xkb_map_new_from_names(context, &newrule, + XKB_KEYMAP_COMPILE_NO_FLAGS); +- wlr_keyboard_set_keymap(kb->device->keyboard, keymap); ++ wlr_keyboard_set_keymap(kb->wlr_keyboard, keymap); + xkb_keymap_unref(keymap); + xkb_context_unref(context); + } +-- +2.42.0 |