fix(client): don't exit when the desktop portal fails to start

The Portal constructor synchronously auto-starts org.freedesktop.portal.Desktop
via a Gio::DBus::Proxy. If that service fails or crashes on start it throws a
Glib::Error, which was previously uncaught and terminated Waybar. Wrap the
construction in a try/catch, log a warning and leave portal as nullptr on
failure, and null-guard every dereference so a missing portal simply disables
light/dark appearance detection instead of crashing.

Fixes #3140, #3601.
This commit is contained in:
Alex
2026-07-04 03:14:13 +02:00
parent d130ce6a66
commit c29ed5f972
+13 -1
View File
@@ -211,7 +211,7 @@ const std::string waybar::Client::getStyle(const std::string& style,
if (style.empty()) { if (style.empty()) {
std::vector<std::string> search_files; std::vector<std::string> search_files;
switch (appearance.value_or(portal->getAppearance())) { switch (appearance.value_or(portal ? portal->getAppearance() : waybar::Appearance::UNKNOWN)) {
case waybar::Appearance::LIGHT: case waybar::Appearance::LIGHT:
search_files.emplace_back("style-light.css"); search_files.emplace_back("style-light.css");
gtk_settings->property_gtk_application_prefer_dark_theme() = false; gtk_settings->property_gtk_application_prefer_dark_theme() = false;
@@ -344,16 +344,26 @@ int waybar::Client::main(int argc, char* argv[]) {
wl_display = gdk_wayland_display_get_wl_display(gdk_display->gobj()); wl_display = gdk_wayland_display_get_wl_display(gdk_display->gobj());
config.load(config_opt); config.load(config_opt);
if (!portal) { if (!portal) {
try {
portal = std::make_unique<waybar::Portal>(); portal = std::make_unique<waybar::Portal>();
} catch (const Glib::Error& e) {
spdlog::warn(
"Failed to connect to the desktop portal, light/dark theme detection disabled: {}",
std::string(e.what()));
} catch (...) {
spdlog::warn("Failed to connect to the desktop portal, light/dark theme detection disabled");
}
} }
m_cssFile = getStyle(style_opt); m_cssFile = getStyle(style_opt);
setupCss(m_cssFile); setupCss(m_cssFile);
m_cssReloadHelper = std::make_unique<CssReloadHelper>(m_cssFile, [&](const std::string& css_file) { setupCss(css_file); }); m_cssReloadHelper = std::make_unique<CssReloadHelper>(m_cssFile, [&](const std::string& css_file) { setupCss(css_file); });
if (portal) {
portal->signal_appearance_changed().connect([&](waybar::Appearance appearance) { portal->signal_appearance_changed().connect([&](waybar::Appearance appearance) {
auto css_file = getStyle(style_opt, appearance); auto css_file = getStyle(style_opt, appearance);
m_cssReloadHelper->changeCssFile(css_file); m_cssReloadHelper->changeCssFile(css_file);
setupCss(css_file); setupCss(css_file);
}); });
}
auto m_config = config.getConfig(); auto m_config = config.getConfig();
if (m_config.isObject() && m_config["reload_style_on_change"].asBool()) { if (m_config.isObject() && m_config["reload_style_on_change"].asBool()) {
@@ -378,5 +388,7 @@ int waybar::Client::main(int argc, char* argv[]) {
void waybar::Client::reset() { void waybar::Client::reset() {
gtk_app->quit(); gtk_app->quit();
// delete signal handler for css changes // delete signal handler for css changes
if (portal) {
portal->signal_appearance_changed().clear(); portal->signal_appearance_changed().clear();
} }
}