Merge pull request #69707 from bruvzg/x11_exfs

[Linux/X11] Split fullscreen mode into `WINDOW_MODE_EXCLUSIVE_FULLSCREEN` and `WINDOW_MODE_FULLSCREEN` to improve multi-window handling.
This commit is contained in:
Rémi Verschelde 2022-12-07 14:29:37 +01:00
commit 39ad411369
No known key found for this signature in database
GPG key ID: C3336907360768E1
3 changed files with 36 additions and 14 deletions

View file

@ -1582,7 +1582,7 @@ void DisplayServerX11::_update_size_hints(WindowID p_window) {
xsh->width = wd.size.width;
xsh->height = wd.size.height;
if (window_mode == WINDOW_MODE_FULLSCREEN) {
if (window_mode == WINDOW_MODE_FULLSCREEN || window_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) {
// Do not set any other hints to prevent the window manager from ignoring the fullscreen flags
} else if (window_get_flag(WINDOW_FLAG_RESIZE_DISABLED, p_window)) {
// If resizing is disabled, use the forced size
@ -1949,7 +1949,7 @@ void DisplayServerX11::_validate_mode_on_map(WindowID p_window) {
// Check if we applied any window modes that didn't take effect while unmapped
const WindowData &wd = windows[p_window];
if (wd.fullscreen && !_window_fullscreen_check(p_window)) {
_set_wm_fullscreen(p_window, true);
_set_wm_fullscreen(p_window, true, wd.exclusive_fullscreen);
} else if (wd.maximized && !_window_maximize_check(p_window, "_NET_WM_STATE")) {
_set_wm_maximized(p_window, true);
} else if (wd.minimized && !_window_minimize_check(p_window)) {
@ -2024,7 +2024,7 @@ void DisplayServerX11::_set_wm_minimized(WindowID p_window, bool p_enabled) {
wd.minimized = p_enabled;
}
void DisplayServerX11::_set_wm_fullscreen(WindowID p_window, bool p_enabled) {
void DisplayServerX11::_set_wm_fullscreen(WindowID p_window, bool p_enabled, bool p_exclusive) {
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
@ -2063,7 +2063,14 @@ void DisplayServerX11::_set_wm_fullscreen(WindowID p_window, bool p_enabled) {
// set bypass compositor hint
Atom bypass_compositor = XInternAtom(x11_display, "_NET_WM_BYPASS_COMPOSITOR", False);
unsigned long compositing_disable_on = p_enabled ? 1 : 0;
unsigned long compositing_disable_on = 0; // Use default.
if (p_enabled) {
if (p_exclusive) {
compositing_disable_on = 1; // Force composition OFF to reduce overhead.
} else {
compositing_disable_on = 2; // Force composition ON to allow popup windows.
}
}
if (bypass_compositor != None) {
XChangeProperty(x11_display, wd.x11_window, bypass_compositor, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&compositing_disable_on, 1);
}
@ -2109,8 +2116,9 @@ void DisplayServerX11::window_set_mode(WindowMode p_mode, WindowID p_window) {
case WINDOW_MODE_FULLSCREEN: {
//Remove full-screen
wd.fullscreen = false;
wd.exclusive_fullscreen = false;
_set_wm_fullscreen(p_window, false);
_set_wm_fullscreen(p_window, false, false);
//un-maximize required for always on top
bool on_top = window_get_flag(WINDOW_FLAG_ALWAYS_ON_TOP, p_window);
@ -2143,7 +2151,13 @@ void DisplayServerX11::window_set_mode(WindowMode p_mode, WindowID p_window) {
}
wd.fullscreen = true;
_set_wm_fullscreen(p_window, true);
if (p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) {
wd.exclusive_fullscreen = true;
_set_wm_fullscreen(p_window, true, true);
} else {
wd.exclusive_fullscreen = false;
_set_wm_fullscreen(p_window, true, false);
}
} break;
case WINDOW_MODE_MAXIMIZED: {
_set_wm_maximized(p_window, true);
@ -2158,7 +2172,11 @@ DisplayServer::WindowMode DisplayServerX11::window_get_mode(WindowID p_window) c
const WindowData &wd = windows[p_window];
if (wd.fullscreen) { //if fullscreen, it's not in another mode
return WINDOW_MODE_FULLSCREEN;
if (wd.exclusive_fullscreen) {
return WINDOW_MODE_EXCLUSIVE_FULLSCREEN;
} else {
return WINDOW_MODE_FULLSCREEN;
}
}
// Test maximized.

View file

@ -159,6 +159,7 @@ class DisplayServerX11 : public DisplayServer {
//better to guess on the fly, given WM can change it
//WindowMode mode;
bool fullscreen = false; //OS can't exit from this mode
bool exclusive_fullscreen = false;
bool on_top = false;
bool borderless = false;
bool resize_disabled = false;
@ -283,7 +284,7 @@ class DisplayServerX11 : public DisplayServer {
bool _window_minimize_check(WindowID p_window) const;
void _validate_mode_on_map(WindowID p_window);
void _update_size_hints(WindowID p_window);
void _set_wm_fullscreen(WindowID p_window, bool p_enabled);
void _set_wm_fullscreen(WindowID p_window, bool p_enabled, bool p_exclusive);
void _set_wm_maximized(WindowID p_window, bool p_enabled);
void _set_wm_minimized(WindowID p_window, bool p_enabled);