gtk-rs / gtk4-rs

Rust bindings of GTK 4
https://gtk-rs.org/gtk4-rs/
MIT License
1.8k stars 167 forks source link

Accessing GtkWidget class methods #1793

Open danirod opened 1 month ago

danirod commented 1 month ago

Discussed in https://github.com/gtk-rs/gtk4-rs/discussions/1790

Originally posted by **danirod** July 4, 2024 Hello there. I am looking for suggestions in regards to using [the class methods for the GtkWidget class](https://docs.gtk.org/gtk4/class.Widget.html#class-methods). In gtk-rs, these methods are part of the [WidgetClassExt](https://docs.rs/gtk4/latest/gtk4/subclass/widget/trait.WidgetClassExt.html), but I can't get my head around how to get access to those methods. In my case, the goal is to have access to the `add_shortcut` method ([docs.rs](https://docs.rs/gtk4/latest/gtk4/subclass/widget/trait.WidgetClassExt.html#method.add_shortcut), [GTK](https://docs.gtk.org/gtk4/class_method.Widget.add_shortcut.html)) so that I can install shortcuts into every instance of a specific widget. I am writing a GTK 4 application and while GNU/Linux is the preferred platform, I am doing my best to make sure that the application looks and works right in Windows and macOS too. In GTK 4, the `` keyboard modifier is bound to the Control key even on macOS, where most users would expect the `` modifier. This means that, by default, the shortcuts for built-in actions like copy and paste from a text field are `Ctrl-C` and `Ctrl-V` rather than `Cmd-C` and `Cmd-V`, unless the application changes them. [In this specific example](https://gaphor.org/2022/12/10/gtk4-macos-keybindings/#built-in-widgets), Gaphor is using the following Python code to change the shortcuts of the selection.select-all action part of the Gtk.TextView widget class, so that every instance of Gtk.TextView uses the new shortcut (the code is actually more complex becuase they are using a function to encapsulate building the shortcut): ```python Gtk.TextView.add_shortcut( new_shortcut_with_args( "a", "select-all", GLib.Variant.new_boolean(True) ) ) ``` One of the benefits of the GObject introspection is that it is very easy to translate code from between languages. However, even if I suspect it cannot be that difficult, I can't call the `add_shortcut` function because I don't know how to get a code path to that method. If this was a custom widget, I could just use the `class_init` function when implementing `ObjectSubclass` for my widget, because I have a Class parameter, but when I try to apply it to the GtkText and GtkTextView widgets like the code I show above, I am not having any luck. For C and Python, the function calls are more obvious (`gtk_widget_class_add_shortcut` and `Gtk.TextView.add_shortcut`), but in Rust it is being a challenge. I don't know if I am supposed to just use `gtk::TextView::add_shortcut()` and make sure that I am using the WidgetClassExt trait in my file (on a first try, doesn't seem to work), or if I have to use a function to get the class first. I've played with the following, but it doesn't compile. ```rust let trigger = gtk::ShortcutTrigger::parse_string("c").unwrap(); let shortcut = gtk::Shortcut::new(Some(trigger), Some(gtk::NamedAction::new("clipboard.copy"))); let text_type = gtk::TextView::static_type(); let text_class = glib::object::Class::from_type(text_type).unwrap(); text_class.add_shortcut(&trigger); ``` I've checked the source code for other programs written in gtk-rs to see if I can learn something from them, but it seems that none of them has had the need to use this function so far. Any advice? Thanks in advance.
nazar-pc commented 1 month ago

BTW Cmd situation on macOS will be fixed in GTK 4.16: https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/7260