mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-25 06:47:19 +00:00
[client] wayland: support LG_DS_WARP_SURFACE
This commit implements support for LG_DS_WARP_SURFACE, as well as a warp routine based on cursor confines. This may not necessarily work for all compositors. As such, the old cursor routines are still kept, and used when wm.warpSupport is set to false.
This commit is contained in:
parent
270631f1b9
commit
9b688909b0
@ -79,6 +79,8 @@ struct WaylandDSState
|
||||
bool fullscreen;
|
||||
uint32_t resizeSerial;
|
||||
bool configured;
|
||||
bool warpSupport;
|
||||
double cursorX, cursorY;
|
||||
|
||||
#ifdef ENABLE_EGL
|
||||
struct wl_egl_window * eglWindow;
|
||||
@ -267,10 +269,11 @@ static const struct wl_registry_listener registryListener = {
|
||||
static void pointerMotionHandler(void * data, struct wl_pointer * pointer,
|
||||
uint32_t serial, wl_fixed_t sxW, wl_fixed_t syW)
|
||||
{
|
||||
int sx = wl_fixed_to_int(sxW);
|
||||
int sy = wl_fixed_to_int(syW);
|
||||
app_updateCursorPos(sx, sy);
|
||||
if (!wm.relativePointer)
|
||||
wm.cursorX = wl_fixed_to_double(sxW);
|
||||
wm.cursorY = wl_fixed_to_double(syW);
|
||||
app_updateCursorPos(wm.cursorX, wm.cursorY);
|
||||
|
||||
if (!wm.warpSupport && !wm.relativePointer)
|
||||
app_handleMouseBasic();
|
||||
}
|
||||
|
||||
@ -283,14 +286,20 @@ static void pointerEnterHandler(void * data, struct wl_pointer * pointer,
|
||||
wl_pointer_set_cursor(pointer, serial, wm.showPointer ? wm.cursor : NULL, 0, 0);
|
||||
wm.pointerEnterSerial = serial;
|
||||
|
||||
wm.cursorX = wl_fixed_to_double(sxW);
|
||||
wm.cursorY = wl_fixed_to_double(syW);
|
||||
app_updateCursorPos(wm.cursorX, wm.cursorY);
|
||||
|
||||
if (wm.warpSupport)
|
||||
{
|
||||
app_handleMouseRelative(0.0, 0.0, 0.0, 0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wm.relativePointer)
|
||||
return;
|
||||
|
||||
int sx = wl_fixed_to_int(sxW);
|
||||
int sy = wl_fixed_to_int(syW);
|
||||
app_resyncMouseBasic();
|
||||
app_updateCursorPos(sx, sy);
|
||||
if (!wm.relativePointer)
|
||||
app_handleMouseBasic();
|
||||
}
|
||||
|
||||
@ -348,6 +357,26 @@ static const struct wl_pointer_listener pointerListener = {
|
||||
.axis = pointerAxisHandler,
|
||||
};
|
||||
|
||||
static void relativePointerMotionHandler(void * data,
|
||||
struct zwp_relative_pointer_v1 *pointer, uint32_t timeHi, uint32_t timeLo,
|
||||
wl_fixed_t dxW, wl_fixed_t dyW, wl_fixed_t dxUnaccelW,
|
||||
wl_fixed_t dyUnaccelW)
|
||||
{
|
||||
wm.cursorX += wl_fixed_to_double(dxW);
|
||||
wm.cursorY += wl_fixed_to_double(dyW);
|
||||
app_updateCursorPos(wm.cursorX, wm.cursorY);
|
||||
|
||||
app_handleMouseRelative(
|
||||
wl_fixed_to_double(dxW),
|
||||
wl_fixed_to_double(dyW),
|
||||
wl_fixed_to_double(dxUnaccelW),
|
||||
wl_fixed_to_double(dyUnaccelW));
|
||||
}
|
||||
|
||||
static const struct zwp_relative_pointer_v1_listener relativePointerListener = {
|
||||
.relative_motion = relativePointerMotionHandler,
|
||||
};
|
||||
|
||||
static void waylandInhibitIdle(void)
|
||||
{
|
||||
if (wm.idleInhibitManager && !wm.idleInhibitor)
|
||||
@ -644,6 +673,13 @@ static bool waylandInit(const LG_DSInitParams params)
|
||||
DEBUG_WARN("zwp_idle_inhibit_manager_v1 not exported by compositor, will "
|
||||
"not be able to suppress idle states");
|
||||
|
||||
if (wm.warpSupport && (!wm.relativePointerManager || !wm.pointerConstraints))
|
||||
{
|
||||
DEBUG_WARN("Cursor warp is requested, but cannot be honoured due to lack "
|
||||
"of zwp_relative_pointer_manager_v1 or zwp_pointer_constraints_v1");
|
||||
wm.warpSupport = false;
|
||||
}
|
||||
|
||||
wl_seat_add_listener(wm.seat, &seatListener, NULL);
|
||||
xdg_wm_base_add_listener(wm.xdgWmBase, &xdgWmBaseListener, NULL);
|
||||
wl_display_roundtrip(wm.display);
|
||||
@ -651,6 +687,15 @@ static bool waylandInit(const LG_DSInitParams params)
|
||||
wm.dataDevice = wl_data_device_manager_get_data_device(
|
||||
wm.dataDeviceManager, wm.seat);
|
||||
|
||||
if (wm.warpSupport)
|
||||
{
|
||||
wm.relativePointer =
|
||||
zwp_relative_pointer_manager_v1_get_relative_pointer(
|
||||
wm.relativePointerManager, wm.pointer);
|
||||
zwp_relative_pointer_v1_add_listener(wm.relativePointer,
|
||||
&relativePointerListener, NULL);
|
||||
}
|
||||
|
||||
wm.surface = wl_compositor_create_surface(wm.compositor);
|
||||
wm.eglWindow = wl_egl_window_create(wm.surface, params.w, params.h);
|
||||
wm.xdgSurface = xdg_wm_base_get_xdg_surface(wm.xdgWmBase, wm.surface);
|
||||
@ -905,28 +950,12 @@ static bool waylandGetFullscreen(void)
|
||||
return wm.fullscreen;
|
||||
}
|
||||
|
||||
static void relativePointerMotionHandler(void * data,
|
||||
struct zwp_relative_pointer_v1 *pointer, uint32_t timeHi, uint32_t timeLo,
|
||||
wl_fixed_t dxW, wl_fixed_t dyW, wl_fixed_t dxUnaccelW,
|
||||
wl_fixed_t dyUnaccelW)
|
||||
{
|
||||
app_handleMouseRelative(
|
||||
wl_fixed_to_double(dxW),
|
||||
wl_fixed_to_double(dyW),
|
||||
wl_fixed_to_double(dxUnaccelW),
|
||||
wl_fixed_to_double(dyUnaccelW));
|
||||
}
|
||||
|
||||
static const struct zwp_relative_pointer_v1_listener relativePointerListener = {
|
||||
.relative_motion = relativePointerMotionHandler,
|
||||
};
|
||||
|
||||
static void waylandGrabPointer(void)
|
||||
{
|
||||
if (!wm.relativePointerManager || !wm.pointerConstraints)
|
||||
return;
|
||||
|
||||
if (!wm.relativePointer)
|
||||
if (!wm.warpSupport && !wm.relativePointer)
|
||||
{
|
||||
wm.relativePointer =
|
||||
zwp_relative_pointer_manager_v1_get_relative_pointer(
|
||||
@ -945,21 +974,27 @@ static void waylandGrabPointer(void)
|
||||
|
||||
static void waylandUngrabPointer(void)
|
||||
{
|
||||
if (wm.relativePointer)
|
||||
{
|
||||
zwp_relative_pointer_v1_destroy(wm.relativePointer);
|
||||
wm.relativePointer = NULL;
|
||||
}
|
||||
|
||||
if (wm.confinedPointer)
|
||||
{
|
||||
zwp_confined_pointer_v1_destroy(wm.confinedPointer);
|
||||
wm.confinedPointer = NULL;
|
||||
}
|
||||
|
||||
if (!wm.warpSupport)
|
||||
{
|
||||
if (!wm.relativePointer)
|
||||
{
|
||||
wm.relativePointer =
|
||||
zwp_relative_pointer_manager_v1_get_relative_pointer(
|
||||
wm.relativePointerManager, wm.pointer);
|
||||
zwp_relative_pointer_v1_add_listener(wm.relativePointer,
|
||||
&relativePointerListener, NULL);
|
||||
}
|
||||
|
||||
app_resyncMouseBasic();
|
||||
app_handleMouseBasic();
|
||||
}
|
||||
}
|
||||
|
||||
static void waylandGrabKeyboard(void)
|
||||
{
|
||||
@ -981,11 +1016,37 @@ static void waylandUngrabKeyboard(void)
|
||||
|
||||
static void waylandWarpPointer(int x, int y, bool exiting)
|
||||
{
|
||||
// This is an unsupported operation on Wayland.
|
||||
if (x < 0) x = 0;
|
||||
else if (x >= wm.width) x = wm.width - 1;
|
||||
if (y < 0) y = 0;
|
||||
else if (y >= wm.height) y = wm.height - 1;
|
||||
|
||||
struct wl_region * region = wl_compositor_create_region(wm.compositor);
|
||||
wl_region_add(region, x, y, 1, 1);
|
||||
|
||||
if (wm.confinedPointer)
|
||||
{
|
||||
zwp_confined_pointer_v1_set_region(wm.confinedPointer, region);
|
||||
wl_surface_commit(wm.surface);
|
||||
zwp_confined_pointer_v1_set_region(wm.confinedPointer, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct zwp_confined_pointer_v1 * confine;
|
||||
confine = zwp_pointer_constraints_v1_confine_pointer(
|
||||
wm.pointerConstraints, wm.surface, wm.pointer, region,
|
||||
ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
|
||||
wl_surface_commit(wm.surface);
|
||||
zwp_confined_pointer_v1_destroy(confine);
|
||||
}
|
||||
|
||||
wl_surface_commit(wm.surface);
|
||||
wl_region_destroy(region);
|
||||
}
|
||||
|
||||
static void waylandRealignPointer(void)
|
||||
{
|
||||
if (!wm.warpSupport)
|
||||
app_resyncMouseBasic();
|
||||
}
|
||||
|
||||
@ -1015,7 +1076,7 @@ static bool waylandGetProp(LG_DSProperty prop, void * ret)
|
||||
{
|
||||
if (prop == LG_DS_WARP_SUPPORT)
|
||||
{
|
||||
*(enum LG_DSWarpSupport*)ret = LG_DS_WARP_NONE;
|
||||
*(enum LG_DSWarpSupport*)ret = wm.warpSupport ? LG_DS_WARP_SURFACE : LG_DS_WARP_NONE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user