diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-11-20 08:38:46 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2022-11-20 21:11:37 +0800 |
commit | 035d41ac5e5fcbb49eb64b72a924c4d6f89f0579 (patch) | |
tree | 4f461e40c21bfe0e3ec488f91c55d599b317681d /src/nvim/window.c | |
parent | 822eabc5e123bca71ba945467c3b01110bb0e003 (diff) | |
download | rneovim-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.c | 69 |
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; } } } |