Add APIs for finding default input sources

This commit is contained in:
Ray Strode 2023-08-25 22:28:14 -04:00
parent 1f16e3e4d6
commit f65557b057
5 changed files with 1262 additions and 1 deletions

View File

@ -0,0 +1,141 @@
From cf2af4acbea3e5db04d4708e1afd7cfa962af0cd Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 25 Aug 2023 09:47:47 -0400
Subject: [PATCH 1/4] meson: Add python3 to build scripts
We're going to need to use python3 in a future commit to
query langtable for a list of non-latin input sources.
As prep work for that, add the basic goo needed to get
python3 available from the build system.
---
.gitlab-ci.yml | 2 +-
meson.build | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 6d6c7bbc..56962b1c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,49 +1,49 @@
# You can override the included template(s) by including variable overrides
# SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
# Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings
# Dependency Scanning customization: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings
# Note that environment variables can be set in several places
# See https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence
include:
- template: Security/SAST.gitlab-ci.yml
- template: Security/Secret-Detection.gitlab-ci.yml
image: fedora:latest
variables:
LAST_ABI_BREAK: 0da1fcac914ad4c67f016bda7864c4b153cbfbaa
DEPENDENCIES: gtk3-devel gtk4-devel gsettings-desktop-schemas-devel gettext
gtk-doc libxkbcommon-devel xkeyboard-config-devel itstool
gobject-introspection-devel systemd-devel iso-codes-devel
libseccomp-devel gcc gcc-c++ glibc-devel
- meson redhat-rpm-config
+ meson redhat-rpm-config python3-langtable
TEST_DEPENDENCIES: gnome-desktop-testing xorg-x11-server-Xvfb glibc-langpack-en glibc-langpack-he glibc-langpack-ja abattis-cantarell-fonts libabigail git
build_stable:
before_script:
# Undo delangification present in the Fedora Docker images
- rm -f /etc/rpm/macros.image-language-conf
- echo "reinstall glib2" >> translist.txt
# Work-around https://bugzilla.redhat.com/show_bug.cgi?id=1607172#c4
- echo "update dnf gdbm" >> translist.txt
- echo "remove python3-modulemd" >> translist.txt
- dnf shell -y --nogpgcheck translist.txt
- dnf update -y --nogpgcheck
- dnf install -y --nogpgcheck $DEPENDENCIES
- dnf install -y --nogpgcheck $TEST_DEPENDENCIES
script:
- meson --prefix=/usr -Dinstalled_tests=true build
- pushd build
- ninja
- ninja install
- ninja dist
- G_MESSAGES_DEBUG=all xvfb-run -a -s "-screen 0 1024x768x24" ninja test
- G_MESSAGES_DEBUG=all xvfb-run -a -s "-screen 0 1024x768x24"
gnome-desktop-testing-runner --report-directory=test-results gnome-desktop
- popd
- .ci/check-abi ${LAST_ABI_BREAK} $(git rev-parse HEAD)
artifacts:
paths:
- build/meson-logs/
- build/test-results/
when: on_failure
diff --git a/meson.build b/meson.build
index 51a59e33..0419aa3c 100644
--- a/meson.build
+++ b/meson.build
@@ -9,60 +9,63 @@ project('gnome-desktop', 'c',
# Before making a release, the libversion string should be modified.
#
# * Bump the first component if binary compatibility has been broken; or
# * Bump the second component if new APIs are added; or
# * Bump the third component otherwise.
#
# When bumping the first component version, set the second and third components
# to 0. When bumping the second version, set the third one to zero.
#
# A lot easier than libtool, right?
libversion = '2.1.0'
soversion = libversion.split('.')[0]
# Compatibility versions for libgnome-desktop-3
compat_libversion = '20.0.0'
compat_soversion = compat_libversion.split('.')[0]
gdk_pixbuf_req = '>= 2.36.5'
gtk3_req = '>= 3.3.6'
gtk4_req = '>= 4.4.0'
glib_req = '>= 2.53.0'
xrandr_req = '>= 1.3'
schemas_req = '>= 3.27.0'
xext_req = '>= 1.1'
gnome = import('gnome')
i18n = import('i18n')
pkg = import('pkgconfig')
+python = import('python')
+python3 = python.find_installation('python3', modules : ['langtable'])
+
prefix = get_option('prefix')
datadir = prefix / get_option('datadir')
libexecdir = prefix / get_option('libexecdir')
liblocaledir = get_option('prefix') / 'lib/locale'
localedir = datadir / 'locale'
test_metadir = datadir / 'installed-tests' / meson.project_name()
test_execdir = libexecdir / 'installed-tests' / meson.project_name()
versiondir = datadir / 'gnome'
gdk_pixbuf_dep = dependency('gdk-pixbuf-2.0', version: gdk_pixbuf_req)
gtk3_dep = dependency('gtk+-3.0', version: gtk3_req, required: get_option('legacy_library'))
gtk4_dep = dependency('gtk4', version: gtk4_req, required: get_option('build_gtk4'))
glib_dep = dependency('glib-2.0', version: glib_req)
gio_dep = dependency('gio-2.0', version: glib_req)
gio_unix_dep = dependency('gio-unix-2.0', version: glib_req)
schemas_dep = dependency('gsettings-desktop-schemas', version: schemas_req)
fontconfig_dep = dependency('fontconfig')
xkb_config_dep = dependency('xkeyboard-config')
xkbregistry_dep = dependency('xkbregistry', required: false)
iso_codes_dep = dependency('iso-codes')
libsystemd_dep = dependency('libsystemd', required: get_option('systemd'))
udev_dep = dependency('libudev', required: get_option('udev'))
# Check for bubblewrap compatible platform
host_os = host_machine.system()
host_cpu = host_machine.cpu()
supported_os = ['linux']
unsupported_cpus = ['alpha', 'ia64', 'm68k', 'sh4', 'sparc', 'sparc64']
--
2.41.0.rc2

View File

@ -0,0 +1,423 @@
From 34abb9b4f16cba6aac43c63ebd49084200a868d9 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 24 Aug 2023 17:37:37 -0400
Subject: [PATCH 2/4] gnome-languages: Add function to detect non-latin layouts
If user chooses "Russian" we need to add "us" as well so they have
a way to input latin characters.
This commit adds a function to detect layouts that need supplemental
layouts to tag along.
---
.../generate-non-latin-input-sources.py | 39 +++++++++++++++++++
libgnome-desktop/gnome-languages.c | 30 ++++++++++++++
libgnome-desktop/gnome-languages.h | 2 +
libgnome-desktop/meson.build | 7 ++++
4 files changed, 78 insertions(+)
create mode 100644 libgnome-desktop/generate-non-latin-input-sources.py
diff --git a/libgnome-desktop/generate-non-latin-input-sources.py b/libgnome-desktop/generate-non-latin-input-sources.py
new file mode 100644
index 00000000..f0403268
--- /dev/null
+++ b/libgnome-desktop/generate-non-latin-input-sources.py
@@ -0,0 +1,39 @@
+import langtable
+import locale
+
+all_locales = [locale.normalize(locale_id) for locale_id in locale.locale_alias.values()]
+
+non_latin_keyboards = {}
+
+for locale in all_locales:
+ keyboards = langtable.list_keyboards(languageId=locale)
+ for keyboard in keyboards:
+ # Check if the keyboard supports ASCII
+ if not langtable.supports_ascii(keyboardId=keyboard):
+ non_latin_keyboards[keyboard] = 'xkb'
+
+sorted_non_latin_keyboards = sorted(non_latin_keyboards.items(), key=lambda x: x[0])
+
+header_prolog = '''
+typedef struct
+{
+ char *type;
+ char *id;
+} InputSource;
+
+static InputSource non_latin_input_sources[] =
+{
+'''
+
+header_epilog = '''
+};
+'''
+
+with open('non-latin-input-sources.h', 'w') as file:
+ file.write(header_prolog)
+
+ for keyboard, type in sorted_non_latin_keyboards:
+ file.write(f' {{ "{type}", "{keyboard}" }},\n')
+ file.write(" { NULL, NULL },")
+
+ file.write(header_epilog)
diff --git a/libgnome-desktop/gnome-languages.c b/libgnome-desktop/gnome-languages.c
index adfc4eee..cc9bd005 100644
--- a/libgnome-desktop/gnome-languages.c
+++ b/libgnome-desktop/gnome-languages.c
@@ -26,60 +26,61 @@
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <dirent.h>
#include <langinfo.h>
#include <sys/stat.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <glib/gstdio.h>
#ifdef HAVE_XLOCALE
#include <xlocale.h>
#endif
#include "gnome-gettext-portable.h"
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include "gnome-languages.h"
#include <langinfo.h>
#ifndef __LC_LAST
#define __LC_LAST 13
#endif
#define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes"
#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"
#include "default-input-sources.h"
+#include "non-latin-input-sources.h"
typedef struct _GnomeLocale {
char *id;
char *name;
char *language_code;
char *territory_code;
char *codeset;
char *modifier;
} GnomeLocale;
static GHashTable *gnome_languages_map;
static GHashTable *gnome_territories_map;
static GHashTable *gnome_available_locales_map;
static GHashTable *gnome_language_count_map;
static GHashTable *gnome_territory_count_map;
static char * construct_language_name (const char *language,
const char *territory,
const char *codeset,
const char *modifier);
static gboolean language_name_is_valid (const char *language_name);
static void
gnome_locale_free (GnomeLocale *locale)
{
if (locale == NULL) {
return;
}
@@ -1410,30 +1411,59 @@ gnome_get_input_source_from_locale (const char *locale,
DefaultInputSource *dis;
g_autofree gchar *l_code = NULL;
g_autofree gchar *c_code = NULL;
g_autofree gchar *key = NULL;
gint i;
g_return_val_if_fail (locale != NULL, FALSE);
g_return_val_if_fail (type != NULL, FALSE);
g_return_val_if_fail (id != NULL, FALSE);
if (!table) {
table = g_hash_table_new (g_str_hash, g_str_equal);
for (i = 0; default_input_sources[i].id; ++i) {
dis = &default_input_sources[i];
g_hash_table_insert (table, (gpointer) dis->locale, dis);
}
}
if (!gnome_parse_locale (locale, &l_code, &c_code, NULL, NULL))
return FALSE;
key = g_strconcat (l_code, "_", c_code, NULL);
dis = g_hash_table_lookup (table, key);
if (dis) {
*type = dis->type;
*id = dis->id;
}
return dis != NULL;
}
+
+/**
+ * gnome_input_source_is_non_latin:
+ * @type: an input source type (e.g., "xkb" or "ibus")
+ * @id: an input source id (e.g., "us+dvorak" or "anthy")
+ *
+ * Returns whether or not the input source has the ability to enter latin characters.
+ *
+ * Return value: %TRUE if it can't enter latin characters
+ *
+ * Since: 46
+ */
+gboolean
+gnome_input_source_is_non_latin (const char *type,
+ const char *id)
+{
+ size_t i;
+
+ for (i = 0; non_latin_input_sources[i].type != NULL; i++) {
+ if (g_strcmp0 (type, non_latin_input_sources[i].type) != 0)
+ continue;
+
+ if (g_strcmp0 (id, non_latin_input_sources[i].id) != 0)
+ continue;
+
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/libgnome-desktop/gnome-languages.h b/libgnome-desktop/gnome-languages.h
index ed0935c8..ed9242e7 100644
--- a/libgnome-desktop/gnome-languages.h
+++ b/libgnome-desktop/gnome-languages.h
@@ -27,33 +27,35 @@
#error This is unstable API. You must define GNOME_DESKTOP_USE_UNSTABLE_API before including gnome-languages.h
#endif
#include <glib.h>
#include <libgnome-desktop/gnome-desktop-version.h>
G_BEGIN_DECLS
char * gnome_get_language_from_locale (const char *locale,
const char *translation);
char * gnome_get_country_from_locale (const char *locale,
const char *translation);
char ** gnome_get_all_locales (void);
gboolean gnome_parse_locale (const char *locale,
char **language_codep,
char **country_codep,
char **codesetp,
char **modifierp);
char * gnome_normalize_locale (const char *locale);
gboolean gnome_language_has_translations (const char *code);
char * gnome_get_language_from_code (const char *code,
const char *translation);
char * gnome_get_country_from_code (const char *code,
const char *translation);
char * gnome_get_translated_modifier (const char *modifier,
const char *translation);
gboolean gnome_get_input_source_from_locale (const char *locale,
const char **type,
const char **id);
+gboolean gnome_input_source_is_non_latin (const char *type,
+ const char *id);
G_END_DECLS
#endif /* __GNOME_LANGUAGES_H */
diff --git a/libgnome-desktop/meson.build b/libgnome-desktop/meson.build
index 708a4ae8..d41e0cc0 100644
--- a/libgnome-desktop/meson.build
+++ b/libgnome-desktop/meson.build
@@ -28,118 +28,124 @@ conf.set('HAVE_USELOCALE', cc.has_function('uselocale'))
conf.set('HAVE_XLOCALE', cc.has_header('xlocale.h'))
configure_file(
output: 'config.h',
configuration: conf,
)
version_conf = configuration_data()
version_array = meson.project_version().split('.')
version_conf.set('GNOME_PLATFORM', version_array[0])
gnome_desktop_header_file = configure_file(
input: 'gnome-desktop-version.h.in',
output: 'gnome-desktop-version.h',
configuration: version_conf,
)
dbus_xrandr_built_sources = gnome.gdbus_codegen('meta-dbus-xrandr',
'xrandr.xml',
namespace: 'MetaDBus',
interface_prefix: 'org.gnome.Mutter'
)
dbus_idle_built_sources = gnome.gdbus_codegen('meta-dbus-idle-monitor',
'idle-monitor.xml',
namespace: 'MetaDBus',
interface_prefix: 'org.gnome.Mutter',
object_manager: true
)
+non_latin_input_sources = custom_target('generate_non_latin_input_sources_header',
+ output : 'non-latin-input-sources.h',
+ command : [python3, files ('generate-non-latin-input-sources.py')]
+)
+
base_ldflags = []
base_symbol_map = '-Wl,--version-script=@0@'.format(meson.current_source_dir() / 'base-symbol.map')
if cc.has_link_argument(base_symbol_map)
base_ldflags += base_symbol_map
endif
### gnome-desktop-base
libgnome_desktop_base_sources = [
'gnome-desktop-version.c',
'gnome-desktop-thumbnail.c',
'gnome-idle-monitor.c',
'gnome-languages.c',
'gnome-pnp-ids.c',
'gnome-systemd.c',
'gnome-wall-clock.c',
'gnome-xkb-info.c',
]
libgnome_desktop_base_private_sources = [
'gnome-datetime-source.c',
'gnome-desktop-thumbnail-script.c',
'gnome-gettext-portable.c',
]
libgnome_desktop_base_headers = [
gnome_desktop_header_file,
'gnome-desktop-thumbnail.h',
'gnome-idle-monitor.h',
'gnome-languages.h',
'gnome-pnp-ids.h',
'gnome-systemd.h',
'gnome-wall-clock.h',
'gnome-xkb-info.h',
]
if get_option('build_gtk4')
install_headers(libgnome_desktop_base_headers,
subdir: 'gnome-desktop-4.0/libgnome-desktop'
)
base_deps = [
gdk_pixbuf_dep,
glib_dep,
gio_dep,
gio_unix_dep,
libsystemd_dep,
schemas_dep,
xkb_config_dep,
xkbregistry_dep,
iso_codes_dep,
udev_dep,
seccomp_dep,
m_dep,
rt_dep,
]
libgnome_desktop_base = library('gnome-desktop-4',
sources: [
+ non_latin_input_sources,
libgnome_desktop_base_sources,
libgnome_desktop_base_private_sources,
dbus_idle_built_sources,
],
dependencies: base_deps,
soversion: soversion,
version: libversion,
c_args: libargs,
link_args: base_ldflags,
install: true,
include_directories: [
include_directories('.'),
include_directories('..'),
],
)
if get_option('introspection')
libgnome_desktop_base_gir = gnome.generate_gir(libgnome_desktop_base,
sources: [libgnome_desktop_base_headers, libgnome_desktop_base_sources],
export_packages: 'gnome-desktop-4',
namespace: 'GnomeDesktop',
nsversion: '4.0',
includes: ['GObject-2.0', 'Gio-2.0', 'GDesktopEnums-3.0', 'GdkPixbuf-2.0'],
extra_args: ['-DGNOME_DESKTOP_USE_UNSTABLE_API', '--quiet', '--warn-all'],
identifier_prefix: 'Gnome',
symbol_prefix: 'gnome',
install: true,
)
endif
@@ -162,60 +168,61 @@ if get_option('build_gtk4')
include_directories: [
include_directories('.'),
include_directories('..'),
],
)
subdir('gnome-bg')
subdir('gnome-rr')
endif
### Legacy ###
if get_option('legacy_library')
introspection_sources = [
'gnome-desktop-version.c',
'gnome-desktop-thumbnail.c',
'gnome-bg.c',
'gnome-bg-slide-show.c',
'gnome-bg-crossfade.c',
'gnome-rr.c',
'gnome-rr-config.c',
'gnome-rr-output-info.c',
'gnome-systemd.c',
'gnome-pnp-ids.c',
'gnome-wall-clock.c',
'gnome-xkb-info.c',
'gnome-idle-monitor.c',
'gnome-languages.c',
]
libgnome_desktop_sources = [
+ non_latin_input_sources,
introspection_sources,
dbus_xrandr_built_sources,
dbus_idle_built_sources,
'gnome-datetime-source.c',
'gnome-desktop-thumbnail-script.c',
'gnome-gettext-portable.c',
]
libgnome_desktop_headers = [
gnome_desktop_header_file,
'gnome-bg.h',
'gnome-bg-crossfade.h',
'gnome-bg-slide-show.h',
'gnome-desktop-thumbnail.h',
'gnome-rr.h',
'gnome-rr-config.h',
'gnome-systemd.h',
'gnome-pnp-ids.h',
'gnome-wall-clock.h',
'gnome-xkb-info.h',
'gnome-idle-monitor.h',
'gnome-languages.h',
]
install_headers(libgnome_desktop_headers,
subdir: 'gnome-desktop-3.0/libgnome-desktop'
)
gnome_desktop_deps = [
gdk_pixbuf_dep,
--
2.41.0.rc2

View File

@ -0,0 +1,257 @@
From 77a6a304ad6b4d7febe12b3c92da4a00feb1a84e Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 24 Aug 2023 17:43:00 -0400
Subject: [PATCH 3/4] meson: Add codegen for localed
We're going to need to be querying localed for input source information.
This commit paves the way for that by generating proxy glue code for
talking to localed.
---
libgnome-desktop/meson.build | 8 +++++
libgnome-desktop/org.freedesktop.locale1.xml | 38 ++++++++++++++++++++
2 files changed, 46 insertions(+)
create mode 100644 libgnome-desktop/org.freedesktop.locale1.xml
diff --git a/libgnome-desktop/meson.build b/libgnome-desktop/meson.build
index d41e0cc0..164fd2ff 100644
--- a/libgnome-desktop/meson.build
+++ b/libgnome-desktop/meson.build
@@ -28,60 +28,66 @@ conf.set('HAVE_USELOCALE', cc.has_function('uselocale'))
conf.set('HAVE_XLOCALE', cc.has_header('xlocale.h'))
configure_file(
output: 'config.h',
configuration: conf,
)
version_conf = configuration_data()
version_array = meson.project_version().split('.')
version_conf.set('GNOME_PLATFORM', version_array[0])
gnome_desktop_header_file = configure_file(
input: 'gnome-desktop-version.h.in',
output: 'gnome-desktop-version.h',
configuration: version_conf,
)
dbus_xrandr_built_sources = gnome.gdbus_codegen('meta-dbus-xrandr',
'xrandr.xml',
namespace: 'MetaDBus',
interface_prefix: 'org.gnome.Mutter'
)
dbus_idle_built_sources = gnome.gdbus_codegen('meta-dbus-idle-monitor',
'idle-monitor.xml',
namespace: 'MetaDBus',
interface_prefix: 'org.gnome.Mutter',
object_manager: true
)
+dbus_localed_built_sources = gnome.gdbus_codegen('sd-locale1',
+ 'org.freedesktop.locale1.xml',
+ namespace: 'SdDBus',
+ interface_prefix: 'org.freedesktop',
+)
+
non_latin_input_sources = custom_target('generate_non_latin_input_sources_header',
output : 'non-latin-input-sources.h',
command : [python3, files ('generate-non-latin-input-sources.py')]
)
base_ldflags = []
base_symbol_map = '-Wl,--version-script=@0@'.format(meson.current_source_dir() / 'base-symbol.map')
if cc.has_link_argument(base_symbol_map)
base_ldflags += base_symbol_map
endif
### gnome-desktop-base
libgnome_desktop_base_sources = [
'gnome-desktop-version.c',
'gnome-desktop-thumbnail.c',
'gnome-idle-monitor.c',
'gnome-languages.c',
'gnome-pnp-ids.c',
'gnome-systemd.c',
'gnome-wall-clock.c',
'gnome-xkb-info.c',
]
libgnome_desktop_base_private_sources = [
'gnome-datetime-source.c',
'gnome-desktop-thumbnail-script.c',
'gnome-gettext-portable.c',
]
libgnome_desktop_base_headers = [
@@ -95,60 +101,61 @@ libgnome_desktop_base_headers = [
'gnome-xkb-info.h',
]
if get_option('build_gtk4')
install_headers(libgnome_desktop_base_headers,
subdir: 'gnome-desktop-4.0/libgnome-desktop'
)
base_deps = [
gdk_pixbuf_dep,
glib_dep,
gio_dep,
gio_unix_dep,
libsystemd_dep,
schemas_dep,
xkb_config_dep,
xkbregistry_dep,
iso_codes_dep,
udev_dep,
seccomp_dep,
m_dep,
rt_dep,
]
libgnome_desktop_base = library('gnome-desktop-4',
sources: [
non_latin_input_sources,
libgnome_desktop_base_sources,
libgnome_desktop_base_private_sources,
dbus_idle_built_sources,
+ dbus_localed_built_sources,
],
dependencies: base_deps,
soversion: soversion,
version: libversion,
c_args: libargs,
link_args: base_ldflags,
install: true,
include_directories: [
include_directories('.'),
include_directories('..'),
],
)
if get_option('introspection')
libgnome_desktop_base_gir = gnome.generate_gir(libgnome_desktop_base,
sources: [libgnome_desktop_base_headers, libgnome_desktop_base_sources],
export_packages: 'gnome-desktop-4',
namespace: 'GnomeDesktop',
nsversion: '4.0',
includes: ['GObject-2.0', 'Gio-2.0', 'GDesktopEnums-3.0', 'GdkPixbuf-2.0'],
extra_args: ['-DGNOME_DESKTOP_USE_UNSTABLE_API', '--quiet', '--warn-all'],
identifier_prefix: 'Gnome',
symbol_prefix: 'gnome',
install: true,
)
endif
pkg.generate(
libgnome_desktop_base,
requires: ['gsettings-desktop-schemas'],
@@ -172,60 +179,61 @@ if get_option('build_gtk4')
)
subdir('gnome-bg')
subdir('gnome-rr')
endif
### Legacy ###
if get_option('legacy_library')
introspection_sources = [
'gnome-desktop-version.c',
'gnome-desktop-thumbnail.c',
'gnome-bg.c',
'gnome-bg-slide-show.c',
'gnome-bg-crossfade.c',
'gnome-rr.c',
'gnome-rr-config.c',
'gnome-rr-output-info.c',
'gnome-systemd.c',
'gnome-pnp-ids.c',
'gnome-wall-clock.c',
'gnome-xkb-info.c',
'gnome-idle-monitor.c',
'gnome-languages.c',
]
libgnome_desktop_sources = [
non_latin_input_sources,
introspection_sources,
dbus_xrandr_built_sources,
dbus_idle_built_sources,
+ dbus_localed_built_sources,
'gnome-datetime-source.c',
'gnome-desktop-thumbnail-script.c',
'gnome-gettext-portable.c',
]
libgnome_desktop_headers = [
gnome_desktop_header_file,
'gnome-bg.h',
'gnome-bg-crossfade.h',
'gnome-bg-slide-show.h',
'gnome-desktop-thumbnail.h',
'gnome-rr.h',
'gnome-rr-config.h',
'gnome-systemd.h',
'gnome-pnp-ids.h',
'gnome-wall-clock.h',
'gnome-xkb-info.h',
'gnome-idle-monitor.h',
'gnome-languages.h',
]
install_headers(libgnome_desktop_headers,
subdir: 'gnome-desktop-3.0/libgnome-desktop'
)
gnome_desktop_deps = [
gdk_pixbuf_dep,
gtk3_dep,
glib_dep,
gio_dep,
diff --git a/libgnome-desktop/org.freedesktop.locale1.xml b/libgnome-desktop/org.freedesktop.locale1.xml
new file mode 100644
index 00000000..bc23d3a1
--- /dev/null
+++ b/libgnome-desktop/org.freedesktop.locale1.xml
@@ -0,0 +1,38 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.freedesktop.locale1">
+ <property name="Locale" type="as" access="read">
+ </property>
+ <property name="X11Layout" type="s" access="read">
+ </property>
+ <property name="X11Model" type="s" access="read">
+ </property>
+ <property name="X11Variant" type="s" access="read">
+ </property>
+ <property name="X11Options" type="s" access="read">
+ </property>
+ <property name="VConsoleKeymap" type="s" access="read">
+ </property>
+ <property name="VConsoleKeymapToggle" type="s" access="read">
+ </property>
+ <method name="SetLocale">
+ <arg type="as" direction="in"/>
+ <arg type="b" direction="in"/>
+ </method>
+ <method name="SetVConsoleKeyboard">
+ <arg type="s" direction="in"/>
+ <arg type="s" direction="in"/>
+ <arg type="b" direction="in"/>
+ <arg type="b" direction="in"/>
+ </method>
+ <method name="SetX11Keyboard">
+ <arg type="s" direction="in"/>
+ <arg type="s" direction="in"/>
+ <arg type="s" direction="in"/>
+ <arg type="s" direction="in"/>
+ <arg type="b" direction="in"/>
+ <arg type="b" direction="in"/>
+ </method>
+ </interface>
+</node>
--
2.41.0.rc2

View File

@ -0,0 +1,431 @@
From 38c1d2a3c70ba3785cfb22b0baf1f5d97b63b90a Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 24 Aug 2023 19:58:17 -0400
Subject: [PATCH 4/4] languages: Add functions for getting default input
sources
The code to get the default input sources would otherwise need
to be duplicated across control-center, gnome-shell and
gnome-initial-setup.
This commit avoids some of that redundancy by consolidating the
logic into two new functions:
gnome_get_default_input_sources and
gnome_get_default_input_sources_finish
Note, these functions don't provide change notification, so there
is still some redundancy needed by callers.
---
libgnome-desktop/gnome-languages.c | 234 +++++++++++++++++++++++++++++
libgnome-desktop/gnome-languages.h | 9 ++
2 files changed, 243 insertions(+)
diff --git a/libgnome-desktop/gnome-languages.c b/libgnome-desktop/gnome-languages.c
index cc9bd005..65ea2845 100644
--- a/libgnome-desktop/gnome-languages.c
+++ b/libgnome-desktop/gnome-languages.c
@@ -17,60 +17,62 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
* Written by : William Jon McCann <mccann@jhu.edu>
* Ray Strode <rstrode@redhat.com>
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <dirent.h>
#include <langinfo.h>
#include <sys/stat.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <glib/gstdio.h>
#ifdef HAVE_XLOCALE
#include <xlocale.h>
#endif
#include "gnome-gettext-portable.h"
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include "gnome-languages.h"
+#include "sd-locale1.h"
+
#include <langinfo.h>
#ifndef __LC_LAST
#define __LC_LAST 13
#endif
#define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes"
#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"
#include "default-input-sources.h"
#include "non-latin-input-sources.h"
typedef struct _GnomeLocale {
char *id;
char *name;
char *language_code;
char *territory_code;
char *codeset;
char *modifier;
} GnomeLocale;
static GHashTable *gnome_languages_map;
static GHashTable *gnome_territories_map;
static GHashTable *gnome_available_locales_map;
static GHashTable *gnome_language_count_map;
static GHashTable *gnome_territory_count_map;
static char * construct_language_name (const char *language,
const char *territory,
const char *codeset,
const char *modifier);
@@ -1440,30 +1442,262 @@ gnome_get_input_source_from_locale (const char *locale,
}
/**
* gnome_input_source_is_non_latin:
* @type: an input source type (e.g., "xkb" or "ibus")
* @id: an input source id (e.g., "us+dvorak" or "anthy")
*
* Returns whether or not the input source has the ability to enter latin characters.
*
* Return value: %TRUE if it can't enter latin characters
*
* Since: 46
*/
gboolean
gnome_input_source_is_non_latin (const char *type,
const char *id)
{
size_t i;
for (i = 0; non_latin_input_sources[i].type != NULL; i++) {
if (g_strcmp0 (type, non_latin_input_sources[i].type) != 0)
continue;
if (g_strcmp0 (id, non_latin_input_sources[i].id) != 0)
continue;
return TRUE;
}
return FALSE;
}
+
+static void
+on_got_localed_proxy (GObject *object,
+ GAsyncResult *result,
+ GTask *sub_task)
+{
+ g_autoptr(SdDBusLocale1) proxy = NULL;
+ g_autoptr(GError) error = NULL;
+
+ proxy = sd_dbus_locale1_proxy_new_finish (result, &error);
+
+ if (error != NULL) {
+ g_task_return_error (sub_task, g_steal_pointer (&error));
+ } else {
+ g_task_return_pointer (sub_task, g_steal_pointer (&proxy), (GDestroyNotify) g_object_unref);
+ }
+}
+
+static void
+get_localed_proxy (GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ GTask *main_task)
+{
+ g_autoptr(GTask) sub_task = NULL;
+
+ sub_task = g_task_new (NULL,
+ cancellable,
+ callback,
+ main_task);
+
+ sd_dbus_locale1_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ "org.freedesktop.locale1",
+ "/org/freedesktop/locale1",
+ cancellable,
+ (GAsyncReadyCallback)
+ on_got_localed_proxy,
+ sub_task);
+
+ g_object_set_data_full (G_OBJECT (main_task),
+ "gnome-desktop-get-localed-proxy",
+ g_steal_pointer (&sub_task),
+ g_object_unref);
+}
+
+static gboolean
+input_source_equal (const InputSource *a,
+ const InputSource *b)
+{
+ return g_str_equal (a->type, b->type) && g_str_equal (a->id, b->id);
+}
+
+static void
+input_sources_free (InputSource **input_sources)
+{
+ size_t i;
+
+ for (i = 0; input_sources[i] != NULL; i++) {
+ g_free (input_sources[i]->type);
+ g_free (input_sources[i]->id);
+ g_free (input_sources[i]);
+ }
+ g_free (input_sources);
+}
+
+static void
+on_got_localed_proxy_for_getting_default_input_sources (GObject *object,
+ GAsyncResult *result,
+ GTask *main_task)
+{
+ g_autoptr(SdDBusLocale1) proxy = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GPtrArray) input_sources = NULL;
+ g_autofree InputSource *locale_input_source = NULL;
+
+ const char * const *locale_data;
+ g_autofree char *system_locale = NULL;
+ g_autofree char *layouts_string = NULL;
+ g_autofree char *variants_string = NULL;
+ g_auto(GStrv) layouts = NULL;
+ size_t number_of_layouts = 0;
+ g_auto(GStrv) variants = NULL;
+ size_t number_of_variants = 0;
+ const char *type = NULL, *id = NULL;
+ size_t i;
+
+ proxy = g_task_propagate_pointer (G_TASK (result), &error);
+
+ if (proxy == NULL) {
+ g_task_return_error (main_task, g_steal_pointer (&error));
+ return;
+ }
+
+ input_sources = g_ptr_array_new ();
+
+ locale_data = sd_dbus_locale1_get_locale (proxy);
+ for (i = 0; locale_data[i] != NULL; i++) {
+ if (g_str_has_prefix (locale_data[i], "LANG=")) {
+ system_locale = g_strdup (locale_data[i] + strlen("LANG="));
+ break;
+ }
+ }
+
+ if (gnome_get_input_source_from_locale (system_locale, &type, &id)) {
+ locale_input_source = g_new0 (InputSource, 1);
+ locale_input_source->type = g_strdup (type);
+ locale_input_source->id = g_strdup (id);
+
+ /* We add locale derived input source first if it's an input method
+ * and last if it's xkb based.
+ */
+ if (g_strcmp0 (type, "ibus") == 0) {
+ g_ptr_array_add (input_sources, g_steal_pointer (&locale_input_source));
+ }
+ }
+
+ layouts_string = sd_dbus_locale1_dup_x11_layout (proxy);
+ variants_string = sd_dbus_locale1_dup_x11_variant (proxy);
+
+ layouts = g_strsplit (layouts_string, ",", -1);
+
+ if (variants_string[0] != '\0') {
+ variants = g_strsplit (variants_string, ",", -1);
+ } else {
+ variants = g_strdupv ((char *[]) { "", NULL });
+ }
+
+ number_of_layouts = g_strv_length (layouts);
+ number_of_variants = g_strv_length (variants);
+
+ if (number_of_layouts == number_of_variants) {
+ for (i = 0; layouts[i] != NULL; i++) {
+ g_autofree InputSource *input_source = g_new0 (InputSource, 1);
+
+ input_source->type = g_strdup ("xkb");
+ input_source->id = g_strdup_printf ("%s%s%s",
+ layouts[i],
+ variants[i][0] != '\0'? "+" : "",
+ variants[i]);
+
+ if (!g_ptr_array_find_with_equal_func (input_sources, input_source, (GEqualFunc) input_source_equal, NULL)) {
+ g_ptr_array_add (input_sources, g_steal_pointer (&input_source));
+ }
+ }
+ }
+
+ if (locale_input_source != NULL) {
+ if (!g_ptr_array_find_with_equal_func (input_sources, locale_input_source, (GEqualFunc) input_source_equal, NULL)) {
+ g_ptr_array_add (input_sources, g_steal_pointer (&locale_input_source));
+ }
+ }
+
+ if (input_sources->len == 0) {
+ InputSource *input_source = g_new0 (InputSource, 1);
+ input_source->type = g_strdup ("xkb");
+ input_source->id = g_strdup ("us");
+ g_ptr_array_add (input_sources, g_steal_pointer (&input_source));
+ }
+ g_ptr_array_add (input_sources, NULL);
+
+ g_task_return_pointer (main_task, g_ptr_array_steal (input_sources, NULL), (GDestroyNotify) input_sources_free);
+}
+
+/**
+ * gnome_get_default_input_sources:
+ * @cancellable: a #GCancellable
+ * @callback: a #GAsyncReadyCallback
+ * @user_data: user data for @callback
+ *
+ * Asynchronously fetches a list of of default input sources based on locale and system
+ * configuration. This is for when a user has no input sources configured
+ * in GSettings.
+ *
+ * Since: 46
+ */
+void
+gnome_get_default_input_sources (GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ task = g_task_new (NULL,
+ cancellable,
+ callback,
+ user_data);
+
+ get_localed_proxy (cancellable,
+ (GAsyncReadyCallback)
+ on_got_localed_proxy_for_getting_default_input_sources,
+ task);
+}
+
+/**
+ * gnome_get_default_input_sources_finish:
+ * @result: a #GAsyncResult
+ * @types: (transfer full): an array of types (either "xkb" or "ibus")
+ * @error: a #GError
+ *
+ * Returns: (transfer full): a list of default input sources based on locale and system
+ * configuration. This is for when a user has no input sources configured
+ * in GSettings.
+ *
+ * Since: 46
+ */
+char **
+gnome_get_default_input_sources_finish (GAsyncResult *result,
+ char ***types,
+ GError **error)
+{
+ InputSource **input_sources = NULL;
+ size_t i;
+ g_autoptr (GStrvBuilder) ids_builder = NULL;
+ g_autoptr (GStrvBuilder) types_builder = NULL;
+
+ input_sources = g_task_propagate_pointer (G_TASK (result), error);
+
+ if (input_sources == NULL) {
+ return NULL;
+ }
+
+ ids_builder = g_strv_builder_new ();
+ types_builder = g_strv_builder_new ();
+
+ for (i = 0; input_sources[i] != NULL; i++) {
+ g_strv_builder_add (types_builder, input_sources[i]->type);
+ g_strv_builder_add (ids_builder, input_sources[i]->id);
+ }
+
+ if (types != NULL)
+ *types = g_strv_builder_end (types_builder);
+ return g_strv_builder_end (ids_builder);
+}
diff --git a/libgnome-desktop/gnome-languages.h b/libgnome-desktop/gnome-languages.h
index ed9242e7..6876a0bb 100644
--- a/libgnome-desktop/gnome-languages.h
+++ b/libgnome-desktop/gnome-languages.h
@@ -1,61 +1,70 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright 2008 Red Hat, Inc.
* Copyright 2007 William Jon McCann <mccann@jhu.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY 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/>.
*
* Written by: Ray Strode
* William Jon McCann
*/
#ifndef __GNOME_LANGUAGES_H
#define __GNOME_LANGUAGES_H
#ifndef GNOME_DESKTOP_USE_UNSTABLE_API
#error This is unstable API. You must define GNOME_DESKTOP_USE_UNSTABLE_API before including gnome-languages.h
#endif
#include <glib.h>
+#include <gio/gio.h>
#include <libgnome-desktop/gnome-desktop-version.h>
G_BEGIN_DECLS
char * gnome_get_language_from_locale (const char *locale,
const char *translation);
char * gnome_get_country_from_locale (const char *locale,
const char *translation);
char ** gnome_get_all_locales (void);
gboolean gnome_parse_locale (const char *locale,
char **language_codep,
char **country_codep,
char **codesetp,
char **modifierp);
char * gnome_normalize_locale (const char *locale);
gboolean gnome_language_has_translations (const char *code);
char * gnome_get_language_from_code (const char *code,
const char *translation);
char * gnome_get_country_from_code (const char *code,
const char *translation);
char * gnome_get_translated_modifier (const char *modifier,
const char *translation);
gboolean gnome_get_input_source_from_locale (const char *locale,
const char **type,
const char **id);
gboolean gnome_input_source_is_non_latin (const char *type,
const char *id);
+
+void gnome_get_default_input_sources (GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+char ** gnome_get_default_input_sources_finish (GAsyncResult *result,
+ char ***types,
+ GError **error);
G_END_DECLS
#endif /* __GNOME_LANGUAGES_H */
--
2.41.0.rc2

View File

@ -31,7 +31,14 @@ Source4: loupe-defaults.list
Source5: evince-defaults.list Source5: evince-defaults.list
# https://fedoraproject.org/wiki/Changes/Enhanced_Inscript_as_default_Indic_IM # https://fedoraproject.org/wiki/Changes/Enhanced_Inscript_as_default_Indic_IM
Patch0: make-inscript2-default-for-indic-languages.patch Patch: make-inscript2-default-for-indic-languages.patch
# https://pagure.io/fedora-workstation/issue/362
Patch: 0001-meson-Add-python3-to-build-scripts.patch
Patch: 0002-gnome-languages-Add-function-to-detect-non-latin-lay.patch
Patch: 0003-meson-Add-codegen-for-localed.patch
Patch: 0004-languages-Add-functions-for-getting-default-input-so.patch
BuildRequires: gcc BuildRequires: gcc
BuildRequires: gettext BuildRequires: gettext
@ -49,6 +56,8 @@ BuildRequires: pkgconfig(iso-codes)
BuildRequires: pkgconfig(libseccomp) BuildRequires: pkgconfig(libseccomp)
BuildRequires: pkgconfig(libudev) BuildRequires: pkgconfig(libudev)
BuildRequires: pkgconfig(xkeyboard-config) BuildRequires: pkgconfig(xkeyboard-config)
BuildRequires: python3
BuildRequires: python3dist(langtool)
Conflicts: shared-mime-info < 2.0-4 Conflicts: shared-mime-info < 2.0-4
Requires: shared-mime-info Requires: shared-mime-info