My current project has a requirement where a sidebar window needs to be dockable to the right edge of the main app’s window. The client doesn’t want that content inside the main app window. It needs its own title bar and the user should be able to peel it away to a different location, then have it snap back into its docked position when the edges get close together again.
The issue I’m having is that the two windows need to track together in synchrony. The obvious solution (override
ResizableWindow::moved() in the main app window and change the other window’s top left position to the correct spot) works, but it works badly –
moved() is only being called every few hundred ms or so when the main window is being moved around.
auto bounds = this->getBounds();
if (otherWindow && otherWindow->isDocked())
otherWindow->setTopLeftPosition(bounds.getX() + bounds.getWidth(), bounds.getY());
Is there a more responsive approach I could be taking here, but am just not seeing?
It’s probably tidier to have them both become part of the same window when they are docked. That’s the way I’ve seen in done in other apps. If the title bar constraint from the client can be bent a little it’s probably the way to do it…
I guess you could try putting a fast timer on there though as a quick fix and see if that lets you pick up new positions quicker…
Yeah, running a timer is probably the next step to take.
I did it with the single window solution, you could have a look at how this works:
Excellent, thanks – I’ll check it out.
Interesting: putting the code above into a timer callback (with an additional check to make sure that the bounds of the main window have changed since the last callback) behaves identically to the original approach of overriding
::moved() – the bounds of the window aren’t being updated continuously as the window is dragged around.
Well, if you’re not using the system title bar maybe you can hook into the actual mouse drag and do it that way …
Right, my next thought was to point a MouseListener at the main window.