1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-18 00:54:19 +00:00

Linux: Fix sporadic positioning error after window creation

This commit is contained in:
attila 2022-05-16 17:10:12 +02:00
parent e27194272d
commit 751c4177a4
2 changed files with 40 additions and 8 deletions

View file

@ -752,6 +752,16 @@ void Component::addToDesktop (int styleWanted, void* nativeWindowToAttachTo)
peer->setConstrainer (currentConstrainer);
repaint();
#if JUCE_LINUX
// Creating the peer Image on Linux will change the reported position of the window. If
// the Image creation is interleaved with the coming configureNotifyEvents the window
// will appear in the wrong position. To avoid this, we force the Image creation here,
// before handling any of the configureNotifyEvents. The Linux implementation of
// performAnyPendingRepaintsNow() will force update the peer position if necessary.
peer->performAnyPendingRepaintsNow();
#endif
internalHierarchyChanged();
if (auto* handler = getAccessibilityHandler())

View file

@ -92,14 +92,8 @@ public:
}
//==============================================================================
void setBounds (const Rectangle<int>& newBounds, bool isNowFullScreen) override
void forceSetBounds (const Rectangle<int>& correctedNewBounds, bool isNowFullScreen)
{
const auto correctedNewBounds = newBounds.withSize (jmax (1, newBounds.getWidth()),
jmax (1, newBounds.getHeight()));
if (bounds == correctedNewBounds && fullScreen == isNowFullScreen)
return;
bounds = correctedNewBounds;
updateScaleFactorFromNewBounds (bounds, false);
@ -120,6 +114,15 @@ public:
}
}
void setBounds (const Rectangle<int>& newBounds, bool isNowFullScreen) override
{
const auto correctedNewBounds = newBounds.withSize (jmax (1, newBounds.getWidth()),
jmax (1, newBounds.getHeight()));
if (bounds != correctedNewBounds || fullScreen != isNowFullScreen)
forceSetBounds (correctedNewBounds, isNowFullScreen);
}
Point<int> getScreenPosition (bool physical) const
{
auto physicalParentPosition = XWindowSystem::getInstance()->getPhysicalParentScreenPosition();
@ -434,12 +437,31 @@ private:
if (! totalArea.isEmpty())
{
if (image.isNull() || image.getWidth() < totalArea.getWidth()
const auto wasImageNull = image.isNull();
if (wasImageNull || image.getWidth() < totalArea.getWidth()
|| image.getHeight() < totalArea.getHeight())
{
image = XWindowSystem::getInstance()->createImage (isSemiTransparentWindow,
totalArea.getWidth(), totalArea.getHeight(),
useARGBImagesForRendering);
if (wasImageNull)
{
// After calling createImage() XWindowSystem::getWindowBounds() will return
// changed coordinates that look like the result of some position
// defaulting mechanism. If we handle a configureNotifyEvent after
// createImage() and before we would issue new, valid coordinates, we will
// apply these default, unwanted coordinates to our window. To avoid that
// we immediately send another positioning message to guarantee that the
// next configureNotifyEvent will read valid values.
//
// This issue only occurs right after peer creation, when the image is
// null. Updating when only the width or height is changed would lead to
// incorrect behaviour.
peer.forceSetBounds (ScalingHelpers::scaledScreenPosToUnscaled (peer.component,
peer.component.getBoundsInParent()),
peer.isFullScreen());
}
}
startTimer (repaintTimerPeriod);