README

GUI::Wings

Windows with wings: a native GUI framework for Raku. Declarative builders for windows and widgets, every event a Supply, react/whenever as the event loop.

Synopsis

use GUI::Wings;

app 'Counter', {
    my $n = 0;
    window :title('Camelia counts'), :size(480, 220), {
        my $l = label 'clicked 0 times', :font(28);
        my $b = button 'Click me';

        react {
            whenever $b.clicks { $l.text = "clicked {++$n} times" }
            whenever Supply.interval(1) {
                window.title = DateTime.now.hh-mm-ss
            }
            whenever signal(SIGINT) { done }
        }
    }
}

Status

v0.1.2, a proof of concept.

Three backends:

  • Cocoa on macOS

  • Gtk on Linux

  • Win32 on Windows

All three backends are behind a single API.

Supported widgets:

  • window

  • label

  • button

The module splits into a toolkit-free front GUI::Wings and backends behind ten methods: GUI::Wings::Backend::Cocoa, ::Gtk, ::Win32. WINGS_BACKEND picks one of them explicitly.

Examples

examples/counter.raku โ€” a button that counts its clicks

The code shown above in the Synopsis section.

The counter app on macOS

examples/calculator.raku โ€” a four-function desk calculator

Its arithmetic is exact Rats behind a rounded display, so 1 รท 3 ร— 3 is exactly 1, which is more than most desk calculators manage.

One program, three backends, no conditionals in it:

macOS โ€” CocoaUbuntu โ€” GtkWindows 10 โ€” Win32
The calculator on macOS
The calculator on Ubuntu
The calculator on Windows 10

Each takes its look from the toolkit it is standing on: rounded keys and a system orange on macOS, GTK's flatter ones on Ubuntu, and on Windows the digits are ordinary push buttons while the tinted keys are painted by the backend, bevel and all, because Win32 has no coloured button to ask for.

Running them

Both examples take the same command; swap in calculator.raku for the other.

macOS, Raku++RAKUPP_MAIN_THREAD=1 rakupp -I lib examples/counter.raku
macOS or Linux, Rakudoraku -I lib examples/counter.raku
Windows, Raku++rakupp -I lib examples\counter.raku

Test options

  • WINGS_AUTODRIVE=n โ€” clicks every button once a second, n times, then ends the app through its own exit path (SIGINT where there is one; on Windows, by closing every window). The whole GUI proves itself in about n+1 seconds, which is how the examples are checked on a machine nobody is sitting at.

  • WINGS_DEBUG=1 โ€” narrates on stderr: the backend it picked, each window going up, and every title and label the pump reconciles.

  • WINGS_BACKEND=Cocoa|Gtk|Win32 โ€” overrides the choice made from the OS, so the GTK backend can be run on a Mac with GTK installed.

Requirements

  • macOS 10.12.2 or newer (10.12 if you drop :tint). The floor comes from Apple's availability annotations โ€” labelWithString: and buttonWithTitle:target:action: are 10.12, the monospaced-digit font 10.11, setBezelColor: and the system*Color family 10.12.2 โ€” and everything else Wings touches is decades older. Tested on macOS 15.7.

  • Intel and Apple Silicon both, same module file; the alignment enum is the one arch difference and is picked at runtime.

  • Backends: GUI::Wings::Backend::Cocoa (AppKit) is the macOS default โ€” the only one needing RAKUPP_MAIN_THREAD=1, since AppKit alone insists on the process FIRST thread. ::Gtk (GTK3, libgtk-3.so.0) is the Linux default and needs no env var there: GTK only requires that ONE thread makes all its calls, which the pump guarantees. A macOS GTK build is Quartz underneath, so AppKit's first-thread rule applies to it as well โ€” under Raku++ that means RAKUPP_MAIN_THREAD=1, the same as for Cocoa. ::Win32 (user32/gdi32, wide APIs throughout so รท ร— โˆ’ survive) is the Windows default; Win32 is thread- affine like Cocoa but has no first-thread rule, so it needs no env var either.

  • Engines: Rakudo works as-is on all three platforms. Raku++ needs RAKUPP_MAIN_THREAD=1 for Cocoa, and a build newer than v3.26.0 for Win32 โ€” earlier ones cannot drive the Windows API at all (Compatibility).

  • Windows without libffi: Raku++ then calls through a fixed prototype rather than libffi, which the Win32 backend needs to be wide enough for CreateWindowExW's twelve arguments. Builds newer than v3.26.0 are; init says so plainly if it is not, and either a newer engine or set RAKUPP_FFI=C:\path\to\libffi-8.dll (GTK, MSYS2 and Python each ship one) settles it. Rakudo has no such limit.

  • signal(SIGINT) on Windows does not fire, so an app there ends by its window closing rather than by Ctrl+C; WINGS_AUTODRIVE closes the windows for the same reason.

Scope

What v0.1.1 still leaves out: any widget beyond label and button, real layout (children stack top-down and centred unless placed with :at), menus, dialogs, images, and multiple apps per process. The three backends sit behind the same ten methods; a terminal or DOM one would too, and neither exists.

Compatibility

The t/ suite is deliberately headless โ€” the native declarations dlopen on first call, so loading the module opens no window and the tests run on any OS. The GUI itself is tested by the examples, which WINGS_AUTODRIVE drives to a clean exit with no hands on the mouse.

engineversiontestsexamples
Rakudov2026.08 (MoarVM 2026.08, Raku v6.d)8/8both self-drive to exit 0
Raku++v3.25.0 and newer; Win32 needs v3.26.0-g03454ac (RAKUPP_MAIN_THREAD=1 on macOS)8/8both self-drive to exit 0

Backends, and the platform each is supported on:

backendplatformengine
CocoamacOS 15.7, arm64 and x86-64Raku++ (RAKUPP_MAIN_THREAD=1) and Rakudo
GtkGTK 3.24 โ€” Ubuntu, and macOS against Homebrew GTK (Quartz)Raku++ and Rakudo
Win32Windows 10 x64Raku++ and Rakudo

Tested with Raku++ v3.26.0-g03454ac and Rakudo 2026.07/2026.08.

Author

Andrew Shitov (zef:ash).

Licence

Artistic-2.0.

GUI::Wings v0.1.2

A native GUI framework: declarative windows, widgets as Supplies, react/whenever as the event loop.

Authors

  • Andrew Shitov

License

Artistic-2.0

Dependencies

Test Dependencies

Provides

  • GUI::Wings
  • GUI::Wings::Backend::Cocoa
  • GUI::Wings::Backend::Gtk
  • GUI::Wings::Backend::Win32

Documentation

The Camelia image is copyright 2009 by Larry Wall. "Raku" is a trademark of the Yet Another Society. All rights reserved.

Built with Podlite โ€” the markup and publishing tools behind this site.