Resync with trunk

This commit is contained in:
Edoardo Batini 2008-05-23 23:30:53 +02:00
parent 2d65ae5966
commit 39fff2287b
4 changed files with 187 additions and 105 deletions

View File

@ -19,7 +19,7 @@ If true, don't make a noise when applications send the escape sequence for the t
Default value: \fBTrue\fR Default value: \fBTrue\fR
.TP .TP
.B background_color .B background_color
Default colour of terminal background, as a colour specification (can be HTML-style hex digits, or a colour name such as "red"). Default colour of terminal background, as a colour specification (can be HTML-style hex digits, or a colour name such as "red"). \fBNote:\fR You may need to set \fBuse_theme_colors=False\fR to force this setting to take effect.
Default value: \fB#000000\fR Default value: \fB#000000\fR
.TP .TP
.B background_darkness .B background_darkness
@ -51,7 +51,7 @@ An Pango font name. Examples are "Sans 12" or "Monospace Bold 14".
Default value: \fBSerif 10\fR Default value: \fBSerif 10\fR
.TP .TP
.B foreground_color .B foreground_color
Default colour of text in the terminal, as a colour specification (can be HTML-style hex digits, or a colour name such as "red"). Default colour of text in the terminal, as a colour specification (can be HTML-style hex digits, or a colour name such as "red"). \fBNote:\fR You may need to set \fBuse_theme_colors=False\fR to force this setting to take effect.
Default value: \fB#AAAAAA\fR Default value: \fB#AAAAAA\fR
.TP .TP
.B scrollbar_position .B scrollbar_position

View File

@ -50,10 +50,15 @@ if platform.system() == 'FreeBSD':
try: try:
from terminatorlib import freebsd from terminatorlib import freebsd
pid_get_cwd = lambda pid: freebsd.get_process_cwd(pid) pid_get_cwd = lambda pid: freebsd.get_process_cwd(pid)
dbg ('Using FreeBSD pid_get_cwd')
except: except:
dbg ('FreeBSD version too old for pid_get_cwd')
pass pass
elif platform.system == 'Linux': elif platform.system() == 'Linux':
dbg ('Using Linux pid_get_cwd')
pid_get_cwd = lambda pid: os.path.realpath ('/proc/%s/cwd' % pid) pid_get_cwd = lambda pid: os.path.realpath ('/proc/%s/cwd' % pid)
else:
dbg ('Unable to set a pid_get_cwd, unknown system: %s'%platform.system)
# import gtk libs # import gtk libs
# check just in case anyone runs it on a non-gnome system. # check just in case anyone runs it on a non-gnome system.
@ -323,6 +328,7 @@ text/plain
pos = "bottom" pos = "bottom"
return pos return pos
def add_matches (self, lboundry="[[:<:]]", rboundry="[[:>:]]"): def add_matches (self, lboundry="[[:<:]]", rboundry="[[:>:]]"):
userchars = "-A-Za-z0-9" userchars = "-A-Za-z0-9"
passchars = "-A-Za-z0-9,?;.:/!%$^*&~\"#'" passchars = "-A-Za-z0-9,?;.:/!%$^*&~\"#'"
@ -393,8 +399,9 @@ 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 = pid_get_cwd (self._pid)
return (pid_get_cwd(self._pid)) dbg ('get_cwd found: %s'%cwd)
return (cwd)
def reconfigure_vte (self): def reconfigure_vte (self):
# Set our emulation # Set our emulation
@ -498,9 +505,6 @@ text/plain
if self.scrollbar_position == 'hidden' or self.scrollbar_position == 'disabled': if self.scrollbar_position == 'hidden' or self.scrollbar_position == 'disabled':
self._scrollbar.hide () self._scrollbar.hide ()
else: else:
print
print self.scrollbar_position
print
self._scrollbar.show () self._scrollbar.show ()
if self.scrollbar_position == 'right': if self.scrollbar_position == 'right':
self._termbox.reorder_child (self._vte, 0) self._termbox.reorder_child (self._vte, 0)
@ -608,6 +612,12 @@ text/plain
elif keyname in ('Up', 'Down', 'Left', 'Right'): elif keyname in ('Up', 'Down', 'Left', 'Right'):
self.terminator.resizeterm (self, keyname) self.terminator.resizeterm (self, keyname)
return (True) return (True)
elif keyname == 'Page_Down':
self.terminator.move_tab(self, 'right')
return (True)
elif keyname == 'Page_Up':
self.terminator.move_tab(self, 'left')
return (True)
mask = gtk.gdk.CONTROL_MASK mask = gtk.gdk.CONTROL_MASK
if (event.state & mask) == mask: if (event.state & mask) == mask:
@ -720,13 +730,6 @@ text/plain
item = gtk.MenuItem () item = gtk.MenuItem ()
menu.append (item) menu.append (item)
item = gtk.MenuItem (_("M_aximize/Unmaximize"))
item.connect ("activate", lambda menu_item: self.terminator.fullwindow (self))
menu.append (item)
item = gtk.MenuItem ()
menu.append (item)
item = gtk.ImageMenuItem (gtk.STOCK_CLOSE) item = gtk.ImageMenuItem (gtk.STOCK_CLOSE)
item.connect ("activate", lambda menu_item: self.terminator.closeterm (self)) item.connect ("activate", lambda menu_item: self.terminator.closeterm (self))
menu.append (item) menu.append (item)
@ -824,11 +827,9 @@ text/plain
class Terminator: class Terminator:
def __init__ (self, profile, command = None, fullscreen = False, maximise = False, borderless = False): def __init__ (self, profile, command = None, fullscreen = False, maximise = False, borderless = False):
self.profile = profile self.profile = profile
self.command = command self.command = command
self._fullwindow = False
self._fullscreen = False self._fullscreen = False
self.term_list = [] self.term_list = []
stores = [] stores = []
@ -968,8 +969,6 @@ class Terminator:
Add a term to another at position pos Add a term to another at position pos
""" """
vertical = pos in ("top", "bottom") vertical = pos in ("top", "bottom")
# create a new terminal and parent pane.
pane = (vertical) and gtk.VPaned () or gtk.HPaned () pane = (vertical) and gtk.VPaned () or gtk.HPaned ()
# get the parent of the provided terminal # get the parent of the provided terminal
@ -1009,6 +1008,7 @@ class Terminator:
parent.insert_page(pane, None, page) parent.insert_page(pane, None, page)
parent.set_tab_label_text(pane, widget._vte.get_window_title()) parent.set_tab_label_text(pane, widget._vte.get_window_title())
parent.set_tab_label_packing(pane, True, True, gtk.PACK_START) parent.set_tab_label_packing(pane, True, True, gtk.PACK_START)
parent.set_tab_reorderable(pane, True)
parent.set_current_page(page) parent.set_current_page(page)
@ -1053,51 +1053,131 @@ class Terminator:
return (terminal) return (terminal)
def on_page_reordered(self, notebook, child, page_num): def on_page_reordered(self, notebook, child, page_num):
#page has been reordered, we need to get the
# first term and last term
dbg ("Reordered: %d"%page_num) dbg ("Reordered: %d"%page_num)
nbpages = notebook.get_n_pages()
if nbpages == 1:
dbg("[ERROR] only one page in on_page_reordered")
first = self._notebook_first_term(notebook.get_nth_page(page_num))
last = self._notebook_last_term(notebook.get_nth_page(page_num))
firstidx = self.term_list.index(first)
lastidx = self.term_list.index(last)
termslice = self.term_list[firstidx:lastidx+1]
#remove them from the list
for term in termslice:
self.term_list.remove(term)
if page_num == 0:
#first page, we insert before the first term of next page
nexttab = notebook.get_nth_page(1)
sibling = self._notebook_first_term(nexttab)
siblingindex = self.term_list.index(sibling)
for term in termslice:
self.term_list.insert(siblingindex, term)
siblingindex += 1
else:
#other pages, we insert after the last term of previous page
previoustab = notebook.get_nth_page(page_num - 1)
sibling = self._notebook_last_term(previoustab)
print sibling
siblingindex = self.term_list.index(sibling)
for term in termslice:
siblingindex += 1
self.term_list.insert(siblingindex, term)
#for page reorder, we need to get the first term of a notebook
def notebook_first_term(self, notebook):
return self._notebook_first_term(notebook.get_nth_page(0))
def _notebook_first_term(self, child):
if isinstance(child, TerminatorTerm):
return child
elif isinstance(child, gtk.Paned):
return self._notebook_first_term(child.get_child1())
elif isinstance(child, gtk.Notebook):
return self._notebook_first_term(child.get_nth_page(0))
dbg("[ERROR] unsupported class %s in _notebook_first_term" % child.__class__.__name__)
return None
#for page reorder, we need to get the last term of a notebook
def notebook_last_term(self, notebook):
return self._notebook_last_term(notebook.get_nth_page(notebook.get_n_pages()-1))
def _notebook_last_term(self, child):
if isinstance(child, TerminatorTerm):
return child
elif isinstance(child, gtk.Paned):
return self._notebook_first_term(child.get_child2())
elif isinstance(child, gtk.Notebook):
return self._notebook_first_term(child.get_nth_page(child.get_n_pages()-1))
dbg("[ERROR] unsupported class %s in _notebook_last_term" % child.__class__.__name__)
return None
def newtab(self,widget): def newtab(self,widget):
terminal = TerminatorTerm (self, self.profile, None, widget.get_cwd()) terminal = TerminatorTerm (self, self.profile, None, widget.get_cwd())
widgetbox = widget parent = widget.get_parent ()
parent = widgetbox.get_parent ()
if isinstance(parent, gtk.Paned) or isinstance(parent, gtk.Window): if isinstance(parent, gtk.Paned) or isinstance(parent, gtk.Window):
#no notebook yet. #no notebook yet.
notebook = gtk.Notebook() notebook = gtk.Notebook()
notebook.set_tab_pos(gtk.POS_TOP)
notebook.connect('page-reordered',self.on_page_reordered) notebook.connect('page-reordered',self.on_page_reordered)
notebook.set_property('homogeneous', True) notebook.set_property('homogeneous', True)
notebook.set_tab_reorderable(widgetbox, True) notebook.set_tab_reorderable(widget, True)
if isinstance(parent, gtk.Paned): if isinstance(parent, gtk.Paned):
if parent.get_child1() == widgetbox: if parent.get_child1() == widget:
widgetbox.reparent(notebook) widget.reparent(notebook)
parent.pack1(notebook) parent.pack1(notebook)
else: else:
widgetbox.reparent(notebook) widget.reparent(notebook)
parent.pack2(notebook) parent.pack2(notebook)
elif isinstance(parent, gtk.Window): elif isinstance(parent, gtk.Window):
widgetbox.reparent(notebook) widget.reparent(notebook)
parent.add(notebook) parent.add(notebook)
notebook.set_tab_reorderable(widgetbox,True) notebook.set_tab_reorderable(widget,True)
notebooklabel = "" notebooklabel = ""
if widget._vte.get_window_title() is not None: if widget._vte.get_window_title() is not None:
notebooklabel = widget._vte.get_window_title() notebooklabel = widget._vte.get_window_title()
notebook.set_tab_label_text(widgetbox, notebooklabel) notebook.set_tab_label_text(widget, notebooklabel)
notebook. set_tab_label_packing(widgetbox, True, True, gtk.PACK_START) notebook. set_tab_label_packing(widget, True, True, gtk.PACK_START)
notebook.show() notebook.show()
elif isinstance(parent, gtk.Notebook): elif isinstance(parent, gtk.Notebook):
notebook = parent notebook = parent
else: else:
return (False) return (False)
notebook.append_page(terminal,terminal._vte.get_window_title()) ## NOTE
notebook. set_tab_label_packing(terminal, True, True, gtk.PACK_START) ## Here we need to append to the notebook before we can
notebook.set_tab_reorderable(terminal,True) ## spawn the terminal (WINDOW_ID needs to be set)
notebook.set_current_page(-1)
index = self.term_list.index(widget) notebook.append_page(terminal,None)
self.term_list.insert (index + 1, terminal)
terminal.show () terminal.show ()
terminal.spawn_child () terminal.spawn_child ()
## Some gtk/vte weirdness
## If we don't use this silly test,
## terminal._vte.get_window_title() might return
## bogus values
notebooklabel = ""
if terminal._vte.get_window_title() is not None:
notebooklabel = terminal._vte.get_window_title()
notebook.set_tab_label_text(terminal, notebooklabel)
notebook.set_tab_label_packing(terminal, True, True, gtk.PACK_START)
notebook.set_tab_reorderable(terminal,True)
## Now, we set focus on the new term
notebook.set_current_page(-1)
terminal._vte.grab_focus () terminal._vte.grab_focus ()
#adding a new tab, thus we need to get the
# last term of the previous tab and add
# the new term just after
sibling = self._notebook_last_term(notebook.get_nth_page(notebook.page_num(terminal)-1))
index = self.term_list.index(sibling)
self.term_list.insert (index + 1, terminal)
return (True) return (True)
@ -1105,11 +1185,6 @@ class Terminator:
def splitaxis (self, widget, vertical=True): def splitaxis (self, widget, vertical=True):
""" Split the provided widget on the horizontal or vertical axis. """ """ Split the provided widget on the horizontal or vertical axis. """
#should disable splitaxis menu instead?
if self._fullwindow:
return
# create a new terminal and parent pane. # create a new terminal and parent pane.
terminal = TerminatorTerm (self, self.profile, None, widget.get_cwd()) terminal = TerminatorTerm (self, self.profile, None, widget.get_cwd())
pos = vertical and "bottom" or "right" pos = vertical and "bottom" or "right"
@ -1121,9 +1196,6 @@ class Terminator:
def remove(self, widget): def remove(self, widget):
"""Remove a TerminatorTerm from the Terminator view and terms list """Remove a TerminatorTerm from the Terminator view and terms list
Returns True on success, False on failure""" Returns True on success, False on failure"""
if self._fullwindow:
self.show_back_others(widget)
parent = widget.get_parent () parent = widget.get_parent ()
sibling = None sibling = None
@ -1159,6 +1231,8 @@ class Terminator:
grandparent.remove_page(page) grandparent.remove_page(page)
grandparent.insert_page(sibling, None,page) grandparent.insert_page(sibling, None,page)
grandparent.set_tab_label_packing(sibling, True, True, gtk.PACK_START) grandparent.set_tab_label_packing(sibling, True, True, gtk.PACK_START)
grandparent.set_tab_reorderable(sibling, True)
else: else:
grandparent.remove (parent) grandparent.remove (parent)
@ -1265,6 +1339,8 @@ class Terminator:
previousterm._vte.grab_focus () previousterm._vte.grab_focus ()
def resizeterm (self, widget, keyname): def resizeterm (self, widget, keyname):
vertical = False vertical = False
if keyname in ('Up', 'Down'): if keyname in ('Up', 'Down'):
@ -1305,6 +1381,26 @@ class Terminator:
notebook.next_page() notebook.next_page()
return return
def move_tab(self, term, direction):
dbg("moving to direction %s" % direction)
(notebook, page) = self.get_first_notebook_page(term)
page_num = notebook.page_num(page)
nbpages = notebook.get_n_pages()
#dbg ("%s %s %s %s" % (page_num, nbpages,notebook, page))
if page_num == 0 and direction == 'left':
new_page_num = nbpages
elif page_num == nbpages - 1 and direction == 'right':
new_page_num = 0
elif direction == 'left':
new_page_num = page_num - 1
elif direction == 'right':
new_page_num = page_num + 1
else:
dbg("[ERROR] unhandled combination in move_tab: direction = %s page_num = %d" % (direction, page_num))
return False
notebook.reorder_child(page, new_page_num)
return True
def get_first_parent_notebook(self, widget): def get_first_parent_notebook(self, widget):
if isinstance (widget, gtk.Window): if isinstance (widget, gtk.Window):
return None return None
@ -1344,43 +1440,6 @@ class Terminator:
for term in self.term_list: for term in self.term_list:
term.reconfigure_vte () term.reconfigure_vte ()
def fullwindow(self, widget):
if not self._fullwindow:
self.hide_all_but_me(widget)
else:
self.show_back_others(widget)
def hide_all_but_me (self, widget):
"""Proof of concept: Maximize to full window
an instance of TerminatorTerm.
"""
self.old_parent = widget.get_parent()
if isinstance(self.old_parent, gtk.Window):
return
if isinstance(self.old_parent, gtk.Notebook):
self.old_page = self.old_parent.get_current_page()
self.window_child = self.window.get_children()[0]
self.window.remove(self.window_child)
self.old_parent.remove(widget)
self.window.add(widget)
self._fullwindow = True
def show_back_others(self, widget):
"""Proof of concept: Go back to previous application
widget structure.
"""
if self._fullwindow:
self.window.remove(widget)
self.window.add(self.window_child)
self.old_parent.add(widget)
if isinstance(self.old_parent, gtk.Notebook):
self.old_parent.set_current_page(self.old_page)
print "\nPARENT IS A NOTEBOOK\n"
self._fullwindow = False
return
else:
return
if __name__ == '__main__': if __name__ == '__main__':
def execute_cb (option, opt, value, parser): def execute_cb (option, opt, value, parser):

View File

@ -32,7 +32,7 @@ AttributeError. This is by design. If you want to look something
up, set a default for it first.""" up, set a default for it first."""
# import standard python libs # import standard python libs
import os, sys import os, sys, re
# import unix-lib # import unix-lib
import pwd import pwd
@ -58,8 +58,8 @@ class TerminatorConfig:
self.sources.append (source) self.sources.append (source)
def __getattr__ (self, keyname): def __getattr__ (self, keyname):
dbg ("TConfig: Looking for: '%s'"%keyname)
for source in self.sources: for source in self.sources:
dbg ("TConfig: Looking for: '%s' in '%s'"%(keyname, source.type))
try: try:
val = getattr (source, keyname) val = getattr (source, keyname)
dbg (" TConfig: got: '%s' from a '%s'"%(val, source.type)) dbg (" TConfig: got: '%s' from a '%s'"%(val, source.type))
@ -81,11 +81,12 @@ class TerminatorConfValuestore:
'profile_dir' : '/apps/gnome-terminal/profiles', 'profile_dir' : '/apps/gnome-terminal/profiles',
'titlebars' : True, 'titlebars' : True,
'titletips' : False, 'titletips' : False,
'allow_bold' : False, 'allow_bold' : True,
'silent_bell' : True, 'silent_bell' : True,
'background_color' : '#000000', 'background_color' : '#000000',
'background_darkness' : 0.5, 'background_darkness' : 0.5,
'background_type' : 'solid', 'background_type' : 'solid',
'background_image' : '',
'backspace_binding' : 'ascii-del', 'backspace_binding' : 'ascii-del',
'delete_binding' : 'delete-sequence', 'delete_binding' : 'delete-sequence',
'cursor_blink' : False, 'cursor_blink' : False,
@ -112,12 +113,15 @@ class TerminatorConfValuestore:
'ignore_hosts' : ['localhost','127.0.0.0/8','*.local'], 'ignore_hosts' : ['localhost','127.0.0.0/8','*.local'],
'encoding' : 'UTF-8', 'encoding' : 'UTF-8',
'active_encodings' : ['UTF-8', 'ISO-8859-1'], 'active_encodings' : ['UTF-8', 'ISO-8859-1'],
'background_image' : '',
} }
def __getattr__ (self, keyname): def __getattr__ (self, keyname):
if self.values.has_key (keyname): if self.values.has_key (keyname):
dbg ("Returning '%s'"%keyname)
return self.values[keyname] return self.values[keyname]
else: else:
dbg ("Failed to find '%s'"%keyname)
raise (AttributeError) raise (AttributeError)
class TerminatorConfValuestoreDefault (TerminatorConfValuestore): class TerminatorConfValuestoreDefault (TerminatorConfValuestore):
@ -127,6 +131,7 @@ class TerminatorConfValuestoreDefault (TerminatorConfValuestore):
class TerminatorConfValuestoreRC (TerminatorConfValuestore): class TerminatorConfValuestoreRC (TerminatorConfValuestore):
rcfilename = "" rcfilename = ""
splitter = re.compile("\s*=\s*")
#FIXME: use inotify to watch the rc, split __init__ into a parsing function #FIXME: use inotify to watch the rc, split __init__ into a parsing function
# that can be re-used when rc changes. # that can be re-used when rc changes.
def __init__ (self): def __init__ (self):
@ -141,14 +146,33 @@ class TerminatorConfValuestoreRC (TerminatorConfValuestore):
try: try:
item = item.strip () item = item.strip ()
if item and item[0] != '#': if item and item[0] != '#':
(key, value) = item.split ("=") (key, value) = self.splitter.split (item)
dbg (" VS_RCFile: Setting value %s to %s"%(key, value))
if value == 'True': # Check if this is actually a key we care about
if not self.defaults.has_key (key):
raise AttributeError;
deftype = self.defaults[key].__class__.__name__
if deftype == 'bool':
if value.lower () == 'true':
self.values[key] = True self.values[key] = True
elif value == 'False': elif value.lower () == 'false':
self.values[key] = False self.values[key] = False
except: else:
dbg (" VS_RCFile: Exception handling: %s"%item) raise AttributeError
elif deftype == 'int':
self.values[key] = int (value)
elif deftype == 'float':
self.values[key] = float (value)
elif deftype == 'list':
print >> sys.stderr, _("Reading list values from .terminatorrc is not currently supported")
raise ValueError
else:
self.values[key] = value
dbg (" VS_RCFile: Set value '%s' to '%s'"%(key, self.values[key]))
except Exception, e:
dbg (" VS_RCFile: %s Exception handling: %s" % (type(e), item))
pass pass
class TerminatorConfValuestoreGConf (TerminatorConfValuestore): class TerminatorConfValuestoreGConf (TerminatorConfValuestore):

View File

@ -39,20 +39,19 @@ class kinfo_file(Structure):
('kf_sa_peer', sockaddr_storage), ('kf_sa_peer', sockaddr_storage),
] ]
libc = CDLL('libc.so')
len = c_uint(sizeof(c_uint))
ver = c_uint(0)
if (libc.sysctlbyname('kern.osreldate', byref(ver), byref(len), None, 0) < 0):
raise OSError, "sysctlbyname returned < 0"
# kern.proc.filedesc added for procstat(1) after these __FreeBSD_versions
if ver.value < 700104 and ver.value < 800019:
raise NotImplementedError, "cwd detection requires a recent 7.0-STABLE or 8-CURRENT"
def get_process_cwd(pid): def get_process_cwd(pid):
libc = CDLL('libc.so')
len = c_uint(sizeof(c_uint))
ver = c_uint(0)
if (libc.sysctlbyname('kern.osreldate', byref(ver), byref(len), None, 0) < 0):
return None
# kern.proc.filedesc added for procstat(1) after these __FreeBSD_versions
if ver.value < 700104 and ver.value < 800019:
return None
# /usr/include/sys/sysctl.h # /usr/include/sys/sysctl.h
# CTL_KERN, KERN_PROC, KERN_PROC_FILEDESC # CTL_KERN, KERN_PROC, KERN_PROC_FILEDESC
oid = (c_uint * 4)(1, 14, 14, pid) oid = (c_uint * 4)(1, 14, 14, pid)