Initial commit to new repository
This commit is contained in:
194
.decompiledproj/AxCopilot/Handlers/SnapHandler.cs
Normal file
194
.decompiledproj/AxCopilot/Handlers/SnapHandler.cs
Normal file
@@ -0,0 +1,194 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AxCopilot.SDK;
|
||||
using AxCopilot.Services;
|
||||
|
||||
namespace AxCopilot.Handlers;
|
||||
|
||||
public class SnapHandler : IActionHandler
|
||||
{
|
||||
private struct RECT
|
||||
{
|
||||
public int left;
|
||||
|
||||
public int top;
|
||||
|
||||
public int right;
|
||||
|
||||
public int bottom;
|
||||
}
|
||||
|
||||
private struct MONITORINFO
|
||||
{
|
||||
public int cbSize;
|
||||
|
||||
public RECT rcMonitor;
|
||||
|
||||
public RECT rcWork;
|
||||
|
||||
public uint dwFlags;
|
||||
}
|
||||
|
||||
private const uint SWP_SHOWWINDOW = 64u;
|
||||
|
||||
private const uint SWP_NOZORDER = 4u;
|
||||
|
||||
private const uint MONITOR_DEFAULTTONEAREST = 2u;
|
||||
|
||||
private const int SW_RESTORE = 9;
|
||||
|
||||
private const int SW_MAXIMIZE = 3;
|
||||
|
||||
private static readonly (string Key, string Label, string Desc)[] _snapOptions = new(string, string, string)[20]
|
||||
{
|
||||
("left", "왼쪽 절반", "화면 왼쪽 50% 영역에 배치"),
|
||||
("right", "오른쪽 절반", "화면 오른쪽 50% 영역에 배치"),
|
||||
("top", "위쪽 절반", "화면 위쪽 50% 영역에 배치"),
|
||||
("bottom", "아래쪽 절반", "화면 아래쪽 50% 영역에 배치"),
|
||||
("tl", "좌상단 1/4", "화면 좌상단 25% 영역에 배치"),
|
||||
("tr", "우상단 1/4", "화면 우상단 25% 영역에 배치"),
|
||||
("bl", "좌하단 1/4", "화면 좌하단 25% 영역에 배치"),
|
||||
("br", "우하단 1/4", "화면 우하단 25% 영역에 배치"),
|
||||
("l-rt", "좌반 + 우상", "왼쪽 50% + 오른쪽 상단 25% (2창용)"),
|
||||
("l-rb", "좌반 + 우하", "왼쪽 50% + 오른쪽 하단 25% (2창용)"),
|
||||
("r-lt", "우반 + 좌상", "오른쪽 50% + 왼쪽 상단 25% (2창용)"),
|
||||
("r-lb", "우반 + 좌하", "오른쪽 50% + 왼쪽 하단 25% (2창용)"),
|
||||
("third-l", "좌측 1/3", "화면 왼쪽 33% 영역에 배치"),
|
||||
("third-c", "중앙 1/3", "화면 가운데 33% 영역에 배치"),
|
||||
("third-r", "우측 1/3", "화면 오른쪽 33% 영역에 배치"),
|
||||
("two3-l", "좌측 2/3", "화면 왼쪽 66% 영역에 배치"),
|
||||
("two3-r", "우측 2/3", "화면 오른쪽 66% 영역에 배치"),
|
||||
("full", "전체 화면", "최대화"),
|
||||
("center", "화면 중앙", "화면 중앙 80% 크기로 배치"),
|
||||
("restore", "원래 크기 복원", "창을 이전 크기로 복원")
|
||||
};
|
||||
|
||||
public string? Prefix => "snap";
|
||||
|
||||
public PluginMetadata Metadata => new PluginMetadata("WindowSnap", "창 배치 — 2/3/4분할, 1/3·2/3, 전체화면, 중앙, 복원", "1.1", "AX");
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool SetWindowPos(nint hWnd, nint hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool ShowWindow(nint hWnd, int nCmdShow);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern nint MonitorFromWindow(nint hwnd, uint dwFlags);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool GetMonitorInfo(nint hMonitor, ref MONITORINFO lpmi);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool IsWindow(nint hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool IsIconic(nint hWnd);
|
||||
|
||||
public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
|
||||
{
|
||||
string q = query.Trim().ToLowerInvariant();
|
||||
nint previousWindow = WindowTracker.PreviousWindow;
|
||||
bool flag = previousWindow != IntPtr.Zero && IsWindow(previousWindow);
|
||||
string hint = (flag ? "Enter로 현재 활성 창에 적용" : "대상 창 없음 — 런처를 열기 전 창에 적용됩니다");
|
||||
IEnumerable<(string, string, string)> enumerable;
|
||||
if (!string.IsNullOrWhiteSpace(q))
|
||||
{
|
||||
enumerable = _snapOptions.Where(((string Key, string Label, string Desc) o) => o.Key.StartsWith(q) || o.Label.Contains(q));
|
||||
}
|
||||
else
|
||||
{
|
||||
IEnumerable<(string, string, string)> snapOptions = _snapOptions;
|
||||
enumerable = snapOptions;
|
||||
}
|
||||
IEnumerable<(string, string, string)> source = enumerable;
|
||||
List<LauncherItem> list = source.Select<(string, string, string), LauncherItem>(((string Key, string Label, string Desc) o) => new LauncherItem(o.Label, o.Desc + " · " + hint, null, o.Key, null, "\ue8a0")).ToList();
|
||||
if (!list.Any())
|
||||
{
|
||||
list.Add(new LauncherItem("알 수 없는 스냅 방향: " + q, "left / right / tl / tr / bl / br / third-l/c/r / two3-l/r / full / center / restore", null, null, null, "\ue7ba"));
|
||||
}
|
||||
return Task.FromResult((IEnumerable<LauncherItem>)list);
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync(LauncherItem item, CancellationToken ct)
|
||||
{
|
||||
object data = item.Data;
|
||||
if (!(data is string snapKey))
|
||||
{
|
||||
return;
|
||||
}
|
||||
nint hwnd = WindowTracker.PreviousWindow;
|
||||
if (hwnd != IntPtr.Zero && IsWindow(hwnd))
|
||||
{
|
||||
if (IsIconic(hwnd))
|
||||
{
|
||||
ShowWindow(hwnd, 9);
|
||||
}
|
||||
await Task.Delay(80, ct);
|
||||
ApplySnap(hwnd, snapKey);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ApplySnap(nint hwnd, string key)
|
||||
{
|
||||
nint hMonitor = MonitorFromWindow(hwnd, 2u);
|
||||
MONITORINFO lpmi = new MONITORINFO
|
||||
{
|
||||
cbSize = Marshal.SizeOf<MONITORINFO>()
|
||||
};
|
||||
if (!GetMonitorInfo(hMonitor, ref lpmi))
|
||||
{
|
||||
return;
|
||||
}
|
||||
RECT rcWork = lpmi.rcWork;
|
||||
int num = rcWork.right - rcWork.left;
|
||||
int num2 = rcWork.bottom - rcWork.top;
|
||||
int left = rcWork.left;
|
||||
int top = rcWork.top;
|
||||
if (key == "full")
|
||||
{
|
||||
ShowWindow(hwnd, 3);
|
||||
return;
|
||||
}
|
||||
if (key == "restore")
|
||||
{
|
||||
ShowWindow(hwnd, 9);
|
||||
return;
|
||||
}
|
||||
if (1 == 0)
|
||||
{
|
||||
}
|
||||
(int, int, int, int) tuple = key switch
|
||||
{
|
||||
"left" => (left, top, num / 2, num2),
|
||||
"right" => (left + num / 2, top, num / 2, num2),
|
||||
"top" => (left, top, num, num2 / 2),
|
||||
"bottom" => (left, top + num2 / 2, num, num2 / 2),
|
||||
"tl" => (left, top, num / 2, num2 / 2),
|
||||
"tr" => (left + num / 2, top, num / 2, num2 / 2),
|
||||
"bl" => (left, top + num2 / 2, num / 2, num2 / 2),
|
||||
"br" => (left + num / 2, top + num2 / 2, num / 2, num2 / 2),
|
||||
"l-rt" => (left + num / 2, top, num / 2, num2 / 2),
|
||||
"l-rb" => (left + num / 2, top + num2 / 2, num / 2, num2 / 2),
|
||||
"r-lt" => (left, top, num / 2, num2 / 2),
|
||||
"r-lb" => (left, top + num2 / 2, num / 2, num2 / 2),
|
||||
"third-l" => (left, top, num / 3, num2),
|
||||
"third-c" => (left + num / 3, top, num / 3, num2),
|
||||
"third-r" => (left + num * 2 / 3, top, num / 3, num2),
|
||||
"two3-l" => (left, top, num * 2 / 3, num2),
|
||||
"two3-r" => (left + num / 3, top, num * 2 / 3, num2),
|
||||
"center" => (left + num / 10, top + num2 / 10, num * 8 / 10, num2 * 8 / 10),
|
||||
_ => (left, top, num, num2),
|
||||
};
|
||||
if (1 == 0)
|
||||
{
|
||||
}
|
||||
var (x, y, cx, cy) = tuple;
|
||||
ShowWindow(hwnd, 9);
|
||||
SetWindowPos(hwnd, IntPtr.Zero, x, y, cx, cy, 68u);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user