Linux and restoreWindowStateFromString()

I know this has been brought up many times in the past. But I’m still having problems with getWindowStateAsString() and restoreWindowStateFromString() on Linux. Every time the application is saved and restored, the coordinates change by 37 pixels, resulting in the window slowly inching up the screen.

This seems to happen only with Linux when the windows are created with setUsingNativeTitleBar(true). My windows which inherit from DocumentWindow contain this in the constructor:

setUsingNativeTitleBar(true);

if (cfg.containsKey("AppWnd"))
{
    restoreWindowStateFromString(cfg.getValue("AppWnd") );
}
else
{
    centreWithSize(600, 200);
}

…and my destructor has this:

cfg.setValue("AppWnd", getWindowStateAsString());

Looking at the resulting XML, the window height gets shorter by exactly 37 pixels every time the status is saved and restored. For example, consecutive runs of the application results in this:

<VALUE name="AppWnd" val="48 64 1872 920 frame 37 0 0 0"/>
<VALUE name="AppWnd" val="48 64 1872 846 frame 37 0 0 0"/>
<VALUE name="AppWnd" val="48 64 1872 809 frame 37 0 0 0"/>
<VALUE name="AppWnd" val="48 64 1872 772 frame 37 0 0 0"/>

(Note the shrinking 4th value, which I assume is the window height.)

I’m using JUCE 7 (hash 7612f446b5f6e09f23f9702afea48c176276828a from 2 days ago) on Ubuntu 18.04, 20.04, and 22.04.

@t0m you had expressed some interest in this issue in the past. Any idea as to how we can fix this, other than manually editing the XML file and adding 37 to the 4th value before we restore the window state?

Ideally the getWindowStateAsString() and restoreWindowStateFromString() functions should work correctly as long as you call restoreWindowStateFromString() first, but I can see that you do.

We hoped this bug has been squashed, and indeed all the previous ways in which it could have been reproduced seems to be fixed now. The value 37 you are seeing was actually added when fixing the first occurrences of this problem.

I’m looking into this right now, and will update this thread when I’ve found out more.

Thanks. There was a thread in the past where someone indicated that setContentNonOwned() also had something to do with it. My DocumentWindow-derived objects are usually created similar to this:

setContentNonOwned		(&canvas, true	);
setUsingNativeTitleBar	(true			);
setResizable			(true, false	);
setDropShadowEnabled	(true			);

Where canvas is a Component against which I call addAndMakeVisible() all the other controls. And at the bottom of my window constructor once everything is setup I typically call:

setIcon(AppLogo());
ComponentPeer *peer = getPeer();
if (peer)
{
    peer->setIcon(AppLogo());
}

if (cfg.containsKey("StartupWnd"))
{
    restoreWindowStateFromString(cfg.getValue("StartupWnd"));
}
else
{
    centreWithSize(800, 600);
}

setVisible(true);

I’ve recreated the order of those calls, and still no luck with reproducing the issue. I can see the pre-fix behaviour, where the window is marching down, and the current develop where it stays in place.

We may be missing an important detail here. If you could create a minimal project, PIP or otherwise, I’d be happy to take a look.