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,44 +909,54 @@ 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();
app.popup = Some(Popup {
parent: parent_window_id,
id: new_id,
dock_item: toplevel_group.clone(),
popup_type: PopupType::RightClickMenu,
});
let new_id = window::Id::unique(); let mut popup_settings = app.core.applet.get_popup_settings(
self.popup = Some(Popup { parent_window_id,
parent: parent_window_id, new_id,
id: new_id, None,
dock_item: toplevel_group.clone(), None,
popup_type: PopupType::RightClickMenu, None,
}); );
let iced::Rectangle {
let mut popup_settings = self.core.applet.get_popup_settings( x,
parent_window_id, y,
new_id, width,
None, height,
None, } = rectangle;
None, popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> {
); x: x as i32,
let iced::Rectangle { y: y as i32,
x, width: width as i32,
y, height: height as i32,
width, };
height, popup_settings
} = *rectangle; },
popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> { None,
x: x as i32, ));
y: y as i32,
width: width as i32,
height: height as i32,
};
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,48 +998,56 @@ 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 =
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,
new_id,
None,
None,
None,
);
let iced::Rectangle {
x,
y,
width,
height,
} = rectangle;
popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> {
x: x as i32,
y: y as i32,
width: width as i32,
height: height as i32,
};
let max_windows = 7.0;
let window_spacing = 8.0;
popup_settings.positioner.size_limits = match app.core.applet.anchor
{
PanelAnchor::Right | PanelAnchor::Left => Limits::NONE
.min_width(100.0)
.min_height(30.0)
.max_width(window_spacing * 2.0 + TOPLEVEL_BUTTON_WIDTH)
.max_height(
TOPLEVEL_BUTTON_HEIGHT * max_windows
+ window_spacing * (max_windows + 1.0),
),
PanelAnchor::Bottom | PanelAnchor::Top => Limits::NONE
.min_width(30.0)
.min_height(100.0)
.max_width(
TOPLEVEL_BUTTON_WIDTH * max_windows
+ window_spacing * (max_windows + 1.0),
)
.max_height(window_spacing * 2.0 + TOPLEVEL_BUTTON_HEIGHT),
};
popup_settings
},
None,
));
let mut popup_settings = self.core.applet.get_popup_settings( return popup_task;
parent_window_id,
new_id,
None,
None,
None,
);
let iced::Rectangle {
x,
y,
width,
height,
} = *rectangle;
popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> {
x: x as i32,
y: y as i32,
width: width as i32,
height: height as i32,
};
let max_windows = 7.0;
let window_spacing = 8.0;
popup_settings.positioner.size_limits = match self.core.applet.anchor {
PanelAnchor::Right | PanelAnchor::Left => Limits::NONE
.min_width(100.0)
.min_height(30.0)
.max_width(window_spacing * 2.0 + TOPLEVEL_BUTTON_WIDTH)
.max_height(
TOPLEVEL_BUTTON_HEIGHT * max_windows
+ window_spacing * (max_windows + 1.0),
),
PanelAnchor::Bottom | PanelAnchor::Top => Limits::NONE
.min_width(30.0)
.min_height(100.0)
.max_width(
TOPLEVEL_BUTTON_WIDTH * max_windows
+ window_spacing * (max_windows + 1.0),
)
.max_height(window_spacing * 2.0 + TOPLEVEL_BUTTON_HEIGHT),
};
return get_popup(popup_settings);
} }
} }
Message::ToplevelHoverChanged(handle, entering) => { Message::ToplevelHoverChanged(handle, entering) => {
@ -1590,52 +1611,63 @@ 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(
self.core.main_window_id().unwrap(),
new_id,
None,
None,
None,
);
if let Some(iced::Rectangle {
x, x,
y, y,
width, width,
height, height,
}) = rectangle }) = self.rectangles.get(&DockItemId::ActiveOverflow).copied()
{ else {
popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> { return Task::none();
x: *x as i32,
y: *y as i32,
width: *width as i32,
height: *height as i32,
};
}
let applet_suggested_size = self.core.applet.suggested_size(false).0
+ 2 * self.core.applet.suggested_padding(false).0;
let (_favorite_popup_cutoff, active_popup_cutoff) =
self.panel_overflow_lengths();
let popup_applet_count =
self.active_list.len().saturating_sub(
(active_popup_cutoff.unwrap_or_default()).saturating_sub(1),
) as f32;
let popup_applet_size = applet_suggested_size as f32 * popup_applet_count
+ 4.0 * (popup_applet_count - 1.);
let (max_width, max_height) = match self.core.applet.anchor {
PanelAnchor::Top | PanelAnchor::Bottom => {
(popup_applet_size, applet_suggested_size as f32)
}
PanelAnchor::Left | PanelAnchor::Right => {
(applet_suggested_size as f32, popup_applet_size)
}
}; };
popup_settings.positioner.size_limits = Limits::NONE
.max_width(max_width) let popup_task =
.min_width(1.) cosmic::surface::surface_task(cosmic::surface::action::app_popup(
.max_height(max_height) |_| Default::default(),
.min_height(1.); move |app: &mut Self| {
cmds.push(get_popup(popup_settings)); let mut popup_settings = app.core.applet.get_popup_settings(
app.core.main_window_id().unwrap(),
new_id,
None,
None,
None,
);
popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> {
x: x as i32,
y: y as i32,
width: width as i32,
height: height as i32,
};
let applet_suggested_size = app.core.applet.suggested_size(false).0
+ 2 * app.core.applet.suggested_padding(false).0;
let (_favorite_popup_cutoff, active_popup_cutoff) =
app.panel_overflow_lengths();
let popup_applet_count = app.active_list.len().saturating_sub(
(active_popup_cutoff.unwrap_or_default()).saturating_sub(1),
) as f32;
let popup_applet_size = applet_suggested_size as f32
* popup_applet_count
+ 4.0 * (popup_applet_count - 1.);
let (max_width, max_height) = match app.core.applet.anchor {
PanelAnchor::Top | PanelAnchor::Bottom => {
(popup_applet_size, applet_suggested_size as f32)
}
PanelAnchor::Left | PanelAnchor::Right => {
(applet_suggested_size as f32, popup_applet_size)
}
};
popup_settings.positioner.size_limits = Limits::NONE
.max_width(max_width)
.min_width(1.)
.max_height(max_height)
.min_height(1.);
popup_settings
},
None,
));
cmds.push(popup_task);
} }
return Task::batch(cmds); return Task::batch(cmds);
} }
@ -1647,52 +1679,63 @@ 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(
self.core.main_window_id().unwrap(),
new_id,
None,
None,
None,
);
if let Some(iced::Rectangle {
x, x,
y, y,
width, width,
height, height,
}) = rectangle }) = self.rectangles.get(&DockItemId::FavoritesOverflow).copied()
{ else {
popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> { return Task::none();
x: *x as i32,
y: *y as i32,
width: *width as i32,
height: *height as i32,
};
}
let applet_suggested_size = self.core.applet.suggested_size(false).0
+ 2 * self.core.applet.suggested_padding(false).0;
let (favorite_popup_cutoff, _active_popup_cutoff) =
self.panel_overflow_lengths();
let popup_applet_count =
self.pinned_list.len().saturating_sub(
favorite_popup_cutoff.unwrap_or_default().saturating_sub(1),
) as f32;
let popup_applet_size = applet_suggested_size as f32 * popup_applet_count
+ 4.0 * (popup_applet_count - 1.);
let (max_width, max_height) = match self.core.applet.anchor {
PanelAnchor::Top | PanelAnchor::Bottom => {
(popup_applet_size, applet_suggested_size as f32)
}
PanelAnchor::Left | PanelAnchor::Right => {
(applet_suggested_size as f32, popup_applet_size)
}
}; };
popup_settings.positioner.size_limits = Limits::NONE
.max_width(max_width) let popup_task =
.min_width(1.) cosmic::surface::surface_task(cosmic::surface::action::app_popup(
.max_height(max_height) |_| Default::default(),
.min_height(1.); move |app: &mut Self| {
cmds.push(get_popup(popup_settings)); let mut popup_settings = app.core.applet.get_popup_settings(
app.core.main_window_id().unwrap(),
new_id,
None,
None,
None,
);
popup_settings.positioner.anchor_rect = iced::Rectangle::<i32> {
x: x as i32,
y: y as i32,
width: width as i32,
height: height as i32,
};
let applet_suggested_size = app.core.applet.suggested_size(false).0
+ 2 * app.core.applet.suggested_padding(false).0;
let (favorite_popup_cutoff, _active_popup_cutoff) =
app.panel_overflow_lengths();
let popup_applet_count = app.pinned_list.len().saturating_sub(
favorite_popup_cutoff.unwrap_or_default().saturating_sub(1),
) as f32;
let popup_applet_size = applet_suggested_size as f32
* popup_applet_count
+ 4.0 * (popup_applet_count - 1.);
let (max_width, max_height) = match app.core.applet.anchor {
PanelAnchor::Top | PanelAnchor::Bottom => {
(popup_applet_size, applet_suggested_size as f32)
}
PanelAnchor::Left | PanelAnchor::Right => {
(applet_suggested_size as f32, popup_applet_size)
}
};
popup_settings.positioner.size_limits = Limits::NONE
.max_width(max_width)
.min_width(1.)
.max_height(max_height)
.min_height(1.);
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 {
let new_id = window::Id::unique(); return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
self.popup.replace(new_id); |_| Default::default(),
|app: &mut CosmicA11yApplet| {
let new_id = window::Id::unique();
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,
);
popup_settings
},
None, None,
None, ));
);
return get_popup(popup_settings);
} }
} }
Message::CloseRequested(id) => { Message::CloseRequested(id) => {

View file

@ -290,39 +290,48 @@ 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 {
let new_id = window::Id::unique(); return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
self.popup.replace(new_id); |_| Default::default(),
|app: &mut Self| {
let new_id = window::Id::unique();
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) =
(150, &[100][..]) if amplification_source() {
} else { (150, &[100][..])
(100, &[][..]) } else {
}; (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,
);
if let Some(r) = app.rectangle {
popup_settings.positioner.anchor_rect = Rectangle {
x: r.x as i32,
y: r.y as i32,
width: r.width as i32,
height: r.height as i32,
};
}
popup_settings
},
None, None,
None, ));
None,
);
if let Some(r) = self.rectangle {
popup_settings.positioner.anchor_rect = Rectangle {
x: r.x as i32,
y: r.y as i32,
width: r.width as i32,
height: r.height as i32,
};
}
return get_popup(popup_settings);
} }
} }

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 =
let new_id = window::Id::unique(); cosmic::surface::surface_task(cosmic::surface::action::app_popup(
self.popup.replace(new_id); |_| Default::default(),
move |app: &mut Self| {
let popup_settings = self.core.applet.get_popup_settings( let new_id = window::Id::unique();
self.core.main_window_id().unwrap(), app.popup.replace(new_id);
new_id, app.core.applet.get_popup_settings(
None, app.core.main_window_id().unwrap(),
None, new_id,
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 {
let new_id = Id::unique(); return crate::surface::surface_task(crate::surface::action::app_popup(
self.popup.replace(new_id); |_| Default::default(),
let popup_settings = self.core.applet.get_popup_settings( |app: &mut Window| {
self.core.main_window_id().unwrap(), let new_id = Id::unique();
new_id, app.popup.replace(new_id);
let popup_settings = app.core.applet.get_popup_settings(
app.core.main_window_id().unwrap(),
new_id,
None,
None,
None,
);
popup_settings
},
None, None,
None, ));
None,
);
get_popup(popup_settings)
}; };
} }
Message::PopupClosed(id) => { Message::PopupClosed(id) => {

View file

@ -248,40 +248,48 @@ 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 {
let new_id = window::Id::unique(); return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
let pos = self.max_icon_count().unwrap_or_default(); |_| Default::default(),
|app: &mut Self| {
let new_id = window::Id::unique();
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);
PanelAnchor::Top | PanelAnchor::Bottom => iced::Rectangle { let rectangle = match app.core.applet.anchor {
x: major_axis_len as i32, PanelAnchor::Top | PanelAnchor::Bottom => iced::Rectangle {
y: 0, x: major_axis_len as i32,
width: icon_size as i32, y: 0,
height: icon_size as i32, width: icon_size as i32,
height: icon_size as i32,
},
PanelAnchor::Left | PanelAnchor::Right => iced::Rectangle {
x: 0,
y: major_axis_len as i32,
width: icon_size as i32,
height: icon_size as i32,
},
};
let mut popup_settings = app.core.applet.get_popup_settings(
app.core.main_window_id().unwrap(),
new_id,
None,
None,
None,
);
popup_settings.positioner.anchor_rect = rectangle;
popup_settings
}, },
PanelAnchor::Left | PanelAnchor::Right => iced::Rectangle {
x: 0,
y: major_axis_len as i32,
width: icon_size as i32,
height: icon_size as i32,
},
};
let mut popup_settings = self.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(),
new_id,
None, None,
None, ));
None,
);
popup_settings.positioner.anchor_rect = rectangle;
return get_popup(popup_settings);
} }
} }
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(),
new_id,
None,
None,
None,
);
tasks.push(system_conn()); tasks.push(cosmic::surface::surface_task(
tasks.push(get_popup(popup_settings)); cosmic::surface::action::app_popup(
|_| Default::default(),
|app: &mut Self| {
let new_id = window::Id::unique();
app.popup.replace(new_id);
return Task::batch(tasks).map(cosmic::Action::App); let popup_settings = app.core.applet.get_popup_settings(
app.core.main_window_id().unwrap(),
new_id,
None,
None,
None,
);
popup_settings
},
None,
),
));
return Task::batch(tasks);
} }
} }
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 {
let new_id = window::Id::unique(); return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
self.popup.replace(new_id); |_| Default::default(),
|app: &mut Self| {
let new_id = window::Id::unique();
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,
);
popup_settings
},
None, None,
None, ));
None,
);
return get_popup(popup_settings);
} }
} }
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 {
let new_id = window::Id::unique(); return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
self.popup.replace(new_id); |_| Default::default(),
|app: &mut Power| {
let new_id = window::Id::unique();
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,
);
popup_settings
},
None, None,
None, ));
None,
);
return get_popup(popup_settings);
} }
} }
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 (i, parent) = self
.overflow_index()
.and_then(|overflow_i| {
if overflow_i <= i {
Some(i - overflow_i).zip(self.overflow_popup)
} else {
Some((i, self.core.main_window_id().unwrap()))
}
})
.unwrap_or((i, self.core.main_window_id().unwrap()));
let mut popup_settings = self let popup_task =
.core cosmic::surface::surface_task(cosmic::surface::action::app_popup(
.applet |_| Default::default(),
.get_popup_settings(parent, popup_id, None, None, None); move |app: &mut Self| {
self.popup = Some(popup_id); let popup_id = app.next_popup_id();
let i = app.menus.keys().position(|&i| i == id).unwrap();
let (i, parent) = app
.overflow_index()
.and_then(|overflow_i| {
if overflow_i <= i {
Some(i - overflow_i).zip(app.overflow_popup)
} else {
Some((i, app.core.main_window_id().unwrap()))
}
})
.unwrap_or((i, app.core.main_window_id().unwrap()));
if matches!( let mut popup_settings = app
self.core.applet.anchor, .core
PanelAnchor::Left | PanelAnchor::Right .applet
) { .get_popup_settings(parent, popup_id, None, None, None);
let suggested_size = self.core.applet.suggested_size(false).1 app.popup = Some(popup_id);
+ 2 * self.core.applet.suggested_padding(false).1;
popup_settings.positioner.anchor_rect.y = i as i32 * suggested_size as i32; if matches!(
} else { app.core.applet.anchor,
let suggested_size = self.core.applet.suggested_size(false).0 PanelAnchor::Left | PanelAnchor::Right
+ 2 * self.core.applet.suggested_padding(false).1; ) {
popup_settings.positioner.anchor_rect.x = i as i32 * suggested_size as i32; let suggested_size = app.core.applet.suggested_size(false).1
} + 2 * app.core.applet.suggested_padding(false).1;
cmds.push(get_popup(popup_settings)); popup_settings.positioner.anchor_rect.y =
i as i32 * suggested_size as i32;
} else {
let suggested_size = app.core.applet.suggested_size(false).0
+ 2 * app.core.applet.suggested_padding(false).1;
popup_settings.positioner.anchor_rect.x =
i as i32 * suggested_size as i32;
}
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 {
Some((i, app.core.main_window_id().unwrap()))
}
})
.unwrap_or((i, app.core.main_window_id().unwrap()));
let mut popup_settings = app
.core
.applet
.get_popup_settings(parent, popup_id, None, None, None);
app.popup = Some(popup_id);
if matches!(
app.core.applet.anchor,
PanelAnchor::Left | PanelAnchor::Right
) {
let suggested_size = app.core.applet.suggested_size(true).1
+ 2 * app.core.applet.suggested_padding(true).1;
popup_settings.positioner.anchor_rect.y =
i as i32 * suggested_size as i32;
} else { } else {
Some((i, self.core.main_window_id().unwrap())) let suggested_size = app.core.applet.suggested_size(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
.unwrap_or((i, self.core.main_window_id().unwrap())); },
None,
));
cmds.push(popup_task);
let mut popup_settings = self
.core
.applet
.get_popup_settings(parent, popup_id, None, None, None);
self.popup = Some(popup_id);
if matches!(
self.core.applet.anchor,
PanelAnchor::Left | PanelAnchor::Right
) {
let suggested_size = self.core.applet.suggested_size(true).1
+ 2 * self.core.applet.suggested_padding(true).1;
popup_settings.positioner.anchor_rect.y = i as i32 * suggested_size as i32;
} else {
let suggested_size = self.core.applet.suggested_size(true).0
+ 2 * self.core.applet.suggested_padding(true).0;
popup_settings.positioner.anchor_rect.x = i as i32 * suggested_size as i32;
}
cmds.push(get_popup(popup_settings));
Task::batch(cmds) Task::batch(cmds)
} }
Msg::WheelScrolled(delta) => { Msg::WheelScrolled(delta) => {
@ -398,33 +419,41 @@ 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(),
popup_id, move |app: &mut Self| {
None, let popup_id = app.next_popup_id();
None, let mut popup_settings = app.core.applet.get_popup_settings(
None, app.core.main_window_id().unwrap(),
); popup_id,
popup_settings.close_with_children = false; None,
None,
None,
);
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 popup_id = self.next_popup_id();
let mut popup_settings = self.core.applet.get_popup_settings(
self.core.main_window_id().unwrap(),
popup_id,
None,
None,
None,
);
self.popup = Some(popup_id);
let Some(i) = self.overflow_index() else { let Some(i) = self.overflow_index() else {
return Task::batch(cmds); return Task::batch(cmds);
}; };
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,
None,
None,
None,
);
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 =
} else { i as i32 * suggested_size as i32;
let suggested_size = self.core.applet.suggested_size(false).0 } else {
+ 2 * self.core.applet.suggested_padding(false).1; let suggested_size = app.core.applet.suggested_size(false).0
popup_settings.positioner.anchor_rect.x = i as i32 * suggested_size as i32; + 2 * app.core.applet.suggested_padding(false).1;
} popup_settings.positioner.anchor_rect.x =
cmds.push(get_popup(popup_settings)); i as i32 * suggested_size as i32;
}
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 {
let new_id = Id::unique(); return cosmic::surface::surface_task(cosmic::surface::action::app_popup(
self.popup = Some(new_id); |_| Default::default(),
let popup_settings = self.core.applet.get_popup_settings( |app: &mut Self| {
self.core.main_window_id().unwrap(), let new_id = Id::unique();
new_id, app.popup = Some(new_id);
Some((1, 1)), 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, None,
None, ));
);
get_popup(popup_settings)
}; };
} }
Message::PopupClosed(id) => { Message::PopupClosed(id) => {

View file

@ -520,35 +520,40 @@ 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,
);
let Rectangle {
x,
y,
width,
height,
} = app.rectangle;
popup_settings.positioner.anchor_rect = Rectangle::<i32> {
x: x.max(1.) as i32,
y: y.max(1.) as i32,
width: width.max(1.) as i32,
height: height.max(1.) as i32,
};
popup_settings.positioner.size = None;
popup_settings
},
None, None,
None, ));
None,
);
let Rectangle {
x,
y,
width,
height,
} = self.rectangle;
popup_settings.positioner.anchor_rect = Rectangle::<i32> {
x: x.max(1.) as i32,
y: y.max(1.) as i32,
width: width.max(1.) as i32,
height: height.max(1.) as i32,
};
popup_settings.positioner.size = None;
get_popup(popup_settings)
} }
} }
Message::Tick => { Message::Tick => {

View file

@ -202,24 +202,20 @@ 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) .padding(if horizontal {
.align_x(Alignment::Center) [0, self.core.applet.suggested_padding(true).1]
.align_y(Alignment::Center),
)
.padding(if horizontal {
[0, self.core.applet.suggested_padding(true).1]
} else {
[self.core.applet.suggested_padding(true).1, 0]
})
.on_press(
if w.state.contains(ext_workspace_handle_v1::State::Active) {
Message::WorkspaceOverview
} else { } else {
Message::WorkspacePressed(w.handle.clone()) [self.core.applet.suggested_padding(true).1, 0]
}, })
) .on_press(
.padding(0); if w.state.contains(ext_workspace_handle_v1::State::Active) {
Message::WorkspaceOverview
} else {
Message::WorkspacePressed(w.handle.clone())
},
)
.padding(0);
btn.class( btn.class(
if w.state.contains(ext_workspace_handle_v1::State::Active) { if w.state.contains(ext_workspace_handle_v1::State::Active) {

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 {