Simplify GUI settings and build flags

This commit is contained in:
every_holiday
2026-06-26 09:16:46 +09:00
parent 4d77e67870
commit ae426244e0
22 changed files with 846 additions and 237 deletions

View File

@@ -3,120 +3,87 @@ package app
import (
"fmt"
"log"
"os/exec"
"strings"
"syscall"
"unsafe"
)
const (
vkControl = 0x11
vkShift = 0x10
vkM = 0x4D
keyUp = 0x0002
swRestore = 9
)
func pressDiscordMuteHotkey() error {
script := `
$ErrorActionPreference = "Stop"
user32 := syscall.NewLazyDLL("user32.dll")
enumWindows := user32.NewProc("EnumWindows")
getWindowTextW := user32.NewProc("GetWindowTextW")
isWindowVisible := user32.NewProc("IsWindowVisible")
setForegroundWindow := user32.NewProc("SetForegroundWindow")
showWindow := user32.NewProc("ShowWindow")
getWindowRect := user32.NewProc("GetWindowRect")
keybdEvent := user32.NewProc("keybd_event")
setCursorPos := user32.NewProc("SetCursorPos")
sleep := syscall.NewLazyDLL("kernel32.dll").NewProc("Sleep")
Add-Type @"
using System;
using System.Runtime.InteropServices;
public static class Win32 {
[StructLayout(LayoutKind.Sequential)]
public struct RECT {
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[DllImport("user32.dll")]
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")]
public static extern bool SetCursorPos(int X, int Y);
[DllImport("user32.dll")]
public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, UIntPtr dwExtraInfo);
}
"@
function Click-WindowCenter($p) {
if ($null -eq $p) { return }
$hWnd = [IntPtr]$p.MainWindowHandle
if ($hWnd -eq [IntPtr]::Zero) { return }
$rect = New-Object 'Win32+RECT'
if (-not [Win32]::GetWindowRect($hWnd, [ref]$rect)) { return }
$x = [int](($rect.Left + $rect.Right) / 2)
$y = [int](($rect.Top + $rect.Bottom) / 2)
[Win32]::SetCursorPos($x, $y) | Out-Null
Start-Sleep -Milliseconds 50
[Win32]::mouse_event(0x0002, 0, 0, 0, [UIntPtr]::Zero)
[Win32]::mouse_event(0x0004, 0, 0, 0, [UIntPtr]::Zero)
Start-Sleep -Milliseconds 100
}
function Get-DiscordWindows {
$windows = foreach ($p in Get-Process) {
$title = ($p.MainWindowTitle | Out-String).Trim()
if (-not $title) { continue }
if (-not $title.ToLower().Contains('discord')) { continue }
$p
}
if (-not $windows) { return @() }
return $windows
}
function Get-BestDiscordWindow {
$windows = Get-DiscordWindows
if (-not $windows -or $windows.Count -eq 0) { return $null }
$browserKeywords = @('google chrome', 'microsoft edge', 'mozilla firefox', 'brave', 'opera')
$ranked = $windows | Sort-Object {
$title = ($_.MainWindowTitle | Out-String).Trim().ToLower()
$score = 0
foreach ($keyword in $browserKeywords) {
if ($title.Contains($keyword)) { $score += 10 }
}
if ($title -match '^\(\d+\)\s*discord') { $score += 20 }
if ($title.Contains('discord')) { $score += 5 }
$score
} -Descending
return $ranked | Select-Object -First 1
}
function Get-VRChatWindow {
$windows = Get-Process | Where-Object {
$_.MainWindowTitle -and (
$_.MainWindowTitle -eq 'VRChat' -or $_.MainWindowTitle.ToLower().StartsWith('vrchat ')
)
}
if (-not $windows) { return $null }
return $windows | Sort-Object { $_.MainWindowHandle } -Descending | Select-Object -First 1
}
function Activate-Window($p) {
if ($null -eq $p) { return }
$wshell = New-Object -ComObject WScript.Shell
try { $null = $wshell.AppActivate($p.Id) } catch {}
Start-Sleep -Milliseconds 200
Click-WindowCenter $p
}
$discord = Get-BestDiscordWindow
if ($null -eq $discord) { exit 2 }
Activate-Window $discord
$wshell = New-Object -ComObject WScript.Shell
Start-Sleep -Milliseconds 200
$wshell.SendKeys('^+m')
Start-Sleep -Milliseconds 200
$vrchat = Get-VRChatWindow
if ($null -ne $vrchat) {
Activate-Window $vrchat
}
`
cmd := exec.Command("powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", script)
out, err := cmd.CombinedOutput()
if len(out) > 0 {
log.Printf("discord mute output: %s", string(out))
var target uintptr
cb := syscall.NewCallback(func(hwnd uintptr, lparam uintptr) uintptr {
vis, _, _ := isWindowVisible.Call(hwnd)
if vis == 0 {
return 1
}
buf := make([]uint16, 512)
n, _, _ := getWindowTextW.Call(hwnd, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)))
if n == 0 {
return 1
}
title := strings.ToLower(strings.TrimSpace(syscall.UTF16ToString(buf[:n])))
if !strings.Contains(title, "discord") {
return 1
}
target = hwnd
return 0
})
r1, _, err1 := enumWindows.Call(cb, 0)
if r1 == 0 && target == 0 {
return fmt.Errorf("discord window not found: %v", err1)
}
if err != nil {
return fmt.Errorf("discord mute failed: %w", err)
if target == 0 {
return fmt.Errorf("discord window not found")
}
showWindow.Call(target, swRestore)
setForegroundWindow.Call(target)
sleep.Call(150)
type rect struct {
Left int32
Top int32
Right int32
Bottom int32
}
var r rect
if v, _, _ := getWindowRect.Call(target, uintptr(unsafe.Pointer(&r))); v != 0 {
x := int((r.Left + r.Right) / 2)
y := int((r.Top + r.Bottom) / 2)
setCursorPos.Call(uintptr(x), uintptr(y))
sleep.Call(50)
}
send := func(vk byte, flags uintptr) {
keybdEvent.Call(uintptr(vk), 0, flags, 0)
}
send(vkControl, 0)
send(vkShift, 0)
send(vkM, 0)
send(vkM, keyUp)
send(vkShift, keyUp)
send(vkControl, keyUp)
sleep.Call(100)
SetDiscordWindow("Discord")
log.Printf("discord hotkey sent via keybd_event")
return nil
}