Update to 45.0 and refresh live user mode patchset
Personal preference: let's keep the entire patchset in one file, to make it slightly easier to rebase.
This commit is contained in:
parent
43bfe4b2d1
commit
93dba97ce6
@ -1,150 +0,0 @@
|
||||
From 555b00faf5c25f6903ff9f247a60b0a488bfee14 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Tue, 15 Aug 2023 10:53:41 -0400
|
||||
Subject: [PATCH 1/9] gnome-initial-setup: Bump GLib required version to 2.76
|
||||
|
||||
This gives us GStrvBuilder, g_ptr_array_sort_values, etc
|
||||
---
|
||||
gnome-initial-setup/meson.build | 2 +-
|
||||
meson.build | 4 ++--
|
||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/gnome-initial-setup/meson.build b/gnome-initial-setup/meson.build
|
||||
index a6a014d1..64fa834a 100644
|
||||
--- a/gnome-initial-setup/meson.build
|
||||
+++ b/gnome-initial-setup/meson.build
|
||||
@@ -25,61 +25,61 @@ sources += [
|
||||
'gis-driver.h',
|
||||
'gis-keyring.h'
|
||||
]
|
||||
|
||||
geocode_glib_2_dep = dependency(
|
||||
'geocode-glib-2.0',
|
||||
fallback: ['geocode-glib', 'geocode_glib_dep'],
|
||||
default_options: [
|
||||
'enable-gtk-doc=false',
|
||||
'enable-installed-tests=false',
|
||||
'enable-introspection=false',
|
||||
'soup2=false',
|
||||
],
|
||||
)
|
||||
|
||||
gweather_dep = dependency('gweather4')
|
||||
|
||||
subdir('pages')
|
||||
|
||||
dependencies = [
|
||||
dependency ('libnm', version: '>= 1.2'),
|
||||
dependency ('libnma-gtk4', version: '>= 1.0'),
|
||||
dependency ('polkit-gobject-1', version: '>= 0.103'),
|
||||
dependency ('accountsservice'),
|
||||
geocode_glib_2_dep,
|
||||
dependency ('gnome-desktop-4'),
|
||||
dependency ('gsettings-desktop-schemas', version: '>= 3.37.1'),
|
||||
dependency ('fontconfig'),
|
||||
dependency ('goa-1.0'),
|
||||
dependency ('gtk4', version: '>= 4.6'),
|
||||
- dependency ('glib-2.0', version: '>= 2.63.1'),
|
||||
+ dependency ('glib-2.0', version: '>= 2.76.0'),
|
||||
dependency ('gio-unix-2.0', version: '>= 2.53.0'),
|
||||
dependency ('gdm', version: '>= 3.8.3'),
|
||||
gweather_dep,
|
||||
dependency ('libgeoclue-2.0', version: '>= 2.3.1'),
|
||||
cc.find_library('m', required: false),
|
||||
dependency ('pango', version: '>= 1.32.5'),
|
||||
dependency ('json-glib-1.0'),
|
||||
dependency ('krb5'),
|
||||
dependency ('libsecret-1', version: '>= 0.18.8'),
|
||||
dependency ('pwquality'),
|
||||
dependency ('rest-1.0'),
|
||||
ibus_dep,
|
||||
libmalcontent_dep,
|
||||
libmalcontent_ui_dep,
|
||||
libadwaita_dep,
|
||||
webkitgtk_dep
|
||||
]
|
||||
|
||||
executable(
|
||||
'gnome-initial-setup',
|
||||
sources,
|
||||
include_directories: config_h_dir,
|
||||
dependencies: dependencies,
|
||||
install: true,
|
||||
install_dir: get_option('libexecdir')
|
||||
)
|
||||
|
||||
executable(
|
||||
'gnome-initial-setup-copy-worker',
|
||||
['gnome-initial-setup-copy-worker.c'],
|
||||
diff --git a/meson.build b/meson.build
|
||||
index a1057988..7dd876e3 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -3,62 +3,62 @@ project('gnome-initial-setup',
|
||||
version: '45.beta',
|
||||
license: 'GPL-2.0-or-later',
|
||||
meson_version: '>= 0.53.0',
|
||||
)
|
||||
|
||||
cc = meson.get_compiler('c')
|
||||
gnome = import('gnome')
|
||||
i18n = import('i18n')
|
||||
|
||||
prefix = get_option('prefix')
|
||||
po_dir = join_paths(meson.current_source_dir(), 'po')
|
||||
bin_dir = join_paths(prefix, get_option('bindir'))
|
||||
data_dir = join_paths(prefix, get_option('datadir'))
|
||||
locale_dir = join_paths(prefix, get_option('localedir'))
|
||||
libexec_dir = join_paths(prefix, get_option('libexecdir'))
|
||||
sysconf_dir = join_paths(prefix, get_option('sysconfdir'))
|
||||
pkgdata_dir = join_paths(data_dir, meson.project_name())
|
||||
pkgsysconf_dir = join_paths(sysconf_dir, meson.project_name())
|
||||
|
||||
conf = configuration_data()
|
||||
conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
|
||||
conf.set_quoted('GNOMELOCALEDIR', locale_dir)
|
||||
conf.set_quoted('PKGDATADIR', pkgdata_dir)
|
||||
conf.set_quoted('DATADIR', data_dir)
|
||||
conf.set_quoted('PKGSYSCONFDIR', pkgsysconf_dir)
|
||||
conf.set_quoted('SYSCONFDIR', sysconf_dir)
|
||||
conf.set_quoted('LIBEXECDIR', libexec_dir)
|
||||
conf.set('SECRET_API_SUBJECT_TO_CHANGE', true)
|
||||
conf.set_quoted('G_LOG_DOMAIN', 'InitialSetup')
|
||||
conf.set('G_LOG_USE_STRUCTURED', true)
|
||||
-conf.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_2_64')
|
||||
-conf.set('GLIB_VERSION_MAX_ALLOWED', 'GLIB_VERSION_2_64')
|
||||
+conf.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_2_76')
|
||||
+conf.set('GLIB_VERSION_MAX_ALLOWED', 'GLIB_VERSION_2_76')
|
||||
|
||||
enable_systemd = get_option('systemd')
|
||||
if enable_systemd
|
||||
systemd_dep = dependency('systemd', version: '>= 242', required: false)
|
||||
assert(systemd_dep.found(), 'Systemd support explicitly required, but systemd not found')
|
||||
|
||||
systemd_userunitdir = systemd_dep.get_variable(pkgconfig: 'systemduserunitdir',
|
||||
pkgconfig_define: ['prefix', prefix])
|
||||
systemd_sysusersdir = systemd_dep.get_variable(pkgconfig: 'sysusersdir',
|
||||
pkgconfig_define: ['prefix', prefix])
|
||||
endif
|
||||
|
||||
vendor_conf_file = get_option('vendor-conf-file')
|
||||
if vendor_conf_file != ''
|
||||
conf.set_quoted('VENDOR_CONF_FILE', vendor_conf_file)
|
||||
endif
|
||||
|
||||
# Needed for the 'keyboard' page
|
||||
ibus_dep = dependency ('ibus-1.0',
|
||||
version: '>= 1.4.99',
|
||||
required: get_option('ibus'))
|
||||
have_ibus = ibus_dep.found()
|
||||
conf.set('HAVE_IBUS', have_ibus)
|
||||
|
||||
# Check for libadwaita before malcontent-ui, otherwise Meson may search and
|
||||
# find an older version of libadwaita in the host system, cache it, and fail
|
||||
# to fallback to a submodule.
|
||||
libadwaita_dep = dependency(
|
||||
'libadwaita-1',
|
||||
version: '>= 1.2.alpha',
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,91 +0,0 @@
|
||||
From 1a15a39b5cc4cfa14f3b953c19b03901c923cbc1 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Sat, 9 Sep 2023 17:07:46 -0400
|
||||
Subject: [PATCH 2/9] keyboard: Don't require localed for existing user mode
|
||||
|
||||
If we're in existing user mode, the user may not have
|
||||
permission to set the system keymap.
|
||||
|
||||
This commit makes sure that lack of permission doesn't
|
||||
prevent the keyboard page from completing.
|
||||
---
|
||||
gnome-initial-setup/pages/keyboard/gis-keyboard-page.c | 9 +++++++--
|
||||
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c b/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c
|
||||
index fa41230f..da384495 100644
|
||||
--- a/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c
|
||||
+++ b/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c
|
||||
@@ -388,62 +388,67 @@ preselect_input_source (GisKeyboardPage *self)
|
||||
* - If we got nothing from gnome-desktop and there's no system-wide
|
||||
* keyboard layout set, we don't preselect anything.
|
||||
*
|
||||
* See:
|
||||
* - https://bugzilla.gnome.org/show_bug.cgi?id=776189
|
||||
* - https://gitlab.gnome.org/GNOME/gnome-initial-setup/-/issues/104
|
||||
*/
|
||||
language = cc_common_language_get_current_language ();
|
||||
|
||||
desktop_got_something = gnome_get_input_source_from_locale (language, &type, &id);
|
||||
desktop_got_input_method = (desktop_got_something && g_strcmp0 (type, "xkb") != 0);
|
||||
|
||||
if (desktop_got_something && (desktop_got_input_method || !priv->system_sources)) {
|
||||
cc_input_chooser_set_input (CC_INPUT_CHOOSER (priv->input_chooser),
|
||||
id, type);
|
||||
} else if (priv->system_sources) {
|
||||
cc_input_chooser_set_input (CC_INPUT_CHOOSER (priv->input_chooser),
|
||||
(const gchar *) priv->system_sources->data,
|
||||
"xkb");
|
||||
}
|
||||
|
||||
g_free (language);
|
||||
}
|
||||
|
||||
static void
|
||||
update_page_complete (GisKeyboardPage *self)
|
||||
{
|
||||
GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self);
|
||||
gboolean complete;
|
||||
|
||||
- complete = (priv->localed != NULL &&
|
||||
- cc_input_chooser_get_input_id (CC_INPUT_CHOOSER (priv->input_chooser)) != NULL);
|
||||
+ if (gis_driver_get_mode (GIS_PAGE (self)->driver) == GIS_DRIVER_MODE_NEW_USER) {
|
||||
+ complete = (priv->localed != NULL &&
|
||||
+ cc_input_chooser_get_input_id (CC_INPUT_CHOOSER (priv->input_chooser)) != NULL);
|
||||
+ } else {
|
||||
+ complete = cc_input_chooser_get_input_id (CC_INPUT_CHOOSER (priv->input_chooser)) != NULL;
|
||||
+ }
|
||||
+
|
||||
gis_page_set_complete (GIS_PAGE (self), complete);
|
||||
}
|
||||
|
||||
static void
|
||||
localed_proxy_ready (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer data)
|
||||
{
|
||||
GisKeyboardPage *self = data;
|
||||
GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self);
|
||||
GDBusProxy *proxy;
|
||||
GError *error = NULL;
|
||||
|
||||
proxy = g_dbus_proxy_new_finish (res, &error);
|
||||
|
||||
if (!proxy) {
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Failed to contact localed: %s", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
priv->localed = proxy;
|
||||
|
||||
preselect_input_source (self);
|
||||
update_page_complete (self);
|
||||
}
|
||||
|
||||
static void
|
||||
input_confirmed (CcInputChooser *chooser,
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,295 +0,0 @@
|
||||
From ec880bd018b4ff243baba1d44ac24ff3558b13b5 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Fri, 8 Sep 2023 11:02:39 -0400
|
||||
Subject: [PATCH 3/9] language: Don't proceed until localed has set locale
|
||||
|
||||
In sysmte modes, the keyboard page requires reading the locale from
|
||||
localed, so we need to make sure the setting has been applied before
|
||||
proceeding to the keyboard page from the language page.
|
||||
|
||||
This commit changes the Next button to desensitize if a set locale
|
||||
operation is pending.
|
||||
---
|
||||
.../pages/language/gis-language-page.c | 31 +++++++++++++++++--
|
||||
1 file changed, 28 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/gnome-initial-setup/pages/language/gis-language-page.c b/gnome-initial-setup/pages/language/gis-language-page.c
|
||||
index 87b9f2d8..26a01257 100644
|
||||
--- a/gnome-initial-setup/pages/language/gis-language-page.c
|
||||
+++ b/gnome-initial-setup/pages/language/gis-language-page.c
|
||||
@@ -29,181 +29,204 @@
|
||||
#define GNOME_SYSTEM_LOCALE_DIR "org.gnome.system.locale"
|
||||
#define REGION_KEY "region"
|
||||
|
||||
#include "config.h"
|
||||
#include "language-resources.h"
|
||||
#include "gis-welcome-widget.h"
|
||||
#include "cc-language-chooser.h"
|
||||
#include "gis-language-page.h"
|
||||
|
||||
#include <act/act-user-manager.h>
|
||||
#include <polkit/polkit.h>
|
||||
#include <locale.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
struct _GisLanguagePagePrivate
|
||||
{
|
||||
GtkWidget *logo;
|
||||
GtkWidget *welcome_widget;
|
||||
GtkWidget *language_chooser;
|
||||
|
||||
GDBusProxy *localed;
|
||||
GPermission *permission;
|
||||
const gchar *new_locale_id;
|
||||
|
||||
GCancellable *cancellable;
|
||||
};
|
||||
typedef struct _GisLanguagePagePrivate GisLanguagePagePrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GisLanguagePage, gis_language_page, GIS_TYPE_PAGE);
|
||||
|
||||
+static void
|
||||
+on_locale_set (GDBusProxy *proxy,
|
||||
+ GAsyncResult *result,
|
||||
+ GisLanguagePage *self)
|
||||
+{
|
||||
+ g_autoptr(GError) error = NULL;
|
||||
+ g_autoptr(GVariant) call_result = NULL;
|
||||
+
|
||||
+ call_result = g_dbus_proxy_call_finish (proxy, result, &error);
|
||||
+
|
||||
+ if (error != NULL) {
|
||||
+ g_warning ("Could not set system locale: %s", error->message);
|
||||
+ }
|
||||
+
|
||||
+ gis_page_set_complete (GIS_PAGE (self), TRUE);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
set_localed_locale (GisLanguagePage *self)
|
||||
{
|
||||
GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (self);
|
||||
GVariantBuilder *b;
|
||||
gchar *s;
|
||||
|
||||
b = g_variant_builder_new (G_VARIANT_TYPE ("as"));
|
||||
s = g_strconcat ("LANG=", priv->new_locale_id, NULL);
|
||||
g_variant_builder_add (b, "s", s);
|
||||
g_free (s);
|
||||
|
||||
g_dbus_proxy_call (priv->localed,
|
||||
"SetLocale",
|
||||
g_variant_new ("(asb)", b, TRUE),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
- -1, NULL, NULL, NULL);
|
||||
+ -1, priv->cancellable,
|
||||
+ (GAsyncReadyCallback) on_locale_set,
|
||||
+ self);
|
||||
g_variant_builder_unref (b);
|
||||
}
|
||||
|
||||
static void
|
||||
change_locale_permission_acquired (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer data)
|
||||
{
|
||||
GisLanguagePage *page = GIS_LANGUAGE_PAGE (data);
|
||||
GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page);
|
||||
GError *error = NULL;
|
||||
gboolean allowed;
|
||||
|
||||
allowed = g_permission_acquire_finish (priv->permission, res, &error);
|
||||
if (error) {
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Failed to acquire permission: %s", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (allowed)
|
||||
set_localed_locale (page);
|
||||
}
|
||||
|
||||
static void
|
||||
user_loaded (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
gchar *new_locale_id = user_data;
|
||||
|
||||
act_user_set_language (ACT_USER (object), new_locale_id);
|
||||
|
||||
g_free (new_locale_id);
|
||||
}
|
||||
|
||||
static void
|
||||
language_changed (CcLanguageChooser *chooser,
|
||||
GParamSpec *pspec,
|
||||
GisLanguagePage *page)
|
||||
{
|
||||
GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page);
|
||||
GisDriver *driver;
|
||||
GSettings *region_settings;
|
||||
ActUser *user;
|
||||
|
||||
priv->new_locale_id = cc_language_chooser_get_language (chooser);
|
||||
driver = GIS_PAGE (page)->driver;
|
||||
|
||||
gis_driver_set_user_language (driver, priv->new_locale_id, TRUE);
|
||||
gtk_widget_set_default_direction (gtk_get_locale_direction ());
|
||||
|
||||
if (gis_driver_get_mode (driver) == GIS_DRIVER_MODE_NEW_USER) {
|
||||
+
|
||||
+ gis_page_set_complete (GIS_PAGE (page), FALSE);
|
||||
+
|
||||
if (g_permission_get_allowed (priv->permission)) {
|
||||
set_localed_locale (page);
|
||||
}
|
||||
else if (g_permission_get_can_acquire (priv->permission)) {
|
||||
g_permission_acquire_async (priv->permission,
|
||||
NULL,
|
||||
change_locale_permission_acquired,
|
||||
page);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure we won't override the selected language for format strings */
|
||||
region_settings = g_settings_new (GNOME_SYSTEM_LOCALE_DIR);
|
||||
g_settings_reset (region_settings, REGION_KEY);
|
||||
g_object_unref (region_settings);
|
||||
|
||||
user = act_user_manager_get_user (act_user_manager_get_default (),
|
||||
g_get_user_name ());
|
||||
if (act_user_is_loaded (user))
|
||||
act_user_set_language (user, priv->new_locale_id);
|
||||
else
|
||||
g_signal_connect (user,
|
||||
"notify::is-loaded",
|
||||
G_CALLBACK (user_loaded),
|
||||
g_strdup (priv->new_locale_id));
|
||||
|
||||
gis_welcome_widget_show_locale (GIS_WELCOME_WIDGET (priv->welcome_widget),
|
||||
priv->new_locale_id);
|
||||
}
|
||||
|
||||
static void
|
||||
localed_proxy_ready (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer data)
|
||||
{
|
||||
GisLanguagePage *self = data;
|
||||
GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (self);
|
||||
GDBusProxy *proxy;
|
||||
GError *error = NULL;
|
||||
|
||||
proxy = g_dbus_proxy_new_finish (res, &error);
|
||||
|
||||
if (!proxy) {
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Failed to contact localed: %s", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
priv->localed = proxy;
|
||||
+ gis_page_set_complete (GIS_PAGE (self), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
update_distro_logo (GisLanguagePage *page)
|
||||
{
|
||||
GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page);
|
||||
g_autofree char *id = g_get_os_info (G_OS_INFO_KEY_ID);
|
||||
gsize i;
|
||||
|
||||
static const struct {
|
||||
const char *id;
|
||||
const char *logo;
|
||||
} id_to_logo[] = {
|
||||
{ "debian", "emblem-debian" },
|
||||
{ "fedora", "fedora-logo-icon" },
|
||||
{ "ubuntu", "ubuntu-logo-icon" },
|
||||
{ "openSUSE Tumbleweed", "opensuse-logo-icon" },
|
||||
{ "openSUSE Leap", "opensuse-logo-icon" },
|
||||
{ "SLED", "suse-logo-icon" },
|
||||
{ "SLES", "suse-logo-icon" },
|
||||
};
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (id_to_logo); i++)
|
||||
{
|
||||
if (g_strcmp0 (id, id_to_logo[i].id) == 0)
|
||||
{
|
||||
g_object_set (priv->logo, "icon-name", id_to_logo[i].logo, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -224,62 +247,64 @@ gis_language_page_constructed (GObject *object)
|
||||
GDBusConnection *bus;
|
||||
|
||||
g_type_ensure (CC_TYPE_LANGUAGE_CHOOSER);
|
||||
|
||||
G_OBJECT_CLASS (gis_language_page_parent_class)->constructed (object);
|
||||
|
||||
update_distro_logo (page);
|
||||
|
||||
g_signal_connect (priv->language_chooser, "notify::language",
|
||||
G_CALLBACK (language_changed), page);
|
||||
g_signal_connect (priv->language_chooser, "confirm",
|
||||
G_CALLBACK (language_confirmed), page);
|
||||
|
||||
/* If we're in new user mode then we're manipulating system settings */
|
||||
if (gis_driver_get_mode (GIS_PAGE (page)->driver) == GIS_DRIVER_MODE_NEW_USER)
|
||||
{
|
||||
priv->permission = polkit_permission_new_sync ("org.freedesktop.locale1.set-locale", NULL, NULL, NULL);
|
||||
|
||||
bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL);
|
||||
g_dbus_proxy_new (bus,
|
||||
G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES,
|
||||
NULL,
|
||||
"org.freedesktop.locale1",
|
||||
"/org/freedesktop/locale1",
|
||||
"org.freedesktop.locale1",
|
||||
priv->cancellable,
|
||||
(GAsyncReadyCallback) localed_proxy_ready,
|
||||
object);
|
||||
g_object_unref (bus);
|
||||
}
|
||||
-
|
||||
- gis_page_set_complete (GIS_PAGE (page), TRUE);
|
||||
+ else
|
||||
+ {
|
||||
+ gis_page_set_complete (GIS_PAGE (page), TRUE);
|
||||
+ }
|
||||
gtk_widget_set_visible (GTK_WIDGET (page), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gis_language_page_locale_changed (GisPage *page)
|
||||
{
|
||||
gis_page_set_title (GIS_PAGE (page), _("Welcome"));
|
||||
}
|
||||
|
||||
static void
|
||||
gis_language_page_dispose (GObject *object)
|
||||
{
|
||||
GisLanguagePage *page = GIS_LANGUAGE_PAGE (object);
|
||||
GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page);
|
||||
|
||||
g_clear_object (&priv->permission);
|
||||
g_clear_object (&priv->localed);
|
||||
g_clear_object (&priv->cancellable);
|
||||
|
||||
G_OBJECT_CLASS (gis_language_page_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gis_language_page_class_init (GisLanguagePageClass *klass)
|
||||
{
|
||||
GisPageClass *page_class = GIS_PAGE_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), "/org/gnome/initial-setup/gis-language-page.ui");
|
||||
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,776 +0,0 @@
|
||||
From f34f6580a33b4e5e4073ea1ddf10e7a9b4aa751e Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Thu, 24 Aug 2023 21:19:40 -0400
|
||||
Subject: [PATCH 4/9] keyboard: Get default input sources from gnome-desktop
|
||||
|
||||
Right now, we figure out the default input sources ourselves,
|
||||
based on the current locale and layout information coming from
|
||||
localed.
|
||||
|
||||
This logic needs to be duplicated in several components, so its
|
||||
now provided by gnome-desktop.
|
||||
|
||||
This commit changes it over to use gnome-desktop APIs.
|
||||
|
||||
The same time if leverages a gnome-desktop API to fix a bug
|
||||
where cyrillic layouts were getting added without a latin
|
||||
counterpart.
|
||||
---
|
||||
.../pages/keyboard/gis-keyboard-page.c | 475 +++++++++---------
|
||||
1 file changed, 239 insertions(+), 236 deletions(-)
|
||||
|
||||
diff --git a/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c b/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c
|
||||
index da384495..f2bfe164 100644
|
||||
--- a/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c
|
||||
+++ b/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c
|
||||
@@ -17,508 +17,511 @@
|
||||
* Author: Sergey Udaltsov <svu@gnome.org>
|
||||
* Michael Wood <michael.g.wood@intel.com>
|
||||
*
|
||||
* Based on gnome-control-center cc-region-panel.c
|
||||
*/
|
||||
|
||||
#define PAGE_ID "keyboard"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <locale.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <polkit/polkit.h>
|
||||
|
||||
#define GNOME_DESKTOP_USE_UNSTABLE_API
|
||||
#include <libgnome-desktop/gnome-languages.h>
|
||||
|
||||
#include "gis-keyboard-page.h"
|
||||
#include "keyboard-resources.h"
|
||||
#include "cc-input-chooser.h"
|
||||
|
||||
#include "cc-common-language.h"
|
||||
|
||||
#include "gis-page-header.h"
|
||||
|
||||
#define GNOME_DESKTOP_INPUT_SOURCES_DIR "org.gnome.desktop.input-sources"
|
||||
#define KEY_CURRENT_INPUT_SOURCE "current"
|
||||
#define KEY_INPUT_SOURCES "sources"
|
||||
+#define KEY_MRU_SOURCES "mru-sources"
|
||||
+#define KEY_INPUT_OPTIONS "xkb-options"
|
||||
|
||||
struct _GisKeyboardPagePrivate {
|
||||
GtkWidget *input_chooser;
|
||||
|
||||
GDBusProxy *localed;
|
||||
GCancellable *cancellable;
|
||||
GPermission *permission;
|
||||
GSettings *input_settings;
|
||||
-
|
||||
- GSList *system_sources;
|
||||
+ char **default_input_source_ids;
|
||||
+ char **default_input_source_types;
|
||||
+ char **default_options;
|
||||
+ char **system_layouts;
|
||||
+ char **system_variants;
|
||||
+ char **system_options;
|
||||
+
|
||||
+ gboolean should_skip;
|
||||
};
|
||||
typedef struct _GisKeyboardPagePrivate GisKeyboardPagePrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GisKeyboardPage, gis_keyboard_page, GIS_TYPE_PAGE);
|
||||
|
||||
static void
|
||||
gis_keyboard_page_finalize (GObject *object)
|
||||
{
|
||||
GisKeyboardPage *self = GIS_KEYBOARD_PAGE (object);
|
||||
GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self);
|
||||
|
||||
if (priv->cancellable)
|
||||
g_cancellable_cancel (priv->cancellable);
|
||||
g_clear_object (&priv->cancellable);
|
||||
|
||||
g_clear_object (&priv->permission);
|
||||
g_clear_object (&priv->localed);
|
||||
g_clear_object (&priv->input_settings);
|
||||
-
|
||||
- g_slist_free_full (priv->system_sources, g_free);
|
||||
+ g_clear_pointer (&priv->default_input_source_ids, g_strfreev);
|
||||
+ g_clear_pointer (&priv->default_input_source_types, g_strfreev);
|
||||
+ g_clear_pointer (&priv->default_options, g_strfreev);
|
||||
+ g_clear_pointer (&priv->system_layouts, g_strfreev);
|
||||
+ g_clear_pointer (&priv->system_variants, g_strfreev);
|
||||
+ g_clear_pointer (&priv->system_options, g_strfreev);
|
||||
|
||||
G_OBJECT_CLASS (gis_keyboard_page_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
-set_input_settings (GisKeyboardPage *self)
|
||||
+add_defaults_to_variant_builder (GisKeyboardPage *self,
|
||||
+ const char *already_added_type,
|
||||
+ const char *already_added_id,
|
||||
+ GVariantBuilder *input_source_builder,
|
||||
+ char **default_layout)
|
||||
+
|
||||
{
|
||||
GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self);
|
||||
- const gchar *type;
|
||||
- const gchar *id;
|
||||
- GVariantBuilder builder;
|
||||
- GSList *l;
|
||||
- gboolean is_xkb_source = FALSE;
|
||||
+ size_t i;
|
||||
|
||||
- type = cc_input_chooser_get_input_type (CC_INPUT_CHOOSER (priv->input_chooser));
|
||||
- id = cc_input_chooser_get_input_id (CC_INPUT_CHOOSER (priv->input_chooser));
|
||||
+ for (i = 0; priv->default_input_source_ids && priv->default_input_source_ids[i] != NULL; i++) {
|
||||
+ if (g_strcmp0 (already_added_id, priv->default_input_source_ids[i]) == 0 && g_strcmp0 (already_added_type, priv->default_input_source_types[i]) == 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ss)"));
|
||||
+ g_variant_builder_add (input_source_builder, "(ss)", priv->default_input_source_types[i], priv->default_input_source_ids[i]);
|
||||
|
||||
- if (g_str_equal (type, "xkb")) {
|
||||
- g_variant_builder_add (&builder, "(ss)", type, id);
|
||||
- is_xkb_source = TRUE;
|
||||
+ if (*default_layout != NULL) {
|
||||
+ if (!gnome_input_source_is_non_latin (priv->default_input_source_types[i], priv->default_input_source_ids[i])) {
|
||||
+ *default_layout = g_strdup (priv->default_input_source_ids[i]);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
+}
|
||||
|
||||
- for (l = priv->system_sources; l; l = l->next) {
|
||||
- const gchar *sid = l->data;
|
||||
|
||||
- if (g_str_equal (id, sid) && g_str_equal (type, "xkb"))
|
||||
- continue;
|
||||
+static void
|
||||
+add_input_source_to_arrays (GisKeyboardPage *self,
|
||||
+ const char *type,
|
||||
+ const char *id,
|
||||
+ GPtrArray *layouts_array,
|
||||
+ GPtrArray *variants_array)
|
||||
+{
|
||||
+ g_auto(GStrv) layout_and_variant = NULL;
|
||||
+ const char *layout, *variant;
|
||||
+
|
||||
+ if (!g_str_equal (type, "xkb")) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ layout_and_variant = g_strsplit (id, "+", -1);
|
||||
+
|
||||
+ layout = layout_and_variant[0];
|
||||
+ variant = layout_and_variant[1]?: "";
|
||||
+
|
||||
+ if (g_ptr_array_find_with_equal_func (layouts_array, layout, g_str_equal, NULL) &&
|
||||
+ g_ptr_array_find_with_equal_func (variants_array, variant, g_str_equal, NULL)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ g_ptr_array_add (layouts_array, g_strdup (layout));
|
||||
+ g_ptr_array_add (variants_array, g_strdup (variant));
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+add_defaults_to_arrays (GisKeyboardPage *self,
|
||||
+ GPtrArray *layouts_array,
|
||||
+ GPtrArray *variants_array)
|
||||
+{
|
||||
+ GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self);
|
||||
+ size_t i;
|
||||
+
|
||||
+ for (i = 0; priv->default_input_source_ids && priv->default_input_source_ids[i] != NULL; i++) {
|
||||
+ add_input_source_to_arrays (self, priv->default_input_source_types[i], priv->default_input_source_ids[i], layouts_array, variants_array);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+set_input_settings (GisKeyboardPage *self,
|
||||
+ const char *type,
|
||||
+ const char *id)
|
||||
+{
|
||||
+ GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self);
|
||||
+ g_autofree char *layout = NULL;
|
||||
+ g_autofree char *variant = NULL;
|
||||
+ g_autoptr(GVariant) default_input_sources = NULL;
|
||||
+ g_autoptr(GVariant) input_sources = NULL;
|
||||
+ g_autoptr(GPtrArray) layouts_array = NULL;
|
||||
+ g_autoptr(GPtrArray) variants_array = NULL;
|
||||
+ GVariantBuilder input_source_builder;
|
||||
+ GVariantBuilder input_options_builder;
|
||||
+ g_autoptr(GVariant) input_options = NULL;
|
||||
+ gboolean is_system_mode;
|
||||
+ size_t i;
|
||||
+ g_autofree char *default_input_source_id = NULL;
|
||||
+
|
||||
+ default_input_sources = g_settings_get_default_value (priv->input_settings, KEY_INPUT_SOURCES);
|
||||
+ input_sources = g_settings_get_value (priv->input_settings, KEY_INPUT_SOURCES);
|
||||
+
|
||||
+ if (!g_variant_equal (default_input_sources, input_sources))
|
||||
+ return;
|
||||
+
|
||||
+ g_clear_pointer (&input_sources, g_variant_unref);
|
||||
+
|
||||
+ g_variant_builder_init (&input_options_builder, G_VARIANT_TYPE ("as"));
|
||||
+
|
||||
+ is_system_mode = gis_driver_get_mode (GIS_PAGE (self)->driver) == GIS_DRIVER_MODE_NEW_USER;
|
||||
+
|
||||
+ layouts_array = g_ptr_array_new ();
|
||||
+ variants_array = g_ptr_array_new ();
|
||||
+
|
||||
+ /* Notice the added latin layout (if relevant) gets put first for gsettings
|
||||
+ * (input_source_builder and last for localed (layouts_array/variants_array)
|
||||
+ * This ensures we get a cyrillic layout on ttys, but a latin layout by default
|
||||
+ * in the UI.
|
||||
+ */
|
||||
+ g_variant_builder_init (&input_source_builder, G_VARIANT_TYPE ("a(ss)"));
|
||||
+ if (type != NULL && id != NULL) {
|
||||
+ add_input_source_to_arrays (self, type, id, layouts_array, variants_array);
|
||||
+
|
||||
+ if (gnome_input_source_is_non_latin (type, id)) {
|
||||
+ default_input_source_id = g_strdup ("us");
|
||||
+ add_input_source_to_arrays (self, "xkb", default_input_source_id, layouts_array, variants_array);
|
||||
+ g_variant_builder_add (&input_source_builder, "(ss)", "xkb", default_input_source_id);
|
||||
+ } else {
|
||||
+ default_input_source_id = g_strdup (id);
|
||||
+ }
|
||||
|
||||
- g_variant_builder_add (&builder, "(ss)", "xkb", sid);
|
||||
+ g_variant_builder_add (&input_source_builder, "(ss)", type, id);
|
||||
}
|
||||
|
||||
- if (!is_xkb_source)
|
||||
- g_variant_builder_add (&builder, "(ss)", type, id);
|
||||
+ if (default_input_source_id == NULL || !is_system_mode) {
|
||||
+ add_defaults_to_variant_builder (self, type, id, &input_source_builder, &default_input_source_id);
|
||||
+ }
|
||||
+ input_sources = g_variant_builder_end (&input_source_builder);
|
||||
+
|
||||
+ for (i = 0; priv->default_options[i] != NULL; i++) {
|
||||
+ g_variant_builder_add (&input_options_builder, "s", priv->default_options[i]);
|
||||
+ }
|
||||
+ input_options = g_variant_builder_end (&input_options_builder);
|
||||
+
|
||||
+ add_defaults_to_arrays (self, layouts_array, variants_array);
|
||||
+ g_ptr_array_add (layouts_array, NULL);
|
||||
+ g_ptr_array_add (variants_array, NULL);
|
||||
+
|
||||
+ priv->system_layouts = (char **) g_ptr_array_steal (layouts_array, NULL);
|
||||
+ priv->system_variants = (char **) g_ptr_array_steal (variants_array, NULL);
|
||||
|
||||
- g_settings_set_value (priv->input_settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder));
|
||||
- g_settings_set_uint (priv->input_settings, KEY_CURRENT_INPUT_SOURCE, 0);
|
||||
+ g_variant_get (input_options, "^as", &priv->system_options);
|
||||
+
|
||||
+ g_settings_set_value (priv->input_settings, KEY_INPUT_SOURCES, g_steal_pointer (&input_sources));
|
||||
+ g_settings_set_value (priv->input_settings, KEY_INPUT_OPTIONS, g_steal_pointer (&input_options));
|
||||
+
|
||||
+ if (default_input_source_id != NULL) {
|
||||
+ GVariantBuilder mru_input_source_builder;
|
||||
+
|
||||
+ g_variant_builder_init (&mru_input_source_builder, G_VARIANT_TYPE ("a(ss)"));
|
||||
+ g_variant_builder_add (&mru_input_source_builder, "(ss)", type, default_input_source_id);
|
||||
+ g_settings_set_value (priv->input_settings, KEY_MRU_SOURCES, g_variant_builder_end (&mru_input_source_builder));
|
||||
+ }
|
||||
|
||||
- g_settings_apply (priv->input_settings);
|
||||
+ g_settings_apply (priv->input_settings);
|
||||
}
|
||||
|
||||
static void
|
||||
set_localed_input (GisKeyboardPage *self)
|
||||
{
|
||||
GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self);
|
||||
- const gchar *layout, *variant;
|
||||
- GString *layouts;
|
||||
- GString *variants;
|
||||
- GSList *l;
|
||||
+ g_autofree char *layouts = NULL;
|
||||
+ g_autofree char *variants = NULL;
|
||||
+ g_autofree char *options = NULL;
|
||||
|
||||
if (!priv->localed)
|
||||
return;
|
||||
|
||||
- cc_input_chooser_get_layout (CC_INPUT_CHOOSER (priv->input_chooser), &layout, &variant);
|
||||
- if (layout == NULL)
|
||||
- layout = "";
|
||||
- if (variant == NULL)
|
||||
- variant = "";
|
||||
-
|
||||
- layouts = g_string_new (layout);
|
||||
- variants = g_string_new (variant);
|
||||
-
|
||||
-#define LAYOUT(a) (a[0])
|
||||
-#define VARIANT(a) (a[1] ? a[1] : "")
|
||||
- for (l = priv->system_sources; l; l = l->next) {
|
||||
- const gchar *sid = l->data;
|
||||
- gchar **lv = g_strsplit (sid, "+", -1);
|
||||
-
|
||||
- if (!g_str_equal (LAYOUT (lv), layout) ||
|
||||
- !g_str_equal (VARIANT (lv), variant)) {
|
||||
- if (layouts->str[0]) {
|
||||
- g_string_append_c (layouts, ',');
|
||||
- g_string_append_c (variants, ',');
|
||||
- }
|
||||
- g_string_append (layouts, LAYOUT (lv));
|
||||
- g_string_append (variants, VARIANT (lv));
|
||||
- }
|
||||
- g_strfreev (lv);
|
||||
- }
|
||||
-#undef LAYOUT
|
||||
-#undef VARIANT
|
||||
+ layouts = g_strjoinv (",", priv->system_layouts);
|
||||
+ variants = g_strjoinv (",", priv->system_variants);
|
||||
+ options = g_strjoinv (",", priv->system_options);
|
||||
|
||||
g_dbus_proxy_call (priv->localed,
|
||||
"SetX11Keyboard",
|
||||
- g_variant_new ("(ssssbb)", layouts->str, "", variants->str, "", TRUE, TRUE),
|
||||
+ g_variant_new ("(ssssbb)", layouts, "", variants, options, TRUE, TRUE),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1, NULL, NULL, NULL);
|
||||
- g_string_free (layouts, TRUE);
|
||||
- g_string_free (variants, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
change_locale_permission_acquired (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer data)
|
||||
{
|
||||
GisKeyboardPage *page = GIS_KEYBOARD_PAGE (data);
|
||||
GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (page);
|
||||
GError *error = NULL;
|
||||
gboolean allowed;
|
||||
|
||||
allowed = g_permission_acquire_finish (priv->permission, res, &error);
|
||||
if (error) {
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Failed to acquire permission: %s", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (allowed)
|
||||
set_localed_input (GIS_KEYBOARD_PAGE (data));
|
||||
}
|
||||
|
||||
static void
|
||||
update_input (GisKeyboardPage *self)
|
||||
{
|
||||
GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self);
|
||||
+ const gchar *type;
|
||||
+ const gchar *id;
|
||||
|
||||
- set_input_settings (self);
|
||||
+ type = cc_input_chooser_get_input_type (CC_INPUT_CHOOSER (priv->input_chooser));
|
||||
+ id = cc_input_chooser_get_input_id (CC_INPUT_CHOOSER (priv->input_chooser));
|
||||
+
|
||||
+ set_input_settings (self, type, id);
|
||||
|
||||
if (gis_driver_get_mode (GIS_PAGE (self)->driver) == GIS_DRIVER_MODE_NEW_USER) {
|
||||
if (g_permission_get_allowed (priv->permission)) {
|
||||
set_localed_input (self);
|
||||
} else if (g_permission_get_can_acquire (priv->permission)) {
|
||||
g_permission_acquire_async (priv->permission,
|
||||
NULL,
|
||||
change_locale_permission_acquired,
|
||||
self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gis_keyboard_page_apply (GisPage *page,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
update_input (GIS_KEYBOARD_PAGE (page));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
-static GSList *
|
||||
-get_localed_input (GDBusProxy *proxy)
|
||||
-{
|
||||
- GVariant *v;
|
||||
- const gchar *s;
|
||||
- gchar *id;
|
||||
- guint i, n;
|
||||
- gchar **layouts = NULL;
|
||||
- gchar **variants = NULL;
|
||||
- GSList *sources = NULL;
|
||||
-
|
||||
- v = g_dbus_proxy_get_cached_property (proxy, "X11Layout");
|
||||
- if (v) {
|
||||
- s = g_variant_get_string (v, NULL);
|
||||
- layouts = g_strsplit (s, ",", -1);
|
||||
- g_variant_unref (v);
|
||||
- }
|
||||
-
|
||||
- v = g_dbus_proxy_get_cached_property (proxy, "X11Variant");
|
||||
- if (v) {
|
||||
- s = g_variant_get_string (v, NULL);
|
||||
- if (s && *s)
|
||||
- variants = g_strsplit (s, ",", -1);
|
||||
- g_variant_unref (v);
|
||||
- }
|
||||
-
|
||||
- if (variants && variants[0])
|
||||
- n = MIN (g_strv_length (layouts), g_strv_length (variants));
|
||||
- else if (layouts && layouts[0])
|
||||
- n = g_strv_length (layouts);
|
||||
- else
|
||||
- n = 0;
|
||||
-
|
||||
- for (i = 0; i < n && layouts[i][0]; i++) {
|
||||
- if (variants && variants[i] && variants[i][0])
|
||||
- id = g_strdup_printf ("%s+%s", layouts[i], variants[i]);
|
||||
- else
|
||||
- id = g_strdup (layouts[i]);
|
||||
- sources = g_slist_prepend (sources, id);
|
||||
- }
|
||||
-
|
||||
- g_strfreev (variants);
|
||||
- g_strfreev (layouts);
|
||||
-
|
||||
- return sources;
|
||||
-}
|
||||
-
|
||||
static void
|
||||
-add_default_keyboard_layout (GDBusProxy *proxy,
|
||||
- GVariantBuilder *builder)
|
||||
+add_default_input_sources (GisKeyboardPage *self)
|
||||
{
|
||||
- GSList *sources = get_localed_input (proxy);
|
||||
- sources = g_slist_reverse (sources);
|
||||
-
|
||||
- for (; sources; sources = sources->next)
|
||||
- g_variant_builder_add (builder, "(ss)", "xkb",
|
||||
- (const gchar *) sources->data);
|
||||
-
|
||||
- g_slist_free_full (sources, g_free);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-add_default_input_sources (GisKeyboardPage *self,
|
||||
- GDBusProxy *proxy)
|
||||
-{
|
||||
- const gchar *type;
|
||||
- const gchar *id;
|
||||
- gchar *language;
|
||||
- GVariantBuilder builder;
|
||||
- GSettings *input_settings;
|
||||
-
|
||||
- input_settings = g_settings_new (GNOME_DESKTOP_INPUT_SOURCES_DIR);
|
||||
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ss)"));
|
||||
-
|
||||
- add_default_keyboard_layout (proxy, &builder);
|
||||
-
|
||||
- /* add other input sources */
|
||||
- language = cc_common_language_get_current_language ();
|
||||
- if (gnome_get_input_source_from_locale (language, &type, &id)) {
|
||||
- if (!g_str_equal (type, "xkb"))
|
||||
- g_variant_builder_add (&builder, "(ss)", type, id);
|
||||
- }
|
||||
- g_free (language);
|
||||
-
|
||||
- g_settings_delay (input_settings);
|
||||
- g_settings_set_value (input_settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder));
|
||||
- g_settings_set_uint (input_settings, KEY_CURRENT_INPUT_SOURCE, 0);
|
||||
- g_settings_apply (input_settings);
|
||||
-
|
||||
- g_object_unref (input_settings);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-skip_proxy_ready (GObject *source,
|
||||
- GAsyncResult *res,
|
||||
- gpointer data)
|
||||
-{
|
||||
- GisKeyboardPage *self = data;
|
||||
- GDBusProxy *proxy;
|
||||
- GError *error = NULL;
|
||||
-
|
||||
- proxy = g_dbus_proxy_new_finish (res, &error);
|
||||
-
|
||||
- if (!proxy) {
|
||||
- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
- g_warning ("Failed to contact localed: %s", error->message);
|
||||
- g_error_free (error);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- add_default_input_sources (self, proxy);
|
||||
-
|
||||
- g_object_unref (proxy);
|
||||
+ set_input_settings (self, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gis_keyboard_page_skip (GisPage *page)
|
||||
{
|
||||
GisKeyboardPage *self = GIS_KEYBOARD_PAGE (page);
|
||||
GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self);
|
||||
|
||||
- g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
|
||||
- G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES,
|
||||
- NULL,
|
||||
- "org.freedesktop.locale1",
|
||||
- "/org/freedesktop/locale1",
|
||||
- "org.freedesktop.locale1",
|
||||
- priv->cancellable,
|
||||
- (GAsyncReadyCallback) skip_proxy_ready,
|
||||
- self);
|
||||
+ priv->should_skip = TRUE;
|
||||
+
|
||||
+ if (priv->default_input_source_ids != NULL)
|
||||
+ add_default_input_sources (self);
|
||||
}
|
||||
|
||||
static void
|
||||
preselect_input_source (GisKeyboardPage *self)
|
||||
{
|
||||
- const gchar *type;
|
||||
- const gchar *id;
|
||||
- gchar *language;
|
||||
- gboolean desktop_got_something;
|
||||
- gboolean desktop_got_input_method;
|
||||
+ const char *language = NULL;
|
||||
|
||||
GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self);
|
||||
- GSList *sources = get_localed_input (priv->localed);
|
||||
-
|
||||
- /* These will be added silently after the user selection when
|
||||
- * writing out the settings. */
|
||||
- g_slist_free_full (priv->system_sources, g_free);
|
||||
- priv->system_sources = g_slist_reverse (sources);
|
||||
-
|
||||
- /* We have two potential sources of information as to which
|
||||
- * source to pre-select here: the keyboard layout that is
|
||||
- * configured system-wide (read from priv->system_sources),
|
||||
- * and a gnome-desktop function that lets us look up a default
|
||||
- * input source for a given language.
|
||||
- *
|
||||
- * An important limitation here is that there is no system-wide
|
||||
- * configuration for input methods, so if the best choice for the
|
||||
- * language is an input method, we will only find it from the
|
||||
- * gnome-desktop lookup. But if both sources give us keyboard layouts,
|
||||
- * we want to prefer the one that's configured system-wide over the one
|
||||
- * from gnome-desktop.
|
||||
- *
|
||||
- * So we first do the gnome-desktop lookup, and keep track of what we
|
||||
- * got.
|
||||
- *
|
||||
- * - If we got an input method, we preselect that, and we're done.
|
||||
- * - If we got a keyboard layout, and there's no system-wide keyboard
|
||||
- * layout set, we preselect the layout we got from gnome-desktop.
|
||||
- * - If we didn't get an input method from gnome-desktop and there
|
||||
- * is a system-wide keyboard layout set, we preselect that.
|
||||
- * - If we got nothing from gnome-desktop and there's no system-wide
|
||||
- * keyboard layout set, we don't preselect anything.
|
||||
- *
|
||||
- * See:
|
||||
- * - https://bugzilla.gnome.org/show_bug.cgi?id=776189
|
||||
- * - https://gitlab.gnome.org/GNOME/gnome-initial-setup/-/issues/104
|
||||
- */
|
||||
- language = cc_common_language_get_current_language ();
|
||||
|
||||
- desktop_got_something = gnome_get_input_source_from_locale (language, &type, &id);
|
||||
- desktop_got_input_method = (desktop_got_something && g_strcmp0 (type, "xkb") != 0);
|
||||
+ language = cc_common_language_get_current_language ();
|
||||
|
||||
- if (desktop_got_something && (desktop_got_input_method || !priv->system_sources)) {
|
||||
- cc_input_chooser_set_input (CC_INPUT_CHOOSER (priv->input_chooser),
|
||||
- id, type);
|
||||
- } else if (priv->system_sources) {
|
||||
- cc_input_chooser_set_input (CC_INPUT_CHOOSER (priv->input_chooser),
|
||||
- (const gchar *) priv->system_sources->data,
|
||||
- "xkb");
|
||||
+ /* We deduce the initial input source from language if we're in a system mode
|
||||
+ * (where preexisting system configuration may be stale) or if the language
|
||||
+ * requires an input method (because there is no way for system configuration
|
||||
+ * to denote the need for an input method)
|
||||
+ *
|
||||
+ * If it's a non-system mode we can trust the system configuration is probably
|
||||
+ * a better bet than a heuristic based on locale.
|
||||
+ */
|
||||
+ if (language != NULL) {
|
||||
+ gboolean got_input_source;
|
||||
+ const char *id, *type;
|
||||
+
|
||||
+ got_input_source = gnome_get_input_source_from_locale (language, &type, &id);
|
||||
+
|
||||
+ if (got_input_source) {
|
||||
+ gboolean is_system_mode = gis_driver_get_mode (GIS_PAGE (self)->driver) == GIS_DRIVER_MODE_NEW_USER;
|
||||
+ if (is_system_mode || g_str_equal (type, "ibus")) {
|
||||
+ cc_input_chooser_set_input (CC_INPUT_CHOOSER (priv->input_chooser),
|
||||
+ id,
|
||||
+ type);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
- g_free (language);
|
||||
+ cc_input_chooser_set_input (CC_INPUT_CHOOSER (priv->input_chooser),
|
||||
+ priv->default_input_source_ids[0],
|
||||
+ priv->default_input_source_types[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
update_page_complete (GisKeyboardPage *self)
|
||||
{
|
||||
GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self);
|
||||
gboolean complete;
|
||||
|
||||
if (gis_driver_get_mode (GIS_PAGE (self)->driver) == GIS_DRIVER_MODE_NEW_USER) {
|
||||
complete = (priv->localed != NULL &&
|
||||
cc_input_chooser_get_input_id (CC_INPUT_CHOOSER (priv->input_chooser)) != NULL);
|
||||
} else {
|
||||
complete = cc_input_chooser_get_input_id (CC_INPUT_CHOOSER (priv->input_chooser)) != NULL;
|
||||
}
|
||||
|
||||
gis_page_set_complete (GIS_PAGE (self), complete);
|
||||
}
|
||||
|
||||
static void
|
||||
localed_proxy_ready (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer data)
|
||||
{
|
||||
GisKeyboardPage *self = data;
|
||||
GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self);
|
||||
GDBusProxy *proxy;
|
||||
GError *error = NULL;
|
||||
|
||||
proxy = g_dbus_proxy_new_finish (res, &error);
|
||||
|
||||
if (!proxy) {
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Failed to contact localed: %s", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
priv->localed = proxy;
|
||||
-
|
||||
- preselect_input_source (self);
|
||||
- update_page_complete (self);
|
||||
+ update_page_complete (self);
|
||||
}
|
||||
|
||||
static void
|
||||
input_confirmed (CcInputChooser *chooser,
|
||||
GisKeyboardPage *self)
|
||||
{
|
||||
gis_assistant_next_page (gis_driver_get_assistant (GIS_PAGE (self)->driver));
|
||||
}
|
||||
|
||||
static void
|
||||
input_changed (CcInputChooser *chooser,
|
||||
GisKeyboardPage *self)
|
||||
{
|
||||
update_page_complete (self);
|
||||
}
|
||||
|
||||
+static void
|
||||
+on_got_default_sources (GObject *source,
|
||||
+ GAsyncResult *res,
|
||||
+ gpointer data)
|
||||
+{
|
||||
+ GisKeyboardPage *self = data;
|
||||
+ GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self);
|
||||
+ g_autoptr (GError) error = NULL;
|
||||
+ gboolean success = FALSE;
|
||||
+ g_auto (GStrv) ids = NULL;
|
||||
+ g_auto (GStrv) types = NULL;
|
||||
+ g_auto (GStrv) options = NULL;
|
||||
+
|
||||
+ success = gnome_get_default_input_sources_finish (res, &ids, &types, &options, &error);
|
||||
+
|
||||
+ if (!success) {
|
||||
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
+ g_warning ("Failed to fetch default input sources: %s", error->message);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ priv->default_input_source_ids = g_steal_pointer (&ids);
|
||||
+ priv->default_input_source_types = g_steal_pointer (&types);
|
||||
+ priv->default_options = g_steal_pointer (&options);
|
||||
+
|
||||
+ if (priv->should_skip) {
|
||||
+ add_default_input_sources (self);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ preselect_input_source (self);
|
||||
+ update_page_complete (self);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
gis_keyboard_page_constructed (GObject *object)
|
||||
{
|
||||
GisKeyboardPage *self = GIS_KEYBOARD_PAGE (object);
|
||||
GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self);
|
||||
|
||||
G_OBJECT_CLASS (gis_keyboard_page_parent_class)->constructed (object);
|
||||
|
||||
g_signal_connect (priv->input_chooser, "confirm",
|
||||
G_CALLBACK (input_confirmed), self);
|
||||
g_signal_connect (priv->input_chooser, "changed",
|
||||
G_CALLBACK (input_changed), self);
|
||||
|
||||
priv->input_settings = g_settings_new (GNOME_DESKTOP_INPUT_SOURCES_DIR);
|
||||
g_settings_delay (priv->input_settings);
|
||||
|
||||
priv->cancellable = g_cancellable_new ();
|
||||
|
||||
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES,
|
||||
NULL,
|
||||
"org.freedesktop.locale1",
|
||||
"/org/freedesktop/locale1",
|
||||
"org.freedesktop.locale1",
|
||||
priv->cancellable,
|
||||
(GAsyncReadyCallback) localed_proxy_ready,
|
||||
self);
|
||||
|
||||
+ gnome_get_default_input_sources (priv->cancellable, on_got_default_sources, self);
|
||||
+
|
||||
/* If we're in new user mode then we're manipulating system settings */
|
||||
if (gis_driver_get_mode (GIS_PAGE (self)->driver) == GIS_DRIVER_MODE_NEW_USER)
|
||||
priv->permission = polkit_permission_new_sync ("org.freedesktop.locale1.set-keyboard", NULL, NULL, NULL);
|
||||
|
||||
update_page_complete (self);
|
||||
|
||||
gtk_widget_set_visible (GTK_WIDGET (self), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gis_keyboard_page_locale_changed (GisPage *page)
|
||||
{
|
||||
gis_page_set_title (GIS_PAGE (page), _("Typing"));
|
||||
}
|
||||
|
||||
static void
|
||||
gis_keyboard_page_class_init (GisKeyboardPageClass * klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GisPageClass * page_class = GIS_PAGE_CLASS (klass);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), "/org/gnome/initial-setup/gis-keyboard-page.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisKeyboardPage, input_chooser);
|
||||
|
||||
page_class->page_id = PAGE_ID;
|
||||
page_class->apply = gis_keyboard_page_apply;
|
||||
page_class->skip = gis_keyboard_page_skip;
|
||||
page_class->locale_changed = gis_keyboard_page_locale_changed;
|
||||
object_class->constructed = gis_keyboard_page_constructed;
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,633 +0,0 @@
|
||||
From 07f191dbc961b793fe9761f577d94f5f10502380 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Sun, 13 Aug 2023 09:09:56 -0400
|
||||
Subject: [PATCH 5/9] driver: Specify mode via flags instead of boolean
|
||||
|
||||
At the moment we just have system mode and new user mode,
|
||||
but we're actually going to want other modes (such as
|
||||
live user mode) as well.
|
||||
|
||||
Currently the code distinguishes between its two available
|
||||
modes using a boolean `is_new_user`. That isn't extensible beyond
|
||||
two modes, so this commit changes it use bit flags instead.
|
||||
---
|
||||
gnome-initial-setup/gis-driver.c | 17 ++-
|
||||
gnome-initial-setup/gis-driver.h | 8 +-
|
||||
gnome-initial-setup/gnome-initial-setup.c | 128 +++++++++++++---------
|
||||
3 files changed, 93 insertions(+), 60 deletions(-)
|
||||
|
||||
diff --git a/gnome-initial-setup/gis-driver.c b/gnome-initial-setup/gis-driver.c
|
||||
index 98b4fc3e..d3013063 100644
|
||||
--- a/gnome-initial-setup/gis-driver.c
|
||||
+++ b/gnome-initial-setup/gis-driver.c
|
||||
@@ -9,75 +9,74 @@
|
||||
*
|
||||
* 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:
|
||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gnome-initial-setup.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_WEBKITGTK_6_0
|
||||
#include <webkit/webkit.h>
|
||||
#else
|
||||
#include <webkit2/webkit2.h>
|
||||
#endif
|
||||
|
||||
#include "cc-common-language.h"
|
||||
#include "gis-assistant.h"
|
||||
|
||||
-#define GIS_TYPE_DRIVER_MODE (gis_driver_mode_get_type ())
|
||||
-
|
||||
/* Statically include this for now. Maybe later
|
||||
* we'll generate this from glib-mkenums. */
|
||||
GType
|
||||
gis_driver_mode_get_type (void) {
|
||||
static GType enum_type_id = 0;
|
||||
if (G_UNLIKELY (!enum_type_id))
|
||||
{
|
||||
- static const GEnumValue values[] = {
|
||||
+ static const GFlagsValue values[] = {
|
||||
{ GIS_DRIVER_MODE_NEW_USER, "GIS_DRIVER_MODE_NEW_USER", "new_user" },
|
||||
{ GIS_DRIVER_MODE_EXISTING_USER, "GIS_DRIVER_MODE_EXISTING_USER", "existing_user" },
|
||||
+ { GIS_DRIVER_MODE_ALL, "GIS_DRIVER_MODE_ALL", "all" },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
- enum_type_id = g_enum_register_static("GisDriverMode", values);
|
||||
+ enum_type_id = g_flags_register_static("GisDriverMode", values);
|
||||
}
|
||||
return enum_type_id;
|
||||
}
|
||||
|
||||
enum {
|
||||
REBUILD_PAGES,
|
||||
LOCALE_CHANGED,
|
||||
LAST_SIGNAL,
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
typedef enum {
|
||||
PROP_MODE = 1,
|
||||
PROP_USERNAME,
|
||||
PROP_SMALL_SCREEN,
|
||||
PROP_PARENTAL_CONTROLS_ENABLED,
|
||||
PROP_FULL_NAME,
|
||||
PROP_AVATAR,
|
||||
} GisDriverProperty;
|
||||
|
||||
static GParamSpec *obj_props[PROP_AVATAR + 1];
|
||||
|
||||
struct _GisDriver {
|
||||
AdwApplication parent_instance;
|
||||
|
||||
GtkWindow *main_window;
|
||||
GisAssistant *assistant;
|
||||
|
||||
GdmClient *client;
|
||||
@@ -624,61 +623,61 @@ gis_driver_get_property (GObject *object,
|
||||
break;
|
||||
case PROP_SMALL_SCREEN:
|
||||
g_value_set_boolean (value, driver->small_screen);
|
||||
break;
|
||||
case PROP_PARENTAL_CONTROLS_ENABLED:
|
||||
g_value_set_boolean (value, driver->parental_controls_enabled);
|
||||
break;
|
||||
case PROP_FULL_NAME:
|
||||
g_value_set_string (value, driver->full_name);
|
||||
break;
|
||||
case PROP_AVATAR:
|
||||
g_value_set_object (value, driver->avatar);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gis_driver_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GisDriver *driver = GIS_DRIVER (object);
|
||||
|
||||
switch ((GisDriverProperty) prop_id)
|
||||
{
|
||||
case PROP_MODE:
|
||||
- driver->mode = g_value_get_enum (value);
|
||||
+ driver->mode = g_value_get_flags (value);
|
||||
break;
|
||||
case PROP_USERNAME:
|
||||
g_free (driver->username);
|
||||
driver->username = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_PARENTAL_CONTROLS_ENABLED:
|
||||
gis_driver_set_parental_controls_enabled (driver, g_value_get_boolean (value));
|
||||
break;
|
||||
case PROP_FULL_NAME:
|
||||
gis_driver_set_full_name (driver, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_AVATAR:
|
||||
gis_driver_set_avatar (driver, g_value_get_object (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gis_driver_activate (GApplication *app)
|
||||
{
|
||||
GisDriver *driver = GIS_DRIVER (app);
|
||||
|
||||
G_APPLICATION_CLASS (gis_driver_parent_class)->activate (app);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (driver->main_window));
|
||||
}
|
||||
|
||||
@@ -826,64 +825,64 @@ gis_driver_init (GisDriver *driver)
|
||||
static void
|
||||
gis_driver_class_init (GisDriverClass *klass)
|
||||
{
|
||||
GApplicationClass *application_class = G_APPLICATION_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->get_property = gis_driver_get_property;
|
||||
gobject_class->set_property = gis_driver_set_property;
|
||||
gobject_class->dispose = gis_driver_dispose;
|
||||
gobject_class->finalize = gis_driver_finalize;
|
||||
application_class->startup = gis_driver_startup;
|
||||
application_class->activate = gis_driver_activate;
|
||||
|
||||
signals[REBUILD_PAGES] =
|
||||
g_signal_new ("rebuild-pages",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
signals[LOCALE_CHANGED] =
|
||||
g_signal_new ("locale-changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
obj_props[PROP_MODE] =
|
||||
- g_param_spec_enum ("mode", "", "",
|
||||
- GIS_TYPE_DRIVER_MODE,
|
||||
- GIS_DRIVER_MODE_EXISTING_USER,
|
||||
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
||||
+ g_param_spec_flags ("mode", "", "",
|
||||
+ GIS_TYPE_DRIVER_MODE,
|
||||
+ GIS_DRIVER_MODE_EXISTING_USER,
|
||||
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
obj_props[PROP_USERNAME] =
|
||||
g_param_spec_string ("username", "", "",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
obj_props[PROP_SMALL_SCREEN] =
|
||||
g_param_spec_boolean ("small-screen", "", "",
|
||||
FALSE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GisDriver:parental-controls-enabled:
|
||||
*
|
||||
* Whether parental controls are enabled for the main user. If this is %TRUE,
|
||||
* two user accounts will be created when this page is saved: one for the main
|
||||
* user (a child) which will be a standard account; and one for the parent
|
||||
* which will be an administrative account.
|
||||
*
|
||||
* Since: 3.36
|
||||
*/
|
||||
obj_props[PROP_PARENTAL_CONTROLS_ENABLED] =
|
||||
g_param_spec_boolean ("parental-controls-enabled",
|
||||
"Parental Controls Enabled",
|
||||
"Whether parental controls are enabled for the main user.",
|
||||
FALSE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GisDriver:full-name: (nullable)
|
||||
diff --git a/gnome-initial-setup/gis-driver.h b/gnome-initial-setup/gis-driver.h
|
||||
index 9b935e24..b57db2e2 100644
|
||||
--- a/gnome-initial-setup/gis-driver.h
|
||||
+++ b/gnome-initial-setup/gis-driver.h
|
||||
@@ -4,74 +4,78 @@
|
||||
*
|
||||
* 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:
|
||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||
*/
|
||||
|
||||
#ifndef __GIS_DRIVER_H__
|
||||
#define __GIS_DRIVER_H__
|
||||
|
||||
#include "gis-assistant.h"
|
||||
#include "gis-page.h"
|
||||
#include <act/act-user-manager.h>
|
||||
#include <gdm/gdm-client.h>
|
||||
#include <adwaita.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GIS_TYPE_DRIVER (gis_driver_get_type ())
|
||||
+#define GIS_TYPE_DRIVER_MODE (gis_driver_mode_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GisDriver, gis_driver, GIS, DRIVER, AdwApplication)
|
||||
|
||||
typedef enum {
|
||||
UM_LOCAL,
|
||||
UM_ENTERPRISE,
|
||||
NUM_MODES,
|
||||
} UmAccountMode;
|
||||
|
||||
typedef enum {
|
||||
- GIS_DRIVER_MODE_NEW_USER,
|
||||
- GIS_DRIVER_MODE_EXISTING_USER,
|
||||
+ GIS_DRIVER_MODE_NEW_USER = 1 << 0,
|
||||
+ GIS_DRIVER_MODE_EXISTING_USER = 1 << 1,
|
||||
+ GIS_DRIVER_MODE_ALL = (GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
||||
} GisDriverMode;
|
||||
|
||||
+GType gis_driver_mode_get_type (void);
|
||||
+
|
||||
GisAssistant *gis_driver_get_assistant (GisDriver *driver);
|
||||
|
||||
void gis_driver_set_user_permissions (GisDriver *driver,
|
||||
ActUser *user,
|
||||
const gchar *password);
|
||||
|
||||
void gis_driver_get_user_permissions (GisDriver *driver,
|
||||
ActUser **user,
|
||||
const gchar **password);
|
||||
|
||||
void gis_driver_set_parent_permissions (GisDriver *driver,
|
||||
ActUser *parent,
|
||||
const gchar *password);
|
||||
|
||||
void gis_driver_get_parent_permissions (GisDriver *driver,
|
||||
ActUser **parent,
|
||||
const gchar **password);
|
||||
|
||||
void gis_driver_set_account_mode (GisDriver *driver,
|
||||
UmAccountMode mode);
|
||||
|
||||
UmAccountMode gis_driver_get_account_mode (GisDriver *driver);
|
||||
|
||||
void gis_driver_set_parental_controls_enabled (GisDriver *driver,
|
||||
gboolean parental_controls_enabled);
|
||||
|
||||
gboolean gis_driver_get_parental_controls_enabled (GisDriver *driver);
|
||||
|
||||
void gis_driver_set_user_language (GisDriver *driver,
|
||||
const gchar *lang_id,
|
||||
diff --git a/gnome-initial-setup/gnome-initial-setup.c b/gnome-initial-setup/gnome-initial-setup.c
|
||||
index 113ded36..59955779 100644
|
||||
--- a/gnome-initial-setup/gnome-initial-setup.c
|
||||
+++ b/gnome-initial-setup/gnome-initial-setup.c
|
||||
@@ -29,228 +29,258 @@
|
||||
#include <stdlib.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "pages/welcome/gis-welcome-page.h"
|
||||
#include "pages/language/gis-language-page.h"
|
||||
#include "pages/keyboard/gis-keyboard-page.h"
|
||||
#include "pages/network/gis-network-page.h"
|
||||
#include "pages/timezone/gis-timezone-page.h"
|
||||
#include "pages/privacy/gis-privacy-page.h"
|
||||
#include "pages/software/gis-software-page.h"
|
||||
#include "pages/goa/gis-goa-page.h"
|
||||
#include "pages/account/gis-account-pages.h"
|
||||
#include "pages/parental-controls/gis-parental-controls-page.h"
|
||||
#include "pages/password/gis-password-page.h"
|
||||
#include "pages/summary/gis-summary-page.h"
|
||||
|
||||
#define VENDOR_PAGES_GROUP "pages"
|
||||
#define VENDOR_SKIP_KEY "skip"
|
||||
#define VENDOR_NEW_USER_ONLY_KEY "new_user_only"
|
||||
#define VENDOR_EXISTING_USER_ONLY_KEY "existing_user_only"
|
||||
|
||||
static gboolean force_existing_user_mode;
|
||||
|
||||
static GPtrArray *skipped_pages;
|
||||
|
||||
typedef GisPage *(*PreparePage) (GisDriver *driver);
|
||||
|
||||
typedef struct {
|
||||
const gchar *page_id;
|
||||
PreparePage prepare_page_func;
|
||||
- gboolean new_user_only;
|
||||
+ GisDriverMode modes;
|
||||
} PageData;
|
||||
|
||||
-#define PAGE(name, new_user_only) { #name, gis_prepare_ ## name ## _page, new_user_only }
|
||||
+#define PAGE(name, modes) { #name, gis_prepare_ ## name ## _page, modes }
|
||||
|
||||
static PageData page_table[] = {
|
||||
- PAGE (welcome, FALSE),
|
||||
- PAGE (language, FALSE),
|
||||
- PAGE (keyboard, FALSE),
|
||||
- PAGE (network, FALSE),
|
||||
- PAGE (privacy, FALSE),
|
||||
- PAGE (timezone, TRUE),
|
||||
- PAGE (software, TRUE),
|
||||
- PAGE (goa, FALSE),
|
||||
- PAGE (account, TRUE),
|
||||
- PAGE (password, TRUE),
|
||||
+ PAGE (welcome, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
||||
+ PAGE (language, GIS_DRIVER_MODE_ALL),
|
||||
+ PAGE (keyboard, GIS_DRIVER_MODE_ALL),
|
||||
+ PAGE (network, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
||||
+ PAGE (privacy, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
||||
+ PAGE (timezone, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
||||
+ PAGE (software, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
||||
+ PAGE (goa, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
||||
+ PAGE (account, GIS_DRIVER_MODE_NEW_USER),
|
||||
+ PAGE (password, GIS_DRIVER_MODE_NEW_USER),
|
||||
#ifdef HAVE_PARENTAL_CONTROLS
|
||||
- PAGE (parental_controls, TRUE),
|
||||
- PAGE (parent_password, TRUE),
|
||||
+ PAGE (parental_controls, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
||||
+ PAGE (parent_password, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
||||
#endif
|
||||
- PAGE (summary, FALSE),
|
||||
+ PAGE (summary, GIS_DRIVER_MODE_NEW_USER),
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
#undef PAGE
|
||||
|
||||
static gboolean
|
||||
should_skip_page (const gchar *page_id,
|
||||
gchar **skip_pages)
|
||||
{
|
||||
guint i = 0;
|
||||
|
||||
/* special case welcome. We only want to show it if language
|
||||
* is skipped
|
||||
*/
|
||||
if (strcmp (page_id, "welcome") == 0)
|
||||
return !should_skip_page ("language", skip_pages);
|
||||
|
||||
/* check through our skip pages list for pages we don't want */
|
||||
if (skip_pages) {
|
||||
while (skip_pages[i]) {
|
||||
if (g_strcmp0 (skip_pages[i], page_id) == 0)
|
||||
return TRUE;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gchar **
|
||||
-strv_append (gchar **a,
|
||||
- gchar **b)
|
||||
+pages_to_skip_from_file (GisDriver *driver)
|
||||
{
|
||||
- guint n = g_strv_length (a);
|
||||
- guint m = g_strv_length (b);
|
||||
-
|
||||
- a = g_renew (gchar *, a, n + m + 1);
|
||||
- for (guint i = 0; i < m; i++)
|
||||
- a[n + i] = g_strdup (b[i]);
|
||||
- a[n + m] = NULL;
|
||||
-
|
||||
- return a;
|
||||
-}
|
||||
-
|
||||
-static gchar **
|
||||
-pages_to_skip_from_file (GisDriver *driver,
|
||||
- gboolean is_new_user)
|
||||
-{
|
||||
- GStrv skip_pages = NULL;
|
||||
- GStrv additional_skip_pages = NULL;
|
||||
+ GisDriverMode driver_mode;
|
||||
+ GisDriverMode other_modes;
|
||||
+ g_autoptr(GStrvBuilder) builder = g_strv_builder_new();
|
||||
+ g_auto (GStrv) skip_pages = NULL;
|
||||
+ g_autofree char *mode_group = NULL;
|
||||
+ g_autoptr (GFlagsClass) driver_mode_flags_class = NULL;
|
||||
+ const GFlagsValue *driver_mode_flags = NULL;
|
||||
|
||||
/* This code will read the keyfile containing vendor customization options and
|
||||
* look for options under the "pages" group, and supports the following keys:
|
||||
* - skip (optional): list of pages to be skipped always
|
||||
* - new_user_only (optional): list of pages to be skipped in existing user mode
|
||||
* - existing_user_only (optional): list of pages to be skipped in new user mode
|
||||
*
|
||||
+ * In addition it will look for options under the "{mode} pages" group where {mode} is the
|
||||
+ * current driver mode for the following keys:
|
||||
+ * - skip (optional): list of pages to be skipped for the current mode
|
||||
+ *
|
||||
* This is how this file might look on a vendor image:
|
||||
*
|
||||
* [pages]
|
||||
* skip=timezone
|
||||
+ *
|
||||
+ * [new_user pages]
|
||||
+ * skip=language;keyboard
|
||||
+ *
|
||||
+ * Older files might look like so:
|
||||
+ *
|
||||
+ * [pages]
|
||||
+ * skip=timezone
|
||||
* existing_user_only=language;keyboard
|
||||
*/
|
||||
|
||||
skip_pages = gis_driver_conf_get_string_list (driver, VENDOR_PAGES_GROUP,
|
||||
VENDOR_SKIP_KEY, NULL);
|
||||
- additional_skip_pages =
|
||||
- gis_driver_conf_get_string_list (driver, VENDOR_PAGES_GROUP,
|
||||
- is_new_user ? VENDOR_EXISTING_USER_ONLY_KEY : VENDOR_NEW_USER_ONLY_KEY,
|
||||
- NULL);
|
||||
-
|
||||
- if (!skip_pages && additional_skip_pages) {
|
||||
- skip_pages = additional_skip_pages;
|
||||
- } else if (skip_pages && additional_skip_pages) {
|
||||
- skip_pages = strv_append (skip_pages, additional_skip_pages);
|
||||
- g_strfreev (additional_skip_pages);
|
||||
+ if (skip_pages != NULL)
|
||||
+ {
|
||||
+ g_strv_builder_addv (builder, (const char **) skip_pages);
|
||||
+ g_clear_pointer (&skip_pages, g_strfreev);
|
||||
+ }
|
||||
+
|
||||
+ driver_mode_flags_class = g_type_class_ref (GIS_TYPE_DRIVER_MODE);
|
||||
+
|
||||
+ driver_mode = gis_driver_get_mode (driver);
|
||||
+ driver_mode_flags = g_flags_get_first_value (driver_mode_flags_class, driver_mode);
|
||||
+
|
||||
+ mode_group = g_strdup_printf ("%s pages", driver_mode_flags->value_nick);
|
||||
+ skip_pages = gis_driver_conf_get_string_list (driver, mode_group,
|
||||
+ VENDOR_SKIP_KEY, NULL);
|
||||
+ if (skip_pages != NULL)
|
||||
+ {
|
||||
+ g_strv_builder_addv (builder, (const char **) skip_pages);
|
||||
+ g_clear_pointer (&skip_pages, g_strfreev);
|
||||
+ }
|
||||
+
|
||||
+ other_modes = GIS_DRIVER_MODE_ALL & ~driver_mode;
|
||||
+ while (other_modes) {
|
||||
+ const GFlagsValue *other_mode_flags = g_flags_get_first_value (driver_mode_flags_class, other_modes);
|
||||
+
|
||||
+ if (other_mode_flags != NULL) {
|
||||
+ g_autofree char *vendor_key = g_strdup_printf ("%s_only", other_mode_flags->value_nick);
|
||||
+
|
||||
+ skip_pages = gis_driver_conf_get_string_list (driver, VENDOR_PAGES_GROUP,
|
||||
+ vendor_key, NULL);
|
||||
+
|
||||
+ if (skip_pages != NULL)
|
||||
+ {
|
||||
+ g_strv_builder_addv (builder, (const char **) skip_pages);
|
||||
+ g_clear_pointer (&skip_pages, g_strfreev);
|
||||
+ }
|
||||
+
|
||||
+ other_modes &= ~other_mode_flags->value;
|
||||
+ }
|
||||
}
|
||||
|
||||
- return skip_pages;
|
||||
+ return g_strv_builder_end (builder);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_pages_after (GisAssistant *assistant,
|
||||
GisPage *page)
|
||||
{
|
||||
GList *pages, *l, *next;
|
||||
|
||||
pages = gis_assistant_get_all_pages (assistant);
|
||||
|
||||
for (l = pages; l != NULL; l = l->next)
|
||||
if (l->data == page)
|
||||
break;
|
||||
|
||||
l = l->next;
|
||||
for (; l != NULL; l = next) {
|
||||
next = l->next;
|
||||
gis_assistant_remove_page (assistant, l->data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_page (gpointer data)
|
||||
{
|
||||
GtkWidget *assistant;
|
||||
GisPage *page;
|
||||
|
||||
page = data;
|
||||
assistant = gtk_widget_get_ancestor (GTK_WIDGET (page), GIS_TYPE_ASSISTANT);
|
||||
|
||||
if (assistant)
|
||||
gis_assistant_remove_page (GIS_ASSISTANT (assistant), page);
|
||||
}
|
||||
|
||||
static void
|
||||
rebuild_pages_cb (GisDriver *driver)
|
||||
{
|
||||
PageData *page_data;
|
||||
GisPage *page;
|
||||
GisAssistant *assistant;
|
||||
GisPage *current_page;
|
||||
gchar **skip_pages;
|
||||
- gboolean is_new_user, skipped;
|
||||
+ GisDriverMode driver_mode;
|
||||
+ gboolean skipped;
|
||||
|
||||
assistant = gis_driver_get_assistant (driver);
|
||||
current_page = gis_assistant_get_current_page (assistant);
|
||||
page_data = page_table;
|
||||
|
||||
g_ptr_array_free (skipped_pages, TRUE);
|
||||
skipped_pages = g_ptr_array_new_with_free_func (destroy_page);
|
||||
|
||||
if (current_page != NULL) {
|
||||
destroy_pages_after (assistant, current_page);
|
||||
|
||||
for (page_data = page_table; page_data->page_id != NULL; ++page_data)
|
||||
if (g_str_equal (page_data->page_id, GIS_PAGE_GET_CLASS (current_page)->page_id))
|
||||
break;
|
||||
|
||||
++page_data;
|
||||
}
|
||||
|
||||
- is_new_user = (gis_driver_get_mode (driver) == GIS_DRIVER_MODE_NEW_USER);
|
||||
- skip_pages = pages_to_skip_from_file (driver, is_new_user);
|
||||
+ driver_mode = gis_driver_get_mode (driver);
|
||||
+ skip_pages = pages_to_skip_from_file (driver);
|
||||
|
||||
for (; page_data->page_id != NULL; ++page_data) {
|
||||
skipped = FALSE;
|
||||
|
||||
- if ((page_data->new_user_only && !is_new_user) ||
|
||||
+ if (((page_data->modes & driver_mode) == 0) ||
|
||||
(should_skip_page (page_data->page_id, skip_pages)))
|
||||
skipped = TRUE;
|
||||
|
||||
page = page_data->prepare_page_func (driver);
|
||||
if (!page)
|
||||
continue;
|
||||
|
||||
if (skipped) {
|
||||
gis_page_skip (page);
|
||||
g_ptr_array_add (skipped_pages, page);
|
||||
} else {
|
||||
gis_driver_add_page (driver, page);
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev (skip_pages);
|
||||
}
|
||||
|
||||
static GisDriverMode
|
||||
get_mode (void)
|
||||
{
|
||||
if (force_existing_user_mode)
|
||||
return GIS_DRIVER_MODE_EXISTING_USER;
|
||||
else
|
||||
return GIS_DRIVER_MODE_NEW_USER;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
initial_setup_disabled_by_anaconda (void)
|
||||
{
|
||||
--
|
||||
2.41.0
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,539 +0,0 @@
|
||||
From 53f42c970a1233c84dcc80667a096eb428f27592 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Wed, 16 Aug 2023 10:47:13 -0400
|
||||
Subject: [PATCH 7/9] initial-setup: Don't show duplicated pages between modes
|
||||
|
||||
It's possible a user just got asked questions in live mode
|
||||
before install that they'll then get asked again on first
|
||||
boot when the initial user is created.
|
||||
|
||||
This commit tracks that information so it doesn't get reasked.
|
||||
---
|
||||
data/meson.build | 6 +++
|
||||
gnome-initial-setup/gis-driver.c | 3 ++
|
||||
gnome-initial-setup/gnome-initial-setup.c | 65 +++++++++++++++++++++++
|
||||
meson.build | 4 ++
|
||||
4 files changed, 78 insertions(+)
|
||||
|
||||
diff --git a/data/meson.build b/data/meson.build
|
||||
index 6a4ef7df..0bfccf56 100644
|
||||
--- a/data/meson.build
|
||||
+++ b/data/meson.build
|
||||
@@ -103,30 +103,36 @@ if enable_systemd
|
||||
install_data('gnome-initial-setup.conf', install_dir: systemd_sysusersdir)
|
||||
endif
|
||||
|
||||
|
||||
rules_dir = join_paths(data_dir, 'polkit-1', 'rules.d')
|
||||
configure_file(
|
||||
input: '20-gnome-initial-setup.rules.in',
|
||||
output: '20-gnome-initial-setup.rules',
|
||||
install: true,
|
||||
install_dir: rules_dir,
|
||||
configuration: data_conf,
|
||||
)
|
||||
|
||||
session_dir = join_paths(data_dir, 'gnome-session', 'sessions')
|
||||
configure_file(
|
||||
input: '@0@.session.in'.format(meson.project_name()),
|
||||
output: '@BASENAME@',
|
||||
configuration: {
|
||||
'this_component': meson.project_name(),
|
||||
'gnome_session_required_components': ';'.join([
|
||||
gis_shell_component,
|
||||
meson.project_name(),
|
||||
] +
|
||||
gis_gnome_session_required_components),
|
||||
},
|
||||
install_dir: session_dir,
|
||||
)
|
||||
|
||||
mode_dir = join_paths(data_dir, 'gnome-shell', 'modes')
|
||||
install_data('initial-setup.json', install_dir: mode_dir)
|
||||
+
|
||||
+install_subdir(
|
||||
+ 'gnome-initial-setup',
|
||||
+ install_dir : working_dir,
|
||||
+ strip_directory : true
|
||||
+)
|
||||
diff --git a/gnome-initial-setup/gis-driver.c b/gnome-initial-setup/gis-driver.c
|
||||
index b18a3808..41cd6e38 100644
|
||||
--- a/gnome-initial-setup/gis-driver.c
|
||||
+++ b/gnome-initial-setup/gis-driver.c
|
||||
@@ -80,90 +80,93 @@ struct _GisDriver {
|
||||
|
||||
GtkWindow *main_window;
|
||||
GisAssistant *assistant;
|
||||
|
||||
GdmClient *client;
|
||||
GdmGreeter *greeter;
|
||||
GdmUserVerifier *user_verifier;
|
||||
|
||||
ActUser *user_account;
|
||||
gchar *user_password;
|
||||
|
||||
ActUser *parent_account; /* (owned) (nullable) */
|
||||
gchar *parent_password; /* (owned) (nullable) */
|
||||
|
||||
gboolean parental_controls_enabled;
|
||||
|
||||
gchar *lang_id;
|
||||
gchar *username;
|
||||
gchar *full_name; /* (owned) (nullable) */
|
||||
|
||||
GdkPaintable *avatar; /* (owned) (nullable) */
|
||||
|
||||
GisDriverMode mode;
|
||||
UmAccountMode account_mode;
|
||||
gboolean small_screen;
|
||||
|
||||
locale_t locale;
|
||||
|
||||
const gchar *vendor_conf_file_path;
|
||||
GKeyFile *vendor_conf_file;
|
||||
+
|
||||
+ GKeyFile *state_file;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GisDriver, gis_driver, ADW_TYPE_APPLICATION)
|
||||
|
||||
static void
|
||||
gis_driver_dispose (GObject *object)
|
||||
{
|
||||
GisDriver *driver = GIS_DRIVER (object);
|
||||
|
||||
g_clear_object (&driver->user_verifier);
|
||||
g_clear_object (&driver->greeter);
|
||||
g_clear_object (&driver->client);
|
||||
|
||||
G_OBJECT_CLASS (gis_driver_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gis_driver_finalize (GObject *object)
|
||||
{
|
||||
GisDriver *driver = GIS_DRIVER (object);
|
||||
|
||||
g_free (driver->lang_id);
|
||||
g_free (driver->username);
|
||||
g_free (driver->full_name);
|
||||
g_free (driver->user_password);
|
||||
|
||||
g_clear_object (&driver->avatar);
|
||||
|
||||
g_clear_object (&driver->user_account);
|
||||
g_clear_pointer (&driver->vendor_conf_file, g_key_file_free);
|
||||
+ g_clear_pointer (&driver->state_file, g_key_file_free);
|
||||
|
||||
g_clear_object (&driver->parent_account);
|
||||
g_free (driver->parent_password);
|
||||
|
||||
if (driver->locale != (locale_t) 0)
|
||||
{
|
||||
uselocale (LC_GLOBAL_LOCALE);
|
||||
freelocale (driver->locale);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gis_driver_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
assistant_page_changed (GtkScrolledWindow *sw)
|
||||
{
|
||||
gtk_adjustment_set_value (gtk_scrolled_window_get_vadjustment (sw), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
prepare_main_window (GisDriver *driver)
|
||||
{
|
||||
GtkWidget *child, *sw;
|
||||
|
||||
child = gtk_window_get_child (GTK_WINDOW (driver->main_window));
|
||||
g_object_ref (child);
|
||||
gtk_window_set_child (GTK_WINDOW (driver->main_window), NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_window_set_child (GTK_WINDOW (driver->main_window), sw);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), child);
|
||||
diff --git a/gnome-initial-setup/gnome-initial-setup.c b/gnome-initial-setup/gnome-initial-setup.c
|
||||
index bc7a4ee9..2bd2d375 100644
|
||||
--- a/gnome-initial-setup/gnome-initial-setup.c
|
||||
+++ b/gnome-initial-setup/gnome-initial-setup.c
|
||||
@@ -22,60 +22,62 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gnome-initial-setup.h"
|
||||
|
||||
#include <adwaita.h>
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "pages/welcome/gis-welcome-page.h"
|
||||
#include "pages/language/gis-language-page.h"
|
||||
#include "pages/keyboard/gis-keyboard-page.h"
|
||||
#include "pages/network/gis-network-page.h"
|
||||
#include "pages/timezone/gis-timezone-page.h"
|
||||
#include "pages/privacy/gis-privacy-page.h"
|
||||
#include "pages/software/gis-software-page.h"
|
||||
#include "pages/goa/gis-goa-page.h"
|
||||
#include "pages/account/gis-account-pages.h"
|
||||
#include "pages/parental-controls/gis-parental-controls-page.h"
|
||||
#include "pages/password/gis-password-page.h"
|
||||
#include "pages/summary/gis-summary-page.h"
|
||||
#include "pages/install/gis-install-page.h"
|
||||
|
||||
#define VENDOR_PAGES_GROUP "pages"
|
||||
#define VENDOR_SKIP_KEY "skip"
|
||||
#define VENDOR_NEW_USER_ONLY_KEY "new_user_only"
|
||||
#define VENDOR_EXISTING_USER_ONLY_KEY "existing_user_only"
|
||||
#define VENDOR_LIVE_USER_ONLY_KEY "live_user_only"
|
||||
|
||||
+#define STATE_FILE GIS_WORKING_DIR "/state"
|
||||
+
|
||||
static gboolean force_existing_user_mode;
|
||||
static gboolean force_live_user_mode;
|
||||
|
||||
static GPtrArray *skipped_pages;
|
||||
|
||||
typedef GisPage *(*PreparePage) (GisDriver *driver);
|
||||
|
||||
typedef struct {
|
||||
const gchar *page_id;
|
||||
PreparePage prepare_page_func;
|
||||
GisDriverMode modes;
|
||||
} PageData;
|
||||
|
||||
#define PAGE(name, modes) { #name, gis_prepare_ ## name ## _page, modes }
|
||||
|
||||
static PageData page_table[] = {
|
||||
PAGE (welcome, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
||||
PAGE (language, GIS_DRIVER_MODE_ALL),
|
||||
PAGE (keyboard, GIS_DRIVER_MODE_ALL),
|
||||
PAGE (network, GIS_DRIVER_MODE_ALL),
|
||||
PAGE (privacy, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
||||
PAGE (timezone, GIS_DRIVER_MODE_ALL),
|
||||
PAGE (software, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
||||
PAGE (goa, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
||||
/* In live user mode, the account page isn't displayed, it just quietly creates the live user */
|
||||
PAGE (account, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_LIVE_USER),
|
||||
PAGE (password, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_LIVE_USER),
|
||||
#ifdef HAVE_PARENTAL_CONTROLS
|
||||
PAGE (parental_controls, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
||||
PAGE (parent_password, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
||||
@@ -94,60 +96,61 @@ should_skip_page (const gchar *page_id,
|
||||
guint i = 0;
|
||||
|
||||
/* special case welcome. We only want to show it if language
|
||||
* is skipped
|
||||
*/
|
||||
if (strcmp (page_id, "welcome") == 0)
|
||||
return !should_skip_page ("language", skip_pages);
|
||||
|
||||
/* check through our skip pages list for pages we don't want */
|
||||
if (skip_pages) {
|
||||
while (skip_pages[i]) {
|
||||
if (g_strcmp0 (skip_pages[i], page_id) == 0)
|
||||
return TRUE;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gchar **
|
||||
pages_to_skip_from_file (GisDriver *driver)
|
||||
{
|
||||
GisDriverMode driver_mode;
|
||||
GisDriverMode other_modes;
|
||||
g_autoptr(GStrvBuilder) builder = g_strv_builder_new();
|
||||
g_auto (GStrv) skip_pages = NULL;
|
||||
g_autofree char *mode_group = NULL;
|
||||
g_autoptr (GFlagsClass) driver_mode_flags_class = NULL;
|
||||
const GFlagsValue *driver_mode_flags = NULL;
|
||||
+ g_autoptr (GError) error = NULL;
|
||||
|
||||
/* This code will read the keyfile containing vendor customization options and
|
||||
* look for options under the "pages" group, and supports the following keys:
|
||||
* - skip (optional): list of pages to be skipped always
|
||||
* - new_user_only (optional): list of pages to be skipped for modes other than new_user
|
||||
* - existing_user_only (optional): list of pages to be skipped for modes other than existing_user
|
||||
*
|
||||
* In addition it will look for options under the "{mode} pages" group where {mode} is the
|
||||
* current driver mode for the following keys:
|
||||
* - skip (optional): list of pages to be skipped for the current mode
|
||||
*
|
||||
* This is how this file might look on a vendor image:
|
||||
*
|
||||
* [pages]
|
||||
* skip=timezone
|
||||
*
|
||||
* [new_user pages]
|
||||
* skip=language;keyboard
|
||||
*
|
||||
* Older files might look like so:
|
||||
*
|
||||
* [pages]
|
||||
* skip=timezone
|
||||
* existing_user_only=language;keyboard
|
||||
*/
|
||||
|
||||
skip_pages = gis_driver_conf_get_string_list (driver, VENDOR_PAGES_GROUP,
|
||||
VENDOR_SKIP_KEY, NULL);
|
||||
if (skip_pages != NULL)
|
||||
{
|
||||
@@ -162,60 +165,80 @@ pages_to_skip_from_file (GisDriver *driver)
|
||||
|
||||
mode_group = g_strdup_printf ("%s pages", driver_mode_flags->value_nick);
|
||||
skip_pages = gis_driver_conf_get_string_list (driver, mode_group,
|
||||
VENDOR_SKIP_KEY, NULL);
|
||||
if (skip_pages != NULL)
|
||||
{
|
||||
g_strv_builder_addv (builder, (const char **) skip_pages);
|
||||
g_clear_pointer (&skip_pages, g_strfreev);
|
||||
}
|
||||
|
||||
other_modes = GIS_DRIVER_MODE_ALL & ~driver_mode;
|
||||
while (other_modes) {
|
||||
const GFlagsValue *other_mode_flags = g_flags_get_first_value (driver_mode_flags_class, other_modes);
|
||||
|
||||
if (other_mode_flags != NULL) {
|
||||
g_autofree char *vendor_key = g_strdup_printf ("%s_only", other_mode_flags->value_nick);
|
||||
|
||||
skip_pages = gis_driver_conf_get_string_list (driver, VENDOR_PAGES_GROUP,
|
||||
vendor_key, NULL);
|
||||
|
||||
if (skip_pages != NULL)
|
||||
{
|
||||
g_strv_builder_addv (builder, (const char **) skip_pages);
|
||||
g_clear_pointer (&skip_pages, g_strfreev);
|
||||
}
|
||||
|
||||
other_modes &= ~other_mode_flags->value;
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Also, if this is a system mode, we check if the user already answered questions earlier in
|
||||
+ * a different system mode, and skip those pages too.
|
||||
+ */
|
||||
+ if (driver_mode & GIS_DRIVER_MODE_NEW_USER) {
|
||||
+ g_autoptr(GKeyFile) state = NULL;
|
||||
+ gboolean state_loaded;
|
||||
+
|
||||
+ state = g_key_file_new ();
|
||||
+ state_loaded = g_key_file_load_from_file (state, STATE_FILE, G_KEY_FILE_NONE, &error);
|
||||
+
|
||||
+ if (state_loaded) {
|
||||
+ skip_pages = g_key_file_get_string_list (state, VENDOR_PAGES_GROUP, VENDOR_SKIP_KEY, NULL, NULL);
|
||||
+
|
||||
+ if (skip_pages != NULL) {
|
||||
+ g_strv_builder_addv (builder, (const char **) skip_pages);
|
||||
+ g_clear_pointer (&skip_pages, g_strfreev);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
return g_strv_builder_end (builder);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_pages_after (GisAssistant *assistant,
|
||||
GisPage *page)
|
||||
{
|
||||
GList *pages, *l, *next;
|
||||
|
||||
pages = gis_assistant_get_all_pages (assistant);
|
||||
|
||||
for (l = pages; l != NULL; l = l->next)
|
||||
if (l->data == page)
|
||||
break;
|
||||
|
||||
l = l->next;
|
||||
for (; l != NULL; l = next) {
|
||||
next = l->next;
|
||||
gis_assistant_remove_page (assistant, l->data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_page (gpointer data)
|
||||
{
|
||||
GtkWidget *assistant;
|
||||
GisPage *page;
|
||||
|
||||
page = data;
|
||||
assistant = gtk_widget_get_ancestor (GTK_WIDGET (page), GIS_TYPE_ASSISTANT);
|
||||
@@ -371,59 +394,101 @@ main (int argc, char *argv[])
|
||||
* it does in new-user mode, disable Initial Setup for existing users.
|
||||
*
|
||||
* https://gitlab.gnome.org/GNOME/gnome-initial-setup/-/issues/120#note_1019004
|
||||
* https://gitlab.gnome.org/GNOME/gnome-initial-setup/-/issues/12
|
||||
*/
|
||||
if (mode == GIS_DRIVER_MODE_EXISTING_USER) {
|
||||
g_message ("Skipping gnome-initial-setup for existing user");
|
||||
gis_ensure_stamp_files (driver);
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* We only do this in existing-user mode, because if gdm launches us
|
||||
* in new-user mode and we just exit, gdm's special g-i-s session
|
||||
* never terminates. */
|
||||
if (initial_setup_disabled_by_anaconda () &&
|
||||
mode == GIS_DRIVER_MODE_EXISTING_USER) {
|
||||
gis_ensure_stamp_files (driver);
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
g_signal_connect (driver, "rebuild-pages", G_CALLBACK (rebuild_pages_cb), NULL);
|
||||
status = g_application_run (G_APPLICATION (driver), argc, argv);
|
||||
|
||||
g_ptr_array_free (skipped_pages, TRUE);
|
||||
|
||||
g_object_unref (driver);
|
||||
g_option_context_free (context);
|
||||
return status;
|
||||
}
|
||||
|
||||
+static void
|
||||
+write_state (GisDriver *driver)
|
||||
+{
|
||||
+ g_autoptr(GKeyFile) state = NULL;
|
||||
+ g_autoptr(GError) error = NULL;
|
||||
+ g_autoptr(GStrvBuilder) builder = NULL;
|
||||
+ g_auto(GStrv) visited_pages = NULL;
|
||||
+ GisAssistant *assistant;
|
||||
+ GList *pages, *node;
|
||||
+
|
||||
+ assistant = gis_driver_get_assistant (driver);
|
||||
+
|
||||
+ if (assistant == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ state = g_key_file_new ();
|
||||
+
|
||||
+ builder = g_strv_builder_new ();
|
||||
+
|
||||
+ pages = gis_assistant_get_all_pages (assistant);
|
||||
+ for (node = pages; node != NULL; node = node->next) {
|
||||
+ GisPage *page = node->data;
|
||||
+ g_strv_builder_add (builder, GIS_PAGE_GET_CLASS (page)->page_id);
|
||||
+ }
|
||||
+
|
||||
+ visited_pages = g_strv_builder_end (builder);
|
||||
+
|
||||
+ g_key_file_set_string_list (state,
|
||||
+ VENDOR_PAGES_GROUP,
|
||||
+ VENDOR_SKIP_KEY,
|
||||
+ (const char * const *)
|
||||
+ visited_pages,
|
||||
+ g_strv_length (visited_pages));
|
||||
+
|
||||
+ if (!g_key_file_save_to_file (state, STATE_FILE, &error)) {
|
||||
+ g_warning ("Unable to save state to %s: %s", STATE_FILE, error->message);
|
||||
+ return;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void
|
||||
gis_ensure_stamp_files (GisDriver *driver)
|
||||
{
|
||||
g_autofree gchar *done_file = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
done_file = g_build_filename (g_get_user_config_dir (), "gnome-initial-setup-done", NULL);
|
||||
if (!g_file_set_contents (done_file, "yes", -1, &error)) {
|
||||
g_warning ("Unable to create %s: %s", done_file, error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
+
|
||||
+ write_state (driver);
|
||||
}
|
||||
|
||||
/**
|
||||
* gis_get_mock_mode:
|
||||
*
|
||||
* Gets whether gnome-initial-setup has been built for development, and hence
|
||||
* shouldn’t permanently change any system configuration.
|
||||
*
|
||||
* By default, mock mode is enabled when running in a build environment. This
|
||||
* heuristic may be changed in future.
|
||||
*
|
||||
* Returns: %TRUE if in mock mode, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
gis_get_mock_mode (void)
|
||||
{
|
||||
return (g_getenv ("UNDER_JHBUILD") != NULL);
|
||||
}
|
||||
diff --git a/meson.build b/meson.build
|
||||
index 7dd876e3..7058e6cf 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -1,59 +1,63 @@
|
||||
project('gnome-initial-setup',
|
||||
['c'],
|
||||
version: '45.beta',
|
||||
license: 'GPL-2.0-or-later',
|
||||
meson_version: '>= 0.53.0',
|
||||
)
|
||||
|
||||
cc = meson.get_compiler('c')
|
||||
gnome = import('gnome')
|
||||
i18n = import('i18n')
|
||||
|
||||
prefix = get_option('prefix')
|
||||
po_dir = join_paths(meson.current_source_dir(), 'po')
|
||||
bin_dir = join_paths(prefix, get_option('bindir'))
|
||||
data_dir = join_paths(prefix, get_option('datadir'))
|
||||
locale_dir = join_paths(prefix, get_option('localedir'))
|
||||
+localstate_dir = join_paths(prefix, get_option('localstatedir'))
|
||||
libexec_dir = join_paths(prefix, get_option('libexecdir'))
|
||||
sysconf_dir = join_paths(prefix, get_option('sysconfdir'))
|
||||
pkgdata_dir = join_paths(data_dir, meson.project_name())
|
||||
pkgsysconf_dir = join_paths(sysconf_dir, meson.project_name())
|
||||
+working_dir = join_paths(localstate_dir, 'lib', 'gnome-initial-setup')
|
||||
|
||||
conf = configuration_data()
|
||||
conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
|
||||
conf.set_quoted('GNOMELOCALEDIR', locale_dir)
|
||||
conf.set_quoted('PKGDATADIR', pkgdata_dir)
|
||||
conf.set_quoted('DATADIR', data_dir)
|
||||
+conf.set_quoted('LOCALSTATEDIR', localstate_dir)
|
||||
conf.set_quoted('PKGSYSCONFDIR', pkgsysconf_dir)
|
||||
conf.set_quoted('SYSCONFDIR', sysconf_dir)
|
||||
conf.set_quoted('LIBEXECDIR', libexec_dir)
|
||||
+conf.set_quoted('GIS_WORKING_DIR', working_dir)
|
||||
conf.set('SECRET_API_SUBJECT_TO_CHANGE', true)
|
||||
conf.set_quoted('G_LOG_DOMAIN', 'InitialSetup')
|
||||
conf.set('G_LOG_USE_STRUCTURED', true)
|
||||
conf.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_2_76')
|
||||
conf.set('GLIB_VERSION_MAX_ALLOWED', 'GLIB_VERSION_2_76')
|
||||
|
||||
enable_systemd = get_option('systemd')
|
||||
if enable_systemd
|
||||
systemd_dep = dependency('systemd', version: '>= 242', required: false)
|
||||
assert(systemd_dep.found(), 'Systemd support explicitly required, but systemd not found')
|
||||
|
||||
systemd_userunitdir = systemd_dep.get_variable(pkgconfig: 'systemduserunitdir',
|
||||
pkgconfig_define: ['prefix', prefix])
|
||||
systemd_sysusersdir = systemd_dep.get_variable(pkgconfig: 'sysusersdir',
|
||||
pkgconfig_define: ['prefix', prefix])
|
||||
endif
|
||||
|
||||
vendor_conf_file = get_option('vendor-conf-file')
|
||||
if vendor_conf_file != ''
|
||||
conf.set_quoted('VENDOR_CONF_FILE', vendor_conf_file)
|
||||
endif
|
||||
|
||||
# Needed for the 'keyboard' page
|
||||
ibus_dep = dependency ('ibus-1.0',
|
||||
version: '>= 1.4.99',
|
||||
required: get_option('ibus'))
|
||||
have_ibus = ibus_dep.found()
|
||||
conf.set('HAVE_IBUS', have_ibus)
|
||||
|
||||
# Check for libadwaita before malcontent-ui, otherwise Meson may search and
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,51 +0,0 @@
|
||||
From 2706720a58dba752ca0dbc65d7f1425df7db3bda Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Sun, 13 Aug 2023 16:33:49 -0400
|
||||
Subject: [PATCH 8/9] polkit: Add fedora specfic rules
|
||||
|
||||
We should probably add some way to check vendor.conf for the policy
|
||||
updates instead of a hardcoded list.
|
||||
---
|
||||
data/20-gnome-initial-setup.rules.in | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/data/20-gnome-initial-setup.rules.in b/data/20-gnome-initial-setup.rules.in
|
||||
index 881efde9..f5b7d981 100644
|
||||
--- a/data/20-gnome-initial-setup.rules.in
|
||||
+++ b/data/20-gnome-initial-setup.rules.in
|
||||
@@ -1,30 +1,31 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// DO NOT EDIT THIS FILE, it will be overwritten on update.
|
||||
//
|
||||
// Allow the gnome-initial-setup user to do certain actions without
|
||||
// being interrupted by password dialogs
|
||||
|
||||
polkit.addRule(function(action, subject) {
|
||||
if (subject.user !== 'gnome-initial-setup')
|
||||
return undefined;
|
||||
|
||||
var actionMatches = (action.id.indexOf('org.freedesktop.hostname1.') === 0 ||
|
||||
action.id.indexOf('org.freedesktop.NetworkManager.') === 0 ||
|
||||
action.id.indexOf('org.freedesktop.locale1.') === 0 ||
|
||||
action.id.indexOf('org.freedesktop.accounts.') === 0 ||
|
||||
action.id.indexOf('org.freedesktop.timedate1.') === 0 ||
|
||||
action.id.indexOf('org.freedesktop.realmd.') === 0 ||
|
||||
action.id.indexOf('com.endlessm.ParentalControls.') === 0 ||
|
||||
action.id.indexOf('org.fedoraproject.thirdparty.') === 0 ||
|
||||
- action.id.indexOf('org.freedesktop.login1.reboot') === 0);
|
||||
+ action.id.indexOf('org.freedesktop.login1.reboot') === 0 ||
|
||||
+ action.id.indexOf('org.fedoraproject.pkexec.liveinst') === 0);
|
||||
|
||||
if (actionMatches) {
|
||||
if (subject.local)
|
||||
return 'yes';
|
||||
else
|
||||
return 'auth_admin';
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,117 +0,0 @@
|
||||
From d42637a6f59981bac75a55eaee8fd1fc3b251e02 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Tue, 22 Aug 2023 13:51:40 -0400
|
||||
Subject: [PATCH 9/9] gnome-initial-setup: Read /etc/sysconfig/anaconda
|
||||
|
||||
Just as /var/lib/gnome-initial-setup/state may show pages the user has
|
||||
already answered, on Fedora, /etc/sysconfig/anaconda shows pages the user has
|
||||
already answered via Anaconda.
|
||||
|
||||
This commit skips those from the --new-user mode as well.
|
||||
---
|
||||
gnome-initial-setup/gnome-initial-setup.c | 23 +++++++++++++++++++++++
|
||||
1 file changed, 23 insertions(+)
|
||||
|
||||
diff --git a/gnome-initial-setup/gnome-initial-setup.c b/gnome-initial-setup/gnome-initial-setup.c
|
||||
index 2bd2d375..474dfc58 100644
|
||||
--- a/gnome-initial-setup/gnome-initial-setup.c
|
||||
+++ b/gnome-initial-setup/gnome-initial-setup.c
|
||||
@@ -171,72 +171,95 @@ pages_to_skip_from_file (GisDriver *driver)
|
||||
g_strv_builder_addv (builder, (const char **) skip_pages);
|
||||
g_clear_pointer (&skip_pages, g_strfreev);
|
||||
}
|
||||
|
||||
other_modes = GIS_DRIVER_MODE_ALL & ~driver_mode;
|
||||
while (other_modes) {
|
||||
const GFlagsValue *other_mode_flags = g_flags_get_first_value (driver_mode_flags_class, other_modes);
|
||||
|
||||
if (other_mode_flags != NULL) {
|
||||
g_autofree char *vendor_key = g_strdup_printf ("%s_only", other_mode_flags->value_nick);
|
||||
|
||||
skip_pages = gis_driver_conf_get_string_list (driver, VENDOR_PAGES_GROUP,
|
||||
vendor_key, NULL);
|
||||
|
||||
if (skip_pages != NULL)
|
||||
{
|
||||
g_strv_builder_addv (builder, (const char **) skip_pages);
|
||||
g_clear_pointer (&skip_pages, g_strfreev);
|
||||
}
|
||||
|
||||
other_modes &= ~other_mode_flags->value;
|
||||
}
|
||||
}
|
||||
|
||||
/* Also, if this is a system mode, we check if the user already answered questions earlier in
|
||||
* a different system mode, and skip those pages too.
|
||||
*/
|
||||
if (driver_mode & GIS_DRIVER_MODE_NEW_USER) {
|
||||
g_autoptr(GKeyFile) state = NULL;
|
||||
gboolean state_loaded;
|
||||
+ g_autoptr(GKeyFile) anaconda = NULL;
|
||||
+ gboolean anaconda_loaded;
|
||||
|
||||
state = g_key_file_new ();
|
||||
state_loaded = g_key_file_load_from_file (state, STATE_FILE, G_KEY_FILE_NONE, &error);
|
||||
|
||||
if (state_loaded) {
|
||||
skip_pages = g_key_file_get_string_list (state, VENDOR_PAGES_GROUP, VENDOR_SKIP_KEY, NULL, NULL);
|
||||
|
||||
if (skip_pages != NULL) {
|
||||
g_strv_builder_addv (builder, (const char **) skip_pages);
|
||||
g_clear_pointer (&skip_pages, g_strfreev);
|
||||
}
|
||||
}
|
||||
+
|
||||
+ anaconda = g_key_file_new ();
|
||||
+ anaconda_loaded = g_key_file_load_from_file (anaconda, "/etc/sysconfig/anaconda", G_KEY_FILE_NONE, NULL);
|
||||
+
|
||||
+ if (anaconda_loaded) {
|
||||
+ struct {
|
||||
+ const char *spoke_name;
|
||||
+ const char *page_name;
|
||||
+ } spoke_page_map[] = {
|
||||
+ { "WelcomeLanguageSpoke", "language" },
|
||||
+ { "DatetimeSpoke", "timezone" },
|
||||
+ { "KeyboardSpoke", "keyboard" },
|
||||
+ { NULL, NULL }
|
||||
+ };
|
||||
+ size_t i;
|
||||
+
|
||||
+ for (i = 0; spoke_page_map[i].spoke_name != NULL; i++) {
|
||||
+ if (g_key_file_get_boolean (anaconda, spoke_page_map[i].spoke_name, "visited", NULL))
|
||||
+ g_strv_builder_add (builder, spoke_page_map[i].page_name);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
return g_strv_builder_end (builder);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_pages_after (GisAssistant *assistant,
|
||||
GisPage *page)
|
||||
{
|
||||
GList *pages, *l, *next;
|
||||
|
||||
pages = gis_assistant_get_all_pages (assistant);
|
||||
|
||||
for (l = pages; l != NULL; l = l->next)
|
||||
if (l->data == page)
|
||||
break;
|
||||
|
||||
l = l->next;
|
||||
for (; l != NULL; l = next) {
|
||||
next = l->next;
|
||||
gis_assistant_remove_page (assistant, l->data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_page (gpointer data)
|
||||
{
|
||||
GtkWidget *assistant;
|
||||
GisPage *page;
|
||||
|
||||
--
|
||||
2.41.0
|
||||
|
@ -17,16 +17,8 @@ URL: https://wiki.gnome.org/Design/OS/InitialSetup
|
||||
Source0: https://download.gnome.org/sources/%{name}/45/%{name}-%{tarball_version}.tar.xz
|
||||
Source1: vendor.conf
|
||||
|
||||
Patch: 0001-gnome-initial-setup-Bump-GLib-required-version-to-2..patch
|
||||
Patch: 0002-keyboard-Don-t-require-localed-for-existing-user-mod.patch
|
||||
Patch: 0003-language-Don-t-proceed-until-localed-has-set-locale.patch
|
||||
Patch: 0004-keyboard-Get-default-input-sources-from-gnome-deskto.patch
|
||||
Patch: 0005-driver-Specify-mode-via-flags-instead-of-boolean.patch
|
||||
Patch: 0006-gnome-initial-setup-Add-live-user-mode.patch
|
||||
Patch: 0007-initial-setup-Don-t-show-duplicated-pages-between-mo.patch
|
||||
Patch: 0008-polkit-Add-fedora-specfic-rules.patch
|
||||
Patch: 0009-gnome-initial-setup-Read-etc-sysconfig-anaconda.patch
|
||||
|
||||
# https://gitlab.gnome.org/GNOME/gnome-initial-setup/-/merge_requests/200
|
||||
Patch: live-user-mode.patch
|
||||
|
||||
BuildRequires: desktop-file-utils
|
||||
BuildRequires: gcc
|
||||
|
2480
live-user-mode.patch
Normal file
2480
live-user-mode.patch
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user