Skip to content

Commit 2b5a318

Browse files
committed
fix(terminals): avoid startup overwrite and simplify terminal resolution
1 parent e51de26 commit 2b5a318

5 files changed

Lines changed: 522 additions & 67 deletions

File tree

src/application.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,10 @@ impl DistroShelfApplication {
249249

250250
command_runner.output_tracker().enable();
251251

252-
self.set_root_store(RootStore::new(command_runner));
252+
let root_store = RootStore::new(command_runner.clone());
253+
root_store.start_background_tasks();
254+
255+
self.set_root_store(root_store);
253256
let window =
254257
DistroShelfWindow::new(self.upcast_ref::<adw::Application>(), self.root_store());
255258
window.upcast()

src/backends/supported_terminals.rs

Lines changed: 58 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ mod imp {
109109
pub list: RefCell<Vec<Terminal>>,
110110
pub custom_list_path: PathBuf,
111111
pub command_runner: OnceCell<CommandRunner>,
112+
pub json_terminals_query: Query<Vec<Terminal>>,
112113
pub flatpak_terminals_query: Query<Vec<Terminal>>,
113114
}
114115

@@ -119,6 +120,7 @@ mod imp {
119120
list: RefCell::new(vec![]),
120121
custom_list_path,
121122
command_runner: OnceCell::new(),
123+
json_terminals_query: Query::new("json_terminals".into(), || async { Ok(vec![]) }),
122124
flatpak_terminals_query: Query::new("flatpak_terminals".into(), || async {
123125
Ok(vec![])
124126
}),
@@ -154,30 +156,48 @@ impl TerminalRepository {
154156
.unwrap();
155157

156158
let mut list = SUPPORTED_TERMINALS.clone();
157-
if let Ok(loaded_list) = Self::load_terminals_from_json(&this.imp().custom_list_path) {
158-
list.extend(loaded_list);
159-
} else {
160-
warn!(
161-
"Failed to load custom terminals from JSON file {:?}",
162-
&this.imp().custom_list_path
163-
);
164-
}
165-
166159
list.sort_by(|a, b| a.name.cmp(&b.name));
167160
this.imp().list.replace(list);
168161

162+
// Set up the json terminals query fetcher
163+
let custom_list_path = this.imp().custom_list_path.clone();
164+
this.imp().json_terminals_query.set_fetcher(move || {
165+
let custom_list_path = custom_list_path.clone();
166+
async move {
167+
match Self::load_terminals_from_json(&custom_list_path) {
168+
Ok(terminals) => Ok(terminals),
169+
Err(e) if !custom_list_path.exists() => Ok(vec![]),
170+
Err(e) => {
171+
warn!(
172+
"Failed to load custom terminals from JSON file {:?}: {}",
173+
custom_list_path,
174+
e
175+
);
176+
Err(e)
177+
}
178+
}
179+
}
180+
});
181+
169182
// Set up the flatpak terminals query fetcher
170183
let runner = command_runner.clone();
171184
this.imp().flatpak_terminals_query.set_fetcher(move || {
172185
let runner = runner.clone();
173186
async move { Self::fetch_flatpak_terminals(&runner).await }
174187
});
175188

189+
let this_clone = this.clone();
190+
this.json_terminals_query().connect_success(move |terminals| {
191+
this_clone.apply_custom_terminals(terminals.clone());
192+
this_clone.emit_by_name::<()>("terminals-changed", &[]);
193+
});
194+
176195
// Connect to query success to update the terminal list
177196
let this_clone = this.clone();
178197
this.flatpak_terminals_query()
179198
.connect_success(move |terminals| {
180-
this_clone.merge_flatpak_terminals(terminals.clone());
199+
this_clone.apply_flatpak_terminals(terminals.clone());
200+
this_clone.emit_by_name::<()>("terminals-changed", &[]);
181201
});
182202

183203
this
@@ -205,27 +225,42 @@ impl TerminalRepository {
205225
Ok(found_terminals)
206226
}
207227

208-
fn merge_flatpak_terminals(&self, terminals: Vec<Terminal>) {
209-
if terminals.is_empty() {
210-
return;
211-
}
228+
fn apply_custom_terminals(&self, terminals: Vec<Terminal>) {
229+
let mut list = self.imp().list.borrow_mut();
230+
list.retain(|terminal| terminal.read_only);
231+
list.extend(terminals.into_iter().map(|mut terminal| {
232+
terminal.read_only = false;
233+
terminal
234+
}));
235+
list.sort_by(|a, b| a.name.cmp(&b.name));
236+
}
212237

238+
fn apply_flatpak_terminals(&self, terminals: Vec<Terminal>) {
213239
let mut list = self.imp().list.borrow_mut();
214-
// Build a set of existing terminal identifiers to avoid duplicates
215-
let existing_ids: HashSet<String> = list.iter().map(|t| t.full_command_id()).collect();
216240

217-
// Only add terminals that don't already exist
241+
let flatpak_candidate_ids: HashSet<String> = FLATPAK_TERMINAL_CANDIDATES
242+
.iter()
243+
.map(|terminal| terminal.full_command_id())
244+
.collect();
245+
list.retain(|terminal| !flatpak_candidate_ids.contains(&terminal.full_command_id()));
246+
247+
let existing_ids: HashSet<String> = list.iter().map(|t| t.full_command_id()).collect();
218248
let new_terminals: Vec<Terminal> = terminals
219249
.into_iter()
220250
.filter(|t| !existing_ids.contains(&t.full_command_id()))
221251
.collect();
222252

223-
if !new_terminals.is_empty() {
224-
list.extend(new_terminals);
225-
list.sort_by(|a, b| a.name.cmp(&b.name));
226-
drop(list);
227-
self.emit_by_name::<()>("terminals-changed", &[]);
228-
}
253+
list.extend(new_terminals);
254+
list.sort_by(|a, b| a.name.cmp(&b.name));
255+
}
256+
257+
pub fn load_all(&self) {
258+
self.json_terminals_query().refetch();
259+
self.flatpak_terminals_query().refetch();
260+
}
261+
262+
pub fn json_terminals_query(&self) -> Query<Vec<Terminal>> {
263+
self.imp().json_terminals_query.clone()
229264
}
230265

231266
pub fn flatpak_terminals_query(&self) -> Query<Vec<Terminal>> {

0 commit comments

Comments
 (0)