AgentStack
SKILL verified MIT Self-run

Avalonia Input Interaction

skill-linuxdevel-avalonia-skills-avalonia-input-interaction · by linuxdevel

Use when handling pointer events, keyboard input, gestures, focus, drag-and-drop, or hot keys in Avalonia. Covers PointerPressed/Released/Moved, KeyDown/KeyUp, TextInput, HotKeyManager, KeyGesture, focus management, TapGestureRecognizer, PinchGestureRecognizer, DragDrop.DoDragDrop, DataObject, and Cursor types.

No reviews yet
0 installs
10 views
0.0% view→install

Install

$ agentstack add skill-linuxdevel-avalonia-skills-avalonia-input-interaction

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Avalonia Input Interaction? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Avalonia Input & Interaction

Overview

All input routes as routed events (bubbling by default, tunneling with "Preview" prefix). Pointer events are unified across mouse, touch, and stylus.

Pointer Events

| Event | Fires when | |---|---| | PointerPressed | Button/finger down | | PointerReleased | Button/finger up | | PointerMoved | Pointer moves over control | | PointerEntered | Pointer enters bounds | | PointerExited | Pointer leaves bounds | | PointerCaptureLost | Capture released | | Tapped | Quick tap/click | | DoubleTapped | Double tap/click | | RightTapped | Right-click / long press |

myControl.PointerPressed += (s, e) =>
{
    var point = e.GetPosition(myControl);
    var props = e.GetCurrentPoint(myControl).Properties;
    if (props.IsLeftButtonPressed) { /* left click */ }
    if (props.IsRightButtonPressed) { /* right click */ }
    if (props.IsMiddleButtonPressed) { /* middle click */ }
};

Capture pointer (receive events outside bounds):

myControl.PointerPressed += (s, e) =>
{
    e.Pointer.Capture(myControl);
};
myControl.PointerReleased += (s, e) =>
{
    e.Pointer.Capture(null); // release
};

Check pointer type:

myControl.PointerPressed += (s, e) =>
{
    if (e.Pointer.Type == PointerType.Touch) { /* touch */ }
    if (e.Pointer.Type == PointerType.Pen) { /* stylus */ }
};

Keyboard Events

| Event | Fires when | |---|---| | KeyDown | Key pressed (repeats while held) | | KeyUp | Key released | | TextInput | Text character produced |

myControl.KeyDown += (s, e) =>
{
    if (e.Key == Key.Enter && e.KeyModifiers == KeyModifiers.Control)
    {
        e.Handled = true; // stop bubbling + prevent default
        SubmitForm();
    }
};
myTextBox.TextInput += (s, e) =>
{
    if (!char.IsDigit(e.Text![0]))
        e.Handled = true; // block non-digit input
};

KeyModifiers flags: None, Alt, Control, Shift, Meta (combinable with |)

// Ctrl+Shift+Z
if (e.Key == Key.Z && e.KeyModifiers == (KeyModifiers.Control | KeyModifiers.Shift))

Hot Keys

XAML registration:

Code registration:

HotKeyManager.RegisterHotKey(myControl, new KeyGesture(Key.S, KeyModifiers.Control));
HotKeyManager.SetHotKey(myButton, new KeyGesture(Key.F5));

Unregister:

HotKeyManager.SetHotKey(myControl, null);

Focus

// Programmatic focus
myControl.Focus();

// Via FocusManager
var fm = TopLevel.GetTopLevel(this)?.FocusManager;
fm?.Focus(myControl, NavigationMethod.Tab);

// Get currently focused element
var focused = fm?.GetFocusedElement();

XAML focus control:

           
                
            

Pseudoclasses for styling:


    

    

Focus scope (contains Tab navigation):


    

Gesture Recognizers

Add to any InputElement.GestureRecognizers:


    
        
        
    
private void OnPinchUpdated(object? sender, PinchEventArgs e)
{
    _scale *= e.Scale;
    myBorder.RenderTransform = new ScaleTransform(_scale, _scale);
}

| Recognizer | Events | |---|---| | TapGestureRecognizer | Tapped | | DoubleTapGestureRecognizer | DoubleTapped | | PinchGestureRecognizer | PinchUpdated, PinchEnded | | PullGestureRecognizer | PullDelta, PullEnded | | ScrollGestureRecognizer | ScrollGesture, ScrollGestureEnded, ScrollGestureInertiaStarting |

Drag and Drop

Source (initiates drag):

private async void OnPointerPressed(object? sender, PointerPressedEventArgs e)
{
    var data = new DataObject();
    data.Set(DataFormats.Text, "dragged text");
    data.Set("custom/format", myObject);

    var result = await DragDrop.DoDragDrop(e, data,
        DragDropEffects.Copy | DragDropEffects.Move);
    // result: DragDropEffects indicating what happened
}

Target (receives drop):

private void OnDragOver(object? sender, DragEventArgs e)
{
    e.DragEffects = e.Data.Contains(DataFormats.Text)
        ? DragDropEffects.Copy
        : DragDropEffects.None;
    e.Handled = true;
}

private void OnDrop(object? sender, DragEventArgs e)
{
    if (e.Data.Contains(DataFormats.Text))
    {
        var text = e.Data.GetText();
        // use text
    }
    if (e.Data.Contains(DataFormats.Files))
    {
        var files = e.Data.GetFiles();
        // IEnumerable
    }
}

Built-in DataFormats: Text, Files, FileNames

Cursor

Available cursors: Default, Arrow, Cross, Hand, Help, IBeam, No, SizeAll, SizeNESW, SizeNS, SizeNWSE, SizeWE, TopSide, BottomSide, LeftSide, RightSide, Wait, None

Custom cursor from bitmap:

var cursor = new Cursor(myBitmap, new PixelPoint(hotspotX, hotspotY));
myControl.Cursor = cursor;

Scroll Events

myControl.PointerWheelChanged += (s, e) =>
{
    var delta = e.Delta; // Vector: X for horizontal, Y for vertical
    ScrollBy(-delta.Y * 30);
};

Common Mistakes

  • Not setting e.Handled = true on KeyDown — event bubbles to parent; TextBox will still consume keys
  • DragDrop.DoDragDrop must be called on pointer event — calling after await loses the pointer event context
  • Focus() before control is attached to visual tree — silently does nothing; call in OnAttachedToVisualTree or later
  • Gesture recognizers vs. eventsTapped/DoubleTapped fire on InputElement directly; TapGestureRecognizer needed only for custom gesture behavior
  • DragDrop.AllowDrop is an attached property — must be set on the drop target, not a parent
  • PointerPressed fires before Tapped — don't handle both if one is sufficient

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.