Update for toplevel-info cctk changes

Requires pop-os/cosmic-protocols#49.

The duplication between applets, and
cosmic-workspace/xdg-desktop-portal-cosmic, should be moved to shared
abstractions. But that can be done after moving to
`ext-image-copy-capture`.

`ToplevelInfo` now contains both ext and cosmic handles, so the tuples
of handles and info are needed. Use just the info.
This commit is contained in:
Ian Douglas Scott 2025-02-12 10:42:32 -08:00 committed by Ian Douglas Scott
parent 69fd2b62df
commit e9848a2d4f
9 changed files with 218 additions and 178 deletions

34
Cargo.lock generated
View file

@ -1382,7 +1382,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-client-toolkit" name = "cosmic-client-toolkit"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/cosmic-protocols?rev=29ab323#29ab32305c6457fccf0728caaaf79fcac4cca665" source = "git+https://github.com/pop-os/cosmic-protocols?rev=178eb0b#178eb0b14a0e5c192f64f6dee6c40341a8e5ee51"
dependencies = [ dependencies = [
"cosmic-protocols", "cosmic-protocols",
"libc", "libc",
@ -1404,7 +1404,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-config" name = "cosmic-config"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#f59eb77252d1730319d532fc0a0c50ce860edd9d" source = "git+https://github.com/pop-os/libcosmic#0b7e23444afb3f351cd947c52babb6b87f30381d"
dependencies = [ dependencies = [
"atomicwrites", "atomicwrites",
"cosmic-config-derive", "cosmic-config-derive",
@ -1426,7 +1426,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-config-derive" name = "cosmic-config-derive"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#f59eb77252d1730319d532fc0a0c50ce860edd9d" source = "git+https://github.com/pop-os/libcosmic#0b7e23444afb3f351cd947c52babb6b87f30381d"
dependencies = [ dependencies = [
"quote", "quote",
"syn 1.0.109", "syn 1.0.109",
@ -1521,7 +1521,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-protocols" name = "cosmic-protocols"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/cosmic-protocols?rev=29ab323#29ab32305c6457fccf0728caaaf79fcac4cca665" source = "git+https://github.com/pop-os/cosmic-protocols?rev=178eb0b#178eb0b14a0e5c192f64f6dee6c40341a8e5ee51"
dependencies = [ dependencies = [
"bitflags 2.8.0", "bitflags 2.8.0",
"wayland-backend", "wayland-backend",
@ -1586,7 +1586,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-theme" name = "cosmic-theme"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#f59eb77252d1730319d532fc0a0c50ce860edd9d" source = "git+https://github.com/pop-os/libcosmic#0b7e23444afb3f351cd947c52babb6b87f30381d"
dependencies = [ dependencies = [
"almost", "almost",
"cosmic-config", "cosmic-config",
@ -2961,7 +2961,7 @@ dependencies = [
[[package]] [[package]]
name = "iced" name = "iced"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#f59eb77252d1730319d532fc0a0c50ce860edd9d" source = "git+https://github.com/pop-os/libcosmic#0b7e23444afb3f351cd947c52babb6b87f30381d"
dependencies = [ dependencies = [
"dnd", "dnd",
"iced_accessibility", "iced_accessibility",
@ -2979,7 +2979,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_accessibility" name = "iced_accessibility"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#f59eb77252d1730319d532fc0a0c50ce860edd9d" source = "git+https://github.com/pop-os/libcosmic#0b7e23444afb3f351cd947c52babb6b87f30381d"
dependencies = [ dependencies = [
"accesskit", "accesskit",
"accesskit_winit", "accesskit_winit",
@ -2988,7 +2988,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_core" name = "iced_core"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#f59eb77252d1730319d532fc0a0c50ce860edd9d" source = "git+https://github.com/pop-os/libcosmic#0b7e23444afb3f351cd947c52babb6b87f30381d"
dependencies = [ dependencies = [
"bitflags 2.8.0", "bitflags 2.8.0",
"bytes", "bytes",
@ -3012,7 +3012,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_futures" name = "iced_futures"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#f59eb77252d1730319d532fc0a0c50ce860edd9d" source = "git+https://github.com/pop-os/libcosmic#0b7e23444afb3f351cd947c52babb6b87f30381d"
dependencies = [ dependencies = [
"futures", "futures",
"iced_core", "iced_core",
@ -3038,7 +3038,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_graphics" name = "iced_graphics"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#f59eb77252d1730319d532fc0a0c50ce860edd9d" source = "git+https://github.com/pop-os/libcosmic#0b7e23444afb3f351cd947c52babb6b87f30381d"
dependencies = [ dependencies = [
"bitflags 2.8.0", "bitflags 2.8.0",
"bytemuck", "bytemuck",
@ -3060,7 +3060,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_renderer" name = "iced_renderer"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#f59eb77252d1730319d532fc0a0c50ce860edd9d" source = "git+https://github.com/pop-os/libcosmic#0b7e23444afb3f351cd947c52babb6b87f30381d"
dependencies = [ dependencies = [
"iced_graphics", "iced_graphics",
"iced_tiny_skia", "iced_tiny_skia",
@ -3072,7 +3072,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_runtime" name = "iced_runtime"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#f59eb77252d1730319d532fc0a0c50ce860edd9d" source = "git+https://github.com/pop-os/libcosmic#0b7e23444afb3f351cd947c52babb6b87f30381d"
dependencies = [ dependencies = [
"bytes", "bytes",
"cosmic-client-toolkit", "cosmic-client-toolkit",
@ -3087,7 +3087,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_tiny_skia" name = "iced_tiny_skia"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#f59eb77252d1730319d532fc0a0c50ce860edd9d" source = "git+https://github.com/pop-os/libcosmic#0b7e23444afb3f351cd947c52babb6b87f30381d"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"cosmic-text", "cosmic-text",
@ -3103,7 +3103,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_wgpu" name = "iced_wgpu"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#f59eb77252d1730319d532fc0a0c50ce860edd9d" source = "git+https://github.com/pop-os/libcosmic#0b7e23444afb3f351cd947c52babb6b87f30381d"
dependencies = [ dependencies = [
"as-raw-xcb-connection", "as-raw-xcb-connection",
"bitflags 2.8.0", "bitflags 2.8.0",
@ -3134,7 +3134,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_widget" name = "iced_widget"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#f59eb77252d1730319d532fc0a0c50ce860edd9d" source = "git+https://github.com/pop-os/libcosmic#0b7e23444afb3f351cd947c52babb6b87f30381d"
dependencies = [ dependencies = [
"cosmic-client-toolkit", "cosmic-client-toolkit",
"dnd", "dnd",
@ -3152,7 +3152,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_winit" name = "iced_winit"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#f59eb77252d1730319d532fc0a0c50ce860edd9d" source = "git+https://github.com/pop-os/libcosmic#0b7e23444afb3f351cd947c52babb6b87f30381d"
dependencies = [ dependencies = [
"cosmic-client-toolkit", "cosmic-client-toolkit",
"dnd", "dnd",
@ -3877,7 +3877,7 @@ checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]] [[package]]
name = "libcosmic" name = "libcosmic"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#f59eb77252d1730319d532fc0a0c50ce860edd9d" source = "git+https://github.com/pop-os/libcosmic#0b7e23444afb3f351cd947c52babb6b87f30381d"
dependencies = [ dependencies = [
"apply", "apply",
"ashpd 0.9.2", "ashpd 0.9.2",

View file

@ -24,10 +24,10 @@ resolver = "2"
[workspace.dependencies] [workspace.dependencies]
anyhow = "1.0.81" anyhow = "1.0.81"
cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "29ab323" } cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "178eb0b" }
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 = "29ab323" } ], rev = "178eb0b" }
cosmic-settings-subscriptions = { git = "https://github.com/pop-os/cosmic-settings-subscriptions" } cosmic-settings-subscriptions = { git = "https://github.com/pop-os/cosmic-settings-subscriptions" }
# cosmic-settings-subscriptions = { path = "../cosmic-settings-subscriptions" } # cosmic-settings-subscriptions = { path = "../cosmic-settings-subscriptions" }

View file

@ -14,6 +14,7 @@ use cctk::{
wayland_client::protocol::{ wayland_client::protocol::{
wl_data_device_manager::DndAction, wl_output::WlOutput, wl_seat::WlSeat, wl_data_device_manager::DndAction, wl_output::WlOutput, wl_seat::WlSeat,
}, },
wayland_protocols::ext::foreign_toplevel_list::v1::client::ext_foreign_toplevel_handle_v1::ExtForeignToplevelHandleV1,
}; };
use cosmic::{ use cosmic::{
applet::{ applet::{
@ -44,7 +45,7 @@ use cosmic::{
}; };
use cosmic_app_list_config::{AppListConfig, APP_ID}; use cosmic_app_list_config::{AppListConfig, APP_ID};
use cosmic_protocols::{ use cosmic_protocols::{
toplevel_info::v1::client::zcosmic_toplevel_handle_v1::{State, ZcosmicToplevelHandleV1}, toplevel_info::v1::client::zcosmic_toplevel_handle_v1::State,
workspace::v1::client::zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1, workspace::v1::client::zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1,
}; };
use freedesktop_desktop_entry as fde; use freedesktop_desktop_entry as fde;
@ -127,7 +128,7 @@ struct DockItem {
// ID used internally in the applet. Each dock item // ID used internally in the applet. Each dock item
// have an unique id // have an unique id
id: u32, id: u32,
toplevels: Vec<(ZcosmicToplevelHandleV1, ToplevelInfo, Option<WaylandImage>)>, toplevels: Vec<(ToplevelInfo, Option<WaylandImage>)>,
// Information found in the .desktop file // Information found in the .desktop file
desktop_info: DesktopEntry, desktop_info: DesktopEntry,
// We must use this because the id in `DesktopEntry` is an estimation. // We must use this because the id in `DesktopEntry` is an estimation.
@ -248,7 +249,9 @@ impl DockItem {
.on_press_maybe(if toplevels.is_empty() { .on_press_maybe(if toplevels.is_empty() {
launch_on_preferred_gpu(desktop_info, gpus) launch_on_preferred_gpu(desktop_info, gpus)
} else if toplevels.len() == 1 { } else if toplevels.len() == 1 {
toplevels.first().map(|t| Message::Toggle(t.0.clone())) toplevels
.first()
.map(|t| Message::Toggle(t.0.foreign_toplevel.clone()))
} else { } else {
Some(Message::TopLevelListPopup((*id).into(), window_id)) Some(Message::TopLevelListPopup((*id).into(), window_id))
}) })
@ -348,8 +351,8 @@ enum Message {
GpuRequest(Option<Vec<Gpu>>), GpuRequest(Option<Vec<Gpu>>),
CloseRequested(window::Id), CloseRequested(window::Id),
ClosePopup, ClosePopup,
Activate(ZcosmicToplevelHandleV1), Activate(ExtForeignToplevelHandleV1),
Toggle(ZcosmicToplevelHandleV1), Toggle(ExtForeignToplevelHandleV1),
Exec(String, Option<usize>), Exec(String, Option<usize>),
Quit(String), Quit(String),
NewSeat(WlSeat), NewSeat(WlSeat),
@ -721,9 +724,10 @@ impl cosmic::Application for CosmicAppList {
.chain(self.pinned_list.iter()) .chain(self.pinned_list.iter())
.find(|t| t.id == id) .find(|t| t.id == id)
{ {
for (ref handle, _, _) in &toplevel_group.toplevels { for (info, _) in &toplevel_group.toplevels {
if let Some(tx) = self.wayland_sender.as_ref() { if let Some(tx) = self.wayland_sender.as_ref() {
let _ = tx.send(WaylandRequest::Screencopy(handle.clone())); let _ =
tx.send(WaylandRequest::Screencopy(info.foreign_toplevel.clone()));
} }
} }
@ -844,10 +848,10 @@ impl cosmic::Application for CosmicAppList {
.chain(self.pinned_list.iter()) .chain(self.pinned_list.iter())
.find(|t| t.desktop_info.id() == id) .find(|t| t.desktop_info.id() == id)
{ {
for (handle, _, _) in &toplevel_group.toplevels { for (info, _) in &toplevel_group.toplevels {
if let Some(tx) = self.wayland_sender.as_ref() { if let Some(tx) = self.wayland_sender.as_ref() {
let _ = tx.send(WaylandRequest::Toplevel(ToplevelRequest::Quit( let _ = tx.send(WaylandRequest::Toplevel(ToplevelRequest::Quit(
handle.clone(), info.foreign_toplevel.clone(),
))); )));
} }
} }
@ -1016,10 +1020,10 @@ impl cosmic::Application for CosmicAppList {
.iter_mut() .iter_mut()
.chain(self.pinned_list.iter_mut()) .chain(self.pinned_list.iter_mut())
{ {
if let Some((_, _, ref mut handle_img)) = x if let Some((_, ref mut handle_img)) = x
.toplevels .toplevels
.iter_mut() .iter_mut()
.find(|(toplevel_handle, _, _)| toplevel_handle.clone() == handle) .find(|(info, _)| info.foreign_toplevel == handle)
{ {
*handle_img = Some(img); *handle_img = Some(img);
break 'img_update; break 'img_update;
@ -1050,7 +1054,7 @@ impl cosmic::Application for CosmicAppList {
.map(cosmic::app::message::app); .map(cosmic::app::message::app);
} }
WaylandUpdate::Toplevel(event) => match event { WaylandUpdate::Toplevel(event) => match event {
ToplevelUpdate::Add(handle, mut info) => { ToplevelUpdate::Add(mut info) => {
let new_desktop_info = let new_desktop_info =
load_desktop_entries_from_app_ids(&[&info.app_id], &self.locales) load_desktop_entries_from_app_ids(&[&info.app_id], &self.locales)
.remove(0); .remove(0);
@ -1063,7 +1067,7 @@ impl cosmic::Application for CosmicAppList {
desktop_info.id() == new_desktop_info.id() desktop_info.id() == new_desktop_info.id()
}) })
{ {
t.toplevels.push((handle, info, None)); t.toplevels.push((info, None));
} else { } else {
if info.app_id.is_empty() { if info.app_id.is_empty() {
info.app_id = format!("Unknown Application {}", self.item_ctr); info.app_id = format!("Unknown Application {}", self.item_ctr);
@ -1073,7 +1077,7 @@ impl cosmic::Application for CosmicAppList {
self.active_list.push(DockItem { self.active_list.push(DockItem {
id: self.item_ctr, id: self.item_ctr,
original_app_id: info.app_id.clone(), original_app_id: info.app_id.clone(),
toplevels: vec![(handle, info, None)], toplevels: vec![(info, None)],
desktop_info: new_desktop_info, desktop_info: new_desktop_info,
}); });
} }
@ -1084,11 +1088,12 @@ impl cosmic::Application for CosmicAppList {
.iter_mut() .iter_mut()
.chain(self.pinned_list.iter_mut()) .chain(self.pinned_list.iter_mut())
{ {
t.toplevels.retain(|(t_handle, _, _)| t_handle != &handle); t.toplevels
.retain(|(info, _)| info.foreign_toplevel != handle);
} }
self.active_list.retain(|t| !t.toplevels.is_empty()); self.active_list.retain(|t| !t.toplevels.is_empty());
} }
ToplevelUpdate::Update(handle, info) => { ToplevelUpdate::Update(info) => {
// TODO probably want to make sure it is removed // TODO probably want to make sure it is removed
if info.app_id.is_empty() { if info.app_id.is_empty() {
return Task::none(); return Task::none();
@ -1098,8 +1103,8 @@ impl cosmic::Application for CosmicAppList {
.iter_mut() .iter_mut()
.chain(self.pinned_list.iter_mut()) .chain(self.pinned_list.iter_mut())
{ {
for (t_handle, t_info, _) in &mut toplevel_list.toplevels { for (t_info, _) in &mut toplevel_list.toplevels {
if &handle == t_handle { if info.foreign_toplevel == t_info.foreign_toplevel {
*t_info = info; *t_info = info;
break 'toplevel_loop; break 'toplevel_loop;
} }
@ -1404,7 +1409,7 @@ impl cosmic::Application for CosmicAppList {
dock_item dock_item
.toplevels .toplevels
.iter() .iter()
.any(|y| focused_item.contains(&y.0)), .any(|y| focused_item.contains(&y.0.foreign_toplevel)),
theme.cosmic().radius_xs(), theme.cosmic().radius_xs(),
self.core.main_window_id().unwrap(), self.core.main_window_id().unwrap(),
) )
@ -1447,7 +1452,9 @@ impl cosmic::Application for CosmicAppList {
false, false,
self.config.enable_drag_source, self.config.enable_drag_source,
self.gpus.as_deref(), self.gpus.as_deref(),
item.toplevels.iter().any(|y| focused_item.contains(&y.0)), item.toplevels
.iter()
.any(|y| focused_item.contains(&y.0.foreign_toplevel)),
dot_radius, dot_radius,
self.core.main_window_id().unwrap(), self.core.main_window_id().unwrap(),
), ),
@ -1484,7 +1491,7 @@ impl cosmic::Application for CosmicAppList {
dock_item dock_item
.toplevels .toplevels
.iter() .iter()
.any(|y| focused_item.contains(&y.0)), .any(|y| focused_item.contains(&y.0.foreign_toplevel)),
dot_radius, dot_radius,
self.core.main_window_id().unwrap(), self.core.main_window_id().unwrap(),
) )
@ -1724,16 +1731,17 @@ impl cosmic::Application for CosmicAppList {
if !toplevels.is_empty() { if !toplevels.is_empty() {
let mut list_col = column![]; let mut list_col = column![];
for (handle, info, _) in toplevels { for (info, _) in toplevels {
let title = if info.title.len() > 34 { let title = if info.title.len() > 34 {
format!("{:.32}...", &info.title) format!("{:.32}...", &info.title)
} else { } else {
info.title.clone() info.title.clone()
}; };
list_col = list_col.push( list_col =
menu_button(text::body(title)) list_col
.on_press(Message::Activate(handle.clone())), .push(menu_button(text::body(title)).on_press(
); Message::Activate(info.foreign_toplevel.clone()),
));
} }
content = content.push(list_col); content = content.push(list_col);
content = content.push(divider::horizontal::light()); content = content.push(divider::horizontal::light());
@ -1814,7 +1822,7 @@ impl cosmic::Application for CosmicAppList {
PanelAnchor::Left | PanelAnchor::Right => { PanelAnchor::Left | PanelAnchor::Right => {
let mut content = let mut content =
column![].padding(8).align_x(Alignment::Center).spacing(8); column![].padding(8).align_x(Alignment::Center).spacing(8);
for (handle, info, img) in toplevels { for (info, img) in toplevels {
let title = if info.title.len() > 18 { let title = if info.title.len() > 18 {
format!("{:.16}...", &info.title) format!("{:.16}...", &info.title)
} else { } else {
@ -1822,9 +1830,10 @@ impl cosmic::Application for CosmicAppList {
}; };
content = content.push(toplevel_button( content = content.push(toplevel_button(
img.clone(), img.clone(),
Message::Toggle(handle.clone()), Message::Toggle(info.foreign_toplevel.clone()),
title, title,
self.currently_active_toplevel().contains(handle), self.currently_active_toplevel()
.contains(&info.foreign_toplevel),
)); ));
} }
self.core self.core
@ -1835,7 +1844,7 @@ impl cosmic::Application for CosmicAppList {
} }
PanelAnchor::Bottom | PanelAnchor::Top => { PanelAnchor::Bottom | PanelAnchor::Top => {
let mut content = row![].padding(8).align_y(Alignment::Center).spacing(8); let mut content = row![].padding(8).align_y(Alignment::Center).spacing(8);
for (handle, info, img) in toplevels { for (info, img) in toplevels {
let title = if info.title.len() > 18 { let title = if info.title.len() > 18 {
format!("{:.16}...", &info.title) format!("{:.16}...", &info.title)
} else { } else {
@ -1843,9 +1852,10 @@ impl cosmic::Application for CosmicAppList {
}; };
content = content.push(toplevel_button( content = content.push(toplevel_button(
img.clone(), img.clone(),
Message::Toggle(handle.clone()), Message::Toggle(info.foreign_toplevel.clone()),
title, title,
self.currently_active_toplevel().contains(handle), self.currently_active_toplevel()
.contains(&info.foreign_toplevel),
)); ));
} }
self.core self.core
@ -1886,7 +1896,7 @@ impl cosmic::Application for CosmicAppList {
dock_item dock_item
.toplevels .toplevels
.iter() .iter()
.any(|y| focused_item.contains(&y.0)), .any(|y| focused_item.contains(&y.0.foreign_toplevel)),
dot_radius, dot_radius,
id, id,
) )
@ -1973,7 +1983,7 @@ impl cosmic::Application for CosmicAppList {
dock_item dock_item
.toplevels .toplevels
.iter() .iter()
.any(|y| focused_item.contains(&y.0)), .any(|y| focused_item.contains(&y.0.foreign_toplevel)),
dot_radius, dot_radius,
id, id,
) )
@ -2129,15 +2139,15 @@ impl CosmicAppList {
return (Some(favorite_index), active_index); return (Some(favorite_index), active_index);
} }
fn currently_active_toplevel(&self) -> Vec<ZcosmicToplevelHandleV1> { fn currently_active_toplevel(&self) -> Vec<ExtForeignToplevelHandleV1> {
if self.active_workspaces.is_empty() { if self.active_workspaces.is_empty() {
return Vec::new(); return Vec::new();
} }
let current_output = self.core.applet.output_name.clone(); let current_output = self.core.applet.output_name.clone();
let mut focused_toplevels: Vec<ZcosmicToplevelHandleV1> = Vec::new(); let mut focused_toplevels: Vec<ExtForeignToplevelHandleV1> = Vec::new();
let active_workspaces = self.active_workspaces.clone(); let active_workspaces = self.active_workspaces.clone();
for toplevel_list in self.active_list.iter().chain(self.pinned_list.iter()) { for toplevel_list in self.active_list.iter().chain(self.pinned_list.iter()) {
for (t_handle, t_info, _) in &toplevel_list.toplevels { for (t_info, _) in &toplevel_list.toplevels {
if t_info.state.contains(&State::Activated) if t_info.state.contains(&State::Activated)
&& active_workspaces && active_workspaces
.iter() .iter()
@ -2148,7 +2158,7 @@ impl CosmicAppList {
}) })
}) })
{ {
focused_toplevels.push(t_handle.clone()); focused_toplevels.push(t_info.foreign_toplevel.clone());
} }
} }
} }

View file

@ -39,10 +39,11 @@ use cctk::{
}, },
Connection, Dispatch, QueueHandle, WEnum, Connection, Dispatch, QueueHandle, WEnum,
}, },
wayland_protocols::ext::foreign_toplevel_list::v1::client::ext_foreign_toplevel_handle_v1::ExtForeignToplevelHandleV1,
workspace::{WorkspaceHandler, WorkspaceState}, workspace::{WorkspaceHandler, WorkspaceState},
}; };
use cosmic_protocols::{ use cosmic_protocols::{
toplevel_info::v1::client::zcosmic_toplevel_handle_v1::{self, ZcosmicToplevelHandleV1}, toplevel_info::v1::client::zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
toplevel_management::v1::client::zcosmic_toplevel_manager_v1, toplevel_management::v1::client::zcosmic_toplevel_manager_v1,
workspace::v1::client::zcosmic_workspace_handle_v1::State as WorkspaceUpdateState, workspace::v1::client::zcosmic_workspace_handle_v1::State as WorkspaceUpdateState,
}; };
@ -235,15 +236,12 @@ impl ToplevelInfoHandler for AppData {
&mut self, &mut self,
_conn: &Connection, _conn: &Connection,
_qh: &QueueHandle<Self>, _qh: &QueueHandle<Self>,
toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1, toplevel: &ExtForeignToplevelHandleV1,
) { ) {
if let Some(info) = self.toplevel_info_state.info(toplevel) { if let Some(info) = self.toplevel_info_state.info(toplevel) {
let _ = self let _ = self
.tx .tx
.unbounded_send(WaylandUpdate::Toplevel(ToplevelUpdate::Add( .unbounded_send(WaylandUpdate::Toplevel(ToplevelUpdate::Add(info.clone())));
toplevel.clone(),
info.clone(),
)));
} }
} }
@ -251,13 +249,12 @@ impl ToplevelInfoHandler for AppData {
&mut self, &mut self,
_conn: &Connection, _conn: &Connection,
_qh: &QueueHandle<Self>, _qh: &QueueHandle<Self>,
toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1, toplevel: &ExtForeignToplevelHandleV1,
) { ) {
if let Some(info) = self.toplevel_info_state.info(toplevel) { if let Some(info) = self.toplevel_info_state.info(toplevel) {
let _ = self let _ = self
.tx .tx
.unbounded_send(WaylandUpdate::Toplevel(ToplevelUpdate::Update( .unbounded_send(WaylandUpdate::Toplevel(ToplevelUpdate::Update(
toplevel.clone(),
info.clone(), info.clone(),
))); )));
} }
@ -267,7 +264,7 @@ impl ToplevelInfoHandler for AppData {
&mut self, &mut self,
_conn: &Connection, _conn: &Connection,
_qh: &QueueHandle<Self>, _qh: &QueueHandle<Self>,
toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1, toplevel: &ExtForeignToplevelHandleV1,
) { ) {
let _ = self let _ = self
.tx .tx
@ -479,7 +476,17 @@ impl<T: AsFd> ShmImage<T> {
} }
impl AppData { impl AppData {
fn send_image(&self, handle: ZcosmicToplevelHandleV1) { fn cosmic_toplevel(
&self,
handle: &ExtForeignToplevelHandleV1,
) -> Option<ZcosmicToplevelHandleV1> {
self.toplevel_info_state
.info(&handle)?
.cosmic_toplevel
.clone()
}
fn send_image(&self, handle: ExtForeignToplevelHandleV1) {
let tx = self.tx.clone(); let tx = self.tx.clone();
let capture_data = CaptureData { let capture_data = CaptureData {
qh: self.queue_handle.clone(), qh: self.queue_handle.clone(),
@ -487,6 +494,9 @@ impl AppData {
wl_shm: self.shm_state.wl_shm().clone(), wl_shm: self.shm_state.wl_shm().clone(),
capturer: self.screencopy_state.capturer().clone(), capturer: self.screencopy_state.capturer().clone(),
}; };
let Some(cosmic_toplevel) = self.cosmic_toplevel(&handle) else {
return;
};
std::thread::spawn(move || { std::thread::spawn(move || {
use std::ffi::CStr; use std::ffi::CStr;
let name = unsafe { CStr::from_bytes_with_nul_unchecked(b"app-list-screencopy\0") }; let name = unsafe { CStr::from_bytes_with_nul_unchecked(b"app-list-screencopy\0") };
@ -496,7 +506,7 @@ impl AppData {
}; };
// XXX is this going to use to much memory? // XXX is this going to use to much memory?
let img = capture_data.capture_source_shm_fd(false, handle.clone(), fd, None); let img = capture_data.capture_source_shm_fd(false, cosmic_toplevel, fd, None);
if let Some(img) = img { if let Some(img) = img {
let Ok(img) = img.image() else { let Ok(img) = img.image() else {
tracing::error!("Failed to get RgbaImage"); tracing::error!("Failed to get RgbaImage");
@ -621,18 +631,24 @@ pub(crate) fn wayland_handler(
} }
WaylandRequest::Toplevel(req) => match req { WaylandRequest::Toplevel(req) => match req {
ToplevelRequest::Activate(handle) => { ToplevelRequest::Activate(handle) => {
if let Some(seat) = state.seat_state.seats().next() { if let Some(cosmic_toplevel) = state.cosmic_toplevel(&handle) {
let manager = &state.toplevel_manager_state.manager; if let Some(seat) = state.seat_state.seats().next() {
manager.activate(&handle, &seat); let manager = &state.toplevel_manager_state.manager;
manager.activate(&cosmic_toplevel, &seat);
}
} }
} }
ToplevelRequest::Minimize(handle) => { ToplevelRequest::Minimize(handle) => {
let manager = &state.toplevel_manager_state.manager; if let Some(cosmic_toplevel) = state.cosmic_toplevel(&handle) {
manager.set_minimized(&handle); let manager = &state.toplevel_manager_state.manager;
manager.set_minimized(&cosmic_toplevel);
}
} }
ToplevelRequest::Quit(handle) => { ToplevelRequest::Quit(handle) => {
let manager = &state.toplevel_manager_state.manager; if let Some(cosmic_toplevel) = state.cosmic_toplevel(&handle) {
manager.close(&handle); let manager = &state.toplevel_manager_state.manager;
manager.close(&cosmic_toplevel);
}
} }
}, },
WaylandRequest::TokenRequest { WaylandRequest::TokenRequest {

View file

@ -6,15 +6,13 @@ use cctk::{
sctk::{output::OutputInfo, reexports::calloop}, sctk::{output::OutputInfo, reexports::calloop},
toplevel_info::ToplevelInfo, toplevel_info::ToplevelInfo,
wayland_client::protocol::wl_output::WlOutput, wayland_client::protocol::wl_output::WlOutput,
wayland_protocols::ext::foreign_toplevel_list::v1::client::ext_foreign_toplevel_handle_v1::ExtForeignToplevelHandleV1,
}; };
use cosmic::{ use cosmic::{
iced::{self, stream, Subscription}, iced::{self, stream, Subscription},
iced_core::image::Bytes, iced_core::image::Bytes,
}; };
use cosmic_protocols::{ use cosmic_protocols::workspace::v1::client::zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1;
toplevel_info::v1::client::zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
workspace::v1::client::zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1,
};
use image::EncodableLayout; use image::EncodableLayout;
use futures::{ use futures::{
@ -120,14 +118,14 @@ pub enum WaylandUpdate {
exec: String, exec: String,
gpu_idx: Option<usize>, gpu_idx: Option<usize>,
}, },
Image(ZcosmicToplevelHandleV1, WaylandImage), Image(ExtForeignToplevelHandleV1, WaylandImage),
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum ToplevelUpdate { pub enum ToplevelUpdate {
Add(ZcosmicToplevelHandleV1, ToplevelInfo), Add(ToplevelInfo),
Update(ZcosmicToplevelHandleV1, ToplevelInfo), Update(ToplevelInfo),
Remove(ZcosmicToplevelHandleV1), Remove(ExtForeignToplevelHandleV1),
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -145,12 +143,12 @@ pub enum WaylandRequest {
exec: String, exec: String,
gpu_idx: Option<usize>, gpu_idx: Option<usize>,
}, },
Screencopy(ZcosmicToplevelHandleV1), Screencopy(ExtForeignToplevelHandleV1),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum ToplevelRequest { pub enum ToplevelRequest {
Activate(ZcosmicToplevelHandleV1), Activate(ExtForeignToplevelHandleV1),
Minimize(ZcosmicToplevelHandleV1), Minimize(ExtForeignToplevelHandleV1),
Quit(ZcosmicToplevelHandleV1), Quit(ExtForeignToplevelHandleV1),
} }

View file

@ -11,8 +11,8 @@ use cosmic::{
app, app,
applet::cosmic_panel_config::PanelAnchor, applet::cosmic_panel_config::PanelAnchor,
cctk::{ cctk::{
cosmic_protocols::toplevel_info::v1::client::zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
sctk::reexports::calloop, toplevel_info::ToplevelInfo, sctk::reexports::calloop, toplevel_info::ToplevelInfo,
wayland_protocols::ext::foreign_toplevel_list::v1::client::ext_foreign_toplevel_handle_v1::ExtForeignToplevelHandleV1,
}, },
desktop::DesktopEntryData, desktop::DesktopEntryData,
iced::{ iced::{
@ -45,12 +45,7 @@ pub fn run() -> cosmic::iced::Result {
#[derive(Default)] #[derive(Default)]
struct Minimize { struct Minimize {
core: cosmic::app::Core, core: cosmic::app::Core,
apps: Vec<( apps: Vec<(ToplevelInfo, DesktopEntryData, Option<WaylandImage>)>,
ZcosmicToplevelHandleV1,
ToplevelInfo,
DesktopEntryData,
Option<WaylandImage>,
)>,
tx: Option<calloop::channel::Sender<WaylandRequest>>, tx: Option<calloop::channel::Sender<WaylandRequest>>,
overflow_popup: Option<window::Id>, overflow_popup: Option<window::Id>,
} }
@ -83,7 +78,7 @@ impl Minimize {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum Message { enum Message {
Wayland(WaylandUpdate), Wayland(WaylandUpdate),
Activate(ZcosmicToplevelHandleV1), Activate(ExtForeignToplevelHandleV1),
Closed(window::Id), Closed(window::Id),
OpenOverflowPopup, OpenOverflowPopup,
CloseOverflowPopup, CloseOverflowPopup,
@ -127,7 +122,7 @@ impl cosmic::Application for Minimize {
panic!("Wayland Subscription ended...") panic!("Wayland Subscription ended...")
} }
WaylandUpdate::Toplevel(t) => match t { WaylandUpdate::Toplevel(t) => match t {
ToplevelUpdate::Add(handle, info) | ToplevelUpdate::Update(handle, info) => { ToplevelUpdate::Add(info) | ToplevelUpdate::Update(info) => {
let data = |id| { let data = |id| {
cosmic::desktop::load_applications_for_app_ids( cosmic::desktop::load_applications_for_app_ids(
None, None,
@ -137,24 +132,32 @@ impl cosmic::Application for Minimize {
) )
.remove(0) .remove(0)
}; };
if let Some(pos) = self.apps.iter_mut().position(|a| a.0 == handle) { if let Some(pos) = self
if self.apps[pos].1.app_id != info.app_id { .apps
self.apps[pos].2 = data(&info.app_id) .iter_mut()
.position(|a| a.0.foreign_toplevel == info.foreign_toplevel)
{
if self.apps[pos].0.app_id != info.app_id {
self.apps[pos].1 = data(&info.app_id)
} }
self.apps[pos].1 = info; self.apps[pos].0 = info;
} else { } else {
let data = data(&info.app_id); let data = data(&info.app_id);
self.apps.push((handle, info, data, None)); self.apps.push((info, data, None));
} }
} }
ToplevelUpdate::Remove(handle) => { ToplevelUpdate::Remove(handle) => {
self.apps.retain(|a| a.0 != handle); self.apps.retain(|a| a.0.foreign_toplevel != handle);
self.apps.shrink_to_fit(); self.apps.shrink_to_fit();
} }
}, },
WaylandUpdate::Image(handle, img) => { WaylandUpdate::Image(handle, img) => {
if let Some(pos) = self.apps.iter().position(|a| a.0 == handle) { if let Some(pos) = self
self.apps[pos].3 = Some(img); .apps
.iter()
.position(|a| a.0.foreign_toplevel == handle)
{
self.apps[pos].2 = Some(img);
} }
} }
}, },
@ -230,31 +233,29 @@ impl cosmic::Application for Minimize {
let padding = self.core.applet.suggested_padding(false); let padding = self.core.applet.suggested_padding(false);
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] let icon_buttons = self.apps[..max_icon_count].iter().map(|(info, data, img)| {
.iter() tooltip(
.map(|(handle, _, data, img)| { Element::from(crate::window_image::WindowImage::new(
tooltip( img.clone(),
Element::from(crate::window_image::WindowImage::new( &data.icon,
img.clone(), width as f32,
&data.icon, Message::Activate(info.foreign_toplevel.clone()),
width as f32, padding,
Message::Activate(handle.clone()), )),
padding, text(data.name.clone()).shaping(text::Shaping::Advanced),
)), // tooltip::Position::FollowCursor,
text(data.name.clone()).shaping(text::Shaping::Advanced), // FIXME tooltip fails to appear when created as indicated in design
// tooltip::Position::FollowCursor, // maybe it should be a subsurface
// FIXME tooltip fails to appear when created as indicated in design match self.core.applet.anchor {
// maybe it should be a subsurface PanelAnchor::Left => tooltip::Position::Right,
match self.core.applet.anchor { PanelAnchor::Right => tooltip::Position::Left,
PanelAnchor::Left => tooltip::Position::Right, PanelAnchor::Top => tooltip::Position::Bottom,
PanelAnchor::Right => tooltip::Position::Left, PanelAnchor::Bottom => tooltip::Position::Top,
PanelAnchor::Top => tooltip::Position::Bottom, },
PanelAnchor::Bottom => tooltip::Position::Top, )
}, .snap_within_viewport(false)
) .into()
.snap_within_viewport(false) });
.into()
});
let overflow_btn = if max_icon_count < self.apps.len() { let overflow_btn = if max_icon_count < self.apps.len() {
let icon = match self.core.applet.anchor { let icon = match self.core.applet.anchor {
PanelAnchor::Bottom => "go-up-symbolic", PanelAnchor::Bottom => "go-up-symbolic",
@ -335,31 +336,29 @@ impl cosmic::Application for Minimize {
let padding = self.core.applet.suggested_padding(false); let padding = self.core.applet.suggested_padding(false);
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..] let icon_buttons = self.apps[max_icon_count..].iter().map(|(info, data, img)| {
.iter() tooltip(
.map(|(handle, _, data, img)| { Element::from(crate::window_image::WindowImage::new(
tooltip( img.clone(),
Element::from(crate::window_image::WindowImage::new( &data.icon,
img.clone(), width as f32,
&data.icon, Message::Activate(info.foreign_toplevel.clone()),
width as f32, padding,
Message::Activate(handle.clone()), )),
padding, text(data.name.clone()).shaping(text::Shaping::Advanced),
)), // tooltip::Position::FollowCursor,
text(data.name.clone()).shaping(text::Shaping::Advanced), // FIXME tooltip fails to appear when created as indicated in design
// tooltip::Position::FollowCursor, // maybe it should be a subsurface
// FIXME tooltip fails to appear when created as indicated in design match self.core.applet.anchor {
// maybe it should be a subsurface PanelAnchor::Left => tooltip::Position::Right,
match self.core.applet.anchor { PanelAnchor::Right => tooltip::Position::Left,
PanelAnchor::Left => tooltip::Position::Right, PanelAnchor::Top => tooltip::Position::Bottom,
PanelAnchor::Right => tooltip::Position::Left, PanelAnchor::Bottom => tooltip::Position::Top,
PanelAnchor::Top => tooltip::Position::Bottom, },
PanelAnchor::Bottom => tooltip::Position::Top, )
}, .snap_within_viewport(false)
) .into()
.snap_within_viewport(false) });
.into()
});
// TODO optional dividers on ends if detects app list neighbor // TODO optional dividers on ends if detects app list neighbor
// not sure the best way to tell if there is an adjacent app-list // not sure the best way to tell if there is an adjacent app-list

View file

@ -42,6 +42,7 @@ use cosmic::{
}, },
Dispatch, Dispatch,
}, },
wayland_protocols::ext::foreign_toplevel_list::v1::client::ext_foreign_toplevel_handle_v1::ExtForeignToplevelHandleV1,
}, },
iced_futures::futures, iced_futures::futures,
}; };
@ -291,7 +292,17 @@ impl ToplevelManagerHandler for AppData {
} }
} }
impl AppData { impl AppData {
fn send_image(&self, handle: ZcosmicToplevelHandleV1) { fn cosmic_toplevel(
&self,
handle: &ExtForeignToplevelHandleV1,
) -> Option<ZcosmicToplevelHandleV1> {
self.toplevel_info_state
.info(&handle)?
.cosmic_toplevel
.clone()
}
fn send_image(&self, handle: ExtForeignToplevelHandleV1) {
let mut tx = self.tx.clone(); let mut tx = self.tx.clone();
let capure_data = CaptureData { let capure_data = CaptureData {
qh: self.queue_handle.clone(), qh: self.queue_handle.clone(),
@ -299,6 +310,9 @@ impl AppData {
wl_shm: self.shm_state.wl_shm().clone(), wl_shm: self.shm_state.wl_shm().clone(),
capturer: self.screencopy_state.capturer().clone(), capturer: self.screencopy_state.capturer().clone(),
}; };
let Some(cosmic_toplevel) = self.cosmic_toplevel(&handle) else {
return;
};
std::thread::spawn(move || { std::thread::spawn(move || {
use std::ffi::CStr; use std::ffi::CStr;
let name = let name =
@ -309,7 +323,7 @@ impl AppData {
}; };
// XXX is this going to use to much memory? // XXX is this going to use to much memory?
let img = capure_data.capture_source_shm_fd(false, handle.clone(), fd, None); let img = capure_data.capture_source_shm_fd(false, cosmic_toplevel, fd, None);
if let Some(img) = img { if let Some(img) = img {
let Ok(mut img) = img.image() else { let Ok(mut img) = img.image() else {
tracing::error!("Failed to get RgbaImage"); tracing::error!("Failed to get RgbaImage");
@ -353,7 +367,7 @@ impl ToplevelInfoHandler for AppData {
&mut self, &mut self,
_conn: &Connection, _conn: &Connection,
_qh: &QueueHandle<Self>, _qh: &QueueHandle<Self>,
toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1, toplevel: &ExtForeignToplevelHandleV1,
) { ) {
if let Some(info) = self.toplevel_info_state.info(toplevel) { if let Some(info) = self.toplevel_info_state.info(toplevel) {
if info if info
@ -362,9 +376,10 @@ impl ToplevelInfoHandler for AppData {
{ {
// spawn thread for sending the image // spawn thread for sending the image
self.send_image(toplevel.clone()); self.send_image(toplevel.clone());
let _ = futures::executor::block_on(self.tx.send(WaylandUpdate::Toplevel( let _ = futures::executor::block_on(
ToplevelUpdate::Add(toplevel.clone(), info.clone()), self.tx
))); .send(WaylandUpdate::Toplevel(ToplevelUpdate::Add(info.clone()))),
);
} else { } else {
let _ = futures::executor::block_on(self.tx.send(WaylandUpdate::Toplevel( let _ = futures::executor::block_on(self.tx.send(WaylandUpdate::Toplevel(
ToplevelUpdate::Remove(toplevel.clone()), ToplevelUpdate::Remove(toplevel.clone()),
@ -377,7 +392,7 @@ impl ToplevelInfoHandler for AppData {
&mut self, &mut self,
_conn: &Connection, _conn: &Connection,
_qh: &QueueHandle<Self>, _qh: &QueueHandle<Self>,
toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1, toplevel: &ExtForeignToplevelHandleV1,
) { ) {
if let Some(info) = self.toplevel_info_state.info(toplevel) { if let Some(info) = self.toplevel_info_state.info(toplevel) {
if info if info
@ -386,7 +401,7 @@ impl ToplevelInfoHandler for AppData {
{ {
self.send_image(toplevel.clone()); self.send_image(toplevel.clone());
let _ = futures::executor::block_on(self.tx.send(WaylandUpdate::Toplevel( let _ = futures::executor::block_on(self.tx.send(WaylandUpdate::Toplevel(
ToplevelUpdate::Update(toplevel.clone(), info.clone()), ToplevelUpdate::Update(info.clone()),
))); )));
} else { } else {
let _ = futures::executor::block_on(self.tx.send(WaylandUpdate::Toplevel( let _ = futures::executor::block_on(self.tx.send(WaylandUpdate::Toplevel(
@ -400,7 +415,7 @@ impl ToplevelInfoHandler for AppData {
&mut self, &mut self,
_conn: &Connection, _conn: &Connection,
_qh: &QueueHandle<Self>, _qh: &QueueHandle<Self>,
toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1, toplevel: &ExtForeignToplevelHandleV1,
) { ) {
let _ = futures::executor::block_on(self.tx.send(WaylandUpdate::Toplevel( let _ = futures::executor::block_on(self.tx.send(WaylandUpdate::Toplevel(
ToplevelUpdate::Remove(toplevel.clone()), ToplevelUpdate::Remove(toplevel.clone()),
@ -442,7 +457,9 @@ pub(crate) fn wayland_handler(
ToplevelRequest::Activate(handle) => { ToplevelRequest::Activate(handle) => {
if let Some(seat) = state.seat_state.seats().next() { if let Some(seat) = state.seat_state.seats().next() {
let manager = &state.toplevel_manager_state.manager; let manager = &state.toplevel_manager_state.manager;
manager.activate(&handle, &seat); if let Some(cosmic_toplevel) = state.cosmic_toplevel(&handle) {
manager.activate(&cosmic_toplevel, &seat);
}
} }
} }
}, },

View file

@ -7,12 +7,14 @@
//! Source: `Interface '/org/freedesktop/UPower/KbdBacklight' from service 'org.freedesktop.UPower' on system bus`. //! Source: `Interface '/org/freedesktop/UPower/KbdBacklight' from service 'org.freedesktop.UPower' on system bus`.
use cctk::{sctk::reexports::calloop, toplevel_info::ToplevelInfo}; use cctk::{sctk::reexports::calloop, toplevel_info::ToplevelInfo};
use cosmic::{ use cosmic::{
cctk::{self, cosmic_protocols}, cctk::{
self,
wayland_protocols::ext::foreign_toplevel_list::v1::client::ext_foreign_toplevel_handle_v1::ExtForeignToplevelHandleV1,
},
iced::{self, Subscription}, iced::{self, Subscription},
iced_core::image::Bytes, iced_core::image::Bytes,
iced_futures::{futures, stream}, iced_futures::{futures, stream},
}; };
use cosmic_protocols::toplevel_info::v1::client::zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1;
use futures::SinkExt; use futures::SinkExt;
use image::EncodableLayout; use image::EncodableLayout;
use std::fmt::Debug; use std::fmt::Debug;
@ -45,7 +47,7 @@ pub enum WaylandUpdate {
Init(calloop::channel::Sender<WaylandRequest>), Init(calloop::channel::Sender<WaylandRequest>),
Finished, Finished,
Toplevel(ToplevelUpdate), Toplevel(ToplevelUpdate),
Image(ZcosmicToplevelHandleV1, WaylandImage), Image(ExtForeignToplevelHandleV1, WaylandImage),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -73,9 +75,9 @@ impl AsRef<[u8]> for WaylandImage {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum ToplevelUpdate { pub enum ToplevelUpdate {
Add(ZcosmicToplevelHandleV1, ToplevelInfo), Add(ToplevelInfo),
Update(ZcosmicToplevelHandleV1, ToplevelInfo), Update(ToplevelInfo),
Remove(ZcosmicToplevelHandleV1), Remove(ExtForeignToplevelHandleV1),
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -85,5 +87,5 @@ pub enum WaylandRequest {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum ToplevelRequest { pub enum ToplevelRequest {
Activate(ZcosmicToplevelHandleV1), Activate(ExtForeignToplevelHandleV1),
} }

View file

@ -11,13 +11,11 @@ use cctk::{
}, },
toplevel_info::{ToplevelInfoHandler, ToplevelInfoState}, toplevel_info::{ToplevelInfoHandler, ToplevelInfoState},
wayland_client::WEnum, wayland_client::WEnum,
wayland_protocols::ext::foreign_toplevel_list::v1::client::ext_foreign_toplevel_handle_v1::ExtForeignToplevelHandleV1,
workspace::{WorkspaceHandler, WorkspaceState}, workspace::{WorkspaceHandler, WorkspaceState},
}; };
use cosmic::iced::futures; use cosmic::iced::futures;
use cosmic_protocols::{ use cosmic_protocols::workspace::v1::client::zcosmic_workspace_handle_v1::{self, TilingState};
toplevel_info::v1::client::zcosmic_toplevel_handle_v1,
workspace::v1::client::zcosmic_workspace_handle_v1::{self, TilingState},
};
use futures::{channel::mpsc, executor::block_on, SinkExt}; use futures::{channel::mpsc, executor::block_on, SinkExt};
use std::{ use std::{
collections::HashSet, collections::HashSet,
@ -274,7 +272,7 @@ impl ToplevelInfoHandler for State {
&mut self, &mut self,
_conn: &Connection, _conn: &Connection,
_qh: &QueueHandle<Self>, _qh: &QueueHandle<Self>,
toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1, toplevel: &ExtForeignToplevelHandleV1,
) { ) {
let Some(w) = self let Some(w) = self
.toplevel_info_state .toplevel_info_state
@ -290,7 +288,7 @@ impl ToplevelInfoHandler for State {
&mut self, &mut self,
_conn: &Connection, _conn: &Connection,
_qh: &QueueHandle<Self>, _qh: &QueueHandle<Self>,
toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1, toplevel: &ExtForeignToplevelHandleV1,
) { ) {
let Some(w) = self let Some(w) = self
.toplevel_info_state .toplevel_info_state
@ -306,7 +304,7 @@ impl ToplevelInfoHandler for State {
&mut self, &mut self,
_conn: &Connection, _conn: &Connection,
_qh: &QueueHandle<Self>, _qh: &QueueHandle<Self>,
_toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1, _toplevel: &ExtForeignToplevelHandleV1,
) { ) {
} }
} }