From 2b3d7be9cb7253d852db0214f7c492d6aec8f74a Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Tue, 20 Oct 2020 23:18:58 -0700 Subject: [PATCH 1/9] feat(bar): let gtk-layer-shell manage exclusive zone Previous attempts to use auto exclusive zone from gtk-layer-shell failed because gls was expecting real booleans (`TRUE`/`FALSE`) as set_anchor arguments. With that being fixed, gtk_layer_auto_exclusive_zone_enable makes gls handle everything related to the bar resizing. The only remaining purpose of onConfigureGLS is to log warnings and bar size changes; gtk-layer-shell code path no longer needs saved width_ or height_ values. --- src/bar.cpp | 72 ++++++++++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/src/bar.cpp b/src/bar.cpp index 8af6b971..7f60b2fc 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -2,10 +2,11 @@ #include #endif +#include + #include "bar.hpp" #include "client.hpp" #include "factory.hpp" -#include waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) : output(w_output), @@ -134,33 +135,32 @@ void waybar::Bar::initGtkLayerShell() { gtk_layer_set_monitor(gtk_window, output->monitor->gobj()); gtk_layer_set_namespace(gtk_window, "waybar"); - gtk_layer_set_anchor( - gtk_window, GTK_LAYER_SHELL_EDGE_LEFT, anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT); - gtk_layer_set_anchor( - gtk_window, GTK_LAYER_SHELL_EDGE_RIGHT, anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT); - gtk_layer_set_anchor( - gtk_window, GTK_LAYER_SHELL_EDGE_TOP, anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP); - gtk_layer_set_anchor( - gtk_window, GTK_LAYER_SHELL_EDGE_BOTTOM, anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM); + gtk_layer_set_anchor(gtk_window, + GTK_LAYER_SHELL_EDGE_LEFT, + (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT) ? TRUE : FALSE); + gtk_layer_set_anchor(gtk_window, + GTK_LAYER_SHELL_EDGE_RIGHT, + (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT) ? TRUE : FALSE); + gtk_layer_set_anchor(gtk_window, + GTK_LAYER_SHELL_EDGE_TOP, + (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) ? TRUE : FALSE); + gtk_layer_set_anchor(gtk_window, + GTK_LAYER_SHELL_EDGE_BOTTOM, + (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM) ? TRUE : FALSE); gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_LEFT, margins_.left); gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_RIGHT, margins_.right); gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_TOP, margins_.top); gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_BOTTOM, margins_.bottom); - if (width_ > 1 && height_ > 1) { - /* configure events are not emitted if the bar is using initial size */ - setExclusiveZone(width_, height_); - } + setExclusiveZone(width_, height_); } void waybar::Bar::onConfigureGLS(GdkEventConfigure* ev) { /* * GTK wants new size for the window. - * Actual resizing is done within the gtk-layer-shell code; the only remaining action is to apply - * exclusive zone. - * gtk_layer_auto_exclusive_zone_enable() could handle even that, but at the cost of ignoring - * margins on unanchored edge. + * Actual resizing and management of the exclusve zone is handled within the gtk-layer-shell code. + * This event handler only updates stored size of the window and prints some warnings. * * Note: forced resizing to a window smaller than required by GTK would not work with * gtk-layer-shell. @@ -170,14 +170,13 @@ void waybar::Bar::onConfigureGLS(GdkEventConfigure* ev) { spdlog::warn(MIN_WIDTH_MSG, width_, ev->width); } } else { - if (!vertical && height_ > 1 && ev->height > static_cast(height_)) { + if (height_ > 1 && ev->height > static_cast(height_)) { spdlog::warn(MIN_HEIGHT_MSG, height_, ev->height); } } width_ = ev->width; height_ = ev->height; spdlog::info(BAR_SIZE_MSG, width_, height_, output->name); - setExclusiveZone(width_, height_); } void waybar::Bar::onMapGLS(GdkEventAny* ev) { @@ -262,26 +261,31 @@ void waybar::Bar::onMap(GdkEventAny* ev) { } void waybar::Bar::setExclusiveZone(uint32_t width, uint32_t height) { - auto zone = 0; - if (visible) { - // exclusive zone already includes margin for anchored edge, - // only opposite margin should be added - if (vertical) { - zone += width; - zone += (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT) ? margins_.right : margins_.left; - } else { - zone += height; - zone += (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) ? margins_.bottom : margins_.top; - } - } - spdlog::debug("Set exclusive zone {} for output {}", zone, output->name); - #ifdef HAVE_GTK_LAYER_SHELL if (use_gls_) { - gtk_layer_set_exclusive_zone(window.gobj(), zone); + if (visible) { + spdlog::debug("Enable auto exclusive zone for output {}", output->name); + gtk_layer_auto_exclusive_zone_enable(window.gobj()); + } else { + spdlog::debug("Disable exclusive zone for output {}", output->name); + gtk_layer_set_exclusive_zone(window.gobj(), 0); + } } else #endif { + auto zone = 0; + if (visible) { + // exclusive zone already includes margin for anchored edge, + // only opposite margin should be added + if (vertical) { + zone += width; + zone += (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT) ? margins_.right : margins_.left; + } else { + zone += height; + zone += (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) ? margins_.bottom : margins_.top; + } + } + spdlog::debug("Set exclusive zone {} for output {}", zone, output->name); zwlr_layer_surface_v1_set_exclusive_zone(layer_surface_, zone); } } From 7735c80d0e421ab0787f99db6c269895ef856729 Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Wed, 21 Oct 2020 22:16:12 -0700 Subject: [PATCH 2/9] refactor(bar): Split GLS and raw layer-shell implementations Extract two surface implementations from the bar class: GLSSurfaceImpl and RawSurfaceImpl. This change allowed to remove _all_ surface type conditionals and significantly simplify the Bar code. The change also applies PImpl pattern to the Bar, allowing to remove some headers and fields from `bar.hpp`. --- include/bar.hpp | 62 ++--- src/bar.cpp | 644 ++++++++++++++++++++++++++++-------------------- 2 files changed, 408 insertions(+), 298 deletions(-) diff --git a/include/bar.hpp b/include/bar.hpp index fdc5a739..df503275 100644 --- a/include/bar.hpp +++ b/include/bar.hpp @@ -7,6 +7,7 @@ #include #include #include + #include "AModule.hpp" #include "idle-inhibit-unstable-v1-client-protocol.h" #include "wlr-layer-shell-unstable-v1-client-protocol.h" @@ -23,13 +24,35 @@ struct waybar_output { nullptr, &zxdg_output_v1_destroy}; }; +struct bar_margins { + int top = 0; + int right = 0; + int bottom = 0; + int left = 0; +}; + +class BarSurface { + protected: + BarSurface() = default; + + public: + virtual void set_exclusive_zone(bool enable) = 0; + virtual void set_layer(const std::string_view &layer) = 0; + virtual void set_margins(const struct bar_margins &margins) = 0; + virtual void set_position(const std::string_view &position) = 0; + virtual void set_size(uint32_t width, uint32_t height) = 0; + + virtual ~BarSurface() = default; +}; + class Bar { public: Bar(struct waybar_output *w_output, const Json::Value &); Bar(const Bar &) = delete; ~Bar() = default; - auto toggle() -> void; + void setVisible(bool visible); + void toggle(); void handleSignal(int); struct waybar_output *output; @@ -40,48 +63,15 @@ class Bar { Gtk::Window window; private: - static constexpr const char *MIN_HEIGHT_MSG = - "Requested height: {} exceeds the minimum height: {} required by the modules"; - static constexpr const char *MIN_WIDTH_MSG = - "Requested width: {} exceeds the minimum width: {} required by the modules"; - static constexpr const char *BAR_SIZE_MSG = - "Bar configured (width: {}, height: {}) for output: {}"; - static constexpr const char *SIZE_DEFINED = - "{} size is defined in the config file so it will stay like that"; - static void layerSurfaceHandleConfigure(void *, struct zwlr_layer_surface_v1 *, uint32_t, - uint32_t, uint32_t); - static void layerSurfaceHandleClosed(void *, struct zwlr_layer_surface_v1 *); - -#ifdef HAVE_GTK_LAYER_SHELL - /* gtk-layer-shell code */ - void initGtkLayerShell(); - void onConfigureGLS(GdkEventConfigure *ev); - void onMapGLS(GdkEventAny *ev); -#endif - /* fallback layer-surface code */ - void onConfigure(GdkEventConfigure *ev); - void onRealize(); - void onMap(GdkEventAny *ev); - void setSurfaceSize(uint32_t width, uint32_t height); - /* common code */ - void setExclusiveZone(uint32_t width, uint32_t height); + void onMap(GdkEventAny *); auto setupWidgets() -> void; void getModules(const Factory &, const std::string &); void setupAltFormatKeyForModule(const std::string &module_name); void setupAltFormatKeyForModuleList(const char *module_list_name); - struct margins { - int top = 0; - int right = 0; - int bottom = 0; - int left = 0; - } margins_; - struct zwlr_layer_surface_v1 *layer_surface_; - // use gtk-layer-shell instead of handling layer surfaces directly - bool use_gls_ = false; + std::unique_ptr surface_impl_; uint32_t width_ = 0; uint32_t height_ = 1; - uint8_t anchor_; Gtk::Box left_; Gtk::Box center_; Gtk::Box right_; diff --git a/src/bar.cpp b/src/bar.cpp index 7f60b2fc..a684f12b 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -8,13 +8,346 @@ #include "client.hpp" #include "factory.hpp" +namespace waybar { +static constexpr const char* MIN_HEIGHT_MSG = + "Requested height: {} exceeds the minimum height: {} required by the modules"; + +static constexpr const char* MIN_WIDTH_MSG = + "Requested width: {} exceeds the minimum width: {} required by the modules"; + +static constexpr const char* BAR_SIZE_MSG = "Bar configured (width: {}, height: {}) for output: {}"; + +static constexpr const char* SIZE_DEFINED = + "{} size is defined in the config file so it will stay like that"; + +#ifdef HAVE_GTK_LAYER_SHELL +struct GLSSurfaceImpl : public BarSurface, public sigc::trackable { + GLSSurfaceImpl(Gtk::Window& window, struct waybar_output& output) : window_{window} { + output_name_ = output.name; + // this has to be executed before GtkWindow.realize + gtk_layer_init_for_window(window_.gobj()); + gtk_layer_set_keyboard_interactivity(window.gobj(), FALSE); + gtk_layer_set_monitor(window_.gobj(), output.monitor->gobj()); + gtk_layer_set_namespace(window_.gobj(), "waybar"); + + window.signal_configure_event().connect_notify( + sigc::mem_fun(*this, &GLSSurfaceImpl::on_configure)); + } + + void set_exclusive_zone(bool enable) override { + if (enable) { + gtk_layer_auto_exclusive_zone_enable(window_.gobj()); + } else { + gtk_layer_set_exclusive_zone(window_.gobj(), 0); + } + } + + void set_margins(const struct bar_margins& margins) override { + gtk_layer_set_margin(window_.gobj(), GTK_LAYER_SHELL_EDGE_LEFT, margins.left); + gtk_layer_set_margin(window_.gobj(), GTK_LAYER_SHELL_EDGE_RIGHT, margins.right); + gtk_layer_set_margin(window_.gobj(), GTK_LAYER_SHELL_EDGE_TOP, margins.top); + gtk_layer_set_margin(window_.gobj(), GTK_LAYER_SHELL_EDGE_BOTTOM, margins.bottom); + } + + void set_layer(const std::string_view& value) override { + auto layer = GTK_LAYER_SHELL_LAYER_BOTTOM; + if (value == "top") { + layer = GTK_LAYER_SHELL_LAYER_TOP; + } else if (value == "overlay") { + layer = GTK_LAYER_SHELL_LAYER_OVERLAY; + } + gtk_layer_set_layer(window_.gobj(), layer); + } + + void set_position(const std::string_view& position) override { + auto unanchored = GTK_LAYER_SHELL_EDGE_BOTTOM; + vertical_ = false; + if (position == "bottom") { + unanchored = GTK_LAYER_SHELL_EDGE_TOP; + } else if (position == "left") { + unanchored = GTK_LAYER_SHELL_EDGE_RIGHT; + vertical_ = true; + } else if (position == "right") { + vertical_ = true; + unanchored = GTK_LAYER_SHELL_EDGE_LEFT; + } + for (auto edge : {GTK_LAYER_SHELL_EDGE_LEFT, + GTK_LAYER_SHELL_EDGE_RIGHT, + GTK_LAYER_SHELL_EDGE_TOP, + GTK_LAYER_SHELL_EDGE_BOTTOM}) { + gtk_layer_set_anchor(window_.gobj(), edge, unanchored != edge); + } + } + + void set_size(uint32_t width, uint32_t height) override { + width_ = width; + height_ = height; + window_.set_size_request(width_, height_); + }; + + private: + Gtk::Window& window_; + std::string output_name_; + uint32_t width_; + uint32_t height_; + bool vertical_ = false; + + void on_configure(GdkEventConfigure* ev) { + /* + * GTK wants new size for the window. + * Actual resizing and management of the exclusve zone is handled within the gtk-layer-shell + * code. This event handler only updates stored size of the window and prints some warnings. + * + * Note: forced resizing to a window smaller than required by GTK would not work with + * gtk-layer-shell. + */ + if (vertical_) { + if (width_ > 1 && ev->width > static_cast(width_)) { + spdlog::warn(MIN_WIDTH_MSG, width_, ev->width); + } + } else { + if (height_ > 1 && ev->height > static_cast(height_)) { + spdlog::warn(MIN_HEIGHT_MSG, height_, ev->height); + } + } + width_ = ev->width; + height_ = ev->height; + spdlog::info(BAR_SIZE_MSG, width_, height_, output_name_); + } +}; +#endif + +struct RawSurfaceImpl : public BarSurface, public sigc::trackable { + RawSurfaceImpl(Gtk::Window& window, struct waybar_output& output) : window_{window} { + output_ = gdk_wayland_monitor_get_wl_output(output.monitor->gobj()); + output_name_ = output.name; + + window.signal_realize().connect_notify(sigc::mem_fun(*this, &RawSurfaceImpl::on_realize)); + window.signal_map_event().connect_notify(sigc::mem_fun(*this, &RawSurfaceImpl::on_map)); + window.signal_configure_event().connect_notify( + sigc::mem_fun(*this, &RawSurfaceImpl::on_configure)); + + if (window.get_realized()) { + on_realize(); + } + } + + void set_exclusive_zone(bool enable) override { + exclusive_zone_ = enable; + if (layer_surface_) { + auto zone = 0; + if (enable) { + // exclusive zone already includes margin for anchored edge, + // only opposite margin should be added + if ((anchor_ & VERTICAL_ANCHOR) == VERTICAL_ANCHOR) { + zone += width_; + zone += (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT) ? margins_.right : margins_.left; + } else { + zone += height_; + zone += (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) ? margins_.bottom : margins_.top; + } + } + spdlog::debug("Set exclusive zone {} for output {}", zone, output_name_); + zwlr_layer_surface_v1_set_exclusive_zone(layer_surface_, zone); + } + } + + void set_layer(const std::string_view& layer) override { + layer_ = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM; + if (layer == "top") { + layer_ = ZWLR_LAYER_SHELL_V1_LAYER_TOP; + } else if (layer == "overlay") { + layer_ = ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY; + } + // updating already mapped window + if (layer_surface_) { + if (zwlr_layer_surface_v1_get_version(layer_surface_) >= + ZWLR_LAYER_SURFACE_V1_SET_LAYER_SINCE_VERSION) { + zwlr_layer_surface_v1_set_layer(layer_surface_, layer_); + commit(); + } else { + spdlog::warn("Unable to set layer: layer-shell interface version is too old"); + } + } + } + + void set_margins(const struct bar_margins& margins) override { + margins_ = margins; + // updating already mapped window + if (layer_surface_) { + zwlr_layer_surface_v1_set_margin( + layer_surface_, margins_.top, margins_.right, margins_.bottom, margins_.left); + commit(); + } + } + + void set_position(const std::string_view& position) override { + anchor_ = HORIZONTAL_ANCHOR | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; + if (position == "bottom") { + anchor_ = HORIZONTAL_ANCHOR | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; + } else if (position == "left") { + anchor_ = VERTICAL_ANCHOR | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT; + } else if (position == "right") { + anchor_ = VERTICAL_ANCHOR | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; + } + + // updating already mapped window + if (layer_surface_) { + zwlr_layer_surface_v1_set_anchor(layer_surface_, anchor_); + commit(); + } + } + + void set_size(uint32_t width, uint32_t height) override { + width_ = width; + height_ = height; + // layer_shell.configure handler should update exclusive zone if size changes + window_.set_size_request(width, height); + }; + + private: + constexpr static uint8_t VERTICAL_ANCHOR = + ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; + constexpr static uint8_t HORIZONTAL_ANCHOR = + ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; + + Gtk::Window& window_; + std::string output_name_; + uint32_t width_; + uint32_t height_; + uint8_t anchor_ = HORIZONTAL_ANCHOR | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; + bool exclusive_zone_ = true; + struct bar_margins margins_; + + zwlr_layer_shell_v1_layer layer_ = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM; + struct wl_output* output_ = nullptr; + struct wl_surface* surface_ = nullptr; + struct zwlr_layer_surface_v1* layer_surface_ = nullptr; + + void on_realize() { + auto gdk_window = window_.get_window()->gobj(); + gdk_wayland_window_set_use_custom_surface(gdk_window); + } + + void on_map(GdkEventAny* ev) { + auto client = Client::inst(); + auto gdk_window = window_.get_window()->gobj(); + surface_ = gdk_wayland_window_get_wl_surface(gdk_window); + + layer_surface_ = zwlr_layer_shell_v1_get_layer_surface( + client->layer_shell, surface_, output_, layer_, "waybar"); + + zwlr_layer_surface_v1_set_keyboard_interactivity(layer_surface_, false); + + zwlr_layer_surface_v1_set_anchor(layer_surface_, anchor_); + zwlr_layer_surface_v1_set_margin( + layer_surface_, margins_.top, margins_.right, margins_.bottom, margins_.left); + set_surface_size(width_, height_); + set_exclusive_zone(exclusive_zone_); + + static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { + .configure = on_surface_configure, + .closed = on_surface_closed, + }; + zwlr_layer_surface_v1_add_listener(layer_surface_, &layer_surface_listener, this); + + wl_surface_commit(surface_); + wl_display_roundtrip(client->wl_display); + } + + void on_configure(GdkEventConfigure* ev) { + /* + * GTK wants new size for the window. + * + * Prefer configured size if it's non-default. + * If the size is not set and the window is smaller than requested by GTK, request resize from + * layer surface. + */ + auto tmp_height = height_; + auto tmp_width = width_; + if (ev->height > static_cast(height_)) { + // Default minimal value + if (height_ > 1) { + spdlog::warn(MIN_HEIGHT_MSG, height_, ev->height); + } + /* + if (config["height"].isUInt()) { + spdlog::info(SIZE_DEFINED, "Height"); + } else */ + tmp_height = ev->height; + } + if (ev->width > static_cast(width_)) { + // Default minimal value + if (width_ > 1) { + spdlog::warn(MIN_WIDTH_MSG, width_, ev->width); + } + /* + if (config["width"].isUInt()) { + spdlog::info(SIZE_DEFINED, "Width"); + } else */ + tmp_width = ev->width; + } + if (tmp_width != width_ || tmp_height != height_) { + set_surface_size(tmp_width, tmp_height); + } + } + + void commit() { + if (window_.get_mapped()) { + wl_surface_commit(surface_); + } + } + + void set_surface_size(uint32_t width, uint32_t height) { + /* If the client is anchored to two opposite edges, layer_surface.configure will return + * size without margins for the axis. + * layer_surface.set_size, however, expects size with margins for the anchored axis. + * This is not specified by wlr-layer-shell and based on actual behavior of sway. + */ + bool vertical = (anchor_ & VERTICAL_ANCHOR) == VERTICAL_ANCHOR; + if (vertical && height > 1) { + height += margins_.top + margins_.bottom; + } + if (!vertical && width > 1) { + width += margins_.right + margins_.left; + } + spdlog::debug("Set surface size {}x{} for output {}", width, height, output_name_); + zwlr_layer_surface_v1_set_size(layer_surface_, width, height); + } + + static void on_surface_configure(void* data, struct zwlr_layer_surface_v1* surface, + uint32_t serial, uint32_t width, uint32_t height) { + auto o = static_cast(data); + if (width != o->width_ || height != o->height_) { + o->width_ = width; + o->height_ = height; + o->window_.set_size_request(o->width_, o->height_); + o->window_.resize(o->width_, o->height_); + o->set_exclusive_zone(o->exclusive_zone_); + spdlog::info(BAR_SIZE_MSG, + o->width_ == 1 ? "auto" : std::to_string(o->width_), + o->height_ == 1 ? "auto" : std::to_string(o->height_), + o->output_name_); + wl_surface_commit(o->surface_); + } + zwlr_layer_surface_v1_ack_configure(surface, serial); + } + + static void on_surface_closed(void* data, struct zwlr_layer_surface_v1* /* surface */) { + auto o = static_cast(data); + if (o->layer_surface_) { + zwlr_layer_surface_v1_destroy(o->layer_surface_); + o->layer_surface_ = nullptr; + } + } +}; + +}; // namespace waybar + waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) : output(w_output), config(w_config), - surface(nullptr), window{Gtk::WindowType::WINDOW_TOPLEVEL}, - layer_surface_(nullptr), - anchor_(ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP), left_(Gtk::ORIENTATION_HORIZONTAL, 0), center_(Gtk::ORIENTATION_HORIZONTAL, 0), right_(Gtk::ORIENTATION_HORIZONTAL, 0), @@ -29,32 +362,22 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) center_.get_style_context()->add_class("modules-center"); right_.get_style_context()->add_class("modules-right"); - if (config["position"] == "right" || config["position"] == "left") { + auto position = config["position"].asString(); + + if (position == "right" || position == "left") { + left_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0); + center_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0); + right_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0); + box_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0); + vertical = true; + height_ = 0; width_ = 1; } height_ = config["height"].isUInt() ? config["height"].asUInt() : height_; width_ = config["width"].isUInt() ? config["width"].asUInt() : width_; - if (config["position"] == "bottom") { - anchor_ = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; - } else if (config["position"] == "left") { - anchor_ = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT; - } else if (config["position"] == "right") { - anchor_ = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; - } - 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; - } 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; - left_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0); - center_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0); - right_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0); - box_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0); - vertical = true; - } + struct bar_margins margins_; if (config["margin-top"].isInt() || config["margin-right"].isInt() || config["margin-bottom"].isInt() || config["margin-left"].isInt()) { @@ -102,210 +425,51 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) } #ifdef HAVE_GTK_LAYER_SHELL - use_gls_ = config["gtk-layer-shell"].isBool() ? config["gtk-layer-shell"].asBool() : true; - if (use_gls_) { - initGtkLayerShell(); - window.signal_map_event().connect_notify(sigc::mem_fun(*this, &Bar::onMapGLS)); - window.signal_configure_event().connect_notify(sigc::mem_fun(*this, &Bar::onConfigureGLS)); - } -#endif - - if (!use_gls_) { - window.signal_realize().connect_notify(sigc::mem_fun(*this, &Bar::onRealize)); - window.signal_map_event().connect_notify(sigc::mem_fun(*this, &Bar::onMap)); - window.signal_configure_event().connect_notify(sigc::mem_fun(*this, &Bar::onConfigure)); - } - window.set_size_request(width_, height_); - setupWidgets(); - - if (!use_gls_ && window.get_realized()) { - onRealize(); - } - window.show_all(); -} - -#ifdef HAVE_GTK_LAYER_SHELL -void waybar::Bar::initGtkLayerShell() { - auto gtk_window = window.gobj(); - // this has to be executed before GtkWindow.realize - gtk_layer_init_for_window(gtk_window); - gtk_layer_set_keyboard_interactivity(gtk_window, FALSE); - auto layer = config["layer"] == "top" ? GTK_LAYER_SHELL_LAYER_TOP : GTK_LAYER_SHELL_LAYER_BOTTOM; - gtk_layer_set_layer(gtk_window, layer); - gtk_layer_set_monitor(gtk_window, output->monitor->gobj()); - gtk_layer_set_namespace(gtk_window, "waybar"); - - gtk_layer_set_anchor(gtk_window, - GTK_LAYER_SHELL_EDGE_LEFT, - (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT) ? TRUE : FALSE); - gtk_layer_set_anchor(gtk_window, - GTK_LAYER_SHELL_EDGE_RIGHT, - (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT) ? TRUE : FALSE); - gtk_layer_set_anchor(gtk_window, - GTK_LAYER_SHELL_EDGE_TOP, - (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) ? TRUE : FALSE); - gtk_layer_set_anchor(gtk_window, - GTK_LAYER_SHELL_EDGE_BOTTOM, - (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM) ? TRUE : FALSE); - - gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_LEFT, margins_.left); - gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_RIGHT, margins_.right); - gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_TOP, margins_.top); - gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_BOTTOM, margins_.bottom); - - setExclusiveZone(width_, height_); -} - -void waybar::Bar::onConfigureGLS(GdkEventConfigure* ev) { - /* - * GTK wants new size for the window. - * Actual resizing and management of the exclusve zone is handled within the gtk-layer-shell code. - * This event handler only updates stored size of the window and prints some warnings. - * - * Note: forced resizing to a window smaller than required by GTK would not work with - * gtk-layer-shell. - */ - if (vertical) { - if (width_ > 1 && ev->width > static_cast(width_)) { - spdlog::warn(MIN_WIDTH_MSG, width_, ev->width); - } - } else { - if (height_ > 1 && ev->height > static_cast(height_)) { - spdlog::warn(MIN_HEIGHT_MSG, height_, ev->height); - } - } - width_ = ev->width; - height_ = ev->height; - spdlog::info(BAR_SIZE_MSG, width_, height_, output->name); -} - -void waybar::Bar::onMapGLS(GdkEventAny* ev) { - /* - * Obtain a pointer to the custom layer surface for modules that require it (idle_inhibitor). - */ - auto gdk_window = window.get_window(); - surface = gdk_wayland_window_get_wl_surface(gdk_window->gobj()); -} - -#endif - -void waybar::Bar::onConfigure(GdkEventConfigure* ev) { - /* - * GTK wants new size for the window. - * - * Prefer configured size if it's non-default. - * If the size is not set and the window is smaller than requested by GTK, request resize from - * layer surface. - */ - auto tmp_height = height_; - auto tmp_width = width_; - if (ev->height > static_cast(height_)) { - // Default minimal value - if (height_ > 1) { - spdlog::warn(MIN_HEIGHT_MSG, height_, ev->height); - } - if (config["height"].isUInt()) { - spdlog::info(SIZE_DEFINED, "Height"); - } else { - tmp_height = ev->height; - } - } - if (ev->width > static_cast(width_)) { - // Default minimal value - if (width_ > 1) { - spdlog::warn(MIN_WIDTH_MSG, width_, ev->width); - } - if (config["width"].isUInt()) { - spdlog::info(SIZE_DEFINED, "Width"); - } else { - tmp_width = ev->width; - } - } - if (tmp_width != width_ || tmp_height != height_) { - setSurfaceSize(tmp_width, tmp_height); - } -} - -void waybar::Bar::onRealize() { - auto gdk_window = window.get_window()->gobj(); - gdk_wayland_window_set_use_custom_surface(gdk_window); -} - -void waybar::Bar::onMap(GdkEventAny* ev) { - auto gdk_window = window.get_window()->gobj(); - surface = gdk_wayland_window_get_wl_surface(gdk_window); - - auto client = waybar::Client::inst(); - // owned by output->monitor; no need to destroy - auto wl_output = gdk_wayland_monitor_get_wl_output(output->monitor->gobj()); - auto layer = - config["layer"] == "top" ? ZWLR_LAYER_SHELL_V1_LAYER_TOP : ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM; - layer_surface_ = zwlr_layer_shell_v1_get_layer_surface( - client->layer_shell, surface, wl_output, layer, "waybar"); - - zwlr_layer_surface_v1_set_keyboard_interactivity(layer_surface_, false); - zwlr_layer_surface_v1_set_anchor(layer_surface_, anchor_); - zwlr_layer_surface_v1_set_margin( - layer_surface_, margins_.top, margins_.right, margins_.bottom, margins_.left); - setSurfaceSize(width_, height_); - setExclusiveZone(width_, height_); - - static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { - .configure = layerSurfaceHandleConfigure, - .closed = layerSurfaceHandleClosed, - }; - zwlr_layer_surface_v1_add_listener(layer_surface_, &layer_surface_listener, this); - - wl_surface_commit(surface); - wl_display_roundtrip(client->wl_display); -} - -void waybar::Bar::setExclusiveZone(uint32_t width, uint32_t height) { -#ifdef HAVE_GTK_LAYER_SHELL - if (use_gls_) { - if (visible) { - spdlog::debug("Enable auto exclusive zone for output {}", output->name); - gtk_layer_auto_exclusive_zone_enable(window.gobj()); - } else { - spdlog::debug("Disable exclusive zone for output {}", output->name); - gtk_layer_set_exclusive_zone(window.gobj(), 0); - } + bool use_gls = config["gtk-layer-shell"].isBool() ? config["gtk-layer-shell"].asBool() : true; + if (use_gls) { + surface_impl_ = std::make_unique(window, *output); } else #endif { - auto zone = 0; - if (visible) { - // exclusive zone already includes margin for anchored edge, - // only opposite margin should be added - if (vertical) { - zone += width; - zone += (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT) ? margins_.right : margins_.left; - } else { - zone += height; - zone += (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) ? margins_.bottom : margins_.top; - } - } - spdlog::debug("Set exclusive zone {} for output {}", zone, output->name); - zwlr_layer_surface_v1_set_exclusive_zone(layer_surface_, zone); + surface_impl_ = std::make_unique(window, *output); } + + if (config["layer"].isString()) { + surface_impl_->set_layer(config["layer"].asString()); + } + surface_impl_->set_exclusive_zone(true); + surface_impl_->set_margins(margins_); + surface_impl_->set_position(position); + surface_impl_->set_size(width_, height_); + + window.signal_map_event().connect_notify(sigc::mem_fun(*this, &Bar::onMap)); + + setupWidgets(); + window.show_all(); } -void waybar::Bar::setSurfaceSize(uint32_t width, uint32_t height) { - /* If the client is anchored to two opposite edges, layer_surface.configure will return - * size without margins for the axis. - * layer_surface.set_size, however, expects size with margins for the anchored axis. - * This is not specified by wlr-layer-shell and based on actual behavior of sway. +void waybar::Bar::onMap(GdkEventAny*) { + /* + * Obtain a pointer to the custom layer surface for modules that require it (idle_inhibitor). */ - if (vertical && height > 1) { - height += margins_.top + margins_.bottom; - } - if (!vertical && width > 1) { - width += margins_.right + margins_.left; - } - spdlog::debug("Set surface size {}x{} for output {}", width, height, output->name); - zwlr_layer_surface_v1_set_size(layer_surface_, width, height); + auto gdk_window = window.get_window()->gobj(); + surface = gdk_wayland_window_get_wl_surface(gdk_window); } +void waybar::Bar::setVisible(bool value) { + visible = value; + if (!visible) { + window.get_style_context()->add_class("hidden"); + window.set_opacity(0); + } else { + window.get_style_context()->remove_class("hidden"); + window.set_opacity(1); + } + surface_impl_->set_exclusive_zone(visible); +} + +void waybar::Bar::toggle() { setVisible(!visible); } + // Converting string to button code rn as to avoid doing it later void waybar::Bar::setupAltFormatKeyForModule(const std::string& module_name) { if (config.isMember(module_name)) { @@ -367,50 +531,6 @@ void waybar::Bar::handleSignal(int signal) { } } -void waybar::Bar::layerSurfaceHandleConfigure(void* data, struct zwlr_layer_surface_v1* surface, - uint32_t serial, uint32_t width, uint32_t height) { - auto o = static_cast(data); - if (width != o->width_ || height != o->height_) { - o->width_ = width; - o->height_ = height; - o->window.set_size_request(o->width_, o->height_); - o->window.resize(o->width_, o->height_); - o->setExclusiveZone(width, height); - spdlog::info(BAR_SIZE_MSG, - o->width_ == 1 ? "auto" : std::to_string(o->width_), - o->height_ == 1 ? "auto" : std::to_string(o->height_), - o->output->name); - wl_surface_commit(o->surface); - } - zwlr_layer_surface_v1_ack_configure(surface, serial); -} - -void waybar::Bar::layerSurfaceHandleClosed(void* data, struct zwlr_layer_surface_v1* /*surface*/) { - auto o = static_cast(data); - if (o->layer_surface_) { - zwlr_layer_surface_v1_destroy(o->layer_surface_); - o->layer_surface_ = nullptr; - } - o->modules_left_.clear(); - o->modules_center_.clear(); - o->modules_right_.clear(); -} - -auto waybar::Bar::toggle() -> void { - visible = !visible; - if (!visible) { - window.get_style_context()->add_class("hidden"); - window.set_opacity(0); - } else { - window.get_style_context()->remove_class("hidden"); - window.set_opacity(1); - } - setExclusiveZone(width_, height_); - if (!use_gls_) { - wl_surface_commit(surface); - } -} - void waybar::Bar::getModules(const Factory& factory, const std::string& pos) { if (config[pos].isArray()) { for (const auto& name : config[pos]) { From f01996ae997d4d2aa8ce9904332d99f12f3e4e2c Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Wed, 28 Oct 2020 08:06:40 -0700 Subject: [PATCH 3/9] fix(bar): CamelCase SurfaceImpl method names --- include/bar.hpp | 10 +++---- src/bar.cpp | 70 ++++++++++++++++++++++++------------------------- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/include/bar.hpp b/include/bar.hpp index df503275..1e3d37b0 100644 --- a/include/bar.hpp +++ b/include/bar.hpp @@ -36,11 +36,11 @@ class BarSurface { BarSurface() = default; public: - virtual void set_exclusive_zone(bool enable) = 0; - virtual void set_layer(const std::string_view &layer) = 0; - virtual void set_margins(const struct bar_margins &margins) = 0; - virtual void set_position(const std::string_view &position) = 0; - virtual void set_size(uint32_t width, uint32_t height) = 0; + virtual void setExclusiveZone(bool enable) = 0; + virtual void setLayer(const std::string_view &layer) = 0; + virtual void setMargins(const struct bar_margins &margins) = 0; + virtual void setPosition(const std::string_view &position) = 0; + virtual void setSize(uint32_t width, uint32_t height) = 0; virtual ~BarSurface() = default; }; diff --git a/src/bar.cpp b/src/bar.cpp index a684f12b..c7387e38 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -31,10 +31,10 @@ struct GLSSurfaceImpl : public BarSurface, public sigc::trackable { gtk_layer_set_namespace(window_.gobj(), "waybar"); window.signal_configure_event().connect_notify( - sigc::mem_fun(*this, &GLSSurfaceImpl::on_configure)); + sigc::mem_fun(*this, &GLSSurfaceImpl::onConfigure)); } - void set_exclusive_zone(bool enable) override { + void setExclusiveZone(bool enable) override { if (enable) { gtk_layer_auto_exclusive_zone_enable(window_.gobj()); } else { @@ -42,14 +42,14 @@ struct GLSSurfaceImpl : public BarSurface, public sigc::trackable { } } - void set_margins(const struct bar_margins& margins) override { + void setMargins(const struct bar_margins& margins) override { gtk_layer_set_margin(window_.gobj(), GTK_LAYER_SHELL_EDGE_LEFT, margins.left); gtk_layer_set_margin(window_.gobj(), GTK_LAYER_SHELL_EDGE_RIGHT, margins.right); gtk_layer_set_margin(window_.gobj(), GTK_LAYER_SHELL_EDGE_TOP, margins.top); gtk_layer_set_margin(window_.gobj(), GTK_LAYER_SHELL_EDGE_BOTTOM, margins.bottom); } - void set_layer(const std::string_view& value) override { + void setLayer(const std::string_view& value) override { auto layer = GTK_LAYER_SHELL_LAYER_BOTTOM; if (value == "top") { layer = GTK_LAYER_SHELL_LAYER_TOP; @@ -59,7 +59,7 @@ struct GLSSurfaceImpl : public BarSurface, public sigc::trackable { gtk_layer_set_layer(window_.gobj(), layer); } - void set_position(const std::string_view& position) override { + void setPosition(const std::string_view& position) override { auto unanchored = GTK_LAYER_SHELL_EDGE_BOTTOM; vertical_ = false; if (position == "bottom") { @@ -79,7 +79,7 @@ struct GLSSurfaceImpl : public BarSurface, public sigc::trackable { } } - void set_size(uint32_t width, uint32_t height) override { + void setSize(uint32_t width, uint32_t height) override { width_ = width; height_ = height; window_.set_size_request(width_, height_); @@ -92,7 +92,7 @@ struct GLSSurfaceImpl : public BarSurface, public sigc::trackable { uint32_t height_; bool vertical_ = false; - void on_configure(GdkEventConfigure* ev) { + void onConfigure(GdkEventConfigure* ev) { /* * GTK wants new size for the window. * Actual resizing and management of the exclusve zone is handled within the gtk-layer-shell @@ -122,17 +122,17 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { output_ = gdk_wayland_monitor_get_wl_output(output.monitor->gobj()); output_name_ = output.name; - window.signal_realize().connect_notify(sigc::mem_fun(*this, &RawSurfaceImpl::on_realize)); - window.signal_map_event().connect_notify(sigc::mem_fun(*this, &RawSurfaceImpl::on_map)); + window.signal_realize().connect_notify(sigc::mem_fun(*this, &RawSurfaceImpl::onRealize)); + window.signal_map_event().connect_notify(sigc::mem_fun(*this, &RawSurfaceImpl::onMap)); window.signal_configure_event().connect_notify( - sigc::mem_fun(*this, &RawSurfaceImpl::on_configure)); + sigc::mem_fun(*this, &RawSurfaceImpl::onConfigure)); if (window.get_realized()) { - on_realize(); + onRealize(); } } - void set_exclusive_zone(bool enable) override { + void setExclusiveZone(bool enable) override { exclusive_zone_ = enable; if (layer_surface_) { auto zone = 0; @@ -152,7 +152,7 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { } } - void set_layer(const std::string_view& layer) override { + void setLayer(const std::string_view& layer) override { layer_ = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM; if (layer == "top") { layer_ = ZWLR_LAYER_SHELL_V1_LAYER_TOP; @@ -171,7 +171,7 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { } } - void set_margins(const struct bar_margins& margins) override { + void setMargins(const struct bar_margins& margins) override { margins_ = margins; // updating already mapped window if (layer_surface_) { @@ -181,7 +181,7 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { } } - void set_position(const std::string_view& position) override { + void setPosition(const std::string_view& position) override { anchor_ = HORIZONTAL_ANCHOR | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; if (position == "bottom") { anchor_ = HORIZONTAL_ANCHOR | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; @@ -198,7 +198,7 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { } } - void set_size(uint32_t width, uint32_t height) override { + void setSize(uint32_t width, uint32_t height) override { width_ = width; height_ = height; // layer_shell.configure handler should update exclusive zone if size changes @@ -224,12 +224,12 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { struct wl_surface* surface_ = nullptr; struct zwlr_layer_surface_v1* layer_surface_ = nullptr; - void on_realize() { + void onRealize() { auto gdk_window = window_.get_window()->gobj(); gdk_wayland_window_set_use_custom_surface(gdk_window); } - void on_map(GdkEventAny* ev) { + void onMap(GdkEventAny* ev) { auto client = Client::inst(); auto gdk_window = window_.get_window()->gobj(); surface_ = gdk_wayland_window_get_wl_surface(gdk_window); @@ -242,12 +242,12 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { zwlr_layer_surface_v1_set_anchor(layer_surface_, anchor_); zwlr_layer_surface_v1_set_margin( layer_surface_, margins_.top, margins_.right, margins_.bottom, margins_.left); - set_surface_size(width_, height_); - set_exclusive_zone(exclusive_zone_); + setSurfaceSize(width_, height_); + setExclusiveZone(exclusive_zone_); static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { - .configure = on_surface_configure, - .closed = on_surface_closed, + .configure = onSurfaceConfigure, + .closed = onSurfaceClosed, }; zwlr_layer_surface_v1_add_listener(layer_surface_, &layer_surface_listener, this); @@ -255,7 +255,7 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { wl_display_roundtrip(client->wl_display); } - void on_configure(GdkEventConfigure* ev) { + void onConfigure(GdkEventConfigure* ev) { /* * GTK wants new size for the window. * @@ -288,7 +288,7 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { tmp_width = ev->width; } if (tmp_width != width_ || tmp_height != height_) { - set_surface_size(tmp_width, tmp_height); + setSurfaceSize(tmp_width, tmp_height); } } @@ -298,7 +298,7 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { } } - void set_surface_size(uint32_t width, uint32_t height) { + void setSurfaceSize(uint32_t width, uint32_t height) { /* If the client is anchored to two opposite edges, layer_surface.configure will return * size without margins for the axis. * layer_surface.set_size, however, expects size with margins for the anchored axis. @@ -315,15 +315,15 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { zwlr_layer_surface_v1_set_size(layer_surface_, width, height); } - static void on_surface_configure(void* data, struct zwlr_layer_surface_v1* surface, - uint32_t serial, uint32_t width, uint32_t height) { + static void onSurfaceConfigure(void* data, struct zwlr_layer_surface_v1* surface, uint32_t serial, + uint32_t width, uint32_t height) { auto o = static_cast(data); if (width != o->width_ || height != o->height_) { o->width_ = width; o->height_ = height; o->window_.set_size_request(o->width_, o->height_); o->window_.resize(o->width_, o->height_); - o->set_exclusive_zone(o->exclusive_zone_); + o->setExclusiveZone(o->exclusive_zone_); spdlog::info(BAR_SIZE_MSG, o->width_ == 1 ? "auto" : std::to_string(o->width_), o->height_ == 1 ? "auto" : std::to_string(o->height_), @@ -333,7 +333,7 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { zwlr_layer_surface_v1_ack_configure(surface, serial); } - static void on_surface_closed(void* data, struct zwlr_layer_surface_v1* /* surface */) { + static void onSurfaceClosed(void* data, struct zwlr_layer_surface_v1* /* surface */) { auto o = static_cast(data); if (o->layer_surface_) { zwlr_layer_surface_v1_destroy(o->layer_surface_); @@ -435,12 +435,12 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) } if (config["layer"].isString()) { - surface_impl_->set_layer(config["layer"].asString()); + surface_impl_->setLayer(config["layer"].asString()); } - surface_impl_->set_exclusive_zone(true); - surface_impl_->set_margins(margins_); - surface_impl_->set_position(position); - surface_impl_->set_size(width_, height_); + surface_impl_->setExclusiveZone(true); + surface_impl_->setMargins(margins_); + surface_impl_->setPosition(position); + surface_impl_->setSize(width_, height_); window.signal_map_event().connect_notify(sigc::mem_fun(*this, &Bar::onMap)); @@ -465,7 +465,7 @@ void waybar::Bar::setVisible(bool value) { window.get_style_context()->remove_class("hidden"); window.set_opacity(1); } - surface_impl_->set_exclusive_zone(visible); + surface_impl_->setExclusiveZone(visible); } void waybar::Bar::toggle() { setVisible(!visible); } From f97de599dde49943d2742db2903b83769601deac Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Wed, 21 Oct 2020 22:45:03 -0700 Subject: [PATCH 4/9] refactor: header cleanup Replace a couple of header includes with forward declarations. --- include/bar.hpp | 2 -- include/client.hpp | 4 ++++ src/bar.cpp | 1 + src/client.cpp | 3 +++ src/modules/idle_inhibitor.cpp | 2 ++ 5 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/bar.hpp b/include/bar.hpp index 1e3d37b0..d4748d5a 100644 --- a/include/bar.hpp +++ b/include/bar.hpp @@ -9,8 +9,6 @@ #include #include "AModule.hpp" -#include "idle-inhibit-unstable-v1-client-protocol.h" -#include "wlr-layer-shell-unstable-v1-client-protocol.h" #include "xdg-output-unstable-v1-client-protocol.h" namespace waybar { diff --git a/include/client.hpp b/include/client.hpp index 39b6ae3b..05215cc0 100644 --- a/include/client.hpp +++ b/include/client.hpp @@ -8,6 +8,10 @@ #include #include "bar.hpp" +struct zwlr_layer_shell_v1; +struct zwp_idle_inhibitor_v1; +struct zwp_idle_inhibit_manager_v1; + namespace waybar { class Client { diff --git a/src/bar.cpp b/src/bar.cpp index c7387e38..fb04f627 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -7,6 +7,7 @@ #include "bar.hpp" #include "client.hpp" #include "factory.hpp" +#include "wlr-layer-shell-unstable-v1-client-protocol.h" namespace waybar { static constexpr const char* MIN_HEIGHT_MSG = diff --git a/src/client.cpp b/src/client.cpp index 9dd93d81..005761ee 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -6,6 +6,9 @@ #include "util/clara.hpp" #include "util/json.hpp" +#include "idle-inhibit-unstable-v1-client-protocol.h" +#include "wlr-layer-shell-unstable-v1-client-protocol.h" + waybar::Client *waybar::Client::inst() { static auto c = new Client(); return c; diff --git a/src/modules/idle_inhibitor.cpp b/src/modules/idle_inhibitor.cpp index d94e9579..d2cfe905 100644 --- a/src/modules/idle_inhibitor.cpp +++ b/src/modules/idle_inhibitor.cpp @@ -1,4 +1,6 @@ #include "modules/idle_inhibitor.hpp" + +#include "idle-inhibit-unstable-v1-client-protocol.h" #include "util/command.hpp" waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar& bar, From d4d35e6b2b6f142844e18c69164c38d6b02f185a Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Thu, 22 Oct 2020 08:04:57 -0700 Subject: [PATCH 5/9] chore(subprojects): update gtk-layer-shell to 0.4.0 --- subprojects/gtk-layer-shell.wrap | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subprojects/gtk-layer-shell.wrap b/subprojects/gtk-layer-shell.wrap index 6fe68c3f..555fbcb6 100644 --- a/subprojects/gtk-layer-shell.wrap +++ b/subprojects/gtk-layer-shell.wrap @@ -1,5 +1,5 @@ [wrap-file] -directory = gtk-layer-shell-0.3.0 -source_filename = gtk-layer-shell-0.3.0.tar.gz -source_hash = edd5e31279d494df66da9e9190c219fa295da547f5538207685e98468dbc134d -source_url = https://github.com/wmww/gtk-layer-shell/archive/v0.3.0/gtk-layer-shell-0.3.0.tar.gz +directory = gtk-layer-shell-0.4.0 +source_filename = gtk-layer-shell-0.4.0.tar.gz +source_hash = 52fd74d3161fefa5528585ca5a523c3150934961f2284ad010ae54336dad097e +source_url = https://github.com/wmww/gtk-layer-shell/archive/v0.4.0/gtk-layer-shell-0.4.0.tar.gz From 591a417b7db973304e788ccf58bbbfdb289ed9a7 Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Fri, 23 Oct 2020 00:13:23 -0700 Subject: [PATCH 6/9] fix(bar): rework surface commit calls for RawSurfaceImpl wayland log shows that some changes were committed twice and some weren't committed until the next redraw. --- include/bar.hpp | 1 + src/bar.cpp | 34 ++++++++++++++++------------------ 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/include/bar.hpp b/include/bar.hpp index d4748d5a..8348070f 100644 --- a/include/bar.hpp +++ b/include/bar.hpp @@ -39,6 +39,7 @@ class BarSurface { virtual void setMargins(const struct bar_margins &margins) = 0; virtual void setPosition(const std::string_view &position) = 0; virtual void setSize(uint32_t width, uint32_t height) = 0; + virtual void commit(){}; virtual ~BarSurface() = default; }; diff --git a/src/bar.cpp b/src/bar.cpp index fb04f627..8e5d7b05 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -165,7 +165,6 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { if (zwlr_layer_surface_v1_get_version(layer_surface_) >= ZWLR_LAYER_SURFACE_V1_SET_LAYER_SINCE_VERSION) { zwlr_layer_surface_v1_set_layer(layer_surface_, layer_); - commit(); } else { spdlog::warn("Unable to set layer: layer-shell interface version is too old"); } @@ -178,7 +177,6 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { if (layer_surface_) { zwlr_layer_surface_v1_set_margin( layer_surface_, margins_.top, margins_.right, margins_.bottom, margins_.left); - commit(); } } @@ -195,7 +193,6 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { // updating already mapped window if (layer_surface_) { zwlr_layer_surface_v1_set_anchor(layer_surface_, anchor_); - commit(); } } @@ -206,6 +203,12 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { window_.set_size_request(width, height); }; + void commit() override { + if (surface_) { + wl_surface_commit(surface_); + } + } + private: constexpr static uint8_t VERTICAL_ANCHOR = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; @@ -231,6 +234,10 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { } void onMap(GdkEventAny* ev) { + static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { + .configure = onSurfaceConfigure, + .closed = onSurfaceClosed, + }; auto client = Client::inst(); auto gdk_window = window_.get_window()->gobj(); surface_ = gdk_wayland_window_get_wl_surface(gdk_window); @@ -238,21 +245,16 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { layer_surface_ = zwlr_layer_shell_v1_get_layer_surface( client->layer_shell, surface_, output_, layer_, "waybar"); + zwlr_layer_surface_v1_add_listener(layer_surface_, &layer_surface_listener, this); zwlr_layer_surface_v1_set_keyboard_interactivity(layer_surface_, false); - zwlr_layer_surface_v1_set_anchor(layer_surface_, anchor_); zwlr_layer_surface_v1_set_margin( layer_surface_, margins_.top, margins_.right, margins_.bottom, margins_.left); + setSurfaceSize(width_, height_); setExclusiveZone(exclusive_zone_); - static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { - .configure = onSurfaceConfigure, - .closed = onSurfaceClosed, - }; - zwlr_layer_surface_v1_add_listener(layer_surface_, &layer_surface_listener, this); - - wl_surface_commit(surface_); + commit(); wl_display_roundtrip(client->wl_display); } @@ -290,12 +292,7 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { } if (tmp_width != width_ || tmp_height != height_) { setSurfaceSize(tmp_width, tmp_height); - } - } - - void commit() { - if (window_.get_mapped()) { - wl_surface_commit(surface_); + commit(); } } @@ -329,7 +326,7 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { o->width_ == 1 ? "auto" : std::to_string(o->width_), o->height_ == 1 ? "auto" : std::to_string(o->height_), o->output_name_); - wl_surface_commit(o->surface_); + o->commit(); } zwlr_layer_surface_v1_ack_configure(surface, serial); } @@ -467,6 +464,7 @@ void waybar::Bar::setVisible(bool value) { window.set_opacity(1); } surface_impl_->setExclusiveZone(visible); + surface_impl_->commit(); } void waybar::Bar::toggle() { setVisible(!visible); } From fe3aeb36c51267b87c8a8b8fa2ea827047c25196 Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Fri, 23 Oct 2020 00:49:09 -0700 Subject: [PATCH 7/9] refactor(bar): wrap layer_surface pointer in unique_ptr --- src/bar.cpp | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/bar.cpp b/src/bar.cpp index 8e5d7b05..c2cf6d34 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -4,6 +4,8 @@ #include +#include + #include "bar.hpp" #include "client.hpp" #include "factory.hpp" @@ -149,7 +151,7 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { } } spdlog::debug("Set exclusive zone {} for output {}", zone, output_name_); - zwlr_layer_surface_v1_set_exclusive_zone(layer_surface_, zone); + zwlr_layer_surface_v1_set_exclusive_zone(layer_surface_.get(), zone); } } @@ -162,9 +164,9 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { } // updating already mapped window if (layer_surface_) { - if (zwlr_layer_surface_v1_get_version(layer_surface_) >= + if (zwlr_layer_surface_v1_get_version(layer_surface_.get()) >= ZWLR_LAYER_SURFACE_V1_SET_LAYER_SINCE_VERSION) { - zwlr_layer_surface_v1_set_layer(layer_surface_, layer_); + zwlr_layer_surface_v1_set_layer(layer_surface_.get(), layer_); } else { spdlog::warn("Unable to set layer: layer-shell interface version is too old"); } @@ -176,7 +178,7 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { // updating already mapped window if (layer_surface_) { zwlr_layer_surface_v1_set_margin( - layer_surface_, margins_.top, margins_.right, margins_.bottom, margins_.left); + layer_surface_.get(), margins_.top, margins_.right, margins_.bottom, margins_.left); } } @@ -192,7 +194,7 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { // updating already mapped window if (layer_surface_) { - zwlr_layer_surface_v1_set_anchor(layer_surface_, anchor_); + zwlr_layer_surface_v1_set_anchor(layer_surface_.get(), anchor_); } } @@ -215,6 +217,11 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { constexpr static uint8_t HORIZONTAL_ANCHOR = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; + template + using deleter_fn = std::integral_constant; + using layer_surface_ptr = + std::unique_ptr>; + Gtk::Window& window_; std::string output_name_; uint32_t width_; @@ -223,10 +230,10 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { bool exclusive_zone_ = true; struct bar_margins margins_; - zwlr_layer_shell_v1_layer layer_ = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM; - struct wl_output* output_ = nullptr; - struct wl_surface* surface_ = nullptr; - struct zwlr_layer_surface_v1* layer_surface_ = nullptr; + zwlr_layer_shell_v1_layer layer_ = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM; + struct wl_output* output_ = nullptr; // owned by GTK + struct wl_surface* surface_ = nullptr; // owned by GTK + layer_surface_ptr layer_surface_; void onRealize() { auto gdk_window = window_.get_window()->gobj(); @@ -242,14 +249,14 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { auto gdk_window = window_.get_window()->gobj(); surface_ = gdk_wayland_window_get_wl_surface(gdk_window); - layer_surface_ = zwlr_layer_shell_v1_get_layer_surface( - client->layer_shell, surface_, output_, layer_, "waybar"); + layer_surface_.reset(zwlr_layer_shell_v1_get_layer_surface( + client->layer_shell, surface_, output_, layer_, "waybar")); - zwlr_layer_surface_v1_add_listener(layer_surface_, &layer_surface_listener, this); - zwlr_layer_surface_v1_set_keyboard_interactivity(layer_surface_, false); - zwlr_layer_surface_v1_set_anchor(layer_surface_, anchor_); + zwlr_layer_surface_v1_add_listener(layer_surface_.get(), &layer_surface_listener, this); + zwlr_layer_surface_v1_set_keyboard_interactivity(layer_surface_.get(), false); + zwlr_layer_surface_v1_set_anchor(layer_surface_.get(), anchor_); zwlr_layer_surface_v1_set_margin( - layer_surface_, margins_.top, margins_.right, margins_.bottom, margins_.left); + layer_surface_.get(), margins_.top, margins_.right, margins_.bottom, margins_.left); setSurfaceSize(width_, height_); setExclusiveZone(exclusive_zone_); @@ -310,7 +317,7 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { width += margins_.right + margins_.left; } spdlog::debug("Set surface size {}x{} for output {}", width, height, output_name_); - zwlr_layer_surface_v1_set_size(layer_surface_, width, height); + zwlr_layer_surface_v1_set_size(layer_surface_.get(), width, height); } static void onSurfaceConfigure(void* data, struct zwlr_layer_surface_v1* surface, uint32_t serial, @@ -333,10 +340,7 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { static void onSurfaceClosed(void* data, struct zwlr_layer_surface_v1* /* surface */) { auto o = static_cast(data); - if (o->layer_surface_) { - zwlr_layer_surface_v1_destroy(o->layer_surface_); - o->layer_surface_ = nullptr; - } + o->layer_surface_.reset(); } }; From fc5906dbd4a9d026a6f746ffe37ec69ee5e2e7ea Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Thu, 22 Oct 2020 23:04:58 -0700 Subject: [PATCH 8/9] feat(bar): change layer to `bottom` when hidden Invisible bar on a `top` layer would still intercept pointer events and stop them from reaching windows below. Always changing the layer to to `bottom` along with making bar invisible would prevent that. --- include/bar.hpp | 9 ++++++++- src/bar.cpp | 27 +++++++++++++++++---------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/include/bar.hpp b/include/bar.hpp index 8348070f..88df8b71 100644 --- a/include/bar.hpp +++ b/include/bar.hpp @@ -22,6 +22,12 @@ struct waybar_output { nullptr, &zxdg_output_v1_destroy}; }; +enum class bar_layer : uint8_t { + BOTTOM, + TOP, + OVERLAY, +}; + struct bar_margins { int top = 0; int right = 0; @@ -35,7 +41,7 @@ class BarSurface { public: virtual void setExclusiveZone(bool enable) = 0; - virtual void setLayer(const std::string_view &layer) = 0; + virtual void setLayer(bar_layer layer) = 0; virtual void setMargins(const struct bar_margins &margins) = 0; virtual void setPosition(const std::string_view &position) = 0; virtual void setSize(uint32_t width, uint32_t height) = 0; @@ -71,6 +77,7 @@ class Bar { std::unique_ptr surface_impl_; uint32_t width_ = 0; uint32_t height_ = 1; + bar_layer layer_; Gtk::Box left_; Gtk::Box center_; Gtk::Box right_; diff --git a/src/bar.cpp b/src/bar.cpp index c2cf6d34..f0fe64a7 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -52,11 +52,11 @@ struct GLSSurfaceImpl : public BarSurface, public sigc::trackable { gtk_layer_set_margin(window_.gobj(), GTK_LAYER_SHELL_EDGE_BOTTOM, margins.bottom); } - void setLayer(const std::string_view& value) override { + void setLayer(bar_layer value) override { auto layer = GTK_LAYER_SHELL_LAYER_BOTTOM; - if (value == "top") { + if (value == bar_layer::TOP) { layer = GTK_LAYER_SHELL_LAYER_TOP; - } else if (value == "overlay") { + } else if (value == bar_layer::OVERLAY) { layer = GTK_LAYER_SHELL_LAYER_OVERLAY; } gtk_layer_set_layer(window_.gobj(), layer); @@ -155,11 +155,11 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { } } - void setLayer(const std::string_view& layer) override { + void setLayer(bar_layer layer) override { layer_ = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM; - if (layer == "top") { + if (layer == bar_layer::TOP) { layer_ = ZWLR_LAYER_SHELL_V1_LAYER_TOP; - } else if (layer == "overlay") { + } else if (layer == bar_layer::OVERLAY) { layer_ = ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY; } // updating already mapped window @@ -168,7 +168,7 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { ZWLR_LAYER_SURFACE_V1_SET_LAYER_SINCE_VERSION) { zwlr_layer_surface_v1_set_layer(layer_surface_.get(), layer_); } else { - spdlog::warn("Unable to set layer: layer-shell interface version is too old"); + spdlog::warn("Unable to change layer: layer-shell implementation is too old"); } } } @@ -350,6 +350,7 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) : output(w_output), config(w_config), window{Gtk::WindowType::WINDOW_TOPLEVEL}, + layer_{bar_layer::BOTTOM}, left_(Gtk::ORIENTATION_HORIZONTAL, 0), center_(Gtk::ORIENTATION_HORIZONTAL, 0), right_(Gtk::ORIENTATION_HORIZONTAL, 0), @@ -364,6 +365,12 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) center_.get_style_context()->add_class("modules-center"); right_.get_style_context()->add_class("modules-right"); + if (config["layer"] == "top") { + layer_ = bar_layer::TOP; + } else if (config["layer"] == "overlay") { + layer_ = bar_layer::OVERLAY; + } + auto position = config["position"].asString(); if (position == "right" || position == "left") { @@ -436,9 +443,7 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) surface_impl_ = std::make_unique(window, *output); } - if (config["layer"].isString()) { - surface_impl_->setLayer(config["layer"].asString()); - } + surface_impl_->setLayer(layer_); surface_impl_->setExclusiveZone(true); surface_impl_->setMargins(margins_); surface_impl_->setPosition(position); @@ -463,9 +468,11 @@ void waybar::Bar::setVisible(bool value) { if (!visible) { window.get_style_context()->add_class("hidden"); window.set_opacity(0); + surface_impl_->setLayer(bar_layer::BOTTOM); } else { window.get_style_context()->remove_class("hidden"); window.set_opacity(1); + surface_impl_->setLayer(layer_); } surface_impl_->setExclusiveZone(visible); surface_impl_->commit(); From 9c566564e1c892b4f681be3787cd8a589f95a0ec Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Fri, 23 Oct 2020 02:59:04 -0700 Subject: [PATCH 9/9] fix(bar): address some of RawSurfaceImpl resizing issues --- include/bar.hpp | 2 -- src/bar.cpp | 55 ++++++++++++++++++++++++++++--------------------- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/include/bar.hpp b/include/bar.hpp index 88df8b71..8aab8f7c 100644 --- a/include/bar.hpp +++ b/include/bar.hpp @@ -75,8 +75,6 @@ class Bar { void setupAltFormatKeyForModuleList(const char *module_list_name); std::unique_ptr surface_impl_; - uint32_t width_ = 0; - uint32_t height_ = 1; bar_layer layer_; Gtk::Box left_; Gtk::Box center_; diff --git a/src/bar.cpp b/src/bar.cpp index f0fe64a7..771adab5 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -199,8 +199,8 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { } void setSize(uint32_t width, uint32_t height) override { - width_ = width; - height_ = height; + configured_width_ = width_ = width; + configured_height_ = height_ = height; // layer_shell.configure handler should update exclusive zone if size changes window_.set_size_request(width, height); }; @@ -224,8 +224,10 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { Gtk::Window& window_; std::string output_name_; - uint32_t width_; - uint32_t height_; + uint32_t configured_width_ = 0; + uint32_t configured_height_ = 0; + uint32_t width_ = 0; + uint32_t height_ = 0; uint8_t anchor_ = HORIZONTAL_ANCHOR | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; bool exclusive_zone_ = true; struct bar_margins margins_; @@ -280,22 +282,22 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { if (height_ > 1) { spdlog::warn(MIN_HEIGHT_MSG, height_, ev->height); } - /* - if (config["height"].isUInt()) { + if (configured_height_ > 1) { spdlog::info(SIZE_DEFINED, "Height"); - } else */ - tmp_height = ev->height; + } else { + tmp_height = ev->height; + } } if (ev->width > static_cast(width_)) { // Default minimal value if (width_ > 1) { spdlog::warn(MIN_WIDTH_MSG, width_, ev->width); } - /* - if (config["width"].isUInt()) { + if (configured_width_ > 1) { spdlog::info(SIZE_DEFINED, "Width"); - } else */ - tmp_width = ev->width; + } else { + tmp_width = ev->width; + } } if (tmp_width != width_ || tmp_height != height_) { setSurfaceSize(tmp_width, tmp_height); @@ -308,13 +310,20 @@ struct RawSurfaceImpl : public BarSurface, public sigc::trackable { * size without margins for the axis. * layer_surface.set_size, however, expects size with margins for the anchored axis. * This is not specified by wlr-layer-shell and based on actual behavior of sway. + * + * If the size for unanchored axis is not set (0), change request to 1 to avoid automatic + * assignment by the compositor. */ - bool vertical = (anchor_ & VERTICAL_ANCHOR) == VERTICAL_ANCHOR; - if (vertical && height > 1) { - height += margins_.top + margins_.bottom; - } - if (!vertical && width > 1) { - width += margins_.right + margins_.left; + if ((anchor_ & VERTICAL_ANCHOR) == VERTICAL_ANCHOR) { + width = width > 0 ? width : 1; + if (height > 1) { + height += margins_.top + margins_.bottom; + } + } else { + height = height > 0 ? height : 1; + if (width > 1) { + width += margins_.right + margins_.left; + } } spdlog::debug("Set surface size {}x{} for output {}", width, height, output_name_); zwlr_layer_surface_v1_set_size(layer_surface_.get(), width, height); @@ -379,12 +388,10 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) right_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0); box_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0); vertical = true; - - height_ = 0; - width_ = 1; } - height_ = config["height"].isUInt() ? config["height"].asUInt() : height_; - width_ = config["width"].isUInt() ? config["width"].asUInt() : width_; + + uint32_t height = config["height"].isUInt() ? config["height"].asUInt() : 0; + uint32_t width = config["width"].isUInt() ? config["width"].asUInt() : 0; struct bar_margins margins_; @@ -447,7 +454,7 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) surface_impl_->setExclusiveZone(true); surface_impl_->setMargins(margins_); surface_impl_->setPosition(position); - surface_impl_->setSize(width_, height_); + surface_impl_->setSize(width, height); window.signal_map_event().connect_notify(sigc::mem_fun(*this, &Bar::onMap));