Edit

Haptics in Windows apps

Haptics add a sense of touch to digital interactions, making experiences feel more responsive and intuitive. While most digital interfaces rely on visual or auditory feedback alone, haptic feedback provides a physical confirmation that reinforces user input and creates a clearer, more immediate connection between action and response.

Windows supports contextual haptic feedback through the InputHapticsManager API, enabling apps to deliver consistent touch feedback across supported devices.

Tip

For more details and visual guides, see Haptics design and implementation on microsoft.design.

Why add haptics?

Adding haptic feedback to your app benefits users in three key ways:

Clarity — Haptic feedback reinforces interactions by providing a physical confirmation, helping make actions feel responsive and reducing uncertainty about whether an action occurred.

Inclusion — Haptics extend feedback beyond visual and auditory channels, helping make interactions more accessible for users with different needs and preferences.

Delight — Thoughtfully designed haptics bring interactions to life through subtle, expressive feedback—adding moments of delight beyond basic function.

Passive vs. active haptics

Haptic feedback can be either:

  • Passive — comes directly from physical interaction with hardware (for example, the tactile click of a physical button).
  • Active — generated by the device and controlled through software using the InputHapticsManager API.

The InputHapticsManager API enables active haptics, letting your app control when feedback occurs and what it feels like. Haptics are most effective when used alongside visual and auditory feedback, reinforcing interactions without adding complexity.

Haptic language

Windows provides a set of predefined haptic waveforms designed for common interaction patterns. Each waveform has a distinct feel and purpose, helping create consistent experiences across applications and devices.

Waveforms are defined by three characteristics:

Characteristic Description
Intensity How strong the feedback feels.
Decay How quickly the feedback fades.
Sharpness The character of the feedback, ranging from soft to crisp.

Interaction feedback waveforms

These waveforms provide feedback during an interaction.

Waveform API constant Description
Hover Hover A light pulse that indicates hover states, signaling an upcoming action.
Collide Collide A soft pulse that indicates reaching a boundary or limit.
Align Align A sharp pulse when an object snaps to an alignment guide.
Step Step A firm pulse for discrete changes, such as moving through steps or values.
Grow Grow A dynamic pulse that conveys motion, transitions, or intelligent system activity.

Process confirmation waveforms

These waveforms communicate the outcome of a completed action.

Waveform API constant Description
Success Success An ascending pattern that confirms a completed action.
Error Error A descending pattern that indicates a failed action.

Note

Collide, Align, Step, and Grow were added in Windows SDK 10.0.28000.1839. On earlier SDK versions, fall back to Click or check for support with ApiInformation before using them.

User control and intensity

Haptic preferences vary by user. Windows allows users to adjust intensity or turn haptics off entirely in Settings > Bluetooth & devices > Touch.

Design your experience so it remains clear and usable even when haptics are reduced or disabled. Never rely on haptics as the sole indicator of an interaction outcome.

When to use haptics

Haptics should feel like a natural part of an interaction—not a distraction. Use them to reinforce user input, not to add decoration. The following principles guide when and how to use haptics effectively.

1. Establish a clear cause–effect relationship

Haptic feedback should be a reliable response to user input. Reserve it for user-initiated actions to create a clear, intuitive connection. Delays weaken that connection—aim for latency under 50 ms between the triggering event and feedback delivery.

2. Provide signals, not noise

Not every interaction needs feedback. Use haptics where they add value. The following patterns represent common scenarios where haptics improve clarity:

Scenario Purpose Trigger Recommended waveform
Object alignment Indicate when an object aligns to the edge or center of another object. Cursor snaps to an alignment guide while moving or resizing. Align
Drop target Indicate that an item can be dropped at the current location. Dragging an item over a valid drop target. Click (Hover)
Slider detent Indicate discrete steps or values within a range. Control reaches a step or snaps to a value. Step
Screen edge Indicate that a boundary has been reached. Dragging a window to the edge of the screen to activate Snap. Collide

3. Provide haptics consistently

Apply haptics consistently across similar interactions so users can build an understanding of what each signal represents. Use each waveform for its intended purpose and avoid mixing patterns for the same interaction type.

When combining haptics with visual or audio feedback, align them in timing and intensity. Well-designed haptics may go unnoticed consciously, but their absence is felt.

Supported devices

Haptics are supported on input devices such as mice, touchpads, and pens. Availability varies by model and manufacturer. Always check for support at runtime before calling haptics APIs (see Check for support below).

Requirements

Requirement Details
Namespace Windows.Devices.Haptics
Minimum OS Windows 11, SDK 10.0.28000.1721 (March 2026)
Align / Collide / Step / Grow waveforms SDK 10.0.28000.1839 (April 2026)
API contract UniversalApiContract version 19.0

To target earlier OS versions, use ApiInformation.IsTypePresent to guard all calls (see code below).

Implementing haptics

Use the InputHapticsManager API to add haptic feedback to your app.

Check for support

Always verify that the API is available and that a haptic device is present before use. The API is not present on older OS versions, and not all input devices support haptics.

using Windows.Devices.Haptics;
using Windows.Foundation.Metadata;

// Guard against older OS versions where the API is absent.
bool apiPresent = ApiInformation.IsTypePresent("Windows.Devices.Haptics.InputHapticsManager");

// Check that a supported haptic device is connected.
bool supported = apiPresent && InputHapticsManager.IsSupported();

Trigger a waveform

Call InputHapticsManager.GetForCurrentThread() on the UI thread to obtain a manager instance scoped to the current thread's input focus. Device detection and routing are handled automatically—you don't need to enumerate devices yourself.

using Windows.Devices.Haptics;

if (supported)
{
    var mgr = InputHapticsManager.GetForCurrentThread();

    // The second parameter is a fallback waveform used if the first is
    // unsupported. Passing 0 lets the system choose a device-appropriate
    // fallback. TrySendHapticWaveform returns false if neither waveform is
    // supported; this is a non-fatal condition.
    bool sent = mgr.TrySendHapticWaveform(
        KnownSimpleHapticsControllerWaveforms.Align,
        0);
}

Important

Call GetForCurrentThread() from the UI thread (or the thread that owns input focus). Calling it from a background thread will not route feedback to the correct device.

Stop playback

Call TryStopFeedback when a drag or interaction ends to halt any ongoing haptic playback.

using Windows.Devices.Haptics;

if (supported)
{
    InputHapticsManager
        .GetForCurrentThread()
        .TryStopFeedback();
}

Implementation examples

Object alignment

Alignment guides are common in design tools, presentation editors, and diagramming apps. Haptic feedback adds a second channel so users can feel when objects snap into place—reducing the need to zoom in to visually confirm alignment.

When to fire: Use the alignment guide's appearance as the trigger. When your snap logic shows a guide, fire the haptic. If no guide appears, don't fire. This keeps haptic events tightly coupled to visible system feedback.

Avoid duplicates: A shape can align to multiple guides simultaneously (for example, left edge and top edge). Treat this as a single interaction—track active guides and only fire when a new guide appears.

using Windows.Devices.Haptics;

private readonly HashSet<int> _activeGuides = new();

// Call this after computing which alignment guides are currently visible.
void OnGuidesUpdated(IEnumerable<int> currentGuideIds)
{
    var currentGuides = currentGuideIds.ToHashSet();

    bool hasNewGuide = currentGuides.Except(_activeGuides).Any();

    // Update the tracked set in place (field is readonly).
    _activeGuides.Clear();
    _activeGuides.UnionWith(currentGuides);

    if (hasNewGuide && supported)
    {
        InputHapticsManager.GetForCurrentThread()
            .TrySendHapticWaveform(
                KnownSimpleHapticsControllerWaveforms.Align,
                0);
    }
}

Sliders

Haptics improve slider interactions by anchoring feedback to meaningful positions. Always tie feedback to visible markers the user can understand—tick marks, named values, or range boundaries.

When to fire: Fire haptics as the thumb crosses each tick mark. Avoid continuous feedback between ticks, which can feel distracting.

using Windows.Devices.Haptics;

double _previousValue;
const double TickInterval = 25.0;

void OnSliderValueChanged(double newValue)
{
    int previousTick = (int)(_previousValue / TickInterval);
    int currentTick  = (int)(newValue       / TickInterval);

    if (currentTick != previousTick && supported)
    {
        InputHapticsManager.GetForCurrentThread()
            .TrySendHapticWaveform(
                KnownSimpleHapticsControllerWaveforms.Step,
                0);
    }

    _previousValue = newValue;
}

Refining the experience: Scale haptic intensity based on slider position to help users sense where they are within the range. Use TrySendHapticWaveformForPlayCount, which accepts an explicit intensity value from 0.0 to 1.0.

void OnSliderValueChangedWithIntensity(double newValue, double maxValue)
{
    int previousTick = (int)(_previousValue / TickInterval);
    int currentTick  = (int)(newValue       / TickInterval);

    if (currentTick != previousTick && supported)
    {
        double intensity = newValue / maxValue; // Scale 0.0–1.0

        InputHapticsManager.GetForCurrentThread()
            .TrySendHapticWaveformForPlayCount(
                KnownSimpleHapticsControllerWaveforms.Step,
                0,          // fallback waveform
                intensity,
                1,          // playCount
                TimeSpan.Zero);
    }

    _previousValue = newValue;
}

Drag interactions and intent detection

During a drag, an object can cross many alignment boundaries—page center, guides, other objects. Triggering haptics at every crossing can overwhelm users, especially during fast movements when they are repositioning rather than trying to be precise.

Use intent detection to fire feedback only when the user is trying to align deliberately, not just passing through.

Approach 1: Speed filter

Suppress haptics when the cursor is moving quickly, reserving feedback for slower, more deliberate movement.

  • Stabilize the signal. Avoid using raw cursor deltas, which can be noisy across input types, DPI settings, and display configurations. Normalize and smooth the signal.
  • Choose a threshold carefully. Validate across different devices, input types, display scales, and multi-display setups.

Approach 2: Timer debounce

When an object enters a trigger zone, start a short timer (50 ms is a reasonable starting point). If the object remains in the zone when the timer completes, treat it as intentional and fire the haptic. If the object moves on before the timer fires, suppress the feedback.

  • Simpler to implement and tends to produce more stable behavior than speed filtering.
  • A 50 ms delay is long enough to distinguish deliberate alignment from a quick pass, while remaining below the threshold of noticeable latency.
using Windows.Devices.Haptics;

private DispatcherTimer? _alignTimer;

void OnObjectEnteredAlignmentZone()
{
    _alignTimer?.Stop();
    _alignTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(50) };
    _alignTimer.Tick += (_, _) =>
    {
        _alignTimer.Stop();
        if (supported)
        {
            InputHapticsManager.GetForCurrentThread()
                .TrySendHapticWaveform(
                    KnownSimpleHapticsControllerWaveforms.Align,
                    0);
        }
    };
    _alignTimer.Start();
}

void OnObjectLeftAlignmentZone()
{
    _alignTimer?.Stop();
}

Choosing between the two

Speed filter Timer debounce
How it works Reactive—measures movement in real time Predictive—waits briefly to confirm intent
Feel Can feel more immediate Slightly delayed, but more consistent
Tuning effort Higher—requires careful calibration Lower—a single delay value is usually sufficient
Recommended for Apps requiring highly responsive feedback Most apps; good default starting point