Merge branch containing huge number of fixes from Egmont

* Add word chars back in if VTE is 0.40+
* Add option to toggle the rewrap on resize
* Make Zoom/Maximize inactive if a single terminal (Egmont
* Add dimming for 256 colour palettes
* Update TERM/COLORTERM to more modern values
* Fix deprcation warning in later GTK versions
* Fix separator sizing
* Fix positioning of group popup menu for later versions of GTK
* Correct some British spelt translated strings to American
* Fix double double-click on titlebar in later GTK3
* Fix the palette for inactive terminals after Prefs window
* Fix copy on selection to work on already open terminals
* Fix unwanted seperator size change, and increase granularity of dim/transparent sliders
* Fix cwd when new term spawned from a symlinked directory
* Correct terminator_config man page regarding scrollback
* Fix exception when Ctrl-clicking the terminal when not over a URL
* Fix Ctrl-click on URL if terminal has padding
* Fix right-click for mouse aware apps
This commit is contained in:
Stephen Boddy 2015-11-30 00:41:08 +01:00
commit 4435be2350
10 changed files with 240 additions and 51 deletions

View File

@ -1,3 +1,49 @@
terminator GTK3:
Features
* Add word chars back in if VTE is 0.40+ (Egmont Koblinger,
LP#1518078)
Enhancements
* Add option to toggle the rewrap on resize (Egmont Koblinger,
LP#1518077)
* Make Zoom/Maximize inactive if a single terminal (Egmont
Koblinger, LP#1518081)
* Add dimming for 256 colour palettes (Egmont Koblinger,
LP#1518111)
* Update TERM/COLORTERM to more modern values (Egmont Koblinger,
LP#1518557)
Bug fixes
* Fix a GI version warning for Notify library (Mattias Eriksson)
* Fix warning trying to import the __init__.py file as a plugin
(Mattias Eriksson, LP#1518065)
* Fix deprcation warning in later GTK versions (Egmont Koblinger,
LP#1518063)
* Fix separator sizing (Egmont Koblinger, LP#1518069)
* Fix positioning of group popup menu for later versions of GTK
(Egmont Koblinger, LP#1518058)
* Correct some British spelt translated strings to American
(Egmont Koblinger, LP#1518085)
* Fix double double-click on titlebar in later GTK3 (Egmont
Koblinger, LP#1518094)
* Fix the palette for inactive terminals after Prefs window
(Egmont Koblinger, LP#1518108)
* Fix copy on selection to work on already open terminals
(Egmont Koblinger, LP#1518109)
* Fix unwanted seperator size change, and increase granularity of
dim/transparent sliders (Egmont Koblinger, LP#1518114)
* Fix cwd when new term spawned from a symlinked directory
(Egmont Koblinger, LP#1518554)
* Correct terminator_config man page regarding scrollback
(Egmont Koblinger, LP#1518559)
* Fix exception when Ctrl-clicking the terminal when not over a
URL (Egmont Koblinger, LP#1518592)
* Fix Ctrl-click on URL if terminal has padding (Egmont
Koblinger, LP#1518596)
* Fix right-click for mouse aware apps ((Egmont Koblinger,
LP#1518700)
terminator 0.97:
* Allow font dimming in inactive terminals
* Allow URL handler plugins to override label text for URL context

View File

@ -382,13 +382,13 @@ Default value: Current value of \fBforeground_color\fR
Default shape of cursor. Possibilities are "block", "ibeam", and "underline".
Default value: \fBblock\fR
.TP
.B xterm
.B term
This translates into the value that will be set for TERM in the environment of your terminals.
Default value: \fBxterm\fR
Default value: \fBxterm-256color\fR
.TP
.B colorterm
This translates into the value that will be set for COLORTERM in the environment of your terminals.
Default value: \fBgnome-terminal\fR
Default value: \fBtruecolor\fR
.TP
.B use_system_font
Whether or not to use the GNOME default monospace font for terminals.
@ -423,11 +423,11 @@ If true, whenever there's new output the terminal will scroll to the bottom.
Default value: \fBTrue\fR
.TP
.B scrollback_lines
Number of scrollback lines to keep around. You can scroll back in the terminal by this number of lines; lines that don't fit in the scrollback are discarded. Be careful with this setting; it's the primary factor in determining how much memory the terminal will use.
Number of scrollback lines to keep around. You can scroll back in the terminal by this number of lines; lines that don't fit in the scrollback are discarded. Warning: with large values, rewrapping on resize might be slow.
Default value: \fB500\fR
.TP
.B scrollback_infinite
If this is set to True, scrollback_lines will be ignored and VTE will continue to allocate RAM for scrollback history.
If this is set to True, scrollback_lines will be ignored and VTE will keep the entire scrollback history.
Default value: \fBFalse\fR
.TP
.B focus_on_close
@ -442,6 +442,10 @@ Default value: \fBclose\fR
.B palette
Terminals have a 16-colour palette that applications inside the terminal can use. This is that palette, in the form of a colon-separated list of colour names. Colour names should be in hex format e.g. "#FF00FF".
.TP
.B word_chars
These characters are included when selecting text by double clicking.
Default value: \fB',./?%&#:_'\fR
.TP
.B mouse_autohide \fR(boolean)
Controls whether the mouse cursor should be hidden while typing.
Default value: \fBTrue\fR
@ -465,6 +469,10 @@ Default value: \fBUTF-8\fR
.B copy_on_selection \fR(boolean)
If set to True, text selections will be automatically copied to the clipboard, in addition to being made the Primary selection.
Default value: \fBFalse\fR
.TP
.B rewrap_on_resize \fR(boolean)
If True, the terminal contents are rewrapped when the terminal's width changes. Warning: This might be slow if you have a huge scrollback buffer.
Default value: \fBTrue\fR
.SH layouts
@ -487,4 +495,5 @@ Window objects may not have a parent attribute. \fBEvery\fR other object must sp
Terminator plugins can add their own configuration to the config file, and will appear as a sub-section. Please refer to the documentation of individual plugins for more information.
.SH "SEE ALSO"
.BR gnome\-terminal(1), http://www.voidspace.org.uk/python/configobj.html
.TP
\fBterminator\fP(1), http://www.voidspace.org.uk/python/configobj.html

View File

@ -212,8 +212,8 @@ DEFAULTS = {
'cursor_blink' : True,
'cursor_shape' : 'block',
'cursor_color' : '#aaaaaa',
'term' : 'xterm',
'colorterm' : 'gnome-terminal',
'term' : 'xterm-256color',
'colorterm' : 'truecolor',
'font' : 'Mono 10',
'foreground_color' : '#aaaaaa',
'show_titlebar' : True,
@ -227,6 +227,7 @@ DEFAULTS = {
'palette' : '#2e3436:#cc0000:#4e9a06:#c4a000:\
#3465a4:#75507b:#06989a:#d3d7cf:#555753:#ef2929:#8ae234:#fce94f:\
#729fcf:#ad7fa8:#34e2e2:#eeeeec',
'word_chars' : ',./?%&#:_',
'mouse_autohide' : True,
'update_records' : True,
'login_shell' : False,
@ -240,6 +241,7 @@ DEFAULTS = {
'force_no_bell' : False,
'cycle_term_tab' : True,
'copy_on_selection' : False,
'rewrap_on_resize' : True,
'split_to_group' : False,
'autoclean_groups' : True,
'http_proxy' : '',

View File

@ -73,6 +73,8 @@ class EditableLabel(Gtk.EventBox):
if event.button != 1:
return False
if event.type == Gdk.EventType._2BUTTON_PRESS:
if self._entry:
return False
self.remove (self._label)
self._entry = Gtk.Entry ()
self._entry.set_text (self._label.get_text ())

View File

@ -49,7 +49,7 @@ def parse_options():
parser.add_option('-v', '--version', action='store_true', dest='version',
help=_('Display program version'))
parser.add_option('-m', '--maximise', action='store_true', dest='maximise',
help=_('Maximise the window'))
help=_('Maximize the window'))
parser.add_option('-f', '--fullscreen', action='store_true',
dest='fullscreen', help=_('Make the window fill the screen'))
parser.add_option('-b', '--borderless', action='store_true',

View File

@ -69,7 +69,7 @@
<col id="0" translatable="yes">Black on white</col>
</row>
<row>
<col id="0" translatable="yes">Grey on black</col>
<col id="0" translatable="yes">Gray on black</col>
</row>
<row>
<col id="0" translatable="yes">Green on black</col>
@ -861,10 +861,12 @@
</child>
<child>
<object class="GtkHScale" id="inactive_color_offset">
<property name="width_request">100</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">adjustment7</property>
<property name="round_digits">1</property>
<property name="round_digits">2</property>
<property name="digits">2</property>
<property name="value_pos">left</property>
<signal name="change-value" handler="on_inactive_color_offset_change_value" swapped="no"/>
</object>
@ -1603,6 +1605,63 @@
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="rewrap_on_resize_checkbutton">
<property name="label" translatable="yes">Rewrap on resize</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_rewrap_on_resize_toggled" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">5</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="word_chars_hbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel" id="word_chars_entry_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Select-by-_word characters:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">word_chars_entry</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="word_chars_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">•</property>
<signal name="changed" handler="on_word_chars_entry_changed" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">6</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -2782,7 +2841,8 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">background_darkness_scale</property>
<property name="round_digits">1</property>
<property name="round_digits">2</property>
<property name="digits">2</property>
<property name="value_pos">bottom</property>
<signal name="change-value" handler="on_darken_background_scale_change_value" swapped="no"/>
</object>

View File

@ -115,7 +115,7 @@ class PrefsEditor:
'resize_right' : _('Resize the terminal right'),
'move_tab_right' : _('Move the tab right'),
'move_tab_left' : _('Move the tab left'),
'toggle_zoom' : _('Maximise terminal'),
'toggle_zoom' : _('Maximize terminal'),
'scaled_zoom' : _('Zoom terminal'),
'next_tab' : _('Switch to the next tab'),
'prev_tab' : _('Switch to the previous tab'),
@ -421,6 +421,15 @@ class PrefsEditor:
# Copy on selection
widget = guiget('copy_on_selection')
widget.set_active(self.config['copy_on_selection'])
# Rewrap on resize
widget = guiget('rewrap_on_resize_checkbutton')
widget.set_active(self.config['rewrap_on_resize'])
# Word chars
widget = guiget('word_chars_entry')
widget.set_text(self.config['word_chars'])
# Word char support was missing from vte 0.38, hide from the UI
if not hasattr(self.term.vte, 'set_word_char_exceptions'):
guiget('word_chars_hbox').hide()
# Cursor shape
widget = guiget('cursor_shape_combobox')
if self.config['cursor_shape'] == 'underline':
@ -696,6 +705,11 @@ class PrefsEditor:
self.config['copy_on_selection'] = widget.get_active()
self.config.save()
def on_rewrap_on_resize_toggled(self, widget):
"""Rewrap on resize setting changed"""
self.config['rewrap_on_resize'] = widget.get_active()
self.config.save()
def on_cursor_blink_toggled(self, widget):
"""Cursor blink setting changed"""
self.config['cursor_blink'] = widget.get_active()
@ -812,9 +826,12 @@ class PrefsEditor:
self.config['scrollbar_position'] = value
self.config.save()
def on_darken_background_scale_change_value(self, widget, scroll, value):
def on_darken_background_scale_change_value(self, widget, scroll, _value_not_rounded):
"""Background darkness setting changed"""
self.config['background_darkness'] = round(value, 2)
value = widget.get_value() # This one is rounded according to the UI.
if value > 1.0:
value = 1.0
self.config['background_darkness'] = value
self.config.save()
def on_palette_combobox_changed(self, widget):
@ -921,6 +938,11 @@ class PrefsEditor:
self.config['cursor_shape'] = value
self.config.save()
def on_word_chars_entry_changed(self, widget):
"""Word characters changed"""
self.config['word_chars'] = widget.get_text()
self.config.save()
def on_font_selector_font_set(self, widget):
"""Font changed"""
self.config['font'] = widget.get_font_name()
@ -961,16 +983,18 @@ class PrefsEditor:
self.config['title_transmit_fg_color'] = color2hex(widget)
self.config.save()
def on_inactive_color_offset_change_value(self, widget, scroll, value):
def on_inactive_color_offset_change_value(self, widget, scroll, _value_not_rounded):
"""Inactive color offset setting changed"""
value = widget.get_value() # This one is rounded according to the UI.
if value > 1.0:
value = 1.0
self.config['inactive_color_offset'] = round(value, 2)
self.config['inactive_color_offset'] = value
self.config.save()
def on_handlesize_change_value(self, widget, scroll, value):
def on_handlesize_change_value(self, widget, scroll, _value_not_rounded):
"""Handle size changed"""
value = int(value)
value = widget.get_value() # This one is rounded according to the UI.
value = int(value) # Cast to int.
if value > 5:
value = 5
self.config['handle_size'] = value

View File

@ -352,6 +352,10 @@ class Terminal(Gtk.VBox):
self.vte.match_remove(self.matches[name])
del(self.matches[name])
def maybe_copy_clipboard(self):
if self.config['copy_on_selection']:
self.vte.copy_clipboard()
def connect_signals(self):
"""Connect all the gtk signals and drag-n-drop mechanics"""
@ -410,10 +414,8 @@ class Terminal(Gtk.VBox):
self.vte.connect('drag-data-received',
self.on_drag_data_received, self)
# FIXME: Shouldn't this be in configure()?
if self.config['copy_on_selection']:
self.cnxids.new(self.vte, 'selection-changed',
lambda widget: self.vte.copy_clipboard())
self.cnxids.new(self.vte, 'selection-changed',
lambda widget: self.maybe_copy_clipboard())
if self.composite_support:
self.vte.connect('composited-changed', self.reconfigure)
@ -549,8 +551,10 @@ class Terminal(Gtk.VBox):
return(menu)
def position_popup_group_menu(self, menu, widget):
def position_popup_group_menu(self, menu, *args):
"""Calculate the position of the group popup menu"""
# GTK API, or GIR just changed the args. See LP#1518058
widget = args[-1]
_screen_w = Gdk.Screen.width()
screen_h = Gdk.Screen.height()
@ -628,6 +632,9 @@ class Terminal(Gtk.VBox):
if self.custom_encoding != True:
self.vte.set_encoding(self.config['encoding'])
# Word char support was missing from vte 0.38, silently skip this setting
if hasattr(self.vte, 'set_word_char_exceptions'):
self.vte.set_word_char_exceptions(self.config['word_chars'])
self.vte.set_mouse_autohide(self.config['mouse_autohide'])
backspace = self.config['backspace_binding']
@ -715,19 +722,41 @@ class Terminal(Gtk.VBox):
getattr(self.fgcolor_inactive, "blue")))
colors = self.config['palette'].split(':')
self.palette_active = []
self.palette_inactive = []
for color in colors:
if color:
newcolor = Gdk.RGBA()
newcolor.parse(color)
newcolor_inactive = newcolor.copy()
for bit in ['red', 'green', 'blue']:
setattr(newcolor_inactive, bit,
getattr(newcolor_inactive, bit) * factor)
self.palette_active.append(newcolor)
self.palette_inactive.append(newcolor_inactive)
self.vte.set_colors(self.fgcolor_active, self.bgcolor,
self.palette_active)
if len(colors) == 16:
# RGB values for indices 16..255 copied from vte source in order to dim them
shades = [0, 95, 135, 175, 215, 255]
for r in xrange(0, 6):
for g in xrange(0, 6):
for b in xrange(0, 6):
newcolor = Gdk.RGBA()
setattr(newcolor, "red", shades[r] / 255.0)
setattr(newcolor, "green", shades[g] / 255.0)
setattr(newcolor, "blue", shades[b] / 255.0)
self.palette_active.append(newcolor)
for y in xrange(8, 248, 10):
newcolor = Gdk.RGBA()
setattr(newcolor, "red", y / 255.0)
setattr(newcolor, "green", y / 255.0)
setattr(newcolor, "blue", y / 255.0)
self.palette_active.append(newcolor)
self.palette_inactive = []
for color in self.palette_active:
newcolor = Gdk.RGBA()
for bit in ['red', 'green', 'blue']:
setattr(newcolor, bit,
getattr(color, bit) * factor)
self.palette_inactive.append(newcolor)
if self.terminator.last_focused_term == self:
self.vte.set_colors(self.fgcolor_active, self.bgcolor,
self.palette_active)
else:
self.vte.set_colors(self.fgcolor_inactive, self.bgcolor,
self.palette_inactive)
self.set_cursor_color()
self.vte.set_cursor_shape(getattr(Vte.CursorShape,
self.config['cursor_shape'].upper()));
@ -770,6 +799,8 @@ class Terminal(Gtk.VBox):
elif self.config['scrollbar_position'] == 'right':
self.reorder_child(self.vte, 0)
self.vte.set_rewrap_on_resize(self.config['rewrap_on_resize'])
self.titlebar.update()
self.vte.queue_draw()
@ -889,17 +920,22 @@ class Terminal(Gtk.VBox):
if event.button == 1:
# Ctrl+leftclick on a URL should open it
if event.get_state() & Gdk.ModifierType.CONTROL_MASK == Gdk.ModifierType.CONTROL_MASK:
url = self.check_for_url(event)
if url:
url = self.vte.match_check_event(event)
if url[0]:
self.open_url(url, prepare=True)
elif event.button == 2:
# middleclick should paste the clipboard
self.paste_clipboard(True)
return(True)
elif event.button == 3:
# rightclick should display a context menu if Ctrl is not pressed
# rightclick should display a context menu if Ctrl is not pressed,
# plus either the app is not interested in mouse events or Shift is pressed
if event.get_state() & Gdk.ModifierType.CONTROL_MASK == 0:
self.popup_menu(widget, event)
if event.get_state() & Gdk.ModifierType.SHIFT_MASK == 0:
if not Vte.Terminal.do_button_press_event(self.vte, event):
self.popup_menu(widget, event)
else:
self.popup_menu(widget, event)
return(True)
return(False)
@ -1363,6 +1399,7 @@ class Terminal(Gtk.VBox):
envv = []
envv.append('TERM=%s' % self.config['term'])
envv.append('COLORTERM=%s' % self.config['colorterm'])
envv.append('PWD=%s' % self.cwd)
envv.append('TERMINATOR_UUID=%s' % self.uuid.urn)
if self.terminator.dbus_name:
envv.append('TERMINATOR_DBUS_NAME=%s' % self.terminator.dbus_name)
@ -1386,11 +1423,6 @@ class Terminal(Gtk.VBox):
self.vte.feed(_('Unable to start shell:') + shell)
return(-1)
def check_for_url(self, event):
"""Check if the mouse is over a URL"""
return (self.vte.match_check(int(event.x / self.vte.get_char_width()),
int(event.y / self.vte.get_char_height())))
def prepare_url(self, urlmatch):
"""Prepare a URL from a VTE match"""
url = urlmatch[0]

View File

@ -40,7 +40,7 @@ class TerminalPopupMenu(object):
self.config.set_profile(terminal.get_profile())
if event:
url = terminal.check_for_url(event)
url = terminal.vte.match_check_event(event)
button = event.button
time = event.time
else:
@ -151,12 +151,16 @@ class TerminalPopupMenu(object):
menu.append(Gtk.MenuItem())
if not terminal.is_zoomed():
sensitive = not terminal.get_toplevel() == terminal.get_parent()
item = Gtk.MenuItem.new_with_mnemonic(_('_Zoom terminal'))
item.connect('activate', terminal.zoom)
item.set_sensitive(sensitive)
menu.append(item)
item = Gtk.MenuItem.new_with_mnemonic(_('Ma_ximise terminal'))
item = Gtk.MenuItem.new_with_mnemonic(_('Ma_ximize terminal'))
item.connect('activate', terminal.maximise)
item.set_sensitive(sensitive)
menu.append(item)
menu.append(Gtk.MenuItem())

View File

@ -16,8 +16,7 @@ from cwd import get_pid_cwd
from version import APP_NAME, APP_VERSION
def eventkey2gdkevent(eventkey): # FIXME FOR GTK3: is there a simpler way of casting from specific EventKey to generic (union) GdkEvent?
gdkevent = Gdk.Event(eventkey.type)
gdkevent.key.type = eventkey.type
gdkevent = Gdk.Event.new(eventkey.type)
gdkevent.key.window = eventkey.window
gdkevent.key.send_event = eventkey.send_event
gdkevent.key.time = eventkey.time
@ -40,6 +39,8 @@ class Terminator(Borg):
groups = None
config = None
keybindings = None
style_provider = None
last_focused_term = None
origcwd = None
dbus_path = None
@ -364,14 +365,23 @@ class Terminator(Borg):
def reconfigure(self):
"""Update configuration for the whole application"""
if self.style_provider is not None:
Gtk.StyleContext.remove_provider_for_screen(
Gdk.Screen.get_default(),
self.style_provider)
self.style_provider = None
if self.config['handle_size'] in xrange(0, 6):
Gtk.rc_parse_string("""
style "terminator-paned-style" {
GtkPaned::handle_size = %s
css = """
GtkPaned {
-GtkPaned-handle-size: %s
}
class "GtkPaned" style "terminator-paned-style"
""" % self.config['handle_size'])
Gtk.rc_reset_styles(Gtk.Settings.get_default())
""" % self.config['handle_size']
self.style_provider = Gtk.CssProvider()
self.style_provider.load_from_data(css)
Gtk.StyleContext.add_provider_for_screen(
Gdk.Screen.get_default(),
self.style_provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
# Cause all the terminals to reconfigure
for terminal in self.terminals: