[client] ds: add surface-only warp variant

This commit converts the output of ds->getProp(LG_DS_WARP_SUPPORT) to
an enum containing three items:

* LG_DS_WARP_NONE: warp is not supported at all
* LG_DS_WARP_SURFACE: warp is possible, but only inside the window
* LG_DS_WARP_SCREEN: warp is possible anywhere on the screen

LG_DS_WARP_NONE corresponds to the old false return value, and
LG_DS_WARP_SCREEN corresponds to the old true return value.

LG_DS_WARP_SURFACE is designed for Wayland, where warping is possible,
but only in our window. In this case, since we cannot warp outside
the window, we can warp the cursor to the edge when we attempt to exit.
If the cursor leaves, the normal leave routine gets called, and the
cursor disappears. If the cursor does not end up leaving, we grab it
again.
This commit is contained in:
Quantum
2021-02-15 19:40:44 -05:00
committed by Geoffrey McRae
parent d86014e5ff
commit 270631f1b9
4 changed files with 109 additions and 64 deletions

View File

@@ -1015,7 +1015,7 @@ static bool waylandGetProp(LG_DSProperty prop, void * ret)
{
if (prop == LG_DS_WARP_SUPPORT)
{
*(bool*)ret = false;
*(enum LG_DSWarpSupport*)ret = LG_DS_WARP_NONE;
return true;
}

View File

@@ -449,52 +449,62 @@ static void x11Free(void)
static bool x11GetProp(LG_DSProperty prop, void *ret)
{
if (prop != LG_DS_MAX_MULTISAMPLE)
return false;
Display * dpy = XOpenDisplay(NULL);
if (!dpy)
return false;
XVisualInfo queryTemplate;
queryTemplate.screen = 0;
int visualCount;
int maxSamples = -1;
XVisualInfo * visuals = XGetVisualInfo(dpy, VisualScreenMask,
&queryTemplate, &visualCount);
for (int i = 0; i < visualCount; i++)
switch (prop)
{
XVisualInfo * visual = &visuals[i];
case LG_DS_WARP_SUPPORT:
*(enum LG_DSWarpSupport*)ret = LG_DS_WARP_SCREEN;
return true;
int res, supportsGL;
// Some GLX visuals do not use GL, and these must be ignored in our search.
if ((res = glXGetConfig(dpy, visual, GLX_USE_GL, &supportsGL)) != 0 ||
!supportsGL)
continue;
case LG_DS_MAX_MULTISAMPLE:
{
Display * dpy = XOpenDisplay(NULL);
if (!dpy)
return false;
int sampleBuffers, samples;
if ((res = glXGetConfig(dpy, visual, GLX_SAMPLE_BUFFERS, &sampleBuffers)) != 0)
continue;
XVisualInfo queryTemplate;
queryTemplate.screen = 0;
// Will be 1 if this visual supports multisampling
if (sampleBuffers != 1)
continue;
int visualCount;
int maxSamples = -1;
XVisualInfo * visuals = XGetVisualInfo(dpy, VisualScreenMask,
&queryTemplate, &visualCount);
if ((res = glXGetConfig(dpy, visual, GLX_SAMPLES, &samples)) != 0)
continue;
for (int i = 0; i < visualCount; i++)
{
XVisualInfo * visual = &visuals[i];
// Track the largest number of samples supported
if (samples > maxSamples)
maxSamples = samples;
int res, supportsGL;
// Some GLX visuals do not use GL, and these must be ignored in our search.
if ((res = glXGetConfig(dpy, visual, GLX_USE_GL, &supportsGL)) != 0 ||
!supportsGL)
continue;
int sampleBuffers, samples;
if ((res = glXGetConfig(dpy, visual, GLX_SAMPLE_BUFFERS, &sampleBuffers)) != 0)
continue;
// Will be 1 if this visual supports multisampling
if (sampleBuffers != 1)
continue;
if ((res = glXGetConfig(dpy, visual, GLX_SAMPLES, &samples)) != 0)
continue;
// Track the largest number of samples supported
if (samples > maxSamples)
maxSamples = samples;
}
XFree(visuals);
XCloseDisplay(dpy);
*(int*)ret = maxSamples;
return true;
}
default:
return true;
}
XFree(visuals);
XCloseDisplay(dpy);
*(int*)ret = maxSamples;
return true;
}
static int x11EventThread(void * unused)