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

  • From: Carlo Lanzotti <clanzotti@xxxxxxxxxxxxx>
  • To: haiku-3rdparty-dev@xxxxxxxxxxxxx
  • Date: Thu, 17 Nov 2022 11:11:21 +0100

Hi Philippe,

That’s exactly what I did. I didn’t used B_MODAL_WINDOW but I added the Go 
(modified) code in my ‘loop lock’ function (I’ve only one window and a child 
view). Unfortunately my application still get locked and no messages are 
forwarded to the main window nor to the view. Maybe I missing something.

The fact is that the modal dialog are part of my system, so no haiku 
dialog/window are created, I only need to allow the main window (and the view) 
to continue receiving messages from the OS. That’s what the other OS do by 
calling their functions as I mentioned (sort of pseudo code and what I'm trying 
to achieve):

Int do_modal()
{
        // Local loop here
        while(running)
        {
                if(getMouseEvent())
                {
                        forwardMouseEvent();
                }

                if(getKeyEvent())
                {
                        forwardKeyEvent();
                }

                …

                engine->loop();
        }
}

Thanks for your reply,

Carlo

Il giorno 17 nov 2022, alle ore 01:01, Philippe Houdoin 
<philippe.houdoin@xxxxxxxxx> ha scritto:

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 
<mailto: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 <mailto: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 
<mailto: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: