Gtk4: Replacement for `Gtk.CellRendererAccel` and how to use it in `Gtk.ListBoxRow`

Hi,

How can I use Gtk.CellRendererAccel in Gtk.ListBox / Gtk.ListBoxRow?

I’ve read Gtk – 4.0: List Widget Overview, looks the Gtk.CellRendererAccel cannot be used in Gtk.ListBox. If so, what’s the replacement for Gtk.CellRendererAccel for Gtk.ListBox ? And how to use it in Gtk.ListBoxRow?

I don’t want to recreate the wheel if it has already existed.

I searched the gtk4 doc and really didn’t find the replacement for Gtk.CellRendererAccel.

Any suggestion?

Thanks.

Cell renderers are not widgets, so you can’t add them to a widget that does not expect them.

Currently, there’s no replacement for GtkCellRendererAccel. You can replace it by using a plain GtkLabel, and a GtkEventControllerKey to listen to key press and release events, and then turn the key and modifiers into strings.

Yes, it is. I failed to do that.

It’s pity that there is not a replacement for GtkCellRendererAccel. Thanks for your advice very much, I’ll try to implement one. :blush:

Hi @ebassi,

I create a Gtk.Box and put a Gtk.Button in it. When clicking the button, I change the button to a New accelerator button, and add a Gtk.EventControllerKey to this button. Afterwards I except when I press any key, the Gtk.EventControllerKey can catch it. Code like the below lines:

const rendererAccelBox = new Gtk.Box({
    spacing: 6,
    margin_top: 6,
    margin_bottom: 6,
    margin_start: 6,
    margin_end: 6,
});

const addAccelButton = new Gtk.Button({
	label: 'Add accelerator',
});
addAccelButton.connect('clicked', () => {
	const newAccelButton = new Gtk.Button({
		label: 'New accelerator...',
	});
	const eventControllerKey = new Gtk.EventControllerKey();
	newAccelButton.add_controller(eventControllerKey);

	// newAccelButton.grab_focus();	
   newAccelButton.set_state_flags(Gtk.StateFlags.GTK_STATE_FLAG_ACTIVE, true);
   // Error! Gtk does not have expose gtk_grab_add?
	Gtk.grab_add(newAccelButton);

	eventControllerKey.connect('key-pressed', (_widget, keyval, keycode, state) => {
		log('key-pressed');
	});
   rendererAccelBox.append(newAccelButton);

});

When I click the New accelerator button, and press any key, the
Gtk.EventControllerKey can catch it.

I’ve read the source code of gtkcellrendereraccel.c#gtk_cell_editable_widget_new, it uses gtk_grab_add to grab the keyboard and pointer events.

My question is that how can I make the New accelerator button grab the keyboard and pointer events? I can’t find suitable APIs in the Gtk – 4.0

If the code / implement is not right, please let me know. Thank you very much.

Looks I figure out what’s wrong here.

Use newAccelButton.grab_focus(); can grab the focus after the newAccelButton is added to a Gtk.Box.

Hi @ebassi ,

I think the keys received by GtkEventControllerKey are defined in gdkkeysyms.h

And I want to send the keys to ydotool. But ydotool can only accept key names defined in/usr/include/linux/input-event-codes.h.

How can translate the keys in gdkkeysyms.h to keys in input-event-codes.h? Is there any API / tool can do this for me?

Thanks.

No, there is no such API; you’ll have to create a translation map yourself.

The GDK key symbols come from X11 for historical reasons, and we update them regularly: https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gdk/gdkkeysyms-update.pl

@ebassi

Hello again.

How can I set up ctrl_l+s and ctrl_r+s respectively? I mean ctrl_l and ctrl_r are two different modifier keys. The same as ALT and Shift etc. So ctrl_l+s and ctrl_r+s are different.

I checked the source code of Gtk, GdkModifierType only has one GDK_CONTROL_MASK, one GDK_SHIFT_MASK and GDK_ALT_MASK etc. Does this mean the GtkEventControllerKey can’t distinguish the left key and the right key, so that I can’t set ctrl_l+s or ctrl_r+s?

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.