audrey/src/application.rs

129 lines
4.3 KiB
Rust
Raw Normal View History

2024-10-29 13:02:29 +00:00
mod imp {
2024-11-02 14:43:43 +00:00
use crate::{mpv, ui};
use adw::{prelude::*, subclass::prelude::*};
2024-10-29 13:02:29 +00:00
use gtk::glib;
2024-11-02 19:57:12 +00:00
use std::rc::Rc;
2024-10-29 12:01:42 +00:00
2024-10-29 13:02:29 +00:00
#[derive(Default)]
2024-11-02 14:43:43 +00:00
pub struct Application {
2024-11-02 20:11:18 +00:00
// FIXME: move somewhere else
2024-11-02 19:57:12 +00:00
mpv: Rc<mpv::Handle>,
2024-11-02 14:43:43 +00:00
}
2024-10-29 13:02:29 +00:00
#[glib::object_subclass]
impl ObjectSubclass for Application {
const NAME: &'static str = "AudreyApplication";
type Type = super::Application;
type ParentType = adw::Application;
2024-10-29 12:01:42 +00:00
}
2024-10-29 13:02:29 +00:00
impl ObjectImpl for Application {}
impl ApplicationImpl for Application {
fn activate(&self) {
self.parent_activate();
match self.obj().active_window() {
2024-11-01 11:11:49 +00:00
None => {
let window = ui::Window::new(self.obj().as_ref());
window.present();
2024-11-02 16:05:26 +00:00
self.mpv
.set_property("audio-client-name", "audrey")
.unwrap();
self.mpv
.set_property("user-agent", crate::USER_AGENT)
.unwrap();
self.mpv.set_property("video", false).unwrap();
self.mpv.set_property("prefetch-playlist", true).unwrap();
self.mpv.set_property("gapless-audio", true).unwrap();
2024-11-02 14:43:43 +00:00
// TODO: observe properties
2024-11-02 19:57:12 +00:00
let mpv_weak = Rc::downgrade(&self.mpv);
2024-11-02 16:29:53 +00:00
glib::spawn_future_local(async move {
2024-11-02 19:57:12 +00:00
while let Some(mpv) = mpv_weak.upgrade() {
match mpv.tick() {
None => break,
2024-11-02 20:18:27 +00:00
Some(listener) => {
drop(mpv); // don't
listener.await;
}
2024-11-02 19:57:12 +00:00
}
2024-11-02 14:43:43 +00:00
}
2024-11-02 16:29:53 +00:00
});
2024-11-02 14:43:43 +00:00
2024-11-01 12:50:29 +00:00
glib::spawn_future_local(async move {
2024-11-01 11:11:49 +00:00
let conn = zbus::connection::Builder::session()
2024-11-01 12:50:29 +00:00
.expect("could not connect to the session bus")
2024-11-01 11:11:49 +00:00
.internal_executor(false)
.build()
.await
2024-11-01 12:50:29 +00:00
.expect("could not build connection to the session bus");
2024-11-01 12:58:59 +00:00
// run this in glib's main loop
glib::spawn_future_local(glib::clone!(
#[strong]
conn,
async move {
loop {
conn.executor().tick().await;
}
}
));
2024-11-01 12:50:29 +00:00
crate::Mpris::setup(conn.object_server(), &window)
.await
.expect("could not serve mpris");
2024-11-02 11:24:25 +00:00
crate::mpris::Player::setup(conn.object_server(), &window.playbin())
.await
.expect("could not serve mpris player");
2024-11-01 12:50:29 +00:00
2024-11-01 12:53:42 +00:00
drop(window); // don't keep this alive
2024-11-01 12:50:29 +00:00
// always set up handlers before requesting service name
conn.request_name("org.mpris.MediaPlayer2.audrey")
.await
.expect("could not register name in session bus");
2024-11-01 11:11:49 +00:00
});
}
2024-10-29 13:02:29 +00:00
Some(win) => win.present(),
}
}
2024-10-29 12:01:42 +00:00
}
2024-10-29 13:02:29 +00:00
impl GtkApplicationImpl for Application {}
impl AdwApplicationImpl for Application {}
2024-11-02 14:43:43 +00:00
impl Application {}
2024-11-02 20:11:18 +00:00
impl Drop for Application {
fn drop(&mut self) {
println!("dropping AudreyApplication");
self.mpv.command(["quit"]).unwrap();
}
}
2024-10-29 12:01:42 +00:00
}
2024-10-29 13:02:29 +00:00
use gtk::{gio, glib};
2024-10-29 12:01:42 +00:00
glib::wrapper! {
2024-10-29 13:02:29 +00:00
pub struct Application(ObjectSubclass<imp::Application>)
2024-10-29 12:01:42 +00:00
@extends adw::Application, gtk::Application, gio::Application,
@implements gio::ActionGroup, gio::ActionMap;
}
2024-10-30 03:26:53 +00:00
impl Default for Application {
fn default() -> Self {
glib::Object::builder::<Application>()
2024-11-01 08:47:03 +00:00
.property("application-id", crate::APP_ID)
2024-10-29 13:02:29 +00:00
.property("flags", gio::ApplicationFlags::default())
.build()
2024-10-29 12:01:42 +00:00
}
}
2024-10-30 03:26:53 +00:00
impl Application {
pub fn new() -> Self {
Self::default()
}
}