srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/wayland/src/state/mod.rs
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2025-08-15 23:22:00 +0200
committersrdusr <[email protected]>2025-08-15 23:22:00 +0200
commitcc22fe69a68e0fff027d833029aea850976488c8 (patch)
treeeb1350c24c61b5d4b30d763d64149a5c6504a925 /crates/wayland/src/state/mod.rs
parent6694a2d9946d98d5752d84b22c45879cab5c9abe (diff)
downloadsrdwm-cc22fe69a68e0fff027d833029aea850976488c8.tar.gz
srdwm-cc22fe69a68e0fff027d833029aea850976488c8.zip
Add real desktop icons plus right-click desktop/icon context menus
Closes "right-click on bare desktop" - previously a true no-op, nothing rendered above the wallpaper at all. Requested directly: a real desktop "just like windows does" - Home/Computer/Trash plus one icon per real ~/Desktop entry, individually draggable with persisted grid positions, double-click to open, right-click menus (per-icon "Open" plus "Set as Wallpaper" for image files when general.wallpaper_command is set; bare desktop "New Folder"/"Refresh"). Architecture mirrors the existing context_menu.rs/snap_flyout.rs "compositor-owned floating UI" pattern: desktop_icons.rs (data model, grid layout, filesystem scan, hit-test), desktop_icons_state.rs (JSON persistence, same shape as monitor_layout.rs), desktop_menu.rs (the new right-click menu, reusing decoration::render_context_menu's existing rasterizer), state/desktop_icons.rs (CompState glue: rescan/select/drag/ open/persist), and a new decoration::render_desktop_icon rasterizer -- hand-drawn glyphs, since no PNG/SVG decoding capability exists anywhere in this workspace. Wired into both render loops (udev and winit) above the wallpaper and below every window, and into input/pointer.rs's button/ motion handlers for selection, drag, double-click, and both menus. Four new config keys: general.desktop_icons (default true - a directly requested, purely visual feature, unlike the opt-in-while-experimental general.gpu), general.file_manager, general.desktop_icon_single_click, general.wallpaper_command (all default off/empty). Deliberately out of scope for this pass, stated up front: move-to-trash and "Empty Trash" (destructive, no confirmation-dialog primitive to gate them on yet), filesystem watching, multi-select, per-mimetype icon art, icons on any monitor but the primary one. 124 wayland-crate tests (up from 106), full workspace build and clippy clean.
Diffstat (limited to 'crates/wayland/src/state/mod.rs')
-rw-r--r--crates/wayland/src/state/mod.rs33
1 files changed, 33 insertions, 0 deletions
diff --git a/crates/wayland/src/state/mod.rs b/crates/wayland/src/state/mod.rs
index 0ef4346..66f9ec6 100644
--- a/crates/wayland/src/state/mod.rs
+++ b/crates/wayland/src/state/mod.rs
@@ -340,6 +340,38 @@ pub(crate) struct CompState {
/// Rasterised pixels for the currently-open `snap_flyout`, same
/// build-once-on-open pattern as `context_menu_buffer`.
pub(crate) snap_flyout_buffer: Option<MemoryRenderBuffer>,
+ /// The real desktop icons (Home/Computer/Trash plus `~/Desktop`'s own
+ /// contents) - see `desktop_icons.rs`. `None` until the first render
+ /// pass populates it (lazily, once the primary monitor's own geometry
+ /// is actually known - see `state/desktop_icons.rs::ensure_desktop_
+ /// icons`), and permanently `None` when `general.desktop_icons` is off.
+ pub(crate) desktop_icons: Option<crate::desktop_icons::DesktopIcons>,
+ /// Rasterised pixels per icon, keyed by `DesktopIcon::id` - rebuilt
+ /// only for the one icon whose selection/drag state actually changed,
+ /// same cached-until-dirty convention as every other decoration
+ /// buffer in this codebase.
+ pub(crate) desktop_icon_buffers: HashMap<String, MemoryRenderBuffer>,
+ /// An in-progress icon drag: the icon's own id, the pointer's grab
+ /// offset from that icon's cell origin at the moment the drag started
+ /// (so the icon tracks the pointer smoothly rather than snapping its
+ /// top-left corner straight to the cursor), and the icon's own live
+ /// top-left position this frame - updated on every pointer-motion
+ /// event by `update_desktop_icon_drag`, read straight back by
+ /// `desktop_icon_render_list` with no separate "current pointer
+ /// position" field needed anywhere on `CompState`. `None` whenever no
+ /// drag is active.
+ #[allow(clippy::type_complexity)]
+ pub(crate) desktop_icon_drag: Option<(String, (i32, i32), (i32, i32))>,
+ /// The right-click desktop-icon/bare-desktop menu, if one is currently
+ /// open - see `desktop_menu.rs`. Same lifecycle/mutual-exclusion
+ /// story as `context_menu`/`snap_flyout` above.
+ pub(crate) desktop_menu: Option<crate::desktop_menu::DesktopMenu>,
+ /// Same build-once-on-open pattern as `context_menu_buffer`.
+ pub(crate) desktop_menu_buffer: Option<MemoryRenderBuffer>,
+ /// Same double-click bookkeeping as `last_titlebar_click`, keyed by
+ /// `DesktopIcon::id` instead of `WindowId` since a desktop icon isn't
+ /// a window - see `CompState::is_double_click`'s own doc comment.
+ pub(crate) last_icon_click: Option<(String, u32)>,
pub(crate) wm: Rc<RefCell<WindowManager>>,
pub(crate) surface_to_id: HashMap<WlSurface, WindowId>,
pub(crate) id_to_window: HashMap<WindowId, DWindow>,
@@ -822,6 +854,7 @@ impl CompState {
}
+mod desktop_icons;
mod focus;
mod geometry;
mod layers;