connect handler for new window and quit all from dock menu
This commit is contained in:
parent
ca89fb6199
commit
21bc4af3c9
5 changed files with 88 additions and 19 deletions
|
|
@ -35,6 +35,7 @@ impl DockItem {
|
||||||
|
|
||||||
let item_box = Box::new(Orientation::Vertical, 0);
|
let item_box = Box::new(Orientation::Vertical, 0);
|
||||||
self_.set_child(Some(&item_box));
|
self_.set_child(Some(&item_box));
|
||||||
|
self_.add_css_class("dock_item");
|
||||||
|
|
||||||
let image = cascade! {
|
let image = cascade! {
|
||||||
Image::new();
|
Image::new();
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ use crate::dock_object::DockObject;
|
||||||
pub struct DockPopover {
|
pub struct DockPopover {
|
||||||
pub menu_handle: Rc<RefCell<Box>>,
|
pub menu_handle: Rc<RefCell<Box>>,
|
||||||
pub all_windows_item_revealer: Rc<RefCell<Revealer>>,
|
pub all_windows_item_revealer: Rc<RefCell<Revealer>>,
|
||||||
|
pub all_windows_item_header: Rc<RefCell<Button>>,
|
||||||
pub window_list: Rc<RefCell<ListBox>>,
|
pub window_list: Rc<RefCell<ListBox>>,
|
||||||
pub launch_new_item: Rc<RefCell<Button>>,
|
pub launch_new_item: Rc<RefCell<Button>>,
|
||||||
pub favorite_item: Rc<RefCell<Button>>,
|
pub favorite_item: Rc<RefCell<Button>>,
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
use cascade::cascade;
|
use cascade::cascade;
|
||||||
use gtk4::ffi::gtk_window_close;
|
use gio::DesktopAppInfo;
|
||||||
use gtk4::subclass::prelude::*;
|
use gtk4::subclass::prelude::*;
|
||||||
use gtk4::{gio, glib};
|
use gtk4::{gio, glib};
|
||||||
use gtk4::{prelude::*, Label};
|
use gtk4::{prelude::*, Label};
|
||||||
use gtk4::{Box, Button, Image, ListBox, Orientation, Revealer};
|
use gtk4::{Box, Button, Image, ListBox, Orientation, Revealer, Window};
|
||||||
|
|
||||||
use crate::dock_object::DockObject;
|
use crate::dock_object::{self, DockObject};
|
||||||
use crate::utils::BoxedWindowList;
|
use crate::utils::BoxedWindowList;
|
||||||
|
use crate::Event;
|
||||||
|
use crate::TX;
|
||||||
|
|
||||||
mod imp;
|
mod imp;
|
||||||
|
|
||||||
|
|
@ -88,6 +90,7 @@ impl DockPopover {
|
||||||
..set_pixel_size(16);
|
..set_pixel_size(16);
|
||||||
};
|
};
|
||||||
all_windows_item_header_box.append(&all_windows_item_header_icon);
|
all_windows_item_header_box.append(&all_windows_item_header_icon);
|
||||||
|
imp.all_windows_item_header.replace(all_windows_item_header);
|
||||||
|
|
||||||
if let Ok(window_list) = dock_object
|
if let Ok(window_list) = dock_object
|
||||||
.property("active")
|
.property("active")
|
||||||
|
|
@ -99,7 +102,7 @@ impl DockPopover {
|
||||||
} else {
|
} else {
|
||||||
let window_list_revealer = cascade! {
|
let window_list_revealer = cascade! {
|
||||||
Revealer::new();
|
Revealer::new();
|
||||||
..set_reveal_child(true);
|
..set_reveal_child(false);
|
||||||
..set_transition_type(gtk4::RevealerTransitionType::SlideDown);
|
..set_transition_type(gtk4::RevealerTransitionType::SlideDown);
|
||||||
};
|
};
|
||||||
all_windows_item_container.append(&window_list_revealer);
|
all_windows_item_container.append(&window_list_revealer);
|
||||||
|
|
@ -129,6 +132,8 @@ impl DockPopover {
|
||||||
window_box.append(&window_image);
|
window_box.append(&window_image);
|
||||||
window_box.append(&window_title);
|
window_box.append(&window_title);
|
||||||
}
|
}
|
||||||
|
imp.all_windows_item_revealer.replace(window_list_revealer);
|
||||||
|
imp.window_list.replace(window_listbox);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -142,11 +147,13 @@ impl DockPopover {
|
||||||
Button::with_label("New Window");
|
Button::with_label("New Window");
|
||||||
};
|
};
|
||||||
launch_item_container.append(&launch_new_item);
|
launch_item_container.append(&launch_new_item);
|
||||||
|
imp.launch_new_item.replace(launch_new_item);
|
||||||
|
|
||||||
let favorite_item = cascade! {
|
let favorite_item = cascade! {
|
||||||
Button::with_label(if dock_object.property("saved").unwrap().get::<bool>().unwrap() {"Remove from Favorites"} else {"Add to Favorites"});
|
Button::with_label(if dock_object.property("saved").unwrap().get::<bool>().unwrap() {"Remove from Favorites"} else {"Add to Favorites"});
|
||||||
};
|
};
|
||||||
menu_handle.append(&favorite_item);
|
menu_handle.append(&favorite_item);
|
||||||
|
imp.favorite_item.replace(favorite_item);
|
||||||
|
|
||||||
if let Ok(window_list) = dock_object
|
if let Ok(window_list) = dock_object
|
||||||
.property("active")
|
.property("active")
|
||||||
|
|
@ -158,6 +165,7 @@ impl DockPopover {
|
||||||
Button::with_label(format!("Quit {} Windows", window_list.0.len()).as_str());
|
Button::with_label(format!("Quit {} Windows", window_list.0.len()).as_str());
|
||||||
};
|
};
|
||||||
menu_handle.append(&quit_all_item);
|
menu_handle.append(&quit_all_item);
|
||||||
|
imp.quit_all_item.replace(quit_all_item);
|
||||||
} else {
|
} else {
|
||||||
let quit_all_item = cascade! {
|
let quit_all_item = cascade! {
|
||||||
Button::with_label("Quit");
|
Button::with_label("Quit");
|
||||||
|
|
@ -166,6 +174,7 @@ impl DockPopover {
|
||||||
if window_list.0.len() == 0 {
|
if window_list.0.len() == 0 {
|
||||||
quit_all_item.hide();
|
quit_all_item.hide();
|
||||||
}
|
}
|
||||||
|
imp.quit_all_item.replace(quit_all_item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.setup_handlers();
|
self.setup_handlers();
|
||||||
|
|
@ -184,6 +193,57 @@ impl DockPopover {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_handlers(&self) {
|
fn setup_handlers(&self) {
|
||||||
// todo!();
|
let imp = imp::DockPopover::from_instance(&self);
|
||||||
|
let dock_object = imp.dock_object.borrow();
|
||||||
|
let launch_new_item = imp.launch_new_item.borrow();
|
||||||
|
let favorite_item = imp.favorite_item.borrow();
|
||||||
|
let quit_all_item = imp.quit_all_item.borrow();
|
||||||
|
let window_listbox = imp.window_list.borrow();
|
||||||
|
let all_windows_header = imp.all_windows_item_header.borrow();
|
||||||
|
let revealer = &imp.all_windows_item_revealer;
|
||||||
|
|
||||||
|
if let Some(dock_object) = dock_object.as_ref() {
|
||||||
|
println!("setting up popover menu handlers");
|
||||||
|
launch_new_item.connect_clicked(glib::clone!(@weak dock_object => move |self_| {
|
||||||
|
let app_info = dock_object.property("appinfo").expect("DockObject must have appinfo property").get::<Option<DesktopAppInfo>>().expect("Failed to convert value to DesktopAppInfo").unwrap();
|
||||||
|
|
||||||
|
let window = self_.root().unwrap().downcast::<Window>().unwrap();
|
||||||
|
let context = window.display().app_launch_context();
|
||||||
|
if let Err(err) = app_info.launch(&[], Some(&context)) {
|
||||||
|
gtk4::MessageDialog::builder()
|
||||||
|
.text(&format!("Failed to start {}", app_info.name()))
|
||||||
|
.secondary_text(&err.to_string())
|
||||||
|
.message_type(gtk4::MessageType::Error)
|
||||||
|
.modal(true)
|
||||||
|
.transient_for(&window)
|
||||||
|
.build()
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
quit_all_item.connect_clicked(glib::clone!(@weak dock_object => move |self_| {
|
||||||
|
let active = dock_object.property("active").expect("DockObject must have active property").get::<BoxedWindowList>().expect("Failed to convert value to WindowList").0;
|
||||||
|
for w in active {
|
||||||
|
let entity = w.entity.clone();
|
||||||
|
glib::MainContext::default().spawn_local(async move {
|
||||||
|
if let Some(tx) = TX.get() {
|
||||||
|
let _ = tx.send(Event::Close(entity)).await;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
favorite_item.connect_clicked(glib::clone!(@weak dock_object => move |self_| {
|
||||||
|
println!("handling favorite");
|
||||||
|
}));
|
||||||
|
|
||||||
|
all_windows_header.connect_clicked(
|
||||||
|
glib::clone!(@weak dock_object, @weak revealer => move |self_| {
|
||||||
|
dbg!(dock_object);
|
||||||
|
let revealer = revealer.borrow();
|
||||||
|
revealer.set_reveal_child(!revealer.reveals_child())
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ static X11_CONN: OnceCell<RustConnection> = OnceCell::new();
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
WindowList(Vec<Item>),
|
WindowList(Vec<Item>),
|
||||||
Activate((u32, u32)),
|
Activate((u32, u32)),
|
||||||
|
Close((u32, u32)),
|
||||||
RefreshFromCache,
|
RefreshFromCache,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,7 +53,7 @@ pub struct Item {
|
||||||
desktop_entry: String,
|
desktop_entry: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn_launcher(tx: mpsc::Sender<Event>) -> Connection {
|
fn spawn_zbus(tx: mpsc::Sender<Event>) -> Connection {
|
||||||
let connection = block_on(Connection::session()).unwrap();
|
let connection = block_on(Connection::session()).unwrap();
|
||||||
|
|
||||||
let sender = tx.clone();
|
let sender = tx.clone();
|
||||||
|
|
@ -110,7 +111,7 @@ fn main() {
|
||||||
app.connect_activate(move |app| {
|
app.connect_activate(move |app| {
|
||||||
let (tx, mut rx) = mpsc::channel(100);
|
let (tx, mut rx) = mpsc::channel(100);
|
||||||
|
|
||||||
let zbus_conn = spawn_launcher(tx.clone());
|
let zbus_conn = spawn_zbus(tx.clone());
|
||||||
if TX.set(tx).is_err() {
|
if TX.set(tx).is_err() {
|
||||||
println!("failed to set global Sender. Exiting");
|
println!("failed to set global Sender. Exiting");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
|
|
@ -136,6 +137,12 @@ fn main() {
|
||||||
.await
|
.await
|
||||||
.expect("Failed to focus selected window");
|
.expect("Failed to focus selected window");
|
||||||
}
|
}
|
||||||
|
Event::Close(e) => {
|
||||||
|
let _activate_window = zbus_conn
|
||||||
|
.call_method(Some(DEST), PATH, Some(DEST), "WindowQuit", &((e,)))
|
||||||
|
.await
|
||||||
|
.expect("Failed to close selected window");
|
||||||
|
}
|
||||||
Event::RefreshFromCache => {
|
Event::RefreshFromCache => {
|
||||||
// println!("refreshing model from cache");
|
// println!("refreshing model from cache");
|
||||||
let cached_results = cached_results.as_ref();
|
let cached_results = cached_results.as_ref();
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,18 @@ listview row {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button.dock_item:hover {
|
||||||
|
background: #888888;
|
||||||
|
border-radius: 12px;
|
||||||
|
border-width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.dock_item {
|
||||||
|
background: #333333;
|
||||||
|
border-radius: 12px;
|
||||||
|
border-width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
list {
|
list {
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
background: #333333;
|
background: #333333;
|
||||||
|
|
@ -34,18 +46,6 @@ list row {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:hover {
|
|
||||||
background: #888888;
|
|
||||||
border-radius: 12px;
|
|
||||||
border-width: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
background: #333333;
|
|
||||||
border-radius: 12px;
|
|
||||||
border-width: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
box.dock {
|
box.dock {
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
background: #333333;
|
background: #333333;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue