summaryrefslogtreecommitdiff
path: root/src/window.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c115
1 files changed, 79 insertions, 36 deletions
diff --git a/src/window.c b/src/window.c
index 43ea423dd9d..c51649679da 100644
--- a/src/window.c
+++ b/src/window.c
@@ -21,6 +21,8 @@ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
#include <config.h>
+#include <stdio.h>
+
#include "lisp.h"
#include "buffer.h"
#include "keyboard.h"
@@ -34,6 +36,7 @@ Boston, MA 02110-1301, USA. */
#include "dispextern.h"
#include "blockinput.h"
#include "intervals.h"
+#include "termhooks.h" /* For FRAME_TERMINAL. */
#ifdef HAVE_X_WINDOWS
#include "xterm.h"
@@ -190,6 +193,10 @@ Lisp_Object Qtemp_buffer_show_hook;
EMACS_INT split_height_threshold;
+/* How to split windows (horizontally/vertically/hybrid). */
+
+Lisp_Object Vsplit_window_preferred_function;
+
/* Number of lines of continuity in scrolling by screenfuls. */
EMACS_INT next_screen_context_lines;
@@ -1788,12 +1795,28 @@ candidate_window_p (window, owindow, minibuf, all_frames)
else if (EQ (all_frames, Qvisible))
{
FRAME_SAMPLE_VISIBILITY (f);
- candidate_p = FRAME_VISIBLE_P (f);
+ candidate_p = FRAME_VISIBLE_P (f)
+ && (FRAME_TERMINAL (XFRAME (w->frame))
+ == FRAME_TERMINAL (XFRAME (selected_frame)));
+
}
else if (INTEGERP (all_frames) && XINT (all_frames) == 0)
{
FRAME_SAMPLE_VISIBILITY (f);
- candidate_p = FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f);
+ candidate_p = (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)
+#ifdef HAVE_X_WINDOWS
+ /* Yuck!! If we've just created the frame and the
+ window-manager requested the user to place it
+ manually, the window may still not be considered
+ `visible'. I'd argue it should be at least
+ something like `iconified', but don't know how to do
+ that yet. --Stef */
+ || (FRAME_X_P (f) && f->output_data.x->asked_for_visible
+ && !f->output_data.x->has_been_visible)
+#endif
+ )
+ && (FRAME_TERMINAL (XFRAME (w->frame))
+ == FRAME_TERMINAL (XFRAME (selected_frame)));
}
else if (WINDOWP (all_frames))
candidate_p = (EQ (FRAME_MINIBUF_WINDOW (f), all_frames)
@@ -2162,8 +2185,10 @@ window_loop (type, obj, mini, frames)
if (NILP (best_window))
best_window = window;
else if (EQ (window, selected_window))
- /* For compatibility with 20.x, prefer to return
- selected-window. */
+ /* Prefer to return selected-window. */
+ RETURN_UNGCPRO (window);
+ else if (EQ (Fwindow_frame (window), selected_frame))
+ /* Prefer windows on the current frame. */
best_window = window;
}
break;
@@ -3445,6 +3470,22 @@ selects the buffer of the selected window before each command. */)
if (EQ (window, selected_window))
return window;
+ sf = SELECTED_FRAME ();
+ if (XFRAME (WINDOW_FRAME (w)) != sf)
+ {
+ XFRAME (WINDOW_FRAME (w))->selected_window = window;
+ /* Use this rather than Fhandle_switch_frame
+ so that FRAME_FOCUS_FRAME is moved appropriately as we
+ move around in the state where a minibuffer in a separate
+ frame is active. */
+ Fselect_frame (WINDOW_FRAME (w));
+ /* Fselect_frame called us back so we've done all the work already. */
+ eassert (EQ (window, selected_window));
+ return window;
+ }
+ else
+ sf->selected_window = window;
+
/* Store the current buffer's actual point into the
old selected window. It belongs to that window,
and when the window is not selected, must be in the window. */
@@ -3458,18 +3499,6 @@ selects the buffer of the selected window before each command. */)
}
selected_window = window;
- sf = SELECTED_FRAME ();
- if (XFRAME (WINDOW_FRAME (w)) != sf)
- {
- XFRAME (WINDOW_FRAME (w))->selected_window = window;
- /* Use this rather than Fhandle_switch_frame
- so that FRAME_FOCUS_FRAME is moved appropriately as we
- move around in the state where a minibuffer in a separate
- frame is active. */
- Fselect_frame (WINDOW_FRAME (w));
- }
- else
- sf->selected_window = window;
if (NILP (norecord))
record_buffer (w->buffer);
@@ -3649,7 +3678,7 @@ If `even-window-heights' is non-nil, window heights will be evened out
if displaying the buffer causes two vertically adjacent windows to be
displayed. */)
(buffer, not_this_window, frame)
- register Lisp_Object buffer, not_this_window, frame;
+ Lisp_Object buffer, not_this_window, frame;
{
register Lisp_Object window, tem, swp;
struct frame *f;
@@ -3721,6 +3750,8 @@ displayed. */)
|| !NILP (XWINDOW (FRAME_ROOT_WINDOW (f))->dedicated))
{
Lisp_Object frames;
+ struct gcpro gcpro1;
+ GCPRO1 (buffer);
frames = Qnil;
if (FRAME_MINIBUF_ONLY_P (f))
@@ -3752,26 +3783,26 @@ displayed. */)
if (!NILP (window)
&& ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window)->frame))
&& WINDOW_FULL_WIDTH_P (XWINDOW (window))
- && (window_height (window) >= split_height_threshold
- || (NILP (XWINDOW (window)->parent)))
+ && (window_height (window) >= split_height_threshold
+ || (NILP (XWINDOW (window)->parent)))
&& (window_height (window)
>= (2 * window_min_size_2 (XWINDOW (window), 0))))
- window = Fsplit_window (window, Qnil, Qnil);
+ window = call1 (Vsplit_window_preferred_function, window);
else
{
Lisp_Object upper, other;
window = Fget_lru_window (frames, Qt);
- /* If the LRU window is tall enough, and either eligible for splitting
- and selected or the only window, split it. */
+ /* If the LRU window is tall enough, and either eligible for
+ splitting and selected or the only window, split it. */
if (!NILP (window)
&& ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window)->frame))
- && ((EQ (window, selected_window)
- && window_height (window) >= split_height_threshold)
- || (NILP (XWINDOW (window)->parent)))
- && (window_height (window)
- >= (2 * window_min_size_2 (XWINDOW (window), 0))))
- window = Fsplit_window (window, Qnil, Qnil);
+ && ((EQ (window, selected_window)
+ && window_height (window) >= split_height_threshold)
+ || (NILP (XWINDOW (window)->parent)))
+ && (window_height (window)
+ >= (2 * window_min_size_2 (XWINDOW (window), 0))))
+ window = call1 (Vsplit_window_preferred_function, window);
else
window = Fget_lru_window (frames, Qnil);
/* If Fget_lru_window returned nil, try other approaches. */
@@ -3817,6 +3848,7 @@ displayed. */)
0);
}
}
+ UNGCPRO;
}
else
window = Fget_lru_window (Qnil, Qnil);
@@ -6017,7 +6049,7 @@ zero means top of window, negative means relative to bottom of window. */)
struct save_window_data
{
- EMACS_INT size_from_Lisp_Vector_struct;
+ EMACS_UINT size;
struct Lisp_Vector *next_from_Lisp_Vector_struct;
Lisp_Object frame_cols, frame_lines, frame_menu_bar_lines;
Lisp_Object frame_tool_bar_lines;
@@ -6040,7 +6072,7 @@ struct save_window_data
struct saved_window
{
/* these first two must agree with struct Lisp_Vector in lisp.h */
- EMACS_INT size_from_Lisp_Vector_struct;
+ EMACS_UINT size;
struct Lisp_Vector *next_from_Lisp_Vector_struct;
Lisp_Object window;
@@ -6631,6 +6663,7 @@ redirection (see `redirect-frame-focus'). */)
n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f)));
vec = allocate_other_vector (VECSIZE (struct save_window_data));
+ XSETPVECTYPE (vec, PVEC_WINDOW_CONFIGURATION);
data = (struct save_window_data *)vec;
XSETFASTINT (data->frame_cols, FRAME_COLS (f));
@@ -7102,11 +7135,12 @@ freeze_window_start (w, freeze_p)
struct window *w;
void *freeze_p;
{
- if (w == XWINDOW (selected_window)
- || MINI_WINDOW_P (w)
- || (MINI_WINDOW_P (XWINDOW (selected_window))
- && ! NILP (Vminibuf_scroll_window)
- && w == XWINDOW (Vminibuf_scroll_window)))
+ if (MINI_WINDOW_P (w)
+ || (WINDOWP (selected_window) /* Can be nil in corner cases. */
+ && (w == XWINDOW (selected_window)
+ || (MINI_WINDOW_P (XWINDOW (selected_window))
+ && ! NILP (Vminibuf_scroll_window)
+ && w == XWINDOW (Vminibuf_scroll_window)))))
freeze_p = NULL;
w->frozen_window_start_p = freeze_p != NULL;
@@ -7269,7 +7303,7 @@ and scrolling positions. */)
void
init_window_once ()
{
- struct frame *f = make_terminal_frame ();
+ struct frame *f = make_initial_frame ();
XSETFRAME (selected_frame, f);
Vterminal_frame = selected_frame;
minibuf_window = f->minibuffer_window;
@@ -7488,6 +7522,15 @@ by `display-buffer'. The value is in line units.
If there is only one window, it is split regardless of this value. */);
split_height_threshold = 500;
+ DEFVAR_LISP ("split-window-preferred-function",
+ &Vsplit_window_preferred_function,
+ doc: /* Function to use to split a window.
+This is used by `display-buffer' to allow the user to choose whether
+to split windows horizontally or vertically or some mix of the two.
+It is called with a window as single argument and should split it in two
+and return the new window. */);
+ Vsplit_window_preferred_function = intern ("split-window");
+
DEFVAR_INT ("window-min-height", &window_min_height,
doc: /* *Delete any window less than this tall (including its mode line).
The value is in line units. */);