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.
pull/892/head
Aleksei Bavshin 2020-10-22 23:04:58 -07:00
parent fe3aeb36c5
commit fc5906dbd4
No known key found for this signature in database
GPG Key ID: 4F071603387A382A
2 changed files with 25 additions and 11 deletions

View File

@ -22,6 +22,12 @@ struct waybar_output {
nullptr, &zxdg_output_v1_destroy}; nullptr, &zxdg_output_v1_destroy};
}; };
enum class bar_layer : uint8_t {
BOTTOM,
TOP,
OVERLAY,
};
struct bar_margins { struct bar_margins {
int top = 0; int top = 0;
int right = 0; int right = 0;
@ -35,7 +41,7 @@ class BarSurface {
public: public:
virtual void setExclusiveZone(bool enable) = 0; 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 setMargins(const struct bar_margins &margins) = 0;
virtual void setPosition(const std::string_view &position) = 0; virtual void setPosition(const std::string_view &position) = 0;
virtual void setSize(uint32_t width, uint32_t height) = 0; virtual void setSize(uint32_t width, uint32_t height) = 0;
@ -71,6 +77,7 @@ class Bar {
std::unique_ptr<BarSurface> surface_impl_; std::unique_ptr<BarSurface> surface_impl_;
uint32_t width_ = 0; uint32_t width_ = 0;
uint32_t height_ = 1; uint32_t height_ = 1;
bar_layer layer_;
Gtk::Box left_; Gtk::Box left_;
Gtk::Box center_; Gtk::Box center_;
Gtk::Box right_; Gtk::Box right_;

View File

@ -52,11 +52,11 @@ struct GLSSurfaceImpl : public BarSurface, public sigc::trackable {
gtk_layer_set_margin(window_.gobj(), GTK_LAYER_SHELL_EDGE_BOTTOM, margins.bottom); 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; auto layer = GTK_LAYER_SHELL_LAYER_BOTTOM;
if (value == "top") { if (value == bar_layer::TOP) {
layer = GTK_LAYER_SHELL_LAYER_TOP; layer = GTK_LAYER_SHELL_LAYER_TOP;
} else if (value == "overlay") { } else if (value == bar_layer::OVERLAY) {
layer = GTK_LAYER_SHELL_LAYER_OVERLAY; layer = GTK_LAYER_SHELL_LAYER_OVERLAY;
} }
gtk_layer_set_layer(window_.gobj(), layer); 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; layer_ = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM;
if (layer == "top") { if (layer == bar_layer::TOP) {
layer_ = ZWLR_LAYER_SHELL_V1_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; layer_ = ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY;
} }
// updating already mapped window // 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_SINCE_VERSION) {
zwlr_layer_surface_v1_set_layer(layer_surface_.get(), layer_); zwlr_layer_surface_v1_set_layer(layer_surface_.get(), layer_);
} else { } 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), : output(w_output),
config(w_config), config(w_config),
window{Gtk::WindowType::WINDOW_TOPLEVEL}, window{Gtk::WindowType::WINDOW_TOPLEVEL},
layer_{bar_layer::BOTTOM},
left_(Gtk::ORIENTATION_HORIZONTAL, 0), left_(Gtk::ORIENTATION_HORIZONTAL, 0),
center_(Gtk::ORIENTATION_HORIZONTAL, 0), center_(Gtk::ORIENTATION_HORIZONTAL, 0),
right_(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"); center_.get_style_context()->add_class("modules-center");
right_.get_style_context()->add_class("modules-right"); 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(); auto position = config["position"].asString();
if (position == "right" || position == "left") { 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<RawSurfaceImpl>(window, *output); surface_impl_ = std::make_unique<RawSurfaceImpl>(window, *output);
} }
if (config["layer"].isString()) { surface_impl_->setLayer(layer_);
surface_impl_->setLayer(config["layer"].asString());
}
surface_impl_->setExclusiveZone(true); surface_impl_->setExclusiveZone(true);
surface_impl_->setMargins(margins_); surface_impl_->setMargins(margins_);
surface_impl_->setPosition(position); surface_impl_->setPosition(position);
@ -463,9 +468,11 @@ void waybar::Bar::setVisible(bool value) {
if (!visible) { if (!visible) {
window.get_style_context()->add_class("hidden"); window.get_style_context()->add_class("hidden");
window.set_opacity(0); window.set_opacity(0);
surface_impl_->setLayer(bar_layer::BOTTOM);
} else { } else {
window.get_style_context()->remove_class("hidden"); window.get_style_context()->remove_class("hidden");
window.set_opacity(1); window.set_opacity(1);
surface_impl_->setLayer(layer_);
} }
surface_impl_->setExclusiveZone(visible); surface_impl_->setExclusiveZone(visible);
surface_impl_->commit(); surface_impl_->commit();