2018-08-08 21:54:58 +00:00
|
|
|
#include "client.hpp"
|
2018-11-15 13:44:43 +00:00
|
|
|
#include <iostream>
|
2018-08-08 21:54:58 +00:00
|
|
|
|
|
|
|
waybar::Client::Client(int argc, char* argv[])
|
2018-08-29 19:07:58 +00:00
|
|
|
: gtk_app(Gtk::Application::create(argc, argv, "fr.arouillard.waybar")),
|
|
|
|
gdk_display(Gdk::Display::get_default())
|
2018-08-09 12:04:48 +00:00
|
|
|
{
|
2018-08-29 19:07:58 +00:00
|
|
|
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());
|
2018-08-09 12:04:48 +00:00
|
|
|
auto getFirstValidPath = [] (std::vector<std::string> possiblePaths) {
|
|
|
|
wordexp_t p;
|
|
|
|
|
2018-08-16 12:29:41 +00:00
|
|
|
for (const std::string &path: possiblePaths) {
|
2018-08-09 12:04:48 +00:00
|
|
|
if (wordexp(path.c_str(), &p, 0) == 0) {
|
2018-08-16 12:29:41 +00:00
|
|
|
if (access(*p.we_wordv, F_OK) == 0) {
|
|
|
|
std::string result = *p.we_wordv;
|
2018-08-09 12:04:48 +00:00
|
|
|
wordfree(&p);
|
|
|
|
return result;
|
|
|
|
}
|
2018-08-15 15:31:45 +00:00
|
|
|
wordfree(&p);
|
2018-08-09 12:04:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::string();
|
|
|
|
};
|
|
|
|
|
2018-08-16 12:29:41 +00:00
|
|
|
config_file = getFirstValidPath({
|
2018-08-09 12:04:48 +00:00
|
|
|
"$XDG_CONFIG_HOME/waybar/config",
|
|
|
|
"$HOME/waybar/config",
|
2018-08-09 15:02:30 +00:00
|
|
|
"/etc/xdg/waybar/config",
|
2018-08-09 12:04:48 +00:00
|
|
|
"./resources/config",
|
|
|
|
});
|
2018-08-16 12:29:41 +00:00
|
|
|
css_file = getFirstValidPath({
|
2018-08-09 12:04:48 +00:00
|
|
|
"$XDG_CONFIG_HOME/waybar/style.css",
|
|
|
|
"$HOME/waybar/style.css",
|
2018-08-09 15:02:30 +00:00
|
|
|
"/etc/xdg/waybar/style.css",
|
2018-08-09 12:04:48 +00:00
|
|
|
"./resources/style.css",
|
|
|
|
});
|
2018-11-23 18:31:40 +00:00
|
|
|
if (css_file.empty() || config_file.empty()) {
|
|
|
|
throw std::runtime_error("Missing required resources files");
|
|
|
|
}
|
2018-11-15 13:44:43 +00:00
|
|
|
std::cout << "Resources files: " + config_file + ", " + css_file << std::endl;
|
2018-08-09 12:04:48 +00:00
|
|
|
}
|
2018-08-08 21:54:58 +00:00
|
|
|
|
2018-08-16 12:29:41 +00:00
|
|
|
void waybar::Client::handleGlobal(void *data, struct wl_registry *registry,
|
2018-08-09 18:22:01 +00:00
|
|
|
uint32_t name, const char *interface, uint32_t version)
|
|
|
|
{
|
2018-08-16 12:29:41 +00:00
|
|
|
auto o = static_cast<waybar::Client *>(data);
|
|
|
|
if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
|
|
|
|
o->layer_shell = static_cast<struct zwlr_layer_shell_v1 *>(
|
|
|
|
wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, version));
|
|
|
|
} else if (strcmp(interface, wl_output_interface.name) == 0) {
|
2018-08-14 23:53:43 +00:00
|
|
|
auto output = std::make_unique<struct wl_output *>();
|
2018-08-16 12:29:41 +00:00
|
|
|
*output = static_cast<struct wl_output *>(wl_registry_bind(registry, name,
|
|
|
|
&wl_output_interface, version));
|
|
|
|
if (o->xdg_output_manager != nullptr) {
|
2018-08-19 11:39:57 +00:00
|
|
|
o->bars.emplace_back(std::make_unique<Bar>(*o, std::move(output), name));
|
2018-08-16 12:29:41 +00:00
|
|
|
}
|
|
|
|
} else if (strcmp(interface, wl_seat_interface.name) == 0) {
|
|
|
|
o->seat = static_cast<struct wl_seat *>(wl_registry_bind(registry, name,
|
|
|
|
&wl_seat_interface, version));
|
|
|
|
} else if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0
|
|
|
|
&& version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION) {
|
|
|
|
o->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));
|
|
|
|
}
|
2018-08-09 18:22:01 +00:00
|
|
|
}
|
|
|
|
|
2018-08-19 11:39:57 +00:00
|
|
|
void waybar::Client::handleGlobalRemove(void* data,
|
|
|
|
struct wl_registry* /*registry*/, uint32_t name)
|
2018-08-09 18:22:01 +00:00
|
|
|
{
|
2018-08-19 11:39:57 +00:00
|
|
|
auto o = static_cast<waybar::Client *>(data);
|
|
|
|
for (auto it = o->bars.begin(); it != o->bars.end(); ++it) {
|
|
|
|
if ((**it).wl_name == name) {
|
|
|
|
o->bars.erase(it);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-08-09 18:22:01 +00:00
|
|
|
}
|
|
|
|
|
2018-08-16 12:29:41 +00:00
|
|
|
void waybar::Client::bindInterfaces()
|
2018-08-08 21:54:58 +00:00
|
|
|
{
|
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 = {
|
2018-08-16 12:29:41 +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);
|
2018-11-16 09:02:12 +00:00
|
|
|
if (!layer_shell || !seat || !xdg_output_manager) {
|
|
|
|
throw std::runtime_error("Failed to acquire required resources.");
|
|
|
|
}
|
|
|
|
wl_display_roundtrip(wl_display);
|
2018-08-08 21:54:58 +00:00
|
|
|
}
|
|
|
|
|
2018-08-16 12:29:41 +00:00
|
|
|
int waybar::Client::main(int /*argc*/, char* /*argv*/[])
|
2018-08-08 21:54:58 +00:00
|
|
|
{
|
2018-08-16 12:29:41 +00:00
|
|
|
bindInterfaces();
|
2018-08-19 11:39:57 +00:00
|
|
|
gtk_app->hold();
|
|
|
|
gtk_app->run();
|
2018-08-17 18:28:26 +00:00
|
|
|
bars.clear();
|
|
|
|
zxdg_output_manager_v1_destroy(xdg_output_manager);
|
|
|
|
zwlr_layer_shell_v1_destroy(layer_shell);
|
|
|
|
wl_registry_destroy(registry);
|
|
|
|
wl_seat_destroy(seat);
|
|
|
|
wl_display_disconnect(wl_display);
|
2018-08-08 21:54:58 +00:00
|
|
|
return 0;
|
|
|
|
}
|