@@ -20,8 +20,6 @@ use pop_launcher::{
20
20
Request ,
21
21
} ;
22
22
use std:: borrow:: Cow ;
23
- use std:: iter;
24
- use std:: time:: Instant ;
25
23
use tokio:: io:: { AsyncWrite , AsyncWriteExt } ;
26
24
27
25
use self :: toplevel_handler:: { toplevel_handler, ToplevelAction } ;
@@ -111,7 +109,7 @@ pub async fn main() {
111
109
112
110
struct App < W > {
113
111
locales : Vec < String > ,
114
- desktop_entries : Vec < DesktopEntry < ' static > > ,
112
+ desktop_entries : Vec < DesktopEntry > ,
115
113
ids_to_ignore : Vec < u32 > ,
116
114
toplevels : Vec < Box < ToplevelInfo > > ,
117
115
calloop_tx : calloop:: channel:: Sender < ToplevelAction > ,
@@ -126,10 +124,9 @@ impl<W: AsyncWrite + Unpin> App<W> {
126
124
127
125
let locales = fde:: get_languages_from_env ( ) ;
128
126
129
- let paths = fde:: Iter :: new ( fde:: default_paths ( ) ) ;
130
-
131
- let desktop_entries = DesktopEntry :: from_paths ( paths, & locales)
132
- . filter_map ( |e| e. ok ( ) )
127
+ let desktop_entries = fde:: Iter :: new ( fde:: default_paths ( ) )
128
+ . map ( |path| DesktopEntry :: from_path ( path, Some ( & locales) ) )
129
+ . filter_map ( Result :: ok)
133
130
. collect :: < Vec < _ > > ( ) ;
134
131
135
132
(
@@ -178,82 +175,53 @@ impl<W: AsyncWrite + Unpin> App<W> {
178
175
}
179
176
180
177
async fn search ( & mut self , query : & str ) {
181
- let query = query. to_ascii_lowercase ( ) ;
178
+ fn contains_pattern ( needle : & str , haystack : & [ & str ] ) -> bool {
179
+ let needle = needle. to_ascii_lowercase ( ) ;
180
+ haystack. iter ( ) . all ( |h| needle. contains ( h) )
181
+ }
182
182
183
- for info in self . toplevels . iter ( ) . rev ( ) {
184
- let entry = if query. is_empty ( ) {
185
- fde:: matching:: get_best_match (
186
- & [ & info. app_id , & info. title ] ,
187
- & self . desktop_entries ,
188
- fde:: matching:: MatchAppIdOptions :: default ( ) ,
189
- )
190
- } else {
191
- let lowercase_title = info. title . to_lowercase ( ) ;
192
- let window_words = lowercase_title
193
- . split_whitespace ( )
194
- . chain ( iter:: once ( info. app_id . as_str ( ) ) )
195
- . chain ( iter:: once ( info. title . as_str ( ) ) )
196
- . collect :: < Vec < _ > > ( ) ;
183
+ let query = query. to_ascii_lowercase ( ) ;
184
+ let haystack = query. split_ascii_whitespace ( ) . collect :: < Vec < & str > > ( ) ;
197
185
198
- // if there's an exact appid match, use that instead
199
- let exact_appid_match = self
200
- . desktop_entries
201
- . iter ( )
202
- . find ( |de| de. appid == info. app_id ) ;
203
- if exact_appid_match. is_some ( )
204
- && fde:: matching:: get_entry_score (
205
- & query,
206
- exact_appid_match. unwrap ( ) ,
207
- & self . locales ,
208
- & window_words,
209
- ) > 0.8
210
- {
211
- exact_appid_match
212
- } else {
213
- fde:: matching:: get_best_match (
214
- & window_words,
215
- & self . desktop_entries ,
216
- fde:: matching:: MatchAppIdOptions :: default ( ) ,
217
- )
218
- . and_then ( |de| {
219
- let score = fde:: matching:: get_entry_score (
220
- & query,
221
- de,
222
- & self . locales ,
223
- & window_words,
224
- ) ;
186
+ for info in & self . toplevels {
187
+ let retain = query. is_empty ( )
188
+ || contains_pattern ( & info. app_id , & haystack)
189
+ || contains_pattern ( & info. title , & haystack) ;
225
190
226
- if score > 0.8 {
227
- Some ( de)
228
- } else {
229
- None
230
- }
231
- } )
232
- }
233
- } ;
191
+ if !retain {
192
+ continue ;
193
+ }
234
194
235
- if let Some ( de) = entry {
236
- let icon_name = if let Some ( icon) = de. icon ( ) {
237
- Cow :: Owned ( icon. to_owned ( ) )
238
- } else {
239
- Cow :: Borrowed ( "application-x-executable" )
240
- } ;
195
+ let appid = fde:: unicase:: Ascii :: new ( info. app_id . as_str ( ) ) ;
241
196
242
- let response = PluginResponse :: Append ( PluginSearchResult {
243
- // XXX protocol id may be re-used later
244
- id : info . foreign_toplevel . id ( ) . protocol_id ( ) ,
245
- window : Some ( ( 0 , info . foreign_toplevel . id ( ) . protocol_id ( ) ) ) ,
246
- description : info . title . clone ( ) ,
247
- name : get_description ( de , & self . locales ) ,
248
- icon : Some ( IconSource :: Name ( icon_name ) ) ,
249
- .. Default :: default ( )
250
- } ) ;
197
+ let entry = fde :: find_app_by_id ( & self . desktop_entries , appid )
198
+ . map ( ToOwned :: to_owned )
199
+ . unwrap_or_else ( || fde :: DesktopEntry :: from_appid ( appid . to_string ( ) ) . to_owned ( ) ) ;
200
+
201
+ let icon_name = if let Some ( icon ) = entry . icon ( ) {
202
+ Cow :: Owned ( icon . to_owned ( ) )
203
+ } else {
204
+ Cow :: Borrowed ( "application-x-executable" )
205
+ } ;
251
206
252
- send ( & mut self . tx , response) . await ;
253
- }
207
+ let response = PluginResponse :: Append ( PluginSearchResult {
208
+ // XXX protocol id may be re-used later
209
+ id : info. foreign_toplevel . id ( ) . protocol_id ( ) ,
210
+ window : Some ( ( 0 , info. foreign_toplevel . id ( ) . protocol_id ( ) ) ) ,
211
+ description : info. title . clone ( ) ,
212
+ name : get_description ( & entry, & self . locales ) ,
213
+ icon : Some ( IconSource :: Name ( icon_name) ) ,
214
+ ..Default :: default ( )
215
+ } ) ;
216
+
217
+ send (
218
+ & mut self . tx ,
219
+ response,
220
+ )
221
+ . await ;
254
222
}
255
223
256
224
send ( & mut self . tx , PluginResponse :: Finished ) . await ;
257
- let _ = self . tx . flush ( ) . await ;
225
+ let _ = self . tx . flush ( ) ;
258
226
}
259
227
}
0 commit comments