in src/Avalonia.X11/X11Window.cs [515:674]
private void OnEvent(ref XEvent ev)
{
if (_inputRoot is null)
return;
if(_mode.OnEvent(ref ev))
return;
_activationTracker?.OnEvent(ref ev);
if (ev.type == XEventName.MapNotify)
{
_mapped = true;
if (_useRenderWindow)
XMapWindow(_x11.Display, _renderHandle);
}
else if (ev.type == XEventName.UnmapNotify)
_mapped = false;
else if (ev.type == XEventName.Expose ||
(ev.type == XEventName.VisibilityNotify &&
ev.VisibilityEvent.state < 2))
{
EnqueuePaint();
}
else if (ev.type == XEventName.MotionNotify)
MouseEvent(RawPointerEventType.Move, ref ev, ev.MotionEvent.state);
else if (ev.type == XEventName.LeaveNotify)
MouseEvent(RawPointerEventType.LeaveWindow, ref ev, ev.CrossingEvent.state);
else if (ev.type == XEventName.PropertyNotify)
{
OnPropertyChange(ev.PropertyEvent.atom, ev.PropertyEvent.state == 0);
}
else if (ev.type == XEventName.ButtonPress)
{
if (ActivateTransientChildIfNeeded())
return;
if (ev.ButtonEvent.button < 4 || ev.ButtonEvent.button == 8 || ev.ButtonEvent.button == 9)
MouseEvent(
ev.ButtonEvent.button switch
{
1 => RawPointerEventType.LeftButtonDown,
2 => RawPointerEventType.MiddleButtonDown,
3 => RawPointerEventType.RightButtonDown,
8 => RawPointerEventType.XButton1Down,
9 => RawPointerEventType.XButton2Down,
_ => throw new NotSupportedException("Unexepected RawPointerEventType.")
},
ref ev, ev.ButtonEvent.state);
else
{
var delta = ev.ButtonEvent.button == 4
? new Vector(0, 1)
: ev.ButtonEvent.button == 5
? new Vector(0, -1)
: ev.ButtonEvent.button == 6
? new Vector(1, 0)
: 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);
}
}
else if (ev.type == XEventName.ButtonRelease)
{
if (ev.ButtonEvent.button < 4 || ev.ButtonEvent.button == 8 || ev.ButtonEvent.button == 9)
MouseEvent(
ev.ButtonEvent.button switch
{
1 => RawPointerEventType.LeftButtonUp,
2 => RawPointerEventType.MiddleButtonUp,
3 => RawPointerEventType.RightButtonUp,
8 => RawPointerEventType.XButton1Up,
9 => RawPointerEventType.XButton2Up,
_ => throw new NotSupportedException("Unexepected RawPointerEventType.")
},
ref ev, ev.ButtonEvent.state);
}
else if (ev.type == XEventName.ConfigureNotify)
{
if (ev.ConfigureEvent.window != _handle)
return;
var needEnqueue = (_configure == null);
_configure = ev.ConfigureEvent;
if (ev.ConfigureEvent.override_redirect != 0 || ev.ConfigureEvent.send_event != 0)
_configurePoint = new PixelPoint(ev.ConfigureEvent.x, ev.ConfigureEvent.y);
else
{
XTranslateCoordinates(_x11.Display, _handle, _x11.RootWindow,
0, 0,
out var tx, out var ty, out _);
_configurePoint = new PixelPoint(tx, ty);
}
if (needEnqueue)
Dispatcher.UIThread.Post(() =>
{
if (_configure == null)
return;
var cev = _configure.Value;
var npos = _configurePoint.Value;
_configure = null;
_configurePoint = null;
var nsize = new PixelSize(cev.width, cev.height);
var changedSize = _realSize != nsize;
var changedPos = _position == null || npos != _position;
_realSize = nsize;
_position = npos;
bool updatedSizeViaScaling = false;
if (changedPos)
{
PositionChanged?.Invoke(npos);
updatedSizeViaScaling = UpdateScaling();
}
UpdateImePosition();
if (changedSize && !updatedSizeViaScaling && !_overrideRedirect)
Resized?.Invoke(ClientSize, WindowResizeReason.Unspecified);
}, DispatcherPriority.AsyncRenderTargetResize);
if (_useRenderWindow && !_useCompositorDrivenRenderWindowResize)
XConfigureResizeWindow(_x11.Display, _renderHandle, ev.ConfigureEvent.width,
ev.ConfigureEvent.height);
if (_xSyncState == XSyncState.WaitConfigure)
{
_xSyncState = XSyncState.WaitPaint;
EnqueuePaint();
}
}
else if (ev.type == XEventName.DestroyNotify
&& ev.DestroyWindowEvent.window == _handle)
{
_mode.OnDestroyNotify();
Cleanup(true);
}
else if (ev.type == XEventName.ClientMessage)
{
if (ev.ClientMessageEvent.message_type == _x11.Atoms.WM_PROTOCOLS)
{
if (ev.ClientMessageEvent.ptr1 == _x11.Atoms.WM_DELETE_WINDOW)
{
if (IsEnabled && Closing?.Invoke(WindowCloseReason.WindowClosing) != true)
Dispose();
}
else if (ev.ClientMessageEvent.ptr1 == _x11.Atoms._NET_WM_SYNC_REQUEST)
{
_xSyncValue.Lo = new UIntPtr(ev.ClientMessageEvent.ptr3.ToPointer()).ToUInt32();
_xSyncValue.Hi = ev.ClientMessageEvent.ptr4.ToInt32();
_xSyncState = XSyncState.WaitConfigure;
}
}
}
else if (ev.type == XEventName.KeyPress || ev.type == XEventName.KeyRelease)
{
if (ActivateTransientChildIfNeeded())
return;
HandleKeyEvent(ref ev);
}
}