diff --git a/cosmic-app-list/src/app.rs b/cosmic-app-list/src/app.rs index 7018d5ae3..5c2ac0962 100755 --- a/cosmic-app-list/src/app.rs +++ b/cosmic-app-list/src/app.rs @@ -53,7 +53,6 @@ use cosmic_app_list_config::{APP_ID, AppListConfig}; use cosmic_protocols::toplevel_info::v1::client::zcosmic_toplevel_handle_v1::State; use futures::future::pending; use iced::{Alignment, Background, Length}; -use itertools::Itertools; use std::{borrow::Cow, collections::HashMap, path::PathBuf, rc::Rc, str::FromStr, time::Duration}; use switcheroo_control::Gpu; use tokio::time::sleep; @@ -177,31 +176,24 @@ impl DockItem { .width(app_icon.icon_size.into()) .height(app_icon.icon_size.into()); - let dots = if toplevels.is_empty() { - (0..1) - .map(|_| { - container(vertical_space().height(Length::Fixed(0.0))) - .padding(app_icon.dot_radius) - .into() - }) - .collect_vec() - } else { - (0..1) - .map(|_| { - container(if toplevels.len() == 1 { - vertical_space().height(Length::Fixed(0.0)) - } else { - match applet.anchor { - PanelAnchor::Left | PanelAnchor::Right => { - vertical_space().height(app_icon.bar_size) - } - PanelAnchor::Top | PanelAnchor::Bottom => { - horizontal_space().width(app_icon.bar_size) - } - } - }) - .padding(app_icon.dot_radius) - .class(theme::style::Container::Custom(Box::new(move |theme| { + let dot_constructor = || { + let space = if toplevels.len() <= 1 { + vertical_space().height(Length::Fixed(0.0)) + } else { + match applet.anchor { + PanelAnchor::Left | PanelAnchor::Right => { + vertical_space().height(app_icon.bar_size) + } + PanelAnchor::Top | PanelAnchor::Bottom => { + horizontal_space().width(app_icon.bar_size) + } + } + }; + let mut container = container(space).padding(app_icon.dot_radius); + + if !toplevels.is_empty() { + container = + container.class(theme::style::Container::Custom(Box::new(move |theme| { container::Style { text_color: Some(Color::TRANSPARENT), background: if is_focused { @@ -218,34 +210,35 @@ impl DockItem { icon_color: Some(Color::TRANSPARENT), } }))) - .into() - }) - .collect_vec() + } + container.into() }; + let dots = std::iter::repeat_with(dot_constructor).take(2); + let icon_wrapper: Element<_> = match applet.anchor { - PanelAnchor::Left => row(vec![ + PanelAnchor::Left => row([ column(dots).into(), horizontal_space().width(Length::Fixed(1.0)).into(), cosmic_icon.clone().into(), ]) .align_y(Alignment::Center) .into(), - PanelAnchor::Right => row(vec![ + PanelAnchor::Right => row([ cosmic_icon.clone().into(), horizontal_space().width(Length::Fixed(1.0)).into(), column(dots).into(), ]) .align_y(Alignment::Center) .into(), - PanelAnchor::Top => column(vec![ + PanelAnchor::Top => column([ row(dots).into(), vertical_space().height(Length::Fixed(1.0)).into(), cosmic_icon.clone().into(), ]) .align_x(Alignment::Center) .into(), - PanelAnchor::Bottom => column(vec![ + PanelAnchor::Bottom => column([ cosmic_icon.clone().into(), vertical_space().height(Length::Fixed(1.0)).into(), row(dots).into(), @@ -470,7 +463,7 @@ where img.img.clone(), ))) } else { - Image::new(Handle::from_rgba(1, 1, vec![0, 0, 0, 255])).into() + Image::new(Handle::from_rgba(1, 1, [0u8, 0u8, 0u8, 255u8].as_slice())).into() }) .class(Container::Custom(Box::new(move |theme| { container::Style { @@ -590,7 +583,7 @@ fn find_desktop_entries<'a>( app_ids.iter().map(|fav| { let unicase_fav = fde::unicase::Ascii::new(fav.as_str()); fde::find_app_by_id(desktop_entries, unicase_fav).map_or_else( - || fde::DesktopEntry::from_appid(fav.clone()).clone(), + || fde::DesktopEntry::from_appid(fav.clone()), ToOwned::to_owned, ) }) @@ -612,7 +605,7 @@ impl CosmicAppList { .map(|(pinned_ctr, (e, original_id))| DockItem { id: pinned_ctr as u32, toplevels: Vec::new(), - desktop_info: e.clone(), + desktop_info: e, original_app_id: original_id.clone(), }) .collect(); @@ -673,7 +666,7 @@ impl cosmic::Application for CosmicAppList { } else { self.overflow_active_popup = None; self.overflow_favorites_popup = None; - return Task::batch(vec![destroy_popup(popup_id), destroy_popup(parent)]); + return Task::batch([destroy_popup(popup_id), destroy_popup(parent)]); } } if let Some(toplevel_group) = self @@ -733,7 +726,7 @@ impl cosmic::Application for CosmicAppList { } else { self.overflow_active_popup = None; self.overflow_favorites_popup = None; - return Task::batch(vec![destroy_popup(popup_id), destroy_popup(parent)]); + return Task::batch([destroy_popup(popup_id), destroy_popup(parent)]); } } if let Some(toplevel_group) = self @@ -1490,7 +1483,10 @@ impl cosmic::Application for CosmicAppList { } else { 0 }; - let favorites: Vec<_> = (&mut self.pinned_list.iter().rev()) + let favorites: Vec<_> = self + .pinned_list + .iter() + .rev() .filter(|f| { if favorite_to_remove > 0 && f.toplevels.is_empty() { favorite_to_remove -= 1; @@ -1524,7 +1520,7 @@ impl cosmic::Application for CosmicAppList { .desktop_info .full_name(&self.locales) .unwrap_or_default() - .to_string(), + .into_owned(), self.popup.is_some(), Message::Surface, None, @@ -1618,7 +1614,7 @@ impl cosmic::Application for CosmicAppList { .desktop_info .full_name(&self.locales) .unwrap_or_default() - .to_string(), + .into_owned(), self.popup.is_some(), Message::Surface, None, @@ -1812,11 +1808,7 @@ impl cosmic::Application for CosmicAppList { Message::Exec(exec.to_string(), None, desktop_info.terminal()), )); } else if let Some(gpus) = self.gpus.as_ref() { - let default_idx = if desktop_info.prefers_non_default_gpu() { - gpus.iter().position(|gpu| !gpu.default).unwrap_or(0) - } else { - gpus.iter().position(|gpu| gpu.default).unwrap_or(0) - }; + let default_idx = preferred_gpu_idx(desktop_info, gpus.iter()); for (i, gpu) in gpus.iter().enumerate() { content = content.push( menu_button(text::body(format!( @@ -2037,7 +2029,7 @@ impl cosmic::Application for CosmicAppList { .desktop_info .full_name(&self.locales) .unwrap_or_default() - .to_string(), + .into_owned(), self.popup.is_some(), Message::Surface, None, @@ -2101,7 +2093,10 @@ impl cosmic::Application for CosmicAppList { 0 }; let mut favorites_extra = Vec::with_capacity(favorite_to_remove); - let mut favorites: Vec<_> = (&mut self.pinned_list.iter().rev()) + let mut favorites: Vec<_> = self + .pinned_list + .iter() + .rev() .filter(|f| { if favorite_to_remove > 0 && f.toplevels.is_empty() { favorite_to_remove -= 1; @@ -2190,7 +2185,7 @@ impl cosmic::Application for CosmicAppList { } fn subscription(&self) -> Subscription { - Subscription::batch(vec![ + Subscription::batch([ wayland_subscription().map(Message::Wayland), listen_with(|e, _, id| match e { cosmic::iced_runtime::core::Event::PlatformSpecific( @@ -2299,9 +2294,9 @@ impl CosmicAppList { if self.active_workspaces.is_empty() { return Vec::new(); } - let current_output = self.core.applet.output_name.clone(); + let current_output = self.core.applet.output_name.as_ref(); let mut focused_toplevels: Vec = Vec::new(); - let active_workspaces = self.active_workspaces.clone(); + let active_workspaces = &self.active_workspaces; for toplevel_list in self.active_list.iter().chain(self.pinned_list.iter()) { for (t_info, _) in &toplevel_list.toplevels { if t_info.state.contains(&State::Activated) @@ -2349,10 +2344,7 @@ impl CosmicAppList { let is_proton_game = info.app_id == "steam_app_default"; if is_proton_game || info.app_id.ends_with(".exe") { for entry in &self.desktop_entries { - let localised_name = entry - .name(&self.locales) - .map(|x| x.to_string()) - .unwrap_or_default(); + let localised_name = entry.name(&self.locales).unwrap_or_default(); if localised_name == info.title { // if this is a proton game, we only want @@ -2378,13 +2370,7 @@ impl CosmicAppList { fn launch_on_preferred_gpu(desktop_info: &DesktopEntry, gpus: Option<&[Gpu]>) -> Option { let exec = desktop_info.exec()?; - let gpu_idx = gpus.map(|gpus| { - if desktop_info.prefers_non_default_gpu() { - gpus.iter().position(|gpu| !gpu.default).unwrap_or(0) - } else { - gpus.iter().position(|gpu| gpu.default).unwrap_or(0) - } - }); + let gpu_idx = gpus.map(|gpus| preferred_gpu_idx(desktop_info, gpus.iter())); Some(Message::Exec( exec.to_string(), @@ -2393,6 +2379,14 @@ fn launch_on_preferred_gpu(desktop_info: &DesktopEntry, gpus: Option<&[Gpu]>) -> )) } +fn preferred_gpu_idx<'a, I>(desktop_info: &DesktopEntry, mut gpus: I) -> usize +where + I: Iterator, +{ + gpus.position(|gpu| gpu.default ^ desktop_info.prefers_non_default_gpu()) + .unwrap_or(0) +} + #[derive(Debug, Default, Clone)] pub struct DndPathBuf(PathBuf); @@ -2428,8 +2422,6 @@ impl AsMimeTypes for DndPathBuf { } fn as_bytes(&self, _mime_type: &str) -> Option> { - Some(Cow::Owned( - self.0.clone().to_str()?.to_string().into_bytes(), - )) + Some(Cow::Owned(self.0.to_str()?.as_bytes().to_vec())) } } diff --git a/cosmic-app-list/src/wayland_handler.rs b/cosmic-app-list/src/wayland_handler.rs index a12fb6350..e5202cd9b 100644 --- a/cosmic-app-list/src/wayland_handler.rs +++ b/cosmic-app-list/src/wayland_handler.rs @@ -87,10 +87,7 @@ impl OutputHandler for AppData { if let Some(info) = self.output_state.info(&output) { let _ = self .tx - .unbounded_send(WaylandUpdate::Output(OutputUpdate::Add( - output.clone(), - info.clone(), - ))); + .unbounded_send(WaylandUpdate::Output(OutputUpdate::Add(output, info))); } } @@ -103,10 +100,7 @@ impl OutputHandler for AppData { if let Some(info) = self.output_state.info(&output) { let _ = self .tx - .unbounded_send(WaylandUpdate::Output(OutputUpdate::Update( - output.clone(), - info.clone(), - ))); + .unbounded_send(WaylandUpdate::Output(OutputUpdate::Update(output, info))); } } @@ -118,7 +112,7 @@ impl OutputHandler for AppData { ) { let _ = self .tx - .unbounded_send(WaylandUpdate::Output(OutputUpdate::Remove(output.clone()))); + .unbounded_send(WaylandUpdate::Output(OutputUpdate::Remove(output))); } } @@ -136,12 +130,12 @@ impl WorkspaceHandler for AppData { .iter() .filter_map(|handle| self.workspace_state.workspace_info(handle)) .find(|w| w.state.contains(WorkspaceUpdateState::Active)) + .map(|workspace| workspace.handle.clone()) }) - .map(|workspace| workspace.handle.clone()) .collect::>(); let _ = self .tx - .unbounded_send(WaylandUpdate::Workspace(active_workspaces.clone())); + .unbounded_send(WaylandUpdate::Workspace(active_workspaces)); } } @@ -699,7 +693,6 @@ pub(crate) fn wayland_handler( exit: false, tx, conn, - queue_handle: qh.clone(), output_state: OutputState::new(&globals, &qh), workspace_state: WorkspaceState::new(®istry_state, &qh), toplevel_info_state: ToplevelInfoState::new(®istry_state, &qh), @@ -709,6 +702,7 @@ pub(crate) fn wayland_handler( seat_state: SeatState::new(&globals, &qh), shm_state: Shm::bind(&globals, &qh).unwrap(), activation_state: ActivationState::bind::(&globals, &qh).ok(), + queue_handle: qh, }; loop { diff --git a/cosmic-app-list/src/wayland_subscription.rs b/cosmic-app-list/src/wayland_subscription.rs index f4cdc9fc5..016e83aea 100644 --- a/cosmic-app-list/src/wayland_subscription.rs +++ b/cosmic-app-list/src/wayland_subscription.rs @@ -57,11 +57,13 @@ pub struct WaylandImage { impl WaylandImage { pub fn new(img: image::RgbaImage) -> Self { + let width = img.width(); + let height = img.height(); + Self { - // TODO avoid copy? - img: Bytes::copy_from_slice(img.as_bytes()), - width: img.width(), - height: img.height(), + img: Bytes::from_owner(img.into_vec()), + width, + height, } } } diff --git a/cosmic-applet-a11y/src/app.rs b/cosmic-applet-a11y/src/app.rs index 3caefe825..e79f96fcb 100644 --- a/cosmic-applet-a11y/src/app.rs +++ b/cosmic-applet-a11y/src/app.rs @@ -401,7 +401,7 @@ impl cosmic::Application for CosmicA11yApplet { } fn subscription(&self) -> Subscription { - Subscription::batch(vec![ + Subscription::batch([ accessibility::subscription().map(Message::DBusUpdate), backend::wayland::a11y_subscription().map(Message::WaylandUpdate), self.timeline diff --git a/cosmic-applet-audio/src/lib.rs b/cosmic-applet-audio/src/lib.rs index fda314078..d84102ea3 100644 --- a/cosmic-applet-audio/src/lib.rs +++ b/cosmic-applet-audio/src/lib.rs @@ -131,8 +131,9 @@ impl Audio { } } -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Default)] enum IsOpen { + #[default] None, Output, Input, @@ -289,12 +290,6 @@ impl cosmic::Application for Audio { ( Self { core, - is_open: IsOpen::None, - current_output: None, - current_input: None, - outputs: vec![], - inputs: vec![], - token_tx: None, ..Default::default() }, Task::none(), @@ -495,17 +490,11 @@ impl cosmic::Application for Audio { match msg { // This is where we match messages from the subscription to app state pulse::Message::SetSinks(sinks) => self.outputs = sinks, - pulse::Message::SetSources(sources) => { - self.inputs = sources - .into_iter() - .filter(|source| { - !source - .name - .as_ref() - .unwrap_or(&String::from("Generic")) - .contains("monitor") - }) - .collect() + pulse::Message::SetSources(mut sources) => { + sources.retain(|source| { + !source.name.as_ref().is_some_and(|n| n.contains("monitor")) + }); + self.inputs = sources; } pulse::Message::SetDefaultSink(sink) => { self.update_output(Some(sink)); @@ -682,7 +671,7 @@ impl cosmic::Application for Audio { } fn subscription(&self) -> Subscription { - Subscription::batch(vec![ + Subscription::batch([ pulse::connect().map(Message::Pulse), self.timeline .as_subscription() @@ -738,11 +727,11 @@ impl cosmic::Application for Audio { .autosize_window(if let Some(Some(playback_buttons)) = playback_buttons { match self.core.applet.anchor { PanelAnchor::Left | PanelAnchor::Right => Element::from( - Column::with_children(vec![playback_buttons, btn.into()]) + Column::with_children([playback_buttons, btn.into()]) .align_x(Alignment::Center), ), PanelAnchor::Top | PanelAnchor::Bottom => { - Row::with_children(vec![playback_buttons, btn.into()]) + Row::with_children([playback_buttons, btn.into()]) .align_y(Alignment::Center) .into() } @@ -833,14 +822,7 @@ impl cosmic::Application for Audio { Some(output) => pretty_name(output.description.clone()), None => String::from("No device selected"), }, - self.outputs - .clone() - .into_iter() - .map(|output| ( - output.name.clone().unwrap_or_default(), - pretty_name(output.description) - )) - .collect(), + self.outputs.as_slice(), Message::OutputToggle, Message::OutputChanged, ), @@ -851,14 +833,7 @@ impl cosmic::Application for Audio { Some(input) => pretty_name(input.description.clone()), None => fl!("no-device"), }, - self.inputs - .clone() - .into_iter() - .map(|input| ( - input.name.clone().unwrap_or_default(), - pretty_name(input.description) - )) - .collect(), + self.inputs.as_slice(), Message::InputToggle, Message::InputChanged, ) @@ -986,17 +961,23 @@ fn revealer( open: bool, title: String, selected: String, - options: Vec<(String, String)>, + device_info: &[DeviceInfo], toggle: Message, mut change: impl FnMut(String) -> Message + 'static, ) -> widget::Column<'static, Message, crate::Theme, Renderer> { if open { - options.iter().fold( + let options = device_info.iter().map(|device| { + ( + device.name.clone().unwrap_or_default(), + pretty_name(device.description.clone()), + ) + }); + options.fold( column![revealer_head(open, title, selected, toggle)].width(Length::Fill), |col, (id, name)| { col.push( - menu_button(text::body(name.clone())) - .on_press(change(id.clone())) + menu_button(text::body(name)) + .on_press(change(id)) .width(Length::Fill) .padding([8, 48]), ) @@ -1057,12 +1038,6 @@ impl PulseState { } } -impl Default for IsOpen { - fn default() -> Self { - Self::None - } -} - fn volume_to_percent(volume: Volume) -> f64 { volume.0 as f64 * 100. / FULL_VOLUME } diff --git a/cosmic-applet-audio/src/mpris_subscription.rs b/cosmic-applet-audio/src/mpris_subscription.rs index ef8c62104..c2e010dcb 100644 --- a/cosmic-applet-audio/src/mpris_subscription.rs +++ b/cosmic-applet-audio/src/mpris_subscription.rs @@ -171,7 +171,7 @@ impl State { filter_firefox_players(&mut players); // pre-sort by path so that the same player is always selected - players.sort_by(|a, b| a.name().cmp(b.name())); + players.sort_unstable_by(|a, b| a.name().cmp(b.name())); let mut state = Self { conn, @@ -179,7 +179,7 @@ impl State { players, active_player: None, active_player_metadata_stream: None, - any_player_state_stream: futures::stream::select_all(Vec::new()), + any_player_state_stream: futures::stream::select_all([]), }; state.update_active_player().await; state.update_any_player_state_stream().await; @@ -243,7 +243,7 @@ async fn run(output: &mut futures::channel::mpsc::Sender) { let mut state = match State::new().await { Ok(state) => state, Err(err) => { - tracing::error!("Faile do monitor for mpris clients: {}", err); + tracing::error!("Failed to monitor for mpris clients: {}", err); return; } }; diff --git a/cosmic-applet-audio/src/pulse.rs b/cosmic-applet-audio/src/pulse.rs index b7104ee11..97d45666c 100644 --- a/cosmic-applet-audio/src/pulse.rs +++ b/cosmic-applet-audio/src/pulse.rs @@ -777,8 +777,8 @@ pub struct DeviceInfo { impl<'a> From<&SinkInfo<'a>> for DeviceInfo { fn from(info: &SinkInfo<'a>) -> Self { Self { - name: info.name.clone().map(|x| x.into_owned()), - description: info.description.clone().map(|x| x.into_owned()), + name: info.name.as_deref().map(str::to_string), + description: info.description.as_deref().map(str::to_string), volume: info.volume, mute: info.mute, index: info.index, @@ -789,8 +789,8 @@ impl<'a> From<&SinkInfo<'a>> for DeviceInfo { impl<'a> From<&SourceInfo<'a>> for DeviceInfo { fn from(info: &SourceInfo<'a>) -> Self { Self { - name: info.name.clone().map(|x| x.into_owned()), - description: info.description.clone().map(|x| x.into_owned()), + name: info.name.as_deref().map(str::to_string), + description: info.description.as_deref().map(str::to_string), volume: info.volume, mute: info.mute, index: info.index, @@ -824,14 +824,15 @@ pub struct ServerInfo { impl<'a> From<&'a pulse::context::introspect::ServerInfo<'a>> for ServerInfo { fn from(info: &'a pulse::context::introspect::ServerInfo<'a>) -> Self { + use std::borrow::Cow; Self { - user_name: info.user_name.as_ref().map(|cow| cow.to_string()), - host_name: info.host_name.as_ref().map(|cow| cow.to_string()), - server_version: info.server_version.as_ref().map(|cow| cow.to_string()), - server_name: info.server_name.as_ref().map(|cow| cow.to_string()), + user_name: info.user_name.as_ref().map(Cow::to_string), + host_name: info.host_name.as_ref().map(Cow::to_string), + server_version: info.server_version.as_ref().map(Cow::to_string), + server_name: info.server_name.as_ref().map(Cow::to_string), //sample_spec: info.sample_spec, - default_sink_name: info.default_sink_name.as_ref().map(|cow| cow.to_string()), - default_source_name: info.default_source_name.as_ref().map(|cow| cow.to_string()), + default_sink_name: info.default_sink_name.as_ref().map(Cow::to_string), + default_source_name: info.default_source_name.as_ref().map(Cow::to_string), cookie: info.cookie, //channel_map: info.channel_map, } diff --git a/cosmic-applet-battery/src/app.rs b/cosmic-applet-battery/src/app.rs index 2b60ca86b..30bbabfe5 100644 --- a/cosmic-applet-battery/src/app.rs +++ b/cosmic-applet-battery/src/app.rs @@ -154,8 +154,7 @@ impl CosmicBatteryApplet { } } else { "off" - } - .to_string(); + }; self.display_icon_name = format!("cosmic-applet-battery-display-brightness-{screen_brightness}-symbolic",); @@ -219,7 +218,7 @@ impl cosmic::Application for CosmicBatteryApplet { ..Default::default() }, - Task::batch(vec![zbus_session_cmd, init_charging_limit_cmd]), + Task::batch([zbus_session_cmd, init_charging_limit_cmd]), ) } @@ -508,10 +507,10 @@ impl cosmic::Application for CosmicBatteryApplet { .into(); match self.core.applet.anchor { - PanelAnchor::Left | PanelAnchor::Right => Column::with_children(vec![btn, dot]) + PanelAnchor::Left | PanelAnchor::Right => Column::with_children([btn, dot]) .align_x(Alignment::Center) .into(), - PanelAnchor::Top | PanelAnchor::Bottom => Row::with_children(vec![btn, dot]) + PanelAnchor::Top | PanelAnchor::Bottom => Row::with_children([btn, dot]) .align_y(Alignment::Center) .into(), } diff --git a/cosmic-applet-battery/src/dgpu.rs b/cosmic-applet-battery/src/dgpu.rs index 7fd022650..e035d56c8 100644 --- a/cosmic-applet-battery/src/dgpu.rs +++ b/cosmic-applet-battery/src/dgpu.rs @@ -205,17 +205,17 @@ impl Gpu { // figure out bus path for calling nvidia-smi let mut sys_path = PathBuf::from("/sys/class/drm"); sys_path.push(self.path.components().next_back()?.as_os_str()); - let buslink = std::fs::read_link(sys_path) - .ok()? - .components() - .rev() - .nth(2)? - .as_os_str() - .to_string_lossy() - .into_owned(); + let buslink = std::fs::read_link(sys_path).ok()?; + let buslink = buslink.components().nth_back(2)?.as_os_str(); let smi_output = match tokio::process::Command::new("nvidia-smi") - .args(["pmon", "--id", &buslink, "--count", "1"]) + .args([ + "pmon".as_ref(), + "--id".as_ref(), + buslink, + "--count".as_ref(), + "1".as_ref(), + ]) .output() .await { diff --git a/cosmic-applet-bluetooth/src/app.rs b/cosmic-applet-bluetooth/src/app.rs index 6a6425700..e3068a919 100644 --- a/cosmic-applet-bluetooth/src/app.rs +++ b/cosmic-applet-bluetooth/src/app.rs @@ -112,7 +112,7 @@ impl cosmic::Application for CosmicBluetoothApplet { match message { Message::TogglePopup => { if let Some(p) = self.popup.take() { - return Task::batch(vec![ + return Task::batch([ destroy_popup(p), cosmic::task::future( set_tick(Duration::from_secs(10)) @@ -134,7 +134,7 @@ impl cosmic::Application for CosmicBluetoothApplet { ); let tx = self.bluer_sender.clone(); - return Task::batch(vec![ + return Task::batch([ iced::Task::perform( async { if let Some(tx) = tx { @@ -361,7 +361,7 @@ impl cosmic::Application for CosmicBluetoothApplet { space_xxs, space_s, .. } = theme::active().cosmic().spacing; - let mut known_bluetooth = vec![]; + let mut known_bluetooth = Vec::new(); // PERF: This should be pre-filtered in an update. for dev in self.bluer_state.devices.iter().filter(|d| { self.request_confirmation @@ -370,7 +370,7 @@ impl cosmic::Application for CosmicBluetoothApplet { }) { let mut row = row![ icon::from_name(dev.icon).size(16).symbolic(true), - text::body(dev.name.clone()) + text::body(dev.name.as_str()) .align_x(Alignment::Start) .align_y(Alignment::Center) .width(Length::Fill) @@ -493,7 +493,7 @@ impl cosmic::Application for CosmicBluetoothApplet { padded_control( text::body(fl!( "confirm-pin", - HashMap::from_iter(vec![("deviceName", device.name.clone())]) + HashMap::from([("deviceName", device.name.clone())]) )) .align_x(Alignment::Start) .align_y(Alignment::Center) @@ -571,7 +571,7 @@ impl cosmic::Application for CosmicBluetoothApplet { } fn subscription(&self) -> Subscription { - Subscription::batch(vec![ + Subscription::batch([ activation_token_subscription(0).map(Message::Token), bluetooth_subscription(0).map(Message::BluetoothEvent), self.timeline diff --git a/cosmic-applet-bluetooth/src/bluetooth.rs b/cosmic-applet-bluetooth/src/bluetooth.rs index cf2bc6adc..76bed7287 100644 --- a/cosmic-applet-bluetooth/src/bluetooth.rs +++ b/cosmic-applet-bluetooth/src/bluetooth.rs @@ -249,12 +249,7 @@ impl Ord for BluerDevice { impl PartialOrd for BluerDevice { #[inline] fn partial_cmp(&self, other: &Self) -> Option { - match self.status.cmp(&other.status) { - std::cmp::Ordering::Equal => { - Some(self.name.to_lowercase().cmp(&other.name.to_lowercase())) - } - o => Some(o), - } + Some(self.cmp(other)) } } @@ -813,6 +808,6 @@ async fn build_device_list(mut devices: Vec, adapter: &Adapter) -> devices.push(device); } - devices.sort(); + devices.sort_unstable(); devices } diff --git a/cosmic-applet-input-sources/src/lib.rs b/cosmic-applet-input-sources/src/lib.rs index 630caa947..64de4cf70 100644 --- a/cosmic-applet-input-sources/src/lib.rs +++ b/cosmic-applet-input-sources/src/lib.rs @@ -242,8 +242,8 @@ impl cosmic::Application for Window { widget::column::with_capacity(4 + self.active_layouts.len()).padding([8, 0]); for (id, layout) in self.active_layouts.iter().enumerate() { let group = widget::column::with_capacity(2) - .push(widget::text::body(layout.description.clone())) - .push(widget::text::caption(layout.layout.clone())); + .push(widget::text::body(layout.description.as_str())) + .push(widget::text::caption(layout.layout.as_str())); content_list = content_list .push(applet::menu_button(group).on_press(Message::SetActiveLayout(id))); } diff --git a/cosmic-applet-minimize/src/lib.rs b/cosmic-applet-minimize/src/lib.rs index e8f4ffeac..b76ebeab0 100644 --- a/cosmic-applet-minimize/src/lib.rs +++ b/cosmic-applet-minimize/src/lib.rs @@ -173,7 +173,7 @@ impl cosmic::Application for Minimize { // Temporarily take ownership to appease the borrow checker. let mut apps = std::mem::take(&mut self.apps); - if let Some(pos) = apps.iter_mut().position(|a| { + if let Some(pos) = apps.iter().position(|a| { a.toplevel_info.foreign_toplevel == toplevel_info.foreign_toplevel }) { if apps[pos].toplevel_info.app_id != toplevel_info.app_id { @@ -194,7 +194,7 @@ impl cosmic::Application for Minimize { name: desktop_entry .full_name(&self.locales) .unwrap_or(Cow::Borrowed(&desktop_entry.appid)) - .to_string(), + .into_owned(), icon_source: fde::IconSource::from_unknown( desktop_entry.icon().unwrap_or(&desktop_entry.appid), ), diff --git a/cosmic-applet-minimize/src/wayland_handler.rs b/cosmic-applet-minimize/src/wayland_handler.rs index 6373f1a54..af244a857 100644 --- a/cosmic-applet-minimize/src/wayland_handler.rs +++ b/cosmic-applet-minimize/src/wayland_handler.rs @@ -237,7 +237,7 @@ impl ShmImage { pub fn image(&self) -> anyhow::Result { let mmap = unsafe { memmap2::Mmap::map(&self.fd.as_fd())? }; image::RgbaImage::from_raw(self.width, self.height, mmap.to_vec()) - .ok_or(anyhow::anyhow!("ShmImage had incorrect size")) + .ok_or_else(|| anyhow::anyhow!("ShmImage had incorrect size")) } } @@ -475,12 +475,12 @@ pub(crate) fn wayland_handler( exit: false, tx, conn, - queue_handle: qh.clone(), shm_state, screencopy_state, seat_state: SeatState::new(&globals, &qh), toplevel_info_state: ToplevelInfoState::new(®istry_state, &qh), toplevel_manager_state: ToplevelManagerState::new(®istry_state, &qh), + queue_handle: qh, registry_state, }; diff --git a/cosmic-applet-network/src/app.rs b/cosmic-applet-network/src/app.rs index 8606bad65..636978230 100644 --- a/cosmic-applet-network/src/app.rs +++ b/cosmic-applet-network/src/app.rs @@ -370,7 +370,7 @@ impl cosmic::Application for CosmicNetworkApplet { } = &req { if let Some(NewConnectionState::Waiting(access_point)) = - self.new_connection.clone() + self.new_connection.as_ref() { if !success && ssid == &access_point.ssid @@ -384,7 +384,7 @@ impl cosmic::Application for CosmicNetworkApplet { } } else if let Some(NewConnectionState::EnterPassword { access_point, .. - }) = self.new_connection.clone() + }) = self.new_connection.as_ref() { if success && ssid == &access_point.ssid && *hw_address == access_point.hw_address { self.new_connection = None; @@ -863,7 +863,7 @@ impl cosmic::Application for CosmicNetworkApplet { let mut btn_content = vec![ column![ text::body(display_name), - Column::with_children(vec![text("Adapter").size(10).into()]) + Column::with_children([text("Adapter").size(10).into()]) ] .width(Length::Fill) .into(), @@ -1149,7 +1149,7 @@ impl cosmic::Application for CosmicNetworkApplet { if let Some(conn) = self.conn.as_ref() { let has_popup = self.popup.is_some(); - Subscription::batch(vec![ + Subscription::batch([ timeline, network_sub, token_sub, @@ -1161,7 +1161,7 @@ impl cosmic::Application for CosmicNetworkApplet { .map(Message::NetworkManagerEvent), ]) } else { - Subscription::batch(vec![timeline, network_sub, token_sub]) + Subscription::batch([timeline, network_sub, token_sub]) } } diff --git a/cosmic-applet-network/src/network_manager/available_wifi.rs b/cosmic-applet-network/src/network_manager/available_wifi.rs index e43c54708..c6be87629 100644 --- a/cosmic-applet-network/src/network_manager/available_wifi.rs +++ b/cosmic-applet-network/src/network_manager/available_wifi.rs @@ -9,7 +9,6 @@ use cosmic_dbus_networkmanager::{ }; use futures_util::StreamExt; -use itertools::Itertools; use std::collections::HashMap; use zbus::zvariant::ObjectPath; @@ -37,7 +36,7 @@ pub async fn handle_wireless_device( // Sort by strength and remove duplicates let mut aps = HashMap::::new(); for ap in access_points { - let ssid = String::from_utf8_lossy(&ap.ssid().await?.clone()).into_owned(); + let ssid = String::from_utf8_lossy(ap.ssid().await?.as_slice()).into_owned(); let wps_push = ap.flags().await?.contains(ApFlags::WPS_PBC); let strength = ap.strength().await?; if let Some(access_point) = aps.get(&ssid) { @@ -77,10 +76,8 @@ pub async fn handle_wireless_device( }, ); } - let aps = aps - .into_values() - .sorted_by(|a, b| b.strength.cmp(&a.strength)) - .collect(); + let mut aps = aps.into_values().collect::>(); + aps.sort_unstable_by_key(|ap| ap.strength); Ok(aps) } diff --git a/cosmic-applet-network/src/network_manager/current_networks.rs b/cosmic-applet-network/src/network_manager/current_networks.rs index 95243aa21..a92e04182 100644 --- a/cosmic-applet-network/src/network_manager/current_networks.rs +++ b/cosmic-applet-network/src/network_manager/current_networks.rs @@ -71,15 +71,7 @@ pub async fn active_connections( } } - info.sort_by(|a, b| { - let helper = |conn: &ActiveConnectionInfo| match conn { - ActiveConnectionInfo::Vpn { name, .. } => format!("0{name}"), - ActiveConnectionInfo::Wired { name, .. } => format!("1{name}"), - ActiveConnectionInfo::WiFi { name, .. } => format!("2{name}"), - }; - helper(a).cmp(&helper(b)) - }); - + info.sort_unstable(); Ok(info) } @@ -107,16 +99,74 @@ pub enum ActiveConnectionInfo { impl ActiveConnectionInfo { pub fn name(&self) -> String { match &self { - Self::Wired { name, .. } => name.clone(), - Self::WiFi { name, .. } => name.clone(), - Self::Vpn { name, .. } => name.clone(), + Self::Wired { name, .. } | Self::WiFi { name, .. } | Self::Vpn { name, .. } => { + name.clone() + } } } pub fn hw_address(&self) -> HwAddress { match &self { - Self::Wired { hw_address, .. } => *hw_address, - Self::WiFi { hw_address, .. } => *hw_address, + Self::Wired { hw_address, .. } | Self::WiFi { hw_address, .. } => *hw_address, Self::Vpn { .. } => HwAddress::default(), } } } + +impl std::cmp::Ord for ActiveConnectionInfo { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + match (self, other) { + (Self::Vpn { .. }, Self::Wired { .. } | Self::WiFi { .. }) + | (Self::Wired { .. }, Self::WiFi { .. }) => std::cmp::Ordering::Greater, + + (Self::WiFi { .. }, Self::Wired { .. } | Self::Vpn { .. }) + | (Self::Wired { .. }, Self::Vpn { .. }) => std::cmp::Ordering::Less, + + (Self::Vpn { name: n1, .. }, Self::Vpn { name: n2, .. }) + | (Self::Wired { name: n1, .. }, Self::Wired { name: n2, .. }) + | (Self::WiFi { name: n1, .. }, Self::WiFi { name: n2, .. }) => n1.cmp(n2), + } + } +} + +impl std::cmp::Eq for ActiveConnectionInfo {} + +impl std::cmp::PartialOrd for ActiveConnectionInfo { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl std::cmp::PartialEq for ActiveConnectionInfo { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + ( + Self::Wired { + name: n1, + hw_address: a1, + .. + }, + Self::Wired { + name: n2, + hw_address: a2, + .. + }, + ) + | ( + Self::WiFi { + name: n1, + hw_address: a1, + .. + }, + Self::WiFi { + name: n2, + hw_address: a2, + .. + }, + ) => n1 == n2 && a1 == a2, + + (Self::Vpn { name: n1, .. }, Self::Vpn { name: n2, .. }) => n1 == n2, + + _ => false, + } + } +} diff --git a/cosmic-applet-network/src/network_manager/mod.rs b/cosmic-applet-network/src/network_manager/mod.rs index f75c8081c..96f28f2be 100644 --- a/cosmic-applet-network/src/network_manager/mod.rs +++ b/cosmic-applet-network/src/network_manager/mod.rs @@ -263,10 +263,9 @@ async fn start_listening( let settings = c.get_settings().await.ok().unwrap_or_default(); let s = Settings::new(settings); if s.wifi - .clone() - .and_then(|w| w.ssid) - .and_then(|ssid| String::from_utf8(ssid).ok()) - .is_some_and(|s| s == ssid) + .as_ref() + .and_then(|w| w.ssid.as_deref()) + .is_some_and(|s| std::str::from_utf8(s).is_ok_and(|s| s == ssid)) { // todo most likely we can here forget ssid from wrong hw_address _ = c.delete().await; @@ -421,7 +420,7 @@ impl NetworkManagerState { let s = NetworkManagerSettings::new(conn).await?; _ = s.load_connections(&[]).await; let known_conns = s.list_connections().await.unwrap_or_default(); - let mut active_conns = active_connections( + let active_conns = active_connections( network_manager .active_connections() .await @@ -429,14 +428,7 @@ impl NetworkManagerState { ) .await .unwrap_or_default(); - active_conns.sort_by(|a, b| { - let helper = |conn: &ActiveConnectionInfo| match conn { - ActiveConnectionInfo::Vpn { name, .. } => format!("0{name}"), - ActiveConnectionInfo::Wired { name, .. } => format!("1{name}"), - ActiveConnectionInfo::WiFi { name, .. } => format!("2{name}"), - }; - helper(a).cmp(&helper(b)) - }); + // active_conns.sort(); active_connections should have already sorted the vector let devices = network_manager.devices().await.ok().unwrap_or_default(); let wireless_access_point_futures: Vec<_> = devices .into_iter() @@ -483,7 +475,7 @@ impl NetworkManagerState { }) .cloned() .collect(); - wireless_access_points.sort_by(|a, b| b.strength.cmp(&a.strength)); + wireless_access_points.sort_by_key(|ap| ap.strength); self_.wireless_access_points = wireless_access_points; for ap in &self_.wireless_access_points { tracing::info!( @@ -519,11 +511,11 @@ impl NetworkManagerState { let nm = NetworkManager::new(conn).await?; for c in nm.active_connections().await.unwrap_or_default() { - if self - .wireless_access_points - .iter() - .any(|w| Ok(Some(w.ssid.clone())) == c.cached_id() && w.hw_address == hw_address) - { + if self.wireless_access_points.iter().any(|w| { + c.cached_id() + .is_ok_and(|opt| opt.is_some_and(|id| id == w.ssid)) + && w.hw_address == hw_address + }) { _ = nm.deactivate_connection(&c).await; } } @@ -556,7 +548,7 @@ impl NetworkManagerState { HashMap::from([ ("identity", Value::Str(identity.into())), // most common default - ("eap", Value::Array(vec!["peap"].into())), + ("eap", Value::Array(["peap"].as_slice().into())), // most common default ("phase2-auth", Value::Str("mschapv2".into())), ("password", Value::Str(password.unwrap_or("").into())), @@ -605,16 +597,13 @@ impl NetworkManagerState { let s = Settings::new(settings); // todo try to add hw_address comparing here if it changes anything - if let Some(cur_ssid) = s - .wifi - .clone() - .and_then(|w| w.ssid) - .and_then(|ssid| String::from_utf8(ssid).ok()) + if s.wifi + .as_ref() + .and_then(|w| w.ssid.as_deref()) + .is_some_and(|s| std::str::from_utf8(s).is_ok_and(|cur_ssid| cur_ssid == ssid)) { - if cur_ssid == ssid { - known_conn = Some(c); - break; - } + known_conn = Some(c); + break; } } diff --git a/cosmic-applet-notifications/src/lib.rs b/cosmic-applet-notifications/src/lib.rs index 64a7dcd13..19782f0ca 100644 --- a/cosmic-applet-notifications/src/lib.rs +++ b/cosmic-applet-notifications/src/lib.rs @@ -56,7 +56,7 @@ struct Notifications { impl Notifications { fn update_cards(&mut self, id: id::Cards) { - if let Some((id, _, card_value, ..)) = self.cards.iter_mut().find(|c| c.0 == id) { + if let Some((id, _, card_value, ..)) = self.cards.iter().find(|c| c.0 == id) { let chain = if *card_value { chain::Cards::on(id.clone(), 1.) } else { @@ -152,7 +152,7 @@ impl cosmic::Application for Notifications { } fn subscription(&self) -> Subscription { - Subscription::batch(vec![ + Subscription::batch([ self.core .watch_config(cosmic_notifications_config::ID) .map(|res| { @@ -217,7 +217,7 @@ impl cosmic::Application for Notifications { c.1.push(n); c.3 = fl!( "show-more", - HashMap::from_iter(vec![("more", c.1.len().saturating_sub(1))]) + HashMap::from([("more", c.1.len().saturating_sub(1))]) ); } } else { @@ -225,7 +225,7 @@ impl cosmic::Application for Notifications { id::Cards::new(n.app_name.clone()), vec![n], false, - fl!("show-more", HashMap::from_iter(vec![("more", "1")])), + fl!("show-more", HashMap::from([("more", "1")])), fl!("show-less"), fl!("clear-group"), )); @@ -263,7 +263,7 @@ impl cosmic::Application for Notifications { c.1.retain(|n| n.id != id); c.3 = fl!( "show-more", - HashMap::from_iter(vec![("more", c.1.len().saturating_sub(1))]) + HashMap::from([("more", c.1.len().saturating_sub(1))]) ); } self.cards.retain(|c| !c.1.is_empty()); @@ -581,9 +581,9 @@ fn duration_ago_msg(notification: &Notification) -> String { let min = d.as_secs() / 60; let hrs = min / 60; if hrs > 0 { - fl!("hours-ago", HashMap::from_iter(vec![("duration", hrs)])) + fl!("hours-ago", HashMap::from([("duration", hrs)])) } else { - fl!("minutes-ago", HashMap::from_iter(vec![("duration", min)])) + fl!("minutes-ago", HashMap::from([("duration", min)])) } } else { String::new() diff --git a/cosmic-applet-notifications/src/subscriptions/notifications.rs b/cosmic-applet-notifications/src/subscriptions/notifications.rs index 67846cd7e..a945e4490 100644 --- a/cosmic-applet-notifications/src/subscriptions/notifications.rs +++ b/cosmic-applet-notifications/src/subscriptions/notifications.rs @@ -80,7 +80,7 @@ pub fn notifications(proxy: NotificationsAppletProxy<'static>) -> Subscription { if let Some(msg) = v { - let Some(args) = msg.args().into_iter().next() else { + let Ok(args) = msg.args() else { break; }; let notification = Notification::new( diff --git a/cosmic-applet-status-area/src/components/app.rs b/cosmic-applet-status-area/src/components/app.rs index 29430d863..4240f2aee 100644 --- a/cosmic-applet-status-area/src/components/app.rs +++ b/cosmic-applet-status-area/src/components/app.rs @@ -380,8 +380,7 @@ impl cosmic::Application for App { } self.overflow_popup = Some(popup_id); - let cmds = vec![get_popup(popup_settings)]; - return Task::batch(cmds); + return get_popup(popup_settings); } else { return Task::none(); } diff --git a/cosmic-applet-tiling/src/window.rs b/cosmic-applet-tiling/src/window.rs index 13d333ecd..7a081cce8 100644 --- a/cosmic-applet-tiling/src/window.rs +++ b/cosmic-applet-tiling/src/window.rs @@ -132,7 +132,7 @@ impl cosmic::Application for Window { .timeline .as_subscription() .map(|(_, now)| Message::Frame(now)); - Subscription::batch(vec![ + Subscription::batch([ timeline, self.core .watch_config::("com.system76.CosmicComp") diff --git a/cosmic-applet-time/src/window.rs b/cosmic-applet-time/src/window.rs index b28d08fb2..2353db267 100644 --- a/cosmic-applet-time/src/window.rs +++ b/cosmic-applet-time/src/window.rs @@ -125,12 +125,11 @@ impl Window { first_day_of_week, ); - let mut day_iter = first_day.iter_days(); + let day_iter = first_day.iter_days(); let prefs = DateTimeFormatterPreferences::from(self.locale.clone()); let weekday = DateTimeFormatter::try_new(prefs, fieldsets::E::short()).unwrap(); - for _ in 0..7 { - let date = day_iter.next().unwrap(); + for date in day_iter.take(7) { let datetime = self.create_datetime(&date); calendar = calendar.push( text::caption(weekday.format(&datetime).to_string()) @@ -447,7 +446,7 @@ impl cosmic::Application for Window { } let show_seconds_rx = self.show_seconds_tx.subscribe(); - Subscription::batch(vec![ + Subscription::batch([ rectangle_tracker_subscription(0).map(|e| Message::Rectangle(e.1)), time_subscription(show_seconds_rx), activation_token_subscription(0).map(Message::Token), diff --git a/cosmic-applet-workspaces/src/components/app.rs b/cosmic-applet-workspaces/src/components/app.rs index e3241d937..b3a73e40c 100644 --- a/cosmic-applet-workspaces/src/components/app.rs +++ b/cosmic-applet-workspaces/src/components/app.rs @@ -351,7 +351,7 @@ impl cosmic::Application for IcedWorkspacesApplet { } fn subscription(&self) -> Subscription { - Subscription::batch(vec![ + Subscription::batch([ workspaces().map(Message::WorkspaceUpdate), event::listen_with(|e, _, _| match e { Mouse(mouse::Event::WheelScrolled { delta }) => Some(Message::WheelScrolled(delta)),