mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-09 00:31:31 +00:00
[client] cursor: improve Wayland hotspot alignment
Center the Wayland diagnostic cursor on its actual pointer hotspot and preserve it while cursor themes are reloaded for output-scale changes. Round fractional guest positions to the nearest logical pixel instead of biasing synchronization toward the top-left corner. Resynchronize the hardware pointer when a cursor shape changes its hotspot. Only perform the extra synchronization when the hotspot actually changes, and update the basic-mode projection at the same time.
This commit is contained in:
@@ -157,7 +157,8 @@ bool waylandCursorInit(void)
|
|||||||
wlWm.cursorSquareBuffer = createSquareCursorBuffer();
|
wlWm.cursorSquareBuffer = createSquareCursorBuffer();
|
||||||
if (wlWm.cursorSquareBuffer)
|
if (wlWm.cursorSquareBuffer)
|
||||||
{
|
{
|
||||||
wlWm.cursors[LG_POINTER_SQUARE] = wl_compositor_create_surface(wlWm.compositor);
|
wlWm.cursors[LG_POINTER_SQUARE] = wl_compositor_create_surface(wlWm.compositor);
|
||||||
|
wlWm.cursorHot[LG_POINTER_SQUARE] = (struct Point) { 2, 2 };
|
||||||
wl_surface_attach(wlWm.cursors[LG_POINTER_SQUARE], wlWm.cursorSquareBuffer, 0, 0);
|
wl_surface_attach(wlWm.cursors[LG_POINTER_SQUARE], wlWm.cursorSquareBuffer, 0, 0);
|
||||||
wl_surface_commit(wlWm.cursors[LG_POINTER_SQUARE]);
|
wl_surface_commit(wlWm.cursors[LG_POINTER_SQUARE]);
|
||||||
}
|
}
|
||||||
@@ -213,6 +214,10 @@ void waylandCursorScaleChange(void)
|
|||||||
memcpy(old, wlWm.cursors, sizeof(old));
|
memcpy(old, wlWm.cursors, sizeof(old));
|
||||||
memset(wlWm.cursors, 0, sizeof(wlWm.cursors));
|
memset(wlWm.cursors, 0, sizeof(wlWm.cursors));
|
||||||
|
|
||||||
|
/* the diagnostic cursor is not part of the cursor theme */
|
||||||
|
wlWm.cursors[LG_POINTER_SQUARE] = old[LG_POINTER_SQUARE];
|
||||||
|
old[LG_POINTER_SQUARE] = NULL;
|
||||||
|
|
||||||
if (wlWm.cursorTheme)
|
if (wlWm.cursorTheme)
|
||||||
wl_cursor_theme_destroy(wlWm.cursorTheme);
|
wl_cursor_theme_destroy(wlWm.cursorTheme);
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "wayland.h"
|
#include "wayland.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <math.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
@@ -1027,5 +1028,5 @@ void waylandGuestPointerUpdated(double x, double y, double localX, double localY
|
|||||||
|
|
||||||
MTRACE("guest warp guest=%.3f,%.3f local=%.3f,%.3f",
|
MTRACE("guest warp guest=%.3f,%.3f local=%.3f,%.3f",
|
||||||
x, y, localX, localY);
|
x, y, localX, localY);
|
||||||
waylandWarpPointer((int) localX, (int) localY, false);
|
waylandWarpPointer((int) round(localX), (int) round(localY), false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1076,6 +1076,7 @@ int main_cursorThread(void * unused)
|
|||||||
|
|
||||||
const bool wasRendered = g_cursor.guest.visible &&
|
const bool wasRendered = g_cursor.guest.visible &&
|
||||||
(g_cursor.draw || !g_params.useSpiceInput);
|
(g_cursor.draw || !g_params.useSpiceInput);
|
||||||
|
bool hotspotChanged = false;
|
||||||
|
|
||||||
if (pointer.flags & LG_TRANSPORT_POINTER_VISIBLE_VALID)
|
if (pointer.flags & LG_TRANSPORT_POINTER_VISIBLE_VALID)
|
||||||
g_cursor.guest.visible =
|
g_cursor.guest.visible =
|
||||||
@@ -1094,8 +1095,8 @@ int main_cursorThread(void * unused)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_cursor.guest.hx = pointer.hx;
|
hotspotChanged =
|
||||||
g_cursor.guest.hy = pointer.hy;
|
g_cursor.guest.hx != pointer.hx || g_cursor.guest.hy != pointer.hy;
|
||||||
if (!RENDERER(onMouseShape, cursorType, pointer.width, pointer.height,
|
if (!RENDERER(onMouseShape, cursorType, pointer.width, pointer.height,
|
||||||
pointer.pitch, pointer.shape))
|
pointer.pitch, pointer.shape))
|
||||||
{
|
{
|
||||||
@@ -1103,6 +1104,8 @@ int main_cursorThread(void * unused)
|
|||||||
g_state.transportOps->releasePointer(g_state.transport, &pointer);
|
g_state.transportOps->releasePointer(g_state.transport, &pointer);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
g_cursor.guest.hx = pointer.hx;
|
||||||
|
g_cursor.guest.hy = pointer.hy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pointer.flags & LG_TRANSPORT_POINTER_COLOR_TRANSFORM) &&
|
if ((pointer.flags & LG_TRANSPORT_POINTER_COLOR_TRANSFORM) &&
|
||||||
@@ -1132,9 +1135,14 @@ int main_cursorThread(void * unused)
|
|||||||
core_alignToGuest();
|
core_alignToGuest();
|
||||||
app_resyncMouseBasic();
|
app_resyncMouseBasic();
|
||||||
}
|
}
|
||||||
core_handleGuestMouseUpdate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hotspotChanged)
|
||||||
|
app_resyncMouseBasic();
|
||||||
|
|
||||||
|
if ((pointer.flags & LG_TRANSPORT_POINTER_POSITION) || hotspotChanged)
|
||||||
|
core_handleGuestMouseUpdate();
|
||||||
|
|
||||||
app_updateMouseState();
|
app_updateMouseState();
|
||||||
g_cursor.redraw = false;
|
g_cursor.redraw = false;
|
||||||
RENDERER(onMouseEvent,
|
RENDERER(onMouseEvent,
|
||||||
|
|||||||
Reference in New Issue
Block a user