cocoa

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Aug 10, 2026 License: BSD-3-Clause Imports: 1 Imported by: 0

Documentation

Overview

Package cocoa is the pure-Go (CGO-free, via purego) macOS AppKit windowing backend for the go-widgets toolkit. It opens a real NSWindow with a content NSView, blits the toolkit's RGBA framebuffer into it through an NSBitmapImageRep in -drawRect:, and routes native NSEvent mouse/scroll/key input into toolkit.Event, so a go-widgets widget tree runs on a macOS desktop exactly as it does on X11, Wayland or in the browser/wasm host.

The Objective-C runtime is reached through the fleet's shared bridge github.com/go-macos/objc (Send/RegisterClass/GetClass/NSString/GoString/…), itself layered over github.com/ebitengine/purego — no cgo — so the whole module builds and links with CGO_ENABLED=0.

This file is the SOVEREIGN, OS-INDEPENDENT half: the NSEvent→toolkit.Event mapping (key decode, modifier decode, button/wheel mapping), the flipped-view coordinate maths and the damage-rect→dirty-rect conversion, all expressed over plain Go values with a single toolkit dependency (the event model). It carries NO objc/purego/unsafe dependency, so it builds — and is unit-tested to 100% — on every GOOS, mirroring internal/wasmbox's protocol.go. The thin AppKit glue that actually creates the NSWindow, presents the bitmap and pumps the run loop lives in cocoa_darwin.go (//go:build darwin) and drives everything here.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DecodeKey

func DecodeKey(keyCode uint16, chars string) (name string, r rune)

DecodeKey maps an NSEvent keyDown/keyUp to either a symbolic key NAME (DOM-style: "Enter", "ArrowLeft", …, exactly the names the toolkit widgets match and the wasmbox backend emits) or a printable rune. keyCode is checked first so Return/Escape/Delete/arrows never leak through as control or private-use runes. A result of ("", 0) means the key carries nothing to deliver (an unmapped or non-printable key).

chars is the event's -charactersIgnoringModifiers value; only a single genuine printable rune (>= 0x20, not DEL, and outside the NSFunctionKey private-use range U+F700..U+F8FF, where AppKit reports arrows/F-keys) is accepted as text — the identical filter the reader precedent applies.

func DecodeMods

func DecodeMods(flags uint64) (shift, ctrl bool)

DecodeMods splits an NSEvent modifierFlags mask into the toolkit's Shift/Ctrl booleans. Shift maps from NSEventModifierFlagShift; Ctrl maps from EITHER Control OR Command, so a ⌘-based macOS shortcut reaches a widget with the same Ctrl flag an X11/Wayland Control chord would — keeping the toolkit's platform-neutral Ctrl shortcut semantics (Ctrl+C / Cmd+C both land as Ctrl).

func DefaultContentSize added in v0.6.1

func DefaultContentSize(visW, visH float64) (w, h int)

DefaultContentSize picks a readable default window content size, in LOGICAL points, from the main screen's visible frame (visW×visH, also in points). It takes defaultScreenFraction of the visible area and clamps each axis to the [min,max] readability band, then to the visible extent so the window never exceeds the usable screen. When the screen size is unknown (visW or visH ≤ 0) it returns the fixed fallback. The result is always ≥ 1×1 and ≤ the visible frame, so a defaulted window is legible without manual sizing.

func DirtyRect

func DirtyRect(r toolkit.Rect, scale float64) (x, y, w, h float64)

DirtyRect converts a damage rectangle in DEVICE pixels (top-left origin, the space RenderDamaged reports and the framebuffer uses) to a rectangle in the flipped content view's POINT coordinates, ready for -setNeedsDisplayInRect:. Because the content view is flipped (isFlipped → top-left origin, matching the buffer), only a scale division is needed — no Y flip. The returned rectangle is clamped to be non-negative and is expanded to whole points (floor origin, ceil far edge) so a sub-point damage rect never leaves a seam.

func MapKey

func MapKey(keyCode uint16, chars string, shift, ctrl, press bool) []toolkit.Event

MapKey turns a decoded keyDown/keyUp into the toolkit event(s) it produces, mirroring the X11 and wasmbox backends EXACTLY:

  • a named key yields a single EventKeyDown (press) / EventKeyUp (release) carrying the name in Code;
  • a printable key yields EventKeyDown+EventChar on press (Char being the committed rune) and a single EventKeyUp on release — the same press/char split the X11 backend performs;
  • a key that decodes to nothing (unmapped / pure modifier) delivers nothing.

The result is nil when the key maps to no toolkit event.

func MapMouseDown

func MapMouseDown(x, y int, shift, ctrl bool) toolkit.Event

MapMouseDown turns a left/other mouse-button press at the given view-local pixel into an EventClick, mirroring the X11 ButtonPress (buttons 1–3 → click) mapping. macOS delivers separate selectors per button; the backend routes all of them here.

func MapMouseMove

func MapMouseMove(x, y int, buttonHeld, shift, ctrl bool) toolkit.Event

MapMouseMove turns a pointer move into a drag (a button held) or a plain hover move, per buttonHeld — the same drag-vs-move split the X11/Wayland backends derive from the event's button-state mask (AppKit instead delivers -mouseMoved: vs -mouseDragged:, which the glue collapses into buttonHeld).

func MapMouseUp

func MapMouseUp(x, y int, shift, ctrl bool) toolkit.Event

MapMouseUp turns a mouse-button release into an EventMouseUp.

func MapScroll

func MapScroll(x, y int, deltaY float64, shift, ctrl bool) toolkit.Event

MapScroll turns an AppKit -scrollingDeltaY into an EventScroll whose Delta is normalised to the toolkit's ±1 row step. AppKit's scrollingDeltaY is POSITIVE when the content is pushed up (a natural upward swipe); the toolkit's Delta is POSITIVE to scroll down/forward, so the sign is inverted — matching the browser/wheel convention the X11 and wasmbox backends use. A zero delta yields a Delta-0 EventScroll (harmless; scrollable widgets clamp it), so the mapping is total.

func ViewCoords

func ViewCoords(px, py, boundsHPoints, scale float64) (int, int)

ViewCoords converts an NSEvent -locationInWindow (window base coordinates, which are ALWAYS bottom-left origin in points, even in a flipped view) to device-pixel coordinates with a top-left origin — the coordinate space the toolkit framebuffer and every toolkit.Event uses.

boundsHPoints is the content view's height in points; scale is the window's backing scale factor (1 on a non-Retina display, 2 on Retina). The Y axis is flipped (boundsHPoints - py) to move the origin to the top, then both axes are multiplied by scale to reach device pixels.

Types

This section is empty.

Jump to

Keyboard shortcuts

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