/* Window creation, deletion and examination for GNU Emacs.
Does not include redisplay.
- Copyright (C) 1985,86,87,93,94,95,96,97,1998,2000, 2001
+ Copyright (C) 1985,86,87,93,94,95,96,97,1998,2000, 2001, 2002
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#ifdef MSDOS
#include "msdos.h"
#endif
-#ifdef macintosh
+#ifdef MAC_OS
#include "macterm.h"
#endif
ON_VERTICAL_BORDER,
ON_HEADER_LINE,
ON_LEFT_FRINGE,
- ON_RIGHT_FRINGE
+ ON_RIGHT_FRINGE,
+ ON_LEFT_MARGIN,
+ ON_RIGHT_MARGIN
};
Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configuration_p;
Lisp_Object Qwindow_size_fixed;
+extern Lisp_Object Qleft_margin, Qright_margin;
extern Lisp_Object Qheight, Qwidth;
static int displayed_window_lines P_ ((struct window *));
Lisp_Object minibuf_window;
+/* Non-nil means it is the window whose mode line should be
+ shown as the selected window when the minibuffer is selected. */
+
+Lisp_Object minibuf_selected_window;
+
/* Non-nil means it is the window for C-M-v to scroll
when the mini-buffer is selected. */
Lisp_Object Vtemp_buffer_show_function;
+/* Non-zero means to use mode-line-inactive face in all windows but the
+ selected-window and the minibuffer-scroll-window when the
+ minibuffer is active. */
+int mode_line_in_non_selected_windows;
+
/* If a window gets smaller than either of these, it is removed. */
-int window_min_height;
-int window_min_width;
+EMACS_INT window_min_height;
+EMACS_INT window_min_width;
/* Nonzero implies Fdisplay_buffer should create windows. */
/* Fdisplay_buffer always splits the largest window
if that window is more than this high. */
-int split_height_threshold;
+EMACS_INT split_height_threshold;
/* Number of lines of continuity in scrolling by screenfuls. */
-int next_screen_context_lines;
+EMACS_INT next_screen_context_lines;
/* Incremented for each window created. */
static int inhibit_frame_unsplittable;
#endif /* 0 */
-extern int scroll_margin;
+extern EMACS_INT scroll_margin;
extern Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
\f
bzero (&p->phys_cursor, sizeof (p->phys_cursor));
p->desired_matrix = p->current_matrix = 0;
p->phys_cursor_type = -1;
+ p->phys_cursor_width = -1;
p->must_be_updated_p = 0;
XSETFASTINT (p->window_end_vpos, 0);
XSETFASTINT (p->window_end_pos, 0);
XSETWINDOW (val, p);
XSETFASTINT (p->last_point, 0);
p->frozen_window_start_p = 0;
+ p->height_fixed_p = 0;
+ p->last_cursor_off_p = p->cursor_off_p = 0;
Vwindow_list = Qnil;
return val;
return 3.
if it is on the window's top line, return 4;
if it is in left or right fringe of the window,
- return 5 or 6, and convert *X and *Y to window-relative corrdinates.
+ return 5 or 6, and convert *X and *Y to window-relative coordinates;
+ if it is in the marginal area to the left/right of the window,
+ return 7 or 8, and convert *X and *Y to window-relative coordinates.
X and Y are frame relative pixel coordinates. */
/* The width of the area where the vertical line can be dragged.
(Between mode lines for instance. */
int grabbable_width = ux;
+ int lmargin_width = 0, rmargin_width = 0;
if (*x < x0 || *x >= x1)
return ON_NOTHING;
}
else
{
- *x -= left_x;
- *y -= top_y;
- part = ON_TEXT;
+ lmargin_width = window_box_width (w, LEFT_MARGIN_AREA);
+ rmargin_width = window_box_width (w, RIGHT_MARGIN_AREA);
+ /* You can never be on a margin area if its width is zero. */
+ if (lmargin_width
+ && *x <= window_box_right (w, LEFT_MARGIN_AREA))
+ part = ON_LEFT_MARGIN;
+ else if (rmargin_width
+ && *x >= window_box_left (w, RIGHT_MARGIN_AREA))
+ part = ON_RIGHT_MARGIN;
+ else
+ {
+ part = ON_TEXT;
+ *x -= left_x;
+ *y -= top_y;
+ }
}
}
else
}
else
{
- /* Convert X and Y to window-relative pixel coordinates. */
- *x -= left_x;
- *y -= top_y;
- part = ON_TEXT;
+ lmargin_width = window_box_width (w, LEFT_MARGIN_AREA);
+ rmargin_width = window_box_width (w, RIGHT_MARGIN_AREA);
+ /* You can never be on a margin area if its width is zero.
+ This is especially important for character terminals. */
+ if (lmargin_width
+ && *x <= window_box_right (w, LEFT_MARGIN_AREA))
+ part = ON_LEFT_MARGIN;
+ else if (rmargin_width
+ && *x >= window_box_left (w, RIGHT_MARGIN_AREA))
+ part = ON_RIGHT_MARGIN;
+ else
+ {
+ part = ON_TEXT;
+ /* Convert X and Y to window-relative pixel coordinates. */
+ *x -= left_x;
+ *y -= top_y;
+ }
}
}
If they are in the left fringe of WINDOW, `left-fringe' is returned.
If they are in the right fringe of WINDOW, `right-fringe' is returned.
If they are on the border between WINDOW and its right sibling,
- `vertical-line' is returned. */)
+ `vertical-line' is returned.
+If they are in the windows's left or right marginal areas, `left-margin'\n\
+ or `right-margin' is returned. */)
(coordinates, window)
register Lisp_Object coordinates, window;
{
case ON_RIGHT_FRINGE:
return Qright_fringe;
+ case ON_LEFT_MARGIN:
+ return Qleft_margin;
+
+ case ON_RIGHT_MARGIN:
+ return Qright_margin;
+
default:
abort ();
}
bzero (&p->last_cursor, sizeof (p->last_cursor));
bzero (&p->phys_cursor, sizeof (p->phys_cursor));
p->phys_cursor_type = -1;
+ p->phys_cursor_width = -1;
p->must_be_updated_p = 0;
p->pseudo_window_p = 0;
XSETFASTINT (p->window_end_vpos, 0);
might crash Emacs. */
#define MIN_SAFE_WINDOW_WIDTH (2)
-#define MIN_SAFE_WINDOW_HEIGHT (2)
+#define MIN_SAFE_WINDOW_HEIGHT (1)
/* Make sure that window_min_height and window_min_width are
not too small; if they are, set them to safe minima. */
int *rows, *cols;
{
/* For height, we have to see:
- whether the frame has a minibuffer,
- whether it wants a mode line, and
- whether it has a menu bar. */
- int min_height =
- (FRAME_MINIBUF_ONLY_P (frame) ? MIN_SAFE_WINDOW_HEIGHT - 1
- : (! FRAME_HAS_MINIBUF_P (frame)) ? MIN_SAFE_WINDOW_HEIGHT
- : 2 * MIN_SAFE_WINDOW_HEIGHT - 1);
+ how many windows the frame has at minimum (one or two),
+ and whether it has a menu bar or other special stuff at the top. */
+ int min_height
+ = ((FRAME_MINIBUF_ONLY_P (frame) || ! FRAME_HAS_MINIBUF_P (frame))
+ ? MIN_SAFE_WINDOW_HEIGHT
+ : 2 * MIN_SAFE_WINDOW_HEIGHT);
if (FRAME_TOP_MARGIN (frame) > 0)
min_height += FRAME_TOP_MARGIN (frame);
argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).
If `pop-up-frames' is non-nil, make a new frame if no window shows BUFFER.
Returns the window displaying BUFFER.
-If `display-reuse-frames' is non-nil, and another frame is currently
+If `display-buffer-reuse-frames' is non-nil, and another frame is currently
displaying BUFFER, then simply raise that frame.
The variables `special-display-buffer-names', `special-display-regexps',
}
}
- /* If the user wants pop-up-frames or display-reuse-frames, then
+ /* If the user wants pop-up-frames or display-buffer-reuse-frames,
look for a window showing BUFFER on any visible or iconified frame.
Otherwise search only the current frame. */
if (! NILP (frame))
register int delta1;
register int opht = (*sizefun) (parent);
- /* If trying to grow this window to or beyond size of the parent,
- make delta1 so big that, on shrinking back down,
- all the siblings end up with less than one line and are deleted. */
if (opht <= XINT (*sizep) + delta)
- delta1 = opht * opht * 2;
+ {
+ /* If trying to grow this window to or beyond size of the parent,
+ just delete all the sibling windows. */
+ Lisp_Object start, tem, next;
+
+ start = XWINDOW (parent)->vchild;
+ if (NILP (start))
+ start = XWINDOW (parent)->hchild;
+
+ /* Delete any siblings that come after WINDOW. */
+ tem = XWINDOW (window)->next;
+ while (! NILP (tem))
+ {
+ next = XWINDOW (tem)->next;
+ delete_window (tem);
+ tem = next;
+ }
+
+ /* Delete any siblings that come after WINDOW.
+ Note that if START is not WINDOW, then WINDOW still
+ Fhas siblings, so WINDOW has not yet replaced its parent. */
+ tem = start;
+ while (! EQ (tem, window))
+ {
+ next = XWINDOW (tem)->next;
+ delete_window (tem);
+ tem = next;
+ }
+ }
else
{
/* Otherwise, make delta1 just right so that if we add
++n;
delta1 = n * delta;
- }
- /* Add delta1 lines or columns to this window, and to the parent,
- keeping things consistent while not affecting siblings. */
- XSETINT (CURSIZE (parent), opht + delta1);
- (*setsizefun) (window, XINT (*sizep) + delta1, 0);
-
- /* Squeeze out delta1 lines or columns from our parent,
- shriking this window and siblings proportionately.
- This brings parent back to correct size.
- Delta1 was calculated so this makes this window the desired size,
- taking it all out of the siblings. */
- (*setsizefun) (parent, opht, 0);
+ /* Add delta1 lines or columns to this window, and to the parent,
+ keeping things consistent while not affecting siblings. */
+ XSETINT (CURSIZE (parent), opht + delta1);
+ (*setsizefun) (window, XINT (*sizep) + delta1, 0);
+
+ /* Squeeze out delta1 lines or columns from our parent,
+ shriking this window and siblings proportionately.
+ This brings parent back to correct size.
+ Delta1 was calculated so this makes this window the desired size,
+ taking it all out of the siblings. */
+ (*setsizefun) (parent, opht, 0);
+
+ }
}
XSETFASTINT (p->last_modified, 0);
in the scroll margin at the top. */
move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
while (it.current_y < this_scroll_margin)
- move_it_by_lines (&it, 1, 1);
+ {
+ int prev = it.current_y;
+ move_it_by_lines (&it, 1, 1);
+ if (prev == it.current_y)
+ break;
+ }
SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
}
else if (n < 0)
return result;
}
+DEFUN ("minibuffer-selected-window", Fminibuffer_selected_window, Sminibuffer_selected_window, 0, 0, 0,
+ doc: /* Return the window which was selected when entering the minibuffer.
+Returns nil, if current window is not a minibuffer window. */)
+ ()
+{
+ if (minibuf_level > 0
+ && MINI_WINDOW_P (XWINDOW (selected_window))
+ && !NILP (minibuf_selected_window)
+ && WINDOW_LIVE_P (minibuf_selected_window))
+ return minibuf_selected_window;
+
+ return Qnil;
+}
+
/* Value is the number of lines actually displayed in window W,
as opposed to its height. */
Lisp_Object current_window;
Lisp_Object current_buffer;
Lisp_Object minibuf_scroll_window;
+ Lisp_Object minibuf_selected_window;
Lisp_Object root_window;
Lisp_Object focus_frame;
/* Record the values of window-min-width and window-min-height
window_min_width = XINT (data->min_width);
Vminibuf_scroll_window = data->minibuf_scroll_window;
+ minibuf_selected_window = data->minibuf_selected_window;
return (FRAME_LIVE_P (f) ? Qt : Qnil);
}
data->selected_frame = selected_frame;
data->current_window = FRAME_SELECTED_WINDOW (f);
XSETBUFFER (data->current_buffer, current_buffer);
- data->minibuf_scroll_window = Vminibuf_scroll_window;
+ data->minibuf_scroll_window = minibuf_level > 0 ? Vminibuf_scroll_window : Qnil;
+ data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window : Qnil;
data->root_window = FRAME_ROOT_WINDOW (f);
data->focus_frame = FRAME_FOCUS_FRAME (f);
XSETINT (data->min_height, window_min_height);
if (! EQ (d1->current_buffer, d2->current_buffer))
return 0;
if (! ignore_positions)
- if (! EQ (d1->minibuf_scroll_window, d2->minibuf_scroll_window))
- return 0;
+ {
+ if (! EQ (d1->minibuf_scroll_window, d2->minibuf_scroll_window))
+ return 0;
+ if (! EQ (d1->minibuf_selected_window, d2->minibuf_selected_window))
+ return 0;
+ }
/* Don't compare the root_window field.
We don't require the two configurations
to use the same window object,
staticpro (&Vwindow_list);
+ minibuf_selected_window = Qnil;
+ staticpro (&minibuf_selected_window);
+
DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function,
doc: /* Non-nil means call as function to display a help buffer.
The function is called with one argument, the buffer to be displayed.
doc: /* Non-nil means it is the window that C-M-v in minibuffer should scroll. */);
Vminibuf_scroll_window = Qnil;
+ DEFVAR_BOOL ("mode-line-in-non-selected-windows", &mode_line_in_non_selected_windows,
+ doc: /* Non-nil means to use `mode-line-inactive' face in non-selected windows.
+If the minibuffer is active, the `minibuffer-scroll-window' mode line
+is displayed in the `mode-line' face. */);
+ mode_line_in_non_selected_windows = 1;
+
DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer,
doc: /* If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window. */);
Vother_window_scroll_buffer = Qnil;
defsubr (&Sscroll_right);
defsubr (&Sother_window_for_scrolling);
defsubr (&Sscroll_other_window);
+ defsubr (&Sminibuffer_selected_window);
defsubr (&Srecenter);
defsubr (&Swindow_text_height);
defsubr (&Smove_to_window_line);