Reputation: 966
I have a problem adding accelerators to a menu that appears on a Gtk.EventBox() that contains only a Vte.Terminal(). The menu appears OK, and copy and paste work fine, but the accelerators just don't seem to work. They are grabbed by VTE before they get to my eventBox (weirdly, 'cause my eventbox is above the vte widget) and, for example, Ctrl+Shift+C works as Ctrl+C on a terminal and just interrupts the current process. Any ideas on how to go about this?
The relevant association of menuitem-accelerator is the comment code.
def terminalBox(self, terminal):
"""Given a terminal, creates an EventBox for the Box that has as
a children said terminal"""
eventTerminalBox = Gtk.EventBox()
terminalBox = Gtk.Box()
terminalBox.pack_start(terminal, True, True, 0)
eventTerminalBox.connect("button_press_event", self.right_click)
eventTerminalBox.add(terminalBox)
return eventTerminalBox
def right_click(self, eventbox, event):
"""Defines the menu created when a user rightclicks on the
terminal eventbox"""
menu = Gtk.Menu()
copy = Gtk.MenuItem("Copy")
paste = Gtk.MenuItem("Paste")
menu.append(paste)
menu.append(copy)
# TODO: make accelerators for copy paste work. add accel for paste
#accelgroup = Gtk.AccelGroup()
#self.add_accel_group(accelgroup)
#accellabel = Gtk.AccelLabel("Copy/Paste")
#accellabel.set_hexpand(True)
#copy.add_accelerator("activate",
# accelgroup,
# Gdk.keyval_from_name("c"),
# Gdk.ModifierType.SHIFT_MASK |
# Gdk.ModifierType.CONTROL_MASK,
# Gtk.AccelFlags.VISIBLE)
copy.connect("activate", self.copy_text)
paste.connect("activate", self.paste_text)
copy.show()
paste.show()
menu.popup(None, None, None, None, event.button, event.time)
def copy_text(self, button):
"""What happens when the user copies text"""
content = self.selection_clipboard.wait_for_text()
self.clipboard.set_text(content, -1)
def paste_text(self, button):
"""What happens when the user pastes text"""
currentTerminal = self.getCurrentFocusedTerminal()
currentTerminal.paste_clipboard()
Upvotes: 2
Views: 425
Reputation: 966
OK, in case anyone else needs help with this. I gave up with GTK menu accelerators, so instead I turned to my Vte Widget. There, I connected the key_press_event signal to a method which detects which keys are pressed, and in case it finds the combination of Ctrl+Shift it returns. The return is important because that's what blocks VTE from actually doing something else with the shorcut, like killing the process on Ctrl+Shift+C.
class Terminal(Vte.Terminal):
"""Defines a simple terminal"""
def __init__(self, CONF):
super(Vte.Terminal, self).__init__()
self.pty = self.pty_new_sync(Vte.PtyFlags.DEFAULT, None)
self.set_pty(self.pty)
self.connect("key_press_event", self.copy_or_paste)
self.set_scrollback_lines(-1)
self.set_audible_bell(0)
def copy_or_paste(self, widget, event):
"""Decides if the Ctrl+Shift is pressed, in which case returns True.
If Ctrl+Shift+C or Ctrl+Shift+V are pressed, copies or pastes,
acordingly. Return necesary so it doesn't perform other action,
like killing the process, on Ctrl+C.
"""
control_key = Gdk.ModifierType.CONTROL_MASK
shift_key = Gdk.ModifierType.SHIFT_MASK
if event.type == Gdk.EventType.KEY_PRESS:
if event.state == shift_key | control_key: #both shift and control
if event.keyval == 67: # that's the C key
self.copy_clipboard()
elif event.keyval == 86: # and that's the V key
self.paste_clipboard()
return True
Upvotes: 1