Synchronized movement of CallOutBox


Juce 1.53, running a plugin within JUCE plugin host.

When I launch a CallOutBox with enterModalState in OSX, the title bar of the plugin window is grabbable and allows the plugin window to be moved during the time that the CallOutBox is visible. The CallOutBox does not mimic this movement, though. This means that the CallOutBox is no longer positioned correctly against the rest of the GUI. Is there a way to synchronize the movement of the CallOutBox to match that of the window with the target?

The only kludge I’ve been able to come up with is to have a timer callback which checks the position of the parent window’s componentpeer and then reposition the calloutbox if the parent window has moved. This involved making a custom version of calloutbox, so that I could simply change the targetPoint position without doing a full call to updatePosition() (which looks to do a new layout of the calloutbox from scratch, not guaranteeing that the arrow will come off the calloutbox at the same point as the original layout).

Does a better solution exist?


Callout boxes aren’t really designed to hang around, the idea is more that they’re modal/temporary, so I wouldn’t really have thought this matters too much. TBH I doubt if even OS-native callouts or menus would follow their window around like that.


This non-synchronized movement seems to apply to all components launched by enterModalState (popup menus, calloutboxes, dialogs, alerts) … having some/many of those lose positioning seems like it could be quite confusing/misleading to a user (popups especially)

As simply the first one I tested, in OSX, if you open TextEdit, and then get the save dialog to open up … if you then move the underlying window via titlebar dragging, then the save dialog moves along with the movements of the underlying window …

Yeah, but that’s a bad example, because file-selection dialog sheets in OSX are the only ones I can think of that work like that. Almost all other kinds of pop-ups in OSX and pretty much every floating dialog in Linux/Windows don’t follow their parents around.

I presume the following are also bad examples for some reason … smile:

Safari->recent-search popup menu opened by black triangle near magnifying glass in upper right corner of browser

Safari->View->"Customize Toolbar…" dialog

I also don’t think I’d particularly care if every O/S and every app behaved exactly the same … it seems like a very bad user experience to be able to minimize/destroy/move your app and be left staring at some number of floating popup menus, calloutboxes, dialogs, etc. … especially when many of those (callouts, popups) cannot be canceled without the rest of the application (i.e. you have to click on the application, but not on the popup/callout, to cancel the popup/callout), and most of those items won’t inherently indicate to which application they belong.

In full disclosure, the 4th scenario I tested, the “Find” window in TextEdit, does not follow any editor window, but I suspect that is because a single “Find” window applies to all open editor windows (it searches the currently selected window, which can be switched without dismissing the Find window itself).

No, those are the same example! They’re all OSX ‘sheets’, exactly like the file dialog. I thought you were talking about callout boxes, which I take to mean the pointy pop-up windows, a bit like a speech bubble…

Apologies for any/all confusion/ignorance on my part (I have no idea what a ‘sheet’ is) …

I’m talking about anything that I’ve launched using enterModalState (callout boxes, popup menus, alerts, dialogs) … callout boxes were simply meant as one concrete example of the problem (a bit messier perhaps than the others because of the localization of the callout arrow). If I launch any of those items via enterModalState, and then interact with the titlebar in OSX (which you’ve indicated can’t be prevented), then none of those items react appropriately (for lack of a better word) … like I’ve said, I have a timer kludge in place which looks to see if any modal windows are open and then repositions them according to perceived movements in the parent window (or minimizes them, or destroys them) … just was hoping there was a better solution. The timer seems to be working passably …


?? That’s just not true. When you move a window, any modal comps are dismissed. E.g. in the juce demo, open a menu or something, and drag the window - it gets dismissed.

I don’t know if there is any behavior distinction between an app environment (juce demo) and a plugin environment (my situation)?

In the juce demo, a popup menu disappears when the titlebar of the main window is clicked (which removes the need to deal with titlebar actions) … this is not so for my plugin running in the juce host app: clicking on the titlebar of the plugin does not dismiss the popup menu … and I am allowed to access all titlebar functionality.

Also dialogs and alerts behave more as expected in the demo relative to the titlebar (you can’t access/grab the titlebar until the dialogs have been dismissed). The demo callout box seems to largely behave the same (as expected) relative to the titlebar.

CallOut boxes:
demo launches with runModalLoop()
my plugin launches with enterModalState() (as per your caveats elsewhere in the forum about running anything modally in a plugin)

demo and plugin both launched with showMenuAsync

demo and plugin both launched with showMessageBoxAsync

plugin launched via enterModalState () (as per your caveats elsewhere in the forum about running anything modally in a plugin)

Perhaps/hopefully you can provide some insights into these differences?

Ah, sorry - it’s different for plugins. The window belongs to the host, we have no way of tracking any events that happen outside the plugin’s own area. I’d really recommend keeping everything inside your plugin window if possible, and avoiding popping out external windows, as you never know how it’ll interact with all the different hosts.

Ok … thanks.

Do people just not use FileChoosers and PopupMenus (run non-modally) in plugins? Or do they accept these quirks?

Thanks again.