diff --git a/niri-config/src/appearance.rs b/niri-config/src/appearance.rs index 77ee5894..eba265b0 100644 --- a/niri-config/src/appearance.rs +++ b/niri-config/src/appearance.rs @@ -383,17 +383,12 @@ pub struct ShadowOffset { pub y: FloatOrInt<-65535, 65535>, } -#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq)] pub struct WorkspaceShadow { - #[knuffel(child)] pub off: bool, - #[knuffel(child, default = Self::default().offset)] pub offset: ShadowOffset, - #[knuffel(child, unwrap(argument), default = Self::default().softness)] - pub softness: FloatOrInt<0, 1024>, - #[knuffel(child, unwrap(argument), default = Self::default().spread)] - pub spread: FloatOrInt<-1024, 1024>, - #[knuffel(child, default = Self::default().color)] + pub softness: f64, + pub spread: f64, pub color: Color, } @@ -405,8 +400,8 @@ impl Default for WorkspaceShadow { x: FloatOrInt(0.), y: FloatOrInt(10.), }, - softness: FloatOrInt(40.), - spread: FloatOrInt(10.), + softness: 40., + spread: 10., color: Color::from_rgba8_unpremul(0, 0, 0, 0x50), } } @@ -417,8 +412,8 @@ impl From for Shadow { Self { on: !value.off, offset: value.offset, - softness: value.softness.0, - spread: value.spread.0, + softness: value.softness, + spread: value.spread, draw_behind_window: false, color: value.color, inactive_color: None, @@ -426,6 +421,34 @@ impl From for Shadow { } } +#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)] +pub struct WorkspaceShadowPart { + #[knuffel(child)] + pub off: bool, + #[knuffel(child)] + pub on: bool, + #[knuffel(child)] + pub offset: Option, + #[knuffel(child, unwrap(argument))] + pub softness: Option>, + #[knuffel(child, unwrap(argument))] + pub spread: Option>, + #[knuffel(child)] + pub color: Option, +} + +impl MergeWith for WorkspaceShadow { + fn merge_with(&mut self, part: &WorkspaceShadowPart) { + self.off |= part.off; + if part.on { + self.off = false; + } + + merge_clone!((self, part), offset, color); + merge!((self, part), softness, spread); + } +} + #[derive(Debug, Clone, Copy, PartialEq)] pub struct TabIndicator { pub off: bool, diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index 009d484a..7a07b71b 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -187,14 +187,14 @@ where match name { // TODO: most (all?) of these need to be merged instead "input" => m_replace!(input), - "cursor" => m_replace!(cursor), - "clipboard" => m_replace!(clipboard), - "hotkey-overlay" => m_replace!(hotkey_overlay), - "config-notification" => m_replace!(config_notification), + "cursor" => m_merge!(cursor), + "clipboard" => m_merge!(clipboard), + "hotkey-overlay" => m_merge!(hotkey_overlay), + "config-notification" => m_merge!(config_notification), "animations" => m_replace!(animations), "gestures" => m_replace!(gestures), - "overview" => m_replace!(overview), - "xwayland-satellite" => m_replace!(xwayland_satellite), + "overview" => m_merge!(overview), + "xwayland-satellite" => m_merge!(xwayland_satellite), "switch-events" => m_merge!(switch_events), "debug" => m_merge!(debug), @@ -1459,9 +1459,7 @@ mod tests { }, }, overview: Overview { - zoom: FloatOrInt( - 0.5, - ), + zoom: 0.5, backdrop_color: Color { r: 0.15, g: 0.15, @@ -1478,12 +1476,8 @@ mod tests { 10.0, ), }, - softness: FloatOrInt( - 40.0, - ), - spread: FloatOrInt( - 10.0, - ), + softness: 40.0, + spread: 10.0, color: Color { r: 0.0, g: 0.0, diff --git a/niri-config/src/misc.rs b/niri-config/src/misc.rs index 5252c8bf..66a200ca 100644 --- a/niri-config/src/misc.rs +++ b/niri-config/src/misc.rs @@ -1,4 +1,5 @@ -use crate::appearance::{Color, WorkspaceShadow, DEFAULT_BACKDROP_COLOR}; +use crate::appearance::{Color, WorkspaceShadow, WorkspaceShadowPart, DEFAULT_BACKDROP_COLOR}; +use crate::utils::{Flag, MergeWith}; use crate::FloatOrInt; #[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)] @@ -13,15 +14,11 @@ pub struct SpawnShAtStartup { pub command: String, } -#[derive(knuffel::Decode, Debug, PartialEq)] +#[derive(Debug, PartialEq)] pub struct Cursor { - #[knuffel(child, unwrap(argument), default = String::from("default"))] pub xcursor_theme: String, - #[knuffel(child, unwrap(argument), default = 24)] pub xcursor_size: u8, - #[knuffel(child)] pub hide_when_typing: bool, - #[knuffel(child, unwrap(argument))] pub hide_after_inactive_ms: Option, } @@ -36,6 +33,26 @@ impl Default for Cursor { } } +#[derive(knuffel::Decode, Debug, PartialEq)] +pub struct CursorPart { + #[knuffel(child, unwrap(argument))] + pub xcursor_theme: Option, + #[knuffel(child, unwrap(argument))] + pub xcursor_size: Option, + #[knuffel(child)] + pub hide_when_typing: Option, + #[knuffel(child, unwrap(argument))] + pub hide_after_inactive_ms: Option, +} + +impl MergeWith for Cursor { + fn merge_with(&mut self, part: &CursorPart) { + merge_clone!((self, part), xcursor_theme, xcursor_size); + merge!((self, part), hide_when_typing); + merge_clone_opt!((self, part), hide_after_inactive_ms); + } +} + #[derive(knuffel::Decode, Debug, Clone, PartialEq)] pub struct ScreenshotPath(#[knuffel(argument)] pub Option); @@ -47,46 +64,94 @@ impl Default for ScreenshotPath { } } -#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] pub struct HotkeyOverlay { - #[knuffel(child)] pub skip_at_startup: bool, - #[knuffel(child)] pub hide_not_bound: bool, } #[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq, Eq)] -pub struct ConfigNotification { +pub struct HotkeyOverlayPart { #[knuffel(child)] + pub skip_at_startup: Option, + #[knuffel(child)] + pub hide_not_bound: Option, +} + +impl MergeWith for HotkeyOverlay { + fn merge_with(&mut self, part: &HotkeyOverlayPart) { + merge!((self, part), skip_at_startup, hide_not_bound); + } +} + +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] +pub struct ConfigNotification { pub disable_failed: bool, } #[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq, Eq)] -pub struct Clipboard { +pub struct ConfigNotificationPart { #[knuffel(child)] + pub disable_failed: Option, +} + +impl MergeWith for ConfigNotification { + fn merge_with(&mut self, part: &ConfigNotificationPart) { + merge!((self, part), disable_failed); + } +} + +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] +pub struct Clipboard { pub disable_primary: bool, } -#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)] +#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq, Eq)] +pub struct ClipboardPart { + #[knuffel(child)] + pub disable_primary: Option, +} + +impl MergeWith for Clipboard { + fn merge_with(&mut self, part: &ClipboardPart) { + merge!((self, part), disable_primary); + } +} + +#[derive(Debug, Clone, Copy, PartialEq)] pub struct Overview { - #[knuffel(child, unwrap(argument), default = Self::default().zoom)] - pub zoom: FloatOrInt<0, 1>, - #[knuffel(child, default = Self::default().backdrop_color)] + pub zoom: f64, pub backdrop_color: Color, - #[knuffel(child, default)] pub workspace_shadow: WorkspaceShadow, } impl Default for Overview { fn default() -> Self { Self { - zoom: FloatOrInt(0.5), + zoom: 0.5, backdrop_color: DEFAULT_BACKDROP_COLOR, workspace_shadow: WorkspaceShadow::default(), } } } +#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)] +pub struct OverviewPart { + #[knuffel(child, unwrap(argument))] + pub zoom: Option>, + #[knuffel(child)] + pub backdrop_color: Option, + #[knuffel(child)] + pub workspace_shadow: Option, +} + +impl MergeWith for Overview { + fn merge_with(&mut self, part: &OverviewPart) { + merge!((self, part), zoom, workspace_shadow); + merge_clone!((self, part), backdrop_color); + } +} + #[derive(knuffel::Decode, Debug, Default, Clone, PartialEq, Eq)] pub struct Environment(#[knuffel(children)] pub Vec); @@ -98,11 +163,9 @@ pub struct EnvironmentVariable { pub value: Option, } -#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct XwaylandSatellite { - #[knuffel(child)] pub off: bool, - #[knuffel(child, unwrap(argument), default = Self::default().path)] pub path: String, } @@ -114,3 +177,24 @@ impl Default for XwaylandSatellite { } } } + +#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)] +pub struct XwaylandSatellitePart { + #[knuffel(child)] + pub off: bool, + #[knuffel(child)] + pub on: bool, + #[knuffel(child, unwrap(argument))] + pub path: Option, +} + +impl MergeWith for XwaylandSatellite { + fn merge_with(&mut self, part: &XwaylandSatellitePart) { + self.off |= part.off; + if part.on { + self.off = false; + } + + merge_clone!((self, part), path); + } +} diff --git a/src/layout/mod.rs b/src/layout/mod.rs index e60828d9..79da17b5 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -4916,7 +4916,7 @@ impl Default for MonitorSet { fn compute_overview_zoom(options: &Options, overview_progress: Option) -> f64 { // Clamp to some sane values. - let zoom = options.overview.zoom.0.clamp(0.0001, 0.75); + let zoom = options.overview.zoom.clamp(0.0001, 0.75); if let Some(p) = overview_progress { (1. - p * (1. - zoom)).max(0.0001)