aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/keyboard-lomiri.c118
-rw-r--r--src/keyboard-x11.c179
-rw-r--r--src/keyboard.h4
-rw-r--r--src/service.c75
-rw-r--r--src/system-layouts.h186
5 files changed, 312 insertions, 250 deletions
diff --git a/src/keyboard-lomiri.c b/src/keyboard-lomiri.c
index 637bb9f4..bc6b3f93 100644
--- a/src/keyboard-lomiri.c
+++ b/src/keyboard-lomiri.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2024 Robert Tari <robert@tari.in>
+ * Copyright 2021-2025 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
@@ -19,6 +19,7 @@
#include <glib-object.h>
#include "languages.h"
#include "keyboard.h"
+#include "system-layouts.h"
enum
{
@@ -178,7 +179,7 @@ guint keyboard_GetLayoutIndex (Keyboard *pKeyboard)
return pKeyboard->pPrivate->nLayout;
}
-void keyboard_GetLayout(Keyboard *pKeyboard, gint nLayout, gchar **pLanguage, gchar **pDescription)
+void keyboard_GetLayout(Keyboard *pKeyboard, gint nLayout, gchar **pLanguage, gchar **pDescription, gchar **pId)
{
if (nLayout == -1)
{
@@ -198,6 +199,11 @@ void keyboard_GetLayout(Keyboard *pKeyboard, gint nLayout, gchar **pLanguage, gc
{
*pDescription = g_strdup(pLayout->sDescription);
}
+
+ if (pId != NULL)
+ {
+ *pId = g_strdup (sLayout);
+ }
}
void keyboard_SetLayout(Keyboard *pKeyboard, gint nLayout)
@@ -373,6 +379,7 @@ static void onSourcesChanged (GSettings *pSettings, const gchar *sKey, gpointer
static void keyboard_init(Keyboard *self)
{
self->pPrivate = keyboard_get_instance_private(self);
+ self->pPrivate->lLayoutRec = NULL;
self->pPrivate->lLayouts = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, freeLayout);
// Read all available layouts
@@ -445,111 +452,22 @@ static void keyboard_init(Keyboard *self)
}
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++)
- {
- gboolean bIsLayout = g_str_has_prefix(lLines[nLine], "XKBLAYOUT");
-
- if (bIsLayout == TRUE)
- {
- gboolean bQuoted = g_strrstr(lLines[nLine], "\"") != NULL;
- gchar *sLayout = NULL;
-
- if (bQuoted == TRUE)
- {
- sLayout = (lLines[nLine] + 11);
- guint nLength = strlen(sLayout);
- sLayout[nLength - 1] = '\0';
- }
- else
- {
- sLayout = (lLines[nLine] + 10);
- }
+ // Get system layouts
+ getSystemLayouts ("/etc/default/keyboard", &self->pPrivate->lLayoutRec, NULL, FALSE);
- lLayouts = g_strsplit(sLayout, ",", -1);
-
- continue;
- }
-
- gboolean bIsVariant = g_str_has_prefix(lLines[nLine], "XKBVARIANT");
-
- if (bIsVariant == TRUE)
- {
- gboolean bQuoted = g_strrstr(lLines[nLine], "\"") != NULL;
- gchar *sVariant = NULL;
-
- if (bQuoted == TRUE)
- {
- sVariant = (lLines[nLine] + 12);
- guint nLength = strlen(sVariant);
- sVariant[nLength - 1] = '\0';
- }
- else
- {
- sVariant = (lLines[nLine] + 11);
- }
-
- lVariants = g_strsplit(sVariant, ",", -1);
-
- continue;
- }
- }
-
- guint nVariants = 0;
-
- if (lVariants != NULL)
+ if (!self->pPrivate->lLayoutRec)
{
- g_strv_length(lVariants);
- }
-
- if (lLayouts != NULL)
- {
- guint nLayouts = g_strv_length(lLayouts);
-
- for (guint nLayout = 0; nLayout < nLayouts; 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);
- }
-
- self->pPrivate->nLayout = 0;
-
- g_strfreev(lLayouts);
+ getSystemLayouts ("/etc/X11/xorg.conf.d/00-keyboard.conf", &self->pPrivate->lLayoutRec, NULL, FALSE);
}
- if (lVariants != NULL)
+ if (!self->pPrivate->lLayoutRec)
{
- g_strfreev(lVariants);
+ gchar *sId = g_strdup ("us");
+ self->pPrivate->lLayoutRec = g_slist_append (self->pPrivate->lLayoutRec, sId);
}
- g_strfreev(lLines);
- g_free(sFile);
+ 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..27dfb97c 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-2025 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
@@ -20,6 +20,7 @@
#include <libxklavier/xklavier.h>
#include "languages.h"
#include "keyboard.h"
+#include "system-layouts.h"
#define GREETER_BUS_NAME "org.ayatana.greeter"
#define GREETER_BUS_PATH "/org/ayatana/greeter"
@@ -48,7 +49,7 @@ struct _KeyboardPrivate
GDBusConnection *pConnection;
guint nSubscription;
gchar *sUser;
- gchar *sSystemLayout;
+ GStrv lSystemLayouts;
};
typedef KeyboardPrivate priv_t;
@@ -148,7 +149,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 +194,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);
@@ -378,7 +390,7 @@ guint keyboard_GetLayoutIndex (Keyboard *pKeyboard)
return pKeyboard->pPrivate->nLayout;
}
-void keyboard_GetLayout(Keyboard *pKeyboard, gint nLayout, gchar **pLanguage, gchar **pDescription)
+void keyboard_GetLayout(Keyboard *pKeyboard, gint nLayout, gchar **pLanguage, gchar **pDescription, gchar **pId)
{
if (nLayout == -1)
{
@@ -420,7 +432,14 @@ void keyboard_GetLayout(Keyboard *pKeyboard, gint nLayout, gchar **pLanguage, gc
*pDescription = g_strdup(pLayout->sDescription);
}
- g_free(sId);
+ if (pId != NULL)
+ {
+ *pId = sId;
+ }
+ else
+ {
+ g_free(sId);
+ }
}
void keyboard_SetLayout(Keyboard *pKeyboard, gint nLayout)
@@ -494,9 +513,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);
@@ -556,6 +575,7 @@ static void onUserChanged (GDBusConnection *pConnection, const gchar *sSender, c
static void keyboard_init(Keyboard *self)
{
self->pPrivate = keyboard_get_instance_private(self);
+ self->pPrivate->lLayoutRec = NULL;
self->pPrivate->lLayouts = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, freeLayout);
// Read all available layouts
@@ -645,145 +665,26 @@ 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
- gboolean bDefaultLocation = g_file_test ("/etc/default/keyboard", G_FILE_TEST_EXISTS);
- gchar *sLocation = NULL;
+ // Get system layouts
+ getSystemLayouts ("/etc/default/keyboard", &self->pPrivate->lLayoutRec, &self->pPrivate->lSystemLayouts, TRUE);
- if (bDefaultLocation)
+ if (!self->pPrivate->lLayoutRec)
{
- sLocation = "/etc/default/keyboard";
+ getSystemLayouts ("/etc/X11/xorg.conf.d/00-keyboard.conf", &self->pPrivate->lLayoutRec, &self->pPrivate->lSystemLayouts, TRUE);
}
- else
- {
- sLocation = "/etc/X11/xorg.conf.d/00-keyboard.conf";
- }
-
- gchar *sFile = NULL;
- GError *pError = NULL;
- g_file_get_contents (sLocation, &sFile, NULL, &pError);
- gchar *sLayout = NULL;
- gchar *sVariant = NULL;
- if (!pError)
- {
- GRegex *pRegex = NULL;
-
- if (bDefaultLocation)
- {
- #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 (!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 = g_match_info_fetch (pMatchInfo, 1);
- }
- else
- {
- g_error ("PANIC: No system XkbLayout found");
- }
-
- g_match_info_free (pMatchInfo);
- g_regex_unref (pRegex);
- }
- else
- {
- g_error ("PANIC: Failed to compile regex: %s", pError->message);
- g_error_free (pError);
- }
-
- 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 (!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)
- {
- sVariant = g_match_info_fetch (pMatchInfo, 1);
- }
-
- g_match_info_free (pMatchInfo);
- g_regex_unref (pRegex);
- }
- else
- {
- g_error ("PANIC: Failed to compile regex: %s", pError->message);
- g_error_free (pError);
- }
-
- g_free(sFile);
- }
- else
- {
- g_error ("PANIC: Failed to get %s contents: %s", sLocation, pError->message);
- g_error_free (pError);
- }
-
- gchar *sId = NULL;
- guint nVariant = 0;
-
- if (sVariant)
- {
- nVariant = strlen (sVariant);
- }
-
- if (nVariant)
- {
- sId = g_strconcat (sLayout, "+", sVariant, NULL);
- }
- else
+ if (!self->pPrivate->lLayoutRec)
{
- sId = g_strdup (sLayout);
+ GStrvBuilder *pBuilder = g_strv_builder_new ();
+ gchar *sId = g_strdup ("us");
+ self->pPrivate->lLayoutRec = g_slist_append (self->pPrivate->lLayoutRec, sId);
+ g_strv_builder_add (pBuilder, sId);
+ self->pPrivate->lSystemLayouts = g_strv_builder_end (pBuilder);
+ g_strv_builder_unref (pBuilder);
}
- g_free (sLayout);
- g_free (sVariant);
- self->pPrivate->lLayoutRec = g_slist_append (self->pPrivate->lLayoutRec, sId);
- self->pPrivate->sSystemLayout = g_strdup (sId);
self->pPrivate->nLayout = 0;
+ //~ Get system layouts
ActUserManager *pManager = act_user_manager_get_default();
gboolean bIsLoaded;
diff --git a/src/keyboard.h b/src/keyboard.h
index 39f822cd..49c21056 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2023 Robert Tari <robert@tari.in>
+ * Copyright 2021-2025 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 @@ Keyboard* keyboard_new();
void keyboard_AddSource(Keyboard *pKeyboard);
guint keyboard_GetNumLayouts(Keyboard *pKeyboard);
guint keyboard_GetLayoutIndex (Keyboard *pKeyboard);
-void keyboard_GetLayout(Keyboard *pKeyboard, gint nLayout, gchar **pLanguage, gchar **pDescription);
+void keyboard_GetLayout(Keyboard *pKeyboard, gint nLayout, gchar **pLanguage, gchar **pDescription, gchar **pId);
void keyboard_SetLayout(Keyboard *pKeyboard, gint nLayout);
G_END_DECLS
diff --git a/src/service.c b/src/service.c
index 6d083569..f4b086cc 100644
--- a/src/service.c
+++ b/src/service.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2023 Robert Tari <robert@tari.in>
+ * Copyright 2021-2025 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
@@ -31,7 +31,7 @@ static Keyboard* (*m_fnKeyboardNew)();
static void (*m_fnKeyboardAddSource)(Keyboard *pKeyboard);
static guint (*m_fnKeyboardGetNumLayouts)(Keyboard *pKeyboard);
static guint (*m_fnKeyboardGetLayoutIndex)(Keyboard *pKeyboard);
-static void (*m_fnKeyboardGetLayout)(Keyboard *pKeyboard, gint nLayout, gchar **pLanguage, gchar **pDescription);
+static void (*m_fnKeyboardGetLayout)(Keyboard *pKeyboard, gint nLayout, gchar **pLanguage, gchar **pDescription, gchar **pId);
static void (*m_fnKeyboardSetLayout)(Keyboard *pKeyboard, gint nLayout);
enum
@@ -80,6 +80,8 @@ struct _IndicatorKeyboardServicePrivate
GMenu *pLayoutSection;
Keyboard *pKeyboard;
GSettings *pSettings;
+ GSettings *pLomiriSettings;
+ gboolean bLomiri;
};
typedef IndicatorKeyboardServicePrivate priv_t;
@@ -119,7 +121,7 @@ static GVariant* createHeaderState(IndicatorKeyboardService *self, int nProfile)
else
{
gchar *sLanguage;
- m_fnKeyboardGetLayout(self->pPrivate->pKeyboard, -1, &sLanguage, NULL);
+ m_fnKeyboardGetLayout(self->pPrivate->pKeyboard, -1, &sLanguage, NULL, NULL);
gchar *sIcon = g_strconcat("ayatana-indicator-keyboard-", sLanguage, NULL);
g_free(sLanguage);
@@ -156,7 +158,7 @@ static GMenuModel* createLayoutSection(IndicatorKeyboardService *self)
{
gchar *sLanguage;
gchar *sDescription;
- m_fnKeyboardGetLayout(self->pPrivate->pKeyboard, nLayout, &sLanguage, &sDescription);
+ m_fnKeyboardGetLayout(self->pPrivate->pKeyboard, nLayout, &sLanguage, &sDescription, NULL);
GMenuItem *pItem = g_menu_item_new(sDescription, NULL);
g_free(sDescription);
g_menu_item_set_action_and_target_value(pItem, "indicator.layout", g_variant_new_byte(nLayout));
@@ -185,6 +187,15 @@ static GMenuModel* createLayoutSection(IndicatorKeyboardService *self)
static GMenuModel* createSettingsSection(IndicatorKeyboardService *self)
{
GMenu * pMenu = g_menu_new();
+
+ if (self->pPrivate->bLomiri && (!ayatana_common_utils_is_ubuntutouch()))
+ {
+ GMenuItem *pItem = g_menu_item_new (_("Always show OSK"), "indicator.osk(true)");
+ g_menu_item_set_attribute (pItem, "x-ayatana-type", "s", "org.ayatana.indicator.switch");
+ g_menu_append_item (pMenu, pItem);
+ g_object_unref (pItem);
+ }
+
g_menu_append(pMenu, _("Keyboard Settings…"), "indicator.settings");
return G_MENU_MODEL(pMenu);
@@ -315,13 +326,15 @@ static void onLayoutSelected(GSimpleAction *pAction, GVariant *pVariant, gpointe
m_fnKeyboardSetLayout(self->pPrivate->pKeyboard, nLayout);
}
-static void onSettings(GSimpleAction *pAction, GVariant *pVariant, gpointer pUserData)
+static void onSettings(GSimpleAction *pAction, GVariant *pVariant, gpointer pData)
{
+ IndicatorKeyboardService *self = INDICATOR_KEYBOARD_SERVICE (pData);
+
if (ayatana_common_utils_is_mate())
{
ayatana_common_utils_execute_command("mate-keyboard-properties");
}
- else if (ayatana_common_utils_is_lomiri())
+ else if (self->pPrivate->bLomiri)
{
ayatana_common_utils_open_url("settings:///system/hw-keyboard-layouts");
}
@@ -332,21 +345,45 @@ static void onDisplay (GSimpleAction *pAction, GVariant *pVariant, gpointer pDat
IndicatorKeyboardService *self = INDICATOR_KEYBOARD_SERVICE (pData);
guint nLayout = m_fnKeyboardGetLayoutIndex (self->pPrivate->pKeyboard);
gchar *sProgram = NULL;
+ gchar *sArgs = NULL;
+ gboolean bMate = ayatana_common_utils_is_mate ();
+ gboolean bLomiri = ayatana_common_utils_is_lomiri ();
- if (ayatana_common_utils_is_mate ())
+ if (bMate)
{
sProgram = "matekbd-keyboard-display";
+ sArgs = g_strdup_printf ("-g %i", nLayout + 1);
+ }
+ else if (bLomiri)
+ {
+
+ sProgram = "tecla";
+ m_fnKeyboardGetLayout (self->pPrivate->pKeyboard, -1, NULL, NULL, &sArgs);
}
else
{
sProgram = "gkbd-keyboard-display";
+ sArgs = g_strdup_printf ("-g %i", nLayout + 1);
}
- gchar *sArgs = g_strdup_printf ("-g %i", nLayout + 1);
ayatana_common_utils_execute_command_warn (sProgram, sArgs);
g_free (sArgs);
}
+static gboolean valueFromVariant (GValue *pValue, GVariant *pVariant, gpointer pUserData)
+{
+ g_value_set_variant (pValue, pVariant);
+
+ return TRUE;
+}
+
+static GVariant* valueToVariant (const GValue *pValue, const GVariantType *pType, gpointer pUserData)
+{
+ GVariant *pVariant = g_value_dup_variant (pValue);
+
+ return pVariant;
+}
+
static void initActions(IndicatorKeyboardService *self)
{
GSimpleAction *pAction;
@@ -366,6 +403,16 @@ static void initActions(IndicatorKeyboardService *self)
self->pPrivate->pLayoutAction = pAction;
g_signal_connect(pAction, "activate", G_CALLBACK(onLayoutSelected), self);
+ if (self->pPrivate->bLomiri && (!ayatana_common_utils_is_ubuntutouch()))
+ {
+ gboolean bOsk = g_settings_get_boolean (self->pPrivate->pLomiriSettings, "always-show-osk");
+ GVariant *pOsk = g_variant_new_boolean (bOsk);
+ pAction = g_simple_action_new_stateful ("osk", G_VARIANT_TYPE_BOOLEAN, pOsk);
+ g_settings_bind_with_mapping (self->pPrivate->pLomiriSettings, "always-show-osk", pAction, "state", G_SETTINGS_BIND_DEFAULT, valueFromVariant, valueToVariant, NULL, NULL);
+ g_action_map_add_action (G_ACTION_MAP (self->pPrivate->pActionGroup), G_ACTION (pAction));
+ g_object_unref (G_OBJECT (pAction));
+ }
+
pAction = g_simple_action_new("settings", NULL);
g_action_map_add_action(G_ACTION_MAP(self->pPrivate->pActionGroup), G_ACTION(pAction));
self->pPrivate->pSettingsAction = pAction;
@@ -462,6 +509,8 @@ static void onDispose(GObject *pObject)
g_clear_object (&self->pPrivate->pSettings);
}
+ g_clear_object (&self->pPrivate->pLomiriSettings);
+
if (self->pPrivate->pKeyboard != NULL)
{
g_object_unref(G_OBJECT(self->pPrivate->pKeyboard));
@@ -512,8 +561,9 @@ static void onSettingsChanged(GSettings *pSettings, gchar *sKey, gpointer pData)
static void indicator_keyboard_service_init(IndicatorKeyboardService *self)
{
gchar *sLib = "libayatana-keyboard-x11.so.0";
+ gboolean bLomiri = ayatana_common_utils_is_lomiri ();
- if (ayatana_common_utils_is_lomiri())
+ if (bLomiri)
{
sLib = "libayatana-keyboard-lomiri.so.0";
}
@@ -540,9 +590,16 @@ static void indicator_keyboard_service_init(IndicatorKeyboardService *self)
m_fnKeyboardGetLayout = dlsym(m_pLibHandle, "keyboard_GetLayout");
m_fnKeyboardSetLayout = dlsym(m_pLibHandle, "keyboard_SetLayout");
self->pPrivate = indicator_keyboard_service_get_instance_private(self);
+ self->pPrivate->bLomiri = bLomiri;
self->pPrivate->pCancellable = g_cancellable_new();
self->pPrivate->pSettings = g_settings_new ("org.ayatana.indicator.keyboard");
g_signal_connect(self->pPrivate->pSettings, "changed", G_CALLBACK(onSettingsChanged), self);
+
+ if (self->pPrivate->bLomiri)
+ {
+ self->pPrivate->pLomiriSettings = g_settings_new ("com.lomiri.Shell");
+ }
+
self->pPrivate->pKeyboard = m_fnKeyboardNew();
g_signal_connect(self->pPrivate->pKeyboard, KEYBOARD_LAYOUT_CHANGED, G_CALLBACK(onLayoutChanged), self);
g_signal_connect(self->pPrivate->pKeyboard, KEYBOARD_CONFIG_CHANGED, G_CALLBACK(onConfigChanged), self);
diff --git a/src/system-layouts.h b/src/system-layouts.h
new file mode 100644
index 00000000..af9b2b5c
--- /dev/null
+++ b/src/system-layouts.h
@@ -0,0 +1,186 @@
+/*
+ * Copyright 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
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __SYSTEM_LAYOUTS__
+#define __SYSTEM_LAYOUTS__
+
+G_BEGIN_DECLS
+
+static void getSystemLayouts (gchar *sLocation, GSList **lLayoutRec, GStrv *lSystemLayouts, gboolean bSystemLayouts)
+{
+ gboolean bExists = g_file_test (sLocation, G_FILE_TEST_EXISTS);
+
+ if (!bExists)
+ {
+ return;
+ }
+
+ gchar *sFile = NULL;
+ GError *pError = NULL;
+ g_file_get_contents (sLocation, &sFile, NULL, &pError);
+
+ if (pError)
+ {
+ g_error_free (pError);
+
+ return;
+ }
+
+ GRegex *pRegex = NULL;
+ gboolean bDefaultLocation = g_str_equal (sLocation, "/etc/default/keyboard");
+
+ if (bDefaultLocation)
+ {
+ #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 (pError)
+ {
+ g_warning ("Panic: Failed to compile regex: %s", pError->message);
+ g_error_free (pError);
+ g_free(sFile);
+
+ return;
+ }
+
+ 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)
+ {
+ g_regex_unref (pRegex);
+ g_free(sFile);
+
+ return;
+ }
+
+ gchar *sLayouts = g_match_info_fetch (pMatchInfo, 1);
+ GStrv lLayouts = g_strsplit (sLayouts, ",", -1);
+ g_free (sLayouts);
+ g_match_info_free (pMatchInfo);
+ g_regex_unref (pRegex);
+
+ 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 (pError)
+ {
+ g_warning ("Panic: Failed to compile regex: %s", pError->message);
+ g_error_free (pError);
+ g_free(sFile);
+
+ return;
+ }
+
+ #if GLIB_CHECK_VERSION(2, 73, 0)
+ bMatch = g_regex_match (pRegex, sFile, G_REGEX_MATCH_DEFAULT, &pMatchInfo);
+ #else
+ bMatch = g_regex_match (pRegex, sFile, (GRegexMatchFlags) 0, &pMatchInfo);
+ #endif
+
+ if (!bMatch)
+ {
+ g_regex_unref (pRegex);
+ g_free(sFile);
+
+ return;
+ }
+
+ gchar *sVariants = g_match_info_fetch (pMatchInfo, 1);
+ GStrv lVariants = g_strsplit (sVariants, ",", -1);
+ g_free (sVariants);
+ g_match_info_free (pMatchInfo);
+ g_regex_unref (pRegex);
+ g_free(sFile);
+ guint nLayouts = g_strv_length (lLayouts);
+ GStrvBuilder *pBuilder = NULL;
+
+ if (bSystemLayouts)
+ {
+ pBuilder = g_strv_builder_new ();
+ }
+
+ for (guint nLayout = 0; nLayout < nLayouts; nLayout++)
+ {
+ gchar *sId = NULL;
+ guint nVariantLength = 0;
+
+ if (lVariants && lVariants[nLayout])
+ {
+ nVariantLength = strlen (lVariants[nLayout]);
+ }
+
+ if (nVariantLength)
+ {
+ sId = g_strconcat (lLayouts[nLayout], "+", lVariants[nLayout], NULL);
+ }
+ else
+ {
+ sId = g_strdup (lLayouts[nLayout]);
+ }
+
+ *lLayoutRec = g_slist_append (*lLayoutRec, sId);
+
+ if (bSystemLayouts)
+ {
+ g_strv_builder_add (pBuilder, sId);
+ }
+ }
+
+ if (bSystemLayouts)
+ {
+ *lSystemLayouts = g_strv_builder_end (pBuilder);
+ g_strv_builder_unref (pBuilder);
+ }
+
+ g_strfreev (lLayouts);
+ g_strfreev (lVariants);
+}
+
+G_END_DECLS
+
+#endif