Introduce X session support by way of gnome.ui.

This involves moving cwd detection and url_show into class Terminator, since we need to initialize gnome earlier.
This commit is contained in:
Thomas Hurst 2008-08-29 19:18:31 +01:00
parent 11df8b9783
commit 9d183ed5e1
2 changed files with 77 additions and 34 deletions

View File

@ -16,6 +16,8 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
"""Terminator by Chris Jones <cmsj@tenshu.net>""" """Terminator by Chris Jones <cmsj@tenshu.net>"""
import time, re, sys, os, platform
import pygtk import pygtk
pygtk.require ("2.0") pygtk.require ("2.0")
import gobject, gtk, pango import gobject, gtk, pango
@ -29,7 +31,6 @@ from terminatorlib.keybindings import TerminatorKeybindings
from terminatorlib.terminatorterm import TerminatorTerm from terminatorlib.terminatorterm import TerminatorTerm
class TerminatorNotebookTabLabel(gtk.HBox): class TerminatorNotebookTabLabel(gtk.HBox):
def __init__(self, title, notebook, terminator): def __init__(self, title, notebook, terminator):
gtk.HBox.__init__(self, False) gtk.HBox.__init__(self, False)
self._notebook = notebook self._notebook = notebook
@ -88,6 +89,7 @@ class TerminatorNotebookTabLabel(gtk.HBox):
def width_request(self): def width_request(self):
return self.size_request()[0] return self.size_request()[0]
class Terminator: class Terminator:
def __init__ (self, profile = None, command = None, fullscreen = False, def __init__ (self, profile = None, command = None, fullscreen = False,
maximise = False, borderless = False, no_gconf = False, maximise = False, borderless = False, no_gconf = False,
@ -100,6 +102,7 @@ class Terminator:
self._fullscreen = False self._fullscreen = False
self._geometry = geometry self._geometry = geometry
self.debugaddress = None self.debugaddress = None
self.start_cwd = os.getcwd()
self.term_list = [] self.term_list = []
stores = [] stores = []
stores.append (config.TerminatorConfValuestoreRC ()) stores.append (config.TerminatorConfValuestoreRC ())
@ -124,6 +127,42 @@ class Terminator:
self.conf = config.TerminatorConfig (stores) self.conf = config.TerminatorConfig (stores)
# Sort out cwd detection code, if available
self.pid_get_cwd = lambda pid: None
if platform.system() == 'FreeBSD':
try:
from terminatorlib import freebsd
self.pid_get_cwd = freebsd.get_process_cwd
dbg ('Using FreeBSD self.pid_get_cwd')
except (OSError, NotImplementedError, ImportError):
dbg ('FreeBSD version too old for self.pid_get_cwd')
pass
elif platform.system() == 'Linux':
dbg ('Using Linux self.pid_get_cwd')
self.pid_get_cwd = lambda pid: os.path.realpath ('/proc/%s/cwd' % pid)
else:
dbg ('Unable to set a self.pid_get_cwd, unknown system: %s' % platform.system)
# import a library for viewing URLs
try:
dbg ('Trying to import gnome for X session and backup URL handling support')
global gnome
import gnome, gnome.ui
self.gnome_program = gnome.init(APP_NAME, APP_VERSION)
self.url_show = gnome.url_show
# X session saving support
self.gnome_client = gnome.ui.master_client()
self.gnome_client.connect_to_session_manager()
self.gnome_client.connect('save-yourself', self.save_yourself)
self.gnome_client.connect('die', self.die)
except ImportError:
# webbrowser.open() is not really useful, but will do as a fallback
dbg ('gnome not available, no X session support, backup URL handling via webbrowser module')
import webbrowser
self.url_show = webbrowser.open
self.icon_theme = gtk.IconTheme () self.icon_theme = gtk.IconTheme ()
self.keybindings = TerminatorKeybindings() self.keybindings = TerminatorKeybindings()
@ -201,6 +240,39 @@ class Terminator:
self.window.show () self.window.show ()
term.spawn_child () term.spawn_child ()
def die(self):
self.save_yourself ()
gtk.main_quit ()
def save_yourself (self):
""" Save as much of our state as possible for the X session manager """
dbg("Saving session for xsm")
args = []
drop_next_arg = False
geompatt = re.compile(r'^--geometry(=.+)?')
for arg in sys.argv[1:]:
mo = geompatt.match(arg)
if mo:
if not mo.group(1):
drop_next_arg = True
elif not drop_next_arg:
args.append(arg)
drop_next_arg = False
cmd = [sys.executable, sys.argv[0]]
# pygtk docs suggest the session manager protocol handles this for us.
#cmd.append(("--geometry=%dx%d" % self.window.get_size()) + ("+%d+%d" % self.window.get_position()))
cmd += args
dbg("Session restart command: %s" % repr(cmd))
c = self.gnome_client
c.set_restart_style(gnome.ui.RESTART_IF_RUNNING)
c.set_current_directory(self.start_cwd)
# I hear rumors that some Fedora systems need (len(cmd), cmd)
c.set_clone_command(cmd)
c.set_restart_command(cmd)
return True
def maximize (self): def maximize (self):
""" Maximize the Terminator window.""" """ Maximize the Terminator window."""
self.window.maximize () self.window.maximize ()
@ -259,7 +331,7 @@ class Terminator:
return not (result == gtk.RESPONSE_ACCEPT) return not (result == gtk.RESPONSE_ACCEPT)
def on_destroy_event (self, widget, data=None): def on_destroy_event (self, widget, data=None):
gtk.main_quit () self.die()
# keybindings for the whole terminal window (affects the main # keybindings for the whole terminal window (affects the main
# windows containing the splited terminals) # windows containing the splited terminals)

View File

@ -19,7 +19,7 @@
import pygtk import pygtk
pygtk.require ("2.0") pygtk.require ("2.0")
import gobject, gtk, pango import gobject, gtk, pango
import os, platform, sys, subprocess, pwd import os, sys, subprocess, pwd
#import version details #import version details
from terminatorlib.version import * from terminatorlib.version import *
@ -52,35 +52,6 @@ class TerminatorTerm (gtk.VBox):
self.conf = terminator.conf self.conf = terminator.conf
self.command = command self.command = command
# Sort out cwd detection code, if available
self.pid_get_cwd = lambda pid: None
if platform.system() == 'FreeBSD':
try:
from terminatorlib import freebsd
self.pid_get_cwd = lambda pid: freebsd.get_process_cwd(pid)
dbg ('Using FreeBSD self.pid_get_cwd')
except (OSError, NotImplementedError, ImportError):
dbg ('FreeBSD version too old for self.pid_get_cwd')
pass
elif platform.system() == 'Linux':
dbg ('Using Linux self.pid_get_cwd')
self.pid_get_cwd = lambda pid: os.path.realpath ('/proc/%s/cwd' % pid)
else:
dbg ('Unable to set a self.pid_get_cwd, unknown system: %s'%platform.system)
# import a library for viewing URLs
try:
# gnome.url_show() is really useful
dbg ('url_show: importing gnome module')
import gnome
gnome.init ('terminator', 'terminator')
self.url_show = gnome.url_show
except ImportError:
# webbrowser.open() is not really useful, but will do as a fallback
dbg ('url_show: gnome module failed, using webbrowser')
import webbrowser
self.url_show = webbrowser.open
self.cwd = cwd or os.getcwd(); self.cwd = cwd or os.getcwd();
if not os.path.exists(self.cwd) or not os.path.isdir(self.cwd): if not os.path.exists(self.cwd) or not os.path.isdir(self.cwd):
self.cwd = pwd.getpwuid(os.getuid ())[5] self.cwd = pwd.getpwuid(os.getuid ())[5]
@ -203,7 +174,7 @@ class TerminatorTerm (gtk.VBox):
except: except:
try: try:
dbg ('openurl: calling url_show') dbg ('openurl: calling url_show')
self.url_show (url) self.terminator.url_show (url)
except: except:
dbg ('openurl: url_show failed. No URL for you') dbg ('openurl: url_show failed. No URL for you')
pass pass
@ -499,7 +470,7 @@ text/plain
""" Return the current working directory of the subprocess. """ Return the current working directory of the subprocess.
This function requires OS specific behaviours This function requires OS specific behaviours
""" """
cwd = self.pid_get_cwd (self._pid) cwd = self.terminator.pid_get_cwd (self._pid)
dbg ('get_cwd found: %s'%cwd) dbg ('get_cwd found: %s'%cwd)
return (cwd) return (cwd)