From 7b23d586846e9cdb10f203f25a472bf945f4ed68 Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Sat, 17 Aug 2024 21:55:28 -0700 Subject: [PATCH] fix(bar): force commit for occluded surfaces All the mode or visibility changes require `wl_surface_commit` to be applied. gtk-layer-shell will attempt to force GTK to commit, but may fail if the surface has stopped receiving frame callbacks[^1]. Thus, we could get stuck in a state where the bar is hidden and unable to regain visibility. To address this, a new API has been added to gtk-layer-shell, `gtk_layer_try_force_commit`, which does `wl_surface_commit` with the necessary safety checks to avoid corrupting GTK internal state. Note: this change bumps gtk-layer-shell requirement to 0.9.0. [^1]: https://github.com/wmww/gtk-layer-shell/issues/185 --- meson.build | 2 +- src/bar.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 42f9da92..f4941c8f 100644 --- a/meson.build +++ b/meson.build @@ -106,7 +106,7 @@ if libsndio.found() endif endif -gtk_layer_shell = dependency('gtk-layer-shell-0', version: ['>=0.6.0'], +gtk_layer_shell = dependency('gtk-layer-shell-0', version: ['>=0.9.0'], default_options: ['introspection=false', 'vapi=false'], fallback: ['gtk-layer-shell', 'gtk_layer_shell']) systemd = dependency('systemd', required: get_option('systemd')) diff --git a/src/bar.cpp b/src/bar.cpp index 8bb214c0..ebe23367 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -132,6 +132,7 @@ void from_json(const Json::Value& j, std::map& m) { 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}, x_global(0), y_global(0), @@ -339,6 +340,13 @@ void waybar::Bar::setMode(const struct bar_mode& mode) { window.get_style_context()->add_class("hidden"); window.set_opacity(0); } + /* + * All the changes above require `wl_surface_commit`. + * gtk-layer-shell schedules a commit on the next frame event in GTK, but this could fail in + * certain scenarios, such as fully occluded bar. + */ + gtk_layer_try_force_commit(gtk_window); + wl_display_flush(Client::inst()->wl_display); } void waybar::Bar::setPassThrough(bool passthrough) {