diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 842df3ef2..7ed0d03c3 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -608,6 +608,18 @@ inline static const std::vector CONFIG_OPTIONS = { .type = CONFIG_OPTION_BOOL, .data = SConfigOptionDescription::SBoolData{false}, }, + SConfigOptionDescription{ + .value = "input:touchpad:flip_x", + .description = "Inverts the horizontal movement of the touchpad", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{false}, + }, + SConfigOptionDescription{ + .value = "input:touchpad:flip_y", + .description = "Inverts the vertical movement of the touchpad", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{false}, + }, /* * input:touchdevice: diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 2547992b4..f85010afc 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -603,6 +603,8 @@ CConfigManager::CConfigManager() { registerConfigVar("input:touchpad:tap-and-drag", Hyprlang::INT{1}); registerConfigVar("input:touchpad:drag_lock", Hyprlang::INT{0}); registerConfigVar("input:touchpad:scroll_factor", {1.f}); + registerConfigVar("input:touchpad:flip_x", Hyprlang::INT{0}); + registerConfigVar("input:touchpad:flip_y", Hyprlang::INT{0}); registerConfigVar("input:touchdevice:transform", Hyprlang::INT{0}); registerConfigVar("input:touchdevice:output", {"[[Auto]]"}); registerConfigVar("input:touchdevice:enabled", Hyprlang::INT{1}); @@ -731,6 +733,8 @@ CConfigManager::CConfigManager() { m_pConfig->addSpecialConfigValue("device", "relative_input", Hyprlang::INT{0}); // only for tablets m_pConfig->addSpecialConfigValue("device", "active_area_position", Hyprlang::VEC2{0, 0}); // only for tablets m_pConfig->addSpecialConfigValue("device", "active_area_size", Hyprlang::VEC2{0, 0}); // only for tablets + m_pConfig->addSpecialConfigValue("device", "flip_x", Hyprlang::INT{0}); // only for touchpads + m_pConfig->addSpecialConfigValue("device", "flip_y", Hyprlang::INT{0}); // only for touchpads // keywords m_pConfig->registerHandler(&::handleExec, "exec", {false}); diff --git a/src/devices/IPointer.hpp b/src/devices/IPointer.hpp index ea9cb9f45..19d91c6c1 100644 --- a/src/devices/IPointer.hpp +++ b/src/devices/IPointer.hpp @@ -17,9 +17,10 @@ class IPointer : public IHID { virtual SP aq() = 0; struct SMotionEvent { - uint32_t timeMs = 0; - Vector2D delta, unaccel; - bool mouse = false; + uint32_t timeMs = 0; + Vector2D delta, unaccel; + bool mouse = false; + SP device; }; struct SMotionAbsoluteEvent { @@ -109,6 +110,8 @@ class IPointer : public IHID { bool connected = false; // means connected to the cursor std::string boundOutput = ""; + bool flipX = false; // decide to invert horizontal movement + bool flipY = false; // decide to invert vertical movement WP self; }; diff --git a/src/devices/Mouse.cpp b/src/devices/Mouse.cpp index 41652ce45..87f6d33ba 100644 --- a/src/devices/Mouse.cpp +++ b/src/devices/Mouse.cpp @@ -27,6 +27,7 @@ CMouse::CMouse(SP mouse_) : mouse(mouse_) { .delta = E.delta, .unaccel = E.unaccel, .mouse = true, + .device = self.lock(), }); }); diff --git a/src/devices/VirtualPointer.cpp b/src/devices/VirtualPointer.cpp index 7cfb06313..e98acd04f 100644 --- a/src/devices/VirtualPointer.cpp +++ b/src/devices/VirtualPointer.cpp @@ -19,7 +19,11 @@ CVirtualPointer::CVirtualPointer(SP resource) : point events.destroy.emit(); }); - listeners.motion = pointer->events.move.registerListener([this](std::any d) { pointerEvents.motion.emit(d); }); + listeners.motion = pointer->events.move.registerListener([this](std::any d) { + auto E = std::any_cast(d); + E.device = self.lock(); + pointerEvents.motion.emit(E); + }); listeners.motionAbsolute = pointer->events.warp.registerListener([this](std::any d) { // we need to unpack the event and add our device here because it's required to calculate the position correctly auto E = std::any_cast(d); diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index dffbddc2e..ba0b2df43 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -90,14 +90,28 @@ CInputManager::~CInputManager() { void CInputManager::onMouseMoved(IPointer::SMotionEvent e) { static auto PNOACCEL = CConfigValue("input:force_no_accel"); - const auto DELTA = *PNOACCEL == 1 ? e.unaccel : e.delta; + Vector2D delta = e.delta; + Vector2D unaccel = e.unaccel; + + if (!e.mouse && e.device) { + if (e.device->flipX) { + delta.x = -delta.x; + unaccel.x = -unaccel.x; + } + if (e.device->flipY) { + delta.y = -delta.y; + unaccel.y = -unaccel.y; + } + } + + const auto DELTA = *PNOACCEL == 1 ? unaccel : delta; if (g_pSeatManager->isPointerFrameSkipped) - g_pPointerManager->storeMovement((uint64_t)e.timeMs, DELTA, e.unaccel); + g_pPointerManager->storeMovement((uint64_t)e.timeMs, DELTA, unaccel); else - g_pPointerManager->setStoredMovement((uint64_t)e.timeMs, DELTA, e.unaccel); + g_pPointerManager->setStoredMovement((uint64_t)e.timeMs, DELTA, unaccel); - PROTO::relativePointer->sendRelativeMotion((uint64_t)e.timeMs * 1000, DELTA, e.unaccel); + PROTO::relativePointer->sendRelativeMotion((uint64_t)e.timeMs * 1000, DELTA, unaccel); if (e.mouse) recheckMouseWarpOnMouseInput(); @@ -1180,6 +1194,9 @@ void CInputManager::setPointerConfigs() { const auto LIBINPUTSENS = std::clamp(g_pConfigManager->getDeviceFloat(devname, "sensitivity", "input:sensitivity"), -1.f, 1.f); libinput_device_config_accel_set_speed(LIBINPUTDEV, LIBINPUTSENS); + m->flipX = g_pConfigManager->getDeviceInt(devname, "flip_x", "input:touchpad:flip_x") != 0; + m->flipY = g_pConfigManager->getDeviceInt(devname, "flip_y", "input:touchpad:flip_y") != 0; + const auto ACCELPROFILE = g_pConfigManager->getDeviceString(devname, "accel_profile", "input:accel_profile"); const auto SCROLLPOINTS = g_pConfigManager->getDeviceString(devname, "scroll_points", "input:scroll_points"); diff --git a/src/protocols/VirtualPointer.cpp b/src/protocols/VirtualPointer.cpp index 33641a7bb..8dc4bab60 100644 --- a/src/protocols/VirtualPointer.cpp +++ b/src/protocols/VirtualPointer.cpp @@ -19,6 +19,7 @@ CVirtualPointerV1Resource::CVirtualPointerV1Resource(SP r .timeMs = timeMs, .delta = {wl_fixed_to_double(dx), wl_fixed_to_double(dy)}, .unaccel = {wl_fixed_to_double(dx), wl_fixed_to_double(dy)}, + .device = nullptr, }); });