Compare commits
14 commits
93ab0f391d
...
d35202a885
| Author | SHA1 | Date | |
|---|---|---|---|
| d35202a885 | |||
| a4597a5be4 | |||
| 8b032b9446 | |||
| f299ea5b8e | |||
| 89d4e58754 | |||
| 28e7e2c37e | |||
| 6c24edfae2 | |||
|
|
1c7143af97 | ||
|
|
4f5825b0b2 | ||
|
|
936147ecf6 | ||
|
|
22d6f353f1 | ||
| 28010fd260 | |||
| a7cd859317 | |||
| 5cb0dbb0c5 |
43 changed files with 762 additions and 618 deletions
736
Cargo.lock
generated
736
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
54
Cargo.toml
54
Cargo.toml
|
|
@ -25,11 +25,11 @@ resolver = "3"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
anyhow = "1.0.102"
|
anyhow = "1.0.102"
|
||||||
cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "d0e95be" }
|
cctk = { package = "cosmic-client-toolkit", path = "../cosmic-protocols/client-toolkit" }
|
||||||
cosmic-applets-config = { path = "cosmic-applets-config" }
|
cosmic-applets-config = { path = "cosmic-applets-config" }
|
||||||
cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols", default-features = false, features = [
|
cosmic-protocols = { path = "../cosmic-protocols", default-features = false, features = [
|
||||||
"client",
|
"client",
|
||||||
], rev = "d0e95be" }
|
]}
|
||||||
|
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
futures-util = "0.3"
|
futures-util = "0.3"
|
||||||
|
|
@ -38,7 +38,7 @@ i18n-embed = { version = "0.16.0", features = [
|
||||||
"desktop-requester",
|
"desktop-requester",
|
||||||
] }
|
] }
|
||||||
i18n-embed-fl = "0.10"
|
i18n-embed-fl = "0.10"
|
||||||
libcosmic = { git = "https://github.com/pop-os/libcosmic", default-features = false, features = [
|
cosmic = { package = "libcosmic-yoda", path = "../libcosmic", default-features = false, features = [
|
||||||
"applet",
|
"applet",
|
||||||
"applet-token",
|
"applet-token",
|
||||||
"dbus-config",
|
"dbus-config",
|
||||||
|
|
@ -48,6 +48,7 @@ libcosmic = { git = "https://github.com/pop-os/libcosmic", default-features = fa
|
||||||
"desktop-systemd-scope",
|
"desktop-systemd-scope",
|
||||||
"winit",
|
"winit",
|
||||||
] }
|
] }
|
||||||
|
cosmic-comp-config = { path = "../cosmic-comp/cosmic-comp-config" }
|
||||||
rust-embed = "8.11.0"
|
rust-embed = "8.11.0"
|
||||||
rust-embed-utils = "8.11.0"
|
rust-embed-utils = "8.11.0"
|
||||||
rustc-hash = "2.1"
|
rustc-hash = "2.1"
|
||||||
|
|
@ -58,7 +59,7 @@ tracing-subscriber = { version = "0.3.22", features = ["env-filter"] }
|
||||||
tracing-log = "0.2.0"
|
tracing-log = "0.2.0"
|
||||||
tokio = { version = "1.49.0", features = ["full"] }
|
tokio = { version = "1.49.0", features = ["full"] }
|
||||||
# cosmic-config = { path = "../libcosmic/cosmic-config" }
|
# cosmic-config = { path = "../libcosmic/cosmic-config" }
|
||||||
cosmic-config = { git = "https://github.com/pop-os/libcosmic" }
|
cosmic-config = { path = "../libcosmic/cosmic-config" }
|
||||||
serde = { version = "1.0.228", features = ["derive"] }
|
serde = { version = "1.0.228", features = ["derive"] }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
|
|
@ -82,12 +83,51 @@ ignored = ["libcosmic"]
|
||||||
# winit = { git = "https://github.com/rust-windowing/winit.git", rev = "241b7a80bba96c91fa3901729cd5dec66abb9be4" }
|
# winit = { git = "https://github.com/rust-windowing/winit.git", rev = "241b7a80bba96c91fa3901729cd5dec66abb9be4" }
|
||||||
# winit = { path = "../winit" }
|
# winit = { path = "../winit" }
|
||||||
|
|
||||||
|
[patch."https://github.com/pop-os/libcosmic"]
|
||||||
|
cosmic-config = { path = "/home/lionel/Projets/COSMIC/libcosmic/cosmic-config" }
|
||||||
|
cosmic-theme = { path = "/home/lionel/Projets/COSMIC/libcosmic/cosmic-theme" }
|
||||||
|
iced = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced" }
|
||||||
|
iced_accessibility = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/accessibility" }
|
||||||
|
iced_core = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/core" }
|
||||||
|
iced_futures = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/futures" }
|
||||||
|
iced_graphics = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/graphics" }
|
||||||
|
iced_renderer = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/renderer" }
|
||||||
|
iced_runtime = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/runtime" }
|
||||||
|
iced_tiny_skia = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/tiny_skia" }
|
||||||
|
iced_wgpu = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/wgpu" }
|
||||||
|
iced_widget = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/widget" }
|
||||||
|
iced_winit = { path = "/home/lionel/Projets/COSMIC/libcosmic/iced/winit" }
|
||||||
|
|
||||||
[patch."https://github.com/smithay/client-toolkit.git"]
|
[patch."https://github.com/smithay/client-toolkit.git"]
|
||||||
sctk = { package = "smithay-client-toolkit", version = "0.20.0" }
|
sctk = { package = "smithay-client-toolkit", version = "0.20.0" }
|
||||||
|
|
||||||
[patch."https://github.com/pop-os/cosmic-protocols"]
|
[patch."https://github.com/pop-os/cosmic-protocols"]
|
||||||
cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols//", branch = "main" }
|
cosmic-protocols = { path = "/home/lionel/Projets/COSMIC/cosmic-protocols" }
|
||||||
cosmic-client-toolkit = { git = "https://github.com/pop-os/cosmic-protocols//", branch = "main" }
|
cosmic-client-toolkit = { path = "/home/lionel/Projets/COSMIC/cosmic-protocols/client-toolkit" }
|
||||||
|
|
||||||
|
[patch."https://github.com/pop-os/cosmic-panel"]
|
||||||
|
cosmic-panel-config = { path = "/home/lionel/Projets/COSMIC/cosmic-panel/cosmic-panel-config" }
|
||||||
|
xdg-shell-wrapper-config = { path = "/home/lionel/Projets/COSMIC/cosmic-panel/xdg-shell-wrapper-config" }
|
||||||
|
|
||||||
|
[patch."https://github.com/pop-os/cosmic-notifications"]
|
||||||
|
cosmic-notifications-config = { path = "/home/lionel/Projets/COSMIC/cosmic-notifications/cosmic-notifications-config" }
|
||||||
|
cosmic-notifications-util = { path = "/home/lionel/Projets/COSMIC/cosmic-notifications/cosmic-notifications-util" }
|
||||||
|
|
||||||
|
[patch."https://github.com/pop-os/cosmic-settings"]
|
||||||
|
cosmic-settings-a11y-manager-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/a11y-manager" }
|
||||||
|
cosmic-settings-accessibility-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/accessibility" }
|
||||||
|
cosmic-settings-airplane-mode-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/airplane-mode" }
|
||||||
|
cosmic-settings-daemon-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/settings-daemon" }
|
||||||
|
cosmic-settings-network-manager-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/network-manager" }
|
||||||
|
cosmic-settings-sound-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/sound" }
|
||||||
|
cosmic-settings-upower-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/upower" }
|
||||||
|
|
||||||
|
[patch."https://github.com/pop-os/cosmic-settings/"]
|
||||||
|
cosmic-settings-airplane-mode-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/airplane-mode" }
|
||||||
|
cosmic-settings-network-manager-subscription = { path = "/home/lionel/Projets/COSMIC/cosmic-settings/subscriptions/network-manager" }
|
||||||
|
|
||||||
|
[patch."https://github.com/pop-os/cosmic-text.git"]
|
||||||
|
cosmic-text = { path = "../cosmic-text" }
|
||||||
|
|
||||||
# [patch.'https://github.com/pop-os/dbus-settings-bindings']
|
# [patch.'https://github.com/pop-os/dbus-settings-bindings']
|
||||||
# cosmic-dbus-networkmanager = { path = "../dbus-settings-bindings/networkmanager" }
|
# cosmic-dbus-networkmanager = { path = "../dbus-settings-bindings/networkmanager" }
|
||||||
|
|
|
||||||
|
|
@ -13,13 +13,13 @@ futures.workspace = true
|
||||||
i18n-embed.workspace = true
|
i18n-embed.workspace = true
|
||||||
i18n-embed-fl.workspace = true
|
i18n-embed-fl.workspace = true
|
||||||
image = { version = "0.25.9", default-features = false }
|
image = { version = "0.25.9", default-features = false }
|
||||||
libcosmic.workspace = true
|
cosmic.workspace = true
|
||||||
memmap2 = "0.9.10"
|
memmap2 = "0.9.10"
|
||||||
fastrand = "2.3.0"
|
fastrand = "2.3.0"
|
||||||
rust-embed.workspace = true
|
rust-embed.workspace = true
|
||||||
rustix.workspace = true
|
rustix.workspace = true
|
||||||
rustc-hash.workspace = true
|
rustc-hash.workspace = true
|
||||||
switcheroo-control = { git = "https://github.com/pop-os/dbus-settings-bindings" }
|
switcheroo-control = { path = "../../dbus-settings-bindings/switcheroo-control" }
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
tracing-log.workspace = true
|
tracing-log.workspace = true
|
||||||
tracing-subscriber.workspace = true
|
tracing-subscriber.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -6,5 +6,5 @@ edition = "2024"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libcosmic.workspace = true
|
cosmic.workspace = true
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
|
|
|
||||||
|
|
@ -187,6 +187,11 @@ impl DockItem {
|
||||||
dot_border_radius: [f32; 4],
|
dot_border_radius: [f32; 4],
|
||||||
window_id: window::Id,
|
window_id: window::Id,
|
||||||
filter: Option<&dyn Fn(&ToplevelInfo) -> bool>,
|
filter: Option<&dyn Fn(&ToplevelInfo) -> bool>,
|
||||||
|
// Yoda: multiplier on the computed icon size (1.0 = default,
|
||||||
|
// >1.0 = magnified e.g. on hover for the macOS Tahoe effect).
|
||||||
|
// Applied to the icon's rendered width/height only — indicator
|
||||||
|
// dot and surrounding layout stay at base size.
|
||||||
|
icon_scale: f32,
|
||||||
) -> Element<'_, Message> {
|
) -> Element<'_, Message> {
|
||||||
let Self {
|
let Self {
|
||||||
toplevels,
|
toplevels,
|
||||||
|
|
@ -205,17 +210,35 @@ impl DockItem {
|
||||||
};
|
};
|
||||||
let toplevel_count = filtered_toplevels.len();
|
let toplevel_count = filtered_toplevels.len();
|
||||||
|
|
||||||
|
// Cairo-like : pastille plus petite + atténuée quand toutes les fenêtres
|
||||||
|
// de cette app sont minimisées.
|
||||||
|
let all_minimized = toplevel_count > 0
|
||||||
|
&& filtered_toplevels
|
||||||
|
.iter()
|
||||||
|
.all(|(info, _)| info.state.contains(&State::Minimized));
|
||||||
|
|
||||||
let app_icon = AppletIconData::new(applet);
|
let app_icon = AppletIconData::new(applet);
|
||||||
|
|
||||||
|
// Yoda: scaled icon size for hover magnification. Clamped so
|
||||||
|
// tiny floats don't round to 0 and huge ones stay within u16.
|
||||||
|
let scaled_icon_size = ((f32::from(app_icon.icon_size) * icon_scale).round() as i32)
|
||||||
|
.clamp(1, u16::MAX as i32) as u16;
|
||||||
let cosmic_icon = cosmic::widget::icon(
|
let cosmic_icon = cosmic::widget::icon(
|
||||||
fde::IconSource::from_unknown(desktop_info.icon().unwrap_or_default()).as_cosmic_icon(),
|
fde::IconSource::from_unknown(desktop_info.icon().unwrap_or_default()).as_cosmic_icon(),
|
||||||
)
|
)
|
||||||
// sets the preferred icon size variant
|
// sets the preferred icon size variant
|
||||||
.size(128)
|
.size(128)
|
||||||
.width(app_icon.icon_size.into())
|
.width(scaled_icon_size.into())
|
||||||
.height(app_icon.icon_size.into());
|
.height(scaled_icon_size.into());
|
||||||
|
|
||||||
let indicator = {
|
let indicator = {
|
||||||
|
// Padding réduit quand minimisée → pastille plus petite.
|
||||||
|
let effective_radius = if all_minimized {
|
||||||
|
(app_icon.dot_radius * 0.55).max(1.0)
|
||||||
|
} else {
|
||||||
|
app_icon.dot_radius
|
||||||
|
};
|
||||||
|
|
||||||
let container = if toplevel_count <= 1 {
|
let container = if toplevel_count <= 1 {
|
||||||
vertical_space().height(Length::Fixed(0.0))
|
vertical_space().height(Length::Fixed(0.0))
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -229,22 +252,34 @@ impl DockItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.padding(app_icon.dot_radius);
|
.padding(effective_radius);
|
||||||
|
|
||||||
if toplevel_count == 0 {
|
if toplevel_count == 0 {
|
||||||
container
|
container
|
||||||
} else {
|
} else {
|
||||||
container.class(theme::Container::custom(move |theme| container::Style {
|
container.class(theme::Container::custom(move |theme| {
|
||||||
background: if is_focused {
|
let cosmic = theme.cosmic();
|
||||||
Some(Background::Color(theme.cosmic().accent_color().into()))
|
let accent: iced::Color = cosmic.accent_color().into();
|
||||||
|
let on_bg: iced::Color = cosmic.on_bg_color().into();
|
||||||
|
// Teinte neutre atténuée quand toutes les fenêtres sont minimisées.
|
||||||
|
let muted = iced::Color { a: 0.45, ..on_bg };
|
||||||
|
|
||||||
|
let fill = if all_minimized {
|
||||||
|
muted
|
||||||
|
} else if is_focused {
|
||||||
|
accent
|
||||||
} else {
|
} else {
|
||||||
Some(Background::Color(theme.cosmic().on_bg_color().into()))
|
on_bg
|
||||||
},
|
};
|
||||||
border: Border {
|
|
||||||
radius: dot_border_radius.into(),
|
container::Style {
|
||||||
|
background: Some(Background::Color(fill)),
|
||||||
|
border: Border {
|
||||||
|
radius: dot_border_radius.into(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
}
|
||||||
..Default::default()
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -374,6 +409,21 @@ struct CosmicAppList {
|
||||||
output_list: FxHashMap<WlOutput, OutputInfo>,
|
output_list: FxHashMap<WlOutput, OutputInfo>,
|
||||||
locales: Vec<String>,
|
locales: Vec<String>,
|
||||||
hovered_toplevel: Option<ExtForeignToplevelHandleV1>,
|
hovered_toplevel: Option<ExtForeignToplevelHandleV1>,
|
||||||
|
/// Yoda: which dock icon the pointer is currently over (for hover
|
||||||
|
/// magnification). None = no dock icon hovered.
|
||||||
|
hovered_dock_item: Option<DockItemId>,
|
||||||
|
/// Yoda: animated "virtual cursor" center used by the fisheye
|
||||||
|
/// formula — lerps toward the real hovered icon's center on each
|
||||||
|
/// AnimTick, so the bell curve slides smoothly from one icon to the
|
||||||
|
/// next instead of snapping.
|
||||||
|
anim_hover_center: Option<(f32, f32)>,
|
||||||
|
/// Yoda: fade-in/out intensity of the magnification effect
|
||||||
|
/// (0.0 = icons flat, 1.0 = full fisheye). Targets 1.0 while the
|
||||||
|
/// pointer is over any dock icon, 0.0 otherwise. Lerped on AnimTick.
|
||||||
|
anim_hover_intensity: f32,
|
||||||
|
/// Yoda: timestamp of the last AnimTick, for dt-based exponential
|
||||||
|
/// smoothing. `None` on first tick.
|
||||||
|
anim_last_tick: Option<std::time::Instant>,
|
||||||
overflow_favorites_popup: Option<window::Id>,
|
overflow_favorites_popup: Option<window::Id>,
|
||||||
overflow_active_popup: Option<window::Id>,
|
overflow_active_popup: Option<window::Id>,
|
||||||
}
|
}
|
||||||
|
|
@ -385,10 +435,18 @@ pub enum PopupType {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
#[allow(dead_code)]
|
||||||
enum Message {
|
enum Message {
|
||||||
Wayland(WaylandUpdate),
|
Wayland(WaylandUpdate),
|
||||||
PinApp(u32),
|
PinApp(u32),
|
||||||
UnpinApp(u32),
|
UnpinApp(u32),
|
||||||
|
/// Yoda: pointer entered (Some) or left (None) a dock icon — drives
|
||||||
|
/// the macOS Tahoe-style hover magnification effect.
|
||||||
|
DockItemHover(Option<DockItemId>),
|
||||||
|
/// Yoda: ticked at ~60fps by the animation subscription. Advances
|
||||||
|
/// anim_hover_center + anim_hover_intensity toward their targets so
|
||||||
|
/// the fisheye effect transitions smoothly instead of snapping.
|
||||||
|
AnimTick(std::time::Instant),
|
||||||
Popup(u32, window::Id),
|
Popup(u32, window::Id),
|
||||||
Pressed(window::Id),
|
Pressed(window::Id),
|
||||||
ToplevelListPopup(u32, window::Id),
|
ToplevelListPopup(u32, window::Id),
|
||||||
|
|
@ -647,6 +705,79 @@ impl CosmicAppList {
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Yoda: macOS-Tahoe fisheye-style magnification. Returns the
|
||||||
|
/// per-icon size multiplier based on the distance (in pixels) from
|
||||||
|
/// the currently hovered icon's center to this icon's center.
|
||||||
|
///
|
||||||
|
/// Uses a gaussian bell curve so the hovered icon peaks at
|
||||||
|
/// 1.0 + PEAK, immediate neighbors still bulge noticeably, and icons
|
||||||
|
/// further away relax back to 1.0× — that's the smooth neighbour
|
||||||
|
/// deformation people associate with the macOS Dock.
|
||||||
|
///
|
||||||
|
/// Falls back to binary 1.3×/1.0× when the rectangle tracker hasn't
|
||||||
|
/// populated yet (first render, or just after layout changes).
|
||||||
|
///
|
||||||
|
/// Uses the animated hover center (anim_hover_center) and intensity
|
||||||
|
/// (anim_hover_intensity) so inter-icon transitions slide smoothly
|
||||||
|
/// and the whole effect fades in/out at the dock's edges.
|
||||||
|
fn icon_scale_for(&self, id: &DockItemId) -> f32 {
|
||||||
|
const PEAK: f32 = 0.35;
|
||||||
|
// sigma expressed in multiples of the hovered icon's size —
|
||||||
|
// 1.4 means the ±1 neighbors sit ~0.7σ away and still bulge
|
||||||
|
// visibly, while ±3+ has collapsed to ~1.0× (fisheye footprint
|
||||||
|
// close to 5 icons wide, Tahoe-ish).
|
||||||
|
const SIGMA_FACTOR: f32 = 1.4;
|
||||||
|
|
||||||
|
// No intensity at all → skip the rest.
|
||||||
|
if self.anim_hover_intensity < 0.001 {
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prefer the animated center (smooth); fall back to the real
|
||||||
|
// hovered icon's center (first render, before tick fires).
|
||||||
|
let hover_center = self.anim_hover_center.or_else(|| {
|
||||||
|
let hovered_id = self.hovered_dock_item.as_ref()?;
|
||||||
|
let r = self.rectangles.get(hovered_id)?;
|
||||||
|
Some((r.x + r.width / 2.0, r.y + r.height / 2.0))
|
||||||
|
});
|
||||||
|
let Some(hover_center) = hover_center else {
|
||||||
|
// No coords yet — visibly peak on the exact hovered id so
|
||||||
|
// the very first frame still responds.
|
||||||
|
return if self.hovered_dock_item.as_ref() == Some(id) {
|
||||||
|
1.0 + PEAK * self.anim_hover_intensity
|
||||||
|
} else {
|
||||||
|
1.0
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
let this_rect = match self.rectangles.get(id) {
|
||||||
|
Some(r) => r,
|
||||||
|
None => return 1.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let is_horizontal = matches!(
|
||||||
|
self.core.applet.anchor,
|
||||||
|
PanelAnchor::Top | PanelAnchor::Bottom
|
||||||
|
);
|
||||||
|
let this_center = if is_horizontal {
|
||||||
|
this_rect.x + this_rect.width / 2.0
|
||||||
|
} else {
|
||||||
|
this_rect.y + this_rect.height / 2.0
|
||||||
|
};
|
||||||
|
let hover_axis = if is_horizontal { hover_center.0 } else { hover_center.1 };
|
||||||
|
let distance = (this_center - hover_axis).abs();
|
||||||
|
let icon_extent = if is_horizontal {
|
||||||
|
this_rect.width
|
||||||
|
} else {
|
||||||
|
this_rect.height
|
||||||
|
}
|
||||||
|
.max(1.0);
|
||||||
|
let sigma = icon_extent * SIGMA_FACTOR;
|
||||||
|
// exp(-t²) bell curve, t = distance / sigma
|
||||||
|
let t = distance / sigma;
|
||||||
|
1.0 + PEAK * self.anim_hover_intensity * (-t * t).exp()
|
||||||
|
}
|
||||||
|
|
||||||
fn is_on_current_monitor_and_workspace(&self, toplevel_info: &ToplevelInfo) -> bool {
|
fn is_on_current_monitor_and_workspace(&self, toplevel_info: &ToplevelInfo) -> bool {
|
||||||
use cosmic_app_list_config::ToplevelFilter;
|
use cosmic_app_list_config::ToplevelFilter;
|
||||||
|
|
||||||
|
|
@ -1582,6 +1713,52 @@ impl cosmic::Application for CosmicAppList {
|
||||||
Message::GpuRequest(gpus) => {
|
Message::GpuRequest(gpus) => {
|
||||||
self.gpus = gpus;
|
self.gpus = gpus;
|
||||||
}
|
}
|
||||||
|
Message::DockItemHover(id) => {
|
||||||
|
self.hovered_dock_item = id;
|
||||||
|
// Seed the animated center on the very first hover so
|
||||||
|
// the bell doesn't "fly in" from (0,0).
|
||||||
|
if self.anim_hover_center.is_none()
|
||||||
|
&& let Some(hovered_id) = self.hovered_dock_item.as_ref()
|
||||||
|
&& let Some(r) = self.rectangles.get(hovered_id)
|
||||||
|
{
|
||||||
|
self.anim_hover_center = Some((
|
||||||
|
r.x + r.width / 2.0,
|
||||||
|
r.y + r.height / 2.0,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Message::AnimTick(now) => {
|
||||||
|
// dt-based exponential smoothing: reach ~99% of the
|
||||||
|
// target in ~120ms at 60fps (about 7 ticks).
|
||||||
|
let dt = self
|
||||||
|
.anim_last_tick
|
||||||
|
.map(|prev| now.saturating_duration_since(prev).as_secs_f32())
|
||||||
|
.unwrap_or(0.016)
|
||||||
|
.min(0.1); // clamp so a long pause doesn't snap
|
||||||
|
self.anim_last_tick = Some(now);
|
||||||
|
|
||||||
|
// Intensity: target 1.0 when any icon is hovered, 0.0 else.
|
||||||
|
let intensity_target = if self.hovered_dock_item.is_some() { 1.0 } else { 0.0 };
|
||||||
|
let tau = 0.060_f32; // time-constant (s); smaller = snappier
|
||||||
|
let alpha = 1.0 - (-dt / tau).exp();
|
||||||
|
self.anim_hover_intensity += (intensity_target - self.anim_hover_intensity) * alpha;
|
||||||
|
|
||||||
|
// Hovered-center smoothing: chase the real rect's center.
|
||||||
|
if let Some(hovered_id) = self.hovered_dock_item.as_ref()
|
||||||
|
&& let Some(r) = self.rectangles.get(hovered_id)
|
||||||
|
{
|
||||||
|
let target = (r.x + r.width / 2.0, r.y + r.height / 2.0);
|
||||||
|
let current = self.anim_hover_center.unwrap_or(target);
|
||||||
|
self.anim_hover_center = Some((
|
||||||
|
current.0 + (target.0 - current.0) * alpha,
|
||||||
|
current.1 + (target.1 - current.1) * alpha,
|
||||||
|
));
|
||||||
|
} else if self.anim_hover_intensity < 0.01 {
|
||||||
|
// Nothing hovered + intensity faded out → forget the
|
||||||
|
// animated center so the next hover seeds fresh.
|
||||||
|
self.anim_hover_center = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
Message::OpenActive => {
|
Message::OpenActive => {
|
||||||
let create_new = self.overflow_active_popup.is_none();
|
let create_new = self.overflow_active_popup.is_none();
|
||||||
let mut cmds = vec![self.close_popups()];
|
let mut cmds = vec![self.close_popups()];
|
||||||
|
|
@ -1763,7 +1940,9 @@ impl cosmic::Application for CosmicAppList {
|
||||||
.filter(|(info, _)| self.is_on_current_monitor_and_workspace(info))
|
.filter(|(info, _)| self.is_on_current_monitor_and_workspace(info))
|
||||||
.any(|y| focused_item.contains(&y.0.foreign_toplevel));
|
.any(|y| focused_item.contains(&y.0.foreign_toplevel));
|
||||||
|
|
||||||
self.core
|
let dock_id = dock_item.id;
|
||||||
|
let icon_scale = self.icon_scale_for(&DockItemId::from(dock_id));
|
||||||
|
let tooltip = self.core
|
||||||
.applet
|
.applet
|
||||||
.applet_tooltip::<Message>(
|
.applet_tooltip::<Message>(
|
||||||
dock_item.as_icon(
|
dock_item.as_icon(
|
||||||
|
|
@ -1776,6 +1955,7 @@ impl cosmic::Application for CosmicAppList {
|
||||||
dot_radius,
|
dot_radius,
|
||||||
self.core.main_window_id().unwrap(),
|
self.core.main_window_id().unwrap(),
|
||||||
Some(&|info| self.is_on_current_monitor_and_workspace(info)),
|
Some(&|info| self.is_on_current_monitor_and_workspace(info)),
|
||||||
|
icon_scale,
|
||||||
),
|
),
|
||||||
dock_item
|
dock_item
|
||||||
.desktop_info
|
.desktop_info
|
||||||
|
|
@ -1785,7 +1965,10 @@ impl cosmic::Application for CosmicAppList {
|
||||||
self.popup.is_some(),
|
self.popup.is_some(),
|
||||||
Message::Surface,
|
Message::Surface,
|
||||||
None,
|
None,
|
||||||
)
|
);
|
||||||
|
cosmic::widget::mouse_area(tooltip)
|
||||||
|
.on_enter(Message::DockItemHover(Some(DockItemId::from(dock_id))))
|
||||||
|
.on_exit(Message::DockItemHover(None))
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
@ -1836,6 +2019,10 @@ impl cosmic::Application for CosmicAppList {
|
||||||
dot_radius,
|
dot_radius,
|
||||||
self.core.main_window_id().unwrap(),
|
self.core.main_window_id().unwrap(),
|
||||||
Some(&|info| self.is_on_current_monitor_and_workspace(info)),
|
Some(&|info| self.is_on_current_monitor_and_workspace(info)),
|
||||||
|
// Yoda: no magnification on DnD-preview icons — these
|
||||||
|
// float around as the user drags, so static 1.0 is
|
||||||
|
// less visually confusing.
|
||||||
|
1.0,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else if self.is_listening_for_dnd && self.pinned_list.is_empty() {
|
} else if self.is_listening_for_dnd && self.pinned_list.is_empty() {
|
||||||
|
|
@ -1875,8 +2062,10 @@ impl cosmic::Application for CosmicAppList {
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(info, _)| self.is_on_current_monitor_and_workspace(info))
|
.filter(|(info, _)| self.is_on_current_monitor_and_workspace(info))
|
||||||
.any(|y| focused_item.contains(&y.0.foreign_toplevel));
|
.any(|y| focused_item.contains(&y.0.foreign_toplevel));
|
||||||
|
let dock_id = dock_item.id;
|
||||||
|
let icon_scale = self.icon_scale_for(&DockItemId::from(dock_id));
|
||||||
|
|
||||||
self.core
|
let tooltip = self.core
|
||||||
.applet
|
.applet
|
||||||
.applet_tooltip(
|
.applet_tooltip(
|
||||||
dock_item.as_icon(
|
dock_item.as_icon(
|
||||||
|
|
@ -1889,6 +2078,7 @@ impl cosmic::Application for CosmicAppList {
|
||||||
dot_radius,
|
dot_radius,
|
||||||
self.core.main_window_id().unwrap(),
|
self.core.main_window_id().unwrap(),
|
||||||
Some(&|info| self.is_on_current_monitor_and_workspace(info)),
|
Some(&|info| self.is_on_current_monitor_and_workspace(info)),
|
||||||
|
icon_scale,
|
||||||
),
|
),
|
||||||
dock_item
|
dock_item
|
||||||
.desktop_info
|
.desktop_info
|
||||||
|
|
@ -1898,7 +2088,10 @@ impl cosmic::Application for CosmicAppList {
|
||||||
self.popup.is_some(),
|
self.popup.is_some(),
|
||||||
Message::Surface,
|
Message::Surface,
|
||||||
None,
|
None,
|
||||||
)
|
);
|
||||||
|
cosmic::widget::mouse_area(tooltip)
|
||||||
|
.on_enter(Message::DockItemHover(Some(DockItemId::from(dock_id))))
|
||||||
|
.on_exit(Message::DockItemHover(None))
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
@ -2313,6 +2506,10 @@ impl cosmic::Application for CosmicAppList {
|
||||||
dot_radius,
|
dot_radius,
|
||||||
id,
|
id,
|
||||||
Some(&|info| self.is_on_current_monitor_and_workspace(info)),
|
Some(&|info| self.is_on_current_monitor_and_workspace(info)),
|
||||||
|
// Yoda: icons in the overflow popup are
|
||||||
|
// already smaller-grid — keep them at 1.0
|
||||||
|
// so the popup doesn't reshuffle on hover.
|
||||||
|
1.0,
|
||||||
),
|
),
|
||||||
dock_item
|
dock_item
|
||||||
.desktop_info
|
.desktop_info
|
||||||
|
|
@ -2421,6 +2618,10 @@ impl cosmic::Application for CosmicAppList {
|
||||||
dot_radius,
|
dot_radius,
|
||||||
id,
|
id,
|
||||||
Some(&|info| self.is_on_current_monitor_and_workspace(info)),
|
Some(&|info| self.is_on_current_monitor_and_workspace(info)),
|
||||||
|
// Yoda: popup icons stay at 1.0 (hover
|
||||||
|
// magnification is applied to the main
|
||||||
|
// dock row only).
|
||||||
|
1.0,
|
||||||
),
|
),
|
||||||
dock_item
|
dock_item
|
||||||
.desktop_info
|
.desktop_info
|
||||||
|
|
@ -2479,7 +2680,21 @@ impl cosmic::Application for CosmicAppList {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn subscription(&self) -> Subscription<Message> {
|
fn subscription(&self) -> Subscription<Message> {
|
||||||
|
// Yoda: ~60fps animation ticks for the fisheye magnification.
|
||||||
|
// Only emitted when an animation is actually in progress (hover
|
||||||
|
// intensity >0 OR still fading out) — keeps the panel idle when
|
||||||
|
// the pointer is nowhere near the dock.
|
||||||
|
let anim_active = self.hovered_dock_item.is_some()
|
||||||
|
|| self.anim_hover_intensity > 0.001;
|
||||||
|
let anim_subscription = if anim_active {
|
||||||
|
cosmic::iced::time::every(std::time::Duration::from_millis(16))
|
||||||
|
.map(Message::AnimTick)
|
||||||
|
} else {
|
||||||
|
Subscription::none()
|
||||||
|
};
|
||||||
|
|
||||||
Subscription::batch([
|
Subscription::batch([
|
||||||
|
anim_subscription,
|
||||||
wayland_subscription().map(Message::Wayland),
|
wayland_subscription().map(Message::Wayland),
|
||||||
listen_with(|e, _, id| match e {
|
listen_with(|e, _, id| match e {
|
||||||
cosmic::iced::core::Event::PlatformSpecific(event::PlatformSpecific::Wayland(
|
cosmic::iced::core::Event::PlatformSpecific(event::PlatformSpecific::Wayland(
|
||||||
|
|
|
||||||
|
|
@ -388,7 +388,10 @@ impl CaptureData {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
self.conn.flush().unwrap();
|
if let Err(err) = self.conn.flush() {
|
||||||
|
tracing::error!("Wayland flush failed during screencopy session create: {err}");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
let formats = session
|
let formats = session
|
||||||
.wait_while(|data| data.formats.is_none())
|
.wait_while(|data| data.formats.is_none())
|
||||||
|
|
@ -437,7 +440,10 @@ impl CaptureData {
|
||||||
session: capture_session.clone(),
|
session: capture_session.clone(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
self.conn.flush().unwrap();
|
if let Err(err) = self.conn.flush() {
|
||||||
|
tracing::error!("Wayland flush failed during screencopy capture: {err}");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: wait for server to release buffer?
|
// TODO: wait for server to release buffer?
|
||||||
let res = session
|
let res = session
|
||||||
|
|
@ -709,7 +715,10 @@ pub(crate) fn wayland_handler(
|
||||||
if app_data.exit {
|
if app_data.exit {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
event_loop.dispatch(None, &mut app_data).unwrap();
|
if let Err(err) = event_loop.dispatch(None, &mut app_data) {
|
||||||
|
tracing::error!("Wayland event loop terminated: {err}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ cctk.workspace = true
|
||||||
cosmic-protocols.workspace = true
|
cosmic-protocols.workspace = true
|
||||||
i18n-embed-fl.workspace = true
|
i18n-embed-fl.workspace = true
|
||||||
i18n-embed.workspace = true
|
i18n-embed.workspace = true
|
||||||
libcosmic.workspace = true
|
cosmic.workspace = true
|
||||||
rust-embed.workspace = true
|
rust-embed.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
tracing-log.workspace = true
|
tracing-log.workspace = true
|
||||||
|
|
@ -17,9 +17,7 @@ tracing-subscriber.workspace = true
|
||||||
tracing.workspace = true
|
tracing.workspace = true
|
||||||
|
|
||||||
[dependencies.cosmic-settings-a11y-manager-subscription]
|
[dependencies.cosmic-settings-a11y-manager-subscription]
|
||||||
git = "https://github.com/pop-os/cosmic-settings"
|
path = "../../cosmic-settings/subscriptions/a11y-manager"
|
||||||
# path = "../../cosmic-settings/subscriptions/a11y-manager"
|
|
||||||
|
|
||||||
[dependencies.cosmic-settings-accessibility-subscription]
|
[dependencies.cosmic-settings-accessibility-subscription]
|
||||||
git = "https://github.com/pop-os/cosmic-settings"
|
path = "../../cosmic-settings/subscriptions/accessibility"
|
||||||
# path = "../../cosmic-settings/subscriptions/accessibility"
|
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,9 @@ use cosmic::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use cosmic_settings_a11y_manager_subscription::{
|
use cosmic_settings_a11y_manager_subscription::{
|
||||||
self as cosmic_a11y_manager, AccessibilityEvent, AccessibilityRequest, ColorFilter,
|
AccessibilityEvent, AccessibilityRequest, ColorFilter,
|
||||||
};
|
};
|
||||||
use cosmic_settings_accessibility_subscription::{self as accessibility};
|
use cosmic_settings_accessibility_subscription::{self as accessibility};
|
||||||
use std::sync::LazyLock;
|
|
||||||
use tokio::sync::mpsc::UnboundedSender;
|
use tokio::sync::mpsc::UnboundedSender;
|
||||||
|
|
||||||
pub fn run() -> cosmic::iced::Result {
|
pub fn run() -> cosmic::iced::Result {
|
||||||
|
|
@ -52,6 +51,7 @@ struct CosmicA11yApplet {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
#[allow(dead_code)]
|
||||||
enum Message {
|
enum Message {
|
||||||
TogglePopup,
|
TogglePopup,
|
||||||
CloseRequested(window::Id),
|
CloseRequested(window::Id),
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,12 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use anyhow;
|
use anyhow;
|
||||||
use cctk::sctk::reexports::calloop::{self, channel::SyncSender};
|
use cctk::sctk::reexports::calloop::{self};
|
||||||
use cosmic::iced::{
|
use cosmic::iced::{
|
||||||
self, Subscription,
|
self, Subscription,
|
||||||
futures::{self, SinkExt, StreamExt, channel::mpsc},
|
futures::{self, SinkExt},
|
||||||
stream,
|
stream,
|
||||||
};
|
};
|
||||||
use cosmic_protocols::a11y::v1::client::cosmic_a11y_manager_v1::Filter;
|
|
||||||
use cosmic_settings_a11y_manager_subscription::{
|
use cosmic_settings_a11y_manager_subscription::{
|
||||||
self as thread, AccessibilityEvent, AccessibilityRequest,
|
self as thread, AccessibilityEvent, AccessibilityRequest,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,8 @@ license = "GPL-3.0-only"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
i18n-embed-fl.workspace = true
|
i18n-embed-fl.workspace = true
|
||||||
i18n-embed.workspace = true
|
i18n-embed.workspace = true
|
||||||
libcosmic.workspace = true
|
cosmic.workspace = true
|
||||||
mpris2-zbus = { git = "https://github.com/pop-os/dbus-settings-bindings" }
|
mpris2-zbus = { path = "../../dbus-settings-bindings/mpris2" }
|
||||||
# mpris2-zbus = { path = "../../dbus-settings-bindings/mpris2" }
|
|
||||||
rust-embed.workspace = true
|
rust-embed.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
|
|
@ -21,5 +20,4 @@ urlencoding = "2.1.3"
|
||||||
zbus.workspace = true
|
zbus.workspace = true
|
||||||
|
|
||||||
[dependencies.cosmic-settings-sound-subscription]
|
[dependencies.cosmic-settings-sound-subscription]
|
||||||
git = "https://github.com/pop-os/cosmic-settings"
|
path = "../../cosmic-settings/subscriptions/sound"
|
||||||
# path = "../../cosmic-settings/subscriptions/sound"
|
|
||||||
|
|
|
||||||
|
|
@ -487,11 +487,31 @@ impl cosmic::Application for Audio {
|
||||||
.icon_button(self.output_icon_name())
|
.icon_button(self.output_icon_name())
|
||||||
.on_press_down(Message::TogglePopup);
|
.on_press_down(Message::TogglePopup);
|
||||||
|
|
||||||
const WHEEL_STEP: f32 = 5.0; // 5% per wheel event
|
const WHEEL_STEP: f32 = 5.0; // 5% par cran logique
|
||||||
|
// Wayland axis_v120 envoie un cran physique en rafale de plusieurs
|
||||||
|
// ScrollDelta::Pixels (5–8 events ~15–20px), pour ~120px par cran. On
|
||||||
|
// accumule ces sub-events dans un thread_local et on n'émet qu'au
|
||||||
|
// passage d'un seuil — sinon `signum()` faisait croire que chaque
|
||||||
|
// sub-event = un cran, et un seul cran physique faisait chuter le
|
||||||
|
// volume jusqu'à 0 ("coupe le son").
|
||||||
|
const PIXEL_THRESHOLD: f32 = 15.0; // px par cran logique
|
||||||
|
std::thread_local! {
|
||||||
|
static PIXEL_ACC: std::cell::Cell<f32> = const { std::cell::Cell::new(0.0) };
|
||||||
|
}
|
||||||
let btn = crate::mouse_area::MouseArea::new(btn).on_mouse_wheel(|delta| {
|
let btn = crate::mouse_area::MouseArea::new(btn).on_mouse_wheel(|delta| {
|
||||||
let scroll_vector = match delta {
|
let scroll_vector = match delta {
|
||||||
iced::mouse::ScrollDelta::Lines { y, .. } => y.signum() * WHEEL_STEP, // -1/0/1
|
iced::mouse::ScrollDelta::Lines { y, .. } => {
|
||||||
iced::mouse::ScrollDelta::Pixels { y, .. } => y.signum(), // -1/0/1
|
PIXEL_ACC.with(|a| a.set(0.0));
|
||||||
|
y * WHEEL_STEP
|
||||||
|
}
|
||||||
|
iced::mouse::ScrollDelta::Pixels { y, .. } => {
|
||||||
|
PIXEL_ACC.with(|acc_cell| {
|
||||||
|
let acc = acc_cell.get() + y;
|
||||||
|
let steps = (acc / PIXEL_THRESHOLD).trunc();
|
||||||
|
acc_cell.set(acc - steps * PIXEL_THRESHOLD);
|
||||||
|
steps * WHEEL_STEP
|
||||||
|
})
|
||||||
|
}
|
||||||
};
|
};
|
||||||
if scroll_vector == 0.0 {
|
if scroll_vector == 0.0 {
|
||||||
return Message::Ignore;
|
return Message::Ignore;
|
||||||
|
|
@ -499,7 +519,7 @@ impl cosmic::Application for Audio {
|
||||||
|
|
||||||
let new_volume = (self.model.sink_volume as f64 + (scroll_vector as f64))
|
let new_volume = (self.model.sink_volume as f64 + (scroll_vector as f64))
|
||||||
.clamp(0.0, self.max_sink_volume as f64);
|
.clamp(0.0, self.max_sink_volume as f64);
|
||||||
Message::SetSinkVolume(new_volume as u32)
|
Message::SetSinkVolume(new_volume.round() as u32)
|
||||||
});
|
});
|
||||||
|
|
||||||
let playback_buttons = (!self.core.applet.suggested_bounds.as_ref().is_some_and(|c| {
|
let playback_buttons = (!self.core.applet.suggested_bounds.as_ref().is_some_and(|c| {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use cosmic::iced::core::Point;
|
||||||
|
|
||||||
use cosmic::iced::core::{
|
use cosmic::iced::core::{
|
||||||
Clipboard, Element, Layout, Length, Rectangle, Shell, Size, Widget,
|
Clipboard, Element, Layout, Length, Rectangle, Shell, Size, Widget,
|
||||||
event::{self, Event},
|
event::Event,
|
||||||
layout, mouse, overlay, renderer, touch,
|
layout, mouse, overlay, renderer, touch,
|
||||||
widget::{Operation, Tree, tree},
|
widget::{Operation, Tree, tree},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ drm = "0.14.1"
|
||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
i18n-embed-fl.workspace = true
|
i18n-embed-fl.workspace = true
|
||||||
i18n-embed.workspace = true
|
i18n-embed.workspace = true
|
||||||
libcosmic.workspace = true
|
cosmic.workspace = true
|
||||||
rust-embed.workspace = true
|
rust-embed.workspace = true
|
||||||
rustc-hash.workspace = true
|
rustc-hash.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
|
|
@ -24,9 +24,7 @@ zbus.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
|
|
||||||
[dependencies.cosmic-settings-upower-subscription]
|
[dependencies.cosmic-settings-upower-subscription]
|
||||||
git = "https://github.com/pop-os/cosmic-settings"
|
path = "../../cosmic-settings/subscriptions/upower"
|
||||||
# path = "../../cosmic-settings/subscriptions/upower"
|
|
||||||
|
|
||||||
[dependencies.cosmic-settings-daemon-subscription]
|
[dependencies.cosmic-settings-daemon-subscription]
|
||||||
git = "https://github.com/pop-os/cosmic-settings"
|
path = "../../cosmic-settings/subscriptions/settings-daemon"
|
||||||
# path = "../../cosmic-settings/subscriptions/settings-daemon"
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ use cosmic_settings_upower_subscription::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use std::{path::PathBuf, sync::LazyLock, time::Duration};
|
use std::{path::PathBuf, time::Duration};
|
||||||
use tokio::sync::mpsc::UnboundedSender;
|
use tokio::sync::mpsc::UnboundedSender;
|
||||||
|
|
||||||
// XXX improve
|
// XXX improve
|
||||||
|
|
@ -172,6 +172,7 @@ impl CosmicBatteryApplet {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
#[allow(dead_code)]
|
||||||
enum Message {
|
enum Message {
|
||||||
TogglePopup,
|
TogglePopup,
|
||||||
CloseRequested(window::Id),
|
CloseRequested(window::Id),
|
||||||
|
|
@ -507,7 +508,7 @@ impl cosmic::Application for CosmicBatteryApplet {
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view(&self) -> Element<Message> {
|
fn view(&self) -> Element<'_, Message> {
|
||||||
let is_horizontal = match self.core.applet.anchor {
|
let is_horizontal = match self.core.applet.anchor {
|
||||||
PanelAnchor::Top | PanelAnchor::Bottom => true,
|
PanelAnchor::Top | PanelAnchor::Bottom => true,
|
||||||
PanelAnchor::Left | PanelAnchor::Right => false,
|
PanelAnchor::Left | PanelAnchor::Right => false,
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ bluer = { version = "0.17", features = ["bluetoothd", "id"] }
|
||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
i18n-embed-fl.workspace = true
|
i18n-embed-fl.workspace = true
|
||||||
i18n-embed.workspace = true
|
i18n-embed.workspace = true
|
||||||
libcosmic.workspace = true
|
cosmic.workspace = true
|
||||||
fastrand = "2.3.0"
|
fastrand = "2.3.0"
|
||||||
rust-embed.workspace = true
|
rust-embed.workspace = true
|
||||||
rustc-hash.workspace = true
|
rustc-hash.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ use cosmic::{
|
||||||
widget::{button, divider, icon, scrollable, text},
|
widget::{button, divider, icon, scrollable, text},
|
||||||
};
|
};
|
||||||
use futures::FutureExt;
|
use futures::FutureExt;
|
||||||
use std::{collections::HashMap, sync::LazyLock, time::Duration};
|
use std::{collections::HashMap, time::Duration};
|
||||||
use tokio::sync::mpsc::Sender;
|
use tokio::sync::mpsc::Sender;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -63,6 +63,7 @@ impl CosmicBluetoothApplet {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
#[allow(dead_code)]
|
||||||
enum Message {
|
enum Message {
|
||||||
TogglePopup,
|
TogglePopup,
|
||||||
CloseRequested(window::Id),
|
CloseRequested(window::Id),
|
||||||
|
|
@ -145,7 +146,7 @@ impl cosmic::Application for CosmicBluetoothApplet {
|
||||||
}
|
}
|
||||||
Message::BluetoothEvent(e) => match e {
|
Message::BluetoothEvent(e) => match e {
|
||||||
BluerEvent::RequestResponse {
|
BluerEvent::RequestResponse {
|
||||||
req,
|
req: _,
|
||||||
state,
|
state,
|
||||||
err_msg,
|
err_msg,
|
||||||
} => {
|
} => {
|
||||||
|
|
|
||||||
|
|
@ -149,8 +149,6 @@ pub fn bluetooth_subscription<I: 'static + Hash + Copy + Send + Sync + Debug>(
|
||||||
},
|
},
|
||||||
|
|
||||||
BluerSessionEvent::AgentEvent(e) => BluerEvent::AgentEvent(e),
|
BluerSessionEvent::AgentEvent(e) => BluerEvent::AgentEvent(e),
|
||||||
|
|
||||||
_ => return,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_ = output.send(message).await;
|
_ = output.send(message).await;
|
||||||
|
|
@ -199,6 +197,7 @@ pub enum BluerRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
#[allow(dead_code)]
|
||||||
pub enum BluerEvent {
|
pub enum BluerEvent {
|
||||||
RequestResponse {
|
RequestResponse {
|
||||||
req: BluerRequest,
|
req: BluerRequest,
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ edition = "2024"
|
||||||
license = "GPL-3.0-only"
|
license = "GPL-3.0-only"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cosmic-comp-config = { git = "https://github.com/pop-os/cosmic-comp.git", rev = "5eb5af4" }
|
cosmic-comp-config.workspace = true
|
||||||
i18n-embed-fl.workspace = true
|
i18n-embed-fl.workspace = true
|
||||||
i18n-embed.workspace = true
|
i18n-embed.workspace = true
|
||||||
libcosmic.workspace = true
|
cosmic.workspace = true
|
||||||
rust-embed.workspace = true
|
rust-embed.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
tracing-log.workspace = true
|
tracing-log.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
mod localize;
|
mod localize;
|
||||||
|
|
||||||
use cosmic::iced::{Alignment, Length};
|
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
app,
|
app,
|
||||||
app::Core,
|
app::Core,
|
||||||
|
|
@ -14,16 +13,14 @@ use cosmic::{
|
||||||
iced::{
|
iced::{
|
||||||
Rectangle, Task,
|
Rectangle, Task,
|
||||||
platform_specific::shell::commands::popup::{destroy_popup, get_popup},
|
platform_specific::shell::commands::popup::{destroy_popup, get_popup},
|
||||||
widget::{column, row},
|
|
||||||
window::Id,
|
window::Id,
|
||||||
},
|
},
|
||||||
iced::{core::window, runtime::Appearance},
|
iced::core::window,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
surface, theme,
|
surface, theme,
|
||||||
widget::{
|
widget::{
|
||||||
self, autosize,
|
self, autosize,
|
||||||
rectangle_tracker::{RectangleTracker, RectangleUpdate, rectangle_tracker_subscription},
|
rectangle_tracker::{RectangleTracker, RectangleUpdate, rectangle_tracker_subscription},
|
||||||
space,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use cosmic_comp_config::CosmicCompConfig;
|
use cosmic_comp_config::CosmicCompConfig;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ anyhow.workspace = true
|
||||||
i18n-embed-fl.workspace = true
|
i18n-embed-fl.workspace = true
|
||||||
i18n-embed.workspace = true
|
i18n-embed.workspace = true
|
||||||
image = { version = "0.25.9", default-features = false }
|
image = { version = "0.25.9", default-features = false }
|
||||||
libcosmic.workspace = true
|
cosmic.workspace = true
|
||||||
memmap2 = "0.9.10"
|
memmap2 = "0.9.10"
|
||||||
rust-embed.workspace = true
|
rust-embed.workspace = true
|
||||||
rustix.workspace = true
|
rustix.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -316,7 +316,7 @@ impl cosmic::Application for Minimize {
|
||||||
} else {
|
} else {
|
||||||
(cross_padding, major_padding)
|
(cross_padding, major_padding)
|
||||||
};
|
};
|
||||||
let theme = self.core.system_theme().cosmic();
|
let _theme = self.core.system_theme().cosmic();
|
||||||
let icon_buttons = self.apps[..max_icon_count].iter().map(|app| {
|
let icon_buttons = self.apps[..max_icon_count].iter().map(|app| {
|
||||||
self.core
|
self.core
|
||||||
.applet
|
.applet
|
||||||
|
|
@ -420,7 +420,7 @@ impl cosmic::Application for Minimize {
|
||||||
(cross_padding, major_padding)
|
(cross_padding, major_padding)
|
||||||
};
|
};
|
||||||
let theme = self.core.system_theme().cosmic();
|
let theme = self.core.system_theme().cosmic();
|
||||||
let space_xxs = theme.space_xxs();
|
let _space_xxs = theme.space_xxs();
|
||||||
let icon_buttons = self.apps[max_icon_count..].iter().map(|app| {
|
let icon_buttons = self.apps[max_icon_count..].iter().map(|app| {
|
||||||
tooltip(
|
tooltip(
|
||||||
Element::from(crate::window_image::WindowImage::new(
|
Element::from(crate::window_image::WindowImage::new(
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,12 @@ license = "GPL-3.0-or-later"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
async-fn-stream = "0.3"
|
async-fn-stream = "0.3"
|
||||||
cosmic-dbus-networkmanager = { git = "https://github.com/pop-os/dbus-settings-bindings" }
|
cosmic-dbus-networkmanager = { path = "../../dbus-settings-bindings/networkmanager" }
|
||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
futures-util.workspace = true
|
futures-util.workspace = true
|
||||||
i18n-embed-fl.workspace = true
|
i18n-embed-fl.workspace = true
|
||||||
i18n-embed.workspace = true
|
i18n-embed.workspace = true
|
||||||
libcosmic = { workspace = true, features = [
|
cosmic = { workspace = true, features = [
|
||||||
"applet",
|
"applet",
|
||||||
"applet-token",
|
"applet-token",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
|
@ -26,16 +26,14 @@ tracing-log.workspace = true
|
||||||
tracing-subscriber.workspace = true
|
tracing-subscriber.workspace = true
|
||||||
tracing.workspace = true
|
tracing.workspace = true
|
||||||
zbus.workspace = true
|
zbus.workspace = true
|
||||||
nm-secret-agent-manager = { git = "https://github.com/pop-os/dbus-settings-bindings/" }
|
nm-secret-agent-manager = { path = "../../dbus-settings-bindings/nm-secret-agent-manager" }
|
||||||
indexmap = "2.13.0"
|
indexmap = "2.13.0"
|
||||||
secure-string = "0.3.0"
|
secure-string = "0.3.0"
|
||||||
uuid = { version = "1.21.0", features = ["v4"] }
|
uuid = { version = "1.21.0", features = ["v4"] }
|
||||||
|
|
||||||
|
|
||||||
[dependencies.cosmic-settings-network-manager-subscription]
|
[dependencies.cosmic-settings-network-manager-subscription]
|
||||||
git = "https://github.com/pop-os/cosmic-settings/"
|
path = "../../cosmic-settings/subscriptions/network-manager"
|
||||||
# path = "../../cosmic-settings/subscriptions/network-manager"
|
|
||||||
|
|
||||||
[dependencies.cosmic-settings-airplane-mode-subscription]
|
[dependencies.cosmic-settings-airplane-mode-subscription]
|
||||||
git = "https://github.com/pop-os/cosmic-settings/"
|
path = "../../cosmic-settings/subscriptions/airplane-mode"
|
||||||
# path = "../../cosmic-settings/subscriptions/airplane-mode"
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ use anyhow::Context;
|
||||||
use cosmic_dbus_networkmanager::settings::{NetworkManagerSettings, connection::Settings};
|
use cosmic_dbus_networkmanager::settings::{NetworkManagerSettings, connection::Settings};
|
||||||
use cosmic_settings_network_manager_subscription::{
|
use cosmic_settings_network_manager_subscription::{
|
||||||
self as network_manager, NetworkManagerState, UUID,
|
self as network_manager, NetworkManagerState, UUID,
|
||||||
active_conns::active_conns_subscription,
|
|
||||||
available_wifi::{AccessPoint, NetworkType},
|
available_wifi::{AccessPoint, NetworkType},
|
||||||
current_networks::ActiveConnectionInfo,
|
current_networks::ActiveConnectionInfo,
|
||||||
hw_address::HwAddress,
|
hw_address::HwAddress,
|
||||||
|
|
@ -15,7 +14,6 @@ use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
collections::{BTreeMap, BTreeSet},
|
collections::{BTreeMap, BTreeSet},
|
||||||
sync::{Arc, LazyLock},
|
sync::{Arc, LazyLock},
|
||||||
time::Duration,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
|
|
@ -33,17 +31,14 @@ use cosmic::{
|
||||||
},
|
},
|
||||||
surface, theme,
|
surface, theme,
|
||||||
widget::{
|
widget::{
|
||||||
Column, Id, Row, button, column, container, divider,
|
Id, button, column, container, divider,
|
||||||
icon::{self, from_name},
|
icon::{self, from_name},
|
||||||
row, scrollable, secure_input, text, text_input, toggler,
|
row, scrollable, secure_input, text, text_input, toggler,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use cosmic_dbus_networkmanager::interface::{
|
use cosmic_dbus_networkmanager::interface::enums::{ActiveConnectionState, DeviceState, NmConnectivityState};
|
||||||
access_point,
|
|
||||||
enums::{ActiveConnectionState, DeviceState, NmConnectivityState, NmState},
|
|
||||||
};
|
|
||||||
|
|
||||||
use futures::{StreamExt, channel::mpsc::TrySendError};
|
use futures::StreamExt;
|
||||||
use zbus::{Connection, zvariant::ObjectPath};
|
use zbus::{Connection, zvariant::ObjectPath};
|
||||||
|
|
||||||
use crate::{config, fl};
|
use crate::{config, fl};
|
||||||
|
|
@ -74,6 +69,7 @@ impl NewConnectionState {
|
||||||
}
|
}
|
||||||
.ssid
|
.ssid
|
||||||
}
|
}
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn hw_address(&self) -> HwAddress {
|
pub fn hw_address(&self) -> HwAddress {
|
||||||
match self {
|
match self {
|
||||||
Self::EnterPassword { access_point, .. } => access_point,
|
Self::EnterPassword { access_point, .. } => access_point,
|
||||||
|
|
@ -96,6 +92,7 @@ impl From<NewConnectionState> for AccessPoint {
|
||||||
|
|
||||||
pub static SECURE_INPUT_WIFI: LazyLock<Id> = LazyLock::new(Id::unique);
|
pub static SECURE_INPUT_WIFI: LazyLock<Id> = LazyLock::new(Id::unique);
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone)]
|
||||||
pub struct MyNetworkState {
|
pub struct MyNetworkState {
|
||||||
pub known_vpns: IndexMap<UUID, ConnectionSettings>,
|
pub known_vpns: IndexMap<UUID, ConnectionSettings>,
|
||||||
|
|
@ -107,6 +104,7 @@ pub struct MyNetworkState {
|
||||||
pub requested_vpn: Option<RequestedVpn>,
|
pub requested_vpn: Option<RequestedVpn>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct RequestedVpn {
|
pub struct RequestedVpn {
|
||||||
name: String,
|
name: String,
|
||||||
|
|
@ -123,6 +121,7 @@ pub enum ConnectionSettings {
|
||||||
Wireguard { id: String },
|
Wireguard { id: String },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct VpnConnectionSettings {
|
pub struct VpnConnectionSettings {
|
||||||
id: String,
|
id: String,
|
||||||
|
|
@ -136,6 +135,7 @@ enum ConnectionType {
|
||||||
Password,
|
Password,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
impl VpnConnectionSettings {
|
impl VpnConnectionSettings {
|
||||||
fn password_flag(&self) -> Option<PasswordFlag> {
|
fn password_flag(&self) -> Option<PasswordFlag> {
|
||||||
self.connection_type
|
self.connection_type
|
||||||
|
|
@ -366,15 +366,12 @@ impl CosmicNetworkApplet {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_togglers(&mut self, state: &NetworkManagerState) {
|
fn update_togglers(&mut self, state: &NetworkManagerState) {
|
||||||
let mut changed = false;
|
|
||||||
if self.nm_state.nm_state.wifi_enabled != state.wifi_enabled {
|
if self.nm_state.nm_state.wifi_enabled != state.wifi_enabled {
|
||||||
self.nm_state.nm_state.wifi_enabled = state.wifi_enabled;
|
self.nm_state.nm_state.wifi_enabled = state.wifi_enabled;
|
||||||
changed = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.nm_state.nm_state.airplane_mode != state.airplane_mode {
|
if self.nm_state.nm_state.airplane_mode != state.airplane_mode {
|
||||||
self.nm_state.nm_state.airplane_mode = state.airplane_mode;
|
self.nm_state.nm_state.airplane_mode = state.airplane_mode;
|
||||||
changed = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -447,6 +444,7 @@ impl CosmicNetworkApplet {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
#[allow(dead_code)]
|
||||||
pub(crate) enum Message {
|
pub(crate) enum Message {
|
||||||
TogglePopup,
|
TogglePopup,
|
||||||
CloseRequested(window::Id),
|
CloseRequested(window::Id),
|
||||||
|
|
@ -501,8 +499,9 @@ pub(crate) enum Message {
|
||||||
SelectDevice(Option<Arc<network_manager::devices::DeviceInfo>>),
|
SelectDevice(Option<Arc<network_manager::devices::DeviceInfo>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Password {
|
pub(crate) struct Password {
|
||||||
ssid: network_manager::SSID,
|
ssid: network_manager::SSID,
|
||||||
hw_address: HwAddress,
|
hw_address: HwAddress,
|
||||||
identity: Option<String>,
|
identity: Option<String>,
|
||||||
|
|
@ -759,7 +758,7 @@ impl cosmic::Application for CosmicNetworkApplet {
|
||||||
const APP_ID: &'static str = config::APP_ID;
|
const APP_ID: &'static str = config::APP_ID;
|
||||||
|
|
||||||
fn init(core: cosmic::app::Core, _flags: ()) -> (Self, app::Task<Message>) {
|
fn init(core: cosmic::app::Core, _flags: ()) -> (Self, app::Task<Message>) {
|
||||||
let mut applet = Self {
|
let applet = Self {
|
||||||
core,
|
core,
|
||||||
icon_name: "network-wired-disconnected-symbolic".to_string(),
|
icon_name: "network-wired-disconnected-symbolic".to_string(),
|
||||||
token_tx: None,
|
token_tx: None,
|
||||||
|
|
@ -1153,9 +1152,9 @@ impl cosmic::Application for CosmicNetworkApplet {
|
||||||
} => {
|
} => {
|
||||||
if let network_manager::Request::SelectAccessPoint(
|
if let network_manager::Request::SelectAccessPoint(
|
||||||
ssid,
|
ssid,
|
||||||
hw_address,
|
_hw_address,
|
||||||
_network_type,
|
_network_type,
|
||||||
secret_tx,
|
_secret_tx,
|
||||||
) = &req
|
) = &req
|
||||||
{
|
{
|
||||||
let conn_match = self
|
let conn_match = self
|
||||||
|
|
@ -1168,7 +1167,7 @@ impl cosmic::Application for CosmicNetworkApplet {
|
||||||
.active_conns
|
.active_conns
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.find(|ap| {
|
.find(|ap| {
|
||||||
let ap_hw_address = match ap {
|
let _ap_hw_address = match ap {
|
||||||
ActiveConnectionInfo::Wired { hw_address, .. }
|
ActiveConnectionInfo::Wired { hw_address, .. }
|
||||||
| ActiveConnectionInfo::WiFi { hw_address, .. } => {
|
| ActiveConnectionInfo::WiFi { hw_address, .. } => {
|
||||||
HwAddress::from_str(&hw_address).unwrap()
|
HwAddress::from_str(&hw_address).unwrap()
|
||||||
|
|
@ -1192,8 +1191,8 @@ impl cosmic::Application for CosmicNetworkApplet {
|
||||||
ssid,
|
ssid,
|
||||||
identity: _,
|
identity: _,
|
||||||
password: _,
|
password: _,
|
||||||
secret_tx,
|
secret_tx: _,
|
||||||
interface
|
interface: _
|
||||||
} = &req
|
} = &req
|
||||||
{
|
{
|
||||||
if let Some(NewConnectionState::Waiting(access_point)) =
|
if let Some(NewConnectionState::Waiting(access_point)) =
|
||||||
|
|
@ -1246,9 +1245,9 @@ impl cosmic::Application for CosmicNetworkApplet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cosmic_settings_network_manager_subscription::Event::WiFiCredentials {
|
cosmic_settings_network_manager_subscription::Event::WiFiCredentials {
|
||||||
ssid,
|
ssid: _,
|
||||||
password,
|
password: _,
|
||||||
security_type,
|
security_type: _,
|
||||||
} => {}
|
} => {}
|
||||||
},
|
},
|
||||||
Message::NetworkManagerConnect(connection) => {
|
Message::NetworkManagerConnect(connection) => {
|
||||||
|
|
@ -1441,7 +1440,7 @@ impl cosmic::Application for CosmicNetworkApplet {
|
||||||
}
|
}
|
||||||
ActiveConnectionInfo::Wired {
|
ActiveConnectionInfo::Wired {
|
||||||
name,
|
name,
|
||||||
hw_address,
|
hw_address: _,
|
||||||
speed,
|
speed,
|
||||||
ip_addresses,
|
ip_addresses,
|
||||||
} => {
|
} => {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ license = "GPL-3.0-only"
|
||||||
cosmic-notifications-util = { git = "https://github.com/pop-os/cosmic-notifications" }
|
cosmic-notifications-util = { git = "https://github.com/pop-os/cosmic-notifications" }
|
||||||
cosmic-notifications-config = { git = "https://github.com/pop-os/cosmic-notifications" }
|
cosmic-notifications-config = { git = "https://github.com/pop-os/cosmic-notifications" }
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
libcosmic.workspace = true
|
cosmic.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
# cosmic-notifications-util = { path = "../../cosmic-notifications-daemon/cosmic-notifications-util" }
|
# cosmic-notifications-util = { path = "../../cosmic-notifications-daemon/cosmic-notifications-util" }
|
||||||
# cosmic-notifications-config = { path = "../../cosmic-notifications-daemon/cosmic-notifications-config" }
|
# cosmic-notifications-config = { path = "../../cosmic-notifications-daemon/cosmic-notifications-config" }
|
||||||
|
|
|
||||||
|
|
@ -20,14 +20,14 @@ use cosmic::{
|
||||||
window,
|
window,
|
||||||
},
|
},
|
||||||
surface, theme,
|
surface, theme,
|
||||||
widget::{Column, button, cards, container, divider, icon, scrollable, space, text, toggler},
|
widget::{Column, button, cards, container, divider, icon, scrollable, text, toggler},
|
||||||
};
|
};
|
||||||
|
|
||||||
use cosmic::iced::futures::executor::block_on;
|
use cosmic::iced::futures::executor::block_on;
|
||||||
|
|
||||||
use cosmic_notifications_config::NotificationsConfig;
|
use cosmic_notifications_config::NotificationsConfig;
|
||||||
use cosmic_notifications_util::{ActionId, Image, Notification};
|
use cosmic_notifications_util::{ActionId, Image, Notification};
|
||||||
use std::{borrow::Cow, collections::HashMap, path::PathBuf, sync::LazyLock};
|
use std::{borrow::Cow, collections::HashMap};
|
||||||
use subscriptions::notifications::{self, NotificationsAppletProxy};
|
use subscriptions::notifications::{self, NotificationsAppletProxy};
|
||||||
use tokio::sync::mpsc::Sender;
|
use tokio::sync::mpsc::Sender;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
@ -65,6 +65,7 @@ impl Notifications {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
#[allow(dead_code)]
|
||||||
enum Message {
|
enum Message {
|
||||||
TogglePopup,
|
TogglePopup,
|
||||||
CloseRequested(window::Id),
|
CloseRequested(window::Id),
|
||||||
|
|
@ -279,7 +280,7 @@ impl cosmic::Application for Notifications {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::CardsToggled(name, expanded) => {
|
Message::CardsToggled(name, expanded) => {
|
||||||
let id = if let Some((id, _, n_expanded, ..)) = self
|
let _id = if let Some((id, _, n_expanded, ..)) = self
|
||||||
.cards
|
.cards
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.find(|c| c.1.iter().any(|notif| name == notif.app_name))
|
.find(|c| c.1.iter().any(|notif| name == notif.app_name))
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ license = "GPL-3.0-only"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
i18n-embed-fl.workspace = true
|
i18n-embed-fl.workspace = true
|
||||||
i18n-embed.workspace = true
|
i18n-embed.workspace = true
|
||||||
libcosmic.workspace = true
|
cosmic.workspace = true
|
||||||
logind-zbus = "5.3.2"
|
logind-zbus = "5.3.2"
|
||||||
rust-embed.workspace = true
|
rust-embed.workspace = true
|
||||||
rustix.workspace = true
|
rustix.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,8 @@ use cosmic::{
|
||||||
window,
|
window,
|
||||||
},
|
},
|
||||||
surface, theme,
|
surface, theme,
|
||||||
widget::{Space, button, divider, icon, space, text},
|
widget::{button, divider, icon, space, text},
|
||||||
};
|
};
|
||||||
use std::sync::LazyLock;
|
|
||||||
|
|
||||||
use logind_zbus::{
|
use logind_zbus::{
|
||||||
manager::ManagerProxy,
|
manager::ManagerProxy,
|
||||||
|
|
@ -35,9 +34,6 @@ pub mod session_manager;
|
||||||
|
|
||||||
use crate::{cosmic_session::CosmicSessionProxy, session_manager::SessionManagerProxy};
|
use crate::{cosmic_session::CosmicSessionProxy, session_manager::SessionManagerProxy};
|
||||||
|
|
||||||
static SUBSURFACE_ID: LazyLock<cosmic::widget::Id> =
|
|
||||||
LazyLock::new(|| cosmic::widget::Id::new("subsurface"));
|
|
||||||
|
|
||||||
pub fn run() -> cosmic::iced::Result {
|
pub fn run() -> cosmic::iced::Result {
|
||||||
localize::localize();
|
localize::localize();
|
||||||
|
|
||||||
|
|
@ -49,7 +45,6 @@ struct Power {
|
||||||
icon_name: String,
|
icon_name: String,
|
||||||
popup: Option<window::Id>,
|
popup: Option<window::Id>,
|
||||||
token_tx: Option<calloop::channel::Sender<TokenRequest>>,
|
token_tx: Option<calloop::channel::Sender<TokenRequest>>,
|
||||||
subsurface_id: window::Id,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
|
@ -75,6 +70,7 @@ impl PowerAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
#[allow(dead_code)]
|
||||||
enum Message {
|
enum Message {
|
||||||
Action(PowerAction),
|
Action(PowerAction),
|
||||||
TogglePopup,
|
TogglePopup,
|
||||||
|
|
@ -104,7 +100,6 @@ impl cosmic::Application for Power {
|
||||||
Self {
|
Self {
|
||||||
core,
|
core,
|
||||||
icon_name: "system-shutdown-symbolic".to_string(),
|
icon_name: "system-shutdown-symbolic".to_string(),
|
||||||
subsurface_id: window::Id::unique(),
|
|
||||||
token_tx: None,
|
token_tx: None,
|
||||||
popup: Option::default(),
|
popup: Option::default(),
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ license = "GPL-3.0-only"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
libcosmic.workspace = true
|
cosmic.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
rustc-hash.workspace = true
|
rustc-hash.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ use cosmic::{
|
||||||
iced::{
|
iced::{
|
||||||
self, Length, Subscription,
|
self, Length, Subscription,
|
||||||
platform_specific::shell::commands::popup::{destroy_popup, get_popup},
|
platform_specific::shell::commands::popup::{destroy_popup, get_popup},
|
||||||
theme::Style,
|
|
||||||
window,
|
window,
|
||||||
},
|
},
|
||||||
surface,
|
surface,
|
||||||
|
|
@ -25,6 +24,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
#[allow(dead_code)]
|
||||||
pub enum Msg {
|
pub enum Msg {
|
||||||
None,
|
None,
|
||||||
Activate(usize),
|
Activate(usize),
|
||||||
|
|
@ -577,7 +577,7 @@ fn menu_icon_button<'a>(
|
||||||
let icon = menu.icon_handle().clone();
|
let icon = menu.icon_handle().clone();
|
||||||
|
|
||||||
let theme = cosmic::theme::active();
|
let theme = cosmic::theme::active();
|
||||||
let theme = theme.cosmic();
|
let _theme = theme.cosmic();
|
||||||
|
|
||||||
let suggested = applet.suggested_size(true);
|
let suggested = applet.suggested_size(true);
|
||||||
let padding = applet.suggested_padding(true).1;
|
let padding = applet.suggested_padding(true).1;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use cosmic::{
|
||||||
iced,
|
iced,
|
||||||
widget::icon::{self, IconFallback},
|
widget::icon::{self, IconFallback},
|
||||||
};
|
};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::Path;
|
||||||
|
|
||||||
use crate::subscriptions::status_notifier_item::{IconUpdate, Layout, StatusNotifierItem};
|
use crate::subscriptions::status_notifier_item::{IconUpdate, Layout, StatusNotifierItem};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,21 +10,18 @@
|
||||||
//! can be socket-activated and not conflict with anything else running as a status notifier
|
//! can be socket-activated and not conflict with anything else running as a status notifier
|
||||||
//! watcher.
|
//! watcher.
|
||||||
//!
|
//!
|
||||||
//! The daemon runs as long as as there is at least one client still connected. Which it checks
|
//! The daemon runs as long as there is at least one client still connected.
|
||||||
//! for every `REFRESH_INTERVAL`.
|
|
||||||
|
|
||||||
use crate::subscriptions::status_notifier_watcher::server::create_service;
|
use crate::subscriptions::status_notifier_watcher::server::create_service;
|
||||||
use crate::unique_names::UniqueNames;
|
use crate::unique_names::UniqueNames;
|
||||||
|
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use std::{collections::HashSet, time::Duration};
|
use std::collections::HashSet;
|
||||||
use zbus::fdo;
|
use zbus::fdo;
|
||||||
use zbus::message::Header;
|
use zbus::message::Header;
|
||||||
|
|
||||||
const DBUS_NAME: &str = "com.system76.CosmicStatusNotifierWatcher";
|
const DBUS_NAME: &str = "com.system76.CosmicStatusNotifierWatcher";
|
||||||
const OBJECT_PATH: &str = "/CosmicStatusNotifierWatcher";
|
const OBJECT_PATH: &str = "/CosmicStatusNotifierWatcher";
|
||||||
const REFRESH_INTERVAL: Duration = Duration::from_secs(60);
|
|
||||||
|
|
||||||
/// Run daemon
|
/// Run daemon
|
||||||
pub fn run() -> cosmic::iced::Result {
|
pub fn run() -> cosmic::iced::Result {
|
||||||
if let Err(err) = run_inner() {
|
if let Err(err) = run_inner() {
|
||||||
|
|
@ -42,7 +39,7 @@ pub async fn cosmic_register(conn: &zbus::Connection) -> zbus::Result<()> {
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
while let Some(value) = stream.next().await {
|
while let Some(value) = stream.next().await {
|
||||||
if let Some(_unique_name) = value {
|
if let Some(_unique_name) = value {
|
||||||
/// Register with new owner
|
// Register with new owner.
|
||||||
let _ = cosmic_watcher.register_applet().await;
|
let _ = cosmic_watcher.register_applet().await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ edition = "2024"
|
||||||
license = "GPL-3.0-only"
|
license = "GPL-3.0-only"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libcosmic.workspace = true
|
cosmic.workspace = true
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
cctk.workspace = true
|
cctk.workspace = true
|
||||||
cosmic-comp-config = { git = "https://github.com/pop-os/cosmic-comp.git", rev = "5eb5af4" }
|
cosmic-comp-config.workspace = true
|
||||||
cosmic-protocols.workspace = true
|
cosmic-protocols.workspace = true
|
||||||
i18n-embed-fl.workspace = true
|
i18n-embed-fl.workspace = true
|
||||||
i18n-embed.workspace = true
|
i18n-embed.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ use cosmic::{
|
||||||
};
|
};
|
||||||
use cosmic_comp_config::{CosmicCompConfig, TileBehavior};
|
use cosmic_comp_config::{CosmicCompConfig, TileBehavior};
|
||||||
use cosmic_protocols::workspace::v2::client::zcosmic_workspace_handle_v2::TilingState;
|
use cosmic_protocols::workspace::v2::client::zcosmic_workspace_handle_v2::TilingState;
|
||||||
use std::{thread, time::Instant};
|
use std::thread;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
const ID: &str = "com.system76.CosmicAppletTiling";
|
const ID: &str = "com.system76.CosmicAppletTiling";
|
||||||
|
|
@ -46,6 +46,7 @@ pub struct Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
#[allow(dead_code)]
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
TogglePopup,
|
TogglePopup,
|
||||||
PopupClosed(Id),
|
PopupClosed(Id),
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ cosmic-applets-config.workspace = true
|
||||||
jiff = "0.2"
|
jiff = "0.2"
|
||||||
i18n-embed-fl.workspace = true
|
i18n-embed-fl.workspace = true
|
||||||
i18n-embed.workspace = true
|
i18n-embed.workspace = true
|
||||||
libcosmic.workspace = true
|
cosmic.workspace = true
|
||||||
rust-embed.workspace = true
|
rust-embed.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
tracing-log.workspace = true
|
tracing-log.workspace = true
|
||||||
|
|
@ -17,5 +17,5 @@ tracing-subscriber.workspace = true
|
||||||
tracing.workspace = true
|
tracing.workspace = true
|
||||||
icu = { version = "2.1.1", features = ["compiled_data"] }
|
icu = { version = "2.1.1", features = ["compiled_data"] }
|
||||||
zbus.workspace = true
|
zbus.workspace = true
|
||||||
timedate-zbus = { git = "https://github.com/pop-os/dbus-settings-bindings" }
|
timedate-zbus = { path = "../../dbus-settings-bindings/timedate" }
|
||||||
logind-zbus = "5.3.2"
|
logind-zbus = "5.3.2"
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,7 @@ pub struct Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
#[allow(dead_code)]
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
TogglePopup,
|
TogglePopup,
|
||||||
CloseRequested(window::Id),
|
CloseRequested(window::Id),
|
||||||
|
|
@ -361,7 +362,7 @@ impl cosmic::Application for Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn subscription(&self) -> Subscription<Message> {
|
fn subscription(&self) -> Subscription<Message> {
|
||||||
fn time_subscription(mut show_seconds: watch::Receiver<bool>) -> Subscription<Message> {
|
fn time_subscription(show_seconds: watch::Receiver<bool>) -> Subscription<Message> {
|
||||||
struct Wrapper {
|
struct Wrapper {
|
||||||
inner: watch::Receiver<bool>,
|
inner: watch::Receiver<bool>,
|
||||||
id: &'static str,
|
id: &'static str,
|
||||||
|
|
@ -376,7 +377,7 @@ impl cosmic::Application for Window {
|
||||||
inner: show_seconds,
|
inner: show_seconds,
|
||||||
id: "time-sub",
|
id: "time-sub",
|
||||||
},
|
},
|
||||||
|Wrapper { inner, id }| {
|
|Wrapper { inner, id: _ }| {
|
||||||
let mut show_seconds = inner.clone();
|
let mut show_seconds = inner.clone();
|
||||||
stream::channel(1, move |mut output: mpsc::Sender<Message>| async move {
|
stream::channel(1, move |mut output: mpsc::Sender<Message>| async move {
|
||||||
// Mark this receiver's state as changed so that it always receives an initial
|
// Mark this receiver's state as changed so that it always receives an initial
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ edition = "2024"
|
||||||
license = "GPL-3.0-only"
|
license = "GPL-3.0-only"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libcosmic.workspace = true
|
cosmic.workspace = true
|
||||||
cctk.workspace = true
|
cctk.workspace = true
|
||||||
tracing.workspace = true
|
tracing.workspace = true
|
||||||
tracing-subscriber.workspace = true
|
tracing-subscriber.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ impl IcedWorkspacesApplet {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
#[allow(dead_code)]
|
||||||
enum Message {
|
enum Message {
|
||||||
WorkspaceUpdate(WorkspacesUpdate),
|
WorkspaceUpdate(WorkspacesUpdate),
|
||||||
WorkspacePressed(ExtWorkspaceHandleV1),
|
WorkspacePressed(ExtWorkspaceHandleV1),
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ cosmic-applet-time = { path = "../cosmic-applet-time" }
|
||||||
cosmic-applet-workspaces = { path = "../cosmic-applet-workspaces" }
|
cosmic-applet-workspaces = { path = "../cosmic-applet-workspaces" }
|
||||||
cosmic-applet-input-sources = { path = "../cosmic-applet-input-sources" }
|
cosmic-applet-input-sources = { path = "../cosmic-applet-input-sources" }
|
||||||
cosmic-panel-button = { path = "../cosmic-panel-button" }
|
cosmic-panel-button = { path = "../cosmic-panel-button" }
|
||||||
libcosmic.workspace = true
|
cosmic.workspace = true
|
||||||
tracing.workspace = true
|
tracing.workspace = true
|
||||||
tracing-subscriber.workspace = true
|
tracing-subscriber.workspace = true
|
||||||
tracing-log.workspace = true
|
tracing-log.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -12,26 +12,44 @@ fn main() -> cosmic::iced::Result {
|
||||||
};
|
};
|
||||||
|
|
||||||
let start = applet.rfind('/').map_or(0, |v| v + 1);
|
let start = applet.rfind('/').map_or(0, |v| v + 1);
|
||||||
let cmd = &applet.as_str()[start..];
|
let cmd = applet.as_str()[start..].to_string();
|
||||||
|
|
||||||
tracing::info!("Starting `{cmd}` with version {VERSION}");
|
tracing::info!("Starting `{cmd}` with version {VERSION}");
|
||||||
|
|
||||||
match cmd {
|
let cmd_for_run = cmd.clone();
|
||||||
"cosmic-app-list" => cosmic_app_list::run(),
|
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(move || {
|
||||||
"cosmic-applet-a11y" => cosmic_applet_a11y::run(),
|
match cmd_for_run.as_str() {
|
||||||
"cosmic-applet-audio" => cosmic_applet_audio::run(),
|
"cosmic-app-list" => cosmic_app_list::run(),
|
||||||
"cosmic-applet-battery" => cosmic_applet_battery::run(),
|
"cosmic-applet-a11y" => cosmic_applet_a11y::run(),
|
||||||
"cosmic-applet-bluetooth" => cosmic_applet_bluetooth::run(),
|
"cosmic-applet-audio" => cosmic_applet_audio::run(),
|
||||||
"cosmic-applet-minimize" => cosmic_applet_minimize::run(),
|
"cosmic-applet-battery" => cosmic_applet_battery::run(),
|
||||||
"cosmic-applet-network" => cosmic_applet_network::run(),
|
"cosmic-applet-bluetooth" => cosmic_applet_bluetooth::run(),
|
||||||
"cosmic-applet-notifications" => cosmic_applet_notifications::run(),
|
"cosmic-applet-minimize" => cosmic_applet_minimize::run(),
|
||||||
"cosmic-applet-power" => cosmic_applet_power::run(),
|
"cosmic-applet-network" => cosmic_applet_network::run(),
|
||||||
"cosmic-applet-status-area" => cosmic_applet_status_area::run(),
|
"cosmic-applet-notifications" => cosmic_applet_notifications::run(),
|
||||||
"cosmic-applet-tiling" => cosmic_applet_tiling::run(),
|
"cosmic-applet-power" => cosmic_applet_power::run(),
|
||||||
"cosmic-applet-time" => cosmic_applet_time::run(),
|
"cosmic-applet-status-area" => cosmic_applet_status_area::run(),
|
||||||
"cosmic-applet-workspaces" => cosmic_applet_workspaces::run(),
|
"cosmic-applet-tiling" => cosmic_applet_tiling::run(),
|
||||||
"cosmic-applet-input-sources" => cosmic_applet_input_sources::run(),
|
"cosmic-applet-time" => cosmic_applet_time::run(),
|
||||||
"cosmic-panel-button" => cosmic_panel_button::run(),
|
"cosmic-applet-workspaces" => cosmic_applet_workspaces::run(),
|
||||||
_ => Ok(()),
|
"cosmic-applet-input-sources" => cosmic_applet_input_sources::run(),
|
||||||
|
"cosmic-panel-button" => cosmic_panel_button::run(),
|
||||||
|
_ => Ok(()),
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(r) => r,
|
||||||
|
Err(payload) => {
|
||||||
|
let msg = payload
|
||||||
|
.downcast_ref::<&str>()
|
||||||
|
.map(|s| s.to_string())
|
||||||
|
.or_else(|| payload.downcast_ref::<String>().cloned())
|
||||||
|
.unwrap_or_else(|| "<non-string panic>".to_string());
|
||||||
|
tracing::error!(
|
||||||
|
"`{cmd}` panicked (likely compositor disconnect), exiting cleanly: {msg}"
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ edition = "2024"
|
||||||
license = "GPL-3.0-only"
|
license = "GPL-3.0-only"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libcosmic.workspace = true
|
cosmic.workspace = true
|
||||||
rustc-hash.workspace = true
|
rustc-hash.workspace = true
|
||||||
tracing.workspace = true
|
tracing.workspace = true
|
||||||
tracing-subscriber.workspace = true
|
tracing-subscriber.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ impl Button {
|
||||||
icon: cosmic::widget::icon::Handle,
|
icon: cosmic::widget::icon::Handle,
|
||||||
) -> cosmic::widget::Button<'a, Message> {
|
) -> cosmic::widget::Button<'a, Message> {
|
||||||
let theme = cosmic::theme::active();
|
let theme = cosmic::theme::active();
|
||||||
let theme = theme.cosmic();
|
let _theme = theme.cosmic();
|
||||||
|
|
||||||
let suggested = self.core.applet.suggested_size(icon.symbolic);
|
let suggested = self.core.applet.suggested_size(icon.symbolic);
|
||||||
let (major_padding, applet_padding_minor_axis) =
|
let (major_padding, applet_padding_minor_axis) =
|
||||||
|
|
|
||||||
56
redeploy.sh
Executable file
56
redeploy.sh
Executable file
|
|
@ -0,0 +1,56 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Recompile et déploie le fork local cosmic-applets (multiplexor cosmic-applets +
|
||||||
|
# binaire séparé cosmic-app-list).
|
||||||
|
#
|
||||||
|
# Cibles : /usr/local/bin/cosmic-applets et /usr/local/bin/cosmic-app-list
|
||||||
|
# (binaires compilés manuellement, hors pacman, qui priment sur ceux du paquet
|
||||||
|
# via $PATH /usr/local/bin avant /usr/bin).
|
||||||
|
#
|
||||||
|
# Branche de déploiement : yoda-dock-magnification (contient les commits
|
||||||
|
# magnification + le fix Wayland error handling).
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO="/home/lionel/Devels/cosmic-applets"
|
||||||
|
TARGETS=(
|
||||||
|
"cosmic-applets"
|
||||||
|
"cosmic-app-list"
|
||||||
|
"cosmic-panel-button"
|
||||||
|
)
|
||||||
|
BIN_DIR="/usr/local/bin"
|
||||||
|
|
||||||
|
cd "$REPO"
|
||||||
|
|
||||||
|
echo "==> Branche actuelle : $(git branch --show-current)"
|
||||||
|
echo "==> Build release (workspace)..."
|
||||||
|
cargo build --release --workspace
|
||||||
|
|
||||||
|
STAMP=$(date +%Y%m%d-%H%M%S)
|
||||||
|
for bin in "${TARGETS[@]}"; do
|
||||||
|
src="$REPO/target/release/$bin"
|
||||||
|
dst="$BIN_DIR/$bin"
|
||||||
|
|
||||||
|
if [[ ! -f "$src" ]]; then
|
||||||
|
echo "!! Binaire absent après build : $src" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "$dst" ]]; then
|
||||||
|
echo "==> Backup $dst"
|
||||||
|
sudo cp -a "$dst" "${dst}.bak.${STAMP}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> Install $src -> $dst"
|
||||||
|
sudo install -m755 "$src" "$dst"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "==> Kill des process applet en cours (cosmic-panel relancera à la demande)"
|
||||||
|
pkill -u "$USER" -f "/usr/local/bin/cosmic-applet" || true
|
||||||
|
pkill -u "$USER" -f "/usr/local/bin/cosmic-app-list" || true
|
||||||
|
pkill -u "$USER" -f "/usr/local/bin/cosmic-panel-button" || true
|
||||||
|
|
||||||
|
echo "==> Vérif"
|
||||||
|
for bin in "${TARGETS[@]}"; do
|
||||||
|
file "$BIN_DIR/$bin"
|
||||||
|
done
|
||||||
|
echo "OK — relogin recommandé pour repartir sur des process applet propres."
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "1.90.0"
|
channel = "1.93.0"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue