init
This commit is contained in:
+33
@@ -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)
|
||||
@@ -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
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
+13
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
+108
@@ -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
|
||||
|
||||
+16
@@ -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)
|
||||
@@ -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
|
||||
|
||||
+10
@@ -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)
|
||||
+461
@@ -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
|
||||
|
||||
+14
@@ -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)
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user