Skip to content

Commit 5252d3e

Browse files
authored
Merge pull request #3271 from onesounds/250223FluentTest2
Fluent Window
2 parents e28a69c + 944393c commit 5252d3e

36 files changed

+1978
-1313
lines changed

Flow.Launcher.Core/Resource/Theme.cs

Lines changed: 444 additions & 91 deletions
Large diffs are not rendered by default.
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
using System.Collections.Generic;
2+
using System;
3+
using System.Runtime.InteropServices;
4+
using System.Windows;
5+
using Windows.Win32;
6+
using Windows.Win32.Foundation;
7+
using Windows.Win32.Graphics.Gdi;
8+
using Windows.Win32.UI.WindowsAndMessaging;
9+
10+
namespace Flow.Launcher.Infrastructure;
11+
12+
/// <summary>
13+
/// Contains full information about a display monitor.
14+
/// Codes are edited from: <see href="https://github.com/Jack251970/DesktopWidgets3">.
15+
/// </summary>
16+
internal class MonitorInfo
17+
{
18+
/// <summary>
19+
/// Gets the display monitors (including invisible pseudo-monitors associated with the mirroring drivers).
20+
/// </summary>
21+
/// <returns>A list of display monitors</returns>
22+
public static unsafe IList<MonitorInfo> GetDisplayMonitors()
23+
{
24+
var monitorCount = PInvoke.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CMONITORS);
25+
var list = new List<MonitorInfo>(monitorCount);
26+
var callback = new MONITORENUMPROC((HMONITOR monitor, HDC deviceContext, RECT* rect, LPARAM data) =>
27+
{
28+
list.Add(new MonitorInfo(monitor, rect));
29+
return true;
30+
});
31+
var dwData = new LPARAM();
32+
var hdc = new HDC();
33+
bool ok = PInvoke.EnumDisplayMonitors(hdc, (RECT?)null, callback, dwData);
34+
if (!ok)
35+
{
36+
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
37+
}
38+
return list;
39+
}
40+
41+
/// <summary>
42+
/// Gets the display monitor that is nearest to a given window.
43+
/// </summary>
44+
/// <param name="hwnd">Window handle</param>
45+
/// <returns>The display monitor that is nearest to a given window, or null if no monitor is found.</returns>
46+
public static unsafe MonitorInfo GetNearestDisplayMonitor(HWND hwnd)
47+
{
48+
var nearestMonitor = PInvoke.MonitorFromWindow(hwnd, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST);
49+
MonitorInfo nearestMonitorInfo = null;
50+
var callback = new MONITORENUMPROC((HMONITOR monitor, HDC deviceContext, RECT* rect, LPARAM data) =>
51+
{
52+
if (monitor == nearestMonitor)
53+
{
54+
nearestMonitorInfo = new MonitorInfo(monitor, rect);
55+
return false;
56+
}
57+
return true;
58+
});
59+
var dwData = new LPARAM();
60+
var hdc = new HDC();
61+
bool ok = PInvoke.EnumDisplayMonitors(hdc, (RECT?)null, callback, dwData);
62+
if (!ok)
63+
{
64+
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
65+
}
66+
return nearestMonitorInfo;
67+
}
68+
69+
private readonly HMONITOR _monitor;
70+
71+
internal unsafe MonitorInfo(HMONITOR monitor, RECT* rect)
72+
{
73+
RectMonitor =
74+
new Rect(new Point(rect->left, rect->top),
75+
new Point(rect->right, rect->bottom));
76+
_monitor = monitor;
77+
var info = new MONITORINFOEXW() { monitorInfo = new MONITORINFO() { cbSize = (uint)sizeof(MONITORINFOEXW) } };
78+
GetMonitorInfo(monitor, ref info);
79+
RectWork =
80+
new Rect(new Point(info.monitorInfo.rcWork.left, info.monitorInfo.rcWork.top),
81+
new Point(info.monitorInfo.rcWork.right, info.monitorInfo.rcWork.bottom));
82+
Name = new string(info.szDevice.AsSpan()).Replace("\0", "").Trim();
83+
}
84+
85+
/// <summary>
86+
/// Gets the name of the display.
87+
/// </summary>
88+
public string Name { get; }
89+
90+
/// <summary>
91+
/// Gets the display monitor rectangle, expressed in virtual-screen coordinates.
92+
/// </summary>
93+
/// <remarks>
94+
/// <note>If the monitor is not the primary display monitor, some of the rectangle's coordinates may be negative values.</note>
95+
/// </remarks>
96+
public Rect RectMonitor { get; }
97+
98+
/// <summary>
99+
/// Gets the work area rectangle of the display monitor, expressed in virtual-screen coordinates.
100+
/// </summary>
101+
/// <remarks>
102+
/// <note>If the monitor is not the primary display monitor, some of the rectangle's coordinates may be negative values.</note>
103+
/// </remarks>
104+
public Rect RectWork { get; }
105+
106+
/// <summary>
107+
/// Gets if the monitor is the the primary display monitor.
108+
/// </summary>
109+
public bool IsPrimary => _monitor == PInvoke.MonitorFromWindow(new(IntPtr.Zero), MONITOR_FROM_FLAGS.MONITOR_DEFAULTTOPRIMARY);
110+
111+
/// <inheritdoc />
112+
public override string ToString() => $"{Name} {RectMonitor.Width}x{RectMonitor.Height}";
113+
114+
private static unsafe bool GetMonitorInfo(HMONITOR hMonitor, ref MONITORINFOEXW lpmi)
115+
{
116+
fixed (MONITORINFOEXW* lpmiLocal = &lpmi)
117+
{
118+
var lpmiBase = (MONITORINFO*)lpmiLocal;
119+
var __result = PInvoke.GetMonitorInfo(hMonitor, lpmiBase);
120+
return __result;
121+
}
122+
}
123+
}

Flow.Launcher.Infrastructure/NativeMethods.txt

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,34 @@ WM_KEYUP
1616
WM_SYSKEYDOWN
1717
WM_SYSKEYUP
1818

19-
EnumWindows
19+
EnumWindows
20+
21+
DwmSetWindowAttribute
22+
DWM_SYSTEMBACKDROP_TYPE
23+
DWM_WINDOW_CORNER_PREFERENCE
24+
25+
MAX_PATH
26+
SystemParametersInfo
27+
28+
SetForegroundWindow
29+
30+
GetWindowLong
31+
GetForegroundWindow
32+
GetDesktopWindow
33+
GetShellWindow
34+
GetWindowRect
35+
GetClassName
36+
FindWindowEx
37+
WINDOW_STYLE
38+
39+
SetLastError
40+
WINDOW_EX_STYLE
41+
42+
GetSystemMetrics
43+
EnumDisplayMonitors
44+
MonitorFromWindow
45+
GetMonitorInfo
46+
MONITORINFOEXW
47+
48+
WM_ENTERSIZEMOVE
49+
WM_EXITSIZEMOVE
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Runtime.InteropServices;
2+
using Windows.Win32.Foundation;
3+
using Windows.Win32.UI.WindowsAndMessaging;
4+
5+
namespace Windows.Win32;
6+
7+
// Edited from: https://github.com/files-community/Files
8+
internal static partial class PInvoke
9+
{
10+
[DllImport("User32", EntryPoint = "SetWindowLongW", ExactSpelling = true)]
11+
static extern int _SetWindowLong(HWND hWnd, int nIndex, int dwNewLong);
12+
13+
[DllImport("User32", EntryPoint = "SetWindowLongPtrW", ExactSpelling = true)]
14+
static extern nint _SetWindowLongPtr(HWND hWnd, int nIndex, nint dwNewLong);
15+
16+
// NOTE:
17+
// CsWin32 doesn't generate SetWindowLong on other than x86 and vice versa.
18+
// For more info, visit https://github.com/microsoft/CsWin32/issues/882
19+
public static unsafe nint SetWindowLongPtr(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex, nint dwNewLong)
20+
{
21+
return sizeof(nint) is 4
22+
? _SetWindowLong(hWnd, (int)nIndex, (int)dwNewLong)
23+
: _SetWindowLongPtr(hWnd, (int)nIndex, dwNewLong);
24+
}
25+
}

Flow.Launcher.Infrastructure/UserSettings/Settings.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public string Theme
7676
}
7777
}
7878
public bool UseDropShadowEffect { get; set; } = true;
79+
public BackdropTypes BackdropType{ get; set; } = BackdropTypes.None;
7980

8081
/* Appearance Settings. It should be separated from the setting later.*/
8182
public double WindowHeightSize { get; set; } = 42;
@@ -430,4 +431,12 @@ public enum AnimationSpeeds
430431
Fast,
431432
Custom
432433
}
434+
435+
public enum BackdropTypes
436+
{
437+
None,
438+
Acrylic,
439+
Mica,
440+
MicaAlt
441+
}
433442
}

0 commit comments

Comments
 (0)