From 0a5e65dc06f5bb07f2d02974727d9df0a101032a Mon Sep 17 00:00:00 2001 From: Brandon Wright Date: Mon, 2 Apr 2018 20:01:14 -0500 Subject: [PATCH] Add workarounds based on window manager for override-redirect. --- gfx/common/x11_common.c | 62 ++++++++++++++++++++++++++++++++++ gfx/common/x11_common.h | 2 ++ gfx/drivers_context/x_ctx.c | 18 ++++++++-- gfx/drivers_context/xegl_ctx.c | 18 ++++++++-- 4 files changed, 94 insertions(+), 6 deletions(-) diff --git a/gfx/common/x11_common.c b/gfx/common/x11_common.c index 57133f344f..1ab16b90b7 100644 --- a/gfx/common/x11_common.c +++ b/gfx/common/x11_common.c @@ -685,3 +685,65 @@ void x11_event_queue_check(XEvent *event) XIfEvent(g_x11_dpy, event, x11_wait_notify, NULL); } +char *x11_get_wm_name(Display *dpy) +{ + Atom XA_NET_SUPPORTING_WM_CHECK = XInternAtom(g_x11_dpy, "_NET_SUPPORTING_WM_CHECK", False); + Atom XA_NET_WM_NAME = XInternAtom(g_x11_dpy, "_NET_WM_NAME", False); + Atom XA_UTF8_STRING = XInternAtom(g_x11_dpy, "UTF8_STRING", False); + int status; + Atom type; + int format; + unsigned long nitems; + unsigned long bytes_after; + unsigned char *propdata; + char *title; + Window window; + + if (!XA_NET_SUPPORTING_WM_CHECK || !XA_NET_WM_NAME) + return NULL; + + status = XGetWindowProperty(dpy, + DefaultRootWindow(dpy), + XA_NET_SUPPORTING_WM_CHECK, + 0, + 1, + False, + XA_WINDOW, + &type, + &format, + &nitems, + &bytes_after, + &propdata); + + if (status == Success && propdata) + window = ((Window *) propdata)[0]; + else + return NULL; + + XFree(propdata); + + status = XGetWindowProperty(dpy, + window, + XA_NET_WM_NAME, + 0, + 8192, + False, + XA_UTF8_STRING, + &type, + &format, + &nitems, + &bytes_after, + &propdata); + + if (status == Success && propdata) + { + title = strdup((char *) propdata); + } + else + return NULL; + + XFree(propdata); + + return title; +} + diff --git a/gfx/common/x11_common.h b/gfx/common/x11_common.h index 20d8d49080..ec4fa0dc28 100644 --- a/gfx/common/x11_common.h +++ b/gfx/common/x11_common.h @@ -75,5 +75,7 @@ void x11_install_quit_atom(void); void x11_event_queue_check(XEvent *event); +char *x11_get_wm_name(Display *dpy); + #endif diff --git a/gfx/drivers_context/x_ctx.c b/gfx/drivers_context/x_ctx.c index 2940b50989..387336f6a9 100644 --- a/gfx/drivers_context/x_ctx.c +++ b/gfx/drivers_context/x_ctx.c @@ -632,6 +632,7 @@ static bool gfx_ctx_x_set_video_mode(void *data, int y_off = 0; XVisualInfo *vi = NULL; XSetWindowAttributes swa = {0}; + char *wm_name = NULL; int (*old_handler)(Display*, XErrorEvent*) = NULL; gfx_ctx_x_data_t *x = (gfx_ctx_x_data_t*)data; Atom net_wm_icon = XInternAtom(g_x11_dpy, "_NET_WM_ICON", False); @@ -679,6 +680,7 @@ static bool gfx_ctx_x_set_video_mode(void *data, swa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | LeaveWindowMask | EnterWindowMask | ButtonReleaseMask | ButtonPressMask; + swa.override_redirect = False; if (fullscreen && !windowed_full) { @@ -691,7 +693,18 @@ static bool gfx_ctx_x_set_video_mode(void *data, RARCH_ERR("[GLX]: Entering true fullscreen failed. Will attempt windowed mode.\n"); } - swa.override_redirect = true_full ? True : False; + wm_name = x11_get_wm_name(g_x11_dpy); + if (wm_name) + { + RARCH_LOG("[GLX]: Window manager is %s.\n", wm_name); + + if (true_full && strcasestr(wm_name, "xfwm")) + { + RARCH_LOG("[GLX]: Using override-redirect workaround.\n"); + swa.override_redirect = True; + } + free(wm_name); + } if (video_info->monitor_index) g_x11_screen = video_info->monitor_index - 1; @@ -722,7 +735,7 @@ static bool gfx_ctx_x_set_video_mode(void *data, g_x11_win = XCreateWindow(g_x11_dpy, RootWindow(g_x11_dpy, vi->screen), x_off, y_off, width, height, 0, vi->depth, InputOutput, vi->visual, - CWBorderPixel | CWColormap | CWEventMask, + CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &swa); XSetWindowBackground(g_x11_dpy, g_x11_win, 0); @@ -781,7 +794,6 @@ static bool gfx_ctx_x_set_video_mode(void *data, RARCH_LOG("[GLX]: Using true fullscreen.\n"); XMapRaised(g_x11_dpy, g_x11_win); x11_set_net_wm_fullscreen(g_x11_dpy, g_x11_win); - XChangeWindowAttributes(g_x11_dpy, g_x11_win, CWOverrideRedirect, &swa); } else if (fullscreen) { diff --git a/gfx/drivers_context/xegl_ctx.c b/gfx/drivers_context/xegl_ctx.c index 4338545999..2f120ad956 100644 --- a/gfx/drivers_context/xegl_ctx.c +++ b/gfx/drivers_context/xegl_ctx.c @@ -272,6 +272,7 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, XVisualInfo temp = {0}; XSetWindowAttributes swa = {0}; XVisualInfo *vi = NULL; + char *wm_name = NULL; xegl_ctx_data_t *xegl = (xegl_ctx_data_t*)data; settings_t *settings = config_get_ptr(); @@ -298,6 +299,7 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, vi->visual, AllocNone); swa.event_mask = StructureNotifyMask | KeyPressMask | ButtonPressMask | ButtonReleaseMask | KeyReleaseMask; + swa.override_redirect = False; if (fullscreen && !video_info->windowed_fullscreen) { @@ -310,7 +312,18 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, RARCH_ERR("[X/EGL]: Entering true fullscreen failed. Will attempt windowed mode.\n"); } - swa.override_redirect = true_full ? True : False; + wm_name = x11_get_wm_name(g_x11_dpy); + if (wm_name) + { + RARCH_LOG("[X/EGL]: Window manager is %s.\n", wm_name); + + if (true_full && strcasestr(wm_name, "xfwm")) + { + RARCH_LOG("[X/EGL]: Using override-redirect workaround.\n"); + swa.override_redirect = True; + } + free(wm_name); + } if (video_info->monitor_index) g_x11_screen = video_info->monitor_index - 1; @@ -341,7 +354,7 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, g_x11_win = XCreateWindow(g_x11_dpy, RootWindow(g_x11_dpy, vi->screen), x_off, y_off, width, height, 0, vi->depth, InputOutput, vi->visual, - CWBorderPixel | CWColormap | CWEventMask, + CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &swa); XSetWindowBackground(g_x11_dpy, g_x11_win, 0); @@ -375,7 +388,6 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, RARCH_LOG("[X/EGL]: Using true fullscreen.\n"); XMapRaised(g_x11_dpy, g_x11_win); x11_set_net_wm_fullscreen(g_x11_dpy, g_x11_win); - XChangeWindowAttributes(g_x11_dpy, g_x11_win, CWOverrideRedirect, &swa); } else if (fullscreen) {