aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/testsuite/gdb.tui/new-layout.exp5
-rw-r--r--gdb/tui/tui-layout.c69
-rw-r--r--gdb/tui/tui-layout.h47
-rw-r--r--gdb/tui/tui-win.c6
4 files changed, 102 insertions, 25 deletions
diff --git a/gdb/testsuite/gdb.tui/new-layout.exp b/gdb/testsuite/gdb.tui/new-layout.exp
index 0d49d03..883c760 100644
--- a/gdb/testsuite/gdb.tui/new-layout.exp
+++ b/gdb/testsuite/gdb.tui/new-layout.exp
@@ -71,6 +71,11 @@ set layouts \
[list h "{-horizontal asm 1 src 1} 1 status 0 cmd 1" \
{{0 0 40 15} {39 0 41 15}} \
"$hex <main>.*21.*return 0"] \
+ [list example3 "{-horizontal src 1 cmd 1} 1 status 0 asm 1" \
+ {{0 0 40 11} {0 12 80 12}} \
+ "21.*return 0.*$hex <main>"] \
+ [list example4 "src 1 status 0 {-horizontal cmd 1 regs 1} 1" \
+ {{0 0 80 11} {40 12 40 12}} ""] \
[list cmd_only "cmd 1" {} ""]]
# Helper function to verify a list of boxes.
diff --git a/gdb/tui/tui-layout.c b/gdb/tui/tui-layout.c
index 874760d..d326c05 100644
--- a/gdb/tui/tui-layout.c
+++ b/gdb/tui/tui-layout.c
@@ -67,7 +67,7 @@ std::vector<tui_win_info *> tui_windows;
/* See tui-layout.h. */
void
-tui_apply_current_layout ()
+tui_apply_current_layout (bool preserve_cmd_win_size_p)
{
struct gdbarch *gdbarch;
CORE_ADDR addr;
@@ -77,7 +77,8 @@ tui_apply_current_layout ()
for (tui_win_info *win_info : tui_windows)
win_info->make_visible (false);
- applied_layout->apply (0, 0, tui_term_width (), tui_term_height ());
+ applied_layout->apply (0, 0, tui_term_width (), tui_term_height (),
+ preserve_cmd_win_size_p);
/* Keep the list of internal windows up-to-date. */
for (int win_type = SRC_WIN; (win_type < MAX_MAJOR_WINDOWS); win_type++)
@@ -134,9 +135,18 @@ tui_adjust_window_width (struct tui_win_info *win, int new_width)
static void
tui_set_layout (tui_layout_split *layout)
{
+ std::string old_fingerprint;
+ if (applied_layout != nullptr)
+ old_fingerprint = applied_layout->layout_fingerprint ();
+
applied_skeleton = layout;
applied_layout = layout->clone ();
- tui_apply_current_layout ();
+
+ std::string new_fingerprint = applied_layout->layout_fingerprint ();
+ bool preserve_command_window_size
+ = (TUI_CMD_WIN != nullptr && old_fingerprint == new_fingerprint);
+
+ tui_apply_current_layout (preserve_command_window_size);
}
/* See tui-layout.h. */
@@ -158,7 +168,7 @@ tui_add_win_to_layout (enum tui_win_type type)
const char *name = type == SRC_WIN ? SRC_NAME : DISASSEM_NAME;
applied_layout->replace_window (tui_win_list[other]->name (), name);
- tui_apply_current_layout ();
+ tui_apply_current_layout (true);
}
/* Find LAYOUT in the "layouts" global and return its index. */
@@ -271,7 +281,7 @@ tui_remove_some_windows ()
}
applied_layout->remove_windows (focus->name ());
- tui_apply_current_layout ();
+ tui_apply_current_layout (true);
}
static void
@@ -411,7 +421,8 @@ tui_layout_window::clone () const
/* See tui-layout.h. */
void
-tui_layout_window::apply (int x_, int y_, int width_, int height_)
+tui_layout_window::apply (int x_, int y_, int width_, int height_,
+ bool preserve_cmd_win_size_p)
{
x = x_;
y = y_;
@@ -492,6 +503,17 @@ tui_layout_window::specification (ui_file *output, int depth)
/* See tui-layout.h. */
+std::string
+tui_layout_window::layout_fingerprint () const
+{
+ if (strcmp (get_name (), "cmd") == 0)
+ return "C";
+ else
+ return "";
+}
+
+/* See tui-layout.h. */
+
void
tui_layout_split::add_split (std::unique_ptr<tui_layout_split> &&layout,
int weight)
@@ -716,8 +738,11 @@ tui_layout_split::set_size (const char *name, int new_size, bool set_width_p)
}
else
{
- /* Simply re-apply the updated layout. */
- apply (x, y, width, height);
+ /* Simply re-apply the updated layout. We pass false here so that
+ the cmd window can be resized. However, we should have already
+ resized everything above to be "just right", so the apply call
+ here should not end up changing the sizes at all. */
+ apply (x, y, width, height, false);
}
return HANDLED;
@@ -726,7 +751,8 @@ tui_layout_split::set_size (const char *name, int new_size, bool set_width_p)
/* See tui-layout.h. */
void
-tui_layout_split::apply (int x_, int y_, int width_, int height_)
+tui_layout_split::apply (int x_, int y_, int width_, int height_,
+ bool preserve_cmd_win_size_p)
{
TUI_SCOPED_DEBUG_ENTER_EXIT;
@@ -781,7 +807,7 @@ tui_layout_split::apply (int x_, int y_, int width_, int height_)
m_splits[i].layout->get_sizes (m_vertical, &info[i].min_size,
&info[i].max_size);
- if (!m_applied
+ if (preserve_cmd_win_size_p
&& cmd_win_already_exists
&& m_splits[i].layout->get_name () != nullptr
&& strcmp (m_splits[i].layout->get_name (), "cmd") == 0)
@@ -964,13 +990,13 @@ tui_layout_split::apply (int x_, int y_, int width_, int height_)
else if (info[i].share_box)
--size_accum;
if (m_vertical)
- m_splits[i].layout->apply (x, y + size_accum, width, info[i].size);
+ m_splits[i].layout->apply (x, y + size_accum, width, info[i].size,
+ preserve_cmd_win_size_p);
else
- m_splits[i].layout->apply (x + size_accum, y, info[i].size, height);
+ m_splits[i].layout->apply (x + size_accum, y, info[i].size, height,
+ preserve_cmd_win_size_p);
size_accum += info[i].size;
}
-
- m_applied = true;
}
/* See tui-layout.h. */
@@ -1031,6 +1057,21 @@ tui_layout_split::specification (ui_file *output, int depth)
gdb_puts ("}", output);
}
+/* See tui-layout.h. */
+
+std::string
+tui_layout_split::layout_fingerprint () const
+{
+ for (auto &item : m_splits)
+ {
+ std::string fp = item.layout->layout_fingerprint ();
+ if (!fp.empty ())
+ return std::string (m_vertical ? "V" : "H") + fp;
+ }
+
+ return "";
+}
+
/* Destroy the layout associated with SELF. */
static void
diff --git a/gdb/tui/tui-layout.h b/gdb/tui/tui-layout.h
index 9cfcfb8..32bc951 100644
--- a/gdb/tui/tui-layout.h
+++ b/gdb/tui/tui-layout.h
@@ -55,8 +55,12 @@ public:
"skeleton" layout. */
virtual std::unique_ptr<tui_layout_base> clone () const = 0;
- /* Change the size and location of this layout. */
- virtual void apply (int x, int y, int width, int height) = 0;
+ /* Change the size and location of this layout. When
+ PRESERVE_CMD_WIN_SIZE_P is true the current size of the TUI_CMD_WIN
+ is preserved, otherwise, the TUI_CMD_WIN will resize just like any
+ other window. */
+ virtual void apply (int x, int y, int width, int height,
+ bool preserve_cmd_win_size_p) = 0;
/* Return the minimum and maximum height or width of this layout.
HEIGHT is true to fetch height, false to fetch width. */
@@ -97,6 +101,26 @@ public:
depth of this layout in the hierarchy (zero-based). */
virtual void specification (ui_file *output, int depth) = 0;
+ /* Return a FINGERPRINT string containing an abstract representation of
+ the location of the cmd window in this layout.
+
+ When called on a complete, top-level layout, the fingerprint will be a
+ non-empty string made of 'V' and 'H' characters, followed by a single
+ 'C' character. Each 'V' and 'H' represents a vertical or horizontal
+ layout that must be passed through in order to find the cmd
+ window.
+
+ Of course, layouts are built recursively, so, when called on a partial
+ layout, if this object represents a single window, then either the
+ empty string is returned (for non-cmd windows), or a string
+ containing a single 'C' is returned.
+
+ For object representing layouts, if the layout contains the cmd
+ window then we will get back a valid fingerprint string (contains 'V'
+ and 'H', ends with 'C'), or, if this layout doesn't contain the cmd
+ window, an empty string is returned. */
+ virtual std::string layout_fingerprint () const = 0;
+
/* Add all windows to the WINDOWS vector. */
virtual void get_windows (std::vector<tui_win_info *> *windows) = 0;
@@ -126,7 +150,8 @@ public:
std::unique_ptr<tui_layout_base> clone () const override;
- void apply (int x, int y, int width, int height) override;
+ void apply (int x, int y, int width, int height,
+ bool preserve_cmd_win_size_p) override;
const char *get_name () const override
{
@@ -155,6 +180,8 @@ public:
void specification (ui_file *output, int depth) override;
+ std::string layout_fingerprint () const override;
+
/* See tui_layout_base::get_windows. */
void get_windows (std::vector<tui_win_info *> *windows) override
{
@@ -201,7 +228,8 @@ public:
std::unique_ptr<tui_layout_base> clone () const override;
- void apply (int x, int y, int width, int height) override;
+ void apply (int x, int y, int width, int height,
+ bool preserve_cmd_win_size_p) override;
tui_adjust_result set_height (const char *name, int new_height) override
{
@@ -225,6 +253,8 @@ public:
void specification (ui_file *output, int depth) override;
+ std::string layout_fingerprint () const override;
+
/* See tui_layout_base::get_windows. */
void get_windows (std::vector<tui_win_info *> *windows) override
{
@@ -289,9 +319,6 @@ private:
/* True if the windows in this split are arranged vertically. */
bool m_vertical;
-
- /* True if this layout has already been applied at least once. */
- bool m_applied = false;
};
/* Add the specified window to the layout in a logical way. This
@@ -314,8 +341,10 @@ extern void tui_regs_layout ();
some other window is chosen to remain. */
extern void tui_remove_some_windows ();
-/* Apply the current layout. */
-extern void tui_apply_current_layout ();
+/* Apply the current layout. When PRESERVE_CMD_WIN_SIZE_P is true the
+ current size of the TUI_CMD_WIN is preserved, otherwise, the TUI_CMD_WIN
+ will resize just like any other window. */
+extern void tui_apply_current_layout (bool);
/* Adjust the window height of WIN to NEW_HEIGHT. */
extern void tui_adjust_window_height (struct tui_win_info *win,
diff --git a/gdb/tui/tui-win.c b/gdb/tui/tui-win.c
index 8564f9e..2ec6180 100644
--- a/gdb/tui/tui-win.c
+++ b/gdb/tui/tui-win.c
@@ -511,8 +511,10 @@ tui_resize_all (void)
AIX 5.3 does not define clear. */
erase ();
clearok (curscr, TRUE);
- tui_apply_current_layout ();
- /* Turn keypad back on. */
+ /* Apply the current layout. The 'false' here allows the command
+ window to resize proportionately with containing terminal, rather
+ than maintaining a fixed size. */
+ tui_apply_current_layout (false); /* Turn keypad back on. */
keypad (TUI_CMD_WIN->handle.get (), TRUE);
}
}