From 76073fe5fad8799e5850805f2f090af2cb62c741 Mon Sep 17 00:00:00 2001 From: Berke Güzel Date: Tue, 13 Oct 2026 23:41:31 +0300 Subject: Simplify the public event and CPU API Applications now need far less ceremony: hello.c is a 20-line loop that handles REFRESH, CLOSE and QUIT and draws into the surface's own pixels. - Fold GEOMETRY, STATE and FOCUS into one WINDOW event carrying size, scale and state; unchanged values send nothing. - Guarantee REFRESH once a window has a size and after every resize, never at size zero. - Merge DROP_HOVER into DROP with over/leave/data actions and give drag and drop actions enums. - Keep event strings valid until the next wait and drop yasl_event_release; empty or failed waits report NONE. - Replace copy-in presentation with a lent pixel buffer: yasl_cpu_pixels and yasl_cpu_present. - Remove yasl_poll_event, yasl_cpu_read_pixels, unused event fields and comments that restated names. - Wayland: resize floating windows in request_size instead of reporting it unsupported, and stop marking new GPU surfaces as Vulkan so yasl_vulkan_create_surface no longer fails with NATIVE_WINDOW_IN_USE. Also includes the in-progress public API refactor that was uncommitted in the tree (removal of the app/loop layer, new surface, GL and Vulkan entry points). Co-Authored-By: Claude Opus 5.5 --- docs/getting-started.md | 138 +++++++++++++++++------------------------------- 1 file changed, 48 insertions(+), 90 deletions(-) (limited to 'docs/getting-started.md') diff --git a/docs/getting-started.md b/docs/getting-started.md index d1f284d..bb7f095 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,113 +1,71 @@ # Getting started -YASL gives a C application desktop windows with CPU pixel targets, scale-aware -geometry, queued input, clipboard text, and optional frame pacing. It fits -software-rendered tools such as editors, terminals, drawing applications, and -custom interfaces that already have their own renderer. A window needs neither -an OpenGL context nor a graphics device supplied by the application. +YASL creates desktop surfaces and delivers queued input. You own the event loop, +renderer, graphics device/context use, and application lifetime. -The core headers expose no window system types. Native handles and Metal drawing -are separate opt-in extensions. YASL currently supports Linux (Wayland and X11) -and macOS (Cocoa); it does not provide widgets, font shaping, audio, an OpenGL -context API, or a Vulkan surface API. It is pre-release software; see the -[API policy](api-policy.md) before distributing a library that depends on its ABI. - -## Build and run - -Use a C23 compiler, Meson 1.6 or newer, and Ninja. GCC and Clang can build the library. On Linux install either backend's development dependencies: - -| Backend | pkg-config dependencies | -| --- | --- | -| Wayland | `wayland-client`, `wayland-cursor`, `xkbcommon` | -| X11 | `x11`, `xi`, `xkbcommon`, `xext`; optional `xrandr` | -| Linux desktop services | Optional `dbus-1` for notifications and appearance | -| Cocoa | macOS 14+ SDK with AppKit, Metal, QuartzCore, and UserNotifications; Metal-capable device | +Build with a C23 compiler, Meson 1.6+, and Ninja. Linux backend dependencies are +wayland-client, wayland-cursor, xkbcommon, or x11, xi, xext, xkbcommon (optional +xrandr). Optional egl and wayland-egl enable GL contexts; Vulkan SDK development +files enable the Vulkan bridge. Optional dbus-1 enables Linux desktop services. +Cocoa requires macOS 14+ and the AppKit, Metal, QuartzCore, OpenGL, and +UserNotifications system frameworks. Optional Vulkan SDK enables MoltenVK WSI. ```sh meson setup build meson compile -C build ./build/yasl-hello +./build/yasl-game meson test -C build --print-errorlogs ``` -Each Linux backend defaults to `auto`, meaning build it when its dependencies -are available. Require one with `-Dwayland=enabled` or `-Dx11=enabled`; omit one -with `-Dwayland=disabled` or `-Dx11=disabled`. At least one backend is required. -`-Ddbus` works the same way for the optional D-Bus desktop services. -Cocoa is selected on macOS and requires no extra third-party dependencies. -Its minimum deployment target is macOS 14. Set `MACOSX_DEPLOYMENT_TARGET=14.0` -(or newer) before configuring if your toolchain defaults to an older target. -CPU pixel targets are presented through the system's Metal device; applications -do not need to create or manage that device themselves. +Backend options `-Dwayland=enabled|disabled|auto`, `-Dx11=...`, and `-Ddbus=...` +control dependency selection. At least one window backend must be built. Runtime +AUTO selects the native session and falls back to another built Linux backend. +For an explicit choice call `yasl_set_backend` before creating any surface. -The complete beginner example is [hello.c](../examples/hello.c). It lets -`yasl_run()` create its window from `yasl_app_desc.window`, fills every pixel -with an RGB gradient, and presents inside a frame callback. -`yasl_run()` handles input delivery, display notifications, and cleanup. The -[interactive window](../examples/simple_window.c) adds pointer input; the -[tablet example](../examples/tablet.c) demonstrates retained application content, -pressure, erasers, resizing, and scale changes. +## A window -## Link an application +```c +#include + +int main(void) +{ + yasl_surface *s = yasl_surface_create("Example", 800, 600, 0); + if (!s) return 1; + /* Attach a GPU renderer here and draw on each REFRESH. */ + yasl_event event; + while (yasl_wait_event(&event, -1) >= 0 && + event.type != YASL_EVENT_CLOSE && event.type != YASL_EVENT_QUIT) { + } + /* Destroy GPU objects before shutting down. */ + yasl_shutdown(); + return 0; +} +``` -Install the libraries, public headers, and pkg-config metadata into your prefix: +The first creation initializes a shared backend. More windows use that backend; +there is no public display/context object. Closing the final window does not +implicitly terminate the application or reset configuration. `yasl_shutdown` +releases shared resources and restores defaults. + +[hello.c](../examples/hello.c) draws into a CPU surface's pixel buffer on every REFRESH. [game.c](../examples/game.c) creates a GL context, binds it, +loads procedures, draws, and swaps. [tablet.c](../examples/tablet.c) retains a canvas +and draws pressure-sensitive pen/eraser strokes. [notepad.c](../examples/notepad.c) +uses a worker queue, wakeups, clipboard, IME, and its own blink deadline. + +## Link and install ```sh meson setup build --prefix=/usr/local --libdir=lib meson compile -C build meson install -C build cc -std=c23 examples/hello.c -o hello $(pkg-config --cflags --libs yasl) -./hello -``` - -The prefix must be writable. For a custom prefix, add its pkg-config directory -to `PKG_CONFIG_PATH` and its library directory to the runtime loader path. -Use `pkg-config --static --libs yasl` for static consumers so backend dependencies -are included. Installed native accessor headers match the built backends. - -A Meson application can instead vendor the source under `subprojects/yasl`: - -```meson -project('my-app', 'c', default_options: ['c_std=c23']) -yasl = subproject('yasl').get_variable('yasl_dep') -executable('my-app', 'main.c', dependencies: yasl) -``` - -The subproject dependency includes headers and backend link dependencies. -Public headers can be included from C++11 or newer; the library itself builds -as C23. The libraries, public headers, and pkg-config metadata are installed together. - -## The application cycle - -1. Include `` and initialize a `yasl_app_desc` with your userdata and - `init`, `event`, and `frame` callbacks. Call `yasl_run(&desc)`. -2. In `init`, create a toplevel with a positive **logical-pixel** size and call - `yasl_surface_request_frame(surface)` for the first redraw. -3. In `event`, handle the union member selected by `event->type`. Return - `YASL_APP_QUIT` for a close request, `YASL_APP_ERROR` for failure, or - `YASL_APP_CONTINUE` to keep running. -4. In `frame`, fill every pixel in `frame->target.pixels` with premultiplied - `0xAARRGGBB` and present once with `yasl_frame_present(frame, NULL, 0)`. -5. Let the runner close remaining surfaces and the display. Release your own - resources in the optional `quit` callback or after `yasl_run()` returns. - -```c -struct yasl_app_desc desc = { - .app_id = "org.example.app", - .userdata = &app, - .init = init, - .event = event, - .frame = draw, -}; -return yasl_run(&desc); ``` -The default pacing mode sleeps until input, resize, or a requested redraw. -Use `YASL_PACING_CONTINUOUS` for an animation or game. The core API still supports -manual dispatch/poll/flush when an application owns its event loop; see the guide. +Use a writable prefix. For a custom prefix configure PKG_CONFIG_PATH and the +runtime library search path. Static consumers use `pkg-config --static --libs yasl`. +Public headers also compile as C++11. Native headers and the Vulkan header are +installed only when their respective support is built. -See the [application guide](guide.md) for drawing, input, popups, timers, and -platform limits, or the comments in the [public header](../include/yasl/yasl.h) -for each function's contract. To build the searchable HTML reference, install -Doxygen and run `doxygen Doxyfile` from the repository root. Open -`build-docs/html/index.html`; Doxygen is not needed to build the library. +See the [guide](guide.md) for geometry, event lifetime, GPU ownership, input, and +backend limits. `doxygen Doxyfile` builds the reference in build-docs/html. -- cgit v1.2.3