mirror of
https://github.com/Vita3K/Vita3K.git
synced 2026-07-11 01:34:23 +02:00
overlay: fix input related bugs
This commit is contained in:
@@ -577,6 +577,7 @@ void apply_renderer_config(EmuEnvState &emuenv) {
|
||||
r.common_dialog = &emuenv.common_dialog;
|
||||
r.sys_date_format = cc.sys_date_format;
|
||||
r.sys_lang = cc.sys_lang;
|
||||
r.sys_button = cc.sys_button;
|
||||
|
||||
r.show_compile_shaders = emuenv.cfg.show_compile_shaders;
|
||||
app::sync_perf_overlay_config(emuenv);
|
||||
@@ -592,8 +593,6 @@ void apply_renderer_config(EmuEnvState &emuenv) {
|
||||
ctrl.overlay_input_intercepted.store(true, std::memory_order_relaxed);
|
||||
} else {
|
||||
ctrl.overlay_input_intercepted.store(false, std::memory_order_relaxed);
|
||||
std::lock_guard<std::mutex> lock(ctrl.mutex);
|
||||
ctrl.ignore_input = true;
|
||||
}
|
||||
},
|
||||
[&emuenv]() -> overlay::overlay_touch_state {
|
||||
@@ -662,6 +661,7 @@ void apply_runtime_settings(EmuEnvState &emuenv) {
|
||||
emuenv.display.fps_hack = cc.fps_hack;
|
||||
r.sys_date_format = cc.sys_date_format;
|
||||
r.sys_lang = cc.sys_lang;
|
||||
r.sys_button = cc.sys_button;
|
||||
r.show_compile_shaders = emuenv.cfg.show_compile_shaders;
|
||||
app::sync_perf_overlay_config(emuenv);
|
||||
}
|
||||
|
||||
@@ -248,10 +248,6 @@ void AppSessionController::apply_runtime_state_locked() {
|
||||
|
||||
const bool overlay_intercepted = paused || input_intercepted;
|
||||
emuenv.ctrl.overlay_input_intercepted.store(overlay_intercepted, std::memory_order_relaxed);
|
||||
if (overlay_intercepted || currently_paused != paused) {
|
||||
std::lock_guard<std::mutex> ctrl_lock(emuenv.ctrl.mutex);
|
||||
emuenv.ctrl.ignore_input = true;
|
||||
}
|
||||
|
||||
emuenv.renderer->paused.store(paused, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,6 @@ struct CtrlState {
|
||||
VirtualKeyboardState keyboard_state;
|
||||
|
||||
std::atomic<bool> overlay_input_intercepted{ false };
|
||||
bool ignore_input = false;
|
||||
|
||||
struct OverlayMouseState {
|
||||
std::atomic<float> x{ 0.f };
|
||||
@@ -95,7 +94,6 @@ struct CtrlState {
|
||||
std::fill_n(last_vcount, 5, 0);
|
||||
keyboard_state = {};
|
||||
overlay_input_intercepted.store(false, std::memory_order_relaxed);
|
||||
ignore_input = false;
|
||||
overlay_mouse.x.store(0.f, std::memory_order_relaxed);
|
||||
overlay_mouse.y.store(0.f, std::memory_order_relaxed);
|
||||
overlay_mouse.pressed.store(false, std::memory_order_relaxed);
|
||||
|
||||
@@ -278,18 +278,6 @@ static void retrieve_ctrl_data(EmuEnvState &emuenv, int port, bool is_v2, bool n
|
||||
}
|
||||
}
|
||||
|
||||
if (state.ignore_input) {
|
||||
constexpr uint32_t face_mask = SCE_CTRL_CROSS | SCE_CTRL_CIRCLE | SCE_CTRL_TRIANGLE
|
||||
| SCE_CTRL_SQUARE | SCE_CTRL_START | SCE_CTRL_SELECT;
|
||||
if (buttons & face_mask) {
|
||||
buttons = 0;
|
||||
axes.fill(0);
|
||||
reset_axes();
|
||||
return;
|
||||
}
|
||||
state.ignore_input = false;
|
||||
}
|
||||
|
||||
reset_axes();
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,20 @@
|
||||
#include <util/tracy.h>
|
||||
TRACY_MODULE_NAME(SceCommonDialog);
|
||||
|
||||
namespace {
|
||||
void complete_trophy_setup_dialog(DialogState &dialog) {
|
||||
std::lock_guard<std::recursive_mutex> lock(dialog.mutex);
|
||||
if (dialog.type != TROPHY_SETUP_DIALOG || dialog.status != SCE_COMMON_DIALOG_STATUS_RUNNING)
|
||||
return;
|
||||
|
||||
if (SDL_GetTicks() < dialog.trophy.tick)
|
||||
return;
|
||||
|
||||
dialog.status = SCE_COMMON_DIALOG_STATUS_FINISHED;
|
||||
dialog.result = SCE_COMMON_DIALOG_RESULT_OK;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
template <>
|
||||
std::string to_debug_str<SceMsgDialogProgressBarTarget>(const MemState &mem, SceMsgDialogProgressBarTarget type) {
|
||||
switch (type) {
|
||||
@@ -740,6 +754,7 @@ EXPORT(int, sceNpTrophySetupDialogAbort) {
|
||||
|
||||
EXPORT(int, sceNpTrophySetupDialogGetResult, Ptr<SceNpTrophySetupDialogResult> result) {
|
||||
TRACY_FUNC(sceNpTrophySetupDialogGetResult, result);
|
||||
complete_trophy_setup_dialog(emuenv.common_dialog);
|
||||
if (emuenv.common_dialog.type != TROPHY_SETUP_DIALOG || emuenv.common_dialog.status != SCE_COMMON_DIALOG_STATUS_FINISHED)
|
||||
return RET_ERROR(SCE_COMMON_DIALOG_ERROR_NOT_FINISHED);
|
||||
|
||||
@@ -749,6 +764,7 @@ EXPORT(int, sceNpTrophySetupDialogGetResult, Ptr<SceNpTrophySetupDialogResult> r
|
||||
|
||||
EXPORT(int, sceNpTrophySetupDialogGetStatus) {
|
||||
TRACY_FUNC(sceNpTrophySetupDialogGetStatus);
|
||||
complete_trophy_setup_dialog(emuenv.common_dialog);
|
||||
return emuenv.common_dialog.status;
|
||||
}
|
||||
|
||||
@@ -765,6 +781,7 @@ EXPORT(int, sceNpTrophySetupDialogInit, const Ptr<SceNpTrophySetupDialogParam> p
|
||||
|
||||
EXPORT(int, sceNpTrophySetupDialogTerm) {
|
||||
TRACY_FUNC(sceNpTrophySetupDialogTerm);
|
||||
complete_trophy_setup_dialog(emuenv.common_dialog);
|
||||
if (emuenv.common_dialog.type != TROPHY_SETUP_DIALOG)
|
||||
return RET_ERROR(SCE_COMMON_DIALOG_ERROR_NOT_IN_USE);
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
void on_button_pressed(pad_button button_press, bool is_auto_repeat) override;
|
||||
void on_touch_pressed(float vx, float vy) override;
|
||||
|
||||
bool poll_dialog(DialogState &dialog, int date_format);
|
||||
bool poll_dialog(DialogState &dialog, int date_format, int sys_button);
|
||||
|
||||
private:
|
||||
int m_active_type = 0;
|
||||
@@ -169,6 +169,10 @@ private:
|
||||
|
||||
DialogState *m_dialog = nullptr;
|
||||
int m_date_format = 0;
|
||||
int m_sys_button = 0;
|
||||
|
||||
bool is_confirm_button(pad_button button) const;
|
||||
bool is_cancel_button(pad_button button) const;
|
||||
|
||||
static constexpr uint16_t k_vw = 960;
|
||||
static constexpr uint16_t k_vh = 544;
|
||||
|
||||
@@ -88,6 +88,7 @@ public:
|
||||
m_stop_input_loop.store(false);
|
||||
m_stop_pad_interception.store(false);
|
||||
}
|
||||
void stop_input_processing(bool stop_pad_interception);
|
||||
|
||||
compiled_resource get_compiled() override = 0;
|
||||
|
||||
|
||||
@@ -173,9 +173,10 @@ std::string common_dialog_overlay::format_date_time(int date_format, const void
|
||||
return date_str + fmt::format(" {}:{:02d}", dt->hour, dt->minute);
|
||||
}
|
||||
|
||||
bool common_dialog_overlay::poll_dialog(DialogState &dialog, int date_format) {
|
||||
bool common_dialog_overlay::poll_dialog(DialogState &dialog, int date_format, int sys_button) {
|
||||
m_dialog = &dialog;
|
||||
m_date_format = date_format;
|
||||
m_sys_button = sys_button;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lock(dialog.mutex);
|
||||
|
||||
@@ -415,6 +416,18 @@ bool common_dialog_overlay::poll_dialog(DialogState &dialog, int date_format) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool common_dialog_overlay::is_confirm_button(pad_button button) const {
|
||||
if (m_sys_button == SCE_SYSTEM_PARAM_ENTER_BUTTON_CIRCLE)
|
||||
return button == pad_button::circle;
|
||||
return button == pad_button::cross;
|
||||
}
|
||||
|
||||
bool common_dialog_overlay::is_cancel_button(pad_button button) const {
|
||||
if (m_sys_button == SCE_SYSTEM_PARAM_ENTER_BUTTON_CIRCLE)
|
||||
return button == pad_button::cross;
|
||||
return button == pad_button::circle;
|
||||
}
|
||||
|
||||
void common_dialog_overlay::update(uint64_t timestamp_us) {
|
||||
if (m_fade_anim.active)
|
||||
m_fade_anim.update(timestamp_us);
|
||||
@@ -1519,6 +1532,27 @@ void common_dialog_overlay::handle_message_input(pad_button btn, DialogState &di
|
||||
if (m_buttons.empty())
|
||||
return;
|
||||
|
||||
if (is_confirm_button(btn)) {
|
||||
const auto &selected = m_buttons[m_selected_button];
|
||||
dialog.msg.status = selected.value;
|
||||
dialog.result = SCE_COMMON_DIALOG_RESULT_OK;
|
||||
dialog.status = SCE_COMMON_DIALOG_STATUS_FINISHED;
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_cancel_button(btn)) {
|
||||
if (m_buttons.size() > 1) {
|
||||
dialog.msg.status = m_buttons.back().value;
|
||||
dialog.result = SCE_COMMON_DIALOG_RESULT_OK;
|
||||
dialog.status = SCE_COMMON_DIALOG_STATUS_FINISHED;
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (btn) {
|
||||
case pad_button::dpad_left:
|
||||
case pad_button::ls_left:
|
||||
@@ -1530,30 +1564,45 @@ void common_dialog_overlay::handle_message_input(pad_button btn, DialogState &di
|
||||
if (m_selected_button < static_cast<int>(m_buttons.size()) - 1)
|
||||
m_selected_button++;
|
||||
break;
|
||||
case pad_button::cross: {
|
||||
const auto &selected = m_buttons[m_selected_button];
|
||||
dialog.msg.status = selected.value;
|
||||
dialog.result = SCE_COMMON_DIALOG_RESULT_OK;
|
||||
dialog.status = SCE_COMMON_DIALOG_STATUS_FINISHED;
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
break;
|
||||
}
|
||||
case pad_button::circle:
|
||||
if (m_buttons.size() > 1) {
|
||||
dialog.msg.status = m_buttons.back().value;
|
||||
dialog.result = SCE_COMMON_DIALOG_RESULT_OK;
|
||||
dialog.status = SCE_COMMON_DIALOG_STATUS_FINISHED;
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void common_dialog_overlay::handle_savedata_list_input(pad_button btn, DialogState &dialog) {
|
||||
if (is_confirm_button(btn)) {
|
||||
if (m_cancel_btn_focused) {
|
||||
dialog.savedata.button_id = SCE_SAVEDATA_DIALOG_BUTTON_ID_INVALID;
|
||||
dialog.savedata.draw_info_window = false;
|
||||
dialog.result = SCE_COMMON_DIALOG_RESULT_USER_CANCELED;
|
||||
dialog.substatus = SCE_COMMON_DIALOG_STATUS_FINISHED;
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_save_slots.empty()) {
|
||||
const uint32_t slot_index = m_save_slots[m_selected_slot]->slot_index;
|
||||
dialog.savedata.selected_save = slot_index;
|
||||
dialog.result = SCE_COMMON_DIALOG_RESULT_OK;
|
||||
dialog.substatus = SCE_COMMON_DIALOG_STATUS_FINISHED;
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
dialog.savedata.mode_to_display = SCE_SAVEDATA_DIALOG_MODE_FIXED;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_cancel_button(btn)) {
|
||||
dialog.savedata.button_id = SCE_SAVEDATA_DIALOG_BUTTON_ID_INVALID;
|
||||
dialog.savedata.draw_info_window = false;
|
||||
dialog.result = SCE_COMMON_DIALOG_RESULT_USER_CANCELED;
|
||||
dialog.substatus = SCE_COMMON_DIALOG_STATUS_FINISHED;
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (btn) {
|
||||
case pad_button::dpad_up:
|
||||
case pad_button::ls_up:
|
||||
@@ -1580,40 +1629,12 @@ void common_dialog_overlay::handle_savedata_list_input(pad_button btn, DialogSta
|
||||
m_scroll_offset = m_selected_slot - k_max_visible_slots + 1;
|
||||
}
|
||||
break;
|
||||
case pad_button::cross:
|
||||
if (m_cancel_btn_focused) {
|
||||
dialog.savedata.button_id = SCE_SAVEDATA_DIALOG_BUTTON_ID_INVALID;
|
||||
dialog.savedata.draw_info_window = false;
|
||||
dialog.result = SCE_COMMON_DIALOG_RESULT_USER_CANCELED;
|
||||
dialog.substatus = SCE_COMMON_DIALOG_STATUS_FINISHED;
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
break;
|
||||
}
|
||||
if (!m_save_slots.empty()) {
|
||||
const uint32_t slot_index = m_save_slots[m_selected_slot]->slot_index;
|
||||
dialog.savedata.selected_save = slot_index;
|
||||
dialog.result = SCE_COMMON_DIALOG_RESULT_OK;
|
||||
dialog.substatus = SCE_COMMON_DIALOG_STATUS_FINISHED;
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
dialog.savedata.mode_to_display = SCE_SAVEDATA_DIALOG_MODE_FIXED;
|
||||
}
|
||||
break;
|
||||
case pad_button::triangle:
|
||||
if (!m_cancel_btn_focused && !m_save_slots.empty() && m_save_slots[m_selected_slot]->has_data) {
|
||||
dialog.savedata.draw_info_window = true;
|
||||
dialog.savedata.selected_save = m_save_slots[m_selected_slot]->slot_index;
|
||||
}
|
||||
break;
|
||||
case pad_button::circle:
|
||||
dialog.savedata.button_id = SCE_SAVEDATA_DIALOG_BUTTON_ID_INVALID;
|
||||
dialog.savedata.draw_info_window = false;
|
||||
dialog.result = SCE_COMMON_DIALOG_RESULT_USER_CANCELED;
|
||||
dialog.substatus = SCE_COMMON_DIALOG_STATUS_FINISHED;
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1623,6 +1644,25 @@ void common_dialog_overlay::handle_savedata_fixed_input(pad_button btn, DialogSt
|
||||
if (m_buttons.empty())
|
||||
return;
|
||||
|
||||
if (is_confirm_button(btn)) {
|
||||
const auto &selected = m_buttons[m_selected_button];
|
||||
dialog.savedata.button_id = selected.value;
|
||||
dialog.result = SCE_COMMON_DIALOG_RESULT_OK;
|
||||
dialog.substatus = SCE_COMMON_DIALOG_STATUS_FINISHED;
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_cancel_button(btn)) {
|
||||
dialog.savedata.button_id = SCE_SAVEDATA_DIALOG_BUTTON_ID_INVALID;
|
||||
dialog.result = SCE_COMMON_DIALOG_RESULT_USER_CANCELED;
|
||||
dialog.substatus = SCE_COMMON_DIALOG_STATUS_FINISHED;
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (btn) {
|
||||
case pad_button::dpad_left:
|
||||
case pad_button::ls_left:
|
||||
@@ -1634,22 +1674,6 @@ void common_dialog_overlay::handle_savedata_fixed_input(pad_button btn, DialogSt
|
||||
if (m_selected_button < static_cast<int>(m_buttons.size()) - 1)
|
||||
m_selected_button++;
|
||||
break;
|
||||
case pad_button::cross: {
|
||||
const auto &selected = m_buttons[m_selected_button];
|
||||
dialog.savedata.button_id = selected.value;
|
||||
dialog.result = SCE_COMMON_DIALOG_RESULT_OK;
|
||||
dialog.substatus = SCE_COMMON_DIALOG_STATUS_FINISHED;
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
break;
|
||||
}
|
||||
case pad_button::circle:
|
||||
dialog.savedata.button_id = SCE_SAVEDATA_DIALOG_BUTTON_ID_INVALID;
|
||||
dialog.result = SCE_COMMON_DIALOG_RESULT_USER_CANCELED;
|
||||
dialog.substatus = SCE_COMMON_DIALOG_STATUS_FINISHED;
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1667,6 +1691,28 @@ void common_dialog_overlay::handle_savedata_info_input(pad_button btn, DialogSta
|
||||
}
|
||||
|
||||
void common_dialog_overlay::handle_ime_input(pad_button btn, DialogState &dialog) {
|
||||
if (is_confirm_button(btn)) {
|
||||
if (m_selected_button == 0) {
|
||||
submit_ime_dialog(dialog);
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
} else {
|
||||
cancel_ime_dialog(dialog);
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_cancel_button(btn)) {
|
||||
if (m_ime_cancelable) {
|
||||
cancel_ime_dialog(dialog);
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (btn) {
|
||||
case pad_button::dpad_left:
|
||||
case pad_button::ls_left:
|
||||
@@ -1678,25 +1724,6 @@ void common_dialog_overlay::handle_ime_input(pad_button btn, DialogState &dialog
|
||||
if (m_selected_button < static_cast<int>(m_buttons.size()) - 1)
|
||||
m_selected_button++;
|
||||
break;
|
||||
case pad_button::cross: {
|
||||
if (m_selected_button == 0) {
|
||||
submit_ime_dialog(dialog);
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
} else {
|
||||
cancel_ime_dialog(dialog);
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case pad_button::circle:
|
||||
if (m_ime_cancelable) {
|
||||
cancel_ime_dialog(dialog);
|
||||
m_stop_input_loop.store(true);
|
||||
m_stop_pad_interception.store(true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1707,6 +1734,8 @@ void common_dialog_overlay::on_touch_pressed(float vx, float vy) {
|
||||
return;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lock(m_dialog->mutex);
|
||||
const auto confirm_button = (m_sys_button == SCE_SYSTEM_PARAM_ENTER_BUTTON_CIRCLE) ? pad_button::circle : pad_button::cross;
|
||||
const auto cancel_button = (m_sys_button == SCE_SYSTEM_PARAM_ENTER_BUTTON_CIRCLE) ? pad_button::cross : pad_button::circle;
|
||||
|
||||
switch (m_active_type) {
|
||||
case MESSAGE_DIALOG:
|
||||
@@ -1716,7 +1745,7 @@ void common_dialog_overlay::on_touch_pressed(float vx, float vy) {
|
||||
if (vx >= btn.bg.x && vx <= btn.bg.x + btn.bg.w
|
||||
&& vy >= btn.bg.y && vy <= btn.bg.y + btn.bg.h) {
|
||||
m_selected_button = static_cast<int>(i);
|
||||
on_button_pressed(pad_button::cross, false);
|
||||
on_button_pressed(confirm_button, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1724,7 +1753,7 @@ void common_dialog_overlay::on_touch_pressed(float vx, float vy) {
|
||||
}
|
||||
case SAVEDATA_DIALOG: {
|
||||
if (m_savedata_info_mode) {
|
||||
on_button_pressed(pad_button::circle, false);
|
||||
on_button_pressed(cancel_button, false);
|
||||
return;
|
||||
}
|
||||
if (m_savedata_list_mode) {
|
||||
@@ -1732,7 +1761,7 @@ void common_dialog_overlay::on_touch_pressed(float vx, float vy) {
|
||||
const uint16_t cancel_w = 46, cancel_h = 46;
|
||||
if (vx >= cancel_x && vx <= cancel_x + cancel_w
|
||||
&& vy >= cancel_y && vy <= cancel_y + cancel_h) {
|
||||
on_button_pressed(pad_button::circle, false);
|
||||
on_button_pressed(cancel_button, false);
|
||||
return;
|
||||
}
|
||||
const int16_t list_start_y = 96;
|
||||
@@ -1759,7 +1788,7 @@ void common_dialog_overlay::on_touch_pressed(float vx, float vy) {
|
||||
|
||||
m_selected_slot = i;
|
||||
m_cancel_btn_focused = false;
|
||||
on_button_pressed(pad_button::cross, false);
|
||||
on_button_pressed(confirm_button, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1769,7 +1798,7 @@ void common_dialog_overlay::on_touch_pressed(float vx, float vy) {
|
||||
if (vx >= btn.bg.x && vx <= btn.bg.x + btn.bg.w
|
||||
&& vy >= btn.bg.y && vy <= btn.bg.y + btn.bg.h) {
|
||||
m_selected_button = static_cast<int>(i);
|
||||
on_button_pressed(pad_button::cross, false);
|
||||
on_button_pressed(confirm_button, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,6 +174,7 @@ void display_manager::on_overlay_removed(const std::shared_ptr<overlay> &item) {
|
||||
return;
|
||||
}
|
||||
|
||||
iface->stop_input_processing(true);
|
||||
iface->detach_input();
|
||||
}
|
||||
|
||||
|
||||
@@ -148,31 +148,35 @@ int32_t user_interface::run_input_loop(overlay_input_handler *input, std::functi
|
||||
input->set_intercepted(false);
|
||||
}
|
||||
|
||||
m_interactive.store(false);
|
||||
m_input_loop_exited.store(true);
|
||||
m_input_loop_exited.notify_all();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void user_interface::close(bool use_callback, bool stop_pad_interception) {
|
||||
void user_interface::stop_input_processing(bool stop_pad_interception) {
|
||||
m_stop_pad_interception.store(stop_pad_interception);
|
||||
m_stop_input_loop.store(true);
|
||||
|
||||
const bool interactive = m_interactive.load();
|
||||
const bool same_thread = interactive && std::this_thread::get_id() == m_input_loop_thread_id;
|
||||
if (interactive && !same_thread) {
|
||||
m_input_loop_exited.wait(false);
|
||||
}
|
||||
|
||||
if (stop_pad_interception && release_intercept && (!same_thread) && !m_interactive.load()) {
|
||||
release_intercept();
|
||||
}
|
||||
}
|
||||
|
||||
void user_interface::close(bool use_callback, bool stop_pad_interception) {
|
||||
stop_input_processing(stop_pad_interception);
|
||||
|
||||
// If the input loop is running on a different thread, wait for it to fully
|
||||
// exit before firing callbacks. When close() is called from within
|
||||
// on_button_pressed (same thread as run_input_loop), the loop will exit
|
||||
// naturally after the callback returns — no wait needed.
|
||||
if (m_interactive.load() && std::this_thread::get_id() != m_input_loop_thread_id) {
|
||||
m_input_loop_exited.wait(false);
|
||||
}
|
||||
|
||||
// Only disable pad interception if this user interface is not interactive.
|
||||
// Interactive user interfaces handle this in run_input_loop in order to
|
||||
// prevent potential mutex issues.
|
||||
if (!m_interactive.load() && m_stop_pad_interception.load() && release_intercept) {
|
||||
release_intercept();
|
||||
}
|
||||
|
||||
if (on_close && use_callback) {
|
||||
on_close(return_code);
|
||||
}
|
||||
|
||||
@@ -183,6 +183,7 @@ struct State {
|
||||
DialogState *common_dialog = nullptr;
|
||||
int sys_date_format = 0;
|
||||
int sys_lang = 0;
|
||||
int sys_button = 0;
|
||||
|
||||
PerformanceOverlayState perf_overlay;
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ void State::update_overlays() {
|
||||
dlg = overlay_manager->create<overlay::common_dialog_overlay>();
|
||||
just_created = true;
|
||||
}
|
||||
if (dlg->poll_dialog(*common_dialog, sys_date_format)
|
||||
if (dlg->poll_dialog(*common_dialog, sys_date_format, sys_button)
|
||||
&& common_dialog->type != TROPHY_SETUP_DIALOG) {
|
||||
if (just_created || dlg->input_loop_exited()) {
|
||||
dlg->reset_input_loop();
|
||||
|
||||
Reference in New Issue
Block a user