Resync with trunk
This commit is contained in:
parent
2d65ae5966
commit
39fff2287b
|
@ -19,7 +19,7 @@ If true, don't make a noise when applications send the escape sequence for the t
|
|||
Default value: \fBTrue\fR
|
||||
.TP
|
||||
.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
|
||||
.TP
|
||||
.B background_darkness
|
||||
|
@ -51,7 +51,7 @@ An Pango font name. Examples are "Sans 12" or "Monospace Bold 14".
|
|||
Default value: \fBSerif 10\fR
|
||||
.TP
|
||||
.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
|
||||
.TP
|
||||
.B scrollbar_position
|
||||
|
|
219
terminator
219
terminator
|
@ -50,10 +50,15 @@ if platform.system() == 'FreeBSD':
|
|||
try:
|
||||
from terminatorlib import freebsd
|
||||
pid_get_cwd = lambda pid: freebsd.get_process_cwd(pid)
|
||||
dbg ('Using FreeBSD pid_get_cwd')
|
||||
except:
|
||||
dbg ('FreeBSD version too old for pid_get_cwd')
|
||||
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)
|
||||
else:
|
||||
dbg ('Unable to set a pid_get_cwd, unknown system: %s'%platform.system)
|
||||
|
||||
# import gtk libs
|
||||
# check just in case anyone runs it on a non-gnome system.
|
||||
|
@ -323,6 +328,7 @@ text/plain
|
|||
pos = "bottom"
|
||||
return pos
|
||||
|
||||
|
||||
def add_matches (self, lboundry="[[:<:]]", rboundry="[[:>:]]"):
|
||||
userchars = "-A-Za-z0-9"
|
||||
passchars = "-A-Za-z0-9,?;.:/!%$^*&~\"#'"
|
||||
|
@ -393,8 +399,9 @@ text/plain
|
|||
""" Return the current working directory of the subprocess.
|
||||
This function requires OS specific behaviours
|
||||
"""
|
||||
|
||||
return (pid_get_cwd(self._pid))
|
||||
cwd = pid_get_cwd (self._pid)
|
||||
dbg ('get_cwd found: %s'%cwd)
|
||||
return (cwd)
|
||||
|
||||
def reconfigure_vte (self):
|
||||
# Set our emulation
|
||||
|
@ -498,9 +505,6 @@ text/plain
|
|||
if self.scrollbar_position == 'hidden' or self.scrollbar_position == 'disabled':
|
||||
self._scrollbar.hide ()
|
||||
else:
|
||||
print
|
||||
print self.scrollbar_position
|
||||
print
|
||||
self._scrollbar.show ()
|
||||
if self.scrollbar_position == 'right':
|
||||
self._termbox.reorder_child (self._vte, 0)
|
||||
|
@ -608,7 +612,13 @@ text/plain
|
|||
elif keyname in ('Up', 'Down', 'Left', 'Right'):
|
||||
self.terminator.resizeterm (self, keyname)
|
||||
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
|
||||
if (event.state & mask) == mask:
|
||||
if keyname == 'Page_Down':
|
||||
|
@ -720,13 +730,6 @@ text/plain
|
|||
item = gtk.MenuItem ()
|
||||
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.connect ("activate", lambda menu_item: self.terminator.closeterm (self))
|
||||
menu.append (item)
|
||||
|
@ -824,11 +827,9 @@ text/plain
|
|||
|
||||
class Terminator:
|
||||
def __init__ (self, profile, command = None, fullscreen = False, maximise = False, borderless = False):
|
||||
|
||||
self.profile = profile
|
||||
self.command = command
|
||||
|
||||
self._fullwindow = False
|
||||
|
||||
self._fullscreen = False
|
||||
self.term_list = []
|
||||
stores = []
|
||||
|
@ -968,8 +969,6 @@ class Terminator:
|
|||
Add a term to another at position pos
|
||||
"""
|
||||
vertical = pos in ("top", "bottom")
|
||||
|
||||
# create a new terminal and parent pane.
|
||||
pane = (vertical) and gtk.VPaned () or gtk.HPaned ()
|
||||
|
||||
# get the parent of the provided terminal
|
||||
|
@ -1009,6 +1008,7 @@ class Terminator:
|
|||
parent.insert_page(pane, None, page)
|
||||
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_reorderable(pane, True)
|
||||
parent.set_current_page(page)
|
||||
|
||||
|
||||
|
@ -1053,51 +1053,131 @@ class Terminator:
|
|||
return (terminal)
|
||||
|
||||
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)
|
||||
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):
|
||||
terminal = TerminatorTerm (self, self.profile, None, widget.get_cwd())
|
||||
widgetbox = widget
|
||||
parent = widgetbox.get_parent ()
|
||||
parent = widget.get_parent ()
|
||||
|
||||
if isinstance(parent, gtk.Paned) or isinstance(parent, gtk.Window):
|
||||
#no notebook yet.
|
||||
notebook = gtk.Notebook()
|
||||
notebook.set_tab_pos(gtk.POS_TOP)
|
||||
notebook.connect('page-reordered',self.on_page_reordered)
|
||||
notebook.set_property('homogeneous', True)
|
||||
notebook.set_tab_reorderable(widgetbox, True)
|
||||
notebook.set_tab_reorderable(widget, True)
|
||||
|
||||
if isinstance(parent, gtk.Paned):
|
||||
if parent.get_child1() == widgetbox:
|
||||
widgetbox.reparent(notebook)
|
||||
if parent.get_child1() == widget:
|
||||
widget.reparent(notebook)
|
||||
parent.pack1(notebook)
|
||||
else:
|
||||
widgetbox.reparent(notebook)
|
||||
widget.reparent(notebook)
|
||||
parent.pack2(notebook)
|
||||
elif isinstance(parent, gtk.Window):
|
||||
widgetbox.reparent(notebook)
|
||||
widget.reparent(notebook)
|
||||
parent.add(notebook)
|
||||
notebook.set_tab_reorderable(widgetbox,True)
|
||||
notebook.set_tab_reorderable(widget,True)
|
||||
notebooklabel = ""
|
||||
if widget._vte.get_window_title() is not None:
|
||||
notebooklabel = widget._vte.get_window_title()
|
||||
notebook.set_tab_label_text(widgetbox, notebooklabel)
|
||||
notebook. set_tab_label_packing(widgetbox, True, True, gtk.PACK_START)
|
||||
notebook.set_tab_label_text(widget, notebooklabel)
|
||||
notebook. set_tab_label_packing(widget, True, True, gtk.PACK_START)
|
||||
notebook.show()
|
||||
elif isinstance(parent, gtk.Notebook):
|
||||
notebook = parent
|
||||
else:
|
||||
return (False)
|
||||
|
||||
notebook.append_page(terminal,terminal._vte.get_window_title())
|
||||
notebook. set_tab_label_packing(terminal, True, True, gtk.PACK_START)
|
||||
notebook.set_tab_reorderable(terminal,True)
|
||||
notebook.set_current_page(-1)
|
||||
index = self.term_list.index(widget)
|
||||
self.term_list.insert (index + 1, terminal)
|
||||
## NOTE
|
||||
## Here we need to append to the notebook before we can
|
||||
## spawn the terminal (WINDOW_ID needs to be set)
|
||||
|
||||
notebook.append_page(terminal,None)
|
||||
terminal.show ()
|
||||
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 ()
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
|
@ -1105,11 +1185,6 @@ class Terminator:
|
|||
|
||||
def splitaxis (self, widget, vertical=True):
|
||||
""" 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.
|
||||
terminal = TerminatorTerm (self, self.profile, None, widget.get_cwd())
|
||||
pos = vertical and "bottom" or "right"
|
||||
|
@ -1121,9 +1196,6 @@ class Terminator:
|
|||
def remove(self, widget):
|
||||
"""Remove a TerminatorTerm from the Terminator view and terms list
|
||||
Returns True on success, False on failure"""
|
||||
if self._fullwindow:
|
||||
self.show_back_others(widget)
|
||||
|
||||
parent = widget.get_parent ()
|
||||
sibling = None
|
||||
|
||||
|
@ -1159,6 +1231,8 @@ class Terminator:
|
|||
grandparent.remove_page(page)
|
||||
grandparent.insert_page(sibling, None,page)
|
||||
grandparent.set_tab_label_packing(sibling, True, True, gtk.PACK_START)
|
||||
grandparent.set_tab_reorderable(sibling, True)
|
||||
|
||||
|
||||
else:
|
||||
grandparent.remove (parent)
|
||||
|
@ -1264,6 +1338,8 @@ class Terminator:
|
|||
break
|
||||
previousterm._vte.grab_focus ()
|
||||
|
||||
|
||||
|
||||
|
||||
def resizeterm (self, widget, keyname):
|
||||
vertical = False
|
||||
|
@ -1305,6 +1381,26 @@ class Terminator:
|
|||
notebook.next_page()
|
||||
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):
|
||||
if isinstance (widget, gtk.Window):
|
||||
return None
|
||||
|
@ -1344,43 +1440,6 @@ class Terminator:
|
|||
for term in self.term_list:
|
||||
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__':
|
||||
|
||||
def execute_cb (option, opt, value, parser):
|
||||
|
|
|
@ -32,7 +32,7 @@ AttributeError. This is by design. If you want to look something
|
|||
up, set a default for it first."""
|
||||
|
||||
# import standard python libs
|
||||
import os, sys
|
||||
import os, sys, re
|
||||
|
||||
# import unix-lib
|
||||
import pwd
|
||||
|
@ -58,8 +58,8 @@ class TerminatorConfig:
|
|||
self.sources.append (source)
|
||||
|
||||
def __getattr__ (self, keyname):
|
||||
dbg ("TConfig: Looking for: '%s'"%keyname)
|
||||
for source in self.sources:
|
||||
dbg ("TConfig: Looking for: '%s' in '%s'"%(keyname, source.type))
|
||||
try:
|
||||
val = getattr (source, keyname)
|
||||
dbg (" TConfig: got: '%s' from a '%s'"%(val, source.type))
|
||||
|
@ -81,11 +81,12 @@ class TerminatorConfValuestore:
|
|||
'profile_dir' : '/apps/gnome-terminal/profiles',
|
||||
'titlebars' : True,
|
||||
'titletips' : False,
|
||||
'allow_bold' : False,
|
||||
'allow_bold' : True,
|
||||
'silent_bell' : True,
|
||||
'background_color' : '#000000',
|
||||
'background_darkness' : 0.5,
|
||||
'background_type' : 'solid',
|
||||
'background_image' : '',
|
||||
'backspace_binding' : 'ascii-del',
|
||||
'delete_binding' : 'delete-sequence',
|
||||
'cursor_blink' : False,
|
||||
|
@ -112,12 +113,15 @@ class TerminatorConfValuestore:
|
|||
'ignore_hosts' : ['localhost','127.0.0.0/8','*.local'],
|
||||
'encoding' : 'UTF-8',
|
||||
'active_encodings' : ['UTF-8', 'ISO-8859-1'],
|
||||
'background_image' : '',
|
||||
}
|
||||
|
||||
def __getattr__ (self, keyname):
|
||||
if self.values.has_key (keyname):
|
||||
dbg ("Returning '%s'"%keyname)
|
||||
return self.values[keyname]
|
||||
else:
|
||||
dbg ("Failed to find '%s'"%keyname)
|
||||
raise (AttributeError)
|
||||
|
||||
class TerminatorConfValuestoreDefault (TerminatorConfValuestore):
|
||||
|
@ -127,6 +131,7 @@ class TerminatorConfValuestoreDefault (TerminatorConfValuestore):
|
|||
|
||||
class TerminatorConfValuestoreRC (TerminatorConfValuestore):
|
||||
rcfilename = ""
|
||||
splitter = re.compile("\s*=\s*")
|
||||
#FIXME: use inotify to watch the rc, split __init__ into a parsing function
|
||||
# that can be re-used when rc changes.
|
||||
def __init__ (self):
|
||||
|
@ -141,14 +146,33 @@ class TerminatorConfValuestoreRC (TerminatorConfValuestore):
|
|||
try:
|
||||
item = item.strip ()
|
||||
if item and item[0] != '#':
|
||||
(key, value) = item.split ("=")
|
||||
dbg (" VS_RCFile: Setting value %s to %s"%(key, value))
|
||||
if value == 'True':
|
||||
self.values[key] = True
|
||||
elif value == 'False':
|
||||
self.values[key] = False
|
||||
except:
|
||||
dbg (" VS_RCFile: Exception handling: %s"%item)
|
||||
(key, value) = self.splitter.split (item)
|
||||
|
||||
# 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
|
||||
elif value.lower () == 'false':
|
||||
self.values[key] = False
|
||||
else:
|
||||
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
|
||||
|
||||
class TerminatorConfValuestoreGConf (TerminatorConfValuestore):
|
||||
|
|
|
@ -39,20 +39,19 @@ class kinfo_file(Structure):
|
|||
('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):
|
||||
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
|
||||
# CTL_KERN, KERN_PROC, KERN_PROC_FILEDESC
|
||||
oid = (c_uint * 4)(1, 14, 14, pid)
|
||||
|
|
Loading…
Reference in New Issue