bevy_web_fullscreen 0.2.1

Bevy plugin for automatic resizing of primary bevy window to fit browser viewport
Documentation
use bevy::{
    prelude::{App, Plugin, Res, ResMut, Resource},
    window::Windows,
};
use std::sync::{
    mpsc::{Receiver, Sender},
    Mutex,
};

#[derive(Resource)]
struct OnResizeSender(Mutex<Sender<()>>);
#[derive(Resource)]
struct OnResizeReceiver(Mutex<Receiver<()>>);

pub struct FullViewportPlugin;

impl Plugin for FullViewportPlugin {
    fn build(&self, app: &mut App) {
        let channel = std::sync::mpsc::channel();
        let resize_sender = OnResizeSender(Mutex::new(channel.0));
        let resize_receiver = OnResizeReceiver(Mutex::new(channel.1));

        app.insert_resource(resize_sender)
            .insert_resource(resize_receiver)
            .add_startup_system(setup_viewport_resize_system)
            .add_system(viewport_resize_system);
    }
}

fn get_viewport_size() -> (f32, f32) {
    let web_window = web_sys::window().expect("could not get window");
    let document_element = web_window
        .document()
        .expect("could not get document")
        .document_element()
        .expect("could not get document element");

    let width = document_element.client_width();
    let height = document_element.client_height();

    (width as f32, height as f32)
}

fn setup_viewport_resize_system(resize_sender: Res<OnResizeSender>) {
    let web_window = web_sys::window().expect("could not get window");
    let local_sender = resize_sender.0.lock().unwrap().clone();

    local_sender.send(()).unwrap();

    gloo_events::EventListener::new(&web_window, "resize", move |_event| {
        local_sender.send(()).unwrap();
    })
    .forget();
}

fn viewport_resize_system(
    mut windows: ResMut<Windows>,
    resize_receiver: Res<OnResizeReceiver>,
) {
    if resize_receiver.0.lock().unwrap().try_recv().is_ok() {
        if let Some(window) = windows.get_primary_mut() {
            let size = get_viewport_size();
            window.set_resolution(size.0, size.1);
        }
    }
}