Re: [Tutor] How to use "curses.resizeterm(nlines, ncols)"
On Sun, Feb 24, 2019 at 4:40 PM Cameron Simpson wrote: > I've modified your script. Please try the script appended below. The > short answer is that resizeterm() is _not_ normally useful to you, the > programmer; it will only be useful if curses does not get to notice > terminal size changes - _then_ you could use it to provide that > facility. > > The script below is like yours: 'q' to quit, other keys to refresh and > retest. Notice that the version below does not update (max_y,max_x) or > call resizeterm(); initially you want to see what is_term_resized() > does. It also shows you what got tested. > #!/usr/bin/env python3 > > import curses > > def start_cli(stdscr): > max_y, max_x = stdscr.getmaxyx() > stdscr.clear() > stdscr.border() > stdscr.addstr(2, 2, "This is the beginning!") > stdscr.refresh() > while True: > char = chr(stdscr.getch()) > if char in 'Qq': > return > tested = "is_term_resized(max_x=%d, max_y=%d)" % (max_x, max_y) > internal = "getmaxyx() => y=%d, x=%d" % stdscr.getmaxyx() > resized = curses.is_term_resized(max_y, max_x) > result = "%s => %s" % (tested, resized) > stdscr.clear() > stdscr.addstr(max_y//2, max_x//2, result) > stdscr.addstr(max_y//2 + 1, max_x//2, internal) > if curses.is_term_resized(max_y, max_x): > ##max_y, max_x = stdscr.getmaxyx() > stdscr.addstr(max_y//2 + 2, max_x//2, "You resized the terminal!") > ##stdscr.addstr(max_y//2 + 2, max_x//2, "Resizing your window -- > NOW!") > ##curses.resizeterm(max_y, max_x) > else: > stdscr.addstr(max_y//2 + 2, max_x//2, "Not resized.") > stdscr.border() > stdscr.refresh() > > if __name__ == '__main__': > curses.wrapper(start_cli) While playing around with the above as I manually resized the terminal window I noticed the program crashing with a curses.ERR exception if I shrank the window so much that the program could not place the text at the programmed coordinates. This makes sense. But, as usual, this has gotten me to wonder that if I ever use curses to write a program that others would be using if it is worthwhile to at least warn the users against overly shrinking their terminal window or somehow trying to handle the resulting exception? Or does such a user "deserve" what he/she gets? ~(:>)) -- boB ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to use "curses.resizeterm(nlines, ncols)"
All is is_term_resized, resizeterm and the "internal" resize_term functions are recent additions :-) From "man 3 resizeterm": This extension of ncurses was introduced in mid-1995. It was adopted in NetBSD curses (2001) and PDCurses (2003). For some definition of "recent" :) I have an odd relationship with curses, I was at UC Berkeley when Ken Arnold adapted it from bits of Bill Joy's vi - "we" needed a terminal-independent way to address things when the ADM3A terminal and a bit later the HP 2621 turned up, making such programming possible (he needed it for rogue, as I reacall); the version of curses we all use now was shepharded by Pavel Curtis, a classmate of mine from Berkeley High School. That said I don't know any magic stories... a number of Python modules have made an easier to use interface to a popular library but curses seems to be pretty much a direct transliteration, warts and all. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to use "curses.resizeterm(nlines, ncols)"
On 24Feb2019 17:48, boB Stepp wrote: On Sun, Feb 24, 2019 at 2:52 PM Mats Wichmann wrote: If it's snippets you want, I always look at programcreek. These are always part of something bigger so they may not fit your request to have them be something you can run. https://www.programcreek.com/python/example/57429/curses.is_term_resized Thanks for the link! It looks useful for future research! Seconded. I did not know about this either! However, in the context of the current discussion, especially after Cameron's revelations, I cannot help but wonder if the writers of the three code snippets did not truly understand resizeterm()? Especially the first example is very similar to my testing script. But I did not go to the full-fledge programs to see if there was something unusual going on, so I may be overly harsh is my first impression. I think the first two snippets definitely don't. The third I'm less sure about. resizeterm is easy to misunderstand. Anyway, I should add a few remarks: 1: the use case for resizeterm() is for when curses has not noticed a resize. This can happen in remote terminal environments or where for some very weird reason the curses programme isn't in the terminal's control group. Most remote facilities (eg ssh and telnet) try to propagate terminal resize information, so remote curses stays informed. 2: much more useful is is_term_resized(). Many curses programmes need to know the termianl size (from getmaxyx()) in order to size their output (crop long lines, scale subwindows, what have you). So you might reasonably keep a copy of the result of getmaxyx() at the start of the programme: tty_y, tty_x = getmaxyx() and then call: if is_term_resized(tty_y, tty_x): # update size tty_y, tty_x = getmaxyx() # recompute the sizes for various displayed things # redisplay everything... at suitable times, because is_term_resized() is exactly for checking if the actual size (known by curses) matches some notional size (tty_y, tty_x, known by you, the programmer). All is is_term_resized, resizeterm and the "internal" resize_term functions are recent additions :-) From "man 3 resizeterm": This extension of ncurses was introduced in mid-1995. It was adopted in NetBSD curses (2001) and PDCurses (2003). Cheers, Cameron Simpson ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to use "curses.resizeterm(nlines, ncols)"
On Sun, Feb 24, 2019 at 2:52 PM Mats Wichmann wrote: > > On 2/24/19 1:30 PM, boB Stepp wrote: > > > So what am I misunderstanding? Can someone show me a code snippet > > that I can run which will demonstrate the usefulness and usage of > > curses.resizeterm()? > > > > TIA! > > > > If it's snippets you want, I always look at programcreek. These are > always part of something bigger so they may not fit your request to have > them be something you can run. > > https://www.programcreek.com/python/example/57429/curses.is_term_resized Thanks for the link! It looks useful for future research! However, in the context of the current discussion, especially after Cameron's revelations, I cannot help but wonder if the writers of the three code snippets did not truly understand resizeterm()? Especially the first example is very similar to my testing script. But I did not go to the full-fledge programs to see if there was something unusual going on, so I may be overly harsh is my first impression. -- boB ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to use "curses.resizeterm(nlines, ncols)"
On Sun, Feb 24, 2019 at 4:40 PM Cameron Simpson wrote: > > On 24Feb2019 14:30, boB Stepp wrote: > >What you say makes sense and supports much of what I had concluded > >from my coding experiments. However, I still cannot get the function > >call, curses.resizeterm(), to do anything meaningful, which suggests > >that I still do not truly understand its usage. > > Likely so. The important thing you may be missing is that curses > _itself_ calls resizeterm() automatically when it gets a SIGWINCH, so in > normal situations you do not need to call this function. AHA! It is exactly that. How am I to know this from reading the existing Python 3 docs??? I spent *much* time trying different coding efforts to get resizeterm() to do something, ANYTHING, when all along this was happening automatically behind the scenes. > Because of this, getmaxyx() is always correct for the size of the > terminal. > > Secondarily, resizeterm() does not make a change to the terminal itself. I realized this before I sent my original post. I really think the name chosen, resizeterm, is a very misleading name! > >I created the > >following script to test things out: > [...] > > I've modified your script. Please try the script appended below. The > short answer is that resizeterm() is _not_ normally useful to you, the > programmer; it will only be useful if curses does not get to notice > terminal size changes - _then_ you could use it to provide that > facility. Thanks for the additional clarity provided with your modifications! boB ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to use "curses.resizeterm(nlines, ncols)"
On 24Feb2019 22:51, Mark Lawrence wrote: As I know squat about the curses module is this a time when a bug report could be put into the docs to clarify things, or do you have to know something about curses before you try using the Python wrapper? Well, both. The Python curses module is mostly a thin shim around the curses(3) C library. So the real semantics come from that; the Python module doco test closely resembles the text from the curses(3) manual entry (what you get from the "man 3 curses" command). The curses(3) manual entry (well, ncurses on my Mac here) says: The ncurses library includes facilities for responding to window resizing events, e.g., when running in an xterm. See the resizeterm(3X) and wresize(3X) manual pages for details. In addition, the library may be configured with a SIGWINCH handler. and resizeterm(3) says in part: resizeterm The function resizeterm resizes the standard and current windows to the specified dimensions, and adjusts other bookkeeping data used by the ncurses library that record the window dimensions such as the LINES and COLS variables. However, since people using the Python module might reasonably be expected to know less than those using the C library directly it would be useful to make it more clear that resizeterm() is essentailly "tell curses the terminal size" function, not a "make the terminal a specific size" function, and that because curses normally notices changes automatically then it is uncommon to need to call resizeterm(). Cheers, Cameron Simpson ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to use "curses.resizeterm(nlines, ncols)"
On 24/02/2019 22:39, Cameron Simpson wrote: On 24Feb2019 14:30, boB Stepp wrote: On Sun, Feb 24, 2019 at 1:39 AM Cameron Simpson wrote: It looks like the resizeterm() function updates the curses _internal_ records of what it believes the physcial terminal size to be. When you physically resize a terminal the processes within it receive a SIGWINCH signal, and those which pay attention to that signal should then consult the terminal to find out its new size. The curses library notices this signal, and calls resizeterm() to update its own internal idea of the terminal size so that it knows how to draw correctly on the screen. It does _not_ change the terminal; it changes curses' beliefs _about_ the terminal. [...] The is_term_resized() function looks up the current physical size and reports False if that matches curses current beliefs, and True if it does not match, meaning that the physical size has changed since curses last set up its beliefs [...] What you say makes sense and supports much of what I had concluded from my coding experiments. However, I still cannot get the function call, curses.resizeterm(), to do anything meaningful, which suggests that I still do not truly understand its usage. Likely so. The important thing you may be missing is that curses _itself_ calls resizeterm() automatically when it gets a SIGWINCH, so in normal situations you do not need to call this function. Because of this, getmaxyx() is always correct for the size of the terminal. Secondarily, resizeterm() does not make a change to the terminal itself. Note that is_term_resized(y,x) is a _test_: it asks whether curses' idea of the screen size does not match (y,x). (y,x) is a pair of numbers that _you_, the programmer, is keeping track of. If you set it once at the start of the programme: max_y, max_x = stdscr.getmaxyx() and never update it then is_term_resized(max_y, max_x) will report True if the terminal has changed size. If you update the (max_y,max_x) values regularly from getmaxyx() then they will always match and is_term_resized will always report False. I created the following script to test things out: [...] I've modified your script. Please try the script appended below. The short answer is that resizeterm() is _not_ normally useful to you, the programmer; it will only be useful if curses does not get to notice terminal size changes - _then_ you could use it to provide that facility. The script below is like yours: 'q' to quit, other keys to refresh and retest. Notice that the version below does not update (max_y,max_x) or call resizeterm(); initially you want to see what is_term_resized() does. It also shows you what got tested. Cheers, Cameron Simpson #!/usr/bin/env python3 import curses def start_cli(stdscr): max_y, max_x = stdscr.getmaxyx() stdscr.clear() stdscr.border() stdscr.addstr(2, 2, "This is the beginning!") stdscr.refresh() while True: char = chr(stdscr.getch()) if char in 'Qq': return tested = "is_term_resized(max_x=%d, max_y=%d)" % (max_x, max_y) internal = "getmaxyx() => y=%d, x=%d" % stdscr.getmaxyx() resized = curses.is_term_resized(max_y, max_x) result = "%s => %s" % (tested, resized) stdscr.clear() stdscr.addstr(max_y//2, max_x//2, result) stdscr.addstr(max_y//2 + 1, max_x//2, internal) if curses.is_term_resized(max_y, max_x): ##max_y, max_x = stdscr.getmaxyx() stdscr.addstr(max_y//2 + 2, max_x//2, "You resized the terminal!") ##stdscr.addstr(max_y//2 + 2, max_x//2, "Resizing your window -- NOW!") ##curses.resizeterm(max_y, max_x) else: stdscr.addstr(max_y//2 + 2, max_x//2, "Not resized.") stdscr.border() stdscr.refresh() if __name__ == '__main__': curses.wrapper(start_cli) As I know squat about the curses module is this a time when a bug report could be put into the docs to clarify things, or do you have to know something about curses before you try using the Python wrapper? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to use "curses.resizeterm(nlines, ncols)"
On 24Feb2019 14:30, boB Stepp wrote: On Sun, Feb 24, 2019 at 1:39 AM Cameron Simpson wrote: It looks like the resizeterm() function updates the curses _internal_ records of what it believes the physcial terminal size to be. When you physically resize a terminal the processes within it receive a SIGWINCH signal, and those which pay attention to that signal should then consult the terminal to find out its new size. The curses library notices this signal, and calls resizeterm() to update its own internal idea of the terminal size so that it knows how to draw correctly on the screen. It does _not_ change the terminal; it changes curses' beliefs _about_ the terminal. [...] The is_term_resized() function looks up the current physical size and reports False if that matches curses current beliefs, and True if it does not match, meaning that the physical size has changed since curses last set up its beliefs [...] What you say makes sense and supports much of what I had concluded from my coding experiments. However, I still cannot get the function call, curses.resizeterm(), to do anything meaningful, which suggests that I still do not truly understand its usage. Likely so. The important thing you may be missing is that curses _itself_ calls resizeterm() automatically when it gets a SIGWINCH, so in normal situations you do not need to call this function. Because of this, getmaxyx() is always correct for the size of the terminal. Secondarily, resizeterm() does not make a change to the terminal itself. Note that is_term_resized(y,x) is a _test_: it asks whether curses' idea of the screen size does not match (y,x). (y,x) is a pair of numbers that _you_, the programmer, is keeping track of. If you set it once at the start of the programme: max_y, max_x = stdscr.getmaxyx() and never update it then is_term_resized(max_y, max_x) will report True if the terminal has changed size. If you update the (max_y,max_x) values regularly from getmaxyx() then they will always match and is_term_resized will always report False. I created the following script to test things out: [...] I've modified your script. Please try the script appended below. The short answer is that resizeterm() is _not_ normally useful to you, the programmer; it will only be useful if curses does not get to notice terminal size changes - _then_ you could use it to provide that facility. The script below is like yours: 'q' to quit, other keys to refresh and retest. Notice that the version below does not update (max_y,max_x) or call resizeterm(); initially you want to see what is_term_resized() does. It also shows you what got tested. Cheers, Cameron Simpson #!/usr/bin/env python3 import curses def start_cli(stdscr): max_y, max_x = stdscr.getmaxyx() stdscr.clear() stdscr.border() stdscr.addstr(2, 2, "This is the beginning!") stdscr.refresh() while True: char = chr(stdscr.getch()) if char in 'Qq': return tested = "is_term_resized(max_x=%d, max_y=%d)" % (max_x, max_y) internal = "getmaxyx() => y=%d, x=%d" % stdscr.getmaxyx() resized = curses.is_term_resized(max_y, max_x) result = "%s => %s" % (tested, resized) stdscr.clear() stdscr.addstr(max_y//2, max_x//2, result) stdscr.addstr(max_y//2 + 1, max_x//2, internal) if curses.is_term_resized(max_y, max_x): ##max_y, max_x = stdscr.getmaxyx() stdscr.addstr(max_y//2 + 2, max_x//2, "You resized the terminal!") ##stdscr.addstr(max_y//2 + 2, max_x//2, "Resizing your window -- NOW!") ##curses.resizeterm(max_y, max_x) else: stdscr.addstr(max_y//2 + 2, max_x//2, "Not resized.") stdscr.border() stdscr.refresh() if __name__ == '__main__': curses.wrapper(start_cli) ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to use "curses.resizeterm(nlines, ncols)"
On 2/24/19 1:30 PM, boB Stepp wrote: So what am I misunderstanding? Can someone show me a code snippet that I can run which will demonstrate the usefulness and usage of curses.resizeterm()? TIA! If it's snippets you want, I always look at programcreek. These are always part of something bigger so they may not fit your request to have them be something you can run. https://www.programcreek.com/python/example/57429/curses.is_term_resized (I didn't get any hits when I tried resizeterm directly, even though the calls are there...) ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to use "curses.resizeterm(nlines, ncols)"
On Sun, Feb 24, 2019 at 1:39 AM Cameron Simpson wrote: > It looks like the resizeterm() function updates the curses _internal_ > records of what it believes the physcial terminal size to be. When you > physically resize a terminal the processes within it receive a SIGWINCH > signal, and those which pay attention to that signal should then consult > the terminal to find out its new size. > > The curses library notices this signal, and calls resizeterm() to update > its own internal idea of the terminal size so that it knows how to draw > correctly on the screen. It does _not_ change the terminal; it changes > curses' beliefs _about_ the terminal. > > If you call resizeterm() yourself you will cause curses to act from then > on as though the physcial terminal has the size you supplied. That may > make for bad rendering if that size does not match reality (consider > cursor motions "from the right edge" or "from the bottom edge" - their > sizes are computed from where curses thinks those edges are). > > Test the function curses.is_term_resized(nlines,ncols), whose doco says: > > Return True if resize_term() would modify the window structure, False > otherwise. > > The is_term_resized() function looks up the current physical size and > reports False if that matches curses current beliefs, and True if it > does not match, meaning that the physical size has changed since curses > last set up its beliefs (for example, in some environment where the > resize _doesn't_ propagate a SIGWINCH to the process using curses, so it > hasn't noticed). > > Does this clarify things for you? What you say makes sense and supports much of what I had concluded from my coding experiments. However, I still cannot get the function call, curses.resizeterm(), to do anything meaningful, which suggests that I still do not truly understand its usage. I created the following script to test things out: #!/usr/bin/env python3 import curses def start_cli(stdscr): max_y, max_x = stdscr.getmaxyx() stdscr.clear() stdscr.border() stdscr.addstr(2, 2, "This is the beginning!") stdscr.refresh() while True: char = chr(stdscr.getch()) if char in 'Qq': return if curses.is_term_resized(max_y, max_x): max_y, max_x = stdscr.getmaxyx() stdscr.clear() stdscr.addstr(max_y//2, max_x//2, "You resized the terminal!") stdscr.addstr(max_y//2 + 1, max_x//2, "Resizing your window -- NOW!") #curses.resizeterm(max_y, max_x) stdscr.border() stdscr.refresh() if __name__ == '__main__': curses.wrapper(start_cli) Notice that I have "curses.resizeterm( ..." commented out. Whether I comment it out or leave it in, the behavior I observe while manually resizing my terminal window is the same. The stdscr.border() still tracks around the limits of the full terminal screen size. I had also tried not adding stdscr.border() in the if block, thinking that maybe curses.resizeterm() would redraw the border once I refreshed the screen, but that did not happen. So what am I misunderstanding? Can someone show me a code snippet that I can run which will demonstrate the usefulness and usage of curses.resizeterm()? TIA! -- boB ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to use "curses.resizeterm(nlines, ncols)"
On 24/02/2019 05:00, boB Stepp wrote: > curses.resizeterm(nlines, ncols)¶ > > Resize the standard and current windows to the specified dimensions, > and adjusts other bookkeeping data used by the curses library that > record the window dimensions (in particular the SIGWINCH handler). > > > After much experimentation -- to no good effect -- I have concluded > that "resizeterm" does *not* mean resize the terminal window that the > curses program is running within. Correct. curses knows nothing about the GUI window. Curses is a windowing toolkit for use inside a standard 24x80 text terminal. You can have multiple small windows inside the screen and move/resize them. Each one can have its own individual textual content. It is how we built forms based applications before GUIs were invented. Nowadays it's mostly used for screen and cursor control within the single main window. (A similar graphical text style framework on DOS was TurboVision by Borland). If you used curses to draw a border round your window then call resizeterm you might see something happening... -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor