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:
commit
39ad411369
3 changed files with 36 additions and 14 deletions
|
@ -1633,14 +1633,17 @@
|
||||||
Maximized window mode, i.e. [Window] will occupy whole screen area except task bar and still display its borders. Normally happens when the minimize button is pressed.
|
Maximized window mode, i.e. [Window] will occupy whole screen area except task bar and still display its borders. Normally happens when the minimize button is pressed.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="WINDOW_MODE_FULLSCREEN" value="3" enum="WindowMode">
|
<constant name="WINDOW_MODE_FULLSCREEN" value="3" enum="WindowMode">
|
||||||
Full screen window mode. Note that this is not [i]exclusive[/i] full screen. On Windows and Linux (X11), a borderless window is used to emulate full screen. On macOS, a new desktop is used to display the running project.
|
Full screen mode with full multi-window support.
|
||||||
Regardless of the platform, enabling full screen will change the window size to match the monitor's size. Therefore, make sure your project supports [url=$DOCS_URL/tutorials/rendering/multiple_resolutions.html]multiple resolutions[/url] when enabling full screen mode.
|
Full screen window cover the entire display area of a screen, have no border or decorations. Display video mode is not changed.
|
||||||
|
[b]Note:[/b] Regardless of the platform, enabling full screen will change the window size to match the monitor's size. Therefore, make sure your project supports [url=$DOCS_URL/tutorials/rendering/multiple_resolutions.html]multiple resolutions[/url] when enabling full screen mode.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="WINDOW_MODE_EXCLUSIVE_FULLSCREEN" value="4" enum="WindowMode">
|
<constant name="WINDOW_MODE_EXCLUSIVE_FULLSCREEN" value="4" enum="WindowMode">
|
||||||
Exclusive full screen window mode. This mode is implemented on Windows and macOS only. On other platforms, it is equivalent to [constant WINDOW_MODE_FULLSCREEN].
|
A single window full screen mode. This mode has less overhead, but only one window can be open on a given screen at a time (opening a child window or application switching will trigger a full screen transition).
|
||||||
[b]On Windows:[/b] Only one window in exclusive full screen mode can be visible on a given screen at a time. If multiple windows are in exclusive full screen mode for the same screen, the last one being set to this mode takes precedence.
|
Full screen window cover the entire display area of a screen, have no border or decorations. Display video mode is not changed.
|
||||||
[b]On macOS:[/b] Exclusive full-screen mode prevents Dock and Menu from showing up when the mouse pointer is hovering the edge of the screen.
|
[b]On Windows:[/b] Depending on video driver, full screen transition might cause screens to go black for a moment.
|
||||||
Regardless of the platform, enabling full screen will change the window size to match the monitor's size. Therefore, make sure your project supports [url=$DOCS_URL/tutorials/rendering/multiple_resolutions.html]multiple resolutions[/url] when enabling full screen mode.
|
[b]On macOS:[/b] Exclusive full screen mode prevents Dock and Menu from showing up when the mouse pointer is hovering the edge of the screen.
|
||||||
|
[b]On Linux (X11):[/b] Exclusive full screen mode bypasses compositor.
|
||||||
|
[b]Note:[/b] Regardless of the platform, enabling full screen will change the window size to match the monitor's size. Therefore, make sure your project supports [url=$DOCS_URL/tutorials/rendering/multiple_resolutions.html]multiple resolutions[/url] when enabling full screen mode.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="WINDOW_FLAG_RESIZE_DISABLED" value="0" enum="WindowFlags">
|
<constant name="WINDOW_FLAG_RESIZE_DISABLED" value="0" enum="WindowFlags">
|
||||||
The window can't be resizing by dragging its resize grip. It's still possible to resize the window using [method window_set_size]. This flag is ignored for full screen windows.
|
The window can't be resizing by dragging its resize grip. It's still possible to resize the window using [method window_set_size]. This flag is ignored for full screen windows.
|
||||||
|
|
|
@ -1582,7 +1582,7 @@ void DisplayServerX11::_update_size_hints(WindowID p_window) {
|
||||||
xsh->width = wd.size.width;
|
xsh->width = wd.size.width;
|
||||||
xsh->height = wd.size.height;
|
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
|
// 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)) {
|
} else if (window_get_flag(WINDOW_FLAG_RESIZE_DISABLED, p_window)) {
|
||||||
// If resizing is disabled, use the forced size
|
// 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
|
// Check if we applied any window modes that didn't take effect while unmapped
|
||||||
const WindowData &wd = windows[p_window];
|
const WindowData &wd = windows[p_window];
|
||||||
if (wd.fullscreen && !_window_fullscreen_check(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")) {
|
} else if (wd.maximized && !_window_maximize_check(p_window, "_NET_WM_STATE")) {
|
||||||
_set_wm_maximized(p_window, true);
|
_set_wm_maximized(p_window, true);
|
||||||
} else if (wd.minimized && !_window_minimize_check(p_window)) {
|
} 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;
|
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));
|
ERR_FAIL_COND(!windows.has(p_window));
|
||||||
WindowData &wd = windows[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
|
// set bypass compositor hint
|
||||||
Atom bypass_compositor = XInternAtom(x11_display, "_NET_WM_BYPASS_COMPOSITOR", False);
|
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) {
|
if (bypass_compositor != None) {
|
||||||
XChangeProperty(x11_display, wd.x11_window, bypass_compositor, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&compositing_disable_on, 1);
|
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: {
|
case WINDOW_MODE_FULLSCREEN: {
|
||||||
//Remove full-screen
|
//Remove full-screen
|
||||||
wd.fullscreen = false;
|
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
|
//un-maximize required for always on top
|
||||||
bool on_top = window_get_flag(WINDOW_FLAG_ALWAYS_ON_TOP, p_window);
|
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;
|
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;
|
} break;
|
||||||
case WINDOW_MODE_MAXIMIZED: {
|
case WINDOW_MODE_MAXIMIZED: {
|
||||||
_set_wm_maximized(p_window, true);
|
_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];
|
const WindowData &wd = windows[p_window];
|
||||||
|
|
||||||
if (wd.fullscreen) { //if fullscreen, it's not in another mode
|
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.
|
// Test maximized.
|
||||||
|
|
|
@ -159,6 +159,7 @@ class DisplayServerX11 : public DisplayServer {
|
||||||
//better to guess on the fly, given WM can change it
|
//better to guess on the fly, given WM can change it
|
||||||
//WindowMode mode;
|
//WindowMode mode;
|
||||||
bool fullscreen = false; //OS can't exit from this mode
|
bool fullscreen = false; //OS can't exit from this mode
|
||||||
|
bool exclusive_fullscreen = false;
|
||||||
bool on_top = false;
|
bool on_top = false;
|
||||||
bool borderless = false;
|
bool borderless = false;
|
||||||
bool resize_disabled = false;
|
bool resize_disabled = false;
|
||||||
|
@ -283,7 +284,7 @@ class DisplayServerX11 : public DisplayServer {
|
||||||
bool _window_minimize_check(WindowID p_window) const;
|
bool _window_minimize_check(WindowID p_window) const;
|
||||||
void _validate_mode_on_map(WindowID p_window);
|
void _validate_mode_on_map(WindowID p_window);
|
||||||
void _update_size_hints(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_maximized(WindowID p_window, bool p_enabled);
|
||||||
void _set_wm_minimized(WindowID p_window, bool p_enabled);
|
void _set_wm_minimized(WindowID p_window, bool p_enabled);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue