- commit
- e9d14d4512107849c9c644bda7f4c452127de096
- parent
- 345a7f2a5ef179d85f3e6b96a3b1fade58910e90
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2026-03-12 07:55
[Settings] implement gsettings sync
Diffstat
| A | Settings/.gitignore | 1 | + |
| A | Settings/Makefile | 6 | ++++++ |
| A | Settings/PKGBUILD | 18 | ++++++++++++++++++ |
| A | Settings/sync.c | 113 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | Settings/systemd/service | 8 | ++++++++ |
5 files changed, 146 insertions, 0 deletions
diff --git a/Settings/.gitignore b/Settings/.gitignore
@@ -0,0 +1 @@ -1 1 sync
diff --git a/Settings/Makefile b/Settings/Makefile
@@ -0,0 +1,6 @@
-1 1 PREFIX = /usr
-1 2 CFLAGS = -std=c99 -Wall -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 `pkg-config --cflags gio-2.0`
-1 3 LDFLAGS = -s -Wl,-z,relro `pkg-config --libs gio-2.0`
-1 4
-1 5 sync: sync.c
-1 6 gcc $< -o $@ ${CFLAGS} ${LDFLAGS}
diff --git a/Settings/PKGBUILD b/Settings/PKGBUILD
@@ -0,0 +1,18 @@
-1 1 pkgname='xi-portal-settings-sync'
-1 2 pkgdesc='Sync Settings portal to gsettings'
-1 3 pkgver='0.0.0'
-1 4 arch=('amd64')
-1 5 url='https://github.com/xi/xi-desktop-portals'
-1 6 license='MIT'
-1 7 depends=(
-1 8 libglib2.0-0t64
-1 9 )
-1 10 makedepends=(
-1 11 libgio-2.0-dev
-1 12 )
-1 13
-1 14 package() {
-1 15 make
-1 16 install -Dm 755 sync "$pkgdir/usr/bin/$pkgname"
-1 17 install -Dm 644 systemd/service "$pkgdir/usr/lib/systemd/user/$pkgname.service"
-1 18 }
diff --git a/Settings/sync.c b/Settings/sync.c
@@ -0,0 +1,113 @@
-1 1 #include <dirent.h>
-1 2 #include <fcntl.h>
-1 3 #include <limits.h>
-1 4 #include <stdio.h>
-1 5 #include <stdlib.h>
-1 6 #include <sys/inotify.h>
-1 7 #include <sys/epoll.h>
-1 8 #include <unistd.h>
-1 9
-1 10 #include <gio/gio.h>
-1 11
-1 12 #define EVENT_SIZE (sizeof(struct inotify_event))
-1 13 #define BUF_LEN (1024 * (EVENT_SIZE + 16))
-1 14
-1 15 char root[PATH_MAX - 64];
-1 16 GSettings *settings, *settings_a11y;
-1 17
-1 18 void on_change(const char *key) {
-1 19 char path[PATH_MAX];
-1 20 snprintf(path, sizeof(path), "%s/%s", root, key);
-1 21
-1 22 int fd = open(path, O_RDONLY);
-1 23 if (fd < 0) {
-1 24 return;
-1 25 }
-1 26 char value[256];
-1 27 int len = read(fd, value, sizeof(value) - 1);
-1 28 close(fd);
-1 29 if (len < 0) {
-1 30 return;
-1 31 }
-1 32 value[len] = '\0';
-1 33 g_strchomp(value);
-1 34
-1 35 if (strcmp(key, "color-scheme") == 0) {
-1 36 if (strcmp(value, "dark") == 0) {
-1 37 g_settings_set_string(settings, "color-scheme", "prefer-dark");
-1 38 } else if (strcmp(value, "light") == 0) {
-1 39 g_settings_set_string(settings, "color-scheme", "prefer-light");
-1 40 } else {
-1 41 g_settings_set_string(settings, "color-scheme", "default");
-1 42 }
-1 43 } else if (strcmp(key, "accent-color") == 0) {
-1 44 // TODO: translate color to color name
-1 45 g_settings_set_string(settings, "accent-color", value);
-1 46 } else if (strcmp(key, "reduced-motion") == 0) {
-1 47 if (strcmp(value, "reduced") == 0) {
-1 48 g_settings_set_string(settings_a11y, "reduced-motion", "reduce");
-1 49 } else {
-1 50 g_settings_set_string(settings_a11y, "reduced-motion", "no-preference");
-1 51 }
-1 52 } else if (strcmp(key, "contrast") == 0) {
-1 53 if (strcmp(value, "high") == 0) {
-1 54 g_settings_set_boolean(settings_a11y, "high-contrast", TRUE);
-1 55 } else {
-1 56 g_settings_set_boolean(settings_a11y, "high-contrast", FALSE);
-1 57 }
-1 58 }
-1 59 }
-1 60
-1 61 int main() {
-1 62 snprintf(
-1 63 root, sizeof(root), "%s/org.freedesktop.appearance", g_get_user_config_dir()
-1 64 );
-1 65
-1 66 settings = g_settings_new("org.gnome.desktop.interface");
-1 67 settings_a11y = g_settings_new("org.gnome.desktop.a11y.interface");
-1 68
-1 69 int fd = inotify_init();
-1 70 if (fd < 0) {
-1 71 perror("inotify_init");
-1 72 return EXIT_FAILURE;
-1 73 }
-1 74 int wd = inotify_add_watch(fd, root, IN_CLOSE_WRITE);
-1 75 if (wd < 0) {
-1 76 perror("inotify_add_watch");
-1 77 return EXIT_FAILURE;
-1 78 }
-1 79
-1 80 DIR *d = opendir(root);
-1 81 struct dirent *entry;
-1 82 if (d) {
-1 83 while ((entry = readdir(d))) {
-1 84 on_change(entry->d_name);
-1 85 }
-1 86 closedir(d);
-1 87 }
-1 88
-1 89 int epfd = epoll_create(1);
-1 90 struct epoll_event ev, events[1];
-1 91 ev.events = EPOLLIN;
-1 92 epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
-1 93
-1 94 char buf[BUF_LEN];
-1 95 struct inotify_event *event;
-1 96
-1 97 while (1) {
-1 98 epoll_wait(epfd, events, 1, -1);
-1 99
-1 100 int length = read(fd, buf, sizeof(buf));
-1 101 if (length < 0) {
-1 102 perror("read");
-1 103 return EXIT_FAILURE;
-1 104 }
-1 105
-1 106 int i = 0;
-1 107 while (i < length) {
-1 108 event = (struct inotify_event *)&buf[i];
-1 109 on_change(event->name);
-1 110 i += EVENT_SIZE + event->len;
-1 111 }
-1 112 }
-1 113 }
diff --git a/Settings/systemd/service b/Settings/systemd/service
@@ -0,0 +1,8 @@ -1 1 [Unit] -1 2 Description=Settings portal sync -1 3 -1 4 [Service] -1 5 ExecStart=/usr/bin/xi-portal-settings-sync -1 6 -1 7 [Install] -1 8 WantedBy=graphical-session.target