From b3cfc8a0f3f923b4d60fe1079e94d9ee2b131bcc Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Tue, 3 Mar 2020 19:10:40 +0000 Subject: [PATCH 1/3] gsettings: Don't crash when unavailable --- eekboard/eekboard-context-service.c | 34 ++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/eekboard/eekboard-context-service.c b/eekboard/eekboard-context-service.c index c07885c2..a6961662 100644 --- a/eekboard/eekboard-context-service.c +++ b/eekboard/eekboard-context-service.c @@ -113,6 +113,9 @@ eekboard_context_service_dispose (GObject *object) static void settings_get_layout(GSettings *settings, char **type, char **layout) { + if (!settings) { + return; + } GVariant *inputs = g_settings_get_value(settings, "sources"); if (g_variant_n_children(inputs) == 0) { g_warning("No system layout present"); @@ -257,14 +260,29 @@ eekboard_context_service_init (EekboardContextService *self) g_direct_equal, NULL, (GDestroyNotify)g_object_unref); - - self->priv->settings = g_settings_new ("org.gnome.desktop.input-sources"); - gulong conn_id = g_signal_connect(self->priv->settings, "change-event", - G_CALLBACK(settings_handle_layout_changed), - self); - if (conn_id == 0) { - g_warning ("Could not connect to gsettings updates, layout" - " changing unavailable"); + const char *schema_name = "org.gnome.desktop.input-sources"; + GSettingsSchemaSource *ssrc = g_settings_schema_source_get_default(); + if (ssrc) { + GSettingsSchema *schema = g_settings_schema_source_lookup(ssrc, + schema_name, + TRUE); + if (schema) { + // Not referencing the found schema directly, + // because it's not clear how... + self->priv->settings = g_settings_new (schema_name); + gulong conn_id = g_signal_connect(self->priv->settings, "change-event", + G_CALLBACK(settings_handle_layout_changed), + self); + if (conn_id == 0) { + g_warning ("Could not connect to gsettings updates, " + "automatic layout changing unavailable"); + } + } else { + g_warning("Gsettings schema %s is not installed on the system. " + "Layout switching unavailable", schema_name); + } + } else { + g_warning("No gsettings schemas installed. Layout switching unavailable."); } self->priv->overlay = NULL; From 8bae8fe5bba2e81ce7aeafd2fc3034d457db1b22 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Tue, 3 Mar 2020 19:25:49 +0000 Subject: [PATCH 2/3] dbus: Don't crash if can't make a connection --- src/server-main.c | 53 +++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/server-main.c b/src/server-main.c index 68a5f06a..db427791 100644 --- a/src/server-main.c +++ b/src/server-main.c @@ -222,9 +222,9 @@ main (int argc, char **argv) error = NULL; connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); if (connection == NULL) { - g_printerr ("Can't connect to the bus: %s\n", error->message); + g_printerr ("Can't connect to the bus: %s. " + "Visibility switching unavailable.", error->message); g_error_free (error); - exit (1); } break; case G_BUS_TYPE_NONE: @@ -246,25 +246,28 @@ main (int argc, char **argv) g_assert_not_reached (); break; } + guint owner_id = 0; + DBusHandler *service = NULL; + if (connection) { + service = dbus_handler_new(connection, DBUS_SERVICE_PATH); - DBusHandler *service = dbus_handler_new(connection, DBUS_SERVICE_PATH); + if (service == NULL) { + g_printerr ("Can't create dbus server\n"); + exit (1); + } + instance.dbus_handler = service; - if (service == NULL) { - g_printerr ("Can't create dbus server\n"); - exit (1); - } - instance.dbus_handler = service; - - guint owner_id = g_bus_own_name_on_connection (connection, - DBUS_SERVICE_INTERFACE, - G_BUS_NAME_OWNER_FLAGS_NONE, - on_name_acquired, - on_name_lost, - NULL, - NULL); - if (owner_id == 0) { - g_printerr ("Can't own the name\n"); - exit (1); + owner_id = g_bus_own_name_on_connection (connection, + DBUS_SERVICE_INTERFACE, + G_BUS_NAME_OWNER_FLAGS_NONE, + on_name_acquired, + on_name_lost, + NULL, + NULL); + if (owner_id == 0) { + g_printerr ("Can't own the name\n"); + exit (1); + } } instance.submission = get_submission(instance.wayland.input_method_manager, @@ -296,9 +299,15 @@ main (int argc, char **argv) g_main_loop_run (loop); - g_bus_unown_name (owner_id); - g_object_unref (service); - g_object_unref (connection); + if (connection) { + if (service) { + if (owner_id != 0) { + g_bus_unown_name (owner_id); + } + g_object_unref (service); + } + g_object_unref (connection); + } g_main_loop_unref (loop); squeek_wayland_deinit (&instance.wayland); From 8ac2b5a7134e1d6781b81707ef426dfbccde4002 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Tue, 3 Mar 2020 19:46:53 +0000 Subject: [PATCH 3/3] gsettings: Don't crash on switching when unavailable --- src/popover.rs | 55 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/src/popover.rs b/src/popover.rs index 8330a920..96d3a971 100644 --- a/src/popover.rs +++ b/src/popover.rs @@ -132,19 +132,40 @@ fn make_menu_builder(inputs: Vec<(&str, OwnedTranslation)>) -> gtk::Builder { ) } +fn get_settings(schema_name: &str) -> Option { + let mut error_handler = logging::Print{}; + gio::SettingsSchemaSource::get_default() + .or_warn( + &mut error_handler, + logging::Problem::Surprise, + "No gsettings schemas installed.", + ) + .and_then(|sss| + sss.lookup(schema_name, true) + .or_warn( + &mut error_handler, + logging::Problem::Surprise, + &format!("Gsettings schema {} not installed", schema_name), + ) + ) + .map(|_sschema| gio::Settings::new(schema_name)) +} + fn set_layout(kind: String, name: String) { - let settings = gio::Settings::new("org.gnome.desktop.input-sources"); - let inputs = settings.get_value("sources").unwrap(); - let current = (kind.clone(), name.clone()); - let inputs = variants::get_tuples(inputs).into_iter() - .filter(|t| t != ¤t); - let inputs = vec![(kind, name)].into_iter() - .chain(inputs).collect(); - settings.set_value( - "sources", - &variants::ArrayPairString(inputs).to_variant(), - ); - settings.apply(); + let settings = get_settings("org.gnome.desktop.input-sources"); + if let Some(settings) = settings { + let inputs = settings.get_value("sources").unwrap(); + let current = (kind.clone(), name.clone()); + let inputs = variants::get_tuples(inputs).into_iter() + .filter(|t| t != ¤t); + let inputs = vec![(kind, name)].into_iter() + .chain(inputs).collect(); + settings.set_value( + "sources", + &variants::ArrayPairString(inputs).to_variant(), + ); + settings.apply(); + } } /// A reference to what the user wants to see @@ -284,9 +305,13 @@ pub fn show( let overlay_layouts = resources::get_overlays().into_iter() .map(|name| LayoutId::Local(name.to_string())); - let settings = gio::Settings::new("org.gnome.desktop.input-sources"); - let inputs = settings.get_value("sources").unwrap(); - let inputs = variants::get_tuples(inputs); + let settings = get_settings("org.gnome.desktop.input-sources"); + let inputs = settings + .map(|settings| { + let inputs = settings.get_value("sources").unwrap(); + variants::get_tuples(inputs) + }) + .unwrap_or_else(|| Vec::new()); let system_layouts: Vec = inputs.into_iter() .map(|(kind, name)| LayoutId::System { kind, name })