Open Cliear opened 1 year ago
Here are some issues:
#include <X11/Xlib.h>
int main(int argc, char const argv[]) { Display display = XOpenDisplay(NULL); int x = 500; int y = 200; int width = 800; int height = 600; unsigned long border_width = 0; unsigned long border_color = WhitePixel(display, DefaultScreen(display)); unsigned long background = WhitePixel(display, DefaultScreen(display)); Window window = XCreateSimpleWindow(display, DefaultRootWindow(display), x, y, width, height, border_width, border_color, background);
XSelectInput(display, window, ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask);
XMapWindow(display, window);
XFlush(display);
XEvent report;
for (;;) {
XNextEvent(display, &report);
}
return 0;
}
![shadow](https://github.com/godotengine/godot/assets/48273990/9d3c6e4a-f269-4cc3-98cf-8df549e6c861)
There is an area outside the border that belongs to this window, but it cannot receive any events.
If you use the _MOTIF_WM_HINTS to remove decorations, this shadow window will still persist:
int main(int argc, char const argv[]) { Display display = XOpenDisplay(NULL); int x = 500; int y = 200; int width = 800; int height = 600; unsigned long border_width = 0; unsigned long border_color = WhitePixel(display, DefaultScreen(display)); unsigned long background = WhitePixel(display, DefaultScreen(display)); Window window = XCreateSimpleWindow(display, DefaultRootWindow(display), x, y, width, height, border_width, border_color, background);
enum MWM_Flag {
MWM_HINTS_FUNCTIONS = 1 << 0,
MWM_HINTS_DECORATIONS = 1 << 1,
MWM_HINTS_INPUT_MODE = 1 << 2,
MWM_HINTS_STATUS = 1 << 3
};
enum MWM_Decor {
MWM_DECOR_NOTHING = 0,
MWM_DECOR_ALL = 1 << 0,
MWM_DECOR_BORDER = 1 << 1,
MWM_DECOR_RESIZEH = 1 << 2,
MWM_DECOR_TITLE = 1 << 3,
MWM_DECOR_MENU = 1 << 4,
MWM_DECOR_MINIMIZE = 1 << 5,
MWM_DECOR_MAXIMIZE = 1 << 6,
};
struct {
uint32_t flags;
uint32_t functions;
uint32_t decorations;
int32_t input_mode;
uint32_t status;
} hints = {
.flags = MWM_HINTS_DECORATIONS,
.decorations = MWM_DECOR_NOTHING
};
Atom property = XInternAtom(display, "_MOTIF_WM_HINTS", True);
if (property != None) {
XChangeProperty(display, window, property, property, 32, PropModeReplace, (unsigned char *)&hints, sizeof(hints) / 4);
}
XSelectInput(display, window, ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask);
XMapWindow(display, window);
XFlush(display);
XEvent report;
for (;;) {
XNextEvent(display, &report);
}
return 0;
}
![no_decoration_shadow](https://github.com/godotengine/godot/assets/48273990/e9d420e9-6483-4a8a-adaf-8be864d3380e)
2. WSLg has a bug, when a x11 window has the type _NET_WM_WINDOW_TYPE_UTILITY, it appears to be covered by the shadow window, causing it to not receive any events:
int main(int argc, char const argv[]) { Display display = XOpenDisplay(NULL); int x = 500; int y = 200; int width = 800; int height = 600; unsigned long border_width = 0; unsigned long border_color = WhitePixel(display, DefaultScreen(display)); unsigned long background = WhitePixel(display, DefaultScreen(display)); Window window = XCreateSimpleWindow(display, DefaultRootWindow(display), x, y, width, height, border_width, border_color, background);
Atom type_atom = XInternAtom(display, "_NET_WM_WINDOW_TYPE_UTILITY", False);
Atom wt_atom = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
if (wt_atom != None && type_atom != None) {
XChangeProperty(display, window, wt_atom, XA_ATOM, 32, PropModeReplace, (unsigned char *)&type_atom, 1);
}
XSelectInput(display, window, ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask);
XMapWindow(display, window);
XFlush(display);
XEvent report;
for (;;) {
XNextEvent(display, &report);
switch (report.type)
{
case Expose:
puts("Expose");
break;
case ConfigureNotify:
puts("ConfigureNotify");
break;
case MapNotify:
puts("MapNotify");
break;
case ReparentNotify:
puts("ReparentNotify");
break;
default:
puts("Receive a event!");
break;
}
}
return 0;
}
![utility](https://github.com/godotengine/godot/assets/48273990/998d67bf-0355-411d-9732-b568cfb354c6)
This type must be set after waiting for a while following the use of XMapWinodw, and then it must be made effective by using XUnMapWindow followed by XMapWindow again.
The first issue might cause bugs when godot queries the window's position and size in WSLg.
When _NET_WM_WINDOW_TYPE_UTILITY is commented out, the bug seems to be fixed, and the popup window can receive events: https://github.com/Cliear/godot/blob/fab7c74eb46039fc39c129ac1d671fd0cba77b81/platform/linuxbsd/x11/display_server_x11.cpp#L5703-L5707 It seems to be running corrctly, but it is indeed affected by the first issue: The shadow window is still there, and it covers part of other windows.The bug comes from the following code: https://github.com/godotengine/godot/blob/26d1577f3985363faab48a65e9a0d9eed0e26d86/platform/linuxbsd/x11/display_server_x11.cpp#L2365-L2379 https://github.com/godotengine/godot/blob/26d1577f3985363faab48a65e9a0d9eed0e26d86/platform/linuxbsd/x11/display_server_x11.cpp#L2185-L2199 If it's a borderless window, it shouldn't require decorations.However, in WSLg, even when using _MOTIF_WM_HINTS, it always seems to factor in the shadow window when calculating the border size and position. When making the folloing changes, the bug will be fixed: https://github.com/Cliear/godot/blob/dae7f4f3b6df321bef355cec71a41a6d2628ea0e/platform/linuxbsd/x11/display_server_x11.cpp#L2184-L2201 https://github.com/Cliear/godot/blob/dae7f4f3b6df321bef355cec71a41a6d2628ea0e/platform/linuxbsd/x11/display_server_x11.cpp#L2366-L2383 Since a borderless window should have no decorations, there's no check to determine if it's a borderless window.This is result:
Here are a few solutions:
Godot version
4.*
System information
WSLg Version: 1.0.51
Issue description
https://github.com/godotengine/godot/assets/48273990/fa64749e-33c3-4481-bd16-d9b75bef3d31
https://github.com/godotengine/godot/assets/48273990/0151233d-3635-4614-aced-17d25b2eceaa
Steps to reproduce
No matter what wsl distribution is used, as long as godot4 is run through wslg, no popup toorbar can be clicked.
Minimal reproduction project
N/A