status bar
git clone https://git.lucas.co/cce-status-interface.git
chore: clippy-clean; import WidgetHostExt
Clippy with warnings as errors passes on every target: cce-ui's house-style
allowances (too many arguments, complex types) in [lints.clippy], clippy's own
mechanical fixes (is_none_or, as_chunks, is_multiple_of, next_back, a copied
Copy value, a collapsed if), and the context menu's unwrap after is_some
rewritten as if-let. color() moved to cce_ui::widget::WidgetHostExt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cargo.toml | 6 ++++++
src/bin/cce-xembed-tray/x11.rs | 8 ++++----
src/main.rs | 29 ++++++++++-------------------
src/tray.rs | 8 ++++----
4 files changed, 24 insertions(+), 27 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
index a236ee8..8fe6f96 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -37,3 +37,9 @@ x11rb = { version = "0.13", features = ["damage", "shape", "xfixes"] }
+
+[lints.clippy]
+# The toolkit's house style (cce-ui's [lints.clippy]): geometry, colour and paint state
+# taken piecewise, and the legacy tuple views.
+too_many_arguments = "allow"
+type_complexity = "allow"
diff --git a/src/bin/cce-xembed-tray/x11.rs b/src/bin/cce-xembed-tray/x11.rs
index 5130bef..42f7aea 100644
--- a/src/bin/cce-xembed-tray/x11.rs
+++ b/src/bin/cce-xembed-tray/x11.rs
@@ -636,7 +636,7 @@ impl Tray {
.get_property(false, icon, self.atoms._XEMBED_INFO, AtomEnum::ANY, 0, 2)?
.reply()?;
let flags = reply.value32().and_then(|mut v| v.nth(1));
- if flags.map_or(true, |f| f & XEMBED_MAPPED != 0) {
+ if flags.is_none_or(|f| f & XEMBED_MAPPED != 0) {
self.conn.map_window(icon)?;
} else {
self.conn.unmap_window(icon)?;
@@ -676,7 +676,7 @@ impl Tray {
};
let lsb = self.conn.setup().image_byte_order == ImageOrder::LSB_FIRST;
let pixels = to_sni_argb(&reply.data, reply.depth, lsb)?;
- if pixels.chunks_exact(4).all(|p| p[0] == 0) {
+ if pixels.as_chunks::<4>().0.iter().all(|p| p[0] == 0) {
return None;
}
let entry = self.icons.get_mut(&icon)?;
@@ -721,11 +721,11 @@ fn clamp_i16(v: i32) -> i16 {
/// order, straight alpha. X's ARGB visuals are premultiplied; a depth-24
/// image has no alpha and is opaque. `None` for any other layout.
pub fn to_sni_argb(data: &[u8], depth: u8, lsb_first: bool) -> Option<Vec<u8>> {
- if data.len() % 4 != 0 || !(depth == 24 || depth == 32) {
+ if !data.len().is_multiple_of(4) || !(depth == 24 || depth == 32) {
return None;
}
let mut out = Vec::with_capacity(data.len());
- for px in data.chunks_exact(4) {
+ for px in data.as_chunks::<4>().0 {
let bytes = [px[0], px[1], px[2], px[3]];
let v = if lsb_first { u32::from_le_bytes(bytes) } else { u32::from_be_bytes(bytes) };
let a = if depth == 32 { (v >> 24) as u8 } else { 255 };
diff --git a/src/main.rs b/src/main.rs
index 42ea909..d9ef7d0 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -23,10 +23,7 @@ use cce_ui::cosmic_text::{
Attrs, Buffer, FontSystem, Metrics,
};
use cce_ui::color;
-use cce_ui::widget::{
- WidgetHost,
- MouseButton, ElementState, MouseScrollDelta, KeyEvent,
-};
+use cce_ui::widget::{WidgetHost, MouseButton, ElementState, MouseScrollDelta, KeyEvent, WidgetHostExt};
#[derive(Debug, Clone)]
pub struct TrayPixmap {
@@ -764,7 +761,7 @@ impl StatusApp {
return trimmed.to_string();
}
}
- let last_segment = fallback_id.split('/').last().unwrap_or(fallback_id);
+ let last_segment = fallback_id.split('/').next_back().unwrap_or(fallback_id);
let cleaned = last_segment
.split('_')
.next()
@@ -1399,16 +1396,16 @@ impl cce_ui::engine::Application for StatusApp {
// Every module can host an in-surface menu, so every process listens
// for the compositor's click-away dismiss pushes.
tokio::spawn(spawn_status_listener("dismiss".to_string(), sender.clone()));
- let is_primary_for_switcher = selected_module.as_ref().map_or(true, |(name, _)| name == "window");
+ let is_primary_for_switcher = selected_module.as_ref().is_none_or(|(name, _)| name == "window");
if is_primary_for_switcher {
tokio::spawn(spawn_switcher_listener(sender.clone()));
}
- let has_tray = selected_module.as_ref().map_or(true, |(name, _)| name == "tray");
+ let has_tray = selected_module.as_ref().is_none_or(|(name, _)| name == "tray");
if has_tray {
tokio::spawn(spawn_status_tray(sender.clone()));
}
- let has_stats = selected_module.as_ref().map_or(true, |(name, _)| {
+ let has_stats = selected_module.as_ref().is_none_or(|(name, _)| {
name == "stats" || name == "cpu" || name == "memory" || name == "brightness" || name == "volume" || name == "battery" || name == "wifi" || name == "clock"
});
// The backlight and the sink are what a keypress moves, so they get a
@@ -1465,7 +1462,7 @@ impl cce_ui::engine::Application for StatusApp {
sender,
last_config_modified: cce_ui::config::config_files_modified(),
selected_module_name: selected_module.as_ref().map(|(n, _)| n.clone()),
- selected_module_side: selected_module.as_ref().map(|(_, s)| s.clone()),
+ selected_module_side: selected_module.as_ref().map(|(_, s)| *s),
status_hide_mode: false,
adjust_position_mode: false,
seen_renderer: false,
@@ -1890,7 +1887,7 @@ impl cce_ui::engine::Application for StatusApp {
// An open in-surface menu owns every button event: row clicks run
// their action (dispatch / DBusMenu event / page navigation); any
// other press (bar strip, menu padding, right-click) closes.
- if self.context_menu.is_some() {
+ if let Some(menu) = self.context_menu.as_mut() {
if state != ElementState::Pressed {
return None;
}
@@ -1899,15 +1896,10 @@ impl cce_ui::engine::Application for StatusApp {
if self.menu_closing {
return None;
}
- let hit = if button == MouseButton::Left {
- self.context_menu.as_ref().and_then(|m| m.item_at(lx, ly))
- } else {
- None
- };
+ let hit = if button == MouseButton::Left { menu.item_at(lx, ly) } else { None };
let mut result = None;
match hit {
Some(i) => {
- let menu = self.context_menu.as_mut().unwrap();
let action = menu.rows().get(i).map(|r| r.action.clone());
match action {
Some(MenuRowAction::Dispatch(ev)) => {
@@ -2165,12 +2157,11 @@ impl cce_ui::engine::Application for StatusApp {
if button == MouseButton::Left {
let mut clicked_window = false;
for mb in &self.module_bounds {
- if mb.name == "window" {
- if coord >= mb.x && coord <= (mb.x + mb.w) {
+ if mb.name == "window"
+ && coord >= mb.x && coord <= (mb.x + mb.w) {
clicked_window = true;
break;
}
- }
}
if clicked_window {
diff --git a/src/tray.rs b/src/tray.rs
index 8006ccf..727c9e0 100644
--- a/src/tray.rs
+++ b/src/tray.rs
@@ -122,7 +122,7 @@ pub(crate) fn load_png_as_pixmap(path: &std::path::Path) -> Option<TrayPixmap> {
let actual_bytes = &buf[..info.buffer_size()];
match info.color_type {
png::ColorType::Rgba => {
- for chunk in actual_bytes.chunks_exact(4) {
+ for chunk in actual_bytes.as_chunks::<4>().0 {
argb_pixels.push(chunk[3]); // A
argb_pixels.push(chunk[0]); // R
argb_pixels.push(chunk[1]); // G
@@ -130,7 +130,7 @@ pub(crate) fn load_png_as_pixmap(path: &std::path::Path) -> Option<TrayPixmap> {
}
}
png::ColorType::Rgb => {
- for chunk in actual_bytes.chunks_exact(3) {
+ for chunk in actual_bytes.as_chunks::<3>().0 {
argb_pixels.push(255); // A
argb_pixels.push(chunk[0]); // R
argb_pixels.push(chunk[1]); // G
@@ -146,7 +146,7 @@ pub(crate) fn load_png_as_pixmap(path: &std::path::Path) -> Option<TrayPixmap> {
}
}
png::ColorType::GrayscaleAlpha => {
- for chunk in actual_bytes.chunks_exact(2) {
+ for chunk in actual_bytes.as_chunks::<2>().0 {
argb_pixels.push(chunk[1]); // A
argb_pixels.push(chunk[0]); // R
argb_pixels.push(chunk[0]); // G
@@ -183,7 +183,7 @@ pub(crate) fn load_svg_as_pixmap(path: &std::path::Path) -> Option<TrayPixmap> {
let raw_pixels = pixmap.data();
let mut argb_pixels = Vec::with_capacity((target_w * target_h * 4) as usize);
- for chunk in raw_pixels.chunks_exact(4) {
+ for chunk in raw_pixels.as_chunks::<4>().0 {
argb_pixels.push(chunk[3]); // A
argb_pixels.push(chunk[0]); // R
argb_pixels.push(chunk[1]); // G