Merge branch 'dev' into plugin_initialization

This commit is contained in:
Jack Ye 2025-07-24 11:54:19 +01:00 committed by GitHub
commit 97fb8d680f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 1000 additions and 600 deletions

View file

@ -55,12 +55,12 @@
<ItemGroup>
<PackageReference Include="Droplex" Version="1.7.0" />
<PackageReference Include="FSharp.Core" Version="9.0.201" />
<PackageReference Include="Meziantou.Framework.Win32.Jobs" Version="3.4.0" />
<PackageReference Include="FSharp.Core" Version="9.0.300" />
<PackageReference Include="Meziantou.Framework.Win32.Jobs" Version="3.4.3" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
<PackageReference Include="SemanticVersioning" Version="3.0.0" />
<PackageReference Include="squirrel.windows" Version="1.5.2" NoWarn="NU1701" />
<PackageReference Include="StreamJsonRpc" Version="2.21.10" />
<PackageReference Include="StreamJsonRpc" Version="2.22.11" />
</ItemGroup>
<ItemGroup>

View file

@ -13,15 +13,15 @@
},
"FSharp.Core": {
"type": "Direct",
"requested": "[9.0.101, )",
"resolved": "9.0.101",
"contentHash": "3/YR1SDWFA+Ojx9HiBwND+0UR8ZWoeZfkhD0DWAPCDdr/YI+CyFkArmMGzGSyPXeYtjG0sy0emzfyNwjt7zhig=="
"requested": "[9.0.300, )",
"resolved": "9.0.300",
"contentHash": "TVt2J7RCE1KCS2IaONF+p8/KIZ1eHNbW+7qmKF6hGoD4tXl+o07ja1mPtFjMqRa5uHMFaTrGTPn/m945WnDLiQ=="
},
"Meziantou.Framework.Win32.Jobs": {
"type": "Direct",
"requested": "[3.4.0, )",
"resolved": "3.4.0",
"contentHash": "5GGLckfpwoC1jznInEYfK2INrHyD7K1RtwZJ98kNPKBU6jeu24i4zfgDGHHfb+eK3J+eFPAxo0aYcbUxNXIbNw=="
"requested": "[3.4.3, )",
"resolved": "3.4.3",
"contentHash": "REjInKnQ0OrhjjtSMPQtLtdURctCroB4L8Sd2gjTOYDysklvsdnrStx1tHS7uLv+fSyFF3aazZmo5Ka0v1oz/w=="
},
"Microsoft.IO.RecyclableMemoryStream": {
"type": "Direct",
@ -29,6 +29,12 @@
"resolved": "3.0.1",
"contentHash": "s/s20YTVY9r9TPfTrN5g8zPF1YhwxyqO6PxUkrYTGI2B+OGPe9AdajWZrLhFqXIvqIW23fnUE4+ztrUWNU1+9g=="
},
"SemanticVersioning": {
"type": "Direct",
"requested": "[3.0.0, )",
"resolved": "3.0.0",
"contentHash": "RR+8GbPQ/gjDqov/1QN1OPoUlbUruNwcL3WjWCeLw+MY7+od/ENhnkYxCfAC6rQLIu3QifaJt3kPYyP3RumqMQ=="
},
"squirrel.windows": {
"type": "Direct",
"requested": "[1.5.2, )",
@ -42,16 +48,15 @@
},
"StreamJsonRpc": {
"type": "Direct",
"requested": "[2.20.20, )",
"resolved": "2.20.20",
"contentHash": "gwG7KViLbSWS7EI0kYevinVmIga9wZNrpSY/FnWyC6DbdjKJ1xlv/FV1L9b0rLkVP8cGxfIMexdvo/+2W5eq6Q==",
"requested": "[2.22.11, )",
"resolved": "2.22.11",
"contentHash": "TQcqBFswLNpdSJANjhxZmIIe0Yl0kGqzjZ+uHLdhrkxntofvNu6C53XPEEYQ3Wkj8AorKumkuv/VMvTH4BHOZw==",
"dependencies": {
"MessagePack": "2.5.187",
"Microsoft.VisualStudio.Threading": "17.10.48",
"Microsoft.VisualStudio.Threading.Analyzers": "17.10.48",
"MessagePack": "2.5.192",
"Microsoft.VisualStudio.Threading.Only": "17.13.61",
"Microsoft.VisualStudio.Validation": "17.8.8",
"Nerdbank.Streams": "2.11.74",
"Newtonsoft.Json": "13.0.1",
"Nerdbank.Streams": "2.12.87",
"Newtonsoft.Json": "13.0.3",
"System.IO.Pipelines": "8.0.0"
}
},
@ -65,8 +70,8 @@
},
"BitFaster.Caching": {
"type": "Transitive",
"resolved": "2.5.3",
"contentHash": "Vo/39qcam5Xe+DbyfH0JZyqPswdOoa7jv4PGtRJ6Wj8AU+aZ+TuJRlJcIe+MQjRTJwliI8k8VSQpN8sEoBIv2g=="
"resolved": "2.5.4",
"contentHash": "1QroTY1PVCZOSG9FnkkCrmCKk/+bZCgI/YXq376HnYwUDJ4Ho0EaV4YaA/5v5WYLnwIwIO7RZkdWbg9pxIpueQ=="
},
"CommunityToolkit.Mvvm": {
"type": "Transitive",
@ -78,6 +83,11 @@
"resolved": "1.0.0",
"contentHash": "nwbZAYd+DblXAIzlnwDSnl0CiCm8jWLfHSYnoN4wYhtIav6AegB3+T/vKzLbU2IZlPB8Bvl8U3NXpx3eaz+N5w=="
},
"InputSimulator": {
"type": "Transitive",
"resolved": "1.0.4",
"contentHash": "D0LvRCPQMX6/FJHBjng+RO+wRDuHTJrfo7IAc7rmkPvRqchdVGJWg3y70peOtDy3OLNK+HSOwVkH4GiuLnkKgA=="
},
"JetBrains.Annotations": {
"type": "Transitive",
"resolved": "2024.3.0",
@ -85,36 +95,36 @@
},
"MemoryPack": {
"type": "Transitive",
"resolved": "1.21.3",
"contentHash": "cwCtED8y400vMWx/Vp0QCSeEpVFjDU4JwF52VX9WTaqVERUvNqjG9n6osFlmFuytegyXnHvYEu1qRJ8rv/rkbg==",
"resolved": "1.21.4",
"contentHash": "wy3JTBNBsO8LfQcBvvYsWr3lm2Oakolrfu0UQ3oSJSEiD+7ye0GUhYTaXuYYBowqsXBXWD9gf2218ae0JRiYVQ==",
"dependencies": {
"MemoryPack.Core": "1.21.3",
"MemoryPack.Generator": "1.21.3"
"MemoryPack.Core": "1.21.4",
"MemoryPack.Generator": "1.21.4"
}
},
"MemoryPack.Core": {
"type": "Transitive",
"resolved": "1.21.3",
"contentHash": "ajrYoBWT2aKeH4tlY8q/1C9qK1R/NK+7FkuVOX58ebOSxkABoFTqCR7W+Zk2rakUHZiEgNdRqO67hiRZPq6fLA=="
"resolved": "1.21.4",
"contentHash": "6RszGorZ0ejNmp37ZcboPBMvvPCuNW2jlrdQfcs/lMzE5b3pmPF6hsm/laDc34hRlbAST1ZxaX/DvYu2DF5sBQ=="
},
"MemoryPack.Generator": {
"type": "Transitive",
"resolved": "1.21.3",
"contentHash": "hYU0TAIarDKnbkNIWvb7P4zBUL+CTahkuNkczsKvycSMR5kiwQ4IfLexywNKX3s05Izp4gzDSPbueepNWZRpWA=="
"resolved": "1.21.4",
"contentHash": "g14EsSS85yn0lHTi0J9ivqlZMf09A2iI51fmI+0KkzIzyCbWOBWPi5mdaY7YWmXprk12aYh9u/qfWHQUYthlwg=="
},
"MessagePack": {
"type": "Transitive",
"resolved": "2.5.187",
"contentHash": "uW4j8m4Nc+2Mk5n6arOChavJ9bLjkis0qWASOj2h2OwmfINuzYv+mjCHUymrYhmyyKTu3N+ObtTXAY4uQ7jIhg==",
"resolved": "2.5.192",
"contentHash": "Jtle5MaFeIFkdXtxQeL9Tu2Y3HsAQGoSntOzrn6Br/jrl6c8QmG22GEioT5HBtZJR0zw0s46OnKU8ei2M3QifA==",
"dependencies": {
"MessagePack.Annotations": "2.5.187",
"MessagePack.Annotations": "2.5.192",
"Microsoft.NET.StringTools": "17.6.3"
}
},
"MessagePack.Annotations": {
"type": "Transitive",
"resolved": "2.5.187",
"contentHash": "/IvvMMS8opvlHjEJ/fR2Cal4Co726Kj77Z8KiohFhuHfLHHmb9uUxW5+tSCL4ToKFfkQlrS3HD638mRq83ySqA=="
"resolved": "2.5.192",
"contentHash": "jaJuwcgovWIZ8Zysdyf3b7b34/BrADw4v82GaEZymUhDd3ScMPrYd/cttekeDteJJPXseJxp04yTIcxiVUjTWg=="
},
"Microsoft.NET.StringTools": {
"type": "Transitive",
@ -123,17 +133,26 @@
},
"Microsoft.VisualStudio.Threading": {
"type": "Transitive",
"resolved": "17.12.19",
"contentHash": "eLiGMkMYyaSguqHs3lsrFxy3tAWSLuPEL2pIWRcADMDVAs2xqm3dr1d9QYjiEusTgiClF9KD6OB2NdZP72Oy0Q==",
"resolved": "17.14.15",
"contentHash": "1DrCusT3xNLSlaJg77BsUSAzrhjdZBAvvsS0PMzyPM+fGais6SnISOhqdZQop8VVMIBLsYm2gyF9W7THjgavwA==",
"dependencies": {
"Microsoft.VisualStudio.Threading.Analyzers": "17.12.19",
"Microsoft.VisualStudio.Threading.Analyzers": "17.14.15",
"Microsoft.VisualStudio.Threading.Only": "17.14.15",
"Microsoft.VisualStudio.Validation": "17.8.8"
}
},
"Microsoft.VisualStudio.Threading.Analyzers": {
"type": "Transitive",
"resolved": "17.12.19",
"contentHash": "v3IYeedjoktvZ+GqYmLudxZJngmf/YWIxNT2Uy6QMMN19cvw+nkWoip1Gr1RtnFkUo1MPUVMis4C8Kj8d8DpSQ=="
"resolved": "17.14.15",
"contentHash": "mXQPJsbuUD2ydq4/ffd8h8tSOFCXec+2xJOVNCvXjuMOq/+5EKHq3D2m2MC2+nUaXeFMSt66VS/J4HdKBixgcw=="
},
"Microsoft.VisualStudio.Threading.Only": {
"type": "Transitive",
"resolved": "17.14.15",
"contentHash": "NqONyw1RXyj9P3k5e1uU2k9kc1ptwuU5NJQzG+MPq7vQVHUzBY8HLuJf/N2Rw5H/myD96CVxziDxmjawPuzntw==",
"dependencies": {
"Microsoft.VisualStudio.Validation": "17.8.8"
}
},
"Microsoft.VisualStudio.Validation": {
"type": "Transitive",
@ -142,8 +161,8 @@
},
"Microsoft.Win32.SystemEvents": {
"type": "Transitive",
"resolved": "9.0.2",
"contentHash": "5BkGZ6mHp2dHydR29sb0fDfAuqkv30AHtTih8wMzvPZysOmBFvHfnkR2w3tsc0pSiIg8ZoKyefJXWy9r3pBh0w=="
"resolved": "9.0.7",
"contentHash": "lFGY2aGgmMREPJEfOmZcA6v0CLjWVpcfNHRgqYMoSQhy80+GxhYqdW5xe+DCLrVqE1M7/0RpOkIo49/KH/cd/A=="
},
"Mono.Cecil": {
"type": "Transitive",
@ -152,32 +171,50 @@
},
"Nerdbank.Streams": {
"type": "Transitive",
"resolved": "2.11.74",
"contentHash": "r4G7uHHfoo8LCilPOdtf2C+Q5ymHOAXtciT4ZtB2xRlAvv4gPkWBYNAijFblStv3+uidp81j5DP11jMZl4BfJw==",
"resolved": "2.12.87",
"contentHash": "oDKOeKZ865I5X8qmU3IXMyrAnssYEiYWTobPGdrqubN3RtTzEHIv+D6fwhdcfrdhPJzHjCkK/ORztR/IsnmA6g==",
"dependencies": {
"Microsoft.VisualStudio.Threading": "17.10.48",
"Microsoft.VisualStudio.Threading.Only": "17.13.61",
"Microsoft.VisualStudio.Validation": "17.8.8",
"System.IO.Pipelines": "8.0.0"
}
},
"Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.1",
"contentHash": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A=="
"resolved": "13.0.3",
"contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ=="
},
"NHotkey": {
"type": "Transitive",
"resolved": "3.0.0",
"contentHash": "IEghs0QqWsQYH0uUmvIl0Ye6RaebWRh38eB6ToOkDnQucTYRGFOgtig0gSxlwCszTilYFz3n1ZuY762x+kDR3A=="
},
"NHotkey.Wpf": {
"type": "Transitive",
"resolved": "3.0.0",
"contentHash": "BIUKlhTG5KtFf9OQzWvkmVmktt5/FFj6AOEgag8Uf0R2YdZt5ajUzs3sVskcJcT2TztWlEHKQr1jFj3KQ0D9Nw==",
"dependencies": {
"NHotkey": "3.0.0"
}
},
"NLog": {
"type": "Transitive",
"resolved": "4.7.10",
"contentHash": "rcegW7kYOCjl7wX0SzsqpPBqnJ51JKi1WkYb6QBVX0Wc5IgH19Pv4t/co+T0s06OS0Ne44xgkY/mHg0PdrmJow=="
"resolved": "6.0.1",
"contentHash": "qDWiqy8/xdpZKtHna/645KbalwP86N2NFJEzfqhcv+Si4V2iNaEfR/dCneuF/4+Dcwl3f7jHMXj3ndWYftV3Ug=="
},
"PropertyChanged.Fody": {
"NLog.OutputDebugString": {
"type": "Transitive",
"resolved": "3.4.0",
"contentHash": "IAZyq0uolKo2WYm4mjx+q7A8fSGFT0x2e1s3y+ODn4JI0kqTDoo9GF2tdaypUzRFJZfdMxfC5HZW9QzdJLtOnA==",
"resolved": "6.0.1",
"contentHash": "wwJCQLaHVzuRf8TsXB+EEdrzVvE3dnzCSMQMDgwkw3AXp8VSp3JSVF/Q/H0oEqggKgKhPs13hh3a7svyQr4s3A==",
"dependencies": {
"Fody": "6.5.1"
"NLog": "6.0.1"
}
},
"SharpVectors.Wpf": {
"type": "Transitive",
"resolved": "1.8.4.2",
"contentHash": "PNxLkMBJnV8A+6yH9OqOlhLJegvWP/dvh0rAJp2l0kcrR+rB4R2tQ9vhUqka+UilH4atN8T6zvjDOizVyfz2Ng=="
},
"Splat": {
"type": "Transitive",
"resolved": "1.6.2",
@ -185,10 +222,10 @@
},
"System.Drawing.Common": {
"type": "Transitive",
"resolved": "9.0.2",
"contentHash": "JU947wzf8JbBS16Y5EIZzAlyQU+k68D7LRx6y03s2wlhlvLqkt/8uPBrjv2hJnnaJKbdb0GhQ3JZsfYXhrRjyg==",
"resolved": "9.0.7",
"contentHash": "1k/Pk7hcM3vP2tfIRRS2ECCCN7ya+hvocsM1JMc4ZDCU6qw7yOuUmqmCDfgXZ4Q4FS6jass2EAai5ByKodDi0g==",
"dependencies": {
"Microsoft.Win32.SystemEvents": "9.0.2"
"Microsoft.Win32.SystemEvents": "9.0.7"
}
},
"System.IO.Pipelines": {
@ -203,8 +240,8 @@
},
"ToolGood.Words.Pinyin": {
"type": "Transitive",
"resolved": "3.0.1.4",
"contentHash": "uQo97618y9yzLDxrnehPN+/tuiOlk5BqieEdwctHZOAS9miMXnHKgMFYVw8CSGXRglyTYXlrW7qtUlU7Fje5Ew=="
"resolved": "3.1.0.3",
"contentHash": "VKcf8sUq/+LyY99WgLhOu7Q32ROEyR30/2xCCj9ADRi45wVC7kpXrYCf9vH1qirkmrIfpL8inoxAbrqAlfXxsQ=="
},
"YamlDotNet": {
"type": "Transitive",
@ -215,22 +252,24 @@
"type": "Project",
"dependencies": {
"Ben.Demystifier": "[0.4.1, )",
"BitFaster.Caching": "[2.5.3, )",
"BitFaster.Caching": "[2.5.4, )",
"CommunityToolkit.Mvvm": "[8.4.0, )",
"Flow.Launcher.Plugin": "[4.4.0, )",
"MemoryPack": "[1.21.3, )",
"Microsoft.VisualStudio.Threading": "[17.12.19, )",
"NLog": "[4.7.10, )",
"PropertyChanged.Fody": "[3.4.0, )",
"System.Drawing.Common": "[9.0.2, )",
"ToolGood.Words.Pinyin": "[3.0.1.4, )"
"Flow.Launcher.Plugin": "[4.7.0, )",
"InputSimulator": "[1.0.4, )",
"MemoryPack": "[1.21.4, )",
"Microsoft.VisualStudio.Threading": "[17.14.15, )",
"NHotkey.Wpf": "[3.0.0, )",
"NLog": "[6.0.1, )",
"NLog.OutputDebugString": "[6.0.1, )",
"SharpVectors.Wpf": "[1.8.4.2, )",
"System.Drawing.Common": "[9.0.7, )",
"ToolGood.Words.Pinyin": "[3.1.0.3, )"
}
},
"flow.launcher.plugin": {
"type": "Project",
"dependencies": {
"JetBrains.Annotations": "[2024.3.0, )",
"PropertyChanged.Fody": "[3.4.0, )"
"JetBrains.Annotations": "[2024.3.0, )"
}
}
}

View file

@ -54,29 +54,28 @@
<ItemGroup>
<PackageReference Include="Ben.Demystifier" Version="0.4.1" />
<PackageReference Include="BitFaster.Caching" Version="2.5.3" />
<PackageReference Include="BitFaster.Caching" Version="2.5.4" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="Fody" Version="6.5.5">
<PackageReference Include="Fody" Version="6.9.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="InputSimulator" Version="1.0.4" />
<PackageReference Include="MemoryPack" Version="1.21.4" />
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="17.12.19" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.106">
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="17.14.15" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.183">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NHotkey.Wpf" Version="3.0.0" />
<PackageReference Include="NLog" Version="4.7.10" />
<PackageReference Include="PropertyChanged.Fody" Version="3.4.0">
<PackageReference Include="NLog" Version="6.0.1" />
<PackageReference Include="NLog.OutputDebugString" Version="6.0.1" />
<PackageReference Include="PropertyChanged.Fody" Version="4.1.0">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="SharpVectors.Wpf" Version="1.8.4.2" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
<!--ToolGood.Words.Pinyin v3.0.2.6 results in high memory usage when search with pinyin is enabled-->
<!--Bumping to it or higher needs to test and ensure this is no longer a problem-->
<PackageReference Include="ToolGood.Words.Pinyin" Version="3.0.1.4" />
<PackageReference Include="System.Drawing.Common" Version="9.0.7" />
<PackageReference Include="ToolGood.Words.Pinyin" Version="3.1.0.3" />
</ItemGroup>
</Project>

View file

@ -34,12 +34,6 @@ WINDOW_STYLE
SetLastError
WINDOW_EX_STYLE
GetSystemMetrics
EnumDisplayMonitors
MonitorFromWindow
GetMonitorInfo
MONITORINFOEXW
WM_ENTERSIZEMOVE
WM_EXITSIZEMOVE
WM_NCLBUTTONDBLCLK
@ -90,3 +84,6 @@ OpenProcess
QueryFullProcessImageName
EVENT_OBJECT_HIDE
EVENT_SYSTEM_DIALOGEND
WM_POWERBROADCAST
PBT_APMRESUMEAUTOMATIC

View file

@ -13,6 +13,7 @@ using System.Windows.Interop;
using System.Windows.Markup;
using System.Windows.Media;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.SharedModels;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
using Windows.Win32;
@ -120,9 +121,9 @@ namespace Flow.Launcher.Infrastructure
#region Window Foreground
public static nint GetForegroundWindow()
public static unsafe nint GetForegroundWindow()
{
return PInvoke.GetForegroundWindow().Value;
return (nint)PInvoke.GetForegroundWindow().Value;
}
public static bool SetForegroundWindow(Window window)
@ -286,15 +287,15 @@ namespace Flow.Launcher.Infrastructure
{
var hWndDesktop = PInvoke.FindWindowEx(hWnd, HWND.Null, "SHELLDLL_DefView", null);
hWndDesktop = PInvoke.FindWindowEx(hWndDesktop, HWND.Null, "SysListView32", "FolderView");
if (hWndDesktop.Value != IntPtr.Zero)
if (hWndDesktop != HWND.Null)
{
return false;
}
}
var monitorInfo = MonitorInfo.GetNearestDisplayMonitor(hWnd);
return (appBounds.bottom - appBounds.top) == monitorInfo.RectMonitor.Height &&
(appBounds.right - appBounds.left) == monitorInfo.RectMonitor.Width;
return (appBounds.bottom - appBounds.top) == monitorInfo.Bounds.Height &&
(appBounds.right - appBounds.left) == monitorInfo.Bounds.Width;
}
#endregion
@ -337,6 +338,9 @@ namespace Flow.Launcher.Infrastructure
public const int SC_MAXIMIZE = (int)PInvoke.SC_MAXIMIZE;
public const int SC_MINIMIZE = (int)PInvoke.SC_MINIMIZE;
public const int WM_POWERBROADCAST = (int)PInvoke.WM_POWERBROADCAST;
public const int PBT_APMRESUMEAUTOMATIC = (int)PInvoke.PBT_APMRESUMEAUTOMATIC;
#endregion
#region Window Handle
@ -497,7 +501,7 @@ namespace Flow.Launcher.Infrastructure
/// Restores the previously backed-up keyboard layout.
/// If it wasn't backed up or has already been restored, this method does nothing.
/// </summary>
public static void RestorePreviousKeyboardLayout()
public unsafe static void RestorePreviousKeyboardLayout()
{
if (_previousLayout == HKL.Null) return;
@ -508,7 +512,7 @@ namespace Flow.Launcher.Infrastructure
hwnd,
PInvoke.WM_INPUTLANGCHANGEREQUEST,
PInvoke.INPUTLANGCHANGE_FORWARD,
_previousLayout.Value
new LPARAM((nint)_previousLayout.Value)
);
_previousLayout = HKL.Null;
@ -816,20 +820,17 @@ namespace Flow.Launcher.Infrastructure
if (threadId == 0) return string.Empty;
var process = PInvoke.OpenProcess(PROCESS_ACCESS_RIGHTS.PROCESS_QUERY_LIMITED_INFORMATION, false, pid);
if (process.Value != IntPtr.Zero)
if (process != HWND.Null)
{
using var safeHandle = new SafeProcessHandle(process.Value, true);
using var safeHandle = new SafeProcessHandle((nint)process.Value, true);
uint capacity = 2000;
Span<char> buffer = new char[capacity];
fixed (char* pBuffer = buffer)
if (!PInvoke.QueryFullProcessImageName(safeHandle, PROCESS_NAME_FORMAT.PROCESS_NAME_WIN32, buffer, ref capacity))
{
if (!PInvoke.QueryFullProcessImageName(safeHandle, PROCESS_NAME_FORMAT.PROCESS_NAME_WIN32, (PWSTR)pBuffer, ref capacity))
{
return string.Empty;
}
return buffer[..(int)capacity].ToString();
return string.Empty;
}
return buffer[..(int)capacity].ToString();
}
return string.Empty;

View file

@ -13,9 +13,9 @@
},
"BitFaster.Caching": {
"type": "Direct",
"requested": "[2.5.3, )",
"resolved": "2.5.3",
"contentHash": "Vo/39qcam5Xe+DbyfH0JZyqPswdOoa7jv4PGtRJ6Wj8AU+aZ+TuJRlJcIe+MQjRTJwliI8k8VSQpN8sEoBIv2g=="
"requested": "[2.5.4, )",
"resolved": "2.5.4",
"contentHash": "1QroTY1PVCZOSG9FnkkCrmCKk/+bZCgI/YXq376HnYwUDJ4Ho0EaV4YaA/5v5WYLnwIwIO7RZkdWbg9pxIpueQ=="
},
"CommunityToolkit.Mvvm": {
"type": "Direct",
@ -25,70 +25,101 @@
},
"Fody": {
"type": "Direct",
"requested": "[6.5.5, )",
"resolved": "6.5.5",
"contentHash": "Krca41L/PDva1VsmDec5n52cQZxQAQp/bsHdzsNi8iLLI0lqKL94fNIkNaC8tVolUkCyWsbzvxfxJCeD2789fA=="
"requested": "[6.9.2, )",
"resolved": "6.9.2",
"contentHash": "YBHobPGogb0vYhGYIxn/ndWqTjNWZveDi5jdjrcshL2vjwU3gQGyDeI7vGgye+2rAM5fGRvlLgNWLW3DpviS/w=="
},
"InputSimulator": {
"type": "Direct",
"requested": "[1.0.4, )",
"resolved": "1.0.4",
"contentHash": "D0LvRCPQMX6/FJHBjng+RO+wRDuHTJrfo7IAc7rmkPvRqchdVGJWg3y70peOtDy3OLNK+HSOwVkH4GiuLnkKgA=="
},
"MemoryPack": {
"type": "Direct",
"requested": "[1.21.3, )",
"resolved": "1.21.3",
"contentHash": "cwCtED8y400vMWx/Vp0QCSeEpVFjDU4JwF52VX9WTaqVERUvNqjG9n6osFlmFuytegyXnHvYEu1qRJ8rv/rkbg==",
"requested": "[1.21.4, )",
"resolved": "1.21.4",
"contentHash": "wy3JTBNBsO8LfQcBvvYsWr3lm2Oakolrfu0UQ3oSJSEiD+7ye0GUhYTaXuYYBowqsXBXWD9gf2218ae0JRiYVQ==",
"dependencies": {
"MemoryPack.Core": "1.21.3",
"MemoryPack.Generator": "1.21.3"
"MemoryPack.Core": "1.21.4",
"MemoryPack.Generator": "1.21.4"
}
},
"Microsoft.VisualStudio.Threading": {
"type": "Direct",
"requested": "[17.12.19, )",
"resolved": "17.12.19",
"contentHash": "eLiGMkMYyaSguqHs3lsrFxy3tAWSLuPEL2pIWRcADMDVAs2xqm3dr1d9QYjiEusTgiClF9KD6OB2NdZP72Oy0Q==",
"requested": "[17.14.15, )",
"resolved": "17.14.15",
"contentHash": "1DrCusT3xNLSlaJg77BsUSAzrhjdZBAvvsS0PMzyPM+fGais6SnISOhqdZQop8VVMIBLsYm2gyF9W7THjgavwA==",
"dependencies": {
"Microsoft.VisualStudio.Threading.Analyzers": "17.12.19",
"Microsoft.VisualStudio.Threading.Analyzers": "17.14.15",
"Microsoft.VisualStudio.Threading.Only": "17.14.15",
"Microsoft.VisualStudio.Validation": "17.8.8"
}
},
"Microsoft.Windows.CsWin32": {
"type": "Direct",
"requested": "[0.3.106, )",
"resolved": "0.3.106",
"contentHash": "Mx5fK7uN6fwLR4wUghs6//HonAnwPBNmC2oonyJVhCUlHS/r6SUS3NkBc3+gaQiv+0/9bqdj1oSCKQFkNI+21Q==",
"requested": "[0.3.183, )",
"resolved": "0.3.183",
"contentHash": "Ze3aE2y7xgzKxEWtNb4SH0CExXpCHr3sbmwnvMiWMzJhWDX/G4Rs5wgg2UNs3VN+qVHh/DkDWLCPaVQv/b//Nw==",
"dependencies": {
"Microsoft.Windows.SDK.Win32Docs": "0.1.42-alpha",
"Microsoft.Windows.SDK.Win32Metadata": "60.0.34-preview",
"Microsoft.Windows.WDK.Win32Metadata": "0.11.4-experimental"
"Microsoft.Windows.SDK.Win32Metadata": "61.0.15-preview",
"Microsoft.Windows.WDK.Win32Metadata": "0.12.8-experimental"
}
},
"NHotkey.Wpf": {
"type": "Direct",
"requested": "[3.0.0, )",
"resolved": "3.0.0",
"contentHash": "BIUKlhTG5KtFf9OQzWvkmVmktt5/FFj6AOEgag8Uf0R2YdZt5ajUzs3sVskcJcT2TztWlEHKQr1jFj3KQ0D9Nw==",
"dependencies": {
"NHotkey": "3.0.0"
}
},
"NLog": {
"type": "Direct",
"requested": "[4.7.10, )",
"resolved": "4.7.10",
"contentHash": "rcegW7kYOCjl7wX0SzsqpPBqnJ51JKi1WkYb6QBVX0Wc5IgH19Pv4t/co+T0s06OS0Ne44xgkY/mHg0PdrmJow=="
"requested": "[6.0.1, )",
"resolved": "6.0.1",
"contentHash": "qDWiqy8/xdpZKtHna/645KbalwP86N2NFJEzfqhcv+Si4V2iNaEfR/dCneuF/4+Dcwl3f7jHMXj3ndWYftV3Ug=="
},
"NLog.OutputDebugString": {
"type": "Direct",
"requested": "[6.0.1, )",
"resolved": "6.0.1",
"contentHash": "wwJCQLaHVzuRf8TsXB+EEdrzVvE3dnzCSMQMDgwkw3AXp8VSp3JSVF/Q/H0oEqggKgKhPs13hh3a7svyQr4s3A==",
"dependencies": {
"NLog": "6.0.1"
}
},
"PropertyChanged.Fody": {
"type": "Direct",
"requested": "[3.4.0, )",
"resolved": "3.4.0",
"contentHash": "IAZyq0uolKo2WYm4mjx+q7A8fSGFT0x2e1s3y+ODn4JI0kqTDoo9GF2tdaypUzRFJZfdMxfC5HZW9QzdJLtOnA==",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "6v+f9cI8YjnZH2WBHuOqWEAo8DFFNGFIdU8xD3AsL6fhV6Y8oAmVWd7XKk49t8DpeUBwhR/X+97+6Epvek0Y3A==",
"dependencies": {
"Fody": "6.5.1"
"Fody": "6.6.4"
}
},
"SharpVectors.Wpf": {
"type": "Direct",
"requested": "[1.8.4.2, )",
"resolved": "1.8.4.2",
"contentHash": "PNxLkMBJnV8A+6yH9OqOlhLJegvWP/dvh0rAJp2l0kcrR+rB4R2tQ9vhUqka+UilH4atN8T6zvjDOizVyfz2Ng=="
},
"System.Drawing.Common": {
"type": "Direct",
"requested": "[9.0.2, )",
"resolved": "9.0.2",
"contentHash": "JU947wzf8JbBS16Y5EIZzAlyQU+k68D7LRx6y03s2wlhlvLqkt/8uPBrjv2hJnnaJKbdb0GhQ3JZsfYXhrRjyg==",
"requested": "[9.0.7, )",
"resolved": "9.0.7",
"contentHash": "1k/Pk7hcM3vP2tfIRRS2ECCCN7ya+hvocsM1JMc4ZDCU6qw7yOuUmqmCDfgXZ4Q4FS6jass2EAai5ByKodDi0g==",
"dependencies": {
"Microsoft.Win32.SystemEvents": "9.0.2"
"Microsoft.Win32.SystemEvents": "9.0.7"
}
},
"ToolGood.Words.Pinyin": {
"type": "Direct",
"requested": "[3.0.1.4, )",
"resolved": "3.0.1.4",
"contentHash": "uQo97618y9yzLDxrnehPN+/tuiOlk5BqieEdwctHZOAS9miMXnHKgMFYVw8CSGXRglyTYXlrW7qtUlU7Fje5Ew=="
"requested": "[3.1.0.3, )",
"resolved": "3.1.0.3",
"contentHash": "VKcf8sUq/+LyY99WgLhOu7Q32ROEyR30/2xCCj9ADRi45wVC7kpXrYCf9vH1qirkmrIfpL8inoxAbrqAlfXxsQ=="
},
"JetBrains.Annotations": {
"type": "Transitive",
@ -97,18 +128,26 @@
},
"MemoryPack.Core": {
"type": "Transitive",
"resolved": "1.21.3",
"contentHash": "ajrYoBWT2aKeH4tlY8q/1C9qK1R/NK+7FkuVOX58ebOSxkABoFTqCR7W+Zk2rakUHZiEgNdRqO67hiRZPq6fLA=="
"resolved": "1.21.4",
"contentHash": "6RszGorZ0ejNmp37ZcboPBMvvPCuNW2jlrdQfcs/lMzE5b3pmPF6hsm/laDc34hRlbAST1ZxaX/DvYu2DF5sBQ=="
},
"MemoryPack.Generator": {
"type": "Transitive",
"resolved": "1.21.3",
"contentHash": "hYU0TAIarDKnbkNIWvb7P4zBUL+CTahkuNkczsKvycSMR5kiwQ4IfLexywNKX3s05Izp4gzDSPbueepNWZRpWA=="
"resolved": "1.21.4",
"contentHash": "g14EsSS85yn0lHTi0J9ivqlZMf09A2iI51fmI+0KkzIzyCbWOBWPi5mdaY7YWmXprk12aYh9u/qfWHQUYthlwg=="
},
"Microsoft.VisualStudio.Threading.Analyzers": {
"type": "Transitive",
"resolved": "17.12.19",
"contentHash": "v3IYeedjoktvZ+GqYmLudxZJngmf/YWIxNT2Uy6QMMN19cvw+nkWoip1Gr1RtnFkUo1MPUVMis4C8Kj8d8DpSQ=="
"resolved": "17.14.15",
"contentHash": "mXQPJsbuUD2ydq4/ffd8h8tSOFCXec+2xJOVNCvXjuMOq/+5EKHq3D2m2MC2+nUaXeFMSt66VS/J4HdKBixgcw=="
},
"Microsoft.VisualStudio.Threading.Only": {
"type": "Transitive",
"resolved": "17.14.15",
"contentHash": "NqONyw1RXyj9P3k5e1uU2k9kc1ptwuU5NJQzG+MPq7vQVHUzBY8HLuJf/N2Rw5H/myD96CVxziDxmjawPuzntw==",
"dependencies": {
"Microsoft.VisualStudio.Validation": "17.8.8"
}
},
"Microsoft.VisualStudio.Validation": {
"type": "Transitive",
@ -117,8 +156,8 @@
},
"Microsoft.Win32.SystemEvents": {
"type": "Transitive",
"resolved": "9.0.2",
"contentHash": "5BkGZ6mHp2dHydR29sb0fDfAuqkv30AHtTih8wMzvPZysOmBFvHfnkR2w3tsc0pSiIg8ZoKyefJXWy9r3pBh0w=="
"resolved": "9.0.7",
"contentHash": "lFGY2aGgmMREPJEfOmZcA6v0CLjWVpcfNHRgqYMoSQhy80+GxhYqdW5xe+DCLrVqE1M7/0RpOkIo49/KH/cd/A=="
},
"Microsoft.Windows.SDK.Win32Docs": {
"type": "Transitive",
@ -127,17 +166,22 @@
},
"Microsoft.Windows.SDK.Win32Metadata": {
"type": "Transitive",
"resolved": "60.0.34-preview",
"contentHash": "TA3DUNi4CTeo+ItTXBnGZFt2159XOGSl0UOlG5vjDj4WHqZjhwYyyUnzOtrbCERiSaP2Hzg7otJNWwOSZgutyA=="
"resolved": "61.0.15-preview",
"contentHash": "cysex3dazKtCPALCluC2XX3f5Aedy9H2pw5jb+TW5uas2rkem1Z7FRnbUrg2vKx0pk0Qz+4EJNr37HdYTEcvEQ=="
},
"Microsoft.Windows.WDK.Win32Metadata": {
"type": "Transitive",
"resolved": "0.11.4-experimental",
"contentHash": "bf5MCmUyZf0gBlYQjx9UpRAZWBkRndyt9XicR+UNLvAUAFTZQbu6YaX/sNKZlR98Grn0gydfh/yT4I3vc0AIQA==",
"resolved": "0.12.8-experimental",
"contentHash": "3n8R44/Z96Ly+ty4eYVJfESqbzvpw96lRLs3zOzyDmr1x1Kw7FNn5CyE416q+bZQV3e1HRuMUvyegMeRE/WedA==",
"dependencies": {
"Microsoft.Windows.SDK.Win32Metadata": "60.0.34-preview"
"Microsoft.Windows.SDK.Win32Metadata": "61.0.15-preview"
}
},
"NHotkey": {
"type": "Transitive",
"resolved": "3.0.0",
"contentHash": "IEghs0QqWsQYH0uUmvIl0Ye6RaebWRh38eB6ToOkDnQucTYRGFOgtig0gSxlwCszTilYFz3n1ZuY762x+kDR3A=="
},
"System.Reflection.Metadata": {
"type": "Transitive",
"resolved": "5.0.0",
@ -146,8 +190,7 @@
"flow.launcher.plugin": {
"type": "Project",
"dependencies": {
"JetBrains.Annotations": "[2024.3.0, )",
"PropertyChanged.Fody": "[3.4.0, )"
"JetBrains.Annotations": "[2024.3.0, )"
}
}
}

View file

@ -68,17 +68,17 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Fody" Version="6.5.5">
<PackageReference Include="Fody" Version="6.9.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
<PackageReference Include="JetBrains.Annotations" Version="2024.3.0" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.106">
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.183">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="PropertyChanged.Fody" Version="3.4.0">
<PackageReference Include="PropertyChanged.Fody" Version="4.1.0">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

View file

@ -616,5 +616,17 @@ namespace Flow.Launcher.Plugin
/// Invoked when the actual theme of the application has changed. Currently, the plugin will continue to be subscribed even if it is turned off.
/// </summary>
event ActualApplicationThemeChangedEventHandler ActualApplicationThemeChanged;
/// <summary>
/// Get the user data directory of Flow Launcher.
/// </summary>
/// <returns></returns>
string GetDataDirectory();
/// <summary>
/// Get the log directory of Flow Launcher.
/// </summary>
/// <returns></returns>
string GetLogDirectory();
}
}

View file

@ -5,4 +5,12 @@ GetWindowTextLength
WM_KEYDOWN
WM_KEYUP
WM_SYSKEYDOWN
WM_SYSKEYUP
WM_SYSKEYUP
GetSystemMetrics
EnumDisplayMonitors
MonitorFromWindow
GetMonitorInfo
MONITORINFOEXW
GetCursorPos
MonitorFromPoint

View file

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System;
using System.Runtime.InteropServices;
using System.Windows;
using Windows.Win32;
@ -7,13 +6,16 @@ using Windows.Win32.Foundation;
using Windows.Win32.Graphics.Gdi;
using Windows.Win32.UI.WindowsAndMessaging;
namespace Flow.Launcher.Infrastructure;
namespace Flow.Launcher.Plugin.SharedModels;
/// <summary>
/// Contains full information about a display monitor.
/// Codes are edited from: <see href="https://github.com/Jack251970/DesktopWidgets3">.
/// Inspired from: https://github.com/Jack251970/DesktopWidgets3.
/// </summary>
internal class MonitorInfo
/// <remarks>
/// Use this class to replace the System.Windows.Forms.Screen class which can cause possible System.PlatformNotSupportedException.
/// </remarks>
public class MonitorInfo
{
/// <summary>
/// Gets the display monitors (including invisible pseudo-monitors associated with the mirroring drivers).
@ -23,14 +25,14 @@ internal class MonitorInfo
{
var monitorCount = PInvoke.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CMONITORS);
var list = new List<MonitorInfo>(monitorCount);
var callback = new MONITORENUMPROC((HMONITOR monitor, HDC deviceContext, RECT* rect, LPARAM data) =>
var callback = new MONITORENUMPROC((monitor, deviceContext, rect, data) =>
{
list.Add(new MonitorInfo(monitor, rect));
return true;
});
var dwData = new LPARAM();
var hdc = new HDC();
bool ok = PInvoke.EnumDisplayMonitors(hdc, (RECT?)null, callback, dwData);
bool ok = PInvoke.EnumDisplayMonitors(hdc, null, callback, dwData);
if (!ok)
{
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
@ -43,11 +45,11 @@ internal class MonitorInfo
/// </summary>
/// <param name="hwnd">Window handle</param>
/// <returns>The display monitor that is nearest to a given window, or null if no monitor is found.</returns>
public static unsafe MonitorInfo GetNearestDisplayMonitor(HWND hwnd)
public static unsafe MonitorInfo GetNearestDisplayMonitor(nint hwnd)
{
var nearestMonitor = PInvoke.MonitorFromWindow(hwnd, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST);
var nearestMonitor = PInvoke.MonitorFromWindow(new(hwnd), MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST);
MonitorInfo nearestMonitorInfo = null;
var callback = new MONITORENUMPROC((HMONITOR monitor, HDC deviceContext, RECT* rect, LPARAM data) =>
var callback = new MONITORENUMPROC((monitor, deviceContext, rect, data) =>
{
if (monitor == nearestMonitor)
{
@ -58,7 +60,7 @@ internal class MonitorInfo
});
var dwData = new LPARAM();
var hdc = new HDC();
bool ok = PInvoke.EnumDisplayMonitors(hdc, (RECT?)null, callback, dwData);
bool ok = PInvoke.EnumDisplayMonitors(hdc, null, callback, dwData);
if (!ok)
{
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
@ -66,17 +68,75 @@ internal class MonitorInfo
return nearestMonitorInfo;
}
/// <summary>
/// Gets the primary display monitor (the one that contains the taskbar).
/// </summary>
/// <returns>The primary display monitor, or null if no monitor is found.</returns>
public static unsafe MonitorInfo GetPrimaryDisplayMonitor()
{
var primaryMonitor = PInvoke.MonitorFromWindow(new HWND(nint.Zero), MONITOR_FROM_FLAGS.MONITOR_DEFAULTTOPRIMARY);
MonitorInfo primaryMonitorInfo = null;
var callback = new MONITORENUMPROC((monitor, deviceContext, rect, data) =>
{
if (monitor == primaryMonitor)
{
primaryMonitorInfo = new MonitorInfo(monitor, rect);
return false;
}
return true;
});
var dwData = new LPARAM();
var hdc = new HDC();
bool ok = PInvoke.EnumDisplayMonitors(hdc, null, callback, dwData);
if (!ok)
{
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
}
return primaryMonitorInfo;
}
/// <summary>
/// Gets the display monitor that contains the cursor.
/// </summary>
/// <returns>The display monitor that contains the cursor, or null if no monitor is found.</returns>
public static unsafe MonitorInfo GetCursorDisplayMonitor()
{
if (!PInvoke.GetCursorPos(out var pt))
{
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
}
var cursorMonitor = PInvoke.MonitorFromPoint(pt, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST);
MonitorInfo cursorMonitorInfo = null;
var callback = new MONITORENUMPROC((monitor, deviceContext, rect, data) =>
{
if (monitor == cursorMonitor)
{
cursorMonitorInfo = new MonitorInfo(monitor, rect);
return false;
}
return true;
});
var dwData = new LPARAM();
var hdc = new HDC();
bool ok = PInvoke.EnumDisplayMonitors(hdc, null, callback, dwData);
if (!ok)
{
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
}
return cursorMonitorInfo;
}
private readonly HMONITOR _monitor;
internal unsafe MonitorInfo(HMONITOR monitor, RECT* rect)
{
RectMonitor =
Bounds =
new Rect(new Point(rect->left, rect->top),
new Point(rect->right, rect->bottom));
_monitor = monitor;
var info = new MONITORINFOEXW() { monitorInfo = new MONITORINFO() { cbSize = (uint)sizeof(MONITORINFOEXW) } };
GetMonitorInfo(monitor, ref info);
RectWork =
WorkingArea =
new Rect(new Point(info.monitorInfo.rcWork.left, info.monitorInfo.rcWork.top),
new Point(info.monitorInfo.rcWork.right, info.monitorInfo.rcWork.bottom));
Name = new string(info.szDevice.AsSpan()).Replace("\0", "").Trim();
@ -93,7 +153,7 @@ internal class MonitorInfo
/// <remarks>
/// <note>If the monitor is not the primary display monitor, some of the rectangle's coordinates may be negative values.</note>
/// </remarks>
public Rect RectMonitor { get; }
public Rect Bounds { get; }
/// <summary>
/// Gets the work area rectangle of the display monitor, expressed in virtual-screen coordinates.
@ -101,15 +161,15 @@ internal class MonitorInfo
/// <remarks>
/// <note>If the monitor is not the primary display monitor, some of the rectangle's coordinates may be negative values.</note>
/// </remarks>
public Rect RectWork { get; }
public Rect WorkingArea { get; }
/// <summary>
/// Gets if the monitor is the the primary display monitor.
/// Gets if the monitor is the primary display monitor.
/// </summary>
public bool IsPrimary => _monitor == PInvoke.MonitorFromWindow(new(IntPtr.Zero), MONITOR_FROM_FLAGS.MONITOR_DEFAULTTOPRIMARY);
public bool IsPrimary => _monitor == PInvoke.MonitorFromWindow(new(nint.Zero), MONITOR_FROM_FLAGS.MONITOR_DEFAULTTOPRIMARY);
/// <inheritdoc />
public override string ToString() => $"{Name} {RectMonitor.Width}x{RectMonitor.Height}";
public override string ToString() => $"{Name} {Bounds.Width}x{Bounds.Height}";
private static unsafe bool GetMonitorInfo(HMONITOR hMonitor, ref MONITORINFOEXW lpmi)
{

View file

@ -4,9 +4,9 @@
"net9.0-windows7.0": {
"Fody": {
"type": "Direct",
"requested": "[6.5.4, )",
"resolved": "6.5.4",
"contentHash": "GXZuti428IZctfby10xkMbWLCibcb6s29I/psLbBoO2vHJI5eTNVybnlV/Wi1tlIu9GG0bgW/PQwMH+MCldHxw=="
"requested": "[6.9.2, )",
"resolved": "6.9.2",
"contentHash": "YBHobPGogb0vYhGYIxn/ndWqTjNWZveDi5jdjrcshL2vjwU3gQGyDeI7vGgye+2rAM5fGRvlLgNWLW3DpviS/w=="
},
"JetBrains.Annotations": {
"type": "Direct",
@ -16,43 +16,43 @@
},
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
"requested": "[1.1.1, )",
"resolved": "1.1.1",
"contentHash": "IaJGnOv/M7UQjRJks7B6p7pbPnOwisYGOIzqCz5ilGFTApZ3ktOR+6zJ12ZRPInulBmdAf1SrGdDG2MU8g6XTw==",
"requested": "[8.0.0, )",
"resolved": "8.0.0",
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "1.1.1",
"Microsoft.SourceLink.Common": "1.1.1"
"Microsoft.Build.Tasks.Git": "8.0.0",
"Microsoft.SourceLink.Common": "8.0.0"
}
},
"Microsoft.Windows.CsWin32": {
"type": "Direct",
"requested": "[0.3.106, )",
"resolved": "0.3.106",
"contentHash": "Mx5fK7uN6fwLR4wUghs6//HonAnwPBNmC2oonyJVhCUlHS/r6SUS3NkBc3+gaQiv+0/9bqdj1oSCKQFkNI+21Q==",
"requested": "[0.3.183, )",
"resolved": "0.3.183",
"contentHash": "Ze3aE2y7xgzKxEWtNb4SH0CExXpCHr3sbmwnvMiWMzJhWDX/G4Rs5wgg2UNs3VN+qVHh/DkDWLCPaVQv/b//Nw==",
"dependencies": {
"Microsoft.Windows.SDK.Win32Docs": "0.1.42-alpha",
"Microsoft.Windows.SDK.Win32Metadata": "60.0.34-preview",
"Microsoft.Windows.WDK.Win32Metadata": "0.11.4-experimental"
"Microsoft.Windows.SDK.Win32Metadata": "61.0.15-preview",
"Microsoft.Windows.WDK.Win32Metadata": "0.12.8-experimental"
}
},
"PropertyChanged.Fody": {
"type": "Direct",
"requested": "[3.4.0, )",
"resolved": "3.4.0",
"contentHash": "IAZyq0uolKo2WYm4mjx+q7A8fSGFT0x2e1s3y+ODn4JI0kqTDoo9GF2tdaypUzRFJZfdMxfC5HZW9QzdJLtOnA==",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "6v+f9cI8YjnZH2WBHuOqWEAo8DFFNGFIdU8xD3AsL6fhV6Y8oAmVWd7XKk49t8DpeUBwhR/X+97+6Epvek0Y3A==",
"dependencies": {
"Fody": "6.5.1"
"Fody": "6.6.4"
}
},
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "AT3HlgTjsqHnWpBHSNeR0KxbLZD7bztlZVj7I8vgeYG9SYqbeFGh0TM/KVtC6fg53nrWHl3VfZFvb5BiQFcY6Q=="
"resolved": "8.0.0",
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
},
"Microsoft.SourceLink.Common": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "WMcGpWKrmJmzrNeuaEb23bEMnbtR/vLmvZtkAP5qWu7vQsY59GqfRJd65sFpBszbd2k/bQ8cs8eWawQKAabkVg=="
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Microsoft.Windows.SDK.Win32Docs": {
"type": "Transitive",
@ -61,15 +61,15 @@
},
"Microsoft.Windows.SDK.Win32Metadata": {
"type": "Transitive",
"resolved": "60.0.34-preview",
"contentHash": "TA3DUNi4CTeo+ItTXBnGZFt2159XOGSl0UOlG5vjDj4WHqZjhwYyyUnzOtrbCERiSaP2Hzg7otJNWwOSZgutyA=="
"resolved": "61.0.15-preview",
"contentHash": "cysex3dazKtCPALCluC2XX3f5Aedy9H2pw5jb+TW5uas2rkem1Z7FRnbUrg2vKx0pk0Qz+4EJNr37HdYTEcvEQ=="
},
"Microsoft.Windows.WDK.Win32Metadata": {
"type": "Transitive",
"resolved": "0.11.4-experimental",
"contentHash": "bf5MCmUyZf0gBlYQjx9UpRAZWBkRndyt9XicR+UNLvAUAFTZQbu6YaX/sNKZlR98Grn0gydfh/yT4I3vc0AIQA==",
"resolved": "0.12.8-experimental",
"contentHash": "3n8R44/Z96Ly+ty4eYVJfESqbzvpw96lRLs3zOzyDmr1x1Kw7FNn5CyE416q+bZQV3e1HRuMUvyegMeRE/WedA==",
"dependencies": {
"Microsoft.Windows.SDK.Win32Metadata": "60.0.34-preview"
"Microsoft.Windows.SDK.Win32Metadata": "61.0.15-preview"
}
}
}

View file

@ -48,13 +48,13 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="nunit" Version="4.3.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0">
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
</ItemGroup>
</Project>

View file

@ -86,7 +86,7 @@
<ItemGroup>
<PackageReference Include="ChefKeys" Version="0.1.2" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="Fody" Version="6.5.5">
<PackageReference Include="Fody" Version="6.9.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
@ -95,19 +95,18 @@
<PackageReference Include="MdXaml.Html" Version="1.27.0" />
<PackageReference Include="MdXaml.Plugins" Version="1.27.0" />
<PackageReference Include="MdXaml.Svg" Version="1.27.0" />
<!-- Do not upgrade Microsoft.Extensions.DependencyInjection and Microsoft.Extensions.Hosting since we are .Net7.0 -->
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.7" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.7" />
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
<!-- ModernWpfUI v0.9.5 introduced WinRT changes that causes Notification platform unavailable error on some machines -->
<!-- https://github.com/Flow-Launcher/Flow.Launcher/issues/1772#issuecomment-1502440801 -->
<PackageReference Include="ModernWpfUI" Version="0.9.4" />
<PackageReference Include="PropertyChanged.Fody" Version="3.4.0">
<PackageReference Include="PropertyChanged.Fody" Version="4.1.0">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="SemanticVersioning" Version="3.0.0" />
<PackageReference Include="TaskScheduler" Version="2.12.1" />
<PackageReference Include="VirtualizingWrapPanel" Version="2.1.1" />
<PackageReference Include="TaskScheduler" Version="2.12.2" />
<PackageReference Include="VirtualizingWrapPanel" Version="2.3.0" />
</ItemGroup>
<ItemGroup>

View file

@ -121,7 +121,7 @@
<system:String x:Key="SearchPrecisionLow">Low</system:String>
<system:String x:Key="SearchPrecisionRegular">Regular</system:String>
<system:String x:Key="ShouldUsePinyin">Search with Pinyin</system:String>
<system:String x:Key="ShouldUsePinyinToolTip">Allows using Pinyin to search. Pinyin is the standard system of romanized spelling for translating Chinese.</system:String>
<system:String x:Key="ShouldUsePinyinToolTip">Pinyin is the standard system of romanized spelling for translating Chinese. Please note, enabling this can significantly increase memory usage during search.</system:String>
<system:String x:Key="ShouldUseDoublePinyin">Use Double Pinyin</system:String>
<system:String x:Key="ShouldUseDoublePinyinToolTip">Use Double Pinyin instead of Full Pinyin to search.</system:String>
<system:String x:Key="DoublePinyinSchema">Double Pinyin Schema</system:String>

View file

@ -23,14 +23,13 @@ using Flow.Launcher.Infrastructure.DialogJump;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.Plugin.SharedModels;
using Flow.Launcher.ViewModel;
using Microsoft.Win32;
using ModernWpf.Controls;
using DataObject = System.Windows.DataObject;
using Key = System.Windows.Input.Key;
using MouseButtons = System.Windows.Forms.MouseButtons;
using NotifyIcon = System.Windows.Forms.NotifyIcon;
using Screen = System.Windows.Forms.Screen;
namespace Flow.Launcher
{
@ -96,7 +95,6 @@ namespace Flow.Launcher
InitSoundEffects();
DataObject.AddPastingHandler(QueryTextBox, QueryTextBox_OnPaste);
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
_viewModel.ActualApplicationThemeChanged += ViewModel_ActualApplicationThemeChanged;
}
@ -532,7 +530,7 @@ namespace Flow.Launcher
double yRatio = mousePos.Y / maxHeight;
// Current monitor information
var screen = Screen.FromHandle(new WindowInteropHelper(this).Handle);
var screen = MonitorInfo.GetNearestDisplayMonitor(new WindowInteropHelper(this).Handle);
var workingArea = screen.WorkingArea;
var screenLeftTop = Win32Helper.TransformPixelsToDIP(this, workingArea.X, workingArea.Y);
@ -670,6 +668,16 @@ namespace Flow.Launcher
handled = true;
}
break;
case Win32Helper.WM_POWERBROADCAST: // Handle power broadcast messages
// https://learn.microsoft.com/en-us/windows/win32/power/wm-powerbroadcast
if (wParam.ToInt32() == Win32Helper.PBT_APMRESUMEAUTOMATIC)
{
// Fix for sound not playing after sleep / hibernate
// https://stackoverflow.com/questions/64805186/mediaplayer-doesnt-play-after-computer-sleeps
InitSoundEffects();
}
handled = true;
break;
}
return IntPtr.Zero;
@ -679,16 +687,6 @@ namespace Flow.Launcher
#region Window Sound Effects
private void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
{
// Fix for sound not playing after sleep / hibernate
// https://stackoverflow.com/questions/64805186/mediaplayer-doesnt-play-after-computer-sleeps
if (e.Mode == PowerModes.Resume)
{
InitSoundEffects();
}
}
private void InitSoundEffects()
{
if (_settings.WMPInstalled)
@ -954,36 +952,36 @@ namespace Flow.Launcher
}
}
private Screen SelectedScreen()
private MonitorInfo SelectedScreen()
{
Screen screen;
MonitorInfo screen;
switch (_settings.SearchWindowScreen)
{
case SearchWindowScreens.Cursor:
screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
break;
case SearchWindowScreens.Primary:
screen = Screen.PrimaryScreen;
screen = MonitorInfo.GetCursorDisplayMonitor();
break;
case SearchWindowScreens.Focus:
var foregroundWindowHandle = Win32Helper.GetForegroundWindow();
screen = Screen.FromHandle(foregroundWindowHandle);
screen = MonitorInfo.GetNearestDisplayMonitor(Win32Helper.GetForegroundWindow());
break;
case SearchWindowScreens.Primary:
screen = MonitorInfo.GetPrimaryDisplayMonitor();
break;
case SearchWindowScreens.Custom:
if (_settings.CustomScreenNumber <= Screen.AllScreens.Length)
screen = Screen.AllScreens[_settings.CustomScreenNumber - 1];
var allScreens = MonitorInfo.GetDisplayMonitors();
if (_settings.CustomScreenNumber <= allScreens.Count)
screen = allScreens[_settings.CustomScreenNumber - 1];
else
screen = Screen.AllScreens[0];
screen = allScreens[0];
break;
default:
screen = Screen.AllScreens[0];
screen = MonitorInfo.GetDisplayMonitors()[0];
break;
}
return screen ?? Screen.AllScreens[0];
return screen ?? MonitorInfo.GetDisplayMonitors()[0];
}
private double HorizonCenter(Screen screen)
private double HorizonCenter(MonitorInfo screen)
{
var dip1 = Win32Helper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0);
var dip2 = Win32Helper.TransformPixelsToDIP(this, screen.WorkingArea.Width, 0);
@ -991,7 +989,7 @@ namespace Flow.Launcher
return left;
}
private double VerticalCenter(Screen screen)
private double VerticalCenter(MonitorInfo screen)
{
var dip1 = Win32Helper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Y);
var dip2 = Win32Helper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Height);
@ -999,7 +997,7 @@ namespace Flow.Launcher
return top;
}
private double HorizonRight(Screen screen)
private double HorizonRight(MonitorInfo screen)
{
var dip1 = Win32Helper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0);
var dip2 = Win32Helper.TransformPixelsToDIP(this, screen.WorkingArea.Width, 0);
@ -1007,14 +1005,14 @@ namespace Flow.Launcher
return left;
}
private double HorizonLeft(Screen screen)
private double HorizonLeft(MonitorInfo screen)
{
var dip1 = Win32Helper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0);
var left = dip1.X + 10;
return left;
}
public double VerticalTop(Screen screen)
private double VerticalTop(MonitorInfo screen)
{
var dip1 = Win32Helper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Y);
var top = dip1.Y + 10;
@ -1443,7 +1441,6 @@ namespace Flow.Launcher
animationSoundWMP?.Close();
animationSoundWPF?.Dispose();
_viewModel.ActualApplicationThemeChanged -= ViewModel_ActualApplicationThemeChanged;
SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
}
_disposed = true;

View file

@ -1,10 +1,10 @@
using System;
using System.IO;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media.Animation;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin.SharedModels;
namespace Flow.Launcher
{
@ -16,7 +16,7 @@ namespace Flow.Launcher
public Msg()
{
InitializeComponent();
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
var screen = MonitorInfo.GetCursorDisplayMonitor();
var dipWorkingArea = Win32Helper.TransformPixelsToDIP(this,
screen.WorkingArea.Width,
screen.WorkingArea.Height);

View file

@ -1,10 +1,10 @@
using System;
using System.IO;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media.Animation;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin.SharedModels;
namespace Flow.Launcher
{
@ -16,7 +16,7 @@ namespace Flow.Launcher
public MsgWithButton()
{
InitializeComponent();
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
var screen = MonitorInfo.GetCursorDisplayMonitor();
var dipWorkingArea = Win32Helper.TransformPixelsToDIP(this,
screen.WorkingArea.Width,
screen.WorkingArea.Height);

View file

@ -598,6 +598,10 @@ namespace Flow.Launcher
remove => _mainVM.ActualApplicationThemeChanged -= value;
}
public string GetDataDirectory() => DataLocation.DataDirectory();
public string GetLogDirectory() => DataLocation.VersionLogDirectory;
#endregion
#region Private Methods

View file

@ -1,15 +1,15 @@
using Flow.Launcher.Core.ExternalPlugins;
using System;
using System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Documents;
using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher
{
@ -44,7 +44,7 @@ namespace Flow.Launcher
var websiteUrl = exception switch
{
FlowPluginException pluginException =>GetIssuesUrl(pluginException.Metadata.Website),
FlowPluginException pluginException => GetIssuesUrl(pluginException.Metadata.Website),
_ => Constant.IssuesUrl
};
@ -73,17 +73,36 @@ namespace Flow.Launcher
Margin = new Thickness(0)
};
var link = new Hyperlink
Hyperlink link = null;
try
{
IsEnabled = true
};
link.Inlines.Add(url);
link.NavigateUri = new Uri(url);
link.Click += (s, e) => SearchWeb.OpenInBrowserTab(url);
var uri = new Uri(url);
link = new Hyperlink
{
IsEnabled = true
};
link.Inlines.Add(url);
link.NavigateUri = uri;
link.Click += (s, e) => SearchWeb.OpenInBrowserTab(url);
}
catch (Exception)
{
// Leave link as null if the URL is invalid
}
paragraph.Inlines.Add(textBeforeUrl);
paragraph.Inlines.Add(" ");
paragraph.Inlines.Add(link);
if (link is null)
{
// Add the URL as plain text if it is invalid
paragraph.Inlines.Add(url);
}
else
{
// Add the hyperlink if it is valid
paragraph.Inlines.Add(link);
}
paragraph.Inlines.Add("\n");
return paragraph;

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
@ -111,9 +111,9 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
{
get
{
var screens = Screen.AllScreens;
var screens = MonitorInfo.GetDisplayMonitors();
var screenNumbers = new List<int>();
for (int i = 1; i <= screens.Length; i++)
for (int i = 1; i <= screens.Count; i++)
{
screenNumbers.Add(i);
}

View file

@ -76,6 +76,7 @@
<cc:Card
Title="{DynamicResource dialogJumpHotkey}"
Margin="0 14 0 0"
Icon="&#xE8AB;"
Sub="{DynamicResource dialogJumpHotkeyToolTip}">
<flowlauncher:HotkeyControl
ChangeHotkey="{Binding SetDialogJumpHotkeyCommand}"

View file

@ -7,10 +7,10 @@ using System.Windows.Interop;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.SharedModels;
using Flow.Launcher.SettingPages.Views;
using Flow.Launcher.ViewModel;
using ModernWpf.Controls;
using Screen = System.Windows.Forms.Screen;
namespace Flow.Launcher;
@ -202,7 +202,7 @@ public partial class SettingWindow
private static bool IsPositionValid(double top, double left)
{
foreach (var screen in Screen.AllScreens)
foreach (var screen in MonitorInfo.GetDisplayMonitors())
{
var workingArea = screen.WorkingArea;
@ -217,7 +217,7 @@ public partial class SettingWindow
private double WindowLeft()
{
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
var screen = MonitorInfo.GetCursorDisplayMonitor();
var dip1 = Win32Helper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0);
var dip2 = Win32Helper.TransformPixelsToDIP(this, screen.WorkingArea.Width, 0);
var left = (dip2.X - ActualWidth) / 2 + dip1.X;
@ -226,7 +226,7 @@ public partial class SettingWindow
private double WindowTop()
{
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
var screen = MonitorInfo.GetCursorDisplayMonitor();
var dip1 = Win32Helper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Y);
var dip2 = Win32Helper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Height);
var top = (dip2.Y - ActualHeight) / 2 + dip1.Y - 20;

View file

@ -499,15 +499,14 @@ namespace Flow.Launcher.ViewModel
// For Dialog Jump and left click mode, we need to navigate to the path
if (_isDialogJump && Settings.DialogJumpResultBehaviour == DialogJumpResultBehaviours.LeftClick)
{
Hide();
if (SelectedResults.SelectedItem != null && DialogWindowHandle != nint.Zero)
if (result is DialogJumpResult dialogJumpResult)
{
if (result is DialogJumpResult dialogJumpResult)
{
Win32Helper.SetForegroundWindow(DialogWindowHandle);
_ = Task.Run(() => DialogJump.JumpToPathAsync(DialogWindowHandle, dialogJumpResult.DialogJumpPath));
}
Win32Helper.SetForegroundWindow(DialogWindowHandle);
_ = Task.Run(() => DialogJump.JumpToPathAsync(DialogWindowHandle, dialogJumpResult.DialogJumpPath));
}
else
{
App.API.LogError(ClassName, "DialogJumpResult expected but got a different result type.");
}
}
// For query mode, we execute the result

File diff suppressed because it is too large Load diff

View file

@ -96,7 +96,7 @@
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.3" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.7" />
</ItemGroup>
</Project>

View file

@ -47,9 +47,8 @@
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="Droplex" Version="1.7.0" />
<!-- Do not upgrade System.Data.OleDb since we are .Net7.0 -->
<PackageReference Include="System.Data.OleDb" Version="9.0.3" />
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
<PackageReference Include="System.Data.OleDb" Version="9.0.7" />
<PackageReference Include="System.Linq.Async" Version="6.0.3" />
<PackageReference Include="tlbimp-Microsoft.Search.Interop" Version="1.0.0" />
</ItemGroup>

View file

@ -7,6 +7,7 @@ using System.Windows.Input;
using Flow.Launcher.Plugin.Explorer.Search.Everything;
using Flow.Launcher.Plugin.Explorer.Views;
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.Plugin.SharedModels;
using Peter;
using Path = System.IO.Path;
@ -72,10 +73,10 @@ namespace Flow.Launcher.Plugin.Explorer.Search
internal static void ShowNativeContextMenu(string path, ResultType type)
{
var screenWithMouseCursor = System.Windows.Forms.Screen.FromPoint(System.Windows.Forms.Cursor.Position);
var screenWithMouseCursor = MonitorInfo.GetCursorDisplayMonitor();
var xOfScreenCenter = screenWithMouseCursor.WorkingArea.Left + screenWithMouseCursor.WorkingArea.Width / 2;
var yOfScreenCenter = screenWithMouseCursor.WorkingArea.Top + screenWithMouseCursor.WorkingArea.Height / 2;
var showPosition = new System.Drawing.Point(xOfScreenCenter, yOfScreenCenter);
var showPosition = new System.Drawing.Point((int)xOfScreenCenter, (int)yOfScreenCenter);
switch (type)
{

View file

@ -52,7 +52,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.106">
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.183">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View file

@ -163,23 +163,20 @@ namespace Flow.Launcher.Plugin.ProcessKiller
try
{
var handle = PInvoke.OpenProcess(PROCESS_ACCESS_RIGHTS.PROCESS_QUERY_LIMITED_INFORMATION, false, (uint)p.Id);
if (handle.Value == IntPtr.Zero)
if (handle == HWND.Null)
{
return string.Empty;
}
using var safeHandle = new SafeProcessHandle(handle.Value, true);
using var safeHandle = new SafeProcessHandle((nint)handle.Value, true);
uint capacity = 2000;
Span<char> buffer = new char[capacity];
fixed (char* pBuffer = buffer)
if (!PInvoke.QueryFullProcessImageName(safeHandle, PROCESS_NAME_FORMAT.PROCESS_NAME_WIN32, buffer, ref capacity))
{
if (!PInvoke.QueryFullProcessImageName(safeHandle, PROCESS_NAME_FORMAT.PROCESS_NAME_WIN32, (PWSTR)pBuffer, ref capacity))
{
return string.Empty;
}
return buffer[..(int)capacity].ToString();
return string.Empty;
}
return buffer[..(int)capacity].ToString();
}
catch
{

View file

@ -64,8 +64,8 @@
<ItemGroup>
<PackageReference Include="ini-parser" Version="2.5.2" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.0" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.106">
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.7" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.183">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View file

@ -27,28 +27,36 @@ namespace Flow.Launcher.Plugin.Program.Programs
// If there is no resource to localize a file name the method returns a non zero value.
fixed (char* bufferPtr = buffer)
{
var result = PInvoke.SHGetLocalizedName(path, bufferPtr, capacity, out var id);
if (result != HRESULT.S_OK)
int id;
fixed (char* pathPtr = path)
{
return string.Empty;
}
var result = PInvoke.SHGetLocalizedName(new PCWSTR(pathPtr), bufferPtr, capacity, &id);
var resourcePathStr = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(bufferPtr).ToString();
_ = PInvoke.ExpandEnvironmentStrings(resourcePathStr, bufferPtr, capacity);
using var handle = PInvoke.LoadLibraryEx(resourcePathStr,
LOAD_LIBRARY_FLAGS.DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_FLAGS.LOAD_LIBRARY_AS_DATAFILE);
if (handle.IsInvalid)
{
return string.Empty;
}
if (result != HRESULT.S_OK)
{
return string.Empty;
}
// not sure about the behavior of Pinvoke.LoadString, so we clear the buffer before using it (so it must be a null-terminated string)
buffer.Clear();
var resourcePathStr = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(bufferPtr).ToString();
fixed (char* resourcePathPtr = resourcePathStr)
{
_ = PInvoke.ExpandEnvironmentStrings(new PCWSTR(resourcePathPtr), bufferPtr, capacity);
using var handle = PInvoke.LoadLibraryEx(resourcePathStr,
LOAD_LIBRARY_FLAGS.DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_FLAGS.LOAD_LIBRARY_AS_DATAFILE);
if (handle.IsInvalid)
{
return string.Empty;
}
if (PInvoke.LoadString(handle, (uint)id, bufferPtr, capacity) != 0)
{
var lString = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(bufferPtr).ToString();
return lString;
// not sure about the behavior of Pinvoke.LoadString, so we clear the buffer before using it (so it must be a null-terminated string)
buffer.Clear();
if (PInvoke.LoadString(handle, (uint)id, buffer, capacity) != 0)
{
var lString = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(bufferPtr).ToString();
return lString;
}
}
}
}

View file

@ -37,7 +37,6 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Flow.Launcher.Infrastructure\Flow.Launcher.Infrastructure.csproj" />
<ProjectReference Include="..\..\Flow.Launcher.Plugin\Flow.Launcher.Plugin.csproj" />
</ItemGroup>
@ -59,7 +58,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.106">
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.183">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View file

@ -63,6 +63,8 @@
<system:String x:Key="flowlauncher_plugin_sys_dlgtext_restart_computer">Are you sure you want to restart the computer?</system:String>
<system:String x:Key="flowlauncher_plugin_sys_dlgtext_restart_computer_advanced">Are you sure you want to restart the computer with Advanced Boot Options?</system:String>
<system:String x:Key="flowlauncher_plugin_sys_dlgtext_logoff_computer">Are you sure you want to log off?</system:String>
<system:String x:Key="flowlauncher_plugin_sys_dlgtitle_error">Error</system:String>
<system:String x:Key="flowlauncher_plugin_sys_dlgtext_empty_recycle_bin_failed">Failed to empty the recycle bin. This might happen if:{0}- Some items are currently in use{0}- Some items can't be deleted due to permissions{0}Please close any applications that might be using these files and try again.</system:String>
<system:String x:Key="flowlauncher_plugin_sys_command_keyword_setting_window_title">Command Keyword Setting</system:String>
<system:String x:Key="flowlauncher_plugin_sys_custom_command_keyword">Custom Command Keyword</system:String>

View file

@ -5,8 +5,6 @@ using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.UserSettings;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.Security;
@ -52,6 +50,8 @@ namespace Flow.Launcher.Plugin.Sys
private const SHUTDOWN_REASON REASON = SHUTDOWN_REASON.SHTDN_REASON_MAJOR_OTHER |
SHUTDOWN_REASON.SHTDN_REASON_FLAG_PLANNED;
private const string Documentation = "https://flowlauncher.com/docs/#/usage-tips";
private PluginInitContext _context;
private Settings _settings;
private ThemeSelector _themeSelector;
@ -338,11 +338,9 @@ namespace Flow.Launcher.Plugin.Sys
var result = PInvoke.SHEmptyRecycleBin(new(), string.Empty, 0);
if (result != HRESULT.S_OK && result != HRESULT.E_UNEXPECTED)
{
_context.API.ShowMsgBox("Failed to empty the recycle bin. This might happen if:\n" +
"- A file in the recycle bin is in use\n" +
"- You don't have permission to delete some items\n" +
"Please close any applications that might be using these files and try again.",
"Error",
_context.API.ShowMsgBox(
string.Format(_context.API.GetTranslation("flowlauncher_plugin_sys_dlgtext_empty_recycle_bin_failed"), Environment.NewLine),
_context.API.GetTranslation("flowlauncher_plugin_sys_dlgtitle_error"),
MessageBoxButton.OK, MessageBoxImage.Error);
}
@ -404,6 +402,8 @@ namespace Flow.Launcher.Plugin.Sys
IcoPath = "Images\\app.png",
Action = c =>
{
// Hide the window first then open setting dialog because main window can be topmost window which will still display on top of the setting dialog for a while
_context.API.HideMainWindow();
_context.API.OpenSettingDialog();
return true;
}
@ -445,11 +445,11 @@ namespace Flow.Launcher.Plugin.Sys
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xf12b"),
Title = "Open Log Location",
IcoPath = "Images\\app.png",
CopyText = DataLocation.VersionLogDirectory,
AutoCompleteText = DataLocation.VersionLogDirectory,
CopyText = _context.API.GetLogDirectory(),
AutoCompleteText = _context.API.GetLogDirectory(),
Action = c =>
{
_context.API.OpenDirectory(DataLocation.VersionLogDirectory);
_context.API.OpenDirectory(_context.API.GetLogDirectory());
return true;
}
},
@ -458,11 +458,11 @@ namespace Flow.Launcher.Plugin.Sys
Title = "Flow Launcher Tips",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xe897"),
IcoPath = "Images\\app.png",
CopyText = Constant.Documentation,
AutoCompleteText = Constant.Documentation,
CopyText = Documentation,
AutoCompleteText = Documentation,
Action = c =>
{
_context.API.OpenUrl(Constant.Documentation);
_context.API.OpenUrl(Documentation);
return true;
}
},
@ -471,11 +471,11 @@ namespace Flow.Launcher.Plugin.Sys
Title = "Flow Launcher UserData Folder",
Glyph = new GlyphInfo (FontFamily:"/Resources/#Segoe Fluent Icons", Glyph:"\xf12b"),
IcoPath = "Images\\app.png",
CopyText = DataLocation.DataDirectory(),
AutoCompleteText = DataLocation.DataDirectory(),
CopyText = _context.API.GetDataDirectory(),
AutoCompleteText = _context.API.GetDataDirectory(),
Action = c =>
{
_context.API.OpenDirectory(DataLocation.DataDirectory());
_context.API.OpenDirectory(_context.API.GetDataDirectory());
return true;
}
},