aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/window.c
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-11-20 08:38:46 +0800
committerzeertzjq <zeertzjq@outlook.com>2022-11-20 21:11:37 +0800
commit035d41ac5e5fcbb49eb64b72a924c4d6f89f0579 (patch)
tree4f461e40c21bfe0e3ec488f91c55d599b317681d /src/nvim/window.c
parent822eabc5e123bca71ba945467c3b01110bb0e003 (diff)
downloadrneovim-035d41ac5e5fcbb49eb64b72a924c4d6f89f0579.tar.gz
rneovim-035d41ac5e5fcbb49eb64b72a924c4d6f89f0579.tar.bz2
rneovim-035d41ac5e5fcbb49eb64b72a924c4d6f89f0579.zip
vim-patch:partial:9.0.0913: only change in current window triggers the WinScrolled event
Problem: Only a change in the current window triggers the WinScrolled event. Solution: Trigger WinScrolled if any window scrolled or changed size. (issue vim/vim#11576) https://github.com/vim/vim/commit/0a60f79fd0c328b47b36279a95282e9f8d9e7512 Skip locking of window layout and E1312. Copy the latest version of all WinScrolled tests from Vim. Note: patch 9.0.0915 is needed for the Lua tests to pass. Co-authored-by: Bram Moolenaar <Bram@vim.org>
Diffstat (limited to 'src/nvim/window.c')
-rw-r--r--src/nvim/window.c69
1 files changed, 47 insertions, 22 deletions
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 54ab9a0471..4a451975a4 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -5263,35 +5263,60 @@ void win_new_screen_cols(void)
win_reconfig_floats(); // The size of floats might change
}
-/// Trigger WinScrolled for "curwin" if needed.
+/// Make a snapshot of all the window scroll positions and sizes of the current
+/// tab page.
+static void snapshot_windows_scroll_size(void)
+{
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ wp->w_last_topline = wp->w_topline;
+ wp->w_last_leftcol = wp->w_leftcol;
+ wp->w_last_skipcol = wp->w_skipcol;
+ wp->w_last_width = wp->w_width;
+ wp->w_last_height = wp->w_height;
+ }
+}
+
+static bool did_initial_scroll_size_snapshot = false;
+
+void may_make_initial_scroll_size_snapshot(void)
+{
+ if (!did_initial_scroll_size_snapshot) {
+ did_initial_scroll_size_snapshot = true;
+ snapshot_windows_scroll_size();
+ }
+}
+
+/// Trigger WinScrolled if any window scrolled or changed size.
void may_trigger_winscrolled(void)
{
static bool recursive = false;
- if (recursive || !has_event(EVENT_WINSCROLLED)) {
+ if (recursive
+ || !has_event(EVENT_WINSCROLLED)
+ || !did_initial_scroll_size_snapshot) {
return;
}
- win_T *wp = curwin;
- if (wp->w_last_topline != wp->w_topline
- || wp->w_last_leftcol != wp->w_leftcol
- || wp->w_last_skipcol != wp->w_skipcol
- || wp->w_last_width != wp->w_width
- || wp->w_last_height != wp->w_height) {
- char winid[NUMBUFLEN];
- vim_snprintf(winid, sizeof(winid), "%d", wp->handle);
-
- recursive = true;
- apply_autocmds(EVENT_WINSCROLLED, winid, winid, false, wp->w_buffer);
- recursive = false;
-
- // an autocmd may close the window, "wp" may be invalid now
- if (win_valid_any_tab(wp)) {
- wp->w_last_topline = wp->w_topline;
- wp->w_last_leftcol = wp->w_leftcol;
- wp->w_last_skipcol = wp->w_skipcol;
- wp->w_last_width = wp->w_width;
- wp->w_last_height = wp->w_height;
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ if (wp->w_last_topline != wp->w_topline
+ || wp->w_last_leftcol != wp->w_leftcol
+ || wp->w_last_skipcol != wp->w_skipcol
+ || wp->w_last_width != wp->w_width
+ || wp->w_last_height != wp->w_height) {
+ // WinScrolled is triggered only once, even when multiple windows
+ // scrolled or changed size. Store the current values before
+ // triggering the event, if a scroll or resize happens as a side
+ // effect then WinScrolled is triggered again later.
+ snapshot_windows_scroll_size();
+
+ char winid[NUMBUFLEN];
+ vim_snprintf(winid, sizeof(winid), "%d", wp->handle);
+
+ recursive = true;
+ apply_autocmds(EVENT_WINSCROLLED, winid, winid, false, wp->w_buffer);
+ recursive = false;
+
+ break;
}
}
}