Land a modified and extended patch from Andrea Corbellini that adds a dbus server and a new default behaviour to use the dbus server to make terminator processes singletons

This commit is contained in:
Chris Jones 2010-07-21 23:17:34 +01:00
parent 5702bd13f2
commit 9044ffabb0
6 changed files with 128 additions and 1 deletions

View File

@ -32,6 +32,10 @@ Below are the individual sections that can exist in the config file:
.SH "global_config"
These are the options Terminator currently supports in the global_config section:
.TP
.B dbus
Control whether or not Terminator will load its DBus server. When this server is loaded, running Terminator multiple times will cause the first Terminator process to open additional windows. If this configuration item is set to False, or the python dbus module is unavailable, running Terminator multiple times will run a separate Terminator process for each invocation.
Default value: \fBTrue\fR
.TP
.B focus
Control how focus is given to terminals. 'click' means the focus only moves to a terminal after you click in it. 'sloppy' means the focus will follow the mouse pointer. 'system' means the focus will match that used by a GNOME window manager.
Default value: \fBclick\fR

View File

@ -50,6 +50,21 @@ if __name__ == '__main__':
OPTIONS = terminatorlib.optionparse.parse_options()
# Attempt to import our dbus server. If one exists already we will just
# connect to that and ask for a new window. If not, we will create one and
# continue. Failure to import dbus, or the global config option "dbus"
# being False will cause us to continue without the dbus server and open a
# window.
try:
from terminatorlib import ipc
try:
ipc.DBusService()
except ipc.DBusException:
ipc.new_window()
sys.exit()
except ImportError:
pass
MAKER = Factory()
TERMINATOR = Terminator()
TERMINATOR.set_origcwd(ORIGCWD)

View File

@ -76,6 +76,7 @@ except ImportError:
DEFAULTS = {
'global_config': {
'dbus' : True,
'focus' : 'click',
'handle_size' : -1,
'geometry_hinting' : True,

71
terminatorlib/ipc.py Normal file
View File

@ -0,0 +1,71 @@
#!/usr/bin/python
# Terminator by Chris Jones <cmsj@tenshu.net>
# GPL v2 only
"""ipc.py - DBus server and API calls"""
import gtk
import dbus.service
from dbus.exceptions import DBusException
import dbus.glib
from borg import Borg
from terminator import Terminator
from config import Config
CONFIG = Config()
if not CONFIG['dbus']:
# The config says we are not to load dbus, so pretend like we can't
raise ImportError
BUS_BASE = 'net.tenshu.Terminator'
BUS_PATH = '/net/tenshu/Terminator'
try:
# Try and include the X11 display name in the dbus bus name
DISPLAY = gtk.gdk.get_display().replace(':', '').replace('.', '')
BUS_NAME = '%s%s' % (BUS_BASE, DISPLAY)
except:
BUS_NAME = BUS_BASE
class DBusService(Borg, dbus.service.Object):
"""DBus Server class. This is implemented as a Borg"""
bus_name = None
terminator = None
def __init__(self):
"""Class initialiser"""
self.prepare_attributes()
dbus.service.Object.__init__(self, self.bus_name, BUS_PATH)
def prepare_attributes(self):
"""Ensure we are populated"""
if not self.bus_name:
bus = dbus.SessionBus()
proxy = bus.get_object('org.freedesktop.DBus',
'/org/freedesktop/DBus')
flags = 1 | 4 # allow replacement | do not queue
if not proxy.RequestName(BUS_NAME, dbus.UInt32(flags)) in (1, 4):
raise dbus.exceptions.DBusException(
"Couldn't get DBus name %s: Name exists" % BUS_NAME)
self.bus_name = dbus.service.BusName(BUS_NAME,
bus=dbus.SessionBus())
if not self.terminator:
self.terminator = Terminator()
@dbus.service.method(BUS_NAME)
def new_window(self):
"""Create a new Window"""
self.terminator.create_layout('default')
self.terminator.layout_done()
def with_proxy(func):
"""Decorator function to connect to the session dbus bus"""
def _exec(*args, **argd):
bus = dbus.SessionBus()
proxy = bus.get_object(BUS_NAME, BUS_PATH)
func(proxy, *args, **argd)
return _exec
@with_proxy
def new_window(session):
"""Call the dbus method to open a new window"""
session.new_window()

View File

@ -298,7 +298,7 @@
<child>
<object class="GtkTable" id="global_config_table">
<property name="visible">True</property>
<property name="n_rows">6</property>
<property name="n_rows">7</property>
<property name="n_columns">2</property>
<property name="column_spacing">6</property>
<child>
@ -489,6 +489,34 @@
<property name="x_padding">20</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label24">
<property name="visible">True</property>
<property name="label" translatable="yes">DBus server</property>
</object>
<packing>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="dbuscheck">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_dbuscheck_toggled"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
<property name="x_options">GTK_EXPAND</property>
<property name="y_options">GTK_EXPAND</property>
</packing>
</child>
</object>
<packing>
<property name="position">0</property>

View File

@ -215,6 +215,9 @@ class PrefsEditor:
else:
active = 0
widget.set_active(active)
# DBus Server
widget = guiget('dbuscheck')
widget.set_active(self.config['dbus'])
## Profile tab
# Populate the profile list
@ -538,6 +541,11 @@ class PrefsEditor:
self.config['geometry_hinting'] = widget.get_active()
self.config.save()
def on_dbuscheck_toggled(self, widget):
"""DBus server setting changed"""
self.config['dbus'] = widget.get_active()
self.config.save()
def on_winbordercheck_toggled(self, widget):
"""Window border setting changed"""
self.config['borderless'] = not widget.get_active()