Subwindows with ncurses
Here is an example showing the main window with a subwindow:
#include <curses.h>
int main(int argc, char** argv)
{
initscr();
printw("Main window");
WINDOW* subwindow = newwin(10,20,5,15);
refresh();
box(subwindow,0,0);
mvwprintw(subwindow, 1, 1, "subwindow");
refresh();
wrefresh(subwindow);
getch();
delwin(subwindow);
endwin();
return 0;
}
Moving windows in ncurses
Apparently not: a quick check with Solaris 10 gives the same behavior. You might find some scenario where ncurses differs unintentionally, but this is not one of those. The FAQ makes this point about compatibility:
extensions (deviations from SVr4 curses) are allowed only if they do not modify the documented/observed behavior of the API.
The Solaris manual page does not make this clear, since the only mention of subwindows is in regard to moving them:
The
mvwin()
routine moves the window so that the upper left-hand corner is at position (x, y). If the move would cause the window to be off the screen, it is an error and the window is not moved. Moving subwindows is allowed, but should be avoided.
The Solaris source code tells the story for that: it does nothing with subwindows. Some retesting a while back (early 2006) in response to a user's comment about differences pointed out that ncurses was incorrectly attempting to copy subwindows. That part is ifdef'd out (since it's too interesting to just delete). Since there's not much left for mvwin
to do, the actual code is fairly similar.
X/Open's description of mvwin
is too brief and vague to be of any use.
ncurses: Subwin or subpad of a pad
Pads are not regular windows; you cannot make a window inside a pad.
The ncurses library makes these checks, which relate to the question:
- in
subpad
, it checks to ensure that the parent is a pad, and then callsderwin
to do the rest of the work. If the parent is not a pad,subpad
returns an error. subwin
usesderwin
, which ensures that if the parent is a pad, then the result is a pad. Either way, the result is the same type as the parent.
A pad does not exactly "share" memory with a window; it is just a convenient way to translate coordinates to a window.
Python Curses Backspace detection works in main window but not in subwindows
Subwindows don't inherit the keypad
setting. When you create a window, you'll have to set that, if you want to read keys that send "any" of the named KEY_
symbols.
Unable to associate an ncurses form with a window
Windows and pads are similar, but they are not the same. The set_form_win
function expects a window.
The newpad
manual page notes:
It is not legal to call wrefresh
with a pad as an argument; the routines prefresh or
pnoutrefresh should be called instead.
The form library does use pads — internally, for fields — but the windows are just that (no pads). The relevant functions are wcursyncup and wsyncup (it relies on wgetch
for the application for the actual wrefresh
calls).
How to delete a subwindow in the python curses module
Is there a good reason why you're using a subwindow? If you create a new top-level window then the code works correctly - simply change stdscr.subwin
to curses.newwin
and it works as you'd expect.
I'm not a curses expert, but I believe a subwindow shares the character buffer with its parent such that changes to either one will also affect the other. So, if you're looking to sub-divide a window into logical areas (perhaps a menu bar, main area and status bar) then subwindows are useful. If, however, you're looking for something more like a dialog box or pop-up menu then a whole new window (with its own separate buffer) is what you're after.
I can't find any definitive reference for ncurses which agrees or disagrees with me, but man page for AIX seems to corroborate it:
Recall that the subwindow shares its parent's window buffer. Changes made to the shared window buffer in the area covered by a subwindow, through either the parent window or any of its subwindows, affects all windows sharing the window buffer.
Of course, this isn't definitive for ncurses, but I can't find anything to the contrary and it certainly seems to explain the behaviour observed. I also did a crude experiment where, immediately after the subwin.getch()
line in your example, I added this line:
raise Exception(stdscr.instr(20, 15, 3))
In your example, I get JJJ
as the content of the actual main window. If I change to use curses.newwin()
to create the window instead of stdscr.subwin()
I get the expected MMM
.
I don't know how many specific Python curses resources there are, but most of the standard tutorials and documents about ncurses are quite useful for this sort of level. Back when I had to do some work in it, this document was quite useful. If you scroll down to the "An Example" section, you'll see that the menu pop-ups are not subwindows - he alludes to this with the following slightly vague explanation:
We don't want this new window to overwrite previously written characters on the background. They should stay there after the menu closes. This is why the menu window can't be created as a subwindow of stdscr.
Also, I remember that using both stdscr
and your own windows can cause issues - the "official" ncurses introduction has some warnings about this sort of thing. It also suggests avoiding overlapping windows entirely, as they're apparently error-prone, but I don't recall having any issues with them for short-term transient modal dialogs (which is the only use to which I put them). Of course, just because my simple use-case didn't expose any issues doesn't mean there aren't any. In something as complicated as ncurses, however, I can see the wisdom in keeping things as simple as you can.
I hope that's some help. As I said, I'm by no means a curses expert, but hopefully this gets you a few steps further along.
find out if cursor had been set in ncurses.h
It's in the manual page:
The
curs_set
routine sets the cursor state to invisible, normal, or
very visible for visibility equal to 0, 1, or 2 respectively. If the
terminal supports the visibility requested, the previous cursor state
is returned; otherwise,ERR
is returned.
Related Topics
Cmake: How to Change Properties on Subdirectory Project Targets
Does the Alignas Specifier Work with 'New'
Off-The-Shelf C++ Hex Dump Code
How to Call a C++ Method from C
Writing X264 from Opencv 3 with Ffmpeg on Linux
Returning VS. Using a Reference Parameter
How to Use External Dlls in Cmake Project
Is There Any Function Equivalent to Matlab's Imadjust in Opencv with C++
Why Is '"Literal"' Encouraged to Decay to 'Const Char*' in C++ Argument Type Match
Adding Header and .Cpp Files in a Project Built with Cmake
C++ Get String from Clipboard on Linux
What Is a Possible Workaround for Object Slicing in C++
Initializing Map of Maps with Initializer List in VS 2013
Can Virtual Functions Be Constexpr