diff --git a/app/cli/commandlineparser.cpp b/app/cli/commandlineparser.cpp index 8364eb30..413d7513 100644 --- a/app/cli/commandlineparser.cpp +++ b/app/cli/commandlineparser.cpp @@ -298,6 +298,7 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference parser.addToggleOption("multi-controller", "multiple controller support"); parser.addToggleOption("quit-after", "quit app after session"); parser.addToggleOption("absolute-mouse", "remote desktop optimized mouse control"); + parser.addToggleOption("mouse-buttons-swap", "left and right mouse buttons swap"); parser.addToggleOption("touchscreen-trackpad", "touchscreen in trackpad mode"); parser.addToggleOption("game-optimization", "game optimizations"); parser.addToggleOption("audio-on-host", "audio on host PC"); @@ -389,6 +390,9 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference // Resolve --absolute-mouse and --no-absolute-mouse options preferences->absoluteMouseMode = parser.getToggleOptionValue("absolute-mouse", preferences->absoluteMouseMode); + // Resolve --mouse-buttons-swap and --no-mouse-buttons-swap options + preferences->swapMouseButtons = parser.getToggleOptionValue("mouse-buttons-swap", preferences->swapMouseButtons); + // Resolve --touchscreen-trackpad and --no-touchscreen-trackpad options preferences->absoluteTouchMode = !parser.getToggleOptionValue("touchscreen-trackpad", !preferences->absoluteTouchMode); diff --git a/app/gui/SettingsView.qml b/app/gui/SettingsView.qml index 15a9ff6d..a17e8247 100644 --- a/app/gui/SettingsView.qml +++ b/app/gui/SettingsView.qml @@ -638,6 +638,23 @@ Flickable { ToolTip.visible: hovered ToolTip.text: "When enabled, holding the Start button will toggle mouse mode" } + + CheckBox { + id: swapMouseButtonsCheck + hoverEnabled: true + width: parent.width + text: "Swap mouse buttons" + font.pointSize: 12 + checked: StreamingPreferences.swapMouseButtons + onCheckedChanged: { + StreamingPreferences.swapMouseButtons = checked + } + + ToolTip.delay: 1000 + ToolTip.timeout: 3000 + ToolTip.visible: hovered + ToolTip.text: "When checked, swap the left and right mouse buttons" + } } } diff --git a/app/settings/streamingpreferences.cpp b/app/settings/streamingpreferences.cpp index 81494891..71a76bb3 100644 --- a/app/settings/streamingpreferences.cpp +++ b/app/settings/streamingpreferences.cpp @@ -29,6 +29,7 @@ #define SER_DEFAULTVER "defaultver" #define SER_PACKETSIZE "packetsize" #define SER_DETECTNETBLOCKING "detectnetblocking" +#define SER_SWAPMOUSEBUTTONS "swapmousebuttons" #define CURRENT_DEFAULT_VER 1 @@ -70,6 +71,7 @@ void StreamingPreferences::reload() gamepadMouse = settings.value(SER_GAMEPADMOUSE, true).toBool(); detectNetworkBlocking = settings.value(SER_DETECTNETBLOCKING, true).toBool(); packetSize = settings.value(SER_PACKETSIZE, 0).toInt(); + swapMouseButtons = settings.value(SER_SWAPMOUSEBUTTONS, false).toBool(); audioConfig = static_cast(settings.value(SER_AUDIOCFG, static_cast(AudioConfig::AC_STEREO)).toInt()); videoCodecConfig = static_cast(settings.value(SER_VIDEOCFG, @@ -121,6 +123,7 @@ void StreamingPreferences::save() settings.setValue(SER_VIDEODEC, static_cast(videoDecoderSelection)); settings.setValue(SER_WINDOWMODE, static_cast(windowMode)); settings.setValue(SER_DEFAULTVER, CURRENT_DEFAULT_VER); + settings.setValue(SER_SWAPMOUSEBUTTONS, swapMouseButtons); } int StreamingPreferences::getDefaultBitrate(int width, int height, int fps) diff --git a/app/settings/streamingpreferences.h b/app/settings/streamingpreferences.h index f50d8a88..92311756 100644 --- a/app/settings/streamingpreferences.h +++ b/app/settings/streamingpreferences.h @@ -74,6 +74,7 @@ public: Q_PROPERTY(VideoDecoderSelection videoDecoderSelection MEMBER videoDecoderSelection NOTIFY videoDecoderSelectionChanged) Q_PROPERTY(WindowMode windowMode MEMBER windowMode NOTIFY windowModeChanged) Q_PROPERTY(WindowMode recommendedFullScreenMode MEMBER recommendedFullScreenMode CONSTANT) + Q_PROPERTY(bool swapMouseButtons MEMBER swapMouseButtons NOTIFY mouseButtonsChanged) // Directly accessible members for preferences int width; @@ -95,6 +96,7 @@ public: bool richPresence; bool gamepadMouse; bool detectNetworkBlocking; + bool swapMouseButtons; int packetSize; AudioConfig audioConfig; VideoCodecConfig videoCodecConfig; @@ -124,5 +126,6 @@ signals: void richPresenceChanged(); void gamepadMouseChanged(); void detectNetworkBlockingChanged(); + void mouseButtonsChanged(); }; diff --git a/app/streaming/input/input.cpp b/app/streaming/input/input.cpp index 154ba144..c49a24ba 100644 --- a/app/streaming/input/input.cpp +++ b/app/streaming/input/input.cpp @@ -12,6 +12,7 @@ SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs, NvComputer*, int streamWidth, int streamHeight) : m_MultiController(prefs.multiController), m_GamepadMouse(prefs.gamepadMouse), + m_SwapMouseButtons(prefs.swapMouseButtons), m_MouseMoveTimer(0), m_MousePositionLock(0), m_MouseWasInVideoRegion(false), diff --git a/app/streaming/input/input.h b/app/streaming/input/input.h index b6c467a4..7876027b 100644 --- a/app/streaming/input/input.h +++ b/app/streaming/input/input.h @@ -118,6 +118,7 @@ private: SDL_Window* m_Window; bool m_MultiController; bool m_GamepadMouse; + bool m_SwapMouseButtons; SDL_TimerID m_MouseMoveTimer; SDL_atomic_t m_MouseDeltaX; SDL_atomic_t m_MouseDeltaY; diff --git a/app/streaming/input/mouse.cpp b/app/streaming/input/mouse.cpp index feb6d67b..35c541d6 100644 --- a/app/streaming/input/mouse.cpp +++ b/app/streaming/input/mouse.cpp @@ -55,6 +55,14 @@ void SdlInputHandler::handleMouseButtonEvent(SDL_MouseButtonEvent* event) return; } + if (m_SwapMouseButtons) { + if (button == BUTTON_RIGHT) + button = BUTTON_LEFT; + else if (button == BUTTON_LEFT) + button = BUTTON_RIGHT; + } + + LiSendMouseButtonEvent(event->state == SDL_PRESSED ? BUTTON_ACTION_PRESS : BUTTON_ACTION_RELEASE,