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
This commit is contained in:
Aleksei Bavshin 2024-08-17 21:55:28 -07:00
parent 4a6af0da99
commit 7b23d58684
No known key found for this signature in database
GPG Key ID: 4F071603387A382A
2 changed files with 9 additions and 1 deletions

View File

@ -106,7 +106,7 @@ if libsndio.found()
endif endif
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'], default_options: ['introspection=false', 'vapi=false'],
fallback: ['gtk-layer-shell', 'gtk_layer_shell']) fallback: ['gtk-layer-shell', 'gtk_layer_shell'])
systemd = dependency('systemd', required: get_option('systemd')) systemd = dependency('systemd', required: get_option('systemd'))

View File

@ -132,6 +132,7 @@ void from_json(const Json::Value& j, std::map<Key, Value>& m) {
waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) 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),
surface(nullptr),
window{Gtk::WindowType::WINDOW_TOPLEVEL}, window{Gtk::WindowType::WINDOW_TOPLEVEL},
x_global(0), x_global(0),
y_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.get_style_context()->add_class("hidden");
window.set_opacity(0); 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) { void waybar::Bar::setPassThrough(bool passthrough) {