managers: Turn gsettings management into a separate piece.

This commit is contained in:
Dorota Czaplejewicz
2020-03-05 10:25:08 +00:00
parent b19938da01
commit e504154571
3 changed files with 81 additions and 63 deletions

View File

@ -47,7 +47,6 @@ static guint signals[LAST_SIGNAL] = { 0, };
struct _EekboardContextServicePrivate {
LevelKeyboard *keyboard; // currently used keyboard
GSettings *settings; // Owned reference
// Maybe TODO: it's used only for fetching layout type.
// Maybe let UI push the type to this structure?
@ -160,34 +159,9 @@ eekboard_context_service_use_layout(EekboardContextService *context, struct sque
}
}
static void eekboard_context_service_update_settings_layout(EekboardContextService *context) {
g_autofree gchar *keyboard_layout = NULL;
g_autofree gchar *keyboard_type = NULL;
settings_get_layout(context->priv->settings,
&keyboard_type, &keyboard_layout);
if (g_strcmp0(context->layout->layout_name, keyboard_layout) != 0 || context->layout->overlay_name) {
g_free(context->layout->overlay_name);
context->layout->overlay_name = NULL;
if (keyboard_layout) {
g_free(context->layout->layout_name);
context->layout->layout_name = g_strdup(keyboard_layout);
}
// This must actually update the UI.
eekboard_context_service_use_layout(context, context->layout);
}
}
static gboolean
settings_handle_layout_changed(GSettings *s,
gpointer keys, gint n_keys,
gpointer user_data) {
(void)s;
(void)keys;
(void)n_keys;
EekboardContextService *context = user_data;
eekboard_context_service_update_settings_layout(context);
return TRUE;
static void
eekboard_context_service_init (EekboardContextService *self) {
self->priv = EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(self);
}
static void
@ -237,36 +211,6 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass)
pspec);
}
static void
eekboard_context_service_init (EekboardContextService *self)
{
self->priv = EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(self);
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.");
}
}
/**
* eekboard_context_service_destroy:
* @context: an #EekboardContextService
@ -321,7 +265,6 @@ EekboardContextService *eekboard_context_service_new(struct squeek_layout_state
{
EekboardContextService *context = g_object_new (EEKBOARD_TYPE_CONTEXT_SERVICE, NULL);
context->layout = state;
eekboard_context_service_update_settings_layout(context);
eekboard_context_service_use_layout(context, context->layout);
return context;
}
@ -336,3 +279,67 @@ void eekboard_context_service_set_submission(EekboardContextService *context, st
void eekboard_context_service_set_ui(EekboardContextService *context, ServerContextService *ui) {
context->priv->ui = ui;
}
static void settings_update_layout(struct gsettings_tracker *self) {
// The layout in the param must be the same layout as held by context.
g_autofree gchar *keyboard_layout = NULL;
g_autofree gchar *keyboard_type = NULL;
settings_get_layout(self->gsettings,
&keyboard_type, &keyboard_layout);
if (g_strcmp0(self->layout->layout_name, keyboard_layout) != 0 || self->layout->overlay_name) {
g_free(self->layout->overlay_name);
self->layout->overlay_name = NULL;
if (keyboard_layout) {
g_free(self->layout->layout_name);
self->layout->layout_name = g_strdup(keyboard_layout);
}
// This must actually update the UI.
eekboard_context_service_use_layout(self->context, self->layout);
}
}
static gboolean
handle_layout_changed(GSettings *s,
gpointer keys, gint n_keys,
gpointer user_data) {
(void)s;
(void)keys;
(void)n_keys;
struct gsettings_tracker *self = user_data;
settings_update_layout(self);
return TRUE;
}
void eek_gsettings_tracker_init(struct gsettings_tracker *tracker, EekboardContextService *context, struct squeek_layout_state *layout)
{
tracker->layout = layout;
tracker->context = context;
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...
tracker->gsettings = g_settings_new (schema_name);
gulong conn_id = g_signal_connect(tracker->gsettings, "change-event",
G_CALLBACK(handle_layout_changed),
tracker);
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.");
}
settings_update_layout(tracker);
}

View File

@ -47,7 +47,7 @@ typedef struct _EekboardContextServicePrivate EekboardContextServicePrivate;
/**
* EekboardContextService:
*
* Handles layout state, gsettings, and virtual-keyboard.
* Handles layout state, and virtual-keyboard.
*
* TODO: Restrict to managing keyboard layouts, and maybe button repeats,
* and the virtual keyboard protocol.
@ -82,6 +82,16 @@ struct _EekboardContextServiceClass {
GType eekboard_context_service_get_type
(void) G_GNUC_CONST;
/// Handles gsettings os-level keyboard layout switches.
struct gsettings_tracker {
GSettings *gsettings; // Owned reference
EekboardContextService *context; // Unowned
struct squeek_layout_state *layout; // Unowned
};
void eek_gsettings_tracker_init(struct gsettings_tracker* tracker, EekboardContextService *context, struct squeek_layout_state *layout);
EekboardContextService *eekboard_context_service_new(struct squeek_layout_state *state);
void eekboard_context_service_set_submission(EekboardContextService *context, struct submission *submission);
void eekboard_context_service_set_ui(EekboardContextService *context, ServerContextService *ui);

View File

@ -42,11 +42,12 @@
struct squeekboard {
struct squeek_wayland wayland; // Just hooks.
DBusHandler *dbus_handler; // Controls visibility of the OSK.
EekboardContextService *settings_context; // Gsettings hooks.
EekboardContextService *settings_context; // Currently used layout & keyboard.
ServerContextService *ui_context; // mess, includes the entire UI
struct submission *submission; // Wayland text input handling.
struct squeek_layout_state layout_choice; // Currently wanted layout.
struct ui_manager *ui_manager; // UI shape tracker/chooser. TODO: merge with layuot choice
struct gsettings_tracker gsettings_tracker; // Gsettings handling.
};
@ -206,7 +207,7 @@ main (int argc, char **argv)
instance.ui_manager = squeek_uiman_new(instance.wayland.outputs);
instance.settings_context = eekboard_context_service_new(&instance.layout_choice);
eek_gsettings_tracker_init(&instance.gsettings_tracker, instance.settings_context, &instance.layout_choice);
// set up dbus
// TODO: make dbus errors non-always-fatal