Compare commits

..

20 Commits
0.1.1 ... 0.1.3

Author SHA1 Message Date
3f2eb0b492 chore: 0.1.3 2018-10-28 08:39:33 +01:00
4f773ea268 Merge pull request #65 from maxice8/fix-musl
add missing <cstring> include for strncpy, fixes musl
2018-10-28 08:29:56 +01:00
047473e5a4 add missing <cstring> include for strncpy, fixes musl
I/usr/include/libdbusmenu-glib-0.4 -flto -fdiagnostics-color=always -DNDEBUG -pipe -D_FILE_OFFSET_BITS=64 -std=c++17 -DHAVE_SWAY -DHAVE_LIBPULSE -DHAVE_DBUSMENU -D_FORTIFY_SOURCE=2 -mtune=generic -O2 -D_REENTRANT -pthread  -MD -MQ 'waybar@exe/src_modules_sway_ipc_client.cpp.o' -MF 'waybar@exe/src_modules_sway_ipc_client.cpp.o.d' -o 'waybar@exe/src_modules_sway_ipc_client.cpp.o' -c ../src/modules/sway/ipc/client.cpp
../src/modules/sway/ipc/client.cpp: In member function 'int waybar::modules::sway::Ipc::open(const string&) const':
../src/modules/sway/ipc/client.cpp:47:3: error: 'strncpy' was not declared in this scope
   strncpy(addr.sun_path, socketPath.c_str(), sizeof(addr.sun_path) - 1);
   ^~~~~~~
../src/modules/sway/ipc/client.cpp:47:3: note: 'strncpy' is defined in header '<cstring>'; did you forget to '#include <cstring>'?
../src/modules/sway/ipc/client.cpp:2:1:
+#include <cstring>

../src/modules/sway/ipc/client.cpp:47:3:
   strncpy(addr.sun_path, socketPath.c_str(), sizeof(addr.sun_path) - 1);
   ^~~~~~~
[36/44] Compiling C++ object 'waybar@exe/src_modules_custom.cpp.o'.
[37/44] Compiling C++ object 'waybar@exe/src_client.cpp.o'.
[38/44] Compiling C++ object 'waybar@exe/src_modules_cpu.cpp.o'.
ninja: build stopped: subcommand failed.
2018-10-28 04:06:07 -03:00
ed3e4b1395 fix(pulseaudio): check active_port is set 2018-10-27 11:23:43 +02:00
16b01e1059 Merge pull request #62 from colemickens/giounix20
meson: fix 'gio-unix-2.0' dependency
2018-10-27 09:35:47 +02:00
1ae490c8f7 Merge pull request #61 from colemickens/outdir
meson: make extra output directory configurable
2018-10-27 09:16:11 +02:00
0d0a3be483 meson: fix 'gio-unix-2.0' dependency 2018-10-26 23:21:03 -07:00
a1c4b9bb0c meson: make extra output directory configurable 2018-10-26 23:20:38 -07:00
a55a1ae866 fix(tray): icons size 2018-10-26 14:53:39 +02:00
07d8dfb3d6 feat(tray): spacing config 2018-10-26 12:08:50 +02:00
5010227e6b fix(tray): icons 2018-10-26 11:59:03 +02:00
e8f3c1c6b3 chore: v0.1.2 2018-10-26 11:21:04 +02:00
7e6c701659 chore: update README 2018-10-26 11:16:17 +02:00
adc38c3dfe feat(sni): set protocol version 2018-10-26 10:56:45 +02:00
b10907ee44 refactor: remove useless code 2018-10-26 10:39:25 +02:00
0c9699b076 fix: check before set is host registered 2018-10-26 10:27:15 +02:00
63e86fbe9e fix: check type 2018-10-26 10:12:34 +02:00
f20441fa92 refactor: simpler sni naming 2018-10-26 10:05:54 +02:00
3f269ff463 fix: check json::value type 2018-10-26 09:27:16 +02:00
fd76e98552 fix: ifdef include 2018-10-25 19:12:28 +02:00
27 changed files with 161 additions and 138 deletions

View File

@ -7,6 +7,7 @@
**Current features** **Current features**
- Sway Workspaces - Sway Workspaces
- Sway focused window name - Sway focused window name
- Tray (Beta) [#21](https://github.com/Alexays/Waybar/issues/21)
- Local time - Local time
- Battery - Battery
- Network - Network

View File

@ -9,7 +9,9 @@
#include "modules/battery.hpp" #include "modules/battery.hpp"
#include "modules/memory.hpp" #include "modules/memory.hpp"
#include "modules/cpu.hpp" #include "modules/cpu.hpp"
#ifdef HAVE_DBUSMENU
#include "modules/sni/tray.hpp" #include "modules/sni/tray.hpp"
#endif
#ifdef HAVE_LIBNL #ifdef HAVE_LIBNL
#include "modules/network.hpp" #include "modules/network.hpp"
#endif #endif

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <gtkmm.h> #include <gtkmm.h>
#include <json/json.h>
#include <tuple> #include <tuple>
#include <dbus-status-notifier-watcher.h> #include <dbus-status-notifier-watcher.h>
#include "modules/sni/sni.hpp" #include "modules/sni/sni.hpp"
@ -10,7 +10,7 @@ namespace waybar::modules::SNI {
class Host { class Host {
public: public:
Host(Glib::Dispatcher*); Host(Glib::Dispatcher*, const Json::Value&);
std::vector<Item> items; std::vector<Item> items;
private: private:
static void busAcquired(GDBusConnection*, const gchar*, gpointer); static void busAcquired(GDBusConnection*, const gchar*, gpointer);
@ -19,10 +19,8 @@ class Host {
static void nameVanished(GDBusConnection*, const gchar*, gpointer); static void nameVanished(GDBusConnection*, const gchar*, gpointer);
static void proxyReady(GObject*, GAsyncResult*, gpointer); static void proxyReady(GObject*, GAsyncResult*, gpointer);
static void registerHost(GObject*, GAsyncResult*, gpointer); static void registerHost(GObject*, GAsyncResult*, gpointer);
static void itemRegistered(SnOrgKdeStatusNotifierWatcher*, const gchar*, static void itemRegistered(SnWatcher*, const gchar*, gpointer);
gpointer); static void itemUnregistered(SnWatcher*, const gchar*, gpointer);
static void itemUnregistered(SnOrgKdeStatusNotifierWatcher*, const gchar*,
gpointer);
std::tuple<std::string, std::string> getBusNameAndObjectPath(const gchar*); std::tuple<std::string, std::string> getBusNameAndObjectPath(const gchar*);
void addRegisteredItem(const gchar* service); void addRegisteredItem(const gchar* service);
@ -33,7 +31,8 @@ class Host {
std::string object_path_; std::string object_path_;
Glib::Dispatcher* dp_; Glib::Dispatcher* dp_;
GCancellable* cancellable_ = nullptr; GCancellable* cancellable_ = nullptr;
SnOrgKdeStatusNotifierWatcher* watcher_ = nullptr; SnWatcher* watcher_ = nullptr;
const Json::Value &config_;
}; };
} }

View File

@ -2,12 +2,14 @@
#include <dbus-status-notifier-item.h> #include <dbus-status-notifier-item.h>
#include <gtkmm.h> #include <gtkmm.h>
#include <json/json.h>
#include <filesystem>
namespace waybar::modules::SNI { namespace waybar::modules::SNI {
class Item { class Item {
public: public:
Item(std::string, std::string, Glib::Dispatcher *); Item(std::string, std::string, Glib::Dispatcher*, Json::Value);
std::string bus_name; std::string bus_name;
std::string object_path; std::string object_path;
@ -39,13 +41,15 @@ private:
static void handleSecondaryActivate(GObject *, GAsyncResult *, gpointer); static void handleSecondaryActivate(GObject *, GAsyncResult *, gpointer);
void updateImage(); void updateImage();
void updateMenu();
Glib::RefPtr<Gdk::Pixbuf> extractPixBuf(GVariant *variant); Glib::RefPtr<Gdk::Pixbuf> extractPixBuf(GVariant *variant);
Glib::RefPtr<Gdk::Pixbuf> getIconByName(std::string name, int size); Glib::RefPtr<Gdk::Pixbuf> getIconByName(std::string name, int size);
bool handleClick(GdkEventButton *const & /*ev*/); bool handleClick(GdkEventButton *const & /*ev*/);
Glib::Dispatcher *dp_; Glib::Dispatcher *dp_;
GCancellable *cancellable_ = nullptr; GCancellable *cancellable_ = nullptr;
SnOrgKdeStatusNotifierItem *proxy_ = nullptr; SnItem *proxy_ = nullptr;
Json::Value config_;
}; };
} // namespace waybar::modules::SNI } // namespace waybar::modules::SNI

View File

@ -34,13 +34,13 @@ private:
static void nameVanished(GDBusConnection *connection, const char *name, static void nameVanished(GDBusConnection *connection, const char *name,
gpointer data); gpointer data);
void updateRegisteredItems(SnOrgKdeStatusNotifierWatcher *obj); void updateRegisteredItems(SnWatcher *obj);
uint32_t bus_name_id_; uint32_t bus_name_id_;
uint32_t watcher_id_; uint32_t watcher_id_;
GSList *hosts_ = nullptr; GSList *hosts_ = nullptr;
GSList *items_ = nullptr; GSList *items_ = nullptr;
SnOrgKdeStatusNotifierWatcher *watcher_ = nullptr; SnWatcher *watcher_ = nullptr;
}; };
} // namespace waybar::modules::SNI } // namespace waybar::modules::SNI

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <iostream> #include <iostream>
#include <cstring>
#include <unistd.h> #include <unistd.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>

View File

@ -1,6 +1,6 @@
project( project(
'waybar', 'cpp', 'c', 'waybar', 'cpp', 'c',
version: '0.1.0', version: '0.1.3',
license: 'MIT', license: 'MIT',
default_options : [ default_options : [
'cpp_std=c++17', 'cpp_std=c++17',
@ -33,6 +33,7 @@ wayland_protos = dependency('wayland-protocols')
wlroots = dependency('wlroots', fallback: ['wlroots', 'wlroots']) wlroots = dependency('wlroots', fallback: ['wlroots', 'wlroots'])
gtkmm = dependency('gtkmm-3.0') gtkmm = dependency('gtkmm-3.0')
dbusmenu_gtk = dependency('dbusmenu-gtk3-0.4', required: get_option('dbusmenu-gtk')) dbusmenu_gtk = dependency('dbusmenu-gtk3-0.4', required: get_option('dbusmenu-gtk'))
giounix = dependency('gio-unix-2.0', required: get_option('dbusmenu-gtk'))
jsoncpp = dependency('jsoncpp') jsoncpp = dependency('jsoncpp')
sigcpp = dependency('sigc++-2.0') sigcpp = dependency('sigc++-2.0')
libnl = dependency('libnl-3.0', required: get_option('libnl')) libnl = dependency('libnl-3.0', required: get_option('libnl'))
@ -98,6 +99,7 @@ executable(
wayland_cursor, wayland_cursor,
gtkmm, gtkmm,
dbusmenu_gtk, dbusmenu_gtk,
giounix,
libnl, libnl,
libnlgen, libnlgen,
libpulse libpulse
@ -109,7 +111,7 @@ executable(
install_data( install_data(
'./resources/config', './resources/config',
'./resources/style.css', './resources/style.css',
install_dir: '/etc/xdg/waybar', install_dir: join_paths(get_option('out'), 'etc/xdg/waybar')
) )
clangtidy = find_program('clang-tidy', required: false) clangtidy = find_program('clang-tidy', required: false)

View File

@ -1,3 +1,4 @@
option('libnl', type: 'feature', value: 'auto', description: 'Enable libnl support for network related features') option('libnl', type: 'feature', value: 'auto', description: 'Enable libnl support for network related features')
option('pulseaudio', type: 'feature', value: 'auto', description: 'Enable support for pulseaudio') option('pulseaudio', type: 'feature', value: 'auto', description: 'Enable support for pulseaudio')
option('dbusmenu-gtk', type: 'feature', value: 'auto', description: 'Enable support for tray') option('dbusmenu-gtk', type: 'feature', value: 'auto', description: 'Enable support for tray')
option('out', type: 'string', value : '/', description: 'output prefix directory')

View File

@ -2,6 +2,7 @@
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node> <node>
<interface name="org.kde.StatusNotifierItem"> <interface name="org.kde.StatusNotifierItem">
<annotation name="org.gtk.GDBus.C.Name" value="Item" />
<property name="Category" type="s" access="read"/> <property name="Category" type="s" access="read"/>
<property name="Id" type="s" access="read"/> <property name="Id" type="s" access="read"/>
<property name="Title" type="s" access="read"/> <property name="Title" type="s" access="read"/>

View File

@ -1,13 +1,16 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node> <node>
<interface name="org.kde.StatusNotifierWatcher"> <interface name="org.kde.StatusNotifierWatcher">
<annotation name="org.gtk.GDBus.C.Name" value="Watcher" />
<!-- methods --> <!-- methods -->
<method name="RegisterStatusNotifierItem"> <method name="RegisterStatusNotifierItem">
<annotation name="org.gtk.GDBus.C.Name" value="RegisterItem" />
<arg name="service" type="s" direction="in"/> <arg name="service" type="s" direction="in"/>
</method> </method>
<method name="RegisterStatusNotifierHost"> <method name="RegisterStatusNotifierHost">
<annotation name="org.gtk.GDBus.C.Name" value="RegisterHost" />
<arg name="service" type="s" direction="in"/> <arg name="service" type="s" direction="in"/>
</method> </method>
@ -15,10 +18,13 @@
<!-- properties --> <!-- properties -->
<property name="RegisteredStatusNotifierItems" type="as" access="read"> <property name="RegisteredStatusNotifierItems" type="as" access="read">
<annotation name="org.gtk.GDBus.C.Name" value="RegisteredItems" />
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QStringList"/> <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QStringList"/>
</property> </property>
<property name="IsStatusNotifierHostRegistered" type="b" access="read"/> <property name="IsStatusNotifierHostRegistered" type="b" access="read">
<annotation name="org.gtk.GDBus.C.Name" value="IsHostRegistered" />
</property>
<property name="ProtocolVersion" type="i" access="read"/> <property name="ProtocolVersion" type="i" access="read"/>
@ -26,17 +32,21 @@
<!-- signals --> <!-- signals -->
<signal name="StatusNotifierItemRegistered"> <signal name="StatusNotifierItemRegistered">
<arg type="s"/> <annotation name="org.gtk.GDBus.C.Name" value="ItemRegistered" />
<arg type="s" direction="out" name="service" />
</signal> </signal>
<signal name="StatusNotifierItemUnregistered"> <signal name="StatusNotifierItemUnregistered">
<arg type="s"/> <annotation name="org.gtk.GDBus.C.Name" value="ItemUnregistered" />
<arg type="s" direction="out" name="service" />
</signal> </signal>
<signal name="StatusNotifierHostRegistered"> <signal name="StatusNotifierHostRegistered">
<annotation name="org.gtk.GDBus.C.Name" value="HostRegistered" />
</signal> </signal>
<signal name="StatusNotifierHostUnregistered"> <signal name="StatusNotifierHostUnregistered">
<annotation name="org.gtk.GDBus.C.Name" value="HostUnregistered" />
</signal> </signal>
</interface> </interface>
</node> </node>

View File

@ -62,7 +62,7 @@ client_protos_headers += gdbus_header.process('./dbus-menu.xml')
lib_client_protos = static_library( lib_client_protos = static_library(
'client_protos', 'client_protos',
client_protos_src + client_protos_headers, client_protos_src + client_protos_headers,
dependencies: [wayland_client, gtkmm], dependencies: [wayland_client, gtkmm, giounix],
include_directories: include_directories('..'), include_directories: include_directories('..'),
) # for the include directory ) # for the include directory

View File

@ -26,6 +26,10 @@
"sway/window": { "sway/window": {
"max-length": 50 "max-length": 50
}, },
"tray": {
// "icon-size": 21,
"spacing": 10
},
"clock": { "clock": {
"format-alt": "{:%Y-%m-%d}" "format-alt": "{:%Y-%m-%d}"
}, },

View File

@ -4,15 +4,15 @@
waybar::ALabel::ALabel(const Json::Value& config, const std::string format) waybar::ALabel::ALabel(const Json::Value& config, const std::string format)
: config_(config), : config_(config),
format_(config_["format"] ? config_["format"].asString() : format), format_(config_["format"].isString() ? config_["format"].asString() : format),
default_format_(format_) default_format_(format_)
{ {
event_box_.add(label_); event_box_.add(label_);
if (config_["max-length"]) { if (config_["max-length"].isUInt()) {
label_.set_max_width_chars(config_["max-length"].asUInt()); label_.set_max_width_chars(config_["max-length"].asUInt());
label_.set_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END); label_.set_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END);
} }
if (config_["format-alt"]) { if (config_["format-alt"].isString()) {
event_box_.add_events(Gdk::BUTTON_PRESS_MASK); event_box_.add_events(Gdk::BUTTON_PRESS_MASK);
event_box_.signal_button_press_event() event_box_.signal_button_press_event()
.connect(sigc::mem_fun(*this, &ALabel::handleToggle)); .connect(sigc::mem_fun(*this, &ALabel::handleToggle));
@ -40,7 +40,7 @@ std::string waybar::ALabel::getIcon(uint16_t percentage, const std::string& alt)
{ {
auto format_icons = config_["format-icons"]; auto format_icons = config_["format-icons"];
if (format_icons.isObject()) { if (format_icons.isObject()) {
if (!alt.empty() && format_icons[alt]) { if (!alt.empty() && format_icons[alt].isString()) {
format_icons = format_icons[alt]; format_icons = format_icons[alt];
} else { } else {
format_icons = format_icons["default"]; format_icons = format_icons["default"];

View File

@ -53,8 +53,8 @@ waybar::Bar::Bar(const Client& client,
anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
} }
auto height = config_["height"] ? config_["height"].asUInt() : height_; auto height = config_["height"].isUInt() ? config_["height"].asUInt() : height_;
auto width = config_["width"] ? config_["width"].asUInt() : width_; auto width = config_["width"].isUInt() ? config_["width"].asUInt() : width_;
zwlr_layer_surface_v1_set_anchor(layer_surface, anchor); zwlr_layer_surface_v1_set_anchor(layer_surface, anchor);
zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, height); zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, height);
zwlr_layer_surface_v1_set_size(layer_surface, width, height); zwlr_layer_surface_v1_set_size(layer_surface, width, height);
@ -163,7 +163,7 @@ auto waybar::Bar::setupCss() -> void
void waybar::Bar::getModules(const Factory& factory, const std::string& pos) void waybar::Bar::getModules(const Factory& factory, const std::string& pos)
{ {
if (config_[pos]) { if (config_[pos].isArray()) {
for (const auto &name : config_[pos]) { for (const auto &name : config_[pos]) {
try { try {
auto module = factory.makeModule(name.asString()); auto module = factory.makeModule(name.asString());

View File

@ -4,7 +4,7 @@ waybar::modules::Battery::Battery(const Json::Value& config)
: ALabel(config, "{capacity}%") : ALabel(config, "{capacity}%")
{ {
try { try {
if (config_["bat"]) { if (config_["bat"].isString()) {
auto dir = data_dir_ / config_["bat"].asString(); auto dir = data_dir_ / config_["bat"].asString();
if (fs::is_directory(dir) && fs::exists(dir / "capacity") if (fs::is_directory(dir) && fs::exists(dir / "capacity")
&& fs::exists(dir / "status") && fs::exists(dir / "uevent")) { && fs::exists(dir / "status") && fs::exists(dir / "uevent")) {
@ -22,7 +22,7 @@ waybar::modules::Battery::Battery(const Json::Value& config)
throw std::runtime_error(e.what()); throw std::runtime_error(e.what());
} }
if (batteries_.empty()) { if (batteries_.empty()) {
if (config_["bat"]) { if (config_["bat"].isString()) {
throw std::runtime_error("No battery named " + config_["bat"].asString()); throw std::runtime_error("No battery named " + config_["bat"].asString());
} }
throw std::runtime_error("No batteries."); throw std::runtime_error("No batteries.");
@ -47,7 +47,7 @@ void waybar::modules::Battery::worker()
{ {
// Trigger first values // Trigger first values
update(); update();
uint32_t interval = config_["interval"] ? config_["interval"].asUInt() : 60; uint32_t interval = config_["interval"].isUInt() ? config_["interval"].asUInt() : 60;
threadTimer_ = [this, interval] { threadTimer_ = [this, interval] {
thread_.sleep_for(chrono::seconds(interval)); thread_.sleep_for(chrono::seconds(interval));
dp.emit(); dp.emit();
@ -88,7 +88,7 @@ auto waybar::modules::Battery::update() -> void
} else { } else {
label_.get_style_context()->remove_class("charging"); label_.get_style_context()->remove_class("charging");
} }
auto critical = config_["critical"] ? config_["critical"].asUInt() : 15; auto critical = config_["critical"].isUInt() ? config_["critical"].asUInt() : 15;
if (capacity <= critical && !charging) { if (capacity <= critical && !charging) {
label_.get_style_context()->add_class("warning"); label_.get_style_context()->add_class("warning");
} else { } else {

View File

@ -4,7 +4,7 @@ waybar::modules::Clock::Clock(const Json::Value& config)
: ALabel(config, "{:%H:%M}") : ALabel(config, "{:%H:%M}")
{ {
label_.set_name("clock"); label_.set_name("clock");
uint32_t interval = config_["interval"] ? config_["interval"].asUInt() : 60; uint32_t interval = config_["interval"].isUInt() ? config_["interval"].asUInt() : 60;
thread_ = [this, interval] { thread_ = [this, interval] {
auto now = waybar::chrono::clock::now(); auto now = waybar::chrono::clock::now();
dp.emit(); dp.emit();

View File

@ -4,7 +4,7 @@ waybar::modules::Cpu::Cpu(const Json::Value& config)
: ALabel(config, "{}%") : ALabel(config, "{}%")
{ {
label_.set_name("cpu"); label_.set_name("cpu");
uint32_t interval = config_["interval"] ? config_["interval"].asUInt() : 10; uint32_t interval = config_["interval"].isUInt() ? config_["interval"].asUInt() : 10;
thread_ = [this, interval] { thread_ = [this, interval] {
dp.emit(); dp.emit();
thread_.sleep_for(chrono::seconds(interval)); thread_.sleep_for(chrono::seconds(interval));

View File

@ -4,10 +4,10 @@ waybar::modules::Custom::Custom(const std::string name,
const Json::Value& config) const Json::Value& config)
: ALabel(config, "{}"), name_(name) : ALabel(config, "{}"), name_(name)
{ {
if (!config_["exec"]) { if (!config_["exec"].isString()) {
throw std::runtime_error(name_ + " has no exec path."); throw std::runtime_error(name_ + " has no exec path.");
} }
if (config_["interval"]) { if (config_["interval"].isUInt()) {
delayWorker(); delayWorker();
} else { } else {
continuousWorker(); continuousWorker();
@ -19,7 +19,7 @@ void waybar::modules::Custom::delayWorker()
auto interval = config_["interval"].asUInt(); auto interval = config_["interval"].asUInt();
thread_ = [this, interval] { thread_ = [this, interval] {
bool can_update = true; bool can_update = true;
if (config_["exec-if"]) { if (config_["exec-if"].isString()) {
auto res = waybar::util::command::exec(config_["exec-if"].asString()); auto res = waybar::util::command::exec(config_["exec-if"].asString());
if (res.exit_code != 0) { if (res.exit_code != 0) {
can_update = false; can_update = false;

View File

@ -4,7 +4,7 @@ waybar::modules::Memory::Memory(const Json::Value& config)
: ALabel(config, "{}%") : ALabel(config, "{}%")
{ {
label_.set_name("memory"); label_.set_name("memory");
uint32_t interval = config_["interval"] ? config_["interval"].asUInt() : 30; uint32_t interval = config_["interval"].isUInt() ? config_["interval"].asUInt() : 30;
thread_ = [this, interval] { thread_ = [this, interval] {
dp.emit(); dp.emit();
thread_.sleep_for(chrono::seconds(interval)); thread_.sleep_for(chrono::seconds(interval));

View File

@ -14,7 +14,7 @@ waybar::modules::Network::Network(const Json::Value& config)
sizeof(nladdr_)) != 0) { sizeof(nladdr_)) != 0) {
throw std::runtime_error("Can't bind network socket"); throw std::runtime_error("Can't bind network socket");
} }
if (config_["interface"]) { if (config_["interface"].isString()) {
ifid_ = if_nametoindex(config_["interface"].asCString()); ifid_ = if_nametoindex(config_["interface"].asCString());
ifname_ = config_["interface"].asString(); ifname_ = config_["interface"].asString();
if (ifid_ <= 0) { if (ifid_ <= 0) {
@ -56,7 +56,7 @@ waybar::modules::Network::Network(const Json::Value& config)
} }
} }
} }
if (ifid_ <= 0 && !config_["interface"]) { if (ifid_ <= 0 && !config_["interface"].isString()) {
// Need to wait before get external interface // Need to wait before get external interface
thread_.sleep_for(std::chrono::seconds(1)); thread_.sleep_for(std::chrono::seconds(1));
ifid_ = getExternalInterface(); ifid_ = getExternalInterface();
@ -84,15 +84,15 @@ auto waybar::modules::Network::update() -> void
{ {
auto format = format_; auto format = format_;
if (ifid_ <= 0) { if (ifid_ <= 0) {
format = config_["format-disconnected"] format = config_["format-disconnected"].isString()
? config_["format-disconnected"].asString() : format; ? config_["format-disconnected"].asString() : format;
label_.get_style_context()->add_class("disconnected"); label_.get_style_context()->add_class("disconnected");
} else { } else {
if (essid_.empty()) { if (essid_.empty()) {
format = config_["format-ethernet"] format = config_["format-ethernet"].isString()
? config_["format-ethernet"].asString() : format; ? config_["format-ethernet"].asString() : format;
} else { } else {
format = config_["format-wifi"] format = config_["format-wifi"].isString()
? config_["format-wifi"].asString() : format; ? config_["format-wifi"].asString() : format;
} }
label_.get_style_context()->remove_class("disconnected"); label_.get_style_context()->remove_class("disconnected");

View File

@ -89,7 +89,7 @@ void waybar::modules::Pulseaudio::sinkInfoCb(pa_context* /*context*/,
pa->volume_ = std::round(volume * 100.0f); pa->volume_ = std::round(volume * 100.0f);
pa->muted_ = i->mute != 0; pa->muted_ = i->mute != 0;
pa->desc_ = i->description; pa->desc_ = i->description;
pa->port_name_ = i->active_port->name; pa->port_name_ = i->active_port ? i->active_port->name : "Unknown";
pa->dp.emit(); pa->dp.emit();
} }
} }
@ -131,10 +131,10 @@ auto waybar::modules::Pulseaudio::update() -> void
auto format = format_; auto format = format_;
if (muted_) { if (muted_) {
format = format =
config_["format-muted"] ? config_["format-muted"].asString() : format; config_["format-muted"].isString() ? config_["format-muted"].asString() : format;
label_.get_style_context()->add_class("muted"); label_.get_style_context()->add_class("muted");
} else if (port_name_.find("a2dp_sink") != std::string::npos) { } else if (port_name_.find("a2dp_sink") != std::string::npos) {
format = config_["format-bluetooth"] format = config_["format-bluetooth"].isString()
? config_["format-bluetooth"].asString() : format; ? config_["format-bluetooth"].asString() : format;
label_.get_style_context()->add_class("bluetooth"); label_.get_style_context()->add_class("bluetooth");
} else { } else {

View File

@ -4,8 +4,8 @@
using namespace waybar::modules::SNI; using namespace waybar::modules::SNI;
Host::Host(Glib::Dispatcher* dp) Host::Host(Glib::Dispatcher* dp, const Json::Value &config)
: dp_(dp) : dp_(dp), config_(config)
{ {
GBusNameOwnerFlags flags = static_cast<GBusNameOwnerFlags>( GBusNameOwnerFlags flags = static_cast<GBusNameOwnerFlags>(
G_BUS_NAME_OWNER_FLAGS_NONE); G_BUS_NAME_OWNER_FLAGS_NONE);
@ -35,7 +35,7 @@ void Host::nameAppeared(GDBusConnection* connection,
// TODO // TODO
} }
host->cancellable_ = g_cancellable_new(); host->cancellable_ = g_cancellable_new();
sn_org_kde_status_notifier_watcher_proxy_new( sn_watcher_proxy_new(
connection, connection,
G_DBUS_PROXY_FLAGS_NONE, G_DBUS_PROXY_FLAGS_NONE,
"org.kde.StatusNotifierWatcher", "org.kde.StatusNotifierWatcher",
@ -57,8 +57,7 @@ void Host::proxyReady(GObject* src, GAsyncResult* res,
gpointer data) gpointer data)
{ {
GError* error = nullptr; GError* error = nullptr;
SnOrgKdeStatusNotifierWatcher* watcher = SnWatcher* watcher = sn_watcher_proxy_new_finish(res, &error);
sn_org_kde_status_notifier_watcher_proxy_new_finish(res, &error);
if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
std::cerr << error->message << std::endl; std::cerr << error->message << std::endl;
g_error_free(error); g_error_free(error);
@ -71,7 +70,7 @@ void Host::proxyReady(GObject* src, GAsyncResult* res,
g_error_free(error); g_error_free(error);
return; return;
} }
sn_org_kde_status_notifier_watcher_call_register_status_notifier_host( sn_watcher_call_register_host(
host->watcher_, host->object_path_.c_str(), host->cancellable_, host->watcher_, host->object_path_.c_str(), host->cancellable_,
&Host::registerHost, data); &Host::registerHost, data);
} }
@ -80,8 +79,7 @@ void Host::registerHost(GObject* src, GAsyncResult* res,
gpointer data) gpointer data)
{ {
GError* error = nullptr; GError* error = nullptr;
sn_org_kde_status_notifier_watcher_call_register_status_notifier_host_finish( sn_watcher_call_register_host_finish(SN_WATCHER(src), res, &error);
SN_ORG_KDE_STATUS_NOTIFIER_WATCHER(src), res, &error);
if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
std::cerr << error->message << std::endl; std::cerr << error->message << std::endl;
g_error_free(error); g_error_free(error);
@ -93,12 +91,11 @@ void Host::registerHost(GObject* src, GAsyncResult* res,
g_error_free(error); g_error_free(error);
return; return;
} }
g_signal_connect(host->watcher_, "status-notifier-item-registered", g_signal_connect(host->watcher_, "item-registered",
G_CALLBACK(&Host::itemRegistered), data); G_CALLBACK(&Host::itemRegistered), data);
g_signal_connect(host->watcher_, "status-notifier-item-unregistered", g_signal_connect(host->watcher_, "item-unregistered",
G_CALLBACK(&Host::itemUnregistered), data); G_CALLBACK(&Host::itemUnregistered), data);
auto items = auto items = sn_watcher_dup_registered_items(host->watcher_);
sn_org_kde_status_notifier_watcher_dup_registered_status_notifier_items(host->watcher_);
if (items) { if (items) {
for (uint32_t i = 0; items[i] != nullptr; i += 1) { for (uint32_t i = 0; items[i] != nullptr; i += 1) {
host->addRegisteredItem(items[i]); host->addRegisteredItem(items[i]);
@ -108,14 +105,14 @@ void Host::registerHost(GObject* src, GAsyncResult* res,
} }
void Host::itemRegistered( void Host::itemRegistered(
SnOrgKdeStatusNotifierWatcher* watcher, const gchar* service, gpointer data) SnWatcher* watcher, const gchar* service, gpointer data)
{ {
auto host = static_cast<SNI::Host *>(data); auto host = static_cast<SNI::Host *>(data);
host->addRegisteredItem(service); host->addRegisteredItem(service);
} }
void Host::itemUnregistered( void Host::itemUnregistered(
SnOrgKdeStatusNotifierWatcher* watcher, const gchar* service, gpointer data) SnWatcher* watcher, const gchar* service, gpointer data)
{ {
auto host = static_cast<SNI::Host *>(data); auto host = static_cast<SNI::Host *>(data);
auto [bus_name, object_path] = host->getBusNameAndObjectPath(service); auto [bus_name, object_path] = host->getBusNameAndObjectPath(service);
@ -149,5 +146,5 @@ std::tuple<std::string, std::string> Host::getBusNameAndObjectPath(
void Host::addRegisteredItem(const gchar* service) void Host::addRegisteredItem(const gchar* service)
{ {
auto [bus_name, object_path] = getBusNameAndObjectPath(service); auto [bus_name, object_path] = getBusNameAndObjectPath(service);
items.emplace_back(bus_name, object_path, dp_); items.emplace_back(bus_name, object_path, dp_, config_);
} }

View File

@ -4,15 +4,19 @@
#include <libdbusmenu-gtk/dbusmenu-gtk.h> #include <libdbusmenu-gtk/dbusmenu-gtk.h>
waybar::modules::SNI::Item::Item(std::string bn, std::string op, waybar::modules::SNI::Item::Item(std::string bn, std::string op,
Glib::Dispatcher *dp) Glib::Dispatcher *dp, Json::Value config)
: bus_name(bn), object_path(op), event_box(), icon_size(16), : bus_name(bn), object_path(op), event_box(), icon_size(16),
effective_icon_size(0), image(Gtk::manage(new Gtk::Image())), dp_(dp) { effective_icon_size(0), image(Gtk::manage(new Gtk::Image())),
dp_(dp), config_(config) {
if (config_["icon-size"].isUInt()) {
icon_size = config_["icon-size"].asUInt();
}
event_box.add(*image); event_box.add(*image);
event_box.add_events(Gdk::BUTTON_PRESS_MASK); event_box.add_events(Gdk::BUTTON_PRESS_MASK);
event_box.signal_button_press_event().connect( event_box.signal_button_press_event().connect(
sigc::mem_fun(*this, &Item::handleClick)); sigc::mem_fun(*this, &Item::handleClick));
cancellable_ = g_cancellable_new(); cancellable_ = g_cancellable_new();
sn_org_kde_status_notifier_item_proxy_new_for_bus( sn_item_proxy_new_for_bus(
G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, bus_name.c_str(), G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, bus_name.c_str(),
object_path.c_str(), cancellable_, &Item::proxyReady, this); object_path.c_str(), cancellable_, &Item::proxyReady, this);
} }
@ -20,8 +24,7 @@ waybar::modules::SNI::Item::Item(std::string bn, std::string op,
void waybar::modules::SNI::Item::proxyReady(GObject *obj, GAsyncResult *res, void waybar::modules::SNI::Item::proxyReady(GObject *obj, GAsyncResult *res,
gpointer data) { gpointer data) {
GError *error = nullptr; GError *error = nullptr;
SnOrgKdeStatusNotifierItem *proxy = SnItem *proxy = sn_item_proxy_new_for_bus_finish(res, &error);
sn_org_kde_status_notifier_item_proxy_new_for_bus_finish(res, &error);
if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
g_error_free(error); g_error_free(error);
return; return;
@ -113,6 +116,7 @@ void waybar::modules::SNI::Item::getAll(GObject *obj, GAsyncResult *res,
item->icon_theme_path.c_str()); item->icon_theme_path.c_str());
} }
item->updateImage(); item->updateImage();
item->updateMenu();
item->dp_->emit(); item->dp_->emit();
// TODO: handle change // TODO: handle change
} }
@ -165,45 +169,50 @@ waybar::modules::SNI::Item::extractPixBuf(GVariant *variant) {
return Glib::RefPtr<Gdk::Pixbuf>{}; return Glib::RefPtr<Gdk::Pixbuf>{};
} }
void waybar::modules::SNI::Item::updateMenu()
{
event_box.set_tooltip_text(title);
if (!menu.empty()) {
auto *dbmenu = dbusmenu_gtkmenu_new(bus_name.data(), menu.data());
if (dbmenu) {
gtk_menu = Glib::wrap(GTK_MENU(dbmenu), false);
}
}
}
void waybar::modules::SNI::Item::updateImage() void waybar::modules::SNI::Item::updateImage()
{ {
image->set_from_icon_name("image-missing", Gtk::ICON_SIZE_MENU);
image->set_pixel_size(icon_size);
if (!icon_name.empty()) { if (!icon_name.empty()) {
auto pixbuf = getIconByName(icon_name, icon_size);
if (pixbuf->gobj() == nullptr) {
// Try to find icons specified by path and filename
try { try {
pixbuf = Gdk::Pixbuf::create_from_file(icon_name); // Try to find icons specified by path and filename
if (std::filesystem::exists(icon_name)) {
auto pixbuf = Gdk::Pixbuf::create_from_file(icon_name);
if (pixbuf->gobj() != nullptr) { if (pixbuf->gobj() != nullptr) {
// An icon specified by path and filename may be the wrong size for // An icon specified by path and filename may be the wrong size for
// the tray // the tray
pixbuf->scale_simple(icon_size - 2, icon_size - 2, pixbuf = pixbuf->scale_simple(icon_size, icon_size,
Gdk::InterpType::INTERP_BILINEAR); Gdk::InterpType::INTERP_BILINEAR);
image->set(pixbuf);
}
} else {
image->set(getIconByName(icon_name, icon_size));
} }
} catch (Glib::Error &e) { } catch (Glib::Error &e) {
std::cerr << "Exception: " << e.what() << std::endl; std::cerr << "Exception: " << e.what() << std::endl;
pixbuf = getIconByName("image-missing", icon_size);
} }
}
if (pixbuf->gobj() == nullptr) {
pixbuf = getIconByName("image-missing", icon_size);
}
image->set(pixbuf);
} else if (icon_pixmap) { } else if (icon_pixmap) {
// An icon extracted may be the wrong size for the tray
icon_pixmap = icon_pixmap->scale_simple(icon_size, icon_size,
Gdk::InterpType::INTERP_BILINEAR);
image->set(icon_pixmap); image->set(icon_pixmap);
} else {
image->set_from_icon_name("image-missing", Gtk::ICON_SIZE_MENU);
image->set_pixel_size(icon_size);
}
if (!menu.empty()) {
auto *dbmenu = dbusmenu_gtkmenu_new(bus_name.data(), menu.data());
if (dbmenu)
gtk_menu = Glib::wrap(GTK_MENU(dbmenu), false);
} }
} }
Glib::RefPtr<Gdk::Pixbuf> Glib::RefPtr<Gdk::Pixbuf>
waybar::modules::SNI::Item::getIconByName(std::string name, int request_size) { waybar::modules::SNI::Item::getIconByName(std::string name, int request_size) {
int icon_size = 0; int tmp_size = 0;
Glib::RefPtr<Gtk::IconTheme> icon_theme = Gtk::IconTheme::get_default(); Glib::RefPtr<Gtk::IconTheme> icon_theme = Gtk::IconTheme::get_default();
icon_theme->rescan_if_needed(); icon_theme->rescan_if_needed();
auto sizes = icon_theme->get_icon_sizes(name.c_str()); auto sizes = icon_theme->get_icon_sizes(name.c_str());
@ -211,32 +220,30 @@ waybar::modules::SNI::Item::getIconByName(std::string name, int request_size) {
for (auto const &size : sizes) { for (auto const &size : sizes) {
// -1 == scalable // -1 == scalable
if (size == request_size || size == -1) { if (size == request_size || size == -1) {
icon_size = request_size; tmp_size = request_size;
break; break;
} else if (size < request_size || size > icon_size) { } else if (size < request_size || size > tmp_size) {
icon_size = size; tmp_size = size;
} }
} }
if (icon_size == 0) { if (tmp_size == 0) {
icon_size = request_size; tmp_size = request_size;
} }
return icon_theme->load_icon(name.c_str(), icon_size, return icon_theme->load_icon(name.c_str(), tmp_size,
Gtk::IconLookupFlags::ICON_LOOKUP_FORCE_SIZE); Gtk::IconLookupFlags::ICON_LOOKUP_FORCE_SIZE);
} }
void waybar::modules::SNI::Item::handleActivate(GObject *src, GAsyncResult *res, void waybar::modules::SNI::Item::handleActivate(GObject *src, GAsyncResult *res,
gpointer data) { gpointer data) {
auto item = static_cast<SNI::Item *>(data); auto item = static_cast<SNI::Item *>(data);
sn_org_kde_status_notifier_item_call_activate_finish(item->proxy_, res, sn_item_call_activate_finish(item->proxy_, res, nullptr);
nullptr);
} }
void waybar::modules::SNI::Item::handleSecondaryActivate(GObject *src, void waybar::modules::SNI::Item::handleSecondaryActivate(GObject *src,
GAsyncResult *res, GAsyncResult *res,
gpointer data) { gpointer data) {
auto item = static_cast<SNI::Item *>(data); auto item = static_cast<SNI::Item *>(data);
sn_org_kde_status_notifier_item_call_secondary_activate_finish(item->proxy_, sn_item_call_secondary_activate_finish(item->proxy_, res, nullptr);
res, nullptr);
} }
bool waybar::modules::SNI::Item::handleClick(GdkEventButton *const &ev) { bool waybar::modules::SNI::Item::handleClick(GdkEventButton *const &ev) {
@ -247,11 +254,11 @@ bool waybar::modules::SNI::Item::handleClick(GdkEventButton *const &ev) {
} }
gtk_menu->popup(ev->button, ev->time); gtk_menu->popup(ev->button, ev->time);
} else { } else {
sn_org_kde_status_notifier_item_call_activate( sn_item_call_activate(
proxy_, ev->x, ev->y, nullptr, &Item::handleActivate, this); proxy_, ev->x, ev->y, nullptr, &Item::handleActivate, this);
} }
} else if (ev->type == GDK_2BUTTON_PRESS) { } else if (ev->type == GDK_2BUTTON_PRESS) {
sn_org_kde_status_notifier_item_call_secondary_activate( sn_item_call_secondary_activate(
proxy_, ev->x, ev->y, nullptr, &Item::handleSecondaryActivate, this); proxy_, ev->x, ev->y, nullptr, &Item::handleSecondaryActivate, this);
} else { } else {
return false; return false;

View File

@ -12,7 +12,8 @@ Watcher::Watcher()
bus_name_id_ = g_bus_own_name(G_BUS_TYPE_SESSION, bus_name_id_ = g_bus_own_name(G_BUS_TYPE_SESSION,
"org.kde.StatusNotifierWatcher", flags, "org.kde.StatusNotifierWatcher", flags,
&Watcher::busAcquired, nullptr, nullptr, this, nullptr); &Watcher::busAcquired, nullptr, nullptr, this, nullptr);
watcher_ = sn_org_kde_status_notifier_watcher_skeleton_new(); watcher_ = sn_watcher_skeleton_new();
sn_watcher_set_protocol_version(watcher_, 1);
} }
Watcher::~Watcher() Watcher::~Watcher()
@ -31,15 +32,10 @@ void Watcher::busAcquired(GDBusConnection* connection, const gchar* name,
g_error_free(error); g_error_free(error);
return; return;
} }
g_signal_connect_swapped(host->watcher_, g_signal_connect_swapped(host->watcher_, "handle-register-item",
"handle-register-status-notifier-item",
G_CALLBACK(&Watcher::handleRegisterItem), data); G_CALLBACK(&Watcher::handleRegisterItem), data);
g_signal_connect_swapped(host->watcher_, g_signal_connect_swapped(host->watcher_, "handle-register-host",
"handle-register-status-notifier-host",
G_CALLBACK(&Watcher::handleRegisterHost), data); G_CALLBACK(&Watcher::handleRegisterHost), data);
sn_org_kde_status_notifier_watcher_set_protocol_version(host->watcher_, 0);
sn_org_kde_status_notifier_watcher_set_is_status_notifier_host_registered(
host->watcher_, TRUE);
} }
gboolean Watcher::handleRegisterHost(Watcher* obj, gboolean Watcher::handleRegisterHost(Watcher* obj,
@ -66,14 +62,11 @@ gboolean Watcher::handleRegisterHost(Watcher* obj,
} }
watch = gfWatchNew(GF_WATCH_TYPE_HOST, service, bus_name, object_path, obj); watch = gfWatchNew(GF_WATCH_TYPE_HOST, service, bus_name, object_path, obj);
obj->hosts_ = g_slist_prepend(obj->hosts_, watch); obj->hosts_ = g_slist_prepend(obj->hosts_, watch);
sn_org_kde_status_notifier_watcher_set_is_status_notifier_host_registered( if (!sn_watcher_get_is_host_registered(obj->watcher_)) {
obj->watcher_, TRUE); sn_watcher_set_is_host_registered(obj->watcher_, TRUE);
if (g_slist_length(obj->hosts_)) { sn_watcher_emit_host_registered(obj->watcher_);
sn_org_kde_status_notifier_watcher_emit_status_notifier_host_registered(
obj->watcher_);
} }
sn_org_kde_status_notifier_watcher_complete_register_status_notifier_host( sn_watcher_complete_register_host(obj->watcher_, invocation);
obj->watcher_, invocation);
return TRUE; return TRUE;
} }
@ -96,19 +89,16 @@ gboolean Watcher::handleRegisterItem(Watcher* obj,
if (watch != nullptr) { if (watch != nullptr) {
g_warning("Status Notifier Item with bus name '%s' and object path '%s' is already registered", g_warning("Status Notifier Item with bus name '%s' and object path '%s' is already registered",
bus_name, object_path); bus_name, object_path);
sn_org_kde_status_notifier_watcher_complete_register_status_notifier_item( sn_watcher_complete_register_item(obj->watcher_, invocation);
obj->watcher_, invocation);
return TRUE; return TRUE;
} }
watch = gfWatchNew(GF_WATCH_TYPE_ITEM, service, bus_name, object_path, obj); watch = gfWatchNew(GF_WATCH_TYPE_ITEM, service, bus_name, object_path, obj);
obj->items_ = g_slist_prepend(obj->items_, watch); obj->items_ = g_slist_prepend(obj->items_, watch);
obj->updateRegisteredItems(obj->watcher_); obj->updateRegisteredItems(obj->watcher_);
gchar* tmp = g_strdup_printf("%s%s", bus_name, object_path); gchar* tmp = g_strdup_printf("%s%s", bus_name, object_path);
sn_org_kde_status_notifier_watcher_emit_status_notifier_item_registered( sn_watcher_emit_item_registered(obj->watcher_, tmp);
obj->watcher_, tmp);
g_free(tmp); g_free(tmp);
sn_org_kde_status_notifier_watcher_complete_register_status_notifier_item( sn_watcher_complete_register_item(obj->watcher_, invocation);
obj->watcher_, invocation);
return TRUE; return TRUE;
} }
@ -147,22 +137,19 @@ void Watcher::nameVanished(GDBusConnection* connection, const char* name,
if (watch->type == GF_WATCH_TYPE_HOST) { if (watch->type == GF_WATCH_TYPE_HOST) {
watch->watcher->hosts_ = g_slist_remove(watch->watcher->hosts_, watch); watch->watcher->hosts_ = g_slist_remove(watch->watcher->hosts_, watch);
if (watch->watcher->hosts_ == nullptr) { if (watch->watcher->hosts_ == nullptr) {
sn_org_kde_status_notifier_watcher_set_is_status_notifier_host_registered( sn_watcher_set_is_host_registered(watch->watcher->watcher_, FALSE);
watch->watcher->watcher_, FALSE); sn_watcher_emit_host_registered(watch->watcher->watcher_);
sn_org_kde_status_notifier_watcher_emit_status_notifier_host_registered(
watch->watcher->watcher_);
} }
} else if (watch->type == GF_WATCH_TYPE_ITEM) { } else if (watch->type == GF_WATCH_TYPE_ITEM) {
watch->watcher->items_ = g_slist_remove(watch->watcher->items_, watch); watch->watcher->items_ = g_slist_remove(watch->watcher->items_, watch);
watch->watcher->updateRegisteredItems(watch->watcher->watcher_); watch->watcher->updateRegisteredItems(watch->watcher->watcher_);
gchar* tmp = g_strdup_printf("%s%s", watch->bus_name, watch->object_path); gchar* tmp = g_strdup_printf("%s%s", watch->bus_name, watch->object_path);
sn_org_kde_status_notifier_watcher_emit_status_notifier_item_unregistered( sn_watcher_emit_item_unregistered(watch->watcher->watcher_, tmp);
watch->watcher->watcher_, tmp);
g_free(tmp); g_free(tmp);
} }
} }
void Watcher::updateRegisteredItems(SnOrgKdeStatusNotifierWatcher* obj) void Watcher::updateRegisteredItems(SnWatcher* obj)
{ {
GVariantBuilder builder; GVariantBuilder builder;
g_variant_builder_init(&builder, G_VARIANT_TYPE("as")); g_variant_builder_init(&builder, G_VARIANT_TYPE("as"));
@ -174,8 +161,7 @@ void Watcher::updateRegisteredItems(SnOrgKdeStatusNotifierWatcher* obj)
} }
GVariant* variant = g_variant_builder_end(&builder); GVariant* variant = g_variant_builder_end(&builder);
const gchar** items = g_variant_get_strv(variant, nullptr); const gchar** items = g_variant_get_strv(variant, nullptr);
sn_org_kde_status_notifier_watcher_set_registered_status_notifier_items( sn_watcher_set_registered_items(obj, items);
obj, items);
g_variant_unref(variant); g_variant_unref(variant);
g_free(items); g_free(items);
} }

View File

@ -3,11 +3,17 @@
#include <iostream> #include <iostream>
waybar::modules::SNI::Tray::Tray(const Json::Value &config) waybar::modules::SNI::Tray::Tray(const Json::Value &config)
: config_(config), watcher_(), host_(&dp) {} : config_(config), watcher_(), host_(&dp, config)
{
if (config_["spacing"].isUInt()) {
box_.set_spacing(config_["spacing"].asUInt());
}
}
auto waybar::modules::SNI::Tray::update() -> void { auto waybar::modules::SNI::Tray::update() -> void {
auto childrens = box_.get_children();
childrens.erase(childrens.begin(), childrens.end());
for (auto &item : host_.items) { for (auto &item : host_.items) {
item.event_box.set_tooltip_text(item.title);
box_.pack_start(item.event_box); box_.pack_start(item.event_box);
} }
if (box_.get_children().size() > 0) { if (box_.get_children().size() > 0) {
@ -18,4 +24,6 @@ auto waybar::modules::SNI::Tray::update() -> void {
} }
} }
waybar::modules::SNI::Tray::operator Gtk::Widget &() { return box_; } waybar::modules::SNI::Tray::operator Gtk::Widget &() {
return box_;
}

View File

@ -79,7 +79,7 @@ auto waybar::modules::sway::Workspaces::update() -> void
box_.reorder_child(button, node["num"].asInt()); box_.reorder_child(button, node["num"].asInt());
} }
auto icon = getIcon(node["name"].asString(), node); auto icon = getIcon(node["name"].asString(), node);
if (config_["format"]) { if (config_["format"].isString()) {
auto format = config_["format"].asString(); auto format = config_["format"].asString();
button.set_label(fmt::format(format, fmt::arg("icon", icon), button.set_label(fmt::format(format, fmt::arg("icon", icon),
fmt::arg("name", node["name"].asString()), fmt::arg("name", node["name"].asString()),
@ -98,7 +98,7 @@ auto waybar::modules::sway::Workspaces::update() -> void
void waybar::modules::sway::Workspaces::addWorkspace(Json::Value node) void waybar::modules::sway::Workspaces::addWorkspace(Json::Value node)
{ {
auto icon = getIcon(node["name"].asString(), node); auto icon = getIcon(node["name"].asString(), node);
auto format = config_["format"] auto format = config_["format"].isString()
? fmt::format(config_["format"].asString(), fmt::arg("icon", icon), ? fmt::format(config_["format"].asString(), fmt::arg("icon", icon),
fmt::arg("name", node["name"].asString()), fmt::arg("name", node["name"].asString()),
fmt::arg("index", node["num"].asString())) fmt::arg("index", node["num"].asString()))
@ -141,10 +141,10 @@ std::string waybar::modules::sway::Workspaces::getIcon(std::string name,
name, "urgent", "focused", "visible", "default"}; name, "urgent", "focused", "visible", "default"};
for (auto const& key : keys) { for (auto const& key : keys) {
if (key == "focused" || key == "visible" || key == "urgent") { if (key == "focused" || key == "visible" || key == "urgent") {
if (config_["format-icons"][key] && node[key].asBool()) { if (config_["format-icons"][key].isString() && node[key].asBool()) {
return config_["format-icons"][key].asString(); return config_["format-icons"][key].asString();
} }
} else if (config_["format-icons"][key]) { } else if (config_["format-icons"][key].isString()) {
return config_["format-icons"][key].asString(); return config_["format-icons"][key].asString();
} }
} }