object for the derived window.
+.. method:: window.dupwin()
+
+ Return a new window that is an exact duplicate of the window: it has the same
+ size, position, contents and attributes. Unlike a window created by
+ :meth:`subwin` or :meth:`derwin`, the duplicate is independent of the
+ original -- it has its own cell buffer, so later changes to one do not affect
+ the other.
+
+ .. versionadded:: next
+
+
.. method:: window.echochar(ch[, attr])
Add character *ch* with attribute *attr*, and immediately call :meth:`refresh`
accept a :class:`~curses.complexstr`.
(Contributed by Serhiy Storchaka in :gh:`152233`.)
+* Add the :mod:`curses` window method :meth:`~curses.window.dupwin`, which
+ returns a new window that is an independent duplicate of an existing one.
+ (Contributed by Serhiy Storchaka in :gh:`152258`.)
+
gzip
----
del win2
gc_collect()
+ def test_dupwin(self):
+ win = curses.newwin(5, 10, 2, 3)
+ win.addstr(0, 0, 'ABCDE')
+ win.addstr(1, 0, 'fghij')
+ dup = win.dupwin()
+ # Same geometry and contents as the original.
+ self.assertEqual(dup.getbegyx(), win.getbegyx())
+ self.assertEqual(dup.getmaxyx(), win.getmaxyx())
+ self.assertEqual(dup.instr(0, 0, 5), b'ABCDE')
+ self.assertEqual(dup.instr(1, 0, 5), b'fghij')
+ # The duplicate is independent, not a subwindow.
+ if hasattr(dup, 'is_subwin'):
+ self.assertIs(dup.is_subwin(), False)
+ self.assertIsNone(dup.getparent())
+ # Changes to one do not affect the other.
+ dup.addstr(0, 0, 'xxxxx')
+ win.addstr(1, 0, 'YYYYY')
+ self.assertEqual(win.instr(0, 0, 5), b'ABCDE')
+ self.assertEqual(dup.instr(0, 0, 5), b'xxxxx')
+ self.assertEqual(dup.instr(1, 0, 5), b'fghij')
+ self.assertEqual(win.instr(1, 0, 5), b'YYYYY')
+ # A subwindow can also be duplicated; the duplicate is independent.
+ sub = win.subwin(3, 5, 2, 3)
+ subdup = sub.dupwin()
+ self.assertEqual(subdup.getmaxyx(), sub.getmaxyx())
+ if hasattr(subdup, 'is_subwin'):
+ self.assertIs(subdup.is_subwin(), False)
+ self.assertIsNone(subdup.getparent())
+
def test_move_cursor(self):
stdscr = self.stdscr
win = stdscr.subwin(10, 15, 2, 5)
--- /dev/null
+Add the :mod:`curses` window method :meth:`~curses.window.dupwin`, which
+returns a new window that is an independent duplicate of an existing one.
Here's a list of currently unsupported functions:
addchnstr addchstr color_set define_key
- del_curterm dupwin inchnstr inchstr innstr keyok
+ del_curterm inchnstr inchstr innstr keyok
mcprint mvaddchnstr mvaddchstr mvcur mvinchnstr
mvinchstr mvinnstr mmvwaddchnstr mvwaddchstr
mvwinchnstr mvwinchstr mvwinnstr
return PyCursesWindow_New(state, win, NULL, self, self->screen);
}
+/*[clinic input]
+_curses.window.dupwin
+
+Create an exact duplicate of the window.
+
+The new window is independent of the original: it has the same size,
+position, contents and attributes, but its own cell buffer, so later
+changes to one do not affect the other.
+[clinic start generated code]*/
+
+static PyObject *
+_curses_window_dupwin_impl(PyCursesWindowObject *self)
+/*[clinic end generated code: output=37d91aa8f88f13d1 input=787301b3799b618e]*/
+{
+ WINDOW *win = dupwin(self->win);
+ if (win == NULL) {
+ curses_window_set_null_error(self, "dupwin", NULL);
+ return NULL;
+ }
+
+ /* The duplicate owns an independent cell buffer (unlike a subwindow), so
+ it has no parent: pass NULL as orig. Inherit the source encoding and
+ screen so it matches the original. */
+ cursesmodule_state *state = get_cursesmodule_state_by_win(self);
+ return PyCursesWindow_New(state, win, self->encoding, NULL, self->screen);
+}
+
/*[clinic input]
_curses.window.echochar
"deleteln($self, /)\n--\n\n"
"Delete the line under the cursor; move following lines up by one."},
_CURSES_WINDOW_DERWIN_METHODDEF
+ _CURSES_WINDOW_DUPWIN_METHODDEF
_CURSES_WINDOW_ECHOCHAR_METHODDEF
_CURSES_WINDOW_ENCLOSE_METHODDEF
{"erase", PyCursesWindow_werase, METH_NOARGS,
return return_value;
}
+PyDoc_STRVAR(_curses_window_dupwin__doc__,
+"dupwin($self, /)\n"
+"--\n"
+"\n"
+"Create an exact duplicate of the window.\n"
+"\n"
+"The new window is independent of the original: it has the same size,\n"
+"position, contents and attributes, but its own cell buffer, so later\n"
+"changes to one do not affect the other.");
+
+#define _CURSES_WINDOW_DUPWIN_METHODDEF \
+ {"dupwin", (PyCFunction)_curses_window_dupwin, METH_NOARGS, _curses_window_dupwin__doc__},
+
+static PyObject *
+_curses_window_dupwin_impl(PyCursesWindowObject *self);
+
+static PyObject *
+_curses_window_dupwin(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ return _curses_window_dupwin_impl((PyCursesWindowObject *)self);
+}
+
PyDoc_STRVAR(_curses_window_echochar__doc__,
"echochar(ch, [attr])\n"
"Add character ch with attribute attr, and refresh.\n"
#ifndef _CURSES_ASSUME_DEFAULT_COLORS_METHODDEF
#define _CURSES_ASSUME_DEFAULT_COLORS_METHODDEF
#endif /* !defined(_CURSES_ASSUME_DEFAULT_COLORS_METHODDEF) */
-/*[clinic end generated code: output=7940d7d4775b58fd input=a9049054013a1b77]*/
+/*[clinic end generated code: output=9d7ca194927796d8 input=a9049054013a1b77]*/