Skip to content

Port plan-a feat() service path: wallpaper + desktop_shell#159

Merged
senseix21 merged 25 commits into
mainfrom
feature/plan-a-wallpaper-ds-port
May 18, 2026
Merged

Port plan-a feat() service path: wallpaper + desktop_shell#159
senseix21 merged 25 commits into
mainfrom
feature/plan-a-wallpaper-ds-port

Conversation

@senseix21
Copy link
Copy Markdown
Collaborator

Port plan-a feat() service-path rework: capsule_wallpaper + capsule_desktop_shell

Carries forward the feat() integration work that lived only on
feature/plan-a-rusty-user-surface and was not part of the Step-2
port (PR #156 chunk B was compositor + 1.1 typed-errno only). This is the
"port-forward" prerequisite to retiring that branch (see RETIRE_AUDIT.md,
Bucket 5).

capsule_wallpaper (13 commits)

  • 4 new: decode_client/{header,mod,seq,wire}.rs — image decode
    (PNG/BMP/JPEG/LZ4 → stretch-paint) via nonos_toolkit.
  • 8 ported: main.rs, server/handlers/{fade,get_wallpaper,set_policy, set_wallpaper}.rs, setup/{discover,prime}.rs, state/context.rs
    — plan-a's modular service path. main never modified these (they were
    base-identical), so this is a clean 2-way take, no main work lost.
  • Cargo.toml/Cargo.lock: add nonos_toolkit dep (decode_client needs it).
  • Verified 0/0 × 3 triples (x86_64/aarch64/riscv64) against main's
    1.1-ported protocol/ + chunk-A toolkit — confirms both ports faithful.

capsule_desktop_shell (11 commits) — full-tree adoption

  • 3 new: wm_client, wallpaper_client, market_client — ds→wm/wallpaper/
    market IPC integration.
  • 6 modified / 2 deleted: plan-a's coherent service-path architecture
    (main.rs, setup/{discover,mod,prime}.rs, state/context.rs,
    compositor_client/mod.rs; drops compositor_client/health.rs +
    setup/retry.rs).
  • Verified 0/0 × 3 triples.

Accepted trade-off (explicit)

ds adopts plan-a's coherent client-integration architecture. main's chunk-B
ds robustness — probe_compositor, the setup/retry.rs run-retry wrapper,
runrun_once — is superseded by it (the two are incompatible coherent
designs; mixing breaks the build). main's 1.1 typed-errno is preserved:
plan-a's ds also carries 1.1 and it is functionally identical to main's
faithful chunk-B port (build-confirmed). Wallpaper has no such trade-off
(clean 2-way). This is intrinsic to a full plan-a service-path port and was
chosen deliberately over the minimal/confirm-obsolete options.

All 24 commits authored senseix21 <mahdix2118@protonmail.com>, one per file.
After this lands, feature/plan-a-rusty-user-surface is retire-able with
zero residual unique content (git merge -s ours, tree ≡ main).

senseix21 added 25 commits May 18, 2026 16:52
Copilot AI review requested due to automatic review settings May 18, 2026 10:59
@senseix21 senseix21 merged commit dc525cc into main May 18, 2026
33 of 35 checks passed
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Ports the plan-a wallpaper and desktop_shell service-path integration, replacing the wallpaper smoketest with a long-running service and wiring desktop_shell to compositor/wm/wallpaper/market IPC clients.

Changes:

  • Adds wallpaper setup/server/decode paths for solid color and image wallpaper updates.
  • Adds desktop_shell client modules for wm, wallpaper, and market service calls.
  • Reworks desktop_shell setup/discovery state to use the new service-path architecture.

Reviewed changes

Copilot reviewed 22 out of 23 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
userland/capsule_wallpaper/src/state/context.rs Adds setters for color and policy state.
userland/capsule_wallpaper/src/setup/prime.rs Adds desktop_shell discovery and initializes default ARGB state.
userland/capsule_wallpaper/src/setup/discover.rs Generalizes service lookup and adds desktop_shell lookup.
userland/capsule_wallpaper/src/server/handlers/set_wallpaper.rs Adds image decode/paint path alongside solid color updates.
userland/capsule_wallpaper/src/server/handlers/set_policy.rs Routes policy mutation through the new setter.
userland/capsule_wallpaper/src/server/handlers/get_wallpaper.rs Returns composed ARGB state.
userland/capsule_wallpaper/src/server/handlers/fade.rs Applies zero-duration fade immediately and commits damage.
userland/capsule_wallpaper/src/main.rs Converts wallpaper from one-shot smoketest to setup plus service loop.
userland/capsule_wallpaper/src/decode_client/wire.rs Dispatches decode requests to toolkit image decoders.
userland/capsule_wallpaper/src/decode_client/seq.rs Parses decode requests, decodes pixels, and stretch-paints them.
userland/capsule_wallpaper/src/decode_client/mod.rs Exposes the decode client modules and entry point.
userland/capsule_wallpaper/src/decode_client/header.rs Defines decode wire header parsing.
userland/capsule_wallpaper/Cargo.toml Adds nonos_toolkit dependency.
userland/capsule_wallpaper/Cargo.lock Locks the new toolkit dependency.
userland/capsule_desktop_shell/src/wm_client/mod.rs Adds wm healthcheck IPC client.
userland/capsule_desktop_shell/src/wallpaper_client/mod.rs Adds wallpaper policy IPC client.
userland/capsule_desktop_shell/src/state/context.rs Stores discovered service ports in shell state.
userland/capsule_desktop_shell/src/setup/prime.rs Discovers peer services and invokes initial client calls.
userland/capsule_desktop_shell/src/setup/mod.rs Reexports prime setup directly.
userland/capsule_desktop_shell/src/setup/discover.rs Adds wm, wallpaper, and market service discovery.
userland/capsule_desktop_shell/src/market_client/mod.rs Adds market healthcheck IPC client.
userland/capsule_desktop_shell/src/main.rs Registers new client modules.
userland/capsule_desktop_shell/src/compositor_client/mod.rs Removes compositor health client export.
Comments suppressed due to low confidence (3)

userland/capsule_desktop_shell/src/setup/prime.rs:38

  • With the current kernel startup order, market is spawned after desktop_shell (src/userspace/init/entry.rs:97-124), so this one-time optional lookup records 0 whenever both features are enabled. Because market_port is never refreshed later, the added market integration is permanently disabled for the normal boot path.
    let market_port = discover::try_market();

userland/capsule_wallpaper/src/server/handlers/set_wallpaper.rs:30

  • For decoded image wallpapers this path paints pixels but leaves ctx.argb/ctx.alpha as the previous solid-color state. Subsequent GET_WALLPAPER reports that stale color, and a later fade tick repaints the whole surface with ctx.current_argb(), replacing the image with the old solid color.
    } else if decode_and_paint(ctx, body).is_err() {

userland/capsule_wallpaper/src/decode_client/wire.rs:32

  • This exposes JPEG as a supported wallpaper decode kind, but nonos_toolkit::image::jpeg::decode_jpeg_argb8888 currently only parses the header and then returns DecodeError::Unsupported unconditionally. Any JPEG set-wallpaper request will therefore be rejected despite being advertised by the new wire path.

let compositor_port = discover::require_compositor()?;
probe_compositor(compositor_port, 1)?;
let wm_port = discover::require_wm()?;
let wallpaper_port = discover::require_wallpaper()?;

pub fn run() -> Result<Context, &'static str> {
let compositor_port = discover::lookup_compositor_port()?;
let _ = discover::lookup_desktop_shell_port()?;
Comment on lines +1 to +30
use alloc::vec;
use alloc::vec::Vec;

use nonos_libc::mk_ipc_call;

const MAGIC: u32 = 0x4E4D_4B54;
const VERSION: u16 = 1;
const HDR_LEN: usize = 20;
const STATUS_LEN: usize = 4;
const OP_HEALTHCHECK: u16 = 0x0006;

pub fn healthcheck(port: u32, request_id: u32) -> Result<i32, &'static str> {
if port == 0 {
return Ok(0);
}
let mut tx = Vec::with_capacity(HDR_LEN);
tx.extend_from_slice(&MAGIC.to_le_bytes());
tx.extend_from_slice(&VERSION.to_le_bytes());
tx.extend_from_slice(&OP_HEALTHCHECK.to_le_bytes());
tx.extend_from_slice(&0u16.to_le_bytes());
tx.extend_from_slice(&0u16.to_le_bytes());
tx.extend_from_slice(&request_id.to_le_bytes());
tx.extend_from_slice(&0u32.to_le_bytes());

let mut rx = vec![0u8; HDR_LEN + STATUS_LEN];
let rc = mk_ipc_call(port as u64, tx.as_ptr(), tx.len(), rx.as_mut_ptr(), rx.len());
if rc < (HDR_LEN + STATUS_LEN) as i64 {
return Err("market call failed");
}
Ok(i32::from_le_bytes(rx[HDR_LEN..HDR_LEN + STATUS_LEN].try_into().unwrap()))
ctx.set_argb(argb);
let composed = ctx.current_argb();
fill_argb(ctx.backing_va, ctx.stride, ctx.width, ctx.height, composed);
} else if decode_and_paint(ctx, body).is_err() {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants