Merge branch 'Alexays:master' into master

This commit is contained in:
Sonter
2024-09-13 11:31:22 +00:00
committed by GitHub
64 changed files with 1239 additions and 115 deletions

View File

@ -49,8 +49,8 @@ auto getBoolProperty(GDBusProxy* proxy, const char* property_name) -> bool {
return false;
}
auto getOptionalStringProperty(GDBusProxy* proxy, const char* property_name)
-> std::optional<std::string> {
auto getOptionalStringProperty(GDBusProxy* proxy,
const char* property_name) -> std::optional<std::string> {
auto gvar = g_dbus_proxy_get_cached_property(proxy, property_name);
if (gvar) {
std::string property_value = g_variant_get_string(gvar, NULL);
@ -345,8 +345,8 @@ auto waybar::modules::Bluetooth::onInterfaceAddedOrRemoved(GDBusObjectManager* m
auto waybar::modules::Bluetooth::onInterfaceProxyPropertiesChanged(
GDBusObjectManagerClient* manager, GDBusObjectProxy* object_proxy, GDBusProxy* interface_proxy,
GVariant* changed_properties, const gchar* const* invalidated_properties, gpointer user_data)
-> void {
GVariant* changed_properties, const gchar* const* invalidated_properties,
gpointer user_data) -> void {
std::string interface_name = g_dbus_proxy_get_interface_name(interface_proxy);
std::string object_path = g_dbus_object_get_object_path(G_DBUS_OBJECT(object_proxy));
@ -395,8 +395,8 @@ auto waybar::modules::Bluetooth::getDeviceBatteryPercentage(GDBusObject* object)
return std::nullopt;
}
auto waybar::modules::Bluetooth::getDeviceProperties(GDBusObject* object, DeviceInfo& device_info)
-> bool {
auto waybar::modules::Bluetooth::getDeviceProperties(GDBusObject* object,
DeviceInfo& device_info) -> bool {
GDBusProxy* proxy_device = G_DBUS_PROXY(g_dbus_object_get_interface(object, "org.bluez.Device1"));
if (proxy_device != NULL) {
@ -462,9 +462,8 @@ auto waybar::modules::Bluetooth::findCurController() -> std::optional<Controller
return controller_info;
}
auto waybar::modules::Bluetooth::findConnectedDevices(const std::string& cur_controller_path,
std::vector<DeviceInfo>& connected_devices)
-> void {
auto waybar::modules::Bluetooth::findConnectedDevices(
const std::string& cur_controller_path, std::vector<DeviceInfo>& connected_devices) -> void {
GList* objects = g_dbus_object_manager_get_objects(manager_.get());
for (GList* l = objects; l != NULL; l = l->next) {
GDBusObject* object = G_DBUS_OBJECT(l->data);

View File

@ -198,8 +198,8 @@ const unsigned cldRowsInMonth(const year_month& ym, const weekday& firstdow) {
return 2u + ceil<weeks>((weekday{ym / 1} - firstdow) + ((ym / last).day() - day{0})).count();
}
auto cldGetWeekForLine(const year_month& ym, const weekday& firstdow, const unsigned line)
-> const year_month_weekday {
auto cldGetWeekForLine(const year_month& ym, const weekday& firstdow,
const unsigned line) -> const year_month_weekday {
unsigned index{line - 2};
if (weekday{ym / 1} == firstdow) ++index;
return ym / firstdow[index];

View File

@ -53,8 +53,8 @@ static void set_layout(void *data, zdwl_ipc_output_v2 *zdwl_output_v2, uint32_t
// Intentionally empty
}
static void appid(void *data, zdwl_ipc_output_v2 *zdwl_output_v2, const char *appid){
// Intentionally empty
static void appid(void *data, zdwl_ipc_output_v2 *zdwl_output_v2, const char *appid) {
// Intentionally empty
};
static const zdwl_ipc_output_v2_listener output_status_listener_impl{

View File

@ -590,8 +590,8 @@ auto Workspaces::populateIconsMap(const Json::Value &formatIcons) -> void {
m_iconsMap.emplace("", "");
}
auto Workspaces::populateBoolConfig(const Json::Value &config, const std::string &key, bool &member)
-> void {
auto Workspaces::populateBoolConfig(const Json::Value &config, const std::string &key,
bool &member) -> void {
const auto &configValue = config[key];
if (configValue.isBool()) {
member = configValue.asBool();

View File

@ -42,7 +42,6 @@ void waybar::modules::Image::refresh(int sig) {
}
auto waybar::modules::Image::update() -> void {
Glib::RefPtr<Gdk::Pixbuf> pixbuf;
if (config_["path"].isString()) {
path_ = config_["path"].asString();
} else if (config_["exec"].isString()) {
@ -51,19 +50,24 @@ auto waybar::modules::Image::update() -> void {
} else {
path_ = "";
}
if (Glib::file_test(path_, Glib::FILE_TEST_EXISTS))
pixbuf = Gdk::Pixbuf::create_from_file(path_, size_, size_);
else
pixbuf = {};
if (pixbuf) {
if (Glib::file_test(path_, Glib::FILE_TEST_EXISTS)) {
Glib::RefPtr<Gdk::Pixbuf> pixbuf;
int scaled_icon_size = size_ * image_.get_scale_factor();
pixbuf = Gdk::Pixbuf::create_from_file(path_, scaled_icon_size, scaled_icon_size);
auto surface = Gdk::Cairo::create_surface_from_pixbuf(pixbuf, image_.get_scale_factor(),
image_.get_window());
image_.set(surface);
image_.show();
if (tooltipEnabled() && !tooltip_.empty()) {
if (box_.get_tooltip_markup() != tooltip_) {
box_.set_tooltip_markup(tooltip_);
}
}
image_.set(pixbuf);
image_.show();
box_.get_style_context()->remove_class("empty");
} else {
image_.clear();

View File

@ -21,13 +21,13 @@ static uint64_t get_total_memory() {
u_long physmem;
#endif
int mib[] = {
CTL_HW,
CTL_HW,
#if defined(HW_MEMSIZE)
HW_MEMSIZE,
HW_MEMSIZE,
#elif defined(HW_PHYSMEM64)
HW_PHYSMEM64,
HW_PHYSMEM64,
#else
HW_PHYSMEM,
HW_PHYSMEM,
#endif
};
u_int miblen = sizeof(mib) / sizeof(mib[0]);

View File

@ -0,0 +1,261 @@
#include "modules/niri/backend.hpp"
#include <netdb.h>
#include <netinet/in.h>
#include <spdlog/spdlog.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
#include <iostream>
#include <string>
#include <thread>
#include "giomm/datainputstream.h"
#include "giomm/dataoutputstream.h"
#include "giomm/unixinputstream.h"
#include "giomm/unixoutputstream.h"
namespace waybar::modules::niri {
int IPC::connectToSocket() {
const char *socket_path = getenv("NIRI_SOCKET");
if (socket_path == nullptr) {
spdlog::warn("Niri is not running, niri IPC will not be available.");
return -1;
}
struct sockaddr_un addr;
int socketfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (socketfd == -1) {
throw std::runtime_error("socketfd failed");
}
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
addr.sun_path[sizeof(addr.sun_path) - 1] = 0;
int l = sizeof(struct sockaddr_un);
if (connect(socketfd, (struct sockaddr *)&addr, l) == -1) {
close(socketfd);
throw std::runtime_error("unable to connect");
}
return socketfd;
}
void IPC::startIPC() {
// will start IPC and relay events to parseIPC
std::thread([&]() {
int socketfd;
try {
socketfd = connectToSocket();
} catch (std::exception &e) {
spdlog::error("Niri IPC: failed to start, reason: {}", e.what());
return;
}
if (socketfd == -1) return;
spdlog::info("Niri IPC starting");
auto unix_istream = Gio::UnixInputStream::create(socketfd, true);
auto unix_ostream = Gio::UnixOutputStream::create(socketfd, false);
auto istream = Gio::DataInputStream::create(unix_istream);
auto ostream = Gio::DataOutputStream::create(unix_ostream);
if (!ostream->put_string("\"EventStream\"\n") || !ostream->flush()) {
spdlog::error("Niri IPC: failed to start event stream");
return;
}
std::string line;
if (!istream->read_line(line) || line != R"({"Ok":"Handled"})") {
spdlog::error("Niri IPC: failed to start event stream");
return;
}
while (istream->read_line(line)) {
spdlog::debug("Niri IPC: received {}", line);
try {
parseIPC(line);
} catch (std::exception &e) {
spdlog::warn("Failed to parse IPC message: {}, reason: {}", line, e.what());
} catch (...) {
throw;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}).detach();
}
void IPC::parseIPC(const std::string &line) {
const auto ev = parser_.parse(line);
const auto members = ev.getMemberNames();
if (members.size() != 1) throw std::runtime_error("Event must have a single member");
{
auto lock = lockData();
if (const auto &payload = ev["WorkspacesChanged"]) {
workspaces_.clear();
const auto &values = payload["workspaces"];
std::copy(values.begin(), values.end(), std::back_inserter(workspaces_));
std::sort(workspaces_.begin(), workspaces_.end(), [](const auto &a, const auto &b) {
const auto &aOutput = a["output"].asString();
const auto &bOutput = b["output"].asString();
const auto aIdx = a["idx"].asUInt();
const auto bIdx = b["idx"].asUInt();
if (aOutput == bOutput) return aIdx < bIdx;
return aOutput < bOutput;
});
} else if (const auto &payload = ev["WorkspaceActivated"]) {
const auto id = payload["id"].asUInt64();
const auto focused = payload["focused"].asBool();
auto it = std::find_if(workspaces_.begin(), workspaces_.end(),
[id](const auto &ws) { return ws["id"].asUInt64() == id; });
if (it != workspaces_.end()) {
const auto &ws = *it;
const auto &output = ws["output"].asString();
for (auto &ws : workspaces_) {
const auto got_activated = (ws["id"].asUInt64() == id);
if (ws["output"] == output) ws["is_active"] = got_activated;
if (focused) ws["is_focused"] = got_activated;
}
} else {
spdlog::error("Activated unknown workspace");
}
} else if (const auto &payload = ev["WorkspaceActiveWindowChanged"]) {
const auto workspaceId = payload["workspace_id"].asUInt64();
auto it = std::find_if(workspaces_.begin(), workspaces_.end(), [workspaceId](const auto &ws) {
return ws["id"].asUInt64() == workspaceId;
});
if (it != workspaces_.end()) {
auto &ws = *it;
ws["active_window_id"] = payload["active_window_id"];
} else {
spdlog::error("Active window changed on unknown workspace");
}
} else if (const auto &payload = ev["KeyboardLayoutsChanged"]) {
const auto &layouts = payload["keyboard_layouts"];
const auto &names = layouts["names"];
keyboardLayoutCurrent_ = layouts["current_idx"].asUInt();
keyboardLayoutNames_.clear();
for (const auto &fullName : names) keyboardLayoutNames_.push_back(fullName.asString());
} else if (const auto &payload = ev["KeyboardLayoutSwitched"]) {
keyboardLayoutCurrent_ = payload["idx"].asUInt();
} else if (const auto &payload = ev["WindowsChanged"]) {
windows_.clear();
const auto &values = payload["windows"];
std::copy(values.begin(), values.end(), std::back_inserter(windows_));
} else if (const auto &payload = ev["WindowOpenedOrChanged"]) {
const auto &window = payload["window"];
const auto id = window["id"].asUInt64();
auto it = std::find_if(windows_.begin(), windows_.end(),
[id](const auto &win) { return win["id"].asUInt64() == id; });
if (it == windows_.end()) {
windows_.push_back(window);
if (window["is_focused"].asBool()) {
for (auto &win : windows_) {
win["is_focused"] = win["id"].asUInt64() == id;
}
}
} else {
*it = window;
}
} else if (const auto &payload = ev["WindowClosed"]) {
const auto id = payload["id"].asUInt64();
auto it = std::find_if(windows_.begin(), windows_.end(),
[id](const auto &win) { return win["id"].asUInt64() == id; });
if (it != windows_.end()) {
windows_.erase(it);
} else {
spdlog::error("Unknown window closed");
}
} else if (const auto &payload = ev["WindowFocusChanged"]) {
const auto focused = !payload["id"].isNull();
const auto id = payload["id"].asUInt64();
for (auto &win : windows_) {
win["is_focused"] = focused && win["id"].asUInt64() == id;
}
}
}
std::unique_lock lock(callbackMutex_);
for (auto &[eventname, handler] : callbacks_) {
if (eventname == members[0]) {
handler->onEvent(ev);
}
}
}
void IPC::registerForIPC(const std::string &ev, EventHandler *ev_handler) {
if (ev_handler == nullptr) {
return;
}
std::unique_lock lock(callbackMutex_);
callbacks_.emplace_back(ev, ev_handler);
}
void IPC::unregisterForIPC(EventHandler *ev_handler) {
if (ev_handler == nullptr) {
return;
}
std::unique_lock lock(callbackMutex_);
for (auto it = callbacks_.begin(); it != callbacks_.end();) {
auto &[eventname, handler] = *it;
if (handler == ev_handler) {
it = callbacks_.erase(it);
} else {
++it;
}
}
}
Json::Value IPC::send(const Json::Value &request) {
int socketfd = connectToSocket();
if (socketfd == -1) throw std::runtime_error("Niri is not running");
auto unix_istream = Gio::UnixInputStream::create(socketfd, true);
auto unix_ostream = Gio::UnixOutputStream::create(socketfd, false);
auto istream = Gio::DataInputStream::create(unix_istream);
auto ostream = Gio::DataOutputStream::create(unix_ostream);
// Niri needs the request on a single line.
Json::StreamWriterBuilder builder;
builder["indentation"] = "";
std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
std::ostringstream oss;
writer->write(request, &oss);
oss << '\n';
if (!ostream->put_string(oss.str()) || !ostream->flush())
throw std::runtime_error("error writing to niri socket");
std::string line;
if (!istream->read_line(line)) throw std::runtime_error("error reading from niri socket");
std::istringstream iss(std::move(line));
Json::Value response;
iss >> response;
return response;
}
} // namespace waybar::modules::niri

View File

@ -0,0 +1,136 @@
#include "modules/niri/language.hpp"
#include <spdlog/spdlog.h>
#include <xkbcommon/xkbcommon.h>
#include <xkbcommon/xkbregistry.h>
#include "util/string.hpp"
namespace waybar::modules::niri {
Language::Language(const std::string &id, const Bar &bar, const Json::Value &config)
: ALabel(config, "language", id, "{}", 0, true), bar_(bar) {
label_.hide();
if (!gIPC) gIPC = std::make_unique<IPC>();
gIPC->registerForIPC("KeyboardLayoutsChanged", this);
gIPC->registerForIPC("KeyboardLayoutSwitched", this);
updateFromIPC();
dp.emit();
}
Language::~Language() {
gIPC->unregisterForIPC(this);
// wait for possible event handler to finish
std::lock_guard<std::mutex> lock(mutex_);
}
void Language::updateFromIPC() {
std::lock_guard<std::mutex> lock(mutex_);
auto ipcLock = gIPC->lockData();
layouts_.clear();
for (const auto &fullName : gIPC->keyboardLayoutNames()) layouts_.push_back(getLayout(fullName));
current_idx_ = gIPC->keyboardLayoutCurrent();
}
/**
* Language::doUpdate - update workspaces in UI thread.
*
* Note: some member fields are modified by both UI thread and event listener thread, use mutex_ to
* protect these member fields, and lock should released before calling ALabel::update().
*/
void Language::doUpdate() {
std::lock_guard<std::mutex> lock(mutex_);
if (layouts_.size() <= current_idx_) {
spdlog::error("niri language layout index out of bounds");
label_.hide();
return;
}
const auto &layout = layouts_[current_idx_];
spdlog::debug("niri language update with full name {}", layout.full_name);
spdlog::debug("niri language update with short name {}", layout.short_name);
spdlog::debug("niri language update with short description {}", layout.short_description);
spdlog::debug("niri language update with variant {}", layout.variant);
std::string layoutName = std::string{};
if (config_.isMember("format-" + layout.short_description + "-" + layout.variant)) {
const auto propName = "format-" + layout.short_description + "-" + layout.variant;
layoutName = fmt::format(fmt::runtime(format_), config_[propName].asString());
} else if (config_.isMember("format-" + layout.short_description)) {
const auto propName = "format-" + layout.short_description;
layoutName = fmt::format(fmt::runtime(format_), config_[propName].asString());
} else {
layoutName = trim(fmt::format(fmt::runtime(format_), fmt::arg("long", layout.full_name),
fmt::arg("short", layout.short_name),
fmt::arg("shortDescription", layout.short_description),
fmt::arg("variant", layout.variant)));
}
spdlog::debug("niri language formatted layout name {}", layoutName);
if (!format_.empty()) {
label_.show();
label_.set_markup(layoutName);
} else {
label_.hide();
}
}
void Language::update() {
doUpdate();
ALabel::update();
}
void Language::onEvent(const Json::Value &ev) {
if (ev["KeyboardLayoutsChanged"]) {
updateFromIPC();
} else if (ev["KeyboardLayoutSwitched"]) {
std::lock_guard<std::mutex> lock(mutex_);
auto ipcLock = gIPC->lockData();
current_idx_ = gIPC->keyboardLayoutCurrent();
}
dp.emit();
}
Language::Layout Language::getLayout(const std::string &fullName) {
auto *const context = rxkb_context_new(RXKB_CONTEXT_LOAD_EXOTIC_RULES);
rxkb_context_parse_default_ruleset(context);
rxkb_layout *layout = rxkb_layout_first(context);
while (layout != nullptr) {
std::string nameOfLayout = rxkb_layout_get_description(layout);
if (nameOfLayout != fullName) {
layout = rxkb_layout_next(layout);
continue;
}
auto name = std::string(rxkb_layout_get_name(layout));
const auto *variantPtr = rxkb_layout_get_variant(layout);
std::string variant = variantPtr == nullptr ? "" : std::string(variantPtr);
const auto *descriptionPtr = rxkb_layout_get_brief(layout);
std::string description = descriptionPtr == nullptr ? "" : std::string(descriptionPtr);
Layout info = Layout{nameOfLayout, name, variant, description};
rxkb_context_unref(context);
return info;
}
rxkb_context_unref(context);
spdlog::debug("niri language didn't find matching layout for {}", fullName);
return Layout{"", "", "", ""};
}
} // namespace waybar::modules::niri

109
src/modules/niri/window.cpp Normal file
View File

@ -0,0 +1,109 @@
#include "modules/niri/window.hpp"
#include <gtkmm/button.h>
#include <gtkmm/label.h>
#include <spdlog/spdlog.h>
#include "util/rewrite_string.hpp"
#include "util/sanitize_str.hpp"
namespace waybar::modules::niri {
Window::Window(const std::string &id, const Bar &bar, const Json::Value &config)
: AAppIconLabel(config, "window", id, "{title}", 0, true), bar_(bar) {
if (!gIPC) gIPC = std::make_unique<IPC>();
gIPC->registerForIPC("WindowsChanged", this);
gIPC->registerForIPC("WindowOpenedOrChanged", this);
gIPC->registerForIPC("WindowClosed", this);
gIPC->registerForIPC("WindowFocusChanged", this);
dp.emit();
}
Window::~Window() { gIPC->unregisterForIPC(this); }
void Window::onEvent(const Json::Value &ev) { dp.emit(); }
void Window::doUpdate() {
auto ipcLock = gIPC->lockData();
const auto &windows = gIPC->windows();
const auto &workspaces = gIPC->workspaces();
const auto separateOutputs = config_["separate-outputs"].asBool();
const auto ws_it = std::find_if(workspaces.cbegin(), workspaces.cend(), [&](const auto &ws) {
if (separateOutputs) {
return ws["is_active"].asBool() && ws["output"].asString() == bar_.output->name;
}
return ws["is_focused"].asBool();
});
std::vector<Json::Value>::const_iterator it;
if (ws_it == workspaces.cend() || (*ws_it)["active_window_id"].isNull()) {
it = windows.cend();
} else {
const auto id = (*ws_it)["active_window_id"].asUInt64();
it = std::find_if(windows.cbegin(), windows.cend(),
[id](const auto &win) { return win["id"].asUInt64() == id; });
}
setClass("empty", ws_it == workspaces.cend() || (*ws_it)["active_window_id"].isNull());
if (it != windows.cend()) {
const auto &window = *it;
const auto title = window["title"].asString();
const auto appId = window["app_id"].asString();
const auto sanitizedTitle = waybar::util::sanitize_string(title);
const auto sanitizedAppId = waybar::util::sanitize_string(appId);
label_.show();
label_.set_markup(waybar::util::rewriteString(
fmt::format(fmt::runtime(format_), fmt::arg("title", sanitizedTitle),
fmt::arg("app_id", sanitizedAppId)),
config_["rewrite"]));
updateAppIconName(appId, "");
if (tooltipEnabled()) label_.set_tooltip_text(title);
const auto id = window["id"].asUInt64();
const auto workspaceId = window["workspace_id"].asUInt64();
const auto isSolo = std::none_of(windows.cbegin(), windows.cend(), [&](const auto &win) {
return win["id"].asUInt64() != id && win["workspace_id"].asUInt64() == workspaceId;
});
setClass("solo", isSolo);
if (!appId.empty()) setClass(appId, isSolo);
if (oldAppId_ != appId) {
if (!oldAppId_.empty()) setClass(oldAppId_, false);
oldAppId_ = appId;
}
} else {
label_.hide();
updateAppIconName("", "");
setClass("solo", false);
if (!oldAppId_.empty()) setClass(oldAppId_, false);
oldAppId_.clear();
}
}
void Window::update() {
doUpdate();
AAppIconLabel::update();
}
void Window::setClass(const std::string &className, bool enable) {
auto styleContext = bar_.window.get_style_context();
if (enable) {
if (!styleContext->has_class(className)) {
styleContext->add_class(className);
}
} else {
styleContext->remove_class(className);
}
}
} // namespace waybar::modules::niri

View File

@ -0,0 +1,186 @@
#include "modules/niri/workspaces.hpp"
#include <gtkmm/button.h>
#include <gtkmm/label.h>
#include <spdlog/spdlog.h>
namespace waybar::modules::niri {
Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value &config)
: AModule(config, "workspaces", id, false, false), bar_(bar), box_(bar.orientation, 0) {
box_.set_name("workspaces");
if (!id.empty()) {
box_.get_style_context()->add_class(id);
}
box_.get_style_context()->add_class(MODULE_CLASS);
event_box_.add(box_);
if (!gIPC) gIPC = std::make_unique<IPC>();
gIPC->registerForIPC("WorkspacesChanged", this);
gIPC->registerForIPC("WorkspaceActivated", this);
gIPC->registerForIPC("WorkspaceActiveWindowChanged", this);
dp.emit();
}
Workspaces::~Workspaces() { gIPC->unregisterForIPC(this); }
void Workspaces::onEvent(const Json::Value &ev) { dp.emit(); }
void Workspaces::doUpdate() {
auto ipcLock = gIPC->lockData();
const auto alloutputs = config_["all-outputs"].asBool();
std::vector<Json::Value> my_workspaces;
const auto &workspaces = gIPC->workspaces();
std::copy_if(workspaces.cbegin(), workspaces.cend(), std::back_inserter(my_workspaces),
[&](const auto &ws) {
if (alloutputs) return true;
return ws["output"].asString() == bar_.output->name;
});
// Remove buttons for removed workspaces.
for (auto it = buttons_.begin(); it != buttons_.end();) {
auto ws = std::find_if(my_workspaces.begin(), my_workspaces.end(),
[it](const auto &ws) { return ws["id"].asUInt64() == it->first; });
if (ws == my_workspaces.end()) {
it = buttons_.erase(it);
} else {
++it;
}
}
// Add buttons for new workspaces, update existing ones.
for (const auto &ws : my_workspaces) {
auto bit = buttons_.find(ws["id"].asUInt64());
auto &button = bit == buttons_.end() ? addButton(ws) : bit->second;
auto style_context = button.get_style_context();
if (ws["is_focused"].asBool())
style_context->add_class("focused");
else
style_context->remove_class("focused");
if (ws["is_active"].asBool())
style_context->add_class("active");
else
style_context->remove_class("active");
if (ws["output"]) {
if (ws["output"].asString() == bar_.output->name)
style_context->add_class("current_output");
else
style_context->remove_class("current_output");
} else {
style_context->remove_class("current_output");
}
if (ws["active_window_id"].isNull())
style_context->add_class("empty");
else
style_context->remove_class("empty");
std::string name;
if (ws["name"]) {
name = ws["name"].asString();
} else {
name = std::to_string(ws["idx"].asUInt());
}
button.set_name("niri-workspace-" + name);
if (config_["format"].isString()) {
auto format = config_["format"].asString();
name = fmt::format(fmt::runtime(format), fmt::arg("icon", getIcon(name, ws)),
fmt::arg("value", name), fmt::arg("name", ws["name"].asString()),
fmt::arg("index", ws["idx"].asUInt()),
fmt::arg("output", ws["output"].asString()));
}
if (!config_["disable-markup"].asBool()) {
static_cast<Gtk::Label *>(button.get_children()[0])->set_markup(name);
} else {
button.set_label(name);
}
if (config_["current-only"].asBool()) {
const auto *property = alloutputs ? "is_focused" : "is_active";
if (ws[property].asBool())
button.show();
else
button.hide();
} else {
button.show();
}
}
// Refresh the button order.
for (auto it = my_workspaces.cbegin(); it != my_workspaces.cend(); ++it) {
const auto &ws = *it;
auto pos = ws["idx"].asUInt() - 1;
if (alloutputs) pos = it - my_workspaces.cbegin();
auto &button = buttons_[ws["id"].asUInt64()];
box_.reorder_child(button, pos);
}
}
void Workspaces::update() {
doUpdate();
AModule::update();
}
Gtk::Button &Workspaces::addButton(const Json::Value &ws) {
std::string name;
if (ws["name"]) {
name = ws["name"].asString();
} else {
name = std::to_string(ws["idx"].asUInt());
}
auto pair = buttons_.emplace(ws["id"].asUInt64(), name);
auto &&button = pair.first->second;
box_.pack_start(button, false, false, 0);
button.set_relief(Gtk::RELIEF_NONE);
if (!config_["disable-click"].asBool()) {
const auto id = ws["id"].asUInt64();
button.signal_pressed().connect([=] {
try {
// {"Action":{"FocusWorkspace":{"reference":{"Id":1}}}}
Json::Value request(Json::objectValue);
auto &action = (request["Action"] = Json::Value(Json::objectValue));
auto &focusWorkspace = (action["FocusWorkspace"] = Json::Value(Json::objectValue));
auto &reference = (focusWorkspace["reference"] = Json::Value(Json::objectValue));
reference["Id"] = id;
IPC::send(request);
} catch (const std::exception &e) {
spdlog::error("Error switching workspace: {}", e.what());
}
});
}
return button;
}
std::string Workspaces::getIcon(const std::string &value, const Json::Value &ws) {
const auto &icons = config_["format-icons"];
if (!icons) return value;
if (ws["is_focused"].asBool() && icons["focused"]) return icons["focused"].asString();
if (ws["is_active"].asBool() && icons["active"]) return icons["active"].asString();
if (ws["name"]) {
const auto &name = ws["name"].asString();
if (icons[name]) return icons[name].asString();
}
const auto idx = ws["idx"].asString();
if (icons[idx]) return icons[idx].asString();
if (icons["default"]) return icons["default"].asString();
return value;
}
} // namespace waybar::modules::niri

View File

@ -204,7 +204,7 @@ void PowerProfilesDaemon::setPropCb(Glib::RefPtr<Gio::AsyncResult>& r) {
auto _ = powerProfilesProxy_->call_finish(r);
dp.emit();
} catch (const std::exception& e) {
spdlog::error("Failed to set the the active power profile: {}", e.what());
spdlog::error("Failed to set the active power profile: {}", e.what());
} catch (const Glib::Error& e) {
spdlog::error("Failed to set the active power profile: {}", std::string(e.what()));
}

View File

@ -104,9 +104,11 @@ void Item::proxyReady(Glib::RefPtr<Gio::AsyncResult>& result) {
this->updateImage();
} catch (const Glib::Error& err) {
spdlog::error("Failed to create DBus Proxy for {} {}: {}", bus_name, object_path, err.what());
spdlog::error("Failed to create DBus Proxy for {} {}: {}", bus_name, object_path,
std::string(err.what()));
} catch (const std::exception& err) {
spdlog::error("Failed to create DBus Proxy for {} {}: {}", bus_name, object_path, err.what());
spdlog::error("Failed to create DBus Proxy for {} {}: {}", bus_name, object_path,
std::string(err.what()));
}
}
@ -124,14 +126,15 @@ ToolTip get_variant<ToolTip>(const Glib::VariantBase& value) {
result.text = get_variant<Glib::ustring>(container.get_child(2));
auto description = get_variant<Glib::ustring>(container.get_child(3));
if (!description.empty()) {
result.text = fmt::format("<b>{}</b>\n{}", result.text, description);
result.text = fmt::format("<b>{}</b>\n{}", std::string(result.text), std::string(description));
}
return result;
}
void Item::setProperty(const Glib::ustring& name, Glib::VariantBase& value) {
try {
spdlog::trace("Set tray item property: {}.{} = {}", id.empty() ? bus_name : id, name, value);
spdlog::trace("Set tray item property: {}.{} = {}", id.empty() ? bus_name : id,
std::string(name), get_variant<std::string>(value));
if (name == "Category") {
category = get_variant<std::string>(value);
@ -176,10 +179,12 @@ void Item::setProperty(const Glib::ustring& name, Glib::VariantBase& value) {
}
} catch (const Glib::Error& err) {
spdlog::warn("Failed to set tray item property: {}.{}, value = {}, err = {}",
id.empty() ? bus_name : id, name, value, err.what());
id.empty() ? bus_name : id, std::string(name), get_variant<std::string>(value),
std::string(err.what()));
} catch (const std::exception& err) {
spdlog::warn("Failed to set tray item property: {}.{}, value = {}, err = {}",
id.empty() ? bus_name : id, name, value, err.what());
id.empty() ? bus_name : id, std::string(name), get_variant<std::string>(value),
std::string(err.what()));
}
}
@ -221,9 +226,9 @@ void Item::processUpdatedProperties(Glib::RefPtr<Gio::AsyncResult>& _result) {
this->updateImage();
} catch (const Glib::Error& err) {
spdlog::warn("Failed to update properties: {}", err.what());
spdlog::warn("Failed to update properties: {}", std::string(err.what()));
} catch (const std::exception& err) {
spdlog::warn("Failed to update properties: {}", err.what());
spdlog::warn("Failed to update properties: {}", std::string(err.what()));
}
update_pending_.clear();
}
@ -245,7 +250,7 @@ static const std::map<std::string_view, std::set<std::string_view>> signal2props
void Item::onSignal(const Glib::ustring& sender_name, const Glib::ustring& signal_name,
const Glib::VariantContainerBase& arguments) {
spdlog::trace("Tray item '{}' got signal {}", id, signal_name);
spdlog::trace("Tray item '{}' got signal {}", id, std::string(signal_name));
auto changed = signal2props.find(signal_name.raw());
if (changed != signal2props.end()) {
if (update_pending_.empty()) {

View File

@ -384,10 +384,11 @@ void UPower::setDisplayDevice() {
displayDevice = upDevice;
}
}
// Unref current upDevice
if (displayDevice.upDevice != NULL) g_object_unref(thisPtr->upDevice_.upDevice);
// Reassign new upDevice
thisPtr->upDevice_ = displayDevice;
// Unref current upDevice if it exists
if (displayDevice.upDevice != NULL) {
if (thisPtr->upDevice_.upDevice != NULL) g_object_unref(thisPtr->upDevice_.upDevice);
thisPtr->upDevice_ = displayDevice;
}
},
this);
}

View File

@ -118,8 +118,8 @@ auto WorkspaceManager::sort_workspaces() -> void {
}
}
auto WorkspaceManager::register_manager(wl_registry *registry, uint32_t name, uint32_t version)
-> void {
auto WorkspaceManager::register_manager(wl_registry *registry, uint32_t name,
uint32_t version) -> void {
if (workspace_manager_) {
spdlog::warn("Register workspace manager again although already registered!");
return;