2023-08-28 21:45:59 +00:00
|
|
|
|
From e0abb46daa5f5e84b35d8e6481c3408d3c377c40 Mon Sep 17 00:00:00 2001
|
2023-08-14 17:08:43 +00:00
|
|
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
|
|
|
Date: Wed, 16 Aug 2023 10:47:13 -0400
|
2023-08-28 21:45:59 +00:00
|
|
|
|
Subject: [PATCH 07/11] initial-setup: Don't show duplicated pages between
|
2023-08-26 10:19:54 +00:00
|
|
|
|
modes
|
2023-08-14 17:08:43 +00:00
|
|
|
|
|
|
|
|
|
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 ++
|
2023-08-28 21:45:59 +00:00
|
|
|
|
gnome-initial-setup/gnome-initial-setup.c | 65 +++++++++++++++++++++++
|
2023-08-14 17:08:43 +00:00
|
|
|
|
meson.build | 4 ++
|
2023-08-28 21:45:59 +00:00
|
|
|
|
4 files changed, 78 insertions(+)
|
2023-08-14 17:08:43 +00:00
|
|
|
|
|
|
|
|
|
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
|
2023-08-28 21:45:59 +00:00
|
|
|
|
index b18a3808..41cd6e38 100644
|
2023-08-14 17:08:43 +00:00
|
|
|
|
--- a/gnome-initial-setup/gis-driver.c
|
|
|
|
|
+++ b/gnome-initial-setup/gis-driver.c
|
2023-08-28 21:45:59 +00:00
|
|
|
|
@@ -80,90 +80,93 @@ struct _GisDriver {
|
2023-08-14 17:08:43 +00:00
|
|
|
|
|
|
|
|
|
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
|
2023-08-28 21:45:59 +00:00
|
|
|
|
index bc7a4ee9..2bd2d375 100644
|
2023-08-14 17:08:43 +00:00
|
|
|
|
--- a/gnome-initial-setup/gnome-initial-setup.c
|
|
|
|
|
+++ b/gnome-initial-setup/gnome-initial-setup.c
|
2023-08-28 21:45:59 +00:00
|
|
|
|
@@ -22,60 +22,62 @@
|
2023-08-14 17:08:43 +00:00
|
|
|
|
#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"
|
2023-08-28 21:45:59 +00:00
|
|
|
|
#include "pages/install/gis-install-page.h"
|
2023-08-14 17:08:43 +00:00
|
|
|
|
|
|
|
|
|
#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"
|
2023-08-28 21:45:59 +00:00
|
|
|
|
#define VENDOR_LIVE_USER_ONLY_KEY "live_user_only"
|
2023-08-14 17:08:43 +00:00
|
|
|
|
|
|
|
|
|
+#define STATE_FILE GIS_WORKING_DIR "/state"
|
|
|
|
|
+
|
|
|
|
|
static gboolean force_existing_user_mode;
|
2023-08-28 21:45:59 +00:00
|
|
|
|
static gboolean force_live_user_mode;
|
2023-08-14 17:08:43 +00:00
|
|
|
|
|
|
|
|
|
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),
|
2023-08-28 21:45:59 +00:00
|
|
|
|
PAGE (network, GIS_DRIVER_MODE_ALL),
|
2023-08-14 17:08:43 +00:00
|
|
|
|
PAGE (privacy, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
2023-08-28 21:45:59 +00:00
|
|
|
|
PAGE (timezone, GIS_DRIVER_MODE_ALL),
|
2023-08-14 17:08:43 +00:00
|
|
|
|
PAGE (software, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
|
|
|
|
PAGE (goa, GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
2023-08-28 21:45:59 +00:00
|
|
|
|
/* 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),
|
2023-08-14 17:08:43 +00:00
|
|
|
|
#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),
|
2023-08-28 21:45:59 +00:00
|
|
|
|
@@ -94,60 +96,61 @@ should_skip_page (const gchar *page_id,
|
2023-08-14 17:08:43 +00:00
|
|
|
|
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
|
2023-08-28 21:45:59 +00:00
|
|
|
|
* - 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
|
2023-08-14 17:08:43 +00:00
|
|
|
|
*
|
|
|
|
|
* 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)
|
|
|
|
|
{
|
2023-08-28 21:45:59 +00:00
|
|
|
|
@@ -162,60 +165,80 @@ pages_to_skip_from_file (GisDriver *driver)
|
2023-08-14 17:08:43 +00:00
|
|
|
|
|
|
|
|
|
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);
|
2023-08-28 21:45:59 +00:00
|
|
|
|
@@ -371,59 +394,101 @@ main (int argc, char *argv[])
|
2023-08-14 17:08:43 +00:00
|
|
|
|
* 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;
|
|
|
|
|
+
|
2023-08-28 21:45:59 +00:00
|
|
|
|
+ assistant = gis_driver_get_assistant (driver);
|
|
|
|
|
+
|
|
|
|
|
+ if (assistant == NULL)
|
|
|
|
|
+ return;
|
|
|
|
|
+
|
2023-08-14 17:08:43 +00:00
|
|
|
|
+ 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 28cf7998..4c294dfe 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_70')
|
|
|
|
|
conf.set('GLIB_VERSION_MAX_ALLOWED', 'GLIB_VERSION_2_70')
|
|
|
|
|
|
|
|
|
|
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.rc2
|
|
|
|
|
|