Mercurial > hg > xemacs-beta
diff 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 |
line wrap: on
line diff
--- a/lisp/window-xemacs.el Sat Dec 07 22:54:03 2002 +0000 +++ b/lisp/window-xemacs.el Sun Dec 08 10:25:14 2002 +0000 @@ -104,7 +104,324 @@ (if (bufferp buffer) (set-window-buffer window (get-buffer-create buffer))) (set-window-dedicated-p window (not (null buffer)))) + +;; Window configurations +(defstruct saved-window + currentp minibufferp minibuffer-scrollp + buffer mark-marker + start-marker + point-marker + pixel-left pixel-top pixel-right pixel-bottom + hscroll modeline-hscroll + dedicatedp + first-hchild first-vchild next-child) + +(defstruct window-configuration + frame + frame-pixel-width frame-pixel-height + current-buffer + minibuffer-pixel-height + min-width min-height + saved-root-window) + +(defun window-configuration-equal (conf-1 conf-2) + "Returns a boolean indicating whether the two given configurations +are identical." + (or (eq conf-1 conf-2) + (and (eq (window-configuration-frame conf-1) + (window-configuration-frame conf-2)) + (= (window-configuration-frame-pixel-width conf-1) + (window-configuration-frame-pixel-width conf-2)) + (= (window-configuration-frame-pixel-height conf-1) + (window-configuration-frame-pixel-height conf-2)) + (eq (window-configuration-current-buffer conf-1) + (window-configuration-current-buffer conf-2)) + (saved-window-equal (window-configuration-saved-root-window conf-1) + (window-configuration-saved-root-window conf-2))))) + +(defun saved-window-equal (saved-1 saved-2) + "Returns a boolean indicating whether the two given saved windows +are identical." + (or (eq saved-1 saved-2) + (and (eq (saved-window-currentp saved-1) + (saved-window-currentp saved-2)) + (eq (saved-window-minibuffer-scrollp saved-1) + (saved-window-minibuffer-scrollp saved-2)) + (eq (saved-window-buffer saved-1) + (saved-window-buffer saved-2)) + (equal (saved-window-mark-marker saved-1) + (saved-window-mark-marker saved-2)) + (or (and (saved-window-currentp saved-1) + (saved-window-currentp saved-2)) + (equal (saved-window-start-marker saved-1) + (saved-window-start-marker saved-2))) + (or (and (saved-window-currentp saved-1) + (saved-window-currentp saved-2)) + (equal (saved-window-point-marker saved-1) + (saved-window-point-marker saved-2))) + (= (saved-window-pixel-left saved-1) + (saved-window-pixel-left saved-2)) + (= (saved-window-pixel-top saved-1) + (saved-window-pixel-top saved-2)) + (= (saved-window-pixel-right saved-1) + (saved-window-pixel-right saved-2)) + (= (saved-window-pixel-bottom saved-1) + (saved-window-pixel-bottom saved-2)) + (= (saved-window-hscroll saved-1) + (saved-window-hscroll saved-2)) + (= (saved-window-modeline-hscroll saved-1) + (saved-window-modeline-hscroll saved-2)) + (eq (saved-window-dedicatedp saved-1) + (saved-window-dedicatedp saved-2)) + (maybe-saved-window-equal (saved-window-first-hchild saved-1) + (saved-window-first-hchild saved-2)) + (maybe-saved-window-equal (saved-window-first-vchild saved-1) + (saved-window-first-vchild saved-2)) + (maybe-saved-window-equal (saved-window-next-child saved-1) + (saved-window-next-child saved-2))))) + +(defun maybe-saved-window-equal (maybe-saved-1 maybe-saved-2) + "Returns a boolean indicating whether the two given saved windows +or NILs are identical." + (cond + ((and (not maybe-saved-1) (not maybe-saved-2)) t) + ((not maybe-saved-1) (not maybe-saved-2)) + ((not maybe-saved-2) (not maybe-saved-1)) + (t (saved-window-equal maybe-saved-1 maybe-saved-2)))) + +(defun current-window-configuration (&optional frame) + "Return an object representing the current window configuration of FRAME. +If FRAME is nil or omitted, use the selected frame. +This describes the number of windows, their sizes and current buffers, +and for each window on FRAME the displayed buffer, where display +starts, and the positions of point and mark. +An exception is made for point in the current buffer: +its value is -not- saved." + (let ((frame (or frame (selected-frame)))) + ;; The original C code used complicated but still incomplete logic + ;; to decide if and how to restore the size of the minibuffer. It + ;; goes something like this: +; (let ((real-font-height +; (font-height (face-font 'default) frame)) +; (minibuffer-height +; (if (and (minibuffer-window frame) +; (not (frame-minibuffer-only-p frame))) +; (window-pixel-height (minibuffer-window frame)) +; 0))) +; ...) + + (make-window-configuration + :frame frame + :frame-pixel-width (frame-pixel-width frame) + :frame-pixel-height (frame-pixel-height frame) + :current-buffer (current-buffer) + :min-width window-min-width :min-height window-min-height + :minibuffer-pixel-height (window-pixel-height (minibuffer-window frame)) + ;; this tries to do what the old code did: +; :minibuffer-height (if (zerop (% minibuffer-height real-font-height)) +; (- (/ minibuffer-height real-font-height)) ; lines +; minibuffer-height) ; pixels + :saved-root-window (root-window->saved-window (frame-root-window frame))))) + +(defun root-window->saved-window (window) + "Converts a root window into a tree of saved-window structures." + (let ((buffer (window-buffer window)) + (edges (window-pixel-edges window))) + (let ((left (nth 0 edges)) + (top (nth 1 edges)) + (right (nth 2 edges)) + (bottom (nth 3 edges))) + (let ((saved-window + (make-saved-window + :currentp (eq window (selected-window (window-frame window))) + :minibufferp (eq window (minibuffer-window (window-frame window))) + :minibuffer-scrollp (eq window minibuffer-scroll-window) + :buffer buffer + :pixel-left left :pixel-top top :pixel-right right :pixel-bottom bottom + :hscroll (window-hscroll window) + :modeline-hscroll (modeline-hscroll window) + :dedicatedp (window-dedicated-p window) + :first-hchild (if (window-first-hchild window) + (root-window->saved-window (window-first-hchild window)) + nil) + :first-vchild (if (window-first-vchild window) + (root-window->saved-window (window-first-vchild window)) + nil) + :next-child (if (window-next-child window) + (root-window->saved-window (window-next-child window)) + nil)))) + (if buffer + (progn + (let ((marker (make-marker))) + (set-marker marker (window-start window) buffer) + (setf (saved-window-start-marker saved-window) marker)) + (let ((marker (make-marker))) + (if (eq window (selected-window)) + (set-marker marker (point buffer) buffer) + (set-marker marker (window-point window) buffer)) + (setf (saved-window-point-marker saved-window) marker)) + (setf (saved-window-mark-marker saved-window) + (copy-marker (mark-marker t buffer))))) + saved-window)))) + +(defun set-window-configuration (configuration) + "Set the configuration of windows and buffers as specified by CONFIGURATION. +CONFIGURATION must be a value previously returned +by `current-window-configuration'." + (let ((frame (window-configuration-frame configuration))) + (if (and (frame-live-p frame) + (not (window-configuration-equal configuration + (current-window-configuration)))) + (really-set-window-configuration frame configuration)))) + +(defun really-set-window-configuration (frame configuration) + "Set the window configuration CONFIGURATION on live frame FRAME." + ;; avoid potential temporary problems + (setq window-min-width 0) + (setq window-min-height 0) + (setq minibuffer-scroll-window nil) + + (frame-reduce-to-one-window frame) + (set-window-configuration-frame-size configuration) + + ;; these may have changed because of the delete + (let ((root-window (frame-root-window frame))) + (enlarge-window-pixels + (- (window-configuration-minibuffer-pixel-height configuration) + (window-pixel-height (minibuffer-window frame))) + nil + (minibuffer-window frame)) + + ;; avoid that `set-window-point' will set the buffer's point for + ;; the selected window + (select-window (minibuffer-window frame)) + + (let ((window-configuration-current-window nil)) + (restore-saved-window configuration + root-window + (window-configuration-saved-root-window configuration) + 'vertical) + (if window-configuration-current-window + (select-window window-configuration-current-window)))) + + (setq window-min-width (window-configuration-min-width configuration)) + (setq window-min-height (window-configuration-min-height configuration)) + + (set-buffer (window-configuration-current-buffer configuration))) + +(defun set-window-configuration-frame-size (configuration) + "Restore the frame size of a window configuration." + (set-frame-pixel-size + (window-configuration-frame configuration) + (window-configuration-frame-pixel-width configuration) + (window-configuration-frame-pixel-height configuration))) + +(defun frame-reduce-to-one-window (frame) + "Delete all windows except the minibuffer and one other in FRAME." + (let* ((root-window (frame-root-window frame)) + (combination-start (or (window-first-hchild root-window) + (window-first-vchild root-window)))) + (if combination-start + (window-reduce-to-one combination-start)))) + +(defun window-reduce-to-one (window) + "Make sure only one subwindow of WINDOW is left." + (let ((window (window-next-child window))) + (while window + (if (window-live-p window) + (let ((next (window-next-child window))) + (delete-window window) + (setq window next))))) + (cond + ((window-first-hchild window) + (window-reduce-to-one (window-first-hchild window))) + ((window-first-vchild window) + (window-reduce-to-one (window-first-vchild window))))) + +(defun restore-saved-window (configuration window saved-window direction) + "Within CONFIGURATION, restore WINDOW to the state of SAVED-WINDOW." + (if (saved-window-next-child saved-window) + (progn + (if (not (saved-window-minibufferp (saved-window-next-child saved-window))) + (progn + (cond ((eq direction 'vertical) + (split-window window nil nil)) + ((eq direction 'horizontal) + (split-window window nil t))) + (restore-saved-window configuration + (window-next-child window) + (saved-window-next-child saved-window) + direction))) + + (if (saved-window-first-hchild saved-window) + (restore-saved-window configuration + window + (saved-window-first-hchild saved-window) + 'horizontal)) + (if (saved-window-first-vchild saved-window) + (restore-saved-window configuration + window + (saved-window-first-vchild saved-window) + 'vertical)))) + + (if (not (saved-window-minibufferp saved-window)) + (restore-saved-window-parameters configuration window saved-window))) + +(defun restore-saved-window-parameters (configuration window saved-window) + "Restore the window parameters stored in SAVED-WINDOW on WINDOW." + (let ((buffer (saved-window-buffer saved-window))) + (if (and buffer (buffer-live-p buffer)) + (progn + (set-window-buffer window + (saved-window-buffer saved-window)) + (set-window-start window + (marker-position (saved-window-start-marker saved-window))) + (set-window-point window + (marker-position (saved-window-point-marker saved-window))) + (set-marker (mark-marker t buffer) + (marker-position (saved-window-mark-marker saved-window)) + buffer) + (if (not (eq buffer (window-configuration-current-buffer configuration))) + (goto-char (window-point window) buffer))))) + + (if (and (not (saved-window-first-hchild saved-window)) + (not (saved-window-first-vchild saved-window))) + ;; only set size for non-container windows + (progn + ;; If this is the root window, it may be the only window. + ;; Because of mismatches between actual and reported frame + ;; size, it may not let us actually set the size of the root + ;; window to what we want. --Mike + (if (not (eq window (frame-root-window (window-frame window)))) + (progn + (enlarge-window-pixels (- (saved-window-pixel-width saved-window) + (window-pixel-width window)) + t + window) + (enlarge-window-pixels (- (saved-window-pixel-height saved-window) + (window-pixel-height window)) + nil + window))) + (set-window-hscroll window (saved-window-hscroll saved-window)) + (set-modeline-hscroll window + (saved-window-modeline-hscroll saved-window)) + (set-window-dedicated-p window (saved-window-dedicatedp saved-window)))) + + (if (saved-window-currentp saved-window) + (setq window-configuration-current-window window)) + (if (saved-window-minibuffer-scrollp saved-window) + (setq minibuffer-scroll-window window))) + +(defun saved-window-pixel-width (saved-window) + "Compute the pixel width of SAVED-WINDOW." + (- (saved-window-pixel-right saved-window) + (saved-window-pixel-left saved-window))) + +(defun saved-window-pixel-height (saved-window) + "Compute the pixel height of SAVED-WINDOW." + (- (saved-window-pixel-bottom saved-window) + (saved-window-pixel-top saved-window))) ;; The window-config stack is stored as a list in frame property ;; 'window-config-stack, with the most recent element at the front.