mirror of
https://github.com/black-ant/Ant-Browser.git
synced 2026-07-14 18:48:55 +08:00
fix: restore existing window on repeated launch
This commit is contained in:
@@ -16,8 +16,13 @@ const (
|
||||
var (
|
||||
user32Activate = windows.NewLazySystemDLL("user32.dll")
|
||||
procAllowSetForegroundWindow = user32Activate.NewProc("AllowSetForegroundWindow")
|
||||
procAttachThreadInput = user32Activate.NewProc("AttachThreadInput")
|
||||
procEnumWindows = user32Activate.NewProc("EnumWindows")
|
||||
procGetForegroundWindow = user32Activate.NewProc("GetForegroundWindow")
|
||||
procGetWindow = user32Activate.NewProc("GetWindow")
|
||||
procGetWindowTextLengthW = user32Activate.NewProc("GetWindowTextLengthW")
|
||||
procGetWindowThreadProcessID = user32Activate.NewProc("GetWindowThreadProcessId")
|
||||
procIsIconic = user32Activate.NewProc("IsIconic")
|
||||
procIsWindowVisible = user32Activate.NewProc("IsWindowVisible")
|
||||
procShowWindow = user32Activate.NewProc("ShowWindow")
|
||||
procSetForegroundWindow = user32Activate.NewProc("SetForegroundWindow")
|
||||
@@ -25,6 +30,7 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
gwOwner = 4
|
||||
hwndTopmost = ^uintptr(0)
|
||||
hwndNotopmost = ^uintptr(1)
|
||||
swpNoMove = 0x0002
|
||||
@@ -44,8 +50,13 @@ func activateExistingSingleInstanceWindow(pid int) {
|
||||
}
|
||||
grantExistingSingleInstanceForeground(pid)
|
||||
if hwnd := findTopLevelWindowByPID(uint32(pid)); hwnd != 0 {
|
||||
procShowWindow.Call(hwnd, swShow)
|
||||
procShowWindow.Call(hwnd, swRestore)
|
||||
procShowWindow.Call(hwnd, swShow)
|
||||
if ok, _, _ := procSetForegroundWindow.Call(hwnd); ok == 0 {
|
||||
attachForegroundThreadInput(hwnd, func() {
|
||||
procSetForegroundWindow.Call(hwnd)
|
||||
})
|
||||
}
|
||||
if ok, _, _ := procSetForegroundWindow.Call(hwnd); ok == 0 {
|
||||
procSetWindowPos.Call(hwnd, hwndTopmost, 0, 0, 0, 0, swpNoMove|swpNoSize|swpShowWindow)
|
||||
procSetWindowPos.Call(hwnd, hwndNotopmost, 0, 0, 0, 0, swpNoMove|swpNoSize|swpShowWindow)
|
||||
@@ -54,23 +65,77 @@ func activateExistingSingleInstanceWindow(pid int) {
|
||||
}
|
||||
}
|
||||
|
||||
func attachForegroundThreadInput(hwnd uintptr, fn func()) {
|
||||
foreground, _, _ := procGetForegroundWindow.Call()
|
||||
if foreground == 0 || hwnd == 0 {
|
||||
fn()
|
||||
return
|
||||
}
|
||||
|
||||
var foregroundPID uint32
|
||||
foregroundThread, _, _ := procGetWindowThreadProcessID.Call(foreground, uintptr(unsafe.Pointer(&foregroundPID)))
|
||||
var targetPID uint32
|
||||
targetThread, _, _ := procGetWindowThreadProcessID.Call(hwnd, uintptr(unsafe.Pointer(&targetPID)))
|
||||
if foregroundThread == 0 || targetThread == 0 || foregroundThread == targetThread {
|
||||
fn()
|
||||
return
|
||||
}
|
||||
|
||||
procAttachThreadInput.Call(foregroundThread, targetThread, 1)
|
||||
defer procAttachThreadInput.Call(foregroundThread, targetThread, 0)
|
||||
fn()
|
||||
}
|
||||
|
||||
func findTopLevelWindowByPID(pid uint32) uintptr {
|
||||
var matched uintptr
|
||||
type candidateWindow struct {
|
||||
hwnd uintptr
|
||||
visible bool
|
||||
titled bool
|
||||
owned bool
|
||||
minimized bool
|
||||
}
|
||||
var candidates []candidateWindow
|
||||
callback := windows.NewCallback(func(hwnd uintptr, lparam uintptr) uintptr {
|
||||
var windowPID uint32
|
||||
procGetWindowThreadProcessID.Call(hwnd, uintptr(unsafe.Pointer(&windowPID)))
|
||||
if windowPID == pid {
|
||||
if visible, _, _ := procIsWindowVisible.Call(hwnd); visible == 0 && matched != 0 {
|
||||
return 1
|
||||
}
|
||||
matched = hwnd
|
||||
if visible, _, _ := procIsWindowVisible.Call(hwnd); visible != 0 {
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
visible, _, _ := procIsWindowVisible.Call(hwnd)
|
||||
titleLength, _, _ := procGetWindowTextLengthW.Call(hwnd)
|
||||
owner, _, _ := procGetWindow.Call(hwnd, gwOwner)
|
||||
minimized, _, _ := procIsIconic.Call(hwnd)
|
||||
candidates = append(candidates, candidateWindow{
|
||||
hwnd: hwnd,
|
||||
visible: visible != 0,
|
||||
titled: titleLength > 0,
|
||||
owned: owner != 0,
|
||||
minimized: minimized != 0,
|
||||
})
|
||||
}
|
||||
return 1
|
||||
})
|
||||
procEnumWindows.Call(callback, 0)
|
||||
return matched
|
||||
if len(candidates) == 0 {
|
||||
return 0
|
||||
}
|
||||
for _, candidate := range candidates {
|
||||
if candidate.visible && candidate.titled && !candidate.owned {
|
||||
return candidate.hwnd
|
||||
}
|
||||
}
|
||||
for _, candidate := range candidates {
|
||||
if candidate.titled && !candidate.owned {
|
||||
return candidate.hwnd
|
||||
}
|
||||
}
|
||||
for _, candidate := range candidates {
|
||||
if candidate.visible && !candidate.owned {
|
||||
return candidate.hwnd
|
||||
}
|
||||
}
|
||||
for _, candidate := range candidates {
|
||||
if candidate.minimized && !candidate.owned {
|
||||
return candidate.hwnd
|
||||
}
|
||||
}
|
||||
return candidates[0].hwnd
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user