Optimise various low level parts (Stephen Boddy)
This commit is contained in:
commit
32b8d04695
@ -3,6 +3,8 @@ terminator 0.96:
|
||||
* Fix searching with infinite scrollback (Julien Thewys #755077)
|
||||
* Fix searching on Ubuntu 10.10 and 11.04, and implement searching
|
||||
by regular expression (Roberto Aguilar #709018)
|
||||
* Optimise various low level components so they are dramatically
|
||||
faster (Stephen Boddy)
|
||||
|
||||
terminator 0.95:
|
||||
* Add a configuration option to enable a DBus server
|
||||
|
@ -195,7 +195,9 @@ the %s will also close all terminals within it.') % (reqtype, reqtype))
|
||||
def get_visible_terminals(self):
|
||||
"""Walk the widget tree to find all of the visible terminals. That is,
|
||||
any terminals which are not hidden in another Notebook pane"""
|
||||
maker = Factory()
|
||||
if not hasattr(self, 'cached_maker'):
|
||||
self.cached_maker = Factory()
|
||||
maker = self.cached_maker
|
||||
terminals = {}
|
||||
|
||||
for child in self.get_offspring():
|
||||
|
@ -33,6 +33,9 @@ class Factory(Borg):
|
||||
'Notebook': 'notebook',
|
||||
'Container': 'container',
|
||||
'Window': 'window'}
|
||||
types_keys = types.keys()
|
||||
instance_types = {}
|
||||
instance_types_keys = []
|
||||
|
||||
def __init__(self):
|
||||
"""Class initialiser"""
|
||||
@ -45,16 +48,25 @@ class Factory(Borg):
|
||||
|
||||
def isinstance(self, product, classtype):
|
||||
"""Check if a given product is a particular type of object"""
|
||||
if classtype in self.types.keys():
|
||||
# This is quite ugly, but we're importing from the current
|
||||
# directory if that makes sense, otherwise falling back to
|
||||
# terminatorlib. Someone with real Python skills should fix
|
||||
# this to be less insane.
|
||||
if classtype in self.types_keys:
|
||||
# This is now very ugly, but now it's fast :-)
|
||||
# Someone with real Python skills should fix this to be less insane.
|
||||
# Optimisations:
|
||||
# - swap order of imports, otherwise we throw ImportError
|
||||
# almost every time
|
||||
# - cache everything we can
|
||||
try:
|
||||
module = __import__(self.types[classtype], None, None, [''])
|
||||
type_key = 'terminatorlib.%s' % self.types[classtype]
|
||||
if type_key not in self.instance_types_keys:
|
||||
self.instance_types[type_key] = __import__(type_key, None, None, [''])
|
||||
self.instance_types_keys.append(type_key)
|
||||
module = self.instance_types[type_key]
|
||||
except ImportError:
|
||||
module = __import__('terminatorlib.%s' % self.types[classtype],
|
||||
None, None, [''])
|
||||
type_key = self.types[classtype]
|
||||
if type_key not in self.instance_types_keys:
|
||||
self.instance_types[type_key] = __import__(type_key, None, None, [''])
|
||||
self.instance_types_keys.append(type_key)
|
||||
module = self.instance_types[type_key]
|
||||
return(isinstance(product, getattr(module, classtype)))
|
||||
else:
|
||||
err('Factory::isinstance: unknown class type: %s' % classtype)
|
||||
|
@ -12,7 +12,7 @@ from factory import Factory
|
||||
from container import Container
|
||||
from editablelabel import EditableLabel
|
||||
from translation import _
|
||||
from util import err, dbg, get_top_window, enumerate_descendants
|
||||
from util import err, dbg, enumerate_descendants
|
||||
|
||||
class Notebook(Container, gtk.Notebook):
|
||||
"""Class implementing a gtk.Notebook container"""
|
||||
@ -173,7 +173,7 @@ class Notebook(Container, gtk.Notebook):
|
||||
def newtab(self, debugtab=False, widget=None, cwd=None):
|
||||
"""Add a new tab, optionally supplying a child widget"""
|
||||
maker = Factory()
|
||||
top_window = get_top_window(self)
|
||||
top_window = self.get_toplevel()
|
||||
|
||||
if not widget:
|
||||
widget = maker.make('Terminal')
|
||||
|
@ -7,7 +7,7 @@ variants"""
|
||||
import gobject
|
||||
import gtk
|
||||
|
||||
from util import dbg, err, get_top_window
|
||||
from util import dbg, err
|
||||
from terminator import Terminator
|
||||
from factory import Factory
|
||||
from container import Container
|
||||
@ -86,7 +86,7 @@ class Paned(Container):
|
||||
raise ValueError('Paned widgets can only have two children')
|
||||
|
||||
if maker.isinstance(widget, 'Terminal'):
|
||||
top_window = get_top_window(self)
|
||||
top_window = self.get_toplevel()
|
||||
signals = {'close-term': self.wrapcloseterm,
|
||||
'split-horiz': self.split_horiz,
|
||||
'split-vert': self.split_vert,
|
||||
|
@ -15,7 +15,7 @@ import pango
|
||||
import subprocess
|
||||
import urllib
|
||||
|
||||
from util import dbg, err, gerr, get_top_window
|
||||
from util import dbg, err, gerr
|
||||
import util
|
||||
from config import Config
|
||||
from cwd import get_default_cwd
|
||||
@ -118,6 +118,8 @@ class Terminal(gtk.VBox):
|
||||
self.origcwd = self.terminator.origcwd
|
||||
self.clipboard = gtk.clipboard_get(gtk.gdk.SELECTION_CLIPBOARD)
|
||||
|
||||
self.pending_on_vte_size_allocate = False
|
||||
|
||||
self.vte = vte.Terminal()
|
||||
self.vte.set_size(80, 24)
|
||||
self.vte._expose_data = None
|
||||
@ -335,7 +337,7 @@ for %s (%s)' % (name, urlplugin.__class__.__name__))
|
||||
self.emit('title-change', self.get_window_title()))
|
||||
self.vte.connect('grab-focus', self.on_vte_focus)
|
||||
self.vte.connect('focus-in-event', self.on_vte_focus_in)
|
||||
self.vte.connect('size-allocate', self.on_vte_size_allocate)
|
||||
self.vte.connect('size-allocate', self.deferred_on_vte_size_allocate)
|
||||
|
||||
self.vte.add_events(gtk.gdk.ENTER_NOTIFY_MASK)
|
||||
self.vte.connect('enter_notify_event',
|
||||
@ -747,7 +749,7 @@ for %s (%s)' % (name, urlplugin.__class__.__name__))
|
||||
# maybe we can emit the key event and let Terminator() care?
|
||||
groupsend = self.terminator.groupsend
|
||||
groupsend_type = self.terminator.groupsend_type
|
||||
window_focussed = get_top_window(self.vte).get_property('has-toplevel-focus')
|
||||
window_focussed = self.vte.get_toplevel().get_property('has-toplevel-focus')
|
||||
if groupsend != groupsend_type['off'] and window_focussed and self.vte.is_focus():
|
||||
if self.group and groupsend == groupsend_type['group']:
|
||||
self.terminator.group_emit(self, self.group, 'key-press-event',
|
||||
@ -961,7 +963,7 @@ for %s (%s)' % (name, urlplugin.__class__.__name__))
|
||||
|
||||
def ensure_visible_and_focussed(self):
|
||||
"""Make sure that we're visible and focussed"""
|
||||
window = util.get_top_window(self)
|
||||
window = self.get_toplevel()
|
||||
topchild = window.get_child()
|
||||
maker = Factory()
|
||||
|
||||
@ -1002,12 +1004,24 @@ for %s (%s)' % (name, urlplugin.__class__.__name__))
|
||||
"""A child widget is done editing a label, return focus to VTE"""
|
||||
self.vte.grab_focus()
|
||||
|
||||
def deferred_on_vte_size_allocate(self, widget, allocation):
|
||||
# widget & allocation are not used in on_vte_size_allocate, so we
|
||||
# can use the on_vte_size_allocate instead of duplicating the code
|
||||
if self.pending_on_vte_size_allocate == True:
|
||||
return
|
||||
self.pending_on_vte_size_allocate = True
|
||||
gobject.idle_add(self.do_deferred_on_vte_size_allocate, widget, allocation)
|
||||
|
||||
def do_deferred_on_vte_size_allocate(self, widget, allocation):
|
||||
self.pending_on_vte_size_allocate = False
|
||||
self.on_vte_size_allocate(widget, allocation)
|
||||
|
||||
def on_vte_size_allocate(self, widget, allocation):
|
||||
self.titlebar.update_terminal_size(self.vte.get_column_count(),
|
||||
self.vte.get_row_count())
|
||||
if self.vte.window and self.config['geometry_hinting']:
|
||||
window = util.get_top_window(self)
|
||||
window.set_rough_geometry_hints()
|
||||
window = self.get_toplevel()
|
||||
window.deferred_set_rough_geometry_hints()
|
||||
|
||||
def on_vte_notify_enter(self, term, event):
|
||||
"""Handle the mouse entering this terminal"""
|
||||
@ -1079,7 +1093,7 @@ for %s (%s)' % (name, urlplugin.__class__.__name__))
|
||||
"""Determine if we are a zoomed terminal"""
|
||||
prop = None
|
||||
parent = self.get_parent()
|
||||
window = get_top_window(self)
|
||||
window = self.get_toplevel()
|
||||
|
||||
try:
|
||||
prop = window.get_property('term-zoomed')
|
||||
@ -1313,7 +1327,7 @@ for %s (%s)' % (name, urlplugin.__class__.__name__))
|
||||
def on_beep(self, widget):
|
||||
"""Set the urgency hint for our window"""
|
||||
if self.config['urgent_bell'] == True:
|
||||
window = util.get_top_window(self)
|
||||
window = self.get_toplevel()
|
||||
window.set_urgency_hint(True)
|
||||
if self.config['icon_bell'] == True:
|
||||
self.titlebar.icon_bell()
|
||||
|
@ -89,14 +89,6 @@ def has_ancestor(widget, wtype):
|
||||
return(True)
|
||||
return(False)
|
||||
|
||||
def get_top_window(widget):
|
||||
"""Return the Window instance a widget belongs to"""
|
||||
parent = widget.get_parent()
|
||||
while parent:
|
||||
widget = parent
|
||||
parent = widget.get_parent()
|
||||
return(widget)
|
||||
|
||||
def path_lookup(command):
|
||||
'''Find a command in our path'''
|
||||
if os.path.isabs(command):
|
||||
|
@ -81,6 +81,8 @@ class Window(Container, gtk.Window):
|
||||
err('Window::__init__: Unable to parse geometry: %s' %
|
||||
options.geometry)
|
||||
|
||||
self.pending_set_rough_geometry_hint = False
|
||||
|
||||
def do_get_property(self, prop):
|
||||
"""Handle gobject getting a property"""
|
||||
if prop.name in ['term_zoomed', 'term-zoomed']:
|
||||
@ -480,7 +482,9 @@ class Window(Container, gtk.Window):
|
||||
"""Walk down the widget tree to find all of the visible terminals.
|
||||
Mostly using Container::get_visible_terminals()"""
|
||||
terminals = {}
|
||||
maker = Factory()
|
||||
if not hasattr(self, 'cached_maker'):
|
||||
self.cached_maker = Factory()
|
||||
maker = self.cached_maker
|
||||
child = self.get_child()
|
||||
|
||||
if not child:
|
||||
@ -508,10 +512,24 @@ class Window(Container, gtk.Window):
|
||||
return(terminal)
|
||||
return(None)
|
||||
|
||||
def deferred_set_rough_geometry_hints(self):
|
||||
# no parameters are used in set_rough_geometry_hints, so we can
|
||||
# use the set_rough_geometry_hints
|
||||
if self.pending_set_rough_geometry_hint == True:
|
||||
return
|
||||
self.pending_set_rough_geometry_hint = True
|
||||
gobject.idle_add(self.do_deferred_set_rough_geometry_hints)
|
||||
|
||||
def do_deferred_set_rough_geometry_hints(self):
|
||||
self.pending_set_rough_geometry_hint = False
|
||||
self.set_rough_geometry_hints()
|
||||
|
||||
def set_rough_geometry_hints(self):
|
||||
"""Walk all the terminals along the top and left edges to fake up how
|
||||
many columns/rows we sort of have"""
|
||||
maker = Factory()
|
||||
if not hasattr(self, 'cached_maker'):
|
||||
self.cached_maker = Factory()
|
||||
maker = self.cached_maker
|
||||
if maker.isinstance(self.get_child(), 'Notebook'):
|
||||
dbg("We don't currently support geometry hinting with tabs")
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user