Auto-applied suggestions on libcosmic-yoda lib only: unused imports,
unused-by-name params (prefixed with _), redundant mutability. From 113
warnings down to 14 (the 14 remaining are real signals: never-read
fields, unreachable patterns, etc., to be reviewed manually).
Leyoda 2026 – GPLv3
Lets libcosmic build standalone again — no longer relies on cosmic-files'
[patch] redirect to /home/lionel/Devels/window_clipboard.
Leyoda 2026 – GPLv3
Writes the gtk-decoration-layout key to ~/.config/gtk-{3,4}.0/settings.ini
and best-effort updates GNOME's button-layout GSettings key for apps that
still consult it. Factors out write_gtk_settings_key for reuse.
Leyoda 2026 – GPLv3
Pick up yoda-wayland-only HEAD on leyoda/iced-yoda with softbuffer +
window_clipboard workspace default-features=false — drops the last
x11 crates. See cosmic-yoterm yoda-v5 for full cut metrics.
Dep chain audit showed winit, iced_winit and iced_tiny_skia all had
"x11" in their default features. Even though our Wayland-only build
doesn't use any X11 code path, the defaults were propagating through
cargo feature unification — winit-x11, tiny-xlib, x11-dl, etc. were
all being linked.
Fix, at the dep declaration level:
- [dependencies.iced_winit] default-features = false + wayland/wayland-dlopen
- [dependencies.iced_tiny_skia] default-features = false + wayland
- iced submodule's workspace winit = { ..., default-features = false }
Result on cosmic-yoterm binary:
- size: 55.4 MB -> 53.8 MB (-1.6 MB, ~3%)
- winit symbols: 2151 -> 1340 (-811)
- x11 symbols: 1526 -> 503 (-1023)
Remaining x11 footprint (~500 symbols):
- clipboard_x11 / x11rb: window_clipboard pulls both x11 + wayland
backends unconditionally on unix targets. Would need forking
window_clipboard to gate x11 behind a feature.
- tiny-xlib / as-raw-xcb-connection: low-level window-handle bindings
pulled by wgpu/softbuffer even when no X11 windows ever exist.
Dead code at runtime, probably best left alone until wgpu/raw-window-handle
upstream make these optional.
Two perf + correctness wins packaged as +yoda-v2 (version bump 0.1.0-yoda
-> 0.1.0-yoda.2):
1. color_picker::draw() — use the theme: &Theme parameter already passed
to draw() instead of THEME.lock().unwrap().clone() which cloned the
whole Theme on every redraw (src/widget/color_picker/mod.rs:622).
Upstreamable.
2. Dropped feature = "winit" from 21 combined cfg attrs in context_menu.rs,
menu/menu_bar.rs, menu/menu_inner.rs. These triple-gates (wayland +
winit + surface-message) were silently disabling all context-menu and
menubar popup creation in yoda apps (which don't activate the winit
feature). Now the code only gates on wayland + surface-message, which
is our actual runtime path. Matches the ungate we already did on
surface/action.rs in Phase 3d.
cargo check --lib passes. All 4 consumer apps rebuilt + installed as
+yoda-v2 (backup of previous yoda binaries in .pre-yoda-v2 siblings).
During Phase 3d it surfaced that several widgets keep a three-clause
cfg `#[cfg(all(feature = "winit", feature = "wayland", target_os = "linux"))]`
(e.g. dropdown::widget::with_popup, widget/mod.rs menu bits,
theme/style/mod.rs). Since the yoda fork is wayland-only the "winit"
clause is vestigial — dropping it unhides these methods for Wayland
consumers (cosmic-settings needs Dropdown::with_popup on the wallpaper
page).
Also fixed a cfg asymmetry in responsive_menu_bar.rs: the fallback
block was gated `cfg(not(all(winit, wayland, linux)))` while the
primary block was `cfg(all(wayland, linux))`. With winit removed both
blocks were active and we got E0308 expected-() — aligned the cfgs so
exactly one branch compiles.
Reverts the soft-fork pivot (6736a596). Strategy chosen with user:
full cascade fork. Every consumer (leyoda/cosmic-files + each leyoda/app)
depends on libcosmic-yoda by explicit path, so there are no transitive
deps left asking for the upstream 'libcosmic' crate — no [patch]
unification issues, no two-version traps.
Changes:
- Cargo.toml: name = libcosmic-yoda, version = 0.1.0-yoda
- i18n/*/libcosmic.ftl -> libcosmic_yoda.ftl (71 locales)
- examples/*/Cargo.toml dep refs back to libcosmic-yoda
- compat stub features (winit=[], x11=[]) kept for upstream deps that
might still request them during the migration window
cargo check --lib passes.
The initial hard rename (255cf7cc) broke because Cargo's [patch] with
`package = libcosmic-yoda` does NOT unify across the transitive graph.
cosmic-files (still upstream) asks for "libcosmic"; patched with a
renamed package it ends up as a separate crate, leading to two copies
of cosmic::Theme/Action with incompatible types.
Soft fork keeps the yoda identity where it counts and stays compatible:
- Cargo name : libcosmic (for patch/unification)
- Version : 1.0.0 (same major as upstream so [patch] semver-accepts it)
- Lib name : cosmic (unchanged)
- Repo : leyoda/libcosmic-yoda on Forgejo (yoda lineage)
- Branch : main (vs upstream master)
Revert parts:
- examples/*/Cargo.toml dep refs back to libcosmic
- i18n/*/libcosmic_yoda.ftl renamed back to libcosmic.ftl
Added:
- Compat stub features: winit = [], x11 = [] — empty so Cargo can satisfy
upstream deps asking for these, but no code is actually gated on them
any more (all removed in Phase 2).
Ungates done to make the Wayland path self-sufficient after winit removal:
- src/lib.rs: pub mod app + pub use Application/ApplicationExt no longer
gated on winit; prelude exports ApplicationExt unconditionally
- src/surface/action.rs: 6 functions had #[cfg(all(wayland, linux, winit))]
triple-gates; simplified to #[cfg(all(wayland, linux))] since winit is
no longer a meaningful gate (wayland is now the only shell)
- 12 standalone #[cfg(feature = "winit")] annotations removed from src/
(their gated code is now always compiled)
cargo check --lib + cargo check in cosmic-yoterm both pass with a single
libcosmic v1.0.0 in the tree.
Part of the yoda fork direction: libcosmic-yoda is Wayland-only going forward.
Cargo.toml changes:
- default features: remove winit, x11, iced-wayland, multi-window -> add wayland
- applet feature: remove winit dep
- merge iced-wayland into wayland (simpler feature graph)
- remove winit, winit_debug, winit_tokio, winit_wgpu, x11, iced-wayland features
- keep iced_winit dep (it's a misnomer — also hosts the wayland/cctk runtime)
Workspace:
- examples/* excluded (many depend on winit/x11) — revisited in a later phase
Behavior:
- Library builds clean in release with default features (cargo check + cargo build --release --lib OK)
- 58 lines in src/ gated on feature "winit" become unreachable (dead-code warnings — cleanup deferred)
- 108 lines gated on feature "wayland" now always active via default
--all-features is known-broken because tokio/async-std/smol are mutually
exclusive — this is pre-existing, not a Phase 2 regression.
Fork point: pop-os/libcosmic 1.0.0 + perf/quickwins-bundle + macOS
window controls feature. From here the crate diverges under the yoda
lineage with its own versioning.
Changes:
- Cargo.toml: name = libcosmic-yoda, version = 0.1.0-yoda
- [lib] name = cosmic kept unchanged — consumer code still does 'use cosmic::...'
- examples/*/Cargo.toml: updated all libcosmic dep references to libcosmic-yoda
- i18n/*/libcosmic.ftl renamed to libcosmic_yoda.ftl (71 locales) to match
the new name expected by fluent_language_loader!() macro
cargo check --lib passes. Examples not yet validated — Phase 2 (Wayland-only
cut) will rework them anyway.
Adds a new public enum `WindowControlsPosition { Start, End }` and a
matching field on `HeaderBar`, allowing window controls (close / minimize
/ maximize) to be packed on the start side of the headerbar (macOS
style, icon order close → minimize → maximize) instead of the default
end side (Linux / GNOME style, minimize → maximize → close).
Wiring:
- `crate::widget::WindowControlsPosition` re-exported alongside
`HeaderBar`.
- `HeaderBar::controls_position(Option<WindowControlsPosition>)` setter;
when left unset, falls back to `crate::config::window_controls_position()`
(reads `CosmicTk.window_controls_position`), mirroring how `density`
falls back to `header_size()`.
- New `CosmicTk.window_controls_position` field with default `End` for
backwards compatibility; serde-friendly enum so existing configs keep
working via `#[serde(default)]` semantics.
Tested with cosmic-yoterm, cosmic-settings, cosmic-edit, cosmic-files
rebuilt against this libcosmic via a local `[patch]` override. Config
changes picked up live through the existing cosmic-config subscription.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two independent bugs prevented tab drag-and-drop reorder from working
on cosmic-comp (and likely other compositors):
1. allow_reorder required DndAction::Move to be negotiated via
OfferEvent::SelectedAction, which cosmic-comp does not always emit
for self-drops (the SelectedAction event either never arrives or
arrives with DndAction::empty()). Add a fallback: accept self-drops
whenever state.dragging_tab is set. dragging_tab is only populated
by start_tab_drag on this same widget, so this is safe; mime match
and on_reorder presence are checked below.
2. reorder_event_for_drop preferred drop_hint.side over positional
swap, producing counter-intuitive no-ops: dropping A (pos 0) on the
left half of B (pos 1) resolved to "Before B" which, after removing
A, lands at pos 0 again — the tab appeared not to move. Always use
default_insert_position, which derives direction from dragged vs
target positions (Konsole/Firefox/Chrome-style swap semantics).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Fires in addition to on_activate when the same entity is left-clicked
twice within 400 ms. Lets applications bind quick actions (e.g. rename
a tab) without blocking the normal single-click activation path.
- New Widget::on_double_click builder mirroring on_activate/on_close.
- last_click field on LocalState for timestamp tracking.
- Detection branch in the mouse handler after on_activate fires, so the
target entity is already focused when the callback runs.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Model::clear() cloned the entire order VecDeque to iterate while
remove() mutated it, producing an O(n) allocation proportional to the
number of items — needless on a clear() which is going to drop all of
them anyway.
Replace the clone with std::mem::take(&mut self.order): we iterate the
taken VecDeque (transferring ownership), and the inner self.order.remove(index)
in each remove() call now finds position()==None and no-ops, since
self.order has been swapped with an empty default.
Same semantics, zero allocation. Noticeable on large nav/table models
(>100 items) and on apps that reset state frequently (settings pages,
file lists, context menus).
malloc_trim(0) was called at the end of every update() and view(),
reaching 60-200 Hz during typical scrolling, resize, or animation.
Each call walks the glibc heap (10 us to several ms depending on
fragmentation) and could consume a substantial fraction of the frame
budget in worst cases.
Throttle trim() to once per second using a thread-local Instant,
preserving the existing API. RSS stays bounded (1 Hz is enough to
release collectable pages soon after) while per-frame cost becomes
a single thread-local check plus a duration comparison.
No call-site changes required; the three existing trim(0) invocations
in src/app/cosmic.rs (update, view multi-window, view single-window)
now fall under the throttle transparently.
- [x] I have disclosed use of any AI generated code in my commit
messages.
- If you are using an LLM, and do not fully understand the changes it is
making to the code base, do not create a PR.
- In our experience, AI generated code often results in overly complex
code that lacks enough context for a proper fix or feature inclusion.
This results in considerably longer code reviews. Due to this, AI
authored or partially authored PRs may be closed without comment.
- [x] I understand these changes in full and will be able to respond to
review comments.
- [x] My change is accurately described in the commit message.
- [x] My contribution is tested and working as described.
- [x] I have read the [Developer Certificate of
Origin](https://developercertificate.org/) and certify my contribution
under its conditions.
adds a feature to select from the start of the sentence until the last
occurrence of a character. This can be used to select until the
extension in cosmic-files save dialog or rename pop up.
Also, it adds a feature to select until the last occurrence of a
character on double-click.