Date: Tuesday, October 7, 2014 @ 22:56:18 Author: bgyorgy Revision: 120373
upgpkg: lxsession 1:0.5.0-1 Update to version 0.5.0 Added: lxsession/trunk/fix-lxpolkit.patch lxsession/trunk/fix-lxsession-db.patch lxsession/trunk/fix-lxsession-edit.patch lxsession/trunk/fix-userswitch.patch Modified: lxsession/trunk/PKGBUILD Deleted: lxsession/trunk/lxsession-0.4.6.1-logind-support.patch ----------------------------------------+ PKGBUILD | 43 +- fix-lxpolkit.patch | 18 fix-lxsession-db.patch | 42 ++ fix-lxsession-edit.patch | 24 + fix-userswitch.patch | 35 + lxsession-0.4.6.1-logind-support.patch | 608 ------------------------------- 6 files changed, 151 insertions(+), 619 deletions(-) Modified: PKGBUILD =================================================================== --- PKGBUILD 2014-10-07 20:27:01 UTC (rev 120372) +++ PKGBUILD 2014-10-07 20:56:18 UTC (rev 120373) @@ -4,8 +4,8 @@ # Contributor: Juergen Hoetzel <juer...@archlinux.org> pkgname=lxsession -pkgver=0.4.6.1 -pkgrel=2 +pkgver=0.5.0 +pkgrel=1 epoch=1 pkgdesc='Lightweight X11 session manager' arch=('i686' 'x86_64') @@ -12,18 +12,39 @@ url="http://lxde.org/" license=('GPL2') groups=('lxde') -depends=('gtk2' 'dbus') -makedepends=('pkgconfig' 'intltool') -replaces=('lxde-settings-daemon' 'lxsession-lite') -conflicts=('lxsession-lite' 'lxde-settings-daemon') -source=(http://downloads.sourceforge.net/lxde/$pkgname-$pkgver.tar.gz - lxsession-0.4.6.1-logind-support.patch) -md5sums=('e456b64c5ab3652a4dec661ec706dc6e' - '0ec60da2c876b14928ea22a6c29fc0a7') +depends=('gtk2' 'dbus-glib' 'polkit') +makedepends=('intltool' 'docbook-xsl' 'vala') +replaces=('lxpolkit' 'lxsession-lite' 'lxde-settings-daemon') +conflicts=('lxpolkit' 'lxsession-lite' 'lxde-settings-daemon') +source=(http://downloads.sourceforge.net/lxde/$pkgname-$pkgver.tar.xz + fix-lxsession-db.patch + fix-lxsession-edit.patch + fix-userswitch.patch + fix-lxpolkit.patch) +md5sums=('6ef8b1487e60376e2381b2dec9c94734' + '289040c2789f429e73af946295e4d3f5' + '3dd128815be533b406353af0fec6081c' + 'f2d40d5c9ff1ea740463a2cecc6bd9a0' + '71adf77e5b9ba82a29ba448a4f5aa1d6') prepare() { cd $pkgname-$pkgver - patch -Np1 -i ../lxsession-0.4.6.1-logind-support.patch + + # lxsession-db: Don't hang when MIME folders are not available. + # https://sourceforge.net/p/lxde/patches/479/ + patch -Np1 -i ../fix-lxsession-db.patch + + # lxsession-edit: Fix segfault on exit when kf is not set. + # https://sourceforge.net/p/lxde/patches/480/ + patch -Np1 -i ../fix-lxsession-edit.patch + + # lxsession-logout: Fix user switch with LightDM when GDM is installed. + # https://sourceforge.net/p/lxde/patches/481/ + patch -Np1 -i ../fix-userswitch.patch + + # Set lxpolkit by default, so lxsession will autostart it on login. + # https://sourceforge.net/p/lxde/patches/478/ + patch -Np1 -i ../fix-lxpolkit.patch } build() { Added: fix-lxpolkit.patch =================================================================== --- fix-lxpolkit.patch (rev 0) +++ fix-lxpolkit.patch 2014-10-07 20:56:18 UTC (rev 120373) @@ -0,0 +1,18 @@ +commit a9f032312f8c1254b00840dd084e241c964897ea +Author: Balló György <ballog...@gmail.com> +Date: Tue Oct 7 21:19:52 2014 +0200 + + Set lxpolkit by default, so lxsession will autostart it on login. + +diff --git a/lxsession/settings.vala b/lxsession/settings.vala +index 399deb2..c31f49d 100644 +--- a/lxsession/settings.vala ++++ b/lxsession/settings.vala +@@ -252,6 +252,7 @@ namespace Lxsession + /* Keep old behavior for autostarted application if this option is not specify */ + set_generic_default("Session", "disable_autostart", null, "string", "no"); + ++ set_generic_default("Session", "polkit", "command", "string", "lxpolkit"); + set_generic_default("Session", "clipboard", "command", "string", "lxclipboard"); + set_generic_default("Session", "xsettings_manager", "command", "string", "build-in"); + set_generic_default("Session", "proxy_manager", "command", "string", "build-in"); Added: fix-lxsession-db.patch =================================================================== --- fix-lxsession-db.patch (rev 0) +++ fix-lxsession-db.patch 2014-10-07 20:56:18 UTC (rev 120373) @@ -0,0 +1,42 @@ +commit 5f37ab207ac330ac1cc2b3136793e2bcd4fbb2b4 +Author: Balló György <ballog...@gmail.com> +Date: Tue Oct 7 21:23:13 2014 +0200 + + lxsession-db: Don't hang when MIME folders are not available. + +diff --git a/lxsession-db/desktop-files-backend.vala b/lxsession-db/desktop-files-backend.vala +index d68644d..a9a52e8 100644 +--- a/lxsession-db/desktop-files-backend.vala ++++ b/lxsession-db/desktop-files-backend.vala +@@ -315,21 +315,21 @@ namespace Lxsession + } + } + } +- +- if (mode == "installed") +- { +- finish_scanning_installed(); +- } +- else if (mode == "available") +- { +- finish_scanning_available(); +- } +- + } + catch (Error err) + { + stderr.printf ("Error: list_files failed: %s\n", err.message); + } ++ ++ if (mode == "installed") ++ { ++ finish_scanning_installed(); ++ } ++ else if (mode == "available") ++ { ++ finish_scanning_available(); ++ } ++ + message ("Finishing scanning\n"); + } + Added: fix-lxsession-edit.patch =================================================================== --- fix-lxsession-edit.patch (rev 0) +++ fix-lxsession-edit.patch 2014-10-07 20:56:18 UTC (rev 120373) @@ -0,0 +1,24 @@ +commit a742cb3dd6d2e30bc3792d0d1741ee5fca887b1d +Author: Balló György <ballog...@gmail.com> +Date: Tue Oct 7 22:18:22 2014 +0200 + + lxsession-edit: Fix segfault on exit when kf is not set. + +diff --git a/lxsession-edit/lxsession-edit.c b/lxsession-edit/lxsession-edit.c +index 7e2a4c1..88fe9d1 100644 +--- a/lxsession-edit/lxsession-edit.c ++++ b/lxsession-edit/lxsession-edit.c +@@ -82,11 +82,12 @@ int main(int argc, char** argv) + load_autostart(session_name); + gtk_tree_view_set_model( (GtkTreeView*)autostarts, (GtkTreeModel*)get_autostart_list() ); + ++ kf = g_key_file_new(); ++ + /* if we are running under LXSession */ + if( g_getenv("_LXSESSION_PID") ) + { + /* wm settings (only show this when we are under lxsession) */ +- kf = g_key_file_new(); + cfg = g_build_filename( g_get_user_config_dir(), "lxsession", session_name, CONFIG_FILE_NAME, NULL ); + loaded = g_key_file_load_from_file(kf, cfg, 0, NULL); + if( !loaded ) Added: fix-userswitch.patch =================================================================== --- fix-userswitch.patch (rev 0) +++ fix-userswitch.patch 2014-10-07 20:56:18 UTC (rev 120373) @@ -0,0 +1,35 @@ +commit ec869453ecbb4a71611392b077b6c3f5fc093712 +Author: Balló György <ballog...@gmail.com> +Date: Tue Oct 7 21:28:55 2014 +0200 + + lxsession-logout: Fix user switch with LightDM when GDM is installed. + + We can't rely on gdmflexiserver, because GDM's version is incompatible with LightDM. + +diff --git a/lxsession-logout/lxsession-logout.c b/lxsession-logout/lxsession-logout.c +index 9ace78d..a928118 100644 +--- a/lxsession-logout/lxsession-logout.c ++++ b/lxsession-logout/lxsession-logout.c +@@ -530,21 +530,7 @@ int main(int argc, char * argv[]) + handler_context.switch_user_GDM = TRUE; + } + +- /* lightdm also use gdmflexiserver */ +- if (verify_running("lightdm", "gdmflexiserver")) +- { +- handler_context.switch_user_available = TRUE; +- handler_context.switch_user_GDM = TRUE; +- } +- +- /* lightdm also use gdmflexiserver */ +- if (verify_running("lightdm", "gdmflexiserver")) +- { +- handler_context.switch_user_available = TRUE; +- handler_context.switch_user_GDM = TRUE; +- } +- +- /* lightdm can also be find by the env */ ++ /* lightdm can be find by the env */ + if (g_getenv("XDG_SEAT_PATH")) + { + handler_context.switch_user_available = TRUE; Deleted: lxsession-0.4.6.1-logind-support.patch =================================================================== --- lxsession-0.4.6.1-logind-support.patch 2014-10-07 20:27:01 UTC (rev 120372) +++ lxsession-0.4.6.1-logind-support.patch 2014-10-07 20:56:18 UTC (rev 120373) @@ -1,608 +0,0 @@ ---- lxsession-0.4.6.1/lxsession-logout/dbus-interface.c 2011-07-27 21:26:36.000000000 +0200 -+++ lxsession-0.4.6.1/lxsession-logout-logind/dbus-interface.c 2012-11-13 17:26:30.807070976 +0100 -@@ -51,13 +51,20 @@ - char * dbus_HAL_Reboot(void); - char * dbus_HAL_Suspend(void); - char * dbus_HAL_Hibernate(void); -+gboolean dbus_logind_CanPowerOff(void); -+gboolean dbus_logind_CanReboot(void); -+gboolean dbus_logind_CanSuspend(void); -+gboolean dbus_logind_CanHibernate(void); -+char * dbus_logind_PowerOff(void); -+char * dbus_logind_Reboot(void); -+char * dbus_logind_Suspend(void); -+char * dbus_logind_Hibernate(void); -+char * dbus_LXDE_Logout(void); - /* End FORWARDS */ - - /* Connect to the system bus. Once a connection is made, it is saved for reuse. */ --static DBusConnection * dbus_connect(void) -+static DBusConnection * dbus_connect_system(void) - { -- if ((dbus_context.connection == NULL) && ( ! dbus_context.connection_tried)) -- { - DBusError error; - dbus_error_init(&error); - dbus_context.connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); -@@ -67,16 +74,57 @@ - dbus_error_free(&error); - } - dbus_context.connection_tried = TRUE; -- } - - return dbus_context.connection; - } - -+static DBusConnection * dbus_connect_session(void) -+{ -+ DBusError error; -+ dbus_error_init(&error); -+ dbus_context.connection = dbus_bus_get(DBUS_BUS_SESSION, &error); -+ if (dbus_context.connection == NULL) -+ { -+ g_warning(G_STRLOC ": Failed to connect to the session message bus: %s", error.message); -+ dbus_error_free(&error); -+ } -+ dbus_context.connection_tried = TRUE; -+ -+ return dbus_context.connection; -+} -+ -+ - /* Send a message. */ --static DBusMessage * dbus_send_message(DBusMessage * message, char * * error_text) -+static DBusMessage * dbus_send_message_system(DBusMessage * message, char * * error_text) - { - /* Get a connection handle. */ -- DBusConnection * connection = dbus_connect(); -+ DBusConnection * connection = dbus_connect_system(); -+ if (connection == NULL) -+ return FALSE; -+ -+ /* Send the message. */ -+ DBusError error; -+ dbus_error_init(&error); -+ DBusMessage * reply = dbus_connection_send_with_reply_and_block(connection, message, DBUS_TIMEOUT, &error); -+ dbus_message_unref(message); -+ if (reply == NULL) -+ { -+ if ((error.name == NULL) || (strcmp(error.name, DBUS_ERROR_NO_REPLY) != 0)) -+ { -+ if (error_text != NULL) -+ *error_text = g_strdup(error.message); -+ g_warning(G_STRLOC ": DBUS: %s", error.message); -+ } -+ dbus_error_free(&error); -+ } -+ return reply; -+} -+ -+/* Send a message. */ -+static DBusMessage * dbus_send_message_session(DBusMessage * message, char * * error_text) -+{ -+ /* Get a connection handle. */ -+ DBusConnection * connection = dbus_connect_session(); - if (connection == NULL) - return FALSE; - -@@ -132,6 +180,36 @@ - } - return result; - } -+ -+/* Read a result for a method that returns a string encoded boolean. */ -+static gboolean dbus_read_result_sboolean(DBusMessage * reply) -+{ -+ gboolean result = FALSE; -+ char* string_result; -+ if (reply != NULL) -+ { -+ /* Get the string result. */ -+ DBusError error; -+ dbus_error_init(&error); -+ dbus_bool_t status = dbus_message_get_args( -+ reply, -+ &error, -+ DBUS_TYPE_STRING, &string_result, -+ DBUS_TYPE_INVALID); -+ if ( ! status) -+ { -+ g_warning(G_STRLOC ": DBUS: %s", error.message); -+ dbus_error_free(&error); -+ } -+ else -+ { -+ if (!strcmp(string_result, "yes")) -+ result = TRUE; -+ } -+ dbus_message_unref(reply); -+ } -+ return result; -+} - #endif - - /*** ConsoleKit mechanism ***/ -@@ -152,7 +230,7 @@ - static gboolean dbus_ConsoleKit_query(const char * const query) - { - #ifdef HAVE_DBUS -- return dbus_read_result_boolean(dbus_send_message(dbus_ConsoleKit_formulate_message(query), NULL)); -+ return dbus_read_result_boolean(dbus_send_message_system(dbus_ConsoleKit_formulate_message(query), NULL)); - #else - return FALSE; - #endif -@@ -163,7 +241,7 @@ - { - #ifdef HAVE_DBUS - char * error = NULL; -- dbus_read_result_void(dbus_send_message(dbus_ConsoleKit_formulate_message(command), &error)); -+ dbus_read_result_void(dbus_send_message_system(dbus_ConsoleKit_formulate_message(command), &error)); - return error; - #else - return NULL; -@@ -225,7 +303,7 @@ - DBUS_TYPE_INVALID); - - /* Send the message. */ -- DBusMessage * reply = dbus_send_message(message, NULL); -+ DBusMessage * reply = dbus_send_message_system(message, NULL); - if (reply == NULL) - return FALSE; - -@@ -252,7 +330,7 @@ - { - #ifdef HAVE_DBUS - char * error = NULL; -- dbus_read_result_void(dbus_send_message(dbus_UPower_formulate_command(command), &error)); -+ dbus_read_result_void(dbus_send_message_system(dbus_UPower_formulate_command(command), &error)); - return error; - #else - return NULL; -@@ -329,7 +407,7 @@ - DBusMessage * message = dbus_HAL_formulate_string_property_query(property); - if (message == NULL) - return FALSE; -- DBusMessage * reply = dbus_send_message(message, NULL); -+ DBusMessage * reply = dbus_send_message_system(message, NULL); - if (reply == NULL) - return FALSE; - dbus_message_unref(reply); -@@ -343,7 +421,7 @@ - static gboolean dbus_HAL_boolean_query(const char * const property) - { - #ifdef HAVE_DBUS -- return dbus_read_result_boolean(dbus_send_message(dbus_HAL_formulate_boolean_property_query(property), NULL)); -+ return dbus_read_result_boolean(dbus_send_message_system(dbus_HAL_formulate_boolean_property_query(property), NULL)); - #else - return FALSE; - #endif -@@ -367,7 +445,7 @@ - - /* Send the message and wait for a reply. */ - char * error = NULL; -- dbus_read_result_void(dbus_send_message(message, &error)); -+ dbus_read_result_void(dbus_send_message_system(message, &error)); - return error; - #else - return NULL; -@@ -421,3 +499,185 @@ - { - return dbus_HAL_command("Hibernate"); - } -+ -+/*** logind mechanism ***/ -+ -+#ifdef HAVE_DBUS -+/* Formulate a message to the logind Manager interface to query a property. */ -+static DBusMessage * dbus_logind_formulate_query(const char * const query) -+{ -+ return dbus_message_new_method_call( -+ "org.freedesktop.login1", -+ "/org/freedesktop/login1", -+ "org.freedesktop.login1.Manager", -+ query); -+} -+ -+/* Formulate a message to the logind Manager interface. */ -+static DBusMessage * dbus_logind_formulate_message(const char * const method) -+{ -+ static dbus_bool_t interactive = FALSE; -+ DBusMessage * message = dbus_message_new_method_call( -+ "org.freedesktop.login1", -+ "/org/freedesktop/login1", -+ "org.freedesktop.login1.Manager", -+ method); -+ if (message != NULL) -+ dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &interactive, DBUS_TYPE_INVALID); -+ return message; -+} -+#endif -+ -+/* Send a specified query to the logind interface and process a boolean result. */ -+static gboolean dbus_logind_query(const char * const query) -+{ -+#ifdef HAVE_DBUS -+ return dbus_read_result_sboolean(dbus_send_message_system(dbus_logind_formulate_query(query), NULL)); -+#else -+ return FALSE; -+#endif -+} -+ -+/* Send a specified command to the logind interface and process a void result. */ -+static char * dbus_logind_command(const char * const command) -+{ -+#ifdef HAVE_DBUS -+ char * error = NULL; -+ dbus_read_result_void(dbus_send_message_system(dbus_logind_formulate_message(command), &error)); -+ return error; -+#else -+ return NULL; -+#endif -+} -+ -+/* Read the can-poweroff property of logind. */ -+gboolean dbus_logind_CanPowerOff(void) -+{ -+ return dbus_logind_query("CanPowerOff"); -+} -+ -+/* Read the can-reboot property of logind. */ -+gboolean dbus_logind_CanReboot(void) -+{ -+ return dbus_logind_query("CanReboot"); -+} -+ -+/* Read the can-suspend property of logind. */ -+gboolean dbus_logind_CanSuspend(void) -+{ -+ return dbus_logind_query("CanSuspend"); -+} -+ -+/* Read the can-hibernate property of logind. */ -+gboolean dbus_logind_CanHibernate(void) -+{ -+ return dbus_logind_query("CanHibernate"); -+} -+ -+/* Invoke the PowerOff method on logind. */ -+char * dbus_logind_PowerOff(void) -+{ -+ return dbus_logind_command("PowerOff"); -+} -+ -+/* Invoke the Reboot method on logind. */ -+char * dbus_logind_Reboot(void) -+{ -+ return dbus_logind_command("Reboot"); -+} -+ -+/* Invoke the Suspend method on logind. */ -+char * dbus_logind_Suspend(void) -+{ -+ return dbus_logind_command("Suspend"); -+} -+ -+/* Invoke the Hibernate method on logind. */ -+char * dbus_logind_Hibernate(void) -+{ -+ return dbus_logind_command("Hibernate"); -+} -+ -+/*** LXDE mechanism ***/ -+ -+#ifdef HAVE_DBUS -+/* Formulate a message to the LXDE Session Manager interface. */ -+static DBusMessage * dbus_LXDE_formulate_message(const char * const query) -+{ -+ return dbus_message_new_method_call( -+ "org.lxde.SessionManager", -+ "/org/lxde/SessionManager", -+ "org.lxde.SessionManager", -+ query); -+} -+#endif -+ -+/* Send a specified message to the LXDE interface and process a boolean result. */ -+static gboolean dbus_LXDE_query(const char * const query) -+{ -+#ifdef HAVE_DBUS -+ return dbus_read_result_boolean(dbus_send_message_session(dbus_LXDE_formulate_message(query), NULL)); -+#else -+ return FALSE; -+#endif -+} -+ -+/* Send a specified message to the LXDE interface and process a void result. */ -+static char * dbus_LXDE_command(const char * const command) -+{ -+#ifdef HAVE_DBUS -+ char * error = NULL; -+ dbus_read_result_void(dbus_send_message_session(dbus_LXDE_formulate_message(command), &error)); -+ return error; -+#else -+ return NULL; -+#endif -+} -+ -+/* Invoke the Logout method on LXDE. */ -+char * dbus_LXDE_Logout(void) -+{ -+ return dbus_LXDE_command("Logout"); -+} -+ -+/*** Lightdm mechanism ***/ -+ -+#ifdef HAVE_DBUS -+/* Formulate a message to the Lightdm interface. */ -+static DBusMessage * dbus_Lightdm_formulate_message(const char * const query) -+{ -+ return dbus_message_new_method_call( -+ "org.freedesktop.DisplayManager", -+ g_getenv ("XDG_SEAT_PATH"), -+ "org.freedesktop.DisplayManager.Seat", -+ query); -+} -+#endif -+ -+/* Send a specified message to the Lightdm interface and process a boolean result. */ -+static gboolean dbus_Lightdm_query(const char * const query) -+{ -+#ifdef HAVE_DBUS -+ return dbus_read_result_boolean(dbus_send_message_session(dbus_Lightdm_formulate_message(query), NULL)); -+#else -+ return FALSE; -+#endif -+} -+ -+/* Send a specified message to the Lightdm interface and process a void result. */ -+static char * dbus_Lightdm_command(const char * const command) -+{ -+#ifdef HAVE_DBUS -+ char * error = NULL; -+ dbus_read_result_void(dbus_send_message_session(dbus_Lightdm_formulate_message(command), &error)); -+ return error; -+#else -+ return NULL; -+#endif -+} -+ -+/* Invoke the Logout method on LXDE. */ -+char * dbus_Lightdm_SwitchToGreeter(void) -+{ -+ return dbus_Lightdm_command("SwitchToGreeter"); -+} ---- lxsession-0.4.6.1/lxsession-logout/dbus-interface.h 2011-07-27 21:26:36.000000000 +0200 -+++ lxsession-0.4.6.1/lxsession-logout-logind/dbus-interface.h 2012-11-13 17:26:30.807070976 +0100 -@@ -44,4 +44,18 @@ - extern char * dbus_HAL_Suspend(void); - extern char * dbus_HAL_Hibernate(void); - -+/* Interface to logind for shutdown, reboot, suspend, and hibernate. */ -+extern gboolean dbus_logind_CanPowerOff(void); -+extern gboolean dbus_logind_CanRestart(void); -+extern char * dbus_logind_PowerOff(void); -+extern char * dbus_logind_Restart(void); -+extern gboolean dbus_logind_CanSuspend(void); -+extern gboolean dbus_logind_CanHibernate(void); -+extern char * dbus_logind_Suspend(void); -+extern char * dbus_logind_Hibernate(void); -+ -+extern char * dbus_LXDE_Logout(void); -+ -+extern char * dbus_Lightdm_SwitchToGreeter(); -+ - #endif ---- lxsession-0.4.6.1/lxsession-logout/lxsession-logout.c 2011-07-27 21:26:36.000000000 +0200 -+++ lxsession-0.4.6.1/lxsession-logout-logind/lxsession-logout.c 2012-11-13 17:26:30.807070976 +0100 -@@ -69,12 +69,21 @@ - int reboot_HAL : 1; /* Reboot is available via HAL */ - int suspend_HAL : 1; /* Suspend is available via HAL */ - int hibernate_HAL : 1; /* Hibernate is available via HAL */ -+ int shutdown_logind : 1; /* Shutdown is available via logind */ -+ int reboot_logind : 1; /* Reboot is available via logind */ -+ int suspend_logind : 1; /* Suspend is available via logind */ -+ int hibernate_logind : 1; /* Hibernate is available via logind */ - int switch_user_GDM : 1; /* Switch User is available via GDM */ -- int switch_user_KDM : 1; /* Switch User is available via KDM */ -+ int switch_user_LIGHTDM : 1; /* Switch User is available via GDM */ -+ int switch_user_KDM : 1; /* Switch User is available via LIGHTDM */ - int ltsp : 1; /* Shutdown and reboot is accomplished via LTSP */ -+ -+ int lock_screen : 1; /* Lock screen available */ -+ - } HandlerContext; - - static gboolean lock_screen(void); -+static const gchar* determine_lock_screen(void); - static gboolean verify_running(const char * display_manager, const char * executable); - static void logout_clicked(GtkButton * button, HandlerContext * handler_context); - static void change_root_property(GtkWidget* w, const char* prop_name, const char* value); -@@ -93,13 +102,32 @@ - */ - static gboolean lock_screen(void) - { -- if (!g_spawn_command_line_async("lxlock", NULL)) -+ const gchar* program = determine_lock_screen(); -+ -+ if (program) - { -+ g_spawn_command_line_async(program, NULL); - return TRUE; - } - return FALSE; - } - -+static const gchar* determine_lock_screen(void) -+{ -+ const gchar* program = NULL; -+ -+ if (g_find_program_in_path("lxlock")) -+ { -+ program = "lxlock"; -+ } -+ else if (g_find_program_in_path("xdg-screensaver")) -+ { -+ program = "xdg-screensaver lock"; -+ } -+ return program; -+} -+ -+ - /* Verify that a program is running and that an executable is available. */ - static gboolean verify_running(const char * display_manager, const char * executable) - { -@@ -187,6 +215,8 @@ - error_result = dbus_ConsoleKit_Stop(); - else if (handler_context->shutdown_HAL) - error_result = dbus_HAL_Shutdown(); -+ else if (handler_context->shutdown_logind) -+ error_result = dbus_logind_PowerOff(); - - if (error_result != NULL) - gtk_label_set_text(GTK_LABEL(handler_context->error_label), error_result); -@@ -208,6 +238,8 @@ - error_result = dbus_ConsoleKit_Restart(); - else if (handler_context->reboot_HAL) - error_result = dbus_HAL_Reboot(); -+ else if (handler_context->reboot_logind) -+ error_result = dbus_logind_Reboot(); - - if (error_result != NULL) - gtk_label_set_text(GTK_LABEL(handler_context->error_label), error_result); -@@ -225,6 +257,8 @@ - error_result = dbus_UPower_Suspend(); - else if (handler_context->suspend_HAL) - error_result = dbus_HAL_Suspend(); -+ else if (handler_context->suspend_logind) -+ error_result = dbus_logind_Suspend(); - - if (error_result != NULL) - gtk_label_set_text(GTK_LABEL(handler_context->error_label), error_result); -@@ -242,6 +276,8 @@ - error_result = dbus_UPower_Hibernate(); - else if (handler_context->hibernate_HAL) - error_result = dbus_HAL_Hibernate(); -+ else if (handler_context->hibernate_logind) -+ error_result = dbus_logind_Hibernate(); - - if (error_result != NULL) - gtk_label_set_text(GTK_LABEL(handler_context->error_label), error_result); -@@ -258,6 +294,17 @@ - g_spawn_command_line_sync("gdmflexiserver --startnew", NULL, NULL, NULL, NULL); - else if (handler_context->switch_user_KDM) - g_spawn_command_line_sync("kdmctl reserve", NULL, NULL, NULL, NULL); -+ else if (handler_context->switch_user_LIGHTDM) -+ dbus_Lightdm_SwitchToGreeter(); -+ gtk_main_quit(); -+} -+ -+/* Handler for "clicked" signal on Lock button. */ -+static void lock_screen_clicked(GtkButton * button, HandlerContext * handler_context) -+{ -+ gtk_label_set_text(GTK_LABEL(handler_context->error_label), NULL); -+ -+ lock_screen(); - gtk_main_quit(); - } - -@@ -435,6 +482,28 @@ - handler_context.hibernate_HAL = TRUE; - } - -+ /* Initialize capabilities of the logind mechanism. */ -+ if (!handler_context.shutdown_available && dbus_logind_CanPowerOff()) -+ { -+ handler_context.shutdown_available = TRUE; -+ handler_context.shutdown_logind = TRUE; -+ } -+ if (!handler_context.reboot_available && dbus_logind_CanReboot()) -+ { -+ handler_context.reboot_available = TRUE; -+ handler_context.reboot_logind = TRUE; -+ } -+ if (!handler_context.suspend_available && dbus_logind_CanSuspend()) -+ { -+ handler_context.suspend_available = TRUE; -+ handler_context.suspend_logind = TRUE; -+ } -+ if (!handler_context.hibernate_available && dbus_logind_CanHibernate()) -+ { -+ handler_context.hibernate_available = TRUE; -+ handler_context.hibernate_logind = TRUE; -+ } -+ - /* If we are under GDM, its "Switch User" is available. */ - if (verify_running("gdm", "gdmflexiserver")) - { -@@ -442,6 +511,34 @@ - handler_context.switch_user_GDM = TRUE; - } - -+ /* If we are under GDM3, its "Switch User" is available. */ -+ if (verify_running("gdm3", "gdmflexiserver")) -+ { -+ handler_context.switch_user_available = TRUE; -+ handler_context.switch_user_GDM = TRUE; -+ } -+ -+ /* lightdm also use gdmflexiserver */ -+ if (verify_running("lightdm", "gdmflexiserver")) -+ { -+ handler_context.switch_user_available = TRUE; -+ handler_context.switch_user_GDM = TRUE; -+ } -+ -+ /* lightdm also use gdmflexiserver */ -+ if (verify_running("lightdm", "gdmflexiserver")) -+ { -+ handler_context.switch_user_available = TRUE; -+ handler_context.switch_user_GDM = TRUE; -+ } -+ -+ /* lightdm can also be find by the env */ -+ if (g_getenv("XDG_SEAT_PATH")) -+ { -+ handler_context.switch_user_available = TRUE; -+ handler_context.switch_user_LIGHTDM = TRUE; -+ } -+ - /* If we are under KDM, its "Switch User" is available. */ - if (verify_running("kdm", "kdmctl")) - { -@@ -451,7 +548,18 @@ - - /* LTSP support */ - if (g_getenv("LTSP_CLIENT")) -+ { - handler_context.ltsp = TRUE; -+ handler_context.shutdown_available = TRUE; -+ handler_context.reboot_available = TRUE; -+ } -+ -+ /* Lock screen */ -+ const gchar* very_lock_screen = determine_lock_screen(); -+ if (very_lock_screen) -+ { -+ handler_context.lock_screen = TRUE; -+ } - - /* Make the button images accessible. */ - gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), PACKAGE_DATA_DIR "/lxsession/images"); -@@ -596,6 +704,17 @@ - gtk_box_pack_start(GTK_BOX(controls), switch_user_button, FALSE, FALSE, 4); - } - -+ /* Create the Lock Screen button. */ -+ if (handler_context.lock_screen && !handler_context.ltsp) -+ { -+ GtkWidget * lock_screen_button = gtk_button_new_with_mnemonic(_("L_ock Screen")); -+ GtkWidget * image = gtk_image_new_from_icon_name("system-lock-screen", GTK_ICON_SIZE_BUTTON); -+ gtk_button_set_image(GTK_BUTTON(lock_screen_button), image); -+ gtk_button_set_alignment(GTK_BUTTON(lock_screen_button), 0.0, 0.5); -+ g_signal_connect(G_OBJECT(lock_screen_button), "clicked", G_CALLBACK(lock_screen_clicked), &handler_context); -+ gtk_box_pack_start(GTK_BOX(controls), lock_screen_button, FALSE, FALSE, 4); -+ } -+ - /* Create the Logout button. */ - GtkWidget * logout_button = gtk_button_new_with_mnemonic(_("_Logout")); - GtkWidget * image = gtk_image_new_from_icon_name("system-log-out", GTK_ICON_SIZE_BUTTON);