mirror of
https://github.com/project-gauntlet/gauntlet.git
synced 2025-12-23 10:35:53 +00:00
Main application as service. Window hidden by default, shown using dbus
This commit is contained in:
parent
97d154f8b4
commit
7b93ed6d49
5 changed files with 112 additions and 18 deletions
17
src/agent.rs
17
src/agent.rs
|
|
@ -1,3 +1,18 @@
|
|||
pub fn run_agent() {
|
||||
use zbus::{blocking, dbus_proxy, Result};
|
||||
|
||||
#[dbus_proxy(
|
||||
interface = "org.placeholdername.PlaceHolderName",
|
||||
default_service = "org.placeholdername.PlaceHolderName",
|
||||
default_path = "/org/placeholdername/PlaceHolderName"
|
||||
)]
|
||||
trait DbusInterface {
|
||||
async fn open_window(&self) -> Result<()>;
|
||||
}
|
||||
|
||||
pub fn run_agent() {
|
||||
let connection = blocking::Connection::session().unwrap();
|
||||
|
||||
let proxy = DbusInterfaceProxyBlocking::new(&connection).unwrap();
|
||||
|
||||
proxy.open_window().unwrap();
|
||||
}
|
||||
|
|
|
|||
19
src/cli.rs
19
src/cli.rs
|
|
@ -2,15 +2,22 @@ use clap::Parser;
|
|||
use crate::agent::run_agent;
|
||||
use crate::server::run_server;
|
||||
|
||||
#[derive(clap::Parser)]
|
||||
enum Cli {
|
||||
Server,
|
||||
|
||||
#[derive(Debug, clap::Parser)]
|
||||
struct Cli {
|
||||
#[command(subcommand)]
|
||||
command: Option<Commands>,
|
||||
}
|
||||
|
||||
#[derive(Debug, clap::Subcommand)]
|
||||
enum Commands {
|
||||
OpenWindow,
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
match Cli::parse() {
|
||||
Cli::Server => run_server(),
|
||||
Cli::OpenWindow => run_agent()
|
||||
let cli = Cli::parse();
|
||||
match &cli.command {
|
||||
None => run_server(false),
|
||||
Some(Commands::OpenWindow) => run_agent()
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,11 @@ use std::rc::Rc;
|
|||
|
||||
use gtk::glib;
|
||||
use gtk::prelude::*;
|
||||
use tokio::sync::mpsc::UnboundedReceiver;
|
||||
|
||||
use crate::gtk::{PluginContainerContainer, PluginEventSenderContainer, PluginUiContext};
|
||||
use crate::react_side::{PropertyValue, UiEvent, UiEventName, UiRequest, UiRequestData, UiResponseData, UiWidget, UiWidgetId};
|
||||
use crate::server::ServerEvent;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GtkContext {
|
||||
|
|
@ -60,6 +62,21 @@ pub(crate) fn start_request_receiver_loop(
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn start_server_event_receiver_loop(
|
||||
window: gtk::Window,
|
||||
mut server_event_receiver: UnboundedReceiver<ServerEvent>,
|
||||
) {
|
||||
glib::MainContext::default().spawn_local(async move {
|
||||
while let Some(event) = server_event_receiver.recv().await {
|
||||
match event {
|
||||
ServerEvent::OpenWindow => {
|
||||
window.set_visible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async fn run_request_receiver_loop(
|
||||
ui_context: PluginUiContext,
|
||||
container_container: PluginContainerContainer,
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ impl SimpleComponent for AppModel {
|
|||
},
|
||||
connect_is_active_notify => move |window| {
|
||||
if !window.is_active() {
|
||||
// window.application().unwrap().quit()
|
||||
window.set_visible(false);
|
||||
}
|
||||
},
|
||||
match model.state {
|
||||
|
|
@ -185,7 +185,7 @@ impl SimpleComponent for AppModel {
|
|||
AppMsg::CloseCurrentView => {
|
||||
match &self.state {
|
||||
AppState::SearchView => {
|
||||
self.window.application().unwrap().quit();
|
||||
self.window.set_visible(false);
|
||||
}
|
||||
AppState::PluginView { plugin_id, .. } => {
|
||||
self.event_senders_container.send_event(&plugin_id, UiEvent::ViewDestroyed);
|
||||
|
|
|
|||
|
|
@ -1,29 +1,44 @@
|
|||
use std::cell::Cell;
|
||||
use std::collections::HashMap;
|
||||
use std::process::exit;
|
||||
use std::thread;
|
||||
|
||||
use gtk::prelude::{ApplicationExt, ApplicationExtManual, Cast, GtkApplicationExt, WidgetExt};
|
||||
use relm4::{Component, ComponentController};
|
||||
use tokio::runtime::Runtime;
|
||||
use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender};
|
||||
use tokio::task::LocalSet;
|
||||
|
||||
use crate::gtk::{PluginContainerContainer, PluginEventSenderContainer, PluginUiContext, PluginUiData};
|
||||
use crate::gtk::gtk_side::start_request_receiver_loop;
|
||||
use crate::gtk::gtk_side::{start_request_receiver_loop, start_server_event_receiver_loop};
|
||||
use crate::gtk::gui::{AppInput, AppModel};
|
||||
use crate::plugins::PluginManager;
|
||||
use crate::react_side::{PluginReactData, run_react};
|
||||
use crate::search::{SearchIndex, SearchItem};
|
||||
|
||||
struct DbusInterface;
|
||||
pub enum ServerEvent {
|
||||
OpenWindow
|
||||
}
|
||||
|
||||
struct DbusInterface {
|
||||
server_event_sender: UnboundedSender<ServerEvent>,
|
||||
}
|
||||
|
||||
#[zbus::dbus_interface(name = "org.placeholdername.PlaceHolderName")]
|
||||
impl DbusInterface {
|
||||
fn open_window(&mut self) {
|
||||
self.server_event_sender.send(ServerEvent::OpenWindow).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_server() {
|
||||
pub fn run_server(dev: bool) {
|
||||
let runtime = tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let (server_event_sender, server_event_receiver) = tokio::sync::mpsc::unbounded_channel::<ServerEvent>();
|
||||
|
||||
let mut plugin_manager = PluginManager::create();
|
||||
let mut search_index = SearchIndex::create_index().unwrap();
|
||||
|
||||
|
|
@ -48,7 +63,7 @@ pub fn run_server() {
|
|||
let (react_contexts, ui_contexts) = plugin_manager.create_all_contexts();
|
||||
|
||||
let zbus_connection: Result<zbus::Connection, zbus::Error> = runtime.block_on(async {
|
||||
let interface = DbusInterface;
|
||||
let interface = DbusInterface { server_event_sender };
|
||||
|
||||
let conn = zbus::ConnectionBuilder::session()?
|
||||
.name("org.placeholdername.PlaceHolderName")?
|
||||
|
|
@ -67,12 +82,18 @@ pub fn run_server() {
|
|||
exit(1)
|
||||
});
|
||||
|
||||
spawn_gtk_thread(ui_contexts, plugin_manager, search_index);
|
||||
spawn_gtk_thread(dev, ui_contexts, plugin_manager, search_index, server_event_receiver);
|
||||
|
||||
run_react_loops(&runtime, react_contexts);
|
||||
}
|
||||
|
||||
fn spawn_gtk_thread(ui_data: Vec<PluginUiData>, plugin_manager: PluginManager, search_index: SearchIndex) {
|
||||
fn spawn_gtk_thread(
|
||||
dev: bool,
|
||||
ui_data: Vec<PluginUiData>,
|
||||
plugin_manager: PluginManager,
|
||||
search_index: SearchIndex,
|
||||
server_event_receiver: UnboundedReceiver<ServerEvent>,
|
||||
) {
|
||||
let handle = move || {
|
||||
let (contexts, event_senders): (Vec<_>, Vec<_>) = ui_data.into_iter()
|
||||
.map(|ui_data| {
|
||||
|
|
@ -92,7 +113,11 @@ fn spawn_gtk_thread(ui_data: Vec<PluginUiData>, plugin_manager: PluginManager, s
|
|||
let container_container = PluginContainerContainer::new();
|
||||
let event_senders_container = PluginEventSenderContainer::new(event_senders);
|
||||
|
||||
start_request_receiver_loop(ui_contexts, container_container.clone(), event_senders_container.clone());
|
||||
start_request_receiver_loop(
|
||||
ui_contexts,
|
||||
container_container.clone(),
|
||||
event_senders_container.clone(),
|
||||
);
|
||||
|
||||
let input = AppInput {
|
||||
search: search_index.create_handle(),
|
||||
|
|
@ -101,8 +126,38 @@ fn spawn_gtk_thread(ui_data: Vec<PluginUiData>, plugin_manager: PluginManager, s
|
|||
event_senders_container,
|
||||
};
|
||||
|
||||
relm4::RelmApp::from_app(relm4::gtk::Application::builder().build())
|
||||
.run::<AppModel>(input);
|
||||
let application = gtk::Application::builder()
|
||||
.build();
|
||||
|
||||
let _ = application.hold();
|
||||
|
||||
let payload = Cell::new(Some((input, server_event_receiver)));
|
||||
|
||||
application.connect_activate(move |application| {
|
||||
if let Some((input, server_event_receiver)) = payload.take() {
|
||||
let mut controller = AppModel::builder()
|
||||
.launch(input)
|
||||
.detach();
|
||||
|
||||
let window = controller.widget()
|
||||
.clone()
|
||||
.upcast::<gtk::Window>();
|
||||
|
||||
controller.detach_runtime();
|
||||
|
||||
start_server_event_receiver_loop(
|
||||
window.clone(),
|
||||
server_event_receiver,
|
||||
);
|
||||
|
||||
application.add_window(&window);
|
||||
if dev {
|
||||
window.set_visible(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
application.run();
|
||||
};
|
||||
|
||||
thread::Builder::new()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue