Skip to content

Probe for ncurses BUTTON5 support at build time#870

Open
badscrew wants to merge 1 commit into
gyscos:mainfrom
badscrew:fix/ncurses-button5-probe
Open

Probe for ncurses BUTTON5 support at build time#870
badscrew wants to merge 1 commit into
gyscos:mainfrom
badscrew:fix/ncurses-button5-probe

Conversation

@badscrew
Copy link
Copy Markdown
Contributor

@badscrew badscrew commented May 3, 2026

Add build.rs to the cursive crate that checks the ncurses crate's generated raw_constants.rs for BUTTON5_PRESSED. The ncurses crate (v6+) already probes the system headers via C compilation and conditionally includes BUTTON5 constants. We simply read that result — no C compiler invocation needed in our build script.

If BUTTON5 constants are present, sets cfg(has_ncurses_button5); otherwise the BUTTON5 code paths in the ncurses backend are gated out.

This fixes the build failure on macOS where the system ncurses does not provide BUTTON5_* constants.

Resolves #815.

@gyscos
Copy link
Copy Markdown
Owner

gyscos commented May 3, 2026

Thanks for the PR!

I would really like to avoid a build script for cursive if possible. If required for the ncurses support, I'd rather move the ncurses backend to a separate cursive-ncurses crate, which has a build script, and is only pulled in when the ncurses backend is enabled. This way no build script will be required when ncurses support is disabled.

@badscrew
Copy link
Copy Markdown
Contributor Author

badscrew commented May 3, 2026

let me think about that

@badscrew badscrew force-pushed the fix/ncurses-button5-probe branch from 7e73be4 to 675e107 Compare May 3, 2026 19:10
The upstream maintainer requested that the build script be avoided in the
main cursive crate, since it adds overhead for all users regardless of
whether the ncurses backend is enabled.

This commit implements the suggested approach: extract the ncurses backend
into its own cursive-ncurses crate, which owns the build script and the
ncurses dependency. The build script (which probes for BUTTON5 support by
reading the ncurses crate's generated raw_constants.rs) now only runs when
a user explicitly depends on cursive-ncurses, i.e. when ncurses-backend is
enabled. On macOS, where system ncurses does not provide BUTTON5 constants,
the cfg(has_ncurses_button5) flag is correctly left unset.

Changes:
- Add cursive-ncurses/ crate with its own Cargo.toml, build.rs, and
  src/lib.rs containing the full ncurses backend implementation
- Remove cursive/build.rs entirely; cursive now has no build script
- Remove the direct ncurses dependency from cursive/Cargo.toml; the
  ncurses-backend feature now pulls in dep:cursive-ncurses instead
- Flatten the backends module layout: remove the curses/ subdirectory
  (which previously grouped ncurses and pancurses backends despite them
  sharing no code after the extraction), and promote n.rs and pan.rs to
  direct children of backends/
- cursive/src/backends/n.rs is now a thin re-export of cursive-ncurses
- cursive/src/backends/pan.rs is now self-contained with its own copy of
  the shared color/keycode helpers (previously in curses/mod.rs)
- Update all internal references from backends::curses::n/pan to
  backends::n and backends::pan
- Add cursive-ncurses to the workspace members in the root Cargo.toml

The public API of the cursive crate is unchanged.

Fixes gyscos#815.
@badscrew badscrew force-pushed the fix/ncurses-button5-probe branch from 675e107 to d389df8 Compare May 3, 2026 22:05
@badscrew
Copy link
Copy Markdown
Contributor Author

badscrew commented May 3, 2026

Hi @gyscos - Is this looks like what you were thinking about?

I used some assistance from Opus 4.6 to refactor this to be honest, but strategic decisions are mine (most notably removing shared /curses and instead moving ncurses and pancurses to the normal backend place).

There are quite some changes - all builds and the tests pass successfully, I also tested several programs from /examples using ncurses backend on my Mac, they are all behaving as expected.

@@ -53,7 +115,6 @@ fn find_closest_pair(pair: ColorPair) -> (i16, i16) {
fn write_to_tty(bytes: &[u8]) -> io::Result<()> {
let mut tty_output = File::create("/dev/tty").expect("cursive can only run with a tty");
tty_output.write_all(bytes)?;
// tty_output will be flushed automatically at the end of the function.
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to remove this (and other) comments?

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

Successfully merging this pull request may close these issues.

[BUG] Build error when using ncurses-backend

2 participants