CosmosBlueのブログ

日々のよもやま話を徒然と

長時間スリープからの復帰でウィンドウがメインモニターに集まる件(Windows11 23H2 / 24H2)

この記事は、Windows11マルチモニター環境にあって、概ね60分とか90分とか長いスリープから復帰した際に、それまでサブモニターにあったウィンドウが全てメインモニターにリポジションされてしまう事象に対する解決策の一つです。この事象に該当しない方には意味がないかもしれません。

  • 2024年12月6日:

    24H2にアップデート後、スリープ復帰の度にメインモニターに全員集合され、あまりにも鬱陶しいので全力で解決に向けて取り組んだのですが、容易に解決策を見出だすことが出来ず、ふと思い立ってディスプレドライバーのバックワードをやってみることにしました。

    インテルの最新ベンダードライバーを適用していますが、このベンダードライバーは一度新しくすると古いバージョンで上書き更新することができません。そこで8月頃の調子の良かったドライバーを用意しておき、デバイスマネージャーで「デバイスのアンインストール」を実行します。するとディスプレイデバイスが削除され、しばらく待つと(ハードウェア変更のスキャンをしてはいけません)Microsoftデフォルトの「基本ディスプレイアダプター」で認識されます。そうなったら調子の良かった頃のベンダードライバーをインストールします。

    この結果、24H2でメインモニターに全員集合事件が解決しました(解決というか以前のサブモニター残置率に戻りました)。ディスプレイアダプターを一度削除したのが良かったのか、古いドライバーを適用したのが功を奏したのか分かりませんが、半日で全6回のスリープ復帰が全てサブモニ残置を達成しました。これで毎回ウィンドウを戻す苦役から解放されました(と信じたい...)。

    2024年12月6日 追記(Part 2):

    昨夜日またぎで「24H2でメインモニターに全員集合問題」を解決したのですが、今朝Windows Updateで9月頃のインテルUHDグラフィックドライバーをインストールされてしまいました。まあ、入れられちゃったもんは仕方がないので様子を見ていました。

    しかし驚いたことに100%サブモニ残置を達成しています。ということは、効果があったのは「デバイスのアンインストール」をしたことで、ドライバーのバックワードは関係なさそうです。つまり23H2からのデバイス設定移行ではなく、24H2で初めて認識されたデバイスになればスリープ復帰後のウィンドウ再配置が完全に上手くいく、という推論が成り立ちます。

    画面オフだけでS0モダンスタンバイなんかやめちゃえばいいじゃんという声もありますが、スリープ中にはCPUファンも止まるのでPCユニットのヒーリングと長寿命化はやはり大きいです(決して電気代をケチっているのではありません)。

  •  
  • 2025年7月31日 追記:
  • 最新のUHDドライバー32.0.101.6913に入れ替えましたがメインモニター集合が起きたので32.0.101.6734に戻しました。
  •  
  • 2025年6月12日 追記:
  • 最新のUHDドライバー32.0.101.6881に入れ替えましたがサブモニ残置率100%で問題ありません。
  •  
  • 2025年5月31日 追記:
  • 最新のUHDドライバー32.0.101.6874に入れ替えました。いまのところサブモニ残置率100%で問題ありません。
  •  
  • 2025年5月19日 追記:
  • いつまでたってもIntel Corporation Display 32.0.101.5542が(要らないのに)インストール失敗を繰り返しているのでwushowhide.diagcabで消しました。スッキリ
  •  
  • 2025年5月18日 追記:
  • 最新のUHDドライバー32.0.101.6790にしたところメインモニター集合が起きたので6734に戻しました。その前後にWindows Updateから32.0.101.5542という古いドライバーが落ちてきており、それが何か関係しているかもしれません。Intel Corporation Extension(ドライバファーム)32.0.101.5542はインストールされ、Intel Corporation Display 32.0.101.5542はインストール失敗で何度でも落ちてきてエラーになってます。
  •  

以下Windows11 23H2 の電源管理アプローチによる奮闘模様(古い情報です)

いわゆるDP問題ではなく(メイン・サブともHDMI接続)、BIOSもグラフィックドライバーも最新。ブランクスクリーンから指定時間後にスリープ(モダンスタンバイ)に突入し、そこから10分とか20分で復帰した場合、ウィンドウはメイン・サブとも元のままです。ところが長いスリープから復帰すると全てのウィンドウがメインモニターに再配置されてしまいます。

Windows11のディスプレイ設定で「モニターの接続に基づいてウィンドウの位置を記憶する」もチェック、「モニターが接続されていないときにウィンドウを最小化する」もチェックしていますが、位置も覚えてねぇわ、最小化すらされてねぇ。

で、この記事のメソッドがソリューションになり得るかどうかは、事象の類似性に加えて、以下で確認することができます。該当しない方は別のソリューションを探してください。スタートボタンを右クリックして「ターミナル(管理者)」を起動し、次のコマンドを入力します。

  • PS C:\Users\PC-User> powercfg -Q
  •  
  •  
  •  
  •  
  •  

上記コマンドの出力の中から以下の項目を見つけてください。

  • 電源設定の GUID: 94ac6d29-73ce-41a6-809f-6363ba21b47e (ハイブリッド スリープを許可する)
  • GUID エイリアス: HYBRIDSLEEP
  • 利用可能な設定のインデックス: 000
  • 利用可能な設定のフレンドリ名: オフ
  • 利用可能な設定のインデックス: 001
  • 利用可能な設定のフレンドリ名: オン
  • 現在の AC 電源設定のインデックス: 0x00000001
  • 現在の DC 電源設定のインデックス: 0x00000001
  •  
  •  
  •  

現在のAC/DC電源設定のインデックスが1ならこのメソッドで解決できる可能性があります。インデックスが0の場合や、この項目が存在しない場合は残念ながらこのメソッドでは解決できません。

ということから分かるように、このメソッドではインデックスが1の場合これを0にすることで、モダンスタンバイの最終フェーズ(ハイバネーションのような状態)を無効化するということになります。では早速やり方です。

まず、現在適用中の電源プランのGUIDを取得します。

  • PS C:\Users\PC-User> powercfg -L
  • 既存の電源設定 (* アクティブ)
  • -----------------------------------
  • 電源設定の GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (バランス) *
  •  
  •  
  •  

GUIDをメモ帳などにコピペしておきます。続けて前述のpowercfg -Qの出力、ハイブリッドスリープの項目から少し上にサブグループ(スリープ)のGUIDがあるので、それもコピペしておきます。

  • サブグループの GUID: 238c9fa8-0aad-41ed-83f4-97be242c8f20 (スリープ)
  • GUID エイリアス: SUB_SLEEP
  • 電源設定の GUID: 29f6c1db-86da-48c5-9fdb-f2b67b1f44da (次の時間が経過後スリープする)
  • GUID エイリアス: STANDBYIDLE
  • 利用可能な設定の最小値: 0x00000000
  • 利用可能な設定の最大値: 0xffffffff
  • 利用可能な設定の増分: 0x00000001
  • 利用可能な設定の単位: 秒
  • 現在の AC 電源設定のインデックス: 0x00000708
  • 現在の DC 電源設定のインデックス: 0x000000b4
  • 電源設定の GUID: 94ac6d29-73ce-41a6-809f-6363ba21b47e (ハイブリッド スリープを許可する)
  • GUID エイリアス: HYBRIDSLEEP
  • 利用可能な設定のインデックス: 000
  • 利用可能な設定のフレンドリ名: オフ
  • 利用可能な設定のインデックス: 001
  • 利用可能な設定のフレンドリ名: オン
  • 現在の AC 電源設定のインデックス: 0x00000001
  • 現在の DC 電源設定のインデックス: 0x00000001

そして、もちろんハイブリッドスリープのGUIDもコピペしておきます。

では、コピペしたGUIDを用いてハイブリッドスリープをAC/DC共に無効化します。ハイブリッドスリープを無効化してもモダンスタンバイ(S0低電力アイドル)が出来なくなる訳ではありませんので誤解されませんように。

  • PS C:\Users\PC-User> powercfg -setDCValueIndex 381b4222-f694-41f0-9685-ff5bb260df2e 238c9fa8-0aad-41ed-83f4-97be242c8f20 94ac6d29-73ce-41a6-809f-6363ba21b47e 0
  •  
  • PS C:\Users\PC-User> powercfg -setACValueIndex 381b4222-f694-41f0-9685-ff5bb260df2e 238c9fa8-0aad-41ed-83f4-97be242c8f20 94ac6d29-73ce-41a6-809f-6363ba21b47e 0
  •  
  •  
  •  

実行エラーがなければ、再度"powercfg -Q"を出力してハイブリッドスリープの「現在のAC(DC)電源設定のインデックス」が0になっていることを確認します。

  • 電源設定の GUID: 94ac6d29-73ce-41a6-809f-6363ba21b47e (ハイブリッド スリープを許可する)
  • GUID エイリアス: HYBRIDSLEEP
  • 利用可能な設定のインデックス: 000
  • 利用可能な設定のフレンドリ名: オフ
  • 利用可能な設定のインデックス: 001
  • 利用可能な設定のフレンドリ名: オン
  • 現在の AC 電源設定のインデックス: 0x00000000
  • 現在の DC 電源設定のインデックス: 0x00000000
  •  

これでスリープ後60分でも90分でもサブモニターに元あったウィンドウが戻ってくるようになりました。スリープから復帰した際は一瞬何もないデスクトップ画面になるのですが、メインモニターのタスクバーからシュッと飛んで来るようになりました。ここまで長かった・・・

色々な手を打ってみましたが、ことごとくダメでした。特に多かったのはDP問題に帰結する記事や、グラフィックドライバーに帰結する記事でした。中にはお決まりの"これでダメならクリーンインストールしかないですね"的な記事もありました。スリープ復帰時とは言っても浅いスリープでは問題なく、深いスリープだとウィンドウが寄ってくるので、どれも何かが違うと思いながら記事の内容を試行錯誤していました。

問題はスリープが長くなると意図した動作をしないところでした。どう考えてもスリープ中に何らかフェーズが変わり、それが影響してウィンドウ配置の記憶が消散するとしか考えられません。ハイブリッドスリープは「通常はバッテリー駆動のノートPCでデフォ」という記事も自分の勘違いを助長しました。少し前にハイブリッドスリープの設定は一度見たのですが、その時は「AC電源しかない自分のNUC13はハイブリッドスリープを許可していても使われていないはず」と思い込んでしまいました。

また、"powercfg /sleepstudy"でレポートを何度出力してみても、スリープはあれどスリープ後の「休止」の記録がありません。ハイブリッドスリープが「スリープ+休止」だと思っていた自分はここでも「やっぱりハイブリッドスリープは使われてないよな」と思い込んでしまいました。更に惑わされたのは「モダンスタンバイ」と「ハイブリッドスリープ」を同一視する記事や、「ハイブリッドスリープ」と「休止状態」を同一視する記事でした。

「ハイブリッドスリープ」は一定時間スリープした場合、「休止に似た」ステートへ移行する動作を含むスリープで、powercfgではそれをするかどうかを定義している、また、ハイブリッドスリープはあくまでスリープ(の一種)であって、「休止(ハイバネーション)」ではない、だからレポートにも「休止」が付かないのだろう、という仮説を立てました。ちなみに"powercfg /H off"で「休止」を無効にしても、ハイブリッドスリープには何も影響しませんでした。

そこで、あらためてpowercfgを確認してみると、ACもDCもハイブリッドスリープが許可になっていて「ん?これってノートPCとか関係なく動作してんじゃね?」と思い始めました。要は最後のフェーズで休止(的な)状態にならなければ、サブモニターは何もかもを忘れることなく復帰できるんじゃないか?と思ったのが実験契機でした。

ただ、どうしても戻らないウィンドウがあります。サブモニターで最大化したウィンドウと、スナップレイアウトで配置したウィンドウです。これらはメインモニターに置き去りのままです。

どうも左側がサブモニターというのは良くないのかもしれません。メインモニターだけの場合はメインモニター左上隅が座標(0,0)になりますが、拡張表示でサブモニターが左側にあるとサブモニターが仮想デスクトップの座標(0,0)を持ちます。この際にメインモニターの左上隅は(FHDの場合)座標(1920,0)になります(APIではメインモニターが(0,0)で、サブモニターがマイナス座標(-1920,0)になるかも)。サブモニターが右側にある場合なら、サブモニターの状況に関係なく座標(0,0)は常にメインモニターにあります。ここら辺の位置取りとタイミングが関係しているのかなと疑っています。

モニター環境を書き忘れていたので追記しておきます

  • モニター1(メインモニター:向かって右側)
  • BenQ GW2480E
  • 解像度:1920x1080
  • リフレッシュレート:60Hz
  • 使用ポート:HDMI
  • PC側ポート:HDMI1
  • 入力自動切換:On
  • モニター2(サブモニター:向かって左側)
  • BenQ GW2283
  • 解像度:1920x1080
  • リフレッシュレート:60Hz
  • 使用ポート:HDMI1
  • PC側ポート:HDMI2
  • 入力自動切換:On

とにかく環境が千差万別なので、このメソッドでは何ら効果がなくガッカリされる方もいらっしゃると思いますが、その場合はすぐに別の解決策を探しに行く方がよろしいです。ハズレで試行錯誤しても仕方がありませんし、自分もそうやってたどり着いたので。

今回のNUC13はWindows11のISOからDVDを焼いてインストールしたネイティブ11でした。なんかデフォルトで最大限サステナブルな省電力設定になっているようです。Windows10からアップグレードした前機NUC11ではこんな設定をいじった記憶がありません。Media CreatorのDVDやUSBからWindows11をクリーンインストールした方(でマルチモニターの方)はお気をつけくださいませ。

 

※この記事は最大限の省電力を妨げる目的はありません。利便性と省電力のトレードオフはそのPCオーナー自身が自由に考えることであり何ら強制することはありません。この記事によって被ったあらゆる損害についてブログ主は免責とさせて頂きます。