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 @@
-
-
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 @@
-
-
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')