aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2023-06-24 21:43:53 +0200
committerPřemysl Eric Janouch <p@janouch.name>2023-06-24 22:13:08 +0200
commit4b5b8ec9fa583f080e08c1706108137c3cc45159 (patch)
tree97cb729798723247a5775bea8fcecd939311b020
parent3449ac5a125a542c1ce78377f312607faf4271a8 (diff)
downloadfiv-4b5b8ec9fa583f080e08c1706108137c3cc45159.tar.gz
fiv-4b5b8ec9fa583f080e08c1706108137c3cc45159.tar.xz
fiv-4b5b8ec9fa583f080e08c1706108137c3cc45159.zip
Implement our own Preferences dialog
And fix a resource leak.
-rw-r--r--docs/fiv.html10
-rw-r--r--fiv-view.c1
-rw-r--r--fiv.c119
3 files changed, 107 insertions, 23 deletions
diff --git a/docs/fiv.html b/docs/fiv.html
index 72b1963..a458882 100644
--- a/docs/fiv.html
+++ b/docs/fiv.html
@@ -95,14 +95,8 @@ rm -rf ~/.cache/thumbnails/wide-*
<h2>Configuration</h2>
-<p>The few configuration options <i>fiv</i> has can be adjusted using
-<i>dconf-editor</i>, which can be launched in the appropriate location from
-within the application by pressing <kbd>Ctrl</kbd>&#8239;+&#8239;<kbd>,</kbd>.
-For command line usage, there is the <i>gsettings</i> utility:
-
-<pre>
-gsettings list-recursively name.janouch.fiv
-</pre>
+<p>To adjust the few configuration options of <i>fiv</i>,
+press <kbd>Ctrl</kbd>&#8239;+&#8239;<kbd>,</kbd> to open <i>Preferences</i>.
<p>To make your changes take effect, restart <i>fiv</i>.
diff --git a/fiv-view.c b/fiv-view.c
index be8cbe5..bce7a4b 100644
--- a/fiv-view.c
+++ b/fiv-view.c
@@ -556,6 +556,7 @@ fiv_view_realize(GtkWidget *widget)
if (GDK_IS_X11_WINDOW(window) &&
g_settings_get_boolean(settings, "native-view-window"))
gdk_window_ensure_native(window);
+ g_object_unref(settings);
#endif // GDK_WINDOWING_X11
gtk_widget_register_window(widget, window);
diff --git a/fiv.c b/fiv.c
index 76133ae..bf23a44 100644
--- a/fiv.c
+++ b/fiv.c
@@ -514,6 +514,109 @@ show_about_dialog(GtkWidget *parent)
cairo_pattern_destroy(ctx.v_pattern);
}
+// --- Settings ----------------------------------------------------------------
+
+static void
+preferences_make_row(
+ GtkWidget *grid, int *row, GSettings *settings, GSettingsSchemaKey *key)
+{
+ const char *name = g_settings_schema_key_get_name(key);
+ const char *summary = g_settings_schema_key_get_summary(key);
+ const char *description = g_settings_schema_key_get_description(key);
+
+ GtkWidget *widget = NULL;
+ const GVariantType *type = g_settings_schema_key_get_value_type(key);
+ if (g_variant_type_equal(type, G_VARIANT_TYPE_BOOLEAN)) {
+ widget = gtk_switch_new();
+ g_settings_bind(
+ settings, name, widget, "active", G_SETTINGS_BIND_DEFAULT);
+ } else {
+ const gchar *type = NULL;
+ GVariant *value = NULL, *range = g_settings_schema_key_get_range(key);
+ g_variant_get(range, "(&sv)", &type, &value);
+ GVariantIter iter = {};
+ g_variant_iter_init(&iter, value);
+ if (g_str_equal(type, "enum")) {
+ widget = gtk_combo_box_text_new();
+
+ GVariant *child = NULL;
+ while ((child = g_variant_iter_next_value(&iter))) {
+ const char *id = g_variant_get_string(child, NULL);
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(widget), id, id);
+ g_variant_unref(child);
+ }
+
+ g_settings_bind(
+ settings, name, widget, "active-id", G_SETTINGS_BIND_DEFAULT);
+ }
+ g_variant_unref(value);
+ g_variant_unref(range);
+ }
+
+ // Ignore unimplemented value types.
+ if (!widget)
+ return;
+
+ GtkWidget *label = gtk_label_new(summary ? summary : name);
+ gtk_label_set_xalign(GTK_LABEL(label), 0);
+ gtk_widget_set_hexpand(label, TRUE);
+ gtk_grid_attach(GTK_GRID(grid), label, 0, (*row), 1, 1);
+ gtk_widget_set_halign(widget, GTK_ALIGN_END);
+ gtk_grid_attach(GTK_GRID(grid), widget, 1, (*row)++, 1, 1);
+
+ if (description) {
+ GtkWidget *label = gtk_label_new(description);
+ PangoAttrList *attr_list = pango_attr_list_new();
+ pango_attr_list_insert(
+ attr_list, pango_attr_scale_new(PANGO_SCALE_SMALL));
+ gtk_label_set_attributes(
+ GTK_LABEL(label), pango_attr_list_ref(attr_list));
+ pango_attr_list_unref(attr_list);
+
+ gtk_label_set_xalign(GTK_LABEL(label), 0);
+ gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+ gtk_widget_set_sensitive(label, FALSE);
+ gtk_widget_set_size_request(label, 0, -1);
+ gtk_grid_attach(GTK_GRID(grid), label, 0, (*row)++, 1, 1);
+ }
+}
+
+static void
+show_preferences(GtkWidget *parent)
+{
+ GSettingsSchema *schema = NULL;
+ GSettings *settings = g_settings_new(PROJECT_NS PROJECT_NAME);
+ g_object_get(settings, "settings-schema", &schema, NULL);
+
+ GtkWidget *dialog = gtk_widget_new(GTK_TYPE_DIALOG,
+ "use-header-bar", TRUE,
+ "title", "Preferences",
+ "transient-for", parent,
+ "destroy-with-parent", TRUE, NULL);
+
+ GtkWidget *grid = gtk_grid_new();
+ gtk_grid_set_row_spacing(GTK_GRID(grid), 12);
+ gtk_grid_set_column_spacing(GTK_GRID(grid), 24);
+ g_object_set(grid, "margin", 12, NULL);
+ gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+ grid, TRUE, TRUE, 0);
+
+ int row = 0;
+ gchar **keys = g_settings_schema_list_keys(schema);
+ for (gchar **p = keys; *p; p++) {
+ GSettingsSchemaKey *key = g_settings_schema_get_key(schema, *p);
+ preferences_make_row(grid, &row, settings, key);
+ g_settings_schema_key_unref(key);
+ }
+ g_strfreev(keys);
+ g_object_unref(settings);
+
+ gtk_window_set_default_size(GTK_WINDOW(dialog), 600, -1);
+ gtk_widget_show_all(dialog);
+ gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(dialog);
+}
+
// --- Main --------------------------------------------------------------------
// TODO(p): See if it's possible to give separators room to shrink
@@ -1345,20 +1448,6 @@ show_help_shortcuts(void)
}
static void
-show_preferences(void)
-{
- char *argv[] = {"dconf-editor", PROJECT_NS PROJECT_NAME, NULL};
- GError *error = NULL;
- if (!g_spawn_async(
- NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error)) {
- if (g_error_matches(error, G_SPAWN_ERROR, G_SPAWN_ERROR_NOENT))
- g_prefix_error(&error, "%s",
- "Please install dconf-editor, or use the gsettings utility.\n");
- show_error_dialog(error);
- }
-}
-
-static void
toggle_sunlight(void)
{
GtkSettings *settings = gtk_settings_get_default();
@@ -1415,7 +1504,7 @@ on_key_press(G_GNUC_UNUSED GtkWidget *widget, GdkEventKey *event,
show_help_shortcuts();
return TRUE;
case GDK_KEY_comma:
- show_preferences();
+ show_preferences(g.window);
return TRUE;
}
break;