Browse Source

Xdnd: handle key modifiers

pull/20926/head
Julien Lebosquain 10 hours ago
parent
commit
6e377abbbb
No known key found for this signature in database GPG Key ID: 1833CAD10ACC46FD
  1. 23
      src/Avalonia.X11/Selections/DragDrop/X11DragSource.cs
  2. 16
      src/Avalonia.X11/Selections/DragDrop/X11DropTarget.cs
  3. 30
      src/Avalonia.X11/X11EnumExtensions.cs
  4. 2
      src/Avalonia.X11/X11Window.Ime.cs
  5. 28
      src/Avalonia.X11/X11Window.cs
  6. 6
      src/Avalonia.X11/XLib.cs

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

@ -158,8 +158,8 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
{
if (_lastTarget is { } lastTarget)
{
if (lastTarget.InProcessWindow is not null)
ProcessRawDragEvent(lastTarget.InProcessWindow, RawDragEventType.DragLeave, rootPosition);
if (lastTarget.InProcessWindow is { } window)
ProcessRawDragEvent(window, RawDragEventType.DragLeave, rootPosition, motion.state);
else
SendXdndLeave(lastTarget);
}
@ -169,8 +169,8 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
if (target is { } newTarget)
{
if (newTarget.InProcessWindow is not null)
ProcessRawDragEvent(newTarget.InProcessWindow, RawDragEventType.DragEnter, rootPosition);
if (newTarget.InProcessWindow is { } window)
ProcessRawDragEvent(window, RawDragEventType.DragEnter, rootPosition, motion.state);
else
SendXdndEnter(newTarget);
}
@ -178,8 +178,8 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
if (target is { } currentTarget)
{
if (currentTarget.InProcessWindow is not null)
ProcessRawDragEvent(currentTarget.InProcessWindow, RawDragEventType.DragOver, rootPosition);
if (currentTarget.InProcessWindow is { } window)
ProcessRawDragEvent(window, RawDragEventType.DragOver, rootPosition, motion.state);
else
{
var action = XdndActionHelper.EffectsToAction(_allowedEffects, _platform.Info.Atoms);
@ -198,7 +198,7 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
if (lastTarget.InProcessWindow is not null)
{
var rootPosition = new PixelPoint(button.x_root, button.y_root);
ProcessRawDragEvent(lastTarget.InProcessWindow, RawDragEventType.Drop, rootPosition);
ProcessRawDragEvent(lastTarget.InProcessWindow, RawDragEventType.Drop, rootPosition, button.state);
_lastTarget = null;
Complete(_currentEffects);
}
@ -382,7 +382,11 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
XFlush(_platform.Display);
}
private void ProcessRawDragEvent(X11Window targetWindow, RawDragEventType eventType, PixelPoint rootPosition)
private void ProcessRawDragEvent(
X11Window targetWindow,
RawDragEventType eventType,
PixelPoint rootPosition,
XModifierMask modifierMask)
{
if (targetWindow.DragDropDevice is not { } dragDropDevice)
{
@ -391,6 +395,7 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
}
var localPosition = targetWindow.PointToClient(rootPosition);
var modifiers = modifierMask.ToRawInputModifiers();
var dragEvent = new RawDragEvent(
dragDropDevice,
@ -399,7 +404,7 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
localPosition,
_dataTransfer,
_allowedEffects,
RawInputModifiers.None);
modifiers);
dragDropDevice.ProcessRawEvent(dragEvent);

16
src/Avalonia.X11/Selections/DragDrop/X11DropTarget.cs

@ -85,6 +85,7 @@ internal sealed class X11DropTarget
var position = _window.PointToClient(new PixelPoint(screenX, screenY));
var requestedEffects = XdndActionHelper.ActionToEffects(message.ptr5, _atoms);
var eventType = drag.LastPosition is null ? RawDragEventType.DragEnter : RawDragEventType.DragOver;
var modifiers = GetModifiers();
drag.LastPosition = position;
drag.LastTimestamp = message.ptr4;
@ -96,7 +97,7 @@ internal sealed class X11DropTarget
position,
drag,
requestedEffects,
RawInputModifiers.None);
modifiers);
_dragDropDevice.ProcessRawEvent(dragEvent);
@ -111,6 +112,8 @@ internal sealed class X11DropTarget
if (_currentDrag is not { } drag || message.ptr1 != drag.SourceWindow)
return;
var modifiers = GetModifiers();
var dragLeave = new RawDragEvent(
_dragDropDevice,
RawDragEventType.DragLeave,
@ -118,7 +121,7 @@ internal sealed class X11DropTarget
default,
drag,
DragDropEffects.None,
RawInputModifiers.None);
modifiers);
_dragDropDevice.ProcessRawEvent(dragLeave);
@ -130,6 +133,8 @@ internal sealed class X11DropTarget
if (_currentDrag is not { } drag || message.ptr1 != drag.SourceWindow)
return;
var modifiers = GetModifiers();
var drop = new RawDragEvent(
_dragDropDevice,
RawDragEventType.Drop,
@ -137,7 +142,7 @@ internal sealed class X11DropTarget
drag.LastPosition ?? default,
drag,
drag.ResultEffects,
RawInputModifiers.None);
modifiers);
_dragDropDevice.ProcessRawEvent(drop);
@ -176,6 +181,11 @@ internal sealed class X11DropTarget
XFlush(_display);
}
private RawInputModifiers GetModifiers()
=> XQueryPointer(_display, _window.Handle, out _, out _, out _, out _, out _, out _, out var mask) ?
mask.ToRawInputModifiers() :
RawInputModifiers.None;
private void DisposeCurrentDrag()
{
if (_currentDrag is not { } drag)

30
src/Avalonia.X11/X11EnumExtensions.cs

@ -0,0 +1,30 @@
using Avalonia.Input;
namespace Avalonia.X11;
internal static class X11EnumExtensions
{
public static RawInputModifiers ToRawInputModifiers(this XModifierMask state)
{
var rv = default(RawInputModifiers);
if (state.HasAllFlags(XModifierMask.Button1Mask))
rv |= RawInputModifiers.LeftMouseButton;
if (state.HasAllFlags(XModifierMask.Button2Mask))
rv |= RawInputModifiers.RightMouseButton;
if (state.HasAllFlags(XModifierMask.Button3Mask))
rv |= RawInputModifiers.MiddleMouseButton;
if (state.HasAllFlags(XModifierMask.Button4Mask))
rv |= RawInputModifiers.XButton1MouseButton;
if (state.HasAllFlags(XModifierMask.Button5Mask))
rv |= RawInputModifiers.XButton2MouseButton;
if (state.HasAllFlags(XModifierMask.ShiftMask))
rv |= RawInputModifiers.Shift;
if (state.HasAllFlags(XModifierMask.ControlMask))
rv |= RawInputModifiers.Control;
if (state.HasAllFlags(XModifierMask.Mod1Mask))
rv |= RawInputModifiers.Alt;
if (state.HasAllFlags(XModifierMask.Mod4Mask))
rv |= RawInputModifiers.Meta;
return rv;
}
}

2
src/Avalonia.X11/X11Window.Ime.cs

@ -116,7 +116,7 @@ namespace Avalonia.X11
{
var physicalKey = X11KeyTransform.PhysicalKeyFromScanCode(ev.KeyEvent.keycode);
var (x11Key, key, symbol) = LookupKey(ref ev.KeyEvent, physicalKey);
var modifiers = TranslateModifiers(ev.KeyEvent.state);
var modifiers = ev.KeyEvent.state.ToRawInputModifiers();
var timestamp = (ulong)ev.KeyEvent.time.ToInt64();
var args = ev.type == XEventName.KeyPress ?

28
src/Avalonia.X11/X11Window.cs

@ -580,7 +580,7 @@ namespace Avalonia.X11
: new Vector(-1, 0);
ScheduleInput(new RawMouseWheelEventArgs(_mouse, (ulong)ev.ButtonEvent.time.ToInt64(),
_inputRoot, new Point(ev.ButtonEvent.x, ev.ButtonEvent.y), delta,
TranslateModifiers(ev.ButtonEvent.state)), ref ev);
ev.ButtonEvent.state.ToRawInputModifiers()), ref ev);
}
}
@ -855,30 +855,6 @@ namespace Avalonia.X11
}
private static RawInputModifiers TranslateModifiers(XModifierMask state)
{
var rv = default(RawInputModifiers);
if (state.HasAllFlags(XModifierMask.Button1Mask))
rv |= RawInputModifiers.LeftMouseButton;
if (state.HasAllFlags(XModifierMask.Button2Mask))
rv |= RawInputModifiers.RightMouseButton;
if (state.HasAllFlags(XModifierMask.Button3Mask))
rv |= RawInputModifiers.MiddleMouseButton;
if (state.HasAllFlags(XModifierMask.Button4Mask))
rv |= RawInputModifiers.XButton1MouseButton;
if (state.HasAllFlags(XModifierMask.Button5Mask))
rv |= RawInputModifiers.XButton2MouseButton;
if (state.HasAllFlags(XModifierMask.ShiftMask))
rv |= RawInputModifiers.Shift;
if (state.HasAllFlags(XModifierMask.ControlMask))
rv |= RawInputModifiers.Control;
if (state.HasAllFlags(XModifierMask.Mod1Mask))
rv |= RawInputModifiers.Alt;
if (state.HasAllFlags(XModifierMask.Mod4Mask))
rv |= RawInputModifiers.Meta;
return rv;
}
private WindowDecorations _requestedWindowDecorations = WindowDecorations.Full;
private WindowDecorations _windowDecorations = WindowDecorations.Full;
private bool _canResize = true;
@ -986,7 +962,7 @@ namespace Avalonia.X11
return;
var mev = new RawPointerEventArgs(
_mouse, (ulong)ev.ButtonEvent.time.ToInt64(), _inputRoot,
type, new Point(ev.ButtonEvent.x, ev.ButtonEvent.y), TranslateModifiers(mods));
type, new Point(ev.ButtonEvent.x, ev.ButtonEvent.y), mods.ToRawInputModifiers());
ScheduleInput(mev, ref ev);
}

6
src/Avalonia.X11/XLib.cs

@ -175,7 +175,7 @@ namespace Avalonia.X11
[DllImport(libX11)]
public static extern bool XQueryPointer(IntPtr display, IntPtr window, out IntPtr root, out IntPtr child,
out int root_x, out int root_y, out int win_x, out int win_y, out int keys_buttons);
out int root_x, out int root_y, out int win_x, out int win_y, out XModifierMask mask);
[DllImport(libX11)]
public static extern bool XTranslateCoordinates(IntPtr display, IntPtr src_w, IntPtr dest_w, int src_x,
@ -694,7 +694,7 @@ namespace Avalonia.X11
public static void QueryPointer (IntPtr display, IntPtr w, out IntPtr root, out IntPtr child,
out int root_x, out int root_y, out int child_x, out int child_y,
out int mask)
out XModifierMask mask)
{
IntPtr c;
@ -729,7 +729,7 @@ namespace Avalonia.X11
int root_y;
int win_x;
int win_y;
int keys_buttons;
XModifierMask keys_buttons;

Loading…
Cancel
Save