initial support for app library
This commit is contained in:
parent
6ed9fdc9cd
commit
9273ea91e8
8 changed files with 154 additions and 171 deletions
|
|
@ -7,7 +7,7 @@ edition = "2021"
|
||||||
cascade = "1.0.0"
|
cascade = "1.0.0"
|
||||||
derivative = "2.2.0"
|
derivative = "2.2.0"
|
||||||
gdk4 = "0.4.4"
|
gdk4 = "0.4.4"
|
||||||
gdk4-wayland = { version = "0.4.2", optional = true }
|
gdk4-wayland = { version = "0.4.2", features = [ "wayland_crate" ], optional = true }
|
||||||
gdk4-x11 = { version = "0.4.2", features = [ "xlib" ] }
|
gdk4-x11 = { version = "0.4.2", features = [ "xlib" ] }
|
||||||
gio = "0.15.2"
|
gio = "0.15.2"
|
||||||
gobject-sys = "0.15.1"
|
gobject-sys = "0.15.1"
|
||||||
|
|
|
||||||
|
|
@ -131,25 +131,19 @@ impl AppGrid {
|
||||||
let app_grid_view = &imp.app_grid_view.get().unwrap();
|
let app_grid_view = &imp.app_grid_view.get().unwrap();
|
||||||
|
|
||||||
app_grid_view.connect_activate(move |list_view, i| {
|
app_grid_view.connect_activate(move |list_view, i| {
|
||||||
let window = list_view
|
|
||||||
.root()
|
|
||||||
.unwrap()
|
|
||||||
.downcast::<gtk4::Window>()
|
|
||||||
.unwrap();
|
|
||||||
// on activation change the group filter model to use the app names, and category
|
// on activation change the group filter model to use the app names, and category
|
||||||
println!("selected app {}", i);
|
println!("selected app {}", i);
|
||||||
// Launch the application when an item of the list is activated
|
// Launch the application when an item of the list is activated
|
||||||
let model = list_view.model().unwrap();
|
let model = list_view.model().unwrap();
|
||||||
if let Some(item) = model.item(i) {
|
if let Some(item) = model.item(i) {
|
||||||
let app_info = item.downcast::<gio::DesktopAppInfo>().unwrap();
|
let app_info = item.downcast::<gio::DesktopAppInfo>().unwrap();
|
||||||
let context = window.display().app_launch_context();
|
let context = list_view.display().app_launch_context();
|
||||||
if let Err(err) = app_info.launch(&[], Some(&context)) {
|
if let Err(err) = app_info.launch(&[], Some(&context)) {
|
||||||
gtk4::MessageDialog::builder()
|
gtk4::MessageDialog::builder()
|
||||||
.text(&format!("Failed to start {}", app_info.name()))
|
.text(&format!("Failed to start {}", app_info.name()))
|
||||||
.secondary_text(&err.to_string())
|
.secondary_text(&err.to_string())
|
||||||
.message_type(gtk4::MessageType::Error)
|
.message_type(gtk4::MessageType::Error)
|
||||||
.modal(true)
|
.modal(true)
|
||||||
.transient_for(&window)
|
|
||||||
.build()
|
.build()
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ impl GroupGrid {
|
||||||
let self_clone = self.clone();
|
let self_clone = self.clone();
|
||||||
group_grid_view.connect_activate(move |group_grid_view, i| {
|
group_grid_view.connect_activate(move |group_grid_view, i| {
|
||||||
// on activation change the group filter model to use the app names, and category
|
// on activation change the group filter model to use the app names, and category
|
||||||
let window = group_grid_view.root().unwrap().downcast::<Window>().unwrap();
|
// let window = group_grid_view.root().unwrap().downcast::<Window>().unwrap();
|
||||||
println!("grid view activated. {}", i);
|
println!("grid view activated. {}", i);
|
||||||
let group_model = group_grid_view.model().unwrap().downcast::<gtk4::SingleSelection>().unwrap()
|
let group_model = group_grid_view.model().unwrap().downcast::<gtk4::SingleSelection>().unwrap()
|
||||||
.model()
|
.model()
|
||||||
|
|
@ -180,15 +180,15 @@ impl GroupGrid {
|
||||||
.resizable(false)
|
.resizable(false)
|
||||||
.use_header_bar(true.into())
|
.use_header_bar(true.into())
|
||||||
.destroy_with_parent(true)
|
.destroy_with_parent(true)
|
||||||
.transient_for(&window)
|
// .transient_for(&window)
|
||||||
.title("New App Group")
|
.title("New App Group")
|
||||||
.child(&vbox)
|
.child(&vbox)
|
||||||
.build();
|
.build();
|
||||||
let app = window
|
// let app = window
|
||||||
.application()
|
// .application()
|
||||||
.expect("could not get application from window");
|
// .expect("could not get application from window");
|
||||||
|
|
||||||
dialog.set_application(Some(&app));
|
// dialog.set_application(Some(&app));
|
||||||
dialog.add_buttons(&[
|
dialog.add_buttons(&[
|
||||||
("Apply", gtk4::ResponseType::Apply),
|
("Apply", gtk4::ResponseType::Apply),
|
||||||
("Cancel", gtk4::ResponseType::Cancel),
|
("Cancel", gtk4::ResponseType::Cancel),
|
||||||
|
|
@ -215,20 +215,20 @@ impl GroupGrid {
|
||||||
dialog.emit_close();
|
dialog.emit_close();
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
dialog.connect_is_active_notify(move |win| {
|
// dialog.connect_is_active_notify(move |win| {
|
||||||
let app = win
|
// let app = win
|
||||||
.application()
|
// .application()
|
||||||
.expect("could not get application from window");
|
// .expect("could not get application from window");
|
||||||
let active_window = app
|
// let active_window = app
|
||||||
.active_window()
|
// .active_window()
|
||||||
.expect("no active window available, closing app library.");
|
// .expect("no active window available, closing app library.");
|
||||||
dbg!(&active_window);
|
// dbg!(&active_window);
|
||||||
if win == &active_window && !win.is_active() {
|
// if win == &active_window && !win.is_active() {
|
||||||
println!("no focus");
|
// println!("no focus");
|
||||||
// close top level window
|
// // close top level window
|
||||||
window.close();
|
// window.close();
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
dialog.show();
|
dialog.show();
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
@ -257,7 +257,7 @@ impl GroupGrid {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
self_clone
|
self_clone
|
||||||
.emit_by_name::<CustomFilter>("group-changed", &[&new_filter]);
|
.emit_by_name::<()>("group-changed", &[&new_filter]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ mod grid_item;
|
||||||
mod group_grid;
|
mod group_grid;
|
||||||
mod utils;
|
mod utils;
|
||||||
mod window;
|
mod window;
|
||||||
|
mod window_inner;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let app = gtk4::Application::new(Some("com.cosmic.app_library"), Default::default());
|
let app = gtk4::Application::new(Some("com.cosmic.app_library"), Default::default());
|
||||||
|
|
@ -40,7 +41,9 @@ fn load_css() {
|
||||||
|
|
||||||
fn build_ui(app: >k4::Application) {
|
fn build_ui(app: >k4::Application) {
|
||||||
// Create a new custom window and show it
|
// Create a new custom window and show it
|
||||||
let window = AppLibraryWindow::new(app);
|
let display = Display::default().unwrap();
|
||||||
|
window::create(app, display.monitors().item(0).unwrap().downcast().unwrap());
|
||||||
|
// let window = AppLibraryWindow::new(app);
|
||||||
|
|
||||||
window.show();
|
// window.show();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,13 @@
|
||||||
use glib::signal::Inhibit;
|
use crate::window_inner::AppLibraryWindowInner;
|
||||||
use gtk4::glib;
|
use gtk4::glib;
|
||||||
use gtk4::subclass::prelude::*;
|
use gtk4::subclass::prelude::*;
|
||||||
use gtk4::SearchEntry;
|
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
|
|
||||||
use crate::app_grid::AppGrid;
|
|
||||||
use crate::group_grid::GroupGrid;
|
|
||||||
|
|
||||||
// Object holding the state
|
// Object holding the state
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
||||||
pub struct AppLibraryWindow {
|
pub struct AppLibraryWindow {
|
||||||
pub entry: OnceCell<SearchEntry>,
|
pub(super) inner: OnceCell<AppLibraryWindowInner>,
|
||||||
pub app_grid: OnceCell<AppGrid>,
|
|
||||||
pub group_grid: OnceCell<GroupGrid>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The central trait for subclassing a GObject
|
// The central trait for subclassing a GObject
|
||||||
|
|
@ -31,14 +26,7 @@ impl ObjectImpl for AppLibraryWindow {}
|
||||||
impl WidgetImpl for AppLibraryWindow {}
|
impl WidgetImpl for AppLibraryWindow {}
|
||||||
|
|
||||||
// Trait shared by all windows
|
// Trait shared by all windows
|
||||||
impl WindowImpl for AppLibraryWindow {
|
impl WindowImpl for AppLibraryWindow {}
|
||||||
fn close_request(&self, window: &Self::Type) -> Inhibit {
|
|
||||||
let imp = AppLibraryWindow::from_instance(window);
|
|
||||||
imp.group_grid.get().unwrap().store_data();
|
|
||||||
// Pass close request on to the parent
|
|
||||||
self.parent_close_request(window)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trait shared by all application
|
// Trait shared by all application
|
||||||
impl ApplicationWindowImpl for AppLibraryWindow {}
|
impl ApplicationWindowImpl for AppLibraryWindow {}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,91 @@
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::app_grid::AppGrid;
|
use crate::app_grid::AppGrid;
|
||||||
use crate::group_grid::GroupGrid;
|
use crate::group_grid::GroupGrid;
|
||||||
|
use crate::window_inner::AppLibraryWindowInner;
|
||||||
use cascade::cascade;
|
use cascade::cascade;
|
||||||
|
use gdk4::subclass::prelude::ObjectSubclassExt;
|
||||||
use gdk4_x11::X11Display;
|
use gdk4_x11::X11Display;
|
||||||
use glib::Object;
|
use glib::Object;
|
||||||
use gtk4::prelude::*;
|
use gtk4::prelude::*;
|
||||||
use gtk4::subclass::prelude::*;
|
|
||||||
use gtk4::Align;
|
use gtk4::Align;
|
||||||
use gtk4::Application;
|
use gtk4::Application;
|
||||||
|
use gtk4::ApplicationWindow;
|
||||||
use gtk4::Box;
|
use gtk4::Box;
|
||||||
use gtk4::CustomFilter;
|
use gtk4::CustomFilter;
|
||||||
|
use gtk4::Inhibit;
|
||||||
use gtk4::Orientation;
|
use gtk4::Orientation;
|
||||||
use gtk4::SearchEntry;
|
use gtk4::SearchEntry;
|
||||||
use gtk4::Separator;
|
use gtk4::Separator;
|
||||||
use gtk4::{gio, glib};
|
use gtk4::{gdk, gio, glib};
|
||||||
use libcosmic::x;
|
use libcosmic::x;
|
||||||
|
use once_cell::sync::OnceCell;
|
||||||
|
|
||||||
|
pub fn create(app: &Application, monitor: gdk::Monitor) {
|
||||||
|
//quit shortcut
|
||||||
|
app.set_accels_for_action("win.quit", &["<primary>W", "Escape"]);
|
||||||
|
|
||||||
|
#[cfg(feature = "layer-shell")]
|
||||||
|
if let Some(wayland_monitor) = monitor.downcast_ref() {
|
||||||
|
wayland_create(&app, wayland_monitor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cascade! {
|
||||||
|
AppLibraryWindow::new(&app);
|
||||||
|
..show();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup_shortcuts(window: &ApplicationWindow) {
|
||||||
|
let action_quit = gio::SimpleAction::new("quit", None);
|
||||||
|
action_quit.connect_activate(glib::clone!(@weak window => move |_, _| {
|
||||||
|
window.close();
|
||||||
|
}));
|
||||||
|
window.add_action(&action_quit);
|
||||||
|
window.connect_is_active_notify(move |win| {
|
||||||
|
let app = win
|
||||||
|
.application()
|
||||||
|
.expect("could not get application from window");
|
||||||
|
let active_window = app
|
||||||
|
.active_window()
|
||||||
|
.expect("no active window available, closing app library.");
|
||||||
|
dbg!(&active_window);
|
||||||
|
if win == &active_window && !win.is_active() {
|
||||||
|
win.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "layer-shell")]
|
||||||
|
fn wayland_create(app: &Application, monitor: &gdk4_wayland::WaylandMonitor) {
|
||||||
|
use libcosmic::wayland::{Anchor, Layer, LayerShellWindow};
|
||||||
|
|
||||||
|
let window = cascade! {
|
||||||
|
LayerShellWindow::new(Some(monitor), Layer::Top, "");
|
||||||
|
..set_width_request(1200);
|
||||||
|
..set_height_request(800);
|
||||||
|
// ..set_title(Some("Cosmic App Library"));
|
||||||
|
// ..set_decorated(false);
|
||||||
|
..add_css_class("root_window");
|
||||||
|
..set_anchor(Anchor::empty());
|
||||||
|
..show();
|
||||||
|
};
|
||||||
|
|
||||||
|
let app_library = AppLibraryWindowInner::new();
|
||||||
|
window.set_child(Some(&app_library));
|
||||||
|
dbg!(&window);
|
||||||
|
window.show();
|
||||||
|
// window.connect_close_request(
|
||||||
|
// glib::clone!(@strong app_library => @default-return Inhibit(false), move |_| {
|
||||||
|
// app_library.group_grid().unwrap().store_data();
|
||||||
|
// Inhibit(false)
|
||||||
|
// }),
|
||||||
|
// );
|
||||||
|
// setup_shortcuts(window.clone().upcast::<gtk4::ApplicationWindow>());
|
||||||
|
// XXX
|
||||||
|
unsafe { window.set_data("cosmic-app-hold", app.hold()) };
|
||||||
|
}
|
||||||
|
|
||||||
mod imp;
|
mod imp;
|
||||||
|
|
||||||
|
|
@ -26,12 +98,6 @@ glib::wrapper! {
|
||||||
|
|
||||||
impl AppLibraryWindow {
|
impl AppLibraryWindow {
|
||||||
pub fn new(app: &Application) -> Self {
|
pub fn new(app: &Application) -> Self {
|
||||||
//quit shortcut
|
|
||||||
app.set_accels_for_action("win.quit", &["<primary>W", "Escape"]);
|
|
||||||
//launch shortcuts
|
|
||||||
for i in 1..10 {
|
|
||||||
app.set_accels_for_action(&format!("win.launch{}", i), &[&format!("<primary>{}", i)]);
|
|
||||||
}
|
|
||||||
let self_: Self =
|
let self_: Self =
|
||||||
Object::new(&[("application", app)]).expect("Failed to create `AppLibraryWindow`.");
|
Object::new(&[("application", app)]).expect("Failed to create `AppLibraryWindow`.");
|
||||||
let imp = imp::AppLibraryWindow::from_instance(&self_);
|
let imp = imp::AppLibraryWindow::from_instance(&self_);
|
||||||
|
|
@ -43,42 +109,46 @@ impl AppLibraryWindow {
|
||||||
..set_decorated(false);
|
..set_decorated(false);
|
||||||
..add_css_class("root_window");
|
..add_css_class("root_window");
|
||||||
};
|
};
|
||||||
|
let app_library = AppLibraryWindowInner::new();
|
||||||
let app_library = cascade! {
|
|
||||||
Box::new(Orientation::Vertical, 0);
|
|
||||||
..add_css_class("app_library_container");
|
|
||||||
};
|
|
||||||
self_.set_child(Some(&app_library));
|
self_.set_child(Some(&app_library));
|
||||||
|
imp.inner.set(app_library).unwrap();
|
||||||
|
// let app_library = cascade! {
|
||||||
|
// Box::new(Orientation::Vertical, 0);
|
||||||
|
// ..add_css_class("app_library_container");
|
||||||
|
// };
|
||||||
|
// self_.set_child(Some(&app_library));
|
||||||
|
|
||||||
let entry = cascade! {
|
// let entry = cascade! {
|
||||||
SearchEntry::new();
|
// SearchEntry::new();
|
||||||
..set_width_request(300);
|
// ..set_width_request(300);
|
||||||
..set_halign(Align::Center);
|
// ..set_halign(Align::Center);
|
||||||
..set_margin_top(12);
|
// ..set_margin_top(12);
|
||||||
..set_margin_bottom(12);
|
// ..set_margin_bottom(12);
|
||||||
..set_placeholder_text(Some(" Type to search"));
|
// ..set_placeholder_text(Some(" Type to search"));
|
||||||
};
|
// };
|
||||||
app_library.append(&entry);
|
// app_library.append(&entry);
|
||||||
|
|
||||||
let app_grid = AppGrid::new();
|
// let app_grid = AppGrid::new();
|
||||||
app_library.append(&app_grid);
|
// app_library.append(&app_grid);
|
||||||
|
|
||||||
let separator = cascade! {
|
// let separator = cascade! {
|
||||||
Separator::new(Orientation::Horizontal);
|
// Separator::new(Orientation::Horizontal);
|
||||||
..set_hexpand(true);
|
// ..set_hexpand(true);
|
||||||
..set_margin_bottom(12);
|
// ..set_margin_bottom(12);
|
||||||
..set_margin_top(12);
|
// ..set_margin_top(12);
|
||||||
};
|
// };
|
||||||
app_library.append(&separator);
|
// app_library.append(&separator);
|
||||||
|
|
||||||
let group_grid = GroupGrid::new();
|
// let group_grid = GroupGrid::new();
|
||||||
app_library.append(&group_grid);
|
// app_library.append(&group_grid);
|
||||||
|
|
||||||
imp.entry.set(entry).unwrap();
|
// imp.entry.set(entry).unwrap();
|
||||||
imp.app_grid.set(app_grid).unwrap();
|
// imp.app_grid.set(app_grid).unwrap();
|
||||||
imp.group_grid.set(group_grid).unwrap();
|
// imp.group_grid.set(group_grid).unwrap();
|
||||||
|
|
||||||
Self::setup_callbacks(&self_);
|
Self::setup_callbacks(&self_);
|
||||||
|
setup_shortcuts(&self_.clone().upcast::<gtk4::ApplicationWindow>());
|
||||||
|
|
||||||
self_
|
self_
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,58 +156,6 @@ impl AppLibraryWindow {
|
||||||
// Get state
|
// Get state
|
||||||
let imp = imp::AppLibraryWindow::from_instance(self);
|
let imp = imp::AppLibraryWindow::from_instance(self);
|
||||||
let window = self.clone().upcast::<gtk4::Window>();
|
let window = self.clone().upcast::<gtk4::Window>();
|
||||||
let app_grid = &imp.app_grid.get().unwrap();
|
|
||||||
let group_grid = &imp.group_grid.get().unwrap();
|
|
||||||
|
|
||||||
let entry = &imp.entry.get().unwrap();
|
|
||||||
|
|
||||||
group_grid.connect_local(
|
|
||||||
"group-changed",
|
|
||||||
false,
|
|
||||||
glib::clone!(@weak app_grid => @default-return None, move |args| {
|
|
||||||
let new_filter = args[1].get::<CustomFilter>().unwrap();
|
|
||||||
app_grid.set_group_filter(&new_filter);
|
|
||||||
None
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
entry.connect_changed(
|
|
||||||
glib::clone!(@weak app_grid => move |search: >k4::SearchEntry| {
|
|
||||||
let search_text = search.text().to_string().to_lowercase();
|
|
||||||
let new_filter: gtk4::CustomFilter = gtk4::CustomFilter::new(move |obj| {
|
|
||||||
let search_res = obj.downcast_ref::<gio::DesktopAppInfo>()
|
|
||||||
.expect("The Object needs to be of type AppInfo");
|
|
||||||
search_res.name().to_string().to_lowercase().contains(&search_text)
|
|
||||||
});
|
|
||||||
let search_text = search.text().to_string().to_lowercase();
|
|
||||||
let new_sorter: gtk4::CustomSorter = gtk4::CustomSorter::new(move |obj1, obj2| {
|
|
||||||
let app_info1 = obj1.downcast_ref::<gio::DesktopAppInfo>().unwrap();
|
|
||||||
let app_info2 = obj2.downcast_ref::<gio::DesktopAppInfo>().unwrap();
|
|
||||||
if search_text == "" {
|
|
||||||
return app_info1
|
|
||||||
.name()
|
|
||||||
.to_lowercase()
|
|
||||||
.cmp(&app_info2.name().to_lowercase())
|
|
||||||
.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
let i_1 = app_info1.name().to_lowercase().find(&search_text);
|
|
||||||
let i_2 = app_info2.name().to_lowercase().find(&search_text);
|
|
||||||
match (i_1, i_2) {
|
|
||||||
(Some(i_1), Some(i_2)) => i_1.cmp(&i_2).into(),
|
|
||||||
(Some(_), None) => std::cmp::Ordering::Less.into(),
|
|
||||||
(None, Some(_)) => std::cmp::Ordering::Greater.into(),
|
|
||||||
_ => app_info1
|
|
||||||
.name()
|
|
||||||
.to_lowercase()
|
|
||||||
.cmp(&app_info2.name().to_lowercase())
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
app_grid.set_search_filter(&new_filter);
|
|
||||||
app_grid.set_app_sorter(&new_sorter);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
window.connect_realize(move |window| {
|
window.connect_realize(move |window| {
|
||||||
if let Some((display, surface)) = x::get_window_x11(window) {
|
if let Some((display, surface)) = x::get_window_x11(window) {
|
||||||
|
|
@ -192,23 +210,5 @@ impl AppLibraryWindow {
|
||||||
println!("failed to get X11 window");
|
println!("failed to get X11 window");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let action_quit = gio::SimpleAction::new("quit", None);
|
|
||||||
action_quit.connect_activate(glib::clone!(@weak window => move |_, _| {
|
|
||||||
window.close();
|
|
||||||
}));
|
|
||||||
self.add_action(&action_quit);
|
|
||||||
window.connect_is_active_notify(move |win| {
|
|
||||||
let app = win
|
|
||||||
.application()
|
|
||||||
.expect("could not get application from window");
|
|
||||||
let active_window = app
|
|
||||||
.active_window()
|
|
||||||
.expect("no active window available, closing app library.");
|
|
||||||
dbg!(&active_window);
|
|
||||||
if win == &active_window && !win.is_active() {
|
|
||||||
win.close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,17 +77,15 @@ impl AppLibraryWindowInner {
|
||||||
|
|
||||||
let entry = &imp.entry.get().unwrap();
|
let entry = &imp.entry.get().unwrap();
|
||||||
|
|
||||||
group_grid
|
group_grid.connect_local(
|
||||||
.connect_local(
|
"group-changed",
|
||||||
"group-changed",
|
false,
|
||||||
false,
|
glib::clone!(@weak app_grid => @default-return None, move |args| {
|
||||||
glib::clone!(@weak app_grid => @default-return None, move |args| {
|
let new_filter = args[1].get::<CustomFilter>().unwrap();
|
||||||
let new_filter = args[1].get::<CustomFilter>().unwrap();
|
app_grid.set_group_filter(&new_filter);
|
||||||
app_grid.set_group_filter(&new_filter);
|
None
|
||||||
None
|
}),
|
||||||
}),
|
);
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
entry.connect_changed(
|
entry.connect_changed(
|
||||||
glib::clone!(@weak app_grid => move |search: >k4::SearchEntry| {
|
glib::clone!(@weak app_grid => move |search: >k4::SearchEntry| {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use gdk4_wayland::prelude::*;
|
||||||
use gtk4::{
|
use gtk4::{
|
||||||
cairo, gdk,
|
cairo, gdk,
|
||||||
glib::{self, clone, subclass::prelude::*, translate::*},
|
glib::{self, clone, subclass::prelude::*, translate::*},
|
||||||
gsk::{self, traits::RendererExt},
|
gsk::{self, traits::GskRendererExt},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
subclass::prelude::*,
|
subclass::prelude::*,
|
||||||
};
|
};
|
||||||
|
|
@ -497,7 +497,7 @@ pub struct GtkRootInterface {
|
||||||
|
|
||||||
unsafe extern "C" fn get_surface(native: *mut gtk4::ffi::GtkNative) -> *mut gdk::ffi::GdkSurface {
|
unsafe extern "C" fn get_surface(native: *mut gtk4::ffi::GtkNative) -> *mut gdk::ffi::GdkSurface {
|
||||||
let instance = &*(native as *mut <LayerShellWindowInner as ObjectSubclass>::Instance);
|
let instance = &*(native as *mut <LayerShellWindowInner as ObjectSubclass>::Instance);
|
||||||
let imp = instance.impl_();
|
let imp = instance.imp();
|
||||||
imp.surface.borrow().as_ref().map_or(ptr::null_mut(), |x| {
|
imp.surface.borrow().as_ref().map_or(ptr::null_mut(), |x| {
|
||||||
x.upcast_ref::<gdk::Surface>().to_glib_none().0
|
x.upcast_ref::<gdk::Surface>().to_glib_none().0
|
||||||
})
|
})
|
||||||
|
|
@ -505,7 +505,7 @@ unsafe extern "C" fn get_surface(native: *mut gtk4::ffi::GtkNative) -> *mut gdk:
|
||||||
|
|
||||||
unsafe extern "C" fn get_renderer(native: *mut gtk4::ffi::GtkNative) -> *mut gsk::ffi::GskRenderer {
|
unsafe extern "C" fn get_renderer(native: *mut gtk4::ffi::GtkNative) -> *mut gsk::ffi::GskRenderer {
|
||||||
let instance = &*(native as *mut <LayerShellWindowInner as ObjectSubclass>::Instance);
|
let instance = &*(native as *mut <LayerShellWindowInner as ObjectSubclass>::Instance);
|
||||||
let imp = instance.impl_();
|
let imp = instance.imp();
|
||||||
imp.renderer
|
imp.renderer
|
||||||
.borrow()
|
.borrow()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
@ -530,7 +530,7 @@ unsafe extern "C" fn layout(native: *mut gtk4::ffi::GtkNative, width: c_int, hei
|
||||||
|
|
||||||
unsafe extern "C" fn get_display(root: *mut gtk4::ffi::GtkRoot) -> *mut gdk::ffi::GdkDisplay {
|
unsafe extern "C" fn get_display(root: *mut gtk4::ffi::GtkRoot) -> *mut gdk::ffi::GdkDisplay {
|
||||||
let instance = &*(root as *mut <LayerShellWindowInner as ObjectSubclass>::Instance);
|
let instance = &*(root as *mut <LayerShellWindowInner as ObjectSubclass>::Instance);
|
||||||
let imp = instance.impl_();
|
let imp = instance.imp();
|
||||||
imp.display.upcast_ref::<gdk::Display>().to_glib_none().0
|
imp.display.upcast_ref::<gdk::Display>().to_glib_none().0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -538,13 +538,13 @@ unsafe extern "C" fn get_constraint_solver(
|
||||||
root: *mut gtk4::ffi::GtkRoot,
|
root: *mut gtk4::ffi::GtkRoot,
|
||||||
) -> *mut GtkConstraintSolver {
|
) -> *mut GtkConstraintSolver {
|
||||||
let instance = &*(root as *mut <LayerShellWindowInner as ObjectSubclass>::Instance);
|
let instance = &*(root as *mut <LayerShellWindowInner as ObjectSubclass>::Instance);
|
||||||
let imp = instance.impl_();
|
let imp = instance.imp();
|
||||||
imp.constraint_solver.to_glib_none().0
|
imp.constraint_solver.to_glib_none().0
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn get_focus(root: *mut gtk4::ffi::GtkRoot) -> *mut gtk4::ffi::GtkWidget {
|
unsafe extern "C" fn get_focus(root: *mut gtk4::ffi::GtkRoot) -> *mut gtk4::ffi::GtkWidget {
|
||||||
let instance = &*(root as *mut <LayerShellWindowInner as ObjectSubclass>::Instance);
|
let instance = &*(root as *mut <LayerShellWindowInner as ObjectSubclass>::Instance);
|
||||||
let imp = instance.impl_();
|
let imp = instance.imp();
|
||||||
imp.focus_widget
|
imp.focus_widget
|
||||||
.borrow()
|
.borrow()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
@ -554,7 +554,7 @@ unsafe extern "C" fn get_focus(root: *mut gtk4::ffi::GtkRoot) -> *mut gtk4::ffi:
|
||||||
unsafe extern "C" fn set_focus(root: *mut gtk4::ffi::GtkRoot, focus: *mut gtk4::ffi::GtkWidget) {
|
unsafe extern "C" fn set_focus(root: *mut gtk4::ffi::GtkRoot, focus: *mut gtk4::ffi::GtkWidget) {
|
||||||
// TODO: `GtkWindow` does more here
|
// TODO: `GtkWindow` does more here
|
||||||
let instance = &*(root as *mut <LayerShellWindowInner as ObjectSubclass>::Instance);
|
let instance = &*(root as *mut <LayerShellWindowInner as ObjectSubclass>::Instance);
|
||||||
let imp = instance.impl_();
|
let imp = instance.imp();
|
||||||
*imp.focus_widget.borrow_mut() = if focus.is_null() {
|
*imp.focus_widget.borrow_mut() = if focus.is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue