Compare commits

..

No commits in common. "93523c00fb6fb0532c9240a529df6c95debe5b52" and "4df7dc73763af3fd121d7a722b198dae20db558d" have entirely different histories.

3 changed files with 115 additions and 209 deletions

View File

@ -1,14 +1,14 @@
From e40de8cb1f33ebd7978f7f7843aa94ee241cb55a Mon Sep 17 00:00:00 2001
From b5b0214d74ad8eec0cf2da0a3f2afcea8245a782 Mon Sep 17 00:00:00 2001
From: vetu104 <vetu104@proton.me>
Date: Sat, 29 Mar 2025 19:22:37 +0200
Date: Sat, 8 Mar 2025 14:35:42 +0200
Subject: [PATCH] Add a system tray next to sewn's bar
---
Makefile | 23 +-
config.def.h | 5 +
dbus.c | 242 +++++++++++++++
dbus.c | 240 +++++++++++++++
dbus.h | 10 +
dwl.c | 107 ++++++-
dwl.c | 109 ++++++-
systray/helpers.c | 43 +++
systray/helpers.h | 12 +
systray/icon.c | 149 +++++++++
@ -19,9 +19,9 @@ Subject: [PATCH] Add a system tray next to sewn's bar
systray/menu.h | 11 +
systray/tray.c | 237 +++++++++++++++
systray/tray.h | 37 +++
systray/watcher.c | 551 +++++++++++++++++++++++++++++++++
systray/watcher.h | 35 +++
17 files changed, 2681 insertions(+), 13 deletions(-)
systray/watcher.c | 549 +++++++++++++++++++++++++++++++++
systray/watcher.h | 34 +++
17 files changed, 2678 insertions(+), 13 deletions(-)
create mode 100644 dbus.c
create mode 100644 dbus.h
create mode 100644 systray/helpers.c
@ -114,53 +114,46 @@ index 5d1dc2b..451643e 100644
};
diff --git a/dbus.c b/dbus.c
new file mode 100644
index 0000000..125312c
index 0000000..653a133
--- /dev/null
+++ b/dbus.c
@@ -0,0 +1,242 @@
@@ -0,0 +1,240 @@
+#include "dbus.h"
+
+#include "util.h"
+
+#include <dbus/dbus.h>
+#include <stdlib.h>
+#include <wayland-server-core.h>
+
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#if defined __linux__
+#include <sys/eventfd.h>
+#elif defined(__FreeBSD__) || defined(__OpenBSD__)
+#include <sys/event.h>
+#endif
+#include <unistd.h>
+
+static void
+close_pipe(void *data)
+{
+ int *pipefd = data;
+
+ close(pipefd[0]);
+ close(pipefd[1]);
+ free(pipefd);
+}
+int efd = -1;
+
+static int
+dwl_dbus_dispatch(int fd, unsigned int mask, void *data)
+{
+ DBusConnection *conn = data;
+
+ int pending;
+ DBusDispatchStatus oldstatus, newstatus;
+ uint64_t dispatch_pending;
+ DBusDispatchStatus status;
+
+ oldstatus = dbus_connection_get_dispatch_status(conn);
+ newstatus = dbus_connection_dispatch(conn);
+ status = dbus_connection_dispatch(conn);
+
+ /* Don't clear pending flag if status didn't change */
+ if (oldstatus == newstatus)
+ /*
+ * Don't clear pending flag if message queue wasn't
+ * fully drained
+ */
+ if (status != DBUS_DISPATCH_COMPLETE)
+ return 0;
+
+ if (read(fd, &pending, sizeof(int)) < 0) {
+ if (read(fd, &dispatch_pending, sizeof(uint64_t)) < 0)
+ perror("read");
+ die("Error in dbus dispatch");
+ }
+
+ return 0;
+}
@ -249,8 +242,8 @@ index 0000000..125312c
+
+ interval = dbus_timeout_get_interval(timeout);
+
+ timeout_source =
+ wl_event_loop_add_timer(loop, dwl_dbus_timeout_handle, timeout);
+ timeout_source = wl_event_loop_add_timer(
+ loop, dwl_dbus_timeout_handle, timeout);
+
+ r = wl_event_source_timer_update(timeout_source, interval);
+ if (r < 0) {
@ -277,74 +270,77 @@ index 0000000..125312c
+}
+
+static void
+dwl_dbus_dispatch_status(DBusConnection *conn, DBusDispatchStatus status,
+ void *data)
+dwl_dbus_adjust_timeout(DBusTimeout *timeout, void *data)
+{
+ int *pipefd = data;
+ int interval;
+ struct wl_event_source *timeout_source;
+
+ if (status != DBUS_DISPATCH_COMPLETE) {
+ int pending = 1;
+ if (write(pipefd[1], &pending, sizeof(int)) < 0) {
+ timeout_source = dbus_timeout_get_data(timeout);
+
+ if (timeout_source) {
+ interval = dbus_timeout_get_interval(timeout);
+ wl_event_source_timer_update(timeout_source, interval);
+ }
+}
+
+static void
+dwl_dbus_dispatch_status(DBusConnection *conn, DBusDispatchStatus status, void *data)
+{
+ if (status == DBUS_DISPATCH_DATA_REMAINS) {
+ uint64_t dispatch_pending = 1;
+ if (write(efd, &dispatch_pending, sizeof(uint64_t)) < 0)
+ perror("write");
+ die("Error in dispatch status");
+ }
+ }
+}
+
+struct wl_event_source *
+startbus(DBusConnection *conn, struct wl_event_loop *loop)
+{
+ int *pipefd;
+ int pending = 1, flags;
+ struct wl_event_source *bus_source = NULL;
+
+ pipefd = ecalloc(2, sizeof(int));
+
+ /*
+ * Libdbus forbids calling dbus_connection_dipatch from the
+ * DBusDispatchStatusFunction directly. Notify the event loop of
+ * updates via a self-pipe.
+ */
+ if (pipe(pipefd) < 0)
+ goto fail;
+ if (((flags = fcntl(pipefd[0], F_GETFD)) < 0) ||
+ fcntl(pipefd[0], F_SETFD, flags | FD_CLOEXEC) < 0 ||
+ ((flags = fcntl(pipefd[1], F_GETFD)) < 0) ||
+ fcntl(pipefd[1], F_SETFD, flags | FD_CLOEXEC) < 0) {
+ goto fail;
+ }
+ uint64_t dispatch_pending = 1;
+
+ dbus_connection_set_exit_on_disconnect(conn, FALSE);
+
+ bus_source = wl_event_loop_add_fd(loop, pipefd[0], WL_EVENT_READABLE,
+ dwl_dbus_dispatch, conn);
+#if defined __linux__
+ efd = eventfd(0, EFD_CLOEXEC);
+#elif defined(__FreeBSD__) || defined(__OpenBSD__)
+ efd = kqueue();
+#endif
+ if (efd < 0)
+ goto fail;
+
+ dbus_connection_set_dispatch_status_function(conn, dwl_dbus_dispatch_status, NULL, NULL);
+
+ if (!dbus_connection_set_watch_functions(conn, dwl_dbus_add_watch,
+ dwl_dbus_remove_watch,
+ NULL, loop, NULL)) {
+ goto fail;
+ }
+
+ if (!dbus_connection_set_timeout_functions(
+ conn, dwl_dbus_add_timeout, dwl_dbus_remove_timeout,
+ dwl_dbus_adjust_timeout, loop, NULL)) {
+ goto fail;
+ }
+
+ bus_source = wl_event_loop_add_fd(loop, efd, WL_EVENT_READABLE, dwl_dbus_dispatch, conn);
+ if (!bus_source)
+ goto fail;
+
+ dbus_connection_set_dispatch_status_function(conn,
+ dwl_dbus_dispatch_status,
+ pipefd, close_pipe);
+ if (!dbus_connection_set_watch_functions(conn, dwl_dbus_add_watch,
+ dwl_dbus_remove_watch, NULL,
+ loop, NULL)) {
+ goto fail;
+ }
+ if (!dbus_connection_set_timeout_functions(conn, dwl_dbus_add_timeout,
+ dwl_dbus_remove_timeout,
+ NULL, loop, NULL)) {
+ goto fail;
+ }
+ if (dbus_connection_get_dispatch_status(conn) != DBUS_DISPATCH_COMPLETE)
+ if (write(pipefd[1], &pending, sizeof(int)) < 0)
+ goto fail;
+ if (dbus_connection_get_dispatch_status(conn) == DBUS_DISPATCH_DATA_REMAINS)
+ if (write(efd, &dispatch_pending, sizeof(uint64_t)) < 0)
+ perror("write");
+
+ return bus_source;
+
+fail:
+ if (bus_source)
+ wl_event_source_remove(bus_source);
+ dbus_connection_set_timeout_functions(conn, NULL, NULL, NULL, NULL,
+ NULL);
+ if (efd >= 0) {
+ close(efd);
+ efd = -1;
+ }
+ dbus_connection_set_timeout_functions(conn, NULL, NULL, NULL, NULL, NULL);
+ dbus_connection_set_watch_functions(conn, NULL, NULL, NULL, NULL, NULL);
+ dbus_connection_set_dispatch_status_function(conn, NULL, NULL, NULL);
+
@ -355,9 +351,11 @@ index 0000000..125312c
+stopbus(DBusConnection *conn, struct wl_event_source *bus_source)
+{
+ wl_event_source_remove(bus_source);
+ close(efd);
+ efd = -1;
+
+ dbus_connection_set_watch_functions(conn, NULL, NULL, NULL, NULL, NULL);
+ dbus_connection_set_timeout_functions(conn, NULL, NULL, NULL, NULL,
+ NULL);
+ dbus_connection_set_timeout_functions(conn, NULL, NULL, NULL, NULL, NULL);
+ dbus_connection_set_dispatch_status_function(conn, NULL, NULL, NULL);
+}
diff --git a/dbus.h b/dbus.h
@ -377,7 +375,7 @@ index 0000000..b374b98
+
+#endif /* DWLDBUS_H */
diff --git a/dwl.c b/dwl.c
index ece537a..7753ef6 100644
index ece537a..959cc50 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1,6 +1,7 @@
@ -431,7 +429,7 @@ index ece537a..7753ef6 100644
+static DBusConnection *bus_conn;
+static struct wl_event_source *bus_source;
+static Watcher watcher = {.running = 0};
+static Watcher watcher;
+
static const struct wlr_buffer_impl buffer_impl = {
.destroy = bufdestroy,
@ -455,16 +453,20 @@ index ece537a..7753ef6 100644
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
@@ -751,6 +764,8 @@ buttonpress(struct wl_listener *listener, void *data)
@@ -750,17 +763,29 @@ buttonpress(struct wl_listener *listener, void *data)
if (!c && !exclusive_focus &&
(node = wlr_scene_node_at(&layers[LyrBottom]->node, cursor->x, cursor->y, NULL, NULL)) &&
(buffer = wlr_scene_buffer_from_node(node)) && buffer == selmon->scene_buffer) {
+
cx = (cursor->x - selmon->m.x) * selmon->wlr_output->scale;
+ traywidth = tray_get_width(selmon->tray);
+
do
x += TEXTW(selmon, tags[i]);
while (cx >= x && ++i < LENGTH(tags));
@@ -759,8 +774,16 @@ buttonpress(struct wl_listener *listener, void *data)
+
if (i < LENGTH(tags)) {
click = ClkTagBar;
arg.ui = 1 << i;
} else if (cx < x + TEXTW(selmon, selmon->ltsymbol))
click = ClkLtSymbol;
@ -482,7 +484,7 @@ index ece537a..7753ef6 100644
} else
click = ClkTitle;
}
@@ -774,7 +797,12 @@ buttonpress(struct wl_listener *listener, void *data)
@@ -774,7 +799,12 @@ buttonpress(struct wl_listener *listener, void *data)
mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
for (b = buttons; b < END(buttons); b++) {
if (CLEANMASK(mods) == CLEANMASK(b->mod) && event->button == b->button && click == b->click && b->func) {
@ -496,14 +498,12 @@ index ece537a..7753ef6 100644
return;
}
}
@@ -840,6 +868,14 @@ cleanup(void)
@@ -840,6 +870,12 @@ cleanup(void)
destroykeyboardgroup(&kb_group->destroy, NULL);
+ if (watcher.running)
+ watcher_stop(&watcher);
+
+ if (showbar && showsystray) {
+ watcher_stop(&watcher);
+ stopbus(bus_conn, bus_source);
+ dbus_connection_unref(bus_conn);
+ }
@ -596,23 +596,25 @@ index ece537a..7753ef6 100644
void
drawbars(void)
{
@@ -2818,6 +2889,15 @@ setup(void)
@@ -2818,6 +2889,17 @@ setup(void)
status_event_source = wl_event_loop_add_fd(wl_display_get_event_loop(dpy),
STDIN_FILENO, WL_EVENT_READABLE, statusin, NULL);
+ bus_conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
+ if (!bus_conn)
+ die("Failed to connect to bus");
+ bus_source = startbus(bus_conn, event_loop);
+ if (!bus_source)
+ die("Failed to start listening to bus events");
+ if (showbar && showsystray)
+ watcher_start(&watcher, bus_conn, event_loop);
+ if (showbar && showsystray) {
+ bus_conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
+ if (!bus_conn)
+ die("Failed to connect to bus");
+ bus_source = startbus(bus_conn, event_loop);
+ if (!bus_source)
+ die("Failed to start listening to bus events");
+ if (watcher_start(&watcher, bus_conn, event_loop) < 0)
+ die("Failed to start tray watcher");
+ }
+
/* 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 */
@@ -3160,6 +3240,7 @@ updatebar(Monitor *m)
@@ -3160,6 +3242,7 @@ updatebar(Monitor *m)
size_t i;
int rw, rh;
char fontattrs[12];
@ -620,7 +622,7 @@ index ece537a..7753ef6 100644
wlr_output_transformed_resolution(m->wlr_output, &rw, &rh);
m->b.width = rw;
@@ -3185,6 +3266,18 @@ updatebar(Monitor *m)
@@ -3185,6 +3268,18 @@ updatebar(Monitor *m)
m->lrpad = m->drw->font->height;
m->b.height = m->drw->font->height + 2;
m->b.real_height = (int)((float)m->b.height / m->wlr_output->scale);
@ -2422,10 +2424,10 @@ index 0000000..af4e5e3
+#endif /* TRAY_H */
diff --git a/systray/watcher.c b/systray/watcher.c
new file mode 100644
index 0000000..8dd84b9
index 0000000..072ab86
--- /dev/null
+++ b/systray/watcher.c
@@ -0,0 +1,551 @@
@@ -0,0 +1,549 @@
+#include "watcher.h"
+
+#include "item.h"
@ -2906,21 +2908,20 @@ index 0000000..8dd84b9
+static const DBusObjectPathVTable snw_vtable = { .message_function =
+ snw_message_handler };
+
+void
+int
+watcher_start(Watcher *watcher, DBusConnection *conn,
+ struct wl_event_loop *loop)
+{
+ DBusError err = DBUS_ERROR_INIT;
+ int r, flags;
+ int r;
+
+ wl_list_init(&watcher->items);
+ wl_list_init(&watcher->trays);
+ watcher->conn = conn;
+ watcher->loop = loop;
+
+ flags = DBUS_NAME_FLAG_REPLACE_EXISTING | DBUS_NAME_FLAG_DO_NOT_QUEUE;
+ r = dbus_bus_request_name(conn, SNW_NAME,
+ flags, NULL);
+ DBUS_NAME_FLAG_REPLACE_EXISTING, NULL);
+ if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
+ goto fail;
+
@ -2944,13 +2945,13 @@ index 0000000..8dd84b9
+ goto fail;
+ }
+
+ watcher->running = 1;
+ return;
+ dbus_error_free(&err);
+ return 0;
+
+fail:
+ fprintf(stderr, "Couldn't start watcher, systray not available\n");
+ dbus_error_free(&err);
+ return;
+ return -1;
+}
+
+void
@ -2960,7 +2961,6 @@ index 0000000..8dd84b9
+ dbus_bus_remove_match(watcher->conn, match_rule, NULL);
+ dbus_connection_remove_filter(watcher->conn, filter_bus, watcher);
+ dbus_bus_release_name(watcher->conn, SNW_NAME, NULL);
+ watcher->running = 0;
+}
+
+int
@ -2979,10 +2979,10 @@ index 0000000..8dd84b9
+}
diff --git a/systray/watcher.h b/systray/watcher.h
new file mode 100644
index 0000000..127eb64
index 0000000..0178587
--- /dev/null
+++ b/systray/watcher.h
@@ -0,0 +1,35 @@
@@ -0,0 +1,34 @@
+#ifndef WATCHER_H
+#define WATCHER_H
+
@ -3007,10 +3007,9 @@ index 0000000..127eb64
+ struct wl_list trays;
+ struct wl_event_loop *loop;
+ DBusConnection *conn;
+ int running;
+} Watcher;
+
+void watcher_start (Watcher *watcher, DBusConnection *conn,
+int watcher_start (Watcher *watcher, DBusConnection *conn,
+ struct wl_event_loop *loop);
+void watcher_stop (Watcher *watcher);
+
@ -3019,5 +3018,5 @@ index 0000000..127eb64
+
+#endif /* WATCHER_H */
--
2.49.0
2.48.1

View File

@ -1,10 +0,0 @@
### Description
Port of the [tagshift](https://dwm.suckless.org/patches/tagshift/) patch into dwl.
Allows a user to change his view and/or focused client into the next or previous tag.
### Download
- [0.7](/dwl/dwl-patches/raw/branch/main/patches/tagshift/tagshift.patch)
### Authors
- [h3nc4](https://codeberg.org/h3nc4)
me@h3nc4.com

View File

@ -1,83 +0,0 @@
From 938c63ad0a8a706fba0b4db1c66397e9defdcb92 Mon Sep 17 00:00:00 2001
From: h3nc4 <me@h3nc4.com>
Date: Mon, 17 Mar 2025 17:38:22 -0300
Subject: [PATCH] port the tagshift patch from dwm
---
config.def.h | 4 ++++
dwl.c | 37 +++++++++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+)
diff --git a/config.def.h b/config.def.h
index 22d2171..72dbaa1 100644
--- a/config.def.h
+++ b/config.def.h
@@ -131,6 +131,10 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} },
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
{ MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
+ { MODKEY, XKB_KEY_Left, shiftview, {.i = -1 } },
+ { MODKEY, XKB_KEY_Right, shiftview, {.i = +1 } },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Left, shifttag, {.i = -1 } },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Right, shifttag, {.i = +1 } },
{ MODKEY, XKB_KEY_h, setmfact, {.f = -0.05f} },
{ MODKEY, XKB_KEY_l, setmfact, {.f = +0.05f} },
{ MODKEY, XKB_KEY_Return, zoom, {0} },
diff --git a/dwl.c b/dwl.c
index cf3ef70..be1e89e 100644
--- a/dwl.c
+++ b/dwl.c
@@ -333,6 +333,8 @@ static void setmon(Client *c, Monitor *m, uint32_t newtags);
static void setpsel(struct wl_listener *listener, void *data);
static void setsel(struct wl_listener *listener, void *data);
static void setup(void);
+static void shiftview(const Arg *arg);
+static void shifttag(const Arg *arg);
static void spawn(const Arg *arg);
static void startdrag(struct wl_listener *listener, void *data);
static void tag(const Arg *arg);
@@ -2646,6 +2648,41 @@ setup(void)
#endif
}
+void
+shiftview(const Arg *arg)
+{
+ Arg a;
+ int nextseltags, curseltags = selmon->tagset[selmon->seltags];
+ if (arg->i > 0) // left circular shift
+ nextseltags = (curseltags << arg->i) | (curseltags >> (TAGCOUNT - arg->i));
+ else // right circular shift
+ nextseltags = curseltags >> (-arg->i) | (curseltags << (TAGCOUNT + arg->i));
+
+ a.i = nextseltags; // Change view to the new tag
+ view(&a);
+}
+
+void
+shifttag(const Arg *arg)
+{
+ Arg a;
+ int nextseltags, curseltags = selmon->tagset[selmon->seltags];
+ Client *sel = focustop(selmon);
+ if (!sel)
+ return;
+ if (arg->i > 0) // left circular shift
+ nextseltags = (curseltags << arg->i) | (curseltags >> (TAGCOUNT - arg->i));
+ else // right circular shift
+ nextseltags = curseltags >> (-arg->i) | (curseltags << (TAGCOUNT + arg->i));
+
+ sel->tags = nextseltags & TAGMASK;// Apply new tag to the client
+ a.i = nextseltags; // Change view to the new tag
+ view(&a);
+
+ arrange(selmon);
+ printstatus(); // change to 'drawbars();' if using "bars" patch
+}
+
void
spawn(const Arg *arg)
{
--
2.47.2