inputCommon: Mouse fixes

master
german77 2021-02-23 20:39:02 +07:00 committed by german
parent bfa1644464
commit 4738e14cb0
9 changed files with 89 additions and 25 deletions

@ -59,7 +59,7 @@ void Mouse::UpdateYuzuSettings() {
}); });
} }
void Mouse::PressButton(int x, int y, int button_) { void Mouse::PressButton(int x, int y, MouseButton button_) {
const auto button_index = static_cast<std::size_t>(button_); const auto button_index = static_cast<std::size_t>(button_);
if (button_index >= mouse_info.size()) { if (button_index >= mouse_info.size()) {
return; return;
@ -67,7 +67,7 @@ void Mouse::PressButton(int x, int y, int button_) {
const auto button = 1U << button_index; const auto button = 1U << button_index;
buttons |= static_cast<u16>(button); buttons |= static_cast<u16>(button);
last_button = static_cast<MouseButton>(button_index); last_button = button_;
mouse_info[button_index].mouse_origin = Common::MakeVec(x, y); mouse_info[button_index].mouse_origin = Common::MakeVec(x, y);
mouse_info[button_index].last_mouse_position = Common::MakeVec(x, y); mouse_info[button_index].last_mouse_position = Common::MakeVec(x, y);
@ -129,7 +129,7 @@ void Mouse::MouseMove(int x, int y, int center_x, int center_y) {
} }
} }
void Mouse::ReleaseButton(int button_) { void Mouse::ReleaseButton(MouseButton button_) {
const auto button_index = static_cast<std::size_t>(button_); const auto button_index = static_cast<std::size_t>(button_);
if (button_index >= mouse_info.size()) { if (button_index >= mouse_info.size()) {
return; return;
@ -152,6 +152,11 @@ void Mouse::BeginConfiguration() {
void Mouse::EndConfiguration() { void Mouse::EndConfiguration() {
buttons = 0; buttons = 0;
for (MouseInfo& info : mouse_info) {
info.tilt_speed = 0;
info.data.pressed = false;
info.data.axis = {0, 0};
}
last_button = MouseButton::Undefined; last_button = MouseButton::Undefined;
mouse_queue.Clear(); mouse_queue.Clear();
configuring = false; configuring = false;

@ -18,10 +18,12 @@ namespace MouseInput {
enum class MouseButton { enum class MouseButton {
Left, Left,
Wheel,
Right, Right,
Forward, Wheel,
Backward, Backward,
Forward,
Task,
Extra,
Undefined, Undefined,
}; };
@ -51,7 +53,7 @@ public:
* @param y the y-coordinate of the cursor * @param y the y-coordinate of the cursor
* @param button_ the button pressed * @param button_ the button pressed
*/ */
void PressButton(int x, int y, int button_); void PressButton(int x, int y, MouseButton button_);
/** /**
* Signals that mouse has moved. * Signals that mouse has moved.
@ -65,7 +67,7 @@ public:
/** /**
* Signals that a motion sensor tilt has ended. * Signals that a motion sensor tilt has ended.
*/ */
void ReleaseButton(int button_); void ReleaseButton(MouseButton button_);
[[nodiscard]] Common::SPSCQueue<MouseStatus>& GetMouseQueue(); [[nodiscard]] Common::SPSCQueue<MouseStatus>& GetMouseQueue();
[[nodiscard]] const Common::SPSCQueue<MouseStatus>& GetMouseQueue() const; [[nodiscard]] const Common::SPSCQueue<MouseStatus>& GetMouseQueue() const;
@ -94,7 +96,7 @@ private:
u16 buttons{}; u16 buttons{};
std::thread update_thread; std::thread update_thread;
MouseButton last_button{MouseButton::Undefined}; MouseButton last_button{MouseButton::Undefined};
std::array<MouseInfo, 5> mouse_info; std::array<MouseInfo, 7> mouse_info;
Common::SPSCQueue<MouseStatus> mouse_queue; Common::SPSCQueue<MouseStatus> mouse_queue;
bool configuring{false}; bool configuring{false};
bool update_thread_running{true}; bool update_thread_running{true};

@ -383,6 +383,25 @@ void GRenderWindow::keyReleaseEvent(QKeyEvent* event) {
input_subsystem->GetKeyboard()->ReleaseKey(event->key()); input_subsystem->GetKeyboard()->ReleaseKey(event->key());
} }
MouseInput::MouseButton GRenderWindow::QtButtonToMouseButton(Qt::MouseButton button) {
switch (button) {
case Qt::LeftButton:
return MouseInput::MouseButton::Left;
case Qt::RightButton:
return MouseInput::MouseButton::Right;
case Qt::MiddleButton:
return MouseInput::MouseButton::Wheel;
case Qt::BackButton:
return MouseInput::MouseButton::Backward;
case Qt::ForwardButton:
return MouseInput::MouseButton::Forward;
case Qt::TaskButton:
return MouseInput::MouseButton::Task;
default:
return MouseInput::MouseButton::Extra;
}
}
void GRenderWindow::mousePressEvent(QMouseEvent* event) { void GRenderWindow::mousePressEvent(QMouseEvent* event) {
// Touch input is handled in TouchBeginEvent // Touch input is handled in TouchBeginEvent
if (event->source() == Qt::MouseEventSynthesizedBySystem) { if (event->source() == Qt::MouseEventSynthesizedBySystem) {
@ -391,7 +410,8 @@ void GRenderWindow::mousePressEvent(QMouseEvent* event) {
auto pos = event->pos(); auto pos = event->pos();
const auto [x, y] = ScaleTouch(pos); const auto [x, y] = ScaleTouch(pos);
input_subsystem->GetMouse()->PressButton(x, y, event->button()); const auto button = QtButtonToMouseButton(event->button());
input_subsystem->GetMouse()->PressButton(x, y, button);
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
this->TouchPressed(x, y, 0); this->TouchPressed(x, y, 0);
@ -425,7 +445,8 @@ void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) {
return; return;
} }
input_subsystem->GetMouse()->ReleaseButton(event->button()); const auto button = QtButtonToMouseButton(event->button());
input_subsystem->GetMouse()->ReleaseButton(button);
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
this->TouchReleased(0); this->TouchReleased(0);

@ -28,6 +28,10 @@ namespace InputCommon {
class InputSubsystem; class InputSubsystem;
} }
namespace MouseInput {
enum class MouseButton;
}
namespace VideoCore { namespace VideoCore {
enum class LoadCallbackStage; enum class LoadCallbackStage;
} }
@ -149,6 +153,9 @@ public:
void keyPressEvent(QKeyEvent* event) override; void keyPressEvent(QKeyEvent* event) override;
void keyReleaseEvent(QKeyEvent* event) override; void keyReleaseEvent(QKeyEvent* event) override;
/// Converts a Qt mouse button into MouseInput mouse button
static MouseInput::MouseButton QtButtonToMouseButton(Qt::MouseButton button);
void mousePressEvent(QMouseEvent* event) override; void mousePressEvent(QMouseEvent* event) override;
void mouseMoveEvent(QMouseEvent* event) override; void mouseMoveEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override;

@ -235,7 +235,7 @@ const std::array<UISettings::Shortcut, 17> Config::default_hotkeys{{
{QStringLiteral("Restart Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F6"), Qt::WindowShortcut}}, {QStringLiteral("Restart Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F6"), Qt::WindowShortcut}},
{QStringLiteral("Stop Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F5"), Qt::WindowShortcut}}, {QStringLiteral("Stop Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F5"), Qt::WindowShortcut}},
{QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}}, {QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}},
{QStringLiteral("Toggle Mouse Panning"), QStringLiteral("Main Window"), {QStringLiteral("F9"), Qt::ApplicationShortcut}}, {QStringLiteral("Toggle Mouse Panning"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F9"), Qt::ApplicationShortcut}},
{QStringLiteral("Toggle Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Z"), Qt::ApplicationShortcut}}, {QStringLiteral("Toggle Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Z"), Qt::ApplicationShortcut}},
{QStringLiteral("Toggle Status Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+S"), Qt::WindowShortcut}}, {QStringLiteral("Toggle Status Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+S"), Qt::WindowShortcut}},
}}; }};
@ -508,7 +508,7 @@ void Config::ReadControlValues() {
Settings::values.emulate_analog_keyboard = Settings::values.emulate_analog_keyboard =
ReadSetting(QStringLiteral("emulate_analog_keyboard"), false).toBool(); ReadSetting(QStringLiteral("emulate_analog_keyboard"), false).toBool();
Settings::values.mouse_panning = ReadSetting(QStringLiteral("mouse_panning"), false).toBool(); Settings::values.mouse_panning = false;
Settings::values.mouse_panning_sensitivity = Settings::values.mouse_panning_sensitivity =
ReadSetting(QStringLiteral("mouse_panning_sensitivity"), 1).toFloat(); ReadSetting(QStringLiteral("mouse_panning_sensitivity"), 1).toFloat();
@ -1182,7 +1182,6 @@ void Config::SaveControlValues() {
WriteSetting(QStringLiteral("keyboard_enabled"), Settings::values.keyboard_enabled, false); WriteSetting(QStringLiteral("keyboard_enabled"), Settings::values.keyboard_enabled, false);
WriteSetting(QStringLiteral("emulate_analog_keyboard"), WriteSetting(QStringLiteral("emulate_analog_keyboard"),
Settings::values.emulate_analog_keyboard, false); Settings::values.emulate_analog_keyboard, false);
WriteSetting(QStringLiteral("mouse_panning"), Settings::values.mouse_panning, false);
WriteSetting(QStringLiteral("mouse_panning_sensitivity"), WriteSetting(QStringLiteral("mouse_panning_sensitivity"),
Settings::values.mouse_panning_sensitivity, 1.0f); Settings::values.mouse_panning_sensitivity, 1.0f);
qt_config->endGroup(); qt_config->endGroup();

@ -21,6 +21,7 @@
#include "input_common/mouse/mouse_poller.h" #include "input_common/mouse/mouse_poller.h"
#include "input_common/udp/udp.h" #include "input_common/udp/udp.h"
#include "ui_configure_input_player.h" #include "ui_configure_input_player.h"
#include "yuzu/bootmanager.h"
#include "yuzu/configuration/config.h" #include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_input_player.h" #include "yuzu/configuration/configure_input_player.h"
#include "yuzu/configuration/configure_input_player_widget.h" #include "yuzu/configuration/configure_input_player_widget.h"
@ -1345,7 +1346,8 @@ void ConfigureInputPlayer::mousePressEvent(QMouseEvent* event) {
return; return;
} }
input_subsystem->GetMouse()->PressButton(0, 0, event->button()); const auto button = GRenderWindow::QtButtonToMouseButton(event->button());
input_subsystem->GetMouse()->PressButton(0, 0, button);
} }
void ConfigureInputPlayer::keyPressEvent(QKeyEvent* event) { void ConfigureInputPlayer::keyPressEvent(QKeyEvent* event) {

@ -854,8 +854,7 @@ void GMainWindow::InitializeHotkeys() {
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Mouse Panning"), this), connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Mouse Panning"), this),
&QShortcut::activated, this, [&] { &QShortcut::activated, this, [&] {
Settings::values.mouse_panning = !Settings::values.mouse_panning; Settings::values.mouse_panning = !Settings::values.mouse_panning;
if (UISettings::values.hide_mouse || Settings::values.mouse_panning) { if (Settings::values.mouse_panning) {
mouse_hide_timer.start();
render_window->installEventFilter(render_window); render_window->installEventFilter(render_window);
render_window->setAttribute(Qt::WA_Hover, true); render_window->setAttribute(Qt::WA_Hover, true);
} }
@ -1208,11 +1207,14 @@ void GMainWindow::BootGame(const QString& filename, std::size_t program_index) {
renderer_status_button->setDisabled(true); renderer_status_button->setDisabled(true);
if (UISettings::values.hide_mouse || Settings::values.mouse_panning) { if (UISettings::values.hide_mouse || Settings::values.mouse_panning) {
mouse_hide_timer.start();
render_window->installEventFilter(render_window); render_window->installEventFilter(render_window);
render_window->setAttribute(Qt::WA_Hover, true); render_window->setAttribute(Qt::WA_Hover, true);
} }
if (UISettings::values.hide_mouse) {
mouse_hide_timer.start();
}
std::string title_name; std::string title_name;
std::string title_version; std::string title_version;
const auto res = system.GetGameName(title_name); const auto res = system.GetGameName(title_name);
@ -2372,12 +2374,15 @@ void GMainWindow::OnConfigure() {
if ((UISettings::values.hide_mouse || Settings::values.mouse_panning) && emulation_running) { if ((UISettings::values.hide_mouse || Settings::values.mouse_panning) && emulation_running) {
render_window->installEventFilter(render_window); render_window->installEventFilter(render_window);
render_window->setAttribute(Qt::WA_Hover, true); render_window->setAttribute(Qt::WA_Hover, true);
mouse_hide_timer.start();
} else { } else {
render_window->removeEventFilter(render_window); render_window->removeEventFilter(render_window);
render_window->setAttribute(Qt::WA_Hover, false); render_window->setAttribute(Qt::WA_Hover, false);
} }
if (UISettings::values.hide_mouse) {
mouse_hide_timer.start();
}
UpdateStatusButtons(); UpdateStatusButtons();
} }
@ -2615,8 +2620,7 @@ void GMainWindow::UpdateUISettings() {
} }
void GMainWindow::HideMouseCursor() { void GMainWindow::HideMouseCursor() {
if (emu_thread == nullptr || if (emu_thread == nullptr && UISettings::values.hide_mouse) {
(!UISettings::values.hide_mouse && !Settings::values.mouse_panning)) {
mouse_hide_timer.stop(); mouse_hide_timer.stop();
ShowMouseCursor(); ShowMouseCursor();
return; return;
@ -2626,8 +2630,7 @@ void GMainWindow::HideMouseCursor() {
void GMainWindow::ShowMouseCursor() { void GMainWindow::ShowMouseCursor() {
render_window->unsetCursor(); render_window->unsetCursor();
if (emu_thread != nullptr && if (emu_thread != nullptr && UISettings::values.hide_mouse) {
(UISettings::values.hide_mouse || Settings::values.mouse_panning)) {
mouse_hide_timer.start(); mouse_hide_timer.start();
} }
} }

@ -35,18 +35,36 @@ void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
input_subsystem->GetMouse()->MouseMove(x, y, 0, 0); input_subsystem->GetMouse()->MouseMove(x, y, 0, 0);
} }
MouseInput::MouseButton EmuWindow_SDL2::SDLButtonToMouseButton(u32 button) const {
switch (button) {
case SDL_BUTTON_LEFT:
return MouseInput::MouseButton::Left;
case SDL_BUTTON_RIGHT:
return MouseInput::MouseButton::Right;
case SDL_BUTTON_MIDDLE:
return MouseInput::MouseButton::Wheel;
case SDL_BUTTON_X1:
return MouseInput::MouseButton::Backward;
case SDL_BUTTON_X2:
return MouseInput::MouseButton::Forward;
default:
return MouseInput::MouseButton::Undefined;
}
}
void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) { void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
const auto mouse_button = SDLButtonToMouseButton(button);
if (button == SDL_BUTTON_LEFT) { if (button == SDL_BUTTON_LEFT) {
if (state == SDL_PRESSED) { if (state == SDL_PRESSED) {
TouchPressed((unsigned)std::max(x, 0), (unsigned)std::max(y, 0), 0); TouchPressed((unsigned)std::max(x, 0), (unsigned)std::max(y, 0), 0);
} else { } else {
TouchReleased(0); TouchReleased(0);
} }
} else if (button == SDL_BUTTON_RIGHT) {
if (state == SDL_PRESSED) {
input_subsystem->GetMouse()->PressButton(x, y, button);
} else { } else {
input_subsystem->GetMouse()->ReleaseButton(button); if (state == SDL_PRESSED) {
input_subsystem->GetMouse()->PressButton(x, y, mouse_button);
} else {
input_subsystem->GetMouse()->ReleaseButton(mouse_button);
} }
} }
} }

@ -18,6 +18,10 @@ namespace InputCommon {
class InputSubsystem; class InputSubsystem;
} }
namespace MouseInput {
enum class MouseButton;
}
class EmuWindow_SDL2 : public Core::Frontend::EmuWindow { class EmuWindow_SDL2 : public Core::Frontend::EmuWindow {
public: public:
explicit EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem); explicit EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem);
@ -42,6 +46,9 @@ protected:
/// Called by WaitEvent when the mouse moves. /// Called by WaitEvent when the mouse moves.
void OnMouseMotion(s32 x, s32 y); void OnMouseMotion(s32 x, s32 y);
/// Converts a SDL mouse button into MouseInput mouse button
MouseInput::MouseButton SDLButtonToMouseButton(u32 button) const;
/// Called by WaitEvent when a mouse button is pressed or released /// Called by WaitEvent when a mouse button is pressed or released
void OnMouseButton(u32 button, u8 state, s32 x, s32 y); void OnMouseButton(u32 button, u8 state, s32 x, s32 y);