diff --git a/lisp/startup.el b/lisp/startup.el index bb55080..19bdb84 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -99,6 +99,11 @@ startup message unless he personally acts to inhibit it." :type 'boolean :group 'initialization) +(defcustom inhibit-x-session-manager nil + "Non-nil inhibits connecting to the X session manager on startup." + :type 'boolean + :group 'initialization) + (defvar command-switch-alist nil "Alist of command-line switches. Elements look like (SWITCH-STRING . HANDLER-FUNCTION). @@ -1318,6 +1323,20 @@ Consider using a subdirectory instead, e.g.: %s" dir ;; If -batch, terminate after processing the command options. (if noninteractive (kill-emacs t)) + (when (and (not inhibit-x-session-manager) + (or (get 'x 'window-system-initialized) + (getenv "DISPLAY"))) + (condition-case err + (progn + (unless (get 'x 'window-system-initialized) + (x-initialize-window-system) + (put 'x 'window-system-initialized t)) + (x-session-initialize x-display-name)) + (error (display-warning + 'initialization + (format "Could not connect to X session manager: %s" err) + :warning)))) + ;; In daemon mode, start the server to allow clients to connect. ;; This is done after loading the user's init file and after ;; processing all command line arguments to allow e.g. `server-name' diff --git a/src/xsmfns.c b/src/xsmfns.c index 81b0126..6670604 100644 --- a/src/xsmfns.c +++ b/src/xsmfns.c @@ -59,6 +59,10 @@ static int doing_interact; static SmcConn smc_conn; +/* The X terminal on which the session manager connection is opened. */ + +static struct terminal *smc_terminal; + /* The client session id for this session. */ static char *client_id; @@ -390,8 +394,14 @@ create_client_leader_window (struct x_display_info *dpyinfo, char *client_ID) /* Try to open a connection to the session manager. */ -void -x_session_initialize (struct x_display_info *dpyinfo) +DEFUN ("x-session-initialize", Fx_session_initialize, + Sx_session_initialize, 0, 1, 0, + doc: /* Initialize the connection to the X session manager. +This is done automatically on startup if `inhibit-x-session-manager' +is non-nil. The optional parameter TERMINAL should be the X terminal +on which to open the connection. X should be initialized using +`x-initialize-window-system' before calling this. */) + (Lisp_Object terminal) { #define SM_ERRORSTRING_LEN 512 char errorstring[SM_ERRORSTRING_LEN]; @@ -399,6 +409,8 @@ x_session_initialize (struct x_display_info *dpyinfo) SmcCallbacks callbacks; ptrdiff_t name_len = 0; + struct x_display_info *dpyinfo = check_x_display_info (terminal); + ice_fd = -1; doing_interact = False; @@ -465,15 +477,33 @@ x_session_initialize (struct x_display_info *dpyinfo) #else create_client_leader_window (dpyinfo, client_id); #endif + + smc_terminal = dpyinfo->terminal; + smc_terminal->reference_count++; } + + return Qnil; } /* Ensure that the session manager is not contacted again. */ -void -x_session_close (void) +DEFUN ("x-session-close", Fx_session_close, + Sx_session_close, 0, 0, 0, + doc: /* Close the connection to the X session manager. */) + () { + SmcCloseConnection (smc_conn, 0, 0); ice_connection_closed (); + + smc_terminal->reference_count--; + if (smc_terminal->reference_count == 0) + { + Lisp_Object tmp; + XSETTERMINAL (tmp, smc_terminal); + Fdelete_terminal (tmp, Qnil); + } + + return Qnil; } @@ -563,6 +593,8 @@ See also `emacs-save-session-functions', `emacs-session-save' and Vx_session_previous_id = Qnil; defsubr (&Shandle_save_session); + defsubr (&Sx_session_initialize); + defsubr (&Sx_session_close); } #endif /* HAVE_X_SM */ diff --git a/src/xterm.c b/src/xterm.c index beb7d78..42ff947 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -11180,14 +11180,6 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) #endif } -#ifdef HAVE_X_SM - /* Only do this for the very first display in the Emacs session. - Ignore X session management when Emacs was first started on a - tty. */ - if (terminal->id == 1) - x_session_initialize (dpyinfo); -#endif - unblock_input (); return dpyinfo; @@ -11206,11 +11198,6 @@ x_delete_display (struct x_display_info *dpyinfo) for (t = terminal_list; t; t = t->next_terminal) if (t->type == output_x_window && t->display_info.x == dpyinfo) { -#ifdef HAVE_X_SM - /* Close X session management when we close its display. */ - if (t->id == 1 && x_session_have_connection ()) - x_session_close (); -#endif delete_terminal (t); break; } diff --git a/src/xterm.h b/src/xterm.h index c867312..7f5e087 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -1097,9 +1097,7 @@ extern void initialize_frame_menubar (struct frame *); /* Defined in xsmfns.c */ #ifdef HAVE_X_SM -extern void x_session_initialize (struct x_display_info *dpyinfo); extern int x_session_have_connection (void); -extern void x_session_close (void); #endif /* Defined in xterm.c */