fix snapping
This commit is contained in:
@@ -75,8 +75,13 @@ const (
|
|||||||
GW_HWNDPREV = 3
|
GW_HWNDPREV = 3
|
||||||
PW_RENDERFULLCONTENT = 0x00000002
|
PW_RENDERFULLCONTENT = 0x00000002
|
||||||
|
|
||||||
|
STARTF_USESIZE = 0x00000002
|
||||||
STARTF_USEPOSITION = 0x00000004
|
STARTF_USEPOSITION = 0x00000004
|
||||||
CREATE_NEW_CONSOLE = 0x00000010
|
CREATE_NEW_CONSOLE = 0x00000010
|
||||||
|
SWP_NOSIZE = 0x0001
|
||||||
|
SWP_NOZORDER = 0x0004
|
||||||
|
SWP_NOACTIVATE = 0x0010
|
||||||
|
SWP_SHOWWINDOW = 0x0040
|
||||||
MOUSEEVENTF_MOVE = 0x0001
|
MOUSEEVENTF_MOVE = 0x0001
|
||||||
MOUSEEVENTF_LEFTDOWN = 0x0002
|
MOUSEEVENTF_LEFTDOWN = 0x0002
|
||||||
MOUSEEVENTF_LEFTUP = 0x0004
|
MOUSEEVENTF_LEFTUP = 0x0004
|
||||||
|
|||||||
@@ -716,7 +716,9 @@ func StartVirtualProcess(filePath string) (uint32, error) {
|
|||||||
si.cb = uint32(unsafe.Sizeof(si))
|
si.cb = uint32(unsafe.Sizeof(si))
|
||||||
si.dwX = uint32(bounds.Min.X)
|
si.dwX = uint32(bounds.Min.X)
|
||||||
si.dwY = uint32(bounds.Min.Y)
|
si.dwY = uint32(bounds.Min.Y)
|
||||||
si.dwFlags = STARTF_USEPOSITION
|
si.dwXSize = uint32(bounds.Dx())
|
||||||
|
si.dwYSize = uint32(bounds.Dy())
|
||||||
|
si.dwFlags = STARTF_USEPOSITION | STARTF_USESIZE
|
||||||
creationFlags := uintptr(0)
|
creationFlags := uintptr(0)
|
||||||
if virtualCommandNeedsNewConsole(filePath) {
|
if virtualCommandNeedsNewConsole(filePath) {
|
||||||
// Console hosts only consistently honor STARTF_USEPOSITION when Windows
|
// Console hosts only consistently honor STARTF_USEPOSITION when Windows
|
||||||
@@ -782,31 +784,25 @@ func virtualTopLevelWindowSet() map[uintptr]struct{} {
|
|||||||
result := make(map[uintptr]struct{})
|
result := make(map[uintptr]struct{})
|
||||||
deskHwnd, _, _ := procGetDesktopWindow.Call()
|
deskHwnd, _, _ := procGetDesktopWindow.Call()
|
||||||
for hwnd := getTopWindow(deskHwnd); hwnd != 0; hwnd = getWindow(hwnd, GW_HWNDNEXT) {
|
for hwnd := getTopWindow(deskHwnd); hwnd != 0; hwnd = getWindow(hwnd, GW_HWNDNEXT) {
|
||||||
if isWindowVisible(hwnd) {
|
|
||||||
result[hwnd] = struct{}{}
|
result[hwnd] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func moveProcessWindowsToVirtualMonitor(pid uint32, bounds image.Rectangle, baseline map[uintptr]struct{}) {
|
func moveProcessWindowsToVirtualMonitor(pid uint32, bounds image.Rectangle, baseline map[uintptr]struct{}) {
|
||||||
hwndMap := make(map[uintptr]uint32)
|
hwndMap := make(map[uintptr]bool)
|
||||||
|
|
||||||
for attempt := 0; attempt < 75; attempt++ {
|
|
||||||
time.Sleep(200 * time.Millisecond)
|
|
||||||
|
|
||||||
|
for attempt := 0; attempt < 300; attempt++ {
|
||||||
deskHwnd, _, _ := procGetDesktopWindow.Call()
|
deskHwnd, _, _ := procGetDesktopWindow.Call()
|
||||||
hwnd := getTopWindow(deskHwnd)
|
hwnd := getTopWindow(deskHwnd)
|
||||||
if hwnd == 0 {
|
if hwnd == 0 {
|
||||||
|
time.Sleep(virtualPlacementPollDelay(attempt))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
moved := 0
|
moved := 0
|
||||||
for hwnd != 0 {
|
for hwnd != 0 {
|
||||||
if !isWindowVisible(hwnd) {
|
visible := isWindowVisible(hwnd)
|
||||||
hwnd = getWindow(hwnd, GW_HWNDNEXT)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var winPID uint32
|
var winPID uint32
|
||||||
procGetWindowThreadProcessId.Call(hwnd, uintptr(unsafe.Pointer(&winPID)))
|
procGetWindowThreadProcessId.Call(hwnd, uintptr(unsafe.Pointer(&winPID)))
|
||||||
@@ -816,11 +812,10 @@ func moveProcessWindowsToVirtualMonitor(pid uint32, bounds image.Rectangle, base
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, already := hwndMap[hwnd]; already {
|
if alreadyVisibleMove, already := hwndMap[hwnd]; already && (!visible || alreadyVisibleMove) {
|
||||||
hwnd = getWindow(hwnd, GW_HWNDNEXT)
|
hwnd = getWindow(hwnd, GW_HWNDNEXT)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
hwndMap[hwnd] = pid
|
|
||||||
|
|
||||||
var r rect
|
var r rect
|
||||||
procGetWindowRect.Call(hwnd, uintptr(unsafe.Pointer(&r)))
|
procGetWindowRect.Call(hwnd, uintptr(unsafe.Pointer(&r)))
|
||||||
@@ -841,7 +836,12 @@ func moveProcessWindowsToVirtualMonitor(pid uint32, bounds image.Rectangle, base
|
|||||||
if winH > bounds.Dy() {
|
if winH > bounds.Dy() {
|
||||||
winH = bounds.Dy()
|
winH = bounds.Dy()
|
||||||
}
|
}
|
||||||
procSetWindowPos.Call(hwnd, 0, uintptr(newX), uintptr(newY), uintptr(winW), uintptr(winH), 0x0040|0x0010)
|
flags := uintptr(SWP_NOZORDER | SWP_NOACTIVATE)
|
||||||
|
if visible {
|
||||||
|
flags |= SWP_SHOWWINDOW
|
||||||
|
}
|
||||||
|
procSetWindowPos.Call(hwnd, 0, uintptr(newX), uintptr(newY), uintptr(winW), uintptr(winH), flags)
|
||||||
|
hwndMap[hwnd] = visible
|
||||||
|
|
||||||
log.Printf("virtual: moved window hwnd=0x%x (pid=%d) to virtual monitor (%d,%d)", hwnd, pid, bounds.Min.X, bounds.Min.Y)
|
log.Printf("virtual: moved window hwnd=0x%x (pid=%d) to virtual monitor (%d,%d)", hwnd, pid, bounds.Min.X, bounds.Min.Y)
|
||||||
moved++
|
moved++
|
||||||
@@ -849,6 +849,18 @@ func moveProcessWindowsToVirtualMonitor(pid uint32, bounds image.Rectangle, base
|
|||||||
}
|
}
|
||||||
|
|
||||||
_ = moved // keep watching for child/handed-off windows after the first one
|
_ = moved // keep watching for child/handed-off windows after the first one
|
||||||
|
time.Sleep(virtualPlacementPollDelay(attempt))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func virtualPlacementPollDelay(attempt int) time.Duration {
|
||||||
|
switch {
|
||||||
|
case attempt < 120:
|
||||||
|
return 10 * time.Millisecond
|
||||||
|
case attempt < 180:
|
||||||
|
return 50 * time.Millisecond
|
||||||
|
default:
|
||||||
|
return 200 * time.Millisecond
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2302,10 +2314,18 @@ func resizeVirtualWindowIfDragging(screenPt point) {
|
|||||||
}
|
}
|
||||||
const minW, minH = int32(120), int32(80)
|
const minW, minH = int32(120), int32(80)
|
||||||
if right-left < minW {
|
if right-left < minW {
|
||||||
if hit == 10 || hit == 13 || hit == 16 { left = right-minW } else { right = left+minW }
|
if hit == 10 || hit == 13 || hit == 16 {
|
||||||
|
left = right - minW
|
||||||
|
} else {
|
||||||
|
right = left + minW
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if bottom-top < minH {
|
if bottom-top < minH {
|
||||||
if hit == 12 || hit == 13 || hit == 14 { top = bottom-minH } else { bottom = top+minH }
|
if hit == 12 || hit == 13 || hit == 14 {
|
||||||
|
top = bottom - minH
|
||||||
|
} else {
|
||||||
|
bottom = top + minH
|
||||||
|
}
|
||||||
}
|
}
|
||||||
procSetWindowPos.Call(hwnd, 0, uintptr(left), uintptr(top), uintptr(right-left), uintptr(bottom-top), 0x0010|0x0040)
|
procSetWindowPos.Call(hwnd, 0, uintptr(left), uintptr(top), uintptr(right-left), uintptr(bottom-top), 0x0010|0x0040)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user