refactor: format && better output management
parent
817c42841b
commit
807ef32357
110
include/bar.hpp
110
include/bar.hpp
|
@ -1,73 +1,63 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <json/json.h>
|
|
||||||
#include <glibmm/refptr.h>
|
#include <glibmm/refptr.h>
|
||||||
#include <gtkmm/main.h>
|
|
||||||
#include <gtkmm/cssprovider.h>
|
#include <gtkmm/cssprovider.h>
|
||||||
|
#include <gtkmm/main.h>
|
||||||
#include <gtkmm/window.h>
|
#include <gtkmm/window.h>
|
||||||
|
#include <json/json.h>
|
||||||
|
#include "IModule.hpp"
|
||||||
|
#include "idle-inhibit-unstable-v1-client-protocol.h"
|
||||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||||
#include "idle-inhibit-unstable-v1-client-protocol.h"
|
|
||||||
#include "IModule.hpp"
|
|
||||||
|
|
||||||
namespace waybar {
|
namespace waybar {
|
||||||
|
|
||||||
class Client;
|
|
||||||
class Factory;
|
class Factory;
|
||||||
|
struct waybar_output {
|
||||||
class Bar {
|
struct wl_output *output;
|
||||||
public:
|
std::string name;
|
||||||
Bar(const Client&, std::unique_ptr<struct wl_output *>&&, uint32_t);
|
uint32_t wl_name;
|
||||||
Bar(const Bar&) = delete;
|
struct zxdg_output_v1 *xdg_output;
|
||||||
~Bar() = default;
|
Json::Value config;
|
||||||
|
|
||||||
auto toggle() -> void;
|
|
||||||
void handleSignal(int);
|
|
||||||
|
|
||||||
const Client& client;
|
|
||||||
Gtk::Window window;
|
|
||||||
struct wl_surface *surface;
|
|
||||||
struct zwlr_layer_surface_v1 *layer_surface;
|
|
||||||
std::unique_ptr<struct wl_output *> output;
|
|
||||||
std::string output_name;
|
|
||||||
uint32_t wl_name;
|
|
||||||
bool visible = true;
|
|
||||||
bool vertical = false;
|
|
||||||
private:
|
|
||||||
static void handleLogicalPosition(void *, struct zxdg_output_v1 *, int32_t,
|
|
||||||
int32_t);
|
|
||||||
static void handleLogicalSize(void *, struct zxdg_output_v1 *, int32_t,
|
|
||||||
int32_t);
|
|
||||||
static void handleDone(void *, struct zxdg_output_v1 *);
|
|
||||||
static void handleName(void *, struct zxdg_output_v1 *, const char *);
|
|
||||||
static void handleDescription(void *, struct zxdg_output_v1 *,
|
|
||||||
const char *);
|
|
||||||
static void layerSurfaceHandleConfigure(void *,
|
|
||||||
struct zwlr_layer_surface_v1 *, uint32_t, uint32_t, uint32_t);
|
|
||||||
static void layerSurfaceHandleClosed(void *,
|
|
||||||
struct zwlr_layer_surface_v1 *);
|
|
||||||
|
|
||||||
void initBar();
|
|
||||||
bool isValidOutput(const Json::Value &config);
|
|
||||||
void destroyOutput();
|
|
||||||
auto setupConfig() -> void;
|
|
||||||
auto setupWidgets() -> void;
|
|
||||||
auto setupCss() -> void;
|
|
||||||
void getModules(const Factory&, const std::string&);
|
|
||||||
|
|
||||||
uint32_t width_ = 0;
|
|
||||||
uint32_t height_ = 30;
|
|
||||||
Json::Value config_;
|
|
||||||
Glib::RefPtr<Gtk::StyleContext> style_context_;
|
|
||||||
Glib::RefPtr<Gtk::CssProvider> css_provider_;
|
|
||||||
struct zxdg_output_v1 *xdg_output_;
|
|
||||||
Gtk::Box left_;
|
|
||||||
Gtk::Box center_;
|
|
||||||
Gtk::Box right_;
|
|
||||||
Gtk::Box box_;
|
|
||||||
std::vector<std::unique_ptr<waybar::IModule>> modules_left_;
|
|
||||||
std::vector<std::unique_ptr<waybar::IModule>> modules_center_;
|
|
||||||
std::vector<std::unique_ptr<waybar::IModule>> modules_right_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
class Bar {
|
||||||
|
public:
|
||||||
|
Bar(struct waybar_output* w_output);
|
||||||
|
Bar(const Bar &) = delete;
|
||||||
|
~Bar() = default;
|
||||||
|
|
||||||
|
auto toggle() -> void;
|
||||||
|
void handleSignal(int);
|
||||||
|
|
||||||
|
struct waybar_output* output;
|
||||||
|
Gtk::Window window;
|
||||||
|
struct wl_surface *surface;
|
||||||
|
struct zwlr_layer_surface_v1 *layer_surface;
|
||||||
|
bool visible = true;
|
||||||
|
bool vertical = false;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void layerSurfaceHandleConfigure(void *, struct zwlr_layer_surface_v1 *, uint32_t,
|
||||||
|
uint32_t, uint32_t);
|
||||||
|
static void layerSurfaceHandleClosed(void *, struct zwlr_layer_surface_v1 *);
|
||||||
|
|
||||||
|
void destroyOutput();
|
||||||
|
void onWindowRealize();
|
||||||
|
auto setupWidgets() -> void;
|
||||||
|
void getModules(const Factory &, const std::string &);
|
||||||
|
void setupAltFormatKeyForModule(const std::string &module_name);
|
||||||
|
void setupAltFormatKeyForModuleList(const char *module_list_name);
|
||||||
|
|
||||||
|
uint32_t width_ = 0;
|
||||||
|
uint32_t height_ = 30;
|
||||||
|
Gtk::Box left_;
|
||||||
|
Gtk::Box center_;
|
||||||
|
Gtk::Box right_;
|
||||||
|
Gtk::Box box_;
|
||||||
|
std::vector<std::unique_ptr<waybar::IModule>> modules_left_;
|
||||||
|
std::vector<std::unique_ptr<waybar::IModule>> modules_center_;
|
||||||
|
std::vector<std::unique_ptr<waybar::IModule>> modules_right_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar
|
||||||
|
|
|
@ -1,41 +1,55 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <wordexp.h>
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <gdk/gdk.h>
|
#include <gdk/gdk.h>
|
||||||
#include <wayland-client.h>
|
|
||||||
#include <gdk/gdkwayland.h>
|
#include <gdk/gdkwayland.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <wayland-client.h>
|
||||||
|
#include <wordexp.h>
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
|
|
||||||
namespace waybar {
|
namespace waybar {
|
||||||
|
|
||||||
class Client {
|
class Client {
|
||||||
public:
|
public:
|
||||||
Client(int argc, char *argv[]);
|
static Client *inst();
|
||||||
int main(int argc, char *argv[]);
|
int main(int argc, char *argv[]);
|
||||||
|
|
||||||
Glib::RefPtr<Gtk::Application> gtk_app;
|
Glib::RefPtr<Gtk::Application> gtk_app;
|
||||||
std::string css_file;
|
Glib::RefPtr<Gdk::Display> gdk_display;
|
||||||
std::string config_file;
|
struct wl_display *wl_display = nullptr;
|
||||||
Glib::RefPtr<Gdk::Display> gdk_display;
|
struct wl_registry *registry = nullptr;
|
||||||
struct wl_display *wl_display = nullptr;
|
struct zwlr_layer_shell_v1 *layer_shell = nullptr;
|
||||||
struct wl_registry *registry = nullptr;
|
struct zxdg_output_manager_v1 *xdg_output_manager = nullptr;
|
||||||
struct zwlr_layer_shell_v1 *layer_shell = nullptr;
|
struct wl_seat *seat = nullptr;
|
||||||
struct zxdg_output_manager_v1 *xdg_output_manager = nullptr;
|
struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager = nullptr;
|
||||||
struct wl_seat *seat = nullptr;
|
std::vector<std::unique_ptr<Bar>> bars;
|
||||||
struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager = nullptr;
|
|
||||||
std::vector<std::unique_ptr<Bar>> bars;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupConfigs(const std::string& config, const std::string& style);
|
Client();
|
||||||
void bindInterfaces();
|
void setupConfigs(const std::string &config, const std::string &style);
|
||||||
const std::string getValidPath(std::vector<std::string> paths);
|
void bindInterfaces();
|
||||||
|
const std::string getValidPath(std::vector<std::string> paths);
|
||||||
|
void handleOutput(std::unique_ptr<struct waybar_output> &output);
|
||||||
|
bool isValidOutput(const Json::Value &config, std::unique_ptr<struct waybar_output> &output);
|
||||||
|
auto setupConfig() -> void;
|
||||||
|
auto setupCss() -> void;
|
||||||
|
|
||||||
static void handleGlobal(void *data, struct wl_registry *registry,
|
static void handleGlobal(void *data, struct wl_registry *registry, uint32_t name,
|
||||||
uint32_t name, const char *interface, uint32_t version);
|
const char *interface, uint32_t version);
|
||||||
static void handleGlobalRemove(void *data,
|
static void handleGlobalRemove(void *data, struct wl_registry *registry, uint32_t name);
|
||||||
struct wl_registry *registry, uint32_t name);
|
static void handleLogicalPosition(void *, struct zxdg_output_v1 *, int32_t, int32_t);
|
||||||
|
static void handleLogicalSize(void *, struct zxdg_output_v1 *, int32_t, int32_t);
|
||||||
|
static void handleDone(void *, struct zxdg_output_v1 *);
|
||||||
|
static void handleName(void *, struct zxdg_output_v1 *, const char *);
|
||||||
|
static void handleDescription(void *, struct zxdg_output_v1 *, const char *);
|
||||||
|
|
||||||
|
Json::Value config_;
|
||||||
|
std::string css_file_;
|
||||||
|
std::string config_file_;
|
||||||
|
Glib::RefPtr<Gtk::StyleContext> style_context_;
|
||||||
|
Glib::RefPtr<Gtk::CssProvider> css_provider_;
|
||||||
|
std::vector<std::unique_ptr<struct waybar_output>> outputs_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace waybar
|
||||||
|
|
|
@ -28,11 +28,10 @@
|
||||||
#endif
|
#endif
|
||||||
#include "modules/temperature.hpp"
|
#include "modules/temperature.hpp"
|
||||||
#include "modules/custom.hpp"
|
#include "modules/custom.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
|
|
||||||
namespace waybar {
|
namespace waybar {
|
||||||
|
|
||||||
class Bar;
|
|
||||||
|
|
||||||
class Factory {
|
class Factory {
|
||||||
public:
|
public:
|
||||||
Factory(const Bar& bar, const Json::Value& config);
|
Factory(const Bar& bar, const Json::Value& config);
|
||||||
|
|
|
@ -21,7 +21,7 @@ class Network : public ALabel {
|
||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
private:
|
private:
|
||||||
static const uint8_t MAX_RETRY = 5;
|
static const uint8_t MAX_RETRY = 5;
|
||||||
static const uint8_t EPOLL_MAX = 255;
|
static const uint8_t EPOLL_MAX = 200;
|
||||||
|
|
||||||
static int handleEvents(struct nl_msg*, void*);
|
static int handleEvents(struct nl_msg*, void*);
|
||||||
static int handleScan(struct nl_msg*, void*);
|
static int handleScan(struct nl_msg*, void*);
|
||||||
|
|
|
@ -14,6 +14,9 @@ struct JsonParser {
|
||||||
{
|
{
|
||||||
Json::Value root;
|
Json::Value root;
|
||||||
std::string err;
|
std::string err;
|
||||||
|
if (data.empty()) {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
bool res =
|
bool res =
|
||||||
reader_->parse(data.c_str(), data.c_str() + data.size(), &root, &err);
|
reader_->parse(data.c_str(), data.c_str() + data.size(), &root, &err);
|
||||||
if (!res)
|
if (!res)
|
||||||
|
|
288
src/bar.cpp
288
src/bar.cpp
|
@ -1,32 +1,26 @@
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
#include "client.hpp"
|
#include "client.hpp"
|
||||||
#include "factory.hpp"
|
#include "factory.hpp"
|
||||||
#include "util/json.hpp"
|
|
||||||
|
|
||||||
waybar::Bar::Bar(const Client& client,
|
waybar::Bar::Bar(struct waybar_output* w_output)
|
||||||
std::unique_ptr<struct wl_output *> &&p_output, uint32_t p_wl_name)
|
: output(w_output),
|
||||||
: client(client), window{Gtk::WindowType::WINDOW_TOPLEVEL},
|
window{Gtk::WindowType::WINDOW_TOPLEVEL},
|
||||||
surface(nullptr), layer_surface(nullptr),
|
surface(nullptr),
|
||||||
output(std::move(p_output)), wl_name(p_wl_name),
|
layer_surface(nullptr),
|
||||||
left_(Gtk::ORIENTATION_HORIZONTAL, 0), center_(Gtk::ORIENTATION_HORIZONTAL, 0),
|
left_(Gtk::ORIENTATION_HORIZONTAL, 0),
|
||||||
right_(Gtk::ORIENTATION_HORIZONTAL, 0), box_(Gtk::ORIENTATION_HORIZONTAL, 0)
|
center_(Gtk::ORIENTATION_HORIZONTAL, 0),
|
||||||
{
|
right_(Gtk::ORIENTATION_HORIZONTAL, 0),
|
||||||
static const struct zxdg_output_v1_listener xdgOutputListener = {
|
box_(Gtk::ORIENTATION_HORIZONTAL, 0) {
|
||||||
.logical_position = handleLogicalPosition,
|
|
||||||
.logical_size = handleLogicalSize,
|
|
||||||
.done = handleDone,
|
|
||||||
.name = handleName,
|
|
||||||
.description = handleDescription,
|
|
||||||
};
|
|
||||||
xdg_output_ =
|
|
||||||
zxdg_output_manager_v1_get_xdg_output(client.xdg_output_manager, *output);
|
|
||||||
zxdg_output_v1_add_listener(xdg_output_, &xdgOutputListener, this);
|
|
||||||
window.set_title("waybar");
|
window.set_title("waybar");
|
||||||
window.set_name("waybar");
|
window.set_name("waybar");
|
||||||
window.set_decorated(false);
|
window.set_decorated(false);
|
||||||
window.set_resizable(false);
|
window.set_resizable(false);
|
||||||
setupConfig();
|
|
||||||
setupCss();
|
if (output->config["position"] == "right" || output->config["position"] == "left") {
|
||||||
|
height_ = 0;
|
||||||
|
width_ = 30;
|
||||||
|
}
|
||||||
|
window.set_size_request(width_, height_);
|
||||||
|
|
||||||
auto gtk_window = window.gobj();
|
auto gtk_window = window.gobj();
|
||||||
auto gtk_widget = GTK_WIDGET(gtk_window);
|
auto gtk_widget = GTK_WIDGET(gtk_window);
|
||||||
|
@ -34,87 +28,37 @@ waybar::Bar::Bar(const Client& client,
|
||||||
auto gdk_window = window.get_window()->gobj();
|
auto gdk_window = window.get_window()->gobj();
|
||||||
gdk_wayland_window_set_use_custom_surface(gdk_window);
|
gdk_wayland_window_set_use_custom_surface(gdk_window);
|
||||||
surface = gdk_wayland_window_get_wl_surface(gdk_window);
|
surface = gdk_wayland_window_get_wl_surface(gdk_window);
|
||||||
}
|
|
||||||
|
|
||||||
void waybar::Bar::initBar()
|
|
||||||
{
|
|
||||||
// Converting string to button code rn as to avoid doing it later
|
|
||||||
auto setupAltFormatKeyForModule = [this](const std::string& module_name){
|
|
||||||
if (config_.isMember(module_name)) {
|
|
||||||
Json::Value& module = config_[module_name];
|
|
||||||
if (module.isMember("format-alt")) {
|
|
||||||
if (module.isMember("format-alt-click")) {
|
|
||||||
Json::Value& click = module["format-alt-click"];
|
|
||||||
if (click.isString()) {
|
|
||||||
std::string str_click = click.asString();
|
|
||||||
|
|
||||||
if (str_click == "click-right") {
|
|
||||||
module["format-alt-click"] = 3u;
|
|
||||||
} else if (str_click == "click-middle") {
|
|
||||||
module["format-alt-click"] = 2u;
|
|
||||||
} else if (str_click == "click-backward") {
|
|
||||||
module["format-alt-click"] = 8u;
|
|
||||||
} else if (str_click == "click-forward") {
|
|
||||||
module["format-alt-click"] = 9u;
|
|
||||||
} else {
|
|
||||||
module["format-alt-click"] = 1u; // default click-left
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
module["format-alt-click"] = 1u;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
module["format-alt-click"] = 1u;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
auto setupAltFormatKeyForModuleList = [this, &setupAltFormatKeyForModule](const char* module_list_name) {
|
|
||||||
if (config_.isMember(module_list_name)) {
|
|
||||||
Json::Value& modules = config_[module_list_name];
|
|
||||||
for (const Json::Value& module_name : modules) {
|
|
||||||
if (module_name.isString()) {
|
|
||||||
setupAltFormatKeyForModule(module_name.asString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Convert to button code for every module that is used.
|
// Convert to button code for every module that is used.
|
||||||
setupAltFormatKeyForModuleList("modules-left");
|
setupAltFormatKeyForModuleList("modules-left");
|
||||||
setupAltFormatKeyForModuleList("modules-right");
|
setupAltFormatKeyForModuleList("modules-right");
|
||||||
setupAltFormatKeyForModuleList("modules-center");
|
setupAltFormatKeyForModuleList("modules-center");
|
||||||
std::size_t layer = config_["layer"] == "top"
|
std::size_t layer = output->config["layer"] == "top" ? ZWLR_LAYER_SHELL_V1_LAYER_TOP
|
||||||
? ZWLR_LAYER_SHELL_V1_LAYER_TOP : ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM;
|
: ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM;
|
||||||
layer_surface = zwlr_layer_shell_v1_get_layer_surface(
|
layer_surface = zwlr_layer_shell_v1_get_layer_surface(waybar::Client::inst()->layer_shell,
|
||||||
client.layer_shell, surface, *output, layer, "waybar");
|
surface, output->output, layer, "waybar");
|
||||||
|
|
||||||
static const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
|
static const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
|
||||||
.configure = layerSurfaceHandleConfigure,
|
.configure = layerSurfaceHandleConfigure,
|
||||||
.closed = layerSurfaceHandleClosed,
|
.closed = layerSurfaceHandleClosed,
|
||||||
};
|
};
|
||||||
zwlr_layer_surface_v1_add_listener(layer_surface, &layer_surface_listener, this);
|
zwlr_layer_surface_v1_add_listener(layer_surface, &layer_surface_listener, this);
|
||||||
|
|
||||||
if (config_["position"] == "right" || config_["position"] == "left") {
|
auto height = output->config["height"].isUInt() ? output->config["height"].asUInt() : height_;
|
||||||
height_ = 0;
|
auto width = output->config["width"].isUInt() ? output->config["width"].asUInt() : width_;
|
||||||
width_ = 30;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto height = config_["height"].isUInt() ? config_["height"].asUInt() : height_;
|
|
||||||
auto width = config_["width"].isUInt() ? config_["width"].asUInt() : width_;
|
|
||||||
|
|
||||||
std::size_t anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
|
std::size_t anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
|
||||||
if (config_["position"] == "bottom") {
|
if (output->config["position"] == "bottom") {
|
||||||
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
|
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
|
||||||
} else if (config_["position"] == "left") {
|
} else if (output->config["position"] == "left") {
|
||||||
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
|
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
|
||||||
} else if (config_["position"] == "right") {
|
} else if (output->config["position"] == "right") {
|
||||||
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
||||||
}
|
}
|
||||||
if (anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM || anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) {
|
if (anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM || anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) {
|
||||||
anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
||||||
} else if (anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT || anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT) {
|
} else if (anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT ||
|
||||||
|
anchor == ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT) {
|
||||||
anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
|
anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
|
||||||
left_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0);
|
left_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0);
|
||||||
center_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0);
|
center_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0);
|
||||||
|
@ -132,98 +76,66 @@ void waybar::Bar::initBar()
|
||||||
setupWidgets();
|
setupWidgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::Bar::handleLogicalPosition(void* /*data*/,
|
// Converting string to button code rn as to avoid doing it later
|
||||||
struct zxdg_output_v1* /*zxdg_output_v1*/, int32_t /*x*/, int32_t /*y*/)
|
void waybar::Bar::setupAltFormatKeyForModule(const std::string& module_name) {
|
||||||
{
|
if (output->config.isMember(module_name)) {
|
||||||
// Nothing here
|
Json::Value& module = output->config[module_name];
|
||||||
}
|
if (module.isMember("format-alt")) {
|
||||||
|
if (module.isMember("format-alt-click")) {
|
||||||
|
Json::Value& click = module["format-alt-click"];
|
||||||
|
if (click.isString()) {
|
||||||
|
std::string str_click = click.asString();
|
||||||
|
|
||||||
void waybar::Bar::handleLogicalSize(void* /*data*/,
|
if (str_click == "click-right") {
|
||||||
struct zxdg_output_v1* /*zxdg_output_v1*/, int32_t /*width*/,
|
module["format-alt-click"] = 3u;
|
||||||
int32_t /*height*/)
|
} else if (str_click == "click-middle") {
|
||||||
{
|
module["format-alt-click"] = 2u;
|
||||||
// Nothing here
|
} else if (str_click == "click-backward") {
|
||||||
}
|
module["format-alt-click"] = 8u;
|
||||||
|
} else if (str_click == "click-forward") {
|
||||||
void waybar::Bar::handleDone(void* /*data*/,
|
module["format-alt-click"] = 9u;
|
||||||
struct zxdg_output_v1* /*zxdg_output_v1*/)
|
} else {
|
||||||
{
|
module["format-alt-click"] = 1u; // default click-left
|
||||||
// Nothing here
|
}
|
||||||
}
|
} else {
|
||||||
|
module["format-alt-click"] = 1u;
|
||||||
bool waybar::Bar::isValidOutput(const Json::Value &config)
|
}
|
||||||
{
|
} else {
|
||||||
bool found = true;
|
module["format-alt-click"] = 1u;
|
||||||
if (config["output"].isArray()) {
|
|
||||||
bool in_array = false;
|
|
||||||
for (auto const &output : config["output"]) {
|
|
||||||
if (output.isString() && output.asString() == output_name) {
|
|
||||||
in_array = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
found = in_array;
|
|
||||||
}
|
}
|
||||||
if (config["output"].isString() && config["output"].asString() != output_name) {
|
|
||||||
found = false;
|
|
||||||
}
|
|
||||||
return found;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::Bar::handleName(void* data, struct zxdg_output_v1* /*xdg_output*/,
|
void waybar::Bar::setupAltFormatKeyForModuleList(const char* module_list_name) {
|
||||||
const char* name)
|
if (output->config.isMember(module_list_name)) {
|
||||||
{
|
Json::Value& modules = output->config[module_list_name];
|
||||||
auto o = static_cast<waybar::Bar *>(data);
|
for (const Json::Value& module_name : modules) {
|
||||||
o->output_name = name;
|
if (module_name.isString()) {
|
||||||
bool found = true;
|
setupAltFormatKeyForModule(module_name.asString());
|
||||||
if (o->config_.isArray()) {
|
|
||||||
bool in_array = false;
|
|
||||||
for (auto const &config : o->config_) {
|
|
||||||
if (config.isObject() && o->isValidOutput(config)) {
|
|
||||||
in_array = true;
|
|
||||||
o->config_ = config;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
found = in_array;
|
|
||||||
} else {
|
|
||||||
found = o->isValidOutput(o->config_);
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
wl_output_destroy(*o->output);
|
|
||||||
zxdg_output_v1_destroy(o->xdg_output_);
|
|
||||||
} else {
|
|
||||||
o->initBar();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::Bar::handleDescription(void* /*data*/,
|
void waybar::Bar::handleSignal(int signal) {
|
||||||
struct zxdg_output_v1* /*zxdg_output_v1*/, const char* /*description*/)
|
|
||||||
{
|
|
||||||
// Nothing here
|
|
||||||
}
|
|
||||||
|
|
||||||
void waybar::Bar::handleSignal(int signal)
|
|
||||||
{
|
|
||||||
for (auto& module : modules_left_) {
|
for (auto& module : modules_left_) {
|
||||||
auto* custom = dynamic_cast<waybar::modules::Custom*>(module.get());
|
auto* custom = dynamic_cast<waybar::modules::Custom*>(module.get());
|
||||||
if(custom) custom->refresh(signal);
|
if (custom) custom->refresh(signal);
|
||||||
}
|
}
|
||||||
for (auto& module : modules_center_) {
|
for (auto& module : modules_center_) {
|
||||||
auto* custom = dynamic_cast<waybar::modules::Custom*>(module.get());
|
auto* custom = dynamic_cast<waybar::modules::Custom*>(module.get());
|
||||||
if(custom) custom->refresh(signal);
|
if (custom) custom->refresh(signal);
|
||||||
}
|
}
|
||||||
for (auto& module : modules_right_) {
|
for (auto& module : modules_right_) {
|
||||||
auto* custom = dynamic_cast<waybar::modules::Custom*>(module.get());
|
auto* custom = dynamic_cast<waybar::modules::Custom*>(module.get());
|
||||||
if(custom) custom->refresh(signal);
|
if (custom) custom->refresh(signal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::Bar::layerSurfaceHandleConfigure(void* data,
|
void waybar::Bar::layerSurfaceHandleConfigure(void* data, struct zwlr_layer_surface_v1* surface,
|
||||||
struct zwlr_layer_surface_v1* surface, uint32_t serial, uint32_t width,
|
uint32_t serial, uint32_t width, uint32_t height) {
|
||||||
uint32_t height)
|
auto o = static_cast<waybar::Bar*>(data);
|
||||||
{
|
|
||||||
auto o = static_cast<waybar::Bar *>(data);
|
|
||||||
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
||||||
if (width != o->width_ || height != o->height_) {
|
if (width != o->width_ || height != o->height_) {
|
||||||
o->width_ = width;
|
o->width_ = width;
|
||||||
|
@ -234,37 +146,38 @@ void waybar::Bar::layerSurfaceHandleConfigure(void* data,
|
||||||
int min_width, min_height;
|
int min_width, min_height;
|
||||||
o->window.get_size(min_width, min_height);
|
o->window.get_size(min_width, min_height);
|
||||||
if (o->height_ < static_cast<uint32_t>(min_height)) {
|
if (o->height_ < static_cast<uint32_t>(min_height)) {
|
||||||
std::cout << fmt::format("Requested height: {} exceeds the minimum \
|
std::cout << fmt::format(
|
||||||
height: {} required by the modules", o->height_, min_height) << std::endl;
|
"Requested height: {} exceeds the minimum \
|
||||||
|
height: {} required by the modules",
|
||||||
|
o->height_, min_height)
|
||||||
|
<< std::endl;
|
||||||
o->height_ = min_height;
|
o->height_ = min_height;
|
||||||
}
|
}
|
||||||
if (o->width_ < static_cast<uint32_t>(min_width)) {
|
if (o->width_ < static_cast<uint32_t>(min_width)) {
|
||||||
std::cout << fmt::format("Requested width: {} exceeds the minimum \
|
std::cout << fmt::format(
|
||||||
width: {} required by the modules", o->height_, min_width) << std::endl;
|
"Requested width: {} exceeds the minimum \
|
||||||
|
width: {} required by the modules",
|
||||||
|
o->height_, min_width)
|
||||||
|
<< std::endl;
|
||||||
o->width_ = min_width;
|
o->width_ = min_width;
|
||||||
}
|
}
|
||||||
std::cout << fmt::format(
|
std::cout << fmt::format("Bar configured (width: {}, height: {}) for output: {}", o->width_,
|
||||||
"Bar configured (width: {}, height: {}) for output: {}",
|
o->height_, o->output->name)
|
||||||
o->width_, o->height_, o->output_name) << std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
wl_surface_commit(o->surface);
|
wl_surface_commit(o->surface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::Bar::layerSurfaceHandleClosed(void* data,
|
void waybar::Bar::layerSurfaceHandleClosed(void* data, struct zwlr_layer_surface_v1* /*surface*/) {
|
||||||
struct zwlr_layer_surface_v1* /*surface*/)
|
auto o = static_cast<waybar::Bar*>(data);
|
||||||
{
|
|
||||||
auto o = static_cast<waybar::Bar *>(data);
|
|
||||||
zwlr_layer_surface_v1_destroy(o->layer_surface);
|
zwlr_layer_surface_v1_destroy(o->layer_surface);
|
||||||
wl_output_destroy(*o->output);
|
|
||||||
zxdg_output_v1_destroy(o->xdg_output_);
|
|
||||||
o->modules_left_.clear();
|
o->modules_left_.clear();
|
||||||
o->modules_center_.clear();
|
o->modules_center_.clear();
|
||||||
o->modules_right_.clear();
|
o->modules_right_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto waybar::Bar::toggle() -> void
|
auto waybar::Bar::toggle() -> void {
|
||||||
{
|
|
||||||
visible = !visible;
|
visible = !visible;
|
||||||
auto zone = visible ? height_ : 0;
|
auto zone = visible ? height_ : 0;
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
|
@ -276,35 +189,9 @@ auto waybar::Bar::toggle() -> void
|
||||||
wl_surface_commit(surface);
|
wl_surface_commit(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto waybar::Bar::setupConfig() -> void
|
void waybar::Bar::getModules(const Factory& factory, const std::string& pos) {
|
||||||
{
|
if (output->config[pos].isArray()) {
|
||||||
std::ifstream file(client.config_file);
|
for (const auto& name : output->config[pos]) {
|
||||||
if (!file.is_open()) {
|
|
||||||
throw std::runtime_error("Can't open config file");
|
|
||||||
}
|
|
||||||
std::string str((std::istreambuf_iterator<char>(file)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
util::JsonParser parser;
|
|
||||||
config_ = parser.parse(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto waybar::Bar::setupCss() -> void
|
|
||||||
{
|
|
||||||
css_provider_ = Gtk::CssProvider::create();
|
|
||||||
style_context_ = Gtk::StyleContext::create();
|
|
||||||
|
|
||||||
// Load our css file, wherever that may be hiding
|
|
||||||
if (css_provider_->load_from_path(client.css_file)) {
|
|
||||||
Glib::RefPtr<Gdk::Screen> screen = window.get_screen();
|
|
||||||
style_context_->add_provider_for_screen(screen, css_provider_,
|
|
||||||
GTK_STYLE_PROVIDER_PRIORITY_USER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void waybar::Bar::getModules(const Factory& factory, const std::string& pos)
|
|
||||||
{
|
|
||||||
if (config_[pos].isArray()) {
|
|
||||||
for (const auto &name : config_[pos]) {
|
|
||||||
try {
|
try {
|
||||||
auto module = factory.makeModule(name.asString());
|
auto module = factory.makeModule(name.asString());
|
||||||
if (pos == "modules-left") {
|
if (pos == "modules-left") {
|
||||||
|
@ -330,14 +217,13 @@ void waybar::Bar::getModules(const Factory& factory, const std::string& pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto waybar::Bar::setupWidgets() -> void
|
auto waybar::Bar::setupWidgets() -> void {
|
||||||
{
|
|
||||||
window.add(box_);
|
window.add(box_);
|
||||||
box_.pack_start(left_, true, true);
|
box_.pack_start(left_, true, true);
|
||||||
box_.set_center_widget(center_);
|
box_.set_center_widget(center_);
|
||||||
box_.pack_end(right_, true, true);
|
box_.pack_end(right_, true, true);
|
||||||
|
|
||||||
Factory factory(*this, config_);
|
Factory factory(*this, output->config);
|
||||||
getModules(factory, "modules-left");
|
getModules(factory, "modules-left");
|
||||||
getModules(factory, "modules-center");
|
getModules(factory, "modules-center");
|
||||||
getModules(factory, "modules-right");
|
getModules(factory, "modules-right");
|
||||||
|
|
267
src/client.cpp
267
src/client.cpp
|
@ -1,25 +1,20 @@
|
||||||
#include "client.hpp"
|
#include "client.hpp"
|
||||||
#include "util/clara.hpp"
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include "util/clara.hpp"
|
||||||
|
#include "util/json.hpp"
|
||||||
|
|
||||||
waybar::Client::Client(int argc, char* argv[])
|
waybar::Client::Client() {}
|
||||||
: gtk_app(Gtk::Application::create(argc, argv, "fr.arouillard.waybar")),
|
|
||||||
gdk_display(Gdk::Display::get_default())
|
waybar::Client *waybar::Client::inst() {
|
||||||
{
|
static Client *c = new Client();
|
||||||
if (!gdk_display) {
|
return c;
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string waybar::Client::getValidPath(std::vector<std::string> paths)
|
const std::string waybar::Client::getValidPath(std::vector<std::string> paths) {
|
||||||
{
|
|
||||||
wordexp_t p;
|
wordexp_t p;
|
||||||
|
|
||||||
for (const std::string &path: paths) {
|
for (const std::string &path : paths) {
|
||||||
if (wordexp(path.c_str(), &p, 0) == 0) {
|
if (wordexp(path.c_str(), &p, 0) == 0) {
|
||||||
if (access(*p.we_wordv, F_OK) == 0) {
|
if (access(*p.we_wordv, F_OK) == 0) {
|
||||||
std::string result = *p.we_wordv;
|
std::string result = *p.we_wordv;
|
||||||
|
@ -33,77 +28,189 @@ const std::string waybar::Client::getValidPath(std::vector<std::string> paths)
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::Client::handleGlobal(void *data, struct wl_registry *registry,
|
void waybar::Client::handleGlobal(void *data, struct wl_registry *registry, uint32_t name,
|
||||||
uint32_t name, const char *interface, uint32_t version)
|
const char *interface, uint32_t version) {
|
||||||
{
|
auto client = static_cast<Client *>(data);
|
||||||
auto o = static_cast<waybar::Client *>(data);
|
|
||||||
if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
|
if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
|
||||||
o->layer_shell = static_cast<struct zwlr_layer_shell_v1 *>(
|
client->layer_shell = static_cast<struct zwlr_layer_shell_v1 *>(
|
||||||
wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, version));
|
wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, version));
|
||||||
} else if (strcmp(interface, wl_output_interface.name) == 0) {
|
} else if (strcmp(interface, wl_output_interface.name) == 0) {
|
||||||
auto output = std::make_unique<struct wl_output *>();
|
auto wl_output = static_cast<struct wl_output *>(
|
||||||
*output = static_cast<struct wl_output *>(wl_registry_bind(registry, name,
|
wl_registry_bind(registry, name, &wl_output_interface, version));
|
||||||
&wl_output_interface, version));
|
client->outputs_.emplace_back(new struct waybar_output({wl_output, "", name, nullptr}));
|
||||||
if (o->xdg_output_manager != nullptr) {
|
client->handleOutput(client->outputs_.back());
|
||||||
o->bars.emplace_back(std::make_unique<Bar>(*o, std::move(output), name));
|
|
||||||
}
|
|
||||||
} else if (strcmp(interface, wl_seat_interface.name) == 0) {
|
} else if (strcmp(interface, wl_seat_interface.name) == 0) {
|
||||||
o->seat = static_cast<struct wl_seat *>(wl_registry_bind(registry, name,
|
client->seat = static_cast<struct wl_seat *>(
|
||||||
&wl_seat_interface, version));
|
wl_registry_bind(registry, name, &wl_seat_interface, version));
|
||||||
} else if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0
|
} else if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0 &&
|
||||||
&& version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION) {
|
version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION) {
|
||||||
o->xdg_output_manager = static_cast<struct zxdg_output_manager_v1 *>(
|
client->xdg_output_manager = static_cast<struct zxdg_output_manager_v1 *>(wl_registry_bind(
|
||||||
wl_registry_bind(registry, name,
|
registry, name, &zxdg_output_manager_v1_interface, ZXDG_OUTPUT_V1_NAME_SINCE_VERSION));
|
||||||
&zxdg_output_manager_v1_interface, ZXDG_OUTPUT_V1_NAME_SINCE_VERSION));
|
|
||||||
} else if (strcmp(interface, zwp_idle_inhibit_manager_v1_interface.name) == 0) {
|
} else if (strcmp(interface, zwp_idle_inhibit_manager_v1_interface.name) == 0) {
|
||||||
o->idle_inhibit_manager = static_cast<struct zwp_idle_inhibit_manager_v1 *>(
|
waybar::Client::inst()->idle_inhibit_manager =
|
||||||
wl_registry_bind(registry, name,
|
static_cast<struct zwp_idle_inhibit_manager_v1 *>(
|
||||||
&zwp_idle_inhibit_manager_v1_interface, 1));
|
wl_registry_bind(registry, name, &zwp_idle_inhibit_manager_v1_interface, 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::Client::handleGlobalRemove(void* data,
|
void waybar::Client::handleGlobalRemove(void *data, struct wl_registry * /*registry*/,
|
||||||
struct wl_registry* /*registry*/, uint32_t name)
|
uint32_t name) {
|
||||||
{
|
auto client = static_cast<Client *>(data);
|
||||||
auto o = static_cast<waybar::Client *>(data);
|
for (auto it = client->bars.begin(); it != client->bars.end();) {
|
||||||
for (auto it = o->bars.begin(); it != o->bars.end(); ++it) {
|
if ((*it)->output->wl_name == name) {
|
||||||
if ((*it)->wl_name == name) {
|
auto output_name = (*it)->output->name;
|
||||||
auto output_name = (*it)->output_name;
|
(*it)->window.close();
|
||||||
o->bars.erase(it);
|
it = client->bars.erase(it);
|
||||||
std::cout << "Bar removed from output: " + output_name << std::endl;
|
std::cout << "Bar removed from output: " + output_name << std::endl;
|
||||||
break;
|
} else {
|
||||||
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
auto it = std::find_if(client->outputs_.begin(), client->outputs_.end(),
|
||||||
|
[&name](const auto &output) { return output->wl_name == name; });
|
||||||
|
if (it != client->outputs_.end()) {
|
||||||
|
zxdg_output_v1_destroy((*it)->xdg_output);
|
||||||
|
wl_output_destroy((*it)->output);
|
||||||
|
client->outputs_.erase(it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::Client::setupConfigs(const std::string& config, const std::string& style)
|
void waybar::Client::handleOutput(std::unique_ptr<struct waybar_output> &output) {
|
||||||
{
|
static const struct zxdg_output_v1_listener xdgOutputListener = {
|
||||||
config_file = config.empty() ? getValidPath({
|
.logical_position = handleLogicalPosition,
|
||||||
"$XDG_CONFIG_HOME/waybar/config",
|
.logical_size = handleLogicalSize,
|
||||||
"$HOME/.config/waybar/config",
|
.done = handleDone,
|
||||||
"$HOME/waybar/config",
|
.name = handleName,
|
||||||
"/etc/xdg/waybar/config",
|
.description = handleDescription,
|
||||||
"./resources/config",
|
};
|
||||||
}) : config;
|
output->xdg_output = zxdg_output_manager_v1_get_xdg_output(xdg_output_manager, output->output);
|
||||||
css_file = style.empty() ? getValidPath({
|
zxdg_output_v1_add_listener(output->xdg_output, &xdgOutputListener, &output->wl_name);
|
||||||
"$XDG_CONFIG_HOME/waybar/style.css",
|
}
|
||||||
"$HOME/.config/waybar/style.css",
|
|
||||||
"$HOME/waybar/style.css",
|
void waybar::Client::handleLogicalPosition(void * /*data*/,
|
||||||
"/etc/xdg/waybar/style.css",
|
struct zxdg_output_v1 * /*zxdg_output_v1*/,
|
||||||
"./resources/style.css",
|
int32_t /*x*/, int32_t /*y*/) {
|
||||||
}) : style;
|
// Nothing here
|
||||||
if (css_file.empty() || config_file.empty()) {
|
}
|
||||||
|
|
||||||
|
void waybar::Client::handleLogicalSize(void * /*data*/, struct zxdg_output_v1 * /*zxdg_output_v1*/,
|
||||||
|
int32_t /*width*/, int32_t /*height*/) {
|
||||||
|
// Nothing here
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::Client::handleDone(void * /*data*/, struct zxdg_output_v1 * /*zxdg_output_v1*/) {
|
||||||
|
// Nothing here
|
||||||
|
}
|
||||||
|
|
||||||
|
bool waybar::Client::isValidOutput(const Json::Value &config,
|
||||||
|
std::unique_ptr<struct waybar_output> &output) {
|
||||||
|
bool found = true;
|
||||||
|
if (config["output"].isArray()) {
|
||||||
|
bool in_array = false;
|
||||||
|
for (auto const &output_conf : config["output"]) {
|
||||||
|
if (output_conf.isString() && output_conf.asString() == output->name) {
|
||||||
|
in_array = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found = in_array;
|
||||||
|
}
|
||||||
|
if (config["output"].isString() && config["output"].asString() != output->name) {
|
||||||
|
found = false;
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::Client::handleName(void *data, struct zxdg_output_v1 * /*xdg_output*/,
|
||||||
|
const char *name) {
|
||||||
|
auto wl_name = *static_cast<uint32_t *>(data);
|
||||||
|
auto client = waybar::Client::inst();
|
||||||
|
auto it = std::find_if(client->outputs_.begin(), client->outputs_.end(),
|
||||||
|
[&wl_name](const auto &output) { return output->wl_name == wl_name; });
|
||||||
|
if (it == client->outputs_.end()) {
|
||||||
|
std::cerr << "Unable to find valid output" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
(*it)->name = name;
|
||||||
|
bool found = true;
|
||||||
|
if (client->config_.isArray()) {
|
||||||
|
bool in_array = false;
|
||||||
|
for (auto const &config : client->config_) {
|
||||||
|
if (config.isObject() && client->isValidOutput(config, *it)) {
|
||||||
|
in_array = true;
|
||||||
|
(*it)->config = config;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found = in_array;
|
||||||
|
} else {
|
||||||
|
(*it)->config = client->config_;
|
||||||
|
found = client->isValidOutput((*it)->config, *it);
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
wl_output_destroy((*it)->output);
|
||||||
|
zxdg_output_v1_destroy((*it)->xdg_output);
|
||||||
|
} else {
|
||||||
|
client->bars.emplace_back(std::make_unique<Bar>(it->get()));
|
||||||
|
Glib::RefPtr<Gdk::Screen> screen = client->bars.back()->window.get_screen();
|
||||||
|
client->style_context_->add_provider_for_screen(screen, client->css_provider_,
|
||||||
|
GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::Client::handleDescription(void * /*data*/, struct zxdg_output_v1 * /*zxdg_output_v1*/,
|
||||||
|
const char * /*description*/) {
|
||||||
|
// Nothing here
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::Client::setupConfigs(const std::string &config, const std::string &style) {
|
||||||
|
config_file_ = config.empty() ? getValidPath({
|
||||||
|
"$XDG_CONFIG_HOME/waybar/config",
|
||||||
|
"$HOME/.config/waybar/config",
|
||||||
|
"$HOME/waybar/config",
|
||||||
|
"/etc/xdg/waybar/config",
|
||||||
|
"./resources/config",
|
||||||
|
})
|
||||||
|
: config;
|
||||||
|
css_file_ = style.empty() ? getValidPath({
|
||||||
|
"$XDG_CONFIG_HOME/waybar/style.css",
|
||||||
|
"$HOME/.config/waybar/style.css",
|
||||||
|
"$HOME/waybar/style.css",
|
||||||
|
"/etc/xdg/waybar/style.css",
|
||||||
|
"./resources/style.css",
|
||||||
|
})
|
||||||
|
: style;
|
||||||
|
if (css_file_.empty() || config_file_.empty()) {
|
||||||
throw std::runtime_error("Missing required resources files");
|
throw std::runtime_error("Missing required resources files");
|
||||||
}
|
}
|
||||||
std::cout << "Resources files: " + config_file + ", " + css_file << std::endl;
|
std::cout << "Resources files: " + config_file_ + ", " + css_file_ << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::Client::bindInterfaces()
|
auto waybar::Client::setupConfig() -> void {
|
||||||
{
|
std::ifstream file(config_file_);
|
||||||
|
if (!file.is_open()) {
|
||||||
|
throw std::runtime_error("Can't open config file");
|
||||||
|
}
|
||||||
|
std::string str((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
||||||
|
util::JsonParser parser;
|
||||||
|
config_ = parser.parse(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto waybar::Client::setupCss() -> void {
|
||||||
|
css_provider_ = Gtk::CssProvider::create();
|
||||||
|
style_context_ = Gtk::StyleContext::create();
|
||||||
|
|
||||||
|
// Load our css file, wherever that may be hiding
|
||||||
|
if (!css_provider_->load_from_path(css_file_)) {
|
||||||
|
throw std::runtime_error("Can't open style file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::Client::bindInterfaces() {
|
||||||
registry = wl_display_get_registry(wl_display);
|
registry = wl_display_get_registry(wl_display);
|
||||||
static const struct wl_registry_listener registry_listener = {
|
static const struct wl_registry_listener registry_listener = {
|
||||||
.global = handleGlobal,
|
.global = handleGlobal,
|
||||||
.global_remove = handleGlobalRemove,
|
.global_remove = handleGlobalRemove,
|
||||||
};
|
};
|
||||||
wl_registry_add_listener(registry, ®istry_listener, this);
|
wl_registry_add_listener(registry, ®istry_listener, this);
|
||||||
wl_display_roundtrip(wl_display);
|
wl_display_roundtrip(wl_display);
|
||||||
|
@ -113,18 +220,26 @@ void waybar::Client::bindInterfaces()
|
||||||
wl_display_roundtrip(wl_display);
|
wl_display_roundtrip(wl_display);
|
||||||
}
|
}
|
||||||
|
|
||||||
int waybar::Client::main(int argc, char* argv[])
|
int waybar::Client::main(int argc, char *argv[]) {
|
||||||
{
|
gtk_app = Gtk::Application::create(argc, argv, "fr.arouillard.waybar");
|
||||||
|
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());
|
||||||
bool show_help = false;
|
bool show_help = false;
|
||||||
bool show_version = false;
|
bool show_version = false;
|
||||||
std::string config;
|
std::string config;
|
||||||
std::string style;
|
std::string style;
|
||||||
std::string bar_id;
|
std::string bar_id;
|
||||||
auto cli = clara::detail::Help(show_help)
|
auto cli = clara::detail::Help(show_help) |
|
||||||
| clara::detail::Opt(show_version)["-v"]["--version"]("Show version")
|
clara::detail::Opt(show_version)["-v"]["--version"]("Show version") |
|
||||||
| clara::detail::Opt(config, "config")["-c"]["--config"]("Config path")
|
clara::detail::Opt(config, "config")["-c"]["--config"]("Config path") |
|
||||||
| clara::detail::Opt(style, "style")["-s"]["--style"]("Style path")
|
clara::detail::Opt(style, "style")["-s"]["--style"]("Style path") |
|
||||||
| clara::detail::Opt(bar_id, "id")["-b"]["--bar"]("Bar id");
|
clara::detail::Opt(bar_id, "id")["-b"]["--bar"]("Bar id");
|
||||||
auto res = cli.parse(clara::detail::Args(argc, argv));
|
auto res = cli.parse(clara::detail::Args(argc, argv));
|
||||||
if (!res) {
|
if (!res) {
|
||||||
std::cerr << "Error in command line: " << res.errorMessage() << std::endl;
|
std::cerr << "Error in command line: " << res.errorMessage() << std::endl;
|
||||||
|
@ -139,6 +254,8 @@ int waybar::Client::main(int argc, char* argv[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
setupConfigs(config, style);
|
setupConfigs(config, style);
|
||||||
|
setupConfig();
|
||||||
|
setupCss();
|
||||||
bindInterfaces();
|
bindInterfaces();
|
||||||
gtk_app->hold();
|
gtk_app->hold();
|
||||||
gtk_app->run();
|
gtk_app->run();
|
||||||
|
|
19
src/main.cpp
19
src/main.cpp
|
@ -2,31 +2,26 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "client.hpp"
|
#include "client.hpp"
|
||||||
|
|
||||||
namespace waybar {
|
|
||||||
|
|
||||||
static Client* client;
|
|
||||||
|
|
||||||
} // namespace waybar
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
try {
|
try {
|
||||||
waybar::Client c(argc, argv);
|
auto client = waybar::Client::inst();
|
||||||
waybar::client = &c;
|
|
||||||
std::signal(SIGUSR1, [](int /*signal*/) {
|
std::signal(SIGUSR1, [](int /*signal*/) {
|
||||||
for (auto& bar : waybar::client->bars) {
|
for (auto& bar : waybar::Client::inst()->bars) {
|
||||||
bar->toggle();
|
bar->toggle();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
for (int sig = SIGRTMIN + 1; sig <= SIGRTMAX; ++sig) {
|
for (int sig = SIGRTMIN + 1; sig <= SIGRTMAX; ++sig) {
|
||||||
std::signal(sig, [](int sig /*signal*/) {
|
std::signal(sig, [](int sig) {
|
||||||
for (auto& bar : waybar::client->bars) {
|
for (auto& bar : waybar::Client::inst()->bars) {
|
||||||
bar->handleSignal(sig);
|
bar->handleSignal(sig);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.main(argc, argv);
|
auto ret = client->main(argc, argv);
|
||||||
|
delete client;
|
||||||
|
return ret;
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#include "modules/idle_inhibitor.hpp"
|
#include "modules/idle_inhibitor.hpp"
|
||||||
#include "util/command.hpp"
|
#include "util/command.hpp"
|
||||||
|
|
||||||
waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar& bar, const Json::Value& config)
|
waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar& bar,
|
||||||
: ALabel(config, "{status}"), bar_(bar), status_("deactivated"), idle_inhibitor_(nullptr)
|
const Json::Value& config)
|
||||||
{
|
: ALabel(config, "{status}"), bar_(bar), status_("deactivated"), idle_inhibitor_(nullptr) {
|
||||||
label_.set_name("idle_inhibitor");
|
label_.set_name("idle_inhibitor");
|
||||||
if (!id.empty()) {
|
if (!id.empty()) {
|
||||||
label_.get_style_context()->add_class(id);
|
label_.get_style_context()->add_class(id);
|
||||||
|
@ -14,21 +14,18 @@ waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar&
|
||||||
dp.emit();
|
dp.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
waybar::modules::IdleInhibitor::~IdleInhibitor()
|
waybar::modules::IdleInhibitor::~IdleInhibitor() {
|
||||||
{
|
if (idle_inhibitor_) {
|
||||||
if(idle_inhibitor_) {
|
|
||||||
zwp_idle_inhibitor_v1_destroy(idle_inhibitor_);
|
zwp_idle_inhibitor_v1_destroy(idle_inhibitor_);
|
||||||
idle_inhibitor_ = nullptr;
|
idle_inhibitor_ = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto waybar::modules::IdleInhibitor::update() -> void
|
auto waybar::modules::IdleInhibitor::update() -> void {
|
||||||
{
|
|
||||||
label_.set_markup(
|
label_.set_markup(
|
||||||
fmt::format(format_, fmt::arg("status", status_),
|
fmt::format(format_, fmt::arg("status", status_), fmt::arg("icon", getIcon(0, status_))));
|
||||||
fmt::arg("icon", getIcon(0, status_))));
|
|
||||||
label_.get_style_context()->add_class(status_);
|
label_.get_style_context()->add_class(status_);
|
||||||
if(tooltipEnabled()) {
|
if (tooltipEnabled()) {
|
||||||
label_.set_tooltip_text(status_);
|
label_.set_tooltip_text(status_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,10 +36,10 @@ bool waybar::modules::IdleInhibitor::handleToggle(GdkEventButton* const& e) {
|
||||||
if (idle_inhibitor_) {
|
if (idle_inhibitor_) {
|
||||||
zwp_idle_inhibitor_v1_destroy(idle_inhibitor_);
|
zwp_idle_inhibitor_v1_destroy(idle_inhibitor_);
|
||||||
idle_inhibitor_ = nullptr;
|
idle_inhibitor_ = nullptr;
|
||||||
status_ = "deactivated";
|
status_ = "deactivated";
|
||||||
} else {
|
} else {
|
||||||
idle_inhibitor_ = zwp_idle_inhibit_manager_v1_create_inhibitor(
|
idle_inhibitor_ = zwp_idle_inhibit_manager_v1_create_inhibitor(
|
||||||
bar_.client.idle_inhibit_manager, bar_.surface);
|
waybar::Client::inst()->idle_inhibit_manager, bar_.surface);
|
||||||
status_ = "activated";
|
status_ = "activated";
|
||||||
}
|
}
|
||||||
if (config_["on-click"].isString() && e->button == 1) {
|
if (config_["on-click"].isString() && e->button == 1) {
|
||||||
|
|
|
@ -72,7 +72,7 @@ void waybar::modules::Network::createInfoSocket()
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
ev_fd_ = eventfd(0, EFD_NONBLOCK);
|
ev_fd_ = eventfd(0, EFD_NONBLOCK);
|
||||||
struct epoll_event event;
|
struct epoll_event event = {0};
|
||||||
event.events = EPOLLIN | EPOLLET;
|
event.events = EPOLLIN | EPOLLET;
|
||||||
event.data.fd = ev_fd_;
|
event.data.fd = ev_fd_;
|
||||||
if (epoll_ctl(efd_, EPOLL_CTL_ADD, ev_fd_, &event) == -1) {
|
if (epoll_ctl(efd_, EPOLL_CTL_ADD, ev_fd_, &event) == -1) {
|
||||||
|
@ -81,7 +81,7 @@ void waybar::modules::Network::createInfoSocket()
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto fd = nl_socket_get_fd(info_sock_);
|
auto fd = nl_socket_get_fd(info_sock_);
|
||||||
struct epoll_event event;
|
struct epoll_event event = {0};
|
||||||
event.events = EPOLLIN | EPOLLET | EPOLLRDHUP;
|
event.events = EPOLLIN | EPOLLET | EPOLLRDHUP;
|
||||||
event.data.fd = fd;
|
event.data.fd = fd;
|
||||||
if (epoll_ctl(efd_, EPOLL_CTL_ADD, fd, &event) == -1) {
|
if (epoll_ctl(efd_, EPOLL_CTL_ADD, fd, &event) == -1) {
|
||||||
|
@ -114,7 +114,7 @@ void waybar::modules::Network::worker()
|
||||||
}
|
}
|
||||||
thread_timer_.sleep_for(interval_);
|
thread_timer_.sleep_for(interval_);
|
||||||
};
|
};
|
||||||
struct epoll_event events[EPOLL_MAX];
|
struct epoll_event events[EPOLL_MAX] = {{0}};
|
||||||
thread_ = [this, &events] {
|
thread_ = [this, &events] {
|
||||||
int ec = epoll_wait(efd_, events, EPOLL_MAX, -1);
|
int ec = epoll_wait(efd_, events, EPOLL_MAX, -1);
|
||||||
if (ec > 0) {
|
if (ec > 0) {
|
||||||
|
|
|
@ -16,7 +16,19 @@ Host::Host(const std::size_t id, const Json::Value& config,
|
||||||
on_add_(on_add),
|
on_add_(on_add),
|
||||||
on_remove_(on_remove) {}
|
on_remove_(on_remove) {}
|
||||||
|
|
||||||
Host::~Host() { Gio::DBus::unwatch_name(bus_name_id_); }
|
Host::~Host() {
|
||||||
|
if (bus_name_id_ > 0) {
|
||||||
|
Gio::DBus::unwatch_name(bus_name_id_);
|
||||||
|
bus_name_id_ = 0;
|
||||||
|
}
|
||||||
|
if (watcher_id_ > 0) {
|
||||||
|
Gio::DBus::unwatch_name(watcher_id_);
|
||||||
|
watcher_id_ = 0;
|
||||||
|
}
|
||||||
|
g_cancellable_cancel(cancellable_);
|
||||||
|
g_clear_object(&cancellable_);
|
||||||
|
g_clear_object(&watcher_);
|
||||||
|
}
|
||||||
|
|
||||||
void Host::busAcquired(const Glib::RefPtr<Gio::DBus::Connection>& conn, Glib::ustring name) {
|
void Host::busAcquired(const Glib::RefPtr<Gio::DBus::Connection>& conn, Glib::ustring name) {
|
||||||
watcher_id_ = Gio::DBus::watch_name(conn, "org.kde.StatusNotifierWatcher",
|
watcher_id_ = Gio::DBus::watch_name(conn, "org.kde.StatusNotifierWatcher",
|
||||||
|
|
|
@ -8,7 +8,6 @@ waybar::modules::SNI::Tray::Tray(const std::string& id, const Bar& bar, const Js
|
||||||
watcher_(),
|
watcher_(),
|
||||||
host_(nb_hosts_, config, std::bind(&Tray::onAdd, this, std::placeholders::_1),
|
host_(nb_hosts_, config, std::bind(&Tray::onAdd, this, std::placeholders::_1),
|
||||||
std::bind(&Tray::onRemove, this, std::placeholders::_1)) {
|
std::bind(&Tray::onRemove, this, std::placeholders::_1)) {
|
||||||
std::cout << "Tray is in beta, so there may be bugs or even be unusable." << std::endl;
|
|
||||||
if (config_["spacing"].isUInt()) {
|
if (config_["spacing"].isUInt()) {
|
||||||
box_.set_spacing(config_["spacing"].asUInt());
|
box_.set_spacing(config_["spacing"].asUInt());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#include "modules/sway/workspaces.hpp"
|
#include "modules/sway/workspaces.hpp"
|
||||||
|
|
||||||
waybar::modules::sway::Workspaces::Workspaces(const std::string& id, const Bar& bar,
|
waybar::modules::sway::Workspaces::Workspaces(const std::string &id, const Bar &bar,
|
||||||
const Json::Value& config)
|
const Json::Value &config)
|
||||||
: bar_(bar), config_(config),
|
: bar_(bar),
|
||||||
box_(bar.vertical ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL, 0),
|
config_(config),
|
||||||
scrolling_(false)
|
box_(bar.vertical ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL, 0),
|
||||||
{
|
scrolling_(false) {
|
||||||
box_.set_name("workspaces");
|
box_.set_name("workspaces");
|
||||||
if (!id.empty()) {
|
if (!id.empty()) {
|
||||||
box_.get_style_context()->add_class(id);
|
box_.get_style_context()->add_class(id);
|
||||||
|
@ -15,8 +15,7 @@ waybar::modules::sway::Workspaces::Workspaces(const std::string& id, const Bar&
|
||||||
worker();
|
worker();
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::modules::sway::Workspaces::worker()
|
void waybar::modules::sway::Workspaces::worker() {
|
||||||
{
|
|
||||||
thread_ = [this] {
|
thread_ = [this] {
|
||||||
try {
|
try {
|
||||||
if (!workspaces_.empty()) {
|
if (!workspaces_.empty()) {
|
||||||
|
@ -24,36 +23,35 @@ void waybar::modules::sway::Workspaces::worker()
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
auto res = ipc_.sendCmd(IPC_GET_WORKSPACES);
|
auto res = ipc_.sendCmd(IPC_GET_WORKSPACES);
|
||||||
if (thread_.isRunning()) {
|
if (thread_.isRunning()) {
|
||||||
workspaces_ = parser_.parse(res.payload);
|
workspaces_ = parser_.parse(res.payload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dp.emit();
|
dp.emit();
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception &e) {
|
||||||
std::cerr << "Workspaces: " << e.what() << std::endl;
|
std::cerr << "Workspaces: " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto waybar::modules::sway::Workspaces::update() -> void
|
auto waybar::modules::sway::Workspaces::update() -> void {
|
||||||
{
|
bool needReorder = false;
|
||||||
bool needReorder = false;
|
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
for (auto it = buttons_.begin(); it != buttons_.end();) {
|
for (auto it = buttons_.begin(); it != buttons_.end();) {
|
||||||
auto ws = std::find_if(workspaces_.begin(), workspaces_.end(),
|
auto ws = std::find_if(workspaces_.begin(), workspaces_.end(), [it](auto node) -> bool {
|
||||||
[it](auto node) -> bool { return node["name"].asString() == it->first; });
|
return node["name"].asString() == it->first;
|
||||||
|
});
|
||||||
if (ws == workspaces_.end() ||
|
if (ws == workspaces_.end() ||
|
||||||
(!config_["all-outputs"].asBool() && (*ws)["output"].asString() != bar_.output_name)) {
|
(!config_["all-outputs"].asBool() && (*ws)["output"].asString() != bar_.output->name)) {
|
||||||
it = buttons_.erase(it);
|
it = buttons_.erase(it);
|
||||||
needReorder = true;
|
needReorder = true;
|
||||||
} else {
|
} else {
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto const& node : workspaces_) {
|
for (auto const &node : workspaces_) {
|
||||||
if (!config_["all-outputs"].asBool()
|
if (!config_["all-outputs"].asBool() && bar_.output->name != node["output"].asString()) {
|
||||||
&& bar_.output_name != node["output"].asString()) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto it = buttons_.find(node["name"].asString());
|
auto it = buttons_.find(node["name"].asString());
|
||||||
|
@ -80,16 +78,17 @@ auto waybar::modules::sway::Workspaces::update() -> void
|
||||||
if (needReorder) {
|
if (needReorder) {
|
||||||
box_.reorder_child(button, getWorkspaceIndex(node["name"].asString()));
|
box_.reorder_child(button, getWorkspaceIndex(node["name"].asString()));
|
||||||
}
|
}
|
||||||
auto icon = getIcon(node["name"].asString(), node);
|
auto icon = getIcon(node["name"].asString(), node);
|
||||||
std::string output = icon;
|
std::string output = icon;
|
||||||
if (config_["format"].isString()) {
|
if (config_["format"].isString()) {
|
||||||
auto format = config_["format"].asString();
|
auto format = config_["format"].asString();
|
||||||
output = fmt::format(format, fmt::arg("icon", icon),
|
output = fmt::format(format,
|
||||||
fmt::arg("name", trimWorkspaceName(node["name"].asString())),
|
fmt::arg("icon", icon),
|
||||||
fmt::arg("index", node["num"].asString()));
|
fmt::arg("name", trimWorkspaceName(node["name"].asString())),
|
||||||
|
fmt::arg("index", node["num"].asString()));
|
||||||
}
|
}
|
||||||
if (!config_["disable-markup"].asBool()) {
|
if (!config_["disable-markup"].asBool()) {
|
||||||
static_cast<Gtk::Label*>(button.get_children()[0])->set_markup(output);
|
static_cast<Gtk::Label *>(button.get_children()[0])->set_markup(output);
|
||||||
} else {
|
} else {
|
||||||
button.set_label(output);
|
button.set_label(output);
|
||||||
}
|
}
|
||||||
|
@ -101,34 +100,33 @@ auto waybar::modules::sway::Workspaces::update() -> void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::modules::sway::Workspaces::addWorkspace(const Json::Value &node)
|
void waybar::modules::sway::Workspaces::addWorkspace(const Json::Value &node) {
|
||||||
{
|
auto icon = getIcon(node["name"].asString(), node);
|
||||||
auto icon = getIcon(node["name"].asString(), node);
|
|
||||||
auto format = config_["format"].isString()
|
auto format = config_["format"].isString()
|
||||||
? fmt::format(config_["format"].asString(), fmt::arg("icon", icon),
|
? fmt::format(config_["format"].asString(),
|
||||||
fmt::arg("name", trimWorkspaceName(node["name"].asString())),
|
fmt::arg("icon", icon),
|
||||||
fmt::arg("index", node["num"].asString()))
|
fmt::arg("name", trimWorkspaceName(node["name"].asString())),
|
||||||
: icon;
|
fmt::arg("index", node["num"].asString()))
|
||||||
auto pair = buttons_.emplace(node["name"].asString(), format);
|
: icon;
|
||||||
|
auto pair = buttons_.emplace(node["name"].asString(), format);
|
||||||
auto &button = pair.first->second;
|
auto &button = pair.first->second;
|
||||||
if (!config_["disable-markup"].asBool()) {
|
if (!config_["disable-markup"].asBool()) {
|
||||||
static_cast<Gtk::Label*>(button.get_children()[0])->set_markup(format);
|
static_cast<Gtk::Label *>(button.get_children()[0])->set_markup(format);
|
||||||
}
|
}
|
||||||
box_.pack_start(button, false, false, 0);
|
box_.pack_start(button, false, false, 0);
|
||||||
button.set_relief(Gtk::RELIEF_NONE);
|
button.set_relief(Gtk::RELIEF_NONE);
|
||||||
button.signal_clicked().connect([this, pair] {
|
button.signal_clicked().connect([this, pair] {
|
||||||
try {
|
try {
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
auto cmd = fmt::format("workspace \"{}\"", pair.first->first);
|
auto cmd = fmt::format("workspace \"{}\"", pair.first->first);
|
||||||
ipc_.sendCmd(IPC_COMMAND, cmd);
|
ipc_.sendCmd(IPC_COMMAND, cmd);
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception &e) {
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!config_["disable-scroll"].asBool()) {
|
if (!config_["disable-scroll"].asBool()) {
|
||||||
button.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK);
|
button.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK);
|
||||||
button.signal_scroll_event()
|
button.signal_scroll_event().connect(sigc::mem_fun(*this, &Workspaces::handleScroll));
|
||||||
.connect(sigc::mem_fun(*this, &Workspaces::handleScroll));
|
|
||||||
}
|
}
|
||||||
box_.reorder_child(button, getWorkspaceIndex(node["name"].asString()));
|
box_.reorder_child(button, getWorkspaceIndex(node["name"].asString()));
|
||||||
if (node["focused"].asBool()) {
|
if (node["focused"].asBool()) {
|
||||||
|
@ -141,14 +139,13 @@ void waybar::modules::sway::Workspaces::addWorkspace(const Json::Value &node)
|
||||||
button.get_style_context()->add_class("urgent");
|
button.get_style_context()->add_class("urgent");
|
||||||
}
|
}
|
||||||
|
|
||||||
onButtonReady(node, button);
|
onButtonReady(node, button);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string waybar::modules::sway::Workspaces::getIcon(const std::string &name,
|
std::string waybar::modules::sway::Workspaces::getIcon(const std::string &name,
|
||||||
const Json::Value &node)
|
const Json::Value &node) {
|
||||||
{
|
std::vector<std::string> keys = {name, "urgent", "focused", "visible", "default"};
|
||||||
std::vector<std::string> keys = { 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].isString() && node[key].asBool()) {
|
if (config_["format-icons"][key].isString() && node[key].asBool()) {
|
||||||
return config_["format-icons"][key].asString();
|
return config_["format-icons"][key].asString();
|
||||||
|
@ -160,14 +157,13 @@ std::string waybar::modules::sway::Workspaces::getIcon(const std::string &name,
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool waybar::modules::sway::Workspaces::handleScroll(GdkEventScroll *e)
|
bool waybar::modules::sway::Workspaces::handleScroll(GdkEventScroll *e) {
|
||||||
{
|
|
||||||
// Avoid concurrent scroll event
|
// Avoid concurrent scroll event
|
||||||
if (scrolling_) {
|
if (scrolling_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
uint8_t idx;
|
uint8_t idx;
|
||||||
scrolling_ = true;
|
scrolling_ = true;
|
||||||
for (idx = 0; idx < workspaces_.size(); idx += 1) {
|
for (idx = 0; idx < workspaces_.size(); idx += 1) {
|
||||||
if (workspaces_[idx]["focused"].asBool()) {
|
if (workspaces_[idx]["focused"].asBool()) {
|
||||||
|
@ -180,15 +176,14 @@ bool waybar::modules::sway::Workspaces::handleScroll(GdkEventScroll *e)
|
||||||
}
|
}
|
||||||
std::string name;
|
std::string name;
|
||||||
if (e->direction == GDK_SCROLL_UP) {
|
if (e->direction == GDK_SCROLL_UP) {
|
||||||
name = getCycleWorkspace(idx, true);
|
name = getCycleWorkspace(idx, true);
|
||||||
}
|
}
|
||||||
if (e->direction == GDK_SCROLL_DOWN) {
|
if (e->direction == GDK_SCROLL_DOWN) {
|
||||||
name = getCycleWorkspace(idx, false);
|
name = getCycleWorkspace(idx, false);
|
||||||
}
|
}
|
||||||
if (e->direction == GDK_SCROLL_SMOOTH) {
|
if (e->direction == GDK_SCROLL_SMOOTH) {
|
||||||
gdouble delta_x, delta_y;
|
gdouble delta_x, delta_y;
|
||||||
gdk_event_get_scroll_deltas(reinterpret_cast<const GdkEvent *>(e),
|
gdk_event_get_scroll_deltas(reinterpret_cast<const GdkEvent *>(e), &delta_x, &delta_y);
|
||||||
&delta_x, &delta_y);
|
|
||||||
if (delta_y < 0) {
|
if (delta_y < 0) {
|
||||||
name = getCycleWorkspace(idx, true);
|
name = getCycleWorkspace(idx, true);
|
||||||
} else if (delta_y > 0) {
|
} else if (delta_y > 0) {
|
||||||
|
@ -204,17 +199,17 @@ bool waybar::modules::sway::Workspaces::handleScroll(GdkEventScroll *e)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string waybar::modules::sway::Workspaces::getCycleWorkspace(
|
const std::string waybar::modules::sway::Workspaces::getCycleWorkspace(uint8_t focused_workspace,
|
||||||
uint8_t focused_workspace, bool prev) const
|
bool prev) const {
|
||||||
{
|
auto inc = prev ? -1 : 1;
|
||||||
auto inc = prev ? -1 : 1;
|
int size = workspaces_.size();
|
||||||
int size = workspaces_.size();
|
uint8_t idx = 0;
|
||||||
uint8_t idx = 0;
|
|
||||||
for (int i = focused_workspace; i < size && i >= 0; i += inc) {
|
for (int i = focused_workspace; i < size && i >= 0; i += inc) {
|
||||||
bool same_output = (workspaces_[i]["output"].asString() == bar_.output_name
|
bool same_output = (workspaces_[i]["output"].asString() == bar_.output->name &&
|
||||||
&& !config_["all-outputs"].asBool()) || config_["all-outputs"].asBool();
|
!config_["all-outputs"].asBool()) ||
|
||||||
|
config_["all-outputs"].asBool();
|
||||||
bool same_name =
|
bool same_name =
|
||||||
workspaces_[i]["name"].asString() == workspaces_[focused_workspace]["name"].asString();
|
workspaces_[i]["name"].asString() == workspaces_[focused_workspace]["name"].asString();
|
||||||
if (same_output && !same_name) {
|
if (same_output && !same_name) {
|
||||||
return workspaces_[i]["name"].asString();
|
return workspaces_[i]["name"].asString();
|
||||||
}
|
}
|
||||||
|
@ -230,42 +225,39 @@ const std::string waybar::modules::sway::Workspaces::getCycleWorkspace(
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t waybar::modules::sway::Workspaces::getWorkspaceIndex(const std::string &name) const
|
uint16_t waybar::modules::sway::Workspaces::getWorkspaceIndex(const std::string &name) const {
|
||||||
{
|
|
||||||
uint16_t idx = 0;
|
uint16_t idx = 0;
|
||||||
for (const auto &workspace : workspaces_) {
|
for (const auto &workspace : workspaces_) {
|
||||||
if (workspace["name"].asString() == name) {
|
if (workspace["name"].asString() == name) {
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
if (!(!config_["all-outputs"].asBool() && workspace["output"].asString() != bar_.output_name)) {
|
if (!(!config_["all-outputs"].asBool() &&
|
||||||
|
workspace["output"].asString() != bar_.output->name)) {
|
||||||
idx += 1;
|
idx += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return workspaces_.size();
|
return workspaces_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string waybar::modules::sway::Workspaces::trimWorkspaceName(std::string name)
|
std::string waybar::modules::sway::Workspaces::trimWorkspaceName(std::string name) {
|
||||||
{
|
|
||||||
std::size_t found = name.find(":");
|
std::size_t found = name.find(":");
|
||||||
if (found!=std::string::npos) {
|
if (found != std::string::npos) {
|
||||||
return name.substr(found+1);
|
return name.substr(found + 1);
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::modules::sway::Workspaces::onButtonReady(const Json::Value& node, Gtk::Button& button)
|
void waybar::modules::sway::Workspaces::onButtonReady(const Json::Value &node,
|
||||||
{
|
Gtk::Button & button) {
|
||||||
if (config_["current-only"].asBool()) {
|
if (config_["current-only"].asBool()) {
|
||||||
if (node["focused"].asBool()) {
|
if (node["focused"].asBool()) {
|
||||||
button.show();
|
button.show();
|
||||||
} else {
|
} else {
|
||||||
button.hide();
|
button.hide();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
button.show();
|
button.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
waybar::modules::sway::Workspaces::operator Gtk::Widget &() {
|
waybar::modules::sway::Workspaces::operator Gtk::Widget &() { return box_; }
|
||||||
return box_;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue