1636 lines
56 KiB
Diff
1636 lines
56 KiB
Diff
|
From a53288f0ce04d4347635167fc313f357bd02a3e3 Mon Sep 17 00:00:00 2001
|
|||
|
From: Ray Strode <rstrode@redhat.com>
|
|||
|
Date: Sun, 13 Aug 2023 09:39:07 -0400
|
|||
|
Subject: [PATCH 08/12] gnome-initial-setup: Add live user mode
|
|||
|
|
|||
|
This commit adds a new "live user" mode meant to be run in live image
|
|||
|
environments.
|
|||
|
|
|||
|
It asks questions the user should answer before the installer is
|
|||
|
started, and provides a way for the user to initiate the installer
|
|||
|
or just jump into the live session instead.
|
|||
|
---
|
|||
|
data/20-gnome-initial-setup.rules.in | 3 +-
|
|||
|
gnome-initial-setup/gis-driver.c | 4 +-
|
|||
|
gnome-initial-setup/gis-driver.h | 4 +-
|
|||
|
gnome-initial-setup/gis-util.c | 70 ++++
|
|||
|
gnome-initial-setup/gis-util.h | 2 +
|
|||
|
gnome-initial-setup/gnome-initial-setup.c | 26 +-
|
|||
|
.../pages/account/gis-account-pages.c | 21 +
|
|||
|
.../pages/install/gis-install-page.c | 384 ++++++++++++++++++
|
|||
|
.../pages/install/gis-install-page.h | 52 +++
|
|||
|
.../pages/install/gis-install-page.ui | 49 +++
|
|||
|
.../pages/install/install.gresource.xml | 7 +
|
|||
|
gnome-initial-setup/pages/install/meson.build | 9 +
|
|||
|
.../pages/keyboard/gis-keyboard-page.c | 4 +-
|
|||
|
.../pages/language/gis-language-page.c | 5 +-
|
|||
|
gnome-initial-setup/pages/meson.build | 1 +
|
|||
|
.../pages/password/gis-password-page.c | 6 +
|
|||
|
16 files changed, 632 insertions(+), 15 deletions(-)
|
|||
|
create mode 100644 gnome-initial-setup/pages/install/gis-install-page.c
|
|||
|
create mode 100644 gnome-initial-setup/pages/install/gis-install-page.h
|
|||
|
create mode 100644 gnome-initial-setup/pages/install/gis-install-page.ui
|
|||
|
create mode 100644 gnome-initial-setup/pages/install/install.gresource.xml
|
|||
|
create mode 100644 gnome-initial-setup/pages/install/meson.build
|
|||
|
|
|||
|
diff --git a/data/20-gnome-initial-setup.rules.in b/data/20-gnome-initial-setup.rules.in
|
|||
|
index 02fd21d0..881efde9 100644
|
|||
|
--- a/data/20-gnome-initial-setup.rules.in
|
|||
|
+++ b/data/20-gnome-initial-setup.rules.in
|
|||
|
@@ -1,29 +1,30 @@
|
|||
|
// -*- 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.fedoraproject.thirdparty.') === 0 ||
|
|||
|
+ action.id.indexOf('org.freedesktop.login1.reboot') === 0);
|
|||
|
|
|||
|
if (actionMatches) {
|
|||
|
if (subject.local)
|
|||
|
return 'yes';
|
|||
|
else
|
|||
|
return 'auth_admin';
|
|||
|
}
|
|||
|
|
|||
|
return undefined;
|
|||
|
});
|
|||
|
diff --git a/gnome-initial-setup/gis-driver.c b/gnome-initial-setup/gis-driver.c
|
|||
|
index d3013063..b18a3808 100644
|
|||
|
--- a/gnome-initial-setup/gis-driver.c
|
|||
|
+++ b/gnome-initial-setup/gis-driver.c
|
|||
|
@@ -19,60 +19,62 @@
|
|||
|
* 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"
|
|||
|
|
|||
|
/* 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 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_LIVE_USER, "GIS_DRIVER_MODE_LIVE_USER", "live_user" },
|
|||
|
+ { GIS_DRIVER_MODE_SYSTEM, "GIS_DRIVER_MODE_SYSTEM", "system" },
|
|||
|
{ GIS_DRIVER_MODE_ALL, "GIS_DRIVER_MODE_ALL", "all" },
|
|||
|
{ 0, NULL, NULL }
|
|||
|
};
|
|||
|
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;
|
|||
|
|
|||
|
@@ -764,61 +766,61 @@ static void
|
|||
|
connect_to_gdm (GisDriver *driver)
|
|||
|
{
|
|||
|
g_autoptr(GError) error = NULL;
|
|||
|
|
|||
|
driver->client = gdm_client_new ();
|
|||
|
|
|||
|
driver->greeter = gdm_client_get_greeter_sync (driver->client, NULL, &error);
|
|||
|
if (error == NULL)
|
|||
|
driver->user_verifier = gdm_client_get_user_verifier_sync (driver->client, NULL, &error);
|
|||
|
|
|||
|
if (error != NULL) {
|
|||
|
g_warning ("Failed to open connection to GDM: %s", error->message);
|
|||
|
g_clear_object (&driver->user_verifier);
|
|||
|
g_clear_object (&driver->greeter);
|
|||
|
g_clear_object (&driver->client);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
gis_driver_startup (GApplication *app)
|
|||
|
{
|
|||
|
GisDriver *driver = GIS_DRIVER (app);
|
|||
|
WebKitWebContext *context = webkit_web_context_get_default ();
|
|||
|
|
|||
|
G_APPLICATION_CLASS (gis_driver_parent_class)->startup (app);
|
|||
|
|
|||
|
#if !WEBKIT_CHECK_VERSION(2, 39, 5)
|
|||
|
webkit_web_context_set_sandbox_enabled (context, TRUE);
|
|||
|
#endif
|
|||
|
|
|||
|
- if (driver->mode == GIS_DRIVER_MODE_NEW_USER)
|
|||
|
+ if (driver->mode & GIS_DRIVER_MODE_SYSTEM)
|
|||
|
connect_to_gdm (driver);
|
|||
|
|
|||
|
driver->main_window = g_object_new (GTK_TYPE_APPLICATION_WINDOW,
|
|||
|
"application", app,
|
|||
|
"icon-name", "preferences-system",
|
|||
|
"deletable", FALSE,
|
|||
|
"title", _("Initial Setup"),
|
|||
|
NULL);
|
|||
|
|
|||
|
g_signal_connect (driver->main_window,
|
|||
|
"realize",
|
|||
|
G_CALLBACK (window_realize_cb),
|
|||
|
(gpointer)app);
|
|||
|
|
|||
|
driver->assistant = g_object_new (GIS_TYPE_ASSISTANT, NULL);
|
|||
|
gtk_window_set_child (GTK_WINDOW (driver->main_window),
|
|||
|
GTK_WIDGET (driver->assistant));
|
|||
|
|
|||
|
gis_driver_set_user_language (driver, setlocale (LC_MESSAGES, NULL), FALSE);
|
|||
|
|
|||
|
prepare_main_window (driver);
|
|||
|
rebuild_pages (driver);
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
gis_driver_init (GisDriver *driver)
|
|||
|
{
|
|||
|
load_vendor_conf_file (driver);
|
|||
|
}
|
|||
|
|
|||
|
diff --git a/gnome-initial-setup/gis-driver.h b/gnome-initial-setup/gis-driver.h
|
|||
|
index b57db2e2..aedb9a73 100644
|
|||
|
--- a/gnome-initial-setup/gis-driver.h
|
|||
|
+++ b/gnome-initial-setup/gis-driver.h
|
|||
|
@@ -17,61 +17,63 @@
|
|||
|
*
|
|||
|
* 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 = 1 << 0,
|
|||
|
GIS_DRIVER_MODE_EXISTING_USER = 1 << 1,
|
|||
|
- GIS_DRIVER_MODE_ALL = (GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
|||
|
+ GIS_DRIVER_MODE_LIVE_USER = 1 << 2,
|
|||
|
+ GIS_DRIVER_MODE_SYSTEM = (GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_LIVE_USER),
|
|||
|
+ GIS_DRIVER_MODE_ALL = (GIS_DRIVER_MODE_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER | GIS_DRIVER_MODE_LIVE_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);
|
|||
|
|
|||
|
diff --git a/gnome-initial-setup/gis-util.c b/gnome-initial-setup/gis-util.c
|
|||
|
index ac153fc1..315661b6 100644
|
|||
|
--- a/gnome-initial-setup/gis-util.c
|
|||
|
+++ b/gnome-initial-setup/gis-util.c
|
|||
|
@@ -4,30 +4,100 @@
|
|||
|
* 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/>.
|
|||
|
*/
|
|||
|
|
|||
|
#include "config.h"
|
|||
|
|
|||
|
#include <gtk/gtk.h>
|
|||
|
|
|||
|
#include "gis-util.h"
|
|||
|
|
|||
|
void
|
|||
|
gis_add_style_from_resource (const char *resource_path)
|
|||
|
{
|
|||
|
g_autoptr(GtkCssProvider) provider = gtk_css_provider_new ();
|
|||
|
|
|||
|
gtk_css_provider_load_from_resource (provider, resource_path);
|
|||
|
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
|||
|
GTK_STYLE_PROVIDER (provider),
|
|||
|
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
|||
|
}
|
|||
|
+
|
|||
|
+gboolean
|
|||
|
+gis_kernel_command_line_has_argument (const char *arguments[])
|
|||
|
+{
|
|||
|
+ GError *error = NULL;
|
|||
|
+ g_autofree char *contents = NULL;
|
|||
|
+ g_autoptr (GString) pattern = NULL;
|
|||
|
+ gboolean has_argument = FALSE;
|
|||
|
+ size_t i;
|
|||
|
+
|
|||
|
+ if (!g_file_get_contents ("/proc/cmdline", &contents, NULL, &error)) {
|
|||
|
+ g_error_free (error);
|
|||
|
+ return FALSE;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ /* Build up the pattern by iterating through the alternatives,
|
|||
|
+ * escaping all dots so they don't match any character but period,
|
|||
|
+ * and adding word boundary specifiers around the arguments so
|
|||
|
+ * substrings don't get matched.
|
|||
|
+ *
|
|||
|
+ * Also, add a | between each alternative.
|
|||
|
+ */
|
|||
|
+ pattern = g_string_new (NULL);
|
|||
|
+ for (i = 0; arguments[i] != NULL; i++) {
|
|||
|
+ g_autofree char *escaped_argument = g_regex_escape_string (arguments[i], -1);
|
|||
|
+
|
|||
|
+ if (i > 0) {
|
|||
|
+ g_string_append (pattern, "|");
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ g_string_append (pattern, "\\b");
|
|||
|
+
|
|||
|
+ g_string_append (pattern, escaped_argument);
|
|||
|
+
|
|||
|
+ g_string_append (pattern, "\\b");
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ has_argument = g_regex_match_simple (pattern->str, contents, 0, 0);
|
|||
|
+
|
|||
|
+ return has_argument;
|
|||
|
+}
|
|||
|
+
|
|||
|
+void
|
|||
|
+gis_substitute_word_in_text (char **text,
|
|||
|
+ const char *old_word,
|
|||
|
+ const char *new_word)
|
|||
|
+{
|
|||
|
+ g_autoptr (GError) error = NULL;
|
|||
|
+ g_autofree char *pattern = g_strdup_printf ("\\b%s\\b", old_word);
|
|||
|
+ g_autoptr (GRegex) regex = g_regex_new (pattern, 0, 0, &error);
|
|||
|
+ g_autofree char *replacement_text = NULL;
|
|||
|
+
|
|||
|
+ if (text == NULL || *text == NULL) {
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ if (error != NULL) {
|
|||
|
+ g_debug ("Error creating regex to match %s: %s\n", old_word, error->message);
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ replacement_text = g_regex_replace (regex, *text, -1, 0, new_word, 0, &error);
|
|||
|
+
|
|||
|
+ if (error != NULL) {
|
|||
|
+ g_debug ("Error replacing %s with %s in %s: %s\n", old_word, new_word, *text, error->message);
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ g_free (*text);
|
|||
|
+ *text = g_steal_pointer (&replacement_text);
|
|||
|
+}
|
|||
|
diff --git a/gnome-initial-setup/gis-util.h b/gnome-initial-setup/gis-util.h
|
|||
|
index 5041bddd..10dcd70c 100644
|
|||
|
--- a/gnome-initial-setup/gis-util.h
|
|||
|
+++ b/gnome-initial-setup/gis-util.h
|
|||
|
@@ -1,19 +1,21 @@
|
|||
|
/*
|
|||
|
* Copyright 2023 Endless OS Foundation LLC
|
|||
|
*
|
|||
|
* 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/>.
|
|||
|
*/
|
|||
|
#pragma once
|
|||
|
|
|||
|
void gis_add_style_from_resource (const char *path);
|
|||
|
+gboolean gis_kernel_command_line_has_argument (const char *arguments[]);
|
|||
|
+void gis_substitute_word_in_text (char **text, const char *old_word, const char *new_word);
|
|||
|
diff --git a/gnome-initial-setup/gnome-initial-setup.c b/gnome-initial-setup/gnome-initial-setup.c
|
|||
|
index 59955779..bc7a4ee9 100644
|
|||
|
--- a/gnome-initial-setup/gnome-initial-setup.c
|
|||
|
+++ b/gnome-initial-setup/gnome-initial-setup.c
|
|||
|
@@ -14,141 +14,146 @@
|
|||
|
*
|
|||
|
* 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 <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"
|
|||
|
|
|||
|
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_NEW_USER | GIS_DRIVER_MODE_EXISTING_USER),
|
|||
|
+ PAGE (network, GIS_DRIVER_MODE_ALL),
|
|||
|
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 (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),
|
|||
|
- PAGE (account, GIS_DRIVER_MODE_NEW_USER),
|
|||
|
- PAGE (password, GIS_DRIVER_MODE_NEW_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),
|
|||
|
#endif
|
|||
|
PAGE (summary, GIS_DRIVER_MODE_NEW_USER),
|
|||
|
+ PAGE (install, GIS_DRIVER_MODE_LIVE_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 **
|
|||
|
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;
|
|||
|
|
|||
|
/* 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
|
|||
|
+ * - 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)
|
|||
|
{
|
|||
|
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);
|
|||
|
|
|||
|
@@ -250,130 +255,137 @@ rebuild_pages_cb (GisDriver *driver)
|
|||
|
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->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 if (force_live_user_mode)
|
|||
|
+ return GIS_DRIVER_MODE_LIVE_USER;
|
|||
|
else
|
|||
|
return GIS_DRIVER_MODE_NEW_USER;
|
|||
|
}
|
|||
|
|
|||
|
static gboolean
|
|||
|
initial_setup_disabled_by_anaconda (void)
|
|||
|
{
|
|||
|
const gchar *file_name = SYSCONFDIR "/sysconfig/anaconda";
|
|||
|
g_autoptr(GError) error = NULL;
|
|||
|
g_autoptr(GKeyFile) key_file = g_key_file_new ();
|
|||
|
|
|||
|
if (!g_key_file_load_from_file (key_file, file_name, G_KEY_FILE_NONE, &error)) {
|
|||
|
if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) &&
|
|||
|
!g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND)) {
|
|||
|
g_warning ("Could not read %s: %s", file_name, error->message);
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
return g_key_file_get_boolean (key_file, "General", "post_install_tools_disabled", NULL);
|
|||
|
}
|
|||
|
|
|||
|
int
|
|||
|
main (int argc, char *argv[])
|
|||
|
{
|
|||
|
GisDriver *driver;
|
|||
|
int status;
|
|||
|
GOptionContext *context;
|
|||
|
GisDriverMode mode;
|
|||
|
|
|||
|
GOptionEntry entries[] = {
|
|||
|
{ "existing-user", 0, 0, G_OPTION_ARG_NONE, &force_existing_user_mode,
|
|||
|
_("Force existing user mode"), NULL },
|
|||
|
+ { "live-user", 0, 0, G_OPTION_ARG_NONE, &force_live_user_mode,
|
|||
|
+ _("Force live user mode"), NULL },
|
|||
|
{ NULL }
|
|||
|
};
|
|||
|
|
|||
|
g_unsetenv ("GIO_USE_VFS");
|
|||
|
|
|||
|
/* By default, libadwaita reads settings from the Settings portal, which causes
|
|||
|
* the portal to be started, which causes gnome-keyring to be started. This
|
|||
|
* interferes with our attempt below to manually start gnome-keyring and set
|
|||
|
* the login keyring password to a well-known value, which we overwrite with
|
|||
|
* the user's password once they choose one.
|
|||
|
*/
|
|||
|
g_setenv ("ADW_DISABLE_PORTAL", "1", TRUE);
|
|||
|
|
|||
|
context = g_option_context_new (_("— GNOME initial setup"));
|
|||
|
g_option_context_add_main_entries (context, entries, NULL);
|
|||
|
|
|||
|
g_option_context_parse (context, &argc, &argv, NULL);
|
|||
|
|
|||
|
+ if (gis_kernel_command_line_has_argument ((const char *[]) { "rd.live.image", "endless.live_boot", NULL }))
|
|||
|
+ force_live_user_mode = TRUE;
|
|||
|
+
|
|||
|
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
|
|||
|
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
|||
|
textdomain (GETTEXT_PACKAGE);
|
|||
|
|
|||
|
g_message ("Starting gnome-initial-setup");
|
|||
|
if (gis_get_mock_mode ())
|
|||
|
g_message ("Mock mode: changes will not be saved to disk");
|
|||
|
else
|
|||
|
g_message ("Production mode: changes will be saved to disk");
|
|||
|
|
|||
|
skipped_pages = g_ptr_array_new_with_free_func (destroy_page);
|
|||
|
mode = get_mode ();
|
|||
|
|
|||
|
/* When we are running as the gnome-initial-setup user we
|
|||
|
* dont have a normal user session and need to initialize
|
|||
|
* the keyring manually so that we can pass the credentials
|
|||
|
* along to the new user in the handoff.
|
|||
|
*/
|
|||
|
- if (mode == GIS_DRIVER_MODE_NEW_USER && !gis_get_mock_mode ())
|
|||
|
+ if ((mode & GIS_DRIVER_MODE_SYSTEM) && !gis_get_mock_mode ())
|
|||
|
gis_ensure_login_keyring ();
|
|||
|
|
|||
|
driver = gis_driver_new (mode);
|
|||
|
adw_style_manager_set_color_scheme (adw_style_manager_get_default (),
|
|||
|
ADW_COLOR_SCHEME_PREFER_LIGHT);
|
|||
|
|
|||
|
/* On first login, GNOME Shell offers to run a tour. If we also run Initial
|
|||
|
* Setup, the two immovable, centred windows will sit atop one another.
|
|||
|
* Until we have the ability to run Initial Setup in the "kiosk" mode, like
|
|||
|
* 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);
|
|||
|
diff --git a/gnome-initial-setup/pages/account/gis-account-pages.c b/gnome-initial-setup/pages/account/gis-account-pages.c
|
|||
|
index d9cc8d9f..8b0d8e99 100644
|
|||
|
--- a/gnome-initial-setup/pages/account/gis-account-pages.c
|
|||
|
+++ b/gnome-initial-setup/pages/account/gis-account-pages.c
|
|||
|
@@ -1,32 +1,53 @@
|
|||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|||
|
/*
|
|||
|
* Copyright (C) 2013 Red Hat
|
|||
|
*
|
|||
|
* 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>
|
|||
|
*/
|
|||
|
|
|||
|
#include "config.h"
|
|||
|
#include "gis-account-pages.h"
|
|||
|
#include "gis-account-page.h"
|
|||
|
|
|||
|
GisPage *
|
|||
|
gis_prepare_account_page (GisDriver *driver)
|
|||
|
{
|
|||
|
+ GisDriverMode driver_mode;
|
|||
|
+
|
|||
|
+ driver_mode = gis_driver_get_mode (driver);
|
|||
|
+
|
|||
|
+ if (driver_mode == GIS_DRIVER_MODE_LIVE_USER && !gis_kernel_command_line_has_argument ((const char *[]) { "rd.live.overlay", NULL })) {
|
|||
|
+ ActUserManager *act_client = act_user_manager_get_default ();
|
|||
|
+ const char *username = "liveuser";
|
|||
|
+ g_autoptr(ActUser) user = NULL;
|
|||
|
+ g_autoptr(GError) error = NULL;
|
|||
|
+
|
|||
|
+ user = act_user_manager_create_user (act_client, username, username, ACT_USER_ACCOUNT_TYPE_ADMINISTRATOR, &error);
|
|||
|
+
|
|||
|
+ if (user != NULL) {
|
|||
|
+ act_user_set_password_mode (user, ACT_USER_PASSWORD_MODE_NONE);
|
|||
|
+ gis_driver_set_username (driver, username);
|
|||
|
+ gis_driver_set_account_mode (driver, UM_LOCAL);
|
|||
|
+ gis_driver_set_user_permissions (driver, user, NULL);
|
|||
|
+ }
|
|||
|
+ return NULL;
|
|||
|
+ }
|
|||
|
+
|
|||
|
return g_object_new (GIS_TYPE_ACCOUNT_PAGE,
|
|||
|
"driver", driver,
|
|||
|
NULL);
|
|||
|
}
|
|||
|
diff --git a/gnome-initial-setup/pages/install/gis-install-page.c b/gnome-initial-setup/pages/install/gis-install-page.c
|
|||
|
new file mode 100644
|
|||
|
index 00000000..70e3f9ec
|
|||
|
--- /dev/null
|
|||
|
+++ b/gnome-initial-setup/pages/install/gis-install-page.c
|
|||
|
@@ -0,0 +1,384 @@
|
|||
|
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|||
|
+/*
|
|||
|
+ * Copyright (C) 2023 Red Hat
|
|||
|
+ *
|
|||
|
+ * 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/>.
|
|||
|
+ */
|
|||
|
+
|
|||
|
+/* Install page {{{1 */
|
|||
|
+
|
|||
|
+#define PAGE_ID "install"
|
|||
|
+
|
|||
|
+#include "config.h"
|
|||
|
+#include "cc-common-language.h"
|
|||
|
+#include "gis-install-page.h"
|
|||
|
+#include "gis-pkexec.h"
|
|||
|
+
|
|||
|
+#include <glib/gstdio.h>
|
|||
|
+#include <glib/gi18n.h>
|
|||
|
+#include <gio/gio.h>
|
|||
|
+#include <gio/gdesktopappinfo.h>
|
|||
|
+#include <stdlib.h>
|
|||
|
+#include <errno.h>
|
|||
|
+
|
|||
|
+#include <act/act-user-manager.h>
|
|||
|
+
|
|||
|
+#define SERVICE_NAME "gdm-password"
|
|||
|
+#define VENDOR_INSTALLER_GROUP "install"
|
|||
|
+#define VENDOR_APPLICATION_KEY "application"
|
|||
|
+
|
|||
|
+struct _GisInstallPagePrivate {
|
|||
|
+ GtkWidget *try_button;
|
|||
|
+ GtkWidget *install_button;
|
|||
|
+ AdwStatusPage *status_page;
|
|||
|
+ GDesktopAppInfo *installer;
|
|||
|
+
|
|||
|
+ ActUser *user_account;
|
|||
|
+ const gchar *user_password;
|
|||
|
+};
|
|||
|
+typedef struct _GisInstallPagePrivate GisInstallPagePrivate;
|
|||
|
+
|
|||
|
+G_DEFINE_TYPE_WITH_PRIVATE (GisInstallPage, gis_install_page, GIS_TYPE_PAGE);
|
|||
|
+
|
|||
|
+static void
|
|||
|
+request_info_query (GisInstallPage *page,
|
|||
|
+ GdmUserVerifier *user_verifier,
|
|||
|
+ const char *question,
|
|||
|
+ gboolean is_secret)
|
|||
|
+{
|
|||
|
+ /* TODO: pop up modal dialog */
|
|||
|
+ g_debug ("user verifier asks%s question: %s",
|
|||
|
+ is_secret ? " secret" : "",
|
|||
|
+ question);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+on_info (GdmUserVerifier *user_verifier,
|
|||
|
+ const char *service_name,
|
|||
|
+ const char *info,
|
|||
|
+ GisInstallPage *page)
|
|||
|
+{
|
|||
|
+ g_debug ("PAM module info: %s", info);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+on_problem (GdmUserVerifier *user_verifier,
|
|||
|
+ const char *service_name,
|
|||
|
+ const char *problem,
|
|||
|
+ GisInstallPage *page)
|
|||
|
+{
|
|||
|
+ g_warning ("PAM module error: %s", problem);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+on_info_query (GdmUserVerifier *user_verifier,
|
|||
|
+ const char *service_name,
|
|||
|
+ const char *question,
|
|||
|
+ GisInstallPage *page)
|
|||
|
+{
|
|||
|
+ request_info_query (page, user_verifier, question, FALSE);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+on_secret_info_query (GdmUserVerifier *user_verifier,
|
|||
|
+ const char *service_name,
|
|||
|
+ const char *question,
|
|||
|
+ GisInstallPage *page)
|
|||
|
+{
|
|||
|
+ GisInstallPagePrivate *priv = gis_install_page_get_instance_private (page);
|
|||
|
+ gboolean should_send_password = priv->user_password != NULL;
|
|||
|
+
|
|||
|
+ g_debug ("PAM module secret info query: %s", question);
|
|||
|
+ if (should_send_password) {
|
|||
|
+ g_debug ("sending password\n");
|
|||
|
+ gdm_user_verifier_call_answer_query (user_verifier,
|
|||
|
+ service_name,
|
|||
|
+ priv->user_password,
|
|||
|
+ NULL, NULL, NULL);
|
|||
|
+ priv->user_password = NULL;
|
|||
|
+ } else {
|
|||
|
+ request_info_query (page, user_verifier, question, TRUE);
|
|||
|
+ }
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+on_session_opened (GdmGreeter *greeter,
|
|||
|
+ const char *service_name,
|
|||
|
+ GisInstallPage *page)
|
|||
|
+{
|
|||
|
+ gdm_greeter_call_start_session_when_ready_sync (greeter, service_name,
|
|||
|
+ TRUE, NULL, NULL);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+log_user_in (GisInstallPage *page)
|
|||
|
+{
|
|||
|
+ GisInstallPagePrivate *priv = gis_install_page_get_instance_private (page);
|
|||
|
+ g_autoptr(GError) error = NULL;
|
|||
|
+ GdmGreeter *greeter = NULL;
|
|||
|
+ GdmUserVerifier *user_verifier = NULL;
|
|||
|
+
|
|||
|
+ if (!gis_driver_get_gdm_objects (GIS_PAGE (page)->driver,
|
|||
|
+ &greeter, &user_verifier)) {
|
|||
|
+ g_warning ("No GDM connection; not initiating login");
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ g_signal_connect (user_verifier, "info",
|
|||
|
+ G_CALLBACK (on_info), page);
|
|||
|
+ g_signal_connect (user_verifier, "problem",
|
|||
|
+ G_CALLBACK (on_problem), page);
|
|||
|
+ g_signal_connect (user_verifier, "info-query",
|
|||
|
+ G_CALLBACK (on_info_query), page);
|
|||
|
+ g_signal_connect (user_verifier, "secret-info-query",
|
|||
|
+ G_CALLBACK (on_secret_info_query), page);
|
|||
|
+
|
|||
|
+ g_signal_connect (greeter, "session-opened",
|
|||
|
+ G_CALLBACK (on_session_opened), page);
|
|||
|
+
|
|||
|
+ gdm_user_verifier_call_begin_verification_for_user_sync (user_verifier,
|
|||
|
+ SERVICE_NAME,
|
|||
|
+ act_user_get_user_name (priv->user_account),
|
|||
|
+ NULL, &error);
|
|||
|
+
|
|||
|
+ if (error != NULL)
|
|||
|
+ g_warning ("Could not begin verification: %s", error->message);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+on_try_button_clicked (GtkButton *button,
|
|||
|
+ GisInstallPage *page)
|
|||
|
+{
|
|||
|
+ gis_ensure_stamp_files (GIS_PAGE (page)->driver);
|
|||
|
+
|
|||
|
+ gis_driver_hide_window (GIS_PAGE (page)->driver);
|
|||
|
+ log_user_in (page);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+on_installer_exited (GPid pid,
|
|||
|
+ int exit_status,
|
|||
|
+ gpointer user_data)
|
|||
|
+{
|
|||
|
+ g_autoptr (GError) error = NULL;
|
|||
|
+ g_autoptr(GSubprocessLauncher) launcher = NULL;
|
|||
|
+ g_autoptr(GSubprocess) subprocess = NULL;
|
|||
|
+ gboolean started_to_reboot;
|
|||
|
+
|
|||
|
+ launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_SEARCH_PATH_FROM_ENVP);
|
|||
|
+
|
|||
|
+ g_subprocess_launcher_unsetenv (launcher, "SHELL");
|
|||
|
+
|
|||
|
+ subprocess = g_subprocess_launcher_spawn (launcher, &error, "systemctl", "reboot", NULL);
|
|||
|
+
|
|||
|
+ if (subprocess == NULL) {
|
|||
|
+ g_warning ("Failed to initiate reboot: %s\n", error->message);
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ started_to_reboot = g_subprocess_wait (subprocess, NULL, &error);
|
|||
|
+
|
|||
|
+ if (!started_to_reboot) {
|
|||
|
+ g_warning ("Failed to reboot: %s\n", error->message);
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+on_installer_started (GDesktopAppInfo *appinfo,
|
|||
|
+ GPid pid,
|
|||
|
+ gpointer user_data)
|
|||
|
+{
|
|||
|
+ g_child_watch_add (pid, on_installer_exited, user_data);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+run_installer (GisInstallPage *page)
|
|||
|
+{
|
|||
|
+ g_autoptr (GError) error = NULL;
|
|||
|
+ GisInstallPagePrivate *priv = gis_install_page_get_instance_private (page);
|
|||
|
+ gboolean installer_launched;
|
|||
|
+ g_autoptr (GAppLaunchContext) launch_context = NULL;
|
|||
|
+ g_autofree char *language = NULL;
|
|||
|
+
|
|||
|
+ gis_ensure_stamp_files (GIS_PAGE (page)->driver);
|
|||
|
+
|
|||
|
+ launch_context = g_app_launch_context_new ();
|
|||
|
+
|
|||
|
+ g_app_launch_context_unsetenv (launch_context, "SHELL");
|
|||
|
+
|
|||
|
+ language = cc_common_language_get_current_language ();
|
|||
|
+
|
|||
|
+ if (language != NULL)
|
|||
|
+ g_app_launch_context_setenv (launch_context, "LANG", language);
|
|||
|
+
|
|||
|
+ installer_launched = g_desktop_app_info_launch_uris_as_manager (priv->installer,
|
|||
|
+ NULL,
|
|||
|
+ launch_context,
|
|||
|
+ G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_CHILD_INHERITS_STDERR | G_SPAWN_CHILD_INHERITS_STDOUT | G_SPAWN_SEARCH_PATH,
|
|||
|
+ NULL,
|
|||
|
+ NULL,
|
|||
|
+ on_installer_started,
|
|||
|
+ page,
|
|||
|
+ &error);
|
|||
|
+
|
|||
|
+ if (!installer_launched)
|
|||
|
+ g_warning ("Could not launch installer: %s", error->message);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+on_install_button_clicked (GtkButton *button,
|
|||
|
+ GisInstallPage *page)
|
|||
|
+{
|
|||
|
+ gis_driver_hide_window (GIS_PAGE (page)->driver);
|
|||
|
+ run_installer (page);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+gis_install_page_shown (GisPage *page)
|
|||
|
+{
|
|||
|
+ GisInstallPage *install = GIS_INSTALL_PAGE (page);
|
|||
|
+ GisInstallPagePrivate *priv = gis_install_page_get_instance_private (install);
|
|||
|
+ g_autoptr(GError) local_error = NULL;
|
|||
|
+
|
|||
|
+ if (!gis_driver_save_data (GIS_PAGE (page)->driver, &local_error))
|
|||
|
+ g_warning ("Error saving data: %s", local_error->message);
|
|||
|
+
|
|||
|
+ gis_driver_get_user_permissions (GIS_PAGE (page)->driver,
|
|||
|
+ &priv->user_account,
|
|||
|
+ &priv->user_password);
|
|||
|
+
|
|||
|
+ gtk_widget_grab_focus (priv->install_button);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+update_distro_name (GisInstallPage *page)
|
|||
|
+{
|
|||
|
+ GisInstallPagePrivate *priv = gis_install_page_get_instance_private (page);
|
|||
|
+ g_autofree char *name = g_get_os_info (G_OS_INFO_KEY_NAME);
|
|||
|
+ g_autofree char *text = NULL;
|
|||
|
+
|
|||
|
+ if (!name)
|
|||
|
+ name = g_strdup ("GNOME");
|
|||
|
+
|
|||
|
+ text = g_strdup (adw_status_page_get_description (priv->status_page));
|
|||
|
+ gis_substitute_word_in_text (&text, "GNOME", name);
|
|||
|
+ adw_status_page_set_description (priv->status_page, text);
|
|||
|
+ g_clear_pointer (&text, g_free);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+update_distro_logo (GisInstallPage *page)
|
|||
|
+{
|
|||
|
+ GisInstallPagePrivate *priv = gis_install_page_get_instance_private (page);
|
|||
|
+ g_autoptr (GtkIconTheme) icon_theme = NULL;
|
|||
|
+ g_autofree char *logo_name = g_get_os_info ("LOGO");
|
|||
|
+ g_autoptr(GtkIconPaintable) icon_paintable = NULL;
|
|||
|
+ g_autoptr(GPtrArray) array = NULL;
|
|||
|
+ g_autoptr(GIcon) icon = NULL;
|
|||
|
+
|
|||
|
+ if (logo_name == NULL)
|
|||
|
+ logo_name = g_strdup ("gnome-logo");
|
|||
|
+
|
|||
|
+ array = g_ptr_array_new_with_free_func (g_free);
|
|||
|
+ g_ptr_array_add (array, (gpointer) g_strdup_printf ("%s-text", logo_name));
|
|||
|
+ g_ptr_array_add (array, (gpointer) g_strdup_printf ("%s", logo_name));
|
|||
|
+
|
|||
|
+ icon = g_themed_icon_new_from_names ((char **) array->pdata, array->len);
|
|||
|
+ icon_theme = g_object_ref (gtk_icon_theme_get_for_display (gdk_display_get_default ()));
|
|||
|
+ icon_paintable = gtk_icon_theme_lookup_by_gicon (icon_theme, icon,
|
|||
|
+ 192,
|
|||
|
+ gtk_widget_get_scale_factor (GTK_WIDGET (priv->status_page)),
|
|||
|
+ gtk_widget_get_direction (GTK_WIDGET (priv->status_page)),
|
|||
|
+ 0);
|
|||
|
+
|
|||
|
+ adw_status_page_set_paintable (priv->status_page, GDK_PAINTABLE (icon_paintable));
|
|||
|
+}
|
|||
|
+
|
|||
|
+static gboolean
|
|||
|
+find_installer (GisInstallPage *page)
|
|||
|
+{
|
|||
|
+ GisInstallPagePrivate *priv = gis_install_page_get_instance_private (page);
|
|||
|
+ g_autofree char *desktop_file = NULL;
|
|||
|
+
|
|||
|
+ desktop_file = gis_driver_conf_get_string (GIS_PAGE (page)->driver,
|
|||
|
+ VENDOR_INSTALLER_GROUP,
|
|||
|
+ VENDOR_APPLICATION_KEY);
|
|||
|
+
|
|||
|
+ if (!desktop_file)
|
|||
|
+ return FALSE;
|
|||
|
+
|
|||
|
+ priv->installer = g_desktop_app_info_new (desktop_file);
|
|||
|
+
|
|||
|
+ return priv->installer != NULL;
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+gis_install_page_constructed (GObject *object)
|
|||
|
+{
|
|||
|
+ GisInstallPage *page = GIS_INSTALL_PAGE (object);
|
|||
|
+ GisInstallPagePrivate *priv = gis_install_page_get_instance_private (page);
|
|||
|
+
|
|||
|
+ G_OBJECT_CLASS (gis_install_page_parent_class)->constructed (object);
|
|||
|
+
|
|||
|
+ if (!find_installer (page))
|
|||
|
+ gtk_widget_set_sensitive (priv->install_button, FALSE);
|
|||
|
+
|
|||
|
+ update_distro_name (page);
|
|||
|
+ update_distro_logo (page);
|
|||
|
+ g_signal_connect (priv->try_button, "clicked", G_CALLBACK (on_try_button_clicked), page);
|
|||
|
+ g_signal_connect (priv->install_button, "clicked", G_CALLBACK (on_install_button_clicked), page);
|
|||
|
+
|
|||
|
+ gis_page_set_complete (GIS_PAGE (page), TRUE);
|
|||
|
+
|
|||
|
+ gtk_widget_set_visible (GTK_WIDGET (page), TRUE);
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+gis_install_page_locale_changed (GisPage *page)
|
|||
|
+{
|
|||
|
+ gis_page_set_title (page, _("Install or Try?"));
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+gis_install_page_class_init (GisInstallPageClass *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-install-page.ui");
|
|||
|
+
|
|||
|
+ gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisInstallPage, try_button);
|
|||
|
+ gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisInstallPage, install_button);
|
|||
|
+ gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisInstallPage, status_page);
|
|||
|
+
|
|||
|
+ page_class->page_id = PAGE_ID;
|
|||
|
+ page_class->locale_changed = gis_install_page_locale_changed;
|
|||
|
+ page_class->shown = gis_install_page_shown;
|
|||
|
+ object_class->constructed = gis_install_page_constructed;
|
|||
|
+}
|
|||
|
+
|
|||
|
+static void
|
|||
|
+gis_install_page_init (GisInstallPage *page)
|
|||
|
+{
|
|||
|
+ gtk_widget_init_template (GTK_WIDGET (page));
|
|||
|
+}
|
|||
|
+
|
|||
|
+GisPage *
|
|||
|
+gis_prepare_install_page (GisDriver *driver)
|
|||
|
+{
|
|||
|
+ return g_object_new (GIS_TYPE_INSTALL_PAGE,
|
|||
|
+ "driver", driver,
|
|||
|
+ NULL);
|
|||
|
+}
|
|||
|
diff --git a/gnome-initial-setup/pages/install/gis-install-page.h b/gnome-initial-setup/pages/install/gis-install-page.h
|
|||
|
new file mode 100644
|
|||
|
index 00000000..292427d8
|
|||
|
--- /dev/null
|
|||
|
+++ b/gnome-initial-setup/pages/install/gis-install-page.h
|
|||
|
@@ -0,0 +1,52 @@
|
|||
|
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|||
|
+/*
|
|||
|
+ * Copyright (C) 2023 Red Hat
|
|||
|
+ *
|
|||
|
+ * 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/>.
|
|||
|
+ */
|
|||
|
+
|
|||
|
+#ifndef __GIS_INSTALL_PAGE_H__
|
|||
|
+#define __GIS_INSTALL_PAGE_H__
|
|||
|
+
|
|||
|
+#include "gnome-initial-setup.h"
|
|||
|
+
|
|||
|
+G_BEGIN_DECLS
|
|||
|
+
|
|||
|
+#define GIS_TYPE_INSTALL_PAGE (gis_install_page_get_type ())
|
|||
|
+#define GIS_INSTALL_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIS_TYPE_INSTALL_PAGE, GisInstallPage))
|
|||
|
+#define GIS_INSTALL_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIS_TYPE_INSTALL_PAGE, GisInstallPageClass))
|
|||
|
+#define GIS_IS_INSTALL_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIS_TYPE_INSTALL_PAGE))
|
|||
|
+#define GIS_IS_INSTALL_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIS_TYPE_INSTALL_PAGE))
|
|||
|
+#define GIS_INSTALL_PAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIS_TYPE_INSTALL_PAGE, GisInstallPageClass))
|
|||
|
+
|
|||
|
+typedef struct _GisInstallPage GisInstallPage;
|
|||
|
+typedef struct _GisInstallPageClass GisInstallPageClass;
|
|||
|
+
|
|||
|
+struct _GisInstallPage
|
|||
|
+{
|
|||
|
+ GisPage parent;
|
|||
|
+};
|
|||
|
+
|
|||
|
+struct _GisInstallPageClass
|
|||
|
+{
|
|||
|
+ GisPageClass parent_class;
|
|||
|
+};
|
|||
|
+
|
|||
|
+GType gis_install_page_get_type (void);
|
|||
|
+
|
|||
|
+GisPage *gis_prepare_install_page (GisDriver *driver);
|
|||
|
+
|
|||
|
+G_END_DECLS
|
|||
|
+
|
|||
|
+#endif /* __GIS_INSTALL_PAGE_H__ */
|
|||
|
diff --git a/gnome-initial-setup/pages/install/gis-install-page.ui b/gnome-initial-setup/pages/install/gis-install-page.ui
|
|||
|
new file mode 100644
|
|||
|
index 00000000..08cfbd6e
|
|||
|
--- /dev/null
|
|||
|
+++ b/gnome-initial-setup/pages/install/gis-install-page.ui
|
|||
|
@@ -0,0 +1,49 @@
|
|||
|
+<?xml version="1.0" encoding="UTF-8"?>
|
|||
|
+<interface>
|
|||
|
+ <template class="GisInstallPage" parent="GisPage">
|
|||
|
+ <child>
|
|||
|
+ <object class="AdwStatusPage" id="status_page">
|
|||
|
+ <property name="icon-name">gnome-logo</property>
|
|||
|
+ <property name="title" translatable="yes">Install or Try?</property>
|
|||
|
+ <property name="description" translatable="yes">This live media can be used to install GNOME, or it can be used to try GNOME as a temporary system. Installation can be started at any time using the install icon in Activities.</property>
|
|||
|
+
|
|||
|
+ <child>
|
|||
|
+ <object class="GtkButton" id="start_button">
|
|||
|
+ <property name="use_underline">True</property>
|
|||
|
+ <property name="halign">center</property>
|
|||
|
+ <style>
|
|||
|
+ <class name="suggested-action"/>
|
|||
|
+ <class name="pill"/>
|
|||
|
+ </style>
|
|||
|
+ </object>
|
|||
|
+ </child>
|
|||
|
+
|
|||
|
+ <child>
|
|||
|
+ <object class="GtkBox" id="button_box">
|
|||
|
+ <property name="orientation">horizontal</property>
|
|||
|
+ <property name="homogeneous">True</property>
|
|||
|
+ <property name="spacing">24</property>
|
|||
|
+ <property name="halign">center</property>
|
|||
|
+ <child>
|
|||
|
+ <object class="GtkButton" id="install_button">
|
|||
|
+ <property name="label" translatable="yes">Install…</property>
|
|||
|
+ <style>
|
|||
|
+ <class name="suggested-action"/>
|
|||
|
+ <class name="pill"/>
|
|||
|
+ </style>
|
|||
|
+ </object>
|
|||
|
+ </child>
|
|||
|
+ <child>
|
|||
|
+ <object class="GtkButton" id="try_button">
|
|||
|
+ <property name="label" translatable="yes">Try</property>
|
|||
|
+ <style>
|
|||
|
+ <class name="pill"/>
|
|||
|
+ </style>
|
|||
|
+ </object>
|
|||
|
+ </child>
|
|||
|
+ </object>
|
|||
|
+ </child>
|
|||
|
+ </object>
|
|||
|
+ </child>
|
|||
|
+ </template>
|
|||
|
+</interface>
|
|||
|
diff --git a/gnome-initial-setup/pages/install/install.gresource.xml b/gnome-initial-setup/pages/install/install.gresource.xml
|
|||
|
new file mode 100644
|
|||
|
index 00000000..f1802db5
|
|||
|
--- /dev/null
|
|||
|
+++ b/gnome-initial-setup/pages/install/install.gresource.xml
|
|||
|
@@ -0,0 +1,7 @@
|
|||
|
+<?xml version="1.0" encoding="UTF-8"?>
|
|||
|
+<gresources>
|
|||
|
+ <gresource prefix="/org/gnome/initial-setup">
|
|||
|
+ <file preprocess="xml-stripblanks" alias="gis-install-page.ui">gis-install-page.ui</file>
|
|||
|
+ </gresource>
|
|||
|
+</gresources>
|
|||
|
+
|
|||
|
diff --git a/gnome-initial-setup/pages/install/meson.build b/gnome-initial-setup/pages/install/meson.build
|
|||
|
new file mode 100644
|
|||
|
index 00000000..e5084e5e
|
|||
|
--- /dev/null
|
|||
|
+++ b/gnome-initial-setup/pages/install/meson.build
|
|||
|
@@ -0,0 +1,9 @@
|
|||
|
+sources += gnome.compile_resources(
|
|||
|
+ 'install-resources',
|
|||
|
+ files('install.gresource.xml'),
|
|||
|
+ c_name: 'install'
|
|||
|
+)
|
|||
|
+sources += files(
|
|||
|
+ 'gis-install-page.c',
|
|||
|
+ 'gis-install-page.h'
|
|||
|
+)
|
|||
|
diff --git a/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c b/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c
|
|||
|
index 179553da..85028970 100644
|
|||
|
--- a/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c
|
|||
|
+++ b/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c
|
|||
|
@@ -274,61 +274,61 @@ change_locale_permission_acquired (GObject *source,
|
|||
|
{
|
|||
|
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;
|
|||
|
|
|||
|
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 (gis_driver_get_mode (GIS_PAGE (self)->driver) & GIS_DRIVER_MODE_SYSTEM) {
|
|||
|
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 void
|
|||
|
add_default_input_sources (GisKeyboardPage *self)
|
|||
|
{
|
|||
|
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);
|
|||
|
@@ -469,61 +469,61 @@ 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)
|
|||
|
+ if (gis_driver_get_mode (GIS_PAGE (self)->driver) & GIS_DRIVER_MODE_SYSTEM)
|
|||
|
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;
|
|||
|
object_class->finalize = gis_keyboard_page_finalize;
|
|||
|
}
|
|||
|
diff --git a/gnome-initial-setup/pages/language/gis-language-page.c b/gnome-initial-setup/pages/language/gis-language-page.c
|
|||
|
index 26a01257..17117fa1 100644
|
|||
|
--- a/gnome-initial-setup/pages/language/gis-language-page.c
|
|||
|
+++ b/gnome-initial-setup/pages/language/gis-language-page.c
|
|||
|
@@ -118,61 +118,61 @@ change_locale_permission_acquired (GObject *source,
|
|||
|
}
|
|||
|
|
|||
|
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) {
|
|||
|
+ if (gis_driver_get_mode (driver) & GIS_DRIVER_MODE_SYSTEM) {
|
|||
|
|
|||
|
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),
|
|||
|
@@ -230,62 +230,61 @@ update_distro_logo (GisLanguagePage *page)
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
language_confirmed (CcLanguageChooser *chooser,
|
|||
|
GisLanguagePage *page)
|
|||
|
{
|
|||
|
gis_assistant_next_page (gis_driver_get_assistant (GIS_PAGE (page)->driver));
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
gis_language_page_constructed (GObject *object)
|
|||
|
{
|
|||
|
GisLanguagePage *page = GIS_LANGUAGE_PAGE (object);
|
|||
|
GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page);
|
|||
|
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)
|
|||
|
+ if (gis_driver_get_mode (GIS_PAGE (page)->driver) & GIS_DRIVER_MODE_SYSTEM)
|
|||
|
{
|
|||
|
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);
|
|||
|
}
|
|||
|
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)
|
|||
|
diff --git a/gnome-initial-setup/pages/meson.build b/gnome-initial-setup/pages/meson.build
|
|||
|
index 32305018..5ac4a80d 100644
|
|||
|
--- a/gnome-initial-setup/pages/meson.build
|
|||
|
+++ b/gnome-initial-setup/pages/meson.build
|
|||
|
@@ -1,21 +1,22 @@
|
|||
|
pages = [
|
|||
|
'account',
|
|||
|
+ 'install',
|
|||
|
'language',
|
|||
|
'keyboard',
|
|||
|
'network',
|
|||
|
'timezone',
|
|||
|
'privacy',
|
|||
|
'goa',
|
|||
|
'password',
|
|||
|
'software',
|
|||
|
'summary',
|
|||
|
'welcome',
|
|||
|
]
|
|||
|
|
|||
|
if libmalcontent_dep.found() and libmalcontent_ui_dep.found()
|
|||
|
pages += 'parental-controls'
|
|||
|
endif
|
|||
|
|
|||
|
foreach page: pages
|
|||
|
subdir (page)
|
|||
|
endforeach
|
|||
|
diff --git a/gnome-initial-setup/pages/password/gis-password-page.c b/gnome-initial-setup/pages/password/gis-password-page.c
|
|||
|
index 6c12ca38..3d648c48 100644
|
|||
|
--- a/gnome-initial-setup/pages/password/gis-password-page.c
|
|||
|
+++ b/gnome-initial-setup/pages/password/gis-password-page.c
|
|||
|
@@ -464,47 +464,53 @@ gis_password_page_class_init (GisPasswordPageClass *klass)
|
|||
|
*
|
|||
|
* If %FALSE (the default), this page will collect a password for the main
|
|||
|
* user account. If %TRUE, it will collect a password for controlling access
|
|||
|
* to parental controls — this will affect where the password is stored, and
|
|||
|
* the appearance of the page.
|
|||
|
*
|
|||
|
* Since: 3.36
|
|||
|
*/
|
|||
|
obj_props[PROP_PARENT_MODE] =
|
|||
|
g_param_spec_boolean ("parent-mode", "Parent Mode",
|
|||
|
"Whether to collect a password for the main user account or a parent account.",
|
|||
|
FALSE,
|
|||
|
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
|||
|
|
|||
|
g_object_class_install_properties (object_class, G_N_ELEMENTS (obj_props), obj_props);
|
|||
|
|
|||
|
gis_add_style_from_resource ("/org/gnome/initial-setup/gis-password-page.css");
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
gis_password_page_init (GisPasswordPage *page)
|
|||
|
{
|
|||
|
g_type_ensure (GIS_TYPE_PAGE_HEADER);
|
|||
|
|
|||
|
gtk_widget_init_template (GTK_WIDGET (page));
|
|||
|
}
|
|||
|
|
|||
|
GisPage *
|
|||
|
gis_prepare_password_page (GisDriver *driver)
|
|||
|
{
|
|||
|
+ GisDriverMode driver_mode;
|
|||
|
+
|
|||
|
+ driver_mode = gis_driver_get_mode (driver);
|
|||
|
+ if (driver_mode == GIS_DRIVER_MODE_LIVE_USER && !gis_kernel_command_line_has_argument ((const char *[]) { "rd.live.overlay", NULL }))
|
|||
|
+ return NULL;
|
|||
|
+
|
|||
|
return g_object_new (GIS_TYPE_PASSWORD_PAGE,
|
|||
|
"driver", driver,
|
|||
|
NULL);
|
|||
|
}
|
|||
|
|
|||
|
GisPage *
|
|||
|
gis_prepare_parent_password_page (GisDriver *driver)
|
|||
|
{
|
|||
|
/* Skip prompting for the parent password if parental controls aren’t enabled. */
|
|||
|
if (!gis_driver_get_parental_controls_enabled (driver))
|
|||
|
return NULL;
|
|||
|
|
|||
|
return g_object_new (GIS_TYPE_PASSWORD_PAGE,
|
|||
|
"driver", driver,
|
|||
|
"parent-mode", TRUE,
|
|||
|
NULL);
|
|||
|
}
|
|||
|
--
|
|||
|
2.41.0
|
|||
|
|