Improve Discord mute focus handling
This commit is contained in:
122
internal/app/discord.go
Normal file
122
internal/app/discord.go
Normal file
@@ -0,0 +1,122 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func pressDiscordMuteHotkey() error {
|
||||
script := `
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
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))
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("discord mute failed: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user