summaryrefslogtreecommitdiff
path: root/src/managers/PointerManager.cpp
diff options
context:
space:
mode:
authorJaSha256 <151202144+JaSha256@users.noreply.github.com>2026-03-05 16:14:23 +0100
committerGitHub <noreply@github.com>2026-03-05 15:14:23 +0000
commitae9ca17b40e04cd11b53b82e9292d3070710df18 (patch)
tree713ecac5dbef5e05f58fcd4b267bd75f8275ec91 /src/managers/PointerManager.cpp
parent972f23efe824889bdb79869cfd44bd960f96350e (diff)
pointer: fix hardware cursor rendering on rotated/flipped monitors (#13574)
Replace the broken cairo_matrix_rotate() approach with explicit per-transform pattern matrices for all 8 wl_output_transform values.
Diffstat (limited to 'src/managers/PointerManager.cpp')
-rw-r--r--src/managers/PointerManager.cpp35
1 files changed, 17 insertions, 18 deletions
diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp
index 11f54fec..c802d3e1 100644
--- a/src/managers/PointerManager.cpp
+++ b/src/managers/PointerManager.cpp
@@ -540,24 +540,23 @@ SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager
// we need to scale the cursor to the right size, because it might not be (esp with XCursor)
const auto SCALE = texture->m_size / (m_currentCursorImage.size / m_currentCursorImage.scale * state->monitor->m_scale);
- cairo_matrix_scale(&matrixPre, SCALE.x, SCALE.y);
-
- if (TR) {
- cairo_matrix_rotate(&matrixPre, M_PI_2 * sc<double>(TR));
-
- // FIXME: this is wrong, and doesn't work for 5, 6 and 7. (flipped + rot)
- // cba to do it rn, does anyone fucking use that??
- if (TR >= WL_OUTPUT_TRANSFORM_FLIPPED) {
- cairo_matrix_scale(&matrixPre, -1, 1);
- cairo_matrix_translate(&matrixPre, -DMABUF.size.x, 0);
- }
-
- if (TR == 3 || TR == 7)
- cairo_matrix_translate(&matrixPre, -DMABUF.size.x, 0);
- else if (TR == 2 || TR == 6)
- cairo_matrix_translate(&matrixPre, -DMABUF.size.x, -DMABUF.size.y);
- else if (TR == 1 || TR == 5)
- cairo_matrix_translate(&matrixPre, 0, -DMABUF.size.y);
+ const auto SX = SCALE.x, SY = SCALE.y;
+ const auto BW = sc<double>(DMABUF.size.x), BH = sc<double>(DMABUF.size.y);
+
+ // Cairo pattern matrix maps destination coords to source coords (inverse of visual transform).
+ // x_src = xx * x_dst + xy * y_dst + x0
+ // y_src = yx * x_dst + yy * y_dst + y0
+ // cairo_matrix_init(&m, xx, yx, xy, yy, x0, y0)
+ switch (TR) {
+ case WL_OUTPUT_TRANSFORM_NORMAL:
+ default: cairo_matrix_init(&matrixPre, SX, 0, 0, SY, 0, 0); break;
+ case WL_OUTPUT_TRANSFORM_90: cairo_matrix_init(&matrixPre, 0, SY, -SX, 0, SX * BW, 0); break;
+ case WL_OUTPUT_TRANSFORM_180: cairo_matrix_init(&matrixPre, -SX, 0, 0, -SY, SX * BW, SY * BH); break;
+ case WL_OUTPUT_TRANSFORM_270: cairo_matrix_init(&matrixPre, 0, -SY, SX, 0, 0, SY * BH); break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED: cairo_matrix_init(&matrixPre, -SX, 0, 0, SY, SX * BW, 0); break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_90: cairo_matrix_init(&matrixPre, 0, SY, SX, 0, 0, 0); break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_180: cairo_matrix_init(&matrixPre, SX, 0, 0, -SY, 0, SY * BH); break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_270: cairo_matrix_init(&matrixPre, 0, -SY, -SX, 0, SX * BW, SY * BH); break;
}
cairo_pattern_set_matrix(PATTERNPRE, &matrixPre);