| Age | Commit message (Collapse) | Author | Files | Lines |
|
The Lua and IPC/CLI surface for the three new core primitives
(crates/core: aspect_ratio rule action, general.phone_mode, virtual-
pointer window pinning):
- srd.rule(..., { aspect_ratio = "9:16" }): parses a "W:H" string into a
validated (u32, u32), rejecting a malformed value as a real Lua error
at config-load time rather than silently ignoring it.
- general.phone_mode config default, plus srd set phone_mode <bool> for
the live equivalent (same shape as animations/shadows/rounded_corners).
- pin_input IPC dispatch ({"cmd":"pin_input","pid":<pid>,"id":<window
id>}, id omitted to unpin) and its CLI surface, srd dispatch pin input
<pid> <window-id> / unpin input <pid>. Keyed by the owning client's
process id, not an opaque per-object id nothing outside the Wayland
backend could ever learn - a controlling tool already knows its own
pid for free.
See docs/TODO.md for the full design reasoning behind each of these.
|
|
Live testing found v1 genuinely broken, not just rough:
1. Icons weren't rendering reliably at all - ensure_desktop_icons only
ever computed the grid's origin once, on whichever render pass
happened to be first. AGS's own top bar registers its exclusive zone
after that first pass, so origin got permanently baked in at the
pre-bar geometry. Confirmed live via a temporary diagnostic log.
Fixed by re-deriving origin from the primary monitor's current
geometry on every call instead of just the first.
2. Fixed icons (Home/Computer/Trash) always sorted before real files --
confirmed wrong via direct question. The whole list now sorts
alphabetically by label, case-insensitive, fixed icons included.
3. "Set as Wallpaper" was the wrong feature: removed entirely
(DesktopMenuAction::SetWallpaper, general.wallpaper_command,
is_image_path). The user wants that handled by their real file
manager once opened, not reimplemented here.
Also adds real menu functionality per "where are all the options":
Rename (inline text edit, new CompState::renaming_icon field and
keyboard redirect mirroring NativeLock::password's existing precedent),
Delete (moves to ~/.local/share/Trash per the freedesktop.org spec, new
trash.rs module, same-filesystem case, no confirmation - this is the
reversible move-to-trash, not a permanent delete), Empty Trash on the
Trash icon, and Open Terminal Here / Open in File Manager on the
bare-desktop menu (new general.terminal config key).
133 wayland-crate tests (up from 106), full workspace build and clippy
clean.
|
|
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.
|
|
SRDWM_GPU=1 was the only way to opt into the udev backend's GBM+EGL
GPU render path - an env var, not a real config option, with no way
to enable it from init.lua the way every other general.* flag works.
WindowManager::gpu_enabled (plain bool, false by default - unlike
rounded_corners_enabled's Option<bool>, GPU rendering has one
unambiguous default regardless of which backend ends up connecting,
so there's no "let the backend decide" case to preserve) is read from
general.gpu in apply_general_settings, same as every other general.*
key. gpu::probe now takes an explicit enabled: bool instead of
checking the env var itself; udev/platform.rs's call site computes it
as wm.gpu_enabled OR SRDWM_GPU=1, so the env var still works as a
quick manual override for testing without touching config, on top of
the new persistent option.
Falls back to the existing software (Pixman) path exactly as before
on any failure at any step (no GBM device, no atomic-modesetting
support, a software-only EGL renderer, ...) - gpu::probe's own
fallback behavior is unchanged, only how the initial enabled/disabled
decision gets made.
|
|
# Conflicts:
# crates/config/src/engine/general.rs
# crates/wayland/src/udev/drm.rs
# crates/wayland/src/udev/mod.rs
# crates/wayland/src/udev/render.rs
# crates/wayland/src/winit/render.rs
|
|
Fixes a live-reproduced VT-switch busy loop (failed page_flip retried
with no backoff), shadow rendering bleeding onto occluding windows
unclipped, and a winit-backend buffer-age correctness bug that left
stale cross-window pixels on screen. Committing before merging in the
much larger uncommitted rust-rewrite worktree, which independently
touches several of the same files - this is the pre-merge baseline to
diff against, not a claim that these are the final versions of these
fixes.
|
|
Safety commit before reconciling this worktree with main, which has
diverged with its own separate fixes today. Nothing here is reviewed
or curated yet - this exists purely so none of this work can be lost
to a git operation, disk issue, or worktree cleanup while that
reconciliation happens.
|
|
Remaining files from the backlog: Lua config engine
additions (general/register/support/window), workspace Cargo.toml/
Cargo.lock churn from the new dependencies added elsewhere in this
sweep, srdwm/main.rs wiring, and docs (DEFAULTS.md plus a new
SESSION_HANDOFF.md written mid-session for continuity across a restart
- see that file's own header for what it is and isn't).
|
|
Auditing "clicking behavior and basics": general.focus_follows_mouse,
general.mouse_follows_focus, general.auto_raise, general.auto_focus,
the entire window.* namespace (8 more keys, a full duplicate of the
same four plus remember_position/size/state), and general.
smart_placement/border_width were all seeded into default_config() and
documented in DEFAULTS.md, but none were read anywhere - srd.set()/
srd.get() on any of them silently succeeded while doing nothing.
focus_follows_mouse is real, well-defined, and directly relevant to
clicking basics - implemented it plus auto_raise (raise, not just
focus, on hover) rather than just deleting the promise like the
others. WindowManager gained focus_follows_mouse/auto_raise bools,
wired from apply_general_settings the same way every other general.*
flag is. handle_pointer_position now tracks whichever window (content
or decoration) is under the pointer and, when the setting is on and
that differs from the currently-focused window, focuses it through the
same focus_window() free function every click-driven focus change
already uses (real keyboard focus, not just core state) - skipped
entirely while dragging/resizing or over a layer-shell surface, so the
pointer sweeping over other windows mid-drag or hovering a bar can't
steal focus from what's actually being manipulated.
mouse_follows_focus (pointer warp on keybinding-driven focus change)
and auto_focus (no clear distinct meaning beyond click-to-focus) stay
unimplemented and are now undocumented rather than promised.
|
|
MISSING.md had listed this as needing to touch srdwm_core::window::
hit_test's signature at every call site, including the honest-stub
Windows/macOS backends - overstated on closer inspection: that shared
function already takes a plain resize_margin: i32 parameter, agnostic
to where the value comes from. The only real change needed was reading
Window.resize_margin.unwrap_or(wm-wide default) instead of always the
WM-wide value, at the single call site inside WindowManager::hit_test
in core - no backend touched at all.
Window.resize_margin: Option<i32>, WindowRuleActions.resize_margin to
match, applied in add_window/reapply_rules_if_pending the same way
opacity already is. Settable via a rule action or
srd.window.set_resize_margin(n) on the focused window.
|
|
visible_windows' doc comment claimed windows show "on the active
workspace of whichever monitor they're assigned to" - the code never
reads w.monitor at all; current_workspace is one flat value shared by
every monitor, not per-output. Documented that explicitly on both the
field and the method, since this is a real behavioral difference from
Hyprland worth a reader actually seeing, not just an inaccurate comment
to fix quietly.
monitor.primary_workspace/monitor.workspace_count describe a per-
monitor-workspace design that doesn't exist; workspace.auto_switch/
workspace.persistent were never wired to any behavior. All four were
seeded into default_config() and documented in DEFAULTS.md, so
srd.set()/srd.get() on them silently succeeded while doing nothing --
removed from both, matching the precedent already set by general.
rounded_corners' deliberate absence from default_config for a
different reason (backend-dependent default rather than unbuilt).
|
|
Pure reorganization, no behavior change - verified by diffing the
function-name and struct/enum-name sets before/after (both identical)
plus a full cargo test pass. lib.rs is now a thin shim (mod
declarations + pub use) since a crate root can't itself become a
directory; all the actual content moved into engine/, split along the
Lua API's own srd.*/srd.window.*/srd.layout.*/srd.workspace.*/
srd.theme.* namespace groupings the file's own section comments
already used:
- mod.rs: SharedState, Engine, ConfigError, and Engine's core methods
(new/get/set/dispatch/reload/...).
- register.rs: register_srd_module, which wires every fn_* builder
from every other file into the srd Lua table - the one place that
genuinely needs to see all of them.
- general.rs/window.rs/layout.rs/workspace.rs/theme.rs: the fn_*
builder methods themselves, one file per srd.* sub-namespace.
- support.rs: free functions shared across those (do_reload,
parse_direction, flatten_table_into, validate, default_config) and
the WindowAction enum.
- tests.rs: the ~300-line test module, left unsplit for the same
shared-helper reason manager/tests.rs and udev's tests were.
~40 fn_* methods and the support.rs free functions/enum went from
private to pub(super): called across what are now sibling submodules,
which Rust's privacy model doesn't let see each other's private items.
|