Browse Source

Linux: Fix restoreWindowFromStateString() when the peer already exists

v6.1.6
attila 3 years ago
parent
commit
a7811661c5
11 changed files with 121 additions and 21 deletions
  1. +25
    -0
      BREAKING-CHANGES.txt
  2. +1
    -0
      modules/juce_audio_plugin_client/Unity/juce_Unity_Wrapper.cpp
  3. +6
    -0
      modules/juce_gui_basics/native/juce_android_Windowing.cpp
  4. +7
    -6
      modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm
  5. +15
    -4
      modules/juce_gui_basics/native/juce_linux_Windowing.cpp
  6. +14
    -4
      modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm
  7. +5
    -0
      modules/juce_gui_basics/native/juce_win32_Windowing.cpp
  8. +2
    -2
      modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp
  9. +2
    -2
      modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h
  10. +37
    -0
      modules/juce_gui_basics/windows/juce_ComponentPeer.h
  11. +7
    -3
      modules/juce_gui_basics/windows/juce_ResizableWindow.cpp

+ 25
- 0
BREAKING-CHANGES.txt View File

@@ -1,6 +1,31 @@
JUCE breaking changes JUCE breaking changes
===================== =====================


develop
=======

Change
------
The return type of XWindowSystem::getBorderSize() was changed to
ComponentPeer::OptionalBorderSize.

Possible Issues
---------------
User code that uses XWindowSystem::getBorderSize() will fail to build.

Workaround
----------
Use operator bool() to determine the validity of the new return value and
access the contained value using operator*().

Rationale
---------
The XWindow system cannot immediately report the correct border size after
window creation. The underlying X11 calls will signal whether querying the
border size was successful, but there was no way to forward this information
through XWindowSystem::getBorderSize() until this change.


Version 6.1.5 Version 6.1.5
============= =============




+ 1
- 0
modules/juce_audio_plugin_client/Unity/juce_Unity_Wrapper.cpp View File

@@ -270,6 +270,7 @@ private:
bool isFocused() const override { return true; } bool isFocused() const override { return true; }
void grabFocus() override {} void grabFocus() override {}
void* getNativeHandle() const override { return nullptr; } void* getNativeHandle() const override { return nullptr; }
OptionalBorderSize getFrameSizeIfPresent() const override { return {}; }
BorderSize<int> getFrameSize() const override { return {}; } BorderSize<int> getFrameSize() const override { return {}; }
void setVisible (bool) override {} void setVisible (bool) override {}
void setTitle (const String&) override {} void setTitle (const String&) override {}


+ 6
- 0
modules/juce_gui_basics/native/juce_android_Windowing.cpp View File

@@ -631,6 +631,12 @@ public:
(float) localPos.y * scale)); (float) localPos.y * scale));
} }
OptionalBorderSize getFrameSizeIfPresent() const override
{
// TODO
return {};
}
BorderSize<int> getFrameSize() const override BorderSize<int> getFrameSize() const override
{ {
// TODO // TODO


+ 7
- 6
modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm View File

@@ -211,24 +211,25 @@ public:
controller = [newController retain]; controller = [newController retain];
} }
Rectangle<int> getBounds() const override { return getBounds (! isSharedWindow); }
Rectangle<int> getBounds() const override { return getBounds (! isSharedWindow); }
Rectangle<int> getBounds (bool global) const; Rectangle<int> getBounds (bool global) const;
Point<float> localToGlobal (Point<float> relativePosition) override; Point<float> localToGlobal (Point<float> relativePosition) override;
Point<float> globalToLocal (Point<float> screenPosition) override; Point<float> globalToLocal (Point<float> screenPosition) override;
using ComponentPeer::localToGlobal; using ComponentPeer::localToGlobal;
using ComponentPeer::globalToLocal; using ComponentPeer::globalToLocal;
void setAlpha (float newAlpha) override; void setAlpha (float newAlpha) override;
void setMinimised (bool) override {}
bool isMinimised() const override { return false; }
void setMinimised (bool) override {}
bool isMinimised() const override { return false; }
void setFullScreen (bool shouldBeFullScreen) override; void setFullScreen (bool shouldBeFullScreen) override;
bool isFullScreen() const override { return fullScreen; }
bool isFullScreen() const override { return fullScreen; }
bool contains (Point<int> localPos, bool trueIfInAChildWindow) const override; bool contains (Point<int> localPos, bool trueIfInAChildWindow) const override;
BorderSize<int> getFrameSize() const override { return BorderSize<int>(); }
OptionalBorderSize getFrameSizeIfPresent() const override { return {}; }
BorderSize<int> getFrameSize() const override { return BorderSize<int>(); }
bool setAlwaysOnTop (bool alwaysOnTop) override; bool setAlwaysOnTop (bool alwaysOnTop) override;
void toFront (bool makeActiveWindow) override; void toFront (bool makeActiveWindow) override;
void toBehind (ComponentPeer* other) override; void toBehind (ComponentPeer* other) override;
void setIcon (const Image& newIcon) override; void setIcon (const Image& newIcon) override;
StringArray getAvailableRenderingEngines() override { return StringArray ("CoreGraphics Renderer"); }
StringArray getAvailableRenderingEngines() override { return StringArray ("CoreGraphics Renderer"); }
void drawRect (CGRect); void drawRect (CGRect);
bool canBecomeKeyWindow(); bool canBecomeKeyWindow();


+ 15
- 4
modules/juce_gui_basics/native/juce_linux_Windowing.cpp View File

@@ -141,11 +141,17 @@ public:
return bounds; return bounds;
} }
BorderSize<int> getFrameSize() const override
OptionalBorderSize getFrameSizeIfPresent() const override
{ {
return windowBorder; return windowBorder;
} }
BorderSize<int> getFrameSize() const override
{
const auto optionalBorderSize = getFrameSizeIfPresent();
return optionalBorderSize ? (*optionalBorderSize) : BorderSize<int>();
}
Point<float> localToGlobal (Point<float> relativePosition) override Point<float> localToGlobal (Point<float> relativePosition) override
{ {
return relativePosition + getScreenPosition (false).toFloat(); return relativePosition + getScreenPosition (false).toFloat();
@@ -362,9 +368,14 @@ public:
void updateBorderSize() void updateBorderSize()
{ {
if ((styleFlags & windowHasTitleBar) == 0) if ((styleFlags & windowHasTitleBar) == 0)
windowBorder = {};
else if (windowBorder.getTopAndBottom() == 0 && windowBorder.getLeftAndRight() == 0)
{
windowBorder = ComponentPeer::OptionalBorderSize { BorderSize<int>() };
}
else if (! windowBorder
|| ((*windowBorder).getTopAndBottom() == 0 && (*windowBorder).getLeftAndRight() == 0))
{
windowBorder = XWindowSystem::getInstance()->getBorderSize (windowH); windowBorder = XWindowSystem::getInstance()->getBorderSize (windowH);
}
} }
//============================================================================== //==============================================================================
@@ -504,7 +515,7 @@ private:
::Window windowH = {}, parentWindow = {}; ::Window windowH = {}, parentWindow = {};
Rectangle<int> bounds; Rectangle<int> bounds;
BorderSize<int> windowBorder;
ComponentPeer::OptionalBorderSize windowBorder;
bool fullScreen = false, isAlwaysOnTop = false; bool fullScreen = false, isAlwaysOnTop = false;
double currentScaleFactor = 1.0; double currentScaleFactor = 1.0;
Array<Component*> glRepaintListeners; Array<Component*> glRepaintListeners;


+ 14
- 4
modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm View File

@@ -493,12 +493,12 @@ public:
: (v == view); : (v == view);
} }
BorderSize<int> getFrameSize() const override
OptionalBorderSize getFrameSizeIfPresent() const override
{ {
BorderSize<int> b;
if (! isSharedWindow) if (! isSharedWindow)
{ {
BorderSize<int> b;
NSRect v = [view convertRect: [view frame] toView: nil]; NSRect v = [view convertRect: [view frame] toView: nil];
NSRect w = [window frame]; NSRect w = [window frame];
@@ -506,9 +506,19 @@ public:
b.setBottom ((int) v.origin.y); b.setBottom ((int) v.origin.y);
b.setLeft ((int) v.origin.x); b.setLeft ((int) v.origin.x);
b.setRight ((int) (w.size.width - (v.origin.x + v.size.width))); b.setRight ((int) (w.size.width - (v.origin.x + v.size.width)));
return OptionalBorderSize { b };
} }
return b;
return {};
}
BorderSize<int> getFrameSize() const override
{
if (const auto frameSize = getFrameSizeIfPresent())
return *frameSize;
return {};
} }
bool hasNativeTitleBar() const bool hasNativeTitleBar() const


+ 5
- 0
modules/juce_gui_basics/native/juce_win32_Windowing.cpp View File

@@ -1764,6 +1764,11 @@ public:
return w == hwnd || (trueIfInAChildWindow && (IsChild (hwnd, w) != 0)); return w == hwnd || (trueIfInAChildWindow && (IsChild (hwnd, w) != 0));
} }
OptionalBorderSize getFrameSizeIfPresent() const override
{
return ComponentPeer::OptionalBorderSize { windowBorder };
}
BorderSize<int> getFrameSize() const override BorderSize<int> getFrameSize() const override
{ {
return windowBorder; return windowBorder;


+ 2
- 2
modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp View File

@@ -1802,7 +1802,7 @@ bool XWindowSystem::contains (::Window windowH, Point<int> localPos) const
&& child == None; && child == None;
} }
BorderSize<int> XWindowSystem::getBorderSize (::Window windowH) const
ComponentPeer::OptionalBorderSize XWindowSystem::getBorderSize (::Window windowH) const
{ {
jassert (windowH != 0); jassert (windowH != 0);
@@ -1824,7 +1824,7 @@ BorderSize<int> XWindowSystem::getBorderSize (::Window windowH) const
data += sizeof (unsigned long); data += sizeof (unsigned long);
} }
return { (int) sizes[2], (int) sizes[0], (int) sizes[3], (int) sizes[1] };
return ComponentPeer::OptionalBorderSize ({ (int) sizes[2], (int) sizes[0], (int) sizes[3], (int) sizes[1] });
} }
} }


+ 2
- 2
modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h View File

@@ -181,8 +181,8 @@ public:
void setBounds (::Window, Rectangle<int>, bool fullScreen) const; void setBounds (::Window, Rectangle<int>, bool fullScreen) const;
void updateConstraints (::Window) const; void updateConstraints (::Window) const;
BorderSize<int> getBorderSize (::Window) const;
Rectangle<int> getWindowBounds (::Window, ::Window parentWindow);
ComponentPeer::OptionalBorderSize getBorderSize (::Window) const;
Rectangle<int> getWindowBounds (::Window, ::Window parentWindow);
Point<int> getPhysicalParentScreenPosition() const; Point<int> getPhysicalParentScreenPosition() const;
bool contains (::Window, Point<int> localPos) const; bool contains (::Window, Point<int> localPos) const;


+ 37
- 0
modules/juce_gui_basics/windows/juce_ComponentPeer.h View File

@@ -76,6 +76,31 @@ public:
}; };
class OptionalBorderSize final
{
public:
OptionalBorderSize() : valid (false) {}
explicit OptionalBorderSize (BorderSize<int> size) : valid (true), borderSize (std::move (size)) {}
explicit operator bool() const noexcept { return valid; }
const auto& operator*() const noexcept
{
jassert (valid);
return borderSize;
}
const auto* operator->() const noexcept
{
jassert (valid);
return &borderSize;
}
private:
bool valid;
BorderSize<int> borderSize;
};
//============================================================================== //==============================================================================
/** Creates a peer. /** Creates a peer.
@@ -219,6 +244,18 @@ public:
*/ */
virtual bool contains (Point<int> localPos, bool trueIfInAChildWindow) const = 0; virtual bool contains (Point<int> localPos, bool trueIfInAChildWindow) const = 0;
/** Returns the size of the window frame that's around this window.
Depending on the platform the border size may be invalid for a short transient
after creating a new window. Hence the returned value must be checked using
operator bool() and the contained value can be accessed using operator*() only
if it is present.
Whether or not the window has a normal window frame depends on the flags
that were set when the window was created by Component::addToDesktop()
*/
virtual OptionalBorderSize getFrameSizeIfPresent() const = 0;
/** Returns the size of the window frame that's around this window. /** Returns the size of the window frame that's around this window.
Whether or not the window has a normal window frame depends on the flags Whether or not the window has a normal window frame depends on the flags
that were set when the window was created by Component::addToDesktop() that were set when the window was created by Component::addToDesktop()


+ 7
- 3
modules/juce_gui_basics/windows/juce_ResizableWindow.cpp View File

@@ -566,10 +566,12 @@ bool ResizableWindow::restoreWindowStateFromString (const String& s)
if (peer != nullptr) if (peer != nullptr)
{ {
peer->getFrameSize().addTo (newPos);
if (const auto frameSize = peer->getFrameSizeIfPresent())
frameSize->addTo (newPos);
} }
#if JUCE_LINUX #if JUCE_LINUX
else
if (peer == nullptr || ! peer->getFrameSizeIfPresent())
{ {
// We need to adjust for the frame size before we create a peer, as X11 // We need to adjust for the frame size before we create a peer, as X11
// doesn't provide this information at construction time. // doesn't provide this information at construction time.
@@ -580,7 +582,9 @@ bool ResizableWindow::restoreWindowStateFromString (const String& s)
tokens[firstCoord + 7].getIntValue(), tokens[firstCoord + 7].getIntValue(),
tokens[firstCoord + 8].getIntValue() }; tokens[firstCoord + 8].getIntValue() };
frame.addTo (newPos);
newPos.setX (newPos.getX() - frame.getLeft());
newPos.setY (newPos.getY() - frame.getTop());
setBounds (newPos); setBounds (newPos);
} }
} }


Loading…
Cancel
Save