お世話になっております。
表題通り、特定の状況下においてWindowsキー+Arrowキーでのウィンドウスナップが効かなくなる現象が発生いたしました。
複数ディスプレイを接続しているPC環境でPlayerControllerのSetInputMode_GameOnlyを設定し、アプリをウィンドウモードで実行した場合に画面を跨ぐとキーが効かなくなります。
これはPIEのウィンドウモード、パッケージングした.exeどちらの環境でも発生しております。
ブランクプロジェクトの作成と最小限のレベルBPの実装で現象が再現できます。
確認手順
- ブランクプロジェクトを作成
- 空のレベルを作成しBPを開きBeginPlayからPlayerControllerのSetInputMode_GameOnlyを接続する
- New Editor Window (PIE) でウィンドウモードでアプリ起動
- ディスプレイが左右に置いてある状態で右側でアプリが起動したと仮定し、Windowsキー+左Arrowキーを押す
- 右側ディスプレイの左半分にウィンドウがスナップすることを確認
- 再度Windowsキー+左Arrowキーを押す
- 左側ディスプレイの右半分にウィンドウがスナップすることを確認
- 再度Windowsキー+左Arrowキーを押す
- ウィンドウが動かないことを確認
- Windowsキー+右Arrowキーを押す
- ウィンドウが右ディスプレイに移動すること確認
- Windowsキー+右Arrowキーを押す
- ウィンドウが動かないことを確認
現状発生後ウィンドウをクリックしたり、Windowsキーのみを押してスタートメニューを表示させ、再度アプリにフォーカスが移ると正常に挙動するようになります。
そもそもがWindows標準機能の為UEというよりWindows側の問題な可能性がありますが、こちらの現象の解決方法はございますでしょうか?
[Attachment Removed]
ご回答ありがとうございます、ご提示いただいたコードで軽く動作チェックをしてみたところ、報告の現象が解消されることを確認いたしました。
お問い合わせいただけるということ承知いたしました、引き続きよろしくお願いいたします。
[Attachment Removed]
Issues登録の件承知いたしました。
今後はこちらを確認します。
対応につても本格的に組み込み対応を行いたいと思います。
ご対応ありがとうございました。
[Attachment Removed]
お世話になっております。
SetInputMode_GameOnly 呼び出し後に OS(Windows) のマウスキャプチャが設定されたままの状態になるためWindowsキー+方向キーによるスナップからの復元、最大化等の操作が無効化されているようです。
PIE の場合の対症療法としては SetInputMode_GameOnly の少し後(試した限りでは2フレーム以上の遅延が必要でした)に
void UMyBlueprintFunctionLibrary::ReleaseCapture()
{
FSlateApplication::Get().GetPlatformApplication()->SetCapture(nullptr);
}
のようなものを実行してマウスキャプチャを解除することで症状を抑制できるかと思います。
StandaloneGame やパッケージに対しても上記の対応は効果がありますが、
Alt+Tab等のキーボード操作により再度フォーカスを得た際にやはりマウスキャプチャーが設定され症状が再発してしまいます。
こちらについてはアプリケーションの開始後、終了前のタイミングで
FDelegateHandle ActivationCallbackHandle;
void UMyBlueprintFunctionLibrary::RegisterReleaseCaptureCallback(const UObject* WorldContextObject)
{
// アプリケーションがフォーカスを取得した(アクティブ化した)際のコールバックを設定します
FSlateApplication::Get().OnApplicationActivationStateChanged().AddLambda([WorldContextObject](bool bIsActive)
{
if (bIsActive)
{
if (UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull))
{
// マウスキャプチャーより先にコールバックが実行されてしまうので1フレーム遅らせる必要があります
World->GetTimerManager().SetTimerForNextTick([bIsActive]()
{
FSlateApplication::Get().GetPlatformApplication()->SetCapture(nullptr);
}
);
}
}
});
}
void UMyBlueprintFunctionLibrary::UnregisterReleaseCaptureCallback()
{
if(ActivationCallbackHandle.IsValid())
{
FSlateApplication::Get().OnApplicationActivationStateChanged().Remove(ActivationCallbackHandle);
}
}
のようなコードでキャプチャー解除のためのコールバックを追加することで対処可能ではあります。
上記はアプリケーションサイドで可能な対処ですが、
エンジンとしてこの件の扱いについては問い合わせますので追ってこのスレッドにて経過をお知らせします。
よろしくお願いいたします。
[Attachment Removed]
この件について Issues に登録され、下記のリンクより状況を確認できるようになっております。
https://issues.unrealengine.com/issue/UE\-386734
今のところ修正の有無、判断の時期など諸々未定です。
さしあたっては先にご案内したような内容の対処をしていただくくらいかと思います。
すり抜けるケースが見つかるかも知れませんが、同様の現象であれば似た対応が可能かと思われます。
よろしくお願いいたします。
[Attachment Removed]