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
tui_py_window::rerender ()
{
tui_batch_rendering batch;
tui_win_info::rerender ();
gdbpy_enter enter_py;
@@ -206,6 +208,8 @@ tui_py_window::rerender ()
void
tui_py_window::do_scroll_horizontal (int num_to_scroll)
{
tui_batch_rendering batch;
gdbpy_enter enter_py;
if (PyObject_HasAttrString (m_window.get (), "hscroll"))
@@ -220,6 +224,8 @@ tui_py_window::do_scroll_horizontal (int num_to_scroll)
void
tui_py_window::do_scroll_vertical (int num_to_scroll)
{
tui_batch_rendering batch;
gdbpy_enter enter_py;
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
tui_py_window::click (int mouse_x, int mouse_y, int mouse_button)
{
tui_batch_rendering batch;
gdbpy_enter enter_py;
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)
{
tui_batch_rendering batch;
if (full_window)
werase (m_inner_window.get ());

View File

@@ -117,13 +117,6 @@ public:
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. */
virtual void update_tab_width ()
{

View File

@@ -61,6 +61,8 @@ std::vector<tui_win_info *> tui_windows;
void
tui_apply_current_layout (bool preserve_cmd_win_size_p)
{
tui_batch_rendering defer;
for (tui_win_info *win_info : tui_windows)
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);
tui_batch_rendering suppress;
/* Make sure the curses mode is enabled. */
tui_enable ();
tui_suppress_output suppress;
/* Make sure the register window is visible. If not, select an
appropriate layout. We need to do this before trying to run the
'next' or 'prev' commands. */

View File

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

View File

@@ -27,33 +27,27 @@
#include "gdb_curses.h"
/* This is true if we're currently suppressing output, via
wnoutrefresh. This is needed in case we create a new window while
in this mode. */
/* This is true when there is a live instance of tui_batch_rendering.
The outermost tui_batch_rendering will cause a flush to the
screen. */
static bool suppress_output;
/* See tui-data.h. */
tui_suppress_output::tui_suppress_output ()
tui_batch_rendering::tui_batch_rendering ()
: m_saved_suppress (suppress_output)
{
suppress_output = true;
for (const auto &win : all_tui_windows ())
win->no_refresh ();
}
/* See tui-data.h. */
tui_suppress_output::~tui_suppress_output ()
tui_batch_rendering::~tui_batch_rendering ()
{
suppress_output = m_saved_suppress;
if (!suppress_output)
doupdate ();
for (const auto &win : all_tui_windows ())
win->refresh_window ();
}
/* See tui-data.h. */
@@ -61,8 +55,7 @@ tui_suppress_output::~tui_suppress_output ()
void
tui_wrefresh (WINDOW *win)
{
if (!suppress_output)
wrefresh (win);
wnoutrefresh (win);
}
/* 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_highlight_win (struct tui_win_info *);
/* An RAII class that suppresses output on construction (calling
wnoutrefresh on the existing windows), and then flushes the output
(via doupdate) when destroyed. */
/* An RAII class that calls doupdate on destruction (really the
destruction of the outermost instance). This is used to prevent
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:
tui_suppress_output ();
~tui_suppress_output ();
tui_batch_rendering ();
~tui_batch_rendering ();
DISABLE_COPY_AND_ASSIGN (tui_suppress_output);
DISABLE_COPY_AND_ASSIGN (tui_batch_rendering);
private:

View File

@@ -343,7 +343,7 @@ tui_source_window_base::refresh_window ()
int smincol = x + box_width () + left_margin;
int smaxrow = sminrow + m_content.size () - 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

View File

@@ -568,7 +568,7 @@ tui_disable_command (const char *args, int from_tty)
void
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_update_source_windows_with_addr (gdbarch, addr);
}