Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Entire process is terminated when xserver is killed #1047

Open
tydanel opened this issue Jan 15, 2025 · 1 comment
Open

Entire process is terminated when xserver is killed #1047

tydanel opened this issue Jan 15, 2025 · 1 comment

Comments

@tydanel
Copy link

tydanel commented Jan 15, 2025

Describe the bug
Process seems to exit after killing the xserver even though the thread running tao instance is terminated, not sure if this is expected but it seems like this shouldn't be the case.. I might also just be overlooking something here..

If I comment out the tao stuff and leave the xephyr child process stuff the loop continues and if I stop tao and never stop the xserver the loop keeps running...

Not sure what actually causes the entire process to terminate, will keep looking and update if I spot anything

Steps To Reproduce
Will need Xephyr installed but will also work with Xvfb.

use tao::{
    event_loop::{ControlFlow, EventLoopBuilder},
    platform::{run_return::EventLoopExtRunReturn, unix::EventLoopBuilderExtUnix},
    window::WindowBuilder,
};

const DISPLAY: &str = ":60";

fn main() {
    let mut display = spawn_xephyr(DISPLAY, 800, 600);
    std::thread::sleep(std::time::Duration::from_secs(1));
    std::env::set_var("DISPLAY", DISPLAY);

    let (tx_ready, rx_ready) = std::sync::mpsc::channel();

    let mut ui_thread = Some(std::thread::spawn(|| {
        let mut event_loop = EventLoopBuilder::<()>::with_user_event()
            .with_any_thread(true)
            .build();

        let event_proxy = event_loop.create_proxy();

        let mut _window = Some(
            WindowBuilder::new()
                .with_title("Window")
                .with_inner_size(tao::dpi::LogicalSize::new(300.0, 300.0))
                .with_min_inner_size(tao::dpi::LogicalSize::new(200.0, 200.0))
                .build(&event_loop)
                .unwrap(),
        );

        event_loop.run_return(move |event, _, control_flow| {
            *control_flow = ControlFlow::Wait;
            match event {
                tao::event::Event::NewEvents(tao::event::StartCause::Init) => {
                    tx_ready.send(event_proxy.clone()).unwrap();
                }
                tao::event::Event::UserEvent(()) => {
                    *control_flow = tao::event_loop::ControlFlow::Exit;
                    println!("Exiting... {:?}", control_flow);
                }
                _ => {}
            }
        })
    }));

    let event_proxy = rx_ready.recv().unwrap();

    loop {
        println!("Should loop forever");
        std::thread::sleep(std::time::Duration::from_secs(1));

        if ui_thread.is_some() {
            event_proxy.send_event(()).unwrap();
            let ui_thread = ui_thread.take().unwrap();
            ui_thread.join().unwrap();
            let _ = display.kill();
        }
    }
}

fn spawn_xephyr(display_identifier: &str, width: u32, height: u32) -> std::process::Child {
    std::process::Command::new("Xephyr")
        .arg(display_identifier)
        .arg("-screen")
        .arg(format!("{}x{}", width, height))
        .spawn()
        .expect("Failed to start Xephyr")
}

Expected behavior
The loop in main should continue even after the xserver is killed

Platform and Versions (please complete the following information):
OS: Arch Linux x86_64 Linux 6.12.8-arch1-1
Rustc: 1.82.0

@tydanel
Copy link
Author

tydanel commented Jan 15, 2025

Okay from what I can see, when I do this *control_flow = tao::event_loop::ControlFlow::Exit; and then call join() on the JoinHandle the window still remains visible in the xserver and only goes away when the entire process terminates.

I'm guessing this is why the documentation recommends using run() instead of run_return() as it calls process::exit() in order to clear everything up.

A bit of a pain if this can't be resolved but I'm early enough in the project and have an idea to re-architect things to work around this limitation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant