Not receiving messages from subscription::channel

I’m trying to listen to display change events in windows, so I can resize my application. I’m using a hidden window for this, since it needs to be a top level window. I’m able to send the message, and the result is ok, but the main application never receives the event. Any ideas what could be causing it? The websocket example works correctly for me. I’m using version 12 :

main.rs

#[derive(Debug, Clone)]
enum Message {
    Init(window::Id),
    Hide(window::Id),
    Show(window::Id),
    DisplayChanged(monitor::Event),
}

impl Application for Banner {
    type Executor = executor::Default;
    type Flags = config::Settings;
    type Message = Message;
    type Theme = Theme;
...
    fn update(&mut self, message: Message) -> iced::Command<Message> {
        match message {
...
            Message::DisplayChanged(_) => {
                println!("display changed");
                Command::none()
            },
        }
    }

    fn subscription(&self) -> Subscription<Message> { monitor::monitor().map(Message::DisplayChanged) }

monitor.rs

use futures::{channel::mpsc::Sender, sink::SinkExt};
use iced::subscription::{self, Subscription};
use std::sync::{Mutex, OnceLock};
use windows::{
    core::*,
    Win32::{Foundation::*, System::LibraryLoader::GetModuleHandleA, UI::WindowsAndMessaging::*},
};

static SENDER: OnceLock<Mutex<Sender<Event>>> = OnceLock::new();

pub fn monitor() -> Subscription<Event> {
    struct Connect;

    subscription::channel(std::any::TypeId::of::<Connect>(), 100, |output| async move {
        unsafe {
            let instance = GetModuleHandleA(None).unwrap();
            debug_assert!(instance.0 != 0);

            let window_class = s!("window");

            let wc = WNDCLASSA {
                hCursor: LoadCursorW(None, IDC_ARROW).unwrap(),
                hInstance: instance.into(),
                lpszClassName: window_class,

                style: CS_HREDRAW | CS_VREDRAW,
                lpfnWndProc: Some(wndproc),
                ..Default::default()
            };

            let atom = RegisterClassA(&wc);
            debug_assert!(atom != 0);

            SENDER.set(Mutex::new(output)).expect("failed to set monitor sender");

            CreateWindowExA(
                WINDOW_EX_STYLE(0),
                window_class,
                s!("resize_monitor"),
                WS_OVERLAPPEDWINDOW,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                0,
                0,
                HWND_DESKTOP,
                None,
                instance,
                None,
            );

            let mut message = MSG::default();

            loop {
                while GetMessageA(&mut message, None, 0, 0).into() {
                    DispatchMessageA(&message);
                }
            }
        }
    })
}

extern "system" fn wndproc(window: HWND, message: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT {
    unsafe {
        match message {
            WM_DESTROY => {
                PostQuitMessage(0);
                LRESULT(0)
            },
            WM_DISPLAYCHANGE => {
                iced::futures::executor::block_on(async {
                    let mut sender = SENDER.get().unwrap().lock().unwrap();
                    let result = sender.send(Event::DisplayChanged).await;
                    println!("message sent: {result:#?}");
                });
                LRESULT(0)
            },
            _ => DefWindowProcA(window, message, wparam, lparam),
        }
    }
}

#[derive(Debug, Clone)]
pub enum Event {
    DisplayChanged,
}

figured it out based on another post.

            loop {
                while GetMessageA(&mut message, None, 0, 0).into() {
                    DispatchMessageA(&message);
                }
            }

This was blocking the async task. I moved the window creation above that and changed the channel to:

    subscription::channel(std::any::TypeId::of::<Connect>(), 100, |output| async move {
        SENDER.set(Mutex::new(output)).expect("failed to set monitor sender");
        loop {
            futures::future::pending::<bool>().await;
        }
    })