From bd023ae06f43d52ac4092df2500bb1d2f2cc5cb3 Mon Sep 17 00:00:00 2001 From: Emmanuel Hansen Date: Wed, 5 Apr 2023 14:48:17 +0000 Subject: [PATCH] x11 - prevent window from receiving input when disabled --- src/Avalonia.X11/X11Window.cs | 26 +++++++++++++++++++++++++- src/Avalonia.X11/XI2Manager.cs | 3 +++ src/Avalonia.X11/XLib.cs | 3 +++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.X11/X11Window.cs b/src/Avalonia.X11/X11Window.cs index e5373ce42f..6247e8b09e 100644 --- a/src/Avalonia.X11/X11Window.cs +++ b/src/Avalonia.X11/X11Window.cs @@ -24,6 +24,7 @@ using Avalonia.X11.Glx; using Avalonia.X11.NativeDialogs; using static Avalonia.X11.XLib; using Avalonia.Input.Platform; +using System.Runtime.InteropServices; // ReSharper disable IdentifierTypo // ReSharper disable StringLiteralTypo @@ -772,7 +773,7 @@ namespace Avalonia.X11 private void MouseEvent(RawPointerEventType type, ref XEvent ev, XModifierMask mods) { - if (_inputRoot is null) + if (_inputRoot is null || _disabled) return; var mev = new RawPointerEventArgs( _mouse, (ulong)ev.ButtonEvent.time.ToInt64(), _inputRoot, @@ -1201,6 +1202,27 @@ namespace Avalonia.X11 public void SetEnabled(bool enable) { _disabled = !enable; + + var wmHintsPtr = XGetWMHints(_x11.Display, _handle); + + XWMHints hints = default; + + if (wmHintsPtr != IntPtr.Zero) + { + hints = Marshal.PtrToStructure(wmHintsPtr); + } + + var flags = hints.flags.ToInt64(); + flags |= (long)XWMHintsFlags.InputHint; + hints.flags = (IntPtr)flags; + hints.input = enable ? 1 : 0; + + XSetWMHints(_x11.Display, _handle, ref hints); + + if (wmHintsPtr != IntPtr.Zero) + { + XFree(wmHintsPtr); + } } public void SetExtendClientAreaToDecorationsHint(bool extendIntoClientAreaHint) @@ -1290,6 +1312,8 @@ namespace Avalonia.X11 public bool NeedsManagedDecorations => false; + public bool IsEnabled => !_disabled; + public class SurfacePlatformHandle : IPlatformNativeSurfaceHandle { private readonly X11Window _owner; diff --git a/src/Avalonia.X11/XI2Manager.cs b/src/Avalonia.X11/XI2Manager.cs index f66616f2aa..dd2efbd89e 100644 --- a/src/Avalonia.X11/XI2Manager.cs +++ b/src/Avalonia.X11/XI2Manager.cs @@ -217,6 +217,8 @@ namespace Avalonia.X11 private void OnDeviceEvent(IXI2Client client, ParsedDeviceEvent ev) { + if (!client.IsEnabled) + return; if (ev.Type == XiEventType.XI_TouchBegin || ev.Type == XiEventType.XI_TouchUpdate || ev.Type == XiEventType.XI_TouchEnd) @@ -370,6 +372,7 @@ namespace Avalonia.X11 internal interface IXI2Client { + bool IsEnabled { get; } IInputRoot InputRoot { get; } void ScheduleXI2Input(RawInputEventArgs args); IMouseDevice MouseDevice { get; } diff --git a/src/Avalonia.X11/XLib.cs b/src/Avalonia.X11/XLib.cs index 7a43cd378b..641adde7e2 100644 --- a/src/Avalonia.X11/XLib.cs +++ b/src/Avalonia.X11/XLib.cs @@ -375,6 +375,9 @@ namespace Avalonia.X11 [DllImport(libX11)] public static extern void XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints); + [DllImport(libX11)] + public static extern IntPtr XGetWMHints(IntPtr display, IntPtr window); + [DllImport(libX11)] public static extern int XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count);