Skip to content

gh-152263: Add curses soft-label-key functions#152264

Merged
serhiy-storchaka merged 10 commits into
python:mainfrom
serhiy-storchaka:curses-slk
Jun 29, 2026
Merged

gh-152263: Add curses soft-label-key functions#152264
serhiy-storchaka merged 10 commits into
python:mainfrom
serhiy-storchaka:curses-slk

Conversation

@serhiy-storchaka

Copy link
Copy Markdown
Member

Wrap the X/Open Curses soft-label-key functions in the curses module. Soft labels are a row of labels along the bottom line of the screen, conventionally labelling a row of function keys, managed and refreshed independently of the standard window.

Added module-level functions:

  • slk_init(fmt=0) — reserve a screen line for the labels and choose their layout. Must be called before initscr() or newterm().
  • slk_set(labnum, label, justify) / slk_label(labnum) — set and query a label's text.
  • slk_refresh(), slk_noutrefresh(), slk_clear(), slk_restore(), slk_touch().
  • slk_attron(attr), slk_attroff(attr), slk_attrset(attr), slk_attr() — the chtype attribute functions.
  • slk_attr_on(attr), slk_attr_off(attr), slk_attr_set(attr, pair=0), slk_color(pair) — the attr_t/color-pair attribute functions.

slk_set uses slk_wset for wide-character labels when built against ncursesw. Tests drive their own pseudo-terminals (soft labels must be initialised before newterm()), and pass under UTF-8, Latin-1 and C locales.

Wrap the X/Open Curses soft-label-key functions: slk_init, slk_set,
slk_label, slk_refresh, slk_noutrefresh, slk_clear, slk_restore,
slk_touch, the chtype attribute functions slk_attron, slk_attroff,
slk_attrset and slk_attr, and the attr_t functions slk_attr_on,
slk_attr_off, slk_attr_set and slk_color.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@read-the-docs-community

read-the-docs-community Bot commented Jun 26, 2026

Copy link
Copy Markdown

@vstinner

Copy link
Copy Markdown
Member

I didn't know soft-label-key functions. Is it commonly used? I'm not sure that it's worth it to expose these functions.

Soft labels are a row of labels displayed along the bottom line of the screen, conventionally used to label a row of function keys

Would you be able to write a short demo so I can see how it does look like?

(I don't understand well the purpose of these functions.)

@serhiy-storchaka

Copy link
Copy Markdown
Member Author

No, they are not often used. But they are the part of the Posix standard. Demo:

import curses

LABELS = ["Help", "Save", "Open", "Find", "Run", "Stop", "Setup", "Quit"]
def main(stdscr):
    for i, text in enumerate(LABELS):
        curses.slk_set(i + 1, text, 1) # 1 - center
    curses.slk_refresh()
    stdscr.addstr(0, 0, "Soft labels are on the bottom line. Press any key.")
    stdscr.getkey()
curses.slk_init(0) # 3-2-3 layout
curses.wrapper(main)

serhiy-storchaka and others added 5 commits June 26, 2026 20:02
# Conflicts:
#	Doc/whatsnew/3.16.rst
#	Modules/clinic/_cursesmodule.c.h
refresh is a window method, not a module function; reference it as
window.refresh so the documentation builds without warnings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
# Conflicts:
#	Doc/whatsnew/3.16.rst
#	Modules/clinic/_cursesmodule.c.h
# Conflicts:
#	Modules/clinic/_cursesmodule.c.h
@vstinner

Copy link
Copy Markdown
Member

On Fedora 44, the example looks like:

Capture d’écran du 2026-06-29 17-27-53

Comment thread Modules/_cursesmodule.c

fmt: int = 0
Label layout: 0 = 3-2-3, 1 = 4-4 (8 labels each); 2 = 4-4-4,
3 = 4-4-4 with an index line (12 labels each, ncurses extensions).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

3 is only supported on ncurses? If yes, can we reject 3 if the Python _curses module is not linked to ncurses?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I will test how out-of-range values are handled. Most likely you will get a curses.error.

Other implementations can also support them.

Comment thread Modules/_cursesmodule.c Outdated
Comment thread Doc/library/curses.rst Outdated
Comment thread Lib/test/test_curses.py Outdated
Comment thread Lib/test/test_curses.py Outdated
Comment thread Doc/library/curses.rst Outdated

.. _curses-slk:

The following functions manage *soft-label keys*, a row of labels displayed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Would it be possible to move these functions in a new "Soft-label keys" section?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes. I just reorganized the docs (#152584), these functions will be in a separate section.

Co-authored-by: Victor Stinner <vstinner@python.org>

@vstinner vstinner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM.

For slk_init(), I'm fine with not rejecting fmt=3 but just pass the value to curses.

For the doc, I didn't see the reorganized doc. Nice.

@vstinner

Copy link
Copy Markdown
Member

Ah, and good luck to solve the merge conflicts :-)

serhiy-storchaka and others added 3 commits June 29, 2026 19:12
# Conflicts:
#	Doc/library/curses.rst
#	Doc/whatsnew/3.16.rst
#	Modules/clinic/_cursesmodule.c.h
…es curses

Soft-label formats 2 and 3 are ncurses extensions; other curses
implementations (such as NetBSD curses) reject them with an error.
Require every format to work on ncurses, but tolerate the extended
formats being unsupported elsewhere.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@serhiy-storchaka serhiy-storchaka merged commit 089e6f6 into python:main Jun 29, 2026
54 checks passed
@serhiy-storchaka serhiy-storchaka deleted the curses-slk branch June 29, 2026 17:58
@serhiy-storchaka

Copy link
Copy Markdown
Member Author

Thank you. This was peanuts in comparison with five PRs fighting for the same place in What's New, with flaky CI tests.

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.

2 participants