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

[MacOS] Segfault when pressing the "About" button #8

Open
kekeimiku opened this issue Feb 7, 2024 · 15 comments
Open

[MacOS] Segfault when pressing the "About" button #8

kekeimiku opened this issue Feb 7, 2024 · 15 comments

Comments

@kekeimiku
Copy link

OS: macOS M2 14.3 (23D56)

Click on the upper left corner, About
image

terminated by signal SIGSEGV (Address boundary error)

@kekeimiku
Copy link
Author

I tried using https://github.com/rust-native-ui/libui-rs and its About is unclickable.

@nptr
Copy link
Member

nptr commented Feb 9, 2024

:(

  1. Are you doing all UI stuff on the main thread?
  2. Do you have a minimal reproducible example?

If we are unlucky, it could be an issue in the underlying libui-ng, that does the Cocoa Framework abstraction. If it is, I have no way of fixing it because I don't have a Mac. If you feel adventurous you'd have to fix libui-ng and submit a pull request there. I'd then pull in the latest version of libui-ng into this rust crate.

@nptr nptr changed the title crash [MacOS] Segfault when pressing the "About" button Feb 9, 2024
@kekeimiku
Copy link
Author

  1. Do you have a minimal reproducible example?

Just example: https://github.com/libui-rs/libui/blob/development/libui/examples/basic.rs

@kekeimiku
Copy link
Author

I will try libui-ng later.

@kekeimiku
Copy link
Author

kekeimiku commented Feb 13, 2024

@nptr Can libui-ffi be updated to a recent version?

I found it has been fixed.
libui-ng/libui-ng@3e6170f

After I updated locally everything was fine.

@nptr
Copy link
Member

nptr commented Feb 13, 2024

Thanks for the investigation & confirmation!

Yes, I should be able to update libui-ffi relatively easy. Hopefully I can get to it on the weekend.

nptr added a commit that referenced this issue Feb 16, 2024
updated libui-ng, which has the issue resolved
nptr added a commit that referenced this issue Feb 16, 2024
Segfault on the default system menu items (Quit/Preferences/About) that have not yet been attached to by the user.
Updated libui-ng, which has the issue resolved.
@nptr
Copy link
Member

nptr commented Feb 16, 2024

Please check out the current state of development using libui = { git = "https://github.com/libui-rs/libui" } in your cargo.toml instead. Looks like the "About", "Settings" and "Quit" items always exist on macOS and you are supposed to give them callbacks.

I didn't have that functionality until now. See the just updated menu example how its done. Let me know if it works for you.

@kekeimiku
Copy link
Author

Click setting and then close, all item become unclickable.

2024-02-17.08.02.06.mov

@nptr
Copy link
Member

nptr commented Feb 17, 2024

I am out of my depth here and have to investigate. Maybe the guys on libui-ng know more.

@chris-t-jansen
Copy link
Contributor

@nptr I believe this issue was solved by 6d3fc99 and can be safely closed.

@nptr
Copy link
Member

nptr commented Jul 28, 2024

I believe I left it open to remind me that something is still off, according to kekeimiku:

Click setting and then close, all item become unclickable.

You seem to have access to a Mac. Does it work on your machine?

@chris-t-jansen
Copy link
Contributor

Okay, I tested it on a 2023 MacBook Pro (M2 Max chip, macOS 14.5), and the bug is still occurring. However, I discovered that it's not linked to the "Settings..." button in particular; rather, it seems to have something to do with window focus.

If you rewatch kekeimiku's video, you'll notice that, when they click the "About hello" button, the modal message appears in the center of the application window (the "Text Editor" window in this case). However, when they immediately go back and click the "Settings..." button, the modal message appears in the center of the computer screen, and they drag it over into view. Then the menu items get locked.

I can recreate kekeimiku's bug by repeating the same steps. It actually works with the "About ___" button and the "Settings..." button in any order, meaning picking "Settings..." and then "About ___" has the same effect, as well as picking either "About ___" or "Settings..." twice in a row.

The interesting thing is, after closing the first modal window (from clicking either "About ___" or "Settings..."), if I click on the application window to refocus it, when I pick the next menu item (again, either "About ___" or "Settings..."), the bug doesn't occur. The modal popup appears in the center of the application window, not the center of the screen, and I can pick a menu item again. As long as I refocus the window in between menu items, I can repeat it as many times as I want (as far as I can tell), and the bug never occurs.

Honestly, I'm not 100% sure window focus is the actual cause, but if not, it looks an awful lot like a focus issue. Maybe something in the modal popup code that, when closed, forces a refocus of the main window would fix the issue?

@chris-t-jansen
Copy link
Contributor

chris-t-jansen commented Jul 28, 2024

I just confirmed that it seems to be related to the modal popup defocusing the main window. I modified the basic.rs to include some menu items from the menus.rs example, and changed the callback for the first button (which normally changes the button text to "Clicked!") to popup a modal message. I can click that button and close the popup as many times as I want without the bug occurring because, when I click the button again, it refocused the window for a split-second. However, if I click the button in the window, close the popup, and then click one of the app-menu buttons (either "About ___" or "Settings...") without clicking on the window to refocus it, the bug occurs and the menu items get locked out.

Here's my modified version of the basic.rs example code in case you want to try it for yourself:

Click to expand
extern crate libui;

use libui::controls::{Button, Group, Label, VerticalBox};
use libui::prelude::*;

fn main() {
    // Initialize the UI library
    let ui = UI::init().expect("Couldn't initialize UI library");

    libui::menu! { &ui,
        let menu_file = Menu("File") {
            let menu_help_about = AboutItem()
            let menu_file_pref = PreferencesItem()
        }
    }

    // Create a window into which controls can be placed
    let mut win = Window::new(&ui.clone(), "Test App", 200, 200, WindowType::NoMenubar);

    // Create a vertical layout to hold the controls
    let mut vbox = VerticalBox::new();
    vbox.set_padded(true);

    let mut group_vbox = VerticalBox::new();
    let mut group = Group::new("Group");

    // Create two buttons to place in the window
    let mut button = Button::new("Button");
    button.on_clicked({
        let win = win.clone();
        move |_| {
            win.modal_msg("Test Message", "This is a simple test message.");
        }
    });

    let mut quit_button = Button::new("Quit");
    quit_button.on_clicked({
        let ui = ui.clone();
        move |_| {
            ui.quit();
        }
    });

    menu_file_pref.on_clicked(move |_, w| w.modal_msg("Preferences", "Preferences menu item clicked!"));

    menu_help_about.on_clicked(move |_, w| w.modal_msg("About", "libui: Menu Example"));

    // Create a new label. Note that labels don't auto-wrap!
    let mut label_text = String::new();
    label_text.push_str("There is a ton of text in this label.\n");
    label_text.push_str("Pretty much every unicode character is supported.\n");
    label_text.push_str("🎉 用户界面 사용자 인터페이스");
    let label = Label::new(&label_text);

    vbox.append(label, LayoutStrategy::Stretchy);
    group_vbox.append(button, LayoutStrategy::Compact);
    group_vbox.append(quit_button, LayoutStrategy::Compact);
    group.set_child(group_vbox);
    vbox.append(group, LayoutStrategy::Compact);

    // Actually put the button in the window
    win.set_child(vbox);
    // Show the window
    win.show();
    // Run the application
    ui.main();
}

@chris-t-jansen
Copy link
Contributor

Following the window-focus line of reasoning, I think I found a band-aid solution by adding self.clone().show(); to the end of the modal_msg method in the crate (self in this case being the window struct):

/// Open a generic message box to show a message to the user.
/// Returns when the user acknowledges the message.
pub fn modal_msg(&self, title: &str, description: &str) {
    unsafe {
        let c_title = CString::new(title.as_bytes().to_vec()).unwrap();
        let c_description = CString::new(description.as_bytes().to_vec()).unwrap();
        libui_ffi::uiMsgBox(self.uiWindow, c_title.as_ptr(), c_description.as_ptr());
        self.clone().show();
    }
}

I don't think it's necessarily a good solution, but it seems to fix the issue on Mac in my personal testing. @nptr maybe you can devise a better solution. I'm happy to help test any potential fixes.

@chris-t-jansen
Copy link
Contributor

Made a pull request with my band-aid solution (#11), which I also extended to all the popup-window-creating methods which I found to also suffer from this issue (e.g. open_file, modal_err, etc.).

Like I said previously, this doesn't feel like a solid solution since it doesn't understand or address whatever underlying issue is causing the problem; as such, I wouldn't be comfortable merging the PR as-is, but maybe it can serve as a good jumping-off point for a more well-crafted solution.

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

No branches or pull requests

3 participants