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.