diff --git a/flake.lock b/flake.lock new file mode 100644 index 000000000..95a880e21 --- /dev/null +++ b/flake.lock @@ -0,0 +1,48 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1789149629, + "narHash": "sha256-H6GwaZzZf+4npqv0tph94w9tZddSjFjmQrVsW0z78uk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "eaad089433ca2bb662274377d33df3d0e51ef28b", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1789196581, + "narHash": "sha256-yJr1Bt4fKkKIpPYbsKGqJ0VFdoDnURgRwuffmBQ2WzY=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "228ecefb6329d5a531b77b46b581a2f0c26ee056", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix index fd09ceec8..89610a0b6 100644 --- a/flake.nix +++ b/flake.nix @@ -59,15 +59,20 @@ cargoLock = { lockFile = ./Cargo.lock; - # One entry per distinct git source in Cargo.lock. Replace each - # lib.fakeHash with the sha256 that `nix build` prints on the - # first attempt; they must be refreshed whenever the matching - # rev in Cargo.toml moves. + # One entry per distinct git source in Cargo.lock, keyed by any + # one package from it. Two of these are transitive and easy to + # miss by reading Cargo.toml alone: cryoglyph and dpi arrive + # through iced, which pins its own forks. Regenerate the list + # from the lock rather than the manifest: + # grep -B2 'source = "git+' Cargo.lock + # Each hash must be refreshed whenever the matching rev moves. outputHashes = { - "acadrust-0.5.5" = lib.fakeHash; - "cadkernel-0.1.0" = lib.fakeHash; - "iced-0.15.0-dev" = lib.fakeHash; - "iced_aw-0.14.1" = lib.fakeHash; + "acadrust-0.5.5" = "sha256-rYtJaJsb+lZZIDBtPTCfWRVyA1Gfinn3UqJlfzkhhGk="; + "cadkernel-0.1.0" = "sha256-7smcL9oo5mJwoCLYUbD4+lA9Xcm+/qpVswYxzoGjTDk="; + "cryoglyph-0.1.0" = "sha256-5BOJNDcjhpt17/XSri3JGtX8NwC7db18bddp5wanMes="; + "dpi-0.1.1" = "sha256-pQn1lCFSJMkjUfHoggEzMHnm5k+Chnzi5JEDjahnjUA="; + "iced-0.15.0-dev" = "sha256-Atg+nr1VgXwW5I7LiMAMqHemz/9ZiehTc2EWuSFEGHI="; + "iced_aw-0.14.1" = "sha256-OynSIjv8SgSoxpw1S4wH58vDdqga/YojOR5A9ZLKrd8="; }; }; diff --git a/src/app/settings.rs b/src/app/settings.rs index fb9b3ed61..0be12cc9c 100644 --- a/src/app/settings.rs +++ b/src/app/settings.rs @@ -687,6 +687,39 @@ impl Default for UserSettings { mod tests { use super::*; + /// Object snap ships live. The modes were always pre-selected; only the + /// master switch was off, so a new user got a configured snap set that + /// did nothing until they found the status-bar pill. + /// + /// This is asserted rather than checked by eye because the default is + /// only observable in a fresh profile: the app persists settings on + /// change, so an existing settings.json keeps whatever osmode it already + /// holds and never reveals what a new install would do. + #[test] + fn snapping_is_enabled_in_a_fresh_profile() { + let settings = UserSettings::default(); + assert_eq!( + settings.osmode & OSMODE_SUPPRESS, + 0, + "the suppress bit is set, so snapping ships off" + ); + + let (modes, master_on) = snaps_from_osmode(settings.osmode); + assert!(master_on, "decoding the default must report snapping on"); + for expected in [ + SnapType::Endpoint, + SnapType::Midpoint, + SnapType::Center, + SnapType::Intersection, + ] { + assert!(modes.contains(&expected), "{expected:?} is not in the default set"); + } + + // The Snapper and the persisted default have to agree, or the running + // state and the saved state disagree the moment anything is written. + assert_eq!(crate::snap::Snapper::default().snap_enabled, master_on); + } + #[test] fn osmode_encodes_bits_and_suppress() { // Endpoint(1) + Midpoint(2) + Intersection(32) = 35, master on.