Fri, 30 Jun 2017 03:55:21 +0000
Merged in CMaiku/pidgin (pull request #226)
Use GtkApplication session manager
Approved-by: Gary Kramlich <grim@reaperworld.com>
Approved-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
Approved-by: Eion Robb <eionrobb@gmail.com>
| configure.ac | file | annotate | diff | comparison | revisions | |
| pidgin/Makefile.am | file | annotate | diff | comparison | revisions | |
| pidgin/gtksession.c | file | annotate | diff | comparison | revisions | |
| pidgin/gtksession.h | file | annotate | diff | comparison | revisions | |
| pidgin/libpidgin.c | file | annotate | diff | comparison | revisions |
--- a/config.h.mingw Thu Jun 29 22:14:07 2017 -0500 +++ b/config.h.mingw Fri Jun 30 03:55:21 2017 +0000 @@ -287,9 +287,6 @@ /* Define to 1 if you have X11 */ /* #define HAVE_X11 1 */ -/* Define to 1 if you have the <X11/SM/SMlib.h> header file. */ -/* #define HAVE_X11_SM_SMLIB_H 1 */ - /* whether or not we have xsltproc for devhelp index */ /* #define HAVE_XSLTPROC 1 */ @@ -360,9 +357,6 @@ /* Define if we're using XScreenSaver. */ #define USE_SCREENSAVER 1 -/* Define if we're using X Session Management. */ -/* #define USE_SM 1 */ - /* Use voice and video */ /* #define USE_VV 1 */
--- a/configure.ac Thu Jun 29 22:14:07 2017 -0500 +++ b/configure.ac Fri Jun 30 03:55:21 2017 +0000 @@ -523,10 +523,6 @@ [AS_HELP_STRING([--disable-screensaver], [compile without X screensaver extension (used to detect idleness)])], enable_screensaver="$enableval", enable_screensaver="yes") -AC_ARG_ENABLE(sm, - [AS_HELP_STRING([--disable-sm], - [compile without X session management support])], - enable_sm="$enableval", enable_sm="yes") AC_ARG_ENABLE(startup-notification, [AS_HELP_STRING([--disable-startup-notification], [compile without startup notification support])], @@ -645,7 +641,6 @@ AC_SUBST(X11_CFLAGS) else enable_screensaver=no - enable_sm=no enable_gestures=no fi @@ -691,36 +686,6 @@ fi dnl ####################################################################### - dnl # Check for X session management libs - dnl ####################################################################### - if test "x$enable_sm" = "xyes"; then - if test "x$with_x" = "xyes" ; then - enable_sm=no - AC_CHECK_LIB(SM, SmcSaveYourselfDone, found_sm_lib=true, , [$x_libpath_add -lICE]) - if test "x$found_sm_lib" = "xtrue"; then - oldCPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $x_incpath_add" - AC_CHECK_HEADERS(X11/SM/SMlib.h, SM_LIBS="$x_libpath_add -lSM -lICE" enable_sm=yes) - CPPFLAGS="$oldCPPFLAGS" - fi - - if test "x$enable_sm" = "xyes"; then - AC_DEFINE(USE_SM, 1, [Define if we're using X Session Management.]) - AC_SUBST(SM_LIBS) - else - if test "x$force_deps" = "xyes" ; then - AC_MSG_ERROR([ -X session management development headers not found. -Use --disable-sm if you do not need session management support. -]) - fi - fi - else - AC_MSG_ERROR([X support is required to build with X session management support]) - fi - fi - - dnl ####################################################################### dnl # Check for X11 to allow the gestures plugin dnl ####################################################################### if test "x$enable_gestures" = "xyes"; then @@ -788,7 +753,6 @@ enable_cap=no enable_gevolution=no enable_screensaver=no - enable_sm=no enable_startup_notification=no fi # GTK @@ -2172,7 +2136,6 @@ echo Has you....................... : yes echo echo Use XScreenSaver Extension.... : $enable_screensaver -echo Use X Session Management...... : $enable_sm echo Use startup notification...... : $enable_startup_notification echo Build with Enchant support.... : $use_enchant echo Build with GCR widgets........ : $enable_gcr
--- a/doc/reference/pidgin/Makefile.am Thu Jun 29 22:14:07 2017 -0500 +++ b/doc/reference/pidgin/Makefile.am Fri Jun 30 03:55:21 2017 +0000 @@ -120,7 +120,6 @@ $(GSTVIDEO_LIBS) \ $(GSTINTERFACES_LIBS) \ $(XSS_LIBS) \ - $(SM_LIBS) \ $(INTLLIBS) \ $(LIBXML_LIBS) \ $(WEBKIT_LIBS) \
--- a/pidgin/Makefile.am Thu Jun 29 22:14:07 2017 -0500 +++ b/pidgin/Makefile.am Fri Jun 30 03:55:21 2017 +0000 @@ -72,7 +72,6 @@ gtkroomlist.c \ gtksavedstatuses.c \ gtkscrollbook.c \ - gtksession.c \ gtksmiley-manager.c \ gtksmiley-theme.c \ gtksound.c \ @@ -121,7 +120,6 @@ gtkroomlist.h \ gtksavedstatuses.h \ gtkscrollbook.h \ - gtksession.h \ gtksmiley-manager.h \ gtksmiley-theme.h \ gtksound.h \ @@ -203,7 +201,6 @@ $(GSTVIDEO_LIBS) \ $(GSTINTERFACES_LIBS) \ $(XSS_LIBS) \ - $(SM_LIBS) \ $(INTLLIBS) \ $(LIBXML_LIBS) \ $(WEBKIT_LIBS) \
--- a/pidgin/gtkdialogs.c Thu Jun 29 22:14:07 2017 -0500 +++ b/pidgin/gtkdialogs.c Fri Jun 30 03:55:21 2017 +0000 @@ -696,12 +696,6 @@ #endif #ifndef _WIN32 -#ifdef USE_SM - g_string_append(str, "<dt>X Session Management:</dt><dd>Enabled</dd>"); -#else - g_string_append(str, "<dt>X Session Management:</dt><dd>Disabled</dd>"); -#endif - #ifdef USE_SCREENSAVER g_string_append(str, "<dt>XScreenSaver:</dt><dd>Enabled</dd>"); #else
--- a/pidgin/gtksession.c Thu Jun 29 22:14:07 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,414 +0,0 @@ -/* Pidgin is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - * - */ -#include "internal.h" - -#include "core.h" -#include "debug.h" -#include "eventloop.h" -#include "gtksession.h" - -#ifdef USE_SM - -#include <X11/ICE/ICElib.h> -#include <X11/SM/SMlib.h> -#include <gdk/gdkx.h> -#include <unistd.h> -#include <fcntl.h> -#include <gdk/gdk.h> -#include <gtk/gtk.h> - -#include "gtk3compat.h" - -#define ERROR_LENGTH 512 - -static IceIOErrorHandler ice_installed_io_error_handler; -static SmcConn session = NULL; -static gchar *myself = NULL; -static gboolean had_first_save = FALSE; -static gboolean session_managed = FALSE; - -/* ICE belt'n'braces stuff */ - -struct ice_connection_info { - IceConn connection; - guint input_id; -}; - -static void ice_process_messages(gpointer data, gint fd, - PurpleInputCondition condition) { - struct ice_connection_info *conninfo = (struct ice_connection_info*) data; - IceProcessMessagesStatus status; - - /* please don't block... please! */ - status = IceProcessMessages(conninfo->connection, NULL, NULL); - - if (status == IceProcessMessagesIOError) { - purple_debug(PURPLE_DEBUG_INFO, "Session Management", - "ICE IO error, closing connection... "); - - /* IO error, please disconnect */ - IceSetShutdownNegotiation(conninfo->connection, False); - IceCloseConnection(conninfo->connection); - - if (purple_debug_is_verbose()) { - purple_debug_misc("Session Management", - "Connection closed."); - } - - /* cancel the handler */ - purple_input_remove(conninfo->input_id); - } -} - -static void ice_connection_watch(IceConn connection, IcePointer client_data, - Bool opening, IcePointer *watch_data) { - struct ice_connection_info *conninfo = NULL; - - if (opening) { - purple_debug_misc("Session Management", - "Handling new ICE connection..."); - - /* ensure ICE connection is not passed to child processes */ - if (fcntl(IceConnectionNumber(connection), F_SETFD, FD_CLOEXEC) != 0) - purple_debug_warning("gtksession", "couldn't set FD_CLOEXEC\n"); - - conninfo = g_new(struct ice_connection_info, 1); - conninfo->connection = connection; - - /* watch the connection */ - conninfo->input_id = purple_input_add(IceConnectionNumber(connection), PURPLE_INPUT_READ, - ice_process_messages, conninfo); - *watch_data = conninfo; - } else { - purple_debug(PURPLE_DEBUG_INFO, "Session Management", - "Handling closed ICE connection... \n"); - - /* get the input ID back and stop watching it */ - conninfo = (struct ice_connection_info*) *watch_data; - purple_input_remove(conninfo->input_id); - g_free(conninfo); - } - - if (purple_debug_is_verbose()) { - purple_debug_misc("Session Management", - "ICE connection handled."); - } -} - -/* We call any handler installed before (or after) ice_init but - * avoid calling the default libICE handler which does an exit(). - * - * This means we do nothing by default, which is probably correct, - * the connection will get closed by libICE - */ - -static void ice_io_error_handler(IceConn connection) { - purple_debug(PURPLE_DEBUG_INFO, "Session Management", - "Handling ICE IO error... "); - - if (ice_installed_io_error_handler) - (*ice_installed_io_error_handler)(connection); - - if (purple_debug_is_verbose()) { - purple_debug_misc("Session Management", - "ICE IO error handled."); - } -} - -static void ice_init(void) { - IceIOErrorHandler default_handler; - - ice_installed_io_error_handler = IceSetIOErrorHandler(NULL); - default_handler = IceSetIOErrorHandler(ice_io_error_handler); - - if (ice_installed_io_error_handler == default_handler) - ice_installed_io_error_handler = NULL; - - IceAddConnectionWatch(ice_connection_watch, NULL); - - if (purple_debug_is_verbose()) { - purple_debug_misc("Session Management", "ICE initialized."); - } -} - -/* my magic utility function */ - -static gchar **session_make_command(gchar *client_id, gchar *config_dir) { - gint i = 4; - gint j = 0; - gchar **ret; - - if (client_id) i += 2; - if (config_dir) i += 2; /* we will specify purple's user dir */ - - ret = g_new(gchar *, i); - ret[j++] = g_strdup(myself); - - if (client_id) { - ret[j++] = g_strdup("--session"); - ret[j++] = g_strdup(client_id); - } - - if (config_dir) { - ret[j++] = g_strdup("--config"); - ret[j++] = g_strdup(config_dir); - } - - ret[j++] = g_strdup("--display"); - ret[j++] = g_strdup((gchar *)gdk_display_get_name(gdk_display_get_default())); - - ret[j] = NULL; - - return ret; -} - -/* SM callback handlers */ - -static void session_save_yourself(SmcConn conn, SmPointer data, int save_type, - Bool shutdown, int interact_style, Bool fast) { - if (had_first_save == FALSE && save_type == SmSaveLocal && - interact_style == SmInteractStyleNone && !shutdown && - !fast) { - /* this is just a dry run, spit it back */ - purple_debug(PURPLE_DEBUG_INFO, "Session Management", - "Received first save_yourself\n"); - SmcSaveYourselfDone(conn, True); - had_first_save = TRUE; - return; - } - - /* tum ti tum... don't add anything else here without * - * reading SMlib.PS from an X.org ftp server near you */ - - purple_debug(PURPLE_DEBUG_INFO, "Session Management", - "Received save_yourself\n"); - - if (save_type == SmSaveGlobal || save_type == SmSaveBoth) { - /* may as well do something ... */ - /* or not -- save_prefs(); */ - } - - SmcSaveYourselfDone(conn, True); -} - -static void session_die(SmcConn conn, SmPointer data) { - purple_debug(PURPLE_DEBUG_INFO, "Session Management", - "Received die\n"); - purple_core_quit(); -} - -static void session_save_complete(SmcConn conn, SmPointer data) { - purple_debug(PURPLE_DEBUG_INFO, "Session Management", - "Received save_complete\n"); -} - -static void session_shutdown_cancelled(SmcConn conn, SmPointer data) { - purple_debug(PURPLE_DEBUG_INFO, "Session Management", - "Received shutdown_cancelled\n"); -} - -/* utility functions stolen from Gnome-client */ - -static void session_set_value(SmcConn conn, gchar *name, char *type, - int num_vals, SmPropValue *vals) { - SmProp *proplist[1]; - SmProp prop; - - g_return_if_fail(conn); - - prop.name = name; - prop.type = type; - prop.num_vals = num_vals; - prop.vals = vals; - - proplist[0] = ∝ - SmcSetProperties(conn, 1, proplist); -} - -static void session_set_string(SmcConn conn, gchar *name, gchar *value) { - SmPropValue val; - - g_return_if_fail(name); - - val.length = strlen (value)+1; - val.value = value; - - session_set_value(conn, name, SmARRAY8, 1, &val); -} - -static void session_set_gchar(SmcConn conn, gchar *name, gchar value) { - SmPropValue val; - - g_return_if_fail(name); - - val.length = 1; - val.value = &value; - - session_set_value(conn, name, SmCARD8, 1, &val); -} - -static void session_set_array(SmcConn conn, gchar *name, gchar *array[]) { - gint argc; - gchar **ptr; - gint i; - - SmPropValue *vals; - - g_return_if_fail (name); - - /* We count the number of elements in our array. */ - for (ptr = array, argc = 0; *ptr ; ptr++, argc++) /* LOOP */; - - /* Now initialize the 'vals' array. */ - vals = g_new (SmPropValue, argc); - for (ptr = array, i = 0 ; i < argc ; ptr++, i++) { - vals[i].length = strlen (*ptr); - vals[i].value = *ptr; - } - - session_set_value(conn, name, SmLISTofARRAY8, argc, vals); - - g_free (vals); -} - -#endif /* USE_SM */ - -/* setup functions */ - -void -pidgin_session_init(gchar *argv0, gchar *previous_id, gchar *config_dir) -{ -#ifdef USE_SM - SmcCallbacks callbacks; - gchar *client_id = NULL; - gchar error[ERROR_LENGTH] = ""; - gchar *tmp = NULL; - gchar **cmd = NULL; - - if (session != NULL) { - /* session is already established, what the hell is going on? */ - purple_debug(PURPLE_DEBUG_WARNING, "Session Management", - "Duplicated call to pidgin_session_init!\n"); - return; - } - - if (g_getenv("SESSION_MANAGER") == NULL) { - purple_debug(PURPLE_DEBUG_ERROR, "Session Management", - "No SESSION_MANAGER found, aborting.\n"); - return; - } - - ice_init(); - - callbacks.save_yourself.callback = session_save_yourself; - callbacks.die.callback = session_die; - callbacks.save_complete.callback = session_save_complete; - callbacks.shutdown_cancelled.callback = session_shutdown_cancelled; - - callbacks.save_yourself.client_data = NULL; - callbacks.die.client_data = NULL; - callbacks.save_complete.client_data = NULL; - callbacks.shutdown_cancelled.client_data = NULL; - - if (previous_id) { - purple_debug(PURPLE_DEBUG_INFO, "Session Management", - "Connecting with previous ID %s\n", previous_id); - } else { - purple_debug(PURPLE_DEBUG_INFO, "Session Management", - "Connecting with no previous ID\n"); - } - - session = SmcOpenConnection(NULL, "session", SmProtoMajor, SmProtoMinor, SmcSaveYourselfProcMask | - SmcDieProcMask | SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask, - &callbacks, previous_id, &client_id, ERROR_LENGTH, error); - - if (session == NULL) { - if (error[0] != '\0') { - purple_debug(PURPLE_DEBUG_ERROR, "Session Management", - "Connection failed with error: %s\n", error); - } else { - purple_debug(PURPLE_DEBUG_ERROR, "Session Management", - "Connetion failed with unknown error.\n"); - } - return; - } - - tmp = SmcVendor(session); - purple_debug(PURPLE_DEBUG_INFO, "Session Management", - "Connected to manager (%s) with client ID %s\n", - tmp, client_id); - free(tmp); - - session_managed = TRUE; - gdk_x11_set_sm_client_id(client_id); - - tmp = g_get_current_dir(); - session_set_string(session, SmCurrentDirectory, tmp); - g_free(tmp); - - tmp = g_strdup_printf("%d", (int) getpid()); - session_set_string(session, SmProcessID, tmp); - g_free(tmp); - - tmp = g_strdup(g_get_user_name()); - session_set_string(session, SmUserID, tmp); - g_free(tmp); - - session_set_gchar(session, SmRestartStyleHint, (gchar) SmRestartIfRunning); - session_set_string(session, SmProgram, (gchar *) g_get_prgname()); - - myself = g_strdup(argv0); - purple_debug(PURPLE_DEBUG_MISC, "Session Management", - "Using %s as command\n", myself); - - cmd = session_make_command(NULL, config_dir); - session_set_array(session, SmCloneCommand, cmd); - g_strfreev(cmd); - - /* this is currently useless, but gnome-session warns 'the following applications will not - save their current status' bla bla if we don't have it and the user checks 'Save Session' - when they log out */ - cmd = g_new(gchar *, 2); - cmd[0] = g_strdup("/bin/true"); - cmd[1] = NULL; - session_set_array(session, SmDiscardCommand, cmd); - g_strfreev(cmd); - - cmd = session_make_command(client_id, config_dir); - session_set_array(session, SmRestartCommand, cmd); - g_strfreev(cmd); - - g_free(client_id); -#endif /* USE_SM */ -} - -void -pidgin_session_end() -{ -#ifdef USE_SM - if (session == NULL) /* no session to close */ - return; - - SmcCloseConnection(session, 0, NULL); - - purple_debug(PURPLE_DEBUG_INFO, "Session Management", - "Connection closed.\n"); -#endif /* USE_SM */ -}
--- a/pidgin/gtksession.h Thu Jun 29 22:14:07 2017 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* pidgin - * - * Pidgin is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef _PIDGINSESSION_H_ -#define _PIDGINSESSION_H_ -/** - * SECTION:gtksession - * @section_id: pidgin-gtksession - * @short_description: <filename>gtksession.h</filename> - * @title: X Windows Session Management - */ - -G_BEGIN_DECLS - -/**************************************************************************/ -/* X Windows session subsystem */ -/**************************************************************************/ - -/** - * pidgin_session_init: - * @argv0: The first argument passed into the program. This - * will be the name of the executable, e.g. 'purple' - * @previous_id: An optional session ID to use. This can be NULL. - * @config_dir: The path to the configuration directory used by - * this instance of this program, e.g. '/home/user/.purple' - * - * Register this instance of Pidgin with the user's current session - * manager. - */ -void pidgin_session_init(gchar *argv0, gchar *previous_id, gchar *config_dir); - -/** - * pidgin_session_end: - * - * Unregister this instance of Pidgin with the user's current session - * manager. - */ -void pidgin_session_end(void); - -G_END_DECLS - -#endif /* _PIDGINSESSION_H_ */
--- a/pidgin/libpidgin.c Thu Jun 29 22:14:07 2017 -0500 +++ b/pidgin/libpidgin.c Fri Jun 30 03:55:21 2017 +0000 @@ -61,7 +61,6 @@ #include "gtkrequest.h" #include "gtkroomlist.h" #include "gtksavedstatuses.h" -#include "gtksession.h" #include "gtksmiley-theme.h" #include "gtksound.h" #include "gtkutils.h" @@ -292,11 +291,6 @@ static void pidgin_quit(void) { -#ifdef USE_SM - /* unplug */ - pidgin_session_end(); -#endif - /* Uninit */ pidgin_utils_uninit(); pidgin_notify_uninit(); @@ -715,6 +709,8 @@ app = G_APPLICATION(gtk_application_new("im.pidgin.Pidgin", G_APPLICATION_NON_UNIQUE)); + g_object_set(app, "register-session", TRUE, NULL); + g_signal_connect(app, "activate", G_CALLBACK(pidgin_activate_cb), NULL); @@ -797,9 +793,6 @@ ui_main(); -#ifdef USE_SM - pidgin_session_init(argv[0], opt_session_arg, opt_config_dir_arg); -#endif g_free(opt_session_arg); opt_session_arg = NULL; g_free(opt_config_dir_arg);