diff --git a/applet/src/lib.rs b/applet/src/lib.rs index 146261f9..c1825694 100644 --- a/applet/src/lib.rs +++ b/applet/src/lib.rs @@ -120,7 +120,9 @@ impl CosmicAppletHelper { resizable: None, ..Default::default() }), - ..cosmic::settings_with_flags(flags) + default_text_size: 18.0, + default_font: cosmic::font::FONT, + ..Settings::with_flags(flags) } } diff --git a/cosmic-app-list/data/icons/com.system76.CosmicAppList-symbolic.svg b/cosmic-app-list/data/icons/com.system76.CosmicAppList-symbolic.svg deleted file mode 100644 index fc4d934e..00000000 --- a/cosmic-app-list/data/icons/com.system76.CosmicAppList-symbolic.svg +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/cosmic-app-list/data/icons/com.system76.CosmicAppList.Devel.svg b/cosmic-app-list/data/icons/com.system76.CosmicAppList.Devel.svg deleted file mode 100644 index 92533ae1..00000000 --- a/cosmic-app-list/data/icons/com.system76.CosmicAppList.Devel.svg +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/cosmic-app-list/data/icons/com.system76.CosmicAppList.svg b/cosmic-app-list/data/icons/scalable/apps/com.system76.CosmicAppList.svg similarity index 100% rename from cosmic-app-list/data/icons/com.system76.CosmicAppList.svg rename to cosmic-app-list/data/icons/scalable/apps/com.system76.CosmicAppList.svg diff --git a/cosmic-applet-audio/data/icons/com.system76.CosmicAppletAudio.svg b/cosmic-applet-audio/data/icons/scalable/apps/com.system76.CosmicAppletAudio.svg similarity index 100% rename from cosmic-applet-audio/data/icons/com.system76.CosmicAppletAudio.svg rename to cosmic-applet-audio/data/icons/scalable/apps/com.system76.CosmicAppletAudio.svg diff --git a/cosmic-applet-audio/src/main.rs b/cosmic-applet-audio/src/main.rs index 757b10b6..1d4a7668 100644 --- a/cosmic-applet-audio/src/main.rs +++ b/cosmic-applet-audio/src/main.rs @@ -49,6 +49,7 @@ struct Audio { pulse_state: PulseState, applet_helper: CosmicAppletHelper, icon_name: String, + input_icon_name: String, theme: Theme, popup: Option, show_media_controls_in_top_panel: bool, @@ -56,6 +57,58 @@ struct Audio { timeline: Timeline, } +impl Audio { + fn update_output(&mut self, output: Option) { + self.current_output = output; + self.apply_output_volume(); + } + + fn apply_output_volume(&mut self) { + let Some(output) = self.current_output.as_ref() else { + self.icon_name = "audio-volume-muted-symbolic".to_string(); + return; + }; + + let volume = output.volume.avg(); + let output_volume = VolumeLinear::from(volume).0; + if volume.is_muted() { + self.icon_name = "audio-volume-muted-symbolic".to_string(); + } else if output_volume < 0.25 { + self.icon_name = "audio-volume-low-symbolic".to_string(); + } else if output_volume < 0.5 { + self.icon_name = "audio-volume-medium-symbolic".to_string(); + } else if output_volume < 0.75 { + self.icon_name = "audio-volume-high-symbolic".to_string(); + } else { + self.icon_name = "audio-volume-overamplified-symbolic".to_string(); + } + } + + fn update_input(&mut self, input: Option) { + self.current_input = input; + self.apply_input_volume(); + } + + fn apply_input_volume(&mut self) { + let Some(input) = self.current_input.as_ref() else { + self.input_icon_name = "microphone-sensitivity-muted-symbolic".to_string(); + return; + }; + + let volume = input.volume.avg(); + let input_volume = VolumeLinear::from(volume).0; + if volume.is_muted() { + self.input_icon_name = "microphone-sensitivity-muted-symbolic".to_string(); + } else if input_volume < 0.33 { + self.input_icon_name = "microphone-sensitivity-low-symbolic".to_string(); + } else if input_volume < 0.66 { + self.input_icon_name = "microphone-sensitivity-medium-symbolic".to_string(); + } else { + self.input_icon_name = "microphone-sensitivity-high-symbolic".to_string(); + } + } +} + #[derive(Debug, PartialEq, Eq)] enum IsOpen { None, @@ -96,6 +149,7 @@ impl Application for Audio { outputs: vec![], inputs: vec![], icon_name: "audio-volume-high-symbolic".to_string(), + input_icon_name: "audio-input-microphone-symbolic".to_string(), applet_helper, theme, ..Default::default() @@ -165,6 +219,7 @@ impl Application for Audio { o.volume .set(o.volume.len(), VolumeLinear(vol / 100.0).into()) }); + self.apply_output_volume(); if let PulseState::Connected(connection) = &mut self.pulse_state { if let Some(device) = &self.current_output { if let Some(name) = &device.name { @@ -181,6 +236,7 @@ impl Application for Audio { i.volume .set(i.volume.len(), VolumeLinear(vol / 100.0).into()) }); + self.apply_input_volume(); if let PulseState::Connected(connection) = &mut self.pulse_state { if let Some(device) = &self.current_input { if let Some(name) = &device.name { @@ -256,10 +312,10 @@ impl Application for Audio { .collect() } pulse::Message::SetDefaultSink(sink) => { - self.current_output = Some(sink); + self.update_output(Some(sink)); } pulse::Message::SetDefaultSource(source) => { - self.current_input = Some(source) + self.update_input(Some(source)); } pulse::Message::Disconnected => { panic!("Subscriton error handling is bad. This should never happen.") @@ -325,7 +381,7 @@ impl Application for Audio { } else { column![ row![ - icon("audio-volume-high-symbolic", 24).style(Svg::Symbolic), + icon(self.icon_name.as_str(), 24).style(Svg::Symbolic), slider(0.0..=100.0, out_f64, Message::SetOutputVolume) .width(Length::FillPortion(5)), text(format!("{}%", out_f64.round())) @@ -337,7 +393,7 @@ impl Application for Audio { .align_items(Alignment::Center) .padding([8, 24]), row![ - icon("audio-input-microphone-symbolic", 24).style(Svg::Symbolic), + icon(self.input_icon_name.as_str(), 24).style(Svg::Symbolic), slider(0.0..=100.0, in_f64, Message::SetInputVolume) .width(Length::FillPortion(5)), text(format!("{}%", in_f64.round())) diff --git a/cosmic-applet-battery/data/icons/com.system76.CosmicAppletBattery.svg b/cosmic-applet-battery/data/icons/scalable/apps/com.system76.CosmicAppletBattery.svg similarity index 100% rename from cosmic-applet-battery/data/icons/com.system76.CosmicAppletBattery.svg rename to cosmic-applet-battery/data/icons/scalable/apps/com.system76.CosmicAppletBattery.svg diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-display-brightness-high-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-display-brightness-high-symbolic.svg new file mode 100644 index 00000000..3f3ed33a --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-display-brightness-high-symbolic.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-display-brightness-low-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-display-brightness-low-symbolic.svg new file mode 100644 index 00000000..7be46da1 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-display-brightness-low-symbolic.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-display-brightness-medium-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-display-brightness-medium-symbolic.svg new file mode 100644 index 00000000..927cc51b --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-display-brightness-medium-symbolic.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-display-brightness-off-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-display-brightness-off-symbolic.svg new file mode 100644 index 00000000..31db770b --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-display-brightness-off-symbolic.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-0-charging-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-0-charging-symbolic.svg new file mode 100644 index 00000000..741df7bd --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-0-charging-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-0-limited-charging-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-0-limited-charging-symbolic.svg new file mode 100644 index 00000000..ff9c0982 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-0-limited-charging-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-0-limited-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-0-limited-symbolic.svg new file mode 100644 index 00000000..9778f655 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-0-limited-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-0-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-0-symbolic.svg new file mode 100644 index 00000000..d08c5905 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-0-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-10-charging-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-10-charging-symbolic.svg new file mode 100644 index 00000000..20007829 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-10-charging-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-10-limited-charging-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-10-limited-charging-symbolic.svg new file mode 100644 index 00000000..20ff0370 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-10-limited-charging-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-10-limited-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-10-limited-symbolic.svg new file mode 100644 index 00000000..13d3ac9a --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-10-limited-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-10-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-10-symbolic.svg new file mode 100644 index 00000000..ed0d46bc --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-10-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-100-charging-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-100-charging-symbolic.svg new file mode 100644 index 00000000..ce5da7fb --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-100-charging-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-100-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-100-symbolic.svg new file mode 100644 index 00000000..98d2a145 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-100-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-20-charging-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-20-charging-symbolic.svg new file mode 100644 index 00000000..a1d7c593 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-20-charging-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-20-limited-charging-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-20-limited-charging-symbolic.svg new file mode 100644 index 00000000..461bfe50 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-20-limited-charging-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-20-limited-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-20-limited-symbolic.svg new file mode 100644 index 00000000..ed041168 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-20-limited-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-20-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-20-symbolic.svg new file mode 100644 index 00000000..f6fb0c6f --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-20-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-35-charging-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-35-charging-symbolic.svg new file mode 100644 index 00000000..a16368e6 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-35-charging-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-35-limited-charging-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-35-limited-charging-symbolic.svg new file mode 100644 index 00000000..985e48c9 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-35-limited-charging-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-35-limited-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-35-limited-symbolic.svg new file mode 100644 index 00000000..dc5ecc75 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-35-limited-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-35-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-35-symbolic.svg new file mode 100644 index 00000000..a0e18955 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-35-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-5-charging-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-5-charging-symbolic.svg new file mode 100644 index 00000000..20007829 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-5-charging-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-5-limited-charging-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-5-limited-charging-symbolic.svg new file mode 100644 index 00000000..20ff0370 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-5-limited-charging-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-5-limited-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-5-limited-symbolic.svg new file mode 100644 index 00000000..0563ed74 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-5-limited-symbolic.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-5-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-5-symbolic.svg new file mode 100644 index 00000000..8a22b5c2 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-5-symbolic.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-50-charging-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-50-charging-symbolic.svg new file mode 100644 index 00000000..a8c450cf --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-50-charging-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-50-limited-charging-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-50-limited-charging-symbolic.svg new file mode 100644 index 00000000..797f4d8f --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-50-limited-charging-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-50-limited-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-50-limited-symbolic.svg new file mode 100644 index 00000000..08f6a1f3 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-50-limited-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-50-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-50-symbolic.svg new file mode 100644 index 00000000..8d4832ec --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-50-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-65-charging-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-65-charging-symbolic.svg new file mode 100644 index 00000000..abc2f8cb --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-65-charging-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-65-limited-charging-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-65-limited-charging-symbolic.svg new file mode 100644 index 00000000..f8352c0a --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-65-limited-charging-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-65-limited-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-65-limited-symbolic.svg new file mode 100644 index 00000000..43856f75 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-65-limited-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-65-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-65-symbolic.svg new file mode 100644 index 00000000..cd0b042d --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-65-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-80-charging-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-80-charging-symbolic.svg new file mode 100644 index 00000000..7f48912c --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-80-charging-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-80-limited-charging-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-80-limited-charging-symbolic.svg new file mode 100644 index 00000000..6b94cc19 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-80-limited-charging-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-80-limited-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-80-limited-symbolic.svg new file mode 100644 index 00000000..fd8decf8 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-80-limited-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-80-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-80-symbolic.svg new file mode 100644 index 00000000..d934e936 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-80-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-90-charging-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-90-charging-symbolic.svg new file mode 100644 index 00000000..8af91315 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-90-charging-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-90-symbolic.svg b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-90-symbolic.svg new file mode 100644 index 00000000..7029c609 --- /dev/null +++ b/cosmic-applet-battery/data/icons/scalable/status/cosmic-applet-battery-level-90-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/cosmic-applet-battery/src/app.rs b/cosmic-applet-battery/src/app.rs index 1dcda59f..e22f64f5 100644 --- a/cosmic-applet-battery/src/app.rs +++ b/cosmic-applet-battery/src/app.rs @@ -55,9 +55,11 @@ static MAX_CHARGE: Lazy = Lazy::new(id::Toggler::unique); #[derive(Clone, Default)] struct CosmicBatteryApplet { icon_name: String, + display_icon_name: String, theme: Theme, charging_limit: bool, battery_percent: f64, + on_battery: bool, time_remaining: Duration, kbd_brightness: f64, screen_brightness: f64, @@ -71,11 +73,65 @@ struct CosmicBatteryApplet { timeline: Timeline, } +impl CosmicBatteryApplet { + fn update_battery(&mut self, mut percent: f64, on_battery: bool) { + percent = percent.clamp(0.0, 100.0); + self.on_battery = on_battery; + self.battery_percent = percent; + let battery_percent = if self.battery_percent > 95.0 && !self.charging_limit { + 100 + } else if self.battery_percent > 80.0 && !self.charging_limit { + 90 + } else if self.battery_percent > 65.0 { + 80 + } else if self.battery_percent > 35.0 { + 50 + } else if self.battery_percent > 20.0 { + 35 + } else if self.battery_percent > 14.0 { + 20 + } else if self.battery_percent > 9.0 { + 10 + } else if self.battery_percent > 5.0 { + 5 + } else { + 0 + }; + let limited = if self.charging_limit { "limited-" } else { "" }; + let charging = if on_battery { "" } else { "charging-" }; + self.icon_name = + format!("cosmic-applet-battery-level-{battery_percent}-{limited}{charging}symbolic",); + } + + fn update_display(&mut self, mut percent: f64) { + percent = percent.clamp(0.01, 1.0); + self.screen_brightness = percent; + let screen_brightness = if self.screen_brightness < 0.011 { + "off" + } else if self.screen_brightness < 0.333 { + "low" + } else if self.screen_brightness < 0.666 { + "medium" + } else { + "high" + } + .to_string(); + + self.display_icon_name = + format!("cosmic-applet-battery-display-brightness-{screen_brightness}-symbolic",); + } + + fn set_charging_limit(&mut self, limit: bool) { + self.charging_limit = limit; + self.update_battery(self.battery_percent, self.on_battery); + } +} + #[derive(Debug, Clone)] enum Message { TogglePopup, Update { - icon_name: String, + on_battery: bool, percent: f64, time_to_empty: i64, }, @@ -108,6 +164,7 @@ impl Application for CosmicBatteryApplet { ( CosmicBatteryApplet { icon_name: "battery-symbolic".to_string(), + display_icon_name: "display-brightness-symbolic".to_string(), applet_helper, theme, ..Default::default() @@ -130,14 +187,14 @@ impl Application for CosmicBatteryApplet { } } Message::SetScreenBrightness(brightness) => { - self.screen_brightness = (brightness as f64 / 100.0).clamp(0.01, 1.0); + self.update_display((brightness as f64 / 100.0).clamp(0.01, 1.0)); if let Some(tx) = &self.screen_sender { let _ = tx.send(ScreenBacklightRequest::Set(self.screen_brightness)); } } Message::SetChargingLimit(chain, enable) => { self.timeline.set_chain(chain).start(); - self.charging_limit = enable; + self.set_charging_limit(enable); } Message::OpenBatterySettings => { // TODO Ashley @@ -179,12 +236,11 @@ impl Application for CosmicBatteryApplet { } } Message::Update { - icon_name, + on_battery, percent, time_to_empty, } => { - self.icon_name = icon_name; - self.battery_percent = percent; + self.update_battery(percent, on_battery); self.time_remaining = Duration::from_secs(time_to_empty as u64); } Message::UpdateKbdBrightness(b) => { @@ -199,10 +255,10 @@ impl Application for CosmicBatteryApplet { Message::InitScreenBacklight(tx, brightness) => { let _ = tx.send(ScreenBacklightRequest::Get); self.screen_sender = Some(tx); - self.screen_brightness = brightness; + self.update_display(brightness); } Message::UpdateScreenBrightness(b) => { - self.screen_brightness = b; + self.update_display(b); } Message::InitProfile(tx, profile) => { self.power_profile_sender.replace(tx); @@ -236,20 +292,16 @@ impl Application for CosmicBatteryApplet { .into() } else { let name = text(fl!("battery")).size(14); - let description = text( - if "battery-full-charging-symbolic" == self.icon_name - || "battery-full-charged-symbolic" == self.icon_name - { - format!("{}%", self.battery_percent) - } else { - format!( - "{} {} ({:.0}%)", - format_duration(self.time_remaining), - fl!("until-empty"), - self.battery_percent - ) - }, - ) + let description = text(if !self.on_battery { + format!("{}%", self.battery_percent) + } else { + format!( + "{} {} ({:.0}%)", + format_duration(self.time_remaining), + fl!("until-empty"), + self.battery_percent + ) + }) .size(10); self.applet_helper .popup_container( @@ -342,7 +394,7 @@ impl Application for CosmicBatteryApplet { .width(Length::Fill) .padding([0, 12]), row![ - icon("display-brightness-symbolic", 24).style(Svg::Symbolic), + icon(self.display_icon_name.as_str(), 24).style(Svg::Symbolic), slider( 1..=100, (self.screen_brightness * 100.0) as i32, @@ -393,11 +445,11 @@ impl Application for CosmicBatteryApplet { self.applet_helper.theme_subscription(0).map(Message::Theme), device_subscription(0).map( |DeviceDbusEvent::Update { - icon_name, + on_battery, percent, time_to_empty, }| Message::Update { - icon_name, + on_battery, percent, time_to_empty, }, diff --git a/cosmic-applet-battery/src/upower_device.rs b/cosmic-applet-battery/src/upower_device.rs index 48ceaa96..cf4d0050 100644 --- a/cosmic-applet-battery/src/upower_device.rs +++ b/cosmic-applet-battery/src/upower_device.rs @@ -168,19 +168,20 @@ pub fn device_subscription( #[derive(Debug)] pub enum State { Ready, - Waiting(DeviceProxy<'static>), + Waiting(UPowerProxy<'static>, DeviceProxy<'static>), Finished, } -async fn display_device() -> zbus::Result> { +async fn display_device() -> zbus::Result<(UPowerProxy<'static>, DeviceProxy<'static>)> { let connection = zbus::Connection::system().await?; - let upower = UPowerProxy::new(&connection).await?; + let upower: UPowerProxy<'_> = UPowerProxy::new(&connection).await?; let device_path = upower.get_display_device().await?; DeviceProxy::builder(&connection) .path(device_path)? .cache_properties(zbus::CacheProperties::Yes) .build() .await + .map(|dp| (upower, dp)) } async fn start_listening( @@ -189,11 +190,11 @@ async fn start_listening( ) -> State { match state { State::Ready => { - if let Ok(device) = display_device().await { + if let Ok((upower, device)) = display_device().await { _ = output .send(DeviceDbusEvent::Update { - icon_name: device - .cached_icon_name() + on_battery: upower + .cached_on_battery() .unwrap_or_default() .unwrap_or_default(), percent: device @@ -206,13 +207,13 @@ async fn start_listening( .unwrap_or_default(), }) .await; - return State::Waiting(device); + return State::Waiting(upower, device); } State::Finished } - State::Waiting(device) => { + State::Waiting(upower, device) => { let mut stream = futures::stream_select!( - device.receive_icon_name_changed().await.map(|_| ()), + upower.receive_on_battery_changed().await.map(|_| ()), device.receive_percentage_changed().await.map(|_| ()), device.receive_time_to_empty_changed().await.map(|_| ()), ); @@ -220,8 +221,8 @@ async fn start_listening( Some(_) => { _ = output .send(DeviceDbusEvent::Update { - icon_name: device - .cached_icon_name() + on_battery: upower + .cached_on_battery() .unwrap_or_default() .unwrap_or_default(), percent: device @@ -235,7 +236,7 @@ async fn start_listening( }) .await; - State::Waiting(device) + State::Waiting(upower, device) } None => State::Finished, } @@ -247,7 +248,7 @@ async fn start_listening( #[derive(Debug, Clone)] pub enum DeviceDbusEvent { Update { - icon_name: String, + on_battery: bool, percent: f64, time_to_empty: i64, }, diff --git a/cosmic-applet-bluetooth/data/icons/com.system76.CosmicAppletBluetooth.svg b/cosmic-applet-bluetooth/data/icons/scalable/apps/com.system76.CosmicAppletBluetooth.svg similarity index 100% rename from cosmic-applet-bluetooth/data/icons/com.system76.CosmicAppletBluetooth.svg rename to cosmic-applet-bluetooth/data/icons/scalable/apps/com.system76.CosmicAppletBluetooth.svg diff --git a/cosmic-applet-bluetooth/data/icons/scalable/status/cosmic-applet-bluetooth-active-symbolic.svg b/cosmic-applet-bluetooth/data/icons/scalable/status/cosmic-applet-bluetooth-active-symbolic.svg new file mode 100644 index 00000000..e5b4adb8 --- /dev/null +++ b/cosmic-applet-bluetooth/data/icons/scalable/status/cosmic-applet-bluetooth-active-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cosmic-applet-bluetooth/data/icons/scalable/status/cosmic-applet-bluetooth-disabled-symbolic.svg b/cosmic-applet-bluetooth/data/icons/scalable/status/cosmic-applet-bluetooth-disabled-symbolic.svg new file mode 100644 index 00000000..e67b7d2f --- /dev/null +++ b/cosmic-applet-bluetooth/data/icons/scalable/status/cosmic-applet-bluetooth-disabled-symbolic.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/cosmic-applet-bluetooth/src/app.rs b/cosmic-applet-bluetooth/src/app.rs index 367749f7..2510f8f8 100644 --- a/cosmic-applet-bluetooth/src/app.rs +++ b/cosmic-applet-bluetooth/src/app.rs @@ -43,11 +43,21 @@ struct CosmicBluetoothApplet { request_confirmation: Option<(BluerDevice, String, Sender)>, } +impl CosmicBluetoothApplet { + fn update_icon(&mut self) { + self.icon_name = if self.bluer_state.bluetooth_enabled { + "cosmic-applet-bluetooth-active-symbolic" + } else { + "cosmic-applet-bluetooth-disabled-symbolic" + } + .to_string(); + } +} + #[derive(Debug, Clone)] enum Message { TogglePopup, ToggleVisibleDevices(bool), - Errored(String), Ignore, BluetoothEvent(BluerEvent), Request(BluerRequest), @@ -118,7 +128,6 @@ impl Application for CosmicBluetoothApplet { ]); } } - Message::Errored(_) => todo!(), Message::Ignore => {} Message::ToggleVisibleDevices(enabled) => { self.show_visible_devices = enabled; @@ -165,29 +174,19 @@ impl Application for CosmicBluetoothApplet { } // TODO handle agent events BluerEvent::AgentEvent(event) => match event { - crate::bluetooth::BluerAgentEvent::DisplayPinCode(_d, _code) => { - // dbg!((d.name, code)); - } - crate::bluetooth::BluerAgentEvent::DisplayPasskey(_d, _code) => { - // dbg!((d.name, code)); - } + crate::bluetooth::BluerAgentEvent::DisplayPinCode(_d, _code) => {} + crate::bluetooth::BluerAgentEvent::DisplayPasskey(_d, _code) => {} crate::bluetooth::BluerAgentEvent::RequestPinCode(_d) => { // TODO anything to be done here? - // dbg!("request pin code", d.name); } crate::bluetooth::BluerAgentEvent::RequestPasskey(_d) => { // TODO anything to be done here? - // dbg!("request passkey", d.name); } crate::bluetooth::BluerAgentEvent::RequestConfirmation(d, code, tx) => { - // dbg!("request confirmation", &d.name, &code); self.request_confirmation.replace((d, code, tx)); - // let _ = tx.send(false); } crate::bluetooth::BluerAgentEvent::RequestDeviceAuthorization(_d, _tx) => { // TODO anything to be done here? - // dbg!("request device authorization", d.name); - // let_ = tx.send(false); } crate::bluetooth::BluerAgentEvent::RequestServiceAuthorization( _d, @@ -276,6 +275,7 @@ impl Application for CosmicBluetoothApplet { self.theme = t; } } + self.update_icon(); Command::none() } fn view(&self, id: window::Id) -> Element { diff --git a/cosmic-applet-graphics/data/icons/com.system76.CosmicAppletGraphics.svg b/cosmic-applet-graphics/data/icons/scalable/apps/com.system76.CosmicAppletGraphics.svg similarity index 100% rename from cosmic-applet-graphics/data/icons/com.system76.CosmicAppletGraphics.svg rename to cosmic-applet-graphics/data/icons/scalable/apps/com.system76.CosmicAppletGraphics.svg diff --git a/cosmic-applet-graphics/src/window.rs b/cosmic-applet-graphics/src/window.rs index 3941014e..388921f5 100644 --- a/cosmic-applet-graphics/src/window.rs +++ b/cosmic-applet-graphics/src/window.rs @@ -20,6 +20,8 @@ use cosmic::{ use cosmic_applet::{applet_button_theme, cosmic_panel_config::PanelAnchor, CosmicAppletHelper}; use zbus::Connection; +const ID: &str = "com.system76.CosmicAppletGraphics"; + #[derive(Clone, Copy)] enum GraphicsMode { AppliedGraphicsMode(Graphics), @@ -198,17 +200,13 @@ impl Application for Window { match self.applet_helper.anchor { PanelAnchor::Left | PanelAnchor::Right => self .applet_helper - .icon_button("input-gaming-symbolic") + .icon_button(ID) .on_press(Message::TogglePopup) .style(Button::Text) .into(), PanelAnchor::Top | PanelAnchor::Bottom => button(Button::Text) .custom(vec![row![ - icon( - "input-gaming-symbolic", - self.applet_helper.suggested_size().0, - ) - .style(Svg::Symbolic), + icon(ID, self.applet_helper.suggested_size().0,).style(Svg::Symbolic), text(match self.graphics_mode.map(|g| g.inner()) { Some(Graphics::Integrated) => fl!("integrated"), Some(Graphics::Nvidia) => fl!("nvidia"), diff --git a/cosmic-applet-network/data/icons/com.system76.CosmicAppletNetwork.svg b/cosmic-applet-network/data/icons/scalable/apps/com.system76.CosmicAppletNetwork.svg similarity index 100% rename from cosmic-applet-network/data/icons/com.system76.CosmicAppletNetwork.svg rename to cosmic-applet-network/data/icons/scalable/apps/com.system76.CosmicAppletNetwork.svg diff --git a/cosmic-applet-network/i18n/en/cosmic_applet_network.ftl b/cosmic-applet-network/i18n/en/cosmic_applet_network.ftl index bc32c84f..92edbda1 100644 --- a/cosmic-applet-network/i18n/en/cosmic_applet_network.ftl +++ b/cosmic-applet-network/i18n/en/cosmic_applet_network.ftl @@ -1,5 +1,7 @@ network = Network airplane-mode = Airplane mode +airplane-mode-on = Airplane Mode is on +turn-off-airplane-mode = Turn on to enable Wi-Fi, Bluetooth and mobile broadband. wifi = Wi-Fi ipv4 = IPv4 Address ipv6 = IPv6 Address diff --git a/cosmic-applet-network/src/app.rs b/cosmic-applet-network/src/app.rs index f3df9032..e0b8e4ee 100644 --- a/cosmic-applet-network/src/app.rs +++ b/cosmic-applet-network/src/app.rs @@ -95,9 +95,28 @@ struct CosmicNetworkApplet { new_connection: Option, conn: Option, timeline: Timeline, + toggle_wifi_ctr: u128, +} + +fn wifi_icon(strength: u8) -> &'static str { + if strength < 25 { + "network-wireless-signal-weak-symbolic" + } else if strength < 50 { + "network-wireless-signal-ok-symbolic" + } else if strength < 75 { + "network-wireless-signal-good-symbolic" + } else { + "network-wireless-signal-excellent-symbolic" + } } impl CosmicNetworkApplet { + fn update_nm_state(&mut self, new_state: NetworkManagerState) { + self.update_togglers(&new_state); + self.nm_state = new_state; + self.update_icon_name(); + } + fn update_icon_name(&mut self) { self.icon_name = self .nm_state @@ -105,11 +124,12 @@ impl CosmicNetworkApplet { .iter() .fold("network-offline-symbolic", |icon_name, conn| { match (icon_name, conn) { - ("network-offline-symbolic", ActiveConnectionInfo::WiFi { .. }) => { - "network-wireless-symbolic" + ("network-offline-symbolic", ActiveConnectionInfo::WiFi { strength, .. }) => { + wifi_icon(*strength) } - ("network-offline-symbolic", ActiveConnectionInfo::Wired { .. }) - | ("network-wireless-symbolic", ActiveConnectionInfo::Wired { .. }) => { + (_, ActiveConnectionInfo::Wired { .. }) + if icon_name != "network-vpn-symbolic" => + { "network-wired-symbolic" } (_, ActiveConnectionInfo::Vpn { .. }) => "network-vpn-symbolic", @@ -121,7 +141,9 @@ impl CosmicNetworkApplet { fn update_togglers(&mut self, state: &NetworkManagerState) { let timeline = &mut self.timeline; + let mut changed = false; if state.wifi_enabled != self.nm_state.wifi_enabled { + changed = true; let chain = if state.wifi_enabled { chain::Toggler::on(WIFI.clone(), 1.) } else { @@ -131,6 +153,7 @@ impl CosmicNetworkApplet { }; if state.airplane_mode != self.nm_state.airplane_mode { + changed = true; let chain = if state.airplane_mode { chain::Toggler::on(AIRPLANE_MODE.clone(), 1.) } else { @@ -138,8 +161,9 @@ impl CosmicNetworkApplet { }; timeline.set_chain(chain); }; - - timeline.start(); + if changed { + timeline.start(); + } } } @@ -221,11 +245,14 @@ impl Application for CosmicNetworkApplet { // Message::Errored(_) => todo!(), Message::Ignore => {} Message::ToggleAirplaneMode(enabled) => { + self.toggle_wifi_ctr += 1; if let Some(tx) = self.nm_sender.as_mut() { let _ = tx.unbounded_send(NetworkManagerRequest::SetAirplaneMode(enabled)); } } Message::ToggleWiFi(enabled) => { + self.toggle_wifi_ctr += 1; + if let Some(tx) = self.nm_sender.as_mut() { let _ = tx.unbounded_send(NetworkManagerRequest::SetWiFi(enabled)); } @@ -237,20 +264,13 @@ impl Application for CosmicNetworkApplet { state, } => { self.nm_sender.replace(sender); - self.update_togglers(&state); - self.nm_state = state; - self.update_icon_name(); + self.update_nm_state(state); self.conn = Some(conn); } - NetworkManagerEvent::WiFiEnabled(state) => { - self.nm_state = state; - } - NetworkManagerEvent::WirelessAccessPoints(state) => { - self.nm_state = state; - } - NetworkManagerEvent::ActiveConns(state) => { - self.nm_state = state; - self.update_icon_name(); + NetworkManagerEvent::WiFiEnabled(state) + | NetworkManagerEvent::WirelessAccessPoints(state) + | NetworkManagerEvent::ActiveConns(state) => { + self.update_nm_state(state); } NetworkManagerEvent::RequestResponse { state, @@ -264,21 +284,19 @@ impl Application for CosmicNetworkApplet { if self .new_connection .as_ref() - .map(|c| c.ssid() == ssid) + .map(|c| c.ssid() != ssid) .unwrap_or_default() { self.new_connection = None; } } - if success { - self.update_togglers(&state); - } else { + if !success { match req { NetworkManagerRequest::Password(_, _) => { - if let Some(NewConnectionState::EnterPassword { - access_point, - .. - }) = self.new_connection.as_ref() + if let Some( + NewConnectionState::EnterPassword { access_point, .. } + | NewConnectionState::Waiting(access_point), + ) = self.new_connection.as_ref() { self.new_connection .replace(NewConnectionState::Failure(access_point.clone())); @@ -287,8 +305,7 @@ impl Application for CosmicNetworkApplet { _ => {} } } - self.nm_state = state; - self.update_icon_name(); + self.update_nm_state(state); } }, Message::SelectWirelessAccessPoint(access_point) => { @@ -443,6 +460,7 @@ impl Application for CosmicNetworkApplet { name, ip_addresses, state, + strength, .. } => { let mut ipv4 = Vec::with_capacity(ip_addresses.len()); @@ -454,9 +472,7 @@ impl Application for CosmicNetworkApplet { ); } let mut btn_content = vec![ - icon("network-wireless-symbolic", 24) - .style(Svg::Symbolic) - .into(), + icon(wifi_icon(*strength), 24).style(Svg::Symbolic).into(), column![text(name).size(14), Column::with_children(ipv4)] .width(Length::Fill) .into(), @@ -493,43 +509,6 @@ impl Application for CosmicNetworkApplet { } }; } - for known in &self.nm_state.known_access_points { - let mut btn_content = vec![ - icon("network-wireless-symbolic", 24) - .style(Svg::Symbolic) - .into(), - text(&known.ssid).size(14).width(Length::Fill).into(), - ]; - - if known.working { - btn_content.push( - icon("process-working-symbolic", 24) - .style(Svg::Symbolic) - .into(), - ); - } - - let mut btn = button(Button::Secondary) - .custom(vec![Row::with_children(btn_content) - .align_items(Alignment::Center) - .spacing(8) - .into()]) - .padding([8, 24]) - .width(Length::Fill) - .style(button_style()); - btn = match known.state { - DeviceState::Failed - | DeviceState::Unknown - | DeviceState::Unmanaged - | DeviceState::Disconnected - | DeviceState::NeedAuth => { - btn.on_press(Message::ActivateKnownWifi(known.ssid.clone())) - } - DeviceState::Activated => btn.on_press(Message::Disconnect(known.ssid.clone())), - _ => btn, - }; - known_wifi = known_wifi.push(row![btn].align_items(Alignment::Center)); - } let mut content = column![ vpn_ethernet_col, @@ -561,38 +540,106 @@ impl Application for CosmicNetworkApplet { ) .padding([0, 12]), divider::horizontal::light(), - known_wifi, ] .align_items(Alignment::Center) .spacing(8) .padding([8, 0]); - let dropdown_icon = if self.show_visible_networks { - "go-down-symbolic" + if self.nm_state.airplane_mode { + content = content.push( + column!( + icon("airplane-mode-symbolic", 48).style(Svg::Symbolic), + text(fl!("airplane-mode-on")).size(14), + text(fl!("turn-off-airplane-mode")).size(12) + ) + .spacing(8) + .align_items(Alignment::Center) + .width(Length::Fill), + ); } else { - "go-next-symbolic" - }; - let available_connections_btn = button(Button::Secondary) - .custom( - vec![ - text(fl!("visible-wireless-networks")) - .size(14) - .width(Length::Fill) - .height(Length::Fixed(24.0)) - .vertical_alignment(Vertical::Center) - .into(), - container(icon(dropdown_icon, 14).style(Svg::Symbolic)) - .align_x(Horizontal::Center) - .align_y(Vertical::Center) - .width(Length::Fixed(24.0)) - .height(Length::Fixed(24.0)) - .into(), - ] - .into(), - ) - .padding([8, 24]) - .style(button_style()) - .on_press(Message::ToggleVisibleNetworks); - content = content.push(available_connections_btn); + for known in &self.nm_state.known_access_points { + let mut btn_content = Vec::with_capacity(2); + + let ssid = text(&known.ssid).size(14).width(Length::Fill); + if known.working { + btn_content.push( + icon("network-wireless-acquiring-symbolic", 24) + .style(Svg::Symbolic) + .into(), + ); + btn_content.push(ssid.into()); + btn_content.push( + icon("process-working-symbolic", 24) + .style(Svg::Symbolic) + .into(), + ); + } else if matches!(known.state, DeviceState::Unavailable) { + btn_content.push( + icon("network-wireless-disconnected-symbolic", 24) + .style(Svg::Symbolic) + .into(), + ); + btn_content.push(ssid.into()); + } else { + btn_content.push( + icon(wifi_icon(known.strength), 24) + .style(Svg::Symbolic) + .into(), + ); + btn_content.push(ssid.into()); + } + + let mut btn = button(Button::Secondary) + .custom(vec![Row::with_children(btn_content) + .align_items(Alignment::Center) + .spacing(8) + .into()]) + .padding([8, 24]) + .width(Length::Fill) + .style(button_style()); + btn = match known.state { + DeviceState::Failed + | DeviceState::Unknown + | DeviceState::Unmanaged + | DeviceState::Disconnected + | DeviceState::NeedAuth => { + btn.on_press(Message::ActivateKnownWifi(known.ssid.clone())) + } + DeviceState::Activated => { + btn.on_press(Message::Disconnect(known.ssid.clone())) + } + _ => btn, + }; + known_wifi = known_wifi.push(row![btn].align_items(Alignment::Center)); + } + content = content.push(known_wifi); + let dropdown_icon = if self.show_visible_networks { + "go-down-symbolic" + } else { + "go-next-symbolic" + }; + let available_connections_btn = button(Button::Secondary) + .custom( + vec![ + text(fl!("visible-wireless-networks")) + .size(14) + .width(Length::Fill) + .height(Length::Fixed(24.0)) + .vertical_alignment(Vertical::Center) + .into(), + container(icon(dropdown_icon, 14).style(Svg::Symbolic)) + .align_x(Horizontal::Center) + .align_y(Vertical::Center) + .width(Length::Fixed(24.0)) + .height(Length::Fixed(24.0)) + .into(), + ] + .into(), + ) + .padding([8, 24]) + .style(button_style()) + .on_press(Message::ToggleVisibleNetworks); + content = content.push(available_connections_btn); + } if self.show_visible_networks { if let Some(new_conn_state) = self.new_connection.as_ref() { match new_conn_state { @@ -601,7 +648,8 @@ impl Application for CosmicNetworkApplet { password, } => { let id = row![ - icon("network-wireless-symbolic", 24).style(Svg::Symbolic), + icon("network-wireless-acquiring-symbolic", 24) + .style(Svg::Symbolic), text(&access_point.ssid).size(14), ] .align_items(Alignment::Center) @@ -638,7 +686,8 @@ impl Application for CosmicNetworkApplet { } NewConnectionState::Waiting(access_point) => { let id = row![ - icon("network-wireless-symbolic", 24).style(Svg::Symbolic), + icon("network-wireless-acquiring-symbolic", 24) + .style(Svg::Symbolic), text(&access_point.ssid).size(14), ] .align_items(Alignment::Center) @@ -654,7 +703,7 @@ impl Application for CosmicNetworkApplet { } NewConnectionState::Failure(access_point) => { let id = row![ - icon("network-wireless-symbolic", 24).style(Svg::Symbolic), + icon("network-wireless-error-symbolic", 24).style(Svg::Symbolic), text(&access_point.ssid).size(14), ] .align_items(Alignment::Center) @@ -701,7 +750,7 @@ impl Application for CosmicNetworkApplet { } let button = button(button_style()) .custom(vec![row![ - icon("network-wireless-symbolic", 16).style(Svg::Symbolic), + icon(wifi_icon(ap.strength), 16).style(Svg::Symbolic), text(&ap.ssid) .size(14) .height(Length::Fixed(24.0)) @@ -736,9 +785,12 @@ impl Application for CosmicNetworkApplet { self.applet_helper.theme_subscription(0).map(Message::Theme), timeline, network_sub, - active_conns_subscription(0, conn.clone()).map(Message::NetworkManagerEvent), - devices_subscription(0, conn.clone()).map(Message::NetworkManagerEvent), - wireless_enabled_subscription(0, conn.clone()).map(Message::NetworkManagerEvent), + active_conns_subscription(self.toggle_wifi_ctr, conn.clone()) + .map(Message::NetworkManagerEvent), + devices_subscription(self.toggle_wifi_ctr, conn.clone()) + .map(Message::NetworkManagerEvent), + wireless_enabled_subscription(self.toggle_wifi_ctr, conn.clone()) + .map(Message::NetworkManagerEvent), ]) } else { Subscription::batch(vec![timeline, network_sub]) diff --git a/cosmic-applet-network/src/network_manager/active_conns.rs b/cosmic-applet-network/src/network_manager/active_conns.rs index fe728625..baf44be6 100644 --- a/cosmic-applet-network/src/network_manager/active_conns.rs +++ b/cosmic-applet-network/src/network_manager/active_conns.rs @@ -18,6 +18,7 @@ pub fn active_conns_subscription async move { loop { state = start_listening(state, &mut output).await; + _ = tokio::time::sleep(tokio::time::Duration::from_secs(2)).await; } } }) diff --git a/cosmic-applet-network/src/network_manager/current_networks.rs b/cosmic-applet-network/src/network_manager/current_networks.rs index a347e0d3..9f4533d5 100644 --- a/cosmic-applet-network/src/network_manager/current_networks.rs +++ b/cosmic-applet-network/src/network_manager/current_networks.rs @@ -56,6 +56,7 @@ pub async fn active_connections( rsn_flags: access_point.rsn_flags().await?, wpa_flags: access_point.wpa_flags().await?, state, + strength: access_point.strength().await.unwrap_or_default(), }); } } @@ -98,6 +99,7 @@ pub enum ActiveConnectionInfo { rsn_flags: ApSecurityFlags, wpa_flags: ApSecurityFlags, state: ActiveConnectionState, + strength: u8, }, Vpn { name: String, diff --git a/cosmic-applet-network/src/network_manager/devices.rs b/cosmic-applet-network/src/network_manager/devices.rs index d2f2f237..59119203 100644 --- a/cosmic-applet-network/src/network_manager/devices.rs +++ b/cosmic-applet-network/src/network_manager/devices.rs @@ -18,6 +18,7 @@ pub fn devices_subscription( async move { loop { state = start_listening(state, &mut output).await; + _ = tokio::time::sleep(tokio::time::Duration::from_secs(2)).await; } } }) diff --git a/cosmic-applet-network/src/network_manager/mod.rs b/cosmic-applet-network/src/network_manager/mod.rs index d091e2ce..6f4a27a7 100644 --- a/cosmic-applet-network/src/network_manager/mod.rs +++ b/cosmic-applet-network/src/network_manager/mod.rs @@ -140,20 +140,31 @@ async fn start_listening( .output() .await .is_ok(); + let mut state = NetworkManagerState::new(&conn).await.unwrap_or_default(); + state.airplane_mode = if success { + airplane_mode + } else { + !airplane_mode + }; + if state.airplane_mode { + state.wifi_enabled = false; + } _ = output .send(NetworkManagerEvent::RequestResponse { req: NetworkManagerRequest::SetAirplaneMode(airplane_mode), success, - state: NetworkManagerState::new(&conn).await.unwrap_or_default(), + state, }) .await; } Some(NetworkManagerRequest::SetWiFi(enabled)) => { let success = network_manager.set_wireless_enabled(enabled).await.is_ok(); + let mut state = NetworkManagerState::new(&conn).await.unwrap_or_default(); + state.wifi_enabled = if success { enabled } else { !enabled }; let response = NetworkManagerEvent::RequestResponse { req: NetworkManagerRequest::SetWiFi(enabled), success, - state: NetworkManagerState::new(&conn).await.unwrap_or_default(), + state, }; _ = output.send(response).await; } @@ -198,7 +209,6 @@ async fn start_listening( }; if let Some(s) = secrets.get_mut("802-11-wireless-security") { s.insert("psk".into(), Value::Str(password.clone().into()).to_owned()); - drop(s); settings.extend(secrets.into_iter()); let settings: HashMap<_, _> = settings .iter() @@ -519,14 +529,8 @@ impl NetworkManagerState { .output() .await?; let airplane_mode = std::str::from_utf8(&airplaine_mode.stdout).unwrap_or_default(); - let bluetooth_disabled = airplane_mode.contains("Soft blocked: yes"); - - if !network_manager.wireless_enabled().await.unwrap_or_default() { - _self.airplane_mode = bluetooth_disabled; - return Ok(_self); - } else { - _self.wifi_enabled = true; - }; + _self.wifi_enabled = network_manager.wireless_enabled().await.unwrap_or_default(); + _self.airplane_mode = airplane_mode.contains("Soft blocked: yes") && !_self.wifi_enabled; let s = NetworkManagerSettings::new(&conn).await?; _ = s.load_connections(&[]).await; diff --git a/cosmic-applet-network/src/network_manager/wireless_enabled.rs b/cosmic-applet-network/src/network_manager/wireless_enabled.rs index fc4c5d60..295bdf6b 100644 --- a/cosmic-applet-network/src/network_manager/wireless_enabled.rs +++ b/cosmic-applet-network/src/network_manager/wireless_enabled.rs @@ -18,6 +18,7 @@ pub fn wireless_enabled_subscription + + + + + + + + + + + + + + diff --git a/cosmic-applet-notifications/data/icons/scalable/status/cosmic-applet-notification-new-symbolic.svg b/cosmic-applet-notifications/data/icons/scalable/status/cosmic-applet-notification-new-symbolic.svg new file mode 100644 index 00000000..bb94ff64 --- /dev/null +++ b/cosmic-applet-notifications/data/icons/scalable/status/cosmic-applet-notification-new-symbolic.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/cosmic-applet-notifications/data/icons/scalable/status/cosmic-applet-notification-symbolic.svg b/cosmic-applet-notifications/data/icons/scalable/status/cosmic-applet-notification-symbolic.svg new file mode 100644 index 00000000..566d5337 --- /dev/null +++ b/cosmic-applet-notifications/data/icons/scalable/status/cosmic-applet-notification-symbolic.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/cosmic-applet-notifications/src/main.rs b/cosmic-applet-notifications/src/main.rs index d7947be8..e14962ec 100644 --- a/cosmic-applet-notifications/src/main.rs +++ b/cosmic-applet-notifications/src/main.rs @@ -70,6 +70,17 @@ impl Notifications { self.timeline.start(); } } + + fn update_icon(&mut self) { + self.icon_name = if self.config.do_not_disturb { + "cosmic-applet-notification-disabled-symbolic" + } else if self.cards.is_empty() { + "cosmic-applet-notification-symbolic" + } else { + "cosmic-applet-notification-new-symbolic" + } + .to_string(); + } } #[derive(Debug, Clone)] @@ -114,17 +125,15 @@ impl Application for Notifications { }) }) .unwrap_or_default(); - ( - Notifications { - applet_helper, - theme, - icon_name: "notification-alert-symbolic".to_string(), - config_helper: helper, - config, - ..Default::default() - }, - Command::none(), - ) + let mut _self = Notifications { + applet_helper, + theme, + config_helper: helper, + config, + ..Default::default() + }; + _self.update_icon(); + (_self, Command::none()) } fn title(&self) -> String { @@ -175,15 +184,13 @@ impl Application for Notifications { match message { Message::Theme(t) => { self.theme = t; - Command::none() } Message::Frame(now) => { self.timeline.now(now); - Command::none() } Message::TogglePopup => { if let Some(p) = self.popup.take() { - destroy_popup(p) + return destroy_popup(p); } else { self.id_ctr += 1; let new_id = window::Id(self.id_ctr); @@ -201,7 +208,7 @@ impl Application for Notifications { .max_width(444.0) .min_height(100.0) .max_height(900.0); - get_popup(popup_settings) + return get_popup(popup_settings); } } Message::DoNotDisturb(chain, b) => { @@ -212,11 +219,9 @@ impl Application for Notifications { tracing::error!("{:?}", err); } } - Command::none() } Message::Settings => { let _ = process::Command::new("cosmic-settings notifications").spawn(); - Command::none() } Message::NotificationEvent(n) => { if let Some(c) = self @@ -241,13 +246,10 @@ impl Application for Notifications { fl!("show-more", HashMap::from_iter(vec![("more", "1")])), )); } - - Command::none() } - Message::Ignore => Command::none(), + Message::Ignore => {} Message::Config(config) => { self.config = config; - Command::none() } Message::Dismissed(id) => { info!("Dismissed {}", id); @@ -264,12 +266,10 @@ impl Application for Notifications { } }); } - Command::none() } Message::DbusEvent(e) => match e { subscriptions::dbus::Output::Ready(tx) => { self.dbus_sender.replace(tx); - Command::none() } subscriptions::dbus::Output::CloseEvent(id) => { for c in &mut self.cards { @@ -280,8 +280,6 @@ impl Application for Notifications { ); } self.cards.retain(|c| !c.1.is_empty()); - - Command::none() } }, Message::ClearAll(app_name) => { @@ -303,8 +301,6 @@ impl Application for Notifications { } } } - - Command::none() } Message::CardsToggled(name, expanded) => { let id = if let Some((id, _, n_expanded, _)) = self @@ -318,9 +314,10 @@ impl Application for Notifications { return Command::none(); }; self.update_cards(id); - Command::none() } - } + }; + self.update_icon(); + Command::none() } fn view(&self, id: window::Id) -> Element { @@ -346,7 +343,7 @@ impl Application for Notifications { let notifications = if self.cards.is_empty() { row![container( column![ - text_icon(&self.icon_name, 40), + text_icon("cosmic-applet-notification-symbolic", 40), text(&fl!("no-notifications")) ] .align_items(Alignment::Center) diff --git a/cosmic-applet-power/data/icons/com.system76.CosmicAppletPower.svg b/cosmic-applet-power/data/icons/scalable/apps/com.system76.CosmicAppletPower.svg similarity index 100% rename from cosmic-applet-power/data/icons/com.system76.CosmicAppletPower.svg rename to cosmic-applet-power/data/icons/scalable/apps/com.system76.CosmicAppletPower.svg diff --git a/cosmic-applet-time/data/icons/com.system76.CosmicAppletTime.svg b/cosmic-applet-time/data/icons/scalable/apps/com.system76.CosmicAppletTime.svg similarity index 100% rename from cosmic-applet-time/data/icons/com.system76.CosmicAppletTime.svg rename to cosmic-applet-time/data/icons/scalable/apps/com.system76.CosmicAppletTime.svg diff --git a/cosmic-applet-workspaces/data/icons/com.system76.CosmicAppletWorkspaces.svg b/cosmic-applet-workspaces/data/icons/scalable/apps/com.system76.CosmicAppletWorkspaces.svg similarity index 100% rename from cosmic-applet-workspaces/data/icons/com.system76.CosmicAppletWorkspaces.svg rename to cosmic-applet-workspaces/data/icons/scalable/apps/com.system76.CosmicAppletWorkspaces.svg diff --git a/cosmic-panel-app-button/data/icons/com.system76.CosmicPanelAppButton-symbolic.svg b/cosmic-panel-app-button/data/icons/com.system76.CosmicPanelAppButton-symbolic.svg deleted file mode 100644 index a4337c2d..00000000 --- a/cosmic-panel-app-button/data/icons/com.system76.CosmicPanelAppButton-symbolic.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - image/svg+xml - - Pop_icon - - - - - - Pop_icon - - - - - - - - - - - - diff --git a/cosmic-panel-app-button/data/icons/com.system76.CosmicPanelAppButton.Devel.svg b/cosmic-panel-app-button/data/icons/com.system76.CosmicPanelAppButton.Devel.svg deleted file mode 100644 index a4337c2d..00000000 --- a/cosmic-panel-app-button/data/icons/com.system76.CosmicPanelAppButton.Devel.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - image/svg+xml - - Pop_icon - - - - - - Pop_icon - - - - - - - - - - - - diff --git a/cosmic-panel-app-button/data/icons/com.system76.CosmicPanelAppButton.svg b/cosmic-panel-app-button/data/icons/scalable/apps/com.system76.CosmicPanelAppButton.svg similarity index 100% rename from cosmic-panel-app-button/data/icons/com.system76.CosmicPanelAppButton.svg rename to cosmic-panel-app-button/data/icons/scalable/apps/com.system76.CosmicPanelAppButton.svg diff --git a/cosmic-panel-workspaces-button/data/icons/com.system76.CosmicPanelWorkspacesButton.svg b/cosmic-panel-workspaces-button/data/icons/scalable/apps/com.system76.CosmicPanelWorkspacesButton.svg similarity index 100% rename from cosmic-panel-workspaces-button/data/icons/com.system76.CosmicPanelWorkspacesButton.svg rename to cosmic-panel-workspaces-button/data/icons/scalable/apps/com.system76.CosmicPanelWorkspacesButton.svg diff --git a/debian/control b/debian/control index 3d55ea15..3d48b941 100644 --- a/debian/control +++ b/debian/control @@ -19,6 +19,7 @@ Homepage: https://github.com/pop-os/cosmic-applets Package: cosmic-applets Architecture: amd64 arm64 Depends: + cosmic-icons, ${misc:Depends}, ${shlibs:Depends} Recommends: diff --git a/justfile b/justfile index 60d96fb9..363f7fb8 100644 --- a/justfile +++ b/justfile @@ -10,7 +10,7 @@ cargo_args := vendor_args + ' ' + debug_args sharedir := rootdir + prefix + '/share' -iconsdir := sharedir + '/icons/hicolor/scalable/apps' +iconsdir := sharedir + '/icons/hicolor' bindir := rootdir + prefix + '/bin' build: _extract_vendor @@ -24,8 +24,8 @@ build-debug *args: # Compiles with release profile build-release *args: (build-debug '--release' args) -_install_icon path: - install -Dm0644 {{path}} {{iconsdir}}/{{file_name(path)}} +_install_icons name: + find {{name}}/'data'/'icons' -type f -exec echo {} \; | rev | cut -d'/' -f-3 | rev | xargs -d '\n' -I {} install -Dm0644 {{name}}/'data'/'icons'/{} {{iconsdir}}/{} _install_desktop path: install -Dm0644 {{path}} {{sharedir}}/applications/{{file_name(path)}} @@ -33,7 +33,7 @@ _install_desktop path: _install_bin name: install -Dm0755 target/release/{{name}} {{bindir}}/{{name}} -_install id name: (_install_icon name + '/data/icons/' + id + '.svg') (_install_desktop name + '/data/' + id + '.desktop') (_install_bin name) +_install id name: (_install_icons name) (_install_desktop name + '/data/' + id + '.desktop') (_install_bin name) _install_app_list: (_install 'com.system76.CosmicAppList' 'cosmic-app-list') _install_audio: (_install 'com.system76.CosmicAppletAudio' 'cosmic-applet-audio') @@ -48,7 +48,7 @@ _install_time: (_install 'com.system76.CosmicAppletTime' 'cosmic-applet-time') # TODO: Turn this into one configurable applet? _install_panel_button: (_install_bin 'cosmic-panel-button') -_install_button id name: (_install_icon name + '/data/icons/' + id + '.svg') (_install_desktop name + '/data/' + id + '.desktop') +_install_button id name: (_install_icons name) (_install_desktop name + '/data/' + id + '.desktop') _install_app_button: (_install_button 'com.system76.CosmicPanelAppButton' 'cosmic-panel-app-button') _install_workspaces_button: (_install_button 'com.system76.CosmicPanelWorkspacesButton' 'cosmic-panel-workspaces-button')