2023-11-28 (Tue) [長年日記]

_ [ahk] Windows 10 デュアル画面スリープ復帰時ウィンドウ集約問題

タイトル長いな~

手元 PC では、スリープなら問題ないけど画面オフ(省電力機能)で問題が発生する。再開時にウィンドウが全部まとめてメイン画面に行ってしまう感じかな。

Rapid HPD 問題と言うらしい。

色々な解決方法が提案されているけど、AHK で適当に回避できたっぽいので貼る。これから shell:startup に入れて再起動したりとか、少し試してみたい。

#Requires AutoHotkey v2.0

#Warn
#SingleInstance Force

; https://devblogs.microsoft.com/directx/avoid-unexpected-app-rearrangement/
; https://superuser.com/questions/1292435

; 本格的にモニタ電源を監視するならこういう方法があるみたい
; https://www.autohotkey.com/boards/viewtopic.php?p=539708
; でも今回は単純にバーチャルスクリーンの広さで検出している
; https://www.autohotkey.com/docs/v2/lib/SysGet.htm#ExVirtScreenWH
ovx := SysGet(78)
ovy := SysGet(79)

delay := 250

waiting := false
while (true)
{
  nvx := SysGet(78)
  nvy := SysGet(79)
  if (not waiting)
  {
    if (ovx = nvx && ovy = nvy)
      wins := savewins(WinGetlist(, , "Program Manager"))
    else
      waiting := true
  }
  else if (ovx = nvx && ovy = nvy)
  {
    restorewins(wins)
    waiting := false
  }
  Sleep(delay)
}

savewins(ids)
{
  winmap := Map()
  for this_id in ids
  {
    try
    {
      minmax := WinGetminmax(this_id)
      WinGetPos(&x, &y, , , this_id)
    }
    catch TargetError
      continue
    winmap[this_id] := { x: x, y: y, minmax: minmax }
  }
  return winmap
}

restorewins(winmap)
{
  for this_id, d in winmap
  {
    try
    {
      minmax := WinGetMinMax(this_id)
      WinGetPos(&x, &y, , , this_id)
    }
    catch TargetError
      continue
    if (d.x = x && d.y = y && d.minmax = minmax)
      continue
    else if (d.minmax = 0)
      WinMove(d.x, d.y, , , this_id)
    else if (d.minmax = 1)
    {
      WinRestore(this_id)
      WinMove(d.x, d.y, , , this_id)
      WinMaximize(this_id)
    }
  }
}

«前の日記(2023-11-16 (Thu)) 最新