[Bug] Fix COSMIC Time Applet Size to Prevent Applet Shifting in Panel
Issue/Description:
Currently, the COSMIC Time applet dynamically resizes when seconds are enabled, causing other applets in the panel to shift. This results in a distracting and inconsistent layout.
Version:
cosmic-applets:
Installed: 0.1.0~1741529755~24.04~f53e3bd
Steps to Reproduce:
- Add the COSMIC Time applet to the panel.
- Enable seconds in the time format.
- Observe how the panel's applets shift due to the changing width of the time display.
Proposed Solution:
- Use variable fixed width for time applet when seconds are toggled.
- When seconds are enabled it'll use more width but the width won't change when number changes
- When seconds are disabled it'll use less width & width won't change when number changes
Expected Behavior:
The COSMIC Time applet should have a fixed width that accommodates both the time format with and without seconds, ensuring that other panel elements remain stable.
This recent commit implementing widths for applets seems to have fixed this issue: https://github.com/pop-os/cosmic-applets/commit/61d1d1b91d8462bc169e70ff920b5f6850b0d85d
If I'm not wrong they're for applet pop-ups
Ah apologies, you're correct.
Are you still seeing the issue? I have tested using default fonts in various positions among the other applets and not observed any shifting.
I also do not observe any shifting
It only happens if font doesn't have tabular numbers (e.g. Poppins).
This can be solved if each digit has fixed container size & digit itself is centered inside that container. This would allow most of the fonts to render without changing applet size when variable font such as 7 or 8 occurs.
.digit-container {
display: inline-block;
width: 0.6em;
text-align: center;
}
This was attainable in CSS not sure how it works in libcosmic or cosmic-text
Do you know of a few fonts to test this with?
I'm aesthetically challenged. I clicked through 30 fonts without finding one to replicate. 😅
I tried it on Poppins but many pre-installed non mono fonts also does it
Yeah I managed to replicate by installing poppins and setting that as the main font. I was unable to find a clean way to resolve the issue.
Alright. Thanks for the confirmation from both of you. I have an idea for a solution to this issue, but I may have to mess with it after the weekend.
The way I fixed this in my applet was to first measure the "worst case/widest string that could be shown". It seems other toolkits have measurement functions, like QT:
QFontMetrics metrics(font);
int width = metrics.horizontalAdvance("Hello");
For my purpose I implemented below, not sure if there's a better way:
fn measure_text_width(&mut self, text: &str, attrs: &Attrs) -> Option<f32> {
let font_size = self.label_font_size();
let metrics = Metrics::new(font_size.into(), font_size.into());
// Create a buffer to shape the text
let mut buffer = Buffer::new(&mut self.font_system, metrics);
buffer.set_text(&mut self.font_system, text, attrs, Shaping::Advanced);
// Get the width of the first layout line
buffer
.lines
.first()
.and_then(|line| line.layout_opt())
.and_then(|layouts| layouts.first().map(|layout| layout.w.ceil()))
}
Then for example for seconds measure widest possibility, such as ":88", then create a widget with that fixed width and Left/Center/Right justify as desired.
widget::text(seconds)
.size(size)
.width(w)
.wrapping(iced::core::text::Wrapping::None)
.align_x(Horizontal::Left)
Thus avoiding forcing a specific font. It does require listening to font configuration changes and redo the measurement if the user changes font settings. I suppose it could also be used on individual digits to emulate tabular digits with a text widget per digit, as suggested.