Skip to content

Commit 5962d48

Browse files
committed
Tie aware mapping to prevent 10% jumps
1 parent 8dc3542 commit 5962d48

File tree

1 file changed

+75
-8
lines changed
  • cosmic-applet-battery/src

1 file changed

+75
-8
lines changed

cosmic-applet-battery/src/app.rs

Lines changed: 75 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ struct CosmicBatteryApplet {
9898
zbus_connection: Option<zbus::Connection>,
9999
dragging_screen_brightness: bool,
100100
dragging_kbd_brightness: bool,
101+
last_coarse_k: Option<i32>,
101102
}
102103

103104
impl CosmicBatteryApplet {
@@ -135,18 +136,62 @@ impl CosmicBatteryApplet {
135136
format!("cosmic-applet-battery-level-{battery_percent}-{limited}{charging}symbolic",);
136137
}
137138

139+
#[inline]
140+
fn raw_from_step_index(k: i32, max_raw: i32) -> i32 {
141+
// round(k * max / 20) using integer math
142+
((k * max_raw + 10) / 20)
143+
}
144+
145+
/// Resolve rung k for a given raw on coarse panels (max<=20) in a tie-aware way.
146+
/// If multiple rungs map to the same raw, use the last displayed rung to keep
147+
/// GUI steps monotonic in 5% increments (no 10% jumps).
148+
fn resolve_rung_tie_aware(&self, raw: i32, max_raw: i32) -> i32 {
149+
// Exact matches: all k s.t. forward map equals this raw
150+
let mut ks: Vec<i32> = (0..=20)
151+
.filter(|&k| Self::raw_from_step_index(k, max_raw) == raw)
152+
.collect();
153+
154+
if ks.is_empty() {
155+
// Fallback to nearest k
156+
let mut best_k = 0;
157+
let mut best_d = i32::MAX;
158+
for k in 0..=20 {
159+
let d = (Self::raw_from_step_index(k, max_raw) - raw).abs();
160+
if d < best_d {
161+
best_d = d;
162+
best_k = k;
163+
}
164+
}
165+
return best_k;
166+
}
167+
if ks.len() == 1 || self.last_coarse_k.is_none() {
168+
return ks[0];
169+
}
170+
171+
let prev = self.last_coarse_k.unwrap();
172+
let k_lo = ks[0];
173+
let k_hi = *ks.last().unwrap();
174+
// Entering tie from below -> lower first; from above -> higher first
175+
if prev < k_lo { return k_lo; }
176+
if prev == k_lo { return k_hi; } // stuck raw, next upward step
177+
if prev > k_hi { return k_hi; }
178+
if prev == k_hi { return k_lo; } // stuck raw, next downward step
179+
k_lo
180+
}
181+
182+
138183
fn screen_brightness_percent(&self) -> Option<f64> {
139-
let raw = self.screen_brightness? as i64;
140-
let max = self.max_screen_brightness?.max(1) as i64;
184+
let raw = self.screen_brightness? as i32;
185+
let max = self.max_screen_brightness?.max(1) as i32;
141186
if max <= 20 {
142-
// Matching brightness calculation logic from cosmic-osd and cosmic-settings-daemon
143-
let mut k = (raw * 20 + max / 2) / max;
144-
if k < 0 { k = 0; }
145-
if k > 20 { k = 20; }
187+
// TIE-AWARE: invert daemon setpoints with prev-k memory
188+
let k = self.resolve_rung_tie_aware(raw.max(0), max);
146189
let p = if k == 0 { 1 } else { 5 * k };
147-
Some((p as f64) / 100.0)
190+
Some(p as f64 / 100.0)
148191
} else {
149-
let p = ((raw * 100 + max / 2) / max).clamp(1, 100) as f64;
192+
// Fine panels: exact integer percent with 1% floor
193+
let p = (((raw as i64) * 100 + (max as i64) / 2) / (max as i64))
194+
.clamp(1, 100) as f64;
150195
Some(p / 100.0)
151196
}
152197
}
@@ -265,6 +310,15 @@ impl cosmic::Application for CosmicBatteryApplet {
265310
brightness
266311
};
267312
self.screen_brightness = Some(snapped);
313+
// Maintain tie-aware rung memory so GUI steps are 5% even if raw repeats
314+
if let Some(max) = self.max_screen_brightness {
315+
if max > 0 && max <= 20 {
316+
let k = self.resolve_rung_tie_aware(snapped.max(0), max.max(1));
317+
self.last_coarse_k = Some(k);
318+
} else {
319+
self.last_coarse_k = None;
320+
}
321+
}
268322
if !self.dragging_screen_brightness {
269323
self.dragging_screen_brightness = true;
270324
self.update_display();
@@ -484,11 +538,24 @@ impl cosmic::Application for CosmicBatteryApplet {
484538
}
485539
settings_daemon::Event::MaxDisplayBrightness(max_brightness) => {
486540
self.max_screen_brightness = Some(max_brightness);
541+
if max_brightness > 20 {
542+
// Fine panel: no tie memory needed
543+
self.last_coarse_k = None;
544+
}
487545
}
488546
settings_daemon::Event::DisplayBrightness(brightness) => {
489547
if !self.dragging_screen_brightness {
490548
self.screen_brightness = Some(brightness);
491549
}
550+
// Keep tie-aware rung memory in sync with daemon reports
551+
if let Some(max) = self.max_screen_brightness {
552+
if max <= 20 {
553+
let k = self.resolve_rung_tie_aware(brightness.max(0), max.max(1));
554+
self.last_coarse_k = Some(k);
555+
} else {
556+
self.last_coarse_k = None;
557+
}
558+
}
492559
}
493560
},
494561
Message::Surface(a) => {

0 commit comments

Comments
 (0)