diff --git a/gfx/common/x11_common.c b/gfx/common/x11_common.c index fd2832536b..b1eb6d2886 100644 --- a/gfx/common/x11_common.c +++ b/gfx/common/x11_common.c @@ -107,7 +107,48 @@ void x11_show_mouse(Display *dpy, Window win, bool state) x11_hide_mouse(dpy, win); } -void x11_windowed_fullscreen(Display *dpy, Window win) +static bool x11_check_atom_supported(Display *dpy, Atom atom) +{ + Atom XA_NET_SUPPORTED = XInternAtom(dpy, "_NET_SUPPORTED", True); + Atom type; + int format; + unsigned long nitems; + unsigned long bytes_after; + Atom *prop; + int i; + + if (XA_NET_SUPPORTED == None) + return false; + + XGetWindowProperty(dpy, DefaultRootWindow(dpy), XA_NET_SUPPORTED, 0, UINT_MAX, False, XA_ATOM, &type, &format,&nitems, &bytes_after, (unsigned char **) &prop); + + if (!prop || type != XA_ATOM) + { + return false; + } + + for (i = 0; i < nitems; i++) + { + if (prop[i] == atom) + { + XFree(prop); + return true; + } + } + + XFree(prop); + + return false; +} + +bool x11_has_net_wm_fullscreen(Display *dpy) +{ + XA_NET_WM_STATE_FULLSCREEN = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); + + return x11_check_atom_supported(dpy, XA_NET_WM_STATE_FULLSCREEN); +} + +void x11_set_net_wm_fullscreen(Display *dpy, Window win) { XEvent xev = {0}; diff --git a/gfx/common/x11_common.h b/gfx/common/x11_common.h index 23fc4898bc..54718b8ce8 100644 --- a/gfx/common/x11_common.h +++ b/gfx/common/x11_common.h @@ -29,7 +29,8 @@ extern Colormap g_x11_cmap; extern unsigned g_x11_screen; void x11_show_mouse(Display *dpy, Window win, bool state); -void x11_windowed_fullscreen(Display *dpy, Window win); +bool x11_has_net_wm_fullscreen(Display *dpy); +void x11_set_net_wm_fullscreen(Display *dpy, Window win); void x11_suspend_screensaver(Window win, bool enable); bool x11_enter_fullscreen(video_frame_info_t *video_info, Display *dpy, unsigned width, diff --git a/gfx/drivers/xvideo.c b/gfx/drivers/xvideo.c index d516035c45..0479fa73bb 100644 --- a/gfx/drivers/xvideo.c +++ b/gfx/drivers/xvideo.c @@ -583,7 +583,7 @@ static void *xv_init(const video_info_t *video, if (video->fullscreen) { - x11_windowed_fullscreen(g_x11_dpy, g_x11_win); + x11_set_net_wm_fullscreen(g_x11_dpy, g_x11_win); x11_show_mouse(g_x11_dpy, g_x11_win, false); } diff --git a/gfx/drivers_context/x_ctx.c b/gfx/drivers_context/x_ctx.c index 45e6dd02ac..eec1f3dc2b 100644 --- a/gfx/drivers_context/x_ctx.c +++ b/gfx/drivers_context/x_ctx.c @@ -37,6 +37,7 @@ #endif #include +#include #include "../../configuration.h" #include "../../frontend/frontend_driver.h" @@ -678,7 +679,6 @@ static bool gfx_ctx_x_set_video_mode(void *data, swa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | LeaveWindowMask | EnterWindowMask | ButtonReleaseMask | ButtonPressMask; - swa.override_redirect = fullscreen ? True : False; if (fullscreen && !windowed_full) { @@ -691,6 +691,8 @@ 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 = (!x11_has_net_wm_fullscreen(g_x11_dpy) && true_full) ? True : False; + if (video_info->monitor_index) g_x11_screen = video_info->monitor_index - 1; @@ -721,7 +723,7 @@ static bool gfx_ctx_x_set_video_mode(void *data, x_off, y_off, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | - (true_full ? CWOverrideRedirect : 0), &swa); + CWOverrideRedirect, &swa); XSetWindowBackground(g_x11_dpy, g_x11_win, 0); XChangeProperty(g_x11_dpy, g_x11_win, net_wm_icon, cardinal, 32, PropModeReplace, (const unsigned char*)retroarch_icon_data, sizeof(retroarch_icon_data) / sizeof(*retroarch_icon_data)); @@ -778,6 +780,8 @@ static bool gfx_ctx_x_set_video_mode(void *data, { RARCH_LOG("[GLX]: Using true fullscreen.\n"); XMapRaised(g_x11_dpy, g_x11_win); + if (swa.override_redirect == False) + x11_set_net_wm_fullscreen(g_x11_dpy, g_x11_win); } else if (fullscreen) { @@ -792,7 +796,7 @@ static bool gfx_ctx_x_set_video_mode(void *data, * x_off and y_off usually get ignored in XCreateWindow(). */ x11_move_window(g_x11_dpy, g_x11_win, x_off, y_off, width, height); - x11_windowed_fullscreen(g_x11_dpy, g_x11_win); + x11_set_net_wm_fullscreen(g_x11_dpy, g_x11_win); } else { diff --git a/gfx/drivers_context/xegl_ctx.c b/gfx/drivers_context/xegl_ctx.c index c8dbd5432d..e791bf1f42 100644 --- a/gfx/drivers_context/xegl_ctx.c +++ b/gfx/drivers_context/xegl_ctx.c @@ -297,7 +297,6 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, vi->visual, AllocNone); swa.event_mask = StructureNotifyMask | KeyPressMask | ButtonPressMask | ButtonReleaseMask | KeyReleaseMask; - swa.override_redirect = fullscreen ? True : False; if (fullscreen && !video_info->windowed_fullscreen) { @@ -310,6 +309,8 @@ 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 = (!x11_has_net_wm_fullscreen(g_x11_dpy) && true_full) ? True : False; + if (video_info->monitor_index) g_x11_screen = video_info->monitor_index - 1; @@ -340,7 +341,7 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, x_off, y_off, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | - (true_full ? CWOverrideRedirect : 0), &swa); + CWOverrideRedirect, &swa); XSetWindowBackground(g_x11_dpy, g_x11_win, 0); if (fullscreen && config_get_ptr()->bools.video_disable_composition) @@ -372,6 +373,8 @@ 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); + if (swa.override_redirect == False) + x11_set_net_wm_fullscreen(g_x11_dpy, g_x11_win); } else if (fullscreen) { @@ -385,7 +388,7 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, * x_off and y_off usually get ignored in XCreateWindow(). */ x11_move_window(g_x11_dpy, g_x11_win, x_off, y_off, width, height); - x11_windowed_fullscreen(g_x11_dpy, g_x11_win); + x11_set_net_wm_fullscreen(g_x11_dpy, g_x11_win); } else {