1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
To: vim_dev@googlegroups.com
Subject: Patch 7.3.528
Fcc: outbox
From: Bram Moolenaar <Bram@moolenaar.net>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
------------
Patch 7.3.528
Problem: Crash when closing last window in a tab. (Alex Efros)
Solution: Use common code in close_last_window_tabpage(). (Christian
Brabandt)
Files: src/window.c
*** ../vim-7.3.527/src/window.c 2012-03-16 19:07:54.000000000 +0100
--- src/window.c 2012-05-25 12:25:16.000000000 +0200
***************
*** 23,28 ****
--- 23,29 ----
static void win_totop __ARGS((int size, int flags));
static void win_equal_rec __ARGS((win_T *next_curwin, int current, frame_T *topfr, int dir, int col, int row, int width, int height));
static int last_window __ARGS((void));
+ static int close_last_window_tabpage __ARGS((win_T *win, int free_buf, tabpage_T *prev_curtab));
static win_T *win_free_mem __ARGS((win_T *win, int *dirp, tabpage_T *tp));
static frame_T *win_altframe __ARGS((win_T *win, tabpage_T *tp));
static tabpage_T *alt_tabpage __ARGS((void));
***************
*** 2105,2110 ****
--- 2106,2147 ----
}
/*
+ * Close the possibly last window in a tab page.
+ * Returns TRUE when the window was closed already.
+ */
+ static int
+ close_last_window_tabpage(win, free_buf, prev_curtab)
+ win_T *win;
+ int free_buf;
+ tabpage_T *prev_curtab;
+ {
+ if (firstwin == lastwin)
+ {
+ /*
+ * Closing the last window in a tab page. First go to another tab
+ * page and then close the window and the tab page. This avoids that
+ * curwin and curtab are invalid while we are freeing memory, they may
+ * be used in GUI events.
+ */
+ goto_tabpage_tp(alt_tabpage());
+ redraw_tabline = TRUE;
+
+ /* Safety check: Autocommands may have closed the window when jumping
+ * to the other tab page. */
+ if (valid_tabpage(prev_curtab) && prev_curtab->tp_firstwin == win)
+ {
+ int h = tabline_height();
+
+ win_close_othertab(win, free_buf, prev_curtab);
+ if (h != tabline_height())
+ shell_new_rows();
+ }
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ /*
* Close window "win". Only works for the current tab page.
* If "free_buf" is TRUE related buffer may be unloaded.
*
***************
*** 2143,2171 ****
}
#endif
! /*
! * When closing the last window in a tab page first go to another tab
! * page and then close the window and the tab page. This avoids that
! * curwin and curtab are not invalid while we are freeing memory, they may
! * be used in GUI events.
! */
! if (firstwin == lastwin)
! {
! goto_tabpage_tp(alt_tabpage());
! redraw_tabline = TRUE;
!
! /* Safety check: Autocommands may have closed the window when jumping
! * to the other tab page. */
! if (valid_tabpage(prev_curtab) && prev_curtab->tp_firstwin == win)
! {
! int h = tabline_height();
!
! win_close_othertab(win, free_buf, prev_curtab);
! if (h != tabline_height())
! shell_new_rows();
! }
! return;
! }
/* When closing the help window, try restoring a snapshot after closing
* the window. Otherwise clear the snapshot, it's now invalid. */
--- 2180,2190 ----
}
#endif
! /* When closing the last window in a tab page first go to another tab page
! * and then close the window and the tab page to avoid that curwin and
! * curtab are invalid while we are freeing memory. */
! if (close_last_window_tabpage(win, free_buf, prev_curtab))
! return;
/* When closing the help window, try restoring a snapshot after closing
* the window. Otherwise clear the snapshot, it's now invalid. */
***************
*** 2225,2231 ****
/* Autocommands may have closed the window already, or closed the only
* other window or moved to another tab page. */
! if (!win_valid(win) || last_window() || curtab != prev_curtab)
return;
/* Free the memory used for the window and get the window that received
--- 2244,2251 ----
/* Autocommands may have closed the window already, or closed the only
* other window or moved to another tab page. */
! if (!win_valid(win) || last_window() || curtab != prev_curtab
! || close_last_window_tabpage(win, free_buf, prev_curtab))
return;
/* Free the memory used for the window and get the window that received
***************
*** 2310,2316 ****
/*
* Close window "win" in tab page "tp", which is not the current tab page.
! * This may be the last window ih that tab page and result in closing the tab,
* thus "tp" may become invalid!
* Caller must check if buffer is hidden and whether the tabline needs to be
* updated.
--- 2330,2336 ----
/*
* Close window "win" in tab page "tp", which is not the current tab page.
! * This may be the last window in that tab page and result in closing the tab,
* thus "tp" may become invalid!
* Caller must check if buffer is hidden and whether the tabline needs to be
* updated.
*** ../vim-7.3.527/src/version.c 2012-05-25 11:56:06.000000000 +0200
--- src/version.c 2012-05-25 12:38:25.000000000 +0200
***************
*** 716,717 ****
--- 716,719 ----
{ /* Add new patch number below this line */
+ /**/
+ 528,
/**/
--
For society, it's probably a good thing that engineers value function over
appearance. For example, you wouldn't want engineers to build nuclear power
plants that only _look_ like they would keep all the radiation inside.
(Scott Adams - The Dilbert principle)
/// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
|