What I’d like is to be able to nest modal windows:
auto A = new BWindow(…) // Main app window
auto B = new BWindow(…) // First dialog
auto C = new BWindow(…) // Second dialog
But in this case, C doesn’t appear when I call Show. Am I not understanding how it should work? My code is expecting that each dialog blocks the previous windows until it’s closed. It’s not the “Haiku” way of doing things but it’d be helpful to have until I can make the underlying code more Haiku friendly. The use case I’m looking at the moment is in i.Disk where the main window is “A” and “B” is the replication dialog which asks the user for various source and destination folders. Which then spawns “C” a folder selection dialog. If I remove all the SetFeel/AddToSubset calls the dialogs all show up.
I got the same problem with Wayland implementation (GitHub - X547/wayland-server: In-proc Wayland server for Haiku). Nested subsets are not supported yet by Haiku.
We have the same problem in Emacs, which is currently being worked around by keeping all child frames (windows) subset to the toplevel parent.
I’m looking into my own work around(s). By not using AddToSubset and then catching all the mouse / key events in the parent windows and just toss them.
But more importantly I need to keep the z-order of the windows consistent. And I don’t know how to do that just yet. Is there a way to make sure the parent <-> child zorder is maintained?
Enhancement ticket should be filled here I think: https://dev.haiku-os.org/.
I tried to search, but can find only this relevant ticket about different window subset problem: #18273 (Bring app to the top of the z-order when user clicks on any of it's windows.) – Haiku.
Desired behavior should be keeping all subset stack windows z-order sorted.
Z-order sorting logic according to subset hierarchy should be implemented in app_server (currently isn’t).
But I’m not using AddToSubset anymore due to the buggy behaviour. Is there a way to manage zorder without AddToSubset? Like catching a “raise window to the top” event in the message handler and turning it into a no-op?
BWindow::SendBehind can be used to maintain Z-order.
B_WILL_ACCEPT_FIRST_CLICK window flag can be used to avoid sending window to front on content click.
I’ve kinda fixed this in a janky sort of way. Firstly my windows all know what their parent and child relationship is via a doubly linked list. And then they override BWindow::WindowActivated(focus) to catch activate events, where they enforce the z-order with BWindow::SendBehind up and down the list. The mouse and key event code also checks for no child modal window before processing the event. Otherwise it just bins the event. It does flicker a tiny bit when you click off the dialog. But you can move the parent windows around even if you can’t click on them. I may add some more colour coding (grey out elements in the parent window) over time. But for the moment… I think I’m good.