fltk-rs / fltk-rs

Rust bindings for the FLTK GUI library.
MIT License
1.62k stars 108 forks source link

[BUG] How to force redraw of the frame after set_image? #1608

Open AllenDang opened 2 hours ago

AllenDang commented 2 hours ago

Describe the bug

I have a frame with thin_down_box style. After invoke set_image() and set_damage(true), it's image is now changed.

To Reproduce

  1. Create a frame with thin_down_box style
  2. Invoke "set_image()" and "set_damage(true)" and remain mouse cursor still.
  3. The image is not updated.
  4. Move mouse cursor, the image is updated.

It seems if mouse cursor don't move, the window will not redraw no matter what.

Expected behavior

The image of frame will update immediately.

Screenshots

If applicable, add screenshots to help explain your problem.

Desktop info

MoAlyousef commented 2 hours ago

set_damage() flags a redraw of the widget for the next draw cycle, which might be os-specific. For a forced redraw you would need to call frame.redraw(). Setting the image of a widget in FLTK doesn't cause an automatic redraw.

AllenDang commented 2 hours ago

@MoAlyousef Invoke "frame.redraw()" doesn't work if I remain the mouse still. Update only happens when mouse cursor is moved.

The use case is click button to change image of a frame.

update: I cannot repo this issue with a mrp, issue might be caused by something else, I will try to dig out what happened

MoAlyousef commented 1 hour ago

Can you try the following (replace the image path with one you have):

use fltk::{prelude::*, *};

fn main() {
    let app = app::App::default();
    let mut wind = window::Window::default().with_size(400, 300);
    let mut frame = frame::Frame::default().with_size(200, 100).center_of(&wind);
    let mut but = button::Button::new(160, 210, 80, 40, "Click me!");
    wind.end();
    wind.show();

    but.set_callback(move |_| {
        let mut image = image::SharedImage::load("screenshots/calc.jpg").unwrap();
        image.scale(200, 100, true, true);
        frame.set_image(Some(image));
        frame.redraw();
    });

    app.run().unwrap();
}

Launch the binary. The button should have focus, just press the spacebar. Normally the image should show without having to move the mouse or anything. If it doesn't, I'll create a C++ repro of the problem and ask you to try it. If the problem is also present, we'll open an issue in the FLTK repo. The issue could be macos related since the above code works correctly for me on linux and windows, and I don't have a macos system at hand to try it.

AllenDang commented 59 minutes ago

@MoAlyousef In the MRP, I cannot repo this issue. In my app I use lots of tokio spawn and signal send, I'm still trying to find out what causes this issue.

MoAlyousef commented 7 minutes ago

You might try app::awake when sending a signal thru tokio. Things occuring on a thread other than the main ui thread are opaque to FLTK.