Skip to content

Compiler doesn't warn me that add_action_entries cannot be used with gtk::ApplicationWindow #1741

@jakobwerner

Description

@jakobwerner

I have a gtk-rs application with a widget called NewMeasurementWindow which extends the GtkWindow. It is defined as follows:

use gtk::CompositeTemplate;
use gtk::prelude::*;
use gtk::{gio, glib};

mod imp {
    use super::*;
    use glib::Properties;
    use gtk::{SpinButton, glib::subclass::InitializingObject, subclass::prelude::*};
    use std::cell::Cell;

    #[derive(Properties, CompositeTemplate, Debug, Default)]
    #[properties(wrapper_type = super::NewMeasurementWindow)]
    #[template(resource = "/org/codeberg/jdw/thermometer/new_measurement.ui")]
    pub struct NewMeasurementWindow {
        #[template_child]
        pub temperature_spinbutton: TemplateChild<SpinButton>,
        #[property(get, set)]
        temperature: Cell<f64>,
    }

    #[glib::object_subclass]
    impl ObjectSubclass for NewMeasurementWindow {
        const NAME: &'static str = "ThermometerNewMeasurementWindow";
        type Type = super::NewMeasurementWindow;
        type ParentType = gtk::Window;

        fn class_init(klass: &mut Self::Class) {
            klass.bind_template();
        }

        fn instance_init(obj: &InitializingObject<Self>) {
            obj.init_template();
        }
    }

    impl ObjectImpl for NewMeasurementWindow {
        fn constructed(&self) {
            self.parent_constructed();
            let obj = self.obj();
            obj.setup_actions();
        }
    }

    impl WidgetImpl for NewMeasurementWindow {}

    impl WindowImpl for NewMeasurementWindow {}
}

glib::wrapper! {
    pub struct NewMeasurementWindow(ObjectSubclass<imp::NewMeasurementWindow>)
        @extends gtk::Widget, gtk::Window, @implements gio::ActionGroup, gio::ActionMap;
}

impl NewMeasurementWindow {
    pub fn new<P: IsA<gtk::Window>>(_window: &P) -> Self {
        glib::Object::builder().build()
    }

    fn setup_actions(&self) {
        let action_save_measurement = gio::ActionEntry::builder("save_measurement")
            .activate(move |window: &Self, _, _| {
                window.save_measurement();
            })
            .build();

        self.add_action_entries([action_save_measurement]);
    }

    fn save_measurement(&self) {
        println!("Save measurement");
        self.close();
    }
}

The program compiles fine. When I open such a window, the program crashes with the following error:

thread 'main' panicked at /home/jdw/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/glib-0.20.10/src/object.rs:117:23:
assertion failed: self.is::<T>()
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

thread 'main' panicked at library/core/src/panicking.rs:218:5:
panic in a function that cannot unwind
stack backtrace:
   0:     0x5555555db030 - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h9edbd6e38a8b0805
   1:     0x5555555ee2a3 - core::fmt::write::h7b1248e5e0c79c78
   2:     0x5555555b2623 - std::io::Write::write_fmt::h5e301665499081bf
   3:     0x5555555daed3 - std::sys::backtrace::BacktraceLock::print::h4a386d2ef944f43e
   4:     0x5555555d744c - std::panicking::default_hook::{{closure}}::h61b7aa0fc15f236b
   5:     0x5555555d7359 - std::panicking::default_hook::h2d21379b0b23a14f
   6:     0x5555555d78bf - std::panicking::rust_panic_with_hook::h100726ba9570b85a
   7:     0x5555555db3c6 - std::panicking::begin_panic_handler::{{closure}}::h141712493bfacf0c
   8:     0x5555555db239 - std::sys::backtrace::__rust_end_short_backtrace::h891003731531c924
   9:     0x5555555d74ed - rust_begin_unwind
  10:     0x55555556541d - core::panicking::panic_nounwind_fmt::ha2f9a57c040716ff
  11:     0x5555555654b2 - core::panicking::panic_nounwind::h9817f69376d9bbc4
  12:     0x55555556564d - core::panicking::panic_cannot_unwind::h0197944997fd9fc5
  13:     0x555555587e1d - glib::subclass::object::constructed::h435ba5e3fcf32846
                               at /home/jdw/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/glib-0.20.10/src/subclass/object.rs:129:1
  14:     0x7ffff726b576 - g_object_new_internal.part.0
  15:     0x7ffff726d4cc - g_object_new_with_properties
  16:     0x55555559e8a4 - glib::object::Object::new_internal::h5834ae3452c2a787
                               at /home/jdw/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/glib-0.20.10/src/object.rs:1491:19
  17:     0x55555559df46 - glib::object::Object::with_mut_values::h9d80b804d9de2b5b
                               at /home/jdw/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/glib-0.20.10/src/object.rs:1426:18
  18:     0x5555555757a8 - glib::object::ObjectBuilder<O>::build::h391b30c2ead8b58e
                               at /home/jdw/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/glib-0.20.10/src/object.rs:1635:22
  19:     0x555555585176 - thermometer::new_measurement_window::NewMeasurementWindow::new::hc17d3baa6a13f63c
                               at /home/jdw/Projects/08-thermometer/src/new_measurement_window/mod.rs:57:9
  20:     0x55555557faae - thermometer::window::ThermometerWindow::open_new_measurement_window::h41f17b281e7ee39a
                               at /home/jdw/Projects/08-thermometer/src/window/mod.rs:73:38
  21:     0x555555582ca8 - thermometer::window::ThermometerWindow::setup_actions::{{closure}}::h18d6d219704337b2
                               at /home/jdw/Projects/08-thermometer/src/window/mod.rs:65:17
  22:     0x555555570c87 - <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call::hbcc9601763d57c84
                               at /build/rustc-1.86.0-src/library/alloc/src/boxed.rs:1990:9
  23:     0x55555557103c - gio::action_map::ActionMapExtManual::add_action_entries::{{closure}}::h286ef5017a5dd107
                               at /home/jdw/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gio-0.20.11/src/action_map.rs:28:25
  24:     0x555555566d27 - gio::auto::simple_action::SimpleAction::connect_activate::activate_trampoline::h8204a3fc70906102
                               at /home/jdw/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gio-0.20.11/src/auto/simple_action.rs:85:13
  25:     0x7ffff7264fb8 - g_closure_invoke
  26:     0x7ffff72799fb - signal_emit_unlocked_R.isra.0
  27:     0x7ffff727b469 - signal_emit_valist_unlocked
  28:     0x7ffff7281122 - g_signal_emit_valist
  29:     0x7ffff72811df - g_signal_emit
  30:     0x7ffff70ff5fd - g_simple_action_activate
  31:     0x7ffff72651f1 - _g_closure_invoke_va
  32:     0x7ffff727b5a1 - signal_emit_valist_unlocked
  33:     0x7ffff7281122 - g_signal_emit_valist
  34:     0x7ffff72811df - g_signal_emit
  35:     0x7ffff74ee1ba - _gtk_marshal_VOID__INT_DOUBLE_DOUBLEv
  36:     0x7ffff72651f1 - _g_closure_invoke_va
  37:     0x7ffff727b5a1 - signal_emit_valist_unlocked
  38:     0x7ffff7281122 - g_signal_emit_valist
  39:     0x7ffff72811df - g_signal_emit
  40:     0x7ffff75af196 - gtk_gesture_click_end
  41:     0x7ffff726854d - g_cclosure_marshal_VOID__BOXEDv
  42:     0x7ffff72651f1 - _g_closure_invoke_va
  43:     0x7ffff727b5a1 - signal_emit_valist_unlocked
  44:     0x7ffff7281122 - g_signal_emit_valist
  45:     0x7ffff72811df - g_signal_emit
  46:     0x7ffff75abf9b - _gtk_gesture_check_recognized
  47:     0x7ffff75ad81b - gtk_gesture_handle_event
  48:     0x7ffff75b0976 - gtk_gesture_single_handle_event
  49:     0x7ffff7579faa - gtk_event_controller_handle_event
  50:     0x7ffff76db37c - gtk_widget_run_controllers
  51:     0x7ffff76e2ebc - _gtk_widget_captured_event
  52:     0x7ffff75f2cae - gtk_propagate_event_internal
  53:     0x7ffff75f32c3 - gtk_main_do_event
  54:     0x7ffff788e49b - _gdk_marshal_BOOLEAN__POINTER
  55:     0x7ffff792a95f - gdk_surface_event_marshaller
  56:     0x7ffff7264fb8 - g_closure_invoke
  57:     0x7ffff72799fb - signal_emit_unlocked_R.isra.0
  58:     0x7ffff727ad49 - signal_emit_valist_unlocked
  59:     0x7ffff7281122 - g_signal_emit_valist
  60:     0x7ffff72811df - g_signal_emit
  61:     0x7ffff792eaa7 - gdk_surface_handle_event
  62:     0x7ffff78e1e0a - gdk_event_source_dispatch
  63:     0x7ffff6f0181e - g_main_context_dispatch_unlocked
  64:     0x7ffff6f03a90 - g_main_context_iterate_unlocked.isra.0
  65:     0x7ffff6f042bc - g_main_context_iteration
  66:     0x7ffff70f633d - g_application_run
  67:     0x555555583c2e - gio::application::ApplicationExtManual::run_with_args::h4b229f1ca06587a7
                               at /home/jdw/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gio-0.20.11/src/application.rs:29:13
  68:     0x555555583d19 - gio::application::ApplicationExtManual::run::h991efb1f83487616
                               at /home/jdw/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gio-0.20.11/src/application.rs:22:9
  69:     0x5555555782b4 - thermometer::main::h33bef075d2c667a0
                               at /home/jdw/Projects/08-thermometer/src/main.rs:25:5
  70:     0x55555558909b - core::ops::function::FnOnce::call_once::h2692111c27b9f077
                               at /build/rustc-1.86.0-src/library/core/src/ops/function.rs:250:5
  71:     0x55555558395e - std::sys::backtrace::__rust_begin_short_backtrace::h8ca9cc1803342457
                               at /build/rustc-1.86.0-src/library/std/src/sys/backtrace.rs:152:18
  72:     0x55555557f4a1 - std::rt::lang_start::{{closure}}::h0f630ed314038db9
                               at /build/rustc-1.86.0-src/library/std/src/rt.rs:199:18
  73:     0x5555555b9f15 - std::rt::lang_start_internal::he3cad277a2bdfe30
  74:     0x55555557f487 - std::rt::lang_start::h54bd1e1158cd6e48
                               at /build/rustc-1.86.0-src/library/std/src/rt.rs:198:5
  75:     0x55555557831e - main
  76:     0x7ffff6c2a47e - __libc_start_call_main
  77:     0x7ffff6c2a539 - __libc_start_main_impl
  78:     0x555555565b15 - _start
  79:                0x0 - <unknown>
thread caused non-unwinding panic. aborting.
zsh: IOT instruction (core dumped)  cargo run

I was told over on matrix, that this is because add_action_entries only works with GtkApplicationWindows and that my error occurs in this line:

glib::wrapper! {
    pub struct NewMeasurementWindow(ObjectSubclass<imp::NewMeasurementWindow>)
        @extends gtk::Widget, gtk::Window, @implements gio::ActionGroup, gio::ActionMap;
}

I'd like to request that the compiler warns me about the issue and doesn't compile.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions