diff --git a/modules/juce_gui_basics/native/juce_Windowing_linux.cpp b/modules/juce_gui_basics/native/juce_Windowing_linux.cpp index d42a5b321c..aafb0993f7 100644 --- a/modules/juce_gui_basics/native/juce_Windowing_linux.cpp +++ b/modules/juce_gui_basics/native/juce_Windowing_linux.cpp @@ -116,7 +116,7 @@ public: // ConfigureNotify events, many of which has stale size information. By not calling // XWindowSystem::setBounds we are not actualising these old, incorrect sizes. if (! inConfigureNotifyHandler) - XWindowSystem::getInstance()->setBounds (windowH, physicalBounds, isNowFullScreen); + moveResizeSerial = jmax (moveResizeSerial, XWindowSystem::getInstance()->setBounds (windowH, physicalBounds, isNowFullScreen).value_or (0)); fullScreen = isNowFullScreen; @@ -429,6 +429,11 @@ public: bool focused = false; bool inConfigureNotifyHandler = false; + unsigned long getMoveResizeSerial() const + { + return moveResizeSerial; + } + private: //============================================================================== class LinuxRepaintManager @@ -605,6 +610,7 @@ private: double currentScaleFactor = 1.0; Array glRepaintListeners; ScopedWindowAssociation association; + unsigned long moveResizeSerial = 0; //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LinuxComponentPeer) diff --git a/modules/juce_gui_basics/native/juce_XWindowSystem_linux.cpp b/modules/juce_gui_basics/native/juce_XWindowSystem_linux.cpp index 5c3549ac1b..c38cf3493e 100644 --- a/modules/juce_gui_basics/native/juce_XWindowSystem_linux.cpp +++ b/modules/juce_gui_basics/native/juce_XWindowSystem_linux.cpp @@ -1736,7 +1736,7 @@ void XWindowSystem::setVisible (::Window windowH, bool shouldBeVisible) const X11Symbols::getInstance()->xUnmapWindow (display, windowH); } -void XWindowSystem::setBounds (::Window windowH, Rectangle newBounds, bool isFullScreen) const +std::optional XWindowSystem::setBounds (::Window windowH, Rectangle newBounds, bool isFullScreen) const { jassert (windowH != 0); @@ -1792,12 +1792,16 @@ void XWindowSystem::setBounds (::Window windowH, Rectangle newBounds, bool return {}; }(); + const auto serial = X11Symbols::getInstance()->xNextRequest (display); X11Symbols::getInstance()->xMoveResizeWindow (display, windowH, newBounds.getX() - nativeWindowBorder.getLeft(), newBounds.getY() - nativeWindowBorder.getTop(), (unsigned int) newBounds.getWidth(), (unsigned int) newBounds.getHeight()); + return serial; } + + return std::nullopt; } void XWindowSystem::startHostManagedResize (::Window windowH, @@ -3780,6 +3784,11 @@ void XWindowSystem::dismissBlockingModals (LinuxComponentPeer* peer) const void XWindowSystem::handleConfigureNotifyEvent (LinuxComponentPeer* peer, XConfigureEvent& confEvent) const { + // If the incoming event serial is smaller than the serial of a move/resize request we sent previously, + // then we should ignore the incoming event because it will conflict with the pending request. + if (confEvent.serial < peer->getMoveResizeSerial()) + return; + const ScopedValueSetter scope { peer->inConfigureNotifyHandler, true }; peer->updateWindowBounds(); diff --git a/modules/juce_gui_basics/native/juce_XWindowSystem_linux.h b/modules/juce_gui_basics/native/juce_XWindowSystem_linux.h index 7bc74527da..4271f06c64 100644 --- a/modules/juce_gui_basics/native/juce_XWindowSystem_linux.h +++ b/modules/juce_gui_basics/native/juce_XWindowSystem_linux.h @@ -187,7 +187,7 @@ public: void setTitle (::Window, const String&) const; void setIcon (::Window , const Image&) const; void setVisible (::Window, bool shouldBeVisible) const; - void setBounds (::Window, Rectangle, bool fullScreen) const; + [[nodiscard]] std::optional setBounds (::Window, Rectangle, bool fullScreen) const; void updateConstraints (::Window) const; ComponentPeer::OptionalBorderSize getBorderSize (::Window) const;