Quest for eternal dock on Wayland - lambdock (C + GTK4 + Lisp GNU Guile Scheme)
Quest for the eternal Dock on Wayland - lambdock (C + GTK4 + Lisp GNU Guile Scheme)
Quest for the eternal Dock - lambdock 追求永恒的 Dock —— lambdock
This is the story of lambdock: https://codeberg.org/jjba23/lambdock. lambdock is a modern, hyper-hackable, Wayland-native desktop dock application (C and Guile Scheme + GTK4) w/ REPL. As a heavy computer user, spending most of my day enjoying digital life, and as an eye-candy enjoyer and workflow optimization afficionado, I have long dreamt of the ultimate desktop dock. Here’s the story behind lambdock, the Wayland-native beast with infinite hackability, fluid physics animations, instant responsiveness, and free as in freedom. But to get here, I will first take you through the mindset, the graveyard of failed prototypes, the uphill battles and the ultimate conquest of GTK4 C runtime, and embedding of a living, breathing, interactive Lisp heart.
这是关于 lambdock 的故事:https://codeberg.org/jjba23/lambdock。lambdock 是一款现代、极具可黑客性、原生支持 Wayland 的桌面 Dock 应用程序(使用 C 和 Guile Scheme + GTK4 编写),并带有 REPL。作为一个重度电脑用户,我大部分时间都在享受数字生活,同时也是视觉效果爱好者和工作流优化发烧友,我一直梦想着拥有终极的桌面 Dock。这就是 lambdock 背后的故事——这头原生支持 Wayland 的“野兽”拥有无限的可扩展性、流畅的物理动画、即时的响应速度,以及“自由软件”意义上的自由。但在达到这一目标之前,我将带你了解我的心路历程、那些失败原型的坟场、艰难的攻坚战,以及最终征服 GTK4 C 运行时并嵌入一颗鲜活、交互式 Lisp 心脏的过程。
Quest for the eternal Dock
追求永恒的 Dock
For years, desktop GNU/Linux users moving to Wayland faced a recurring tragedy: the loss of iconic, deeply hackable docks like Cairo-Dock and Plank. That being said, anno 2026, those (and other) projects have made great efforts to become Wayland-compatible, so that’s great. While bar engines like Waybar and EWW excel at status displays, a true application dock that can rival those heavyweights (and macOS too) requires a unique blend of layout positioning, dynamic window tracking, auto-hiding, and fluid hover physics for animations. lambdock’s is a story of resilience in many ways, as I cannot even remember how many attempts I made at building a dock (in different ways). Little did I know how many paradigms, ideas and PoCs would collapse before my vision became tangible reality.
多年来,转向 Wayland 的桌面 GNU/Linux 用户面临着一个反复出现的悲剧:失去了像 Cairo-Dock 和 Plank 这样标志性且深度可定制的 Dock。话虽如此,到了 2026 年,这些(以及其他)项目已经做出了巨大努力以实现 Wayland 兼容,这非常棒。虽然像 Waybar 和 EWW 这样的栏引擎在状态显示方面表现出色,但一个能够与那些重量级产品(以及 macOS)相媲美的真正应用程序 Dock,需要布局定位、动态窗口跟踪、自动隐藏和流畅的悬停物理动画的独特结合。lambdock 的故事在许多方面都是关于韧性的,因为我甚至记不清自己尝试过多少次(以不同的方式)构建 Dock。我当时完全没想到,在我的愿景成为现实之前,会有多少范式、想法和概念验证(PoC)会崩塌。
On the 30th of July 2026, I had a revelation and set out to build lambdock: a Wayland-native desktop dock that wouldn’t just replicate the macOS or Cairo-Dock experience, but would transcend it with full runtime inspectability, hackability, and Lisp enlightenment. I find GTK to be the very best UI toolkit for GNU/Linux and other platforms, anno 2026. So for me that choice was pretty clear, even if I also toyed with Qt and others, but GTK always came on top. After the wreckage of many PoCs and while reading some HackerNews in bed, a thought crossed my mind, and suddenly, absolute clarity! Why not use idiomatic modern GTK4, in the language that it’s written in. Oh wait, that language, C, has libguile.h, a great library inter-operability with Lisp (GNU Guile Scheme), allowing bi-directional bindings and communication. Why not go down this rabbit hole, which might at the same time teach me more about my favourite language (GNU Guile) and allow me a frictionless setup with GTK and native super performance.
2026 年 7 月 30 日,我灵光一现,决定开始构建 lambdock:一个原生支持 Wayland 的桌面 Dock,它不仅要复制 macOS 或 Cairo-Dock 的体验,还要通过完全的运行时可检查性、可黑客性和 Lisp 的启迪来超越它们。我认为在 2026 年,GTK 是 GNU/Linux 和其他平台最好的 UI 工具包。所以对我来说,这个选择很明确,尽管我也尝试过 Qt 等其他工具,但 GTK 总是胜出。在经历了许多 PoC 的残骸后,有一天我在床上刷 HackerNews 时,一个念头闪过,突然间,一切都清晰了!为什么不使用地道的现代 GTK4,并用它原本编写的语言来实现呢?等等,那种语言——C 语言,拥有 libguile.h,这是一个与 Lisp (GNU Guile Scheme) 进行互操作的优秀库,允许双向绑定和通信。为什么不钻进这个“兔子洞”呢?这不仅能让我更深入地了解我最喜欢的语言 (GNU Guile),还能让我实现与 GTK 的无缝集成以及极致的原生性能。
I therefore designed lambdock in my mind, in bed, much inspired by Emacs. A powerful, small C core that powers the program, rendering, graphics and low level details, and an embedded GNU Guile Scheme engine that at runtime is the heart and brain of the whole thing. This architecture uniquely delivers interactive socket REPL control, Lisp metaprogramming macros, dynamic multi-dock spawning, native Wayland foreign-toplevel window tracking, and frame-clock-driven hover animations.
因此,我在床上构思了 lambdock,灵感很大程度上来自 Emacs。一个强大且精简的 C 核心负责驱动程序、渲染、图形和底层细节,而一个嵌入式的 GNU Guile Scheme 引擎则在运行时充当整个程序的心脏和大脑。这种架构独特地实现了交互式 Socket REPL 控制、Lisp 元编程宏、动态多 Dock 生成、原生 Wayland 外部顶层窗口跟踪以及由帧时钟驱动的悬停动画。
Graveyard of Prototypes
原型坟场
The journey to lambdock was paved with ambitious Proofs of Concept (PoCs) that ultimately died. I cycled through several languages, approaches, frameworks, and architecture experiments, chasing the dream of rapid development without sacrificing low-level display server control. The quest initially aimed for a pure, 100% Lisp architecture using Guile GI and other existing Guile GTK bindings. However, this vision collapsed under sparse documentation and inscrutable binding layers. Bridging GTK’s imperative, object-oriented state with functional Scheme patterns created constant architectural friction, and a small community meant every binding edge-case became a dead end and a long dive in the rabbit hole.
通往 lambdock 的道路上铺满了最终夭折的雄心勃勃的概念验证(PoC)。我尝试了多种语言、方法、框架和架构实验,追逐着在不牺牲底层显示服务器控制权的前提下实现快速开发的梦想。最初的探索目标是使用 Guile GI 和其他现有的 Guile GTK 绑定,构建一个纯 100% Lisp 的架构。然而,这一愿景在稀缺的文档和晦涩难懂的绑定层面前崩塌了。将 GTK 的命令式、面向对象状态与函数式 Scheme 模式桥接起来,造成了持续的架构摩擦,而小众的社区意味着每一个绑定的边缘情况都成了死胡同,导致我不得不长时间陷入“兔子洞”中。
Trying Python + GTK3/4 offered rapid prototyping and a massive library ecosystem, but crashed into severe real-time performance limits. Single-threaded bottlenecks and Global Interpreter Lock (GIL) stutters ruined fluid slide-out animations unless backed by custom C code. That also triggered me to think, might as well just write this whole thing in C. Coupled with a heavy memory footprint and fragile IPC mechanisms, the runtime proved too heavy and unpredictable for a low-latency desktop dock. Attempts with Rust, GTK bindings, and custom compositor IPC promised memory safety and fearless concurrency, yet introduced severe verbosity and binding friction. Mismatches between Rust’s async event loops and GTK4’s main thread created structural problems, the borrow checker was a real PITA when working with GTK and the dynamic features I wanted to support, while the lack of reflection completely shut the door on (easily) embedding a live, interactive Lisp REPL.
尝试 Python + GTK3/4 虽然提供了快速原型设计和庞大的库生态系统,但却撞上了严重的实时性能瓶颈。单线程瓶颈和全局解释器锁(GIL)导致的卡顿破坏了流畅的滑出动画,除非有自定义的 C 代码支持。这也促使我思考:干脆用 C 语言重写整个程序算了。再加上沉重的内存占用和脆弱的 IPC 机制,这种运行时对于低延迟的桌面 Dock 来说显得过于笨重且不可预测。尝试使用 Rust、GTK 绑定和自定义合成器 IPC 虽然承诺了内存安全和无畏并发,但却引入了严重的冗长代码和绑定摩擦。Rust 的异步事件循环与 GTK4 主线程之间的不匹配造成了结构性问题,借用检查器(Borrow Checker)在处理 GTK 和我想要支持的动态特性时简直是噩梦,而缺乏反射机制则彻底关上了(轻松)嵌入实时交互式 Lisp REPL 的大门。
I made a final attempt by using JavaScript/Node and Layer Shell targeted familiar web-style styling and asynchronous I/O. However, this suffered from bloated resource consumption, poor integration with low-level Wayland protocols, and no clear pathway for Lisp extensibility, and thus it quickly gained its place in the graveyard of abandoned prototypes.
我最后一次尝试是使用 JavaScript/Node 和 Layer Shell,旨在实现熟悉的 Web 风格样式和异步 I/O。然而,这又遭受了资源消耗过大、与底层 Wayland 协议集成度差以及缺乏 Lisp 可扩展性路径的问题,因此它很快也在被遗弃的原型坟场中占据了一席之地。
Iron Skeleton, Lisp Soul
钢铁骨架,Lisp 灵魂
C + GTK4 + gtk4-layer-shell is the undisputed champion of native Wayland surface control. C provides raw speed, zero-cost GLib integration, memory layout efficiency, flawless Wayland scanner protocol generation and the best GTK documentation you can get. GNU Guile Scheme (libguile) is the ultimate runtime mind. Instead of configuring the dock with static, dead JSON or TOML files, embedding Lisp (Guile Scheme) via libguile.h gives the dock a living Lisp heart and turns it into an infinitely extensible program.
C + GTK4 + gtk4-layer-shell 是原生 Wayland 表面控制领域无可争议的冠军。C 语言提供了原始速度、零成本的 GLib 集成、内存布局效率、完美的 Wayland 扫描器协议生成,以及你能找到的最好的 GTK 文档。GNU Guile Scheme (libguile) 是终极的运行时大脑。与其使用静态、死板的 JSON 或 TOML 文件来配置 Dock,不如通过 libguile.h 嵌入 Lisp (Guile Scheme),这赋予了 Dock 一颗鲜活的 Lisp 心脏,并将其变成了一个无限可扩展的程序。
/* The moment C boots the Lisp engine in main.c */ int main(int argc, char *argv) { #ifdef DEFAULT_GSK_RENDERER g_setenv(“GSK_RENDERER”, DEFAULT_GSK_RENDERER, FALSE); #endif / Boot the GNU Guile Scheme engine */
/* C 语言在 main.c 中启动 Lisp 引擎的时刻 */ int main(int argc, char *argv) { #ifdef DEFAULT_GSK_RENDERER g_setenv(“GSK_RENDERER”, DEFAULT_GSK_RENDERER, FALSE); #endif / 启动 GNU Guile Scheme 引擎 */