Re: [Tutor] How to use "curses.resizeterm(nlines, ncols)"

2019-02-24 Thread boB Stepp
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)"

2019-02-24 Thread Mats Wichmann


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)"

2019-02-24 Thread Cameron Simpson

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)"

2019-02-24 Thread boB Stepp
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)"

2019-02-24 Thread boB Stepp
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)"

2019-02-24 Thread Cameron Simpson

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)"

2019-02-24 Thread Mark Lawrence

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)"

2019-02-24 Thread Cameron Simpson

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)"

2019-02-24 Thread Mats Wichmann

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)"

2019-02-24 Thread boB Stepp
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)"

2019-02-24 Thread Alan Gauld via Tutor
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