Replace 3 panicking unwrap() in cosmic-app-list/wayland_handler.rs
(event loop dispatch + 2 conn.flush in screencopy) with logged
errors that break/return None instead.
Wrap cosmic-applets/main.rs entry point in panic::catch_unwind to
catch panics propagating from libcosmic/iced/winit (which we cannot
patch locally without forking) when the COSMIC compositor closes
the Wayland connection at logout. This eliminates the cascade of
~12 SIGABRT coredumps observed at session shutdown.
Panic strategy is unwind (default), catch_unwind is sound here.
Leyoda 2026 – GPLv3
Inter-icon hover changes were snapping because icon_scale_for read the
hovered icon's real rectangle directly. This adds a small animation
layer so the bell center lerps toward the target and the whole effect
fades in/out at the dock's edges.
CosmicAppList gains three fields:
- anim_hover_center: Option<(f32, f32)> — virtual cursor position,
chases the hovered icon's center across ticks.
- anim_hover_intensity: f32 (0..1) — global fade-in/out of the
fisheye. Target 1.0 while a dock icon is hovered, 0.0 otherwise.
- anim_last_tick: Option<Instant> — for dt-based exponential smoothing
(time-constant tau = 60ms, ~99% of target reached in ~120ms).
A new Message::AnimTick(Instant) is emitted at ~60 fps by a
conditional iced::time::every subscription — only active when the
pointer is over a dock icon OR intensity hasn't faded back to ~0 yet,
so the panel stays idle when no one is hovering the dock.
icon_scale_for now reads anim_hover_center instead of rectangles[hovered]
and multiplies the bell's peak by anim_hover_intensity. Behaviour:
- Pointer slides A → B: bell glides continuously, both icons animate.
- Pointer enters dock: icons inflate smoothly over ~120 ms.
- Pointer leaves dock: icons deflate smoothly over ~120 ms.
Fallback paths (first frame, missing rectangles) still respond
instantly so the feature never looks 'stuck' before the animation
kicks in.
Replaces the binary 1.3× hover with a true gaussian bell curve — the
hovered icon still peaks at ~1.35×, but the ±1 neighbours also bulge
noticeably, ±2 a bit, and ±3+ relax to 1.0×. Footprint ~5 icons wide,
matching the macOS Dock fisheye feel.
Implementation in fn icon_scale_for(id):
- Reads the hovered icon's and the current icon's bounds from
self.rectangles (already populated by the existing RectangleTracker
subscription — no new plumbing).
- Distance = |this_center - hovered_center| along the panel's long axis
(horizontal for Top/Bottom anchors, vertical for Left/Right).
- sigma = hovered_extent * 1.4 so the bell's half-width matches one
icon width (neighbors clearly pulled, far icons untouched).
- scale = 1.0 + PEAK * exp(-(d/sigma)²) with PEAK = 0.35.
- Falls back to binary 1.35×/1.0× when rectangle data isn't populated
yet (first render / resize) — visibly responsive even before the
tracker catches up.
No widget signature changes vs v1, just a smarter formula. All five
as_icon call sites already pass the result of icon_scale_for so this
update propagates everywhere.
Still on the TODO list: smooth animation (b). Right now icon→icon
transitions snap instantly; a smoothed_hover_center + tick subscription
would lerp it. Deferred to a follow-up commit.
First pass at the signature macOS Dock effect — the icon under the
pointer grows, adjacent icons stay at base size. Full fisheye (smooth
bell-curve scaling on neighbors) can be a later iteration.
Changes in cosmic-app-list/src/app.rs:
- CosmicAppList gains a hovered_dock_item: Option<DockItemId>
auto-initialized to None via #[derive(Default)].
- New Message::DockItemHover(Option<DockItemId>) handled in update()
by just writing the field; view() then reads it to decide scale.
- DockItem::as_icon gains an icon_scale: f32 parameter. Inside it the
cosmic_icon width/height = (base_icon_size * icon_scale) clamped
to u16; indicator dot and other surrounding layout stay at base
size so only the icon visually bulges.
- New App::icon_scale_for(id) helper: 1.3 if Some(id) == hovered,
1.0 otherwise. Single place to tune the magnification factor.
- The two main dock rows (favorites + filtered_active_list) wrap
their rendered applet_tooltip in widget::mouse_area with
on_enter(DockItemHover(Some(id))) / on_exit(DockItemHover(None))
and call icon_scale_for before rendering.
- The three remaining as_icon call sites (DnD preview, favorites
overflow popup, active overflow popup) pass icon_scale = 1.0 —
hover magnification on those surfaces would look jittery and isn't
needed anyway.
Build: cargo build --release -p cosmic-app-list (≈ 7s). Binary
installed at /usr/local/bin/cosmic-app-list, backup kept as
.pre-magnification.
Implement optional filtering of apps by active workspace or configured
output. The filter_top_levels config option accepts None (no filtering),
ActiveWorkspace (workspace-only), or ConfiguredOutput (monitor and
workspace filtering).
Signed-off-by: Tobias Schaffner <tobiasschaffner87@outlook.com>
With custom panel sizes, we use ranges that equal the values you would normally get from the hardcoded panel sizes
Update libcosmic
Signed-off-by: Ryan Brue <ryanbrue.dev@gmail.com>
In the workspace applet, this now uses `Workspace` in the front-end code
instead of a tuple with unnamed fields. Handling of scrolling is also
moved to the frontend, which uses less code and seems more natural. It
would be good to have a helper in libcosmic for this. It also changes
`ObjectId` to `ExtWorkspaceHandleV1`, which is a little simpler and I
see no reason here to avoid the more strongly typed object.
At some point we may want a shared subscription for workspaces in
multiple applets. As well as a higher-level abstraction for screen
capture.
Requires pop-os/cosmic-protocols#49.
The duplication between applets, and
cosmic-workspace/xdg-desktop-portal-cosmic, should be moved to shared
abstractions. But that can be done after moving to
`ext-image-copy-capture`.
`ToplevelInfo` now contains both ext and cosmic handles, so the tuples
of handles and info are needed. Use just the info.