From bcfe0305a6abf802d5f7ec4a117f4d634e241dcb Mon Sep 17 00:00:00 2001 From: awaescher Date: Thu, 6 Jul 2023 22:22:57 +0200 Subject: [PATCH] Remove dependency to MahApps.Metro --- ReadMe.md | 5 +- StageManager/MainWindow.xaml.cs | 3 +- StageManager/Native/VisualHelper.cs | 82 +++++++++++++++++++++++++++++ StageManager/StageManager.csproj | 36 ++++++------- 4 files changed, 105 insertions(+), 21 deletions(-) create mode 100644 StageManager/Native/VisualHelper.cs diff --git a/ReadMe.md b/ReadMe.md index 9d3dec5..f707a46 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -15,7 +15,7 @@ Download and run the executable from the [Releases tab](https://github.com/awaes - cd into the repository directory - run `dotnet run --project StageManager` -To quit, find the app's tray icon (Windows might have moved this in the overflow menu) and use its context menu to close the app. +To quit, find the app's tray icon (Windows might move it into the overflow menu) and use its context menu to close the app. ### Requirements - Windows 10 version 2004 or newer @@ -35,6 +35,8 @@ This is an experimental fun project. I don't have any idea whether or not this i |scene management with drag&drop|✅| |restore windows on quit/restart|✅| |auto hide & fly-in scenes for maximized windows|✅| +|full screenshots for windows that were minimized on startup|⬜| +|drag windows from other scenes into the current one|✅| |place screenshots in relative size of the desktop|⬜| |place app icons over 3D window adorners|⬜| |rounded corners for the window thumbnails|⬜| @@ -45,6 +47,7 @@ This is an experimental fun project. I don't have any idea whether or not this i |**Product stage**|| |virtual desktop support (pin window)|⬜| |multi-monitor support|⬜| +|visual feedback when dragging windows from other scenes|⬜| |feature parity with macOS Stage Manager|⬜| |**Polishing stage**|| |window animations|⬜| diff --git a/StageManager/MainWindow.xaml.cs b/StageManager/MainWindow.xaml.cs index f8d037a..e9e3acc 100644 --- a/StageManager/MainWindow.xaml.cs +++ b/StageManager/MainWindow.xaml.cs @@ -1,5 +1,4 @@ using AsyncAwaitBestPractices; -using MahApps.Metro.Controls; using Microsoft.Xaml.Behaviors.Core; using SharpHook; using StageManager.Model; @@ -64,7 +63,7 @@ protected override void OnInitialized(EventArgs e) _hook.MouseReleased += OnMouseReleased; _hook.MouseMoved += _hook_MouseMoved; - Task.Run(() => _hook.Run()); + Task.Run(_hook.Run); } protected override void OnClosed(EventArgs e) diff --git a/StageManager/Native/VisualHelper.cs b/StageManager/Native/VisualHelper.cs new file mode 100644 index 0000000..54390e5 --- /dev/null +++ b/StageManager/Native/VisualHelper.cs @@ -0,0 +1,82 @@ +// This file contains two methods taken from MahApps.Metro to be able to remove the NuGet dependency. + +// Taken from +// MahApps.Metro/src/MahApps.Metro/Controls/WinApiHelper.cs +// MahApps.Metro/src/MahApps.Metro/Controls/TreeHelper.cs + +// Original license header: +// +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using ControlzEx.Standard; +using System; +using System.Windows; +using System.Windows.Interop; +using System.Windows.Media; + +namespace StageManager.Native +{ + public static class VisualHelper + { + /// + /// Get the working area size of the monitor from where the visual stays. + /// + /// The visual element to get the monitor information. + /// The working area size of the monitor. + public static Size GetMonitorWorkSize(this Visual visual) + { + if (visual != null) + { + var hwndSource = PresentationSource.FromVisual(visual) as HwndSource; + if (hwndSource != null && !hwndSource.IsDisposed && hwndSource.RootVisual != null && hwndSource.Handle != IntPtr.Zero) + { + IntPtr intPtr = NativeMethods.MonitorFromWindow(hwndSource.Handle, MonitorOptions.MONITOR_DEFAULTTONEAREST); + if (intPtr != IntPtr.Zero) + { + var monitorInfoW = NativeMethods.GetMonitorInfoW(intPtr); + return new Size(monitorInfoW.rcWork.Width, monitorInfoW.rcWork.Height); + } + } + } + + return default; + } + + /// + /// This method is an alternative to WPF's method, which also supports content elements. Keep in mind that for content element, this method falls back to the logical tree of the element! + /// + /// The item to be processed. + /// The submitted item's parent, if available. Otherwise null. + public static DependencyObject? GetParentObject(this DependencyObject? child) + { + if (child is null) + return null; + + // handle content elements separately + if (child is ContentElement contentElement) + { + DependencyObject parent = ContentOperations.GetParent(contentElement); + if (parent is not null) + return parent; + + return contentElement is FrameworkContentElement fce ? fce.Parent : null; + } + + var childParent = VisualTreeHelper.GetParent(child); + if (childParent is not null) + return childParent; + + // also try searching for parent in framework elements (such as DockPanel, etc) + if (child is FrameworkElement frameworkElement) + { + DependencyObject parent = frameworkElement.Parent; + if (parent is not null) + return parent; + } + + return null; + } + } +} diff --git a/StageManager/StageManager.csproj b/StageManager/StageManager.csproj index 7632198..4148369 100644 --- a/StageManager/StageManager.csproj +++ b/StageManager/StageManager.csproj @@ -1,24 +1,24 @@  - - WinExe - net7.0-windows - enable - true - true - StageManager.ico - + + WinExe + net7.0-windows + enable + true + true + StageManager.ico + - - - + + + - - - - - - - + + + + + + +