diff options
-rw-r--r-- | CMakeLists.txt | 8 | ||||
-rw-r--r-- | ChangeLog | 33 | ||||
-rw-r--r-- | NEWS | 9 | ||||
-rw-r--r-- | debian/changelog | 7 | ||||
-rwxr-xr-x | debian/rules | 4 | ||||
-rw-r--r-- | po/ro.po | 26 | ||||
-rw-r--r-- | src/keyboard-lomiri.c | 357 | ||||
-rw-r--r-- | src/keyboard-x11.c | 79 |
8 files changed, 361 insertions, 162 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 57b01d26..07db2fa2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required (VERSION 3.13) -project (ayatana-indicator-keyboard VERSION "24.5.0" LANGUAGES C CXX) +project (ayatana-indicator-keyboard VERSION "24.7.0" LANGUAGES C CXX) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) SET(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "..." FORCE) @@ -9,6 +9,7 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) # Options option(ENABLE_WERROR "Treat all build warnings as errors" OFF) +option(ENABLE_UBUNTU_ACCOUNTSSERVICE "Build with Ubuntu's fork of accountsservice" OFF) set(CMAKE_BUILD_TYPE "Release") @@ -16,6 +17,10 @@ if(ENABLE_WERROR) add_definitions("-Werror") endif() +if(ENABLE_UBUNTU_ACCOUNTSSERVICE) + add_compile_definitions(ENABLE_UBUNTU_ACCOUNTSSERVICE) +endif() + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") add_definitions("-Weverything") else() @@ -51,4 +56,5 @@ add_subdirectory(po) # Display config info message(STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}") +message(STATUS "Build with Ubuntu's fork of accountsservice: ${ENABLE_UBUNTU_ACCOUNTSSERVICE}") message(STATUS "Build with -Werror: ${ENABLE_WERROR}") @@ -1,6 +1,37 @@ +2024-07-10 Mike Gabriel + + * release 24.7.0 (HEAD -> main, tag: 24.7.0) + +2024-07-08 Mike Gabriel + + * Merge branch 'tari01-pr/lomiri-session' (340ef997) + +2024-07-05 Robert Tari + + * debian/rules: Build with ENABLE_UBUNTU_ACCOUNTSSERVICE on Ubuntu + and derivatives (6357866d) + +2024-06-17 Robert Tari + + * Fix integration with Lomiri session (a7045072) + +2024-06-13 Robert Tari + + * Merge branch + 'sunweaver-pr/support-more-characters-in-Xkb-parameters' + (a630e4bb) + +2024-05-28 Mike Gabriel + + * src/keyboard-x11.c: Add ',' and '0-9' as allowed characters to + regexp for XkbLayout. (b18f267f) + * src/keyboard-x11.c: Add ',' and '0-9' as allowed characters to + regexp for XkbVariant. (5bb69d76) + * src/keyboard-x11.c: Amend file permissions (a-x). (fa22c11a) + 2024-05-22 Mike Gabriel - * release 24.5.0 (HEAD -> main, tag: 24.5.0) + * release 24.5.0 (a5c5b784) (tag: 24.5.0) 2024-05-21 Robert Tari @@ -1,3 +1,12 @@ +Overview of changes in ayatana-indicator-keyboard 24.7.0 + + - src/keyboard-x11.c: Amend file permissions (a-x). + - src/keyboard-x11.c: Add ',' and '0-9' as allowed characters to + regexp for XkbVariant. + - src/keyboard-x11.c: Add ',' and '0-9' as allowed characters to + regexp for XkbLayout. + - Fix integration with Lomiri session. + Overview of changes in ayatana-indicator-keyboard 24.5.0 - data/ayatana-indicator-keyboard.service.in: Become part of diff --git a/debian/changelog b/debian/changelog index 6d814381..f6a9a16b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +ayatana-indicator-keyboard (24.7.0-0) unstable; urgency=medium + + * Upstream-provided Debian package for ayatana-indicator-keyboard. + See upstream ChangeLog for recent changes. + + -- Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Wed, 10 Jul 2024 13:26:41 +0200 + ayatana-indicator-keyboard (24.5.0-0) unstable; urgency=medium * Upstream-provided Debian package for ayatana-indicator-keyboard. diff --git a/debian/rules b/debian/rules index 18fd0e0f..56c3a7a8 100755 --- a/debian/rules +++ b/debian/rules @@ -10,7 +10,9 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all DPKG_EXPORT_BUILDFLAGS = 1 include /usr/share/dpkg/buildflags.mk -DEB_CMAKE_EXTRA_FLAGS = $(NULL) +ifeq ($(shell dpkg-vendor --derives-from Ubuntu && echo yes),yes) + DEB_CMAKE_EXTRA_FLAGS = "-DENABLE_UBUNTU_ACCOUNTSSERVICE=ON" +endif %: dh $@ --with systemd @@ -8,50 +8,54 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-10-10 23:57+0200\n" -"PO-Revision-Date: 2021-01-22 23:28+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"PO-Revision-Date: 2024-09-29 00:16+0000\n" +"Last-Translator: Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>\n" +"Language-Team: Romanian <https://hosted.weblate.org/projects/" +"ayatana-indicators/keyboard-applet/ro/>\n" "Language: ro\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < " "20)) ? 1 : 2;\n" +"X-Generator: Weblate 5.8-dev\n" #: data/org.ayatana.indicator.keyboard.gschema.xml:1 msgid "Show the language icon in desktop mode." -msgstr "" +msgstr "Afișează pictograma limbii în modul de birou." #: data/org.ayatana.indicator.keyboard.gschema.xml:2 msgid "" "If enabled, the indicator shows the current layout icon. Otherwise, it " "displays a generic keyboard icon." msgstr "" +"Dacă este activată, indicatorul afișează pictograma aranjamentului curent. " +"În caz contrar, este afișată o pictogramă generică de tastatură." #: data/org.ayatana.indicator.keyboard.gschema.xml:3 msgid "Show the language icon in phone mode." -msgstr "" +msgstr "Afișează pictograma limbii în modul de telefon." #: data/org.ayatana.indicator.keyboard.gschema.xml:4 msgid "Show the language icon in the greeter." -msgstr "" +msgstr "Afișează pictograma de limbă în fereastra de întâmpinare." #: src/service.c:93 msgid "Keyboard" -msgstr "" +msgstr "Tastatură" #: src/service.c:94 msgid "Keyboard layout switcher and settings" -msgstr "" +msgstr "Comutator aranjament tastatură și configurarea acestuia" #: src/service.c:131 msgid "Current keyboard layout" -msgstr "" +msgstr "Aranjamentul curent al tastaturii" #: src/service.c:188 msgid "Keyboard Settings…" -msgstr "" +msgstr "Configurări tastatură…" #: src/service.c:196 msgid "Show Current Layout" -msgstr "" +msgstr "Afișează aranjamentul curent" diff --git a/src/keyboard-lomiri.c b/src/keyboard-lomiri.c index 1455b95e..6666c7b8 100644 --- a/src/keyboard-lomiri.c +++ b/src/keyboard-lomiri.c @@ -1,5 +1,5 @@ /* - * Copyright 2021-2023 Robert Tari <robert@tari.in> + * Copyright 2021-2024 Robert Tari <robert@tari.in> * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published @@ -35,6 +35,7 @@ struct _KeyboardPrivate guint nLayout; GSList *lLayoutRec; GSList *lUsers; + GSettings *pSettings; }; typedef KeyboardPrivate priv_t; @@ -63,11 +64,6 @@ static gboolean isGreeter() return g_str_equal(sUser, "lightdm"); } -static void setAccountsService(Keyboard *pKeyboard) -{ - // TODO -} - static void getAccountsService(Keyboard *pKeyboard) { gboolean bChanged = FALSE; @@ -174,15 +170,7 @@ void keyboard_AddSource(Keyboard *pKeyboard) guint keyboard_GetNumLayouts(Keyboard *pKeyboard) { - if (isGreeter()) - { - return g_slist_length(pKeyboard->pPrivate->lLayoutRec); - } - else - { - // TODO - return 1; - } + return g_slist_length (pKeyboard->pPrivate->lLayoutRec); } guint keyboard_GetLayoutIndex (Keyboard *pKeyboard) @@ -197,31 +185,9 @@ void keyboard_GetLayout(Keyboard *pKeyboard, gint nLayout, gchar **pLanguage, gc nLayout = pKeyboard->pPrivate->nLayout; } - gchar *sId = NULL; - - if (isGreeter() == TRUE) - { - gchar *sLayout = g_slist_nth_data(pKeyboard->pPrivate->lLayoutRec, nLayout); - sId = g_strdup(sLayout); - } - else - { - // TODO - gchar *sLayout = "us"; - gchar *sVariant = ""; - - if (sVariant && strlen(sVariant)) - { - sId = g_strconcat(sLayout, "+", sVariant, NULL); - } - else - { - sId = g_strdup(sLayout); - } - } - + gchar *sLayout = g_slist_nth_data (pKeyboard->pPrivate->lLayoutRec, nLayout); const Layout *pLayout; - g_hash_table_lookup_extended(pKeyboard->pPrivate->lLayouts, sId, NULL, (gpointer*)&pLayout); + g_hash_table_lookup_extended(pKeyboard->pPrivate->lLayouts, sLayout, NULL, (gpointer*)&pLayout); if (pLanguage != NULL) { @@ -232,15 +198,63 @@ void keyboard_GetLayout(Keyboard *pKeyboard, gint nLayout, gchar **pLanguage, gc { *pDescription = g_strdup(pLayout->sDescription); } - - g_free(sId); } void keyboard_SetLayout(Keyboard *pKeyboard, gint nLayout) { if (isGreeter() == FALSE) { - // TODO + gchar *sId = g_slist_nth_data (pKeyboard->pPrivate->lLayoutRec, nLayout); + + GVariantBuilder cSettingsBuilder; + g_variant_builder_init (&cSettingsBuilder, G_VARIANT_TYPE ("a(ss)")); + g_variant_builder_add (&cSettingsBuilder, "(ss)", "xkb", sId); + + GVariantBuilder cAccountsBuilder; + g_variant_builder_init (&cAccountsBuilder, G_VARIANT_TYPE ("aa{ss}")); + GVariantBuilder cDictBuilder; + g_variant_builder_init (&cDictBuilder, G_VARIANT_TYPE ("a{ss}")); + g_variant_builder_add (&cDictBuilder, "{ss}", "xkb", sId); + GVariant *pDict = g_variant_builder_end (&cDictBuilder); + g_variant_builder_add_value (&cAccountsBuilder, pDict); + + guint nSources = g_slist_length (pKeyboard->pPrivate->lLayoutRec); + + for (guint nSource = 0; nSource < nSources; nSource++) + { + if (nSource != nLayout) + { + gchar *sId = g_slist_nth_data (pKeyboard->pPrivate->lLayoutRec, nSource); + + g_variant_builder_add (&cSettingsBuilder, "(ss)", "xkb", sId); + + GVariantBuilder cDictBuilder; + g_variant_builder_init (&cDictBuilder, G_VARIANT_TYPE ("a{ss}")); + g_variant_builder_add (&cDictBuilder, "{ss}", "xkb", sId); + GVariant *pDict = g_variant_builder_end (&cDictBuilder); + g_variant_builder_add_value (&cAccountsBuilder, pDict); + } + } + + GVariant *pSettingsSources = g_variant_builder_end (&cSettingsBuilder); + g_settings_set_value (pKeyboard->pPrivate->pSettings, "sources", pSettingsSources); + + GDBusConnection *pConnection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); + gint nUid = geteuid (); + gchar *sPath = g_strdup_printf ("/org/freedesktop/Accounts/User%i", nUid); + GDBusProxy *pProxy = g_dbus_proxy_new_sync (pConnection, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.freedesktop.Accounts", sPath, "org.freedesktop.DBus.Properties", NULL, NULL); + g_free (sPath); + GVariant *pAccountsSources = g_variant_builder_end (&cAccountsBuilder); + + #ifdef ENABLE_UBUNTU_ACCOUNTSSERVICE + gchar *sInterface = "org.freedesktop.Accounts.User"; + #else + gchar *sInterface = "com.lomiri.shell.AccountsService"; + #endif + + GVariant *pRet = g_dbus_proxy_call_sync (pProxy, "Set", g_variant_new ("(ssv)", sInterface, "InputSources", pAccountsSources), G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + g_variant_unref (pRet); + g_object_unref (pConnection); } else { @@ -272,15 +286,17 @@ void keyboard_SetLayout(Keyboard *pKeyboard, gint nLayout) return; } - } - pKeyboard->pPrivate->nLayout = nLayout; - g_signal_emit(pKeyboard, m_lSignals[LAYOUT_CHANGED], 0); + pKeyboard->pPrivate->nLayout = nLayout; + g_signal_emit(pKeyboard, m_lSignals[LAYOUT_CHANGED], 0); + } } static void onDispose(GObject *pObject) { Keyboard *self = G_KEYBOARD(pObject); + g_signal_handlers_disconnect_by_data (self->pPrivate->pSettings, self); + g_clear_object (&self->pPrivate->pSettings); if (self->pPrivate->lLayouts) { @@ -315,6 +331,45 @@ Keyboard* keyboard_new() return G_KEYBOARD(pObject); } +static void onSourcesChanged (GSettings *pSettings, const gchar *sKey, gpointer pData) +{ + Keyboard *pKeyboard = G_KEYBOARD (pData); + gboolean bsignal = FALSE; + + if (pKeyboard->pPrivate->lLayoutRec) + { + g_slist_free_full (g_steal_pointer (&pKeyboard->pPrivate->lLayoutRec), g_free); + bsignal = TRUE; + } + + GVariant *pList = g_settings_get_value (pSettings, "sources"); + gsize nSources = g_variant_n_children (pList); + + if (nSources) + { + GVariantIter cIter; + g_variant_iter_init (&cIter, pList); + gchar *sLayout = NULL; + + while (g_variant_iter_loop (&cIter, "(ss)", NULL, &sLayout)) + { + pKeyboard->pPrivate->lLayoutRec = g_slist_append (pKeyboard->pPrivate->lLayoutRec, g_strdup (sLayout)); + } + } + else + { + pKeyboard->pPrivate->lLayoutRec = g_slist_append (pKeyboard->pPrivate->lLayoutRec, g_strdup ("us")); + } + + g_variant_unref (pList); + + if (bsignal) + { + g_signal_emit (pKeyboard, m_lSignals[CONFIG_CHANGED], 0); + g_signal_emit (pKeyboard, m_lSignals[LAYOUT_CHANGED], 0); + } +} + static void keyboard_init(Keyboard *self) { self->pPrivate = keyboard_get_instance_private(self); @@ -367,118 +422,178 @@ static void keyboard_init(Keyboard *self) if (isGreeter() == FALSE) { - // TODO self->pPrivate->nLayout = 0; + GSettingsSchemaSource *pSource = g_settings_schema_source_get_default (); + GSettingsSchema *pSchema = NULL; + + if (pSource) + { + pSchema = g_settings_schema_source_lookup (pSource, "org.gnome.desktop.input-sources", FALSE); - setAccountsService(self); + if (pSchema) + { + g_settings_schema_unref (pSchema); + self->pPrivate->pSettings = g_settings_new ("org.gnome.desktop.input-sources"); + g_signal_connect (self->pPrivate->pSettings, "changed::sources", G_CALLBACK (onSourcesChanged), self); + onSourcesChanged (self->pPrivate->pSettings, "sources", self); + } + else + { + g_error ("Panic: no org.gnome.desktop.input-sources schema found"); + } + } } else { - // Get layouts from /etc/default/keyboard - gchar *sFile; - g_file_get_contents ("/etc/default/keyboard", &sFile, NULL, NULL); - gchar **lLines = g_strsplit(sFile, "\n", -1); - guint nLines = g_strv_length(lLines); - gchar **lLayouts = NULL; - gchar **lVariants = NULL; - - for (guint nLine = 0; nLine < nLines; nLine++) + // Get system layouts + gboolean bDefaultLocation = g_file_test ("/etc/default/keyboard", G_FILE_TEST_EXISTS); + gchar *sLocation = NULL; + + if (bDefaultLocation) + { + sLocation = "/etc/default/keyboard"; + } + else + { + sLocation = "/etc/X11/xorg.conf.d/00-keyboard.conf"; + } + + gchar *sFile = NULL; + GError *pError = NULL; + g_file_get_contents (sLocation, &sFile, NULL, &pError); + GStrv lLayouts = NULL; + GStrv lVariants = NULL; + + if (!pError) { - gboolean bIsLayout = g_str_has_prefix(lLines[nLine], "XKBLAYOUT"); + GRegex *pRegex = NULL; - if (bIsLayout == TRUE) + if (bDefaultLocation) { - gboolean bQuoted = g_strrstr(lLines[nLine], "\"") != NULL; - gchar *sLayout = NULL; + #if GLIB_CHECK_VERSION(2, 73, 0) + pRegex = g_regex_new (" *XKBLAYOUT *= *\"*([,a-zA-Z0-9]*)\"*", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &pError); + #else + pRegex = g_regex_new (" *XKBLAYOUT *= *\"*([,a-zA-Z0-9]*)\"*", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, &pError); + #endif + } + else + { + #if GLIB_CHECK_VERSION(2, 73, 0) + pRegex = g_regex_new (" *Option +\"*XkbLayout\"* +\"*([,a-zA-Z0-9]*)\"*", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &pError); + #else + pRegex = g_regex_new (" *Option +\"*XkbLayout\"* +\"*([,a-zA-Z0-9]*)\"*", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, &pError); + #endif + } - if (bQuoted == TRUE) + if (!pError) + { + GMatchInfo *pMatchInfo = NULL; + + #if GLIB_CHECK_VERSION(2, 73, 0) + gboolean bMatch = g_regex_match (pRegex, sFile, G_REGEX_MATCH_DEFAULT, &pMatchInfo); + #else + gboolean bMatch = g_regex_match (pRegex, sFile, (GRegexMatchFlags) 0, &pMatchInfo); + #endif + + if (bMatch) { - sLayout = (lLines[nLine] + 11); - guint nLength = strlen(sLayout); - sLayout[nLength - 1] = '\0'; + gchar *sLayouts = g_match_info_fetch (pMatchInfo, 1); + lLayouts = g_strsplit (sLayouts, ",", -1); + g_free (sLayouts); } else { - sLayout = (lLines[nLine] + 10); + g_error ("PANIC: No system XkbLayout found"); } - lLayouts = g_strsplit(sLayout, ",", -1); - - continue; + g_match_info_free (pMatchInfo); + g_regex_unref (pRegex); + } + else + { + g_error ("PANIC: Failed to compile regex: %s", pError->message); + g_error_free (pError); } - gboolean bIsVariant = g_str_has_prefix(lLines[nLine], "XKBVARIANT"); + if (bDefaultLocation) + { + #if GLIB_CHECK_VERSION(2, 73, 0) + pRegex = g_regex_new (" *XKBVARIANT *= *\"*([,a-zA-Z0-9]*)\"*", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &pError); + #else + pRegex = g_regex_new (" *XKBVARIANT *= *\"*([,a-zA-Z0-9]*)\"*", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, &pError); + #endif + } + else + { + #if GLIB_CHECK_VERSION(2, 73, 0) + pRegex = g_regex_new (" *Option +\"*XkbVariant\"* +\"*([,a-zA-Z0-9]*)\"*", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &pError); + #else + pRegex = g_regex_new (" *Option +\"*XkbVariant\"* +\"*([,a-zA-Z0-9]*)\"*", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, &pError); + #endif + } - if (bIsVariant == TRUE) + if (!pError) { - gboolean bQuoted = g_strrstr(lLines[nLine], "\"") != NULL; - gchar *sVariant = NULL; + GMatchInfo *pMatchInfo = NULL; - if (bQuoted == TRUE) - { - sVariant = (lLines[nLine] + 12); - guint nLength = strlen(sVariant); - sVariant[nLength - 1] = '\0'; - } - else + #if GLIB_CHECK_VERSION(2, 73, 0) + gboolean bMatch = g_regex_match (pRegex, sFile, G_REGEX_MATCH_DEFAULT, &pMatchInfo); + #else + gboolean bMatch = g_regex_match (pRegex, sFile, (GRegexMatchFlags) 0, &pMatchInfo); + #endif + + if (bMatch) { - sVariant = (lLines[nLine] + 11); + gchar *sVariants = g_match_info_fetch (pMatchInfo, 1); + lVariants = g_strsplit (sVariants, ",", -1); + g_free (sVariants); } - lVariants = g_strsplit(sVariant, ",", -1); - - continue; + g_match_info_free (pMatchInfo); + g_regex_unref (pRegex); + } + else + { + g_error ("PANIC: Failed to compile regex: %s", pError->message); + g_error_free (pError); } - } - - guint nVariants = 0; - if (lVariants != NULL) + g_free(sFile); + } + else { - g_strv_length(lVariants); + g_error ("PANIC: Failed to get %s contents: %s", sLocation, pError->message); + g_error_free (pError); } - if (lLayouts != NULL) + guint nLayouts = g_strv_length (lLayouts); + + for (guint nLayout = 0; nLayout < nLayouts; nLayout++) { - guint nLayouts = g_strv_length(lLayouts); + gchar *sId = NULL; + guint nVariantLength = 0; - for (guint nLayout = 0; nLayout < nLayouts; nLayout++) + if (lVariants && lVariants[nLayout]) { - gchar *sId = NULL; - - if (nVariants > nLayout) - { - guint nVariant = strlen(lVariants[nLayout]); - - if (nVariants == nLayouts && nVariant > 0) - { - sId = g_strconcat(lLayouts[nLayout], "+", lVariants[nLayout], NULL); - } - else - { - sId = g_strdup(lLayouts[nLayout]); - } - } - else - { - sId = g_strdup(lLayouts[nLayout]); - } - - self->pPrivate->lLayoutRec = g_slist_append(self->pPrivate->lLayoutRec, sId); + nVariantLength = strlen (lVariants[nLayout]); } - self->pPrivate->nLayout = 0; - - g_strfreev(lLayouts); - } + if (nVariantLength) + { + sId = g_strconcat (lLayouts[nLayout], "+", lVariants[nLayout], NULL); + } + else + { + sId = g_strdup (lLayouts[nLayout]); + } - if (lVariants != NULL) - { - g_strfreev(lVariants); + self->pPrivate->lLayoutRec = g_slist_append (self->pPrivate->lLayoutRec, sId); } - g_strfreev(lLines); - g_free(sFile); + g_strfreev (lLayouts); + g_strfreev (lVariants); + self->pPrivate->nLayout = 0; + //~ Get system layouts ActUserManager *pManager = act_user_manager_get_default(); gboolean bIsLoaded; diff --git a/src/keyboard-x11.c b/src/keyboard-x11.c index d0a445e8..83811521 100644 --- a/src/keyboard-x11.c +++ b/src/keyboard-x11.c @@ -1,5 +1,5 @@ /* - * Copyright 2021-2023 Robert Tari <robert@tari.in> + * Copyright 2021-2024 Robert Tari <robert@tari.in> * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published @@ -48,7 +48,7 @@ struct _KeyboardPrivate GDBusConnection *pConnection; guint nSubscription; gchar *sUser; - gchar *sSystemLayout; + GStrv lSystemLayouts; }; typedef KeyboardPrivate priv_t; @@ -148,7 +148,13 @@ static void getAccountsService(Keyboard *pKeyboard, ActUser *pUser) g_slist_free_full (g_steal_pointer (&pKeyboard->pPrivate->lLayoutRec), g_free); } - pKeyboard->pPrivate->lLayoutRec = g_slist_append (pKeyboard->pPrivate->lLayoutRec, g_strdup (pKeyboard->pPrivate->sSystemLayout)); + guint nLayouts = g_strv_length (pKeyboard->pPrivate->lSystemLayouts); + + for (guint nLayout = 0; nLayout < nLayouts; nLayout++) + { + pKeyboard->pPrivate->lLayoutRec = g_slist_append (pKeyboard->pPrivate->lLayoutRec, g_strdup (pKeyboard->pPrivate->lSystemLayouts[nLayout])); + } + g_timeout_add(500, (GSourceFunc)emitDelayedSignal, pKeyboard); } else @@ -187,7 +193,12 @@ static void getAccountsService(Keyboard *pKeyboard, ActUser *pUser) if (!nLayouts) { - pKeyboard->pPrivate->lLayoutRec = g_slist_append (pKeyboard->pPrivate->lLayoutRec, g_strdup (pKeyboard->pPrivate->sSystemLayout)); + guint nLayouts = g_strv_length (pKeyboard->pPrivate->lSystemLayouts); + + for (guint nLayout = 0; nLayout < nLayouts; nLayout++) + { + pKeyboard->pPrivate->lLayoutRec = g_slist_append (pKeyboard->pPrivate->lLayoutRec, g_strdup (pKeyboard->pPrivate->lSystemLayouts[nLayout])); + } } g_variant_iter_free(pIter); @@ -494,9 +505,9 @@ static void onDispose(GObject *pObject) g_slist_free_full(self->pPrivate->lLayoutRec, g_free); } - if (self->pPrivate->sSystemLayout) + if (self->pPrivate->lSystemLayouts) { - g_free (self->pPrivate->sSystemLayout); + g_strfreev (self->pPrivate->lSystemLayouts); } G_OBJECT_CLASS(keyboard_parent_class)->dispose(pObject); @@ -645,7 +656,7 @@ static void keyboard_init(Keyboard *self) self->pPrivate->lUsers = NULL; self->pPrivate->nSubscription = g_dbus_connection_signal_subscribe (self->pPrivate->pConnection, NULL, GREETER_BUS_NAME, "UserChanged", GREETER_BUS_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, onUserChanged, self, NULL); - // Get system layout + // Get system layouts gboolean bDefaultLocation = g_file_test ("/etc/default/keyboard", G_FILE_TEST_EXISTS); gchar *sLocation = NULL; @@ -661,8 +672,8 @@ static void keyboard_init(Keyboard *self) gchar *sFile = NULL; GError *pError = NULL; g_file_get_contents (sLocation, &sFile, NULL, &pError); - gchar *sLayout = NULL; - gchar *sVariant = NULL; + GStrv lLayouts = NULL; + GStrv lVariants = NULL; if (!pError) { @@ -697,7 +708,9 @@ static void keyboard_init(Keyboard *self) if (bMatch) { - sLayout = g_match_info_fetch (pMatchInfo, 1); + gchar *sLayouts = g_match_info_fetch (pMatchInfo, 1); + lLayouts = g_strsplit (sLayouts, ",", -1); + g_free (sLayouts); } else { @@ -742,7 +755,9 @@ static void keyboard_init(Keyboard *self) if (bMatch) { - sVariant = g_match_info_fetch (pMatchInfo, 1); + gchar *sVariants = g_match_info_fetch (pMatchInfo, 1); + lVariants = g_strsplit (sVariants, ",", -1); + g_free (sVariants); } g_match_info_free (pMatchInfo); @@ -762,28 +777,38 @@ static void keyboard_init(Keyboard *self) g_error_free (pError); } - gchar *sId = NULL; - guint nVariant = 0; + guint nLayouts = g_strv_length (lLayouts); + GStrvBuilder *pBuilder = g_strv_builder_new (); - if (sVariant) + for (guint nLayout = 0; nLayout < nLayouts; nLayout++) { - nVariant = strlen (sVariant); - } + gchar *sId = NULL; + guint nVariantLength = 0; - if (nVariant) - { - sId = g_strconcat (sLayout, "+", sVariant, NULL); - } - else - { - sId = g_strdup (sLayout); + if (lVariants && lVariants[nLayout]) + { + nVariantLength = strlen (lVariants[nLayout]); + } + + if (nVariantLength) + { + sId = g_strconcat (lLayouts[nLayout], "+", lVariants[nLayout], NULL); + } + else + { + sId = g_strdup (lLayouts[nLayout]); + } + + self->pPrivate->lLayoutRec = g_slist_append (self->pPrivate->lLayoutRec, sId); + g_strv_builder_add (pBuilder, sId); } - g_free (sLayout); - g_free (sVariant); - self->pPrivate->lLayoutRec = g_slist_append (self->pPrivate->lLayoutRec, sId); - self->pPrivate->sSystemLayout = g_strdup (sId); + self->pPrivate->lSystemLayouts = g_strv_builder_end (pBuilder); + g_strv_builder_unref (pBuilder); + g_strfreev (lLayouts); + g_strfreev (lVariants); self->pPrivate->nLayout = 0; + //~ Get system layouts ActUserManager *pManager = act_user_manager_get_default(); gboolean bIsLoaded; |