Mercurial > vim
diff src/window.c @ 31158:514ab6bdf73d v9.0.0913
patch 9.0.0913: only change in current window triggers the WinScrolled event
Commit: https://github.com/vim/vim/commit/0a60f79fd0c328b47b36279a95282e9f8d9e7512
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Nov 19 21:18:11 2022 +0000
patch 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 #11576)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 19 Nov 2022 22:30:03 +0100 |
parents | bcda71c89776 |
children | 981f7bc781bb |
line wrap: on
line diff
--- a/src/window.c +++ b/src/window.c @@ -2843,44 +2843,76 @@ trigger_winclosed(win_T *win) } /* - * 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) +{ + win_T *wp; + FOR_ALL_WINDOWS(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; + } +} + +static int 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 int recursive = FALSE; - if (recursive || !has_winscrolled()) + if (recursive + || !has_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) - { - // "curwin" may be different from the actual current window, make sure - // it can be restored. - window_layout_lock(); - - recursive = TRUE; - char_u winid[NUMBUFLEN]; - vim_snprintf((char *)winid, sizeof(winid), "%d", wp->w_id); - apply_autocmds(EVENT_WINSCROLLED, winid, winid, FALSE, wp->w_buffer); - recursive = FALSE; - window_layout_unlock(); - - // an autocmd may close the window, "wp" may be invalid now - if (win_valid_any_tab(wp)) + win_T *wp; + FOR_ALL_WINDOWS(wp) + 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) { - 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(); + + // "curwin" may be different from the actual current window, make + // sure it can be restored. + window_layout_lock(); + + recursive = TRUE; + char_u winid[NUMBUFLEN]; + vim_snprintf((char *)winid, sizeof(winid), "%d", wp->w_id); + apply_autocmds(EVENT_WINSCROLLED, winid, winid, FALSE, + wp->w_buffer); + recursive = FALSE; + window_layout_unlock(); + + break; } - } } /*