Skip to content

Commit ca4258c

Browse files
FreddyFunkwash2
authored andcommitted
adapt UI feedback for the display number indicator and let it appear as a small square at the top of each monitor with the accent color
1 parent c9c62d0 commit ca4258c

File tree

2 files changed

+99
-27
lines changed

2 files changed

+99
-27
lines changed

src/components/app.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ pub enum OsdTask {
7373
Display,
7474
#[clap(about = "Show numbers on all displays for identification")]
7575
IdentifyDisplays,
76+
#[clap(about = "Dismiss display identification numbers")]
77+
DismissDisplayIdentifiers,
7678
#[clap(about = "Toggle the on screen display and start the log out timer")]
7779
LogOut,
7880
#[clap(about = "Toggle the on screen display and start the restart timer")]
@@ -122,6 +124,7 @@ impl OsdTask {
122124
OsdTask::Touchpad => Task::none(),
123125
OsdTask::Display => Task::none(),
124126
OsdTask::IdentifyDisplays => Task::none(),
127+
OsdTask::DismissDisplayIdentifiers => Task::none(),
125128
}
126129
}
127130
}
@@ -279,6 +282,7 @@ pub enum Msg {
279282
ActivationToken(Option<String>),
280283
DisplayIdentifierSurface((SurfaceId, osd_indicator::Msg)),
281284
CreateDisplayIdentifiers(Vec<(String, u32)>),
285+
DismissDisplayIdentifiers,
282286
OutputInfo(WlOutput, String),
283287
}
284288

@@ -786,6 +790,31 @@ impl cosmic::Application for App {
786790
}));
787791
}
788792

793+
Task::batch(tasks)
794+
}
795+
Msg::DismissDisplayIdentifiers => {
796+
let mut tasks = Vec::new();
797+
let ids_to_remove: Vec<SurfaceId> = self
798+
.surfaces
799+
.iter()
800+
.filter_map(|(id, surface)| {
801+
if let Surface::OsdIndicator(state) = surface {
802+
if matches!(state.params(), osd_indicator::Params::DisplayNumber(_)) {
803+
Some(*id)
804+
} else {
805+
None
806+
}
807+
} else {
808+
None
809+
}
810+
})
811+
.collect();
812+
813+
for id in ids_to_remove {
814+
self.surfaces.remove(&id);
815+
tasks.push(destroy_layer_surface(id));
816+
}
817+
789818
Task::batch(tasks)
790819
}
791820
}
@@ -901,6 +930,7 @@ impl cosmic::Application for App {
901930
OsdTask::Touchpad => "touchpad",
902931
OsdTask::Display => "external-display",
903932
OsdTask::IdentifyDisplays => "identify-displays",
933+
OsdTask::DismissDisplayIdentifiers => "dismiss-display-identifiers",
904934
};
905935

906936
let title = fl!(
@@ -1231,6 +1261,8 @@ impl cosmic::Application for App {
12311261
Msg::CreateDisplayIdentifiers(displays)
12321262
})
12331263
.map(cosmic::Action::App);
1264+
} else if let OsdTask::DismissDisplayIdentifiers = cmd {
1265+
return Task::done(cosmic::Action::App(Msg::DismissDisplayIdentifiers));
12341266
}
12351267

12361268
if let Some(prev) = self.action_to_confirm.take() {

src/components/osd_indicator.rs

Lines changed: 67 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use cosmic::{
66
Apply, Element, Task,
77
iced::{self, Alignment, Border, Length, window::Id as SurfaceId},
88
iced_runtime::platform_specific::wayland::layer_surface::{
9-
IcedOutput, SctkLayerSurfaceSettings,
9+
IcedMargin, IcedOutput, SctkLayerSurfaceSettings,
1010
},
1111
iced_winit::commands::{
1212
layer_surface::{
@@ -152,9 +152,30 @@ impl State {
152152

153153
let is_display_number = matches!(params, Params::DisplayNumber(_));
154154
let anchor = if is_display_number {
155-
Anchor::empty() // Center for display numbers
155+
Anchor::TOP
156156
} else {
157-
Anchor::BOTTOM // Bottom for other OSDs
157+
Anchor::BOTTOM
158+
};
159+
160+
// For display numbers, set exclusive_zone to -1 so they don't block input
161+
// in transparent areas. For other OSDs, use default behavior.
162+
let exclusive_zone = if is_display_number { -1 } else { 0 };
163+
let margin = if is_display_number {
164+
// Set top margin for display identifiers
165+
IcedMargin {
166+
top: 48,
167+
right: 0,
168+
bottom: 0,
169+
left: 0,
170+
}
171+
} else {
172+
// No margin for other OSDs (they use widget-based margins)
173+
IcedMargin {
174+
top: 0,
175+
right: 0,
176+
bottom: 0,
177+
left: 0,
178+
}
158179
};
159180

160181
cmds.push(get_layer_surface(SctkLayerSurfaceSettings {
@@ -165,30 +186,55 @@ impl State {
165186
size: None,
166187
anchor,
167188
output,
189+
exclusive_zone,
190+
margin,
168191
..Default::default()
169192
}));
170193

171194
cmds.push(overlap_notify(id, true));
172195

173-
let (cmd, timer_abort) = close_timer();
174-
cmds.push(cmd);
196+
// Display numbers don't auto-close, other OSDs do
197+
let timer_abort = if is_display_number {
198+
// Create a dummy abort handle that never triggers
199+
let (future, timer_abort) = abortable(async {
200+
std::future::pending::<()>().await
201+
});
202+
let _ = Task::perform(future, |_| Msg::Ignore);
203+
timer_abort
204+
} else {
205+
let (cmd, timer_abort) = close_timer();
206+
cmds.push(cmd);
207+
timer_abort
208+
};
175209

176210
let amplification_sink = config::amplification_sink();
177211
let amplification_source = config::amplification_source();
178212

213+
// Margin: (top, right, bottom, left)
214+
// Display numbers at top, other OSDs at bottom
215+
let margin = if is_display_number {
216+
(48, 0, 0, 0) // Top margin for display numbers
217+
} else {
218+
(0, 0, 48, 0) // Bottom margin for other OSDs
219+
};
220+
179221
(
180222
Self {
181223
id,
182224
params,
183225
timer_abort,
184-
margin: (0, 0, 48, 0),
226+
margin,
185227
amplification_sink,
186228
amplification_source,
187229
},
188230
Task::batch(cmds),
189231
)
190232
}
191233

234+
pub fn params(&self) -> &Params {
235+
&self.params
236+
}
237+
192238
// Re-use OSD surface to show a different OSD
193239
// Resets close timer
194240
pub fn replace_params(&mut self, params: Params) -> Task<Msg> {
@@ -323,47 +369,41 @@ impl State {
323369
let theme = cosmic::theme::active();
324370
let cosmic_theme = theme.cosmic();
325371

326-
// Large number display
327372
let number_text = widget::text::title1(format!("{}", display_number))
328-
.size(240)
373+
.size(80)
329374
.line_height(cosmic::iced::widget::text::LineHeight::Absolute(
330-
cosmic::iced::Pixels(240.0),
375+
cosmic::iced::Pixels(80.0),
331376
))
332377
.width(Length::Shrink)
333378
.align_x(Alignment::Center)
334379
.align_y(Alignment::Center);
335380

336381
let content = widget::container(number_text)
337-
.width(Length::Shrink)
338-
.height(Length::Shrink)
382+
.width(Length::Fill)
383+
.height(Length::Fill)
339384
.align_x(Alignment::Center)
340385
.align_y(Alignment::Center);
341386

342-
let vertical_padding = cosmic_theme.space_xxl() + cosmic_theme.space_l();
343-
let horizontal_padding = (80.0 + 1.5 * vertical_padding as f32) as u16;
387+
let padding = cosmic_theme.space_l();
388+
let square_size = 80.0 + (padding * 2) as f32;
344389

345390
let container = widget::container(content)
346-
.padding([
347-
vertical_padding, // top
348-
horizontal_padding, // right
349-
vertical_padding, // bottom
350-
horizontal_padding, // left
351-
])
352-
.width(Length::Shrink)
353-
.height(Length::Shrink)
391+
.padding(padding)
392+
.width(Length::Fixed(square_size))
393+
.height(Length::Fixed(square_size))
354394
.align_x(Alignment::Center)
355395
.align_y(Alignment::Center)
356396
.class(cosmic::theme::Container::custom(move |theme| {
357397
widget::container::Style {
358-
text_color: Some(theme.cosmic().on_bg_color().into()),
359-
background: Some(iced::Color::from(theme.cosmic().bg_color()).into()),
398+
text_color: Some(iced::Color::from(theme.cosmic().on_accent_color()).into()),
399+
background: Some(iced::Color::from(theme.cosmic().accent_color()).into()),
360400
border: Border {
361-
radius: theme.cosmic().radius_xl().into(),
362-
width: 2.0,
363-
color: theme.cosmic().accent_color().into(),
401+
radius: theme.cosmic().radius_m().into(),
402+
width: 0.0,
403+
color: iced::Color::TRANSPARENT,
364404
},
365405
shadow: Default::default(),
366-
icon_color: Some(theme.cosmic().on_bg_color().into()),
406+
icon_color: Some(iced::Color::from(theme.cosmic().on_accent_color()).into()),
367407
}
368408
}));
369409

0 commit comments

Comments
 (0)