Window does not re-draw after setting visibility back on (winit)

I am making a dropdown terminal, I am using winit, crossbeam, win-hotkeys. How come the window does not redraw after changing visibility? it displays initially, but using the hotkeys never displays the window again (i advise testing this on your own system so you can see my issue)

use crossbeam_channel::unbounded;
use win_hotkeys::{HotkeyManager, VKey};
use winit::{
    event::{Event, WindowEvent},
    event_loop::{ControlFlow, EventLoop, EventLoopBuilder},
    window::{WindowBuilder},
};
use std::sync::{Arc, Mutex};
use std::thread;

#[derive(Debug, Clone, Copy)]
enum CustomEvent {
    ToggleVisibility,
}

fn main() {
    
    let event_loop: EventLoop<CustomEvent> = EventLoopBuilder::with_user_event().build();
    let event_proxy = event_loop.create_proxy(); 

    let mut hkm = HotkeyManager::new();

    
    let (tx, _rx) = unbounded();  
    hkm.register_channel(tx);

    let backquote = VKey::from_vk_code(0xC0);

    
    let last_time = Arc::new(Mutex::new(std::time::Instant::now()));

    
    hkm.register_hotkey(backquote, &[VKey::Control], {
        let last_time = Arc::clone(&last_time);
        let event_proxy = event_proxy.clone();
        move || {
            let now = std::time::Instant::now();
            let mut last_time_guard = last_time.lock().unwrap();
            
            if now.duration_since(*last_time_guard) > std::time::Duration::from_millis(300) {
                *last_time_guard = now;
                println!("Ctrl +  hotkey pressed");
                let _ = event_proxy.send_event(CustomEvent::ToggleVisibility); 
            }
        }
    })
    .expect("Failed to register Ctrl+ hotkey");

    hkm.register_hotkey(backquote, &[VKey::LWin], {
        let last_time = Arc::clone(&last_time);
        let event_proxy = event_proxy.clone();
        move || {
            let now = std::time::Instant::now();
            let mut last_time_guard = last_time.lock().unwrap();

            if now.duration_since(*last_time_guard) > std::time::Duration::from_millis(300) {
                *last_time_guard = now;
                println!("Meta +  hotkey pressed");
                let _ = event_proxy.send_event(CustomEvent::ToggleVisibility); 
            }
        }
    })
    .expect("Failed to register Meta+ hotkey");

    
    let window = WindowBuilder::new()
        .with_title("Quake Terminal")
        .with_decorations(false)
        .with_transparent(true)
        .with_inner_size(winit::dpi::LogicalSize::new(800, 400))
        .build(&event_loop)
        .unwrap();

    window.set_visible(true);
    let mut visible = true;

    
    thread::spawn(move || {
        hkm.event_loop();
    });

    
    event_loop.run(move |event, _, control_flow| {
        *control_flow = ControlFlow::Wait;
        match event {
            
            Event::UserEvent(CustomEvent::ToggleVisibility) => {
                visible = !visible;
                println!("Toggling visibility: {}", visible);
                window.set_visible(visible);
                if visible {
                   
                }
            }
            Event::WindowEvent { event, .. } => {
                if let WindowEvent::CloseRequested = event {
                    *control_flow = ControlFlow::Exit;
                }
            }
            _ => (),
        }
    });
}

Cargo.toml (deps):
winit = "0.28"
egui = "0.25"
win-hotkeys = "0.5.0"
crossbeam-channel = "0.5.14"

As far as I’m concerned, a better question is why Windows bothers to paint anything when the window is initially displayed. :man_shrugging: After it becomes visible again, it does seem to be there since I can’t click behind it, but Windows needs you to handle redraws. I also needed to remove .with_transparent(true), probably because this is just using GDI:

            Event::RedrawRequested(_) => {
                let hwnd = HWND(window.hwnd() as *mut c_void);
                let mut ps = PAINTSTRUCT::default();
                unsafe {
                    let hdc = BeginPaint(hwnd, &mut ps);
                    let hbr = CreateSolidBrush(COLORREF(0x2ba5));
                    FillRect(hdc, &ps.rcPaint, hbr);
                    let _ = DeleteObject(hbr.into());
                    let _ = EndPaint(hwnd, &ps);
                }
            },

Once you hook up egui, it should be taking care of painting something in the window for you instead of this.

I tried a massive refactor of my code, so i can use egui, do you know why text is not rendering?
use egui::RawInput;use winit::event::{Event, WindowEvent};use winit::event - Pastebin.com

I'm not at all familiar with equi myself, sorry.