Skip to content

Commit 926abeb

Browse files
ids1024mmstick
authored andcommitted
Update for toplevel-info cctk changes
1 parent 0e01b09 commit 926abeb

File tree

3 files changed

+73
-51
lines changed

3 files changed

+73
-51
lines changed

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/src/cosmic_toplevel/mod.rs

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ mod toplevel_handler;
22

33
use cctk::cosmic_protocols::toplevel_info::v1::client::zcosmic_toplevel_handle_v1::State;
44
use cctk::wayland_client::Proxy;
5-
use cctk::{cosmic_protocols, sctk::reexports::calloop, toplevel_info::ToplevelInfo};
6-
use cosmic_protocols::toplevel_info::v1::client::zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1;
5+
use cctk::{sctk::reexports::calloop, toplevel_info::ToplevelInfo};
76
use fde::DesktopEntry;
87
use freedesktop_desktop_entry as fde;
9-
use toplevel_handler::TopLevelsUpdate;
8+
use toplevel_handler::ToplevelUpdate;
109
use tracing::{debug, error, info, warn};
1110

1211
use crate::desktop_entries::utils::{get_description, is_session_cosmic};
@@ -70,26 +69,33 @@ pub async fn main() {
7069
next_event = toplevel_rx.next();
7170
next_request = second_to_next_request;
7271

73-
for (handle, info) in updates {
74-
match info {
75-
Some(info) => {
76-
if let Some(pos) = app.toplevels.iter().position(|t| t.0 == handle) {
72+
for update in updates {
73+
match update {
74+
ToplevelUpdate::Info(info) => {
75+
if let Some(pos) = app
76+
.toplevels
77+
.iter()
78+
.position(|t| t.foreign_toplevel == info.foreign_toplevel)
79+
{
7780
if info.state.contains(&State::Activated) {
7881
app.toplevels.remove(pos);
79-
app.toplevels.push((handle, Box::new(info)));
82+
app.toplevels.push(Box::new(info));
8083
} else {
81-
app.toplevels[pos].1 = Box::new(info);
84+
app.toplevels[pos] = Box::new(info);
8285
}
8386
} else {
84-
app.toplevels.push((handle, Box::new(info)));
87+
app.toplevels.push(Box::new(info));
8588
}
8689
}
87-
// no info means remove
88-
None => {
89-
if let Some(pos) = app.toplevels.iter().position(|t| t.0 == handle) {
90+
ToplevelUpdate::Remove(foreign_toplevel) => {
91+
if let Some(pos) = app
92+
.toplevels
93+
.iter()
94+
.position(|t| t.foreign_toplevel == foreign_toplevel)
95+
{
9096
app.toplevels.remove(pos);
9197
// ignore requests for this id until after the next search
92-
app.ids_to_ignore.push(handle.id().protocol_id());
98+
app.ids_to_ignore.push(foreign_toplevel.id().protocol_id());
9399
} else {
94100
warn!("no toplevel to remove");
95101
}
@@ -106,13 +112,13 @@ struct App<W> {
106112
locales: Vec<String>,
107113
desktop_entries: Vec<DesktopEntry<'static>>,
108114
ids_to_ignore: Vec<u32>,
109-
toplevels: Vec<(ZcosmicToplevelHandleV1, Box<ToplevelInfo>)>,
115+
toplevels: Vec<Box<ToplevelInfo>>,
110116
calloop_tx: calloop::channel::Sender<ToplevelAction>,
111117
tx: W,
112118
}
113119

114120
impl<W: AsyncWrite + Unpin> App<W> {
115-
fn new(tx: W) -> (Self, mpsc::UnboundedReceiver<TopLevelsUpdate>) {
121+
fn new(tx: W) -> (Self, mpsc::UnboundedReceiver<Vec<ToplevelUpdate>>) {
116122
let (toplevels_tx, toplevel_rx) = mpsc::unbounded();
117123
let (calloop_tx, calloop_rx) = calloop::channel::channel();
118124
let _handle = std::thread::spawn(move || toplevel_handler(toplevels_tx, calloop_rx));
@@ -144,8 +150,8 @@ impl<W: AsyncWrite + Unpin> App<W> {
144150
return;
145151
}
146152
if let Some(handle) = self.toplevels.iter().find_map(|t| {
147-
if t.0.id().protocol_id() == id {
148-
Some(t.0.clone())
153+
if t.foreign_toplevel.id().protocol_id() == id {
154+
Some(t.foreign_toplevel.clone())
149155
} else {
150156
None
151157
}
@@ -160,8 +166,8 @@ impl<W: AsyncWrite + Unpin> App<W> {
160166
return;
161167
}
162168
if let Some(handle) = self.toplevels.iter().find_map(|t| {
163-
if t.0.id().protocol_id() == id {
164-
Some(t.0.clone())
169+
if t.foreign_toplevel.id().protocol_id() == id {
170+
Some(t.foreign_toplevel.clone())
165171
} else {
166172
None
167173
}
@@ -173,7 +179,7 @@ impl<W: AsyncWrite + Unpin> App<W> {
173179
async fn search(&mut self, query: &str) {
174180
let query = query.to_ascii_lowercase();
175181

176-
for (handle, info) in self.toplevels.iter().rev() {
182+
for info in self.toplevels.iter().rev() {
177183
let entry = if query.is_empty() {
178184
fde::matching::get_best_match(
179185
&[&info.app_id, &info.title],
@@ -214,8 +220,8 @@ impl<W: AsyncWrite + Unpin> App<W> {
214220

215221
let response = PluginResponse::Append(PluginSearchResult {
216222
// XXX protocol id may be re-used later
217-
id: handle.id().protocol_id(),
218-
window: Some((0, handle.id().clone().protocol_id())),
223+
id: info.foreign_toplevel.id().protocol_id(),
224+
window: Some((0, info.foreign_toplevel.id().protocol_id())),
219225
description: info.title.clone(),
220226
name: get_description(de, &self.locales),
221227
icon: Some(IconSource::Name(icon_name)),

plugins/src/cosmic_toplevel/toplevel_handler.rs

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use cctk::{
55
toplevel_info::{ToplevelInfo, ToplevelInfoHandler, ToplevelInfoState},
66
toplevel_management::{ToplevelManagerHandler, ToplevelManagerState},
77
wayland_client::{self, WEnum},
8+
wayland_protocols::ext::foreign_toplevel_list::v1::client::ext_foreign_toplevel_handle_v1::ExtForeignToplevelHandleV1,
89
};
910
use sctk::{
1011
self,
@@ -15,7 +16,7 @@ use sctk::{
1516
};
1617

1718
use cosmic_protocols::{
18-
toplevel_info::v1::client::zcosmic_toplevel_handle_v1::{self, ZcosmicToplevelHandleV1},
19+
toplevel_info::v1::client::zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
1920
toplevel_management::v1::client::zcosmic_toplevel_manager_v1,
2021
};
2122
use futures::channel::mpsc::UnboundedSender;
@@ -25,23 +26,35 @@ use wayland_client::{globals::registry_queue_init, Connection, QueueHandle};
2526

2627
#[derive(Debug, Clone)]
2728
pub enum ToplevelAction {
28-
Activate(ZcosmicToplevelHandleV1),
29-
Close(ZcosmicToplevelHandleV1),
29+
Activate(ExtForeignToplevelHandleV1),
30+
Close(ExtForeignToplevelHandleV1),
3031
}
3132

32-
pub type TopLevelsUpdate = Vec<(
33-
zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
34-
Option<ToplevelInfo>,
35-
)>;
33+
pub enum ToplevelUpdate {
34+
Info(ToplevelInfo),
35+
Remove(ExtForeignToplevelHandleV1),
36+
}
3637

3738
struct AppData {
3839
exit: bool,
39-
tx: UnboundedSender<TopLevelsUpdate>,
40+
tx: UnboundedSender<Vec<ToplevelUpdate>>,
4041
registry_state: RegistryState,
4142
toplevel_info_state: ToplevelInfoState,
4243
toplevel_manager_state: ToplevelManagerState,
4344
seat_state: SeatState,
44-
pending_update: HashSet<zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1>,
45+
pending_update: HashSet<ExtForeignToplevelHandleV1>,
46+
}
47+
48+
impl AppData {
49+
fn cosmic_toplevel_for_foreign(
50+
&self,
51+
foreign_toplevel: &ExtForeignToplevelHandleV1,
52+
) -> Option<&ZcosmicToplevelHandleV1> {
53+
self.toplevel_info_state
54+
.info(foreign_toplevel)?
55+
.cosmic_toplevel
56+
.as_ref()
57+
}
4558
}
4659

4760
impl ProvidesRegistryState for AppData {
@@ -103,7 +116,7 @@ impl ToplevelInfoHandler for AppData {
103116
&mut self,
104117
_conn: &Connection,
105118
_qh: &QueueHandle<Self>,
106-
toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
119+
toplevel: &ExtForeignToplevelHandleV1,
107120
) {
108121
self.pending_update.insert(toplevel.clone());
109122
}
@@ -112,7 +125,7 @@ impl ToplevelInfoHandler for AppData {
112125
&mut self,
113126
_conn: &Connection,
114127
_qh: &QueueHandle<Self>,
115-
toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
128+
toplevel: &ExtForeignToplevelHandleV1,
116129
) {
117130
self.pending_update.insert(toplevel.clone());
118131
}
@@ -121,20 +134,20 @@ impl ToplevelInfoHandler for AppData {
121134
&mut self,
122135
_conn: &Connection,
123136
_qh: &QueueHandle<Self>,
124-
toplevel: &zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1,
137+
toplevel: &ExtForeignToplevelHandleV1,
125138
) {
126139
self.pending_update.insert(toplevel.clone());
127140
}
128141

129142
fn info_done(&mut self, _conn: &Connection, _qh: &QueueHandle<Self>) {
130-
let mut res = Vec::with_capacity(self.pending_update.len());
131-
132-
for toplevel_handle in self.pending_update.drain() {
133-
res.push((
134-
toplevel_handle.clone(),
135-
self.toplevel_info_state.info(&toplevel_handle).cloned(),
136-
));
137-
}
143+
let res = self
144+
.pending_update
145+
.drain()
146+
.map(|handle| match self.toplevel_info_state.info(&handle) {
147+
Some(info) => ToplevelUpdate::Info(info.clone()),
148+
None => ToplevelUpdate::Remove(handle),
149+
})
150+
.collect();
138151

139152
if let Err(err) = self.tx.unbounded_send(res) {
140153
warn!("{err}");
@@ -143,7 +156,7 @@ impl ToplevelInfoHandler for AppData {
143156
}
144157

145158
pub(crate) fn toplevel_handler(
146-
tx: UnboundedSender<TopLevelsUpdate>,
159+
tx: UnboundedSender<Vec<ToplevelUpdate>>,
147160
rx: calloop::channel::Channel<ToplevelAction>,
148161
) -> anyhow::Result<()> {
149162
let conn = Connection::connect_to_env()?;
@@ -159,15 +172,18 @@ pub(crate) fn toplevel_handler(
159172
calloop::channel::Event::Msg(req) => match req {
160173
ToplevelAction::Activate(handle) => {
161174
let manager = &state.toplevel_manager_state.manager;
162-
let state = &state.seat_state;
163175
// TODO Ashley how to choose the seat in a multi-seat setup?
164-
for s in state.seats() {
165-
manager.activate(&handle, &s);
176+
if let Some(cosmic_toplevel) = state.cosmic_toplevel_for_foreign(&handle) {
177+
for s in state.seat_state.seats() {
178+
manager.activate(cosmic_toplevel, &s);
179+
}
166180
}
167181
}
168182
ToplevelAction::Close(handle) => {
169183
let manager = &state.toplevel_manager_state.manager;
170-
manager.close(&handle);
184+
if let Some(cosmic_toplevel) = state.cosmic_toplevel_for_foreign(&handle) {
185+
manager.close(cosmic_toplevel);
186+
}
171187
}
172188
},
173189
calloop::channel::Event::Closed => {

0 commit comments

Comments
 (0)