idanarye / woab

Widgets on Actors Bridge - a GUI microframework for combining GTK with Actix
https://crates.io/crates/woab
MIT License
14 stars 1 forks source link

Make dialogs work #30

Closed idanarye closed 3 years ago

idanarye commented 3 years ago

(continuing discussion on #28)

When you open a dialog, GTK will call the on-idle events one more time - and then it won't call them again until the dialog is resolved. That one time is enough to be a problem, since it'll try to crank the Actix loop while triggered. But since it only gets called once - all Actix futures that are not GTK signal handling will be halted.

To make things worse - this does not change the gtk::main_level(), so I can't even detect it...

piegamesde commented 3 years ago

Do modal vs non-modal dialogues make a difference on this?

idanarye commented 3 years ago

This does not seem to be about modality - it seems to be about running it with dialog.run(). If I start the dialog manually with show everything is fine whether I set it to modal or non-modal.

I think the solution will have to be a new function - woab::run_dialog - which will be usable from ctx.spawn() futures:

let dialog = somehow_get_the_dialog();
ctx.spawn(async move {
    woab::run_dialog(&dialog).await
}.into_actor(self).map(|response, actor, _ctx| {
    actor.deal_with_dialog_response(response);
}))

At any rate - I've added an example with some hack that keeps cranking the Actix loop while the dialog is running with run(). But I think the actual implementation of woab::run_dialog should instead use woab::wake_from_outside from #29 - something like:

async fn run_dialog(dialog: gtk::Dialog) -> gtk::ResponseType {
    woab::wake_from_outside(|waker| {
        dialog.set_modal(true);
        dialog.connect_response(|_, response| {
            // Somehow pass `response` to be returned from `run_dialog`. Haven't decided how to do it yet.
            waker.wake_by_ref();
        });
        dialog.show();
    }).await;
}