What was happening here is that because we were detecting window clicks
inside _input, when you clicked overlapping windows, all of them would
receive the click, and all of them would set themselves to active and
move to the foreground. The solution to this was to move the
click-detection into _gui_input instead, which stops the event from
traveling to the back elements. There is, however, a gotcha. Because
_gui_input only fires on the topmost element clicked, the window itself
doesn't receive the event because its children are covering it up and
receive the event instead. To work around this I iterated all the
children of the window, connecting to and forwarding their _gui_input
events to the window root. Thus, buttons still work when you click on
them, but the window also gets to respond as it needs to.
Before this, maximizing a window functioned by reparenting it to a
margincontainer. Now, maximizing a window is a matter of setting its
anchors and offsets. It will require more code but the reparenting
strategy was causing problems because maximized windows were always
displayed below windowed ones. This could technically be solved by
modifying z-indexes of windows individually but this seems like a less
annoying solution than that in the long run.
When I added the "Windows" node to contain all the windows, it started
blocking the inputs to the game window because it covers the entire
window and its mouse_filter was set to block.
Before this, if the headers of two windows overlapped and you clicked
and dragged in that overlap, both windows would move at the same time.
After this, only the front window gets dragged. The way that this works
is that we use _gui_input instead of _input. This works because
_gui_input is only sent to the top-level control.
The Inventory window was created directly in the desktop scene but it
needs to be a template we can instantiate so I've moved it into its own
PackedScene.