[haiku-3rdparty-dev] Re: Dispatch messages

  • From: Philippe Houdoin <philippe.houdoin@xxxxxxxxx>
  • To: haiku-3rdparty-dev@xxxxxxxxxxxxx
  • Date: Thu, 17 Nov 2022 01:01:36 +0100

Now I’m able to dispatch asynchronously UpdateIfNeeded() but still my
underlying view (a BGLView) does not receive messages.
Same for the main window that remains locked even if the messages are
supposed to be sent to it (can’t be maximized nor quitted with the standard
title bar buttons).

Which is logical until this window is not anymore actionable, only
refreshable, as there is another window which get all the actionable
stuffs, your modal window.
I think what you needs is actually to not use B_MODAL_WINDOW but to follow
the same BAlert::Go() way to wait, from *your* main engine loop, that the
quasi-modal window; a non modal/blocking dialog window if you prefer, was
closed or cancelled by the user in order to continue.
You can use a semaphore that the "non blocking dialog" window will raise on
exit/close/cancel like in BAlert::Go(). The other(s) window(s) will keep
being activables  by the user, the user will be able to switch between them
and the non blocking dialog, as all these windows loopers lives actually in
their own threads.

Another way is to really switch fully to a message-driven design : set a
message to send on closure and let the dialog window show and lives. In
your main loop engine, continue as usual but on reception of this message,
you'll know that the dialog was closed. That the way the File panel in
Haiku works, it's fully asynchronous.

Philippe.


Le mer. 16 nov. 2022 à 13:28, Carlo Lanzotti <clanzotti@xxxxxxxxxxxxx> a
écrit :

Hi all,

I admit that I’m struggling trying to find a solution to this problem. Let
me expose the question in a different way:

I’ve a BWindow where I add a BGLview to it and just handle the Pulse
function. Inside the pulse function I do everything needed to allow my
system to loop and respond to events etc…

CustomBGLView::Pulse()
{
engine->Loop();
}

I also reimplemented MouseDown, MouseUp etc… to catch those events and
send it to my system queue that later will be processed in the above Loop()
function.

It can happen that inside the Loop function at some point I need to start
and infinite loop to lock a function and avoid it to return (mostly to call
the modal window I mentioned in the previous email), this is some sort o
pseudo code to make it simple:

Int do_modal()
{
int val = ...
// Some initialization etc…
...

while(running)
{
// Here is where I call the OS’s message loop so the OS can continue
capture messages and forward it to main window.
// This will allow the system to go back again to the engine->Loop()
function and everything will continue to work while still here
// waiting until running will be set to false.

// In Windows it is:
while(PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
    {
        if(GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

// In Linux it is:
while(XPending(disp) > 0)
{

}

// In macOS
NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil
inMode:NSDefaultRunLoopMode dequeue:YES];

[NSApp sendEvent:event];

     [[NSRunLoop currentRunLoop] runUntilDate:nil];

// And other similar mode in other OS


// Haiku?
}

return val;
}

As you can see I do not create any OS specific window/dialog in the
do_modal function (that’s why the BAlert solution it is not useful in my
case).

Actually I tried in so many ways and I tried to follow the Haiku source
code to see how app_server dispatch messages to a target, but still I’ve
not come to a solution yet.
I can of course change the way my system handle this scenario, but it will
require changing a lot of code base and, if possible, I want to avoid it.

So, is there a similar way to handle a situation like the one above?

Many thanks again for your time,

Carlo

Il giorno 14 nov 2022, alle ore 13:43, Carlo Lanzotti <
clanzotti@xxxxxxxxxxxxx> ha scritto:

Hi Zenja, Axel,

Thank you very much for your reply.

Tried the solution found in the BAlert:Go, but still something is not
going the way I expect. Now I’m able to dispatch asynchronously
UpdateIfNeeded() but still my underlying view (a BGLView) does not receive
messages. Same for the main window that remains locked even if the messages
are supposed to be sent to it (can’t be maximized nor quitted with the
standard title bar buttons).

Am I missing something else?

Regards,

Carlo

Il giorno 14 nov 2022, alle ore 08:08, Axel Dörfler <
axeld@xxxxxxxxxxxxxxxx> ha scritto:

Am 13.11.2022 um 22:56 schrieb Zenja Solaja:

I understand your issue, and wont bother discussing the merrits of
blocking. The easy way is to use the B_MODAL_WINDOW creation flag. See
BAlert source as an example.


That's indeed a good example; BAlert::Go() does pretty much what you want.
It waits for the window to close without suppressing window messages.

If you look at the implementation of BWindow::UpdateIfNeeded(), it looks
pretty similar to the sample code you provided.

Bye,
 Axel.








Other related posts: