-rw-r--r-- 7.0K May 19, 2026 · CE824A9 · ~5 min

Swift Adwaita: from 1.2.0 to 1.3.1

swift libadwaita open source swift package linux macos

After the 1.1.0 release, the swift-adwaita library has shipped seven releases in a row. As I keep working on the first real application built with this wrapper, things keep surfacing that synthetic tests never catch — and almost every fix in this cycle came from there. The headline story: swift-adwaita now builds and runs on macOS, and along the way I stepped on a beautiful set of rakes involving Swift Concurrency inside the GLib main-loop, and carefully stepped back off.

Swift Adwaita

The story of a bug: async that never runs

In 1.2.0 I collapsed all dialogs (FileDialog, ColorDialog, FontDialog) onto async throws and dropped the callback variants — felt cleaner that way. A day later it turned out that inside a running GTK application (g_application_run), code like Task { @MainActor in await dialog.open(...) } simply never executes. Swift's default main-actor executor is DispatchQueue.main, and the GLib main-loop doesn't drive it. The process looks alive, no errors surface, the button clicks — but the file dialog never appears.

1.2.1 urgently restored the callback variants for FileDialog, and 1.2.2 closed the hole completely: callback overloads were added for every async API (Clipboard, ColorDialog, FontDialog, UriLauncher, Texture.load). The async variants stay — they're useful for tests and non-GTK contexts — but inside GTK signal handlers the callback form is now the recommended default. The long-term fix (a custom SerialExecutor on top of GLib) is deferred as a separate task.

1.2.0: what landed in the API

  • Async image loading. Texture.load(from:) decodes anything GdkPixbuf supports — PNG, JPEG, GIF, WebP, TIFF, BMP — off the main actor. That's a superset of what the native gdk_texture_new_from_filename handles.
  • Animated image playback. AnimatedImagePlayer drives frames from a GdkPixbufAnimation into a Picture widget, with start / stop / advanceFrame.
  • Application.onOpen and Application.run(arguments:) — file-open activation for apps registered with the G_APPLICATION_HANDLES_OPEN flag.
  • Runtime widget type checks. Widget.gtkType, isInstance(of:), and a stricter tryCast that now actually narrows the type instead of "successfully" casting any widget to anything.
  • Isolated deinits on GObjectRef, GVariant and other wrappers — GObject release now always happens explicitly on the main actor, not on whichever random thread dropped the last reference.
  • Minimum toolchain bumped to Swift 6.2 — isolated deinit is experimental in 6.1, and the release toolchain refused to enable it.

1.2.3–1.2.5: conveniences and clipboard

Three small releases about reaching for CAdwaita less often for routine things:

  • RGBA(hex:) — CSS color parsing: #RGB, #RGBA, #RRGGBB, #RRGGBBAA.
  • IconTheme — a wrapper around gtk_icon_theme_get_for_display with addSearchPath(_:) for app-local icons.
  • ApplicationFlags as an OptionSet: Application(id: "...", flags: [.handlesOpen, .nonUnique]) instead of raw bit masks.
  • MainContext.drainPending() and pump(for:) — one-line replacements for the while g_main_context_pending { g_main_context_iteration } loop that every test suite kept reinventing.
  • Paste interception. Widget.onPasteClipboard, the synchronous Clipboard.containsImage / containsFiles probes, async readTexture / readFiles, and Texture.encodedPNGData() — you can now intercept a pasted image in your editor and pipe it through your own import path, instead of letting GTK shove it in as text.
  • Silencing GTK-CRITICAL spam from GtkScrolledWindow and misconfigured GtkDropTarget — an opt-in log filter plus the correct signatures for the ::enter / ::motion signals.

1.3.0: macOS as a development platform

The main news of the cycle. swift-adwaita now builds and runs on macOS 13+ on Apple Silicon. Linux remains the primary target platform, but you can now develop and test locally on a Mac without spinning up a VM.

  • Install via Homebrew: brew install libadwaita gtksourceview5 pkgconf adwaita-icon-theme. Without adwaita-icon-theme, HeaderBar buttons and banners render empty — Homebrew doesn't pull it in transitively.
  • Required environment variable: XDG_DATA_DIRS=/opt/homebrew/share, otherwise libadwaita can't find its GSettings schemas and aborts at startup.
  • DemoAppLib — all 78 gallery examples now live in a separate library that downstream apps can link against directly. The DemoApp executable became a three-line shim.
  • Xcode example in examples/macos/DemoApp/ — a minimal Xcode 16+ project that wraps the gallery as a regular .app bundle. Cmd+R, and it works.
  • A parallel XCTest suite for macOS. swift-testing on Apple platforms inserts autorelease-pool transitions between tests that conflict with the Cocoa CFRunLoop sources installed by gtk_init — everything aborts on the second test. XCTest doesn't do that, and the same coverage runs there. Linux keeps using swift-testing. Result: 1181 tests / 0 failures on macOS.
  • Three Apple-specific bugs that Linux/glibc happened to mask: Variant.stringValue returned nil for valid strings (a dangling pointer through g_variant_type_checked_); the localization helpers (localized, nlocalized) returned garbage when no translation was available (gettext returns the input pointer untouched, and the Swift→C bridge had already freed it); MediaStream.timestamp failed to compile because gint64 is long on Linux x86_64 but long long on Apple arm64.
  • macOS CI job on macos-26 with Xcode 26.4.1 (Swift 6.3). Build only, no test runs: GitHub-hosted runners are headless, and GTK4-Quartz crashes without a WindowServer session.
  • REUSE 3.3 license metadata — SPDX headers in every source file, reuse lint reports clean.

1.3.1: cleanup

A maintenance release with no API changes. I polished the paste-interception docs in the README, added adwaita-icon-theme to every macOS install snippet (stepped on it, wrote it down), and bumped the Xcode example's deployment target to macOS 26 so it matches what Homebrew now builds GTK4 against — otherwise the linker complains about every dylib.

What's next

The big unsolved problem is still the Swift Concurrency ↔ GLib main-loop integration. Right now you can't write Task { @MainActor in ... } from a click handler in a GTK app, and that's frustrating. The long-term plan is a custom SerialExecutor that routes work through g_idle_add_full instead of DispatchQueue.main. The callback APIs cover every practical scenario today, but a proper executor will need to be written eventually.

The project is open source under the MIT license. The source lives on GitHub, and the documentation with guides is here.

Star Fork

[↵] open page swift-adwaita-from-1-2-0-to-1-3-1.md
-rw-r--r-- 3.4K May 18, 2026 · AC98266 · ~3 min

Video encoding with AV1 codec

ffmpeg av1 video encoding

Encoding video with the AV1 codec

A few months ago @belbous was telling me about the AV1 video codec — how great it is. Recently I decided to experiment with it. Turns out my Ubuntu laptop has the right hardware — an NVIDIA GPU with support for hardware AV1 encoding via NVENC. This capability only arrived with the RTX 40 series: on the 30 series and older, NVENC can decode AV1 but not encode it — for that you're stuck with software on the CPU. Thankfully, it's all integrated into ffmpeg, ready to use.

With Claude Code's help, I dialed in the right settings using a handful of video files as test cases. The goal was to preserve quality while reducing file size. As a result, bitrate doesn't even appear in the configuration. What came out is a bash script that analyzes a video file with ffprobe and, depending on the resolution and color scheme, sets the CQ and other parameters.

Claude Code didn't just pick values at random: it ran several passes on a clip of video, compared the input and output files, pulled out frames, and evaluated the quality itself, even describing the scenes it was comparing — a footprint in the snow, a landscape with trees, Dexter's face 😁.

Initially, Claude Code based its approach on comparing three codecs — H.264, H.265 (aka HEVC), and AV1. The baseline assumption was: H.264 → H.265 yields about 50% compression, and H.265 → AV1 adds another ~30% at the same quality. That said, those 30% apply to software encoders (libaom, SVT-AV1) — hardware AV1 in NVENC runs many times faster, but at the same bitrate it loses to them in quality. I was mainly after disk space savings, so the tradeoff suited me.

On the side, I downmixed the audio to stereo with the Opus codec, since I'm going to be watching on a TV with regular (and pretty mediocre) stereo sound anyway, and I planned to play it from an iPad — which, historically, for some reason can't output 5.1 audio over HDMI (instead of sound, you get hissing).

Encoding video with the AV1 codec

The results are impressive. An episode of Foundation — 4K, HEVC, HDR — shrank from 10.2 GB down to 2 GB. Five times smaller! At visually the same picture quality. To be fair, though: the 5x compression here isn't pure AV1 efficiency so much as a consequence of the source having a very high bitrate (rips usually leave a generous margin). On files that are already compressed more tightly, the gains will be more modest.

A 45-minute episode took about 15 minutes to re-encode. For 4K video, that's very fast. And a 50-minute episode of Dexter in 1080p SDR re-encodes in just 5 minutes. Beautiful.

But there are downsides — out of the box, NVENC doesn't support HDR10+ or Dolby Vision, so that dynamic metadata gets lost during re-encoding. Regular HDR10 with static metadata passes through fine, so basic HDR is intact — the problem is only with the extended formats. There's some workaround where you encode that part separately and splice it back in afterward, but I decided not to bother — my TV isn't all that fancy, it wouldn't have displayed HDR10+ or Dolby Vision anyway. You could also use a different codec that does everything on the CPU — better quality there, and metadata is preserved — but then this same 4K episode would take many hours instead of 15 minutes. So it looks like I've landed on the perfect quality/time balance.

[↵] open page video-encoding-with-av1-codec.md
-rw-r--r-- 1.4K May 15, 2026 · 0437B7F · ~2 min

Video players for Linux

linux video

Video players for Linux

Today at an IT breakfast meetup I was singing the praises of Video Player — a video player from GNOME, formerly known as Showtime. As far as I understand, at some point it became the default video player, including in the latest version of Ubuntu.

I like its minimalism, it plays the files I need, and I appreciate that when you pick an audio track it shows the name of the translation (the dubbing studio) — for some reason not every player does this.

Got home, decided to compare it with other players, opened a file with HDR and Dolby Vision — looks like I praised it a bit too soon. In the screenshot, from top to bottom: Video Player (Showtime), Cine, and VLC.

All three render the colors differently. I think I'll switch to Cine. Judging by its repo, it's a fairly young video player. Like Showtime, it's also based on MPV and written in Python. It just develops more actively, updates ship more often, and — most importantly — the colors come out right. Showtime, as far as I remember, has had issues with HDR for years now, and updates only come out every three to six months.

VLC is a legend, of course — it can play just about anything that's playable — but the interface, in my opinion, has aged quite a bit. Time to make room for the new generation.

[↵] open page video-players-for-linux.md
-rw-r--r-- 1.7K Apr 10, 2026 · 1F1DDF3 · ~2 min

Swifty Notes - a markdown notes manager for Linux in Swift

swift libadwaita open source linux

Swift Notes for Linux

After shipping swift-adwaita, I've been focused on building a first app using it. Something simple, but handy for myself. So now the first app has been shipped.

Swifty Notes is a native GTK/libadwaita Markdown notes application for Linux written in Swift.

The desktop app is the primary experience: write, organize, and preview Markdown notes with native GTK widgets, autosave, remembered workspace state, and adjustable editor settings such as font size, wrapping, indentation, and appearance.

The included CLI works on the same file-backed notes so shell scripts, automation, and AI agents can safely inspect or update notes without a separate database or background service.

  • Create, rename, duplicate, export, and delete Markdown notes.
  • Autosave edits, remember workspace state, and keep note-local image assets together with each note.
  • Adjust editor font size and other writing preferences to fit different screens and workflows.
  • Choose where notes are stored, including a cloud-synced folder, so the same plain files can stay in sync across devices.
  • Import images with drag and drop and render Markdown with a native GTK preview instead of a web view.
  • Use the CLI for JSON-friendly note automation from scripts, shell pipelines, and AI agents.

Get it on Flathub

Swifty Notes for Linux is an open source project, source code is available on GitHub.

Star Fork

[↵] open page swifty-notes-a-markdown-notes-manager-for-linux-in-swift.md
-rw-r--r-- 3.1K Apr 10, 2026 · D872E75 · ~2 min

Swift Adwaita 1.1.0

swift libadwaita open source swift package linux

Swift Adwaita

Swift Adwaita 1.1.0 has been released. I’ve been working on a first app built with this library, so I’ve extended it and fixed some bugs.

Highlights

  • Added GtkSourceView integration with typed Swift wrappers for source editing, syntax highlighting, languages, and style schemes.
  • Expanded widget APIs around popovers, windows, calendar compatibility, and runtime lifecycle handling.
  • Improved release stability with better GLib main-loop integration, broader CI coverage, and additional regression tests.

Added

  • SourceView, SourceBuffer, SourceLanguage, SourceLanguageManager, SourceStyleScheme, and SourceStyleSchemeManager.
  • Typed identifiers for GtkSource languages and style schemes.
  • A new source editor demo example.
  • MainContext.task { ... }, task(after:), and task(every:) as cancellable GLib main-loop work handles.
  • Async MainContext.run, yield, and sleep(for:) helpers for bridging Swift concurrency onto the GLib loop safely.
  • Widget.unparent() and PopoverMenu.unparent().
  • Convenience presentation helpers for Popover and PopoverMenu.
  • Additional regression tests for widget/window parent-chain lookup and expanded coverage for source editing and media behavior.

Changed

  • GtkWindow.present() now retains windows until close, making transient or locally scoped windows safer to use.
  • Widget.window now resolves the containing window through the widget parent chain instead of assuming the GTK root is always a window.
  • Calendar date handling now uses a GTK compatibility shim so the package builds cleanly across older and newer GTK versions.
  • Documentation generation and hosted docs configuration were updated.
  • CI now installs and tests with GtkSourceView 5 system dependencies.

Fixed

  • Fixed deferred signal/user-data cleanup to release captured closures through the GLib main loop instead of Swift main-queue tasks, avoiding lifecycle issues in GTK applications.
  • Fixed a common GTK scheduling pitfall by offering a Task-like API that stays on the GLib main loop instead of DispatchQueue.main.
  • Fixed Swift 6.1 serialized suite visibility issues in the test suite.
  • Fixed the popover/window regression tests to avoid GTK crash paths in CI while still validating the intended behavior.
  • Fixed release documentation and installation instructions to include GtkSourceView 5 development packages.

Documentation and CI

  • Added an API documentation link to the README.
  • Updated installation instructions for Ubuntu/Debian and Fedora.
  • Improved inline documentation consistency across the wrapper API.
  • Extended CI coverage for documentation, formatting, and Swift 6.1 / 6.2 / 6.3 test runs.

This is an open-source project licensed under the MIT license. The source code is available on GitHub. Documentation with guides is available here.

Star Fork

[↵] open page swift-adwaita-1-1-0.md
-rw-r--r-- 3.0K Apr 6, 2026 · B473A60 · ~2 min

HTMLEditor for SwiftUI 1.1.0

swiftui html macos open source

HTMLEditor for SwiftUI 1.1.0

This release focuses on Swift 6.3 compatibility, a substantial rewrite of the editor's highlighting pipeline, and much better responsiveness when editing very large HTML documents.

Added

  • Added the HTMLEditorBenchmarks executable target for repeatable performance measurements.
  • Added benchmark support for full-plan highlighting, overlap reuse, edit invalidation, visible-highlight remapping, and large-document local repaint paths.
  • Added focused regression tests for:
    • planner cache reuse and document-scoped invalidation
    • invalid NSRange and UTF-16 edge cases
    • quoted and unquoted attribute value highlighting
    • visible highlight state remapping
    • block-based highlight coverage
    • large-document editing and scrolling policies

Changed

  • Refactored the editor runtime into smaller focused components, including separate coordinator lifecycle, viewport, editing, policy, coverage, structural-range, and visible-highlight-state files.
  • Refactored the syntax highlighter into planner- and builder-based components for clearer separation of scanning, planning, and application.
  • Moved the editor to an adaptive runtime model that changes behavior based on document size instead of treating all HTML documents the same way.

Improved

  • Greatly improved large-document editing performance with:
    • viewport-first highlighting
    • document-scoped planner caches and targeted invalidation
    • cached visible-range plans
    • block-based highlight coverage tracking
    • structural dirty-range alignment around edits
    • two-phase large-file editing with immediate micro-pass and deferred wider repaint
    • burst-coalesced edit repainting
    • scroll-idle semantic highlighting
    • deferred binding synchronization for large documents
    • allowsNonContiguousLayout enabled automatically in large-file mode
  • Improved highlight stability while typing in the middle of very large HTML by preserving visible overlay state and reducing repaint churn around the caret.
  • Improved performance tuning and observability for large files with dedicated benchmark coverage and runtime probes.

Fixed

  • Fixed compilation and concurrency issues needed for Swift 6.3 compatibility.
  • Fixed several editor update-path issues related to coordinator state, highlighting tasks, and main-actor behavior.
  • Fixed highlight regressions and edge cases involving:
    • partial tags
    • empty input
    • large payloads
    • attribute-value coloring
    • visible highlight loss during large-file editing
    • invalid or clipped visible ranges

Notes

  • Full-document semantic highlighting is still used for smaller HTML inputs.
  • Very large HTML inputs now automatically switch to a more conservative, performance-oriented editing mode to keep scrolling and typing responsive.

Try it on GitHub: https://github.com/makoni/HTMLEditor-SwiftUI

Star Fork

[↵] open page html-editor-for-swiftui-1-1-0.md
-rw-r--r-- 1.4K Mar 31, 2026 · 6420B81 · ~1 min

Swift Adwaita library

swift libadwaita open source swift package linux

Swift Adwaita

A project that I’ve always wanted to create: a library that enables the development of GNOME applications using Swift. While there are some similar libraries available, they appear to be incomplete or not actively maintained. Thanks to Vibe Coding, I managed to complete the project in approximately a week.

swift-adwaita is an imperative Swift 6 wrapper for GTK4 and libadwaita, built for creating native GNOME desktop applications on Linux.

It provides a modern Swift API over GTK and Adwaita with type-safe widgets, signals, property bindings, async operations, and ergonomic convenience helpers, while preserving the native behavior, styling, and feel of the GNOME platform.

  • Native GTK4 and libadwaita application development in Swift
  • Imperative API without a custom DSL
  • Type-safe enums, signals, and property APIs
  • Async/await support for common platform integrations
  • Extensive widget coverage with a real demo application

Here’s a demo app built using swift-adwaita:

This is an open-source project licensed under the MIT license. The source code is available on GitHub. Documentation with guides is available here.

Star Fork

[↵] open page swift-adwaita-library.md
makoni@arm1:~/blog$ cd ./page-2/ // more posts →