This commit is contained in:
Jeremy Soller 2026-07-06 07:12:26 -06:00 • committed by GitHub
commit 0543dd7441
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 998 additions and 941 deletions

811
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -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 = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "a7d2d7a" }
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 = { git = "https://github.com/pop-os/cosmic-protocols", default-features = false, features = [
"client", "client",
], rev = "d0e95be" } ], rev = "a7d2d7a" }
futures = "0.3" futures = "0.3"
futures-util = "0.3" futures-util = "0.3"
@ -74,20 +74,16 @@ ignored = ["libcosmic"]
# cosmic-config = { path = "../libcosmic/cosmic-config" } # cosmic-config = { path = "../libcosmic/cosmic-config" }
# libcosmic = { path = "../libcosmic" } # libcosmic = { path = "../libcosmic" }
# iced_futures = { path = "../libcosmic/iced/futures" } # iced_futures = { path = "../libcosmic/iced/futures" }
# cosmic-config = { git = "https://github.com/pop-os/libcosmic//" } # cosmic-config = { git = "https://github.com/pop-os/libcosmic//", branch = "theme-v2" }
# libcosmic = { git = "https://github.com/pop-os/libcosmic//" } # libcosmic = { git = "https://github.com/pop-os/libcosmic//", branch = "theme-v2" }
# iced_futures = { git = "https://github.com/pop-os/libcosmic//" } # iced_futures = { git = "https://github.com/pop-os/libcosmic//", branch = "theme-v2" }
# [patch."https://github.com/pop-os/winit.git"]
# winit = { git = "https://github.com/rust-windowing/winit.git", rev = "241b7a80bba96c91fa3901729cd5dec66abb9be4" }
# winit = { path = "../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 = { git = "https://github.com/pop-os/cosmic-protocols//", rev = "32283d7" }
cosmic-client-toolkit = { git = "https://github.com/pop-os/cosmic-protocols//", branch = "main" } cosmic-client-toolkit = { git = "https://github.com/pop-os/cosmic-protocols//", rev = "32283d7" }
# [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" }

View file

@ -27,25 +27,28 @@ use cosmic::{
}, },
cosmic_config::{Config, CosmicConfigEntry}, cosmic_config::{Config, CosmicConfigEntry},
desktop::IconSourceExt, desktop::IconSourceExt,
iced::runtime::{core::event, dnd::peek_dnd},
iced::{ iced::{
self, Alignment, Background, Border, Length, Limits, Padding, Subscription, self, Alignment, Background, Border, Length, Limits, Padding, Subscription,
advanced::text::{Ellipsize, EllipsizeHeightLimit}, advanced::text::{Ellipsize, EllipsizeHeightLimit},
clipboard::mime::{AllowedMimeTypes, AsMimeTypes}, clipboard::mime::{AllowedMimeTypes, AsMimeTypes},
event::listen_with, event::listen_with,
platform_specific::shell::commands::popup::{destroy_popup, get_popup}, platform_specific::shell::commands::popup::{destroy_popup, get_popup},
runtime::{core::event, dnd::peek_dnd, platform_specific::wayland::CornerRadius},
widget::{ widget::{
Column, Row, column, mouse_area, row, rule::vertical as vertical_rule, Column, Row, column, mouse_area, row,
space::horizontal as horizontal_space, space::vertical as vertical_space, stack, rule::vertical as vertical_rule,
space::{horizontal as horizontal_space, vertical as vertical_space},
stack,
}, },
window, window,
}, },
surface, surface::{self, action::LiveSettings},
theme::{self, Button, Container}, theme::{self, Button, Container},
widget::{ widget::{
DndDestination, Image, button, container, divider, dnd_source, DndDestination, Image, button, container, divider, dnd_source,
icon::{self, from_name}, icon::{self, from_name},
image::Handle, image::Handle,
menu,
rectangle_tracker::{RectangleTracker, RectangleUpdate, rectangle_tracker_subscription}, rectangle_tracker::{RectangleTracker, RectangleUpdate, rectangle_tracker_subscription},
svg, text, svg, text,
}, },
@ -906,21 +909,27 @@ impl cosmic::Application for CosmicAppList {
.iter() .iter()
.chain(self.pinned_list.iter()) .chain(self.pinned_list.iter())
.find(|t| t.id == id) .find(|t| t.id == id)
.cloned()
{ {
let Some(rectangle) = self.rectangles.get(&toplevel_group.id.into()) else { let Some(rectangle) = self.rectangles.get(&toplevel_group.id.into()).copied()
else {
tracing::error!("No rectangle found for toplevel group"); tracing::error!("No rectangle found for toplevel group");
return Task::none(); return Task::none();
}; };
let corners = self.core.system_theme().cosmic().corner_radii.radius_s;
let popup_task =
cosmic::surface::surface_task(cosmic::surface::action::app_popup(
move |_| LiveSettings::default(),
move |app: &mut Self| {
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.popup = Some(Popup { app.popup = Some(Popup {
parent: parent_window_id, parent: parent_window_id,
id: new_id, id: new_id,
dock_item: toplevel_group.clone(), dock_item: toplevel_group.clone(),
popup_type: PopupType::RightClickMenu, popup_type: PopupType::RightClickMenu,
}); });
let mut popup_settings = self.core.applet.get_popup_settings( let mut popup_settings = app.core.applet.get_popup_settings(
parent_window_id, parent_window_id,
new_id, new_id,
None, None,
@ -932,18 +941,22 @@ impl cosmic::Application for CosmicAppList {
y, y,
width, width,
height, height,
} = *rectangle; } = rectangle;
popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> { popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> {
x: x as i32, x: x as i32,
y: y as i32, y: y as i32,
width: width as i32, width: width as i32,
height: height as i32, height: height as i32,
}; };
popup_settings
},
None,
));
let gpu_update = Task::perform(try_get_gpus(), |gpus| { let gpu_update = Task::perform(try_get_gpus(), |gpus| {
cosmic::Action::App(Message::GpuRequest(gpus)) cosmic::Action::App(Message::GpuRequest(gpus))
}); });
return Task::batch([gpu_update, get_popup(popup_settings)]); return Task::batch([gpu_update, popup_task]);
} }
} }
Message::ToplevelListPopup(id, parent_window_id) => { Message::ToplevelListPopup(id, parent_window_id) => {
@ -974,10 +987,10 @@ impl cosmic::Application for CosmicAppList {
} }
} }
let Some(rectangle) = self.rectangles.get(&toplevel_group.id.into()) else { let Some(rectangle) = self.rectangles.get(&toplevel_group.id.into()).copied()
else {
return Task::none(); return Task::none();
}; };
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.popup = Some(Popup { self.popup = Some(Popup {
parent: parent_window_id, parent: parent_window_id,
@ -985,8 +998,11 @@ impl cosmic::Application for CosmicAppList {
dock_item: toplevel_group.clone(), dock_item: toplevel_group.clone(),
popup_type: PopupType::ToplevelList, popup_type: PopupType::ToplevelList,
}); });
let popup_task =
let mut popup_settings = self.core.applet.get_popup_settings( cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
move |app: &mut Self| {
let mut popup_settings = app.core.applet.get_popup_settings(
parent_window_id, parent_window_id,
new_id, new_id,
None, None,
@ -998,7 +1014,7 @@ impl cosmic::Application for CosmicAppList {
y, y,
width, width,
height, height,
} = *rectangle; } = rectangle;
popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> { popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> {
x: x as i32, x: x as i32,
y: y as i32, y: y as i32,
@ -1007,7 +1023,8 @@ impl cosmic::Application for CosmicAppList {
}; };
let max_windows = 7.0; let max_windows = 7.0;
let window_spacing = 8.0; let window_spacing = 8.0;
popup_settings.positioner.size_limits = match self.core.applet.anchor { popup_settings.positioner.size_limits = match app.core.applet.anchor
{
PanelAnchor::Right | PanelAnchor::Left => Limits::NONE PanelAnchor::Right | PanelAnchor::Left => Limits::NONE
.min_width(100.0) .min_width(100.0)
.min_height(30.0) .min_height(30.0)
@ -1025,8 +1042,12 @@ impl cosmic::Application for CosmicAppList {
) )
.max_height(window_spacing * 2.0 + TOPLEVEL_BUTTON_HEIGHT), .max_height(window_spacing * 2.0 + TOPLEVEL_BUTTON_HEIGHT),
}; };
popup_settings
},
None,
));
return get_popup(popup_settings); return popup_task;
} }
} }
Message::ToplevelHoverChanged(handle, entering) => { Message::ToplevelHoverChanged(handle, entering) => {
@ -1590,39 +1611,46 @@ impl cosmic::Application for CosmicAppList {
if create_new { if create_new {
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.overflow_active_popup = Some(new_id); self.overflow_active_popup = Some(new_id);
let rectangle = self.rectangles.get(&DockItemId::ActiveOverflow); let Some(iced::Rectangle {
let mut popup_settings = self.core.applet.get_popup_settings( x,
self.core.main_window_id().unwrap(), y,
width,
height,
}) = self.rectangles.get(&DockItemId::ActiveOverflow).copied()
else {
return Task::none();
};
let popup_task =
cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
move |app: &mut Self| {
let mut popup_settings = app.core.applet.get_popup_settings(
app.core.main_window_id().unwrap(),
new_id, new_id,
None, None,
None, None,
None, None,
); );
if let Some(iced::Rectangle {
x,
y,
width,
height,
}) = rectangle
{
popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> { popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> {
x: *x as i32, x: x as i32,
y: *y as i32, y: y as i32,
width: *width as i32, width: width as i32,
height: *height as i32, height: height as i32,
}; };
}
let applet_suggested_size = self.core.applet.suggested_size(false).0 let applet_suggested_size = app.core.applet.suggested_size(false).0
+ 2 * self.core.applet.suggested_padding(false).0; + 2 * app.core.applet.suggested_padding(false).0;
let (_favorite_popup_cutoff, active_popup_cutoff) = let (_favorite_popup_cutoff, active_popup_cutoff) =
self.panel_overflow_lengths(); app.panel_overflow_lengths();
let popup_applet_count = let popup_applet_count = app.active_list.len().saturating_sub(
self.active_list.len().saturating_sub(
(active_popup_cutoff.unwrap_or_default()).saturating_sub(1), (active_popup_cutoff.unwrap_or_default()).saturating_sub(1),
) as f32; ) as f32;
let popup_applet_size = applet_suggested_size as f32 * popup_applet_count let popup_applet_size = applet_suggested_size as f32
* popup_applet_count
+ 4.0 * (popup_applet_count - 1.); + 4.0 * (popup_applet_count - 1.);
let (max_width, max_height) = match self.core.applet.anchor { let (max_width, max_height) = match app.core.applet.anchor {
PanelAnchor::Top | PanelAnchor::Bottom => { PanelAnchor::Top | PanelAnchor::Bottom => {
(popup_applet_size, applet_suggested_size as f32) (popup_applet_size, applet_suggested_size as f32)
} }
@ -1635,7 +1663,11 @@ impl cosmic::Application for CosmicAppList {
.min_width(1.) .min_width(1.)
.max_height(max_height) .max_height(max_height)
.min_height(1.); .min_height(1.);
cmds.push(get_popup(popup_settings)); popup_settings
},
None,
));
cmds.push(popup_task);
} }
return Task::batch(cmds); return Task::batch(cmds);
} }
@ -1647,39 +1679,46 @@ impl cosmic::Application for CosmicAppList {
if create_new { if create_new {
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.overflow_favorites_popup = Some(new_id); self.overflow_favorites_popup = Some(new_id);
let rectangle = self.rectangles.get(&DockItemId::FavoritesOverflow); let Some(iced::Rectangle {
let mut popup_settings = self.core.applet.get_popup_settings( x,
self.core.main_window_id().unwrap(), y,
width,
height,
}) = self.rectangles.get(&DockItemId::FavoritesOverflow).copied()
else {
return Task::none();
};
let popup_task =
cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
move |app: &mut Self| {
let mut popup_settings = app.core.applet.get_popup_settings(
app.core.main_window_id().unwrap(),
new_id, new_id,
None, None,
None, None,
None, None,
); );
if let Some(iced::Rectangle {
x,
y,
width,
height,
}) = rectangle
{
popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> { popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> {
x: *x as i32, x: x as i32,
y: *y as i32, y: y as i32,
width: *width as i32, width: width as i32,
height: *height as i32, height: height as i32,
}; };
}
let applet_suggested_size = self.core.applet.suggested_size(false).0 let applet_suggested_size = app.core.applet.suggested_size(false).0
+ 2 * self.core.applet.suggested_padding(false).0; + 2 * app.core.applet.suggested_padding(false).0;
let (favorite_popup_cutoff, _active_popup_cutoff) = let (favorite_popup_cutoff, _active_popup_cutoff) =
self.panel_overflow_lengths(); app.panel_overflow_lengths();
let popup_applet_count = let popup_applet_count = app.pinned_list.len().saturating_sub(
self.pinned_list.len().saturating_sub(
favorite_popup_cutoff.unwrap_or_default().saturating_sub(1), favorite_popup_cutoff.unwrap_or_default().saturating_sub(1),
) as f32; ) as f32;
let popup_applet_size = applet_suggested_size as f32 * popup_applet_count let popup_applet_size = applet_suggested_size as f32
* popup_applet_count
+ 4.0 * (popup_applet_count - 1.); + 4.0 * (popup_applet_count - 1.);
let (max_width, max_height) = match self.core.applet.anchor { let (max_width, max_height) = match app.core.applet.anchor {
PanelAnchor::Top | PanelAnchor::Bottom => { PanelAnchor::Top | PanelAnchor::Bottom => {
(popup_applet_size, applet_suggested_size as f32) (popup_applet_size, applet_suggested_size as f32)
} }
@ -1692,7 +1731,11 @@ impl cosmic::Application for CosmicAppList {
.min_width(1.) .min_width(1.)
.max_height(max_height) .max_height(max_height)
.min_height(1.); .min_height(1.);
cmds.push(get_popup(popup_settings)); popup_settings
},
None,
));
cmds.push(popup_task);
} }
return Task::batch(cmds); return Task::batch(cmds);
} }
@ -2086,7 +2129,8 @@ impl cosmic::Application for CosmicAppList {
.width(Length::Fill) .width(Length::Fill)
} }
let mut content = column![].align_x(Alignment::Center); let mut content =
menu::menu_column::MenuColumn::with_capacity(4).align_x(Alignment::Center);
if let Some(exec) = desktop_info.exec() { if let Some(exec) = desktop_info.exec() {
if !toplevels.is_empty() { if !toplevels.is_empty() {
@ -2197,22 +2241,6 @@ impl cosmic::Application for CosmicAppList {
.popup_container( .popup_container(
container(content) container(content)
.padding(1) .padding(1)
//TODO: move style to libcosmic
.class(theme::Container::custom(|theme| {
let cosmic = theme.cosmic();
let component = &cosmic.background.component;
container::Style {
icon_color: Some(component.on.into()),
text_color: Some(component.on.into()),
background: Some(Background::Color(component.base.into())),
border: Border {
radius: cosmic.radius_s().into(),
width: 1.0,
color: component.divider.into(),
},
..Default::default()
}
}))
.height(Length::Shrink) .height(Length::Shrink)
.width(Length::Fill), .width(Length::Fill),
) )

View file

@ -133,20 +133,27 @@ impl cosmic::Application for CosmicA11yApplet {
} }
Message::TogglePopup => { Message::TogglePopup => {
if let Some(p) = self.popup.take() { if let Some(p) = self.popup.take() {
return destroy_popup(p); return cosmic::surface::surface_task(cosmic::surface::action::destroy_popup(
p,
));
} else { } else {
return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
|app: &mut CosmicA11yApplet| {
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.popup.replace(new_id); app.popup.replace(new_id);
let popup_settings = self.core.applet.get_popup_settings( let popup_settings = app.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(), app.core.main_window_id().unwrap(),
new_id, new_id,
Some((1, 1)), Some((1, 1)),
None, None,
None, None,
); );
popup_settings
return get_popup(popup_settings); },
None,
));
} }
} }
Message::CloseRequested(id) => { Message::CloseRequested(id) => {

View file

@ -290,31 +290,37 @@ impl cosmic::Application for Audio {
Message::Ignore => {} Message::Ignore => {}
Message::TogglePopup => { Message::TogglePopup => {
if let Some(p) = self.popup.take() { if let Some(p) = self.popup.take() {
return destroy_popup(p); return cosmic::surface::surface_task(cosmic::surface::action::destroy_popup(
p,
));
} else { } else {
return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
|app: &mut Self| {
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.popup.replace(new_id); app.popup.replace(new_id);
(self.max_sink_volume, self.sink_breakpoints) = if amplification_sink() { (app.max_sink_volume, app.sink_breakpoints) = if amplification_sink() {
(150, &[100][..]) (150, &[100][..])
} else { } else {
(100, &[][..]) (100, &[][..])
}; };
(self.max_source_volume, self.source_breakpoints) = if amplification_source() { (app.max_source_volume, app.source_breakpoints) =
if amplification_source() {
(150, &[100][..]) (150, &[100][..])
} else { } else {
(100, &[][..]) (100, &[][..])
}; };
let mut popup_settings = self.core.applet.get_popup_settings( let mut popup_settings = app.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(), app.core.main_window_id().unwrap(),
new_id, new_id,
None, None,
None, None,
None, None,
); );
if let Some(r) = self.rectangle { if let Some(r) = app.rectangle {
popup_settings.positioner.anchor_rect = Rectangle { popup_settings.positioner.anchor_rect = Rectangle {
x: r.x as i32, x: r.x as i32,
y: r.y as i32, y: r.y as i32,
@ -322,7 +328,10 @@ impl cosmic::Application for Audio {
height: r.height as i32, height: r.height as i32,
}; };
} }
return get_popup(popup_settings); popup_settings
},
None,
));
} }
} }

View file

@ -365,23 +365,31 @@ impl cosmic::Application for CosmicBatteryApplet {
let _ = tx.send(KeyboardBacklightRequest::Get); let _ = tx.send(KeyboardBacklightRequest::Get);
} }
let new_id = window::Id::unique();
self.popup.replace(new_id);
let popup_settings = self.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(),
new_id,
Some((1, 1)),
None,
None,
);
if let Some(tx) = self.power_profile_sender.as_ref() { if let Some(tx) = self.power_profile_sender.as_ref() {
let _ = tx.send(PowerProfileRequest::Get); let _ = tx.send(PowerProfileRequest::Get);
} }
if let Some(tx) = self.update_trigger.as_ref() { if let Some(tx) = self.update_trigger.as_ref() {
let _ = tx.send(()); let _ = tx.send(());
} }
let mut tasks = vec![get_popup(popup_settings)]; let mut tasks = vec![cosmic::surface::surface_task(
cosmic::surface::action::app_popup(
|_| Default::default(),
|app: &mut Self| {
let new_id = window::Id::unique();
app.popup.replace(new_id);
let popup_settings = app.core.applet.get_popup_settings(
app.core.main_window_id().unwrap(),
new_id,
Some((1, 1)),
None,
None,
);
popup_settings
},
None,
),
)];
if let Some(tx) = &self.settings_daemon_sender { if let Some(tx) = &self.settings_daemon_sender {
let _ = tx.send(settings_daemon::Request::GetDisplayBrightness); let _ = tx.send(settings_daemon::Request::GetDisplayBrightness);
let _ = tx.send(settings_daemon::Request::GetMaxDisplayBrightness); let _ = tx.send(settings_daemon::Request::GetMaxDisplayBrightness);

View file

@ -120,20 +120,25 @@ impl cosmic::Application for CosmicBluetoothApplet {
} else { } else {
set_discovery(true); set_discovery(true);
// TODO request update of state maybe let get_popup_task =
cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
move |app: &mut Self| {
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.popup.replace(new_id); app.popup.replace(new_id);
app.core.applet.get_popup_settings(
let popup_settings = self.core.applet.get_popup_settings( app.core.main_window_id().unwrap(),
self.core.main_window_id().unwrap(),
new_id, new_id,
None, None,
None, None,
None, None,
); )
},
None,
));
return Task::batch([ return Task::batch([
get_popup(popup_settings), get_popup_task,
cosmic::task::future(set_tick(Duration::from_secs(3))) cosmic::task::future(set_tick(Duration::from_secs(3)))
.map(|()| cosmic::Action::App(Message::Ignore)), .map(|()| cosmic::Action::App(Message::Ignore)),
]); ]);

View file

@ -142,19 +142,24 @@ impl cosmic::Application for Window {
match message { match message {
Message::TogglePopup => { Message::TogglePopup => {
return if let Some(p) = self.popup.take() { return if let Some(p) = self.popup.take() {
destroy_popup(p) return crate::surface::surface_task(crate::surface::action::destroy_popup(p));
} else { } else {
return crate::surface::surface_task(crate::surface::action::app_popup(
|_| Default::default(),
|app: &mut Window| {
let new_id = Id::unique(); let new_id = Id::unique();
self.popup.replace(new_id); app.popup.replace(new_id);
let popup_settings = self.core.applet.get_popup_settings( let popup_settings = app.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(), app.core.main_window_id().unwrap(),
new_id, new_id,
None, None,
None, None,
None, None,
); );
popup_settings
get_popup(popup_settings) },
None,
));
}; };
} }
Message::PopupClosed(id) => { Message::PopupClosed(id) => {

View file

@ -248,17 +248,23 @@ impl cosmic::Application for Minimize {
} }
Message::OpenOverflowPopup => { Message::OpenOverflowPopup => {
if let Some(id) = self.overflow_popup.take() { if let Some(id) = self.overflow_popup.take() {
return destroy_popup(id); return cosmic::surface::surface_task(cosmic::surface::action::destroy_popup(
id,
));
} else { } else {
return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
|app: &mut Self| {
let new_id = window::Id::unique(); let new_id = window::Id::unique();
let pos = self.max_icon_count().unwrap_or_default(); let pos = app.max_icon_count().unwrap_or_default();
self.overflow_popup = Some(new_id); app.overflow_popup = Some(new_id);
let icon_size = self.core.applet.suggested_size(true).0 as u32 let icon_size = app.core.applet.suggested_size(true).0 as u32
+ 2 * self.core.applet.suggested_padding(true).1 as u32; + 2 * app.core.applet.suggested_padding(true).1 as u32;
let spacing = self.core.system_theme().cosmic().space_xxs() as u32; let spacing = app.core.system_theme().cosmic().space_xxs() as u32;
let major_axis_len = (icon_size + spacing) * (pos.saturating_sub(1) as u32); let major_axis_len =
let rectangle = match self.core.applet.anchor { (icon_size + spacing) * (pos.saturating_sub(1) as u32);
let rectangle = match app.core.applet.anchor {
PanelAnchor::Top | PanelAnchor::Bottom => iced::Rectangle { PanelAnchor::Top | PanelAnchor::Bottom => iced::Rectangle {
x: major_axis_len as i32, x: major_axis_len as i32,
y: 0, y: 0,
@ -272,16 +278,18 @@ impl cosmic::Application for Minimize {
height: icon_size as i32, height: icon_size as i32,
}, },
}; };
let mut popup_settings = self.core.applet.get_popup_settings( let mut popup_settings = app.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(), app.core.main_window_id().unwrap(),
new_id, new_id,
None, None,
None, None,
None, None,
); );
popup_settings.positioner.anchor_rect = rectangle; popup_settings.positioner.anchor_rect = rectangle;
popup_settings
return get_popup(popup_settings); },
None,
));
} }
} }
Message::CloseOverflowPopup => todo!(), Message::CloseOverflowPopup => todo!(),

View file

@ -731,32 +731,44 @@ impl cosmic::Application for CosmicNetworkApplet {
} else { } else {
let mut tasks = Vec::with_capacity(2); let mut tasks = Vec::with_capacity(2);
if let Some(conn) = self.conn.clone() { if let Some(conn) = self.conn.clone() {
tasks.push(update_state(conn.clone())); tasks.push(update_state(conn.clone()).map(cosmic::Action::App));
tasks.push(update_devices(conn.clone())); tasks.push(update_devices(conn.clone()).map(cosmic::Action::App));
tasks.push(load_vpns(conn)); tasks.push(load_vpns(conn).map(cosmic::Action::App));
let uuid = uuid::Uuid::new_v4().to_string().replace("-", "_"); let uuid = uuid::Uuid::new_v4().to_string().replace("-", "_");
let my_id = format!( let my_id = format!(
"com.system76.CosmicSettings.Applet._{uuid}.NetworkManager.SecretAgent", "com.system76.CosmicSettings.Applet._{uuid}.NetworkManager.SecretAgent",
); );
tasks.push(secret_agent_task(my_id).map(Message::SecretAgent)); tasks.push(
secret_agent_task(my_id)
.map(Message::SecretAgent)
.map(cosmic::Action::App),
);
} }
// TODO request update of state maybe
let new_id = window::Id::unique();
self.popup.replace(new_id);
let popup_settings = self.core.applet.get_popup_settings( tasks.push(system_conn().map(cosmic::Action::App));
self.core.main_window_id().unwrap(),
tasks.push(cosmic::surface::surface_task(
cosmic::surface::action::app_popup(
|_| Default::default(),
|app: &mut Self| {
let new_id = window::Id::unique();
app.popup.replace(new_id);
let popup_settings = app.core.applet.get_popup_settings(
app.core.main_window_id().unwrap(),
new_id, new_id,
None, None,
None, None,
None, None,
); );
popup_settings
},
None,
),
));
tasks.push(system_conn()); return Task::batch(tasks);
tasks.push(get_popup(popup_settings));
return Task::batch(tasks).map(cosmic::Action::App);
} }
} }
Message::ToggleAirplaneMode(enabled) => { Message::ToggleAirplaneMode(enabled) => {
@ -1749,7 +1761,7 @@ impl cosmic::Application for CosmicNetworkApplet {
.icon_size(16) .icon_size(16)
.on_press(Message::ResetFailedKnownSsid( .on_press(Message::ResetFailedKnownSsid(
known.ssid.to_string(), known.ssid.to_string(),
known.hw_address, known.hw_address.clone(),
)) ))
.into(), .into(),
); );
@ -1765,12 +1777,14 @@ impl cosmic::Application for CosmicNetworkApplet {
| DeviceState::Unknown | DeviceState::Unknown
| DeviceState::Unmanaged | DeviceState::Unmanaged
| DeviceState::Disconnected | DeviceState::Disconnected
| DeviceState::NeedAuth => { | DeviceState::NeedAuth => btn.on_press(Message::Connect(
btn.on_press(Message::Connect(known.ssid.clone(), known.hw_address)) known.ssid.clone(),
} known.hw_address.clone(),
DeviceState::Activated => { )),
btn.on_press(Message::Disconnect(known.ssid.clone(), known.hw_address)) DeviceState::Activated => btn.on_press(Message::Disconnect(
} known.ssid.clone(),
known.hw_address.clone(),
)),
_ => btn, _ => btn,
}; };
known_wifi.push(Element::from( known_wifi.push(Element::from(

View file

@ -157,18 +157,23 @@ impl cosmic::Application for Notifications {
if let Some(p) = self.popup.take() { if let Some(p) = self.popup.take() {
return destroy_popup(p); return destroy_popup(p);
} else { } else {
return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
|app: &mut Self| {
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.popup.replace(new_id); app.popup.replace(new_id);
let popup_settings = self.core.applet.get_popup_settings( let popup_settings = app.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(), app.core.main_window_id().unwrap(),
new_id, new_id,
None, None,
None, None,
None, None,
); );
popup_settings
return get_popup(popup_settings); },
None,
));
} }
} }
Message::DoNotDisturb(b) => { Message::DoNotDisturb(b) => {

View file

@ -120,20 +120,27 @@ impl cosmic::Application for Power {
match message { match message {
Message::TogglePopup => { Message::TogglePopup => {
if let Some(p) = self.popup.take() { if let Some(p) = self.popup.take() {
return destroy_popup(p); return cosmic::surface::surface_task(cosmic::surface::action::destroy_popup(
p,
));
} else { } else {
return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
|app: &mut Power| {
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.popup.replace(new_id); app.popup.replace(new_id);
let popup_settings = self.core.applet.get_popup_settings( let popup_settings = app.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(), app.core.main_window_id().unwrap(),
new_id, new_id,
None, None,
None, None,
None, None,
); );
popup_settings
return get_popup(popup_settings); },
None,
));
} }
} }
Message::OpenSettings => { Message::OpenSettings => {

View file

@ -245,38 +245,49 @@ impl cosmic::Application for App {
if let Some(popup_id) = self.popup.take() { if let Some(popup_id) = self.popup.take() {
cmds.push(destroy_popup(popup_id)); cmds.push(destroy_popup(popup_id));
} }
let popup_id = self.next_popup_id();
let i = self.menus.keys().position(|&i| i == id).unwrap(); let popup_task =
let (i, parent) = self cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
move |app: &mut Self| {
let popup_id = app.next_popup_id();
let i = app.menus.keys().position(|&i| i == id).unwrap();
let (i, parent) = app
.overflow_index() .overflow_index()
.and_then(|overflow_i| { .and_then(|overflow_i| {
if overflow_i <= i { if overflow_i <= i {
Some(i - overflow_i).zip(self.overflow_popup) Some(i - overflow_i).zip(app.overflow_popup)
} else { } else {
Some((i, self.core.main_window_id().unwrap())) Some((i, app.core.main_window_id().unwrap()))
} }
}) })
.unwrap_or((i, self.core.main_window_id().unwrap())); .unwrap_or((i, app.core.main_window_id().unwrap()));
let mut popup_settings = self let mut popup_settings = app
.core .core
.applet .applet
.get_popup_settings(parent, popup_id, None, None, None); .get_popup_settings(parent, popup_id, None, None, None);
self.popup = Some(popup_id); app.popup = Some(popup_id);
if matches!( if matches!(
self.core.applet.anchor, app.core.applet.anchor,
PanelAnchor::Left | PanelAnchor::Right PanelAnchor::Left | PanelAnchor::Right
) { ) {
let suggested_size = self.core.applet.suggested_size(false).1 let suggested_size = app.core.applet.suggested_size(false).1
+ 2 * self.core.applet.suggested_padding(false).1; + 2 * app.core.applet.suggested_padding(false).1;
popup_settings.positioner.anchor_rect.y = i as i32 * suggested_size as i32; popup_settings.positioner.anchor_rect.y =
i as i32 * suggested_size as i32;
} else { } else {
let suggested_size = self.core.applet.suggested_size(false).0 let suggested_size = app.core.applet.suggested_size(false).0
+ 2 * self.core.applet.suggested_padding(false).1; + 2 * app.core.applet.suggested_padding(false).1;
popup_settings.positioner.anchor_rect.x = i as i32 * suggested_size as i32; popup_settings.positioner.anchor_rect.x =
i as i32 * suggested_size as i32;
} }
cmds.push(get_popup(popup_settings)); popup_settings
},
None,
));
cmds.push(popup_task);
return app::Task::batch(cmds); return app::Task::batch(cmds);
} else if let Some(popup_id) = self.popup { } else if let Some(popup_id) = self.popup {
self.menus[&id].closed(); self.menus[&id].closed();
@ -338,39 +349,49 @@ impl cosmic::Application for App {
} else { } else {
return Task::none(); return Task::none();
} }
let popup_id = self.next_popup_id(); let popup_task = cosmic::surface::surface_task(cosmic::surface::action::app_popup(
let i = self.menus.keys().position(|&i| i == id).unwrap(); |_| Default::default(),
move |app: &mut Self| {
let popup_id = app.next_popup_id();
let i = app.menus.keys().position(|&i| i == id).unwrap();
let (i, parent) = self let (i, parent) = app
.overflow_index() .overflow_index()
.and_then(|overflow_i| { .and_then(|overflow_i| {
if overflow_i <= i { if overflow_i <= i {
Some(i - overflow_i).zip(self.overflow_popup) Some(i - overflow_i).zip(app.overflow_popup)
} else { } else {
Some((i, self.core.main_window_id().unwrap())) Some((i, app.core.main_window_id().unwrap()))
} }
}) })
.unwrap_or((i, self.core.main_window_id().unwrap())); .unwrap_or((i, app.core.main_window_id().unwrap()));
let mut popup_settings = self let mut popup_settings = app
.core .core
.applet .applet
.get_popup_settings(parent, popup_id, None, None, None); .get_popup_settings(parent, popup_id, None, None, None);
self.popup = Some(popup_id); app.popup = Some(popup_id);
if matches!( if matches!(
self.core.applet.anchor, app.core.applet.anchor,
PanelAnchor::Left | PanelAnchor::Right PanelAnchor::Left | PanelAnchor::Right
) { ) {
let suggested_size = self.core.applet.suggested_size(true).1 let suggested_size = app.core.applet.suggested_size(true).1
+ 2 * self.core.applet.suggested_padding(true).1; + 2 * app.core.applet.suggested_padding(true).1;
popup_settings.positioner.anchor_rect.y = i as i32 * suggested_size as i32; popup_settings.positioner.anchor_rect.y =
i as i32 * suggested_size as i32;
} else { } else {
let suggested_size = self.core.applet.suggested_size(true).0 let suggested_size = app.core.applet.suggested_size(true).0
+ 2 * self.core.applet.suggested_padding(true).0; + 2 * app.core.applet.suggested_padding(true).0;
popup_settings.positioner.anchor_rect.x = i as i32 * suggested_size as i32; popup_settings.positioner.anchor_rect.x =
i as i32 * suggested_size as i32;
} }
cmds.push(get_popup(popup_settings)); popup_settings
},
None,
));
cmds.push(popup_task);
Task::batch(cmds) Task::batch(cmds)
} }
Msg::WheelScrolled(delta) => { Msg::WheelScrolled(delta) => {
@ -398,9 +419,13 @@ impl cosmic::Application for App {
return destroy_popup(popup_id); return destroy_popup(popup_id);
} else if let Some(overflow_index) = self.overflow_index() { } else if let Some(overflow_index) = self.overflow_index() {
// If we don't have an overflow, create it // If we don't have an overflow, create it
let popup_id = self.next_popup_id(); let popup_task =
let mut popup_settings = self.core.applet.get_popup_settings( cosmic::surface::surface_task(cosmic::surface::action::app_popup(
self.core.main_window_id().unwrap(), |_| Default::default(),
move |app: &mut Self| {
let popup_id = app.next_popup_id();
let mut popup_settings = app.core.applet.get_popup_settings(
app.core.main_window_id().unwrap(),
popup_id, popup_id,
None, None,
None, None,
@ -409,22 +434,26 @@ impl cosmic::Application for App {
popup_settings.close_with_children = false; popup_settings.close_with_children = false;
if matches!( if matches!(
self.core.applet.anchor, app.core.applet.anchor,
PanelAnchor::Left | PanelAnchor::Right PanelAnchor::Left | PanelAnchor::Right
) { ) {
let suggested_size = self.core.applet.suggested_size(true).1 let suggested_size = app.core.applet.suggested_size(true).1
+ 2 * self.core.applet.suggested_padding(true).1; + 2 * app.core.applet.suggested_padding(true).1;
popup_settings.positioner.anchor_rect.y = popup_settings.positioner.anchor_rect.y =
overflow_index as i32 * suggested_size as i32; overflow_index as i32 * suggested_size as i32;
} else { } else {
let suggested_size = self.core.applet.suggested_size(true).0 let suggested_size = app.core.applet.suggested_size(true).0
+ 2 * self.core.applet.suggested_padding(true).0; + 2 * app.core.applet.suggested_padding(true).0;
popup_settings.positioner.anchor_rect.x = popup_settings.positioner.anchor_rect.x =
overflow_index as i32 * suggested_size as i32; overflow_index as i32 * suggested_size as i32;
} }
self.overflow_popup = Some(popup_id); app.overflow_popup = Some(popup_id);
return get_popup(popup_settings); popup_settings
},
None,
));
return popup_task;
} else { } else {
return Task::none(); return Task::none();
} }
@ -443,34 +472,41 @@ impl cosmic::Application for App {
} else { } else {
return Task::none(); return Task::none();
} }
let Some(i) = self.overflow_index() else {
let popup_id = self.next_popup_id(); return Task::batch(cmds);
let mut popup_settings = self.core.applet.get_popup_settings( };
self.core.main_window_id().unwrap(), let popup_task = cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
move |app: &mut Self| {
let popup_id = app.next_popup_id();
let mut popup_settings = app.core.applet.get_popup_settings(
app.core.main_window_id().unwrap(),
popup_id, popup_id,
None, None,
None, None,
None, None,
); );
self.popup = Some(popup_id); app.popup = Some(popup_id);
let Some(i) = self.overflow_index() else {
return Task::batch(cmds);
};
if matches!( if matches!(
self.core.applet.anchor, app.core.applet.anchor,
PanelAnchor::Left | PanelAnchor::Right PanelAnchor::Left | PanelAnchor::Right
) { ) {
let suggested_size = self.core.applet.suggested_size(false).1 let suggested_size = app.core.applet.suggested_size(false).1
+ 2 * self.core.applet.suggested_padding(false).1; + 2 * app.core.applet.suggested_padding(false).1;
popup_settings.positioner.anchor_rect.y = i as i32 * suggested_size as i32; popup_settings.positioner.anchor_rect.y =
i as i32 * suggested_size as i32;
} else { } else {
let suggested_size = self.core.applet.suggested_size(false).0 let suggested_size = app.core.applet.suggested_size(false).0
+ 2 * self.core.applet.suggested_padding(false).1; + 2 * app.core.applet.suggested_padding(false).1;
popup_settings.positioner.anchor_rect.x = i as i32 * suggested_size as i32; popup_settings.positioner.anchor_rect.x =
i as i32 * suggested_size as i32;
} }
cmds.push(get_popup(popup_settings)); popup_settings
},
None,
));
cmds.push(popup_task);
Task::batch(cmds) Task::batch(cmds)
} }
} }
@ -655,7 +691,7 @@ fn menu_icon_button<'a>(
.class(if symbolic { .class(if symbolic {
cosmic::theme::Svg::Custom(std::rc::Rc::new(|theme| { cosmic::theme::Svg::Custom(std::rc::Rc::new(|theme| {
cosmic::iced::widget::svg::Style { cosmic::iced::widget::svg::Style {
color: Some(theme.cosmic().background.on.into()), color: Some(theme.cosmic().background(theme.transparent).on.into()),
} }
})) }))
} else { } else {

View file

@ -146,17 +146,22 @@ impl cosmic::Application for Window {
return if let Some(p) = self.popup.take() { return if let Some(p) = self.popup.take() {
destroy_popup(p) destroy_popup(p)
} else { } else {
return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
|_| Default::default(),
|app: &mut Self| {
let new_id = Id::unique(); let new_id = Id::unique();
self.popup = Some(new_id); app.popup = Some(new_id);
let popup_settings = self.core.applet.get_popup_settings( let popup_settings = app.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(), app.core.main_window_id().unwrap(),
new_id, new_id,
Some((1, 1)), Some((1, 1)),
None, None,
None, None,
); );
popup_settings
get_popup(popup_settings) },
None,
));
}; };
} }
Message::PopupClosed(id) => { Message::PopupClosed(id) => {

View file

@ -520,14 +520,17 @@ impl cosmic::Application for Window {
if let Some(p) = self.popup.take() { if let Some(p) = self.popup.take() {
destroy_popup(p) destroy_popup(p)
} else { } else {
self.date_today = self.now.date(); return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
self.date_selected = self.date_today; |_| Default::default(),
|app: &mut Self| {
app.date_today = app.now.date();
app.date_selected = app.date_today;
let new_id = window::Id::unique(); let new_id = window::Id::unique();
self.popup = Some(new_id); app.popup = Some(new_id);
let mut popup_settings = self.core.applet.get_popup_settings( let mut popup_settings = app.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(), app.core.main_window_id().unwrap(),
new_id, new_id,
None, None,
None, None,
@ -538,7 +541,7 @@ impl cosmic::Application for Window {
y, y,
width, width,
height, height,
} = self.rectangle; } = app.rectangle;
popup_settings.positioner.anchor_rect = Rectangle::<i32> { popup_settings.positioner.anchor_rect = Rectangle::<i32> {
x: x.max(1.) as i32, x: x.max(1.) as i32,
y: y.max(1.) as i32, y: y.max(1.) as i32,
@ -547,8 +550,10 @@ impl cosmic::Application for Window {
}; };
popup_settings.positioner.size = None; popup_settings.positioner.size = None;
popup_settings
get_popup(popup_settings) },
None,
));
} }
} }
Message::Tick => { Message::Tick => {

View file

@ -202,11 +202,7 @@ impl cosmic::Application for IcedWorkspacesApplet {
let content = column!(content, space::horizontal().width(Length::Fixed(width))) let content = column!(content, space::horizontal().width(Length::Fixed(width)))
.align_x(Alignment::Center); .align_x(Alignment::Center);
let btn = button( let btn = button(content)
container(content)
.align_x(Alignment::Center)
.align_y(Alignment::Center),
)
.padding(if horizontal { .padding(if horizontal {
[0, self.core.applet.suggested_padding(true).1] [0, self.core.applet.suggested_padding(true).1]
} else { } else {

View file

@ -66,7 +66,7 @@ impl Button {
.class(if symbolic { .class(if symbolic {
cosmic::theme::Svg::Custom(std::rc::Rc::new(|theme| { cosmic::theme::Svg::Custom(std::rc::Rc::new(|theme| {
cosmic::iced::widget::svg::Style { cosmic::iced::widget::svg::Style {
color: Some(theme.cosmic().background.on.into()), color: Some(theme.cosmic().background(theme.transparent).on.into()),
} }
})) }))
} else { } else {