gohook

repository·master·Indexed 19 days ago

https://github.com/robotn/gohook

A low-level system event hooking library for Go that allows developers to register callbacks for keyboard and mouse events, including clicks, movement, and key combinations, across different operating systems.

Tokens
1.7K
Snippets
9
Records
10
Agent score
15%

What's inside gohook

  1. Register event callbacks with Register()

    master

    Use Register to define a callback function that triggers when specific system events occur. You can specify the event type (e.g., KeyDown, MouseDown) and a list of command strings representing the keys or buttons that must be active for the callback to fire.

    Parameters:

    • when (uint8): The type of event to listen for (e.g., KeyDown, KeyUp, MouseDown, MouseMove).
    • cmds ([]string): A slice of key/button command strings. For KeyUp events, these are treated as the keys that must have been released.
    • cb (func(Event)): The callback function executed when the event matches the criteria.
    hook.Register(hook.KeyDown, []string{"a", "b"}, func(e hook.Event) {
        fmt.Printf("Combo detected: %v\n", e)
    })
  2. Listen for mouse movement to a specific position with AddMousePos

    master

    Use AddMousePos(x, y int16) to block execution until the mouse cursor moves to the exact coordinates (x, y).

    // Blocks until mouse moves to x=500, y=500
    hook.AddMousePos(500, 500)
  3. Convert between Rawcode and Keychar

    master

    The package provides utility functions to translate between raw system keycodes and human-readable character strings, with platform-specific implementations for Darwin (macOS), Windows, and Linux.

    • RawcodeToKeychar(r uint16) string: Converts a raw numeric code to a string representation.
    • KeycharToRawcode(kc string) uint16: Converts a character string back to its raw numeric code.
  4. Process system events with Process()

    master

    The Process function starts a background goroutine that listens to a channel of Event objects and dispatches them to the callbacks registered via Register. It returns a channel that signals when the processing loop has finished (e.g., when the input channel is closed).

    Parameters:

    • evChan (<-chan Event): A receive-only channel providing the stream of system events.

    Returns:

    • out (chan bool): A channel that receives true once the evChan is closed and all pending events are processed.
    evChan := make(chan hook.Event)
    // ... populate evChan from system backend ...
    
    done := hook.Process(evChan)
    
    // Wait for processing to complete
    <-done
  5. Add a mouse button event hook with AddMouse

    master

    Use AddMouse(btn string, x ...int16) to listen for mouse button clicks.

    Parameters:

    • btn: The mouse button name. Valid strings include: left, center, right, wheelDown, wheelUp, wheelLeft, wheelRight.
    • x, y (optional): If provided, the hook will only trigger if the mouse button is pressed at these specific coordinates.

    This function blocks until the specified mouse button is pressed (and optionally at the specified location).

    // Listen for a left click anywhere
    hook.AddMouse("left")
    
    // Listen for a left click at coordinates (100, 100)
    hook.AddMouse("left", 100, 100)
  6. Add a global keyboard event hook with AddEvents

    master

    Use AddEvents(key string, arr ...string) to create a global hook that waits for a specific key combination to be released. This function blocks until the specified key is released. You can provide modifier keys (like ctrl or shift) as additional arguments.

    Supported modifiers are resolved via the Keycode map.

    Usage Patterns:

    • Single key: AddEvents("q")
    • Key with modifiers: AddEvents("q", "ctrl", "shift")
    // Blocks until 'q' is released
    hook.AddEvents("q")
    
    // Blocks until 'ctrl+shift+q' is released
    hook.AddEvents("q", "ctrl", "shift")
  7. Add a single keyboard event listener with AddEvent

    master

    Use AddEvent(key string) to listen for a specific keyboard key. If the provided key is not a mouse event string, the function attempts to resolve it using the Keycode map. It returns true if the event listener was successfully added.

    // Example: Listen for the 'a' key
    success := hook.AddEvent("a")
  8. Reference: Event Kind constants

    master

    The following constants define the type of Event being processed. These are used in Register and to identify the type of event in the Event.Kind field.

    const (
    	HookEnabled  = 1
    	HookDisabled = 2
    
    	KeyDown   = 4
    	KeyHold   = 3
    	KeyUp     = 5
    
    	MouseDown = 7
    	MouseHold = 8
    	MouseUp   = 6
    
    	MouseMove  = 9
    	MouseDrag  = 10
    	MouseWheel = 11
    
    	FakeEvent = 12
    )
  9. Understand the Event struct and its fields

    master

    The Event struct represents a captured system input. The fields available depend on the Kind of the event:

    Keyboard Events (KeyDown, KeyHold, KeyUp):

    • Keycode: The numeric code of the key.
    • Rawcode: The raw system code of the key.
    • Keychar: The rune representation of the character (usually the most useful field).
    • Mask: Bitmask for modifier keys.

    Mouse Events (MouseDown, MouseUp, MouseMove, etc.):

    • Button: The button identifier.
    • Clicks: Number of clicks.
    • X, Y: Coordinates of the mouse pointer.
    • Amount: Scroll wheel amount.
    • Rotation: Scroll wheel rotation.
    • Direction: Scroll wheel direction.
    type Event struct {
    	Kind     uint8     `json:"id"` // Event type (e.g., KeyDown, MouseDown)
    	When     time.Time
    	Mask     uint16    `json:"mask"` 
    	Reserved uint16    `json:"reserved"` 
    
    	Keycode uint16    `json:"keycode"` 
    	Rawcode uint16    `json:"rawcode"` 
    	Keychar rune     `json:"keychar"` 
    
    	Button uint16    `json:"button"` 
    	Clicks uint16    `json:"clicks"` 
    
    	X int16     `json:"x"` 
    	Y int16     `json:"y"` 
    
    	Amount    uint16 `json:"amount"` 
    	Rotation  int32  `json:"rotation"` 
    	Direction uint8  `json:"direction"` 
    }