fix(linux): fix touch misalignment for wlgrab on scaled outputs (#4665)

This commit is contained in:
herbie
2026-02-17 23:40:16 -05:00
committed by GitHub
parent 24c5dfd622
commit c9bcee4480
2 changed files with 53 additions and 22 deletions
+37 -22
View File
@@ -902,6 +902,31 @@ namespace input {
input->gamepads[packet->controllerNumber].id = id;
}
/**
* @brief Normalizes coordinates to monitor-local logical touch dimensions.
* @param touch_port The current touch port metadata.
* @param coords The in/out coordinate pair to normalize.
* @return The monitor-local touch port, or std::nullopt if dimensions are invalid.
*/
std::optional<platf::touch_port_t> monitor_touch_port(const input::touch_port_t &touch_port, std::pair<float, float> &coords) {
const float monitor_logical_w = (touch_port.width * touch_port.scalar_inv) / touch_port.scalar_tpcoords;
const float monitor_logical_h = (touch_port.height * touch_port.scalar_inv) / touch_port.scalar_tpcoords;
if (monitor_logical_w <= 0.0f || monitor_logical_h <= 0.0f) {
BOOST_LOG(warning) << "Ignoring touch/pen input due to invalid logical touch dimensions"sv;
return std::nullopt;
}
coords.first = (coords.first - touch_port.offset_x) / monitor_logical_w;
coords.second = (coords.second - touch_port.offset_y) / monitor_logical_h;
return platf::touch_port_t {
touch_port.offset_x,
touch_port.offset_y,
static_cast<int>(monitor_logical_w),
static_cast<int>(monitor_logical_h)
};
}
/**
* @brief Called to pass a touch message to the platform backend.
* @param input The input context pointer.
@@ -919,16 +944,11 @@ namespace input {
}
auto &touch_port = input->touch_port;
platf::touch_port_t abs_port {
touch_port.offset_x,
touch_port.offset_y,
touch_port.env_width,
touch_port.env_height
};
// Renormalize the coordinates
coords->first /= abs_port.width;
coords->second /= abs_port.height;
auto abs_port = monitor_touch_port(touch_port, *coords);
if (!abs_port) {
return;
}
// Normalize rotation value to 0-359 degree range
auto rotation = util::endian::little(packet->rotation);
@@ -941,7 +961,7 @@ namespace input {
{from_clamped_netfloat(packet->contactAreaMajor, 0.0f, 1.0f) * 65535.f,
from_clamped_netfloat(packet->contactAreaMinor, 0.0f, 1.0f) * 65535.f},
rotation,
{abs_port.width / 65535.f, abs_port.height / 65535.f}
{abs_port->width / 65535.f, abs_port->height / 65535.f}
);
platf::touch_input_t touch {
@@ -955,7 +975,7 @@ namespace input {
contact_area.second,
};
platf::touch_update(input->client_context.get(), abs_port, touch);
platf::touch_update(input->client_context.get(), *abs_port, touch);
}
/**
@@ -975,16 +995,11 @@ namespace input {
}
auto &touch_port = input->touch_port;
platf::touch_port_t abs_port {
touch_port.offset_x,
touch_port.offset_y,
touch_port.env_width,
touch_port.env_height
};
// Renormalize the coordinates
coords->first /= abs_port.width;
coords->second /= abs_port.height;
auto abs_port = monitor_touch_port(touch_port, *coords);
if (!abs_port) {
return;
}
// Normalize rotation value to 0-359 degree range
auto rotation = util::endian::little(packet->rotation);
@@ -997,7 +1012,7 @@ namespace input {
{from_clamped_netfloat(packet->contactAreaMajor, 0.0f, 1.0f) * 65535.f,
from_clamped_netfloat(packet->contactAreaMinor, 0.0f, 1.0f) * 65535.f},
rotation,
{abs_port.width / 65535.f, abs_port.height / 65535.f}
{abs_port->width / 65535.f, abs_port->height / 65535.f}
);
platf::pen_input_t pen {
@@ -1013,7 +1028,7 @@ namespace input {
contact_area.second,
};
platf::pen_update(input->client_context.get(), abs_port, pen);
platf::pen_update(input->client_context.get(), *abs_port, pen);
}
/**