Skip to content

Commit

Permalink
Merge branch 'tari01-pr/multiple-system-layouts'
Browse files Browse the repository at this point in the history
Attributes GH PR #71: #71
  • Loading branch information
sunweaver committed Jul 15, 2024
2 parents b5eecfc + 907c32c commit 2da4c6e
Show file tree
Hide file tree
Showing 2 changed files with 170 additions and 101 deletions.
192 changes: 118 additions & 74 deletions src/keyboard-lomiri.c
Original file line number Diff line number Diff line change
Expand Up @@ -445,111 +445,155 @@ 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++)
// 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;
Expand Down
79 changes: 52 additions & 27 deletions src/keyboard-x11.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021-2023 Robert Tari <[email protected]>
* Copyright 2021-2024 Robert Tari <[email protected]>
*
* 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
Expand Down Expand Up @@ -48,7 +48,7 @@ struct _KeyboardPrivate
GDBusConnection *pConnection;
guint nSubscription;
gchar *sUser;
gchar *sSystemLayout;
GStrv lSystemLayouts;
};

typedef KeyboardPrivate priv_t;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand All @@ -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)
{
Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down

0 comments on commit 2da4c6e

Please sign in to comment.