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

Right click on title bar causes event loop to hang #5720

Open
dstric-aqueduct opened this issue Jul 29, 2024 · 8 comments
Open

Right click on title bar causes event loop to hang #5720

dstric-aqueduct opened this issue Jul 29, 2024 · 8 comments
Labels
a:backend-winit Winit backend (mS,mO) a:platform-windows Issue specific to Windows (mT,bS) bug Something isn't working upstream Needs a fix upstream

Comments

@dstric-aqueduct
Copy link

<-- Please mention your platform and the programming language you are using Slint with -->

Windows x86-64 with Rust

<-- For bugs, please give steps on how to reproduce. What is the expected behavior and what do you see instead. -->

Right clicking on the Window title bar seems to pause the event loop. Maximizing the window by making it full screen restarts the loop and updates resume.

We followed the bridge pattern from an example app to handle updating a global parameter:

// The following line ensures that, in release mode, the application does not spawn a console window in Windows.
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

// Include Slint UI modules. Slint is used for creating the graphical interface.
slint::include_modules!();

mod bridge;
mod worker;

fn main() {
    // Initialize the main UI from the `Ui` component defined in Slint.
    let ui = Ui::new().expect("Failed to create UI");

    let stream_dialog = StreamControlsDialog::new().expect("Failed to Stream Controls Dialog");

    bridge::init(&ui);

    // Create a worker thread that will handle background tasks without blocking the UI.
    let worker_h = worker::Worker::new(&ui, &stream_dialog);

    // Bind UI events to their respective handlers.
    bridge::bind_events(&ui, &worker_h);

    ui.global::<SystemDisplayEvents>().on_show_settings(move || {
        stream_dialog.show().expect("Failed to show Stream Controls Dialog");
    });

    // Display the UI window.
    ui.show().expect("Failed to show UI");

    // Run the Slint event loop to keep the UI responsive.
    slint::run_event_loop().expect("Failed to run event loop");

    // Ensure the worker thread is properly joined back before exiting.
    worker_h.join().expect("Worker thread failed to join");
}

Relevant part of worker.rs update logic.

/// Renders UI updates.
#[inline(always)]
fn render_ui_updates<const N: usize>(
    handle: &slint::Weak<Ui>,
    controls_handle: &slint::Weak<StreamControlsDialog>,
    state: &mut State<N>,
    window_size: &Arc<RwLock<PhysicalSize>>,
) {
    let stream_data: Vec<UiStreamData> = state.data.iter().map(|s| s.into()).collect();
    let ws = window_size.read_recursive().clone();
    let chart_image = match state.create_chart(ws) {
        Ok(image) => Some(image),
        Err(e) => {
            log::debug!("Error generating chart: {:?}", e);
            None
        }
    };

    // Update the window size
    let ws = window_size.clone();

    let steam_data_clone = stream_data.clone();

    if let Err(e) = handle.clone().upgrade_in_event_loop(move |h| {
        let mut ws = ws.write();
        *ws = h.window().size();

        let stream_data: VecModel<UiStreamData> = VecModel::from(steam_data_clone);

        h.global::<DataState>()
            .set_streams(ModelRc::from(Rc::new(stream_data)));

        if let Some(image) = chart_image {
            let image = slint::Image::from_rgb8(image);
            h.global::<DataState>().set_chart0(image);
        }
    }) {
        log::error!("{e:?}");
    }

    if let Err(e) = controls_handle.clone().upgrade_in_event_loop(move |h| {
        let stream_data: VecModel<UiStreamData> = VecModel::from(stream_data);

        h.global::<DataState>()
            .set_streams(ModelRc::from(Rc::new(stream_data)));
    }) {
        log::error!("{e:?}");
    }
}

I can provide a movie of the issue if that's helpful.

Finally, thank you for this wonderful framework!

@Vadoola
Copy link

Vadoola commented Jul 29, 2024

I have an issue that may or may not be related. I hadn't posted my issue yet since I was trying to determine if it was something I was doing wrong first (since I'm manually creating the "title bar").

In Tomotroid on my frameless window with manually recreated title bar. When clicking on the Title bar (say to move the window) the active timer pauses. As soon as you release the title bar it starts again.

I only observe this issue on Windows, in both Win 10 and Win 11, release and debug builds. This issue does not occur on Linux (under X11 or Wayland)

@ogoffart
Copy link
Member

Thanks for filling a bug

I can provide a movie of the issue if that's helpful.

Yes please, that'd be helpfull

@ogoffart ogoffart added a:platform-windows Issue specific to Windows (mT,bS) bug Something isn't working labels Jul 30, 2024
@dstric-aqueduct
Copy link
Author

Hi Olivier -

Here's a link to a video of the issue: https://youtu.be/C1vquIm46DA

I couldn't capture the title bar in the video; the displays stop updating immediately after the right click on the title bar (this is Windows 10). Double clicking to make the window full screen restarts the updates.

@Vadoola
Copy link

Vadoola commented Jul 30, 2024

After doing a quick look back at my issue I'm not sure it's related. As already mentioned I'm manually recreating a "title bar", but also after checking again the timer does not stop when I click on the title bar but only when I start moving the window.

If you feel it could be relevant I've captured some videos, if not I can keep digging into the issue on my end and perhaps open another issue. In the Linux video you can see the timer never stops. In Windows I've included a mouse capture overlay you can see when I click the title bar the timer keeps running, but as soon as I start moving the window the timer pauses.

Linux.Wayland-1.mp4
Windows11-1.mp4

@Vadoola
Copy link

Vadoola commented Aug 5, 2024

So I don't want to upload while tethering so I'll have to come back and upload the code to Github and some videos later. But I now have a small sample app that demonstrates both the right click on the tool bar as well as left click and dragging the window using a normally framed window. So it would appear that perhaps these issues are related and not something I'm doing to move my frameless window around.

@Vadoola
Copy link

Vadoola commented Aug 5, 2024

I haven't had a chance to take a video yet. I've only had a chance to test this on Windows 11, not 10 yet, but this repo is a minimum example that demonstrates the issue @dstric-aqueduct and I are both having.

  • Right clicking on the title bar pauses the event loop (or at least the timer)
  • Left clicking on the title bar also seems to pause it, which then includes dragging the window around
  • In my frameless window in Tomotroid the timer only pauses when dragging the window, not when left clicking on my made up "title bar".

If I get a chance I can try and dig into it more later, and upload some videos. in the mean time here is the repo: https://github.com/Vadoola/win_slint_event_loop_issue

@XiongDa457
Copy link

XiongDa457 commented Aug 8, 2024

I have a similar problem, and from what I can see the event loop hangs from moving the window, drag resizing or right clicking the title bar, just anything that has to do with the Windows window manager in general.

@ogoffart
Copy link
Member

ogoffart commented Aug 8, 2024

This seems to be a bug in winit: rust-windowing/winit#3272

@ogoffart ogoffart added a:backend-winit Winit backend (mS,mO) upstream Needs a fix upstream labels Aug 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a:backend-winit Winit backend (mS,mO) a:platform-windows Issue specific to Windows (mT,bS) bug Something isn't working upstream Needs a fix upstream
Projects
None yet
Development

No branches or pull requests

4 participants