Frame: remind users to release laser pointer focus

In flat Vulkan mode, Steam Frame controller buttons can appear not to
reach the game while the system's laser-pointer mode still owns focus.
This is an easy mistake to make when starting a game from the headset.

After a successful boot, show an informational dialog for explicit Flat
Display (Vulkan) mode and for legacy configurations with OpenXR disabled.
The check happens after boot metadata and per-game VR settings are loaded,
so immersive VR and Stereo 3D Screen launches are not interrupted.

Add the requested reminder text and a Never See This Dialog Again
checkbox. Persist the opt-out in Main.Interface, and leave it unchecked by
default so the reminder appears for new users.
This commit is contained in:
Jeremy Bowers committed 2026-10-05 00:33:01 -04:00
1 parent 18e1811dec
commit c652e2d702
6 files changed
+84

No files matched your search

+2
View File
@@ -426,6 +426,8 @@ const Info<bool> MAIN_ABORT_ON_PANIC_ALERT{{System::Main, "Interface", "AbortOnP
const Info<bool> MAIN_OSD_MESSAGES{{System::Main, "Interface", "OnScreenDisplayMessages"}, true};
const Info<int> MAIN_OSD_FONT_SIZE{{System::Main, "Settings", "OSDFontSize"}, 13};
const Info<bool> MAIN_SKIP_NKIT_WARNING{{System::Main, "Interface", "SkipNKitWarning"}, false};
const Info<bool> MAIN_SKIP_FLAT_MODE_INPUT_WARNING{
{System::Main, "Interface", "SkipFlatModeInputWarning"}, false};
const Info<bool> MAIN_CONFIRM_ON_STOP{{System::Main, "Interface", "ConfirmStop"}, true};
const Info<ShowCursor> MAIN_SHOW_CURSOR{{System::Main, "Interface", "CursorVisibility"},
ShowCursor::OnMovement};
+1
View File
@@ -248,6 +248,7 @@ extern const Info<bool> MAIN_ABORT_ON_PANIC_ALERT;
extern const Info<bool> MAIN_OSD_MESSAGES;
extern const Info<int> MAIN_OSD_FONT_SIZE;
extern const Info<bool> MAIN_SKIP_NKIT_WARNING;
extern const Info<bool> MAIN_SKIP_FLAT_MODE_INPUT_WARNING;
extern const Info<bool> MAIN_CONFIRM_ON_STOP;
enum class ShowCursor
+2
View File
@@ -339,6 +339,8 @@ add_executable(dolphin-emu
NetPlay/PadMappingDialog.h
NANDRepairDialog.cpp
NANDRepairDialog.h
FrameFlatModeInputWarningDialog.cpp
FrameFlatModeInputWarningDialog.h
NKitWarningDialog.cpp
NKitWarningDialog.h
QtUtils/AnalyticsPrompt.cpp
@@ -0,0 +1,44 @@
// Copyright 2026 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "DolphinQt/FrameFlatModeInputWarningDialog.h"
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QLabel>
#include <QVBoxLayout>
#include "Common/Config/Config.h"
#include "Core/Config/MainSettings.h"
#include "DolphinQt/Resources.h"
void FrameFlatModeInputWarningDialog::ShowUnlessDisabled(QWidget* parent)
{
if (Config::Get(Config::MAIN_SKIP_FLAT_MODE_INPUT_WARNING))
return;
FrameFlatModeInputWarningDialog dialog(parent);
if (dialog.exec() == QDialog::Accepted && dialog.m_never_show_again->isChecked())
Config::SetBase(Config::MAIN_SKIP_FLAT_MODE_INPUT_WARNING, true);
}
FrameFlatModeInputWarningDialog::FrameFlatModeInputWarningDialog(QWidget* parent) : QDialog(parent)
{
setWindowTitle(tr("Flat-Mode Input Reminder"));
setWindowIcon(Resources::GetAppIcon());
auto* const layout = new QVBoxLayout(this);
auto* const reminder = new QLabel(
tr("Remember, you must click out of laser pointing mode before trying to control the game! "
"Otherwise the game will seem like it has no controls."),
this);
reminder->setWordWrap(true);
layout->addWidget(reminder);
m_never_show_again = new QCheckBox(tr("Never See This Dialog Again"), this);
layout->addWidget(m_never_show_again);
auto* const buttons = new QDialogButtonBox(QDialogButtonBox::Ok, this);
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
layout->addWidget(buttons);
}
@@ -0,0 +1,22 @@
// Copyright 2026 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <QDialog>
class QCheckBox;
class QWidget;
class FrameFlatModeInputWarningDialog final : public QDialog
{
Q_OBJECT
public:
static void ShowUnlessDisabled(QWidget* parent = nullptr);
private:
explicit FrameFlatModeInputWarningDialog(QWidget* parent = nullptr);
QCheckBox* m_never_show_again = nullptr;
};
+13
View File
@@ -45,6 +45,7 @@
#include "Core/BootManager.h"
#include "Core/CommonTitles.h"
#include "Core/Config/AchievementSettings.h"
#include "Core/Config/GraphicsSettings.h"
#include "Core/Config/MainSettings.h"
#include "Core/Config/NetplaySettings.h"
#include "Core/Config/UISettings.h"
@@ -94,6 +95,7 @@
#include "DolphinQt/EmulatedUSB/LogitechMicWindow.h"
#include "DolphinQt/EmulatedUSB/WiiSpeakWindow.h"
#include "DolphinQt/FIFO/FIFOPlayerWindow.h"
#include "DolphinQt/FrameFlatModeInputWarningDialog.h"
#include "DolphinQt/GCMemcardManager.h"
#include "DolphinQt/GameList/GameList.h"
#include "DolphinQt/Host.h"
@@ -132,6 +134,7 @@
#include "UICommon/UICommon.h"
#include "VideoCommon/NetPlayChatUI.h"
#include "VideoCommon/VideoConfig.h"
#ifdef HAVE_XRANDR
#include "UICommon/X11Utils.h"
@@ -1208,6 +1211,16 @@ void MainWindow::StartGame(std::unique_ptr<BootParameters>&& parameters)
return;
}
#ifdef BAIJI_STEAMVR
const OpenXRPresentationMode presentation_mode = Config::Get(Config::GFX_VR_PRESENTATION_MODE);
if (presentation_mode == OpenXRPresentationMode::Vulkan ||
(presentation_mode == OpenXRPresentationMode::Legacy &&
!Config::Get(Config::GFX_VR_ENABLE_OPENXR)))
{
FrameFlatModeInputWarningDialog::ShowUnlessDisabled(this);
}
#endif
#ifdef USE_DISCORD_PRESENCE
if (!NetPlay::IsNetPlayRunning())
Discord::UpdateDiscordPresence();