mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
UX: Option to pause emulation when RPCS3 is not focused
This commit is contained in:
parent
b3b680f073
commit
05824e6acd
@ -106,7 +106,7 @@ class Emulator final
|
||||
|
||||
atomic_t<u64> m_pause_start_time{0}; // set when paused
|
||||
atomic_t<u64> m_pause_amend_time{0}; // increased when resumed
|
||||
atomic_t<u64> m_stop_ctr{0}; // Increments when emulation is stopped
|
||||
atomic_t<u64> m_stop_ctr{1}; // Increments when emulation is stopped
|
||||
|
||||
games_config m_games_config;
|
||||
|
||||
|
@ -326,6 +326,7 @@ struct cfg_root : cfg::node
|
||||
|
||||
cfg::_bool autostart{ this, "Automatically start games after boot", true, true };
|
||||
cfg::_bool autoexit{ this, "Exit RPCS3 when process finishes", false, true };
|
||||
cfg::_bool autopause{ this, "Pause emulation on RPCS3 focus loss", false, true };
|
||||
cfg::_bool start_fullscreen{ this, "Start games in fullscreen mode", false, true };
|
||||
cfg::_bool prevent_display_sleep{ this, "Prevent display sleep while running games", true, true };
|
||||
cfg::_bool show_trophy_popups{ this, "Show trophy popups", true, true };
|
||||
|
@ -162,6 +162,7 @@ enum class emu_settings_type
|
||||
// Misc
|
||||
ExitRPCS3OnFinish,
|
||||
StartOnBoot,
|
||||
PauseOnFocusLoss,
|
||||
StartGameFullscreen,
|
||||
PreventDisplaySleep,
|
||||
ShowTrophyPopups,
|
||||
@ -346,6 +347,7 @@ inline static const QMap<emu_settings_type, cfg_location> settings_location =
|
||||
// Misc
|
||||
{ emu_settings_type::ExitRPCS3OnFinish, { "Miscellaneous", "Exit RPCS3 when process finishes" }},
|
||||
{ emu_settings_type::StartOnBoot, { "Miscellaneous", "Automatically start games after boot" }},
|
||||
{ emu_settings_type::PauseOnFocusLoss, { "Miscellaneous", "Pause emulation on RPCS3 focus loss" }},
|
||||
{ emu_settings_type::StartGameFullscreen, { "Miscellaneous", "Start games in fullscreen mode"}},
|
||||
{ emu_settings_type::PreventDisplaySleep, { "Miscellaneous", "Prevent display sleep while running games"}},
|
||||
{ emu_settings_type::ShowTrophyPopups, { "Miscellaneous", "Show trophy popups"}},
|
||||
|
@ -270,6 +270,7 @@ void gui_application::InitializeConnects()
|
||||
connect(this, &gui_application::OnEmulatorStop, this, &gui_application::StopPlaytime);
|
||||
connect(this, &gui_application::OnEmulatorPause, this, &gui_application::StopPlaytime);
|
||||
connect(this, &gui_application::OnEmulatorResume, this, &gui_application::StartPlaytime);
|
||||
connect(this, &QGuiApplication::applicationStateChanged, this, &gui_application::OnAppStateChanged);
|
||||
|
||||
if (m_main_window)
|
||||
{
|
||||
@ -798,3 +799,76 @@ void gui_application::CallFromMainThread(const std::function<void()>& func, atom
|
||||
wake_up->notify_one();
|
||||
}
|
||||
}
|
||||
|
||||
void gui_application::OnAppStateChanged(Qt::ApplicationState state)
|
||||
{
|
||||
// Invalidate previous delayed pause call (even when the setting is off because it is dynamic)
|
||||
m_pause_delayed_tag++;
|
||||
|
||||
if (!g_cfg.misc.autopause)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto emu_state = Emu.GetStatus();
|
||||
const bool is_active = state == Qt::ApplicationActive;
|
||||
|
||||
if (emu_state != system_state::paused && emu_state != system_state::running)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const bool is_paused = emu_state == system_state::paused;
|
||||
|
||||
if (is_active != is_paused)
|
||||
{
|
||||
// Nothing to do (either paused and this is focus-out event or running and this is a focus-in event)
|
||||
// Invalidate data
|
||||
m_is_pause_on_focus_loss_active = false;
|
||||
m_emu_focus_out_emulation_id = Emulator::stop_counter_t{};
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_paused)
|
||||
{
|
||||
// Check if Emu.Resume() or Emu.Kill() has not been called since
|
||||
if (m_is_pause_on_focus_loss_active && m_pause_amend_time_on_focus_loss == Emu.GetPauseTime() && m_emu_focus_out_emulation_id == Emu.GetEmulationIdentifier())
|
||||
{
|
||||
m_is_pause_on_focus_loss_active = false;
|
||||
Emu.Resume();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Gather validation data
|
||||
m_emu_focus_out_emulation_id = Emu.GetEmulationIdentifier();
|
||||
|
||||
auto pause_callback = [this, delayed_tag = m_pause_delayed_tag]()
|
||||
{
|
||||
// Check if Emu.Kill() has not been called since
|
||||
if (applicationState() != Qt::ApplicationActive && Emu.IsRunning() &&
|
||||
m_emu_focus_out_emulation_id == Emu.GetEmulationIdentifier() &&
|
||||
delayed_tag == m_pause_delayed_tag &&
|
||||
!m_is_pause_on_focus_loss_active)
|
||||
{
|
||||
if (Emu.Pause())
|
||||
{
|
||||
// Gather validation data
|
||||
m_pause_amend_time_on_focus_loss = Emu.GetPauseTime();
|
||||
m_emu_focus_out_emulation_id = Emu.GetEmulationIdentifier();
|
||||
m_is_pause_on_focus_loss_active = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (state == Qt::ApplicationSuspended)
|
||||
{
|
||||
// Must be invoked now (otherwise it may not happen later)
|
||||
pause_callback();
|
||||
return;
|
||||
}
|
||||
|
||||
// Delay pause so it won't immediately pause the emulated application
|
||||
QTimer::singleShot(1000, this, pause_callback);
|
||||
}
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include "main_application.h"
|
||||
|
||||
#include "Emu/System.h"
|
||||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
@ -95,8 +97,14 @@ private:
|
||||
bool m_start_games_fullscreen = false;
|
||||
int m_game_screen_index = -1;
|
||||
|
||||
u64 m_pause_amend_time_on_focus_loss = umax;
|
||||
u64 m_pause_delayed_tag = 0;
|
||||
typename Emulator::stop_counter_t m_emu_focus_out_emulation_id{};
|
||||
bool m_is_pause_on_focus_loss_active = false;
|
||||
|
||||
private Q_SLOTS:
|
||||
void OnChangeStyleSheetRequest();
|
||||
void OnAppStateChanged(Qt::ApplicationState state);
|
||||
|
||||
Q_SIGNALS:
|
||||
void OnEmulatorRun(bool start_playtime);
|
||||
|
@ -1734,6 +1734,9 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
||||
m_emu_settings->EnhanceCheckBox(ui->exitOnStop, emu_settings_type::ExitRPCS3OnFinish);
|
||||
SubscribeTooltip(ui->exitOnStop, tooltips.settings.exit_on_stop);
|
||||
|
||||
m_emu_settings->EnhanceCheckBox(ui->pauseOnFocusLoss, emu_settings_type::PauseOnFocusLoss);
|
||||
SubscribeTooltip(ui->pauseOnFocusLoss, tooltips.settings.pause_on_focus_loss);
|
||||
|
||||
m_emu_settings->EnhanceCheckBox(ui->startGameFullscreen, emu_settings_type::StartGameFullscreen);
|
||||
SubscribeTooltip(ui->startGameFullscreen, tooltips.settings.start_game_fullscreen);
|
||||
|
||||
|
@ -2878,6 +2878,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="pauseOnFocusLoss">
|
||||
<property name="text">
|
||||
<string>Pause emulation on RPCS3 focus loss</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="pausedSavestates">
|
||||
<property name="text">
|
||||
|
@ -122,6 +122,7 @@ public:
|
||||
// emulator
|
||||
|
||||
const QString exit_on_stop = tr("Automatically close RPCS3 when closing a game, or when a game closes itself.");
|
||||
const QString pause_on_focus_loss = tr("Automatically pause emulation when RPCS3 loses its focus or the application is inactive in order to save power and reduce CPU usage.\nDo note that emulation pausing in general is not perfect and may not be compatible with all games.\nAlthough it currently also pauses gameplay, it is not recommended to rely on it as this behavior may be changed in the future and it is not the purpose of this setting.");
|
||||
const QString start_game_fullscreen = tr("Automatically puts the game window in fullscreen.\nDouble click on the game window or press Alt+Enter to toggle fullscreen and windowed mode.");
|
||||
const QString prevent_display_sleep = tr("Prevent the display from sleeping while a game is running.\nThis requires the org.freedesktop.ScreenSaver D-Bus service on Linux.\nThis option will be disabled if the current platform does not support display sleep control.");
|
||||
const QString game_window_title_format = tr("Configure the game window title.\nChanging this and/or adding the framerate may cause buggy or outdated recording software to not notice RPCS3.");
|
||||
|
Loading…
Reference in New Issue
Block a user