diff --git a/.gitignore b/.gitignore
index f341c59..f6afc09 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,6 +45,7 @@ CMakeLists.txt
debian/*.debhelper.log
debian/*.substvars
debian/.debhelper/
+debian/*.debhelper
debian/cinnamon-session-common/
debian/cinnamon-session/
debian/debhelper-build-stamp
diff --git a/cinnamon-session-quit/cinnamon-session-quit.py b/cinnamon-session-quit/cinnamon-session-quit.py
index 14612f8..d706e71 100644
--- a/cinnamon-session-quit/cinnamon-session-quit.py
+++ b/cinnamon-session-quit/cinnamon-session-quit.py
@@ -64,7 +64,10 @@ def __init__(self):
parser.add_argument("--no-prompt", dest="no_prompt", action='store_true',
help=_("Don't prompt for user confirmation"))
parser.add_argument("--sm-owned", action="store_true", help=argparse.SUPPRESS)
- parser.add_argument("--sm-bus-id", dest="bus_id", action="store", help=argparse.SUPPRESS, default=config.DBUS_ADDRESS)
+
+ # unused in 6.4+, kept only for upgrade session (running c-s process is previous version, dialog is new)
+ parser.add_argument("--sm-bus-id", dest="bus_id", action="store", help=argparse.SUPPRESS, default=None)
+
args = parser.parse_args()
self.dialog_response = ResponseCode.NONE
@@ -76,11 +79,7 @@ def __init__(self):
self.force = args.force
self.no_prompt = args.no_prompt
self.sm_owned = args.sm_owned
-
- if self.sm_owned:
- self.bus_id = args.bus_id
- else:
- self.bus_id = None
+ self.bus_id = args.bus_id
self.proxy = None
self.signal_handler_id = 0
@@ -118,7 +117,7 @@ def async_cb(proxy, res):
proxy.call_finish(res)
# self.quit()
except GLib.Error as e:
- print("An error occurred forwarding to the session manager: %s" % e.message)
+ print("An error occurred forwarding to the session manager: %s" % e.message, file=sys.stderr, end=None)
if self.mode == Action.LOGOUT:
arg = LogoutParams.NORMAL
@@ -156,7 +155,7 @@ def async_cb(proxy, res):
)
except GLib.Error as e:
if sm_proxy is None:
- print("Could not forward to org.cinnamon.SessionManager.Manager: %s" % e.message)
+ print("Could not forward to org.cinnamon.SessionManager.Manager: %s" % e.message, file=sys.stderr, end=None)
sys.exit(1)
sys.exit(0)
@@ -169,40 +168,52 @@ def setup_proxy(self):
connection = None
try:
- connection = Gio.DBusConnection.new_for_address_sync(
- self.bus_id,
- Gio.DBusConnectionFlags.AUTHENTICATION_CLIENT,
- None, None
- )
+ # 6.4 and later this will always be None, obsolete connection
+ if self.bus_id is not None:
+ connection = Gio.DBusConnection.new_for_address_sync(
+ self.bus_id,
+ Gio.DBusConnectionFlags.AUTHENTICATION_CLIENT,
+ None, None
+ )
- self.proxy = Gio.DBusProxy.new_sync(
- connection,
- Gio.DBusProxyFlags.DO_NOT_AUTO_START,
- None,
- None,
- "/org/gnome/SessionManager",
- "org.cinnamon.SessionManager.DialogPrivate",
- None
- )
+ self.proxy = Gio.DBusProxy.new_sync(
+ connection,
+ Gio.DBusProxyFlags.DO_NOT_AUTO_START,
+ None,
+ None,
+ "/org/gnome/SessionManager",
+ "org.cinnamon.SessionManager.DialogPrivate",
+ None
+ )
+ else:
+ self.proxy = Gio.DBusProxy.new_for_bus_sync(
+ Gio.BusType.SESSION,
+ Gio.DBusProxyFlags.DO_NOT_AUTO_START,
+ None,
+ "org.gnome.SessionManager",
+ "/org/gnome/SessionManager",
+ "org.cinnamon.SessionManager.EndSessionDialog",
+ None
+ )
self.proxy.connect("g-signal", self.inhibitor_info_received)
except GLib.Error as e:
if connection is None:
- print("Could not connect to session dialog server: %s" % e.message)
+ print("Could not connect to session dialog server: %s" % e.message, file=sys.stderr, end=None)
sys.exit(1)
if self.proxy is None:
- print("Could not create proxy to session dialog interface: %s" % e.message)
+ print("Could not create proxy to session dialog interface: %s" % e.message, file=sys.stderr, end=None)
sys.exit(1)
def inhibitor_info_received(self, proxy, sender, signal, params):
inhibitors = params[0]
if self.dialog_response == ResponseCode.NONE:
- print("Ignoring inhibitor info, still waiting on initial response from user")
+ print("Ignoring inhibitor info, still waiting on initial response from user", file=sys.stderr, end=None)
return
- print("Inhibitor info received (%d inhibitors)" % len(inhibitors))
+ print("Inhibitor info received (%d inhibitors): %s" % (len(inhibitors), params), file=sys.stderr, end=None)
if inhibitors:
self.inhibited = True
@@ -243,8 +254,10 @@ def run_dialog(self):
self.view_stack = self.builder.get_object("view_stack")
self.inhibitor_treeview = self.builder.get_object("inhibitor_treeview")
- can_switch_user, can_stop, can_restart, can_hybrid_sleep, can_suspend, can_hibernate, can_logout = self.get_session_capabilities()
-
+ try:
+ can_switch_user, can_stop, can_restart, can_hybrid_sleep, can_suspend, can_hibernate, can_logout = self.get_session_capabilities()
+ except Exception as e:
+ print(e, file=sys.stderr, end=None)
default_button = None
if self.mode == Action.LOGOUT:
@@ -265,7 +278,7 @@ def run_dialog(self):
self.window.set_icon_name("system-shutdown")
elif self.mode == Action.RESTART:
if not can_restart:
- print("Restart not available")
+ print("Restart not available", file=sys.stderr, end=None)
Gtk.main_quit()
return
self.dialog_label.set_text(_("Restart this system now?"))
@@ -304,7 +317,7 @@ def get_session_capabilities(self):
)
return caps[0]
except GLib.Error as e:
- print("Could not retrieve session capabilities: %s" % e.message)
+ print("Could not retrieve session capabilities: %s" % e.message, file=sys.stderr, end=None)
def start_timer(self):
if self.timer_id > 0:
@@ -315,6 +328,11 @@ def start_timer(self):
self.update_timer()
GLib.timeout_add(1000, self.update_timer)
+ def stop_timer(self):
+ if self.timer_id > 0:
+ GLib.source_remove(self.timer_id)
+ self.timer_id = 0
+
def update_timer(self):
if self.current_time == 0:
self.handle_response(self.window, self.default_response)
@@ -347,15 +365,17 @@ def update_timer(self):
return GLib.SOURCE_CONTINUE
def handle_response(self, dialog, code):
+ self.stop_timer()
+
self.view_stack.set_visible_child_name("busy")
if self.inhibited:
if code == ResponseCode.CONTINUE:
- print("Sending ignore inhibitors")
+ print("Sending ignore inhibitors", file=sys.stderr, end=None)
self.send_command("IgnoreInhibitors")
self.finish_up()
elif code in (ResponseCode.CANCEL, Gtk.ResponseType.NONE, Gtk.ResponseType.DELETE_EVENT):
- print("Canceling action during inhibit phase")
+ print("Canceling action during inhibit phase", file=sys.stderr, end=None)
self.send_command("Cancel")
self.quit()
return
@@ -378,7 +398,7 @@ def handle_response(self, dialog, code):
self.send_command("Cancel")
self.quit(0)
else:
- print("Invalid response code: %d" % code)
+ print("Invalid response code: %d" % code, file=sys.stderr, end=None)
def send_command(self, command):
try:
@@ -391,7 +411,7 @@ def send_command(self, command):
None
)
except GLib.Error as e:
- print("Could not send command '%s' to session manager: %s" % (str(command), e.message))
+ print("Could not send command '%s' to session manager: %s" % (str(command), e.message), file=sys.stderr, end=None)
self.command_sent = True
# wait for inhibit info
@@ -409,7 +429,7 @@ def show_inhibit_view(self, info):
self.view_stack.set_visible_child_name("inhibit")
def on_terminate(self, data=None):
- print("Received SIGTERM from cinnamon-session, exiting")
+ print("Received SIGTERM from cinnamon-session, exiting", file=sys.stderr, end=None)
self.quit(0)
def finish_up(self):
diff --git a/cinnamon-session-quit/config.py.in b/cinnamon-session-quit/config.py.in
index 11daad2..25ca68e 100644
--- a/cinnamon-session-quit/config.py.in
+++ b/cinnamon-session-quit/config.py.in
@@ -3,5 +3,4 @@
LOCALE_DIR=@LOCALE_DIR@
PACKAGE=@PACKAGE@
VERSION=@VERSION@
-DBUS_ADDRESS=@DBUS_ADDRESS@
PKG_DATADIR=@PKG_DATADIR@
diff --git a/cinnamon-session-quit/meson.build b/cinnamon-session-quit/meson.build
index d9a9e44..1706f50 100644
--- a/cinnamon-session-quit/meson.build
+++ b/cinnamon-session-quit/meson.build
@@ -4,7 +4,6 @@ csq_conf.set_quoted('LOCALE_DIR', join_paths(get_option('prefix'), get_option('l
csq_conf.set_quoted('PACKAGE', meson.project_name())
csq_conf.set_quoted('VERSION', meson.project_version())
csq_conf.set_quoted('PKG_DATADIR', pkg_datadir)
-csq_conf.set_quoted('DBUS_ADDRESS', dialog_dbus_address)
config_py = configure_file(
output: 'config.py',
diff --git a/cinnamon-session/csm-manager.c b/cinnamon-session/csm-manager.c
index 2959ffd..2236977 100644
--- a/cinnamon-session/csm-manager.c
+++ b/cinnamon-session/csm-manager.c
@@ -40,6 +40,7 @@
#include "csm-manager.h"
#include "csm-exported-manager.h"
+#include "csm-exported-dialog.h"
#include "csm-store.h"
#include "csm-inhibitor.h"
@@ -85,7 +86,7 @@
#define CSM_MANAGER_SCHEMA "org.cinnamon.SessionManager"
#define KEY_AUTOSAVE "auto-save-session"
#define KEY_LOGOUT_PROMPT "logout-prompt"
-#define KEY_SHOW_FALLBACK_WARNING "show-fallback-warning"
+#define KEY_FORCE_GTK_END_SESSION "force-gtk-end-session-dialog"
#define KEY_BLACKLIST "autostart-blacklist"
#define KEY_PREFER_HYBRID_SLEEP "prefer-hybrid-sleep"
#define KEY_SUSPEND_HIBERNATE "suspend-then-hibernate"
@@ -122,12 +123,6 @@ struct CsmManagerPrivate
CsmPresence *presence;
CsmXsmpServer *xsmp_server;
- GDBusConnection *dialog_connection;
- GDBusServer *dialog_server;
- guint dialog_reg_id;
- CsmLogoutAction dialog_action;
- gchar *dialog_bus_address;
-
char *session_name;
gboolean is_fallback_session : 1;
@@ -160,6 +155,10 @@ struct CsmManagerPrivate
GDBusProxy *bus_proxy;
GDBusConnection *connection;
CsmExportedManager *skeleton;
+ CsmExportedDialog *dialog_skeleton;
+ GDBusProxy *cinnamon_proxy;
+
+ CsmLogoutAction dialog_action;
gboolean dbus_disconnected : 1;
guint name_owner_id;
@@ -182,11 +181,17 @@ enum {
LAST_SIGNAL
};
+typedef enum {
+ DIALOG_MODE_REBOOT,
+ DIALOG_MODE_SHUTDOWN,
+ DIALOG_MODE_LOGOUT
+} DialogMode;
+
static guint signals [LAST_SIGNAL] = { 0 };
static void show_shutdown_dialog (CsmManager *manager,
gboolean is_reboot);
-static void terminate_dialog (void);
+static void close_end_session_dialog (CsmManager *manager);
static void show_logout_dialog (CsmManager *manager);
static void user_logout (CsmManager *manager,
@@ -267,14 +272,6 @@ static void
on_required_app_failure (CsmManager *manager,
CsmApp *app)
{
- gboolean allow_logout;
-
- if (csm_system_is_login_session (manager->priv->system)) {
- allow_logout = FALSE;
- } else {
- allow_logout = !_log_out_is_locked_down (manager);
- }
-
csm_util_init_error (FALSE, "A program required by the session failed to start. App ID: '%s'. Startup ID: '%s'.",
csm_app_peek_app_id (app),
csm_app_peek_startup_id (app));
@@ -519,7 +516,7 @@ end_phase (CsmManager *manager)
{
gboolean start_next_phase = TRUE;
- g_debug ("CsmManager: ending phase %s\n",
+ g_debug ("CsmManager: ending phase %s",
phase_num_to_name (manager->priv->phase));
g_slist_free (manager->priv->pending_apps);
@@ -862,7 +859,7 @@ do_phase_end_session (CsmManager *manager)
data.manager = manager;
data.flags = 0;
- terminate_dialog ();
+ close_end_session_dialog (manager);
if (manager->priv->logout_mode == CSM_MANAGER_LOGOUT_MODE_FORCE) {
data.flags |= CSM_CLIENT_END_SESSION_FLAG_FORCEFUL;
@@ -1077,7 +1074,7 @@ cancel_end_session (CsmManager *manager)
/* remove the dialog before we remove the inhibitors, else the dialog
* will activate itself automatically when the last inhibitor will be
* removed */
- terminate_dialog ();
+ close_end_session_dialog (manager);
/* clear all JIT inhibitors */
csm_store_foreach_remove (manager->priv->inhibitors,
@@ -1166,7 +1163,7 @@ flexiserver_launch (const gchar **argv)
static void
manager_switch_user (CsmManager *manager)
{
- terminate_dialog ();
+ close_end_session_dialog (manager);
/* We have to do this here and in request_switch_user() because this
* function can be called at a later time, not just directly after
@@ -1237,7 +1234,7 @@ manager_attempt_hibernate (CsmManager *manager)
* (if preferences dictate it) */
manager_perhaps_lock (manager);
- terminate_dialog ();
+ close_end_session_dialog (manager);
if (csm_system_can_hibernate (manager->priv->system)) {
csm_system_hibernate (manager->priv->system);
@@ -1251,7 +1248,7 @@ manager_attempt_suspend (CsmManager *manager)
* (if preferences dictate it) */
manager_perhaps_lock (manager);
- terminate_dialog ();
+ close_end_session_dialog (manager);
if (g_settings_get_boolean (manager->priv->settings, KEY_PREFER_HYBRID_SLEEP) &&
csm_system_can_hybrid_sleep (manager->priv->system)) {
@@ -1294,30 +1291,14 @@ emit_inhibitor_info_to_dialog (CsmManager *manager, CsmLogoutAction action)
if (action == CSM_LOGOUT_ACTION_UNDEFINED) {
return;
}
-
+ g_debug ("Sending inhibitor info to end-session dialog");
manager->priv->dialog_action = action;
GVariant *dialog_inhibit_info = build_inhibitor_list_for_dialog (manager->priv->inhibitors,
manager->priv->clients,
action);
- if (manager->priv->dialog_connection != NULL) {
- GError *error = NULL;
-
- if (!g_dbus_connection_emit_signal (manager->priv->dialog_connection,
- NULL,
- "/org/gnome/SessionManager",
- "org.cinnamon.SessionManager.DialogPrivate",
- "InhibitorsChanged",
- dialog_inhibit_info,
- &error)) {
- if (error) {
- g_critical ("Could not send inhibit list to dialog: %s", error->message);
- g_clear_error (&error);
-
- }
- }
- }
+ csm_exported_dialog_emit_inhibitors_changed (manager->priv->dialog_skeleton, dialog_inhibit_info);
}
static void
@@ -1494,7 +1475,7 @@ static void
start_phase (CsmManager *manager)
{
- g_debug ("CsmManager: starting phase %s\n",
+ g_debug ("CsmManager: starting phase %s",
phase_num_to_name (manager->priv->phase));
/* reset state */
@@ -2625,14 +2606,21 @@ on_dbus_proxy_signal (GDBusProxy *proxy,
&new_owner);
if (strlen (new_owner) == 0 && strlen (old_owner) > 0) {
- /* service removed */
- remove_inhibitors_for_connection (manager, old_owner);
- remove_clients_for_connection (manager, old_owner);
+ /* service removed */
+ remove_inhibitors_for_connection (manager, old_owner);
+ remove_clients_for_connection (manager, old_owner);
+
+ if (g_strcmp0 (name, "org.Cinnamon") == 0) {
+ g_debug ("org.Cinnamon has lost its owner (Cinnamon is not running)");
+ }
} else if (strlen (old_owner) == 0 && strlen (new_owner) > 0) {
- /* service added */
+ /* service added */
+ if (g_strcmp0 (name, "org.Cinnamon") == 0) {
+ g_debug ("org.Cinnamon has an owner (Cinnamon is running)");
+ }
- /* use this if we support automatically registering
- * well known bus names */
+ /* use this if we support automatically registering
+ * well known bus names */
}
g_free (name);
@@ -2659,42 +2647,44 @@ on_bus_connection_closed (GDBusConnection *connection,
static gboolean csm_manager_is_switch_user_inhibited (CsmManager *manager);
static gboolean csm_manager_is_suspend_inhibited (CsmManager *manager);
-static void
-handle_dialog_method_call (GDBusConnection *connection,
- const gchar *sender,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *method_name,
- GVariant *parameters,
+static gboolean
+handle_dialog_method_call (CsmExportedDialog *dialog_skeleton,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
CsmManager *manager = CSM_MANAGER (user_data);
+ const gchar *method_name = g_dbus_method_invocation_get_method_name (invocation);
- g_debug("Dialog method received: %s\n", method_name);
+ g_debug("Dialog method received: %s", method_name);
if (g_strcmp0 (method_name, "Suspend") == 0) {
request_suspend (manager);
+ csm_exported_dialog_complete_suspend (dialog_skeleton, invocation);
}
else
if (g_strcmp0 (method_name, "Hibernate") == 0) {
request_hibernate (manager);
+ csm_exported_dialog_complete_hibernate (dialog_skeleton, invocation);
}
else
if (g_strcmp0 (method_name, "Restart") == 0) {
request_reboot (manager);
+ csm_exported_dialog_complete_restart (dialog_skeleton, invocation);
}
else
if (g_strcmp0 (method_name, "Shutdown") == 0) {
request_shutdown (manager);
+ csm_exported_dialog_complete_shutdown (dialog_skeleton, invocation);
}
else
if (g_strcmp0 (method_name, "SwitchUser") == 0) {
request_switch_user (manager);
+ csm_exported_dialog_complete_switch_user (dialog_skeleton, invocation);
}
else
if (g_strcmp0 (method_name, "Logout") == 0) {
request_logout (manager, CSM_MANAGER_LOGOUT_MODE_NO_CONFIRMATION);
+ csm_exported_dialog_complete_logout (dialog_skeleton, invocation);
}
else
if (g_strcmp0 (method_name, "Cancel") == 0) {
@@ -2707,12 +2697,14 @@ handle_dialog_method_call (GDBusConnection *connection,
g_debug ("session-manager dialog was cancelled");
}
- terminate_dialog ();
+ close_end_session_dialog (manager);
+ csm_exported_dialog_complete_logout (dialog_skeleton, invocation);
}
else
if (g_strcmp0 (method_name, "IgnoreInhibitors") == 0) {
- terminate_dialog ();
+ close_end_session_dialog (manager);
do_inhibit_dialog_action (manager);
+ csm_exported_dialog_complete_ignore_inhibitors (dialog_skeleton, invocation);
}
else
if (g_strcmp0 (method_name, "GetCapabilities") == 0) {
@@ -2720,7 +2712,7 @@ handle_dialog_method_call (GDBusConnection *connection,
gboolean can_hybrid_sleep = g_settings_get_boolean (manager->priv->settings, KEY_PREFER_HYBRID_SLEEP) &&
csm_system_can_hybrid_sleep (manager->priv->system);
- ret = g_variant_new ("((bbbbbbb))",
+ ret = g_variant_new ("(bbbbbbb)",
!(_switch_user_is_locked_down (manager) || csm_manager_is_switch_user_inhibited (manager)),
(!_log_out_is_locked_down (manager)) && csm_system_can_stop (manager->priv->system),
(!_log_out_is_locked_down (manager)) && csm_system_can_restart (manager->priv->system),
@@ -2729,94 +2721,17 @@ handle_dialog_method_call (GDBusConnection *connection,
(!csm_manager_is_suspend_inhibited (manager)) && csm_system_can_hibernate (manager->priv->system),
(!csm_manager_is_logout_inhibited (manager)));
- g_dbus_method_invocation_return_value (invocation, ret);
- return;
+ csm_exported_dialog_complete_get_capabilities (dialog_skeleton, invocation, ret);
}
else {
- g_warning ("Unknown method name %s\n", method_name);
+ g_warning ("Unknown method name %s", method_name);
g_dbus_method_invocation_return_error (invocation,
CSM_MANAGER_ERROR,
CSM_MANAGER_ERROR_INVALID_METHOD,
"Unknown method name %s",
method_name);
- return;
- }
-
- g_dbus_method_invocation_return_value (invocation, NULL);
-}
-
-static GDBusNodeInfo *introspection_data = NULL;
-
-/* Introspection data for the service we are exporting */
-static const gchar introspection_xml[] =
- ""
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- "";
-
-static const GDBusInterfaceVTable interface_vtable =
-{
- handle_dialog_method_call,
- NULL,
- NULL,
- { 0 }
-};
-
-static void
-on_dialog_connection_closed (GDBusConnection *connection,
- gboolean vanished,
- GError *error,
- gpointer user_data)
-{
- CsmManager *manager = CSM_MANAGER (user_data);
- g_debug ("Dialog disconnected\n");
-
- g_dbus_connection_unregister_object (connection, manager->priv->dialog_reg_id);
- manager->priv->dialog_reg_id = 0;
-
- g_clear_object (&manager->priv->dialog_connection);
-}
-
-static gboolean
-on_new_dialog_connection (GDBusServer *server,
- GDBusConnection *connection,
- gpointer user_data)
-{
- CsmManager *manager = CSM_MANAGER (user_data);
-
- if (manager->priv->dialog_reg_id > 0) {
- g_message ("Already have a dialog connection, ignoring new one");
- return FALSE;
}
- g_debug ("Dialog connected.\n");
-
- manager->priv->dialog_connection = g_object_ref (connection);
- g_signal_connect (connection, "closed", G_CALLBACK (on_dialog_connection_closed), manager);
- manager->priv->dialog_reg_id = g_dbus_connection_register_object (connection,
- "/org/gnome/SessionManager",
- introspection_data->interfaces[0],
- &interface_vtable,
- manager, /* user_data */
- NULL, /* user_data_free_func */
- NULL); /* GError** */
-
return TRUE;
}
@@ -2847,10 +2762,23 @@ static SkeletonSignal skeleton_signals[] = {
{ "handle-request-reboot", csm_manager_request_reboot }
};
+static SkeletonSignal dialog_skeleton_signals[] = {
+ // signal name callback
+ { "handle-suspend", handle_dialog_method_call },
+ { "handle-hibernate", handle_dialog_method_call },
+ { "handle-restart", handle_dialog_method_call },
+ { "handle-shutdown", handle_dialog_method_call },
+ { "handle-switch-user", handle_dialog_method_call },
+ { "handle-logout", handle_dialog_method_call },
+ { "handle-cancel", handle_dialog_method_call },
+ { "handle-ignore-inhibitors", handle_dialog_method_call },
+ { "handle-get-capabilities", handle_dialog_method_call },
+};
+
static gboolean
register_manager (CsmManager *manager)
{
- CsmExportedManager *skeleton;
+ GDBusInterfaceSkeleton *skeleton;
GError *error = NULL;
gint i;
@@ -2885,10 +2813,19 @@ register_manager (CsmManager *manager)
G_CALLBACK (on_dbus_proxy_signal),
manager);
- skeleton = csm_exported_manager_skeleton_new ();
- manager->priv->skeleton = skeleton;
+ manager->priv->cinnamon_proxy = g_dbus_proxy_new_sync (manager->priv->connection,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ "org.Cinnamon",
+ "/org/Cinnamon",
+ "org.Cinnamon",
+ NULL,
+ &error);
+
+ skeleton = G_DBUS_INTERFACE_SKELETON (csm_exported_manager_skeleton_new ());
+ manager->priv->skeleton = CSM_EXPORTED_MANAGER (skeleton);
- g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (skeleton),
+ g_dbus_interface_skeleton_export (skeleton,
manager->priv->connection,
CSM_MANAGER_DBUS_PATH,
&error);
@@ -2909,44 +2846,23 @@ register_manager (CsmManager *manager)
manager);
}
- // Set up private controller interface for dialog
- gchar *guid = g_dbus_generate_guid ();
- gchar *address;
-
- // Detect guest sessions.
- if (g_str_has_prefix (g_get_home_dir (), "/tmp")) {
- address = g_strdup ("unix:tmpdir=/tmp");
- }
- else {
- address = g_strdup_printf ("%s-%s", DBUS_ADDRESS, guid);
- }
-
- GDBusServer *server = g_dbus_server_new_sync (address,
- G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER,
- guid,
- NULL, NULL, &error);
- g_dbus_server_start (server);
+ skeleton = G_DBUS_INTERFACE_SKELETON (csm_exported_dialog_skeleton_new ());
+ manager->priv->dialog_skeleton = CSM_EXPORTED_DIALOG (skeleton);
- // In normal sessions, this address will be the same as what we provided for g_dbus_server_new_sync.
- // In guest sessions, an abstract address will be generated, so use what the server returns, not
- // what we gave it as an address.
- manager->priv->dialog_bus_address = g_strdup (g_dbus_server_get_client_address (server));
- g_debug ("Dialog server address: %s", manager->priv->dialog_bus_address);
+ g_dbus_interface_skeleton_export (skeleton,
+ manager->priv->connection,
+ CSM_MANAGER_DBUS_PATH,
+ &error);
- g_free (guid);
- g_free (address);
+ for (i = 0; i < G_N_ELEMENTS (dialog_skeleton_signals); i++) {
+ SkeletonSignal sig = dialog_skeleton_signals[i];
- if (server == NULL) {
- g_critical ("Error creating private dialog server. Logout, shutdown, restart will "
- "need to be performed from a terminal: %s", error->message);
- g_clear_error (&error);
- return TRUE;
+ g_signal_connect (skeleton,
+ sig.signal_name,
+ G_CALLBACK (sig.callback),
+ manager);
}
- introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
- manager->priv->dialog_server = server;
- g_signal_connect (server, "new-connection", G_CALLBACK (on_new_dialog_connection), manager);
-
return TRUE;
}
@@ -3537,22 +3453,12 @@ csm_manager_dispose (GObject *object)
g_debug ("CsmManager: disposing manager");
- terminate_dialog ();
+ close_end_session_dialog (manager);
g_clear_object (&manager->priv->xsmp_server);
g_clear_object (&manager->priv->bus_proxy);
-
- if (manager->priv->dialog_reg_id > 0) {
- g_dbus_connection_unregister_object (manager->priv->dialog_connection,
- manager->priv->dialog_reg_id);
- manager->priv->dialog_reg_id = 0;
- g_dbus_node_info_unref (introspection_data);
- g_dbus_server_stop (manager->priv->dialog_server);
- g_object_unref (manager->priv->dialog_server);
- g_object_unref (manager->priv->dialog_connection);
- g_free (manager->priv->dialog_bus_address);
- }
+ g_clear_object (&manager->priv->cinnamon_proxy);
if (manager->priv->clients != NULL) {
g_signal_handlers_disconnect_by_func (manager->priv->clients,
@@ -3970,22 +3876,42 @@ on_dialog_read (GObject *source,
}
static void
-terminate_dialog (void)
+close_end_session_dialog (CsmManager *manager)
{
- if (dialog_process == NULL) {
+ g_debug ("Closing end session dialog");
+
+ if (dialog_process != NULL) {
+ g_subprocess_send_signal (dialog_process, SIGTERM);
return;
}
- g_debug ("Terminating cinnamon-session-quit dialog");
-
- g_subprocess_send_signal(dialog_process, SIGTERM);
+ GError *error = NULL;
+ GVariant *ret = NULL;
+
+ ret = g_dbus_proxy_call_sync (manager->priv->cinnamon_proxy,
+ "CloseEndSessionDialog",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+ g_debug ("ret is: %p", ret);
+
+ g_variant_unref (ret);
+
+ if (error != NULL) {
+ g_critical ("Unable to close Cinnamon's end session dialog: %s", error->message);
+ g_error_free (error);
+ }
}
static void
-launch_dialog (CsmManager *manager, const gchar *flag)
+launch_gtk_dialog (CsmManager *manager,
+ DialogMode mode)
{
GError *error;
- g_debug ("Trying to launch session-manager dialog - 'cinnamon-session-quit --sm-owned --sm-bus-id %s'", manager->priv->dialog_bus_address);
+ const gchar *flag;
+ g_debug ("Trying to launch fallback (Gtk) end-session dialog");
if (dialog_process != NULL) {
g_debug ("There's already a session-manager dialog");
@@ -4000,10 +3926,25 @@ launch_dialog (CsmManager *manager, const gchar *flag)
cancel_end_session (manager);
}
+ switch (mode) {
+ case DIALOG_MODE_LOGOUT:
+ flag = "--logout";
+ break;
+ case DIALOG_MODE_REBOOT:
+ flag = "--reboot";
+ break;
+ case DIALOG_MODE_SHUTDOWN:
+ flag = "--power-off";
+
+ break;
+ default:
+ g_warning ("Unknown dialog mode: %d", mode);
+ return;
+ }
+
const gchar *argv[] = {
"cinnamon-session-quit",
"--sm-owned",
- "--sm-bus-id", manager->priv->dialog_bus_address,
flag,
NULL
};
@@ -4012,7 +3953,7 @@ launch_dialog (CsmManager *manager, const gchar *flag)
GSubprocessFlags flags = G_SUBPROCESS_FLAGS_NONE;
if (debugging) {
- flags = G_SUBPROCESS_FLAGS_STDERR_MERGE | G_SUBPROCESS_FLAGS_STDOUT_PIPE;
+ flags = G_SUBPROCESS_FLAGS_STDERR_PIPE;
}
error = NULL;
@@ -4027,7 +3968,7 @@ launch_dialog (CsmManager *manager, const gchar *flag)
}
if (debugging) {
- GInputStream *stdout = g_subprocess_get_stdout_pipe (dialog_process);
+ GInputStream *stdout = g_subprocess_get_stderr_pipe (dialog_process);
guint8 *buffer = g_malloc (1024);
g_input_stream_read_async (G_INPUT_STREAM (stdout),
buffer,
@@ -4046,9 +3987,60 @@ launch_dialog (CsmManager *manager, const gchar *flag)
manager);
}
+static gboolean
+launch_cinnamon_dialog (CsmManager *manager,
+ DialogMode mode,
+ GError **error)
+{
+ GVariant *ret = NULL;
+
+ g_debug ("Requesting Cinnamon display its end-session dialog");
+
+ ret = g_dbus_proxy_call_sync (manager->priv->cinnamon_proxy,
+ "ShowEndSessionDialog",
+ g_variant_new ("(i)", mode),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ error);
+
+ if (*error != NULL) {
+ return FALSE;
+ }
+ g_debug ("launch ret is: %p", ret);
+
+ g_variant_unref (ret);
+
+ return TRUE;
+}
+
+static void
+show_end_session_dialog (CsmManager *manager,
+ DialogMode mode)
+{
+ GError *error = NULL;
+
+ if (g_settings_get_boolean (manager->priv->settings, KEY_FORCE_GTK_END_SESSION)) {
+ g_debug ("Using Gtk end-session dialog based on settings.");
+ launch_gtk_dialog (manager, mode);
+ return;
+ }
+
+ if (!launch_cinnamon_dialog (manager, mode, &error)) {
+ if (error->code == G_DBUS_ERROR_NAME_HAS_NO_OWNER) {
+ g_debug ("Cinnamon is not running, falling back to Gtk end-session dialog");
+ } else {
+ g_critical ("Failed to launch Cinnamon's end session dialog, falling back to Gtk end-session dialog: %s", error->message);
+ }
+
+ g_error_free (error);
+ launch_gtk_dialog (manager, mode);
+ }
+}
+
static void
show_shutdown_dialog (CsmManager *manager,
- gboolean is_reboot)
+ gboolean is_reboot)
{
if (manager->priv->phase > CSM_MANAGER_PHASE_QUERY_END_SESSION) {
/* Already shutting down, nothing more to do */
@@ -4057,7 +4049,7 @@ show_shutdown_dialog (CsmManager *manager,
manager->priv->logout_mode = CSM_MANAGER_LOGOUT_MODE_NORMAL;
- launch_dialog (manager, is_reboot ? "--reboot" : "--power-off");
+ show_end_session_dialog (manager, is_reboot ? DIALOG_MODE_REBOOT : DIALOG_MODE_SHUTDOWN);
}
static void
@@ -4070,7 +4062,7 @@ show_logout_dialog (CsmManager *manager)
manager->priv->logout_mode = CSM_MANAGER_LOGOUT_MODE_NORMAL;
- launch_dialog (manager, "--logout");
+ show_end_session_dialog (manager, DIALOG_MODE_LOGOUT);
}
static void
diff --git a/cinnamon-session/inhibit-dialog-info.c b/cinnamon-session/inhibit-dialog-info.c
index 05783a3..5df1f39 100644
--- a/cinnamon-session/inhibit-dialog-info.c
+++ b/cinnamon-session/inhibit-dialog-info.c
@@ -138,16 +138,13 @@ add_inhibitor (InhibitDialogInfo *info,
gicon_string = g_icon_to_string (gicon);
}
- // g_variant_builder_open (info->builder, G_VARIANT_TYPE_ARRAY);
+ g_debug ("Adding %s to dialog inhibitor list", name);
+ g_variant_builder_add (info->builder, "(ssss)",
+ name ? name : "none",
+ gicon_string ? gicon_string : "none",
+ csm_inhibitor_peek_reason (inhibitor) ? csm_inhibitor_peek_reason (inhibitor) : "none",
+ csm_inhibitor_peek_id (inhibitor) ? csm_inhibitor_peek_id (inhibitor) : "none");
- GVariant *item = g_variant_new ("(ssss)",
- name ? name : "none",
- gicon_string ? gicon_string : "none",
- csm_inhibitor_peek_reason (inhibitor) ? csm_inhibitor_peek_reason (inhibitor) : "none",
- csm_inhibitor_peek_id (inhibitor) ? csm_inhibitor_peek_id (inhibitor) : "none");
-
- g_variant_builder_add_value (info->builder, item);
- // g_variant_builder_close (info->builder);
info->count++;
g_free (gicon_string);
@@ -161,7 +158,31 @@ add_to_builder (const char *id,
CsmInhibitor *inhibitor,
InhibitDialogInfo *info)
{
- add_inhibitor (info, inhibitor);
+ CsmInhibitorFlag flags = csm_inhibitor_peek_flags (inhibitor);
+
+ switch (info->action) {
+ case CSM_LOGOUT_ACTION_LOGOUT:
+ case CSM_LOGOUT_ACTION_SHUTDOWN:
+ case CSM_LOGOUT_ACTION_REBOOT:
+ if (flags & CSM_INHIBITOR_FLAG_LOGOUT) {
+ add_inhibitor (info, inhibitor);
+ }
+ break;
+ case CSM_LOGOUT_ACTION_SWITCH_USER:
+ if (flags & CSM_INHIBITOR_FLAG_SWITCH_USER) {
+ add_inhibitor (info, inhibitor);
+ }
+ break;
+ case CSM_LOGOUT_ACTION_HIBERNATE:
+ case CSM_LOGOUT_ACTION_SLEEP:
+ if (flags & CSM_INHIBITOR_FLAG_SUSPEND) {
+ add_inhibitor (info, inhibitor);
+ }
+ break;
+ default:
+ break;
+ }
+
return FALSE;
}
@@ -178,30 +199,24 @@ build_inhibitor_list_for_dialog (CsmStore *inhibitors,
CsmStore *clients,
int action)
{
- GVariantBuilder builder;
+ g_autoptr(GVariantBuilder) builder = g_variant_builder_new (G_VARIANT_TYPE ("a(ssss)"));
- g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE);
- g_variant_builder_open (&builder, G_VARIANT_TYPE ("a(ssss)"));
-
- InhibitDialogInfo *info = g_new0 (InhibitDialogInfo, 1);
- info->action = action;
- info->builder = &builder;
+ InhibitDialogInfo info;
+ info.action = action;
+ info.builder = builder;
if (clients != NULL) {
- info->clients = g_object_ref (clients);
+ info.clients = g_object_ref (clients);
}
if (inhibitors != NULL) {
- info->inhibitors = g_object_ref (inhibitors);
+ info.inhibitors = g_object_ref (inhibitors);
}
- populate_builder (info);
-
- g_variant_builder_close (&builder);
+ populate_builder (&info);
- g_object_unref (info->clients);
- g_object_unref (info->inhibitors);
+ g_object_unref (info.clients);
+ g_object_unref (info.inhibitors);
- g_free (info);
- return g_variant_builder_end (&builder);
+ return g_variant_builder_end (builder);
}
diff --git a/cinnamon-session/meson.build b/cinnamon-session/meson.build
index b5e8273..073755d 100644
--- a/cinnamon-session/meson.build
+++ b/cinnamon-session/meson.build
@@ -11,7 +11,8 @@ gdbus_ifaces = [
['exported-client-private', 'org.gnome.SessionManager.ClientPrivate', 'ExportedClientPrivate'],
['exported-app', 'org.gnome.SessionManager.App', 'ExportedApp'],
['exported-inhibitor', 'org.gnome.SessionManager.Inhibitor', 'ExportedInhibitor'],
- ['exported-presence', 'org.gnome.SessionManager.Presence', 'ExportedPresence']
+ ['exported-presence', 'org.gnome.SessionManager.Presence', 'ExportedPresence'],
+ ['exported-dialog', 'org.cinnamon.SessionManager.EndSessionDialog', 'ExportedDialog']
]
gdbus_sources = []
diff --git a/cinnamon-session/org.cinnamon.SessionManager.EndSessionDialog.xml b/cinnamon-session/org.cinnamon.SessionManager.EndSessionDialog.xml
new file mode 100644
index 0000000..593b8b4
--- /dev/null
+++ b/cinnamon-session/org.cinnamon.SessionManager.EndSessionDialog.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/data/org.cinnamon.SessionManager.gschema.xml b/data/org.cinnamon.SessionManager.gschema.xml
index 5a13d6c..cef0255 100644
--- a/data/org.cinnamon.SessionManager.gschema.xml
+++ b/data/org.cinnamon.SessionManager.gschema.xml
@@ -20,10 +20,10 @@
Logout prompt
If enabled, cinnamon-session will prompt the user before ending a session.
-
- true
- Show the fallback warning
- If enabled, cinnamon-session will display a warning dialog after login if the session was automatically fallen back.
+
+ false
+ Always use the session manager's end-session-dialog
+ If enabled, cinnamon-session will not try to use Cinnamon's end-session dialog, instead preferring Gtk fallback.
['gnome-settings-daemon', 'org.gnome.SettingsDaemon', 'gnome-fallback-mount-helper', 'gnome-screensaver', 'mate-screensaver', 'mate-keyring-daemon', 'indicator-session', 'gnome-initial-setup-copy-worker', 'gnome-initial-setup-first-login', 'gnome-welcome-tour', 'xscreensaver-autostart', 'nautilus-autostart', 'nm-applet', 'caja', 'xfce4-power-manager', 'touchegg']
diff --git a/meson.build b/meson.build
index 928d3da..543a345 100644
--- a/meson.build
+++ b/meson.build
@@ -123,7 +123,6 @@ conf.set('ENABLE_IPV6', have_ipv6)
rootInclude = include_directories('.')
-dialog_dbus_address = 'unix:abstract=cinnamon-session-quit-dialog'
pkg_datadir = join_paths(get_option('prefix'), get_option('datadir'), meson.project_name())
conf.set_quoted('PKGDATADIR', pkg_datadir)
@@ -133,7 +132,6 @@ conf.set_quoted('LOCALE_DIR', join_paths(get_option('prefix'), get_optio
conf.set_quoted('PACKAGE', meson.project_name())
conf.set_quoted('VERSION', meson.project_version())
conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
-conf.set_quoted('DBUS_ADDRESS', dialog_dbus_address)
configure_file(