diff --git a/tnz/_termlib.py b/tnz/_termlib.py index d60e91a..2c8afc5 100644 --- a/tnz/_termlib.py +++ b/tnz/_termlib.py @@ -435,6 +435,8 @@ def refresh(self, *, _win_callback=None): if curs_vis: if curs_vis == 2: pendlist.append("\x1b[1 q") + elif curs_vis < 0: + pendlist.append(f"\x1b[{-curs_vis-1} q") else: pendlist.append("\x1b[3 q") @@ -1032,6 +1034,10 @@ def color_pair(cls, pair_number): @_log_errors def curs_set(cls, visibility): """Set cursor visibility. + 0 - Invisible + 1 - Terminal-specific normal mode + 2 - Terminal-specific high visibility mode + <0 - Use absolute value minus one for DECSCUSR value """ cls.__initscr_required() @@ -1040,6 +1046,8 @@ def curs_set(cls, visibility): if cls.__alt_screen: if visibility == 2: cls.__termo.write("\x1b[1 q\x1b[?25h") + elif visibility < 0: + cls.__termo.write(f"\x1b[{-visibility-1} q\x1b[?25h") elif visibility: cls.__termo.write("\x1b[3 q\x1b[?25h") else: diff --git a/tnz/zti.py b/tnz/zti.py index fda73cc..46d4141 100644 --- a/tnz/zti.py +++ b/tnz/zti.py @@ -27,6 +27,8 @@ TNZ_LOGGING (see tnz.py) ZTI_AIDBUFSIZE (9 is default) ZTI_AUTOSIZE + ZTI_CURSOR_INSERT + ZTI_CURSOR_REPLACE ZTI_SECLEVEL (see tnz.py) ZTI_TITLE _BPX_TERMPATH (see _termlib.py) @@ -35,6 +37,7 @@ SPDX-License-Identifier: Apache-2.0 """ + if __name__ == "__main__": # We want to support starting by 'python -m tnz.zti', but that can # generally be problematic because the zti module is imported as @@ -47,6 +50,7 @@ # eventually dropping support for 'python -m tnz.zti' so that we can # avoid this. from tnz import zti + raise SystemExit(zti.main()) import atexit @@ -135,7 +139,7 @@ def __init__(self, stdin=None, stdout=None): self.__has_color = None self.__prog_curs_vis = 0 # cursor invisible in prog mode - self.__cur_curs_vis = 1 # current cursor state + self.__cur_curs_vis = -1 # current cursor state self.__shell_mousemask = None self.ddmrecv = False # allow host-initiated ind$file get @@ -1483,6 +1487,17 @@ def __color_setup(self): self.__has_color = False + def __curs_vis(self, insmode): + if insmode: + curval = os.getenv("ZTI_CURSOR_INSERT", "") + else: + curval = os.getenv("ZTI_CURSOR_REPLACE", "") + + if curval.isdigit(): + return -int(curval)-1 + + return 2 if insmode else 1 + def __dirty_range(self, start, end, tns=None): """Mark a range of screen addresses as dirty. @@ -1978,7 +1993,7 @@ def __r2d2(self, win, waitc, timeout): if show: self.__prog_curs_vis = 0 else: - self.__prog_curs_vis = 1 + self.__prog_curs_vis = self.__curs_vis(False) tout = timeout if timeout > 0: @@ -2038,10 +2053,8 @@ def __r2d2(self, win, waitc, timeout): currow <= endy and curcol > begx and curcol <= endx): - if insmode: - self.__prog_curs_vis = 2 # very visible - else: - self.__prog_curs_vis = 1 # visible + curs_vis = self.__curs_vis(insmode) + self.__prog_curs_vis = curs_vis xpos, ypos = self.twin_loc _logger.debug("before win.move") @@ -2330,10 +2343,7 @@ def __r2d2(self, win, waitc, timeout): _logger.debug("keyed Insert") insmode = (not insmode) - if insmode: - self.__prog_curs_vis = 2 # very visible - else: - self.__prog_curs_vis = 1 # visible + self.__prog_curs_vis = self.__curs_vis(insmode) elif (cstr == "\x1b1" or # ESC+1 (Alt+1) cstr == "ALT_1" or # ESC+1 (Alt+1)