2018-08-08 21:54:58 +00:00
|
|
|
#include "client.hpp"
|
2020-12-25 20:54:38 +00:00
|
|
|
|
2019-05-23 08:13:49 +00:00
|
|
|
#include <spdlog/spdlog.h>
|
2020-12-25 20:54:38 +00:00
|
|
|
|
2018-11-15 13:44:43 +00:00
|
|
|
#include <iostream>
|
2018-08-08 21:54:58 +00:00
|
|
|
|
2023-10-26 21:08:57 +00:00
|
|
|
#include "gtkmm/icontheme.h"
|
2020-10-22 05:45:03 +00:00
|
|
|
#include "idle-inhibit-unstable-v1-client-protocol.h"
|
2020-12-25 20:54:38 +00:00
|
|
|
#include "util/clara.hpp"
|
2022-07-12 05:52:33 +00:00
|
|
|
#include "util/format.hpp"
|
2020-10-22 05:45:03 +00:00
|
|
|
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
|
|
|
|
2019-04-18 15:43:16 +00:00
|
|
|
waybar::Client *waybar::Client::inst() {
|
2019-04-24 10:37:24 +00:00
|
|
|
static auto c = new Client();
|
2019-04-18 15:43:16 +00:00
|
|
|
return c;
|
2018-08-09 12:04:48 +00:00
|
|
|
}
|
2018-08-08 21:54:58 +00:00
|
|
|
|
2019-04-18 15:43:16 +00:00
|
|
|
void waybar::Client::handleGlobal(void *data, struct wl_registry *registry, uint32_t name,
|
|
|
|
const char *interface, uint32_t version) {
|
|
|
|
auto client = static_cast<Client *>(data);
|
2018-08-16 12:29:41 +00:00
|
|
|
if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
|
2020-10-25 05:56:24 +00:00
|
|
|
// limit version to a highest supported by the client protocol file
|
|
|
|
version = std::min<uint32_t>(version, zwlr_layer_shell_v1_interface.version);
|
2019-04-18 15:43:16 +00:00
|
|
|
client->layer_shell = static_cast<struct zwlr_layer_shell_v1 *>(
|
|
|
|
wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, version));
|
|
|
|
} else if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0 &&
|
|
|
|
version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION) {
|
|
|
|
client->xdg_output_manager = static_cast<struct zxdg_output_manager_v1 *>(wl_registry_bind(
|
|
|
|
registry, name, &zxdg_output_manager_v1_interface, ZXDG_OUTPUT_V1_NAME_SINCE_VERSION));
|
2019-02-17 14:27:54 +00:00
|
|
|
} else if (strcmp(interface, zwp_idle_inhibit_manager_v1_interface.name) == 0) {
|
2019-04-19 09:56:40 +00:00
|
|
|
client->idle_inhibit_manager = static_cast<struct zwp_idle_inhibit_manager_v1 *>(
|
|
|
|
wl_registry_bind(registry, name, &zwp_idle_inhibit_manager_v1_interface, 1));
|
2018-08-16 12:29:41 +00:00
|
|
|
}
|
2018-08-09 18:22:01 +00:00
|
|
|
}
|
|
|
|
|
2022-04-06 06:37:19 +00:00
|
|
|
void waybar::Client::handleGlobalRemove(void *data, struct wl_registry * /*registry*/,
|
2019-04-18 15:43:16 +00:00
|
|
|
uint32_t name) {
|
2019-08-28 03:57:23 +00:00
|
|
|
// Nothing here
|
2019-04-18 15:43:16 +00:00
|
|
|
}
|
|
|
|
|
2020-01-14 07:27:57 +00:00
|
|
|
void waybar::Client::handleOutput(struct waybar_output &output) {
|
2019-04-18 15:43:16 +00:00
|
|
|
static const struct zxdg_output_v1_listener xdgOutputListener = {
|
2019-08-28 03:57:23 +00:00
|
|
|
.logical_position = [](void *, struct zxdg_output_v1 *, int32_t, int32_t) {},
|
|
|
|
.logical_size = [](void *, struct zxdg_output_v1 *, int32_t, int32_t) {},
|
2020-12-25 23:03:01 +00:00
|
|
|
.done = &handleOutputDone,
|
|
|
|
.name = &handleOutputName,
|
2020-12-25 20:54:38 +00:00
|
|
|
.description = &handleOutputDescription,
|
2019-04-18 15:43:16 +00:00
|
|
|
};
|
2019-08-28 03:57:23 +00:00
|
|
|
// owned by output->monitor; no need to destroy
|
2020-01-14 07:27:57 +00:00
|
|
|
auto wl_output = gdk_wayland_monitor_get_wl_output(output.monitor->gobj());
|
|
|
|
output.xdg_output.reset(zxdg_output_manager_v1_get_xdg_output(xdg_output_manager, wl_output));
|
|
|
|
zxdg_output_v1_add_listener(output.xdg_output.get(), &xdgOutputListener, &output);
|
2019-04-18 15:43:16 +00:00
|
|
|
}
|
|
|
|
|
2020-01-14 07:27:57 +00:00
|
|
|
struct waybar::waybar_output &waybar::Client::getOutput(void *addr) {
|
2022-04-06 06:37:19 +00:00
|
|
|
auto it = std::find_if(outputs_.begin(), outputs_.end(),
|
|
|
|
[&addr](const auto &output) { return &output == addr; });
|
2019-04-25 11:25:06 +00:00
|
|
|
if (it == outputs_.end()) {
|
|
|
|
throw std::runtime_error("Unable to find valid output");
|
|
|
|
}
|
|
|
|
return *it;
|
|
|
|
}
|
|
|
|
|
2020-01-14 07:27:57 +00:00
|
|
|
std::vector<Json::Value> waybar::Client::getOutputConfigs(struct waybar_output &output) {
|
2021-09-15 14:24:45 +00:00
|
|
|
return config.getOutputConfigs(output.name, output.identifier);
|
2019-04-25 11:25:06 +00:00
|
|
|
}
|
|
|
|
|
2020-12-25 23:03:01 +00:00
|
|
|
void waybar::Client::handleOutputDone(void *data, struct zxdg_output_v1 * /*xdg_output*/) {
|
2019-04-18 15:43:16 +00:00
|
|
|
auto client = waybar::Client::inst();
|
2019-04-25 11:25:06 +00:00
|
|
|
try {
|
2020-12-25 23:03:01 +00:00
|
|
|
auto &output = client->getOutput(data);
|
2021-02-09 07:05:31 +00:00
|
|
|
/**
|
|
|
|
* Multiple .done events may arrive in batch. In this case libwayland would queue
|
|
|
|
* xdg_output.destroy and dispatch all pending events, triggering this callback several times
|
|
|
|
* for the same output. .done events can also arrive after that for a scale or position changes.
|
|
|
|
* We wouldn't want to draw a duplicate bar for each such event either.
|
|
|
|
*
|
|
|
|
* All the properties we care about are immutable so it's safe to delete the xdg_output object
|
|
|
|
* on the first event and use the ptr value to check that the callback was already invoked.
|
|
|
|
*/
|
|
|
|
if (output.xdg_output) {
|
|
|
|
output.xdg_output.reset();
|
|
|
|
spdlog::debug("Output detection done: {} ({})", output.name, output.identifier);
|
|
|
|
|
|
|
|
auto configs = client->getOutputConfigs(output);
|
|
|
|
if (!configs.empty()) {
|
|
|
|
for (const auto &config : configs) {
|
|
|
|
client->bars.emplace_back(std::make_unique<Bar>(&output, config));
|
|
|
|
}
|
2019-04-18 15:43:16 +00:00
|
|
|
}
|
|
|
|
}
|
2019-04-25 11:25:06 +00:00
|
|
|
} catch (const std::exception &e) {
|
|
|
|
std::cerr << e.what() << std::endl;
|
2019-04-18 15:43:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-06 06:37:19 +00:00
|
|
|
void waybar::Client::handleOutputName(void *data, struct zxdg_output_v1 * /*xdg_output*/,
|
2020-12-25 23:03:01 +00:00
|
|
|
const char *name) {
|
|
|
|
auto client = waybar::Client::inst();
|
|
|
|
try {
|
|
|
|
auto &output = client->getOutput(data);
|
|
|
|
output.name = name;
|
|
|
|
} catch (const std::exception &e) {
|
|
|
|
std::cerr << e.what() << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void waybar::Client::handleOutputDescription(void *data, struct zxdg_output_v1 * /*xdg_output*/,
|
|
|
|
const char *description) {
|
|
|
|
auto client = waybar::Client::inst();
|
|
|
|
try {
|
2022-04-06 06:37:19 +00:00
|
|
|
auto &output = client->getOutput(data);
|
2020-12-25 23:03:01 +00:00
|
|
|
const char *open_paren = strrchr(description, '(');
|
|
|
|
|
|
|
|
// Description format: "identifier (name)"
|
|
|
|
size_t identifier_length = open_paren - description;
|
|
|
|
output.identifier = std::string(description, identifier_length - 1);
|
|
|
|
} catch (const std::exception &e) {
|
|
|
|
std::cerr << e.what() << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-28 03:57:23 +00:00
|
|
|
void waybar::Client::handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor) {
|
2020-01-14 07:27:57 +00:00
|
|
|
auto &output = outputs_.emplace_back();
|
|
|
|
output.monitor = monitor;
|
2019-08-28 03:57:23 +00:00
|
|
|
handleOutput(output);
|
|
|
|
}
|
|
|
|
|
|
|
|
void waybar::Client::handleMonitorRemoved(Glib::RefPtr<Gdk::Monitor> monitor) {
|
|
|
|
spdlog::debug("Output removed: {} {}", monitor->get_manufacturer(), monitor->get_model());
|
2021-02-10 03:24:46 +00:00
|
|
|
/* This event can be triggered from wl_display_roundtrip called by GTK or our code.
|
|
|
|
* Defer destruction of bars for the output to the next iteration of the event loop to avoid
|
|
|
|
* deleting objects referenced by currently executed code.
|
|
|
|
*/
|
|
|
|
Glib::signal_idle().connect_once(
|
|
|
|
sigc::bind(sigc::mem_fun(*this, &Client::handleDeferredMonitorRemoval), monitor),
|
|
|
|
Glib::PRIORITY_HIGH_IDLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void waybar::Client::handleDeferredMonitorRemoval(Glib::RefPtr<Gdk::Monitor> monitor) {
|
2019-08-28 03:57:23 +00:00
|
|
|
for (auto it = bars.begin(); it != bars.end();) {
|
|
|
|
if ((*it)->output->monitor == monitor) {
|
|
|
|
auto output_name = (*it)->output->name;
|
2020-05-27 07:10:38 +00:00
|
|
|
(*it)->window.hide();
|
|
|
|
gtk_app->remove_window((*it)->window);
|
2019-08-28 03:57:23 +00:00
|
|
|
it = bars.erase(it);
|
|
|
|
spdlog::info("Bar removed from output: {}", output_name);
|
|
|
|
} else {
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
2020-01-14 07:27:57 +00:00
|
|
|
outputs_.remove_if([&monitor](const auto &output) { return output.monitor == monitor; });
|
2019-04-18 15:43:16 +00:00
|
|
|
}
|
|
|
|
|
search for dark or light mode stylesheet
summary:
-------
This commit adds xdg-desktop-portal support to waybar. If a portal
supporting `org.freedesktop.portal.Settings` exists, then it will be
queried for the current colorscheme. This colorscheme will then be used
to prefer a `style-light.css` or `style-dark.css` over the basic
`style.css`.
technical details:
-----------------
Appearance is provided by several libraries, such as libhandy (mobile)
and libadwaita. However, waybar links to neither of these libraries. As
the amount of code required to communicate with xdg-desktop portal as a
client is rather minimal, I believe doing so is better than linking to
an additional library.
The Gio library for communicating with dbus is rather messy, Instead of
the `Portal` class containing a `Gio::Dbus::Proxy`, it extends it which
simplifies signal handling.
`Portal` then exposes its own signal, which can be listened to by waybar
to update CSS.
For a reference implementation, please see another one of my projects:
https://github.com/4e554c4c/darkman.nvim/blob/main/portal.go
test plan:
---------
If no desktop portal which provides `Settings` exists, then waybar
continues with the log line
```
[2023-09-06 14:14:37.754] [info] Unable to receive desktop appearance: GDBus.Error:org.freedesktop.DBus.Error.UnknownMethod: No such interface “org.freedesktop.portal.Settings” on object at path /org/freedesktop/portal/desktop
```
Furthermore, if `style-light.css` or `style-dark.css` do not exist, then
`style.css` will still be searched for.
Waybar has been tested with both light and dark startup. E.g. if the
appearance is dark on startup the log lines
```
[2023-09-06 14:27:45.379] [info] Discovered appearance 'dark'
[2023-09-06 14:27:45.379] [debug] Try expanding: $XDG_CONFIG_HOME/waybar/style-dark.css
[2023-09-06 14:27:45.379] [debug] Found config file: $XDG_CONFIG_HOME/waybar/style-dark.css
[2023-09-06 14:27:45.379] [info] Using CSS file /home/pounce/.config/waybar/style-dark.css
```
will be observed.
If the color then changes to light during the operation of waybar, it
will change css files:
```
[2023-09-06 14:28:17.173] [info] Received new appearance 'dark'
[2023-09-06 14:28:17.173] [debug] Try expanding: $XDG_CONFIG_HOME/waybar/style-light.css
[2023-09-06 14:28:17.173] [debug] Found config file: $XDG_CONFIG_HOME/waybar/style-light.css
[2023-09-06 14:28:17.173] [info] Using CSS file /home/pounce/.config/waybar/style-light.css
```
Finally, tested resetting waybar and toggling style (works, and style is
only changed once).
fixes: Alexays/Waybar#1973
2023-09-06 15:19:56 +00:00
|
|
|
const std::string waybar::Client::getStyle(const std::string &style,
|
|
|
|
std::optional<Appearance> appearance = std::nullopt) {
|
|
|
|
std::optional<std::string> css_file;
|
2023-09-07 13:43:59 +00:00
|
|
|
if (style.empty()) {
|
search for dark or light mode stylesheet
summary:
-------
This commit adds xdg-desktop-portal support to waybar. If a portal
supporting `org.freedesktop.portal.Settings` exists, then it will be
queried for the current colorscheme. This colorscheme will then be used
to prefer a `style-light.css` or `style-dark.css` over the basic
`style.css`.
technical details:
-----------------
Appearance is provided by several libraries, such as libhandy (mobile)
and libadwaita. However, waybar links to neither of these libraries. As
the amount of code required to communicate with xdg-desktop portal as a
client is rather minimal, I believe doing so is better than linking to
an additional library.
The Gio library for communicating with dbus is rather messy, Instead of
the `Portal` class containing a `Gio::Dbus::Proxy`, it extends it which
simplifies signal handling.
`Portal` then exposes its own signal, which can be listened to by waybar
to update CSS.
For a reference implementation, please see another one of my projects:
https://github.com/4e554c4c/darkman.nvim/blob/main/portal.go
test plan:
---------
If no desktop portal which provides `Settings` exists, then waybar
continues with the log line
```
[2023-09-06 14:14:37.754] [info] Unable to receive desktop appearance: GDBus.Error:org.freedesktop.DBus.Error.UnknownMethod: No such interface “org.freedesktop.portal.Settings” on object at path /org/freedesktop/portal/desktop
```
Furthermore, if `style-light.css` or `style-dark.css` do not exist, then
`style.css` will still be searched for.
Waybar has been tested with both light and dark startup. E.g. if the
appearance is dark on startup the log lines
```
[2023-09-06 14:27:45.379] [info] Discovered appearance 'dark'
[2023-09-06 14:27:45.379] [debug] Try expanding: $XDG_CONFIG_HOME/waybar/style-dark.css
[2023-09-06 14:27:45.379] [debug] Found config file: $XDG_CONFIG_HOME/waybar/style-dark.css
[2023-09-06 14:27:45.379] [info] Using CSS file /home/pounce/.config/waybar/style-dark.css
```
will be observed.
If the color then changes to light during the operation of waybar, it
will change css files:
```
[2023-09-06 14:28:17.173] [info] Received new appearance 'dark'
[2023-09-06 14:28:17.173] [debug] Try expanding: $XDG_CONFIG_HOME/waybar/style-light.css
[2023-09-06 14:28:17.173] [debug] Found config file: $XDG_CONFIG_HOME/waybar/style-light.css
[2023-09-06 14:28:17.173] [info] Using CSS file /home/pounce/.config/waybar/style-light.css
```
Finally, tested resetting waybar and toggling style (works, and style is
only changed once).
fixes: Alexays/Waybar#1973
2023-09-06 15:19:56 +00:00
|
|
|
std::vector<std::string> search_files;
|
|
|
|
switch (appearance.value_or(portal->getAppearance())) {
|
|
|
|
case waybar::Appearance::LIGHT:
|
|
|
|
search_files.push_back("style-light.css");
|
|
|
|
break;
|
|
|
|
case waybar::Appearance::DARK:
|
|
|
|
search_files.push_back("style-dark.css");
|
|
|
|
break;
|
|
|
|
case waybar::Appearance::UNKNOWN:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
search_files.push_back("style.css");
|
|
|
|
css_file = Config::findConfigPath(search_files);
|
2023-09-07 13:43:59 +00:00
|
|
|
} else {
|
|
|
|
css_file = style;
|
search for dark or light mode stylesheet
summary:
-------
This commit adds xdg-desktop-portal support to waybar. If a portal
supporting `org.freedesktop.portal.Settings` exists, then it will be
queried for the current colorscheme. This colorscheme will then be used
to prefer a `style-light.css` or `style-dark.css` over the basic
`style.css`.
technical details:
-----------------
Appearance is provided by several libraries, such as libhandy (mobile)
and libadwaita. However, waybar links to neither of these libraries. As
the amount of code required to communicate with xdg-desktop portal as a
client is rather minimal, I believe doing so is better than linking to
an additional library.
The Gio library for communicating with dbus is rather messy, Instead of
the `Portal` class containing a `Gio::Dbus::Proxy`, it extends it which
simplifies signal handling.
`Portal` then exposes its own signal, which can be listened to by waybar
to update CSS.
For a reference implementation, please see another one of my projects:
https://github.com/4e554c4c/darkman.nvim/blob/main/portal.go
test plan:
---------
If no desktop portal which provides `Settings` exists, then waybar
continues with the log line
```
[2023-09-06 14:14:37.754] [info] Unable to receive desktop appearance: GDBus.Error:org.freedesktop.DBus.Error.UnknownMethod: No such interface “org.freedesktop.portal.Settings” on object at path /org/freedesktop/portal/desktop
```
Furthermore, if `style-light.css` or `style-dark.css` do not exist, then
`style.css` will still be searched for.
Waybar has been tested with both light and dark startup. E.g. if the
appearance is dark on startup the log lines
```
[2023-09-06 14:27:45.379] [info] Discovered appearance 'dark'
[2023-09-06 14:27:45.379] [debug] Try expanding: $XDG_CONFIG_HOME/waybar/style-dark.css
[2023-09-06 14:27:45.379] [debug] Found config file: $XDG_CONFIG_HOME/waybar/style-dark.css
[2023-09-06 14:27:45.379] [info] Using CSS file /home/pounce/.config/waybar/style-dark.css
```
will be observed.
If the color then changes to light during the operation of waybar, it
will change css files:
```
[2023-09-06 14:28:17.173] [info] Received new appearance 'dark'
[2023-09-06 14:28:17.173] [debug] Try expanding: $XDG_CONFIG_HOME/waybar/style-light.css
[2023-09-06 14:28:17.173] [debug] Found config file: $XDG_CONFIG_HOME/waybar/style-light.css
[2023-09-06 14:28:17.173] [info] Using CSS file /home/pounce/.config/waybar/style-light.css
```
Finally, tested resetting waybar and toggling style (works, and style is
only changed once).
fixes: Alexays/Waybar#1973
2023-09-06 15:19:56 +00:00
|
|
|
}
|
2021-08-13 14:19:47 +00:00
|
|
|
if (!css_file) {
|
|
|
|
throw std::runtime_error("Missing required resource files");
|
|
|
|
}
|
|
|
|
spdlog::info("Using CSS file {}", css_file.value());
|
|
|
|
return css_file.value();
|
|
|
|
};
|
|
|
|
|
2019-05-24 07:49:09 +00:00
|
|
|
auto waybar::Client::setupCss(const std::string &css_file) -> void {
|
2019-04-18 15:43:16 +00:00
|
|
|
css_provider_ = Gtk::CssProvider::create();
|
|
|
|
style_context_ = Gtk::StyleContext::create();
|
|
|
|
|
|
|
|
// Load our css file, wherever that may be hiding
|
2019-05-24 07:49:09 +00:00
|
|
|
if (!css_provider_->load_from_path(css_file)) {
|
2019-04-18 15:43:16 +00:00
|
|
|
throw std::runtime_error("Can't open style file");
|
|
|
|
}
|
2021-01-21 01:48:35 +00:00
|
|
|
// there's always only one screen
|
2022-04-06 06:37:19 +00:00
|
|
|
style_context_->add_provider_for_screen(Gdk::Screen::get_default(), css_provider_,
|
|
|
|
GTK_STYLE_PROVIDER_PRIORITY_USER);
|
2019-04-18 15:43:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void waybar::Client::bindInterfaces() {
|
2018-08-16 12:29:41 +00:00
|
|
|
registry = wl_display_get_registry(wl_display);
|
2018-08-09 18:22:01 +00:00
|
|
|
static const struct wl_registry_listener registry_listener = {
|
2019-04-18 15:43:16 +00:00
|
|
|
.global = handleGlobal,
|
|
|
|
.global_remove = handleGlobalRemove,
|
2018-08-09 18:22:01 +00:00
|
|
|
};
|
2018-08-08 21:54:58 +00:00
|
|
|
wl_registry_add_listener(registry, ®istry_listener, this);
|
2018-08-16 12:29:41 +00:00
|
|
|
wl_display_roundtrip(wl_display);
|
2019-04-24 10:37:24 +00:00
|
|
|
if (layer_shell == nullptr || xdg_output_manager == nullptr) {
|
2018-11-16 09:02:12 +00:00
|
|
|
throw std::runtime_error("Failed to acquire required resources.");
|
|
|
|
}
|
2019-08-28 03:57:23 +00:00
|
|
|
// add existing outputs and subscribe to updates
|
|
|
|
for (auto i = 0; i < gdk_display->get_n_monitors(); ++i) {
|
|
|
|
auto monitor = gdk_display->get_monitor(i);
|
|
|
|
handleMonitorAdded(monitor);
|
|
|
|
}
|
|
|
|
gdk_display->signal_monitor_added().connect(sigc::mem_fun(*this, &Client::handleMonitorAdded));
|
|
|
|
gdk_display->signal_monitor_removed().connect(
|
|
|
|
sigc::mem_fun(*this, &Client::handleMonitorRemoved));
|
2018-08-08 21:54:58 +00:00
|
|
|
}
|
|
|
|
|
2019-04-18 15:43:16 +00:00
|
|
|
int waybar::Client::main(int argc, char *argv[]) {
|
2022-04-06 06:37:19 +00:00
|
|
|
bool show_help = false;
|
|
|
|
bool show_version = false;
|
2021-09-15 14:24:45 +00:00
|
|
|
std::string config_opt;
|
|
|
|
std::string style_opt;
|
2019-05-20 11:57:41 +00:00
|
|
|
std::string log_level;
|
2022-04-06 06:37:19 +00:00
|
|
|
auto cli = clara::detail::Help(show_help) |
|
2019-04-18 15:43:16 +00:00
|
|
|
clara::detail::Opt(show_version)["-v"]["--version"]("Show version") |
|
2021-09-15 14:24:45 +00:00
|
|
|
clara::detail::Opt(config_opt, "config")["-c"]["--config"]("Config path") |
|
|
|
|
clara::detail::Opt(style_opt, "style")["-s"]["--style"]("Style path") |
|
2019-05-20 11:57:41 +00:00
|
|
|
clara::detail::Opt(
|
|
|
|
log_level,
|
|
|
|
"trace|debug|info|warning|error|critical|off")["-l"]["--log-level"]("Log level") |
|
2019-04-18 15:43:16 +00:00
|
|
|
clara::detail::Opt(bar_id, "id")["-b"]["--bar"]("Bar id");
|
2018-12-18 16:30:54 +00:00
|
|
|
auto res = cli.parse(clara::detail::Args(argc, argv));
|
|
|
|
if (!res) {
|
2019-05-18 23:44:45 +00:00
|
|
|
spdlog::error("Error in command line: {}", res.errorMessage());
|
2018-12-18 16:30:54 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (show_help) {
|
|
|
|
std::cout << cli << std::endl;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (show_version) {
|
|
|
|
std::cout << "Waybar v" << VERSION << std::endl;
|
|
|
|
return 0;
|
|
|
|
}
|
2019-05-20 11:57:41 +00:00
|
|
|
if (!log_level.empty()) {
|
|
|
|
spdlog::set_level(spdlog::level::from_str(log_level));
|
|
|
|
}
|
2022-04-06 06:37:19 +00:00
|
|
|
gtk_app = Gtk::Application::create(argc, argv, "fr.arouillard.waybar",
|
|
|
|
Gio::APPLICATION_HANDLES_COMMAND_LINE);
|
2023-10-26 21:08:57 +00:00
|
|
|
|
|
|
|
// Initialize Waybars GTK resources with our custom icons
|
|
|
|
auto theme = Gtk::IconTheme::get_default();
|
|
|
|
theme->add_resource_path("/fr/arouillard/waybar/icons");
|
|
|
|
|
2019-05-23 08:13:49 +00:00
|
|
|
gdk_display = Gdk::Display::get_default();
|
|
|
|
if (!gdk_display) {
|
|
|
|
throw std::runtime_error("Can't find display");
|
|
|
|
}
|
|
|
|
if (!GDK_IS_WAYLAND_DISPLAY(gdk_display->gobj())) {
|
|
|
|
throw std::runtime_error("Bar need to run under Wayland");
|
|
|
|
}
|
|
|
|
wl_display = gdk_wayland_display_get_wl_display(gdk_display->gobj());
|
2021-08-13 14:19:47 +00:00
|
|
|
config.load(config_opt);
|
search for dark or light mode stylesheet
summary:
-------
This commit adds xdg-desktop-portal support to waybar. If a portal
supporting `org.freedesktop.portal.Settings` exists, then it will be
queried for the current colorscheme. This colorscheme will then be used
to prefer a `style-light.css` or `style-dark.css` over the basic
`style.css`.
technical details:
-----------------
Appearance is provided by several libraries, such as libhandy (mobile)
and libadwaita. However, waybar links to neither of these libraries. As
the amount of code required to communicate with xdg-desktop portal as a
client is rather minimal, I believe doing so is better than linking to
an additional library.
The Gio library for communicating with dbus is rather messy, Instead of
the `Portal` class containing a `Gio::Dbus::Proxy`, it extends it which
simplifies signal handling.
`Portal` then exposes its own signal, which can be listened to by waybar
to update CSS.
For a reference implementation, please see another one of my projects:
https://github.com/4e554c4c/darkman.nvim/blob/main/portal.go
test plan:
---------
If no desktop portal which provides `Settings` exists, then waybar
continues with the log line
```
[2023-09-06 14:14:37.754] [info] Unable to receive desktop appearance: GDBus.Error:org.freedesktop.DBus.Error.UnknownMethod: No such interface “org.freedesktop.portal.Settings” on object at path /org/freedesktop/portal/desktop
```
Furthermore, if `style-light.css` or `style-dark.css` do not exist, then
`style.css` will still be searched for.
Waybar has been tested with both light and dark startup. E.g. if the
appearance is dark on startup the log lines
```
[2023-09-06 14:27:45.379] [info] Discovered appearance 'dark'
[2023-09-06 14:27:45.379] [debug] Try expanding: $XDG_CONFIG_HOME/waybar/style-dark.css
[2023-09-06 14:27:45.379] [debug] Found config file: $XDG_CONFIG_HOME/waybar/style-dark.css
[2023-09-06 14:27:45.379] [info] Using CSS file /home/pounce/.config/waybar/style-dark.css
```
will be observed.
If the color then changes to light during the operation of waybar, it
will change css files:
```
[2023-09-06 14:28:17.173] [info] Received new appearance 'dark'
[2023-09-06 14:28:17.173] [debug] Try expanding: $XDG_CONFIG_HOME/waybar/style-light.css
[2023-09-06 14:28:17.173] [debug] Found config file: $XDG_CONFIG_HOME/waybar/style-light.css
[2023-09-06 14:28:17.173] [info] Using CSS file /home/pounce/.config/waybar/style-light.css
```
Finally, tested resetting waybar and toggling style (works, and style is
only changed once).
fixes: Alexays/Waybar#1973
2023-09-06 15:19:56 +00:00
|
|
|
if (!portal) {
|
|
|
|
portal = std::make_unique<waybar::Portal>();
|
|
|
|
}
|
2024-01-22 02:23:46 +00:00
|
|
|
m_cssFile = getStyle(style_opt);
|
|
|
|
setupCss(m_cssFile);
|
|
|
|
m_cssReloadHelper = std::make_unique<CssReloadHelper>(m_cssFile, [&]() { setupCss(m_cssFile); });
|
search for dark or light mode stylesheet
summary:
-------
This commit adds xdg-desktop-portal support to waybar. If a portal
supporting `org.freedesktop.portal.Settings` exists, then it will be
queried for the current colorscheme. This colorscheme will then be used
to prefer a `style-light.css` or `style-dark.css` over the basic
`style.css`.
technical details:
-----------------
Appearance is provided by several libraries, such as libhandy (mobile)
and libadwaita. However, waybar links to neither of these libraries. As
the amount of code required to communicate with xdg-desktop portal as a
client is rather minimal, I believe doing so is better than linking to
an additional library.
The Gio library for communicating with dbus is rather messy, Instead of
the `Portal` class containing a `Gio::Dbus::Proxy`, it extends it which
simplifies signal handling.
`Portal` then exposes its own signal, which can be listened to by waybar
to update CSS.
For a reference implementation, please see another one of my projects:
https://github.com/4e554c4c/darkman.nvim/blob/main/portal.go
test plan:
---------
If no desktop portal which provides `Settings` exists, then waybar
continues with the log line
```
[2023-09-06 14:14:37.754] [info] Unable to receive desktop appearance: GDBus.Error:org.freedesktop.DBus.Error.UnknownMethod: No such interface “org.freedesktop.portal.Settings” on object at path /org/freedesktop/portal/desktop
```
Furthermore, if `style-light.css` or `style-dark.css` do not exist, then
`style.css` will still be searched for.
Waybar has been tested with both light and dark startup. E.g. if the
appearance is dark on startup the log lines
```
[2023-09-06 14:27:45.379] [info] Discovered appearance 'dark'
[2023-09-06 14:27:45.379] [debug] Try expanding: $XDG_CONFIG_HOME/waybar/style-dark.css
[2023-09-06 14:27:45.379] [debug] Found config file: $XDG_CONFIG_HOME/waybar/style-dark.css
[2023-09-06 14:27:45.379] [info] Using CSS file /home/pounce/.config/waybar/style-dark.css
```
will be observed.
If the color then changes to light during the operation of waybar, it
will change css files:
```
[2023-09-06 14:28:17.173] [info] Received new appearance 'dark'
[2023-09-06 14:28:17.173] [debug] Try expanding: $XDG_CONFIG_HOME/waybar/style-light.css
[2023-09-06 14:28:17.173] [debug] Found config file: $XDG_CONFIG_HOME/waybar/style-light.css
[2023-09-06 14:28:17.173] [info] Using CSS file /home/pounce/.config/waybar/style-light.css
```
Finally, tested resetting waybar and toggling style (works, and style is
only changed once).
fixes: Alexays/Waybar#1973
2023-09-06 15:19:56 +00:00
|
|
|
portal->signal_appearance_changed().connect([&](waybar::Appearance appearance) {
|
|
|
|
auto css_file = getStyle(style_opt, appearance);
|
|
|
|
setupCss(css_file);
|
|
|
|
});
|
2024-01-22 05:02:01 +00:00
|
|
|
|
|
|
|
if (config.getConfig()["reload_style_on_change"].asBool()) {
|
|
|
|
m_cssReloadHelper->monitorChanges();
|
|
|
|
}
|
2018-08-16 12:29:41 +00:00
|
|
|
bindInterfaces();
|
2019-04-15 09:42:16 +00:00
|
|
|
gtk_app->hold();
|
|
|
|
gtk_app->run();
|
2024-01-22 05:02:01 +00:00
|
|
|
m_cssReloadHelper.reset(); // stop watching css file
|
2018-08-17 18:28:26 +00:00
|
|
|
bars.clear();
|
2018-08-08 21:54:58 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2020-08-27 12:07:19 +00:00
|
|
|
|
search for dark or light mode stylesheet
summary:
-------
This commit adds xdg-desktop-portal support to waybar. If a portal
supporting `org.freedesktop.portal.Settings` exists, then it will be
queried for the current colorscheme. This colorscheme will then be used
to prefer a `style-light.css` or `style-dark.css` over the basic
`style.css`.
technical details:
-----------------
Appearance is provided by several libraries, such as libhandy (mobile)
and libadwaita. However, waybar links to neither of these libraries. As
the amount of code required to communicate with xdg-desktop portal as a
client is rather minimal, I believe doing so is better than linking to
an additional library.
The Gio library for communicating with dbus is rather messy, Instead of
the `Portal` class containing a `Gio::Dbus::Proxy`, it extends it which
simplifies signal handling.
`Portal` then exposes its own signal, which can be listened to by waybar
to update CSS.
For a reference implementation, please see another one of my projects:
https://github.com/4e554c4c/darkman.nvim/blob/main/portal.go
test plan:
---------
If no desktop portal which provides `Settings` exists, then waybar
continues with the log line
```
[2023-09-06 14:14:37.754] [info] Unable to receive desktop appearance: GDBus.Error:org.freedesktop.DBus.Error.UnknownMethod: No such interface “org.freedesktop.portal.Settings” on object at path /org/freedesktop/portal/desktop
```
Furthermore, if `style-light.css` or `style-dark.css` do not exist, then
`style.css` will still be searched for.
Waybar has been tested with both light and dark startup. E.g. if the
appearance is dark on startup the log lines
```
[2023-09-06 14:27:45.379] [info] Discovered appearance 'dark'
[2023-09-06 14:27:45.379] [debug] Try expanding: $XDG_CONFIG_HOME/waybar/style-dark.css
[2023-09-06 14:27:45.379] [debug] Found config file: $XDG_CONFIG_HOME/waybar/style-dark.css
[2023-09-06 14:27:45.379] [info] Using CSS file /home/pounce/.config/waybar/style-dark.css
```
will be observed.
If the color then changes to light during the operation of waybar, it
will change css files:
```
[2023-09-06 14:28:17.173] [info] Received new appearance 'dark'
[2023-09-06 14:28:17.173] [debug] Try expanding: $XDG_CONFIG_HOME/waybar/style-light.css
[2023-09-06 14:28:17.173] [debug] Found config file: $XDG_CONFIG_HOME/waybar/style-light.css
[2023-09-06 14:28:17.173] [info] Using CSS file /home/pounce/.config/waybar/style-light.css
```
Finally, tested resetting waybar and toggling style (works, and style is
only changed once).
fixes: Alexays/Waybar#1973
2023-09-06 15:19:56 +00:00
|
|
|
void waybar::Client::reset() {
|
|
|
|
gtk_app->quit();
|
|
|
|
// delete signal handler for css changes
|
|
|
|
portal->signal_appearance_changed().clear();
|
|
|
|
}
|