Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
52eae6be95 |
@@ -28,6 +28,20 @@ excluded from v1; other connection modes require separate validation.
|
||||
- [Issue tracker workflow](docs/agents/issue-tracker.md): how to query the map's
|
||||
frontier, claim a ticket, and record its resolution.
|
||||
|
||||
## Completed research
|
||||
|
||||
- [Void Linux runtime, permissions, and packaging](docs/research/void-linux.md):
|
||||
runit, device access, authorization, storage, XBPS lifecycle, and libc targets.
|
||||
- [Native niri and Noctalia integration](docs/research/desktop-integration.md):
|
||||
niri 26.04 and Noctalia 5.1.0, native plugin surfaces, lifecycle, theme, and
|
||||
desktop acceptance criteria.
|
||||
- [IBM Carbon desktop strategy](docs/research/carbon-ui.md): official components,
|
||||
runtime alternatives, accessibility, and safe customization workflows.
|
||||
|
||||
Each report cites primary sources and separates recommendations from verified
|
||||
host facts. The map retains the remaining architecture, protocol, interaction,
|
||||
and release decisions.
|
||||
|
||||
The original specification was corrected to reflect current hidraw evidence;
|
||||
its protocol-validation requirements remain in force. Research recommendations
|
||||
are not implementation decisions or passed hardware tests.
|
||||
|
||||
@@ -0,0 +1,279 @@
|
||||
# IBM Carbon desktop UI strategy for VoidKontrol
|
||||
|
||||
Research date: 2026-09-21. Decision input for
|
||||
[Establish a faithful IBM Carbon desktop UI strategy for Void Linux](https://git.bongbetic.com/xavierk/voidkontrol/issues/4).
|
||||
This report recommends a direction and records evidence; it does not select the
|
||||
final stack, establish hardware support, or provide a prototype.
|
||||
|
||||
## Recommendation
|
||||
|
||||
Evaluate **official Carbon React in an unprivileged Tauri desktop application**
|
||||
first. It combines Carbon's maintained component implementation with Void's
|
||||
packaged GTK3/WebKitGTK stack and leaves the device service responsible for all
|
||||
hardware control. Gate selection on a small native-Wayland, accessibility, and
|
||||
packaging proof on the actual supported Void targets. This is an architectural
|
||||
recommendation, not a completed compatibility test. [C1][T1][T2][V1]
|
||||
|
||||
Electron remains a viable Carbon rendering alternative if the project accepts
|
||||
owning a maintained Electron distribution/update route. Do not base that choice
|
||||
on the mere existence of Void's `electron35` source template: the inspected
|
||||
template is explicitly marked broken. A QML main application can implement Carbon,
|
||||
but it would own a new Carbon implementation instead of consuming IBM's maintained
|
||||
React or Web Components libraries. Reserve that extra cost for a demonstrated
|
||||
requirement that the webview approach cannot satisfy. [C1][E1][E2][V2][Q1]
|
||||
|
||||
A Noctalia plugin and the full editor have different responsibilities. The full
|
||||
editor should use Carbon; the shell plugin should use Noctalia's supported API and
|
||||
components and expose a small entry point/status surface. They can share the
|
||||
device service without sharing a rendering toolkit. Exact Noctalia API choices
|
||||
belong to the separate desktop-integration research.
|
||||
|
||||
## Existing behavior and boundaries
|
||||
|
||||
The supplied [control specification](../../KREO-SWARM75-LINUX-CONTROL-SPEC.md)
|
||||
requires an unprivileged UI, a single service owner for discovery/authentication/
|
||||
serialization/readback, a complete backup before the first write, and comparison
|
||||
of readback after every update. It prohibits grabbing input devices, detaching
|
||||
the kernel driver, and automatic writes on startup/reconnect/resume. Protocol
|
||||
payloads and persistence semantics still require authenticated hardware capture.
|
||||
|
||||
The user has chosen verification of the observed USB presentation first and has
|
||||
kept firmware flashing and the factory-reset UI outside v1. A GUI library cannot
|
||||
close any of those protocol evidence gaps. The display should initially use the
|
||||
specification's `Kreo Swarm 75 (signature match)` identification until successful
|
||||
authentication; the observed VID/PID does not establish physical layout or
|
||||
connection-mode compatibility.
|
||||
|
||||
The repository contains a specification and agent documentation, with no existing
|
||||
UI implementation or architecture decision to extend at this research checkout.
|
||||
Consequently, the comparisons below do not propose replacing a working stack.
|
||||
|
||||
## Maintained Carbon support and obligations
|
||||
|
||||
1. Carbon's official developer guide lists **React and Web Components** as
|
||||
officially supported. Other web frameworks have community implementations.
|
||||
The maintained monorepo includes component styles, design tokens, icons, grid,
|
||||
spacing, motion, and typography packages. It does not list an official Qt/QML
|
||||
implementation. This is evidence about the supported offerings, not a claim
|
||||
that no third-party QML project exists. [C1][C2]
|
||||
2. `@carbon/react` supplies components, styles, and icons and requires a frontend
|
||||
build pipeline. A static bundled frontend is sufficient for this desktop
|
||||
editor; a web server framework is not required by Carbon. Official Web
|
||||
Components are a legitimate alternative if the architecture decision finds a
|
||||
concrete reason to avoid React; they still require a web rendering engine.
|
||||
[C1][C2]
|
||||
3. Carbon's themes are `white`, `g10`, `g90`, and `g100`. Use semantic theme,
|
||||
spacing, typography, focus, and layer tokens instead of approximate custom
|
||||
colors. Offer a supported light/dark choice; use Carbon's layering mechanism
|
||||
for nested surfaces. Shell theme synchronization can select a Carbon theme,
|
||||
but arbitrary wallpaper colors should not silently replace its contrast and
|
||||
semantic color relationships. The latter is a product recommendation. [C3]
|
||||
4. Carbon uses IBM Plex. Its current guide recommends per-family packages such
|
||||
as `@ibm/plex-sans` and `@ibm/plex-mono`; the legacy monolithic `@ibm/plex`
|
||||
package is no longer updated. Bundle the required fonts locally so installed
|
||||
operation does not depend on a font CDN. Carbon is Apache-2.0; Plex is SIL
|
||||
OFL-1.1 with reserved name `Plex`. Include the applicable notices and license
|
||||
texts in the distribution. [C2][C4][C5]
|
||||
5. Carbon components follow IBM's accessibility checklist, based on WCAG AA,
|
||||
Section 508, and European standards. Carbon explicitly says accessible
|
||||
components are only part of an accessible product. Test the assembled product
|
||||
in the selected Linux renderer, including screen-reader integration, rather
|
||||
than treating component adoption as application certification. [C6]
|
||||
|
||||
## Desktop choices
|
||||
|
||||
| Choice | Carbon fidelity and ownership | Linux/Void evidence | Decision cost or gate |
|
||||
| --- | --- | --- | --- |
|
||||
| Carbon React + Tauri | Reuses official components; small native IPC bridge can call the service. | Tauri uses WebKitGTK on Linux; its windowing stack uses GTK3. Wry documents the GTK route for Wayland. Void packages the required GTK3/libsoup3 WebKit 4.1 variant with Wayland enabled. [T1][T2][V1] | Build/runtime dependencies and WebKit behavior depend on the distribution. Test Carbon rendering, AT-SPI/screen reader operation, dialogs, scaling, and window activation on niri. |
|
||||
| Carbon React + Electron | Reuses the same official components in bundled Chromium. | Upstream Linux binaries are built on Ubuntu; Electron documents native Wayland selection from version 38 when `XDG_SESSION_TYPE=wayland`. Void's inspected `electron35` template has musl build paths but is marked broken. [E1][E3][V2] | Ships Chromium/Node/Electron updates with the application. Establish a supported runtime distribution, musl route if needed, and package maintenance; the distro template is insufficient proof. |
|
||||
| Qt Quick/QML with a custom Carbon style | Uses Qt controls and explicitly recreates Carbon appearance, layout, states, and interactions. | Qt provides native controls, accessibility metadata, and custom styling. Its listed styles do not include Carbon. [Q1][Q2] | Own the custom Carbon component set, visual parity, accessibility behavior, token mapping, and upstream design changes. Similarity to Noctalia's toolkit does not remove this work. |
|
||||
|
||||
A smaller Tauri application bundle would **not** prove a smaller total installed
|
||||
system or better memory/startup performance: GTK and WebKit dependencies still
|
||||
exist. No benchmark was run. Conversely, Electron's bundled renderer can reduce
|
||||
renderer-version variability but creates direct runtime update responsibility;
|
||||
Electron supports the latest three stable major releases. [T1][E2]
|
||||
|
||||
### glibc and musl
|
||||
|
||||
- Upstream Tauri now includes Alpine/musl prerequisites, warning that some static
|
||||
dependencies may need source builds. Therefore, a blanket claim that Tauri
|
||||
cannot run on musl would be incorrect. Those Alpine instructions are **not a
|
||||
Void compatibility result**. [T3]
|
||||
- Void's `libwebkit2gtk41` template at
|
||||
`954278b83979958bcfdff05f22cf699c9dc20346` is version `2.50.4_1`, enables
|
||||
Wayland, defaults to a bubblewrap sandbox, and depends on `xdg-dbus-proxy` when
|
||||
that option is enabled. It includes musl-compatible build paths rather than a
|
||||
blanket musl prohibition. `libwebkitgtk60` is the GTK4 subpackage; it is not a
|
||||
drop-in substitute for Tauri's GTK3 WebKit 4.1 requirement. Package source
|
||||
availability alone does not prove a successful application build. [V1][T2]
|
||||
- Void's `electron35` template at the same revision is `35.7.2_1`, has
|
||||
`x86_64* aarch64*` architecture patterns and `musl-legacy-compat` paths, but is
|
||||
marked `broken` because its configure tooling uses `FancyURLopener` removed in
|
||||
Python 3.14. This disproves neither all Electron-on-musl possibilities nor the
|
||||
possible existence of an older binary package; it does mean that this template
|
||||
cannot establish a reproducible, maintained current runtime. [V2]
|
||||
- Treat glibc and musl as separate build and runtime targets. A glibc binary or
|
||||
AppImage must not be presented as proof of native musl support. Tauri's own
|
||||
Linux distribution guidance warns that the build system's libc baseline affects
|
||||
compatibility. Which libc and architectures v1 promises remains an architecture
|
||||
decision informed by the Void research. [T4]
|
||||
|
||||
### Security and process boundary
|
||||
|
||||
Both wrappers can preserve the service boundary in the supplied specification.
|
||||
Keep packaged UI assets local, render imported names as text, and expose only
|
||||
typed domain operations through the desktop bridge. Neither JavaScript nor a QML
|
||||
plugin should accept arbitrary HID frames, open `/dev/hidraw*`, run arbitrary shell
|
||||
commands, or gain service credentials. The service must independently authorize
|
||||
and validate requests; hiding a control is not authorization.
|
||||
|
||||
For Tauri, capability/permission configuration constrains webview-to-core calls,
|
||||
while core/plugin code itself has the application's OS privileges. Command
|
||||
implementations remain responsible for enforcing scopes. This is a separate
|
||||
boundary from the service's own peer authentication and device policy. [T5]
|
||||
|
||||
For Electron, retain renderer sandboxing and context isolation, disable Node
|
||||
integration in the renderer, validate IPC sender and arguments, constrain
|
||||
navigation, and use a restrictive content-security policy. Its security guidance
|
||||
also explicitly assigns responsibility for updating Electron, Chromium, Node, and
|
||||
dependencies to the application maintainer. [E4]
|
||||
|
||||
## Proposed interaction requirements
|
||||
|
||||
These are design recommendations derived from the supplied protocol invariants,
|
||||
not additional asserted keyboard capabilities. The service remains authoritative
|
||||
for advertised features, verified ranges, physical key identifiers, raw-value
|
||||
translation, and transaction state.
|
||||
|
||||
### Main organization and keyboard accessibility
|
||||
|
||||
Use a compact Carbon application shell with Device, Lighting, Key mapping,
|
||||
Macros, Typing and power, and Backups as ordinary navigation destinations. Use
|
||||
standard forms for editors and a restrained amount of custom rendering for the
|
||||
physical keyboard preview. This is information architecture for later review,
|
||||
not a locked wireframe.
|
||||
|
||||
The layout preview should use the authenticated physical layout map and identify
|
||||
each key by its position, legend, selected layer, and current assignment. A
|
||||
keyboard-accessible list/form view must offer the same selection and editing
|
||||
operations. The preview cannot be the only means of choosing a key, and color
|
||||
cannot be the only indication of selection, assignment, or errors. A labelled
|
||||
hex/RGB input or equivalent text entry should accompany any color picker.
|
||||
|
||||
For layers, Carbon Tabs can expose Base, Fn, Fn1, and Fn2. Carbon supplies arrow-key
|
||||
navigation and distinguishes automatic versus manual activation. Choose manual
|
||||
activation if changing tabs causes a perceptible read delay; switching the editor
|
||||
layer must not itself write settings or claim to change the keyboard's active
|
||||
hardware layer. [C7]
|
||||
|
||||
All functionality must be reachable without dragging or mouse-only gestures:
|
||||
visible focus, logical tab order, standard activation keys, Escape for transient
|
||||
surfaces, and focus restoration after dialogs. Preserve a path out of every custom
|
||||
control. Provide move-up/down controls if macro actions are reorderable. Avoid
|
||||
stealing ordinary typing or compositor shortcuts just to select physical keys.
|
||||
Carbon's accessibility guidance explicitly requires full keyboard access and
|
||||
testing beyond automated checks. [C6][C8]
|
||||
|
||||
### Readback, changes, and failures
|
||||
|
||||
Keep three concepts separate: the last configuration read from the device, the
|
||||
user's unapplied edits, and the service's current transaction status. Recommended
|
||||
visible states are:
|
||||
|
||||
| Condition | UI behavior |
|
||||
| --- | --- |
|
||||
| No device, unsupported signature, unavailable service, or permission failure | Show a persistent, specific status with the relevant recovery action. Do not present cached state as live device state. |
|
||||
| Authenticating or reading | Identify the operation and withhold hardware writes until the service declares them safe. |
|
||||
| Edits pending | Clearly show unapplied changes and an explicit Apply action. Updating a form or selecting an effect changes local intent only. |
|
||||
| Backing up, writing, or verifying | Show those actual stages. Prevent duplicate submission; do not call a sent command “Saved.” |
|
||||
| Readback matches | Show “Applied and verified.” Claim persistence across power cycles only if the protocol/hardware evidence establishes it. |
|
||||
| Timeout, disconnect, malformed reply, or mismatch | Preserve useful edit context, mark device state uncertain, and show a persistent error. Reconnection/readback precedes an explicit retry; no blind automatic replay. |
|
||||
|
||||
Carbon InlineLoading supplies active/finished/error states and recommends
|
||||
disabling associated actions during submission. Inline notifications persist,
|
||||
and error messages should state the user action that resolves the problem. Use
|
||||
these patterns for operation status; a fleeting toast is insufficient for a failed
|
||||
hardware update. [C9][C10]
|
||||
|
||||
### Feature editors
|
||||
|
||||
| Area | v1 editor implications from the supplied specification |
|
||||
| --- | --- |
|
||||
| Lighting | Only capability-backed effects; five brightness/speed levels; monochrome/colourful; LED enable; one custom per-key frame. Use protocol-owned mappings for self-defined mode and colour-mode raw IDs. Do not invent direction controls or multiple onboard lighting profiles. |
|
||||
| Key mapping | Four layers; physical keys only; keyboard/modifier/combination/media/mouse/disabled/macro choices where verified. Show current and proposed assignments; flag unknown readback without silently replacing it. |
|
||||
| Macros | List the 32 slots; edit ordered press/release/delay actions with visible bounds and slot usage. Limit to 112 actions, 0–65,535 ms delays, and 127 encoded name bytes. Confirm the name encoding before implementing byte counting; “127 characters” is not equivalent. Offer only verified execution modes and validated parameter ranges. |
|
||||
| Typing | Debounce choices 0/10/20/30/40 ms. Tap-delay UI must await its verified range/units. Do not expose unsupported NKRO, report-rate, OS-mode, Win-lock, or Hall-effect controls. |
|
||||
| Power | Display battery/charging only when valid data is available; unknown is not zero. Sleep uses the stated discrete choices, not a free-form unbounded duration. |
|
||||
| Backups and restore | Export a versioned, protocol-independent document; show source identity, timestamp, compatibility checks, and a change preview before explicit restore. Validation and a fresh pre-write backup belong to the service. Do not promise atomic restore unless evidence establishes it; identify partial/interrupted outcomes. |
|
||||
|
||||
A macro action form is sufficient for complete authoring. If a later decision adds
|
||||
recording, it must remain an explicit focused interaction with an obvious stop
|
||||
path and must obey the specification's ban on input-device grabs. Global keyboard
|
||||
recording is not required by the supplied capabilities and should not be added as
|
||||
an implicit interpretation of “complete control.” Never execute a macro merely
|
||||
because a user previews its steps. Layer reset, if included, needs separate
|
||||
verified protocol behavior and explicit user intent; factory reset and firmware
|
||||
flashing remain excluded.
|
||||
|
||||
## Smallest sufficient proof before choosing the stack
|
||||
|
||||
The later architecture/prototype decision should evaluate one packaged Carbon
|
||||
form, layer tabs, a modal, a representative long macro list, the labelled keyboard
|
||||
selector, and simulated service states. It does not need hardware writes.
|
||||
|
||||
1. Build/install/uninstall on the intended Void libc/architecture targets with
|
||||
declared runtime dependencies. Confirm local fonts/assets work without network
|
||||
access and record exact dependency versions.
|
||||
2. Launch as a native Wayland window on niri; verify app identity, keyboard focus,
|
||||
normal resizing, fractional scaling, dialogs/file selection, and behavior when
|
||||
launched from the shell integration. A successful XWayland fallback does not
|
||||
satisfy a native-Wayland claim.
|
||||
3. Operate every representative control by keyboard; test meaningful reading and
|
||||
actions with the target Linux accessibility stack, including modal focus and
|
||||
operation-status announcements. Carbon's upstream tabs screen-reader evidence
|
||||
names JAWS, VoiceOver, and NVDA, so it is not a substitute for a Linux/Orca test.
|
||||
[C7]
|
||||
4. Exercise disconnected, unauthenticated, pending, verifying, and failed states
|
||||
against a fake service; prove no simulated write occurs on launch, navigation,
|
||||
refresh, or reconnect. Confirm duplicate Apply is blocked and stale drafts
|
||||
cannot overwrite a newly read configuration without review.
|
||||
|
||||
Unresolved product decisions are the supported libc/architecture matrix, wrapper
|
||||
selection, theme synchronization policy, and the preferred editor interaction.
|
||||
Unresolved hardware facts include the layout, name encoding, tap-delay parameters,
|
||||
transaction persistence, and individual capability read/write validation. These
|
||||
are explicit decision/proof obligations, not missing Carbon documentation.
|
||||
|
||||
## Sources and retrieval
|
||||
|
||||
Context7 was used first for Carbon, Tauri, Electron, and Qt (`library` then
|
||||
`docs`, no more than three commands for each question). Findings were checked
|
||||
against the following primary documentation/source. No application was built,
|
||||
no packages were installed, no host configuration was changed, and no device I/O
|
||||
was performed for this report.
|
||||
|
||||
- [C1] [Carbon developer introduction](https://carbondesignsystem.com/developing/get-started/) and [React guide](https://carbondesignsystem.com/developing/frameworks/react/).
|
||||
- [C2] [Carbon official repository, packages and license](https://github.com/carbon-design-system/carbon/blob/main/README.md).
|
||||
- [C3] [Carbon themes](https://github.com/carbon-design-system/carbon/blob/main/packages/themes/README.md), [Theme component](https://github.com/carbon-design-system/carbon/blob/main/packages/react/src/components/Theme/Theme.mdx), and [Layer component](https://github.com/carbon-design-system/carbon/blob/main/packages/react/src/components/Layer/Layer.mdx).
|
||||
- [C4] [Carbon IBM Plex guide](https://github.com/carbon-design-system/carbon/blob/main/docs/guides/ibm-plex.md).
|
||||
- [C5] [IBM Plex license](https://github.com/IBM/plex/blob/master/LICENSE.txt).
|
||||
- [C6] [Carbon accessibility overview](https://carbondesignsystem.com/guidelines/accessibility/overview/).
|
||||
- [C7] [Carbon Tabs accessibility](https://carbondesignsystem.com/components/tabs/accessibility/).
|
||||
- [C8] [Carbon accessibility verification guide](https://github.com/carbon-design-system/carbon/blob/main/docs/guides/accessibility.md). Its old IBM-internal DAP setup instructions are not adopted as a project tool requirement.
|
||||
- [C9] [Carbon InlineLoading usage](https://carbondesignsystem.com/components/inline-loading/usage/).
|
||||
- [C10] [Carbon notification usage](https://carbondesignsystem.com/components/notification/usage/) and [Form usage](https://carbondesignsystem.com/components/form/usage/).
|
||||
- [T1] [Tauri webview versions](https://v2.tauri.app/reference/webview-versions/).
|
||||
- [T2] [Wry Wayland/GTK integration](https://github.com/tauri-apps/wry/blob/dev/README.md) and [Tao Linux GTK3 dependency](https://github.com/tauri-apps/tao/blob/dev/README.md).
|
||||
- [T3] [Tauri prerequisites, including Alpine](https://github.com/tauri-apps/tauri-docs/blob/v2/src/content/docs/start/prerequisites.mdx).
|
||||
- [T4] [Tauri Linux distribution/libc baseline guidance](https://github.com/tauri-apps/tauri-docs/blob/v2/src/content/docs/distribute/debian.mdx).
|
||||
- [T5] [Tauri security boundaries](https://github.com/tauri-apps/tauri-docs/blob/v2/src/content/docs/security/index.mdx) and [capabilities](https://github.com/tauri-apps/tauri-docs/blob/v2/src/content/docs/security/capabilities.mdx).
|
||||
- [E1] [Electron platform support](https://github.com/electron/electron/blob/main/README.md).
|
||||
- [E2] [Electron version support policy and cadence](https://github.com/electron/electron/blob/main/docs/tutorial/electron-timelines.md).
|
||||
- [E3] [Electron breaking changes, v38 Wayland default](https://github.com/electron/electron/blob/main/docs/breaking-changes.md).
|
||||
- [E4] [Electron security guidance](https://github.com/electron/electron/blob/main/docs/tutorial/security.md).
|
||||
- [V1] [Void WebKitGTK package source at inspected revision](https://github.com/void-linux/void-packages/blob/954278b83979958bcfdff05f22cf699c9dc20346/srcpkgs/libwebkit2gtk41/template).
|
||||
- [V2] [Void Electron package source at inspected revision](https://github.com/void-linux/void-packages/blob/954278b83979958bcfdff05f22cf699c9dc20346/srcpkgs/electron35/template).
|
||||
- [Q1] [Qt Quick Controls available styles](https://doc.qt.io/qt-6/qtquickcontrols-styles.html).
|
||||
- [Q2] [Qt Quick accessibility](https://doc.qt.io/qt-6/accessible-qtquick.html).
|
||||
{"content_type":"terminal","tokens_before":4605,"tokens_after":4605,"token_count_basis":"o200k_base","ratio":0,"basis":"inferred"}
|
||||
@@ -0,0 +1,194 @@
|
||||
# Native niri and Noctalia integration for VoidKontrol v1
|
||||
|
||||
Research date: 2026-09-21. Research question: [Establish the native niri and Noctalia integration contracts](https://git.bongbetic.com/xavierk/voidkontrol/issues/3).
|
||||
|
||||
## Result
|
||||
|
||||
The requested integration is feasible without systemd. The installed and current stable baselines are **niri 26.04** and **Noctalia 5.1.0**. Noctalia 5 is the native Wayland/C++ shell with **Luau plugins**, not the older Quickshell/QML implementation. A first-class v1 can ship a normal Wayland Carbon application plus a small Noctalia plugin exposing a bar widget, quick panel, and optional control-center shortcut. All hardware requests go through the same unprivileged CLI/service API as the main application. A tray icon is an optional compatibility surface, not a substitute for that plugin. [N1][N2][S1][S2][S3]
|
||||
|
||||
This report resolves the available interfaces and recommends a concrete scope; it does not claim a working implementation, verified keyboard writes, or user acceptance of a UI prototype. The existing hardware specification's authentication, backup, serialization, readback, and no-auto-write invariants remain binding. The user has selected the verified USB presentation first and retained the v1 exclusions for firmware flashing and factory-reset UI.
|
||||
|
||||
## Evidence and version limits
|
||||
|
||||
Current documentation was discovered with Context7 (`library` before `docs`, three commands for Noctalia and two for niri). Claims below were checked against upstream sources, mostly pinned to the installed release tags. Noctalia documentation is also present in its own release tree; that is more reliable for this baseline than old links referring to `noctalia-shell`. The niri 26.04 documentation still mentions the older Quickshell Noctalia in its desktop-shell examples, so the Noctalia repository itself owns the current Noctalia interface facts. [N1][S1]
|
||||
|
||||
Read-only host observations:
|
||||
|
||||
| Observation | Result and implication |
|
||||
| --- | --- |
|
||||
| `niri --version`, `niri msg version`, XBPS package version | Binary and running compositor both report `26.04 (unknown commit)`; installed package is `niri-26.04_1`. CLI/compositor versions currently agree. |
|
||||
| `noctalia --version`, XBPS package version | `noctalia v5.1.0`; installed package `noctalia-5.1.0_1`. The package repository is a local `void-packages/hostdir/binpkgs` directory, so this is not evidence of an official Void repository package. |
|
||||
| Noctalia command discovery | `noctalia msg --help` exposes `plugin`, `plugins`, `panel-toggle`, `settings-open-plugin`, `status`, and `theme-mode-get`. `noctalia plugins --help` exposes offline plugin linting. |
|
||||
| Session environment | Wayland session, current desktop `niri`, session D-Bus address and `NIRI_SOCKET` present. Exact socket paths are deliberately omitted. |
|
||||
| Relevant niri configuration | Included configuration files; Noctalia starts with `spawn-at-startup "noctalia"`. Existing bindings use `noctalia msg ...`. No host files were changed. |
|
||||
| Relevant session launcher | Existing user session wrapper uses `dbus-run-session -- niri --session` under a session supervisor and validates the login/runtime directory. It is a local wrapper, not evidence that upstream `niri-session` supports runit. |
|
||||
| Relevant Noctalia preferences | Built-in/community application-template rewriting is disabled; the shell's polkit agent is enabled. Do not assume application color-file generation is configured. |
|
||||
| Notification D-Bus reads | `GetServerInformation` reports Noctalia `5.1.0`, protocol `1.2`; `GetCapabilities` advertises `actions`, `activation-token`, `body`, `persistence`, and `inline-reply`. No test notification was sent. |
|
||||
| Portal D-Bus reads | `org.freedesktop.portal.Settings` version `2`; `ReadOne("org.freedesktop.appearance", "color-scheme")` returns `1` (dark). `noctalia msg theme-mode-get` also returns `dark`. This verifies the present setting, not live change propagation. |
|
||||
| Upstream release metadata | Latest stable releases queried during research are Noctalia `v5.1.0` (2026-09-10) and niri `v26.04` (2026-04-25). [N1][S1] |
|
||||
|
||||
No user configuration, package installation, theme, panel, compositor, notification, or hardware setting was modified. No keyboard input, window titles, clipboard, notification history, or unrelated personal settings were collected into this report.
|
||||
|
||||
## Session and lifecycle contract
|
||||
|
||||
1. **Keep the device owner independent of the desktop.** The system device service belongs to the Void/runit packaging decision. It must not require `WAYLAND_DISPLAY`, a user's D-Bus session, niri IPC, or Noctalia. Desktop components are clients; restarting the shell cannot start a second hardware owner or implicitly apply settings. This preserves the supplied specification's ownership invariant.
|
||||
2. **Use the existing user's Wayland session.** Void documents `dbus-run-session` when a session bus does not already exist, and elogind/turnstile for `XDG_RUNTIME_DIR`; do not nest a new session bus inside VoidKontrol. Niri documents `niri --session` for init systems other than systemd/dinit. Upstream's `niri-session` adds systemd/dinit supervision and must not be assumed to be the Void/runit entry point. [V1][N2]
|
||||
3. **Noctalia already has a supported startup path:** `spawn-at-startup "noctalia"`. Its own documentation recommends compositor autostart. The plugin loads inside that process; it needs no separate runit or systemd user unit. [S4]
|
||||
4. **The main GUI opens on demand.** A desktop entry, launcher search, niri binding, and plugin Open action should converge on the same single-instance `open` operation. Do not start a hidden full GUI just to display the native Noctalia widget. A daemon already running or a GUI being closed is not a reason to reapply a desired keyboard configuration.
|
||||
5. **Do not claim XDG autostart alone works on stock niri/runit.** Niri's automatic XDG autostart documentation is specifically tied to its systemd session targets. Provide an optional, validated niri configuration snippet when a session component actually needs startup. Do not install systemd units as a v1 requirement. [N3]
|
||||
|
||||
The session must supply a working session D-Bus bus and valid user-owned runtime directory. Missing prerequisites yield a readable desktop diagnostic; they do not prevent headless CLI/device-service use. Void's Wayland guide documents toolkit-specific backends: GTK normally chooses Wayland, while Qt requires its Wayland package/backend. The chosen GUI toolkit must be proven native on this Void baseline during the architecture/UI ticket. [V1][V2]
|
||||
|
||||
## niri application and keybinding contract
|
||||
|
||||
### Identity and launch
|
||||
|
||||
Choose one stable reverse-DNS application ID before publishing packages. Use it consistently as the Wayland `xdg_toplevel` app ID, desktop-entry basename, icon identity, and notification `desktop-entry` hint. Wayland recommends matching the app ID to the `.desktop` basename; Noctalia resolves icons by desktop ID and then `StartupWMClass`. Do not attempt to identify the application by localized window titles. [W1][S6]
|
||||
|
||||
The final public ID is an architecture/package-identity decision, not established by this report. A real candidate under a maintainer-controlled namespace can be selected there; this research does not invent ownership of an `org.voidkontrol` domain.
|
||||
|
||||
Proposed example binding, with the key itself left to the user's configured choice:
|
||||
|
||||
```kdl
|
||||
binds {
|
||||
Mod+K hotkey-overlay-title="Open VoidKontrol" {
|
||||
spawn "voidkontrol" "open";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This is an example, not an edit or a claim that `Mod+K` is unoccupied. Niri's `spawn` takes separate arguments and does not invoke a shell. Use it for fixed commands. Do not set `allow-when-locked=true` for device-editing or UI shortcuts. Provide a configuration snippet for review and validate the resulting configuration instead of replacing the user's files. [N4]
|
||||
|
||||
Niri matches `app-id` with regular expressions; exact sample window rules must escape dots and anchor both ends. The app should tile normally by default, resize sensibly, and retain usable controls at narrow column sizes; forcing floating, global blur, or a workspace assignment is not required for native support. Niri exposes the observed app ID with its window queries. [N5]
|
||||
|
||||
### Activation and IPC
|
||||
|
||||
Use the chosen GUI toolkit's normal single-instance/Wayland activation path. `XDG_ACTIVATION_TOKEN` is a supported token handoff for a newly launched process; consume it correctly and do not propagate it indefinitely. The compositor may reject an ineffective token, so never steal focus in response to a background device event. [W2]
|
||||
|
||||
Niri IPC is a Unix socket named by `NIRI_SOCKET`; requests/replies use newline-delimited JSON. `niri msg --json` is a supported thin wrapper. Human-readable output is explicitly unstable; JSON is intended to remain compatible while adding fields/variants. The Rust `niri-ipc` crate does not promise semver API stability independent of niri. [N6]
|
||||
|
||||
No ongoing niri event stream is necessary for a keyboard manager. If standard activation cannot focus an existing window on the baseline, a narrowly scoped **user-initiated** niri adapter can find the exact app ID with JSON windows and request `focus-window --id`; missing/stale windows must degrade to opening the application. This fallback must never become a prerequisite for hardware access or be used after an unsolicited reconnect. Noctalia's niri guide suggests `honor-xdg-activation-with-invalid-serial` for shell activation, but VoidKontrol should not automatically change this global compositor setting. Validate the normal launch/focus path before deciding whether a fallback is needed. [N6][S4]
|
||||
|
||||
Firmware Base/Fn/Fn1/Fn2 layers are keyboard state, not niri/XKB layout groups. A hardware mapping to a key chord is not itself a new niri action. Keep firmware key assignments, compositor shortcuts, and the host's language layout clearly distinguished; no background edits of niri input configuration are necessary.
|
||||
|
||||
## Native Noctalia plugin contract
|
||||
|
||||
### Supported implementation surface
|
||||
|
||||
Noctalia 5 plugins use `plugin.toml` and isolated Luau entry scripts. Each entry runs off the UI thread with per-call budgets; plugins remain trusted user code, not a security sandbox. The manifest supports `[[widget]]`, `[[shortcut]]`, `[[panel]]`, `[[service]]`, `[[launcher_provider]]`, and `[[desktop_widget]]`. A plugin entry is addressed as `author/plugin:entry`. [S2][S3]
|
||||
|
||||
Recommend these four entries, sharing a single state source:
|
||||
|
||||
| Entry | Minimal v1 responsibility |
|
||||
| --- | --- |
|
||||
| Bar widget | Show keyboard availability/busy/error and battery only when actually available. Click opens the quick panel; tooltip explains unauthenticated, unsupported, disconnected, permission-denied, or stale state. |
|
||||
| Quick panel | Read-only device/connection/status summary; verified LED enable and five-level brightness controls; a small verified effect selector; Open VoidKontrol action for the full editor. All mutating controls are capability-gated. |
|
||||
| Control-center shortcut | Optional user-placeable tile opening the same quick panel. Do not duplicate a second implementation of the controls or overwrite existing shortcuts. |
|
||||
| Background service entry | Obtain one cached CLI/service snapshot and publish it with `noctalia.state` to all visible entries. Multiple monitors/widgets must not multiply USB transactions. |
|
||||
|
||||
The bar widget uses `barWidget.*`; a control-center tile uses `shortcut.*`; the panel uses native `ui.button`, `ui.toggle`, `ui.slider`, `ui.select`, and `panel.render`. `noctalia.togglePanel(id)` opens it in-process. The public `noctalia msg panel-toggle author/plugin:quick` command makes the same panel bindable from niri. Services have no output and are targeted with `all` for plugin IPC. [S3][S5][S6][S7]
|
||||
|
||||
Panel buttons/toggles must not optimistically report a hardware success. Show pending state until the common service reports a successful readback. Disable writes when offline, unauthenticated, unsupported, lacking a required initial backup, unauthorized, or busy. Commit a brightness slider once per deliberate selection/drag completion; never send one hardware write per pixel of pointer motion. Present the protocol's five levels, not a falsely continuous 0–100 hardware scale. Unknown battery is “Unavailable”, not 0%.
|
||||
|
||||
Keep full mapping, macro authoring, import/restore, and detailed conflict/error recovery in the main Carbon application, backed by the same API. The quick panel is a convenient subset; its lack of a macro editor does not remove that feature from v1.
|
||||
|
||||
### Version and execution contract
|
||||
|
||||
Noctalia 5.1.0 source supports plugin API levels **3–30**. API levels are cumulative and independent of the shell release number. Recommend `plugin_api = 24`: it includes direct argv execution (`noctalia.runAsync({ ... }, callback)`), service lifecycle support, relative modules, and the panel controls required here. Raise it only if the final plugin actually uses newer features. Mainline examples using `plugin_api = 3` do not authorize calling later APIs under that declaration. [S8]
|
||||
|
||||
Use direct argv for CLI requests; never interpolate a device ID, effect, path, setting, or user text into a shell command. Check both the immediate launch boolean and the callback result: `exitCode`, `timedOut`, stdout/stderr truncation, bounded JSON parsing, and protocol compatibility. A manifest `dependencies` entry is descriptive metadata and does not prevent enabling a plugin with a missing executable; the plugin must detect that state itself. [S3][S6]
|
||||
|
||||
A small initial implementation can poll a **cached** `status --json` snapshot once every two seconds through the singleton service entry, at most one request in flight; polling that endpoint must not force a new USB read. Refresh immediately after a completed explicit command. This is a proposed implementation choice, not a measured latency claim. It avoids another long-lived session process and requires no new shell-service dependency. If the shared service already supplies a bounded event/watch CLI, reuse that instead. Noctalia supports `runStream()` and terminates streams when the entry stops/reloads, but the documented line callback alone does not establish an EOF/reconnect contract; do not assume one without testing/source verification. [S6]
|
||||
|
||||
An absent CLI, stopped daemon, incompatible API/schema, timeout, malformed response, failed authentication, unplug, and suspend/resume must become explicit non-writable states. Retry **reads** with a bounded cadence; do not retry uncertain writes, queue offline writes, or apply a saved setting when Noctalia restarts. Stale snapshots must carry age/validity so a cached “connected” icon cannot persist indefinitely.
|
||||
|
||||
### Installation and lifecycle
|
||||
|
||||
Noctalia can load plugins from a packaged read-only **path source**, from a user data-directory plugin, or from a git source. Installed is not enabled; enabling also does not place a bar widget automatically. This fits a separate optional VoidKontrol Noctalia integration package plus documented explicit enable/place steps, preserving the user's bar and shortcut layout. The exact XBPS split is owned by the Void packaging ticket. [S9]
|
||||
|
||||
Prefer the packaged path source for the v1 release baseline so plugin and CLI compatibility track the same package update. Do not silently opt the user's shell into a new remote code source or change its global plugin auto-update preference. Plugin state is process-lifetime data, not the authoritative keyboard configuration; desired hardware state, backups, and restore stay with the core application/service. `noctalia.pluginDataDir()` is appropriate only if the plugin needs its own presentation settings/cache; runtime code directories are not writable state. [S6][S9]
|
||||
|
||||
Noctalia's `onEnable()` is an explicit enable hook, not an ordinary startup hook. Do not start/stop the system device daemon from it or from plugin teardown. A shell crash or plugin disable must not affect normal keyboard input or abort the service's consistency handling. [S3]
|
||||
|
||||
### Existing lookalike features do not own Swarm75 control
|
||||
|
||||
Noctalia's standard `keyboard-backlight-*` commands operate its UPower keyboard-backlight devices; they do not implement the Swarm75 authenticated vendor HID protocol. Its `keyboard-layout` entry concerns the host layout. Its `power-*` commands concern system power profiles. These cannot replace the VoidKontrol adapter, firmware layers, or keyboard idle-sleep settings. Noctalia's tray widget does support StatusNotifierItem, but that provides an icon/menu surface rather than the native plugin panel and controls requested here. [S10][S11]
|
||||
|
||||
## Theme, notifications, and accessibility
|
||||
|
||||
**Main application:** retain Carbon's component/tokens/accessibility system and map the desktop's light/dark preference to its supported themes. The standard Settings portal reports `0` no preference, `1` dark, `2` light and emits `SettingChanged`. Prefer the toolkit's standard integration; an explicit bridge should use `ReadOne` on portal version 2, with documented version-1 compatibility if supported. Unknown values become no preference. A deterministic application default and manual preference keep the UI usable without a portal. The final Carbon theme pair and GUI technology belong to the design/architecture ticket. [W3]
|
||||
|
||||
**Noctalia plugin:** use the shell's native controls, fonts, sizing, and semantic palette roles so the bar/panel remain native. Roles resolve live, including a dark shell while apps are light. `noctalia.isDarkMode()` reports the **shell** mode; `noctalia msg theme-mode-get` reports the **app-facing** mode. Noctalia deliberately separates `[theme].mode` and `shell_mode`; treating them as identical is incorrect. Do not copy a wallpaper palette over Carbon's semantic color values automatically or rewrite global GTK/Qt themes. The host has application-template generation disabled. [S5][S6][S12]
|
||||
|
||||
Noctalia exposes `theme_mode_changed` and `colors_changed` hooks if a later explicit integration needs them. They are not required when the toolkit/portal preference works and must not overwrite the user's existing hooks. A theme event must only change presentation; it must never recolor the keyboard automatically. [S13]
|
||||
|
||||
**Notifications:** ordinary application notifications use the session's `org.freedesktop.Notifications`; Noctalia is already the provider on this host. Probe server capabilities before relying on actions. Treat a missing daemon, DND, suppressed toast, or unsupported action as a normal condition; show errors/transaction results in the originating UI as well. The root device service must not guess which user's session bus should receive a notification. [S14]
|
||||
|
||||
Plugin `noctalia.notify()` / `notifyError()` are suitable for brief plugin feedback. They are internal toasts, **never retained in notification history**; standard external notifications can be retained. Avoid duplicate GUI-plus-plugin toasts for one command, and avoid sending macro contents or complete exported settings into notification history. Noctalia does not advertise body-markup support. [S6][S14]
|
||||
|
||||
**Accessibility:** the native panel has standard controls, keyboard navigation, Escape dismissal, host UI scaling and high-contrast settings. Use visible labels and text status alongside icons/color. Do not intercept broad keys or enable a persistent focus-grabbing panel. Noctalia's documented plugin surface does not by itself prove screen-reader semantics for the proposed controls; validate that separately and keep all operations available in the accessible Carbon GUI and CLI. Screen-reader support must not be claimed merely because a native widget rendered. [S5][S15]
|
||||
|
||||
## Proposed shared CLI boundary
|
||||
|
||||
Names below are **proposals for the architecture ticket**, not implemented commands or a final published API. Keep one versioned machine-readable contract for the main GUI and shell plugin; do not expose raw HID frames or a bypass flag through it.
|
||||
|
||||
| Operation | Proposed surface | Required semantics |
|
||||
| --- | --- | --- |
|
||||
| Open or focus editor | `voidkontrol open` | Unprivileged, single-instance, no hardware write; works without Noctalia. |
|
||||
| Cached state | `voidkontrolctl status --json` | Schema version, device token, capability/readiness state, snapshot age/revision, verified current values, optional battery; distinguish missing values from zero. |
|
||||
| Brightness | `voidkontrolctl lighting brightness 0..4 --device <token> --json` | Exact device, locally validated discrete value; service enforces authorization, backup, serialization, and readback. |
|
||||
| LED enable | `voidkontrolctl lighting enabled true\|false --device <token> --json` | Explicit desired state instead of a racy client-side toggle. |
|
||||
| Effect | `voidkontrolctl lighting effect <capability-key> --device <token> --json` | Service-owned logical capability identifier; no guessed raw self-defined/colour-mode values. |
|
||||
|
||||
Mutation requests need a device/session or state revision precondition defined by the core API, so a stale control cannot target a newly connected identical-looking keyboard. If discovery returns multiple indistinguishable devices, show an explicit device choice and disable mutation until selected. Shell widgets must not silently select the first device. Error responses should distinguish unsupported transport/firmware, authentication, permission, missing backup, busy/conflict, disconnected, and uncertain transaction outcome; process exit success must mean the specified verification completed.
|
||||
|
||||
The plugin controls are clients of the service's policy, not a second policy implementation. Full CLI mutation semantics, request identifiers, IPC authentication and restore reconciliation remain core architecture decisions.
|
||||
|
||||
## Recommended v1 release acceptance
|
||||
|
||||
1. On the supported Void/runit session, launch the GUI from a desktop entry, Noctalia launcher, niri binding and native plugin. Observe the same app ID/icon, a native Wayland surface, one application instance, usable narrow-column/fractional-scale layout, and reliable user-initiated focus. Repeat with Noctalia absent: GUI and CLI remain functional.
|
||||
2. Enable the bundled plugin on Noctalia 5.1.0 without a Quickshell dependency or systemd commands. Add its bar widget and control-center shortcut through normal shell settings. Open/close the quick panel with both pointer and `noctalia msg panel-toggle ...`; test multi-monitor placement and keyboard navigation. Run `noctalia plugins lint` against the package.
|
||||
3. Widget and panel reflect **service-verified** device status and supported battery/lighting data. Multiple widget instances share one snapshot source. All controls accurately reflect missing capabilities, permission errors, disconnected devices, no initial backup and busy transactions.
|
||||
4. Exercise one verified lighting action through each frontend and show consistent readback state. Brightness has exactly five hardware levels. Noctalia's host keyboard-backlight, language-layout and host power-profile features remain distinct from Swarm75 control.
|
||||
5. With recorded transport fixtures and then validated hardware, prove no writes on GUI launch, plugin load/reload, shell restart, device reconnect, portal/theme change, suspend/resume, or passive polling. Uncertain writes require recovery/readback rather than blind replay. Typing remains available throughout.
|
||||
6. Kill/restart the GUI and Noctalia independently; disable/re-enable the plugin; stop/restart the device service; unplug/reconnect the keyboard; deliver stale/truncated/incompatible CLI output. Display bounded, recoverable non-writable states, create no duplicate device owners, and never resurrect an old desired setting automatically.
|
||||
7. Test light/dark changes and the deliberately different shell/app mode case. Main GUI retains Carbon semantics; plugin tracks Noctalia's live palette. Test high contrast, non-color status, keyboard access, scale and screen-reader behavior; record any native-shell limitation instead of declaring accessibility from appearance.
|
||||
8. Test notifications with Noctalia available, unavailable and in DND. A suppressed notification cannot hide a transaction error from its originating UI. Inspect history behavior for external versus internal notifications, and ensure no sensitive macro/configuration payload is emitted.
|
||||
9. Record exact niri, Noctalia, plugin API, CLI schema and Void package versions in release evidence. New major Noctalia/plugin API combinations are not automatically supported. Incompatibility must leave the standalone application/CLI usable.
|
||||
|
||||
## Decisions still requiring the wider map
|
||||
|
||||
- Adopt the recommended Carbon main application plus native Noctalia quick controls, and validate that interpretation through the requested UI/design decision. Forcing Carbon-rendered widgets inside Noctalia would be a different custom UI project; Noctalia's supported plugin API renders its native controls.
|
||||
- Select GUI/runtime and public application identity, then prove Wayland launch, activation, resizing, portal theme propagation and accessibility on Void. Research proves the interfaces exist, not that every possible Carbon wrapper implements them correctly.
|
||||
- Lock the shared authenticated IPC/CLI schema and device-selection/concurrency policy, then implement the plugin against it. Desktop research must not decide privileged authorization independently from the daemon architecture.
|
||||
- Decide package/artifact ownership for the optional Noctalia plugin and document enable/place steps. No extra desktop-choice permission is needed to research or package the user's requested niri/Noctalia baseline; changing their running desktop configuration is a separate installation action.
|
||||
|
||||
## Primary sources
|
||||
|
||||
- [N1] [niri 26.04 release](https://github.com/niri-wm/niri/releases/tag/v26.04).
|
||||
- [N2] [niri 26.04 Getting Started](https://github.com/niri-wm/niri/blob/v26.04/docs/wiki/Getting-Started.md).
|
||||
- [N3] [niri 26.04 integration/autostart](https://github.com/niri-wm/niri/blob/v26.04/docs/wiki/Integrating-niri.md) and [startup configuration](https://github.com/niri-wm/niri/blob/v26.04/docs/wiki/Configuration%3A-Miscellaneous.md).
|
||||
- [N4] [niri 26.04 keybindings and spawn semantics](https://github.com/niri-wm/niri/blob/v26.04/docs/wiki/Configuration%3A-Key-Bindings.md).
|
||||
- [N5] [niri 26.04 window rules and app-ID matching](https://github.com/niri-wm/niri/blob/v26.04/docs/wiki/Configuration%3A-Window-Rules.md).
|
||||
- [N6] [niri 26.04 IPC and compatibility](https://github.com/niri-wm/niri/blob/v26.04/docs/wiki/IPC.md); exact focus/spawn flags also checked with installed CLI help.
|
||||
- [S1] [Noctalia 5.1.0 release](https://github.com/noctalia-dev/noctalia/releases/tag/v5.1.0) and [native shell architecture](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/README.md).
|
||||
- [S2] [Noctalia 5.1.0 plugin development overview](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/docs/user/plugins/development/index.mdx).
|
||||
- [S3] [Noctalia 5.1.0 manifest](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/docs/user/plugins/development/manifest.mdx) and [entry lifecycle/presentation APIs](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/docs/user/plugins/development/entries.mdx).
|
||||
- [S4] [Noctalia 5.1.0 compositor startup](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/docs/user/getting-started/running-the-shell.mdx) and [niri integration](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/docs/user/compositor-settings/niri.mdx).
|
||||
- [S5] [Noctalia 5.1.0 declarative controls, panel focus and keyboard handling](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/docs/user/plugins/development/declarative-ui.mdx).
|
||||
- [S6] [Noctalia 5.1.0 runtime API](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/docs/user/plugins/development/runtime-api.mdx).
|
||||
- [S7] [Noctalia 5.1.0 plugin workflow and IPC targets](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/docs/user/plugins/development/workflow.mdx).
|
||||
- [S8] [Noctalia 5.1.0 API history](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/docs/plugin-api.json), [API source bounds](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/src/scripting/plugin_api.h), and [compatibility rules](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/docs/user/plugins/development/plugin-api.mdx).
|
||||
- [S9] [Noctalia 5.1.0 plugin sources, enablement, updates and file locations](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/docs/user/plugins/index.mdx).
|
||||
- [S10] [Noctalia 5.1.0 UPower keyboard-backlight implementation](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/src/system/keyboard_backlight_service.cpp) and [control-center shortcuts](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/docs/user/control-center/shortcuts.mdx).
|
||||
- [S11] [Noctalia 5.1.0 StatusNotifierItem tray](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/docs/user/bar/widgets/tray.mdx).
|
||||
- [S12] [Noctalia 5.1.0 app versus shell mode](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/docs/user/theming/index.mdx), [palette roles](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/docs/user/theming/palette.mdx), and [theme IPC](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/docs/user/ipc/media-and-ui.mdx).
|
||||
- [S13] [Noctalia 5.1.0 event hooks](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/docs/user/automation/hooks.mdx).
|
||||
- [S14] [Noctalia 5.1.0 notification daemon, capabilities, filters and history](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/docs/user/services/notifications.mdx).
|
||||
- [S15] [Noctalia 5.1.0 shell accessibility and keyboard navigation](https://github.com/noctalia-dev/noctalia/blob/v5.1.0/docs/user/configuration/shell.mdx).
|
||||
- [V1] [Void Handbook: session and seat management](https://docs.voidlinux.org/config/session-management.html) ([source](https://github.com/void-linux/void-docs/blob/master/src/config/session-management.md)).
|
||||
- [V2] [Void Handbook: Wayland and native applications](https://docs.voidlinux.org/config/graphical-session/wayland.html) ([source](https://github.com/void-linux/void-docs/blob/master/src/config/graphical-session/wayland.md)).
|
||||
- [W1] [Wayland xdg-shell app-ID protocol](https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/stable/xdg-shell/xdg-shell.xml) ([readable mirror used](https://github.com/wayland-mirror/wayland-protocols/blob/main/stable/xdg-shell/xdg-shell.xml)).
|
||||
- [W2] [Wayland xdg-activation protocol](https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/staging/xdg-activation/xdg-activation-v1.xml) ([readable mirror used](https://github.com/wayland-mirror/wayland-protocols/blob/main/staging/xdg-activation/xdg-activation-v1.xml)).
|
||||
- [W3] [Settings portal source specification](https://github.com/flatpak/xdg-desktop-portal/blob/main/data/org.freedesktop.portal.Settings.xml).
|
||||
{"content_type":"terminal","tokens_before":6926,"tokens_after":6926,"token_count_basis":"o200k_base","ratio":0,"basis":"inferred"}
|
||||
Reference in New Issue
Block a user