Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Source/Android/jni/MainAndroid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,11 @@ bool Host_TASInputHasFocus()
return false;
}

bool Host_DolphinIsActiveApplication()
{
return true;
}

void Host_YieldToUI()
{
}
Expand Down
11 changes: 8 additions & 3 deletions Source/Core/Common/Config/Layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,14 @@ requires(!Common::Enum<T>)
std::optional<T> TryParse(const std::string& str_value)
{
T value;
if (!::TryParse(str_value, &value))
return std::nullopt;
return value;
if (::TryParse(str_value, &value))
return value;

bool bool_value;
if (::TryParse(str_value, &bool_value))
return static_cast<T>(bool_value);

return std::nullopt;
}

template <Common::Enum T>
Expand Down
3 changes: 3 additions & 0 deletions Source/Core/Core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ add_library(core
Config/FreeLookSettings.h
Config/GraphicsSettings.cpp
Config/GraphicsSettings.h
Config/InputFocus.h
Config/MainSettings.cpp
Config/MainSettings.h
Config/NetplaySettings.cpp
Expand Down Expand Up @@ -342,6 +343,8 @@ add_library(core
HW/WiiSave.cpp
HW/WiiSave.h
HW/WiiSaveStructs.h
InputSuppressor.cpp
InputSuppressor.h
IOS/Device.cpp
IOS/Device.h
IOS/DeviceStub.cpp
Expand Down
5 changes: 3 additions & 2 deletions Source/Core/Core/Config/FreeLookSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
#include <string>

#include "Common/Config/Config.h"
#include "Core/Config/InputFocus.h"
#include "Core/FreeLookConfig.h"

namespace Config
{
// Configuration Information
const Info<bool> FREE_LOOK_ENABLED{{System::FreeLook, "General", "Enabled"}, false};
const Info<bool> FREE_LOOK_BACKGROUND_INPUT{{System::FreeLook, "General", "BackgroundInput"},
false};
const Info<InputFocusPolicy> FREE_LOOK_FOCUS_POLICY{
{System::FreeLook, "General", "BackgroundInput"}, InputFocusPolicy::RenderOrTASWindow};

// FreeLook.Controller1
const Info<FreeLook::ControlType> FL1_CONTROL_TYPE{{System::FreeLook, "Camera1", "ControlType"},
Expand Down
4 changes: 3 additions & 1 deletion Source/Core/Core/Config/FreeLookSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ namespace Config
{
// Configuration Information

enum class InputFocusPolicy;

extern const Info<bool> FREE_LOOK_ENABLED;
extern const Info<bool> FREE_LOOK_BACKGROUND_INPUT;
extern const Info<InputFocusPolicy> FREE_LOOK_FOCUS_POLICY;

// FreeLook.Controller1
extern const Info<FreeLook::ControlType> FL1_CONTROL_TYPE;
Expand Down
14 changes: 14 additions & 0 deletions Source/Core/Core/Config/InputFocus.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright 2025 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

namespace Config
{
enum class InputFocusPolicy
{
RenderOrTASWindow = 0,
AnyApplication = 1,
Dolphin = 2,
};
} // namespace Config
4 changes: 3 additions & 1 deletion Source/Core/Core/Config/MainSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "Common/Version.h"
#include "Core/AchievementManager.h"
#include "Core/Config/DefaultLocale.h"
#include "Core/Config/InputFocus.h"
#include "Core/HW/EXI/EXI.h"
#include "Core/HW/EXI/EXI_Device.h"
#include "Core/HW/GCMemcard/GCMemcard.h"
Expand Down Expand Up @@ -515,7 +516,8 @@ const Info<bool> MAIN_MOVIE_SHOW_RERECORD{{System::Main, "Movie", "ShowRerecord"

// Main.Input

const Info<bool> MAIN_INPUT_BACKGROUND_INPUT{{System::Main, "Input", "BackgroundInput"}, false};
const Info<InputFocusPolicy> MAIN_CONTROLLER_FOCUS_POLICY{
{System::Main, "Input", "BackgroundInput"}, InputFocusPolicy::RenderOrTASWindow};

// Main.Debug

Expand Down
4 changes: 3 additions & 1 deletion Source/Core/Core/Config/MainSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ namespace Config
{
// Main.Core

enum class InputFocusPolicy;

extern const Info<bool> MAIN_SKIP_IPL;
extern const Info<PowerPC::CPUCore> MAIN_CPU_CORE;
extern const Info<bool> MAIN_JIT_FOLLOW_BRANCH;
Expand Down Expand Up @@ -330,7 +332,7 @@ extern const Info<bool> MAIN_MOVIE_SHOW_RERECORD;

// Main.Input

extern const Info<bool> MAIN_INPUT_BACKGROUND_INPUT;
extern const Info<InputFocusPolicy> MAIN_CONTROLLER_FOCUS_POLICY;

// Main.Debug

Expand Down
3 changes: 2 additions & 1 deletion Source/Core/Core/Config/UISettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ const Info<bool> MAIN_USE_GAME_COVERS{{System::Main, "General", "UseGameCovers"}
#else
const Info<bool> MAIN_USE_GAME_COVERS{{System::Main, "General", "UseGameCovers"}, false};
#endif
const Info<bool> MAIN_FOCUSED_HOTKEYS{{System::Main, "General", "HotkeysRequireFocus"}, true};
const Info<HotkeyFocusPolicy> MAIN_HOTKEY_FOCUS_POLICY{
{System::Main, "General", "HotkeysRequireFocus"}, HotkeyFocusPolicy::Dolphin};
const Info<bool> MAIN_RECURSIVE_ISO_PATHS{{System::Main, "General", "RecursiveISOPaths"}, false};
const Info<std::string> MAIN_CURRENT_STATE_PATH{{System::Main, "General", "CurrentStatePath"}, ""};

Expand Down
9 changes: 8 additions & 1 deletion Source/Core/Core/Config/UISettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,18 @@ namespace Config
{
// Configuration Information

enum class HotkeyFocusPolicy
{
AnyApplication = 0,
Dolphin = 1,
RenderOrTASWindow = 2,
};

// UI.General

extern const Info<bool> MAIN_USE_DISCORD_PRESENCE;
extern const Info<bool> MAIN_USE_GAME_COVERS;
extern const Info<bool> MAIN_FOCUSED_HOTKEYS;
extern const Info<HotkeyFocusPolicy> MAIN_HOTKEY_FOCUS_POLICY;
extern const Info<bool> MAIN_RECURSIVE_ISO_PATHS;
extern const Info<std::string> MAIN_CURRENT_STATE_PATH;

Expand Down
29 changes: 23 additions & 6 deletions Source/Core/Core/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "Core/Boot/Boot.h"
#include "Core/BootManager.h"
#include "Core/CPUThreadConfigCallback.h"
#include "Core/Config/InputFocus.h"
#include "Core/Config/MainSettings.h"
#include "Core/ConfigManager.h"
#include "Core/CoreTiming.h"
Expand All @@ -62,6 +63,7 @@
#include "Core/HW/Wiimote.h"
#include "Core/Host.h"
#include "Core/IOS/IOS.h"
#include "Core/InputSuppressor.h"
#include "Core/MemTools.h"
#include "Core/Movie.h"
#include "Core/NetPlayClient.h"
Expand Down Expand Up @@ -1037,15 +1039,30 @@ void DoFrameStep(Core::System& system)
}
}

void UpdateInputGate(bool require_focus, bool require_full_focus)
void UpdateInputGate(const Config::InputFocusPolicy input_focus_policy,
const bool require_full_focus)
{
// If the user accepts background input, controls should pass even if an on screen interface is on
using Policy = Config::InputFocusPolicy;

if (InputSuppressor::IsSuppressed())
{
ControlReference::SetInputGate(false);
return;
}

if (input_focus_policy == Policy::AnyApplication ||
(input_focus_policy == Policy::Dolphin && Host_DolphinIsActiveApplication()))
{
// If the user accepts input from windows other than the render window or TAS inputs, controls
// should pass even if an on screen interface is blocking Dolphin's UI.
ControlReference::SetInputGate(true);
return;
}

const bool focus_passes =
!require_focus ||
((Host_RendererHasFocus() || Host_TASInputHasFocus()) && !Host_UIBlocksControllerState());
// Ignore full focus if we don't require basic focus
(Host_RendererHasFocus() || Host_TASInputHasFocus()) && !Host_UIBlocksControllerState();
const bool full_focus_passes =
!require_focus || !require_full_focus || (focus_passes && Host_RendererHasFullFocus());
!require_full_focus || (focus_passes && Host_RendererHasFullFocus());
ControlReference::SetInputGate(focus_passes && full_focus_passes);
}

Expand Down
7 changes: 6 additions & 1 deletion Source/Core/Core/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
struct BootParameters;
struct WindowSystemInfo;

namespace Config
{
enum class InputFocusPolicy;
}

namespace Core
{
class System;
Expand Down Expand Up @@ -191,7 +196,7 @@ void HostDispatchJobs(Core::System& system);

void DoFrameStep(Core::System& system);

void UpdateInputGate(bool require_focus, bool require_full_focus = false);
void UpdateInputGate(Config::InputFocusPolicy input_focus_policy, bool require_full_focus = false);

void UpdateTitle(Core::System& system);

Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/FreeLookManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ void FreeLookController::UpdateInput(CameraControllerInput* camera_controller)
const auto old_gate = ControlReference::GetInputGate();
Common::ScopeGuard gate_guard{[old_gate] { ControlReference::SetInputGate(old_gate); }};
// Switch to the free look focus gate
Core::UpdateInputGate(!Config::Get(Config::FREE_LOOK_BACKGROUND_INPUT));
Core::UpdateInputGate(Config::Get(Config::FREE_LOOK_FOCUS_POLICY));

float dt = 1.0;
if (m_last_free_look_rotate_time)
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/HW/VideoInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,7 @@ void VideoInterfaceManager::Update(u64 ticks)
// This is a nice place to measure performance so we don't have to Throttle elsewhere.
g_perf_metrics.CountPerformanceMarker(ticks, m_system.GetSystemTimers().GetTicksPerSecond());

Core::UpdateInputGate(!Config::Get(Config::MAIN_INPUT_BACKGROUND_INPUT),
Core::UpdateInputGate(Config::Get(Config::MAIN_CONTROLLER_FOCUS_POLICY),
Config::Get(Config::MAIN_LOCK_CURSOR));
auto& si = m_system.GetSerialInterface();
si.UpdateDevices();
Expand Down
1 change: 1 addition & 0 deletions Source/Core/Core/Host.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ bool Host_RendererHasFocus();
bool Host_RendererHasFullFocus();
bool Host_RendererIsFullscreen();
bool Host_TASInputHasFocus();
bool Host_DolphinIsActiveApplication();

void Host_Message(HostMessageID id);
void Host_PPCSymbolsChanged();
Expand Down
13 changes: 0 additions & 13 deletions Source/Core/Core/HotkeyManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,6 @@ namespace HotkeyManagerEmu
{
static std::array<u32, NUM_HOTKEY_GROUPS> s_hotkey_down;
static HotkeyStatus s_hotkey;
static bool s_enabled;

static InputConfig s_config("Hotkeys", _trans("Hotkeys"), "Hotkeys", "Hotkeys");

Expand All @@ -224,16 +223,6 @@ void GetStatus(bool ignore_focus)
static_cast<HotkeyManager*>(s_config.GetController(0))->GetInput(&s_hotkey, ignore_focus);
}

bool IsEnabled()
{
return s_enabled;
}

void Enable(bool enable_toggle)
{
s_enabled = enable_toggle;
}

bool IsPressed(int id, bool held)
{
unsigned int group = static_cast<HotkeyManager*>(s_config.GetController(0))->FindGroupByID(id);
Expand Down Expand Up @@ -302,8 +291,6 @@ void Initialize()
LoadConfig();

s_hotkey_down = {};

s_enabled = true;
}

void LoadConfig()
Expand Down
2 changes: 0 additions & 2 deletions Source/Core/Core/HotkeyManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,5 @@ void LoadConfig();
InputConfig* GetConfig();
ControllerEmu::ControlGroup* GetHotkeyGroup(HotkeyGroup group);
void GetStatus(bool ignore_focus);
bool IsEnabled();
void Enable(bool enable_toggle);
bool IsPressed(int Id, bool held);
} // namespace HotkeyManagerEmu
35 changes: 35 additions & 0 deletions Source/Core/Core/InputSuppressor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2025 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "Core/InputSuppressor.h"

#include <atomic>

namespace
{
static std::atomic_int s_suppression_count = 0;
} // namespace

InputSuppressor::InputSuppressor()
{
AddSuppression();
}
InputSuppressor::~InputSuppressor()
{
RemoveSuppression();
}

bool InputSuppressor::IsSuppressed()
{
return s_suppression_count.load(std::memory_order_relaxed) > 0;
}

void InputSuppressor::AddSuppression()
{
s_suppression_count.fetch_add(1, std::memory_order_relaxed);
}

void InputSuppressor::RemoveSuppression()
{
s_suppression_count.fetch_sub(1, std::memory_order_relaxed);
}
20 changes: 20 additions & 0 deletions Source/Core/Core/InputSuppressor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2025 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

class InputSuppressor final
{
public:
InputSuppressor();
~InputSuppressor();

InputSuppressor(const InputSuppressor&) = delete;
InputSuppressor(InputSuppressor&&) = delete;
InputSuppressor& operator=(const InputSuppressor&) = delete;
InputSuppressor& operator=(InputSuppressor&&) = delete;

static bool IsSuppressed();
static void AddSuppression();
static void RemoveSuppression();
};
3 changes: 3 additions & 0 deletions Source/Core/DolphinLib.props
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@
<ClInclude Include="Core\Config\DefaultLocale.h" />
<ClInclude Include="Core\Config\FreeLookSettings.h" />
<ClInclude Include="Core\Config\GraphicsSettings.h" />
<ClInclude Include="Core\Config\InputFocus.h" />
<ClInclude Include="Core\Config\MainSettings.h" />
<ClInclude Include="Core\Config\NetplaySettings.h" />
<ClInclude Include="Core\Config\SessionSettings.h" />
Expand Down Expand Up @@ -365,6 +366,7 @@
<ClInclude Include="Core\HW\WiimoteReal\WiimoteReal.h" />
<ClInclude Include="Core\HW\WiiSave.h" />
<ClInclude Include="Core\HW\WiiSaveStructs.h" />
<ClInclude Include="Core\InputSuppressor.h" />
<ClInclude Include="Core\IOS\Crypto\Sha.h" />
<ClInclude Include="Core\IOS\Crypto\AesDevice.h" />
<ClInclude Include="Core\IOS\Device.h" />
Expand Down Expand Up @@ -1041,6 +1043,7 @@
<ClCompile Include="Core\HW\WiimoteReal\IOWin.cpp" />
<ClCompile Include="Core\HW\WiimoteReal\WiimoteReal.cpp" />
<ClCompile Include="Core\HW\WiiSave.cpp" />
<ClCompile Include="Core\InputSuppressor.cpp" />
<ClCompile Include="Core\IOS\Crypto\Sha.cpp" />
<ClCompile Include="Core\IOS\Crypto\AesDevice.cpp" />
<ClCompile Include="Core\IOS\Device.cpp" />
Expand Down
5 changes: 5 additions & 0 deletions Source/Core/DolphinNoGUI/MainNoGUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ bool Host_TASInputHasFocus()
return false;
}

bool Host_DolphinIsActiveApplication()
{
return s_platform->IsDolphinActive();
}

void Host_YieldToUI()
{
}
Expand Down
Loading