mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-22 05:27:20 +00:00
[client] x11: properly detect WMEH support for focus events
This commit is contained in:
parent
a6720db749
commit
2e170ad06f
@ -22,11 +22,15 @@
|
|||||||
#define _H_X11DS_ATOMS_
|
#define _H_X11DS_ATOMS_
|
||||||
|
|
||||||
#define DEF_ATOMS() \
|
#define DEF_ATOMS() \
|
||||||
|
DEF_ATOM(_NET_SUPPORTING_WM_CHECK, True) \
|
||||||
|
DEF_ATOM(_NET_SUPPORTED, True) \
|
||||||
|
DEF_ATOM(_NET_WM_NAME, True) \
|
||||||
DEF_ATOM(_NET_REQUEST_FRAME_EXTENTS, True) \
|
DEF_ATOM(_NET_REQUEST_FRAME_EXTENTS, True) \
|
||||||
DEF_ATOM(_NET_FRAME_EXTENTS, True) \
|
DEF_ATOM(_NET_FRAME_EXTENTS, True) \
|
||||||
DEF_ATOM(_NET_WM_BYPASS_COMPOSITOR, False) \
|
DEF_ATOM(_NET_WM_BYPASS_COMPOSITOR, False) \
|
||||||
DEF_ATOM(_NET_WM_STATE, True) \
|
DEF_ATOM(_NET_WM_STATE, True) \
|
||||||
DEF_ATOM(_NET_WM_STATE_FULLSCREEN, True) \
|
DEF_ATOM(_NET_WM_STATE_FULLSCREEN, True) \
|
||||||
|
DEF_ATOM(_NET_WM_STATE_FOCUSED, True) \
|
||||||
DEF_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ, True) \
|
DEF_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ, True) \
|
||||||
DEF_ATOM(_NET_WM_STATE_MAXIMIZED_VERT, True) \
|
DEF_ATOM(_NET_WM_STATE_MAXIMIZED_VERT, True) \
|
||||||
DEF_ATOM(_NET_WM_WINDOW_TYPE, True) \
|
DEF_ATOM(_NET_WM_WINDOW_TYPE, True) \
|
||||||
|
@ -82,6 +82,7 @@ static void x11SetFullscreen(bool fs);
|
|||||||
static int x11EventThread(void * unused);
|
static int x11EventThread(void * unused);
|
||||||
static void x11XInputEvent(XGenericEventCookie *cookie);
|
static void x11XInputEvent(XGenericEventCookie *cookie);
|
||||||
static void x11XPresentEvent(XGenericEventCookie *cookie);
|
static void x11XPresentEvent(XGenericEventCookie *cookie);
|
||||||
|
static void x11GrabPointer(void);
|
||||||
|
|
||||||
static void x11DoPresent(void)
|
static void x11DoPresent(void)
|
||||||
{
|
{
|
||||||
@ -167,6 +168,69 @@ static bool x11EarlyInit(void)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void x11CheckEWMHSupport(void)
|
||||||
|
{
|
||||||
|
if (x11atoms._NET_SUPPORTING_WM_CHECK == None ||
|
||||||
|
x11atoms._NET_SUPPORTED == None)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Atom type;
|
||||||
|
int fmt;
|
||||||
|
unsigned long num, bytes;
|
||||||
|
unsigned char *data;
|
||||||
|
|
||||||
|
if (XGetWindowProperty(x11.display, DefaultRootWindow(x11.display),
|
||||||
|
x11atoms._NET_SUPPORTING_WM_CHECK, 0, ~0L, False, XA_WINDOW,
|
||||||
|
&type, &fmt, &num, &bytes, &data) != Success)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
Window * windowFromRoot = (Window *)data;
|
||||||
|
|
||||||
|
if (XGetWindowProperty(x11.display, *windowFromRoot,
|
||||||
|
x11atoms._NET_SUPPORTING_WM_CHECK, 0, ~0L, False, XA_WINDOW,
|
||||||
|
&type, &fmt, &num, &bytes, &data) != Success)
|
||||||
|
goto out_root;
|
||||||
|
|
||||||
|
Window * windowFromChild = (Window *)data;
|
||||||
|
if (*windowFromChild != *windowFromRoot)
|
||||||
|
goto out_child;
|
||||||
|
|
||||||
|
if (XGetWindowProperty(x11.display, DefaultRootWindow(x11.display),
|
||||||
|
x11atoms._NET_SUPPORTED, 0, ~0L, False, AnyPropertyType,
|
||||||
|
&type, &fmt, &num, &bytes, &data) != Success)
|
||||||
|
goto out_child;
|
||||||
|
|
||||||
|
Atom * supported = (Atom *)data;
|
||||||
|
unsigned long supportedCount = num;
|
||||||
|
|
||||||
|
if (XGetWindowProperty(x11.display, *windowFromRoot,
|
||||||
|
x11atoms._NET_WM_NAME, 0, ~0L, False, AnyPropertyType,
|
||||||
|
&type, &fmt, &num, &bytes, &data) != Success)
|
||||||
|
goto out_supported;
|
||||||
|
|
||||||
|
char * wmName = (char *)data;
|
||||||
|
|
||||||
|
for(unsigned long i = 0; i < supportedCount; ++i)
|
||||||
|
{
|
||||||
|
if (supported[i] == x11atoms._NET_WM_STATE_FOCUSED)
|
||||||
|
x11.ewmhHasFocusEvent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_INFO("EWMH-complient window manager detected: %s", wmName);
|
||||||
|
x11.ewmhSupport = true;
|
||||||
|
|
||||||
|
|
||||||
|
XFree(wmName);
|
||||||
|
out_supported:
|
||||||
|
XFree(supported);
|
||||||
|
out_child:
|
||||||
|
XFree(windowFromChild);
|
||||||
|
out_root:
|
||||||
|
XFree(windowFromRoot);
|
||||||
|
out:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static bool x11Init(const LG_DSInitParams params)
|
static bool x11Init(const LG_DSInitParams params)
|
||||||
{
|
{
|
||||||
XIDeviceInfo *devinfo;
|
XIDeviceInfo *devinfo;
|
||||||
@ -272,6 +336,9 @@ static bool x11Init(const LG_DSInitParams params)
|
|||||||
X11AtomsInit();
|
X11AtomsInit();
|
||||||
XSetWMProtocols(x11.display, x11.window, &x11atoms.WM_DELETE_WINDOW, 1);
|
XSetWMProtocols(x11.display, x11.window, &x11atoms.WM_DELETE_WINDOW, 1);
|
||||||
|
|
||||||
|
// check for Extended Window Manager Hints support
|
||||||
|
x11CheckEWMHSupport();
|
||||||
|
|
||||||
if (params.borderless)
|
if (params.borderless)
|
||||||
{
|
{
|
||||||
if (x11atoms._MOTIF_WM_HINTS)
|
if (x11atoms._MOTIF_WM_HINTS)
|
||||||
@ -457,8 +524,12 @@ static bool x11Init(const LG_DSInitParams params)
|
|||||||
eventmask.mask_len = sizeof(mask);
|
eventmask.mask_len = sizeof(mask);
|
||||||
eventmask.mask = mask;
|
eventmask.mask = mask;
|
||||||
|
|
||||||
XISetMask(mask, XI_FocusIn );
|
if (!x11.ewmhHasFocusEvent)
|
||||||
XISetMask(mask, XI_FocusOut );
|
{
|
||||||
|
XISetMask(mask, XI_FocusIn );
|
||||||
|
XISetMask(mask, XI_FocusOut);
|
||||||
|
}
|
||||||
|
|
||||||
XISetMask(mask, XI_Enter );
|
XISetMask(mask, XI_Enter );
|
||||||
XISetMask(mask, XI_Leave );
|
XISetMask(mask, XI_Leave );
|
||||||
XISetMask(mask, XI_Motion );
|
XISetMask(mask, XI_Motion );
|
||||||
@ -839,6 +910,7 @@ static int x11EventThread(void * unused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case PropertyNotify:
|
case PropertyNotify:
|
||||||
|
|
||||||
// ignore property events that are not for us
|
// ignore property events that are not for us
|
||||||
if (xe.xproperty.display != x11.display ||
|
if (xe.xproperty.display != x11.display ||
|
||||||
xe.xproperty.window != x11.window ||
|
xe.xproperty.window != x11.window ||
|
||||||
@ -860,11 +932,20 @@ static int x11EventThread(void * unused)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
bool fullscreen = false;
|
bool fullscreen = false;
|
||||||
for(int i = 0; i < num; ++i)
|
bool focused = false;
|
||||||
|
for(unsigned long i = 0; i < num; ++i)
|
||||||
{
|
{
|
||||||
Atom prop = ((Atom *)data)[i];
|
Atom prop = ((Atom *)data)[i];
|
||||||
if (prop == x11atoms._NET_WM_STATE_FULLSCREEN)
|
if (prop == x11atoms._NET_WM_STATE_FULLSCREEN)
|
||||||
fullscreen = true;
|
fullscreen = true;
|
||||||
|
else if (prop == x11atoms._NET_WM_STATE_FOCUSED)
|
||||||
|
focused = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x11.focused != focused)
|
||||||
|
{
|
||||||
|
x11.focused = focused;
|
||||||
|
app_handleFocusEvent(focused);
|
||||||
}
|
}
|
||||||
|
|
||||||
x11.fullscreen = fullscreen;
|
x11.fullscreen = fullscreen;
|
||||||
@ -941,6 +1022,9 @@ static void x11XInputEvent(XGenericEventCookie *cookie)
|
|||||||
{
|
{
|
||||||
case XI_FocusIn:
|
case XI_FocusIn:
|
||||||
{
|
{
|
||||||
|
if (x11.ewmhHasFocusEvent)
|
||||||
|
return;
|
||||||
|
|
||||||
atomic_store(&x11.lastWMEvent, microtime());
|
atomic_store(&x11.lastWMEvent, microtime());
|
||||||
if (x11.focused)
|
if (x11.focused)
|
||||||
return;
|
return;
|
||||||
@ -959,6 +1043,9 @@ static void x11XInputEvent(XGenericEventCookie *cookie)
|
|||||||
|
|
||||||
case XI_FocusOut:
|
case XI_FocusOut:
|
||||||
{
|
{
|
||||||
|
if (x11.ewmhHasFocusEvent)
|
||||||
|
return;
|
||||||
|
|
||||||
atomic_store(&x11.lastWMEvent, microtime());
|
atomic_store(&x11.lastWMEvent, microtime());
|
||||||
if (!x11.focused)
|
if (!x11.focused)
|
||||||
return;
|
return;
|
||||||
|
@ -54,6 +54,11 @@ struct X11DSState
|
|||||||
Window window;
|
Window window;
|
||||||
XVisualInfo * visual;
|
XVisualInfo * visual;
|
||||||
|
|
||||||
|
//Extended Window Manager Hints
|
||||||
|
//ref: https://specifications.freedesktop.org/wm-spec/latest/
|
||||||
|
bool ewmhSupport;
|
||||||
|
bool ewmhHasFocusEvent;
|
||||||
|
|
||||||
_Atomic(uint64_t) lastWMEvent;
|
_Atomic(uint64_t) lastWMEvent;
|
||||||
bool invalidateAll;
|
bool invalidateAll;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user