diff --git a/src/lib/common/CMakeLists.txt b/src/lib/common/CMakeLists.txt index 034f2cc6c..3b389a5b8 100644 --- a/src/lib/common/CMakeLists.txt +++ b/src/lib/common/CMakeLists.txt @@ -10,6 +10,7 @@ configure_file(Constants.h.in Constants.h @ONLY) configure_file(VersionInfo.h.in VersionInfo.h @ONLY) add_library(common STATIC + Coordinate.h Enums.h ExitCodes.h I18N.h diff --git a/src/lib/common/Coordinate.h b/src/lib/common/Coordinate.h new file mode 100644 index 000000000..5edb89fbb --- /dev/null +++ b/src/lib/common/Coordinate.h @@ -0,0 +1,21 @@ +/* + * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2026 Deskflow Developers + * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception + */ + +#pragma once + +#include +#include + +struct Coordinate +{ + Q_GADGET; + +public: + int32_t x; + int32_t y; +}; + +using ScrollDelta = Coordinate; diff --git a/src/lib/deskflow/ISecondaryScreen.h b/src/lib/deskflow/ISecondaryScreen.h index 493ca50c7..714695c66 100644 --- a/src/lib/deskflow/ISecondaryScreen.h +++ b/src/lib/deskflow/ISecondaryScreen.h @@ -1,6 +1,6 @@ /* * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers + * SPDX-FileCopyrightText: (C) 2025 - 2026 Deskflow Developers * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. * SPDX-FileCopyrightText: (C) 2003 Chris Schoeneman * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception @@ -8,6 +8,8 @@ #pragma once +#include "common/Coordinate.h" +#include "common/Settings.h" #include "deskflow/MouseTypes.h" //! Secondary screen interface @@ -18,6 +20,12 @@ secondary screen implementations. class ISecondaryScreen { public: + ISecondaryScreen() + { + m_invertScroll = Settings::value(Settings::Client::InvertScrollDirection).toBool(); + m_scrollScale = std::clamp(Settings::value(Settings::Client::YScrollScale).toDouble(), 0.1, 10.0); + } + virtual ~ISecondaryScreen() = default; //! @name accessors //@{ @@ -40,11 +48,37 @@ public: */ virtual void fakeMouseRelativeMove(int32_t dx, int32_t dy) const = 0; - //! Fake mouse wheel - /*! - Synthesize a mouse wheel event of amount \c xDelta and \c yDelta. - */ + /** + * @brief Synthesize a mouse wheel event of amount + * This method should include the use of `applyScrollModifier` before sending the delta + * @param xDelta + * @param yDelta + */ virtual void fakeMouseWheel(int32_t xDelta, int32_t yDelta) const = 0; + /** + * @brief Applies any scroll modfifers to the provided delta, This should only be done inside the subclasses + * fakeMouseWheel impl + * @param delta a ScrollDelta to be modified + * @return the delta with inversion and scale applied + */ + ScrollDelta applyScrollModifier(ScrollDelta delta) const + { + delta.y = static_cast(m_invertScroll ? delta.y * -m_scrollScale : delta.y * m_scrollScale); + return delta; + } + +private: + /** + * @brief this member is used to modify the scroll direction. + * It is used in the applyScrollModifier method + */ + bool m_invertScroll = false; + + /** + * @brief this member is used to modify the scroll scale. + * It is used in the applyScrollModifier method + */ + double m_scrollScale = 1.0; //@} }; diff --git a/src/lib/deskflow/PlatformScreen.cpp b/src/lib/deskflow/PlatformScreen.cpp index 558ac7c25..ec8d09b6b 100644 --- a/src/lib/deskflow/PlatformScreen.cpp +++ b/src/lib/deskflow/PlatformScreen.cpp @@ -1,5 +1,6 @@ /* * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2026 Deskflow Developers * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. * SPDX-FileCopyrightText: (C) 2004 Chris Schoeneman * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception @@ -7,13 +8,11 @@ #include "deskflow/PlatformScreen.h" #include "base/DirectionTypes.h" -#include "common/Settings.h" #include "deskflow/App.h" PlatformScreen::PlatformScreen(IEventQueue *events) : IPlatformScreen(events) { - m_invertScrollDirection = Settings::value(Settings::Client::InvertScrollDirection).toBool(); - m_yScrollScale = std::clamp(Settings::value(Settings::Client::YScrollScale).toDouble(), 0.1, 10.0); + // do nothing } void PlatformScreen::updateKeyMap() @@ -89,13 +88,6 @@ void PlatformScreen::clearStaleModifiers() getKeyState()->clearStaleModifiers(); } -PlatformScreen::ScrollDelta PlatformScreen::applyClientScrollModifier(const PlatformScreen::ScrollDelta rawDelta) const -{ - ScrollDelta correctedDelta = rawDelta; - correctedDelta.yDelta *= m_invertScrollDirection ? -m_yScrollScale : m_yScrollScale; - return correctedDelta; -} - std::string PlatformScreen::sidesMaskToString(uint32_t sides) { using enum DirectionMask; diff --git a/src/lib/deskflow/PlatformScreen.h b/src/lib/deskflow/PlatformScreen.h index ad969a0ca..3b00f7f66 100644 --- a/src/lib/deskflow/PlatformScreen.h +++ b/src/lib/deskflow/PlatformScreen.h @@ -1,5 +1,6 @@ /* * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2026 Deskflow Developers * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. * SPDX-FileCopyrightText: (C) 2004 Chris Schoeneman * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception @@ -18,11 +19,6 @@ subclasses to implement the rest. class PlatformScreen : public IPlatformScreen { public: - struct ScrollDelta - { - int32_t xDelta; - int32_t yDelta; - }; explicit PlatformScreen(IEventQueue *events); ~PlatformScreen() override = default; @@ -100,13 +96,6 @@ protected: // IPlatformScreen overrides void handleSystemEvent(const Event &event) override = 0; - /*! - * \brief applyClientYScrollModifier - * Convert scroll according to client's scroll modifiers - * \return converted value according to the client's scroll modifiers - */ - virtual ScrollDelta applyClientScrollModifier(const ScrollDelta rawDelta) const; - /*! Converts a sides mask (e.g. LeftMask | RightMask) to a string representation (e.g. "LR"). */ diff --git a/src/lib/platform/EiScreen.cpp b/src/lib/platform/EiScreen.cpp index 60297aaf2..22aa637c0 100644 --- a/src/lib/platform/EiScreen.cpp +++ b/src/lib/platform/EiScreen.cpp @@ -1,6 +1,6 @@ /* * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers + * SPDX-FileCopyrightText: (C) 2025 - 2026 Deskflow Developers * SPDX-FileCopyrightText: (C) 2024 Symless Ltd. * SPDX-FileCopyrightText: (C) 2022 Red Hat, Inc. * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception @@ -318,11 +318,11 @@ void EiScreen::fakeMouseWheel(int32_t xDelta, int32_t yDelta) const if (!m_eiPointer) return; - auto adjustedDeltas = applyClientScrollModifier({xDelta, yDelta}); + auto adjustedDeltas = applyScrollModifier({xDelta, yDelta}); // libei and deskflow seem to use opposite directions, so we have // to send EI the opposite of the value received if we want to remain // compatible with other platforms (including X11). - ei_device_scroll_discrete(m_eiPointer, -adjustedDeltas.xDelta, -adjustedDeltas.yDelta); + ei_device_scroll_discrete(m_eiPointer, -adjustedDeltas.x, -adjustedDeltas.y); ei_device_frame(m_eiPointer, ei_now(m_ei)); } diff --git a/src/lib/platform/MSWindowsScreen.cpp b/src/lib/platform/MSWindowsScreen.cpp index 606174e84..07254342d 100644 --- a/src/lib/platform/MSWindowsScreen.cpp +++ b/src/lib/platform/MSWindowsScreen.cpp @@ -1,6 +1,6 @@ /* * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers + * SPDX-FileCopyrightText: (C) 2025 - 2026 Deskflow Developers * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. * SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception @@ -708,8 +708,8 @@ void MSWindowsScreen::fakeMouseRelativeMove(int32_t dx, int32_t dy) const void MSWindowsScreen::fakeMouseWheel(int32_t xDelta, int32_t yDelta) const { - auto adjustedDeltas = applyClientScrollModifier({xDelta, yDelta}); - m_desks->fakeMouseWheel(adjustedDeltas.xDelta, adjustedDeltas.yDelta); + auto adjustedDeltas = applyScrollModifier({xDelta, yDelta}); + m_desks->fakeMouseWheel(adjustedDeltas.x, adjustedDeltas.y); } void MSWindowsScreen::updateKeys() diff --git a/src/lib/platform/OSXScreen.mm b/src/lib/platform/OSXScreen.mm index a7e53d46e..b11353d96 100644 --- a/src/lib/platform/OSXScreen.mm +++ b/src/lib/platform/OSXScreen.mm @@ -1,6 +1,6 @@ /* * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers + * SPDX-FileCopyrightText: (C) 2025 - 2026 Deskflow Developers * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. * SPDX-FileCopyrightText: (C) 2004 Chris Schoeneman * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception @@ -589,13 +589,12 @@ void OSXScreen::fakeMouseWheel(int32_t xDelta, int32_t yDelta) const if (xDelta != 0 || yDelta != 0) { // use server's acceleration with a little boost since other platforms // take one wheel step as a larger step than the mac does. - auto adjustedDeltas = applyClientScrollModifier( - {static_cast(3.0 * xDelta / 120.0), static_cast(3.0 * yDelta / 120.0)} - ); + auto adjustedDeltas = + applyScrollModifier({static_cast(3.0 * xDelta / 120.0), static_cast(3.0 * y / 120.0)}); // create a scroll event, post it and release it. not sure if kCGScrollEventUnitLine // is the right choice here over kCGScrollEventUnitPixel CGEventRef scrollEvent = - CGEventCreateScrollWheelEvent(nullptr, kCGScrollEventUnitLine, 2, adjustedDeltas.yDelta, adjustedDeltas.xDelta); + CGEventCreateScrollWheelEvent(nullptr, kCGScrollEventUnitLine, 2, adjustedDeltas.y, adjustedDeltas.x); // Fix for sticky keys CGEventFlags modifiers = m_keyState->getModifierStateAsOSXFlags(); diff --git a/src/lib/platform/XWindowsScreen.cpp b/src/lib/platform/XWindowsScreen.cpp index 76bf26c01..fdac7ef0d 100644 --- a/src/lib/platform/XWindowsScreen.cpp +++ b/src/lib/platform/XWindowsScreen.cpp @@ -1,6 +1,6 @@ /* * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers + * SPDX-FileCopyrightText: (C) 2025 - 2026 Deskflow Developers * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. * SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception @@ -791,7 +791,7 @@ void XWindowsScreen::fakeMouseWheel(int32_t, int32_t yDelta) const return; } - yDelta = applyClientScrollModifier({0, yDelta}).yDelta; + yDelta = applyScrollModifier({0, yDelta}).y; // choose button depending on rotation direction const unsigned int xButton = mapButtonToX(yDelta >= 0 ? kX11ScrollWheelUp : kX11ScrollWheelDown);