gtk-rs / gtk4-rs

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

Application subclass does not initialize GTK #118

Closed malmz closed 3 years ago

malmz commented 3 years ago

Subclassing GtkApplication and leaving all implementations blank does not call gtk::init(). Docs for GtkApplication says it should be called in parent_startup().

Interestingly, widgets created through a template work without GTK being initialized

sdroege commented 3 years ago

Can you provide a testcase to reproduce the problem you see?

malmz commented 3 years ago
use gio::prelude::*;
use glib::subclass::prelude::*;
use glib::{glib_object_subclass, glib_wrapper};

mod imp {
    use super::*;
    use glib::subclass;
    use gtk::subclass::prelude::*;

    #[derive(Debug)]
    pub struct TestApp {}

    impl ObjectSubclass for TestApp {
        const NAME: &'static str = "TestApp";
        type Type = super::TestApp;
        type ParentType = gtk::Application;
        type Instance = subclass::simple::InstanceStruct<Self>;
        type Class = subclass::simple::ClassStruct<Self>;

        glib_object_subclass!();

        fn new() -> Self {
            Self {}
        }
    }

    impl ObjectImpl for TestApp {}
    impl ApplicationImpl for TestApp {}
    impl GtkApplicationImpl for TestApp {}
}

glib_wrapper! {
    pub struct TestApp(ObjectSubclass<imp::TestApp>)
        @extends gio::Application, gtk::Application;
}

impl TestApp {
    pub fn new() -> Self {
        glib::Object::new(
            Self::static_type(),
            &[
                ("application-id", &"org.malmz.Test"),
                ("flags", &gio::ApplicationFlags::empty()),
            ],
        )
        .expect("Failed to create TestApp")
        .downcast()
        .expect("Created TestApp is of wrong type")
    }
}

fn main() {
    let app = TestApp::new();
    app.connect_activate(|app| {
        dbg!(gtk::is_initialized());
        let window = gtk::ApplicationWindow::new(app);
        let label = gtk::Label::new(Some("Hello"));
        window.set_child(Some(&label));
        window.show();
    });
    std::process::exit(app.run(&std::env::args().collect::<Vec<_>>()));
}

This prints: "gtk::is_initialized() = false" and then crashes trying to create the label

sdroege commented 3 years ago

Apparently this commit was not backported to gtk4: https://github.com/gtk-rs/gtk-rs/commit/25ef6eebce35077c0e2c1e37359b47bd9b19e7a6

@bilelmoussaoui ?

malmz commented 3 years ago

The example above now panics in rt.rs thread 'main' panicked at 'GTK was not actually initialized', /home/malmz/.cargo/git/checkouts/gtk4-rs-e74ad56283dfeb5e/e643e46/gtk4/src/rt.rs:79:9

sdroege commented 3 years ago

That's curious because it's not actually GTK saying it's not initialized (gtk_is_initialized() returns false).

Can you put the full backtrace of the panic here? There's probably a check on the bindings side that happens too early here but not in GTK3.

malmz commented 3 years ago
thread 'main' panicked at 'GTK was not actually initialized', /home/malmz/.cargo/git/checkouts/gtk4-rs-e74ad56283dfeb5e/e643e46/gtk4/src/rt.rs:79:9
stack backtrace:
   0: std::panicking::begin_panic
             at /home/malmz/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:505
   1: gtk4::rt::set_initialized
             at /home/malmz/.cargo/git/checkouts/gtk4-rs-e74ad56283dfeb5e/e643e46/gtk4/src/rt.rs:79
   2: gtk4::subclass::application::application_startup
             at /home/malmz/.cargo/git/checkouts/gtk4-rs-e74ad56283dfeb5e/e643e46/gtk4/src/subclass/application.rs:79
   3: g_signal_emit_valist
   4: g_signal_emit
   5: g_application_register
   6: <unknown>
   7: <T as gio::subclass::application::ApplicationImplExt>::parent_local_command_line
             at /home/malmz/.cargo/git/checkouts/gtk-rs-48ef14c1f17c79fb/f316f40/gio/src/subclass/application.rs:234
   8: gio::subclass::application::ApplicationImpl::local_command_line
             at /home/malmz/.cargo/git/checkouts/gtk-rs-48ef14c1f17c79fb/f316f40/gio/src/subclass/application.rs:101
   9: gio::subclass::application::application_local_command_line
             at /home/malmz/.cargo/git/checkouts/gtk-rs-48ef14c1f17c79fb/f316f40/gio/src/subclass/application.rs:413
  10: g_application_run
  11: <O as gio::application::ApplicationExtManual>::run
             at /home/malmz/.cargo/git/checkouts/gtk-rs-48ef14c1f17c79fb/f316f40/gio/src/application.rs:20
  12: apptest::main
             at ./src/bin/apptest.rs:63
  13: core::ops::function::FnOnce::call_once
             at /home/malmz/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:227
sdroege commented 3 years ago

Ok, this needs some more investigation by someone actually working on the GTK4 bindings then :) @bilelmoussaoui @BrainBlasted

I assume the problem here is that GTK is not actually initialized at this point yet.