Rename tui_suppress_output

This patch renames tui_suppress_output to the more descriptive
tui_batch_rendering.  This code was never really correct, and was
based on a misunderstanding of the curses API.  The updated comments
describe the intended use of this class.

This also removes the erroneous tui_win_info::no_refresh.
wnoutrefresh does not prevent any output; rather, it copies from one
curses buffer to another but (unlike woutrefresh) without then
flushing to the screen.

tui_batch_rendering now works in the correct way: calling doupdate in
the destructor of the outermost instance, thus batching all screen
output until that point.

The patch adds instantiations of tui_batch_rendering to various spots,
to make sure it is active when refreshing.
This commit is contained in:
Tom Tromey
2023-12-17 12:52:33 -07:00
parent 8f934adf59
commit d3acf3d759
9 changed files with 32 additions and 36 deletions

View File

@@ -180,6 +180,8 @@ tui_py_window::~tui_py_window ()
void void
tui_py_window::rerender () tui_py_window::rerender ()
{ {
tui_batch_rendering batch;
tui_win_info::rerender (); tui_win_info::rerender ();
gdbpy_enter enter_py; gdbpy_enter enter_py;
@@ -206,6 +208,8 @@ tui_py_window::rerender ()
void void
tui_py_window::do_scroll_horizontal (int num_to_scroll) tui_py_window::do_scroll_horizontal (int num_to_scroll)
{ {
tui_batch_rendering batch;
gdbpy_enter enter_py; gdbpy_enter enter_py;
if (PyObject_HasAttrString (m_window.get (), "hscroll")) if (PyObject_HasAttrString (m_window.get (), "hscroll"))
@@ -220,6 +224,8 @@ tui_py_window::do_scroll_horizontal (int num_to_scroll)
void void
tui_py_window::do_scroll_vertical (int num_to_scroll) tui_py_window::do_scroll_vertical (int num_to_scroll)
{ {
tui_batch_rendering batch;
gdbpy_enter enter_py; gdbpy_enter enter_py;
if (PyObject_HasAttrString (m_window.get (), "vscroll")) if (PyObject_HasAttrString (m_window.get (), "vscroll"))
@@ -242,6 +248,8 @@ tui_py_window::resize (int height_, int width_, int origin_x_, int origin_y_)
void void
tui_py_window::click (int mouse_x, int mouse_y, int mouse_button) tui_py_window::click (int mouse_x, int mouse_y, int mouse_button)
{ {
tui_batch_rendering batch;
gdbpy_enter enter_py; gdbpy_enter enter_py;
if (PyObject_HasAttrString (m_window.get (), "click")) if (PyObject_HasAttrString (m_window.get (), "click"))
@@ -258,6 +266,8 @@ tui_py_window::output (const char *text, bool full_window)
{ {
if (m_inner_window != nullptr) if (m_inner_window != nullptr)
{ {
tui_batch_rendering batch;
if (full_window) if (full_window)
werase (m_inner_window.get ()); werase (m_inner_window.get ());

View File

@@ -117,13 +117,6 @@ public:
return true; return true;
} }
/* Disable output until the next call to doupdate. */
void no_refresh ()
{
if (handle != nullptr)
wnoutrefresh (handle.get ());
}
/* Called after the tab width has been changed. */ /* Called after the tab width has been changed. */
virtual void update_tab_width () virtual void update_tab_width ()
{ {

View File

@@ -61,6 +61,8 @@ std::vector<tui_win_info *> tui_windows;
void void
tui_apply_current_layout (bool preserve_cmd_win_size_p) tui_apply_current_layout (bool preserve_cmd_win_size_p)
{ {
tui_batch_rendering defer;
for (tui_win_info *win_info : tui_windows) for (tui_win_info *win_info : tui_windows)
win_info->make_visible (false); win_info->make_visible (false);

View File

@@ -492,11 +492,11 @@ tui_reg_command (const char *args, int from_tty)
{ {
size_t len = strlen (args); size_t len = strlen (args);
tui_batch_rendering suppress;
/* Make sure the curses mode is enabled. */ /* Make sure the curses mode is enabled. */
tui_enable (); tui_enable ();
tui_suppress_output suppress;
/* Make sure the register window is visible. If not, select an /* Make sure the register window is visible. If not, select an
appropriate layout. We need to do this before trying to run the appropriate layout. We need to do this before trying to run the
'next' or 'prev' commands. */ 'next' or 'prev' commands. */

View File

@@ -473,11 +473,7 @@ void
tui_refresh_all_win (void) tui_refresh_all_win (void)
{ {
clearok (curscr, TRUE); clearok (curscr, TRUE);
for (tui_win_info *win_info : all_tui_windows ()) doupdate ();
{
if (win_info->is_visible ())
win_info->refresh_window ();
}
} }
void void

View File

@@ -27,33 +27,27 @@
#include "gdb_curses.h" #include "gdb_curses.h"
/* This is true if we're currently suppressing output, via /* This is true when there is a live instance of tui_batch_rendering.
wnoutrefresh. This is needed in case we create a new window while The outermost tui_batch_rendering will cause a flush to the
in this mode. */ screen. */
static bool suppress_output; static bool suppress_output;
/* See tui-data.h. */ /* See tui-data.h. */
tui_suppress_output::tui_suppress_output () tui_batch_rendering::tui_batch_rendering ()
: m_saved_suppress (suppress_output) : m_saved_suppress (suppress_output)
{ {
suppress_output = true; suppress_output = true;
for (const auto &win : all_tui_windows ())
win->no_refresh ();
} }
/* See tui-data.h. */ /* See tui-data.h. */
tui_suppress_output::~tui_suppress_output () tui_batch_rendering::~tui_batch_rendering ()
{ {
suppress_output = m_saved_suppress; suppress_output = m_saved_suppress;
if (!suppress_output) if (!suppress_output)
doupdate (); doupdate ();
for (const auto &win : all_tui_windows ())
win->refresh_window ();
} }
/* See tui-data.h. */ /* See tui-data.h. */
@@ -61,8 +55,7 @@ tui_suppress_output::~tui_suppress_output ()
void void
tui_wrefresh (WINDOW *win) tui_wrefresh (WINDOW *win)
{ {
if (!suppress_output) wnoutrefresh (win);
wrefresh (win);
} }
/* See tui-data.h. */ /* See tui-data.h. */

View File

@@ -29,18 +29,20 @@ struct tui_win_info;
extern void tui_unhighlight_win (struct tui_win_info *); extern void tui_unhighlight_win (struct tui_win_info *);
extern void tui_highlight_win (struct tui_win_info *); extern void tui_highlight_win (struct tui_win_info *);
/* An RAII class that suppresses output on construction (calling /* An RAII class that calls doupdate on destruction (really the
wnoutrefresh on the existing windows), and then flushes the output destruction of the outermost instance). This is used to prevent
(via doupdate) when destroyed. */ flickering -- window implementations should only call wnoutrefresh,
and any time rendering is needed, an object of this type should be
instantiated. */
class tui_suppress_output class tui_batch_rendering
{ {
public: public:
tui_suppress_output (); tui_batch_rendering ();
~tui_suppress_output (); ~tui_batch_rendering ();
DISABLE_COPY_AND_ASSIGN (tui_suppress_output); DISABLE_COPY_AND_ASSIGN (tui_batch_rendering);
private: private:

View File

@@ -343,7 +343,7 @@ tui_source_window_base::refresh_window ()
int smincol = x + box_width () + left_margin; int smincol = x + box_width () + left_margin;
int smaxrow = sminrow + m_content.size () - 1; int smaxrow = sminrow + m_content.size () - 1;
int smaxcol = smincol + view_width - 1; int smaxcol = smincol + view_width - 1;
prefresh (m_pad.get (), 0, pad_x, sminrow, smincol, smaxrow, smaxcol); pnoutrefresh (m_pad.get (), 0, pad_x, sminrow, smincol, smaxrow, smaxcol);
} }
void void

View File

@@ -568,7 +568,7 @@ tui_disable_command (const char *args, int from_tty)
void void
tui_show_assembly (struct gdbarch *gdbarch, CORE_ADDR addr) tui_show_assembly (struct gdbarch *gdbarch, CORE_ADDR addr)
{ {
tui_suppress_output suppress; tui_batch_rendering suppress;
tui_add_win_to_layout (DISASSEM_WIN); tui_add_win_to_layout (DISASSEM_WIN);
tui_update_source_windows_with_addr (gdbarch, addr); tui_update_source_windows_with_addr (gdbarch, addr);
} }