fix(window): making float with title/footer non-float leaks memory (#30551)

(cherry picked from commit 4f9311b759)
This commit is contained in:
zeertzjq
2024-09-28 10:21:06 +08:00
committed by github-actions[bot]
parent 2f3c447605
commit 28fba3bf27
5 changed files with 60 additions and 27 deletions

View File

@@ -447,7 +447,7 @@ void nvim_win_set_config(Window window, Dict(win_config) *config, Error *err)
}
}
}
win->w_config = fconfig;
merge_win_config(&win->w_config, fconfig);
// If there's no "vertical" or "split" set, or if "split" is unchanged,
// then we can just change the size of the window.
@@ -1314,12 +1314,7 @@ static bool parse_win_config(win_T *wp, Dict(win_config) *config, WinConfig *fco
return true;
fail:
if (wp == NULL || fconfig->title_chunks.items != wp->w_config.title_chunks.items) {
clear_virttext(&fconfig->title_chunks);
}
if (wp == NULL || fconfig->footer_chunks.items != wp->w_config.footer_chunks.items) {
clear_virttext(&fconfig->footer_chunks);
}
merge_win_config(fconfig, wp != NULL ? wp->w_config : WIN_CONFIG_INIT);
return false;
#undef HAS_KEY_X
}

View File

@@ -797,6 +797,19 @@ int win_fdccol_count(win_T *wp)
return fdc[0] - '0';
}
/// Merges two window configs, freeing replaced fields if necessary.
void merge_win_config(WinConfig *dst, const WinConfig src)
FUNC_ATTR_NONNULL_ALL
{
if (dst->title_chunks.items != src.title_chunks.items) {
clear_virttext(&dst->title_chunks);
}
if (dst->footer_chunks.items != src.footer_chunks.items) {
clear_virttext(&dst->footer_chunks);
}
*dst = src;
}
void ui_ext_win_position(win_T *wp, bool validate)
{
wp->w_pos_changed = false;
@@ -1297,7 +1310,7 @@ win_T *win_split_ins(int size, int flags, win_T *new_wp, int dir, frame_T *to_fl
new_frame(wp);
// non-floating window doesn't store float config or have a border.
wp->w_config = WIN_CONFIG_INIT;
merge_win_config(&wp->w_config, WIN_CONFIG_INIT);
CLEAR_FIELD(wp->w_border_adj);
}

View File

@@ -202,13 +202,7 @@ void win_config_float(win_T *wp, WinConfig fconfig)
wp->w_config.border_hl_ids,
sizeof fconfig.border_hl_ids) != 0);
if (fconfig.title_chunks.items != wp->w_config.title_chunks.items) {
clear_virttext(&wp->w_config.title_chunks);
}
if (fconfig.footer_chunks.items != wp->w_config.footer_chunks.items) {
clear_virttext(&wp->w_config.footer_chunks);
}
wp->w_config = fconfig;
merge_win_config(&wp->w_config, fconfig);
bool has_border = wp->w_floating && wp->w_config.border;
for (int i = 0; i < 4; i++) {