Search code examples
pythonpython-3.xgtkgtk3pygobject

Gtk.EntryCompletion() popup status to resolve keybind conflict


I have the Gtk.Entry() with Gtk.EntryCompletion(), have binded the arrows key to do different function i.e. navigate through the command history like in terminal.

But navigation on Completion Popup will, conflict with history navigation, Is there any way to check if Completion Popup is visible/active, so that we can turn of history navigation.

Plus, Is there way to get total match count of Completion Popup.

Below is the sample program.

#!/usr/bin/env python3

import gi
gi.require_version('Gtk', '3.0')

from gi.repository import Gtk

entry = Gtk.Entry()

def on_key_press(widget, event):
    # NOTE to stop propagation of signal return True
    if   event.keyval == 65362: widget.set_text("history -1") # Up-arrow
    elif event.keyval == 65364: widget.set_text("history +1") # Down-arrow

entry.connect('key_press_event', on_key_press)

entrycompletion = Gtk.EntryCompletion()
entry.set_completion(entrycompletion)

liststore = Gtk.ListStore(str)
for row in "entry complete key conflit with history".split():
    liststore.append([row])

entrycompletion.set_model(liststore)
entrycompletion.set_text_column(0)

root = Gtk.Window()
root.add(entry)
root.connect('delete-event', Gtk.main_quit)
root.show_all()
Gtk.main()

Solution

  • You need to set the inline selection option to True with entrycompletion.set_inline_selection(True). This will connect the key press event to the completion pop-up menu.

    #!/usr/bin/env python3
    
    import gi
    gi.require_version('Gtk', '3.0')
    
    from gi.repository import Gtk
    
    entry = Gtk.Entry()
    
    def on_key_press(widget, event):
        # NOTE to stop propagation of signal return True
        if   event.keyval == 65362: widget.set_text("history -1") # Up-arrow
        elif event.keyval == 65364: widget.set_text("history +1") # Down-arrow
    
    entry.connect('key_press_event', on_key_press)
    
    entrycompletion = Gtk.EntryCompletion()
    entrycompletion.set_inline_selection(True) #enables selection with up and down arrows
    entry.set_completion(entrycompletion)
    
    liststore = Gtk.ListStore(str)
    for row in "entry complete key conflit with history".split():
        liststore.append([row])
    
    entrycompletion.set_model(liststore)
    entrycompletion.set_text_column(0)
    
    root = Gtk.Window()
    root.add(entry)
    root.connect('delete-event', Gtk.main_quit)
    root.show_all()
    Gtk.main()