Mercurial > hg > xemacs-beta
comparison lisp/window-xemacs.el @ 1149:a123f88fa975
[xemacs-hg @ 2002-12-08 10:24:33 by michaels]
2002-12-02 Mike Sperber <mike@xemacs.org>
* The Great Window Configuration rewrite: Re-implement window
configuration functionality in Emacs Lisp.
* window.h (Fcurrent_window_configuration): Don't export anymore.
(Qcurrent_window_configuration): Declare.
(Qset_window_configuration): Declare.
* event-stream.c (execute_help_form):
* bytecode.c (execute_rare_opcode): Call out to Lisp to save
window excursion.
* window.c (Qcurrent_window_configuration): Declare.
(Qwindow_configurationp):
(Vwindow_configuration_free_list):
(Qset_window_configuration):
(Qtemp_buffer_show_hook):
(struct saved_window):
(struct window_config):
(SAVED_WINDOW_N):
(XWINDOW_CONFIGURATION):
(wrap_window_configuration):
(WINDOW_CONFIGURATIONP):
(CHECK_WINDOW_CONFIGURATION):
(mark_window_config):
(sizeof_window_config_for_n_windows):
(sizeof_window_config):
(print_window_config):
(saved_window_equal):
(window_config_equal):
(Fwindow_configuration_p):
(mark_windows_in_use_closure):
(mark_windows_in_use):
(free_window_configuration):
(Fset_window_configuration):
(count_windows):
(saved_window_index):
(save_window_save):
(Fcurrent_window_configuration):
(Fsave_window_excursion): Remove.
(mark_window_as_deleted): Rectify comment about
`set-window-configuration'.
(Fset_window_buffer): Reinstate code not activated because of old
implementation of window configurations.
(temp_output_buffer_show): Don't run `temp-buffer-show-hook'
anymore---this wasn't supposed to happen anyway according to the
documentation of `temp-buffer-show-function'.
(reinit_vars_of_window): Don't do the window configuration stuff
no more
(vars_of_window): Don't set up `temp-buffer-show-hook' any more.
2002-12-02 Mike Sperber <mike@xemacs.org>
* The Great Window Configuration rewrite: Re-implement window
configuration functionality in Emacs Lisp.
* window-xemacs.el (current-window-configuration):
(set-window-configuration): (plus many functions they depend on)
Re-implement window configurations in Emacs Lisp.
author | michaels |
---|---|
date | Sun, 08 Dec 2002 10:25:14 +0000 |
parents | 4a27df428c73 |
children | 8e95979f01c6 |
comparison
equal
deleted
inserted
replaced
1148:1649f1fb3177 | 1149:a123f88fa975 |
---|---|
102 If BUFFER is nil, make WINDOW not be dedicated (but don't change which | 102 If BUFFER is nil, make WINDOW not be dedicated (but don't change which |
103 buffer appears in it currently)." | 103 buffer appears in it currently)." |
104 (if (bufferp buffer) | 104 (if (bufferp buffer) |
105 (set-window-buffer window (get-buffer-create buffer))) | 105 (set-window-buffer window (get-buffer-create buffer))) |
106 (set-window-dedicated-p window (not (null buffer)))) | 106 (set-window-dedicated-p window (not (null buffer)))) |
107 | 107 |
108 ;; Window configurations | |
109 | |
110 (defstruct saved-window | |
111 currentp minibufferp minibuffer-scrollp | |
112 buffer mark-marker | |
113 start-marker | |
114 point-marker | |
115 pixel-left pixel-top pixel-right pixel-bottom | |
116 hscroll modeline-hscroll | |
117 dedicatedp | |
118 first-hchild first-vchild next-child) | |
119 | |
120 (defstruct window-configuration | |
121 frame | |
122 frame-pixel-width frame-pixel-height | |
123 current-buffer | |
124 minibuffer-pixel-height | |
125 min-width min-height | |
126 saved-root-window) | |
127 | |
128 (defun window-configuration-equal (conf-1 conf-2) | |
129 "Returns a boolean indicating whether the two given configurations | |
130 are identical." | |
131 (or (eq conf-1 conf-2) | |
132 (and (eq (window-configuration-frame conf-1) | |
133 (window-configuration-frame conf-2)) | |
134 (= (window-configuration-frame-pixel-width conf-1) | |
135 (window-configuration-frame-pixel-width conf-2)) | |
136 (= (window-configuration-frame-pixel-height conf-1) | |
137 (window-configuration-frame-pixel-height conf-2)) | |
138 (eq (window-configuration-current-buffer conf-1) | |
139 (window-configuration-current-buffer conf-2)) | |
140 (saved-window-equal (window-configuration-saved-root-window conf-1) | |
141 (window-configuration-saved-root-window conf-2))))) | |
142 | |
143 (defun saved-window-equal (saved-1 saved-2) | |
144 "Returns a boolean indicating whether the two given saved windows | |
145 are identical." | |
146 (or (eq saved-1 saved-2) | |
147 (and (eq (saved-window-currentp saved-1) | |
148 (saved-window-currentp saved-2)) | |
149 (eq (saved-window-minibuffer-scrollp saved-1) | |
150 (saved-window-minibuffer-scrollp saved-2)) | |
151 (eq (saved-window-buffer saved-1) | |
152 (saved-window-buffer saved-2)) | |
153 (equal (saved-window-mark-marker saved-1) | |
154 (saved-window-mark-marker saved-2)) | |
155 (or (and (saved-window-currentp saved-1) | |
156 (saved-window-currentp saved-2)) | |
157 (equal (saved-window-start-marker saved-1) | |
158 (saved-window-start-marker saved-2))) | |
159 (or (and (saved-window-currentp saved-1) | |
160 (saved-window-currentp saved-2)) | |
161 (equal (saved-window-point-marker saved-1) | |
162 (saved-window-point-marker saved-2))) | |
163 (= (saved-window-pixel-left saved-1) | |
164 (saved-window-pixel-left saved-2)) | |
165 (= (saved-window-pixel-top saved-1) | |
166 (saved-window-pixel-top saved-2)) | |
167 (= (saved-window-pixel-right saved-1) | |
168 (saved-window-pixel-right saved-2)) | |
169 (= (saved-window-pixel-bottom saved-1) | |
170 (saved-window-pixel-bottom saved-2)) | |
171 (= (saved-window-hscroll saved-1) | |
172 (saved-window-hscroll saved-2)) | |
173 (= (saved-window-modeline-hscroll saved-1) | |
174 (saved-window-modeline-hscroll saved-2)) | |
175 (eq (saved-window-dedicatedp saved-1) | |
176 (saved-window-dedicatedp saved-2)) | |
177 (maybe-saved-window-equal (saved-window-first-hchild saved-1) | |
178 (saved-window-first-hchild saved-2)) | |
179 (maybe-saved-window-equal (saved-window-first-vchild saved-1) | |
180 (saved-window-first-vchild saved-2)) | |
181 (maybe-saved-window-equal (saved-window-next-child saved-1) | |
182 (saved-window-next-child saved-2))))) | |
183 | |
184 (defun maybe-saved-window-equal (maybe-saved-1 maybe-saved-2) | |
185 "Returns a boolean indicating whether the two given saved windows | |
186 or NILs are identical." | |
187 (cond | |
188 ((and (not maybe-saved-1) (not maybe-saved-2)) t) | |
189 ((not maybe-saved-1) (not maybe-saved-2)) | |
190 ((not maybe-saved-2) (not maybe-saved-1)) | |
191 (t (saved-window-equal maybe-saved-1 maybe-saved-2)))) | |
192 | |
193 (defun current-window-configuration (&optional frame) | |
194 "Return an object representing the current window configuration of FRAME. | |
195 If FRAME is nil or omitted, use the selected frame. | |
196 This describes the number of windows, their sizes and current buffers, | |
197 and for each window on FRAME the displayed buffer, where display | |
198 starts, and the positions of point and mark. | |
199 An exception is made for point in the current buffer: | |
200 its value is -not- saved." | |
201 (let ((frame (or frame (selected-frame)))) | |
202 ;; The original C code used complicated but still incomplete logic | |
203 ;; to decide if and how to restore the size of the minibuffer. It | |
204 ;; goes something like this: | |
205 ; (let ((real-font-height | |
206 ; (font-height (face-font 'default) frame)) | |
207 ; (minibuffer-height | |
208 ; (if (and (minibuffer-window frame) | |
209 ; (not (frame-minibuffer-only-p frame))) | |
210 ; (window-pixel-height (minibuffer-window frame)) | |
211 ; 0))) | |
212 ; ...) | |
213 | |
214 (make-window-configuration | |
215 :frame frame | |
216 :frame-pixel-width (frame-pixel-width frame) | |
217 :frame-pixel-height (frame-pixel-height frame) | |
218 :current-buffer (current-buffer) | |
219 :min-width window-min-width :min-height window-min-height | |
220 :minibuffer-pixel-height (window-pixel-height (minibuffer-window frame)) | |
221 ;; this tries to do what the old code did: | |
222 ; :minibuffer-height (if (zerop (% minibuffer-height real-font-height)) | |
223 ; (- (/ minibuffer-height real-font-height)) ; lines | |
224 ; minibuffer-height) ; pixels | |
225 :saved-root-window (root-window->saved-window (frame-root-window frame))))) | |
226 | |
227 (defun root-window->saved-window (window) | |
228 "Converts a root window into a tree of saved-window structures." | |
229 (let ((buffer (window-buffer window)) | |
230 (edges (window-pixel-edges window))) | |
231 (let ((left (nth 0 edges)) | |
232 (top (nth 1 edges)) | |
233 (right (nth 2 edges)) | |
234 (bottom (nth 3 edges))) | |
235 (let ((saved-window | |
236 (make-saved-window | |
237 :currentp (eq window (selected-window (window-frame window))) | |
238 :minibufferp (eq window (minibuffer-window (window-frame window))) | |
239 :minibuffer-scrollp (eq window minibuffer-scroll-window) | |
240 :buffer buffer | |
241 :pixel-left left :pixel-top top :pixel-right right :pixel-bottom bottom | |
242 :hscroll (window-hscroll window) | |
243 :modeline-hscroll (modeline-hscroll window) | |
244 :dedicatedp (window-dedicated-p window) | |
245 :first-hchild (if (window-first-hchild window) | |
246 (root-window->saved-window (window-first-hchild window)) | |
247 nil) | |
248 :first-vchild (if (window-first-vchild window) | |
249 (root-window->saved-window (window-first-vchild window)) | |
250 nil) | |
251 :next-child (if (window-next-child window) | |
252 (root-window->saved-window (window-next-child window)) | |
253 nil)))) | |
254 (if buffer | |
255 (progn | |
256 (let ((marker (make-marker))) | |
257 (set-marker marker (window-start window) buffer) | |
258 (setf (saved-window-start-marker saved-window) marker)) | |
259 (let ((marker (make-marker))) | |
260 (if (eq window (selected-window)) | |
261 (set-marker marker (point buffer) buffer) | |
262 (set-marker marker (window-point window) buffer)) | |
263 (setf (saved-window-point-marker saved-window) marker)) | |
264 (setf (saved-window-mark-marker saved-window) | |
265 (copy-marker (mark-marker t buffer))))) | |
266 saved-window)))) | |
267 | |
268 (defun set-window-configuration (configuration) | |
269 "Set the configuration of windows and buffers as specified by CONFIGURATION. | |
270 CONFIGURATION must be a value previously returned | |
271 by `current-window-configuration'." | |
272 (let ((frame (window-configuration-frame configuration))) | |
273 (if (and (frame-live-p frame) | |
274 (not (window-configuration-equal configuration | |
275 (current-window-configuration)))) | |
276 (really-set-window-configuration frame configuration)))) | |
277 | |
278 (defun really-set-window-configuration (frame configuration) | |
279 "Set the window configuration CONFIGURATION on live frame FRAME." | |
280 ;; avoid potential temporary problems | |
281 (setq window-min-width 0) | |
282 (setq window-min-height 0) | |
283 (setq minibuffer-scroll-window nil) | |
284 | |
285 (frame-reduce-to-one-window frame) | |
286 (set-window-configuration-frame-size configuration) | |
287 | |
288 ;; these may have changed because of the delete | |
289 (let ((root-window (frame-root-window frame))) | |
290 (enlarge-window-pixels | |
291 (- (window-configuration-minibuffer-pixel-height configuration) | |
292 (window-pixel-height (minibuffer-window frame))) | |
293 nil | |
294 (minibuffer-window frame)) | |
295 | |
296 ;; avoid that `set-window-point' will set the buffer's point for | |
297 ;; the selected window | |
298 (select-window (minibuffer-window frame)) | |
299 | |
300 (let ((window-configuration-current-window nil)) | |
301 (restore-saved-window configuration | |
302 root-window | |
303 (window-configuration-saved-root-window configuration) | |
304 'vertical) | |
305 (if window-configuration-current-window | |
306 (select-window window-configuration-current-window)))) | |
307 | |
308 (setq window-min-width (window-configuration-min-width configuration)) | |
309 (setq window-min-height (window-configuration-min-height configuration)) | |
310 | |
311 (set-buffer (window-configuration-current-buffer configuration))) | |
312 | |
313 (defun set-window-configuration-frame-size (configuration) | |
314 "Restore the frame size of a window configuration." | |
315 (set-frame-pixel-size | |
316 (window-configuration-frame configuration) | |
317 (window-configuration-frame-pixel-width configuration) | |
318 (window-configuration-frame-pixel-height configuration))) | |
319 | |
320 (defun frame-reduce-to-one-window (frame) | |
321 "Delete all windows except the minibuffer and one other in FRAME." | |
322 (let* ((root-window (frame-root-window frame)) | |
323 (combination-start (or (window-first-hchild root-window) | |
324 (window-first-vchild root-window)))) | |
325 (if combination-start | |
326 (window-reduce-to-one combination-start)))) | |
327 | |
328 (defun window-reduce-to-one (window) | |
329 "Make sure only one subwindow of WINDOW is left." | |
330 (let ((window (window-next-child window))) | |
331 (while window | |
332 (if (window-live-p window) | |
333 (let ((next (window-next-child window))) | |
334 (delete-window window) | |
335 (setq window next))))) | |
336 (cond | |
337 ((window-first-hchild window) | |
338 (window-reduce-to-one (window-first-hchild window))) | |
339 ((window-first-vchild window) | |
340 (window-reduce-to-one (window-first-vchild window))))) | |
341 | |
342 (defun restore-saved-window (configuration window saved-window direction) | |
343 "Within CONFIGURATION, restore WINDOW to the state of SAVED-WINDOW." | |
344 (if (saved-window-next-child saved-window) | |
345 (progn | |
346 (if (not (saved-window-minibufferp (saved-window-next-child saved-window))) | |
347 (progn | |
348 (cond ((eq direction 'vertical) | |
349 (split-window window nil nil)) | |
350 ((eq direction 'horizontal) | |
351 (split-window window nil t))) | |
352 (restore-saved-window configuration | |
353 (window-next-child window) | |
354 (saved-window-next-child saved-window) | |
355 direction))) | |
356 | |
357 (if (saved-window-first-hchild saved-window) | |
358 (restore-saved-window configuration | |
359 window | |
360 (saved-window-first-hchild saved-window) | |
361 'horizontal)) | |
362 (if (saved-window-first-vchild saved-window) | |
363 (restore-saved-window configuration | |
364 window | |
365 (saved-window-first-vchild saved-window) | |
366 'vertical)))) | |
367 | |
368 (if (not (saved-window-minibufferp saved-window)) | |
369 (restore-saved-window-parameters configuration window saved-window))) | |
370 | |
371 (defun restore-saved-window-parameters (configuration window saved-window) | |
372 "Restore the window parameters stored in SAVED-WINDOW on WINDOW." | |
373 (let ((buffer (saved-window-buffer saved-window))) | |
374 (if (and buffer (buffer-live-p buffer)) | |
375 (progn | |
376 (set-window-buffer window | |
377 (saved-window-buffer saved-window)) | |
378 (set-window-start window | |
379 (marker-position (saved-window-start-marker saved-window))) | |
380 (set-window-point window | |
381 (marker-position (saved-window-point-marker saved-window))) | |
382 (set-marker (mark-marker t buffer) | |
383 (marker-position (saved-window-mark-marker saved-window)) | |
384 buffer) | |
385 (if (not (eq buffer (window-configuration-current-buffer configuration))) | |
386 (goto-char (window-point window) buffer))))) | |
387 | |
388 (if (and (not (saved-window-first-hchild saved-window)) | |
389 (not (saved-window-first-vchild saved-window))) | |
390 ;; only set size for non-container windows | |
391 (progn | |
392 ;; If this is the root window, it may be the only window. | |
393 ;; Because of mismatches between actual and reported frame | |
394 ;; size, it may not let us actually set the size of the root | |
395 ;; window to what we want. --Mike | |
396 (if (not (eq window (frame-root-window (window-frame window)))) | |
397 (progn | |
398 (enlarge-window-pixels (- (saved-window-pixel-width saved-window) | |
399 (window-pixel-width window)) | |
400 t | |
401 window) | |
402 (enlarge-window-pixels (- (saved-window-pixel-height saved-window) | |
403 (window-pixel-height window)) | |
404 nil | |
405 window))) | |
406 (set-window-hscroll window (saved-window-hscroll saved-window)) | |
407 (set-modeline-hscroll window | |
408 (saved-window-modeline-hscroll saved-window)) | |
409 (set-window-dedicated-p window (saved-window-dedicatedp saved-window)))) | |
410 | |
411 (if (saved-window-currentp saved-window) | |
412 (setq window-configuration-current-window window)) | |
413 (if (saved-window-minibuffer-scrollp saved-window) | |
414 (setq minibuffer-scroll-window window))) | |
415 | |
416 (defun saved-window-pixel-width (saved-window) | |
417 "Compute the pixel width of SAVED-WINDOW." | |
418 (- (saved-window-pixel-right saved-window) | |
419 (saved-window-pixel-left saved-window))) | |
420 | |
421 (defun saved-window-pixel-height (saved-window) | |
422 "Compute the pixel height of SAVED-WINDOW." | |
423 (- (saved-window-pixel-bottom saved-window) | |
424 (saved-window-pixel-top saved-window))) | |
108 | 425 |
109 ;; The window-config stack is stored as a list in frame property | 426 ;; The window-config stack is stored as a list in frame property |
110 ;; 'window-config-stack, with the most recent element at the front. | 427 ;; 'window-config-stack, with the most recent element at the front. |
111 ;; When you pop off an element, the popped off element gets put at the | 428 ;; When you pop off an element, the popped off element gets put at the |
112 ;; front of frame property 'window-config-unpop-stack, so you can | 429 ;; front of frame property 'window-config-unpop-stack, so you can |