Use GtkApplication

This commit is contained in:
Ian Douglas Scott 2021-09-07 12:46:18 -07:00
parent f3828f8239
commit 4e5479cdd8
3 changed files with 97 additions and 34 deletions

89
src/application.rs Normal file
View file

@ -0,0 +1,89 @@
use cascade::cascade;
use gtk4::{
gdk, gio,
glib::{self, clone},
prelude::*,
subclass::prelude::*,
};
use once_cell::unsync::OnceCell;
use std::{cell::Cell, sync::Arc};
use crate::notifications::Notifications;
use crate::status_notifier_watcher;
use crate::window::PanelWindow;
#[derive(Default)]
pub struct PanelAppInner {
notifications: OnceCell<Arc<Notifications>>,
activated: Cell<bool>,
}
#[glib::object_subclass]
impl ObjectSubclass for PanelAppInner {
const NAME: &'static str = "S76CosmicPanelApp";
type ParentType = gtk4::Application;
type Type = PanelApp;
}
impl ObjectImpl for PanelAppInner {
fn constructed(&self, obj: &PanelApp) {
obj.set_application_id(Some("com.system76.cosmicpanel"));
self.parent_constructed(obj);
}
}
impl ApplicationImpl for PanelAppInner {
fn activate(&self, obj: &PanelApp) {
self.parent_activate(obj);
if self.activated.get() {
return;
}
self.activated.set(true);
let display = gdk::Display::default().unwrap();
let monitors = display.monitors().unwrap();
for i in 0..monitors.n_items() {
obj.add_window_for_monitor(monitors.item(i).unwrap().downcast().unwrap());
}
monitors.connect_items_changed(
clone!(@weak obj => move |monitors, position, _removed, added| {
for i in position..position + added {
obj.add_window_for_monitor(monitors
.item(i)
.unwrap()
.downcast::<gdk::Monitor>()
.unwrap());
}
}),
);
status_notifier_watcher::start();
let _ = self.notifications.set(Notifications::new());
}
}
impl GtkApplicationImpl for PanelAppInner {}
glib::wrapper! {
pub struct PanelApp(ObjectSubclass<PanelAppInner>)
@extends gtk4::Application, gio::Application,
@implements gio::ActionGroup, gio::ActionMap;
}
impl PanelApp {
pub fn new() -> Self {
glib::Object::new::<Self>(&[]).unwrap()
}
fn add_window_for_monitor(&self, monitor: gdk::Monitor) {
self.add_window(&cascade! {
PanelWindow::new(monitor);
..show();
});
}
}

View file

@ -1,5 +1,6 @@
use gtk4::{gdk, glib, prelude::*};
use gtk4::prelude::*;
mod application;
mod deref_cell;
mod mpris;
mod mpris_player;
@ -13,36 +14,8 @@ mod time_button;
mod window;
mod x;
use application::PanelApp;
fn main() {
gtk4::init().unwrap();
let main_context = glib::MainContext::default();
let _acquire_guard = main_context.acquire().unwrap();
let display = gdk::Display::default().unwrap();
let monitors = display.monitors().unwrap();
for i in 0..monitors.n_items() {
let monitor = monitors
.item(i)
.unwrap()
.downcast::<gdk::Monitor>()
.unwrap();
window::PanelWindow::new(monitor).show();
}
monitors.connect_items_changed(|monitors, position, _removed, added| {
for i in position..position + added {
let monitor = monitors
.item(i)
.unwrap()
.downcast::<gdk::Monitor>()
.unwrap();
window::PanelWindow::new(monitor).show();
}
});
status_notifier_watcher::start();
let _notificiations = notifications::Notifications::new();
glib::MainLoop::new(None, false).run();
PanelApp::new().run();
}

View file

@ -35,7 +35,7 @@ pub struct PanelWindowInner {
#[glib::object_subclass]
impl ObjectSubclass for PanelWindowInner {
const NAME: &'static str = "S76PanelWindow";
type ParentType = gtk4::Window;
type ParentType = gtk4::ApplicationWindow;
type Type = PanelWindow;
}
@ -112,10 +112,11 @@ impl WidgetImpl for PanelWindowInner {
}
impl WindowImpl for PanelWindowInner {}
impl ApplicationWindowImpl for PanelWindowInner {}
glib::wrapper! {
pub struct PanelWindow(ObjectSubclass<PanelWindowInner>)
@extends gtk4::Window, gtk4::Widget,
@extends gtk4::ApplicationWindow, gtk4::Window, gtk4::Widget,
@implements gtk4::Accessible, gtk4::Buildable, gtk4::ConstraintTarget, gtk4::Native, gtk4::Root, gtk4::ShortcutManager;
}