Browse Source

Xdnd: handle key modifiers

pull/20926/head
Julien Lebosquain 7 months ago
parent
commit
945829b042
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 is { } lastTarget)
{ {
if (lastTarget.InProcessWindow is not null) if (lastTarget.InProcessWindow is { } window)
ProcessRawDragEvent(lastTarget.InProcessWindow, RawDragEventType.DragLeave, rootPosition); ProcessRawDragEvent(window, RawDragEventType.DragLeave, rootPosition, motion.state);
else else
SendXdndLeave(lastTarget); SendXdndLeave(lastTarget);
} }
@ -169,8 +169,8 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
if (target is { } newTarget) if (target is { } newTarget)
{ {
if (newTarget.InProcessWindow is not null) if (newTarget.InProcessWindow is { } window)
ProcessRawDragEvent(newTarget.InProcessWindow, RawDragEventType.DragEnter, rootPosition); ProcessRawDragEvent(window, RawDragEventType.DragEnter, rootPosition, motion.state);
else else
SendXdndEnter(newTarget); SendXdndEnter(newTarget);
} }
@ -178,8 +178,8 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
if (target is { } currentTarget) if (target is { } currentTarget)
{ {
if (currentTarget.InProcessWindow is not null) if (currentTarget.InProcessWindow is { } window)
ProcessRawDragEvent(currentTarget.InProcessWindow, RawDragEventType.DragOver, rootPosition); ProcessRawDragEvent(window, RawDragEventType.DragOver, rootPosition, motion.state);
else else
{ {
var action = XdndActionHelper.EffectsToAction(_allowedEffects, _platform.Info.Atoms); 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) if (lastTarget.InProcessWindow is not null)
{ {
var rootPosition = new PixelPoint(button.x_root, button.y_root); 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; _lastTarget = null;
Complete(_currentEffects); Complete(_currentEffects);
} }
@ -382,7 +382,11 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
XFlush(_platform.Display); 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) if (targetWindow.DragDropDevice is not { } dragDropDevice)
{ {
@ -391,6 +395,7 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
} }
var localPosition = targetWindow.PointToClient(rootPosition); var localPosition = targetWindow.PointToClient(rootPosition);
var modifiers = modifierMask.ToRawInputModifiers();
var dragEvent = new RawDragEvent( var dragEvent = new RawDragEvent(
dragDropDevice, dragDropDevice,
@ -399,7 +404,7 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
localPosition, localPosition,
_dataTransfer, _dataTransfer,
_allowedEffects, _allowedEffects,
RawInputModifiers.None); modifiers);
dragDropDevice.ProcessRawEvent(dragEvent); 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 position = _window.PointToClient(new PixelPoint(screenX, screenY));
var requestedEffects = XdndActionHelper.ActionToEffects(message.ptr5, _atoms); var requestedEffects = XdndActionHelper.ActionToEffects(message.ptr5, _atoms);
var eventType = drag.LastPosition is null ? RawDragEventType.DragEnter : RawDragEventType.DragOver; var eventType = drag.LastPosition is null ? RawDragEventType.DragEnter : RawDragEventType.DragOver;
var modifiers = GetModifiers();
drag.LastPosition = position; drag.LastPosition = position;
drag.LastTimestamp = message.ptr4; drag.LastTimestamp = message.ptr4;
@ -96,7 +97,7 @@ internal sealed class X11DropTarget
position, position,
drag, drag,
requestedEffects, requestedEffects,
RawInputModifiers.None); modifiers);
_dragDropDevice.ProcessRawEvent(dragEvent); _dragDropDevice.ProcessRawEvent(dragEvent);
@ -111,6 +112,8 @@ internal sealed class X11DropTarget
if (_currentDrag is not { } drag || message.ptr1 != drag.SourceWindow) if (_currentDrag is not { } drag || message.ptr1 != drag.SourceWindow)
return; return;
var modifiers = GetModifiers();
var dragLeave = new RawDragEvent( var dragLeave = new RawDragEvent(
_dragDropDevice, _dragDropDevice,
RawDragEventType.DragLeave, RawDragEventType.DragLeave,
@ -118,7 +121,7 @@ internal sealed class X11DropTarget
default, default,
drag, drag,
DragDropEffects.None, DragDropEffects.None,
RawInputModifiers.None); modifiers);
_dragDropDevice.ProcessRawEvent(dragLeave); _dragDropDevice.ProcessRawEvent(dragLeave);
@ -130,6 +133,8 @@ internal sealed class X11DropTarget
if (_currentDrag is not { } drag || message.ptr1 != drag.SourceWindow) if (_currentDrag is not { } drag || message.ptr1 != drag.SourceWindow)
return; return;
var modifiers = GetModifiers();
var drop = new RawDragEvent( var drop = new RawDragEvent(
_dragDropDevice, _dragDropDevice,
RawDragEventType.Drop, RawDragEventType.Drop,
@ -137,7 +142,7 @@ internal sealed class X11DropTarget
drag.LastPosition ?? default, drag.LastPosition ?? default,
drag, drag,
drag.ResultEffects, drag.ResultEffects,
RawInputModifiers.None); modifiers);
_dragDropDevice.ProcessRawEvent(drop); _dragDropDevice.ProcessRawEvent(drop);
@ -176,6 +181,11 @@ internal sealed class X11DropTarget
XFlush(_display); 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() private void DisposeCurrentDrag()
{ {
if (_currentDrag is not { } drag) 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 physicalKey = X11KeyTransform.PhysicalKeyFromScanCode(ev.KeyEvent.keycode);
var (x11Key, key, symbol) = LookupKey(ref ev.KeyEvent, physicalKey); 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 timestamp = (ulong)ev.KeyEvent.time.ToInt64();
var args = ev.type == XEventName.KeyPress ? var args = ev.type == XEventName.KeyPress ?

28
src/Avalonia.X11/X11Window.cs

@ -610,7 +610,7 @@ namespace Avalonia.X11
: new Vector(-1, 0); : new Vector(-1, 0);
ScheduleInput(new RawMouseWheelEventArgs(_mouse, (ulong)ev.ButtonEvent.time.ToInt64(), ScheduleInput(new RawMouseWheelEventArgs(_mouse, (ulong)ev.ButtonEvent.time.ToInt64(),
_inputRoot, new Point(ev.ButtonEvent.x, ev.ButtonEvent.y), delta, _inputRoot, new Point(ev.ButtonEvent.x, ev.ButtonEvent.y), delta,
TranslateModifiers(ev.ButtonEvent.state)), ref ev); ev.ButtonEvent.state.ToRawInputModifiers()), ref ev);
} }
} }
@ -887,30 +887,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 _requestedWindowDecorations = WindowDecorations.Full;
private WindowDecorations _windowDecorations = WindowDecorations.Full; private WindowDecorations _windowDecorations = WindowDecorations.Full;
private bool _canResize = true; private bool _canResize = true;
@ -1018,7 +994,7 @@ namespace Avalonia.X11
return; return;
var mev = new RawPointerEventArgs( var mev = new RawPointerEventArgs(
_mouse, (ulong)ev.ButtonEvent.time.ToInt64(), _inputRoot, _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); ScheduleInput(mev, ref ev);
} }

6
src/Avalonia.X11/XLib.cs

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

Loading…
Cancel
Save