gtk-rs / gtk4-rs

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

Notebook API #286

Closed ricvelozo closed 3 years ago

ricvelozo commented 3 years ago

Notebook::set_current_page() should take i32 instead of u32. The docs says: "If negative, the last page will be used.". Moreover, NotebookPage::get_property_position() returns i32 too.

Also, NotebookPage::get_property_tab_label() causes a crash if no tab label was provided, instead of return None.

bilelmoussaoui commented 3 years ago

set_current_page is already handled correctly. It takes an Option and falls back to -1 if None was provided which is what returns it to the old page.

bilelmoussaoui commented 3 years ago

The Notebook Page APIs will need some fixing though, do you mind sending a PR for that?

ricvelozo commented 3 years ago

I can try.

bilelmoussaoui commented 3 years ago

Please otherwise at least attach an example to reproduce the issues you're facing with the current Notebook API

ricvelozo commented 3 years ago

Basically, I was populating a drop-down list with notebook pages, and the notebook itself was defined in GtkBuilder's XML (that is why the tab has no label).

let workspaces = &*self.workspaces; // TemplateChild<gtk::Notebook>
let workspaces_model = workspaces.get_pages().unwrap();
let workspace_factory = gtk::SignalListItemFactory::new();
workspace_factory.connect_setup(|_, list_item| {
    let label = gtk::LabelBuilder::new().xalign(0.0).build();
    list_item.set_child(Some(&label));
});
workspace_factory.connect_bind(|_, list_item| {
    let child = list_item
        .get_child()
        .expect("the list item has no child set")
        .downcast::<gtk::Label>()
        .expect("failed to cast to `gtk::Label`");
    let item = list_item
        .get_item()
        .expect("the list item is unbound")
        .downcast::<gtk::NotebookPage>()
        .expect("failed to cast to `gtk::NotebookPage`");
    // let tab_label = item.get_property_tab_label().expect("the tab has no label"); // <= Here, the crash
    let tab_label = format!("Workspace {}", item.get_property_position() + 1);
    child.set_label(&tab_label);
});
self.workspace_list.set_factory(Some(&workspace_factory)); // TemplateChild<gtk::DropDown>
self.workspace_list.set_model(Some(&workspaces_model));
<object class="GtkNotebook" id="workspaces">
    <property name="show-border">False</property>
    <property name="show-tabs">False</property>
    <child>
        <object class="GtkLabel">
            <property name="label">Workspace 1</property>
        </object>
    </child>
    <child>
        <object class="GtkLabel">
            <property name="label">Workspace 2</property>
        </object>
    </child>
</object>
bilelmoussaoui commented 3 years ago
    // let tab_label = item.get_property_tab_label().expect("the tab has no label"); /

You shouldn't unwrap here then. The property is nullable and returns a Option. calling expect there means you panic whenever you don't have a title which is wrong. You should handle that in a less-panicy way

ricvelozo commented 3 years ago

The problem is the panic is never called. The program just terminates with no output.

bilelmoussaoui commented 3 years ago

Do you have a backtrace?

ricvelozo commented 3 years ago
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/x86_64-linux-gnu/libthread_db.so.1".

Temporary breakpoint 1, app_template::main () at /home/ricardo/Projetos/app-template-gtk-rs/src/main.rs:11
11      setlocale(LocaleCategory::LcAll, "");
[New Thread 0x7ffff6245700 (LWP 8)]
[New Thread 0x7ffff5a44700 (LWP 9)]
[New Thread 0x7fffefe91700 (LWP 10)]

Thread 1 "app-template" hit Breakpoint 3, <app_template::main_window::imp::MainWindow as glib::subclass::object::ObjectImpl>::constructed::{{closure}} (list_item=0x7fffffffbea0) at /home/ricardo/Projetos/app-template-gtk-rs/src/main_window.rs:115
115                 let tab_label = item.get_property_tab_label().expect("the tab has no label");
[Switching to thread 4 (Thread 0x7fffefe91700 (LWP 10))](running)

Thread 1 "app-template" received signal SIGSEGV, Segmentation fault.
0x00007ffff70c3565 in __strlen_avx2 () from /usr/lib/x86_64-linux-gnu/libc.so.6
sdroege commented 3 years ago

And if you do bt at that point, i.e. where is strlen called from?

ricvelozo commented 3 years ago
> bt
#0  0x00007ffff70c3565 in __strlen_avx2 () at /usr/lib/x86_64-linux-gnu/libc.so.6
#1  0x00005555555b1db7 in glib::gstring::GString::new (ptr=0x0) at /home/ricardo/.cache/gnome-builder/projects/app-template-gtk-rs/builds/br.com.ricardoveloso.AppTemplate.json-flatpak-org.gnome.Platform-x86_64-40-master/.cargo/git/checkouts/gtk-rs-48ef14c1f17c79fb/d45a63e/glib/src/gstring.rs:46
#2  0x00005555555b228d in <glib::gstring::GString as glib::value::FromValueOptional>::from_value_optional (value=0x7fffffffbd48) at /home/ricardo/.cache/gnome-builder/projects/app-template-gtk-rs/builds/br.com.ricardoveloso.AppTemplate.json-flatpak-org.gnome.Platform-x86_64-40-master/.cargo/git/checkouts/gtk-rs-48ef14c1f17c79fb/d45a63e/glib/src/gstring.rs:501
#3  0x000055555559b331 in glib::value::Value::get (self=0x7fffffffbd48) at /home/ricardo/.cache/gnome-builder/projects/app-template-gtk-rs/builds/br.com.ricardoveloso.AppTemplate.json-flatpak-org.gnome.Platform-x86_64-40-master/.cargo/git/checkouts/gtk-rs-48ef14c1f17c79fb/d45a63e/glib/src/value.rs:197
#4  0x0000555555588c07 in gtk4::auto::notebook_page::NotebookPage::get_property_tab_label (self=0x7fffffffbe18) at /home/ricardo/.cache/gnome-builder/projects/app-template-gtk-rs/builds/br.com.ricardoveloso.AppTemplate.json-flatpak-org.gnome.Platform-x86_64-40-master/.cargo/git/checkouts/gtk4-rs-e74ad56283dfeb5e/13a8317/gtk4/src/auto/notebook_page.rs:215
#5  0x000055555557cc9e in <app_template::main_window::imp::MainWindow as glib::subclass::object::ObjectImpl>::constructed::{{closure}} (list_item=0x7fffffffbec0) at /home/ricardo/Projetos/app-template-gtk-rs/src/main_window.rs:115
#6  0x000055555557139c in gtk4::auto::signal_list_item_factory::SignalListItemFactory::connect_bind::bind_trampoline (this=0x7fffe8054240, listitem=0x5555558b3d60, f=0x1) at /home/ricardo/.cache/gnome-builder/projects/app-template-gtk-rs/builds/br.com.ricardoveloso.AppTemplate.json-flatpak-org.gnome.Platform-x86_64-40-master/.cargo/git/checkouts/gtk4-rs-e74ad56283dfeb5e/13a8317/gtk4/src/auto/signal_list_item_factory.rs:43
#7  0x00007ffff72c461e in g_cclosure_marshal_VOID__OBJECTv () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#8  0x00007ffff72c1179 in _g_closure_invoke_va () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#9  0x00007ffff72da7df in g_signal_emit_valist () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#10 0x00007ffff72da9c3 in g_signal_emit () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#11 0x00007ffff79f4918 in gtk_widget_root () at /usr/lib/x86_64-linux-gnu/libgtk-4.so.1
#12 0x00007ffff79f51b8 in gtk_widget_reposition_after () at /usr/lib/x86_64-linux-gnu/libgtk-4.so.1
#13 0x00007ffff78b6ba6 in gtk_list_item_manager_ensure_items () at /usr/lib/x86_64-linux-gnu/libgtk-4.so.1
#14 0x00007ffff78b7a54 in gtk_list_item_tracker_set_position () at /usr/lib/x86_64-linux-gnu/libgtk-4.so.1
#15 0x00007ffff78ac1c8 in gtk_list_base_set_anchor () at /usr/lib/x86_64-linux-gnu/libgtk-4.so.1
#16 0x00007ffff78ad3f5 in gtk_list_base_set_model () at /usr/lib/x86_64-linux-gnu/libgtk-4.so.1
#17 0x00007ffff78bf31b in gtk_list_view_set_model () at /usr/lib/x86_64-linux-gnu/libgtk-4.so.1
#18 0x00007ffff782d8d9 in gtk_drop_down_set_model () at /usr/lib/x86_64-linux-gnu/libgtk-4.so.1
#19 0x000055555556cfa9 in gtk4::auto::drop_down::DropDown::set_model (self=0x5555558281f8, model=...) at /home/ricardo/.cache/gnome-builder/projects/app-template-gtk-rs/builds/br.com.ricardoveloso.AppTemplate.json-flatpak-org.gnome.Platform-x86_64-40-master/.cargo/git/checkouts/gtk4-rs-e74ad56283dfeb5e/13a8317/gtk4/src/auto/drop_down.rs:112
#20 0x0000555555572328 in <app_template::main_window::imp::MainWindow as glib::subclass::object::ObjectImpl>::constructed (self=0x5555558281f0, obj=0x7fffffffc7a8) at /home/ricardo/Projetos/app-template-gtk-rs/src/main_window.rs:120
#21 0x0000555555575e76 in glib::subclass::object::constructed (obj=0x5555558284c0) at /home/ricardo/.cache/gnome-builder/projects/app-template-gtk-rs/builds/br.com.ricardoveloso.AppTemplate.json-flatpak-org.gnome.Platform-x86_64-40-master/.cargo/git/checkouts/gtk-rs-48ef14c1f17c79fb/d45a63e/glib/src/subclass/object.rs:109
#22 0x00007ffff72c6ba7 in g_object_new_internal () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#23 0x00007ffff72c83a9 in g_object_newv () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#24 0x00005555555b085b in glib::object::Object::new_internal (type_=..., params=...) at /home/ricardo/.cache/gnome-builder/projects/app-template-gtk-rs/builds/br.com.ricardoveloso.AppTemplate.json-flatpak-org.gnome.Platform-x86_64-40-master/.cargo/git/checkouts/gtk-rs-48ef14c1f17c79fb/d45a63e/glib/src/object.rs:1155
#25 0x00005555555af9fe in glib::object::Object::with_type (type_=..., properties=...) at /home/ricardo/.cache/gnome-builder/projects/app-template-gtk-rs/builds/br.com.ricardoveloso.AppTemplate.json-flatpak-org.gnome.Platform-x86_64-40-master/.cargo/git/checkouts/gtk-rs-48ef14c1f17c79fb/d45a63e/glib/src/object.rs:1095
#26 0x00005555555880c5 in glib::object::Object::new (properties=...) at /home/ricardo/.cache/gnome-builder/projects/app-template-gtk-rs/builds/br.com.ricardoveloso.AppTemplate.json-flatpak-org.gnome.Platform-x86_64-40-master/.cargo/git/checkouts/gtk-rs-48ef14c1f17c79fb/d45a63e/glib/src/object.rs:1064
#27 0x000055555558120c in app_template::main_window::MainWindow::new (app=0x7fffffffdc38) at /home/ricardo/Projetos/app-template-gtk-rs/src/main_window.rs:148
#28 0x000055555557f094 in app_template::main::{{closure}} (app=0x7fffffffdc38) at /home/ricardo/Projetos/app-template-gtk-rs/src/main.rs:47
#29 0x0000555555582ddc in <O as gio::auto::application::ApplicationExt>::connect_activate::activate_trampoline (this=0x55555575e230, f=0x1) at /home/ricardo/.cache/gnome-builder/projects/app-template-gtk-rs/builds/br.com.ricardoveloso.AppTemplate.json-flatpak-org.gnome.Platform-x86_64-40-master/.cargo/git/checkouts/gtk-rs-48ef14c1f17c79fb/d45a63e/gio/src/auto/application.rs:587
#30 0x00007ffff72c0f3f in g_closure_invoke () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#31 0x00007ffff72d3d4b in signal_emit_unlocked_R.isra.0 () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#32 0x00007ffff72da861 in g_signal_emit_valist () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#33 0x00007ffff72da9c3 in g_signal_emit () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#34 0x00007ffff73f4458 in g_application_real_local_command_line () at /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
#35 0x00007ffff73f45d6 in g_application_run () at /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
#36 0x0000555555581f23 in <O as gio::application::ApplicationExtManual>::run (self=0x7fffffffe298, argv=...) at /home/ricardo/.cache/gnome-builder/projects/app-template-gtk-rs/builds/br.com.ricardoveloso.AppTemplate.json-flatpak-org.gnome.Platform-x86_64-40-master/.cargo/git/checkouts/gtk-rs-48ef14c1f17c79fb/d45a63e/gio/src/application.rs:23
#37 0x0000555555575b53 in app_template::main () at /home/ricardo/Projetos/app-template-gtk-rs/src/main.rs:52
sdroege commented 3 years ago

Ok, fixing :) Thanks!

ricvelozo commented 3 years ago

Sorry for not being more direct, I have no experience with debuggers.

sdroege commented 3 years ago

No problem :) See https://github.com/gtk-rs/gtk-rs/pull/439 for the fix for this crash. It would just panic properly now on your expect().

ricvelozo commented 3 years ago

Thank you!