Actually launch the app lol

This commit is contained in:
Javier Feliz 2025-09-03 20:58:36 -04:00
parent 70c4272611
commit 98dd63b05b
2 changed files with 54 additions and 4 deletions

View File

@ -1,6 +1,7 @@
pub mod drun;
pub mod plugins;
pub mod util;
#[derive(Debug)]
pub enum LaunchError {
CouldNotLaunch(String),
}

View File

@ -4,7 +4,7 @@ use gtk::gdk_pixbuf::Pixbuf;
use gtk::prelude::*;
use gtk::{
Application, ApplicationWindow, Box as GtkBox, Entry, EventControllerKey, IconTheme, Image,
Label, ListBox, Orientation, ScrolledWindow,
Label, ListBox, Orientation, ScrolledWindow, SearchEntry,
};
use gtk4_layer_shell as layerShell;
use layerShell::LayerShell;
@ -76,7 +76,7 @@ impl AppModel {
let main_box = GtkBox::new(Orientation::Vertical, 0);
let search_input = Entry::new();
let search_input = SearchEntry::new();
search_input.set_placeholder_text(Some("Search..."));
let scrolled_window = ScrolledWindow::new();
@ -84,6 +84,8 @@ impl AppModel {
let list_box = ListBox::new();
list_box.set_vexpand(true);
list_box.set_can_focus(true);
list_box.set_activate_on_single_click(false);
scrolled_window.set_child(Some(&list_box));
main_box.append(&search_input);
@ -115,6 +117,12 @@ impl AppModel {
// Populate the list
model.borrow_mut().populate_list();
// Set initial focus to search input so user can start typing immediately
search_input.grab_focus();
// Set up SearchEntry to capture keys from the window for proper navigation
search_input.set_key_capture_widget(Some(&model.borrow().window));
// Connect search input signal
let model_clone = model.clone();
search_input.connect_changed(move |entry| {
@ -123,6 +131,32 @@ impl AppModel {
model_clone.borrow_mut().filter_list(&query);
});
// Connect search navigation signals
let list_box_clone_for_next = list_box.clone();
let list_box_clone_for_prev = list_box.clone();
search_input.connect_next_match(move |_| {
if let Some(selected_row) = list_box_clone_for_next.selected_row() {
let index = selected_row.index();
if let Some(next_row) = list_box_clone_for_next.row_at_index(index + 1) {
list_box_clone_for_next.select_row(Some(&next_row));
}
} else if let Some(first_row) = list_box_clone_for_next.row_at_index(0) {
list_box_clone_for_next.select_row(Some(&first_row));
}
});
search_input.connect_previous_match(move |_| {
if let Some(selected_row) = list_box_clone_for_prev.selected_row() {
let index = selected_row.index();
if index > 0 {
if let Some(prev_row) = list_box_clone_for_prev.row_at_index(index - 1) {
list_box_clone_for_prev.select_row(Some(&prev_row));
}
}
}
});
// Add ESC key handler to close window
let key_controller = EventControllerKey::new();
let window_clone = model.borrow().window.clone();
@ -136,13 +170,23 @@ impl AppModel {
});
model.borrow().window.add_controller(key_controller);
// Connect row activation signal to print app names
// Connect row activation signal to launch app and close launcher
let model_clone_2 = model.clone();
list_box.connect_row_activated(move |_, row| {
let index = row.index() as usize;
let model_ref = model_clone_2.borrow();
if let Some(entry) = model_ref.entries.get(index) {
println!("Selected app: {}", entry.title());
println!("Launching app: {}", entry.title());
match entry.execute() {
Ok(_) => {
println!("App launched successfully, closing launcher");
// Close the launcher window after successful launch
model_ref.window.close();
}
Err(e) => {
eprintln!("Failed to launch app: {:?}", e);
}
}
}
});
@ -162,6 +206,11 @@ impl AppModel {
let widget = list_item.create_widget();
self.list_box.append(&widget);
}
// Always select the first item if available
if let Some(first_row) = self.list_box.row_at_index(0) {
self.list_box.select_row(Some(&first_row));
}
}
fn populate_list(&mut self) {