parent
b03616b766
commit
e291f0a281
237
terminator
237
terminator
|
@ -72,11 +72,12 @@ def openurl (url):
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class TerminatorTerm:
|
class TerminatorTerm (gtk.VBox):
|
||||||
|
|
||||||
matches = {}
|
matches = {}
|
||||||
|
|
||||||
def __init__ (self, terminator, profile = None, command = None, cwd = None):
|
def __init__ (self, terminator, profile = None, command = None, cwd = None):
|
||||||
|
gtk.VBox.__init__ (self)
|
||||||
self.terminator = terminator
|
self.terminator = terminator
|
||||||
self.conf = terminator.conf
|
self.conf = terminator.conf
|
||||||
self.command = command
|
self.command = command
|
||||||
|
@ -99,10 +100,9 @@ class TerminatorTerm:
|
||||||
self._title.show()
|
self._title.show()
|
||||||
self._titlebox = gtk.EventBox()
|
self._titlebox = gtk.EventBox()
|
||||||
self._titlebox.add(self._title)
|
self._titlebox.add(self._title)
|
||||||
self._box = gtk.VBox ()
|
self.show()
|
||||||
self._box.show()
|
self.pack_start(self._titlebox, False)
|
||||||
self._box.pack_start(self._titlebox, False)
|
self.pack_start(self._termbox)
|
||||||
self._box.pack_start(self._termbox)
|
|
||||||
if len(self.terminator.term_list) > 0 and self.conf.titlebars:
|
if len(self.terminator.term_list) > 0 and self.conf.titlebars:
|
||||||
if len(self.terminator.term_list) == 1:
|
if len(self.terminator.term_list) == 1:
|
||||||
self.terminator.term_list[0]._titlebox.show()
|
self.terminator.term_list[0]._titlebox.show()
|
||||||
|
@ -145,10 +145,10 @@ class TerminatorTerm:
|
||||||
self.add_matches()
|
self.add_matches()
|
||||||
|
|
||||||
env_proxy = os.getenv ('http_proxy')
|
env_proxy = os.getenv ('http_proxy')
|
||||||
if not env_proxy:
|
if not env_proxy and self.conf.http_proxy:
|
||||||
os.putenv ('http_proxy', self.conf.http_proxy)
|
os.putenv ('http_proxy', self.conf.http_proxy)
|
||||||
|
|
||||||
self.spawn_child ()
|
os.putenv ('COLORTERM', 'gnome-terminal')
|
||||||
|
|
||||||
def add_matches (self, lboundry="[[:<:]]", rboundry="[[:>:]]"):
|
def add_matches (self, lboundry="[[:<:]]", rboundry="[[:>:]]"):
|
||||||
userchars = "-A-Za-z0-9"
|
userchars = "-A-Za-z0-9"
|
||||||
|
@ -173,6 +173,8 @@ class TerminatorTerm:
|
||||||
def spawn_child (self, event=None):
|
def spawn_child (self, event=None):
|
||||||
update_records = self.conf.update_records
|
update_records = self.conf.update_records
|
||||||
login = self.conf.login_shell
|
login = self.conf.login_shell
|
||||||
|
args = []
|
||||||
|
shell = ''
|
||||||
|
|
||||||
if self.command:
|
if self.command:
|
||||||
args = self.command
|
args = self.command
|
||||||
|
@ -180,24 +182,53 @@ class TerminatorTerm:
|
||||||
elif self.conf.use_custom_command:
|
elif self.conf.use_custom_command:
|
||||||
args = self.conf.custom_command.split ()
|
args = self.conf.custom_command.split ()
|
||||||
shell = args[0]
|
shell = args[0]
|
||||||
else:
|
|
||||||
shell = pwd.getpwuid (os.getuid ())[6]
|
if not os.path.exists (shell):
|
||||||
args = [os.path.basename (shell)]
|
shell = os.getenv ('SHELL') or ''
|
||||||
|
if not os.path.exists (shell):
|
||||||
|
shell = pwd.getpwuid (os.getuid ())[6] or ''
|
||||||
|
if not os.path.exists (shell):
|
||||||
|
for i in ['bash','zsh','tcsh','ksh','csh','sh']:
|
||||||
|
shell = '/usr/bin/%s'%i
|
||||||
|
if not os.path.exists (shell):
|
||||||
|
shell = '/bin/%s'%i
|
||||||
|
if not os.path.exists (shell):
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
break;
|
||||||
|
|
||||||
|
if not os.path.exists (shell):
|
||||||
|
# Give up, we're completely stuck
|
||||||
|
print >> sys.stderr, _('Unable to find a shell')
|
||||||
|
gobject.timeout_add (100, self.terminator.closeterm, self)
|
||||||
|
return (-1)
|
||||||
|
|
||||||
|
if not args:
|
||||||
|
args.append (shell)
|
||||||
|
|
||||||
|
os.putenv ('WINDOWID', '%s'%self._vte.get_parent_window().xid)
|
||||||
|
|
||||||
self._pid = self._vte.fork_command (command = shell, argv = args, envv = [], directory=self.cwd, loglastlog = login, logwtmp = update_records, logutmp = update_records)
|
self._pid = self._vte.fork_command (command = shell, argv = args, envv = [], directory=self.cwd, loglastlog = login, logwtmp = update_records, logutmp = update_records)
|
||||||
|
|
||||||
|
if self._pid == -1:
|
||||||
|
print >>sys.stderr, _('Unable to start shell: ') + shell
|
||||||
|
return (-1)
|
||||||
|
|
||||||
def get_cwd (self):
|
def get_cwd (self):
|
||||||
""" 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 = None
|
||||||
system = platform.system ()
|
system = platform.system ()
|
||||||
|
|
||||||
if system == 'Linux':
|
if system == 'Linux':
|
||||||
cwd = os.path.realpath ('/proc/%s/cwd' % self._pid)
|
try:
|
||||||
else:
|
cwd = os.path.realpath ('/proc/%s/cwd' % self._pid)
|
||||||
# We don't have a child cwd getter for this platform, so let
|
except:
|
||||||
# TerminatorTerm use its default
|
pass
|
||||||
cwd = None
|
|
||||||
return (cwd)
|
return (cwd)
|
||||||
|
|
||||||
def reconfigure_vte (self):
|
def reconfigure_vte (self):
|
||||||
|
@ -315,6 +346,19 @@ class TerminatorTerm:
|
||||||
self.reconfigure_vte ()
|
self.reconfigure_vte ()
|
||||||
|
|
||||||
def on_vte_button_press (self, term, event):
|
def on_vte_button_press (self, term, event):
|
||||||
|
# Left mouse button + Ctrl while over a link should open it
|
||||||
|
mask = gtk.gdk.CONTROL_MASK
|
||||||
|
if (event.state & mask) == mask:
|
||||||
|
if event.button == 1:
|
||||||
|
url = self._vte.match_check (int (event.x / self._vte.get_char_width ()), int (event.y / self._vte.get_char_height ()))
|
||||||
|
if url:
|
||||||
|
if (url[0][0:7] != "mailto:") & (url[1] == self.matches['email']):
|
||||||
|
address = "mailto:" + url[0]
|
||||||
|
else:
|
||||||
|
address = url[0]
|
||||||
|
openurl ( address )
|
||||||
|
return False
|
||||||
|
|
||||||
# Left mouse button should transfer focus to this vte widget
|
# Left mouse button should transfer focus to this vte widget
|
||||||
if event.button == 1:
|
if event.button == 1:
|
||||||
self._vte.grab_focus ()
|
self._vte.grab_focus ()
|
||||||
|
@ -416,8 +460,8 @@ class TerminatorTerm:
|
||||||
pangodesc.set_size (fontsize)
|
pangodesc.set_size (fontsize)
|
||||||
self._vte.set_font (pangodesc)
|
self._vte.set_font (pangodesc)
|
||||||
|
|
||||||
def on_vte_popup_menu (self, term):
|
def on_vte_popup_menu (self, term, event):
|
||||||
self.do_popup ()
|
self.do_popup (event)
|
||||||
|
|
||||||
def do_popup (self, event = None):
|
def do_popup (self, event = None):
|
||||||
menu = self.create_popup_menu (event)
|
menu = self.create_popup_menu (event)
|
||||||
|
@ -530,12 +574,8 @@ class TerminatorTerm:
|
||||||
if vte.get_window_title ():
|
if vte.get_window_title ():
|
||||||
self.terminator.set_window_title("%s: %s" %(APP_NAME.capitalize(), vte.get_window_title ()))
|
self.terminator.set_window_title("%s: %s" %(APP_NAME.capitalize(), vte.get_window_title ()))
|
||||||
|
|
||||||
def get_box (self):
|
|
||||||
return self._box
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
@ -590,9 +630,10 @@ class Terminator:
|
||||||
# FIXME: This should be really be decided from some kind of profile
|
# FIXME: This should be really be decided from some kind of profile
|
||||||
term = (TerminatorTerm (self, self.profile, self.command))
|
term = (TerminatorTerm (self, self.profile, self.command))
|
||||||
self.term_list = [term]
|
self.term_list = [term]
|
||||||
self.widgets = [term]
|
|
||||||
self.window.add (term.get_box ())
|
self.window.add (term)
|
||||||
self.window.show ()
|
self.window.show ()
|
||||||
|
term.spawn_child ()
|
||||||
|
|
||||||
def maximize (self):
|
def maximize (self):
|
||||||
""" Maximize the Terminator window."""
|
""" Maximize the Terminator window."""
|
||||||
|
@ -671,63 +712,58 @@ 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. """
|
||||||
|
|
||||||
# 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())
|
||||||
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
|
||||||
parent = widget.get_box ().get_parent ()
|
parent = widget.get_parent ()
|
||||||
|
|
||||||
if isinstance (parent, gtk.Window):
|
if isinstance (parent, gtk.Window):
|
||||||
# We have just one term
|
# We have just one term
|
||||||
# [Window, Terminal]
|
widget.reparent (pane)
|
||||||
widget.get_box ().reparent (pane)
|
|
||||||
pane.pack1 (widget.get_box (), True, True)
|
pane.pack1 (widget, True, True)
|
||||||
pane.pack2 (terminal.get_box (), True, True)
|
pane.pack2 (terminal, True, True)
|
||||||
|
|
||||||
parent.add (pane)
|
parent.add (pane)
|
||||||
|
|
||||||
position = (vertical) and parent.allocation.height \
|
position = (vertical) and parent.allocation.height \
|
||||||
or parent.allocation.width
|
or parent.allocation.width
|
||||||
# After:
|
|
||||||
# [Window, Pane, OldTerminal, NewTerminal]
|
|
||||||
self.widgets.insert(0, pane)
|
|
||||||
self.widgets.append(terminal)
|
|
||||||
|
|
||||||
if isinstance (parent, gtk.Paned):
|
if isinstance (parent, gtk.Paned):
|
||||||
# We are inside a split term
|
# We are inside a split term
|
||||||
position = (vertical) and widget.get_box().allocation.height \
|
position = (vertical) and widget.allocation.height \
|
||||||
or widget.get_box().allocation.width
|
or widget.allocation.width
|
||||||
## ... Pane, ClickedTerminal, Terminal ...
|
|
||||||
## becomes
|
|
||||||
## ... Pane, Pane, ClickedTerminal, NewTerminal, Terminal]
|
|
||||||
if (widget.get_box () == parent.get_child1 ()):
|
|
||||||
widget.get_box ().reparent (pane)
|
|
||||||
parent.pack1 (pane, True, True)
|
|
||||||
## ... Pane, Terminal, ClickedTerminal ...
|
|
||||||
## becomes
|
|
||||||
## ... Pane, Terminal, Pane, ClickedTerminal, NewTerminal]
|
|
||||||
else:
|
|
||||||
widget.get_box ().reparent (pane)
|
|
||||||
parent.pack2 (pane, True, True)
|
|
||||||
pane.pack1 (widget.get_box (), True, True)
|
|
||||||
pane.pack2 (terminal.get_box (), True, True)
|
|
||||||
|
|
||||||
i = self.widgets.index(widget)
|
if (widget == parent.get_child1 ()):
|
||||||
self.widgets.insert(i, pane)
|
widget.reparent (pane)
|
||||||
self.widgets.insert(i+2, terminal)
|
parent.pack1 (pane, True, True)
|
||||||
|
else:
|
||||||
|
widget.reparent (pane)
|
||||||
|
parent.pack2 (pane, True, True)
|
||||||
|
|
||||||
|
pane.pack1 (widget, True, True)
|
||||||
|
pane.pack2 (terminal, True, True)
|
||||||
|
|
||||||
# show all, set position of the divider
|
# show all, set position of the divider
|
||||||
pane.show ()
|
pane.show ()
|
||||||
pane.set_position (position / 2)
|
pane.set_position (position / 2)
|
||||||
terminal.get_box ().show ()
|
terminal.show ()
|
||||||
|
terminal.spawn_child ()
|
||||||
|
|
||||||
# insert the term reference into the list
|
# insert the term reference into the list
|
||||||
index = self.term_list.index (widget)
|
index = self.term_list.index (widget)
|
||||||
self.term_list.insert (index + 1, terminal)
|
self.term_list.insert (index + 1, terminal)
|
||||||
|
|
||||||
# make the new terminal grab the focus
|
# make the new terminal grab the focus
|
||||||
terminal._vte.grab_focus ()
|
terminal._vte.grab_focus ()
|
||||||
|
|
||||||
return (terminal)
|
return (terminal)
|
||||||
|
|
||||||
def closeterm (self, widget):
|
def closeterm (self, widget):
|
||||||
|
parent = widget.get_parent ()
|
||||||
parent = widget.get_box ().get_parent ()
|
|
||||||
sibling = None
|
sibling = None
|
||||||
|
|
||||||
if isinstance (parent, gtk.Window):
|
if isinstance (parent, gtk.Window):
|
||||||
|
@ -736,23 +772,14 @@ class Terminator:
|
||||||
self.on_destroy_event (parent, gtk.gdk.Event (gtk.gdk.DESTROY))
|
self.on_destroy_event (parent, gtk.gdk.Event (gtk.gdk.DESTROY))
|
||||||
return
|
return
|
||||||
|
|
||||||
## Deletes terminal and pane from self.widgets list
|
|
||||||
i = self.widgets.index(widget)
|
|
||||||
if isinstance(self.widgets[i-1], gtk.Paned):
|
|
||||||
del(self.widgets[i])
|
|
||||||
del(self.widgets[i-1])
|
|
||||||
else:
|
|
||||||
del(self.widgets[i])
|
|
||||||
del(self.widgets[i-2])
|
|
||||||
|
|
||||||
if isinstance (parent, gtk.Paned):
|
if isinstance (parent, gtk.Paned):
|
||||||
index = self.term_list.index (widget)
|
index = self.term_list.index (widget)
|
||||||
grandparent = parent.get_parent ()
|
grandparent = parent.get_parent ()
|
||||||
|
|
||||||
# Discover sibling while all objects exist
|
# Discover sibling while all objects exist
|
||||||
if widget.get_box () == parent.get_child1 ():
|
if widget == parent.get_child1 ():
|
||||||
sibling = parent.get_child2 ()
|
sibling = parent.get_child2 ()
|
||||||
if widget.get_box () == parent.get_child2 ():
|
if widget == parent.get_child2 ():
|
||||||
sibling = parent.get_child1 ()
|
sibling = parent.get_child1 ()
|
||||||
|
|
||||||
if not sibling:
|
if not sibling:
|
||||||
|
@ -763,12 +790,12 @@ class Terminator:
|
||||||
self.term_list.remove (widget)
|
self.term_list.remove (widget)
|
||||||
grandparent.remove (parent)
|
grandparent.remove (parent)
|
||||||
sibling.reparent (grandparent)
|
sibling.reparent (grandparent)
|
||||||
widget.get_box ().destroy ()
|
widget.destroy ()
|
||||||
parent.destroy ()
|
parent.destroy ()
|
||||||
|
|
||||||
if not isinstance (sibling, gtk.Paned):
|
if not isinstance (sibling, gtk.Paned):
|
||||||
for term in self.term_list:
|
for term in self.term_list:
|
||||||
if term.get_box () == sibling:
|
if term == sibling:
|
||||||
term._vte.grab_focus ()
|
term._vte.grab_focus ()
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
@ -810,8 +837,7 @@ class Terminator:
|
||||||
vertical = False
|
vertical = False
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
parent = self.get_first_parent_paned(widget,vertical)
|
||||||
parent = self.get_first_parent_paned(widget.get_box (),vertical)
|
|
||||||
if parent == None:
|
if parent == None:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -821,67 +847,18 @@ class Terminator:
|
||||||
|
|
||||||
if keyname in ('Up', 'Down'):
|
if keyname in ('Up', 'Down'):
|
||||||
maxi = parent.get_child1().get_allocation().height + parent.get_child2().get_allocation().height - 1
|
maxi = parent.get_child1().get_allocation().height + parent.get_child2().get_allocation().height - 1
|
||||||
|
|
||||||
else:
|
else:
|
||||||
maxi = parent.get_child1().get_allocation().width + parent.get_child2().get_allocation().width - 1
|
maxi = parent.get_child1().get_allocation().width + parent.get_child2().get_allocation().width - 1
|
||||||
|
|
||||||
move = 10
|
move = 10
|
||||||
if keyname in ('Up', 'Left'):
|
if keyname in ('Up', 'Left'):
|
||||||
move = -10
|
move = -10
|
||||||
|
|
||||||
move = max(2, parent_position + move)
|
move = max(2, parent.get_position() + move)
|
||||||
move = min(maxi, move)
|
move = min(maxi, move)
|
||||||
|
|
||||||
parent.set_position(move)
|
parent.set_position(move)
|
||||||
|
|
||||||
def hide_all_but_me (self, widget):
|
|
||||||
"""Proof of concept: Maximize an instance of TerminatorTerm
|
|
||||||
"""
|
|
||||||
self.window_child = self.window.get_children()[0]
|
|
||||||
self.old_parent = widget.get_box().get_parent()
|
|
||||||
self.foo = widget
|
|
||||||
self.bar = self.window_child
|
|
||||||
self.window.remove(self.window_child)
|
|
||||||
self.old_parent.remove(widget.get_box())
|
|
||||||
self.window.add(widget.get_box())
|
|
||||||
|
|
||||||
# self.full_win.add(widget.get_box())
|
|
||||||
self.window.show_all()
|
|
||||||
|
|
||||||
def show_back_others(self, widget):
|
|
||||||
"""Proof of concept: Go back to previous application
|
|
||||||
widget structure.
|
|
||||||
"""
|
|
||||||
self.foo = widget
|
|
||||||
|
|
||||||
self.window.remove(widget.get_box())
|
|
||||||
self.window.add(self.window_child)
|
|
||||||
|
|
||||||
self.old_parent.add(widget.get_box())
|
|
||||||
self.window.show_all()
|
|
||||||
|
|
||||||
def restore(self):
|
|
||||||
num_of_widgets = len(self.widgets)
|
|
||||||
if num_of_widgets % 2 == 0:
|
|
||||||
print "Error numer of widgets must be "
|
|
||||||
print
|
|
||||||
print "###################################################"
|
|
||||||
for element in self.widgets:
|
|
||||||
print element
|
|
||||||
print "###################################################"
|
|
||||||
self.window.add (self.restore_tree (self.widgets[0]))
|
|
||||||
self.window.show_all()
|
|
||||||
|
|
||||||
def restore_tree(self, widget):
|
|
||||||
if isinstance(widget, TerminatorTerm):
|
|
||||||
print """RESTORING %s which is child of %s.""" % (widget, widget.get_box().get_parent())
|
|
||||||
return widget.get_box()
|
|
||||||
else:
|
|
||||||
i = self.widgets.index(widget)
|
|
||||||
widget.add1 (self.restore_tree (self.widgets[i+1]))
|
|
||||||
widget.add2 (self.restore_tree (self.widgets[i+2]))
|
|
||||||
widget.show()
|
|
||||||
return widget
|
|
||||||
|
|
||||||
def get_first_parent_paned (self, widget, vertical = None):
|
def get_first_parent_paned (self, widget, vertical = None):
|
||||||
"""This method returns the first parent pane of a widget.
|
"""This method returns the first parent pane of a widget.
|
||||||
if vertical is True returns the first VPaned
|
if vertical is True returns the first VPaned
|
||||||
|
@ -902,6 +879,26 @@ class Terminator:
|
||||||
for term in self.term_list:
|
for term in self.term_list:
|
||||||
term.reconfigure_vte ()
|
term.reconfigure_vte ()
|
||||||
|
|
||||||
|
def hide_all_but_me (self, widget):
|
||||||
|
"""Proof of concept: Maximize to full window
|
||||||
|
an instance of TerminatorTerm.
|
||||||
|
"""
|
||||||
|
self.window_child = self.window.get_children()[0]
|
||||||
|
self.old_parent = widget.get_parent()
|
||||||
|
self.window.remove(self.window_child)
|
||||||
|
self.old_parent.remove(widget)
|
||||||
|
self.window.add(widget)
|
||||||
|
self.window.show_all()
|
||||||
|
|
||||||
|
def show_back_others(self, widget):
|
||||||
|
"""Proof of concept: Go back to previous application
|
||||||
|
widget structure.
|
||||||
|
"""
|
||||||
|
self.window.remove(widget)
|
||||||
|
self.window.add(self.window_child)
|
||||||
|
self.old_parent.add(widget)
|
||||||
|
self.window.show_all()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
def execute_cb (option, opt, value, parser):
|
def execute_cb (option, opt, value, parser):
|
||||||
|
|
Loading…
Reference in New Issue