constantly update active apps on dock
This commit is contained in:
parent
6a479899ad
commit
ad6f147546
4 changed files with 50 additions and 46 deletions
|
|
@ -23,8 +23,9 @@ once_cell = "1.8.0"
|
||||||
xdg = "2.4.0"
|
xdg = "2.4.0"
|
||||||
serde = "1.0.130"
|
serde = "1.0.130"
|
||||||
x11rb = "0.9.0"
|
x11rb = "0.9.0"
|
||||||
|
async-io = "1.6.0"
|
||||||
|
|
||||||
[dependencies.gtk4]
|
[dependencies.gtk4]
|
||||||
package = "gtk4"
|
package = "gtk4"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
features = ["v4_4"]
|
features = ["v4_4"]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::utils::BoxedSearchResults;
|
use crate::utils::BoxedSearchResults;
|
||||||
use gio::DesktopAppInfo;
|
use gio::DesktopAppInfo;
|
||||||
use glib::{FromVariant, ParamFlags, ParamSpec, ToVariant, Value, Variant, VariantTy};
|
use glib::{ParamFlags, ParamSpec, Value};
|
||||||
use gtk4::glib;
|
use gtk4::glib;
|
||||||
use gtk4::prelude::*;
|
use gtk4::prelude::*;
|
||||||
use gtk4::subclass::prelude::*;
|
use gtk4::subclass::prelude::*;
|
||||||
|
|
|
||||||
|
|
@ -16,35 +16,37 @@ impl DockObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_search_results(results: BoxedSearchResults) -> Self {
|
pub fn from_search_results(results: BoxedSearchResults) -> Self {
|
||||||
let appinfo = xdg::BaseDirectories::new()
|
let appinfo = if let Some(first) = results.0.iter().next() {
|
||||||
.expect("could not access XDG Base directory")
|
xdg::BaseDirectories::new()
|
||||||
.get_data_dirs()
|
.expect("could not access XDG Base directory")
|
||||||
.iter_mut()
|
.get_data_dirs()
|
||||||
.filter_map(|xdg_data_path| {
|
.iter_mut()
|
||||||
let defaults = ["Firefox Web Browser", "Files", "Terminal", "Pop!_Shop"];
|
.filter_map(|xdg_data_path| {
|
||||||
xdg_data_path.push("applications");
|
xdg_data_path.push("applications");
|
||||||
dbg!(&xdg_data_path);
|
dbg!(&xdg_data_path);
|
||||||
std::fs::read_dir(xdg_data_path).ok()
|
std::fs::read_dir(xdg_data_path).ok()
|
||||||
})
|
})
|
||||||
.flatten()
|
.flatten()
|
||||||
.filter_map(|dir_entry| {
|
.filter_map(|dir_entry| {
|
||||||
let defaults = ["Firefox Web Browser", "Files", "Terminal", "Pop!_Shop"];
|
if let Ok(dir_entry) = dir_entry {
|
||||||
if let Ok(dir_entry) = dir_entry {
|
if let Some(path) = dir_entry.path().file_name() {
|
||||||
if let Some(path) = dir_entry.path().file_name() {
|
if let Some(path) = path.to_str() {
|
||||||
if let Some(path) = path.to_str() {
|
if let Some(app_info) = gio::DesktopAppInfo::new(path) {
|
||||||
if let Some(app_info) = gio::DesktopAppInfo::new(path) {
|
if app_info.should_show()
|
||||||
if app_info.should_show()
|
&& first.description.as_str() == app_info.name().as_str()
|
||||||
&& defaults.contains(&app_info.name().as_str())
|
{
|
||||||
{
|
return Some(DockObject::new(app_info));
|
||||||
return Some(DockObject::new(app_info));
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
None
|
||||||
None
|
})
|
||||||
})
|
.next()
|
||||||
.next();
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
Object::new(&[("appinfo", &appinfo), ("active", &results)])
|
Object::new(&[("appinfo", &appinfo), ("active", &results)])
|
||||||
.expect("Failed to create `DockObject`.")
|
.expect("Failed to create `DockObject`.")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,23 +4,23 @@ mod dock_object;
|
||||||
mod utils;
|
mod utils;
|
||||||
mod window;
|
mod window;
|
||||||
|
|
||||||
|
use async_io::Timer;
|
||||||
use gdk4::Display;
|
use gdk4::Display;
|
||||||
use gio::DesktopAppInfo;
|
use gio::DesktopAppInfo;
|
||||||
|
use gtk::gio;
|
||||||
|
use gtk::glib;
|
||||||
|
use gtk::prelude::*;
|
||||||
use gtk::Application;
|
use gtk::Application;
|
||||||
use gtk4 as gtk;
|
use gtk4 as gtk;
|
||||||
use gtk4::CssProvider;
|
use gtk4::CssProvider;
|
||||||
use gtk4::StyleContext;
|
use gtk4::StyleContext;
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
|
|
||||||
use gtk::gio;
|
|
||||||
use gtk::glib;
|
|
||||||
use gtk::prelude::*;
|
|
||||||
use pop_launcher_service::IpcClient;
|
use pop_launcher_service::IpcClient;
|
||||||
use postage::mpsc::Sender;
|
use postage::mpsc::Sender;
|
||||||
use postage::prelude::*;
|
use postage::prelude::*;
|
||||||
|
use std::time::Duration;
|
||||||
use x11rb::rust_connection::RustConnection;
|
use x11rb::rust_connection::RustConnection;
|
||||||
|
|
||||||
use self::application_object::ApplicationObject;
|
|
||||||
use self::window::Window;
|
use self::window::Window;
|
||||||
|
|
||||||
const NUM_LAUNCHER_ITEMS: u8 = 10;
|
const NUM_LAUNCHER_ITEMS: u8 = 10;
|
||||||
|
|
@ -33,15 +33,24 @@ pub enum Event {
|
||||||
Activate(u32),
|
Activate(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn_launcher(mut tx: Sender<Event>) -> IpcClient {
|
fn spawn_launcher(tx: Sender<Event>) -> IpcClient {
|
||||||
let (launcher, responses) =
|
let (launcher, responses) =
|
||||||
pop_launcher_service::IpcClient::new().expect("failed to connect to launcher service");
|
pop_launcher_service::IpcClient::new().expect("failed to connect to launcher service");
|
||||||
|
|
||||||
|
let mut sender = tx.clone();
|
||||||
glib::MainContext::default().spawn_local(async move {
|
glib::MainContext::default().spawn_local(async move {
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
futures::pin_mut!(responses);
|
futures::pin_mut!(responses);
|
||||||
while let Some(event) = responses.next().await {
|
while let Some(event) = responses.next().await {
|
||||||
let _ = tx.send(Event::Response(event)).await;
|
let _ = sender.send(Event::Response(event)).await;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut sender = tx.clone();
|
||||||
|
glib::MainContext::default().spawn_local(async move {
|
||||||
|
loop {
|
||||||
|
Timer::after(Duration::from_secs(1)).await;
|
||||||
|
let _ = sender.send(Event::Search(String::new())).await;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -110,19 +119,11 @@ fn main() {
|
||||||
Event::Activate(index) => {
|
Event::Activate(index) => {
|
||||||
let _ = launcher.send(pop_launcher::Request::Activate(index)).await;
|
let _ = launcher.send(pop_launcher::Request::Activate(index)).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::Response(event) => {
|
Event::Response(event) => {
|
||||||
if let pop_launcher::Response::Update(results) = event {
|
if let pop_launcher::Response::Update(_results) = event {
|
||||||
let model = window.saved_app_model();
|
println!("updating active apps")
|
||||||
let model_len = model.n_items();
|
}
|
||||||
dbg!(&results);
|
else if let pop_launcher::Response::DesktopEntry {
|
||||||
let new_results: Vec<glib::Object> = results
|
|
||||||
[0..std::cmp::min(results.len(), NUM_LAUNCHER_ITEMS.into())]
|
|
||||||
.iter()
|
|
||||||
.map(|result| ApplicationObject::new(result).upcast())
|
|
||||||
.collect();
|
|
||||||
model.splice(0, model_len, &new_results[..]);
|
|
||||||
} else if let pop_launcher::Response::DesktopEntry {
|
|
||||||
path,
|
path,
|
||||||
gpu_preference: _gpu_preference, // TODO use GPU preference when launching app
|
gpu_preference: _gpu_preference, // TODO use GPU preference when launching app
|
||||||
} = event
|
} = event
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue