diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 12e81f2a..fde8173d 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -620,16 +620,22 @@ inline static const std::vector CONFIG_OPTIONS = { }, SConfigOptionDescription{ .value = "input:tablet:output", - .description = "the monitor to bind tablets. Empty means unbound..", + .description = "the monitor to bind tablets. Can be current or a monitor name. Leave empty to map across all monitors.", .type = CONFIG_OPTION_STRING_SHORT, .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? }, SConfigOptionDescription{ .value = "input:tablet:region_position", - .description = "position of the mapped region in monitor layout.", + .description = "position of the mapped region in monitor layout relative to the top left corner of the bound monitor or all monitors.", .type = CONFIG_OPTION_VECTOR, .data = SConfigOptionDescription::SVectorData{{}, {-20000, -20000}, {20000, 20000}}, }, + SConfigOptionDescription{ + .value = "input:tablet:absolute_region_position", + .description = "whether to treat the region_position as an absolute position in monitor layout. Only applies when output is empty.", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{false}, + }, SConfigOptionDescription{ .value = "input:tablet:region_size", .description = "size of the mapped region. When this variable is set, tablet input will be mapped to the region. [0, 0] or invalid size means unset.", diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 769a7525..fbbc8dbd 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -516,6 +516,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("input:tablet:transform", Hyprlang::INT{0}); m_pConfig->addConfigValue("input:tablet:output", {STRVAL_EMPTY}); m_pConfig->addConfigValue("input:tablet:region_position", Hyprlang::VEC2{0, 0}); + m_pConfig->addConfigValue("input:tablet:absolute_region_position", Hyprlang::INT{0}); m_pConfig->addConfigValue("input:tablet:region_size", Hyprlang::VEC2{0, 0}); m_pConfig->addConfigValue("input:tablet:relative_input", Hyprlang::INT{0}); m_pConfig->addConfigValue("input:tablet:left_handed", Hyprlang::INT{0}); @@ -625,6 +626,7 @@ CConfigManager::CConfigManager() { m_pConfig->addSpecialConfigValue("device", "output", {STRVAL_EMPTY}); m_pConfig->addSpecialConfigValue("device", "enabled", Hyprlang::INT{1}); // only for mice, touchpads, and touchdevices m_pConfig->addSpecialConfigValue("device", "region_position", Hyprlang::VEC2{0, 0}); // only for tablets + m_pConfig->addSpecialConfigValue("device", "absolute_region_position", Hyprlang::INT{0}); // only for tablets m_pConfig->addSpecialConfigValue("device", "region_size", Hyprlang::VEC2{0, 0}); // only for tablets 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 diff --git a/src/devices/Tablet.hpp b/src/devices/Tablet.hpp index 4894ac8e..8f49c984 100644 --- a/src/devices/Tablet.hpp +++ b/src/devices/Tablet.hpp @@ -92,9 +92,10 @@ class CTablet : public IHID { WP self; bool relativeInput = false; + bool absolutePos = false; std::string boundOutput = ""; CBox activeArea; - CBox boundBox; // output-local + CBox boundBox; private: CTablet(SP tablet); diff --git a/src/devices/VirtualPointer.cpp b/src/devices/VirtualPointer.cpp index 7ad18775..514c8c32 100644 --- a/src/devices/VirtualPointer.cpp +++ b/src/devices/VirtualPointer.cpp @@ -38,7 +38,7 @@ CVirtualPointer::CVirtualPointer(SP resource) : point listeners.holdBegin = pointer->events.holdBegin.registerListener([this](std::any d) { pointerEvents.holdBegin.emit(d); }); listeners.holdEnd = pointer->events.holdEnd.registerListener([this](std::any d) { pointerEvents.holdEnd.emit(d); }); - boundOutput = resource->boundOutput ? resource->boundOutput->szName : "entire"; + boundOutput = resource->boundOutput ? resource->boundOutput->szName : ""; deviceName = pointer->name; } diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index b309ba82..75be235f 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -668,9 +668,7 @@ void CPointerManager::move(const Vector2D& deltaLogical) { } void CPointerManager::warpAbsolute(Vector2D abs, SP dev) { - - PHLMONITOR currentMonitor = g_pCompositor->m_pLastMonitor.lock(); - if (!currentMonitor || !dev) + if (!dev) return; if (!std::isnan(abs.x)) @@ -678,20 +676,44 @@ void CPointerManager::warpAbsolute(Vector2D abs, SP dev) { if (!std::isnan(abs.y)) abs.y = std::clamp(abs.y, 0.0, 1.0); - // in logical global - CBox mappedArea = currentMonitor->logicalBox(); + // find x and y size of the entire space + const auto& MONITORS = g_pCompositor->m_vMonitors; + Vector2D topLeft = MONITORS.at(0)->vecPosition, bottomRight = MONITORS.at(0)->vecPosition + MONITORS.at(0)->vecSize; + for (size_t i = 1; i < MONITORS.size(); ++i) { + const auto EXTENT = MONITORS[i]->logicalBox().extent(); + const auto POS = MONITORS[i]->logicalBox().pos(); + if (EXTENT.x > bottomRight.x) + bottomRight.x = EXTENT.x; + if (EXTENT.y > bottomRight.y) + bottomRight.y = EXTENT.y; + if (POS.x < topLeft.x) + topLeft.x = POS.x; + if (POS.y < topLeft.y) + topLeft.y = POS.y; + } + CBox mappedArea = {topLeft, bottomRight - topLeft}; + + auto outputMappedArea = [&mappedArea](const std::string& output) { + if (output == "current") { + if (const auto PLASTMONITOR = g_pCompositor->m_pLastMonitor.lock(); PLASTMONITOR) + return PLASTMONITOR->logicalBox(); + } else if (const auto PMONITOR = g_pCompositor->getMonitorFromString(output); PMONITOR) + return PMONITOR->logicalBox(); + return mappedArea; + }; switch (dev->getType()) { case HID_TYPE_TABLET: { CTablet* TAB = reinterpret_cast(dev.get()); if (!TAB->boundOutput.empty()) { - if (const auto PMONITOR = g_pCompositor->getMonitorFromString(TAB->boundOutput); PMONITOR) { - currentMonitor = PMONITOR->self.lock(); - mappedArea = currentMonitor->logicalBox(); - } - } + mappedArea = outputMappedArea(TAB->boundOutput); + mappedArea.translate(TAB->boundBox.pos()); + } else if (TAB->absolutePos) { + mappedArea.x = TAB->boundBox.x; + mappedArea.y = TAB->boundBox.y; + } else + mappedArea.translate(TAB->boundBox.pos()); - mappedArea.translate(TAB->boundBox.pos()); if (!TAB->boundBox.empty()) { mappedArea.w = TAB->boundBox.w; mappedArea.h = TAB->boundBox.h; @@ -700,38 +722,14 @@ void CPointerManager::warpAbsolute(Vector2D abs, SP dev) { } case HID_TYPE_TOUCH: { ITouch* TOUCH = reinterpret_cast(dev.get()); - if (!TOUCH->boundOutput.empty()) { - if (const auto PMONITOR = g_pCompositor->getMonitorFromString(TOUCH->boundOutput); PMONITOR) { - currentMonitor = PMONITOR->self.lock(); - mappedArea = currentMonitor->logicalBox(); - } - } + if (!TOUCH->boundOutput.empty()) + mappedArea = outputMappedArea(TOUCH->boundOutput); break; } case HID_TYPE_POINTER: { IPointer* POINTER = reinterpret_cast(dev.get()); - if (!POINTER->boundOutput.empty()) { - if (POINTER->boundOutput == "entire") { - // find x and y size of the entire space - Vector2D bottomRight = {-9999999, -9999999}, topLeft = {9999999, 9999999}; - for (auto const& m : g_pCompositor->m_vMonitors) { - const auto EXTENT = m->logicalBox().extent(); - const auto POS = m->logicalBox().pos(); - if (EXTENT.x > bottomRight.x) - bottomRight.x = EXTENT.x; - if (EXTENT.y > bottomRight.y) - bottomRight.y = EXTENT.y; - if (POS.x < topLeft.x) - topLeft.x = POS.x; - if (POS.y < topLeft.y) - topLeft.y = POS.y; - } - mappedArea = {topLeft, bottomRight - topLeft}; - } else if (const auto PMONITOR = g_pCompositor->getMonitorFromString(POINTER->boundOutput); PMONITOR) { - currentMonitor = PMONITOR->self.lock(); - mappedArea = currentMonitor->logicalBox(); - } - } + if (!POINTER->boundOutput.empty()) + mappedArea = outputMappedArea(POINTER->boundOutput); break; } default: break; diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index c190f589..9110cd15 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -1595,6 +1595,9 @@ void CInputManager::setTabletConfigs() { const auto REGION_SIZE = g_pConfigManager->getDeviceVec(NAME, "region_size", "input:tablet:region_size"); t->boundBox = {REGION_POS, REGION_SIZE}; + const auto ABSOLUTE_REGION_POS = g_pConfigManager->getDeviceInt(NAME, "absolute_region_position", "input:tablet:absolute_region_position"); + t->absolutePos = ABSOLUTE_REGION_POS; + const auto ACTIVE_AREA_SIZE = g_pConfigManager->getDeviceVec(NAME, "active_area_size", "input:tablet:active_area_size"); const auto ACTIVE_AREA_POS = g_pConfigManager->getDeviceVec(NAME, "active_area_position", "input:tablet:active_area_position"); if (ACTIVE_AREA_SIZE.x != 0 || ACTIVE_AREA_SIZE.y != 0) {