wails
wails copied to clipboard
Window maximum width and height issues on Linux Wayland
Description
There are 3 similar issues that I've found:
- It is not possible to resize window beyond a certain width and height for some reason (although MaxWidth and MaxHeight are unset).
- Maximizing the window will move the window to the top left of the screen but it won't take up the entire screen (similarly to the first bug).
- When making the window fullscreen, the window itself will go fullscreen but the webview inside it won't and will center itself in the window.
To Reproduce
For all:
- Make sure you are on Wayland and the app is not ran under Xwayland.
- Unset MaxWidth and MaxHeight or set them to a high value (close to the screen width and height)
- Launch app
First bug:
- Try to resize manually and make the window as big as possible. Second bug:
- Click maximize. Third bug:
- Fullscreen the app.
Expected behaviour
First bug: The app resizes accordingly without constraints. Second bug: The app maximizes. Third bug: The app goes to fullscreen.
Screenshots
Screencast from 2023-02-28 14-06-22.webm
Attempted Fixes
No response
System Details
# System
OS | Manjaro Linux
Version | Unknown
ID | manjaro
Go Version | go1.19.4
Platform | linux
Architecture | amd64
# Wails
Version | v2.3.1
Package Manager | pacman
# Dependencies
Dependency | Package Name | Status | Version
*docker | docker | Available | 1:23.0.1-1
gcc | gcc | Installed | 12.2.1-2
libgtk-3 | gtk3 | Installed | 1:3.24.36-1
libwebkit | webkit2gtk | Installed | 2.38.5-1
npm | npm | Installed | 8.19.2-1
pkg-config | pkgconf | Installed | 1.8.0-1
* - Optional Dependency
Additional context
I have tried to reproduce the problem under Xwayland (launching the app with GDK_BACKEND=x11 and XDG_SESSION_TYPE=X11) but the bugs weren't present there.
I also successfully managed to reproduce the bugs on another machine running Arch with Gnome on Wayland.
Strangely, it also seems that the "phantom maximum width and height" depend on the GTK theme - for some themes they are a bit bigger and for some they are a bit smaller.
Sounds like an upstream bug. Maybe @Lyimmi or @tmclane have more knowledge
Sounds wonderful, I'll take a look at it as soon as I have time this week. (I hope)
Hi, sorry it took me so long to look into this. I think I found the core of the issue.
Wails sets default min and max sizes for the window when they are not set in the app options (to the current display's resolution) and we pass the window geometry hints GDK_HINT_MAX_SIZE | GDK_HINT_MIN_SIZE
to GTK as well, so GTK tries to respect the set window dimension limits.
If I remove the hints in v2/internal/frontend/desktop/linux/window.c L:190 the problem goes away, but then we have no built in window size control via GTK.
As far as I can tell the default Wayland compositor counts the shadows/borders/etc in the window's width and height.
For a quick and dirty temporary fix I recommend to set the window max values in the app options to some arbitrary big number (maybe over a 4k displays resolution).
I'll look into how fix this properly. By the way this is not a unique Wails problem, I found lots of other issues about this, including electron.
Thanks for looking into this @Lyimmi 🙏
Thank you for checking this out! I've tried to look into this myself, but I am far too unfamiliar with GTK to do anything here, especially when taking into account those Wayland quirks.
Nevertheless, I'm grateful for your efforts and I'll provide you with any additional info if I find any. Cheers!
FWIW, I experience the same issue. Installed wails
today, ran the sample app and then just hit "toggle maximize" key combo on the window, it only gets it partially maximized (top+left, leaving a gap on bottom+right).
Wails doctor
# Wails
Version | v2.7.1
Package Manager | dnf
# System
┌────────────────────────────────────────────────────────────────────────────────┐
| OS | Fedora Linux |
| Version | 39 |
| ID | fedora |
| Go Version | go1.21.6 |
| Platform | linux |
| Architecture | amd64 |
| CPU | Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz |
| GPU 1 | GM107M [GeForce GTX 960M] (NVIDIA Corporation) - Driver: nvidia |
| GPU 2 | HD Graphics 530 (Intel Corporation) - Driver: i915 |
| Memory | 15GB |
└────────────────────────────────────────────────────────────────────────────────┘
# Dependencies
┌────────────────────────────────────────────────────────┐
| Dependency | Package Name | Status | Version |
| *docker | moby-engine | Installed | 24.0.5 |
| gcc | gcc-c++ | Installed | 13.2.1 |
| libgtk-3 | gtk3-devel | Installed | 3.24.41 |
| libwebkit | webkit2gtk4.0-devel | Installed | 2.42.3 |
| npm | nodejs-npm | Installed | 10.2.3 |
| pkg-config | pkgconf-pkg-config | Installed | 1.9.5 |
| *upx | upx | Installed | 4.2.2 |
└─────────────── * - Optional Dependency ────────────────┘
Screencast from 2024-02-06 12-11-13.webm
I use Gnome 45.3 on Wayland.
I think I found a way to fix this issue, but I have not seen this kind of solution anywhere, so I'm not exactly sure if it is a good solution.
Basically we could compare the window's initial size and the allocated size that contains the window decorators and shadows as well and add the difference to the window's max size values.
The comparison can be ignored on frameless windows because non decorated windows report the correct size on Wayland.
As far as I can tell the initial window size does not mater, the size of the decorators does not change just the window's size.
The solution still behaves badly on my portrait display, because for some reason Wayland returns the main display's resolution... So the max height is about half of the portrait display's height. At this time I can't figure out why.
What do you think @leaanthony, is it good enough for a PR?
Edit: it needs more work, maximising works, but fullscreen and unfullscreen is still broken.
It would look like this:
void SetMinMaxSize(GtkWindow *window, int min_width, int min_height, int max_width, int max_height)
{
GdkGeometry size;
size.min_width = size.min_height = size.max_width = size.max_height = 0;
GdkRectangle monitorSize = getCurrentMonitorGeometry(window);
if (isNULLRectangle(monitorSize))
{
return;
}
int flags = GDK_HINT_MAX_SIZE | GDK_HINT_MIN_SIZE;
size.max_height = (max_height == 0 ? monitorSize.height : max_height);
size.max_width = (max_width == 0 ? monitorSize.width : max_width);
size.min_height = min_height;
size.min_width = min_width;
// wayland specific code start
# ifdef GDK_WINDOWING_WAYLAND
char *gdkBackend = getenv("XDG_SESSION_TYPE");
if (gdkBackend != NULL && strcmp(gdkBackend, "wayland") == 0 && gtk_window_get_decorated(window)) {
int windowWidth, windowHeight;
gtk_window_get_size(window, &windowWidth, &windowHeight);
GtkAllocation windowAllocation;
gtk_widget_get_allocation(GTK_WIDGET(window), &windowAllocation);
// only for debug
g_printf("window decorated: %d\n", gtk_window_get_decorated(window));
g_printf("window alloc width:%d height:%d\n", windowAllocation.width, windowAllocation.height);
g_printf("window window width:%d height:%d\n", windowWidth, windowHeight);
g_printf("window & decorator diff width:%d height:%d\n", (windowAllocation.width-windowWidth), (windowAllocation.height-windowHeight));
g_printf("window max width:%d height:%d\n", size.max_width, size.max_height);
size.max_height = (windowAllocation.height-windowHeight)+size.max_height;
size.max_width = (windowAllocation.width-windowWidth)+size.max_width;
// only for debug
g_printf("window new max width:%d height:%d\n", size.max_width, size.max_height);
}
#endif
// wayland specific code end
gtk_window_set_geometry_hints(window, NULL, &size, flags);
}
It prints:
window decorated: 1
window alloc width:1452 height:857
window window width:1400 height:768
window & decorator diff width:52 height:89
window max width:2560 height:1080
window new max width:2612 height:1169