mirror of
https://github.com/swaywm/sway.git
synced 2026-06-17 14:33:33 -04:00
Added minimum viable swaybar tray SNI protocol support using sd-bus
This commit is contained in:
parent
456b91600d
commit
854c0d3b6d
13 changed files with 392 additions and 17 deletions
|
|
@ -2,17 +2,14 @@
|
||||||
#define _SWAYBAR_DBUS_H
|
#define _SWAYBAR_DBUS_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <dbus/dbus.h>
|
#include <systemd/sd-bus.h>
|
||||||
extern DBusConnection *conn;
|
|
||||||
|
|
||||||
/**
|
void process_request(int fd, short mask, void *data);
|
||||||
* Should be called in main loop to dispatch events
|
|
||||||
*/
|
|
||||||
void dispatch_dbus();
|
|
||||||
|
|
||||||
/**
|
bool dbus_init();
|
||||||
* Initializes async dbus communication
|
|
||||||
*/
|
void finish_dbus(sd_bus_slot *slot, sd_bus *bus);
|
||||||
int dbus_init();
|
|
||||||
|
int dbus_name_has_owner(sd_bus *bus, const char *name, sd_bus_error *error);
|
||||||
|
|
||||||
#endif /* _SWAYBAR_DBUS_H */
|
#endif /* _SWAYBAR_DBUS_H */
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
#define _SWAYBAR_SNI_H
|
#define _SWAYBAR_SNI_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <client/cairo.h>
|
#include <cairo.h>
|
||||||
|
|
||||||
struct StatusNotifierItem {
|
struct StatusNotifierItem {
|
||||||
/* Name registered to sni watcher */
|
/* Name registered to sni watcher */
|
||||||
|
|
|
||||||
3
include/swaybar/tray/sni_host.h
Normal file
3
include/swaybar/tray/sni_host.h
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
char *init_dbus_sni_host(const char *prefix);
|
||||||
|
|
||||||
|
|
@ -1,10 +1,41 @@
|
||||||
#ifndef _SWAYBAR_SNI_WATCHER_H
|
#ifndef _SWAYBAR_SNI_WATCHER_H
|
||||||
#define _SWAYBAR_SNI_WATCHER_H
|
#define _SWAYBAR_SNI_WATCHER_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <systemd/sd-bus.h>
|
||||||
|
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
|
struct sni_watcher {
|
||||||
|
sd_bus *bus;
|
||||||
|
const char *iface;
|
||||||
|
const char *path;
|
||||||
|
list_t *hosts;
|
||||||
|
list_t *items;
|
||||||
|
int version;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the sni_watcher, the watcher is practically a black box and should
|
* Starts the sni_watcher, the watcher is practically a black box and should
|
||||||
* only be accessed though functions described in its spec
|
* only be accessed though functions described in its spec
|
||||||
*/
|
*/
|
||||||
int init_sni_watcher();
|
|
||||||
|
static int method_register_sni(sd_bus_message *msg, void *userdata,
|
||||||
|
sd_bus_error *ret_error);
|
||||||
|
|
||||||
|
static int property_registered_sni(sd_bus *bus, const char *path,
|
||||||
|
const char *interface, const char *property, sd_bus_message *reply,
|
||||||
|
void *userdata, sd_bus_error *error);
|
||||||
|
|
||||||
|
bool sni_watcher_vtable_init(struct sni_watcher *watcher, sd_bus_slot *slot);
|
||||||
|
|
||||||
|
bool sni_watcher_init(struct sni_watcher *watcher);
|
||||||
|
|
||||||
|
static int handle_new_icon(sd_bus_message *msg, void *userdata,
|
||||||
|
sd_bus_error *ret_error);
|
||||||
|
|
||||||
|
int add_sni_signal_matches(struct sni_watcher *watcher);
|
||||||
|
|
||||||
|
int sni_item_cmp(const void *item, const void *data);
|
||||||
|
|
||||||
#endif /* _SWAYBAR_SNI_WATCHER_H */
|
#endif /* _SWAYBAR_SNI_WATCHER_H */
|
||||||
|
|
|
||||||
|
|
@ -17,16 +17,16 @@ struct tray {
|
||||||
/**
|
/**
|
||||||
* Processes a mouse event on the bar
|
* Processes a mouse event on the bar
|
||||||
*/
|
*/
|
||||||
void tray_mouse_event(struct output *output, int x, int y,
|
//void tray_mouse_event(struct output *output, int x, int y,
|
||||||
uint32_t button, uint32_t state);
|
// uint32_t button, uint32_t state);
|
||||||
|
|
||||||
uint32_t tray_render(struct output *output, struct config *config);
|
//uint32_t tray_render(struct output *output, struct config *config);
|
||||||
|
|
||||||
void tray_upkeep(struct bar *bar);
|
//void tray_upkeep(struct swaybar *bar);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the tray with D-Bus
|
* Initializes the tray with D-Bus
|
||||||
*/
|
*/
|
||||||
void init_tray(struct bar *bar);
|
void tray_init(struct swaybar *bar);
|
||||||
|
|
||||||
#endif /* _SWAYBAR_TRAY_H */
|
#endif /* _SWAYBAR_TRAY_H */
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,10 @@ if elogind.found()
|
||||||
swayidle_deps += elogind
|
swayidle_deps += elogind
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if get_option('enable-tray')
|
||||||
|
conf_data.set('ENABLE_TRAY', true)
|
||||||
|
endif
|
||||||
|
|
||||||
scdoc = find_program('scdoc', required: false)
|
scdoc = find_program('scdoc', required: false)
|
||||||
|
|
||||||
if scdoc.found()
|
if scdoc.found()
|
||||||
|
|
|
||||||
|
|
@ -5,3 +5,4 @@ option('zsh-completions', type: 'boolean', value: true, description: 'Install zs
|
||||||
option('bash-completions', type: 'boolean', value: true, description: 'Install bash shell completions.')
|
option('bash-completions', type: 'boolean', value: true, description: 'Install bash shell completions.')
|
||||||
option('fish-completions', type: 'boolean', value: true, description: 'Install fish shell completions.')
|
option('fish-completions', type: 'boolean', value: true, description: 'Install fish shell completions.')
|
||||||
option('enable-xwayland', type: 'boolean', value: true, description: 'Enable support for X11 applications')
|
option('enable-xwayland', type: 'boolean', value: true, description: 'Enable support for X11 applications')
|
||||||
|
option('enable-tray', type: 'boolean', value: false, description: 'Enable support for the swaybar tray')
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,9 @@
|
||||||
#include "swaybar/status_line.h"
|
#include "swaybar/status_line.h"
|
||||||
#include "swaybar/bar.h"
|
#include "swaybar/bar.h"
|
||||||
#include "swaybar/ipc.h"
|
#include "swaybar/ipc.h"
|
||||||
|
#ifdef ENABLE_TRAY
|
||||||
|
#include "swaybar/tray/tray.h"
|
||||||
|
#endif
|
||||||
#include "ipc-client.h"
|
#include "ipc-client.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
@ -448,6 +451,9 @@ void bar_setup(struct swaybar *bar,
|
||||||
}
|
}
|
||||||
ipc_get_workspaces(bar);
|
ipc_get_workspaces(bar);
|
||||||
render_all_frames(bar);
|
render_all_frames(bar);
|
||||||
|
#ifdef ENABLE_TRAY
|
||||||
|
tray_init(bar);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void display_in(int fd, short mask, void *data) {
|
static void display_in(int fd, short mask, void *data) {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,10 @@ executable(
|
||||||
'main.c',
|
'main.c',
|
||||||
'render.c',
|
'render.c',
|
||||||
'status_line.c',
|
'status_line.c',
|
||||||
|
'tray/dbus.c',
|
||||||
|
'tray/sni_host.c',
|
||||||
|
'tray/sni_watcher.c',
|
||||||
|
'tray/tray.c',
|
||||||
],
|
],
|
||||||
include_directories: [sway_inc],
|
include_directories: [sway_inc],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
|
|
@ -19,6 +23,7 @@ executable(
|
||||||
pango,
|
pango,
|
||||||
pangocairo,
|
pangocairo,
|
||||||
rt,
|
rt,
|
||||||
|
systemd,
|
||||||
wayland_client,
|
wayland_client,
|
||||||
wayland_cursor,
|
wayland_cursor,
|
||||||
wlroots,
|
wlroots,
|
||||||
|
|
|
||||||
131
swaybar/tray/dbus.c
Normal file
131
swaybar/tray/dbus.c
Normal file
|
|
@ -0,0 +1,131 @@
|
||||||
|
#define _XOPEN_SOURCE 500
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#include <dev/evdev/input-event-codes.h>
|
||||||
|
#else
|
||||||
|
#include <linux/input-event-codes.h>
|
||||||
|
#endif
|
||||||
|
#include <poll.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <wlr/util/log.h>
|
||||||
|
#include "swaybar/event_loop.h"
|
||||||
|
#include "swaybar/tray/dbus.h"
|
||||||
|
#include "swaybar/tray/sni_host.h"
|
||||||
|
#include "swaybar/tray/sni_watcher.h"
|
||||||
|
|
||||||
|
static const char *fd_iface = "org.freedesktop.StatusNotifierWatcher";
|
||||||
|
static const char *fd_notifier_host = "org.freedesktop.StatusNotifierHost";
|
||||||
|
|
||||||
|
bool dbus_init() {
|
||||||
|
int ret = 0;
|
||||||
|
sd_bus *bus = NULL;
|
||||||
|
/* BUG: *slot should contained in sni_watcher struct to facilitate multiple
|
||||||
|
* watchers but when done in this way the sd-bus handler callbacks
|
||||||
|
* (handle_new_icon) were getting bad userdata
|
||||||
|
*/
|
||||||
|
|
||||||
|
sd_bus_slot *slot = NULL;
|
||||||
|
// TODO: Add other watchers for KDE, etc.
|
||||||
|
struct sni_watcher fd_sni_watcher = {0};
|
||||||
|
|
||||||
|
ret = sd_bus_open_user(&bus);
|
||||||
|
if (ret < 0) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to connect to user bus: %s",
|
||||||
|
strerror(-ret));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_log(WLR_DEBUG, "Connected to user bus");
|
||||||
|
|
||||||
|
fd_sni_watcher.bus = bus;
|
||||||
|
fd_sni_watcher.iface = fd_iface;
|
||||||
|
sni_watcher_init(&fd_sni_watcher);
|
||||||
|
|
||||||
|
ret = sni_watcher_vtable_init(&fd_sni_watcher, slot);
|
||||||
|
if (ret < 0) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to init freedesktop watcher vtable: %s",
|
||||||
|
strerror(-ret));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = sd_bus_request_name(bus, fd_iface, 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to get freedesktop SNI watcher name: %s",
|
||||||
|
strerror(-ret));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *fd_name = init_dbus_sni_host(fd_notifier_host);
|
||||||
|
if (fd_name == NULL) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to init freedesktop Notifier host");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = sd_bus_request_name(bus, fd_name, 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to get freedesktop notifier host name: %s",
|
||||||
|
strerror(-ret));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_event(sd_bus_get_fd(bus), POLLIN, process_request, bus);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
error:
|
||||||
|
finish_dbus(slot, bus);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void finish_dbus(sd_bus_slot *slot, sd_bus *bus) {
|
||||||
|
sd_bus_slot_unref(slot);
|
||||||
|
sd_bus_unref(bus);
|
||||||
|
}
|
||||||
|
|
||||||
|
void process_request(int fd, short mask, void *data) {
|
||||||
|
int ret = 0;
|
||||||
|
sd_bus *bus = data;
|
||||||
|
wlr_log(WLR_DEBUG, "Processing a bus request");
|
||||||
|
while(1) {
|
||||||
|
ret = sd_bus_process(bus, NULL);
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to process bus: %s", strerror(-ret));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int dbus_name_has_owner(sd_bus *bus, const char *name, sd_bus_error *error) {
|
||||||
|
sd_bus_message *reply = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
int has_owner = 0;
|
||||||
|
|
||||||
|
ret = sd_bus_call_method(bus,
|
||||||
|
"org.freedesktop.DBus",
|
||||||
|
"/org/freedesktop/dbus",
|
||||||
|
"org.freedesktop.DBus",
|
||||||
|
"NameHasOwner",
|
||||||
|
error,
|
||||||
|
&reply,
|
||||||
|
"s",
|
||||||
|
name);
|
||||||
|
if (ret < 0) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to call NameHasOwner on: %s", name);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = sd_bus_message_read_basic(reply, 'b', &has_owner);
|
||||||
|
if (ret < 0) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to read NameHasOwner message on: %s", name);
|
||||||
|
return sd_bus_error_set_errno(error, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return has_owner;
|
||||||
|
}
|
||||||
|
|
||||||
20
swaybar/tray/sni_host.c
Normal file
20
swaybar/tray/sni_host.c
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
char *init_dbus_sni_host(const char *prefix) {
|
||||||
|
char *name = NULL;
|
||||||
|
|
||||||
|
name = calloc(sizeof(char), 256);
|
||||||
|
if (name == NULL) {
|
||||||
|
fprintf(stderr, "Could not allocate SNI host name\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t pid = getpid();
|
||||||
|
snprintf(name, sizeof(char) * 256, "%s-%d", prefix, pid);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
169
swaybar/tray/sni_watcher.c
Normal file
169
swaybar/tray/sni_watcher.c
Normal file
|
|
@ -0,0 +1,169 @@
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
|
#include "swaybar/tray/dbus.h"
|
||||||
|
#include "swaybar/tray/sni_watcher.h"
|
||||||
|
|
||||||
|
static const char *sni_watcher_path = "/StatusNotifierWatcher";
|
||||||
|
|
||||||
|
static int method_register_sni(sd_bus_message *msg, void *userdata, sd_bus_error *ret_error) {
|
||||||
|
struct sni_watcher *watcher = userdata;
|
||||||
|
int ret = 0;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
wlr_log(WLR_INFO, "Interface: %s", watcher->iface);
|
||||||
|
ret = sd_bus_message_read(msg, "s", &name);
|
||||||
|
if (ret < 0) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to parse register SNI item message: %s",
|
||||||
|
strerror(-ret));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_log(WLR_DEBUG, "Incoming SNI registration: %s", name);
|
||||||
|
|
||||||
|
if (!dbus_name_has_owner(sd_bus_message_get_bus(msg), name, NULL)) {
|
||||||
|
wlr_log(WLR_DEBUG, "DBus name does not have owner");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_log(WLR_INFO, "RegisterStatusNotifierItem called with: %s", name);
|
||||||
|
if (list_seq_find(watcher->items, sni_item_cmp, name) != -1) {
|
||||||
|
wlr_log(WLR_DEBUG, "Watcher already has name: %s", name);
|
||||||
|
} else {
|
||||||
|
list_add(watcher->items, name);
|
||||||
|
sd_bus_emit_signal(watcher->bus, watcher->path, watcher->iface,
|
||||||
|
"StatusNotifierItemRegistered", "b", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sd_bus_reply_method_return(msg, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int property_registered_sni(sd_bus *bus, const char *path, const char
|
||||||
|
*interface, const char *property, sd_bus_message *reply,
|
||||||
|
void *userdata, sd_bus_error *error) {
|
||||||
|
struct sni_watcher *watcher = userdata;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
ret = sd_bus_message_open_container(reply, 'a', "s");
|
||||||
|
if (ret < 0) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to open reply container: %s",
|
||||||
|
strerror(-ret));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
for (int i = 0;i < watcher->items->length; i++) {
|
||||||
|
ret = sd_bus_message_append(reply, "s", watcher->items->items[i]);
|
||||||
|
if (ret < 0) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to append to reply container: %s",
|
||||||
|
strerror(-ret));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sd_bus_message_close_container(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const sd_bus_vtable sni_watcher_vtable[] = {
|
||||||
|
SD_BUS_VTABLE_START(0),
|
||||||
|
SD_BUS_METHOD("RegisterStatusNotifierItem", "s", "", method_register_sni,
|
||||||
|
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
// SD_BUS_METHOD("RegisterStatusNotifierHost", "s", "", method_register_snh,
|
||||||
|
// SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
SD_BUS_PROPERTY("RegisteredStatusNotifierItems", "as", property_registered_sni,
|
||||||
|
0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
// SD_BUS_PROPERTY("IsStatusNotifierHostRegistered", "b", property_is_snh_registered,
|
||||||
|
// 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_PROPERTY("ProtocolVersion", "i", NULL, offsetof(struct sni_watcher, version),
|
||||||
|
SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_SIGNAL("StatusNotifierItemRegistered", "s", 0),
|
||||||
|
SD_BUS_SIGNAL("StatusNotifierItemUnregistered", "s", 0),
|
||||||
|
SD_BUS_SIGNAL("StatusNotifierHostRegistered", NULL, 0),
|
||||||
|
SD_BUS_VTABLE_END
|
||||||
|
};
|
||||||
|
|
||||||
|
bool sni_watcher_vtable_init(struct sni_watcher *watcher, sd_bus_slot *slot) {
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
ret = sd_bus_add_object_vtable(watcher->bus, &slot, watcher->path, watcher->iface,
|
||||||
|
sni_watcher_vtable, watcher);
|
||||||
|
if (ret < 0) {
|
||||||
|
wlr_log(WLR_ERROR, "Could not init SNI watcher vtable: %s",
|
||||||
|
strerror(-1));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sni_watcher_init(struct sni_watcher *watcher) {
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
watcher->path = sni_watcher_path;
|
||||||
|
watcher->items = create_list();
|
||||||
|
watcher->hosts = create_list();
|
||||||
|
watcher->version = 0;
|
||||||
|
ret = add_sni_signal_matches(watcher);
|
||||||
|
if (ret < 0) {
|
||||||
|
wlr_log(WLR_ERROR, "Could not init SNI watcher matches: %s",
|
||||||
|
strerror(-1));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_new_icon(sd_bus_message *msg, void *userdata, sd_bus_error *ret_error) {
|
||||||
|
struct sni_watcher *watcher = userdata;
|
||||||
|
int ret = 0;
|
||||||
|
sd_bus_error err = SD_BUS_ERROR_NULL;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
ret = sd_bus_get_property_string(watcher->bus, sd_bus_message_get_sender(msg),
|
||||||
|
"/StatusNotifierItem", sd_bus_message_get_interface(msg), "IconName",
|
||||||
|
&err,
|
||||||
|
&name);
|
||||||
|
if (ret < 0) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to get IconName property: %s",
|
||||||
|
err.message);
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_log(WLR_DEBUG, "Got IconName property: %s", name);
|
||||||
|
// TODO: call code to find the icon path, display the icon, etc.
|
||||||
|
|
||||||
|
finish:
|
||||||
|
sd_bus_error_free(&err);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int add_sni_signal_matches(struct sni_watcher *watcher) {
|
||||||
|
int ret = 0;
|
||||||
|
char *iface = NULL;
|
||||||
|
|
||||||
|
if (strcmp(watcher->iface, "org.freedesktop.StatusNotifierWatcher") == 0) {
|
||||||
|
iface = "org.freedesktop.StatusNotifierItem";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iface == NULL) {
|
||||||
|
wlr_log(WLR_ERROR, "Unsupported interface: %s", watcher->iface);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = sd_bus_match_signal(watcher->bus, NULL, NULL, NULL, iface, "NewIcon",
|
||||||
|
handle_new_icon, watcher);
|
||||||
|
if (ret < 0) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to add match for NewIcon signal: %s",
|
||||||
|
strerror(-ret));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
wlr_log(WLR_DEBUG, "Added NewIcon signal match for: %s", iface);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sni_item_cmp(const void *item, const void *data) {
|
||||||
|
const char *sni_item = item;
|
||||||
|
const char *name = data;
|
||||||
|
return strcmp(sni_item, name);
|
||||||
|
}
|
||||||
|
|
||||||
8
swaybar/tray/tray.c
Normal file
8
swaybar/tray/tray.c
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#include "swaybar/bar.h"
|
||||||
|
#include "swaybar/tray/dbus.h"
|
||||||
|
|
||||||
|
void tray_init(struct swaybar *bar) {
|
||||||
|
dbus_init();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue