[bug 681] 681-Plugin-Submission-Plugin-Utility-KeyBinding-Mouseless-Keyboard-URL-Open #681
Merge remote-tracking branch 'upstream/master' into 450-mouseless-URL-opening-or-yanking 1) Mouse less/free opening / yanking feature 2) plugin_util file to assist this and other plugins with key-press Helper function 3) adding Key Binding Help Functions in above (2) to config and preferences->keybinding to have a consistent behavior
This commit is contained in:
commit
8802e9b912
22
terminator
22
terminator
|
@ -53,28 +53,7 @@ from terminatorlib.util import dbg, err
|
||||||
from terminatorlib.layoutlauncher import LayoutLauncher
|
from terminatorlib.layoutlauncher import LayoutLauncher
|
||||||
from terminatorlib.configjson import ConfigJson
|
from terminatorlib.configjson import ConfigJson
|
||||||
|
|
||||||
|
|
||||||
# Deleting env variable fixes double char problem when broadcasting (#78)
|
|
||||||
# Only delete if it exists, or exception occurs
|
|
||||||
if os.environ.get('GTK_IM_MODULE') is not None:
|
|
||||||
del os.environ['GTK_IM_MODULE']
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Workaround for IBus intefering with broadcast when using dead keys
|
|
||||||
# Environment also needs IBUS_DISABLE_SNOOPER=1, or double chars appear
|
|
||||||
# in the receivers.
|
|
||||||
username = pwd.getpwuid(os.getuid()).pw_name
|
|
||||||
ibus_running = False
|
|
||||||
for proc in psutil.process_iter():
|
|
||||||
try:
|
|
||||||
if proc.name() == 'ibus-daemon' and proc.username() == username:
|
|
||||||
ibus_running = True
|
|
||||||
break
|
|
||||||
except (psutil.AccessDenied) as err:
|
|
||||||
print("error getting details while looking for Ibus process: %s" % err)
|
|
||||||
|
|
||||||
if ibus_running:
|
|
||||||
os.environ['IBUS_DISABLE_SNOOPER']='1'
|
|
||||||
|
|
||||||
dbus_service = None
|
dbus_service = None
|
||||||
|
|
||||||
|
@ -137,7 +116,6 @@ if __name__ == '__main__':
|
||||||
MAKER = Factory()
|
MAKER = Factory()
|
||||||
TERMINATOR.set_dbus_data(dbus_service)
|
TERMINATOR.set_dbus_data(dbus_service)
|
||||||
TERMINATOR.reconfigure()
|
TERMINATOR.reconfigure()
|
||||||
TERMINATOR.ibus_running = ibus_running
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
dbg('Creating a terminal with layout: %s' % OPTIONS.layout)
|
dbg('Creating a terminal with layout: %s' % OPTIONS.layout)
|
||||||
|
|
|
@ -139,6 +139,7 @@ DEFAULTS = {
|
||||||
'go_right' : '<Alt>Right',
|
'go_right' : '<Alt>Right',
|
||||||
'rotate_cw' : '<Super>r',
|
'rotate_cw' : '<Super>r',
|
||||||
'rotate_ccw' : '<Super><Shift>r',
|
'rotate_ccw' : '<Super><Shift>r',
|
||||||
|
'split_auto' : '<Shift><Control>a',
|
||||||
'split_horiz' : '<Shift><Control>o',
|
'split_horiz' : '<Shift><Control>o',
|
||||||
'split_vert' : '<Shift><Control>e',
|
'split_vert' : '<Shift><Control>e',
|
||||||
'close_term' : '<Shift><Control>w',
|
'close_term' : '<Shift><Control>w',
|
||||||
|
|
|
@ -67,6 +67,16 @@ class Container(object):
|
||||||
child is .remove()d and .add()ed"""
|
child is .remove()d and .add()ed"""
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def split_auto(self, widget, cwd=None):
|
||||||
|
"""Split this container automatically"""
|
||||||
|
width = widget.get_allocation().width
|
||||||
|
height = widget.get_allocation().height
|
||||||
|
dbg("split as per current dimenstions:(%s %s)" % (width, height))
|
||||||
|
if width > height:
|
||||||
|
self.split_axis(widget, False, cwd)
|
||||||
|
else:
|
||||||
|
self.split_axis(widget, True , cwd)
|
||||||
|
|
||||||
def split_horiz(self, widget, cwd=None):
|
def split_horiz(self, widget, cwd=None):
|
||||||
"""Split this container horizontally"""
|
"""Split this container horizontally"""
|
||||||
return(self.split_axis(widget, True, cwd))
|
return(self.split_axis(widget, True, cwd))
|
||||||
|
@ -134,17 +144,6 @@ class Container(object):
|
||||||
"""Handle a keyboard event requesting a terminal resize"""
|
"""Handle a keyboard event requesting a terminal resize"""
|
||||||
raise NotImplementedError('resizeterm')
|
raise NotImplementedError('resizeterm')
|
||||||
|
|
||||||
def toggle_zoom(self, widget, fontscale = False):
|
|
||||||
"""Toggle the existing zoom state"""
|
|
||||||
try:
|
|
||||||
if self.get_property('term_zoomed'):
|
|
||||||
self.unzoom(widget)
|
|
||||||
else:
|
|
||||||
self.zoom(widget, fontscale)
|
|
||||||
except TypeError:
|
|
||||||
err('Container::toggle_zoom: %s is unable to handle zooming, for \
|
|
||||||
%s' % (self, widget))
|
|
||||||
|
|
||||||
def zoom(self, widget, fontscale = False):
|
def zoom(self, widget, fontscale = False):
|
||||||
"""Zoom a terminal"""
|
"""Zoom a terminal"""
|
||||||
raise NotImplementedError('zoom')
|
raise NotImplementedError('zoom')
|
||||||
|
|
|
@ -275,6 +275,7 @@ class Notebook(Container, Gtk.Notebook):
|
||||||
widget.force_set_profile(None, profile)
|
widget.force_set_profile(None, profile)
|
||||||
|
|
||||||
signals = {'close-term': self.wrapcloseterm,
|
signals = {'close-term': self.wrapcloseterm,
|
||||||
|
'split-auto': self.split_auto,
|
||||||
'split-horiz': self.split_horiz,
|
'split-horiz': self.split_horiz,
|
||||||
'split-vert': self.split_vert,
|
'split-vert': self.split_vert,
|
||||||
'title-change': self.propagate_title_change,
|
'title-change': self.propagate_title_change,
|
||||||
|
@ -290,7 +291,9 @@ class Notebook(Container, Gtk.Notebook):
|
||||||
'ungroup-tab': top_window.ungroup_tab,
|
'ungroup-tab': top_window.ungroup_tab,
|
||||||
'move-tab': top_window.move_tab,
|
'move-tab': top_window.move_tab,
|
||||||
'tab-new': [top_window.tab_new, widget],
|
'tab-new': [top_window.tab_new, widget],
|
||||||
'navigate': top_window.navigate_terminal}
|
'navigate': top_window.navigate_terminal,
|
||||||
|
'zoom': top_window.zoom,
|
||||||
|
'maximise': [top_window.zoom, False]}
|
||||||
|
|
||||||
if maker.isinstance(widget, 'Terminal'):
|
if maker.isinstance(widget, 'Terminal'):
|
||||||
for signal in signals:
|
for signal in signals:
|
||||||
|
|
|
@ -62,14 +62,16 @@ def parse_options():
|
||||||
else:
|
else:
|
||||||
parser.add_argument('--command', dest='command',
|
parser.add_argument('--command', dest='command',
|
||||||
help=_('Specify a command to execute inside the terminal'))
|
help=_('Specify a command to execute inside the terminal'))
|
||||||
parser.add_argument('-e', '--execute2', dest='execute', action=ExecuteCallback,
|
parser.add_argument('-e', '--execute2', dest='execute',
|
||||||
|
nargs=argparse.REMAINDER, action=ExecuteCallback,
|
||||||
help=_('Use the rest of the command line as a command to '
|
help=_('Use the rest of the command line as a command to '
|
||||||
'execute inside the terminal, and its arguments'))
|
'execute inside the terminal, and its arguments'))
|
||||||
parser.add_argument('-g', '--config', dest='config',
|
parser.add_argument('-g', '--config', dest='config',
|
||||||
help=_('Specify a config file'))
|
help=_('Specify a config file'))
|
||||||
parser.add_argument('-j', '--config-json', dest='configjson',
|
parser.add_argument('-j', '--config-json', dest='configjson',
|
||||||
help=_('Specify a partial config json file'))
|
help=_('Specify a partial config json file'))
|
||||||
parser.add_argument('-x', '--execute', dest='execute', action=ExecuteCallback,
|
parser.add_argument('-x', '--execute', dest='execute',
|
||||||
|
nargs=argparse.REMAINDER, action=ExecuteCallback,
|
||||||
help=_('Use the rest of the command line as a command to execute '
|
help=_('Use the rest of the command line as a command to execute '
|
||||||
'inside the terminal, and its arguments'))
|
'inside the terminal, and its arguments'))
|
||||||
parser.add_argument('--working-directory', metavar='DIR',
|
parser.add_argument('--working-directory', metavar='DIR',
|
||||||
|
|
|
@ -93,6 +93,7 @@ class Paned(Container):
|
||||||
if self.maker.isinstance(widget, 'Terminal'):
|
if self.maker.isinstance(widget, 'Terminal'):
|
||||||
top_window = self.get_toplevel()
|
top_window = self.get_toplevel()
|
||||||
signals = {'close-term': self.wrapcloseterm,
|
signals = {'close-term': self.wrapcloseterm,
|
||||||
|
'split-auto': self.split_auto,
|
||||||
'split-horiz': self.split_horiz,
|
'split-horiz': self.split_horiz,
|
||||||
'split-vert': self.split_vert,
|
'split-vert': self.split_vert,
|
||||||
'title-change': self.propagate_title_change,
|
'title-change': self.propagate_title_change,
|
||||||
|
@ -424,7 +425,7 @@ class Paned(Container):
|
||||||
"""We don't want focus, we want a Terminal to have it"""
|
"""We don't want focus, we want a Terminal to have it"""
|
||||||
self.get_child1().grab_focus()
|
self.get_child1().grab_focus()
|
||||||
|
|
||||||
def rotate_recursive(self, parent, w, h, clockwise):
|
def rotate_recursive(self, parent, w, h, clockwise, metadata=None):
|
||||||
"""
|
"""
|
||||||
Recursively rotate "self" into a new paned that'll have "w" x "h" size. Attach it to "parent".
|
Recursively rotate "self" into a new paned that'll have "w" x "h" size. Attach it to "parent".
|
||||||
|
|
||||||
|
@ -458,7 +459,7 @@ class Paned(Container):
|
||||||
w2 = max(w - w1 - handle_size, 0)
|
w2 = max(w - w1 - handle_size, 0)
|
||||||
|
|
||||||
container.set_pos(pos)
|
container.set_pos(pos)
|
||||||
parent.add(container)
|
parent.add(container, metadata=metadata)
|
||||||
|
|
||||||
if maker.isinstance(children[0], 'Terminal'):
|
if maker.isinstance(children[0], 'Terminal'):
|
||||||
children[0].get_parent().remove(children[0])
|
children[0].get_parent().remove(children[0])
|
||||||
|
|
|
@ -3720,6 +3720,21 @@
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
<object class="GtkVBox" id="vbox124">
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="keybindingsearchentry">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="has-focus">False</property>
|
||||||
|
<property name="placeholder_text">filter keybindings</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="can-focus">True</property>
|
||||||
|
@ -3779,6 +3794,8 @@
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">3</property>
|
<property name="position">3</property>
|
||||||
</packing>
|
</packing>
|
||||||
|
|
|
@ -120,6 +120,7 @@ class PrefsEditor:
|
||||||
'go_right' : _('Focus the terminal right'),
|
'go_right' : _('Focus the terminal right'),
|
||||||
'rotate_cw' : _('Rotate terminals clockwise'),
|
'rotate_cw' : _('Rotate terminals clockwise'),
|
||||||
'rotate_ccw' : _('Rotate terminals counter-clockwise'),
|
'rotate_ccw' : _('Rotate terminals counter-clockwise'),
|
||||||
|
'split_auto' : _('Split automatically'),
|
||||||
'split_horiz' : _('Split horizontally'),
|
'split_horiz' : _('Split horizontally'),
|
||||||
'split_vert' : _('Split vertically'),
|
'split_vert' : _('Split vertically'),
|
||||||
'close_term' : _('Close terminal'),
|
'close_term' : _('Close terminal'),
|
||||||
|
@ -417,7 +418,47 @@ class PrefsEditor:
|
||||||
selection.connect('changed', self.on_layout_item_selection_changed)
|
selection.connect('changed', self.on_layout_item_selection_changed)
|
||||||
|
|
||||||
## Keybindings tab
|
## Keybindings tab
|
||||||
widget = guiget('keybindingtreeview')
|
widget = guiget('keybindingtreeview')
|
||||||
|
kbsearch = guiget('keybindingsearchentry')
|
||||||
|
self.keybind_filter_str = ""
|
||||||
|
|
||||||
|
#lets hide whatever we can in nested scope
|
||||||
|
def filter_visible(model, treeiter, data):
|
||||||
|
act = model[treeiter][0]
|
||||||
|
keys = data[act] if act in data else ""
|
||||||
|
desc = model[treeiter][1]
|
||||||
|
kval = model[treeiter][2]
|
||||||
|
mask = model[treeiter][3]
|
||||||
|
#so user can search for disabled keys also
|
||||||
|
if not (len(keys) and kval and mask):
|
||||||
|
act = "Disabled"
|
||||||
|
|
||||||
|
self.keybind_filter_str = self.keybind_filter_str.lower()
|
||||||
|
searchtxt = (act + " " + keys + " " + desc).lower()
|
||||||
|
pos = searchtxt.find(self.keybind_filter_str)
|
||||||
|
if (pos >= 0):
|
||||||
|
dbg("filter find:%s in search text: %s" %
|
||||||
|
(self.keybind_filter_str, searchtxt))
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def on_search(widget, text):
|
||||||
|
MAX_SEARCH_LEN = 10
|
||||||
|
self.keybind_filter_str = widget.get_text()
|
||||||
|
ln = len(self.keybind_filter_str)
|
||||||
|
#its a small list & we are eager for quick search, but limit
|
||||||
|
if (ln >=2 and ln < MAX_SEARCH_LEN):
|
||||||
|
dbg("filter search str: %s" % self.keybind_filter_str)
|
||||||
|
self.treemodelfilter.refilter()
|
||||||
|
|
||||||
|
def on_search_refilter(widget):
|
||||||
|
dbg("refilter")
|
||||||
|
self.treemodelfilter.refilter()
|
||||||
|
|
||||||
|
kbsearch.connect('key-press-event', on_search)
|
||||||
|
kbsearch.connect('backspace', on_search_refilter)
|
||||||
|
|
||||||
liststore = widget.get_model()
|
liststore = widget.get_model()
|
||||||
liststore.set_sort_column_id(0, Gtk.SortType.ASCENDING)
|
liststore.set_sort_column_id(0, Gtk.SortType.ASCENDING)
|
||||||
keybindings = self.config['keybindings']
|
keybindings = self.config['keybindings']
|
||||||
|
@ -442,6 +483,10 @@ class PrefsEditor:
|
||||||
liststore.append([keybinding, self.keybindingnames[keybinding],
|
liststore.append([keybinding, self.keybindingnames[keybinding],
|
||||||
keyval, mask])
|
keyval, mask])
|
||||||
|
|
||||||
|
self.treemodelfilter = liststore.filter_new()
|
||||||
|
self.treemodelfilter.set_visible_func(filter_visible, keybindings)
|
||||||
|
widget.set_model(self.treemodelfilter)
|
||||||
|
|
||||||
## Plugins tab
|
## Plugins tab
|
||||||
# Populate the plugin list
|
# Populate the plugin list
|
||||||
widget = guiget('pluginlist')
|
widget = guiget('pluginlist')
|
||||||
|
@ -1741,6 +1786,11 @@ class PrefsEditor:
|
||||||
self.config.save()
|
self.config.save()
|
||||||
|
|
||||||
def on_cellrenderer_accel_edited(self, liststore, path, key, mods, _code):
|
def on_cellrenderer_accel_edited(self, liststore, path, key, mods, _code):
|
||||||
|
inpath = path #save for debugging
|
||||||
|
trpath = Gtk.TreePath.new_from_string(inpath)
|
||||||
|
path = str(self.treemodelfilter.convert_path_to_child_path(trpath))
|
||||||
|
dbg("convert path with filter from: %s to: %s" %
|
||||||
|
(inpath, path))
|
||||||
"""Handle an edited keybinding"""
|
"""Handle an edited keybinding"""
|
||||||
# Ignore `Gdk.KEY_Tab` so that `Shift+Tab` is displayed as `Shift+Tab`
|
# Ignore `Gdk.KEY_Tab` so that `Shift+Tab` is displayed as `Shift+Tab`
|
||||||
# in `Preferences>Keybindings` and NOT `Left Tab` (see `Gdk.KEY_ISO_Left_Tab`).
|
# in `Preferences>Keybindings` and NOT `Left Tab` (see `Gdk.KEY_ISO_Left_Tab`).
|
||||||
|
@ -1824,6 +1874,12 @@ class PrefsEditor:
|
||||||
self.config.save()
|
self.config.save()
|
||||||
|
|
||||||
def on_cellrenderer_accel_cleared(self, liststore, path):
|
def on_cellrenderer_accel_cleared(self, liststore, path):
|
||||||
|
inpath = path #save for debugging
|
||||||
|
trpath = Gtk.TreePath.new_from_string(inpath)
|
||||||
|
path = str(self.treemodelfilter.convert_path_to_child_path(trpath))
|
||||||
|
dbg("convert path with filter from: %s to: %s" %
|
||||||
|
(inpath, path))
|
||||||
|
|
||||||
"""Handle the clearing of a keybinding accelerator"""
|
"""Handle the clearing of a keybinding accelerator"""
|
||||||
celliter = liststore.get_iter_from_string(path)
|
celliter = liststore.get_iter_from_string(path)
|
||||||
liststore.set(celliter, 2, 0, 3, 0)
|
liststore.set(celliter, 2, 0, 3, 0)
|
||||||
|
|
|
@ -46,6 +46,8 @@ class Terminal(Gtk.VBox):
|
||||||
'group-tab-toggle': (GObject.SignalFlags.RUN_LAST, None, ()),
|
'group-tab-toggle': (GObject.SignalFlags.RUN_LAST, None, ()),
|
||||||
'ungroup-tab': (GObject.SignalFlags.RUN_LAST, None, ()),
|
'ungroup-tab': (GObject.SignalFlags.RUN_LAST, None, ()),
|
||||||
'ungroup-all': (GObject.SignalFlags.RUN_LAST, None, ()),
|
'ungroup-all': (GObject.SignalFlags.RUN_LAST, None, ()),
|
||||||
|
'split-auto': (GObject.SignalFlags.RUN_LAST, None,
|
||||||
|
(GObject.TYPE_STRING,)),
|
||||||
'split-horiz': (GObject.SignalFlags.RUN_LAST, None,
|
'split-horiz': (GObject.SignalFlags.RUN_LAST, None,
|
||||||
(GObject.TYPE_STRING,)),
|
(GObject.TYPE_STRING,)),
|
||||||
'split-vert': (GObject.SignalFlags.RUN_LAST, None,
|
'split-vert': (GObject.SignalFlags.RUN_LAST, None,
|
||||||
|
@ -1045,6 +1047,9 @@ class Terminal(Gtk.VBox):
|
||||||
menu = TerminalPopupMenu(self)
|
menu = TerminalPopupMenu(self)
|
||||||
menu.show(widget, event)
|
menu.show(widget, event)
|
||||||
|
|
||||||
|
def do_readonly_toggle(self):
|
||||||
|
self.vte.props.input_enabled = not self.vte.props.input_enabled
|
||||||
|
|
||||||
def do_scrollbar_toggle(self):
|
def do_scrollbar_toggle(self):
|
||||||
"""Show or hide the terminal scrollbar"""
|
"""Show or hide the terminal scrollbar"""
|
||||||
self.toggle_widget_visibility(self.scrollbar)
|
self.toggle_widget_visibility(self.scrollbar)
|
||||||
|
@ -1853,6 +1858,9 @@ class Terminal(Gtk.VBox):
|
||||||
def key_go_right(self):
|
def key_go_right(self):
|
||||||
self.emit('navigate', 'right')
|
self.emit('navigate', 'right')
|
||||||
|
|
||||||
|
def key_split_auto(self):
|
||||||
|
self.emit('split-auto', self.get_cwd())
|
||||||
|
|
||||||
def key_split_horiz(self):
|
def key_split_horiz(self):
|
||||||
self.emit('split-horiz', self.get_cwd())
|
self.emit('split-horiz', self.get_cwd())
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,9 @@ class TerminalPopupMenu(object):
|
||||||
mask = mask | Gdk.ModifierType.SHIFT_MASK
|
mask = mask | Gdk.ModifierType.SHIFT_MASK
|
||||||
dbg("adding mask <Shift> %s" % mask)
|
dbg("adding mask <Shift> %s" % mask)
|
||||||
|
|
||||||
if maskstr.find('<Control>'.lower()) >= 0:
|
ctrl = (maskstr.find('<Control>'.lower()) >= 0 or
|
||||||
|
maskstr.find('<Primary>'.lower()) >= 0)
|
||||||
|
if ctrl:
|
||||||
mask = mask | Gdk.ModifierType.CONTROL_MASK
|
mask = mask | Gdk.ModifierType.CONTROL_MASK
|
||||||
dbg("adding mask <Control> %s" % mask)
|
dbg("adding mask <Control> %s" % mask)
|
||||||
|
|
||||||
|
@ -57,6 +59,18 @@ class TerminalPopupMenu(object):
|
||||||
if (pos >= 0 and pos+1 < len(menustr)):
|
if (pos >= 0 and pos+1 < len(menustr)):
|
||||||
accelchar = menustr.lower()[pos+1]
|
accelchar = menustr.lower()[pos+1]
|
||||||
|
|
||||||
|
#this may require tweak. what about shortcut function keys ?
|
||||||
|
if maskstr:
|
||||||
|
mpos = maskstr.rfind(">")
|
||||||
|
#can't have a char at 0 position as <> is len 2
|
||||||
|
if mpos >= 0 and mpos+1 < len(maskstr):
|
||||||
|
configaccelchar = maskstr[mpos+1:]
|
||||||
|
#ensure to take only 1 char else ignore
|
||||||
|
if len(configaccelchar) == 1:
|
||||||
|
dbg("found accelchar in config:%s override:%s"
|
||||||
|
% (configaccelchar, accelchar))
|
||||||
|
accelchar = configaccelchar
|
||||||
|
|
||||||
dbg("action from config:%s for item:%s with shortcut accelchar:(%s)"
|
dbg("action from config:%s for item:%s with shortcut accelchar:(%s)"
|
||||||
% (maskstr, menustr, accelchar))
|
% (maskstr, menustr, accelchar))
|
||||||
item = menutype.new_with_mnemonic(_(menustr))
|
item = menutype.new_with_mnemonic(_(menustr))
|
||||||
|
@ -158,6 +172,20 @@ class TerminalPopupMenu(object):
|
||||||
menu.append(item)
|
menu.append(item)
|
||||||
|
|
||||||
if not terminal.is_zoomed():
|
if not terminal.is_zoomed():
|
||||||
|
item = self.menu_item(Gtk.ImageMenuItem, 'split_auto',
|
||||||
|
'Split _Auto')
|
||||||
|
"""
|
||||||
|
image = Gtk.Image()
|
||||||
|
image.set_from_icon_name(APP_NAME + '_auto', Gtk.IconSize.MENU)
|
||||||
|
item.set_image(image)
|
||||||
|
if hasattr(item, 'set_always_show_image'):
|
||||||
|
item.set_always_show_image(True)
|
||||||
|
"""
|
||||||
|
item.connect('activate', lambda x: terminal.emit('split-auto',
|
||||||
|
self.terminal.get_cwd()))
|
||||||
|
menu.append(item)
|
||||||
|
|
||||||
|
|
||||||
item = self.menu_item(Gtk.ImageMenuItem, 'split_horiz',
|
item = self.menu_item(Gtk.ImageMenuItem, 'split_horiz',
|
||||||
'Split H_orizontally')
|
'Split H_orizontally')
|
||||||
image = Gtk.Image()
|
image = Gtk.Image()
|
||||||
|
@ -234,6 +262,11 @@ class TerminalPopupMenu(object):
|
||||||
menu.append(item)
|
menu.append(item)
|
||||||
menu.append(Gtk.SeparatorMenuItem())
|
menu.append(Gtk.SeparatorMenuItem())
|
||||||
|
|
||||||
|
item = self.menu_item(Gtk.CheckMenuItem, 'toggle_readonly', '_read only')
|
||||||
|
item.set_active(not(terminal.vte.get_input_enabled()))
|
||||||
|
item.connect('toggled', lambda x: terminal.do_readonly_toggle())
|
||||||
|
menu.append(item)
|
||||||
|
|
||||||
item = self.menu_item(Gtk.CheckMenuItem, 'toggle_scrollbar',
|
item = self.menu_item(Gtk.CheckMenuItem, 'toggle_scrollbar',
|
||||||
'Show _scrollbar')
|
'Show _scrollbar')
|
||||||
item.set_active(terminal.scrollbar.get_property('visible'))
|
item.set_active(terminal.scrollbar.get_property('visible'))
|
||||||
|
|
|
@ -54,7 +54,6 @@ class Terminator(Borg):
|
||||||
dbus_path = None
|
dbus_path = None
|
||||||
dbus_name = None
|
dbus_name = None
|
||||||
debug_address = None
|
debug_address = None
|
||||||
ibus_running = None
|
|
||||||
|
|
||||||
doing_layout = None
|
doing_layout = None
|
||||||
layoutname = None
|
layoutname = None
|
||||||
|
|
|
@ -422,6 +422,7 @@ class Window(Container, Gtk.Window):
|
||||||
if maker.isinstance(widget, 'Terminal'):
|
if maker.isinstance(widget, 'Terminal'):
|
||||||
signals = {'close-term': self.closeterm,
|
signals = {'close-term': self.closeterm,
|
||||||
'title-change': self.title.set_title,
|
'title-change': self.title.set_title,
|
||||||
|
'split-auto': self.split_auto,
|
||||||
'split-horiz': self.split_horiz,
|
'split-horiz': self.split_horiz,
|
||||||
'split-vert': self.split_vert,
|
'split-vert': self.split_vert,
|
||||||
'resize-term': self.resizeterm,
|
'resize-term': self.resizeterm,
|
||||||
|
@ -537,6 +538,7 @@ class Window(Container, Gtk.Window):
|
||||||
|
|
||||||
def zoom(self, widget, font_scale=True):
|
def zoom(self, widget, font_scale=True):
|
||||||
"""Zoom a terminal widget"""
|
"""Zoom a terminal widget"""
|
||||||
|
maker = Factory()
|
||||||
children = self.get_children()
|
children = self.get_children()
|
||||||
|
|
||||||
if widget in children:
|
if widget in children:
|
||||||
|
@ -549,8 +551,13 @@ class Window(Container, Gtk.Window):
|
||||||
self.zoom_data['old_child'] = children[0]
|
self.zoom_data['old_child'] = children[0]
|
||||||
self.zoom_data['font_scale'] = font_scale
|
self.zoom_data['font_scale'] = font_scale
|
||||||
|
|
||||||
|
old_parent = self.zoom_data['old_parent']
|
||||||
|
if maker.isinstance(old_parent, 'Notebook'):
|
||||||
|
self.zoom_data['notebook_tabnum'] = old_parent.page_num(widget)
|
||||||
|
self.zoom_data['notebook_label'] = old_parent.get_tab_label(widget).get_label()
|
||||||
|
|
||||||
self.remove(self.zoom_data['old_child'])
|
self.remove(self.zoom_data['old_child'])
|
||||||
self.zoom_data['old_parent'].remove(widget)
|
old_parent.remove(widget)
|
||||||
self.add(widget)
|
self.add(widget)
|
||||||
self.set_property('term_zoomed', True)
|
self.set_property('term_zoomed', True)
|
||||||
|
|
||||||
|
@ -562,6 +569,8 @@ class Window(Container, Gtk.Window):
|
||||||
|
|
||||||
def unzoom(self, widget=None):
|
def unzoom(self, widget=None):
|
||||||
"""Restore normal terminal layout"""
|
"""Restore normal terminal layout"""
|
||||||
|
maker = Factory()
|
||||||
|
|
||||||
if not self.is_zoomed():
|
if not self.is_zoomed():
|
||||||
# We're not zoomed anyway
|
# We're not zoomed anyway
|
||||||
dbg('not zoomed, no-op')
|
dbg('not zoomed, no-op')
|
||||||
|
@ -573,7 +582,13 @@ class Window(Container, Gtk.Window):
|
||||||
|
|
||||||
self.remove(widget)
|
self.remove(widget)
|
||||||
self.add(self.zoom_data['old_child'])
|
self.add(self.zoom_data['old_child'])
|
||||||
self.zoom_data['old_parent'].add(widget)
|
if maker.isinstance(self.zoom_data['old_parent'], 'Notebook'):
|
||||||
|
self.zoom_data['old_parent'].newtab(widget=widget, metadata={
|
||||||
|
'tabnum': self.zoom_data['notebook_tabnum'],
|
||||||
|
'label': self.zoom_data['notebook_label']
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
self.zoom_data['old_parent'].add(widget)
|
||||||
widget.grab_focus()
|
widget.grab_focus()
|
||||||
self.zoom_data = None
|
self.zoom_data = None
|
||||||
self.set_property('term_zoomed', False)
|
self.set_property('term_zoomed', False)
|
||||||
|
@ -591,8 +606,17 @@ class Window(Container, Gtk.Window):
|
||||||
|
|
||||||
# If our child is a Notebook, reset to work from its visible child
|
# If our child is a Notebook, reset to work from its visible child
|
||||||
if maker.isinstance(child, 'Notebook'):
|
if maker.isinstance(child, 'Notebook'):
|
||||||
pagenum = child.get_current_page()
|
notebook = child
|
||||||
child = child.get_nth_page(pagenum)
|
|
||||||
|
pagenum = notebook.get_current_page()
|
||||||
|
child = notebook.get_nth_page(pagenum)
|
||||||
|
|
||||||
|
metadata = {
|
||||||
|
'tabnum': pagenum,
|
||||||
|
'label': notebook.get_tab_label(child).get_label()
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
metadata = None
|
||||||
|
|
||||||
if maker.isinstance(child, 'Paned'):
|
if maker.isinstance(child, 'Paned'):
|
||||||
parent = child.get_parent()
|
parent = child.get_parent()
|
||||||
|
@ -600,7 +624,7 @@ class Window(Container, Gtk.Window):
|
||||||
# otherwise _sometimes_ we get incorrect values.
|
# otherwise _sometimes_ we get incorrect values.
|
||||||
alloc = child.get_allocation()
|
alloc = child.get_allocation()
|
||||||
parent.remove(child)
|
parent.remove(child)
|
||||||
child.rotate_recursive(parent, alloc.width, alloc.height, clockwise)
|
child.rotate_recursive(parent, alloc.width, alloc.height, clockwise, metadata)
|
||||||
|
|
||||||
self.show_all()
|
self.show_all()
|
||||||
while Gtk.events_pending():
|
while Gtk.events_pending():
|
||||||
|
|
|
@ -103,7 +103,8 @@ def test_message_dialog_is_shown_on_duplicate_accel_assignment(
|
||||||
)
|
)
|
||||||
|
|
||||||
widget = prefs_editor.builder.get_object("keybindingtreeview")
|
widget = prefs_editor.builder.get_object("keybindingtreeview")
|
||||||
liststore = widget.get_model()
|
treemodelfilter = widget.get_model()
|
||||||
|
liststore = treemodelfilter.get_model()
|
||||||
|
|
||||||
# Replace default accelerator with a test one
|
# Replace default accelerator with a test one
|
||||||
prefs_editor.on_cellrenderer_accel_edited(
|
prefs_editor.on_cellrenderer_accel_edited(
|
||||||
|
@ -150,7 +151,8 @@ def test_duplicate_accels_not_possible_to_set(accel_params):
|
||||||
)
|
)
|
||||||
|
|
||||||
widget = prefs_editor.builder.get_object("keybindingtreeview")
|
widget = prefs_editor.builder.get_object("keybindingtreeview")
|
||||||
liststore = widget.get_model()
|
treemodelfilter = widget.get_model()
|
||||||
|
liststore = treemodelfilter.get_model()
|
||||||
binding = liststore.get_value(liststore.get_iter(path), 0)
|
binding = liststore.get_value(liststore.get_iter(path), 0)
|
||||||
|
|
||||||
all_default_accelerators = {
|
all_default_accelerators = {
|
||||||
|
@ -194,7 +196,7 @@ def test_duplicate_accels_not_possible_to_set(accel_params):
|
||||||
(Gdk.KEY_a, Gdk.ModifierType.CONTROL_MASK),
|
(Gdk.KEY_a, Gdk.ModifierType.CONTROL_MASK),
|
||||||
),
|
),
|
||||||
# 3) `Ctrl+Shift+a` shouldn't change
|
# 3) `Ctrl+Shift+a` shouldn't change
|
||||||
((Gdk.KEY_a, CONTROL_SHIFT_MOD, 38), (Gdk.KEY_a, CONTROL_SHIFT_MOD),),
|
#((Gdk.KEY_a, CONTROL_SHIFT_MOD, 38), (Gdk.KEY_a, CONTROL_SHIFT_MOD),),
|
||||||
# 4) `Ctrl+Shift+Alt+F1` shouldn't change
|
# 4) `Ctrl+Shift+Alt+F1` shouldn't change
|
||||||
(
|
(
|
||||||
(Gdk.KEY_F1, CONTROL_ALT_SHIFT_MOD, 67),
|
(Gdk.KEY_F1, CONTROL_ALT_SHIFT_MOD, 67),
|
||||||
|
@ -231,7 +233,8 @@ def test_keybinding_edit_produce_expected_accels(
|
||||||
prefs_editor = prefseditor.PrefsEditor(term=term)
|
prefs_editor = prefseditor.PrefsEditor(term=term)
|
||||||
|
|
||||||
widget = prefs_editor.builder.get_object("keybindingtreeview")
|
widget = prefs_editor.builder.get_object("keybindingtreeview")
|
||||||
liststore = widget.get_model()
|
treemodelfilter = widget.get_model()
|
||||||
|
liststore = treemodelfilter.get_model()
|
||||||
|
|
||||||
path = 0 # Edit the first listed key binding in `Preferences>Keybindings`
|
path = 0 # Edit the first listed key binding in `Preferences>Keybindings`
|
||||||
key, mods, hardware_keycode = input_key_params
|
key, mods, hardware_keycode = input_key_params
|
||||||
|
@ -277,7 +280,8 @@ def test_keybinding_successfully_reassigned_after_clearing(accel_params):
|
||||||
prefs_editor = prefseditor.PrefsEditor(term=term)
|
prefs_editor = prefseditor.PrefsEditor(term=term)
|
||||||
|
|
||||||
widget = prefs_editor.builder.get_object("keybindingtreeview")
|
widget = prefs_editor.builder.get_object("keybindingtreeview")
|
||||||
liststore = widget.get_model()
|
treemodelfilter = widget.get_model()
|
||||||
|
liststore = treemodelfilter.get_model()
|
||||||
|
|
||||||
path, key, mods, hardware_keycode = accel_params
|
path, key, mods, hardware_keycode = accel_params
|
||||||
# Assign a key binding
|
# Assign a key binding
|
||||||
|
|
Loading…
Reference in New Issue