wayland_virtual_input_go

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 16, 2025 License: MIT Imports: 0 Imported by: 0

README

Wayland Virtual Input Go Bindings

Production-ready Go bindings for Wayland virtual input protocols - Control mouse and keyboard input programmatically on Wayland compositors.

Go Reference Go Report Card

Overview

This library provides complete, working implementations for:

  • Virtual Pointer (zwlr_virtual_pointer_v1): Mouse movement, clicks, and scrolling
  • Virtual Keyboard (zwp_virtual_keyboard_v1): Keyboard input and key combinations

Built on top of neurlang/wayland client library, these bindings enable applications to inject input events directly into Wayland compositors.

Use Cases
  • Remote desktop applications - Forward input from remote clients
  • Input automation and testing - Programmatic UI testing
  • Accessibility tools - Alternative input methods
  • Screen sharing applications - Multi-user input handling
  • Gaming and simulation - Synthetic input generation

Features

Virtual Pointer
  • Relative and absolute mouse movement
  • Mouse button events (left, right, middle, side, extra)
  • Scroll wheel events (vertical and horizontal)
  • Multiple axis sources (wheel, finger, continuous, wheel tilt)
  • Discrete scrolling support
  • Frame-based event grouping
Virtual Keyboard
  • Individual key press/release events
  • String typing with automatic character mapping
  • Modifier key support (Ctrl, Alt, Shift, etc.)
  • Function keys and navigation keys
  • Numeric keypad support
  • Key combinations and shortcuts
  • Modifier state management

Installation

go get github.com/bnema/wayland-virtual-input-go

Quick Start

Virtual Pointer Example
package main

import (
    "context"
    "log"
    "time"
    
    "github.com/bnema/wayland-virtual-input-go/virtual_pointer"
)

func main() {
    ctx := context.Background()
    
    // Create virtual pointer manager
    manager, err := virtual_pointer.NewVirtualPointerManager(ctx)
    if err != nil {
        log.Fatal(err)
    }
    defer manager.Close()
    
    // Create virtual pointer
    pointer, err := manager.CreatePointer()
    if err != nil {
        log.Fatal(err)
    }
    defer pointer.Close()
    
    // Move mouse relatively (100px right, 50px down)
    err = pointer.MoveRelative(100.0, 50.0)
    if err != nil {
        log.Fatal(err)
    }
    
    // Left click
    err = pointer.LeftClick()
    if err != nil {
        log.Fatal(err)
    }
    
    // Scroll down
    err = pointer.ScrollVertical(5.0)
    if err != nil {
        log.Fatal(err)
    }
}
Virtual Keyboard Example
package main

import (
    "context"
    "log"
    
    "github.com/bnema/wayland-virtual-input-go/virtual_keyboard"
)

func main() {
    ctx := context.Background()
    
    // Create virtual keyboard manager
    manager, err := virtual_keyboard.NewVirtualKeyboardManager(ctx)
    if err != nil {
        log.Fatal(err)
    }
    defer manager.Close()
    
    // Create virtual keyboard
    keyboard, err := manager.CreateKeyboard()
    if err != nil {
        log.Fatal(err)
    }
    defer keyboard.Close()
    
    // Type a string (handles uppercase automatically)
    err = keyboard.TypeString("Hello, Wayland!")
    if err != nil {
        log.Fatal(err)
    }
    
    // Press Enter
    err = keyboard.TypeKey(virtual_keyboard.KEY_ENTER)
    if err != nil {
        log.Fatal(err)
    }
}

API Reference

Virtual Pointer
Main Types
type VirtualPointerManager struct {
    // Creates and manages virtual pointer devices
}

type VirtualPointer struct {
    // Represents a virtual pointer device for input injection
}
Key Methods
// Manager creation
func NewVirtualPointerManager(ctx context.Context) (*VirtualPointerManager, error)
func (m *VirtualPointerManager) CreatePointer() (*VirtualPointer, error)
func (m *VirtualPointerManager) Close() error

// Core pointer operations  
func (p *VirtualPointer) Motion(time time.Time, dx, dy float64) error
func (p *VirtualPointer) Button(time time.Time, button, state uint32) error
func (p *VirtualPointer) Axis(time time.Time, axis uint32, value float64) error
func (p *VirtualPointer) Frame() error
func (p *VirtualPointer) Close() error

// Convenience methods
func (p *VirtualPointer) MoveRelative(dx, dy float64) error
func (p *VirtualPointer) LeftClick() error
func (p *VirtualPointer) RightClick() error
func (p *VirtualPointer) MiddleClick() error  
func (p *VirtualPointer) ScrollVertical(value float64) error
func (p *VirtualPointer) ScrollHorizontal(value float64) error
Constants
// Mouse buttons (Linux input event codes)
const (
    BTN_LEFT   = 0x110
    BTN_RIGHT  = 0x111 
    BTN_MIDDLE = 0x112
    BTN_SIDE   = 0x113
    BTN_EXTRA  = 0x114
)

// Button/axis states
const (
    ButtonStateReleased = 0
    ButtonStatePressed  = 1
    AxisVertical       = 0
    AxisHorizontal     = 1
)
Virtual Keyboard
Main Types
type VirtualKeyboardManager struct {
    // Creates and manages virtual keyboard devices  
}

type VirtualKeyboard struct {
    // Represents a virtual keyboard device for input injection
}
Key Methods
// Manager creation
func NewVirtualKeyboardManager(ctx context.Context) (*VirtualKeyboardManager, error)
func (m *VirtualKeyboardManager) CreateKeyboard() (*VirtualKeyboard, error) 
func (m *VirtualKeyboardManager) Close() error

// Core keyboard operations
func (k *VirtualKeyboard) Key(timestamp time.Time, key uint32, state KeyState) error
func (k *VirtualKeyboard) Modifiers(modsDepressed, modsLatched, modsLocked, group uint32) error
func (k *VirtualKeyboard) Close() error

// Convenience methods
func (k *VirtualKeyboard) PressKey(key uint32) error
func (k *VirtualKeyboard) ReleaseKey(key uint32) error
func (k *VirtualKeyboard) TypeKey(key uint32) error
func (k *VirtualKeyboard) TypeString(text string) error
Constants
// Key codes (Linux input event codes)
const (
    KEY_A = 30; KEY_B = 48; KEY_C = 46; KEY_D = 32; KEY_E = 18
    KEY_F = 33; KEY_G = 34; KEY_H = 35; KEY_I = 23; KEY_J = 36
    // ... (full alphabet A-Z)
    KEY_1 = 2; KEY_2 = 3; KEY_3 = 4; KEY_4 = 5; KEY_5 = 6
    KEY_6 = 7; KEY_7 = 8; KEY_8 = 9; KEY_9 = 10; KEY_0 = 11
    KEY_SPACE = 57; KEY_ENTER = 28; KEY_TAB = 15; KEY_BACKSPACE = 14
    KEY_LEFTSHIFT = 42; KEY_LEFTCTRL = 29; KEY_LEFTALT = 56
    // ... (complete list available in source)
)

// Key states
const (
    KeyStateReleased KeyState = 0
    KeyStatePressed  KeyState = 1  
)

Testing & Examples

Interactive Tests

The library includes interactive test programs that demonstrate real functionality:

# Comprehensive test with both mouse and keyboard
go run tests/inject/main.go

# Minimal mouse movement test  
go run tests/minimal/main.go

Note: These tests require a Wayland compositor that supports virtual input protocols (e.g., Sway, Hyprland).

Running Tests
# Run all tests
go test ./...

# Test specific packages
go test ./virtual_pointer
go test ./virtual_keyboard
go test ./internal/protocols

# Run with coverage
go test -cover ./...

# Debug protocol communication
WAYLAND_DEBUG=1 go run tests/minimal/main.go

Development Tools

Code Generation

The tools/generate.go utility can generate Go bindings from Wayland protocol XML files:

# Generate virtual pointer bindings
go run tools/generate.go \
  -protocol=virtual_pointer \
  -xml=../wlr-protocols/unstable/wlr-virtual-pointer-unstable-v1.xml \
  -output=virtual_pointer/generated.go

# Generate virtual keyboard bindings
go run tools/generate.go \
  -protocol=virtual_keyboard \
  -xml=path/to/virtual-keyboard-unstable-v1.xml \
  -output=virtual_keyboard/generated.go

Architecture

Implementation

This library provides complete, production-ready implementations of Wayland virtual input protocols. Built on neurlang/wayland, it handles all the complex Wayland protocol communication automatically.

Core Components
  1. Protocol Layer (internal/protocols/) - Low-level protocol implementations

    • Direct Wayland protocol request/response handling
    • Proper object lifecycle management
    • Fixed-point number conversion for coordinates
  2. Client Layer (internal/client/) - Wayland connection management

    • Display connection and registry handling
    • Protocol global discovery and binding
    • Event loop and context management
  3. High-Level APIs (virtual_pointer/, virtual_keyboard/) - User-friendly interfaces

    • Convenience methods for common operations
    • Automatic resource cleanup
    • Error handling and validation
Key Features
  • Zero Dependencies - Only depends on neurlang/wayland
  • Thread Safe - Safe for concurrent use
  • Resource Management - Automatic cleanup and proper object destruction
  • Error Handling - Comprehensive error reporting
  • Protocol Compliance - Fully compliant with Wayland protocol specifications

Protocol Support

Implemented Protocols
  • zwlr_virtual_pointer_v1 (wlroots virtual pointer)

    • ✅ Relative pointer motion with fixed-point precision
    • ✅ Button press/release events (left, right, middle, side, extra)
    • ✅ Axis events for scrolling (vertical/horizontal)
    • ✅ Frame-based event grouping
    • ✅ Axis source information
    • ✅ Discrete scrolling support
  • zwp_virtual_keyboard_v1 (Wayland virtual keyboard)

    • ✅ Key press/release events with timestamp
    • ✅ XKB keymap management (automatic default keymap)
    • ✅ Modifier state handling
    • ✅ File descriptor passing for keymaps
Protocol Implementation Details
  • Proper Wayland Object Lifecycle - Correct creation, binding, and destruction
  • Fixed-Point Arithmetic - Wayland uses 24.8 fixed-point for coordinates
  • File Descriptor Handling - Proper fd passing for keyboard keymaps
  • Event Sequencing - Correct ordering of protocol requests
  • Error Handling - Comprehensive error reporting for protocol failures

Security Considerations

Virtual input protocols have significant security implications:

  • Compositor Permission: Most Wayland compositors require explicit permission or privileged access to create virtual input devices
  • Sandboxing: Applications may need special permissions or be run outside sandboxes
  • User Consent: Consider requiring user consent before creating virtual input devices
  • Input Validation: Always validate input parameters to prevent potential security issues

Compatibility

Wayland Compositors

Tested and Working:

  • Sway - Full support for both protocols
  • Hyprland - Full support for both protocols
  • wlroots-based compositors - Full support

Limited/Untested:

  • ⚠️ GNOME - May require additional permissions
  • ⚠️ KDE Plasma - Limited virtual input support
  • Other compositors - Check wayland-info | grep virtual
System Requirements
  • Go 1.19+ (tested on Go 1.20+)
  • Wayland compositor with virtual input protocol support
  • Linux (uses Linux input event codes)
  • Wayland session (XDG_SESSION_TYPE=wayland)
Verification

Check if your compositor supports the required protocols:

# Check available protocols
wayland-info | grep -E "(virtual_pointer|virtual_keyboard)"

# Should show:
# zwlr_virtual_pointer_manager_v1
# zwp_virtual_keyboard_manager_v1

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Write tests for new functionality
  4. Ensure all tests pass
  5. Submit a pull request
Development Guidelines
  • Follow Go conventions and idioms
  • Write comprehensive tests
  • Document all public APIs
  • Maintain backward compatibility
  • Update examples when adding features

License

This project is dual-licensed:

  • The library code is licensed under the MIT License
  • Protocol definitions follow their respective licenses (typically MIT-style)

See the protocol source files for specific licensing information.

Acknowledgments

  • wlroots project for the virtual pointer protocol specification
  • Wayland project for the virtual keyboard protocol specification
  • Go community for excellent tooling and libraries

Support

For bugs, feature requests, or questions:

  1. Check existing issues
  2. Create a new issue with detailed information
  3. Include Go version, OS, and Wayland compositor details
  4. Provide minimal reproduction code when possible

Documentation

Overview

Package wayland_virtual_input_go provides Go bindings for Wayland virtual input protocols.

This library implements Go bindings for the wlr-virtual-pointer-unstable-v1 and virtual-keyboard-unstable-v1 Wayland protocols, enabling applications to inject mouse and keyboard events into Wayland compositors without requiring root privileges.

Supported Protocols

• wlr-virtual-pointer-unstable-v1: Mouse input injection (motion, buttons, scroll) • virtual-keyboard-unstable-v1: Keyboard input injection (keys, modifiers, text) • pointer-constraints-unstable-v1: Exclusive pointer capture and constraints • keyboard-shortcuts-inhibit-unstable-v1: Keyboard shortcut inhibition

Compositor Compatibility

This library is designed for and tested with wlroots-based compositors: • Hyprland (full support) • Sway (full support) • Other wlroots compositors (generally supported)

Note: GNOME and KDE have limited or no support for these protocols.

Security Model

Virtual input protocols work at the user level without requiring root privileges. The Wayland compositor controls access and can implement security policies. Most wlroots-based compositors allow virtual input devices by default.

Basic Usage

Virtual Pointer (Mouse):

import "github.com/bnema/wayland-virtual-input-go/virtual_pointer"

// Create manager and pointer
manager := virtual_pointer.NewVirtualPointerManager(display, registry)
pointer := manager.CreateVirtualPointer(seat)

// Move mouse cursor
pointer.Motion(timestamp, 10.0, 5.0)
pointer.Frame()

// Click left button
pointer.LeftClick()

Virtual Keyboard:

import "github.com/bnema/wayland-virtual-input-go/virtual_keyboard"

// Create manager and keyboard
manager := virtual_keyboard.NewVirtualKeyboardManager(display, registry)
keyboard := manager.CreateVirtualKeyboard(seat)

// Type text
keyboard.TypeString("Hello, World!")

// Press key combination
keyboard.ModifierPress(virtual_keyboard.MOD_CTRL)
keyboard.Key(virtual_keyboard.KEY_C, virtual_keyboard.KEY_STATE_PRESSED)

Architecture

The library provides high-level Go interfaces that wrap the low-level Wayland protocol messages. It includes:

• Protocol-compliant message generation • Convenient wrapper functions for common operations • Proper error handling and resource management • Comprehensive documentation and examples

Thread Safety

The current implementation is not thread-safe. All operations should be performed from the same goroutine that manages the Wayland event loop.

Error Handling

All methods return errors for proper error handling. Common error conditions include: • Wayland connection failures • Protocol not supported by compositor • Invalid parameters or state

See the examples/ directory for complete working examples.

Directories

Path Synopsis
examples
combined_demo command
Combined mouse + keyboard demonstration
Combined mouse + keyboard demonstration
keyboard_simple command
Simple keyboard input example
Simple keyboard input example
mouse_simple command
Simple mouse control example
Simple mouse control example
internal
Package keyboard_shortcuts_inhibitor provides Go bindings for the keyboard-shortcuts-inhibit-unstable-v1 Wayland protocol.
Package keyboard_shortcuts_inhibitor provides Go bindings for the keyboard-shortcuts-inhibit-unstable-v1 Wayland protocol.
Package pointer_constraints provides Go bindings for the pointer-constraints-unstable-v1 Wayland protocol.
Package pointer_constraints provides Go bindings for the pointer-constraints-unstable-v1 Wayland protocol.
Package scanner provides a Wayland protocol scanner that generates Go bindings from XML protocol files.
Package scanner provides a Wayland protocol scanner that generates Go bindings from XML protocol files.
cmd/wayland-scanner command
Command wayland-scanner generates Go bindings from Wayland protocol XML files.
Command wayland-scanner generates Go bindings from Wayland protocol XML files.
tests
inject command
Comprehensive integration test for virtual input functionality
Comprehensive integration test for virtual input functionality
minimal command
Minimal virtual pointer test for basic functionality verification
Minimal virtual pointer test for basic functionality verification
Package main provides a code generator for Wayland virtual input protocol bindings.
Package main provides a code generator for Wayland virtual input protocol bindings.
Package virtual_keyboard provides Go bindings for the virtual-keyboard-unstable-v1 Wayland protocol.
Package virtual_keyboard provides Go bindings for the virtual-keyboard-unstable-v1 Wayland protocol.
Package virtual_pointer provides Go bindings for the wlr-virtual-pointer-unstable-v1 Wayland protocol.
Package virtual_pointer provides Go bindings for the wlr-virtual-pointer-unstable-v1 Wayland protocol.
Package wlclient provides a minimal Wayland client implementation for virtual input protocols.
Package wlclient provides a minimal Wayland client implementation for virtual input protocols.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL