Git Product home page Git Product logo

Comments (14)

antoyo avatar antoyo commented on August 16, 2024 1

I'm now getting segfaults on basic relm examples.
The segfault seems related to GSource stuff, so it might be related to your issues.

Still not sure what is going on…

from relm.

antoyo avatar antoyo commented on August 16, 2024

I'm not exactly sure how to fix that particular issue, but the following would work.
Replace parameters by two vectors:

    for (key, value) in gtk_widget.construct_properties.iter() {
        let key = key.to_string().replace("_", "-");
        let mut remover = Transformer::new(MODEL_IDENT);
        let value = remover.fold_expr(value.clone());
        keys.push(Ident::new(&key, struct_name.span()));
        values.push(quote_spanned! { struct_name.span() =>
            &#value as &dyn ::gtk::glib::value::ToValue
        });
    }

and use them as such instead of using a for loop:

            let mut obj_builder = glib::Object::builder::<#struct_name>();
            #(obj_builder = obj_builder.property(#keys, &#values as &dyn ::gtk::glib::value::ToValue);)*
            obj_builder.build()

By the way, when I wrote that TODO, I was referring to specific widget's builders like ButtonBuilder.
The idea was that this would check that the property exists at compile-time, which doesn't happen when using Object as the properties are string.
But your method works as well.

from relm.

emmanueltouzery avatar emmanueltouzery commented on August 16, 2024

thank you. that took me a little further, sadly I now hit another proc-macro related issue... :(

   |
56 | #[widget]
   | ^^^^^^^^^
   |
   = help: message: `"has-entry"` is not a valid identifier

For now i couldn't track down where that identifier is being declared...

from relm.

antoyo avatar antoyo commented on August 16, 2024

Sorry, there was a mistake in the code above. That's probably this issue.
Here's the new version:

    for (key, value) in gtk_widget.construct_properties.iter() {
        let key = key.to_string().replace("_", "-");
        let mut remover = Transformer::new(MODEL_IDENT);
        let value = remover.fold_expr(value.clone());
        keys.push(key);
        values.push(quote_spanned! { struct_name.span() =>
            &#value as &dyn ::gtk::glib::value::ToValue
        });
    }

from relm.

emmanueltouzery avatar emmanueltouzery commented on August 16, 2024

thank you! that was it, yes...

so now my app builds and starts against gtkrs 0.17.. and sadly the original issue that I was trying to fix is still present. So it was not about the slightly older gtkrs...

Here's the error that I'm getting at startup:

(projectpad:40642): GLib-CRITICAL **: 14:26:53.441: g_source_attach: assertion 'source->context == NULL' failed
thread 'main' panicked at 'assertion failed: `(left != right)`
  left: `0`,
 right: `0`', /home/emmanuel/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.17.9/src/source.rs:50:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

and with the backtrace:


(projectpad:41508): GLib-CRITICAL **: 14:28:24.202: g_source_attach: assertion 'source->context == NULL' failed
thread 'main' panicked at 'assertion failed: `(left != right)`
  left: `0`,
 right: `0`', /home/emmanuel/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.17.9/src/source.rs:50:9
stack backtrace:
   0: rust_begin_unwind
             at /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/std/src/panicking.rs:575:5
   1: core::panicking::panic_fmt
             at /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/core/src/panicking.rs:64:14
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed
             at /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/core/src/panicking.rs:212:5
   4: <glib::source::SourceId as glib::translate::FromGlib<u32>>::from_glib
             at /home/emmanuel/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.17.9/src/source.rs:50:9
   5: glib::translate::from_glib
             at /home/emmanuel/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.17.9/src/translate.rs:1414:5
   6: glib::source::<impl glib::auto::source::Source>::attach
             at /home/emmanuel/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.17.9/src/source.rs:1082:13
   7: relm::core::Channel<MSG>::new
             at /home/emmanuel/.cargo/git/checkouts/relm-8ad96e43440f833f/6603842/src/core/mod.rs:179:9
   8: <projectpad::widgets::project_list::ProjectList as relm::state::Update>::model
             at ./projectpad/src/widgets/project_list.rs:50:33
   9: relm::create_widget
             at /home/emmanuel/.cargo/git/checkouts/relm-8ad96e43440f833f/6603842/src/lib.rs:204:17
  10: <W as relm::container::ContainerWidget>::add_widget
             at /home/emmanuel/.cargo/git/checkouts/relm-8ad96e43440f833f/6603842/src/container.rs:172:47
  11: <projectpad::widgets::win::Win as relm::widget::Widget>::view
             at ./projectpad/src/widgets/win.rs:747:32
  12: relm::create_widget
             at /home/emmanuel/.cargo/git/checkouts/relm-8ad96e43440f833f/6603842/src/lib.rs:205:22
  13: relm::init
             at /home/emmanuel/.cargo/git/checkouts/relm-8ad96e43440f833f/6603842/src/lib.rs:288:37
  14: relm::run
             at /home/emmanuel/.cargo/git/checkouts/relm-8ad96e43440f833f/6603842/src/lib.rs:348:22
  15: relm::widget::Widget::run
             at /home/emmanuel/.cargo/git/checkouts/relm-8ad96e43440f833f/6603842/src/widget.rs:66:9
  16: projectpad::main
             at ./projectpad/src/main.rs:53:5
  17: core::ops::function::FnOnce::call_once
             at /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

The line at my main.rs:53 is the initialization of the first widget:

    widgets::win::Win::run((sql_channel, !db_preexisted)).unwrap();

Last line of my main.rs.

So that worked fine on fedora 37 and is now blowing up on fedora 38. And my app still works in flatpak, since the flatpak ships the runtime/libraries together with the app. I'm guessing something changed in glib::Source recently...

from relm.

antoyo avatar antoyo commented on August 16, 2024

This assert comes from the glib C library:

(projectpad:41508): GLib-CRITICAL **: 14:28:24.202: g_source_attach: assertion 'source->context == NULL' failed

That seems to be this line.
Which we call from here.
I have a feeling that we should set a context in the source created here.
You could try setting the source context to the main context.

from relm.

emmanueltouzery avatar emmanueltouzery commented on August 16, 2024

for now I tried this:

        let mut funcs = Box::new(funcs);
        let source = g_source_new(&mut *funcs, mem::size_of::<SourceData<T>>() as u32);
+       let context: *mut GMainContext = glib::MainContext::default().to_glib_none().0;
+       g_source_attach(source, context);
        ptr::write(&mut (*(source as *mut SourceData<T>)).data, data);
        ptr::write(&mut (*(source as *mut SourceData<T>)).funcs, funcs);
        from_glib_full(source)

But that didn't help.

from relm.

emmanueltouzery avatar emmanueltouzery commented on August 16, 2024

I do see in the apidocs:
https://docs.gtk.org/glib/ctor.Source.new.html

The source will not initially be associated with any GMainContext and must be added to one with g_source_attach() before it will be executed.

However the apidocs also say:
https://docs.gtk.org/glib/method.Source.attach.html

A GMainContext (if NULL, the global-default main context will be used)
The argument can be NULL.

So I tried with NULL too, but that didn't help:

        g_source_attach(source, 0 as *mut GMainContext);

from relm.

antoyo avatar antoyo commented on August 16, 2024

I think the assert is actually the opposite of what I thought.
It looks like we try to attach a context multiple times on the source.
You could try removing that line.
If that doesn't work, you'll need to check if we add it at other places.

from relm.

emmanueltouzery avatar emmanueltouzery commented on August 16, 2024

the current status is that something else breaks if i just comment that line, which led me to think that it's at least sometimes needed. So I did that:

        let main_context = MainContext::default();
        if unsafe {glib_sys::g_source_get_context(source.as_ptr()) == std::ptr::null_mut()} {
            eprintln!("adding src context");
            source.attach(Some(&main_context));
        } else {
            eprintln!("NOT adding src context");
        }

and I got that output:

adding src context
adding src context
adding src context
adding src context
NOT adding src context
adding src context
adding src context
adding src context
NOT adding src context
adding src context
adding src context
adding src context
adding src context

(projectpad:164851): GLib-CRITICAL **: 19:34:10.460: source_remove_from_context: assertion 'source_list != NULL' failed

(projectpad:164851): GLib-CRITICAL **: 19:34:10.460: g_hash_table_remove_internal: assertion 'hash_table != NULL' failed
[1]    164851 segmentation fault (core dumped)  cargo run --bin projectpad

now the app actually starts, but it crashes when exiting.

from relm.

antoyo avatar antoyo commented on August 16, 2024

At that point, I'm not sure.

It looks like the GSource is not initialized correctly, somehow.

If you cannot figure out why it goes in the else, I suggest you ask people that knows the GLib C library.

from relm.

emmanueltouzery avatar emmanueltouzery commented on August 16, 2024

unfortunately, to be completely honest, at this point it's probably more likely that i'll attempt to port my application to relm4/gtk4 :(

from relm.

antoyo avatar antoyo commented on August 16, 2024

I found the problem. This struct needed a #[repr(C)].
I released a new version with it; you can try rebasing on it to see if this fixes your problem.

You should not need the conditional stuff of the last comments.

from relm.

antoyo avatar antoyo commented on August 16, 2024

Closing. Please reopen if you still have an issue.

from relm.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.