summaryrefslogtreecommitdiff
path: root/x11/gnome-session/files
diff options
context:
space:
mode:
Diffstat (limited to 'x11/gnome-session/files')
-rw-r--r--x11/gnome-session/files/patch-data_meson.build18
-rw-r--r--x11/gnome-session/files/patch-doc_man_gnome-session.137
-rw-r--r--x11/gnome-session/files/patch-gnome-session_gsm-autostart-app.c44
-rw-r--r--x11/gnome-session/files/patch-gnome-session_gsm-consolekit.c975
-rw-r--r--x11/gnome-session/files/patch-gnome-session_gsm-consolekit.h62
-rw-r--r--x11/gnome-session/files/patch-gnome-session_gsm-manager.c86
-rw-r--r--x11/gnome-session/files/patch-gnome-session_gsm-system.c28
-rw-r--r--x11/gnome-session/files/patch-gnome-session_gsm-systemd.c25
-rw-r--r--x11/gnome-session/files/patch-gnome-session_gsm-util.c46
-rw-r--r--x11/gnome-session/files/patch-gnome-session_gsm-util.h18
-rw-r--r--x11/gnome-session/files/patch-gnome-session_main.c96
-rw-r--r--x11/gnome-session/files/patch-gnome-session_meson.build13
-rw-r--r--x11/gnome-session/files/patch-meson.build73
-rw-r--r--x11/gnome-session/files/patch-meson__options.txt12
-rw-r--r--x11/gnome-session/files/patch-tools_meson.build18
15 files changed, 1551 insertions, 0 deletions
diff --git a/x11/gnome-session/files/patch-data_meson.build b/x11/gnome-session/files/patch-data_meson.build
new file mode 100644
index 000000000000..0d22a37a99dd
--- /dev/null
+++ b/x11/gnome-session/files/patch-data_meson.build
@@ -0,0 +1,18 @@
+--- data/meson.build.orig 2024-03-18 19:30:06 UTC
++++ data/meson.build
+@@ -108,6 +108,7 @@ install_data(
+ install_dir: join_paths(session_datadir, 'glib-2.0', 'schemas'),
+ )
+
++if enable_systemd_session
+ unit_conf = configuration_data()
+ unit_conf.set('libexecdir', session_libexecdir)
+
+@@ -170,6 +171,7 @@ endforeach
+ session),
+ )
+ endforeach
++endif
+
+ data = files('hardware-compatibility')
+
diff --git a/x11/gnome-session/files/patch-doc_man_gnome-session.1 b/x11/gnome-session/files/patch-doc_man_gnome-session.1
new file mode 100644
index 000000000000..f3aca3c6f497
--- /dev/null
+++ b/x11/gnome-session/files/patch-doc_man_gnome-session.1
@@ -0,0 +1,37 @@
+--- doc/man/gnome-session.1.orig 2024-03-18 19:30:06 UTC
++++ doc/man/gnome-session.1
+@@ -43,6 +43,14 @@ Use the applications defined in \fBSESSION.session\fP.
+ Use the applications defined in \fBSESSION.session\fP. If not specified,
+ \fBgnome.session\fP will be used.
+ .TP
++.I "--builtin"
++Use the legacy non-systemd method of managing the user session. This is the
++opposite of the \fI--systemd\fP option.
++.TP
++.I "--systemd"
++Use the systemd method of managing the user session. This is the opposite of
++the \fI--builtin\fP option.
++.TP
+ .I "--failsafe"
+ Run in fail-safe mode. User-specified applications will not be started.
+ .TP
+@@ -82,11 +90,17 @@ The \fB.session\fP files are looked for in
+ \fB$XDG_CONFIG_DIRS/gnome-session/sessions\fP and
+ \fB$XDG_DATA_DIRS/gnome-session/sessions\fP.
+ .SH systemd
+-\fIgnome-session\fP can pass much of the session management over to systemd.
+-In this case, startup components that have \fBX-GNOME-HiddenUnderSystemd=true\fP
++\fIgnome-session\fP can pass much of the session management over to systemd
++(see the \fI--systemd\fP option which may be the default since 3.34). In this
++case, startup components that have \fBX-GNOME-HiddenUnderSystemd=true\fP
+ set in their \fB.desktop\fP file will be ignored by \fIgnome-session\fP. It
+ instead relies on the fact that these components are managed by systemd.
+ .PP
++As of GNOME 3.34 the systemd support is new and the customizing the
++configuration is not yet easily possible. With GNOME 3.34 it may be best to use
++\fI--builtin\fP if session customizations are required. This is due to the way
++that GNOME currently defines the components that will be started on each session
++type.
+ .PP
+ \fBsystemd\fP provides the two special targets \fBgraphical-session.target\fP
+ and \fBgraphical-session-pre.target\fP which are fully functional and should be
diff --git a/x11/gnome-session/files/patch-gnome-session_gsm-autostart-app.c b/x11/gnome-session/files/patch-gnome-session_gsm-autostart-app.c
new file mode 100644
index 000000000000..6d3d660bd50b
--- /dev/null
+++ b/x11/gnome-session/files/patch-gnome-session_gsm-autostart-app.c
@@ -0,0 +1,44 @@
+--- gnome-session/gsm-autostart-app.c.orig 2024-03-18 19:30:06 UTC
++++ gnome-session/gsm-autostart-app.c
+@@ -31,8 +31,12 @@
+ #define GNOME_DESKTOP_USE_UNSTABLE_API
+ #include <libgnome-desktop/gnome-systemd.h>
+
++#ifdef HAVE_SYSTEMD
++#ifdef ENABLE_SYSTEMD_JOURNAL
+ #include <systemd/sd-journal.h>
++#endif
+ #include <systemd/sd-daemon.h>
++#endif
+
+ #include "gsm-autostart-app.h"
+ #include "gsm-util.h"
+@@ -957,6 +961,7 @@ app_launched (GAppLaunchContext *ctx,
+ NULL, NULL, NULL);
+ }
+
++#ifdef ENABLE_SYSTEMD_JOURNAL
+ static void
+ on_child_setup (GsmAutostartApp *app)
+ {
+@@ -983,6 +988,7 @@ on_child_setup (GsmAutostartApp *app)
+ close (standard_error);
+ }
+ }
++#endif
+
+ static gboolean
+ autostart_app_start_spawn (GsmAutostartApp *app,
+@@ -1033,10 +1039,12 @@ autostart_app_start_spawn (GsmAutostartApp *app,
+ g_app_launch_context_setenv (ctx, "DESKTOP_AUTOSTART_ID", startup_id);
+ }
+
++#ifdef ENABLE_SYSTEMD_JOURNAL
+ if (sd_booted () > 0) {
+ child_setup_func = (GSpawnChildSetupFunc) on_child_setup;
+ child_setup_data = app;
+ }
++#endif
+
+ handler = g_signal_connect (ctx, "launched", G_CALLBACK (app_launched), app);
+ success = g_desktop_app_info_launch_uris_as_manager (priv->app_info,
diff --git a/x11/gnome-session/files/patch-gnome-session_gsm-consolekit.c b/x11/gnome-session/files/patch-gnome-session_gsm-consolekit.c
new file mode 100644
index 000000000000..b26616c7ab86
--- /dev/null
+++ b/x11/gnome-session/files/patch-gnome-session_gsm-consolekit.c
@@ -0,0 +1,975 @@
+--- gnome-session/gsm-consolekit.c.orig 2024-12-30 10:33:10 UTC
++++ gnome-session/gsm-consolekit.c
+@@ -0,0 +1,972 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
++ *
++ * Copyright (C) 2008 Jon McCann <jmccann@redhat.com>
++ *
++ * 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, 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 <errno.h>
++#include <string.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <sys/types.h>
++#include <pwd.h>
++
++#include <glib.h>
++#include <glib-object.h>
++#include <glib/gi18n.h>
++#include <gio/gio.h>
++#include <gio/gunixfdlist.h>
++
++#include "gsm-system.h"
++#include "gsm-consolekit.h"
++
++#define CK_NAME "org.freedesktop.ConsoleKit"
++
++#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager"
++#define CK_MANAGER_INTERFACE CK_NAME ".Manager"
++#define CK_SEAT_INTERFACE CK_NAME ".Seat"
++#define CK_SESSION_INTERFACE CK_NAME ".Session"
++
++
++struct _GsmConsolekitPrivate
++{
++ GDBusProxy *ck_proxy;
++ GDBusProxy *ck_session_proxy;
++
++ char *session_id;
++ gchar *session_path;
++
++ const gchar *inhibit_locks;
++ gint inhibit_fd;
++
++ gboolean is_active;
++
++ gint delay_inhibit_fd;
++ gboolean prepare_for_shutdown_expected;
++};
++
++enum {
++ PROP_0,
++ PROP_ACTIVE
++};
++
++static void gsm_consolekit_system_init (GsmSystemInterface *iface);
++
++G_DEFINE_TYPE_WITH_CODE (GsmConsolekit, gsm_consolekit, G_TYPE_OBJECT,
++ G_IMPLEMENT_INTERFACE (GSM_TYPE_SYSTEM,
++ gsm_consolekit_system_init))
++
++static void
++drop_system_inhibitor (GsmConsolekit *manager)
++{
++ if (manager->priv->inhibit_fd != -1) {
++ g_debug ("GsmConsolekit: Dropping system inhibitor fd %d", manager->priv->inhibit_fd);
++ close (manager->priv->inhibit_fd);
++ manager->priv->inhibit_fd = -1;
++ }
++}
++
++static void
++drop_delay_inhibitor (GsmConsolekit *manager)
++{
++ if (manager->priv->delay_inhibit_fd != -1) {
++ g_debug ("GsmConsolekit: Dropping delay inhibitor");
++ close (manager->priv->delay_inhibit_fd);
++ manager->priv->delay_inhibit_fd = -1;
++ }
++}
++
++static void
++gsm_consolekit_finalize (GObject *object)
++{
++ GsmConsolekit *consolekit = GSM_CONSOLEKIT (object);
++
++ g_clear_object (&consolekit->priv->ck_proxy);
++ g_clear_object (&consolekit->priv->ck_session_proxy);
++ free (consolekit->priv->session_id);
++ g_free (consolekit->priv->session_path);
++
++ drop_system_inhibitor (consolekit);
++ drop_delay_inhibitor (consolekit);
++
++ G_OBJECT_CLASS (gsm_consolekit_parent_class)->finalize (object);
++}
++
++static void
++gsm_consolekit_set_property (GObject *object,
++ guint prop_id,
++ const GValue *value,
++ GParamSpec *pspec)
++{
++ GsmConsolekit *self = GSM_CONSOLEKIT (object);
++
++ switch (prop_id) {
++ case PROP_ACTIVE:
++ self->priv->is_active = g_value_get_boolean (value);
++ break;
++ default:
++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
++ }
++}
++
++static void
++gsm_consolekit_get_property (GObject *object,
++ guint prop_id,
++ GValue *value,
++ GParamSpec *pspec)
++{
++ GsmConsolekit *self = GSM_CONSOLEKIT (object);
++
++ switch (prop_id) {
++ case PROP_ACTIVE:
++ g_value_set_boolean (value, self->priv->is_active);
++ break;
++ default:
++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
++ break;
++ }
++}
++
++static void
++gsm_consolekit_class_init (GsmConsolekitClass *manager_class)
++{
++ GObjectClass *object_class;
++
++ object_class = G_OBJECT_CLASS (manager_class);
++
++ object_class->get_property = gsm_consolekit_get_property;
++ object_class->set_property = gsm_consolekit_set_property;
++ object_class->finalize = gsm_consolekit_finalize;
++
++ g_object_class_override_property (object_class, PROP_ACTIVE, "active");
++
++ g_type_class_add_private (manager_class, sizeof (GsmConsolekitPrivate));
++}
++
++static void ck_session_proxy_signal_cb (GDBusProxy *proxy,
++ const gchar *sender_name,
++ const gchar *signal_name,
++ GVariant *parameters,
++ gpointer user_data);
++
++static void ck_proxy_signal_cb (GDBusProxy *proxy,
++ const gchar *sender_name,
++ const gchar *signal_name,
++ GVariant *parameters,
++ gpointer user_data);
++
++static void
++ck_pid_get_session (GsmConsolekit *manager,
++ pid_t pid,
++ gchar **session_id)
++{
++ GVariant *res;
++
++ *session_id = NULL;
++
++ if (pid < 0) {
++ g_warning ("Calling GetSessionForUnixProcess failed."
++ "Invalid pid.");
++ return;
++ }
++
++ res = g_dbus_proxy_call_sync (manager->priv->ck_proxy,
++ "GetSessionForUnixProcess",
++ g_variant_new ("(u)", pid),
++ 0,
++ -1,
++ NULL,
++ NULL);
++ if (!res) {
++ g_warning ("Calling GetSessionForUnixProcess failed."
++ "Check that ConsoleKit is properly installed.");
++ return;
++ }
++
++ g_variant_get (res, "(o)", session_id);
++ g_variant_unref (res);
++}
++
++static void
++gsm_consolekit_init (GsmConsolekit *manager)
++{
++ GError *error = NULL;
++ GDBusConnection *bus;
++ GVariant *res;
++
++ manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
++ GSM_TYPE_CONSOLEKIT,
++ GsmConsolekitPrivate);
++
++ manager->priv->inhibit_fd = -1;
++ manager->priv->delay_inhibit_fd = -1;
++
++ bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
++ if (bus == NULL)
++ g_error ("Failed to connect to system bus: %s",
++ error->message);
++ manager->priv->ck_proxy =
++ g_dbus_proxy_new_sync (bus,
++ 0,
++ NULL,
++ CK_NAME,
++ CK_MANAGER_PATH,
++ CK_MANAGER_INTERFACE,
++ NULL,
++ &error);
++ if (manager->priv->ck_proxy == NULL) {
++ g_warning ("Failed to connect to consolekit: %s",
++ error->message);
++ g_clear_error (&error);
++ }
++
++ g_signal_connect (manager->priv->ck_proxy, "g-signal",
++ G_CALLBACK (ck_proxy_signal_cb), manager);
++
++ ck_pid_get_session (manager, getpid (), &manager->priv->session_id);
++
++ if (manager->priv->session_id == NULL) {
++ g_warning ("Could not get session id for session. Check that ConsoleKit is "
++ "properly installed.");
++ return;
++ }
++
++ /* in ConsoleKit, the session id is the session path */
++ manager->priv->session_path = g_strdup (manager->priv->session_id);
++
++ manager->priv->ck_session_proxy =
++ g_dbus_proxy_new_sync (bus,
++ 0,
++ NULL,
++ CK_NAME,
++ manager->priv->session_path,
++ CK_SESSION_INTERFACE,
++ NULL,
++ &error);
++ if (manager->priv->ck_proxy == NULL) {
++ g_warning ("Failed to connect to consolekit session: %s",
++ error->message);
++ g_clear_error (&error);
++ }
++
++ g_signal_connect (manager->priv->ck_session_proxy, "g-signal",
++ G_CALLBACK (ck_session_proxy_signal_cb), manager);
++
++ g_object_unref (bus);
++}
++
++static void
++emit_restart_complete (GsmConsolekit *manager,
++ GError *error)
++{
++ GError *call_error;
++
++ call_error = NULL;
++
++ if (error != NULL) {
++ call_error = g_error_new_literal (GSM_SYSTEM_ERROR,
++ GSM_SYSTEM_ERROR_RESTARTING,
++ error->message);
++ }
++
++ g_signal_emit_by_name (G_OBJECT (manager),
++ "request_completed", call_error);
++
++ if (call_error != NULL) {
++ g_error_free (call_error);
++ }
++}
++
++static void
++emit_stop_complete (GsmConsolekit *manager,
++ GError *error)
++{
++ GError *call_error;
++
++ call_error = NULL;
++
++ if (error != NULL) {
++ call_error = g_error_new_literal (GSM_SYSTEM_ERROR,
++ GSM_SYSTEM_ERROR_STOPPING,
++ error->message);
++ }
++
++ g_signal_emit_by_name (G_OBJECT (manager),
++ "request_completed", call_error);
++
++ if (call_error != NULL) {
++ g_error_free (call_error);
++ }
++}
++
++static void
++restart_done (GObject *source,
++ GAsyncResult *result,
++ gpointer user_data)
++{
++ GDBusProxy *proxy = G_DBUS_PROXY (source);
++ GsmConsolekit *manager = user_data;
++ GError *error = NULL;
++ GVariant *res;
++
++ res = g_dbus_proxy_call_finish (proxy, result, &error);
++
++ if (!res) {
++ g_warning ("Unable to restart system: %s", error->message);
++ emit_restart_complete (manager, error);
++ g_error_free (error);
++ } else {
++ emit_restart_complete (manager, NULL);
++ g_variant_unref (res);
++ }
++}
++
++static void
++gsm_consolekit_attempt_restart (GsmSystem *system)
++{
++ GsmConsolekit *manager = GSM_CONSOLEKIT (system);
++
++ /* Use Restart instead of Reboot because it will work on
++ * both CK and CK2 */
++ g_dbus_proxy_call (manager->priv->ck_proxy,
++ "Restart",
++ g_variant_new ("()"),
++ 0,
++ G_MAXINT,
++ NULL,
++ restart_done,
++ manager);
++}
++
++static void
++stop_done (GObject *source,
++ GAsyncResult *result,
++ gpointer user_data)
++{
++ GDBusProxy *proxy = G_DBUS_PROXY (source);
++ GsmConsolekit *manager = user_data;
++ GError *error = NULL;
++ GVariant *res;
++
++ res = g_dbus_proxy_call_finish (proxy, result, &error);
++
++ if (!res) {
++ g_warning ("Unable to stop system: %s", error->message);
++ emit_stop_complete (manager, error);
++ g_error_free (error);
++ } else {
++ emit_stop_complete (manager, NULL);
++ g_variant_unref (res);
++ }
++}
++
++static void
++gsm_consolekit_attempt_stop (GsmSystem *system)
++{
++ GsmConsolekit *manager = GSM_CONSOLEKIT (system);
++
++ /* Use Stop insetad of PowerOff because it will work with
++ * Ck and CK2. */
++ g_dbus_proxy_call (manager->priv->ck_proxy,
++ "Stop",
++ g_variant_new ("()"),
++ 0,
++ G_MAXINT,
++ NULL,
++ stop_done,
++ manager);
++}
++
++static void
++gsm_consolekit_set_session_idle (GsmSystem *system,
++ gboolean is_idle)
++{
++ GsmConsolekit *manager = GSM_CONSOLEKIT (system);
++
++ g_debug ("Updating consolekit idle status: %d", is_idle);
++ g_dbus_proxy_call_sync (manager->priv->ck_session_proxy,
++ "SetIdleHint",
++ g_variant_new ("(b)", is_idle),
++ 0,
++ G_MAXINT,
++ NULL, NULL);
++}
++
++static void
++ck_session_get_seat (GsmConsolekit *manager,
++ gchar **seat)
++{
++ GVariant *res;
++
++ *seat = NULL;
++
++ res = g_dbus_proxy_call_sync (manager->priv->ck_session_proxy,
++ "GetSeatId",
++ g_variant_new ("()"),
++ 0,
++ -1,
++ NULL, NULL);
++ if (!res) {
++ g_warning ("GsmConsoleKit: Calling GetSeatId failed.");
++ return;
++ }
++
++ g_variant_get (res, "(o)", seat);
++ g_variant_unref (res);
++}
++
++/* returns -1 on failure
++ * 0 seat is multi-session
++ * 1 seat is not multi-session
++ */
++static gint
++ck_seat_can_multi_session (GsmConsolekit *manager,
++ const gchar *seat)
++{
++ GDBusConnection *bus;
++ GVariant *res;
++ gboolean can_activate;
++
++
++ bus = g_dbus_proxy_get_connection (manager->priv->ck_proxy);
++ res = g_dbus_connection_call_sync (bus,
++ CK_NAME,
++ seat,
++ CK_SEAT_INTERFACE,
++ "CanActivateSessions",
++ g_variant_new ("()"),
++ G_VARIANT_TYPE_BOOLEAN,
++ 0,
++ -1,
++ NULL, NULL);
++ if (!res) {
++ g_warning ("GsmConsoleKit: Calling GetSeatId failed.");
++ return -1;
++ }
++
++ g_variant_get (res, "(b)", &can_activate);
++ g_variant_unref (res);
++
++ return can_activate == TRUE ? 1 : 0;
++}
++
++static gboolean
++gsm_consolekit_can_switch_user (GsmSystem *system)
++{
++ GsmConsolekit *manager = GSM_CONSOLEKIT (system);
++ gchar *seat;
++ gint ret;
++
++ ck_session_get_seat (manager, &seat);
++ ret = ck_seat_can_multi_session (manager, seat);
++ free (seat);
++
++ return ret > 0;
++}
++
++static gboolean
++gsm_consolekit_can_restart (GsmSystem *system)
++{
++ GsmConsolekit *manager = GSM_CONSOLEKIT (system);
++ GVariant *res;
++ gboolean can_restart;
++
++ res = g_dbus_proxy_call_sync (manager->priv->ck_proxy,
++ "CanRestart",
++ g_variant_new ("()"),
++ 0,
++ G_MAXINT,
++ NULL,
++ NULL);
++ if (!res) {
++ g_warning ("Calling CanRestart failed. Check that ConsoleKit is "
++ "properly installed.");
++ return FALSE;
++ }
++
++ g_variant_get (res, "(b)", &can_restart);
++ g_variant_unref (res);
++
++ return can_restart;
++}
++
++static gboolean
++gsm_consolekit_can_stop (GsmSystem *system)
++{
++ GsmConsolekit *manager = GSM_CONSOLEKIT (system);
++ GVariant *res;
++ gboolean can_stop;
++
++ res = g_dbus_proxy_call_sync (manager->priv->ck_proxy,
++ "CanStop",
++ g_variant_new ("()"),
++ 0,
++ G_MAXINT,
++ NULL,
++ NULL);
++ if (!res) {
++ g_warning ("Calling CanStop failed. Check that ConsoleKit is "
++ "properly installed.");
++ return FALSE;
++ }
++
++ g_variant_get (res, "(b)", &can_stop);
++ g_variant_unref (res);
++
++ return can_stop;
++}
++
++/* returns -1 on failure, 0 on success */
++static gint
++ck_session_get_class (GsmConsolekit *manager,
++ gchar **session_class)
++{
++ GVariant *res;
++
++ *session_class = NULL;
++
++ res = g_dbus_proxy_call_sync (manager->priv->ck_session_proxy,
++ "GetSessionClass",
++ g_variant_new ("()"),
++ 0,
++ -1,
++ NULL, NULL);
++ if (!res) {
++ g_warning ("GsmConsoleKit: Calling GetSessionClass failed.");
++ return -1;
++ }
++
++ g_variant_get (res, "(s)", session_class);
++ g_variant_unref (res);
++
++ return 0;
++}
++
++static gboolean
++gsm_consolekit_is_login_session (GsmSystem *system)
++{
++ GsmConsolekit *manager = GSM_CONSOLEKIT (system);
++ int res;
++ gboolean ret;
++ gchar *session_class = NULL;
++
++ ret = FALSE;
++
++ if (manager->priv->session_id == NULL) {
++ return ret;
++ }
++
++ res = ck_session_get_class (manager, &session_class);
++ if (res < 0) {
++ g_warning ("Could not get session class: %s", strerror (-res));
++ return FALSE;
++ }
++ ret = (g_strcmp0 (session_class, "greeter") == 0);
++ g_free (session_class);
++
++ return ret;
++}
++
++static gboolean
++gsm_consolekit_can_suspend (GsmSystem *system)
++{
++ GsmConsolekit *manager = GSM_CONSOLEKIT (system);
++ gchar *rv;
++ GVariant *res;
++ gboolean can_suspend;
++
++ res = g_dbus_proxy_call_sync (manager->priv->ck_proxy,
++ "CanSuspend",
++ NULL,
++ 0,
++ G_MAXINT,
++ NULL,
++ NULL);
++ if (!res) {
++ g_warning ("Calling CanSuspend failed. Check that ConsoleKit is "
++ "properly installed.");
++ return FALSE;
++ }
++
++ g_variant_get (res, "(s)", &rv);
++ g_variant_unref (res);
++
++ can_suspend = g_strcmp0 (rv, "yes") == 0 ||
++ g_strcmp0 (rv, "challenge") == 0;
++
++ g_free (rv);
++
++ return can_suspend;
++}
++
++static gboolean
++gsm_consolekit_can_hibernate (GsmSystem *system)
++{
++ GsmConsolekit *manager = GSM_CONSOLEKIT (system);
++ gchar *rv;
++ GVariant *res;
++ gboolean can_hibernate;
++
++ res = g_dbus_proxy_call_sync (manager->priv->ck_proxy,
++ "CanHibernate",
++ NULL,
++ 0,
++ G_MAXINT,
++ NULL,
++ NULL);
++ if (!res) {
++ g_warning ("Calling CanHibernate failed. Check that ConsoleKit is "
++ "properly installed.");
++ return FALSE;
++ }
++
++ g_variant_get (res, "(s)", &rv);
++ g_variant_unref (res);
++
++ can_hibernate = g_strcmp0 (rv, "yes") == 0 ||
++ g_strcmp0 (rv, "challenge") == 0;
++
++ g_free (rv);
++
++ return can_hibernate;
++}
++
++static void
++suspend_done (GObject *source,
++ GAsyncResult *result,
++ gpointer user_data)
++{
++ GDBusProxy *proxy = G_DBUS_PROXY (source);
++ GError *error = NULL;
++ GVariant *res;
++
++ res = g_dbus_proxy_call_finish (proxy, result, &error);
++
++ if (!res) {
++ g_warning ("Unable to suspend system: %s", error->message);
++ g_error_free (error);
++ } else {
++ g_variant_unref (res);
++ }
++}
++
++static void
++hibernate_done (GObject *source,
++ GAsyncResult *result,
++ gpointer user_data)
++{
++ GDBusProxy *proxy = G_DBUS_PROXY (source);
++ GError *error = NULL;
++ GVariant *res;
++
++ res = g_dbus_proxy_call_finish (proxy, result, &error);
++
++ if (!res) {
++ g_warning ("Unable to hibernate system: %s", error->message);
++ g_error_free (error);
++ } else {
++ g_variant_unref (res);
++ }
++}
++
++static void
++gsm_consolekit_suspend (GsmSystem *system)
++{
++ GsmConsolekit *manager = GSM_CONSOLEKIT (system);
++
++ g_dbus_proxy_call (manager->priv->ck_proxy,
++ "Suspend",
++ g_variant_new ("(b)", TRUE),
++ 0,
++ G_MAXINT,
++ NULL,
++ suspend_done,
++ manager);
++}
++
++static void
++gsm_consolekit_hibernate (GsmSystem *system)
++{
++ GsmConsolekit *manager = GSM_CONSOLEKIT (system);
++
++ g_dbus_proxy_call (manager->priv->ck_proxy,
++ "Hibernate",
++ g_variant_new ("(b)", TRUE),
++ 0,
++ G_MAXINT,
++ NULL,
++ hibernate_done,
++ manager);
++}
++
++static void
++inhibit_done (GObject *source,
++ GAsyncResult *result,
++ gpointer user_data)
++{
++ GDBusProxy *proxy = G_DBUS_PROXY (source);
++ GsmConsolekit *manager = GSM_CONSOLEKIT (user_data);
++ GError *error = NULL;
++ GVariant *res;
++ GUnixFDList *fd_list = NULL;
++ gint idx;
++
++ /* Drop any previous inhibit before recording the new one */
++ drop_system_inhibitor (manager);
++
++ res = g_dbus_proxy_call_with_unix_fd_list_finish (proxy, &fd_list, result, &error);
++
++ if (!res) {
++ g_warning ("Unable to inhibit system: %s", error->message);
++ g_error_free (error);
++ } else {
++ g_variant_get (res, "(h)", &idx);
++ manager->priv->inhibit_fd = g_unix_fd_list_get (fd_list, idx, &error);
++ if (manager->priv->inhibit_fd == -1) {
++ g_warning ("Failed to receive system inhibitor fd: %s", error->message);
++ g_error_free (error);
++ }
++ g_debug ("System inhibitor fd is %d", manager->priv->inhibit_fd);
++ g_object_unref (fd_list);
++ g_variant_unref (res);
++ }
++
++ /* Handle a race condition, where locks got unset during dbus call */
++ if (manager->priv->inhibit_locks == NULL) {
++ drop_system_inhibitor (manager);
++ }
++}
++
++static void
++gsm_consolekit_set_inhibitors (GsmSystem *system,
++ GsmInhibitorFlag flags)
++{
++ GsmConsolekit *manager = GSM_CONSOLEKIT (system);
++ const gchar *locks = NULL;
++ gboolean inhibit_logout;
++ gboolean inhibit_suspend;
++
++ inhibit_logout = (flags & GSM_INHIBITOR_FLAG_LOGOUT) != 0;
++ inhibit_suspend = (flags & GSM_INHIBITOR_FLAG_SUSPEND) != 0;
++
++ if (inhibit_logout && inhibit_suspend) {
++ locks = "sleep:shutdown";
++ } else if (inhibit_logout) {
++ locks = "shutdown";
++ } else if (inhibit_suspend) {
++ locks = "sleep";
++ }
++ manager->priv->inhibit_locks = locks;
++
++ if (locks != NULL) {
++ g_debug ("Adding system inhibitor on %s", locks);
++ g_dbus_proxy_call_with_unix_fd_list (manager->priv->ck_proxy,
++ "Inhibit",
++ g_variant_new ("(ssss)",
++ locks,
++ g_get_user_name (),
++ "user session inhibited",
++ "block"),
++ 0,
++ G_MAXINT,
++ NULL,
++ NULL,
++ inhibit_done,
++ manager);
++ } else {
++ drop_system_inhibitor (manager);
++ }
++}
++
++static void
++reboot_or_poweroff_done (GObject *source,
++ GAsyncResult *res,
++ gpointer user_data)
++{
++ GsmConsolekit *consolekit = user_data;
++ GVariant *result;
++ GError *error = NULL;
++
++ result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source),
++ res,
++ &error);
++
++ if (result == NULL) {
++ if (!g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED)) {
++ g_warning ("Shutdown failed: %s", error->message);
++ }
++ g_error_free (error);
++ drop_delay_inhibitor (consolekit);
++ g_debug ("GsmConsolekit: shutdown preparation failed");
++ consolekit->priv->prepare_for_shutdown_expected = FALSE;
++ g_signal_emit_by_name (consolekit, "shutdown-prepared", FALSE);
++ } else {
++ g_variant_unref (result);
++ }
++}
++
++static void
++gsm_consolekit_prepare_shutdown (GsmSystem *system,
++ gboolean restart)
++{
++ GsmConsolekit *consolekit = GSM_CONSOLEKIT (system);
++ GUnixFDList *fd_list;
++ GVariant *res;
++ GError *error = NULL;
++ gint idx;
++
++ g_debug ("GsmConsolekit: prepare shutdown");
++
++ res = g_dbus_proxy_call_with_unix_fd_list_sync (consolekit->priv->ck_proxy,
++ "Inhibit",
++ g_variant_new ("(ssss)",
++ "shutdown",
++ g_get_user_name (),
++ "Preparing to end the session",
++ "delay"),
++ 0,
++ G_MAXINT,
++ NULL,
++ &fd_list,
++ NULL,
++ &error);
++ if (res == NULL) {
++ g_warning ("Failed to get delay inhibitor: %s", error->message);
++ g_error_free (error);
++ /* We may fail here with CK and that's ok */
++ } else {
++ g_variant_get (res, "(h)", &idx);
++
++ consolekit->priv->delay_inhibit_fd = g_unix_fd_list_get (fd_list, idx, NULL);
++
++ g_debug ("GsmConsolekit: got delay inhibitor, fd = %d", consolekit->priv->delay_inhibit_fd);
++
++ g_variant_unref (res);
++ g_object_unref (fd_list);
++ }
++
++ consolekit->priv->prepare_for_shutdown_expected = TRUE;
++
++ g_dbus_proxy_call (consolekit->priv->ck_proxy,
++ restart ? "Reboot" : "PowerOff",
++ g_variant_new ("(b)", TRUE),
++ 0,
++ G_MAXINT,
++ NULL,
++ reboot_or_poweroff_done,
++ consolekit);
++}
++
++static void
++gsm_consolekit_complete_shutdown (GsmSystem *system)
++{
++ GsmConsolekit *consolekit = GSM_CONSOLEKIT (system);
++
++ /* remove delay inhibitor, if any */
++ drop_delay_inhibitor (consolekit);
++}
++
++static gboolean
++gsm_consolekit_is_last_session_for_user (GsmSystem *system)
++{
++ return FALSE;
++}
++
++static void
++gsm_consolekit_system_init (GsmSystemInterface *iface)
++{
++ iface->can_switch_user = gsm_consolekit_can_switch_user;
++ iface->can_stop = gsm_consolekit_can_stop;
++ iface->can_restart = gsm_consolekit_can_restart;
++ iface->can_suspend = gsm_consolekit_can_suspend;
++ iface->can_hibernate = gsm_consolekit_can_hibernate;
++ iface->attempt_stop = gsm_consolekit_attempt_stop;
++ iface->attempt_restart = gsm_consolekit_attempt_restart;
++ iface->suspend = gsm_consolekit_suspend;
++ iface->hibernate = gsm_consolekit_hibernate;
++ iface->set_session_idle = gsm_consolekit_set_session_idle;
++ iface->is_login_session = gsm_consolekit_is_login_session;
++ iface->set_inhibitors = gsm_consolekit_set_inhibitors;
++ iface->prepare_shutdown = gsm_consolekit_prepare_shutdown;
++ iface->complete_shutdown = gsm_consolekit_complete_shutdown;
++ iface->is_last_session_for_user = gsm_consolekit_is_last_session_for_user;
++}
++
++GsmConsolekit *
++gsm_consolekit_new (void)
++{
++ GsmConsolekit *manager;
++
++ manager = g_object_new (GSM_TYPE_CONSOLEKIT, NULL);
++
++ return manager;
++}
++
++static void
++ck_proxy_signal_cb (GDBusProxy *proxy,
++ const gchar *sender_name,
++ const gchar *signal_name,
++ GVariant *parameters,
++ gpointer user_data)
++{
++ GsmConsolekit *consolekit = user_data;
++ gboolean is_about_to_shutdown;
++
++ g_debug ("GsmConsolekit: received ConsoleKit signal: %s", signal_name);
++
++ if (g_strcmp0 (signal_name, "PrepareForShutdown") != 0) {
++ g_debug ("GsmConsolekit: ignoring %s signal", signal_name);
++ return;
++ }
++
++ g_variant_get (parameters, "(b)", &is_about_to_shutdown);
++ if (!is_about_to_shutdown) {
++ g_debug ("GsmConsolekit: ignoring %s signal since about-to-shutdown is FALSE", signal_name);
++ return;
++ }
++
++ if (consolekit->priv->prepare_for_shutdown_expected) {
++ g_debug ("GsmConsolekit: shutdown successfully prepared");
++ g_signal_emit_by_name (consolekit, "shutdown-prepared", TRUE);
++ consolekit->priv->prepare_for_shutdown_expected = FALSE;
++ }
++}
++
++static void
++ck_session_proxy_signal_cb (GDBusProxy *proxy,
++ const gchar *sender_name,
++ const gchar *signal_name,
++ GVariant *parameters,
++ gpointer user_data)
++{
++ GsmConsolekit *consolekit = user_data;
++ gboolean is_active;
++
++ g_debug ("GsmConsolekit: received ConsoleKit signal: %s", signal_name);
++
++ if (g_strcmp0 (signal_name, "ActiveChanged") != 0) {
++ g_debug ("GsmConsolekit: ignoring %s signal", signal_name);
++ return;
++ }
++
++ g_variant_get (parameters, "(b)", &is_active);
++ if (consolekit->priv->is_active != is_active) {
++ g_debug ("GsmConsolekit: session state changed");
++ consolekit->priv->is_active = is_active;
++ g_object_notify (G_OBJECT (consolekit), "active");
++ }
++}
diff --git a/x11/gnome-session/files/patch-gnome-session_gsm-consolekit.h b/x11/gnome-session/files/patch-gnome-session_gsm-consolekit.h
new file mode 100644
index 000000000000..63e556f715f7
--- /dev/null
+++ b/x11/gnome-session/files/patch-gnome-session_gsm-consolekit.h
@@ -0,0 +1,62 @@
+--- gnome-session/gsm-consolekit.h.orig 2024-12-30 10:33:15 UTC
++++ gnome-session/gsm-consolekit.h
+@@ -0,0 +1,59 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
++ *
++ * Copyright (C) 2008 Jon McCann <jmccann@redhat.com>
++ *
++ * 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/>.
++ *
++ * Authors:
++ * Jon McCann <jmccann@redhat.com>
++ */
++
++#ifndef __GSM_CONSOLEKIT_H__
++#define __GSM_CONSOLEKIT_H__
++
++#include <glib.h>
++#include <glib-object.h>
++
++G_BEGIN_DECLS
++
++#define GSM_TYPE_CONSOLEKIT (gsm_consolekit_get_type ())
++#define GSM_CONSOLEKIT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSM_TYPE_CONSOLEKIT, GsmConsolekit))
++#define GSM_CONSOLEKIT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSM_TYPE_CONSOLEKIT, GsmConsolekitClass))
++#define GSM_IS_CONSOLEKIT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSM_TYPE_CONSOLEKIT))
++#define GSM_IS_CONSOLEKIT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSM_TYPE_CONSOLEKIT))
++#define GSM_CONSOLEKIT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GSM_TYPE_CONSOLEKIT, GsmConsolekitClass))
++
++typedef struct _GsmConsolekit GsmConsolekit;
++typedef struct _GsmConsolekitClass GsmConsolekitClass;
++typedef struct _GsmConsolekitPrivate GsmConsolekitPrivate;
++
++struct _GsmConsolekit
++{
++ GObject parent;
++
++ GsmConsolekitPrivate *priv;
++};
++
++struct _GsmConsolekitClass
++{
++ GObjectClass parent_class;
++};
++
++GType gsm_consolekit_get_type (void);
++
++GsmConsolekit *gsm_consolekit_new (void) G_GNUC_MALLOC;
++
++G_END_DECLS
++
++#endif /* __GSM_CONSOLEKIT_H__ */
diff --git a/x11/gnome-session/files/patch-gnome-session_gsm-manager.c b/x11/gnome-session/files/patch-gnome-session_gsm-manager.c
new file mode 100644
index 000000000000..fc6d94346b86
--- /dev/null
+++ b/x11/gnome-session/files/patch-gnome-session_gsm-manager.c
@@ -0,0 +1,86 @@
+--- gnome-session/gsm-manager.c.orig 2024-09-19 12:36:55 UTC
++++ gnome-session/gsm-manager.c
+@@ -40,9 +40,17 @@
+ #include "gsm-manager.h"
+ #include "org.gnome.SessionManager.h"
+
++#ifdef ENABLE_SYSTEMD_JOURNAL
+ #include <systemd/sd-journal.h>
++#endif
+
++#ifdef HAVE_SYSTEMD
+ #include <systemd/sd-daemon.h>
++#else
++/* So we don't need to add ifdef's everywhere */
++#define sd_notify(u, m) do {} while (0)
++#define sd_notifyf(u, m, ...) do {} while (0)
++#endif
+
+ #include "gsm-store.h"
+ #include "gsm-inhibitor.h"
+@@ -280,10 +288,12 @@ on_required_app_failure (GsmManager *manager,
+ allow_logout = !_log_out_is_locked_down (manager);
+ }
+
++#ifdef ENABLE_SYSTEMD_JOURNAL
+ sd_journal_send ("MESSAGE_ID=%s", GSM_MANAGER_UNRECOVERABLE_FAILURE_MSGID,
+ "PRIORITY=%d", 3,
+ "MESSAGE=Unrecoverable failure in required component %s", app_id,
+ NULL);
++#endif
+
+ gsm_fail_whale_dialog_we_failed (FALSE,
+ allow_logout,
+@@ -308,10 +318,12 @@ on_display_server_failure (GsmManager *manager,
+ extensions = NULL;
+ }
+
++#ifdef ENABLE_SYSTEMD_JOURNAL
+ sd_journal_send ("MESSAGE_ID=%s", GSM_MANAGER_UNRECOVERABLE_FAILURE_MSGID,
+ "PRIORITY=%d", 3,
+ "MESSAGE=Unrecoverable failure in required component %s", app_id,
+ NULL);
++#endif
+
+ gsm_quit ();
+ }
+@@ -966,6 +978,7 @@ _client_stop (const char *id,
+ return FALSE;
+ }
+
++#ifdef HAVE_SYSTEMD
+ static void
+ maybe_restart_user_bus (GsmManager *manager)
+ {
+@@ -998,6 +1011,7 @@ maybe_restart_user_bus (GsmManager *manager)
+ g_debug ("GsmManager: reloading user bus failed: %s", error->message);
+ }
+ }
++#endif
+
+ static void
+ do_phase_exit (GsmManager *manager)
+@@ -1010,8 +1024,10 @@ do_phase_exit (GsmManager *manager)
+ NULL);
+ }
+
++#ifdef HAVE_SYSTEMD
+ if (!priv->systemd_managed)
+ maybe_restart_user_bus (manager);
++#endif
+
+ end_phase (manager);
+ }
+@@ -1405,10 +1421,12 @@ start_phase (GsmManager *manager)
+ do_phase_startup (manager);
+ break;
+ case GSM_MANAGER_PHASE_RUNNING:
++#ifdef ENABLE_SYSTEMD_JOURNAL
+ sd_journal_send ("MESSAGE_ID=%s", GSM_MANAGER_STARTUP_SUCCEEDED_MSGID,
+ "PRIORITY=%d", 5,
+ "MESSAGE=Entering running state",
+ NULL);
++#endif
+ #ifdef HAVE_X11
+ gsm_xsmp_server_start_accepting_new_clients (priv->xsmp_server);
+ #endif
diff --git a/x11/gnome-session/files/patch-gnome-session_gsm-system.c b/x11/gnome-session/files/patch-gnome-session_gsm-system.c
new file mode 100644
index 000000000000..4fe324d35e2d
--- /dev/null
+++ b/x11/gnome-session/files/patch-gnome-session_gsm-system.c
@@ -0,0 +1,28 @@
+--- gnome-session/gsm-system.c.orig 2024-03-18 19:30:06 UTC
++++ gnome-session/gsm-system.c
+@@ -25,6 +25,9 @@
+
+ #include "gsm-systemd.h"
+
++#ifdef HAVE_CONSOLEKIT
++#include "gsm-consolekit.h"
++#endif
+
+ enum {
+ REQUEST_COMPLETED,
+@@ -266,6 +269,15 @@ gsm_get_system (void)
+ g_debug ("Using systemd for session tracking");
+ }
+ }
++
++#ifdef HAVE_CONSOLEKIT
++ if (system == NULL) {
++ system = GSM_SYSTEM (gsm_consolekit_new ());
++ if (system != NULL) {
++ g_debug ("Using ConsoleKit for session tracking");
++ }
++ }
++#endif
+
+ if (system == NULL) {
+ system = g_object_new (gsm_system_null_get_type (), NULL);
diff --git a/x11/gnome-session/files/patch-gnome-session_gsm-systemd.c b/x11/gnome-session/files/patch-gnome-session_gsm-systemd.c
new file mode 100644
index 000000000000..5c1c3b533983
--- /dev/null
+++ b/x11/gnome-session/files/patch-gnome-session_gsm-systemd.c
@@ -0,0 +1,25 @@
+--- gnome-session/gsm-systemd.c.orig 2024-03-18 19:30:06 UTC
++++ gnome-session/gsm-systemd.c
+@@ -21,6 +21,8 @@
+ #include "config.h"
+ #include "gsm-systemd.h"
+
++#ifdef HAVE_SYSTEMD
++
+ #include <errno.h>
+ #include <string.h>
+ #include <stdlib.h>
+@@ -1169,4 +1171,13 @@ sd_proxy_signal_cb (GDBusProxy *proxy,
+ }
+ }
+
++#else
++
++GsmSystemd *
++gsm_systemd_new (void)
++{
++ return NULL;
++}
++
++#endif
+
diff --git a/x11/gnome-session/files/patch-gnome-session_gsm-util.c b/x11/gnome-session/files/patch-gnome-session_gsm-util.c
new file mode 100644
index 000000000000..8d7b2c9fd1dd
--- /dev/null
+++ b/x11/gnome-session/files/patch-gnome-session_gsm-util.c
@@ -0,0 +1,46 @@
+--- gnome-session/gsm-util.c.orig 2024-03-18 19:30:06 UTC
++++ gnome-session/gsm-util.c
+@@ -73,12 +73,6 @@ static const char * const variable_unsetlist[] = {
+ "LC_COLLATE",
+ "LC_MONETARY",
+ "LC_MESSAGES",
+- "LC_PAPER",
+- "LC_NAME",
+- "LC_ADDRESS",
+- "LC_TELEPHONE",
+- "LC_MEASUREMENT",
+- "LC_IDENTIFICATION",
+ "LC_ALL",
+
+ NULL
+@@ -626,6 +620,7 @@ gsm_util_export_activation_environment (GError **e
+ return environment_updated;
+ }
+
++#ifdef HAVE_SYSTEMD
+ gboolean
+ gsm_util_export_user_environment (GError **error)
+ {
+@@ -884,6 +879,7 @@ gsm_util_systemd_reset_failed (GError **error)
+
+ return TRUE;
+ }
++#endif
+
+ void
+ gsm_util_setenv (const char *variable,
+@@ -907,12 +903,14 @@ gsm_util_setenv (const char *variable,
+ g_clear_error (&error);
+ }
+
++#ifdef HAVE_SYSTEMD
+ /* If this fails, the system user session won't get the updated environment
+ */
+ if (!gsm_util_update_user_environment (variable, value, &error)) {
+ g_debug ("Could not make systemd aware of %s=%s environment variable: %s", variable, value, error->message);
+ g_clear_error (&error);
+ }
++#endif
+ }
+
+ const char * const *
diff --git a/x11/gnome-session/files/patch-gnome-session_gsm-util.h b/x11/gnome-session/files/patch-gnome-session_gsm-util.h
new file mode 100644
index 000000000000..ae1cd96aaa41
--- /dev/null
+++ b/x11/gnome-session/files/patch-gnome-session_gsm-util.h
@@ -0,0 +1,18 @@
+--- gnome-session/gsm-util.h.orig 2024-03-18 19:30:06 UTC
++++ gnome-session/gsm-util.h
+@@ -53,6 +53,7 @@ gboolean gsm_util_export_activation_environment (G
+ const char * const * gsm_util_get_variable_blacklist(void);
+
+ gboolean gsm_util_export_activation_environment (GError **error);
++#ifdef HAVE_SYSTEMD
+ gboolean gsm_util_export_user_environment (GError **error);
+ gboolean gsm_util_systemd_unit_is_active (const char *unit,
+ GError **error);
+@@ -61,6 +62,7 @@ gboolean gsm_util_systemd_reset_failed (G
+ GError **error);
+ gboolean gsm_util_systemd_reset_failed (GError **error);
+
++#endif
+
+ void gsm_quit (void);
+
diff --git a/x11/gnome-session/files/patch-gnome-session_main.c b/x11/gnome-session/files/patch-gnome-session_main.c
new file mode 100644
index 000000000000..5db65d523c47
--- /dev/null
+++ b/x11/gnome-session/files/patch-gnome-session_main.c
@@ -0,0 +1,96 @@
+--- gnome-session/main.c.orig 2024-03-18 19:30:06 UTC
++++ gnome-session/main.c
+@@ -43,11 +43,14 @@
+ #include "gsm-system.h"
+ #include "gsm-fail-whale.h"
+
++#ifdef ENABLE_SYSTEMD_JOURNAL
+ #include <systemd/sd-journal.h>
++#endif
+
+ #define GSM_DBUS_NAME "org.gnome.SessionManager"
+
+ static gboolean systemd_service = FALSE;
++static gboolean use_systemd = USE_SYSTEMD_SESSION;
+ static gboolean failsafe = FALSE;
+ static gboolean show_version = FALSE;
+ static gboolean debug = FALSE;
+@@ -280,6 +283,7 @@ initialize_gio (void)
+ }
+ }
+
++#ifdef ENABLE_SYSTEMD_SESSION
+ static gboolean
+ leader_term_or_int_signal_cb (gpointer data)
+ {
+@@ -485,6 +489,7 @@ systemd_leader_run(void)
+ gsm_main ();
+ exit(0);
+ }
++#endif /* ENABLE_SYSTEMD_SESSION */
+
+ int
+ main (int argc, char **argv)
+@@ -499,7 +504,11 @@ main (int argc, char **argv)
+ guint name_owner_id;
+ GOptionContext *options;
+ static GOptionEntry entries[] = {
++#ifdef ENABLE_SYSTEMD_SESSION
+ { "systemd-service", 0, 0, G_OPTION_ARG_NONE, &systemd_service, N_("Running as systemd service"), NULL },
++ { "systemd", 0, 0, G_OPTION_ARG_NONE, &use_systemd, N_("Use systemd session management"), NULL },
++#endif
++ { "builtin", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &use_systemd, N_("Use builtin session management (rather than the systemd based one)"), NULL },
+ { "autostart", 'a', 0, G_OPTION_ARG_STRING_ARRAY, &override_autostart_dirs, N_("Override standard autostart directories"), N_("AUTOSTART_DIR") },
+ { "session", 0, 0, G_OPTION_ARG_STRING, &opt_session_name, N_("Session to use"), N_("SESSION_NAME") },
+ { "debug", 0, 0, G_OPTION_ARG_NONE, &debug, N_("Enable debugging code"), NULL },
+@@ -553,6 +562,7 @@ main (int argc, char **argv)
+ * journald picks ups the nicer "gnome-session" as the program
+ * name instead of whatever shell script GDM happened to use.
+ */
++#ifdef ENABLE_SYSTEMD_JOURNAL
+ if (!debug) {
+ int journalfd;
+
+@@ -562,6 +572,7 @@ main (int argc, char **argv)
+ dup2(journalfd, 2);
+ }
+ }
++#endif
+
+ gdm_log_init ();
+ gdm_log_set_debug (debug);
+@@ -636,12 +647,15 @@ main (int argc, char **argv)
+
+ session_name = opt_session_name;
+
++#ifdef HAVE_SYSTEMD
+ gsm_util_export_user_environment (&error);
+ if (error && !g_getenv ("RUNNING_UNDER_GDM"))
+ g_warning ("Failed to upload environment to systemd: %s", error->message);
+ g_clear_error (&error);
++#endif
+
+- if (!systemd_service) {
++#ifdef ENABLE_SYSTEMD_SESSION
++ if (use_systemd && !systemd_service) {
+ const gchar *session_type = NULL;
+ g_autofree gchar *gnome_session_target = NULL;
+
+@@ -688,6 +702,7 @@ main (int argc, char **argv)
+ exit (1);
+ }
+ }
++#endif /* ENABLE_SYSTEMD_SESSION */
+
+ {
+ gchar *ibus_path;
+@@ -724,7 +739,9 @@ main (int argc, char **argv)
+
+ gsm_main ();
+
++#ifdef HAVE_SYSTEMD
+ gsm_util_export_user_environment (NULL);
++#endif
+
+ g_clear_object (&manager);
+ g_free (gl_renderer);
diff --git a/x11/gnome-session/files/patch-gnome-session_meson.build b/x11/gnome-session/files/patch-gnome-session_meson.build
new file mode 100644
index 000000000000..baeecf3f34fb
--- /dev/null
+++ b/x11/gnome-session/files/patch-gnome-session_meson.build
@@ -0,0 +1,13 @@
+--- gnome-session/meson.build.orig 2024-03-18 19:30:06 UTC
++++ gnome-session/meson.build
+@@ -60,6 +60,10 @@ endforeach
+ )
+ endforeach
+
++if enable_consolekit
++ sources += files('gsm-consolekit.c')
++endif
++
+ cflags = [
+ '-DLOCALE_DIR="@0@"'.format(session_localedir),
+ '-DDATA_DIR="@0@"'.format(session_pkgdatadir),
diff --git a/x11/gnome-session/files/patch-meson.build b/x11/gnome-session/files/patch-meson.build
new file mode 100644
index 000000000000..bab51fa48748
--- /dev/null
+++ b/x11/gnome-session/files/patch-meson.build
@@ -0,0 +1,73 @@
+--- meson.build.orig 2024-03-18 19:30:06 UTC
++++ meson.build
+@@ -103,19 +103,52 @@ enable_session_selector = get_option('session_selector
+ # Check for session selector GTK+ UI
+ enable_session_selector = get_option('session_selector')
+
+-session_bin_deps += dependency('gio-unix-2.0', version: glib_req_version)
++# Check for session tracking backend
++session_tracking = 'null backend'
+
+-# Check for systemd
+-systemd_userunitdir = get_option('systemduserunitdir')
+-if systemd_userunitdir == ''
+- systemd_dep = dependency('systemd', version: '>= 242', required: true)
+- systemd_userunitdir = systemd_dep.get_variable(pkgconfig: 'systemduserunitdir',
+- pkgconfig_define: ['prefix', session_prefix])
+-endif
++enable_systemd = get_option('systemd')
++enable_systemd_session = get_option('systemd_session') != 'disable'
++use_systemd_session = get_option('systemd_session') == 'default'
++enable_systemd_journal = get_option('systemd_journal')
++enable_consolekit = get_option('consolekit')
++if enable_systemd or enable_consolekit
++ session_bin_deps += dependency('gio-unix-2.0', version: glib_req_version)
+
+-libsystemd_dep = dependency('libsystemd', version: '>= 209', required: true)
+-session_bin_deps += libsystemd_dep
++ # Check for systemd
++ if enable_systemd
++ systemd_userunitdir = get_option('systemduserunitdir')
++ if systemd_userunitdir == ''
++ systemd_dep = dependency('systemd', version: '>= 242', required: true)
++ systemd_userunitdir = systemd_dep.get_variable(pkgconfig: 'systemduserunitdir',
++ pkgconfig_define: ['prefix', session_prefix])
++ endif
+
++ libsystemd_dep = dependency('libsystemd', version: '>= 209', required: true)
++ session_bin_deps += libsystemd_dep
++
++ session_tracking = 'systemd'
++ endif
++
++ # Check for ConsoleKit
++ if enable_consolekit
++ systemd_userunitdir = ''
++
++ if enable_systemd
++ session_tracking += ' (with fallback to ConsoleKit)'
++ else
++ session_tracking = 'ConsoleKit'
++ endif
++ endif
++endif
++if enable_systemd_session
++ assert(enable_systemd, 'Systemd support must be enabled when using systemd session management')
++endif
++config_h.set('HAVE_SYSTEMD', enable_systemd)
++config_h.set('ENABLE_SYSTEMD_SESSION', enable_systemd_session)
++config_h.set('ENABLE_SYSTEMD_JOURNAL', enable_systemd_journal)
++config_h.set('HAVE_CONSOLEKIT', enable_consolekit)
++config_h.set10('USE_SYSTEMD_SESSION', use_systemd_session)
++
+ configure_file(
+ output: 'config.h',
+ configuration: config_h
+@@ -151,6 +184,7 @@ summary_options = {
+ 'Build manpages': get_option('man'),
+ 'Systemd Units Directory': systemd_userunitdir,
+ 'Session Selector Enabled': enable_session_selector,
++ 'Session tracking': session_tracking,
+ }
+
+ summary_dirs = {
diff --git a/x11/gnome-session/files/patch-meson__options.txt b/x11/gnome-session/files/patch-meson__options.txt
new file mode 100644
index 000000000000..039388d5fab6
--- /dev/null
+++ b/x11/gnome-session/files/patch-meson__options.txt
@@ -0,0 +1,12 @@
+--- meson_options.txt.orig 2024-03-18 19:30:06 UTC
++++ meson_options.txt
+@@ -1,5 +1,9 @@ option('session_selector', type: 'boolean', value: fal
+ option('deprecation_flags', type: 'boolean', value: false, description: 'use *_DISABLE_DEPRECATED flags')
+ option('session_selector', type: 'boolean', value: false, description: 'enable building a custom session selector dialog')
++option('systemd', type: 'boolean', value: true, description: 'Use systemd')
++option('systemd_session', type: 'combo', choices: ['disable', 'enable', 'default'], value: 'default', description: 'Whether to include systemd session support and use it by default')
++option('systemd_journal', type: 'boolean', value:'true', description: 'Send log to systemd-journal')
+ option('systemduserunitdir', type: 'string', description: 'Directory for systemd user service files')
++option('consolekit', type: 'boolean', value: false, description: 'Use consolekit')
+ option('docbook', type: 'boolean', value: true, description: 'build documentation')
+ option('man', type: 'boolean', value: true, description: 'build documentation (requires xmlto)')
diff --git a/x11/gnome-session/files/patch-tools_meson.build b/x11/gnome-session/files/patch-tools_meson.build
new file mode 100644
index 000000000000..1cdbd10eb2c9
--- /dev/null
+++ b/x11/gnome-session/files/patch-tools_meson.build
@@ -0,0 +1,18 @@
+--- tools/meson.build.orig 2024-09-19 12:36:55 UTC
++++ tools/meson.build
+@@ -2,9 +2,14 @@ programs = [
+
+ programs = [
+ # name, deps, cflags, install_dir
+- ['gnome-session-ctl', session_bin_deps, cflags, session_libexecdir],
+ ['gnome-session-inhibit', session_deps, cflags, session_bindir],
+ ]
++
++if enable_systemd_session
++ programs += [
++ ['gnome-session-ctl', session_bin_deps, cflags, session_libexecdir],
++ ]
++endif
+
+ if have_x11
+ deps = session_deps + [