xi-desktop-portals

Simpler specifications for Linux desktop APIs.
git clone https://git.ce9e.org/xi-desktop-portals.git

commit
408dbe50bbe489b2864b9408289f1b5d00ee855b
parent
e9d14d4512107849c9c644bda7f4c452127de096
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2026-03-14 12:51
[Settings] use more glib

Diffstat

M Settings/sync.c 155 ++++++++++++++++++++++++++++++++-----------------------------

1 files changed, 81 insertions, 74 deletions


diff --git a/Settings/sync.c b/Settings/sync.c

@@ -1,113 +1,120 @@
    1    -1 #include <dirent.h>
    2    -1 #include <fcntl.h>
    3    -1 #include <limits.h>
    4     1 #include <stdio.h>
    5     2 #include <stdlib.h>
    6    -1 #include <sys/inotify.h>
    7    -1 #include <sys/epoll.h>
    8    -1 #include <unistd.h>
   -1     3 #include <string.h>
    9     4 
   10     5 #include <gio/gio.h>
   -1     6 #include <glib.h>
   11     7 
   12    -1 #define EVENT_SIZE (sizeof(struct inotify_event))
   13    -1 #define BUF_LEN (1024 * (EVENT_SIZE + 16))
   14    -1 
   15    -1 char root[PATH_MAX - 64];
   16     8 GSettings *settings, *settings_a11y;
   17     9 
   18    -1 void on_change(const char *key) {
   19    -1     char path[PATH_MAX];
   20    -1     snprintf(path, sizeof(path), "%s/%s", root, key);
   21    -1 
   22    -1     int fd = open(path, O_RDONLY);
   23    -1     if (fd < 0) {
   24    -1         return;
   25    -1     }
   26    -1     char value[256];
   27    -1     int len = read(fd, value, sizeof(value) - 1);
   28    -1     close(fd);
   29    -1     if (len < 0) {
   -1    10 static void on_change(GFile *file) {
   -1    11     gchar *value = NULL;
   -1    12     if (!g_file_load_contents(file, NULL, &value, NULL, NULL, NULL)) {
   30    13         return;
   31    14     }
   32    -1     value[len] = '\0';
   33    -1     g_strchomp(value);
   -1    15     g_strstrip(value);
   34    16 
   35    -1     if (strcmp(key, "color-scheme") == 0) {
   36    -1         if (strcmp(value, "dark") == 0) {
   -1    17     gchar *key = g_file_get_basename(file);
   -1    18 
   -1    19     if (g_strcmp0(key, "color-scheme") == 0) {
   -1    20         if (g_strcmp0(value, "dark") == 0) {
   37    21             g_settings_set_string(settings, "color-scheme", "prefer-dark");
   38    -1         } else if (strcmp(value, "light") == 0) {
   -1    22         } else if (g_strcmp0(value, "light") == 0) {
   39    23             g_settings_set_string(settings, "color-scheme", "prefer-light");
   40    24         } else {
   41    25             g_settings_set_string(settings, "color-scheme", "default");
   42    26         }
   43    -1     } else if (strcmp(key, "accent-color") == 0) {
   -1    27     } else if (g_strcmp0(key, "accent-color") == 0) {
   44    28         // TODO: translate color to color name
   45    29         g_settings_set_string(settings, "accent-color", value);
   46    -1     } else if (strcmp(key, "reduced-motion") == 0) {
   47    -1         if (strcmp(value, "reduced") == 0) {
   -1    30     } else if (g_strcmp0(key, "reduced-motion") == 0) {
   -1    31         if (g_strcmp0(value, "reduced") == 0) {
   48    32             g_settings_set_string(settings_a11y, "reduced-motion", "reduce");
   49    33         } else {
   50    -1             g_settings_set_string(settings_a11y, "reduced-motion", "no-preference");
   -1    34             g_settings_set_string(
   -1    35                 settings_a11y, "reduced-motion", "no-preference"
   -1    36             );
   51    37         }
   52    -1     } else if (strcmp(key, "contrast") == 0) {
   53    -1         if (strcmp(value, "high") == 0) {
   -1    38     } else if (g_strcmp0(key, "contrast") == 0) {
   -1    39         if (g_strcmp0(value, "high") == 0) {
   54    40             g_settings_set_boolean(settings_a11y, "high-contrast", TRUE);
   55    41         } else {
   56    42             g_settings_set_boolean(settings_a11y, "high-contrast", FALSE);
   57    43         }
   58    44     }
   -1    45 
   -1    46     g_free(key);
   -1    47     g_free(value);
   59    48 }
   60    49 
   61    -1 int main() {
   62    -1     snprintf(
   63    -1         root, sizeof(root), "%s/org.freedesktop.appearance", g_get_user_config_dir()
   -1    50 static void on_monitor_changed(
   -1    51     GFileMonitor *monitor,
   -1    52     GFile *file,
   -1    53     GFile *other_file,
   -1    54     GFileMonitorEvent event_type,
   -1    55     gpointer user_data
   -1    56 ) {
   -1    57     if (event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
   -1    58         on_change(file);
   -1    59     }
   -1    60 }
   -1    61 
   -1    62 static void scan_initial_files(GFile *dir) {
   -1    63     GError *error = NULL;
   -1    64     GFileEnumerator *enumerator = g_file_enumerate_children(
   -1    65         dir,
   -1    66         G_FILE_ATTRIBUTE_STANDARD_NAME,
   -1    67         G_FILE_QUERY_INFO_NONE,
   -1    68         NULL,
   -1    69         &error
   64    70     );
   65    71 
   -1    72     if (error) {
   -1    73         g_error("Failed to enumerate directory: %s", error->message);
   -1    74         exit(EXIT_FAILURE);
   -1    75     }
   -1    76 
   -1    77     GFileInfo *info;
   -1    78     GFile *child;
   -1    79     while ((info = g_file_enumerator_next_file(enumerator, NULL, NULL))) {
   -1    80         child = g_file_enumerator_get_child(enumerator, info);
   -1    81         on_change(child);
   -1    82         g_object_unref(child);
   -1    83         g_object_unref(info);
   -1    84     }
   -1    85 
   -1    86     g_object_unref(enumerator);
   -1    87 }
   -1    88 
   -1    89 int main(void) {
   66    90     settings = g_settings_new("org.gnome.desktop.interface");
   67    91     settings_a11y = g_settings_new("org.gnome.desktop.a11y.interface");
   68    92 
   69    -1     int fd = inotify_init();
   70    -1     if (fd < 0) {
   71    -1         perror("inotify_init");
   72    -1         return EXIT_FAILURE;
   73    -1     }
   74    -1     int wd = inotify_add_watch(fd, root, IN_CLOSE_WRITE);
   75    -1     if (wd < 0) {
   76    -1         perror("inotify_add_watch");
   77    -1         return EXIT_FAILURE;
   78    -1     }
   -1    93     gchar *root = g_build_filename(
   -1    94         g_get_user_config_dir(), "org.freedesktop.appearance", NULL
   -1    95     );
   -1    96     GFile *dir = g_file_new_for_path(root);
   -1    97     g_free(root);
   79    98 
   80    -1     DIR *d = opendir(root);
   81    -1     struct dirent *entry;
   82    -1     if (d) {
   83    -1         while ((entry = readdir(d))) {
   84    -1             on_change(entry->d_name);
   85    -1         }
   86    -1         closedir(d);
   -1    99     GError *error = NULL;
   -1   100     GFileMonitor *monitor =
   -1   101         g_file_monitor_directory(dir, G_FILE_MONITOR_NONE, NULL, &error);
   -1   102     if (error) {
   -1   103         g_error("Failed to create monitor: %s", error->message);
   -1   104         return EXIT_FAILURE;
   87   105     }
   -1   106     g_signal_connect(monitor, "changed", G_CALLBACK(on_monitor_changed), NULL);
   88   107 
   89    -1     int epfd = epoll_create(1);
   90    -1     struct epoll_event ev, events[1];
   91    -1     ev.events = EPOLLIN;
   92    -1     epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
   93    -1 
   94    -1     char buf[BUF_LEN];
   95    -1     struct inotify_event *event;
   -1   108     scan_initial_files(dir);
   96   109 
   97    -1     while (1) {
   98    -1         epoll_wait(epfd, events, 1, -1);
   -1   110     GMainLoop *loop = g_main_loop_new(NULL, FALSE);
   -1   111     g_main_loop_run(loop);
   99   112 
  100    -1         int length = read(fd, buf, sizeof(buf));
  101    -1         if (length < 0) {
  102    -1             perror("read");
  103    -1             return EXIT_FAILURE;
  104    -1         }
   -1   113     g_main_loop_unref(loop);
   -1   114     g_object_unref(monitor);
   -1   115     g_object_unref(dir);
   -1   116     g_object_unref(settings);
   -1   117     g_object_unref(settings_a11y);
  105   118 
  106    -1         int i = 0;
  107    -1         while (i < length) {
  108    -1             event = (struct inotify_event *)&buf[i];
  109    -1             on_change(event->name);
  110    -1             i += EVENT_SIZE + event->len;
  111    -1         }
  112    -1     }
   -1   119     return EXIT_SUCCESS;
  113   120 }