diff --git a/src/Avalonia.Controls/Platform/IWindowImpl.cs b/src/Avalonia.Controls/Platform/IWindowImpl.cs
index 3f2c977718..c5d632c0f7 100644
--- a/src/Avalonia.Controls/Platform/IWindowImpl.cs
+++ b/src/Avalonia.Controls/Platform/IWindowImpl.cs
@@ -16,6 +16,11 @@ namespace Avalonia.Platform
///
WindowState WindowState { get; set; }
+ ///
+ /// Gets or sets a method called when the changes.
+ ///
+ Action WindowStateChanged { get; set; }
+
///
/// Sets the title of the window.
///
diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs
index 16ee3a46b3..6814b8567e 100644
--- a/src/Avalonia.Controls/Window.cs
+++ b/src/Avalonia.Controls/Window.cs
@@ -136,6 +136,7 @@ namespace Avalonia.Controls
: base(impl)
{
impl.Closing = HandleClosing;
+ impl.WindowStateChanged = HandleWindowStateChanged;
_maxPlatformClientSize = PlatformImpl?.MaxClientSize ?? default(Size);
Screens = new Screens(PlatformImpl?.Screen);
}
@@ -308,6 +309,18 @@ namespace Avalonia.Controls
return args.Cancel;
}
+ protected virtual void HandleWindowStateChanged(WindowState state)
+ {
+ if (state == WindowState.Minimized)
+ {
+ Renderer.Stop();
+ }
+ else if (state == WindowState.Normal)
+ {
+ Renderer.Start();
+ }
+ }
+
///
/// Hides the window but does not close it.
///
diff --git a/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs b/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs
index 9750b46aa2..ef16d06b60 100644
--- a/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs
+++ b/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs
@@ -42,6 +42,7 @@ namespace Avalonia.DesignerSupport.Remote
public Func Closing { get; set; }
public IPlatformHandle Handle { get; }
public WindowState WindowState { get; set; }
+ public Action WindowStateChanged { get; set; }
public Size MaxClientSize { get; } = new Size(4096, 4096);
public event Action LostFocus;
diff --git a/src/Avalonia.DesignerSupport/Remote/Stubs.cs b/src/Avalonia.DesignerSupport/Remote/Stubs.cs
index ee8569d748..72fce0d921 100644
--- a/src/Avalonia.DesignerSupport/Remote/Stubs.cs
+++ b/src/Avalonia.DesignerSupport/Remote/Stubs.cs
@@ -32,6 +32,8 @@ namespace Avalonia.DesignerSupport.Remote
public Point Position { get; set; }
public Action PositionChanged { get; set; }
public WindowState WindowState { get; set; }
+ public Action WindowStateChanged { get; set; }
+
public IRenderer CreateRenderer(IRenderRoot root) => new ImmediateRenderer(root);
public void Dispose()
{
diff --git a/src/Gtk/Avalonia.Gtk3/WindowImpl.cs b/src/Gtk/Avalonia.Gtk3/WindowImpl.cs
index 2d309e19d4..ac03816b02 100644
--- a/src/Gtk/Avalonia.Gtk3/WindowImpl.cs
+++ b/src/Gtk/Avalonia.Gtk3/WindowImpl.cs
@@ -43,7 +43,9 @@ namespace Avalonia.Gtk3
}
}
}
-
+
+ public Action WindowStateChanged { get; set; }
+
public IDisposable ShowDialog()
{
Native.GtkWindowSetModal(GtkWidget, true);
diff --git a/src/OSX/Avalonia.MonoMac/WindowImpl.cs b/src/OSX/Avalonia.MonoMac/WindowImpl.cs
index d01cbd6ae3..43d6918112 100644
--- a/src/OSX/Avalonia.MonoMac/WindowImpl.cs
+++ b/src/OSX/Avalonia.MonoMac/WindowImpl.cs
@@ -49,6 +49,8 @@ namespace Avalonia.MonoMac
}
}
+ public Action WindowStateChanged { get; set; }
+
bool IsZoomed => IsDecorated ? Window.IsZoomed : UndecoratedIsMaximized;
public bool UndecoratedIsMaximized => Window.Frame == Window.Screen.VisibleFrame;
diff --git a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
index 5c24aa1c69..fef0ef747d 100644
--- a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
+++ b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
@@ -104,6 +104,30 @@ namespace Avalonia.Win32.Interop
ForceMinimize = 11
}
+ public enum SysCommands
+ {
+ SC_SIZE = 0xF000,
+ SC_MOVE = 0xF010,
+ SC_MINIMIZE = 0xF020,
+ SC_MAXIMIZE = 0xF030,
+ SC_NEXTWINDOW = 0xF040,
+ SC_PREVWINDOW = 0xF050,
+ SC_CLOSE = 0xF060,
+ SC_VSCROLL = 0xF070,
+ SC_HSCROLL = 0xF080,
+ SC_MOUSEMENU = 0xF090,
+ SC_KEYMENU = 0xF100,
+ SC_ARRANGE = 0xF110,
+ SC_RESTORE = 0xF120,
+ SC_TASKLIST = 0xF130,
+ SC_SCREENSAVE = 0xF140,
+ SC_HOTKEY = 0xF150,
+ SC_DEFAULT = 0xF160,
+ SC_MONITORPOWER = 0xF170,
+ SC_CONTEXTHELP = 0xF180,
+ SC_SEPARATOR = 0xF00F,
+ }
+
public enum SystemMetric
{
SM_CXSCREEN = 0, // 0x00
diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs
index cf6cb40e58..399a09ea6c 100644
--- a/src/Windows/Avalonia.Win32/WindowImpl.cs
+++ b/src/Windows/Avalonia.Win32/WindowImpl.cs
@@ -77,6 +77,8 @@ namespace Avalonia.Win32
public Action PositionChanged { get; set; }
+ public Action WindowStateChanged { get; set; }
+
public Thickness BorderThickness
{
get
@@ -627,6 +629,25 @@ namespace Avalonia.Win32
return IntPtr.Zero;
+ case UnmanagedMethods.WindowsMessage.WM_SYSCOMMAND:
+ if (WindowStateChanged != null)
+ {
+ switch ((SysCommands)wParam)
+ {
+ case SysCommands.SC_MINIMIZE:
+ WindowStateChanged(WindowState.Minimized);
+ break;
+ case SysCommands.SC_MAXIMIZE:
+ WindowStateChanged(WindowState.Maximized);
+ break;
+ case SysCommands.SC_RESTORE:
+ WindowStateChanged(WindowState.Normal);
+ break;
+ }
+ }
+
+ break;
+
case UnmanagedMethods.WindowsMessage.WM_MOVE:
PositionChanged?.Invoke(new Point((short)(ToInt32(lParam) & 0xffff), (short)(ToInt32(lParam) >> 16)));
return IntPtr.Zero;