gyscos / cursive

A Text User Interface library for the Rust programming language
MIT License
4.31k stars 247 forks source link

Double click to maximise command prompt window causes crash (Windows, cross-term) #424

Open NecroTechno opened 4 years ago

NecroTechno commented 4 years ago

Bug Report

Using the "double click to maximise window" feature on the Windows command prompt causes the program to crash. Following the stack trace, it appears to be the unwrap on one of the mouse events in the map_key function in backend/crossterm.rs. See the stack trace below.

thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\src\libcore\macros\mod.rs:15:40
stack backtrace:
   0: backtrace::backtrace::trace_unsynchronized
             at C:\Users\VssAdministrator\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.40\src\backtrace\mod.rs:66
   1: std::sys_common::backtrace::_print_fmt
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\/src\libstd\sys_common\backtrace.rs:84
   2: std::sys_common::backtrace::_print::{{impl}}::fmt
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\/src\libstd\sys_common\backtrace.rs:61
   3: core::fmt::write
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\/src\libcore\fmt\mod.rs:1025
   4: std::io::Write::write_fmt<std::sys::windows::stdio::Stderr>
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\/src\libstd\io\mod.rs:1426
   5: std::sys_common::backtrace::_print
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\/src\libstd\sys_common\backtrace.rs:65
   6: std::sys_common::backtrace::print
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\/src\libstd\sys_common\backtrace.rs:50
   7: std::panicking::default_hook::{{closure}}
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\/src\libstd\panicking.rs:193
   8: std::panicking::default_hook
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\/src\libstd\panicking.rs:210
   9: std::panicking::rust_panic_with_hook
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\/src\libstd\panicking.rs:471
  10: std::panicking::begin_panic_handler
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\/src\libstd\panicking.rs:375
  11: core::panicking::panic_fmt
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\/src\libcore\panicking.rs:84
  12: core::panicking::panic
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\/src\libcore\panicking.rs:51
  13: core::option::Option<cursive::event::MouseButton>::unwrap<cursive::event::MouseButton>
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\src\libcore\macros\mod.rs:15
  14: cursive::backend::crossterm::Backend::map_key
             at C:\Users\redacted\.cargo\registry\src\github.com-1ecc6299db9ec823\cursive-0.14.0\src\backend\crossterm.rs:266
  15: cursive::backend::crossterm::{{impl}}::poll_event
             at C:\Users\redacted\.cargo\registry\src\github.com-1ecc6299db9ec823\cursive-0.14.0\src\backend\crossterm.rs:294
  16: cursive::cursive::Cursive::process_events
             at C:\Users\redacted\.cargo\registry\src\github.com-1ecc6299db9ec823\cursive-0.14.0\src\cursive.rs:922
  17: cursive::cursive::Cursive::step
             at C:\Users\redacted\.cargo\registry\src\github.com-1ecc6299db9ec823\cursive-0.14.0\src\cursive.rs:897
  18: cursive::cursive::Cursive::run
             at C:\Users\redacted\.cargo\registry\src\github.com-1ecc6299db9ec823\cursive-0.14.0\src\cursive.rs:883
  19: curse::main
             at .\src\main.rs:53
  20: std::rt::lang_start::{{closure}}<()>
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\src\libstd\rt.rs:67
  21: std::rt::lang_start_internal::{{closure}}
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\/src\libstd\rt.rs:52
  22: std::panicking::try::do_call<closure-0,i32>
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\/src\libstd\panicking.rs:292
  23: panic_unwind::__rust_maybe_catch_panic
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\/src\libpanic_unwind\lib.rs:78
  24: std::panicking::try
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\/src\libstd\panicking.rs:270
  25: std::panic::catch_unwind
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\/src\libstd\panic.rs:394
  26: std::rt::lang_start_internal
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\/src\libstd\rt.rs:51
  27: std::rt::lang_start<()>
             at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8\src\libstd\rt.rs:67
  28: main
  29: invoke_main
             at d:\agent\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
  30: __scrt_common_main_seh
             at d:\agent\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
  31: BaseThreadInitThunk
  32: RtlUserThreadStart
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
error: process didn't exit successfully: `target\debug\curse.exe` (exit code: 101)

Environment

gyscos commented 4 years ago

Thanks for the report!

Seems to be a bug in the crossterm wrapper code, where we apparently detect a "mouse drag event" before a "mouse press event" is detected.

I changed that to use the upstream button rather than our own "last_button" logic; can you try the latest git master to see if it fixes your crash?

NecroTechno commented 4 years ago

Yep, that's fixed it! Thanks for the super quick response! :)

NecroTechno commented 4 years ago

Sorry, perhaps I was a little too quick to celebrate. It seems on the on the master branch I can no longer detect the WindowResize event. Doesn't crash, but even regular resize of dragging the corners of the prompt no longer triggers the event.

gyscos commented 4 years ago

Blast! Not sure what fails here. I'll check if it's a problem in crossterm itself, or in the wrapper code.

gyscos commented 4 years ago

Ah you may have been caught by another change: WindowResize is now a pre-event, so you'll need to use Cursive::set_on_pre_event to add callbacks for that, instead of add_default_callback.

NecroTechno commented 4 years ago

Unfortunately, still doesn't seem to be catching the event, either by double clicking the bar or dragging the window. Maybe I'm doing something else incorrectly?

pub fn resize(siv: &mut Cursive, state_manager: &'static Mutex<StateManager>) {
    siv.pop_layer();

    siv.add_layer(
        OnEventView::new(
            Dialog::around(TextView::new("Please increase the size of your terminal."))
                .title("Menu"),
        )
        .on_pre_event(Event::WindowResize, move |s| {
            let screen_size = s.screen_size();
            if screen_size.x >= 120 && screen_size.y >= 30 {
                menu(s, state_manager);
            }
        }),
    );
}

I've tried logging inside the closure, but I'm getting nothing.

Thanks so much for your help!