aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2023-12-17 12:52:33 -0700
committerTom Tromey <tom@tromey.com>2024-09-07 14:23:04 -0600
commitd3acf3d759d085df544687b39a0c2900d3117bf7 (patch)
treea27f2f8f6e7814b3d1e24ebb159637412084beb6
parent8f934adf59f11dd6c187c09521f7e7d84abcefbe (diff)
downloadgdb-d3acf3d759d085df544687b39a0c2900d3117bf7.zip
gdb-d3acf3d759d085df544687b39a0c2900d3117bf7.tar.gz
gdb-d3acf3d759d085df544687b39a0c2900d3117bf7.tar.bz2
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.
-rw-r--r--gdb/python/py-tui.c10
-rw-r--r--gdb/tui/tui-data.h7
-rw-r--r--gdb/tui/tui-layout.c2
-rw-r--r--gdb/tui/tui-regs.c4
-rw-r--r--gdb/tui/tui-win.c6
-rw-r--r--gdb/tui/tui-wingeneral.c19
-rw-r--r--gdb/tui/tui-wingeneral.h16
-rw-r--r--gdb/tui/tui-winsource.c2
-rw-r--r--gdb/tui/tui.c2
9 files changed, 32 insertions, 36 deletions
diff --git a/gdb/python/py-tui.c b/gdb/python/py-tui.c
index 3bcd02d..b3544c6 100644
--- a/gdb/python/py-tui.c
+++ b/gdb/python/py-tui.c
@@ -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 ());
diff --git a/gdb/tui/tui-data.h b/gdb/tui/tui-data.h
index b9922db..14c9b87 100644
--- a/gdb/tui/tui-data.h
+++ b/gdb/tui/tui-data.h
@@ -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 ()
{
diff --git a/gdb/tui/tui-layout.c b/gdb/tui/tui-layout.c
index 665b521..2b6cb31 100644
--- a/gdb/tui/tui-layout.c
+++ b/gdb/tui/tui-layout.c
@@ -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);
diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c
index 677face..38ddd23 100644
--- a/gdb/tui/tui-regs.c
+++ b/gdb/tui/tui-regs.c
@@ -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. */
diff --git a/gdb/tui/tui-win.c b/gdb/tui/tui-win.c
index c67c4f5..e9a8e46 100644
--- a/gdb/tui/tui-win.c
+++ b/gdb/tui/tui-win.c
@@ -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
diff --git a/gdb/tui/tui-wingeneral.c b/gdb/tui/tui-wingeneral.c
index d113d77..963a165 100644
--- a/gdb/tui/tui-wingeneral.c
+++ b/gdb/tui/tui-wingeneral.c
@@ -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. */
diff --git a/gdb/tui/tui-wingeneral.h b/gdb/tui/tui-wingeneral.h
index 652cef9..6387afd 100644
--- a/gdb/tui/tui-wingeneral.h
+++ b/gdb/tui/tui-wingeneral.h
@@ -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:
diff --git a/gdb/tui/tui-winsource.c b/gdb/tui/tui-winsource.c
index b08fca7..a313e44 100644
--- a/gdb/tui/tui-winsource.c
+++ b/gdb/tui/tui-winsource.c
@@ -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
diff --git a/gdb/tui/tui.c b/gdb/tui/tui.c
index 781ec85..bc96cd8 100644
--- a/gdb/tui/tui.c
+++ b/gdb/tui/tui.c
@@ -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);
}