mirror of
https://github.com/stenzek/duckstation.git
synced 2026-04-15 18:42:33 +00:00
InputManager: Add 'Disable Background Input' option
Ignores controller input when application is not in the foreground.
This commit is contained in:
@@ -2266,9 +2266,10 @@ void FullscreenUI::DrawInterfaceSettingsPage()
|
||||
bsi, FSUI_ICONVSTR(ICON_FA_WAND_MAGIC_SPARKLES, "Inhibit Screensaver"),
|
||||
FSUI_VSTR("Prevents the screen saver from activating and the host from sleeping while emulation is running."),
|
||||
"Main", "InhibitScreensaver", true);
|
||||
DrawToggleSetting(bsi, FSUI_ICONVSTR(ICON_FA_PAUSE, "Pause On Start"),
|
||||
FSUI_VSTR("Pauses the emulator when a game is started."), "Main", "StartPaused", false);
|
||||
DrawToggleSetting(bsi, FSUI_ICONVSTR(ICON_FA_EYE_LOW_VISION, "Pause On Focus Loss"),
|
||||
DrawToggleSetting(bsi, FSUI_ICONVSTR(ICON_FA_EYE_LOW_VISION, "Disable Background Input"),
|
||||
FSUI_VSTR("Prevents inputs from being processed when another application is active."), "Main",
|
||||
"DisableBackgroundInput", false);
|
||||
DrawToggleSetting(bsi, FSUI_ICONVSTR(ICON_FA_PAUSE, "Pause On Focus Loss"),
|
||||
FSUI_VSTR("Pauses the emulator when you minimize the window or switch to another "
|
||||
"application, and unpauses when you switch back."),
|
||||
"Main", "PauseOnFocusLoss", false);
|
||||
@@ -5181,6 +5182,9 @@ void FullscreenUI::DrawAdvancedSettingsPage()
|
||||
FSUI_VSTR("Uses OpenGL ES even when desktop OpenGL is supported. May improve performance on some SBC drivers."),
|
||||
"GPU", "PreferGLESContext", Settings::DEFAULT_GPU_PREFER_GLES_CONTEXT);
|
||||
|
||||
DrawToggleSetting(bsi, FSUI_VSTR("Pause On Start"), FSUI_VSTR("Pauses the emulator when a game is started."), "Main",
|
||||
"StartPaused", false);
|
||||
|
||||
DrawToggleSetting(
|
||||
bsi, FSUI_VSTR("Load Devices From Save States"),
|
||||
FSUI_VSTR("When enabled, memory cards and controllers will be overwritten when save states are loaded."), "Main",
|
||||
|
||||
@@ -261,6 +261,7 @@ TRANSLATE_NOOP("FullscreenUI", "Determines the size of screenshots created by Du
|
||||
TRANSLATE_NOOP("FullscreenUI", "Determines whether a prompt will be displayed to confirm closing the game.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Determines which algorithm is used to convert interlaced frames to progressive for display on your system.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Device Settings");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Disable Background Input");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Disable Mailbox Presentation");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Disable Speedup on MDEC");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Disable Subdirectory Scanning");
|
||||
@@ -560,6 +561,7 @@ TRANSLATE_NOOP("FullscreenUI", "Preload Replacement Textures");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Preserve Projection Precision");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Press To Toggle");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Pressure");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Prevents inputs from being processed when another application is active.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Prevents resizing of the window while a game is running.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Prevents the emulator from producing any audible sound.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Prevents the screen saver from activating and the host from sleeping while emulation is running.");
|
||||
|
||||
@@ -217,6 +217,7 @@ void Settings::Load(const SettingsInterface& si, const SettingsInterface& contro
|
||||
inhibit_screensaver = si.GetBoolValue("Main", "InhibitScreensaver", true);
|
||||
pause_on_focus_loss = si.GetBoolValue("Main", "PauseOnFocusLoss", false);
|
||||
pause_on_controller_disconnection = si.GetBoolValue("Main", "PauseOnControllerDisconnection", false);
|
||||
ignore_background_input = si.GetBoolValue("Main", "IgnoreBackgroundInput", false);
|
||||
save_state_on_exit = si.GetBoolValue("Main", "SaveStateOnExit", true);
|
||||
create_save_state_backups = si.GetBoolValue("Main", "CreateSaveStateBackups", DEFAULT_SAVE_STATE_BACKUPS);
|
||||
confim_power_off = si.GetBoolValue("Main", "ConfirmPowerOff", true);
|
||||
@@ -631,6 +632,8 @@ void Settings::Save(SettingsInterface& si, bool ignore_base) const
|
||||
si.SetBoolValue("Main", "EnableDiscordPresence", enable_discord_presence);
|
||||
}
|
||||
|
||||
si.SetBoolValue("Main", "IgnoreBackgroundInput", ignore_background_input);
|
||||
|
||||
si.SetBoolValue("Main", "LoadDevicesFromSaveStates", load_devices_from_save_states);
|
||||
si.SetBoolValue("Main", "DisableAllEnhancements", disable_all_enhancements);
|
||||
si.SetBoolValue("Main", "RewindEnable", rewind_enable);
|
||||
|
||||
@@ -327,6 +327,7 @@ struct Settings : public GPUSettings
|
||||
bool inhibit_screensaver : 1 = true;
|
||||
bool pause_on_focus_loss : 1 = false;
|
||||
bool pause_on_controller_disconnection : 1 = false;
|
||||
bool ignore_background_input : 1 = false;
|
||||
bool save_state_on_exit : 1 = true;
|
||||
bool create_save_state_backups : 1 = DEFAULT_SAVE_STATE_BACKUPS;
|
||||
bool confim_power_off : 1 = true;
|
||||
|
||||
@@ -4856,6 +4856,9 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
|
||||
}
|
||||
}
|
||||
|
||||
if (g_settings.ignore_background_input != old_settings.ignore_background_input)
|
||||
InputManager::UpdateInputIgnoreState();
|
||||
|
||||
Achievements::UpdateSettings(old_settings);
|
||||
|
||||
#ifdef ENABLE_DISCORD_PRESENCE
|
||||
|
||||
@@ -259,6 +259,8 @@ void AdvancedSettingsWidget::addTweakOptions()
|
||||
"ApplyCompatibilitySettings", true);
|
||||
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Load Devices From Save States"), "Main",
|
||||
"LoadDevicesFromSaveStates", false);
|
||||
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Pause On Start"), "Main", "StartPaused",
|
||||
false);
|
||||
addChoiceTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Save State Compression"), "Main", "SaveStateCompression",
|
||||
&Settings::ParseSaveStateCompressionModeName, &Settings::GetSaveStateCompressionModeName,
|
||||
&Settings::GetSaveStateCompressionModeDisplayName,
|
||||
@@ -334,6 +336,7 @@ void AdvancedSettingsWidget::onResetToDefaultClicked()
|
||||
|
||||
setBooleanTweakOption(m_ui.tweakOptionTable, i++, true); // Apply Game Settings
|
||||
setBooleanTweakOption(m_ui.tweakOptionTable, i++, true); // Apply Compatibility settings
|
||||
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Pause On Start
|
||||
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Load Devices From Save States
|
||||
setChoiceTweakOption(m_ui.tweakOptionTable, i++,
|
||||
Settings::DEFAULT_SAVE_STATE_COMPRESSION_MODE); // Save State Compression
|
||||
@@ -376,6 +379,7 @@ void AdvancedSettingsWidget::onResetToDefaultClicked()
|
||||
INISettingsInterface* sif = m_dialog->getSettingsInterface();
|
||||
sif->DeleteValue("Main", "ApplyCompatibilitySettings");
|
||||
sif->DeleteValue("Main", "LoadDevicesFromSaveStates");
|
||||
sif->DeleteValue("Main", "PauseOnStart");
|
||||
sif->DeleteValue("Main", "CompressSaveStates");
|
||||
sif->DeleteValue("Display", "ActiveStartOffset");
|
||||
sif->DeleteValue("Display", "ActiveEndOffset");
|
||||
|
||||
@@ -67,7 +67,8 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsWindow* dialog, QWidget
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pauseOnFocusLoss, "Main", "PauseOnFocusLoss", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pauseOnControllerDisconnection, "Main",
|
||||
"PauseOnControllerDisconnection", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pauseOnStart, "Main", "StartPaused", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableBackgroundInput, "Main", "DisableBackgroundInput",
|
||||
false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.saveStateOnGameClose, "Main", "SaveStateOnExit", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.confirmGameClose, "Main", "ConfirmPowerOff", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.startFullscreen, "Main", "StartFullscreen", false);
|
||||
@@ -159,8 +160,8 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsWindow* dialog, QWidget
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.inhibitScreensaver, tr("Inhibit Screensaver"), tr("Checked"),
|
||||
tr("Prevents the screen saver from activating and the host from sleeping while emulation is running."));
|
||||
dialog->registerWidgetHelp(m_ui.pauseOnStart, tr("Pause On Start"), tr("Unchecked"),
|
||||
tr("Pauses the emulator when a game is started."));
|
||||
dialog->registerWidgetHelp(m_ui.disableBackgroundInput, tr("Disable Background Input"), tr("Unchecked"),
|
||||
tr("Prevents inputs from being processed when another application is active."));
|
||||
dialog->registerWidgetHelp(m_ui.pauseOnFocusLoss, tr("Pause On Focus Loss"), tr("Unchecked"),
|
||||
tr("Pauses the emulator when you minimize the window or switch to another application, "
|
||||
"and unpauses when you switch back."));
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>652</width>
|
||||
<height>490</height>
|
||||
<height>572</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
@@ -50,13 +50,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="pauseOnStart">
|
||||
<property name="text">
|
||||
<string>Pause On Start</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="pauseOnFocusLoss">
|
||||
<property name="text">
|
||||
@@ -64,13 +57,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="pauseOnControllerDisconnection">
|
||||
<property name="text">
|
||||
<string>Pause On Controller Disconnection</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="createSaveStateBackups">
|
||||
<property name="text">
|
||||
@@ -85,6 +71,20 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="pauseOnControllerDisconnection">
|
||||
<property name="text">
|
||||
<string>Pause On Controller Disconnection</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="disableBackgroundInput">
|
||||
<property name="text">
|
||||
<string>Disable Background Input</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -680,36 +680,6 @@ void MainWindow::onMediaCaptureStopped()
|
||||
m_ui.actionMediaCapture->setChecked(false);
|
||||
}
|
||||
|
||||
void MainWindow::onApplicationStateChanged(Qt::ApplicationState state)
|
||||
{
|
||||
if (!s_locals.system_valid)
|
||||
return;
|
||||
|
||||
const bool focus_loss = (state != Qt::ApplicationActive);
|
||||
if (focus_loss)
|
||||
{
|
||||
if (g_settings.pause_on_focus_loss && !m_was_paused_by_focus_loss && !s_locals.system_paused)
|
||||
{
|
||||
g_core_thread->setSystemPaused(true);
|
||||
m_was_paused_by_focus_loss = true;
|
||||
}
|
||||
|
||||
// Clear the state of all keyboard binds.
|
||||
// That way, if we had a key held down, and lost focus, the bind won't be stuck enabled because we never
|
||||
// got the key release message, because it happened in another window which "stole" the event.
|
||||
g_core_thread->clearInputBindStateFromSource(InputManager::MakeHostKeyboardKey(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_was_paused_by_focus_loss)
|
||||
{
|
||||
if (s_locals.system_paused)
|
||||
g_core_thread->setSystemPaused(false);
|
||||
m_was_paused_by_focus_loss = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onStartFileActionTriggered()
|
||||
{
|
||||
QString filename = QDir::toNativeSeparators(
|
||||
@@ -2440,7 +2410,6 @@ void MainWindow::switchToEmulationView()
|
||||
|
||||
void MainWindow::connectSignals()
|
||||
{
|
||||
connect(qApp, &QGuiApplication::applicationStateChanged, this, &MainWindow::onApplicationStateChanged);
|
||||
connect(m_ui.toolBar, &QToolBar::customContextMenuRequested, this, &MainWindow::onToolbarContextMenuRequested);
|
||||
connect(m_ui.toolBar, &QToolBar::topLevelChanged, this, &MainWindow::onToolbarTopLevelChanged);
|
||||
|
||||
|
||||
@@ -253,8 +253,6 @@ private:
|
||||
Host::AuxiliaryRenderWindowHandle* handle, WindowInfo* wi, Error* error);
|
||||
void onDestroyAuxiliaryRenderWindow(Host::AuxiliaryRenderWindowHandle handle, QPoint* pos, QSize* size);
|
||||
|
||||
void onApplicationStateChanged(Qt::ApplicationState state);
|
||||
|
||||
void onToolbarContextMenuRequested(const QPoint& pos);
|
||||
void onToolbarTopLevelChanged(bool top_level);
|
||||
|
||||
@@ -355,7 +353,6 @@ private:
|
||||
MemoryEditorWindow* m_memory_editor_window = nullptr;
|
||||
CoverDownloadWindow* m_cover_download_window = nullptr;
|
||||
|
||||
bool m_was_paused_by_focus_loss = false;
|
||||
bool m_relative_mouse_mode = false;
|
||||
bool m_hide_mouse_cursor = false;
|
||||
|
||||
|
||||
@@ -1291,17 +1291,6 @@ void CoreThread::updatePostProcessingSettings(bool display, bool internal, bool
|
||||
GPUPresenter::ReloadPostProcessingSettings(display, internal, force_reload);
|
||||
}
|
||||
|
||||
void CoreThread::clearInputBindStateFromSource(InputBindingKey key)
|
||||
{
|
||||
if (!isCurrentThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, &CoreThread::clearInputBindStateFromSource, Qt::QueuedConnection, key);
|
||||
return;
|
||||
}
|
||||
|
||||
InputManager::ClearBindStateFromSource(key);
|
||||
}
|
||||
|
||||
void CoreThread::reloadTextureReplacements()
|
||||
{
|
||||
if (!isCurrentThread())
|
||||
@@ -1658,6 +1647,38 @@ void CoreThread::saveScreenshot()
|
||||
System::SaveScreenshot();
|
||||
}
|
||||
|
||||
void CoreThread::applicationStateChanged(Qt::ApplicationState state)
|
||||
{
|
||||
const bool background = (state != Qt::ApplicationActive);
|
||||
InputManager::OnApplicationBackgroundStateChanged(background);
|
||||
|
||||
if (!System::IsValid())
|
||||
return;
|
||||
|
||||
if (background)
|
||||
{
|
||||
if (g_settings.pause_on_focus_loss && !m_was_paused_by_focus_loss && !System::IsPaused())
|
||||
{
|
||||
setSystemPaused(true);
|
||||
m_was_paused_by_focus_loss = true;
|
||||
}
|
||||
|
||||
// Clear the state of all keyboard binds.
|
||||
// That way, if we had a key held down, and lost focus, the bind won't be stuck enabled because we never
|
||||
// got the key release message, because it happened in another window which "stole" the event.
|
||||
InputManager::ClearBindStateFromSource(InputManager::MakeHostKeyboardKey(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_was_paused_by_focus_loss)
|
||||
{
|
||||
if (System::IsPaused())
|
||||
setSystemPaused(false);
|
||||
m_was_paused_by_focus_loss = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Host::OnAchievementsLoginRequested(Achievements::LoginRequestReason reason)
|
||||
{
|
||||
emit g_core_thread->achievementsLoginRequested(reason);
|
||||
@@ -1964,6 +1985,9 @@ void CoreThread::run()
|
||||
// TODO: Replace this with QThreads
|
||||
s_async_task_queue.SetWorkerCount(NUM_ASYNC_WORKER_THREADS);
|
||||
|
||||
// connections
|
||||
connect(qApp, &QGuiApplication::applicationStateChanged, this, &CoreThread::applicationStateChanged);
|
||||
|
||||
// enumerate all devices, even those which were added early
|
||||
m_input_device_list_model->enumerateDevices();
|
||||
|
||||
|
||||
@@ -166,6 +166,7 @@ public:
|
||||
void dumpVRAM(const QString& path);
|
||||
void dumpSPURAM(const QString& path);
|
||||
void saveScreenshot();
|
||||
void applicationStateChanged(Qt::ApplicationState state);
|
||||
void redrawDisplayWindow();
|
||||
void toggleFullscreen();
|
||||
void setFullscreen(bool fullscreen);
|
||||
@@ -175,7 +176,6 @@ public:
|
||||
void applyCheat(const QString& name);
|
||||
void reloadPostProcessingShaders();
|
||||
void updatePostProcessingSettings(bool display, bool internal, bool force_reload);
|
||||
void clearInputBindStateFromSource(InputBindingKey key);
|
||||
void reloadTextureReplacements();
|
||||
void captureGPUFrameDump();
|
||||
void startControllerTest();
|
||||
@@ -215,6 +215,7 @@ private:
|
||||
bool m_shutdown_flag = false;
|
||||
bool m_gpu_thread_run_idle = false;
|
||||
bool m_is_fullscreen_ui_started = false;
|
||||
bool m_was_paused_by_focus_loss = false;
|
||||
|
||||
float m_last_speed = std::numeric_limits<float>::infinity();
|
||||
float m_last_game_fps = std::numeric_limits<float>::infinity();
|
||||
|
||||
@@ -164,6 +164,7 @@ static void InternalClearEffects();
|
||||
static void GenerateRelativeMouseEvents();
|
||||
[[maybe_unused]] static void ReloadDevices();
|
||||
|
||||
static bool ShouldMaskBackgroundInput(InputBindingKey key);
|
||||
static bool DoEventHook(InputBindingKey key, float value);
|
||||
static bool PreprocessEvent(InputBindingKey key, float value, GenericInputBinding generic_key);
|
||||
static bool ProcessEvent(InputBindingKey key, float value, bool skip_button_handlers);
|
||||
@@ -228,6 +229,14 @@ struct ALIGN_TO_CACHE_LINE State
|
||||
// Input sources. Keyboard/mouse don't exist here.
|
||||
std::array<std::unique_ptr<InputSource>, static_cast<u32>(InputSourceType::Count)> input_sources;
|
||||
|
||||
bool application_in_background = false;
|
||||
bool ignore_input_events = false;
|
||||
bool has_pointer_device_bindings = false;
|
||||
bool relative_mouse_mode = false;
|
||||
bool relative_mouse_mode_active = false;
|
||||
bool hide_host_mouse_cursor = false;
|
||||
bool hide_host_mouse_cusor_active = false;
|
||||
|
||||
#ifdef _WIN32
|
||||
// Device notification handle for Windows.
|
||||
HCMNOTIFICATION device_notification_handle = nullptr;
|
||||
@@ -244,11 +253,6 @@ struct ALIGN_TO_CACHE_LINE State
|
||||
|
||||
// Window size, used for clamping the mouse position in raw input modes.
|
||||
std::array<float, 2> window_size = {};
|
||||
bool has_pointer_device_bindings = false;
|
||||
bool relative_mouse_mode = false;
|
||||
bool relative_mouse_mode_active = false;
|
||||
bool hide_host_mouse_cursor = false;
|
||||
bool hide_host_mouse_cusor_active = false;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -1157,14 +1161,28 @@ bool InputManager::IsAxisHandler(const InputEventHandler& handler)
|
||||
return std::holds_alternative<InputAxisEventHandler>(handler);
|
||||
}
|
||||
|
||||
bool InputManager::InvokeEvents(InputBindingKey key, float value, GenericInputBinding generic_key)
|
||||
bool InputManager::ShouldMaskBackgroundInput(InputBindingKey key)
|
||||
{
|
||||
// Keyboard events won't get sent to us if we're in the background.
|
||||
// We want to still update our mouse pointer state.
|
||||
// Sensors are probably fine, but not used on desktop.
|
||||
// Everything else should be ignored.
|
||||
return (key.source_type > InputSourceType::Sensor && s_state.ignore_input_events);
|
||||
}
|
||||
|
||||
void InputManager::InvokeEvents(InputBindingKey key, float value, GenericInputBinding generic_key)
|
||||
{
|
||||
if (DoEventHook(key, value))
|
||||
return true;
|
||||
return;
|
||||
|
||||
// If imgui ate the event, don't fire our handlers.
|
||||
const bool skip_button_handlers = PreprocessEvent(key, value, generic_key);
|
||||
return ProcessEvent(key, value, skip_button_handlers);
|
||||
|
||||
// Background input test
|
||||
if (ShouldMaskBackgroundInput(key))
|
||||
return;
|
||||
|
||||
ProcessEvent(key, value, skip_button_handlers);
|
||||
}
|
||||
|
||||
bool InputManager::ProcessEvent(InputBindingKey key, float value, bool skip_button_handlers)
|
||||
@@ -1534,7 +1552,7 @@ void InputManager::UpdatePointerRelativeDelta(u32 index, InputPointerAxis axis,
|
||||
|
||||
s_state.host_pointer_positions[index][static_cast<u8>(axis)] += d;
|
||||
s_state.pointer_state[index][static_cast<u8>(axis)].delta.fetch_add(static_cast<s32>(d * 65536.0f),
|
||||
std::memory_order_release);
|
||||
std::memory_order_acq_rel);
|
||||
|
||||
// We need to clamp the position ourselves in relative mode.
|
||||
if (axis <= InputPointerAxis::Y)
|
||||
@@ -1621,6 +1639,32 @@ std::pair<float, float> InputManager::GetDisplayWindowSize()
|
||||
return std::make_pair(s_state.window_size[0], s_state.window_size[1]);
|
||||
}
|
||||
|
||||
void InputManager::OnApplicationBackgroundStateChanged(bool in_background)
|
||||
{
|
||||
s_state.application_in_background = in_background;
|
||||
UpdateInputIgnoreState();
|
||||
}
|
||||
|
||||
void InputManager::UpdateInputIgnoreState()
|
||||
{
|
||||
const bool prev_ignore_input_events = s_state.ignore_input_events;
|
||||
s_state.ignore_input_events = s_state.application_in_background && g_settings.ignore_background_input;
|
||||
if (s_state.ignore_input_events != prev_ignore_input_events)
|
||||
{
|
||||
if (s_state.ignore_input_events)
|
||||
{
|
||||
VERBOSE_COLOR_LOG(StrongOrange, "Application in background, ignoring input events");
|
||||
}
|
||||
else
|
||||
{
|
||||
VERBOSE_COLOR_LOG(StrongGreen, "Application in foreground, processing input events");
|
||||
|
||||
// Synchronize button state, it might have changed
|
||||
SynchronizeBindingHandlerState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InputManager::SetDefaultSourceConfig(SettingsInterface& si)
|
||||
{
|
||||
si.ClearSection("InputSources");
|
||||
|
||||
@@ -310,7 +310,7 @@ void AddVibrationBinding(u32 pad_index, u32 bind_index, const InputBindingKey& b
|
||||
|
||||
/// Updates internal state for any binds for this key, and fires callbacks as needed.
|
||||
/// Returns true if anything was bound to this key, otherwise false.
|
||||
bool InvokeEvents(InputBindingKey key, float value, GenericInputBinding generic_key = GenericInputBinding::Unknown);
|
||||
void InvokeEvents(InputBindingKey key, float value, GenericInputBinding generic_key = GenericInputBinding::Unknown);
|
||||
|
||||
/// Clears internal state for any binds with a matching source/index.
|
||||
void ClearBindStateFromSource(InputBindingKey key);
|
||||
@@ -370,6 +370,10 @@ bool IsUsingRawInput();
|
||||
void SetDisplayWindowSize(float width, float height);
|
||||
std::pair<float, float> GetDisplayWindowSize();
|
||||
|
||||
/// Called when the application window gains or loses focus.
|
||||
void OnApplicationBackgroundStateChanged(bool in_background);
|
||||
void UpdateInputIgnoreState();
|
||||
|
||||
/// Restores default configuration.
|
||||
void SetDefaultSourceConfig(SettingsInterface& si);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user