From dff4fefa5d277b879d47f000f6711fb3470110b6 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sun, 13 Nov 2016 22:02:22 +0000 Subject: [PATCH 01/14] Add Win32 Methods to allow getting of MonitorInfo --- .../Interop/UnmanagedMethods.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs index d115b35a23..c2785095d0 100644 --- a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs +++ b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs @@ -850,6 +850,10 @@ namespace Avalonia.Win32.Interop [DllImport("user32.dll")] public static extern IntPtr MonitorFromWindow(IntPtr hwnd, MONITOR dwFlags); + + [DllImport("user32", EntryPoint = "GetMonitorInfoW", ExactSpelling = true, CharSet = CharSet.Unicode)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetMonitorInfo([In] IntPtr hMonitor, [Out] MONITORINFO lpmi); [return: MarshalAs(UnmanagedType.Bool)] [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] @@ -862,6 +866,23 @@ namespace Avalonia.Win32.Interop MONITOR_DEFAULTTONEAREST = 0x00000002, } + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + internal class MONITORINFO + { + public int cbSize = Marshal.SizeOf(typeof(MONITORINFO)); + public RECT rcMonitor = new RECT(); + public RECT rcWork = new RECT(); + public int dwFlags = 0; + + public enum MonitorOptions : uint + { + MONITOR_DEFAULTTONULL = 0x00000000, + MONITOR_DEFAULTTOPRIMARY = 0x00000001, + MONITOR_DEFAULTTONEAREST = 0x00000002 + } + } + + public enum PROCESS_DPI_AWARENESS { PROCESS_DPI_UNAWARE = 0, From 49f2d7b4770891b6fbea20298d5ebcb797c5f07f Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sun, 13 Nov 2016 22:03:01 +0000 Subject: [PATCH 02/14] WindowImpl on Win32 when no system decorations will not cover taskbar. --- src/Windows/Avalonia.Win32/WindowImpl.cs | 90 +++++++++++++++++------- 1 file changed, 66 insertions(+), 24 deletions(-) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 5db3f69f85..ba348b7d18 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -15,6 +15,7 @@ using Avalonia.Input.Raw; using Avalonia.Platform; using Avalonia.Win32.Input; using Avalonia.Win32.Interop; +using static Avalonia.Win32.Interop.UnmanagedMethods; namespace Avalonia.Win32 { @@ -135,7 +136,7 @@ namespace Avalonia.Win32 { var placement = default(UnmanagedMethods.WINDOWPLACEMENT); UnmanagedMethods.GetWindowPlacement(_hwnd, ref placement); - + switch (placement.ShowCmd) { case UnmanagedMethods.ShowWindowCommand.Maximize: @@ -184,22 +185,32 @@ namespace Avalonia.Win32 public void SetSystemDecorations(bool value) { if (value == _decorated) + { return; - var style = (UnmanagedMethods.WindowStyles) UnmanagedMethods.GetWindowLong(_hwnd, -16); + } + + var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, -16); + style |= UnmanagedMethods.WindowStyles.WS_OVERLAPPEDWINDOW; + if (!value) + { style ^= UnmanagedMethods.WindowStyles.WS_OVERLAPPEDWINDOW; + } UnmanagedMethods.RECT windowRect; UnmanagedMethods.GetWindowRect(_hwnd, out windowRect); + Rect newRect; var oldThickness = BorderThickness; - UnmanagedMethods.SetWindowLong(_hwnd, -16, (uint) style); + UnmanagedMethods.SetWindowLong(_hwnd, -16, (uint)style); + if (value) { var thickness = BorderThickness; + newRect = new Rect( windowRect.left - thickness.Left, windowRect.top - thickness.Top, @@ -207,19 +218,20 @@ namespace Avalonia.Win32 (windowRect.bottom - windowRect.top) + (thickness.Top + thickness.Bottom)); } else + { newRect = new Rect( - windowRect.left + oldThickness.Left, - windowRect.top + oldThickness.Top, - (windowRect.right - windowRect.left) - (oldThickness.Left + oldThickness.Right), - (windowRect.bottom - windowRect.top) - (oldThickness.Top + oldThickness.Bottom)); - UnmanagedMethods.SetWindowPos(_hwnd, IntPtr.Zero, (int) newRect.X, (int) newRect.Y, (int) newRect.Width, - (int) newRect.Height, + windowRect.left + oldThickness.Left, + windowRect.top + oldThickness.Top, + (windowRect.right - windowRect.left) - (oldThickness.Left + oldThickness.Right), + (windowRect.bottom - windowRect.top) - (oldThickness.Top + oldThickness.Bottom)); + } + + UnmanagedMethods.SetWindowPos(_hwnd, IntPtr.Zero, (int)newRect.X, (int)newRect.Y, (int)newRect.Width, + (int)newRect.Height, UnmanagedMethods.SetWindowPosFlags.SWP_NOZORDER | UnmanagedMethods.SetWindowPosFlags.SWP_NOACTIVATE); _decorated = value; - - } public void Invalidate(Rect rect) @@ -268,7 +280,7 @@ namespace Avalonia.Win32 public void BeginMoveDrag() { - UnmanagedMethods.DefWindowProc(_hwnd, (int) UnmanagedMethods.WindowsMessage.WM_NCLBUTTONDOWN, + UnmanagedMethods.DefWindowProc(_hwnd, (int)UnmanagedMethods.WindowsMessage.WM_NCLBUTTONDOWN, new IntPtr((int)UnmanagedMethods.HitTestValues.HTCAPTION), IntPtr.Zero); } @@ -286,8 +298,8 @@ namespace Avalonia.Win32 public void BeginResizeDrag(WindowEdge edge) { - UnmanagedMethods.DefWindowProc(_hwnd, (int) UnmanagedMethods.WindowsMessage.WM_NCLBUTTONDOWN, - new IntPtr((int) EdgeDic[edge]), IntPtr.Zero); + UnmanagedMethods.DefWindowProc(_hwnd, (int)UnmanagedMethods.WindowsMessage.WM_NCLBUTTONDOWN, + new IntPtr((int)EdgeDic[edge]), IntPtr.Zero); } public Point Position @@ -303,8 +315,8 @@ namespace Avalonia.Win32 UnmanagedMethods.SetWindowPos( Handle.Handle, IntPtr.Zero, - (int) value.X, - (int) value.Y, + (int)value.X, + (int)value.Y, 0, 0, UnmanagedMethods.SetWindowPosFlags.SWP_NOSIZE | UnmanagedMethods.SetWindowPosFlags.SWP_NOACTIVATE); @@ -454,7 +466,7 @@ namespace Avalonia.Win32 : RawMouseEventType.MiddleButtonDown, DipFromLParam(lParam), GetMouseModifiers(wParam)); break; - + case UnmanagedMethods.WindowsMessage.WM_LBUTTONUP: case UnmanagedMethods.WindowsMessage.WM_RBUTTONUP: case UnmanagedMethods.WindowsMessage.WM_MBUTTONUP: @@ -462,9 +474,9 @@ namespace Avalonia.Win32 WindowsMouseDevice.Instance, timestamp, _owner, - msg == (int) UnmanagedMethods.WindowsMessage.WM_LBUTTONUP + msg == (int)UnmanagedMethods.WindowsMessage.WM_LBUTTONUP ? RawMouseEventType.LeftButtonUp - : msg == (int) UnmanagedMethods.WindowsMessage.WM_RBUTTONUP + : msg == (int)UnmanagedMethods.WindowsMessage.WM_RBUTTONUP ? RawMouseEventType.RightButtonUp : RawMouseEventType.MiddleButtonUp, DipFromLParam(lParam), GetMouseModifiers(wParam)); @@ -508,7 +520,7 @@ namespace Avalonia.Win32 timestamp, _owner, ScreenToClient(DipFromLParam(lParam)), - new Vector(-(ToInt32(wParam) >> 16) / wheelDelta,0), GetMouseModifiers(wParam)); + new Vector(-(ToInt32(wParam) >> 16) / wheelDelta, 0), GetMouseModifiers(wParam)); break; case UnmanagedMethods.WindowsMessage.WM_MOUSELEAVE: @@ -585,9 +597,9 @@ namespace Avalonia.Win32 var modifiers = WindowsKeyboardDevice.Instance.Modifiers; if (keys.HasFlag(UnmanagedMethods.ModifierKeys.MK_LBUTTON)) modifiers |= InputModifiers.LeftMouseButton; - if(keys.HasFlag(UnmanagedMethods.ModifierKeys.MK_RBUTTON)) - modifiers |= InputModifiers.RightMouseButton; - if(keys.HasFlag(UnmanagedMethods.ModifierKeys.MK_MBUTTON)) + if (keys.HasFlag(UnmanagedMethods.ModifierKeys.MK_RBUTTON)) + modifiers |= InputModifiers.RightMouseButton; + if (keys.HasFlag(UnmanagedMethods.ModifierKeys.MK_MBUTTON)) modifiers |= InputModifiers.MiddleMouseButton; return modifiers; } @@ -666,6 +678,8 @@ namespace Avalonia.Win32 { UnmanagedMethods.ShowWindowCommand command; + bool doShow = true; + switch (state) { case WindowState.Minimized: @@ -673,7 +687,31 @@ namespace Avalonia.Win32 break; case WindowState.Maximized: command = UnmanagedMethods.ShowWindowCommand.Maximize; + + if (!_decorated) + { + IntPtr monitor = MonitorFromWindow(_hwnd, MONITOR.MONITOR_DEFAULTTONEAREST); + + if (monitor != IntPtr.Zero) + { + MONITORINFO monitorInfo = new MONITORINFO(); + + if (UnmanagedMethods.GetMonitorInfo(monitor, monitorInfo)) + { + RECT rcMonitorArea = monitorInfo.rcMonitor; + + var x = monitorInfo.rcWork.left; + var y = monitorInfo.rcWork.top; + var cx = Math.Abs(monitorInfo.rcWork.right - x); + var cy = Math.Abs(monitorInfo.rcWork.bottom - y); + + doShow = false; + UnmanagedMethods.SetWindowPos(_hwnd, new IntPtr(-2), x, y, cx, cy, SetWindowPosFlags.SWP_SHOWWINDOW); + } + } + } break; + case WindowState.Normal: command = UnmanagedMethods.ShowWindowCommand.Restore; break; @@ -681,7 +719,11 @@ namespace Avalonia.Win32 throw new ArgumentException("Invalid WindowState."); } - UnmanagedMethods.ShowWindow(_hwnd, command); + if (doShow) + { + UnmanagedMethods.ShowWindow(_hwnd, command); + } + UnmanagedMethods.SetFocus(_hwnd); } From ae40a3fa5627e1dfc946c399d3100ce2dba6bd5b Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sun, 13 Nov 2016 22:17:46 +0000 Subject: [PATCH 03/14] Add IgnoreTaskbarWhenMaximized property to IWindowImpl --- src/Avalonia.Controls/Window.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs index e0d5cddc9e..2c83cfe1c0 100644 --- a/src/Avalonia.Controls/Window.cs +++ b/src/Avalonia.Controls/Window.cs @@ -64,6 +64,12 @@ namespace Avalonia.Controls public static readonly StyledProperty HasSystemDecorationsProperty = AvaloniaProperty.Register(nameof(HasSystemDecorations), true); + /// + /// When system window decorations are disables sets if the Window when maximized ignores the taskbar. + /// + public static readonly StyledProperty IgnoreTaskbarOnMaximizeProperty = + AvaloniaProperty.Register(nameof(IgnoreTaskBarOnMaximize), false); + /// /// Defines the property. /// @@ -89,6 +95,10 @@ namespace Avalonia.Controls TitleProperty.Changed.AddClassHandler((s, e) => s.PlatformImpl.SetTitle((string)e.NewValue)); HasSystemDecorationsProperty.Changed.AddClassHandler( (s, e) => s.PlatformImpl.SetSystemDecorations((bool) e.NewValue)); + + IgnoreTaskbarOnMaximizeProperty.Changed.AddClassHandler( + (s, e) => s.PlatformImpl.SetIgnoreTaskBarWhenMaximized((bool)e.NewValue)); + IconProperty.Changed.AddClassHandler((s, e) => s.PlatformImpl.SetIcon(((WindowIcon)e.NewValue).PlatformImpl)); } @@ -157,6 +167,15 @@ namespace Avalonia.Controls set { SetValue(HasSystemDecorationsProperty, value); } } + /// + /// When system window decorations are disables sets if the Window when maximized ignores the taskbar. + /// + public bool IgnoreTaskBarOnMaximize + { + get { return GetValue(IgnoreTaskbarOnMaximizeProperty); } + set { SetValue(IgnoreTaskbarOnMaximizeProperty, value); } + } + /// /// Gets or sets the minimized/maximized state of the window. /// From 96c2f947d7cab9c4e4eb938bce815d2d1938061c Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sun, 13 Nov 2016 22:21:36 +0000 Subject: [PATCH 04/14] Implemented SetIgnoreTaskBarWhenMaxmimized for Win32 --- src/Avalonia.Controls/Platform/IWindowImpl.cs | 5 +++++ src/Windows/Avalonia.Win32/WindowImpl.cs | 13 ++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.Controls/Platform/IWindowImpl.cs b/src/Avalonia.Controls/Platform/IWindowImpl.cs index 609e9834cb..b8429d32fc 100644 --- a/src/Avalonia.Controls/Platform/IWindowImpl.cs +++ b/src/Avalonia.Controls/Platform/IWindowImpl.cs @@ -35,6 +35,11 @@ namespace Avalonia.Platform /// void SetSystemDecorations(bool enabled); + /// + /// When system decorations are disabled sets if the maximized state covers the entire screen or just the working area. + /// + void SetIgnoreTaskBarWhenMaximized(bool enable); + /// /// Sets the icon of this window. /// diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index ba348b7d18..c2ef66ce13 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -33,6 +33,7 @@ namespace Avalonia.Win32 private bool _trackingMouse; private bool _isActive; private bool _decorated = true; + private bool _ignoreTaskBarWhenMaximized = true; private double _scaling = 1; private WindowState _showWindowState; @@ -688,7 +689,7 @@ namespace Avalonia.Win32 case WindowState.Maximized: command = UnmanagedMethods.ShowWindowCommand.Maximize; - if (!_decorated) + if (!_decorated && !_ignoreTaskBarWhenMaximized) { IntPtr monitor = MonitorFromWindow(_hwnd, MONITOR.MONITOR_DEFAULTTONEAREST); @@ -741,5 +742,15 @@ namespace Avalonia.Win32 return (int)(ptr.ToInt64() & 0xffffffff); } + + public void SetIgnoreTaskBarWhenMaximized(bool enable) + { + _ignoreTaskBarWhenMaximized = enable; + + if(_showWindowState == WindowState.Maximized) + { + ShowWindow(WindowState.Maximized); + } + } } } From 5cd8d3cfe77c1108b8a6ceb02babe215e5eee666 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sun, 13 Nov 2016 22:34:43 +0000 Subject: [PATCH 05/14] Corrected default value for IgnoreTaskBarOnMaximizeProperty --- src/Avalonia.Controls/Window.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs index 2c83cfe1c0..ae3846096a 100644 --- a/src/Avalonia.Controls/Window.cs +++ b/src/Avalonia.Controls/Window.cs @@ -68,7 +68,7 @@ namespace Avalonia.Controls /// When system window decorations are disables sets if the Window when maximized ignores the taskbar. /// public static readonly StyledProperty IgnoreTaskbarOnMaximizeProperty = - AvaloniaProperty.Register(nameof(IgnoreTaskBarOnMaximize), false); + AvaloniaProperty.Register(nameof(IgnoreTaskBarOnMaximize), true); /// /// Defines the property. From 1efbb9823b63dff49d94f15d60edadea079827c4 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sun, 13 Nov 2016 22:58:45 +0000 Subject: [PATCH 06/14] Fix Win32 WindowImplement to allow it to restore window size when SystemDecorations=false and IgnoreTaskBarWhenMaximized=false --- src/Windows/Avalonia.Win32/WindowImpl.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index c2ef66ce13..d516624224 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -679,7 +679,7 @@ namespace Avalonia.Win32 { UnmanagedMethods.ShowWindowCommand command; - bool doShow = true; + Action afterShow = null; switch (state) { @@ -706,8 +706,10 @@ namespace Avalonia.Win32 var cx = Math.Abs(monitorInfo.rcWork.right - x); var cy = Math.Abs(monitorInfo.rcWork.bottom - y); - doShow = false; - UnmanagedMethods.SetWindowPos(_hwnd, new IntPtr(-2), x, y, cx, cy, SetWindowPosFlags.SWP_SHOWWINDOW); + afterShow = () => + { + UnmanagedMethods.SetWindowPos(_hwnd, new IntPtr(-2), x, y, cx, cy, SetWindowPosFlags.SWP_SHOWWINDOW); + }; } } } @@ -716,13 +718,16 @@ namespace Avalonia.Win32 case WindowState.Normal: command = UnmanagedMethods.ShowWindowCommand.Restore; break; + default: throw new ArgumentException("Invalid WindowState."); } - if (doShow) + UnmanagedMethods.ShowWindow(_hwnd, command); + + if (afterShow != null) { - UnmanagedMethods.ShowWindow(_hwnd, command); + afterShow(); } UnmanagedMethods.SetFocus(_hwnd); From 4b33c02008b0bd6e801ef2406e51a03c7706da8b Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sun, 13 Nov 2016 23:21:20 +0000 Subject: [PATCH 07/14] Completed Gtk Window implementation. --- src/Gtk/Avalonia.Gtk/WindowImplBase.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Gtk/Avalonia.Gtk/WindowImplBase.cs b/src/Gtk/Avalonia.Gtk/WindowImplBase.cs index a9ecfa4058..bcb24e7a29 100644 --- a/src/Gtk/Avalonia.Gtk/WindowImplBase.cs +++ b/src/Gtk/Avalonia.Gtk/WindowImplBase.cs @@ -304,6 +304,11 @@ namespace Avalonia.Gtk args.RetVal = true; } + public void SetIgnoreTaskBarWhenMaximized(bool enable) + { + // No action neccesary on Gtk. + } + public void Dispose() { _window.Hide(); From 07b06aa148df69a5b3bb98c6dd91ff31365a6655 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sun, 13 Nov 2016 23:22:57 +0000 Subject: [PATCH 08/14] Completed Ios AvaloniaView implementation. --- src/iOS/Avalonia.iOS/AvaloniaView.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/iOS/Avalonia.iOS/AvaloniaView.cs b/src/iOS/Avalonia.iOS/AvaloniaView.cs index 8b14d09573..566d924993 100644 --- a/src/iOS/Avalonia.iOS/AvaloniaView.cs +++ b/src/iOS/Avalonia.iOS/AvaloniaView.cs @@ -170,6 +170,11 @@ namespace Avalonia.iOS //Not supported } + public void SetIgnoreTaskBarWhenMaximized(bool enable) + { + //Not supported + } + public override void TouchesEnded(NSSet touches, UIEvent evt) { var touch = touches.AnyObject as UITouch; From dec5682dce412f93b3f3bd85c4a697c726e4af78 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sun, 13 Nov 2016 23:26:33 +0000 Subject: [PATCH 09/14] Completed Andriod IWindowImpl --- .../Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs index c5e3622404..31b41ecaf5 100644 --- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs +++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs @@ -107,6 +107,12 @@ namespace Avalonia.Android.Platform.SkiaPlatform public void SetSystemDecorations(bool enabled) { } + + public void SetIgnoreTaskBarWhenMaximized(bool enable) + { + //Not supported + } + public void Invalidate(Rect rect) { if (Holder?.Surface?.IsValid == true) base.Invalidate(); From 198f18df66bcfa301f940bc84b1273fe06039c86 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 16 Nov 2016 21:00:36 +0000 Subject: [PATCH 10/14] Fix indentation. --- src/Windows/Avalonia.Win32/WindowImpl.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index d516624224..03e76207bf 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -213,10 +213,10 @@ namespace Avalonia.Win32 var thickness = BorderThickness; newRect = new Rect( - windowRect.left - thickness.Left, - windowRect.top - thickness.Top, - (windowRect.right - windowRect.left) + (thickness.Left + thickness.Right), - (windowRect.bottom - windowRect.top) + (thickness.Top + thickness.Bottom)); + windowRect.left - thickness.Left, + windowRect.top - thickness.Top, + (windowRect.right - windowRect.left) + (thickness.Left + thickness.Right), + (windowRect.bottom - windowRect.top) + (thickness.Top + thickness.Bottom)); } else { @@ -231,7 +231,6 @@ namespace Avalonia.Win32 (int)newRect.Height, UnmanagedMethods.SetWindowPosFlags.SWP_NOZORDER | UnmanagedMethods.SetWindowPosFlags.SWP_NOACTIVATE); - _decorated = value; } From 4c4342e2ddca73977d741b47de4235fa0e386889 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 16 Nov 2016 21:07:11 +0000 Subject: [PATCH 11/14] refactored to seperate method. --- src/Windows/Avalonia.Win32/WindowImpl.cs | 60 ++++++++++++------------ 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 03e76207bf..4d0c97dfd6 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -678,44 +678,24 @@ namespace Avalonia.Win32 { UnmanagedMethods.ShowWindowCommand command; - Action afterShow = null; + bool maximizeFillsDesktop = false; // otherwise we cover entire screen. switch (state) { case WindowState.Minimized: - command = UnmanagedMethods.ShowWindowCommand.Minimize; + command = ShowWindowCommand.Minimize; break; case WindowState.Maximized: - command = UnmanagedMethods.ShowWindowCommand.Maximize; + command = ShowWindowCommand.Maximize; if (!_decorated && !_ignoreTaskBarWhenMaximized) { - IntPtr monitor = MonitorFromWindow(_hwnd, MONITOR.MONITOR_DEFAULTTONEAREST); - - if (monitor != IntPtr.Zero) - { - MONITORINFO monitorInfo = new MONITORINFO(); - - if (UnmanagedMethods.GetMonitorInfo(monitor, monitorInfo)) - { - RECT rcMonitorArea = monitorInfo.rcMonitor; - - var x = monitorInfo.rcWork.left; - var y = monitorInfo.rcWork.top; - var cx = Math.Abs(monitorInfo.rcWork.right - x); - var cy = Math.Abs(monitorInfo.rcWork.bottom - y); - - afterShow = () => - { - UnmanagedMethods.SetWindowPos(_hwnd, new IntPtr(-2), x, y, cx, cy, SetWindowPosFlags.SWP_SHOWWINDOW); - }; - } - } + maximizeFillsDesktop = true; } break; case WindowState.Normal: - command = UnmanagedMethods.ShowWindowCommand.Restore; + command = ShowWindowCommand.Restore; break; default: @@ -724,12 +704,34 @@ namespace Avalonia.Win32 UnmanagedMethods.ShowWindow(_hwnd, command); - if (afterShow != null) + if(maximizeFillsDesktop) { - afterShow(); - } + MaximizeWithoutCoveringTaskbar(); + } + + SetFocus(_hwnd); + } + + private void MaximizeWithoutCoveringTaskbar() + { + IntPtr monitor = MonitorFromWindow(_hwnd, MONITOR.MONITOR_DEFAULTTONEAREST); - UnmanagedMethods.SetFocus(_hwnd); + if (monitor != IntPtr.Zero) + { + MONITORINFO monitorInfo = new MONITORINFO(); + + if (GetMonitorInfo(monitor, monitorInfo)) + { + RECT rcMonitorArea = monitorInfo.rcMonitor; + + var x = monitorInfo.rcWork.left; + var y = monitorInfo.rcWork.top; + var cx = Math.Abs(monitorInfo.rcWork.right - x); + var cy = Math.Abs(monitorInfo.rcWork.bottom - y); + + SetWindowPos(_hwnd, new IntPtr(-2), x, y, cx, cy, SetWindowPosFlags.SWP_SHOWWINDOW); + } + } } public void SetIcon(IWindowIconImpl icon) From 43cac2c5620f1eace8882c35ce124a68396e39d9 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 16 Nov 2016 21:20:09 +0000 Subject: [PATCH 12/14] Renamed property to CoverTaskbarWhenMaximized. --- .../Platform/SkiaPlatform/WindowImpl.cs | 2 +- src/Avalonia.Controls/Platform/IWindowImpl.cs | 2 +- src/Avalonia.Controls/Window.cs | 17 +++++++++-------- src/Gtk/Avalonia.Gtk/WindowImplBase.cs | 2 +- src/Windows/Avalonia.Win32/WindowImpl.cs | 8 ++++---- src/iOS/Avalonia.iOS/AvaloniaView.cs | 2 +- 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs index 31b41ecaf5..0e1540b5fd 100644 --- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs +++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs @@ -108,7 +108,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform { } - public void SetIgnoreTaskBarWhenMaximized(bool enable) + public void SetCoverTaskbarWhenMaximized(bool enable) { //Not supported } diff --git a/src/Avalonia.Controls/Platform/IWindowImpl.cs b/src/Avalonia.Controls/Platform/IWindowImpl.cs index b8429d32fc..fd2feb539f 100644 --- a/src/Avalonia.Controls/Platform/IWindowImpl.cs +++ b/src/Avalonia.Controls/Platform/IWindowImpl.cs @@ -38,7 +38,7 @@ namespace Avalonia.Platform /// /// When system decorations are disabled sets if the maximized state covers the entire screen or just the working area. /// - void SetIgnoreTaskBarWhenMaximized(bool enable); + void SetCoverTaskbarWhenMaximized(bool enable); /// /// Sets the icon of this window. diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs index ae3846096a..a66bba1861 100644 --- a/src/Avalonia.Controls/Window.cs +++ b/src/Avalonia.Controls/Window.cs @@ -67,8 +67,8 @@ namespace Avalonia.Controls /// /// When system window decorations are disables sets if the Window when maximized ignores the taskbar. /// - public static readonly StyledProperty IgnoreTaskbarOnMaximizeProperty = - AvaloniaProperty.Register(nameof(IgnoreTaskBarOnMaximize), true); + public static readonly StyledProperty CoverTaskbarOnMaximizeProperty = + AvaloniaProperty.Register(nameof(CoverTaskbarOnMaximize), true); /// /// Defines the property. @@ -96,8 +96,8 @@ namespace Avalonia.Controls HasSystemDecorationsProperty.Changed.AddClassHandler( (s, e) => s.PlatformImpl.SetSystemDecorations((bool) e.NewValue)); - IgnoreTaskbarOnMaximizeProperty.Changed.AddClassHandler( - (s, e) => s.PlatformImpl.SetIgnoreTaskBarWhenMaximized((bool)e.NewValue)); + CoverTaskbarOnMaximizeProperty.Changed.AddClassHandler( + (s, e) => s.PlatformImpl.SetCoverTaskbarWhenMaximized((bool)e.NewValue)); IconProperty.Changed.AddClassHandler((s, e) => s.PlatformImpl.SetIcon(((WindowIcon)e.NewValue).PlatformImpl)); } @@ -168,12 +168,13 @@ namespace Avalonia.Controls } /// - /// When system window decorations are disables sets if the Window when maximized ignores the taskbar. + /// Sets if the Window should Covert the taskbar when Maximized. Only applies to Windows + /// with HasSystemDecorations = false. /// - public bool IgnoreTaskBarOnMaximize + public bool CoverTaskbarOnMaximize { - get { return GetValue(IgnoreTaskbarOnMaximizeProperty); } - set { SetValue(IgnoreTaskbarOnMaximizeProperty, value); } + get { return GetValue(CoverTaskbarOnMaximizeProperty); } + set { SetValue(CoverTaskbarOnMaximizeProperty, value); } } /// diff --git a/src/Gtk/Avalonia.Gtk/WindowImplBase.cs b/src/Gtk/Avalonia.Gtk/WindowImplBase.cs index bcb24e7a29..8641f2f431 100644 --- a/src/Gtk/Avalonia.Gtk/WindowImplBase.cs +++ b/src/Gtk/Avalonia.Gtk/WindowImplBase.cs @@ -304,7 +304,7 @@ namespace Avalonia.Gtk args.RetVal = true; } - public void SetIgnoreTaskBarWhenMaximized(bool enable) + public void SetCoverTaskbarWhenMaximized(bool enable) { // No action neccesary on Gtk. } diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 4d0c97dfd6..0febe70876 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -33,7 +33,7 @@ namespace Avalonia.Win32 private bool _trackingMouse; private bool _isActive; private bool _decorated = true; - private bool _ignoreTaskBarWhenMaximized = true; + private bool _coverTaskBarWhenMaximized = true; private double _scaling = 1; private WindowState _showWindowState; @@ -688,7 +688,7 @@ namespace Avalonia.Win32 case WindowState.Maximized: command = ShowWindowCommand.Maximize; - if (!_decorated && !_ignoreTaskBarWhenMaximized) + if (!_decorated && !_coverTaskBarWhenMaximized) { maximizeFillsDesktop = true; } @@ -749,9 +749,9 @@ namespace Avalonia.Win32 return (int)(ptr.ToInt64() & 0xffffffff); } - public void SetIgnoreTaskBarWhenMaximized(bool enable) + public void SetCoverTaskbarWhenMaximized(bool enable) { - _ignoreTaskBarWhenMaximized = enable; + _coverTaskBarWhenMaximized = enable; if(_showWindowState == WindowState.Maximized) { diff --git a/src/iOS/Avalonia.iOS/AvaloniaView.cs b/src/iOS/Avalonia.iOS/AvaloniaView.cs index 566d924993..67817ef62a 100644 --- a/src/iOS/Avalonia.iOS/AvaloniaView.cs +++ b/src/iOS/Avalonia.iOS/AvaloniaView.cs @@ -170,7 +170,7 @@ namespace Avalonia.iOS //Not supported } - public void SetIgnoreTaskBarWhenMaximized(bool enable) + public void SetCoverTaskbarWhenMaximized(bool enable) { //Not supported } From 1ab0a87780f3dc4f6e0ef1581d3f912970356ed3 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 16 Nov 2016 21:49:24 +0000 Subject: [PATCH 13/14] fix comments. --- src/Avalonia.Controls/Window.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs index a66bba1861..6755dee073 100644 --- a/src/Avalonia.Controls/Window.cs +++ b/src/Avalonia.Controls/Window.cs @@ -65,7 +65,8 @@ namespace Avalonia.Controls AvaloniaProperty.Register(nameof(HasSystemDecorations), true); /// - /// When system window decorations are disables sets if the Window when maximized ignores the taskbar. + /// Sets if the window should cover the taskbar when maximized. Only applies to Windows + /// with HasSystemDecorations = false. /// public static readonly StyledProperty CoverTaskbarOnMaximizeProperty = AvaloniaProperty.Register(nameof(CoverTaskbarOnMaximize), true); @@ -168,7 +169,7 @@ namespace Avalonia.Controls } /// - /// Sets if the Window should Covert the taskbar when Maximized. Only applies to Windows + /// Sets if the window should cover the taskbar when maximized. Only applies to Windows /// with HasSystemDecorations = false. /// public bool CoverTaskbarOnMaximize From 3e5d0e69b0d42d5bb713250786e003470fce2c33 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 16 Nov 2016 21:54:05 +0000 Subject: [PATCH 14/14] fix indentation. --- src/Windows/Avalonia.Win32/WindowImpl.cs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 0febe70876..2129090a64 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -213,18 +213,18 @@ namespace Avalonia.Win32 var thickness = BorderThickness; newRect = new Rect( - windowRect.left - thickness.Left, - windowRect.top - thickness.Top, - (windowRect.right - windowRect.left) + (thickness.Left + thickness.Right), - (windowRect.bottom - windowRect.top) + (thickness.Top + thickness.Bottom)); + windowRect.left - thickness.Left, + windowRect.top - thickness.Top, + (windowRect.right - windowRect.left) + (thickness.Left + thickness.Right), + (windowRect.bottom - windowRect.top) + (thickness.Top + thickness.Bottom)); } else { newRect = new Rect( - windowRect.left + oldThickness.Left, - windowRect.top + oldThickness.Top, - (windowRect.right - windowRect.left) - (oldThickness.Left + oldThickness.Right), - (windowRect.bottom - windowRect.top) - (oldThickness.Top + oldThickness.Bottom)); + windowRect.left + oldThickness.Left, + windowRect.top + oldThickness.Top, + (windowRect.right - windowRect.left) - (oldThickness.Left + oldThickness.Right), + (windowRect.bottom - windowRect.top) - (oldThickness.Top + oldThickness.Bottom)); } UnmanagedMethods.SetWindowPos(_hwnd, IntPtr.Zero, (int)newRect.X, (int)newRect.Y, (int)newRect.Width, @@ -704,10 +704,10 @@ namespace Avalonia.Win32 UnmanagedMethods.ShowWindow(_hwnd, command); - if(maximizeFillsDesktop) + if (maximizeFillsDesktop) { MaximizeWithoutCoveringTaskbar(); - } + } SetFocus(_hwnd); } @@ -729,7 +729,7 @@ namespace Avalonia.Win32 var cx = Math.Abs(monitorInfo.rcWork.right - x); var cy = Math.Abs(monitorInfo.rcWork.bottom - y); - SetWindowPos(_hwnd, new IntPtr(-2), x, y, cx, cy, SetWindowPosFlags.SWP_SHOWWINDOW); + SetWindowPos(_hwnd, new IntPtr(-2), x, y, cx, cy, SetWindowPosFlags.SWP_SHOWWINDOW); } } } @@ -753,7 +753,7 @@ namespace Avalonia.Win32 { _coverTaskBarWhenMaximized = enable; - if(_showWindowState == WindowState.Maximized) + if (_showWindowState == WindowState.Maximized) { ShowWindow(WindowState.Maximized); }