Browse Source

Store X11Window instances inside X11Platform

pull/20926/head
Julien Lebosquain 7 months ago
parent
commit
5e34c8f4ce
No known key found for this signature in database GPG Key ID: 1833CAD10ACC46FD
  1. 10
      src/Avalonia.X11/Dispatching/X11EventDispatcher.cs
  2. 2
      src/Avalonia.X11/Selections/Clipboard/EventStreamWindow.cs
  3. 20
      src/Avalonia.X11/Selections/DragDrop/X11DragSource.cs
  4. 2
      src/Avalonia.X11/X11FocusProxy.cs
  5. 4
      src/Avalonia.X11/X11Globals.cs
  6. 2
      src/Avalonia.X11/X11Platform.cs
  7. 2
      src/Avalonia.X11/X11Window.cs
  8. 7
      src/Avalonia.X11/X11WindowInfo.cs
  9. 2
      src/Avalonia.X11/XLib.cs

10
src/Avalonia.X11/Dispatching/X11EventDispatcher.cs

@ -8,16 +8,16 @@ internal class X11EventDispatcher
{
private readonly AvaloniaX11Platform _platform;
private readonly IntPtr _display;
private readonly Dictionary<IntPtr, X11WindowInfo> _windows;
public delegate void EventHandler(ref XEvent xev);
public int Fd { get; }
private readonly Dictionary<IntPtr, EventHandler> _eventHandlers;
public X11EventDispatcher(AvaloniaX11Platform platform)
{
_platform = platform;
_display = platform.Display;
_eventHandlers = platform.Windows;
_windows = platform.Windows;
Fd = XLib.XConnectionNumber(_display);
}
@ -46,8 +46,8 @@ internal class X11EventDispatcher
_platform.XI2.OnEvent((XIEvent*)xev.GenericEventCookie.data);
}
}
else if (_eventHandlers.TryGetValue(xev.AnyEvent.window, out var handler))
handler(ref xev);
else if (_windows.TryGetValue(xev.AnyEvent.window, out var windowInfo))
windowInfo.EventHandler(ref xev);
}
finally
{
@ -59,4 +59,4 @@ internal class X11EventDispatcher
}
public void Flush() => XFlush(_display);
}
}

2
src/Avalonia.X11/Selections/Clipboard/EventStreamWindow.cs

@ -27,7 +27,7 @@ internal sealed class EventStreamWindow : IXEventWaiter
{
_isForeign = true;
_handle = foreignWindow.Value;
_platform.Windows[_handle] = OnEvent;
_platform.Windows[_handle] = new X11WindowInfo(OnEvent, null);
}
else
_handle = XLib.CreateEventWindow(platform, OnEvent);

20
src/Avalonia.X11/Selections/DragDrop/X11DragSource.cs

@ -44,7 +44,7 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
private readonly TaskCompletionSource<DragDropEffects> _completionSource = new();
private readonly DragDropDataProvider _dataProvider;
private readonly IntPtr[] _formatAtoms;
private X11EventDispatcher.EventHandler? _originalEventHandler;
private X11WindowInfo? _originalSourceWindowInfo;
private bool _pointerGrabbed;
private XdndTargetInfo? _lastTarget;
private IntPtr _lastStatusAction;
@ -61,7 +61,7 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
_allowedEffects = allowedEffects;
_dataProvider = new DragDropDataProvider(platform, dataTransfer);
if (!platform.Windows.TryGetValue(sourceWindow, out _originalEventHandler))
if (!platform.Windows.TryGetValue(sourceWindow, out var sourceWindowInfo))
{
_formatAtoms = [];
_completionSource.TrySetResult(DragDropEffects.None);
@ -93,7 +93,10 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
}
_pointerGrabbed = true;
_platform.Windows[_sourceWindow] = OnEvent;
// Replace the window event handler with our own during the drag operation
_originalSourceWindowInfo = sourceWindowInfo;
_platform.Windows[_sourceWindow] = new X11WindowInfo(OnEvent, sourceWindowInfo.Window);
var atoms = _platform.Info.Atoms;
_formatAtoms = DataFormatHelper.ToAtoms(dataTransfer.Formats, atoms);
@ -130,14 +133,14 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
else if (message.message_type == atoms.XdndFinished)
OnXdndFinished(in message);
else
_originalEventHandler?.Invoke(ref evt);
_originalSourceWindowInfo?.EventHandler(ref evt);
}
else if (evt.type == XEventName.SelectionRequest)
_dataProvider.OnSelectionRequest(in evt.SelectionRequestEvent);
else
_originalEventHandler?.Invoke(ref evt);
_originalSourceWindowInfo?.EventHandler(ref evt);
}
private void OnMotionNotify(in XMotionEvent motion)
@ -337,10 +340,11 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
if (_pointerGrabbed)
UngrabPointer();
if (_originalEventHandler is not null && _platform.Windows.ContainsKey(_sourceWindow))
if (_originalSourceWindowInfo is { } originalSourceWindowInfo &&
_platform.Windows.ContainsKey(_sourceWindow))
{
_platform.Windows[_sourceWindow] = _originalEventHandler;
_originalEventHandler = null;
_platform.Windows[_sourceWindow] = originalSourceWindowInfo;
_originalSourceWindowInfo = null;
}
_lastTarget = null;

2
src/Avalonia.X11/X11FocusProxy.cs

@ -41,7 +41,7 @@ namespace Avalonia.X11
_handle = PrepareXWindow(platform.Info.Display, parent);
_platform = platform;
_ownerEventHandler = eventHandler;
_platform.Windows[_handle] = OnEvent;
_platform.Windows[_handle] = new X11WindowInfo(OnEvent, null);
}
internal void Cleanup()

4
src/Avalonia.X11/X11Globals.cs

@ -40,7 +40,7 @@ namespace Avalonia.X11
_x11 = plat.Info;
_screenNumber = XDefaultScreen(_x11.Display);
_rootWindow = XRootWindow(_x11.Display, _screenNumber);
plat.Windows[_rootWindow] = OnRootWindowEvent;
plat.Windows[_rootWindow] = new X11WindowInfo(OnRootWindowEvent, null);
XSelectInput(_x11.Display, _rootWindow,
new IntPtr((int)(EventMask.StructureNotifyMask | EventMask.PropertyChangeMask)));
@ -156,7 +156,7 @@ namespace Avalonia.X11
CompositionAtomOwner = newOwner;
if (CompositionAtomOwner != IntPtr.Zero)
{
_plat.Windows[newOwner] = HandleCompositionAtomOwnerEvents;
_plat.Windows[newOwner] = new X11WindowInfo(HandleCompositionAtomOwnerEvents, null);
XSelectInput(_x11.Display, CompositionAtomOwner, new IntPtr((int)(EventMask.StructureNotifyMask)));
}

2
src/Avalonia.X11/X11Platform.cs

@ -33,7 +33,7 @@ namespace Avalonia.X11
private X11AtSpiAccessibility? _accessibility;
internal AtSpiServer? AtSpiServer => _accessibility?.Server;
public KeyboardDevice KeyboardDevice => _keyboardDevice.Value;
public Dictionary<IntPtr, X11EventDispatcher.EventHandler> Windows { get; } = new ();
public Dictionary<IntPtr, X11WindowInfo> Windows { get; } = new ();
public XI2Manager? XI2 { get; private set; }
public X11Info Info { get; private set; } = null!;
public X11Screens X11Screens { get; private set; } = null!;

2
src/Avalonia.X11/X11Window.cs

@ -193,7 +193,7 @@ namespace Avalonia.X11
_mode.OnHandleCreated(_handle);
_realSize = new PixelSize(defaultWidth, defaultHeight);
platform.Windows[_handle] = OnEvent;
platform.Windows[_handle] = new X11WindowInfo(OnEvent, this);
XEventMask ignoredMask = XEventMask.SubstructureRedirectMask
| XEventMask.ResizeRedirectMask
| XEventMask.PointerMotionHintMask;

7
src/Avalonia.X11/X11WindowInfo.cs

@ -0,0 +1,7 @@
namespace Avalonia.X11;
internal readonly struct X11WindowInfo(X11EventDispatcher.EventHandler eventHandler, X11Window? window)
{
public X11EventDispatcher.EventHandler EventHandler { get; } = eventHandler;
public X11Window? Window { get; } = window;
}

2
src/Avalonia.X11/XLib.cs

@ -751,7 +751,7 @@ namespace Avalonia.X11
{
var win = XCreateSimpleWindow(plat.Display, plat.Info.DefaultRootWindow,
0, 0, 1, 1, 0, IntPtr.Zero, IntPtr.Zero);
plat.Windows[win] = handler;
plat.Windows[win] = new X11WindowInfo(handler, null);
return win;
}

Loading…
Cancel
Save