Bug: Component::contains() fails when dragging from ListBox

As per subject, it happens in AU plug-ins hosted in Logic on M1 chips.

I suspect the same happens also in other Apple hosts.
The problem doesn’t happen in Standalone on same architecture, and neither in AU on Intel machines.

I have attached code to reproduce the issue: simply generate the Basic plug-in with Projucer then replace the source files with those in the attached ZIP (only the Editor is meaningful actually, I haven’t touched the processor)

As you can see in the screenshots, when dragging an item from the list on the white component, Component::contains() returns “true” when in Standalone, but “false” if it’s the AU plug-in in Logic.

standalone
au-logic

Also not sure if it’s related, but when I’m dragging a row in the AU, the dragged image has a reddish tint overlapped to it, that shouldn’t be there (the one in the standalone is the expected look of it)

Source.zip (6.5 KB)

Gentle request for attention?

The red tint issue is to do with the display of bridged views in plugins hosted out-of-process. The issue is on Apple’s side. I investigated this late last year: BUG? Popup Menu Background and Logic Silicon

I’m not able to test the drag and drop issue right now, but I suspect the observed behaviour is also due to the out-of-process bridging. Perhaps the additional window which shows the selected item is consuming mouse drag events. Could you try changing the true to false at juce_ListBox.cpp:128 and checking whether this allows the drag to succeed?

bumping this – I can help do some debugging if needed -very important feature to my app. Here is my experience:

I have a TableListBox that I want to be able to drag rows to/from other parts of the gui, but when the drag exits the plugin gui, I want it to turn into a file drag external to the app. The issue that is occurring in logic is that as soon as the drag begins (while the mouse is still in the TableListBox), the shouldDropFilesWhenDraggedExternally() method is called in my top level plugin editor class that I have inheriting from DragAndDropContainer. This causes the drag to instantly turn into an external file drag when it’s supposed to be internal at this time (until the mouse leaves the gui ofc). It appears that the component hit test that juce uses internally to check if the drag is internal to the plugin gui is broken when used in logic. I am using an M1 machine so the plugin is being run out of process if that helps!

Finally got round to taking a look at this. I think that the problem stems from isWindowAtPoint in the NSViewComponentPeer. This function calls through to windowNumberAtPoint:belowWindowWithWindowNumber:, which is supposed to return the topmost window that would receive a mouse-down at a given screen position. The docs for this function say:

Because this method uses the same rules as mouse-down hit-testing, windows with transparency at the given point, and windows that ignore mouse events, will not be returned.

But this doesn’t seem to be true in AUs hosted in Logic on Arm. If I add some code like this into isWindowAtPoint, I see that it sometimes returns a window that ignores mouse events (the drag-image window), even though it’s not supposed to!

const auto windowAtPoint = [NSWindow windowNumberAtPoint: screenPoint belowWindowWithWindowNumber: windowToCheck];
auto* mouseWindow = [NSApp windowWithWindowNumber: windowAtPoint];
const auto ignoresEvents = [mouseWindow ignoresMouseEvents];

I tried to continue searching ‘below’ our drag-image window to see whether we eventually reach the main plugin window, but unfortunately we hit another window first. At the moment, I can’t think of a way of determining whether this inserted window is a ‘fake’ window inserted by the out-of-process hosting layer, or a real window that should block the mouse.

To sum up, I think this is another instance of the out-of-process hosting in macOS behaving in an unexpected way. Apple hints at this on their page about debugging AUs.

If custom, free-floating dialogs don’t work as you expect, add them as a subwindow to the main window — this includes custom tooltip and drop-down menu implementations.

Although not satisfying, this is probably the most robust solution. I’ll look at adding an option to the ListBox to disable dragging to external components.

1 Like

This change adds an option to the ListBoxModel to disallow dragging to external windows, which should improve UX in AudioUnits as long as the drag is limited to the plugin editor:

Hey, I’ve run into the same issue in Logic on M2. But checking if the mouse position is within a given component seems to be working if I check if the component bounds contain the mouse position. So simply checking if the point is in the rectangle.
myComponent.getLocalBounds().contains(event.getPosition())
Is anything wrong with this simple approach?

1 Like