[client] wayland: gracefully degrade when protocols are unsupported

zwp_relative_pointer_manager_v1 and zwp_pointer_constraints_v1 are
supported by GNOME/KDE/sway (and most other compositors), but they are
not a required part of the protocol.

Some users also run software in one-off nested compositors like cage[0]
for an extra layer of isolation; cage, at least, does not support
pointer captures.

This commit makes Looking Glass warn when an optional protocol is
unsupported, and fail if a required one is missing. Pointer grab paths
have a new guard against the aforementioned protocols being missing.

[0]: https://github.com/Hjdskes/cage
This commit is contained in:
Tudor Brindus 2021-01-16 13:01:30 -05:00 committed by Geoffrey McRae
parent 2a69a19dbd
commit 56c80a15e6
4 changed files with 28 additions and 8 deletions

View File

@ -38,9 +38,10 @@ static bool sdlEarlyInit(void)
return true; return true;
} }
static void sdlInit(SDL_SysWMinfo * info) static bool sdlInit(SDL_SysWMinfo * info)
{ {
memset(&sdl, 0, sizeof(sdl)); memset(&sdl, 0, sizeof(sdl));
return true;
} }
static void sdlStartup(void) static void sdlStartup(void)

View File

@ -84,8 +84,6 @@ struct WCBState
static struct WaylandDSState wm; static struct WaylandDSState wm;
static struct WCBState wcb; static struct WCBState wcb;
// Wayland support.
// Registry-handling listeners. // Registry-handling listeners.
static void registryGlobalHandler(void * data, struct wl_registry * registry, static void registryGlobalHandler(void * data, struct wl_registry * registry,
@ -279,7 +277,7 @@ static bool waylandEarlyInit(void)
return true; return true;
} }
static void waylandInit(SDL_SysWMinfo * info) static bool waylandInit(SDL_SysWMinfo * info)
{ {
memset(&wm, 0, sizeof(wm)); memset(&wm, 0, sizeof(wm));
@ -290,11 +288,29 @@ static void waylandInit(SDL_SysWMinfo * info)
wl_registry_add_listener(wm.registry, &registryListener, NULL); wl_registry_add_listener(wm.registry, &registryListener, NULL);
wl_display_roundtrip(wm.display); wl_display_roundtrip(wm.display);
if (!wm.seat || !wm.dataDeviceManager)
{
DEBUG_ERROR("Compositor missing a required interface, will not proceed");
return false;
}
if (!wm.relativePointerManager)
DEBUG_WARN("zwp_relative_pointer_manager_v1 not exported by compositor, "
"mouse will not be captured");
if (!wm.pointerConstraints)
DEBUG_WARN("zwp_pointer_constraints_v1 not exported by compositor, mouse "
"will not be captured");
if (!wm.keyboardInhibitManager)
DEBUG_WARN("zwp_keyboard_shortcuts_inhibit_manager_v1 not exported by "
"compositor, keyboard will not be grabbed");
wl_seat_add_listener(wm.seat, &seatListener, NULL); wl_seat_add_listener(wm.seat, &seatListener, NULL);
wl_display_roundtrip(wm.display); wl_display_roundtrip(wm.display);
wm.dataDevice = wl_data_device_manager_get_data_device( wm.dataDevice = wl_data_device_manager_get_data_device(
wm.dataDeviceManager, wm.seat); wm.dataDeviceManager, wm.seat);
return true;
} }
static void waylandStartup(void) static void waylandStartup(void)
@ -317,6 +333,9 @@ static const struct zwp_relative_pointer_v1_listener relativePointerListener = {
static void waylandGrabPointer(void) static void waylandGrabPointer(void)
{ {
if (!wm.relativePointerManager || !wm.pointerConstraints)
return;
if (!wm.relativePointer) if (!wm.relativePointer)
{ {
wm.relativePointer = wm.relativePointer =
@ -402,8 +421,6 @@ static bool waylandEventFilter(SDL_Event * event)
return false; return false;
} }
//asdasd
static const char * textMimetypes[] = static const char * textMimetypes[] =
{ {
"text/plain", "text/plain",

View File

@ -81,7 +81,7 @@ static void x11CBSelectionIncr(const XPropertyEvent e);
static void x11CBSelectionNotify(const XSelectionEvent e); static void x11CBSelectionNotify(const XSelectionEvent e);
static void x11CBXFixesSelectionNotify(const XFixesSelectionNotifyEvent e); static void x11CBXFixesSelectionNotify(const XFixesSelectionNotifyEvent e);
static void x11Init(SDL_SysWMinfo * info) static bool x11Init(SDL_SysWMinfo * info)
{ {
memset(&x11, 0, sizeof(x11)); memset(&x11, 0, sizeof(x11));
x11.display = info->info.x11.display; x11.display = info->info.x11.display;
@ -110,6 +110,8 @@ static void x11Init(SDL_SysWMinfo * info)
(unsigned char *)&value, (unsigned char *)&value,
1 1
); );
return true;
} }
static void x11Startup(void) static void x11Startup(void)

View File

@ -65,7 +65,7 @@ struct LG_DisplayServerOps
bool (*earlyInit)(void); bool (*earlyInit)(void);
/* called after SDL has been initialized */ /* called after SDL has been initialized */
void (*init)(SDL_SysWMinfo * info); bool (*init)(SDL_SysWMinfo * info);
/* called at startup after window creation, renderer and/or SPICE is ready */ /* called at startup after window creation, renderer and/or SPICE is ready */
void (*startup)(); void (*startup)();