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,
|
|
|
|
Some(listener) => listener.await,
|
|
|
|
}
|
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()
|
|
|
|
}
|
|
|
|
}
|