mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-16 00:34:19 +00:00
HWNDComponentPeer: Add setBoundsPhysical() method to set window size in physical pixels
This commit is contained in:
parent
0fab062726
commit
3f13cdb314
2 changed files with 67 additions and 53 deletions
|
|
@ -1422,20 +1422,7 @@ public:
|
|||
|
||||
void setBounds (const Rectangle<int>& bounds, bool isNowFullScreen) override
|
||||
{
|
||||
// If we try to set new bounds while handling an existing position change,
|
||||
// Windows may get confused about our current scale and size.
|
||||
// This can happen when moving a window between displays, because the mouse-move
|
||||
// generator in handlePositionChanged can cause the window to move again.
|
||||
if (inHandlePositionChanged)
|
||||
return;
|
||||
|
||||
if (isNowFullScreen != isFullScreen())
|
||||
setFullScreen (isNowFullScreen);
|
||||
|
||||
const ScopedValueSetter<bool> scope (shouldIgnoreModalDismiss, true);
|
||||
|
||||
const auto borderSize = findPhysicalBorderSize().value_or (BorderSize<int>{});
|
||||
auto newBounds = borderSize.addedTo ([&]
|
||||
setBoundsPhysical (std::invoke ([&]
|
||||
{
|
||||
ScopedThreadDPIAwarenessSetter setter { hwnd };
|
||||
|
||||
|
|
@ -1445,47 +1432,12 @@ public:
|
|||
if (inDpiChange)
|
||||
return convertLogicalScreenRectangleToPhysical (bounds, hwnd);
|
||||
|
||||
if (GetParent (hwnd) != nullptr)
|
||||
return (bounds.toDouble() * getPlatformScaleFactor()).toNearestInt();
|
||||
|
||||
return convertLogicalScreenRectangleToPhysical (bounds, hwnd)
|
||||
.withPosition (Desktop::getInstance().getDisplays().logicalToPhysical (bounds.getTopLeft()));
|
||||
}());
|
||||
|
||||
if (getTransparencyKind() == TransparencyKind::perPixel)
|
||||
{
|
||||
if (auto parentHwnd = GetParent (hwnd))
|
||||
{
|
||||
auto parentRect = convertPhysicalScreenRectangleToLogical (D2DUtilities::toRectangle (getWindowScreenRect (parentHwnd)), hwnd);
|
||||
newBounds.translate (parentRect.getX(), parentRect.getY());
|
||||
}
|
||||
}
|
||||
|
||||
const auto oldBounds = [this]
|
||||
{
|
||||
ScopedThreadDPIAwarenessSetter setter { hwnd };
|
||||
RECT result;
|
||||
GetWindowRect (hwnd, &result);
|
||||
return D2DUtilities::toRectangle (result);
|
||||
}();
|
||||
|
||||
const bool hasMoved = (oldBounds.getPosition() != bounds.getPosition());
|
||||
const bool hasResized = (oldBounds.getWidth() != bounds.getWidth()
|
||||
|| oldBounds.getHeight() != bounds.getHeight());
|
||||
|
||||
DWORD flags = SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED;
|
||||
if (! hasMoved) flags |= SWP_NOMOVE;
|
||||
if (! hasResized) flags |= SWP_NOSIZE;
|
||||
|
||||
SetWindowPos (hwnd,
|
||||
nullptr,
|
||||
newBounds.getX(),
|
||||
newBounds.getY(),
|
||||
newBounds.getWidth(),
|
||||
newBounds.getHeight(),
|
||||
flags);
|
||||
|
||||
if (hasResized && isValidPeer (this))
|
||||
{
|
||||
repaintNowIfTransparent();
|
||||
}
|
||||
}), isNowFullScreen);
|
||||
}
|
||||
|
||||
Rectangle<int> getBounds() const override
|
||||
|
|
@ -4305,6 +4257,62 @@ private:
|
|||
return DefWindowProc (h, message, wParam, lParam);
|
||||
}
|
||||
|
||||
void setBoundsPhysical (const Rectangle<int>& bounds, bool isNowFullScreen)
|
||||
{
|
||||
// If we try to set new bounds while handling an existing position change,
|
||||
// Windows may get confused about our current scale and size.
|
||||
// This can happen when moving a window between displays, because the mouse-move
|
||||
// generator in handlePositionChanged can cause the window to move again.
|
||||
if (inHandlePositionChanged)
|
||||
return;
|
||||
|
||||
if (isNowFullScreen != isFullScreen())
|
||||
setFullScreen (isNowFullScreen);
|
||||
|
||||
const ScopedValueSetter scope (shouldIgnoreModalDismiss, true);
|
||||
|
||||
const auto borderSize = findPhysicalBorderSize().value_or (BorderSize<int>{});
|
||||
auto newBounds = borderSize.addedTo (bounds);
|
||||
|
||||
if (getTransparencyKind() == TransparencyKind::perPixel)
|
||||
{
|
||||
if (auto parentHwnd = GetParent (hwnd))
|
||||
{
|
||||
auto parentRect = convertPhysicalScreenRectangleToLogical (D2DUtilities::toRectangle (getWindowScreenRect (parentHwnd)), hwnd);
|
||||
newBounds.translate (parentRect.getX(), parentRect.getY());
|
||||
}
|
||||
}
|
||||
|
||||
const auto oldBounds = std::invoke ([this]
|
||||
{
|
||||
ScopedThreadDPIAwarenessSetter setter { hwnd };
|
||||
RECT result;
|
||||
GetWindowRect (hwnd, &result);
|
||||
return D2DUtilities::toRectangle (result);
|
||||
});
|
||||
|
||||
const bool hasMoved = (oldBounds.getPosition() != bounds.getPosition());
|
||||
const bool hasResized = (oldBounds.getWidth() != bounds.getWidth()
|
||||
|| oldBounds.getHeight() != bounds.getHeight());
|
||||
|
||||
DWORD flags = SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED;
|
||||
if (! hasMoved) flags |= SWP_NOMOVE;
|
||||
if (! hasResized) flags |= SWP_NOSIZE;
|
||||
|
||||
SetWindowPos (hwnd,
|
||||
nullptr,
|
||||
newBounds.getX(),
|
||||
newBounds.getY(),
|
||||
newBounds.getWidth(),
|
||||
newBounds.getHeight(),
|
||||
flags);
|
||||
|
||||
if (hasResized && isValidPeer (this))
|
||||
{
|
||||
repaintNowIfTransparent();
|
||||
}
|
||||
}
|
||||
|
||||
bool sendInputAttemptWhenModalMessage()
|
||||
{
|
||||
if (! component.isCurrentlyBlockedByAnotherModalComponent())
|
||||
|
|
|
|||
|
|
@ -194,6 +194,12 @@ public:
|
|||
|
||||
If the native window is contained in another window, then the coordinates are
|
||||
relative to the parent window's origin, not the screen origin.
|
||||
In this case, the position is specified in the same coordinate space as the size.
|
||||
|
||||
As an example, imagine that setBounds() is called on a contained ComponentPeer
|
||||
with newBounds set to { 10, 20, 30, 40 }, where the peer's native scale factor is 1.5.
|
||||
The new bounds will be converted to physical pixels, { 15, 30, 45, 60 }, meaning that
|
||||
the peer will be positioned at { 15, 30 } *physical pixels* in the parent.
|
||||
|
||||
This should result in a callback to handleMovedOrResized().
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue