Bugfix: All desktop hotkeys now work in dual-window mode.

The fullscreen hotkey now works differently. It always changes
the fullscreen setting, and attempts to fullscreen both windows
in dual-screen mode *if* they are on different screens. Othewise
it only fullscreens the main screen for consistency between layouts.

Geometry is always saved and restored from UISettings for more
consistency.
This commit is contained in:
David Griswold 2026-03-31 11:53:57 +03:00
parent ab6896a2ca
commit 5b1f27cd2d
4 changed files with 65 additions and 43 deletions

View file

@ -198,6 +198,7 @@ if (ENABLE_QT)
"geometry"
"state"
"geometryRenderWindow"
"geometrySecondaryWindow"
"gameListHeaderState"
"microProfileDialogGeometry"
"name"

View file

@ -858,11 +858,19 @@ void GMainWindow::InitializeHotkeys() {
const bool primary_only = false,
const bool auto_repeat = false) {
static const QString main_window = QStringLiteral("Main Window");
action->setShortcut(hotkey_registry.GetKeySequence(main_window, action_name));
auto context = hotkey_registry.GetShortcutContext(main_window, action_name);
auto shortcut = hotkey_registry.GetKeySequence(main_window, action_name);
action->setShortcut(shortcut);
action->setShortcutContext(context);
action->setAutoRepeat(auto_repeat);
this->addAction(action);
if (!primary_only)
secondary_window->addAction(action);
// handle the shortcuts that are different per-screen
if (context == Qt::WidgetShortcut) {
render_window->addAction(action);
if (!primary_only) {
secondary_window->addAction(action);
}
}
};
link_action_shortcut(ui->action_Load_File, QStringLiteral("Load File"));
@ -874,7 +882,7 @@ void GMainWindow::InitializeHotkeys() {
link_action_shortcut(ui->action_Stop, QStringLiteral("Stop Emulation"));
link_action_shortcut(ui->action_Show_Filter_Bar, QStringLiteral("Toggle Filter Bar"));
link_action_shortcut(ui->action_Show_Status_Bar, QStringLiteral("Toggle Status Bar"));
link_action_shortcut(ui->action_Fullscreen, fullscreen, true);
link_action_shortcut(ui->action_Fullscreen, fullscreen);
link_action_shortcut(ui->action_Capture_Screenshot, QStringLiteral("Capture Screenshot"));
link_action_shortcut(ui->action_Debug_Pause, QStringLiteral("Debug Pause"));
link_action_shortcut(ui->action_Debug_Resume, QStringLiteral("Debug Resume"));
@ -899,10 +907,7 @@ void GMainWindow::InitializeHotkeys() {
// QShortcut Hotkeys
const auto connect_shortcut = [&](const QString& action_name, const auto& function) {
const auto* hotkey = hotkey_registry.GetHotkey(main_window, action_name, this);
const auto* secondary_hotkey =
hotkey_registry.GetHotkey(main_window, action_name, secondary_window);
connect(hotkey, &QShortcut::activated, this, function);
connect(secondary_hotkey, &QShortcut::activated, this, function);
};
connect_shortcut(QStringLiteral("Toggle Screen Layout"), &GMainWindow::ToggleScreenLayout);
@ -972,11 +977,6 @@ void GMainWindow::InitializeHotkeys() {
connect(action, SIGNAL(triggered()), this, slot);
secondary_window->addAction(action);
};
// Use the same fullscreen hotkey as the main window
const auto fullscreen_hotkey = hotkey_registry.GetKeySequence(main_window, fullscreen);
add_secondary_window_hotkey(action_secondary_fullscreen, fullscreen_hotkey,
SLOT(ToggleSecondaryFullscreen()));
}
void GMainWindow::SetDefaultUIGeometry() {
@ -995,6 +995,7 @@ void GMainWindow::RestoreUIState() {
restoreGeometry(UISettings::values.geometry);
restoreState(UISettings::values.state);
render_window->restoreGeometry(UISettings::values.renderwindow_geometry);
secondary_window->restoreGeometry(UISettings::values.secondarywindow_geometry);
#if MICROPROFILE_ENABLED
microProfileDialog->restoreGeometry(UISettings::values.microprofile_geometry);
microProfileDialog->setVisible(UISettings::values.microprofile_visible.GetValue());
@ -2690,6 +2691,9 @@ void GMainWindow::ToggleSecondaryFullscreen() {
}
void GMainWindow::ShowFullscreen() {
QWidget* window_to_change =
ui->action_Single_Window_Mode->isChecked() ? static_cast<QWidget*>(this) : render_window;
if (ui->action_Single_Window_Mode->isChecked()) {
UISettings::values.geometry = saveGeometry();
ui->menubar->hide();
@ -2703,7 +2707,16 @@ void GMainWindow::ShowFullscreen() {
#ifdef NEEDS_ROUND_CORNERS_FIX
WindowCornerManager::instance().blockRoundedCorners(render_window, true);
#endif
render_window->showFullScreen();
}
bool secondary_on_same = window_to_change->screen() == secondary_window->screen();
window_to_change->showFullScreen();
// try to fullscreen the second window if it is visible and on a different screen from main
if (secondary_window->isVisible() && !secondary_on_same) {
UISettings::values.secondarywindow_geometry = secondary_window->saveGeometry();
LOG_INFO(Frontend, "Attempting to fullscreen secondary window");
secondary_window->showFullScreen();
}
}
@ -2723,12 +2736,16 @@ void GMainWindow::HideFullscreen() {
render_window->showNormal();
render_window->restoreGeometry(UISettings::values.renderwindow_geometry);
}
if (secondary_window->isFullScreen()) {
secondary_window->restoreGeometry(UISettings::values.secondarywindow_geometry);
secondary_window->showNormal();
}
}
void GMainWindow::ToggleWindowMode() {
if (ui->action_Single_Window_Mode->isChecked()) {
// Render in the main window...
render_window->BackupGeometry();
UISettings::values.renderwindow_geometry = render_window->saveGeometry();
ui->horizontalLayout->addWidget(render_window);
render_window->setFocusPolicy(Qt::StrongFocus);
if (emulation_running) {
@ -2744,7 +2761,7 @@ void GMainWindow::ToggleWindowMode() {
render_window->setFocusPolicy(Qt::NoFocus);
if (emulation_running) {
render_window->setVisible(true);
render_window->RestoreGeometry();
render_window->restoreGeometry(UISettings::values.renderwindow_geometry);
game_list->show();
}
}
@ -2755,10 +2772,10 @@ void GMainWindow::UpdateSecondaryWindowVisibility() {
return;
}
if (Settings::values.layout_option.GetValue() == Settings::LayoutOption::SeparateWindows) {
secondary_window->RestoreGeometry();
secondary_window->restoreGeometry(UISettings::values.secondarywindow_geometry);
secondary_window->show();
} else {
secondary_window->BackupGeometry();
UISettings::values.secondarywindow_geometry = secondary_window->saveGeometry();
secondary_window->hide();
}
}
@ -3186,7 +3203,6 @@ void GMainWindow::OnCaptureScreenshot() {
.toString(QStringLiteral("dd.MM.yy_hh.mm.ss.z"))
.toStdString();
path.append(fmt::format("/{}_{}.png", filename, timestamp));
auto* const screenshot_window =
secondary_window->HasFocus() ? secondary_window : render_window;
screenshot_window->CaptureScreenshot(
@ -4202,6 +4218,7 @@ void GMainWindow::UpdateUISettings() {
if (!ui->action_Fullscreen->isChecked()) {
UISettings::values.geometry = saveGeometry();
UISettings::values.renderwindow_geometry = render_window->saveGeometry();
UISettings::values.secondarywindow_geometry = secondary_window->saveGeometry();
}
UISettings::values.state = saveState();
#if MICROPROFILE_ENABLED

View file

@ -59,44 +59,44 @@ const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> QtConfi
// clang-format off
const std::array<UISettings::Shortcut, 41> QtConfig::default_hotkeys {{
{QStringLiteral("Advance Frame"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::ApplicationShortcut}},
{QStringLiteral("Audio Mute/Unmute"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+M"), Qt::WindowShortcut}},
{QStringLiteral("Audio Volume Down"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::WindowShortcut}},
{QStringLiteral("Audio Volume Up"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::WindowShortcut}},
{QStringLiteral("Capture Screenshot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+P"), Qt::WidgetWithChildrenShortcut}},
{QStringLiteral("Debug Pause"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F4"),Qt::WidgetWithChildrenShortcut}},
{QStringLiteral("Debug Resume"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F5"),Qt::WidgetWithChildrenShortcut}},
{QStringLiteral("Debug Step"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F6"),Qt::WidgetWithChildrenShortcut}},
{QStringLiteral("Continue/Pause Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F4"), Qt::WindowShortcut}},
{QStringLiteral("Audio Mute/Unmute"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+M"), Qt::ApplicationShortcut}},
{QStringLiteral("Audio Volume Down"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::ApplicationShortcut}},
{QStringLiteral("Audio Volume Up"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::ApplicationShortcut}},
{QStringLiteral("Capture Screenshot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+P"), Qt::ApplicationShortcut}},
{QStringLiteral("Continue/Pause Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F4"), Qt::ApplicationShortcut}},
{QStringLiteral("Debug Pause"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F4"),Qt::ApplicationShortcut}},
{QStringLiteral("Debug Resume"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F5"),Qt::ApplicationShortcut}},
{QStringLiteral("Debug Step"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F6"),Qt::ApplicationShortcut}},
{QStringLiteral("Decrease 3D Factor"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+-"), Qt::ApplicationShortcut}},
{QStringLiteral("Decrease Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("-"), Qt::ApplicationShortcut}},
{QStringLiteral("Exit Azahar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Q"), Qt::WindowShortcut}},
{QStringLiteral("Exit Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("Esc"), Qt::WindowShortcut}},
{QStringLiteral("Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("F11"), Qt::WindowShortcut}},
{QStringLiteral("Exit Azahar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Q"), Qt::ApplicationShortcut}},
{QStringLiteral("Exit Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("Esc"), Qt::ApplicationShortcut}},
{QStringLiteral("Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("F11"), Qt::ApplicationShortcut}},
{QStringLiteral("Increase 3D Factor"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl++"), Qt::ApplicationShortcut}},
{QStringLiteral("Increase Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("+"), Qt::ApplicationShortcut}},
{QStringLiteral("Load Amiibo"), QStringLiteral("Main Window"), {QStringLiteral("F2"), Qt::WidgetWithChildrenShortcut}},
{QStringLiteral("Load File"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+O"), Qt::WidgetWithChildrenShortcut}},
{QStringLiteral("Load from Newest Non-Quicksave Slot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+V"), Qt::WindowShortcut}},
{QStringLiteral("Load Amiibo"), QStringLiteral("Main Window"), {QStringLiteral("F2"), Qt::ApplicationShortcut}},
{QStringLiteral("Load File"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+O"), Qt::ApplicationShortcut}},
{QStringLiteral("Load from Newest Non-Quicksave Slot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+V"), Qt::ApplicationShortcut}},
{QStringLiteral("Multiplayer Browse Public Rooms"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+B"), Qt::ApplicationShortcut}},
{QStringLiteral("Multiplayer Create Room"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+N"), Qt::ApplicationShortcut}},
{QStringLiteral("Multiplayer Direct Connect to Room"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Shift"), Qt::ApplicationShortcut}},
{QStringLiteral("Multiplayer Leave Room"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+L"), Qt::ApplicationShortcut}},
{QStringLiteral("Multiplayer Show Current Room"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+R"), Qt::ApplicationShortcut}},
{QStringLiteral("Quick Save"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::WindowShortcut}},
{QStringLiteral("Quick Load"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::WindowShortcut}},
{QStringLiteral("Quick Save"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::ApplicationShortcut}},
{QStringLiteral("Quick Load"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::ApplicationShortcut}},
{QStringLiteral("Remove Amiibo"), QStringLiteral("Main Window"), {QStringLiteral("F3"), Qt::ApplicationShortcut}},
{QStringLiteral("Restart Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F6"), Qt::WindowShortcut}},
{QStringLiteral("Rotate Screens Upright"), QStringLiteral("Main Window"), {QStringLiteral("F8"), Qt::WindowShortcut}},
{QStringLiteral("Save to Oldest Non-Quicksave Slot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+C"), Qt::WindowShortcut}},
{QStringLiteral("Stop Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F5"), Qt::WindowShortcut}},
{QStringLiteral("Swap Screens"), QStringLiteral("Main Window"), {QStringLiteral("F9"), Qt::WindowShortcut}},
{QStringLiteral("Restart Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F6"), Qt::ApplicationShortcut}},
{QStringLiteral("Rotate Screens Upright"), QStringLiteral("Main Window"), {QStringLiteral("F8"), Qt::ApplicationShortcut}},
{QStringLiteral("Save to Oldest Non-Quicksave Slot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+C"), Qt::ApplicationShortcut}},
{QStringLiteral("Stop Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F5"), Qt::ApplicationShortcut}},
{QStringLiteral("Swap Screens"), QStringLiteral("Main Window"), {QStringLiteral("F9"), Qt::ApplicationShortcut}},
{QStringLiteral("Toggle 3D"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+3"), Qt::ApplicationShortcut}},
{QStringLiteral("Toggle Custom Textures"), QStringLiteral("Main Window"), {QStringLiteral("F7"), Qt::ApplicationShortcut}},
{QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}},
{QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::ApplicationShortcut}},
{QStringLiteral("Toggle Frame Advancing"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+A"), Qt::ApplicationShortcut}},
{QStringLiteral("Toggle Per-Application Speed"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Z"), Qt::ApplicationShortcut}},
{QStringLiteral("Toggle Screen Layout"), QStringLiteral("Main Window"), {QStringLiteral("F10"), Qt::WindowShortcut}},
{QStringLiteral("Toggle Status Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+S"), Qt::WindowShortcut}},
{QStringLiteral("Toggle Screen Layout"), QStringLiteral("Main Window"), {QStringLiteral("F10"), Qt::ApplicationShortcut}},
{QStringLiteral("Toggle Status Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+S"), Qt::ApplicationShortcut}},
{QStringLiteral("Toggle Texture Dumping"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::ApplicationShortcut}},
{QStringLiteral("Toggle Turbo Mode"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::ApplicationShortcut}},
}};
@ -894,6 +894,8 @@ void QtConfig::ReadUILayoutValues() {
UISettings::values.state = ReadSetting(Settings::QKeys::state).toByteArray();
UISettings::values.renderwindow_geometry =
ReadSetting(Settings::QKeys::geometryRenderWindow).toByteArray();
UISettings::values.secondarywindow_geometry =
ReadSetting(Settings::QKeys::geometrySecondaryWindow).toByteArray();
UISettings::values.gamelist_header_state =
ReadSetting(Settings::QKeys::gameListHeaderState).toByteArray();
UISettings::values.microprofile_geometry =
@ -1426,6 +1428,8 @@ void QtConfig::SaveUILayoutValues() {
WriteSetting(Settings::QKeys::geometry, UISettings::values.geometry);
WriteSetting(Settings::QKeys::state, UISettings::values.state);
WriteSetting(Settings::QKeys::geometryRenderWindow, UISettings::values.renderwindow_geometry);
WriteSetting(Settings::QKeys::geometrySecondaryWindow,
UISettings::values.secondarywindow_geometry);
WriteSetting(Settings::QKeys::gameListHeaderState, UISettings::values.gamelist_header_state);
WriteSetting(Settings::QKeys::microProfileDialogGeometry,
UISettings::values.microprofile_geometry);

View file

@ -70,7 +70,7 @@ struct Values {
QByteArray state;
QByteArray renderwindow_geometry;
QByteArray secondarywindow_geometry;
QByteArray gamelist_header_state;
QByteArray microprofile_geometry;