# \[OSX\] Resizing issue with addToDesktop() and attachToNativeWindow

**URL:** <https://forum.juce.com/t/osx-resizing-issue-with-addtodesktop-and-attachtonativewindow/33374>\
**Category:** MacOSX and iOS\
**Created:** [May 14, 2019, 8:27am UTC](https://forum.juce.com/t/osx-resizing-issue-with-addtodesktop-and-attachtonativewindow/33374 "2019-05-14T08:27:41Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![sebk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/sebk/32/6425_2.png) [@sebk](https://forum.juce.com/u/sebk)\
**Post date:** [May 14, 2019, 8:27am UTC](https://forum.juce.com/t/osx-resizing-issue-with-addtodesktop-and-attachtonativewindow/33374/1 "2019-05-14T08:27:41Z")

</div>

Hi,

on OSX we encounter a strange resizing issue with a component attached to a native window. We use this method to host a plugin UI in another surrounding JUCE plugin UI. There is a `AudioProcessorEditor` component and a child component is attached to the top-level component using `addToDesktop(0, getTopLevelComponent()->getWindowHandle())`. Full code can be seen below.

When the top-level component is resized (using the +/- buttons), the attached component should follow but the attached component’s y-position is incorrect afterwards. This is due to the fact that JUCE internally needs to invert the coordinate system at `juce_mac_NSViewComponentPeer.mm, NSViewComponentPeer::setBounds(), l.285`. The transform relies on the dimensions of the superview but this has not yet been set at this point. Hence, the resulting coordinates refer to the old parent window size.

I tried to find a fix like inverting the order of resize callbacks that are triggered in JUCE but did not succeed. My second try was to manually force a complete resize of the window hierachy with the `Resize` button as a workaround. But the resizes bail out as the sizes in JUCE are the same.

So my question would be if you see a potential easy fix in JUCE or if there is a good workaround to make this work in my code? Or maybe I am wrong with my understanding how this should work?

Thanks,  
Sebastian

**Example Code**

```
class NativeComponent : public Component
{
public:
    
    void paint (Graphics& g)
    {
        g.fillAll (Colours::yellow);
        
        g.setColour (Colours::black);
        g.setFont (15.0f);
        g.drawFittedText ("Native window!", getLocalBounds(), Justification::centred, 1);
    }
    
};

class CompPeerTestAudioProcessorEditor : public AudioProcessorEditor, public Button::Listener
{
public:
    CompPeerTestAudioProcessorEditor (CompPeerTestAudioProcessor& p) : AudioProcessorEditor (&p), processor (p)
    {
        setSize (400, 300);
        
        addAndMakeVisible(btnPlus);
        addAndMakeVisible(btnMinus);
        addAndMakeVisible(btnResize);
        
        btnPlus.setButtonText("+");
        btnMinus.setButtonText("-");
        btnResize.setButtonText("Trigger Resize");
        
        btnPlus.addListener(this);
        btnMinus.addListener(this);
        btnResize.addListener(this);
        
        addAndMakeVisible(natcomp);
    }

    ~CompPeerTestAudioProcessorEditor() {}

    //==============================================================================
    void paint (Graphics& g) override
    {
        g.fillAll (Colours::green);
        
        g.setColour (Colours::white);
        g.setFont (15.0f);
        g.drawFittedText ("Hello World!", getLocalBounds(), Justification::centred, 1);
        g.drawLine(0, 100, getWidth(), 100);
        g.drawLine(0, getHeight() - 100, getWidth(), getHeight() - 100);
    }
    
    void resized() override
    {
        btnPlus.setBounds(0, 0, 20, 20);
        btnMinus.setBounds(25, 0, 20, 20);
        btnResize.setBounds(50, 0, 200, 20);
        
        natcomp.setBounds(50, 100, getWidth() - 100, getHeight() - 200);
    }

    void parentHierarchyChanged() override
    {
        natcomp.removeFromDesktop();
        natcomp.addToDesktop(0, getTopLevelComponent()->getWindowHandle());
    }

private:
    
    void buttonClicked(Button* button) override
    {
        if (button == &btnPlus)
        {
            setSize(getWidth(), getHeight() + 200);
        }
        else if (button == &btnMinus)
        {
            setSize(getWidth(), getHeight() - 200);
        }
        else if (button == &btnResize)
        {
            // Force complete resize event chain by changing the size
            setSize(getWidth(), getHeight() - 1);
            setSize(getWidth(), getHeight() + 1);
        }
    }
    
    CompPeerTestAudioProcessor& processor;

    TextButton btnPlus, btnMinus, btnResize;
    NativeComponent natcomp;
    
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CompPeerTestAudioProcessorEditor)
};
```

---

<div class="post-metadata">

**Author:** ![sebk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/sebk/32/6425_2.png) [@sebk](https://forum.juce.com/u/sebk)\
**Post date:** [May 28, 2019, 7:08am UTC](https://forum.juce.com/t/osx-resizing-issue-with-addtodesktop-and-attachtonativewindow/33374/2 "2019-05-28T07:08:44Z")

</div>

Sorry for bumping this issue up a bit.

Could someone from the JUCE team at least recommend a way to force a setBounds() on all components? Or any way to fire the event chain such that all component sizes are recalculated?

That would already be suffcient for my use case. My main problem is that setBounds() does not have any effect because the component size is unchanged although the NSView did not yet pick up the correct size. So calling setBounds() again would already solve the problem.

---

<div class="post-metadata">

**Author:** ![PixelPacker](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/pixelpacker/32/9869_2.png) [@PixelPacker](https://forum.juce.com/u/PixelPacker)\
**Post date:** [November 20, 2020, 9:48pm UTC](https://forum.juce.com/t/osx-resizing-issue-with-addtodesktop-and-attachtonativewindow/33374/3 "2020-11-20T21:48:40Z")

</div>

Just ran into the same issue. I want to show a component that’s always center-top in front of a component attached to an OpenGLContext. I had to do two things to have my overlaid component positioned correctly:

- call `setBounds()` in an async callback fired via the message manager. apparently not all data is up-to-date the moment `componentMovedOrResized()` is called.
- call `setBounds(newbounds.expanded(1))` and then `setBounds(newbounds)` to circumvent the `if (wasMoved || wasResized)` in `Component::setBounds(...)`

yes, it’s a hack and it looks dorky because there’s a delay before the overlay jumpt to the correct position. The glorious pile of spaghetti workaround code now looks like this:

```
SafePointer<UpdateNotification> safeThis(this);

MessageManager::getInstance()->callAsync([safeThis]()
{
    if(UpdateNotification* self = safeThis.getComponent())
    {
        if(const auto parent = self->parent.getComponent())
        {
            const auto boundsInParent = self->getBounds().withCentre(parent->getLocalBounds().getCentre()).withY(0);
            const auto boundOnScreen = parent->localAreaToGlobal(boundsInParent);
            const auto boundsInRealParent = parent->getTopLevelComponent()->getLocalArea(nullptr, boundOnScreen);
            DBG(boundsInRealParent.toString());
            self->setBounds(boundsInRealParent.expanded(1));
            self->setBounds(boundsInRealParent);
        }
    }
});

```

Hope this helps someone.

If anybody has an idea how to do this properly, please chime in. Or maybe there’s a better way to do this. In my particular case I want to show a component in front of a component a OpenGLContext is attached to.

---

<div class="post-metadata">

**Author:** ![reuk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/reuk/32/21494_2.png) [@reuk](https://forum.juce.com/u/reuk)\
**Post date:** [April 28, 2021, 5:18pm UTC](https://forum.juce.com/t/osx-resizing-issue-with-addtodesktop-and-attachtonativewindow/33374/4 "2021-04-28T17:18:06Z")

</div>

Thanks for your patience, and for providing some sample code to reproduce the issue. I’ve merged a fix which should allow the resizing and positioning behaviour of nested NSViews to behave as expected. In particular, your demo code works correctly with this patch applied. Hopefully this change should mean that hacks and workarounds (like slightly resizing an embedded component using an AsyncUpdater) should be unnecessary.

> <https://github.com/juce-framework/JUCE/commit/f73f8ee8497d2ec7f158226ecc0266e30cdb1ea3>

Here on the JUCE team we’ve all tried out this change and checked it for regressions. We think it looks good, but given that this is quite a significant and low-level change, it’s possible that there are still a few subtle bugs lurking. If you encounter any new issues with this change, please let us know!

---

<div class="post-metadata">

**Author:** ![sebk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/sebk/32/6425_2.png) [@sebk](https://forum.juce.com/u/sebk)\
**Post date:** [May 4, 2021, 9:14am UTC](https://forum.juce.com/t/osx-resizing-issue-with-addtodesktop-and-attachtonativewindow/33374/5 "2021-05-04T09:14:40Z")

</div>

Amazing news, thanks for tackling that bug! 🙂 I tested the fix in our app/plugins and it immediatley resolved a couple of very annoying issues we had to workaround for a long time.
