diff --git a/src/Avalonia.X11/X11Window.cs b/src/Avalonia.X11/X11Window.cs index ceb9c5edb8..7fbeaa35cd 100644 --- a/src/Avalonia.X11/X11Window.cs +++ b/src/Avalonia.X11/X11Window.cs @@ -168,15 +168,20 @@ namespace Avalonia.X11 (int)CreateWindowArgs.InputOutput, visual, new UIntPtr((uint)valueMask), ref attr); + AppendPid(_handle); if (_useRenderWindow) + { _renderHandle = XCreateWindow(_x11.Display, _handle, 0, 0, defaultWidth, defaultHeight, 0, depth, (int)CreateWindowArgs.InputOutput, visual, new UIntPtr((uint)(SetWindowValuemask.BorderPixel | SetWindowValuemask.BitGravity | SetWindowValuemask.WinGravity | SetWindowValuemask.BackingStore)), ref attr); + } else + { _renderHandle = _handle; + } Handle = new PlatformHandle(_handle, "XID"); @@ -335,6 +340,55 @@ namespace Avalonia.X11 PropertyMode.Replace, ref hints, 5); } + /// + /// Append `_NET_WM_PID` atom to X11 window + /// + /// + private void AppendPid(IntPtr windowXId) + { + // See https://github.com/AvaloniaUI/Avalonia/issues/17444 + var pid = (uint)s_pid; + // The type of `_NET_WM_PID` is `CARDINAL` which is 32-bit unsigned integer, see https://specifications.freedesktop.org/wm-spec/1.3/ar01s05.html + XChangeProperty(_x11.Display, windowXId, + _x11.Atoms._NET_WM_PID, _x11.Atoms.XA_CARDINAL, 32, + PropertyMode.Replace, ref pid, 1); + + const int maxLength = 1024; + var name = stackalloc byte[maxLength]; + var result = gethostname(name, maxLength); + if (result != 0) + { + // Fail + return; + } + + var length = 0; + while (length < maxLength && name[length] != 0) + { + length++; + } + + XChangeProperty(_x11.Display, windowXId, + _x11.Atoms.XA_WM_CLIENT_MACHINE, _x11.Atoms.XA_STRING, 8, + PropertyMode.Replace, name, length); + } + + [DllImport("libc")] + private static extern int gethostname(byte* name, int len); + + private static readonly int s_pid = GetProcessId(); + + private static int GetProcessId() + { +#if NET6_0_OR_GREATER + var pid = Environment.ProcessId; +#else + using var currentProcess = Process.GetCurrentProcess(); + var pid = currentProcess.Id; +#endif + return pid; + } + private void UpdateSizeHints(PixelSize? preResize, bool forceDisableResize = false) { if (_overrideRedirect)