Skip to content

Commit

Permalink
Merge pull request #6254 from AvaloniaUI/fixes/4739-sizetocontent-dpi…
Browse files Browse the repository at this point in the history
…-change

Fix autosizing when DPI changed
# Conflicts:
#	src/Avalonia.Controls/ApiCompatBaseline.txt
#	src/Avalonia.X11/X11Window.cs
  • Loading branch information
danwalmsley committed Aug 16, 2021
1 parent f8af8d5 commit 069560e
Show file tree
Hide file tree
Showing 27 changed files with 407 additions and 157 deletions.
21 changes: 21 additions & 0 deletions native/Avalonia.Native/src/OSX/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ class WindowBaseImpl;
-(void) setSwRenderedFrame: (AvnFramebuffer* _Nonnull) fb dispose: (IUnknown* _Nonnull) dispose;
-(void) onClosed;
-(AvnPixelSize) getPixelSize;
-(AvnPlatformResizeReason) getResizeReason;
-(void) setResizeReason:(AvnPlatformResizeReason)reason;
@end

@interface AutoFitContentView : NSView
Expand Down Expand Up @@ -51,4 +53,23 @@ struct IWindowStateChanged
virtual AvnWindowState WindowState () = 0;
};

class ResizeScope
{
public:
ResizeScope(AvnView* _Nonnull view, AvnPlatformResizeReason reason)
{
_view = view;
_restore = [view getResizeReason];
[view setResizeReason:reason];
}

~ResizeScope()
{
[_view setResizeReason:_restore];
}
private:
AvnView* _Nonnull _view;
AvnPlatformResizeReason _restore;
};

#endif /* window_h */
21 changes: 17 additions & 4 deletions native/Avalonia.Native/src/OSX/window.mm
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ virtual HRESULT SetMinMaxSize (AvnSize minSize, AvnSize maxSize) override
}
}

virtual HRESULT Resize(double x, double y) override
virtual HRESULT Resize(double x, double y, AvnPlatformResizeReason reason) override
{
if(_inResize)
{
Expand All @@ -268,6 +268,7 @@ virtual HRESULT Resize(double x, double y) override
_inResize = true;

START_COM_CALL;
auto resizeBlock = ResizeScope(View, reason);

@autoreleasepool
{
Expand Down Expand Up @@ -298,7 +299,7 @@ virtual HRESULT Resize(double x, double y) override
{
if(!_shown)
{
BaseEvents->Resized(AvnSize{x,y});
BaseEvents->Resized(AvnSize{x,y}, reason);
}

[Window setContentSize:NSSize{x, y}];
Expand Down Expand Up @@ -1361,6 +1362,7 @@ @implementation AvnView
bool _lastKeyHandled;
AvnPixelSize _lastPixelSize;
NSObject<IRenderTarget>* _renderTarget;
AvnPlatformResizeReason _resizeReason;
}

- (void)onClosed
Expand Down Expand Up @@ -1472,7 +1474,8 @@ -(void)setFrameSize:(NSSize)newSize
_lastPixelSize.Height = (int)fsize.height;
[self updateRenderTarget];

_parent->BaseEvents->Resized(AvnSize{newSize.width, newSize.height});
auto reason = [self inLiveResize] ? ResizeUser : _resizeReason;
_parent->BaseEvents->Resized(AvnSize{newSize.width, newSize.height}, reason);
}
}

Expand Down Expand Up @@ -1971,6 +1974,16 @@ - (void)concludeDragOperation:(nullable id <NSDraggingInfo>)sender

}

- (AvnPlatformResizeReason)getResizeReason
{
return _resizeReason;
}

- (void)setResizeReason:(AvnPlatformResizeReason)reason
{
_resizeReason = reason;
}

@end


Expand Down Expand Up @@ -2358,7 +2371,7 @@ virtual NSWindowStyleMask GetStyle() override
return NSWindowStyleMaskBorderless;
}

virtual HRESULT Resize(double x, double y) override
virtual HRESULT Resize(double x, double y, AvnPlatformResizeReason reason) override
{
START_COM_CALL;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public virtual Point GetAvaloniaPointFromEvent(MotionEvent e, int pointerIndex)

public Action<Rect> Paint { get; set; }

public Action<Size> Resized { get; set; }
public Action<Size, PlatformResizeReason> Resized { get; set; }

public Action<double> ScalingChanged { get; set; }

Expand Down Expand Up @@ -132,7 +132,7 @@ public virtual void Dispose()

protected virtual void OnResized(Size size)
{
Resized?.Invoke(size);
Resized?.Invoke(size, PlatformResizeReason.Unspecified);
}

class ViewImpl : InvalidationAwareSurfaceView, ISurfaceHolderCallback, IInitEditorInfo
Expand Down
13 changes: 12 additions & 1 deletion src/Avalonia.Controls/ApiCompatBaseline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,24 @@ InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Control
InterfacesShouldHaveSameMembers : Interface member 'public System.EventHandler<System.ComponentModel.CancelEventArgs> Avalonia.Controls.ApplicationLifetimes.IClassicDesktopStyleApplicationLifetime.ShutdownRequested' is present in the implementation but not in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Controls.ApplicationLifetimes.IClassicDesktopStyleApplicationLifetime.add_ShutdownRequested(System.EventHandler<System.ComponentModel.CancelEventArgs>)' is present in the implementation but not in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Controls.ApplicationLifetimes.IClassicDesktopStyleApplicationLifetime.remove_ShutdownRequested(System.EventHandler<System.ComponentModel.CancelEventArgs>)' is present in the implementation but not in the contract.
MembersMustExist : Member 'public System.Action<Avalonia.Size> Avalonia.Controls.Embedding.Offscreen.OffscreenTopLevelImplBase.Resized.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public void Avalonia.Controls.Embedding.Offscreen.OffscreenTopLevelImplBase.Resized.set(System.Action<Avalonia.Size>)' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public void Avalonia.Controls.Embedding.Offscreen.OffscreenTopLevelImplBase.SetCursor(Avalonia.Platform.IPlatformHandle)' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public Avalonia.AvaloniaProperty Avalonia.AvaloniaProperty Avalonia.Controls.Notifications.NotificationCard.CloseOnClickProperty' does not exist in the implementation but it does exist in the contract.
EnumValuesMustMatch : Enum value 'Avalonia.Platform.ExtendClientAreaChromeHints Avalonia.Platform.ExtendClientAreaChromeHints.Default' is (System.Int32)2 in the implementation but (System.Int32)1 in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public System.Action<Avalonia.Size, Avalonia.Platform.PlatformResizeReason> Avalonia.Platform.ITopLevelImpl.Resized.get()' is present in the implementation but not in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public System.Action<Avalonia.Size> Avalonia.Platform.ITopLevelImpl.Resized.get()' is present in the contract but not in the implementation.
MembersMustExist : Member 'public System.Action<Avalonia.Size> Avalonia.Platform.ITopLevelImpl.Resized.get()' does not exist in the implementation but it does exist in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Platform.ITopLevelImpl.Resized.set(System.Action<Avalonia.Size, Avalonia.Platform.PlatformResizeReason>)' is present in the implementation but not in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Platform.ITopLevelImpl.Resized.set(System.Action<Avalonia.Size>)' is present in the contract but not in the implementation.
MembersMustExist : Member 'public void Avalonia.Platform.ITopLevelImpl.Resized.set(System.Action<Avalonia.Size>)' does not exist in the implementation but it does exist in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Platform.ITopLevelImpl.SetCursor(Avalonia.Platform.ICursorImpl)' is present in the implementation but not in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Platform.ITopLevelImpl.SetCursor(Avalonia.Platform.IPlatformHandle)' is present in the contract but not in the implementation.
MembersMustExist : Member 'public void Avalonia.Platform.ITopLevelImpl.SetCursor(Avalonia.Platform.IPlatformHandle)' does not exist in the implementation but it does exist in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Platform.IWindowBaseImpl.Show(System.Boolean)' is present in the contract but not in the implementation.
MembersMustExist : Member 'public void Avalonia.Platform.IWindowBaseImpl.Show(System.Boolean)' does not exist in the implementation but it does exist in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Platform.IWindowBaseImpl.Show(System.Boolean, System.Boolean)' is present in the implementation but not in the contract.
Total Issues: 14
InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Platform.IWindowImpl.Resize(Avalonia.Size)' is present in the contract but not in the implementation.
MembersMustExist : Member 'public void Avalonia.Platform.IWindowImpl.Resize(Avalonia.Size)' does not exist in the implementation but it does exist in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Platform.IWindowImpl.Resize(Avalonia.Size, Avalonia.Platform.PlatformResizeReason)' is present in the implementation but not in the contract.
Total Issues: 25
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public Size ClientSize
set
{
_clientSize = value;
Resized?.Invoke(value);
Resized?.Invoke(value, PlatformResizeReason.Unspecified);
}
}

Expand All @@ -47,7 +47,7 @@ public double RenderScaling

public Action<RawInputEventArgs> Input { get; set; }
public Action<Rect> Paint { get; set; }
public Action<Size> Resized { get; set; }
public Action<Size, PlatformResizeReason> Resized { get; set; }
public Action<double> ScalingChanged { get; set; }

public Action<WindowTransparencyLevel> TransparencyLevelChanged { get; set; }
Expand Down
37 changes: 36 additions & 1 deletion src/Avalonia.Controls/Platform/ITopLevelImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,46 @@
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Input.Raw;
using Avalonia.Layout;
using Avalonia.Rendering;
using JetBrains.Annotations;

namespace Avalonia.Platform
{
/// <summary>
/// Describes the reason for a <see cref="ITopLevelImpl.Resized"/> message.
/// </summary>
public enum PlatformResizeReason
{
/// <summary>
/// The resize reason is unknown or unspecified.
/// </summary>
Unspecified,

/// <summary>
/// The resize was due to the user resizing the window, for example by dragging the
/// window frame.
/// </summary>
User,

/// <summary>
/// The resize was initiated by the application, for example by setting one of the sizing-
/// related properties on <see cref="Window"/> such as <see cref="Layoutable.Width"/> or
/// <see cref="Layoutable.Height"/>.
/// </summary>
Application,

/// <summary>
/// The resize was initiated by the layout system.
/// </summary>
Layout,

/// <summary>
/// The resize was due to a change in DPI.
/// </summary>
DpiChange,
}

/// <summary>
/// Defines a platform-specific top-level window implementation.
/// </summary>
Expand Down Expand Up @@ -52,7 +87,7 @@ public interface ITopLevelImpl : IDisposable
/// <summary>
/// Gets or sets a method called when the toplevel is resized.
/// </summary>
Action<Size> Resized { get; set; }
Action<Size, PlatformResizeReason> Resized { get; set; }

/// <summary>
/// Gets or sets a method called when the toplevel's scaling changes.
Expand Down
4 changes: 3 additions & 1 deletion src/Avalonia.Controls/Platform/IWindowImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ public interface IWindowImpl : IWindowBaseImpl
/// <summary>
/// Sets the client size of the top level.
/// </summary>
void Resize(Size clientSize);
/// <param name="clientSize">The new client size.</param>
/// <param name="reason">The reason for the resize.</param>
void Resize(Size clientSize, PlatformResizeReason reason = PlatformResizeReason.Application);

/// <summary>
/// Sets the client size of the top level.
Expand Down
9 changes: 3 additions & 6 deletions src/Avalonia.Controls/Primitives/PopupRoot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,9 @@ protected override Size MeasureOverride(Size availableSize)

protected override sealed Size ArrangeSetBounds(Size size)
{
using (BeginAutoSizing())
{
_positionerParameters.Size = size;
UpdatePosition();
return ClientSize;
}
_positionerParameters.Size = size;
UpdatePosition();
return ClientSize;
}
}
}
6 changes: 5 additions & 1 deletion src/Avalonia.Controls/TopLevel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -360,11 +360,15 @@ protected virtual void HandleClosed()
LayoutManager?.Dispose();
}

[Obsolete("Use HandleResized(Size, PlatformResizeReason)")]
protected virtual void HandleResized(Size clientSize) => HandleResized(clientSize, PlatformResizeReason.Unspecified);

/// <summary>
/// Handles a resize notification from <see cref="ITopLevelImpl.Resized"/>.
/// </summary>
/// <param name="clientSize">The new client size.</param>
protected virtual void HandleResized(Size clientSize)
/// <param name="reason">The reason for the resize.</param>
protected virtual void HandleResized(Size clientSize, PlatformResizeReason reason)
{
ClientSize = clientSize;
Width = clientSize.Width;
Expand Down
Loading

0 comments on commit 069560e

Please sign in to comment.