#define max(a, b) ((a) < (b) ? (b) : (a))
#endif
+/* Values returned from coordinates_in_window. */
+
+enum window_part
+{
+ ON_NOTHING,
+ ON_TEXT,
+ ON_MODE_LINE,
+ ON_VERTICAL_BORDER,
+ ON_HEADER_LINE,
+ ON_LEFT_FRINGE,
+ ON_RIGHT_FRINGE
+};
+
Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configuration_p;
-Lisp_Object Qwindow_size_fixed, Qleft_bitmap_area, Qright_bitmap_area;
+Lisp_Object Qwindow_size_fixed, Qleft_fringe, Qright_fringe;
extern Lisp_Object Qheight, Qwidth;
static struct window *decode_window P_ ((Lisp_Object));
X and Y are frame relative pixel coordinates. */
-static int
+static enum window_part
coordinates_in_window (w, x, y)
register struct window *w;
register int *x, *y;
{
/* Let's make this a global enum later, instead of using numbers
everywhere. */
- enum {ON_NOTHING, ON_TEXT, ON_MODE_LINE, ON_VERTICAL_BORDER,
- ON_HEADER_LINE, ON_LEFT_FRINGE, ON_RIGHT_FRINGE};
-
struct frame *f = XFRAME (WINDOW_FRAME (w));
int left_x, right_x, top_y, bottom_y;
int flags_area_width = FRAME_LEFT_FLAGS_AREA_WIDTH (f);
- int part;
+ enum window_part part;
int ux = CANON_X_UNIT (f), uy = CANON_Y_UNIT (f);
int x0 = XFASTINT (w->left) * ux;
int x1 = x0 + XFASTINT (w->width) * ux;
+ /* The width of the area where the vertical line can be dragged.
+ (Between mode lines for instance. */
+ int grabbable_width = ux;
if (*x < x0 || *x >= x1)
return ON_NOTHING;
if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
{
- if (abs (*x - x0) < ux / 2)
+ if (abs (*x - x0) < grabbable_width)
part = ON_VERTICAL_BORDER;
}
- else if (!WINDOW_RIGHTMOST_P (w) && abs (*x - x1) < ux / 2)
+ else if (!WINDOW_RIGHTMOST_P (w) && abs (*x - x1) < grabbable_width)
part = ON_VERTICAL_BORDER;
}
else if (WINDOW_WANTS_HEADER_LINE_P (w)
if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
{
- if (abs (*x - x0) < ux / 2)
+ if (abs (*x - x0) < grabbable_width)
part = ON_VERTICAL_BORDER;
}
- else if (!WINDOW_RIGHTMOST_P (w) && abs (*x - x1) < ux / 2)
+ else if (!WINDOW_RIGHTMOST_P (w) && abs (*x - x1) < grabbable_width)
part = ON_VERTICAL_BORDER;
}
/* Outside anything interesting? */
|| *x < (left_x
- flags_area_width
- FRAME_LEFT_SCROLL_BAR_WIDTH (f) * ux)
- || *x > right_x + flags_area_width)
+ || *x > (right_x
+ + flags_area_width
+ + FRAME_RIGHT_SCROLL_BAR_WIDTH (f) * ux))
{
part = ON_NOTHING;
}
if (!w->pseudo_window_p
&& !FRAME_HAS_VERTICAL_SCROLL_BARS (f)
&& !WINDOW_RIGHTMOST_P (w)
- && (abs (*x - right_x - flags_area_width) < ux / 2))
+ && (abs (*x - right_x - flags_area_width) < grabbable_width))
{
part = ON_VERTICAL_BORDER;
}
"Return non-nil if COORDINATES are in WINDOW.\n\
COORDINATES is a cons of the form (X . Y), X and Y being distances\n\
measured in characters from the upper-left corner of the frame.\n\
-(0 . 0) denotes the character in the upper left corner of the\n\
+\(0 . 0) denotes the character in the upper left corner of the\n\
frame.\n\
If COORDINATES are in the text portion of WINDOW,\n\
the coordinates relative to the window are returned.\n\
If they are in the mode line of WINDOW, `mode-line' is returned.\n\
If they are in the top mode line of WINDOW, `header-line' is returned.\n\
-If they are in the bitmap-area to the left of the window,\n\
- `left-bitmap-area' is returned, if they are in the area on the right of\n\
- the window, `right-bitmap-area' is returned.\n\
+If they are in the fringe to the left of the window,\n\
+ `left-fringe' is returned, if they are in the area on the right of\n\
+ the window, `right-fringe' is returned.\n\
If they are on the border between WINDOW and its right sibling,\n\
`vertical-line' is returned.")
(coordinates, window)
switch (coordinates_in_window (w, &x, &y))
{
- case 0: /* NOT in window at all. */
+ case ON_NOTHING:
return Qnil;
- case 1: /* In text part of window. */
- /* X and Y are now window relative pixel coordinates.
- Convert them to canonical char units before returning
- them. */
+ case ON_TEXT:
+ /* X and Y are now window relative pixel coordinates. Convert
+ them to canonical char units before returning them. */
return Fcons (CANON_X_FROM_PIXEL_X (f, x),
CANON_Y_FROM_PIXEL_Y (f, y));
- case 2: /* In mode line of window. */
+ case ON_MODE_LINE:
return Qmode_line;
- case 3: /* On right border of window. */
+ case ON_VERTICAL_BORDER:
return Qvertical_line;
- case 4:
+ case ON_HEADER_LINE:
return Qheader_line;
- case 5:
- return Qleft_bitmap_area;
+ case ON_LEFT_FRINGE:
+ return Qleft_fringe;
- case 6:
- return Qright_bitmap_area;
+ case ON_RIGHT_FRINGE:
+ return Qright_fringe;
default:
abort ();
void *user_data;
{
struct check_window_data *cw = (struct check_window_data *) user_data;
- int found;
+ enum window_part found;
+ int continue_p = 1;
found = coordinates_in_window (w, cw->x, cw->y);
- if (found)
+ if (found != ON_NOTHING)
{
*cw->part = found - 1;
XSETWINDOW (*cw->window, w);
+ continue_p = 0;
}
- return !found;
+ return continue_p;
}
&& tool_bar_p
&& WINDOWP (f->tool_bar_window)
&& XINT (XWINDOW (f->tool_bar_window)->height) > 0
- && coordinates_in_window (XWINDOW (f->tool_bar_window), &x, &y))
+ && (coordinates_in_window (XWINDOW (f->tool_bar_window), &x, &y)
+ != ON_NOTHING))
{
*part = 0;
window = f->tool_bar_window;
{
struct text_pos startp;
struct it it;
+ struct buffer *old_buffer = NULL, *b = XBUFFER (buf);
/* In case W->start is out of the range, use something
reasonable. This situation occured when loading a file with
/* Cannot use Fvertical_motion because that function doesn't
cope with variable-height lines. */
+ if (b != current_buffer)
+ {
+ old_buffer = current_buffer;
+ set_buffer_internal (b);
+ }
+
start_display (&it, w, startp);
move_it_vertically (&it, window_box_height (w));
move_it_past_eol (&it);
value = make_number (IT_CHARPOS (it));
+
+ if (old_buffer)
+ set_buffer_internal (old_buffer);
}
else
XSETINT (value, BUF_Z (XBUFFER (buf)) - XFASTINT (w->window_end_pos));
(frame, minibuf, window)
Lisp_Object frame, minibuf, window;
{
-
if (NILP (window))
window = selected_window;
if (NILP (frame))
else
window = FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
- /* Figure out the last window we're going to mess with. Since
- Fnext_window, given the same options, is guaranteed to go in a
- ring, we can just use Fprevious_window to find the last one.
-
- We can't just wait until we hit the first window again, because
- it might be deleted. */
-
windows = window_list_1 (window, mini ? Qt : Qnil, frame_arg);
GCPRO1 (windows);
best_window = Qnil;
? EQ (window, minibuf_window)
: 1))
{
- UNGCPRO;
- return window;
+ if (NILP (best_window))
+ best_window = window;
+ else if (EQ (window, selected_window))
+ /* For compatibility with 20.x, prefer to return
+ selected-window. */
+ best_window = window;
}
break;
sideward = &w->hchild;
forward = &w->vchild;
w->height = make_number (size);
+ w->orig_height = Qnil;
}
if (!NILP (*sideward))
XSETFASTINT (w->window_end_vpos, 0);
bzero (&w->last_cursor, sizeof w->last_cursor);
w->window_end_valid = Qnil;
- XSETFASTINT (w->hscroll, 0);
- XSETFASTINT (w->min_hscroll, 0);
+ w->hscroll = w->min_hscroll = make_number (0);
+ w->vscroll = make_number (0);
set_marker_both (w->pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
set_marker_restricted (w->start,
make_number (b->last_window_start),
\f
DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 2, "p",
"Make current window ARG lines bigger.\n\
-From program, optional second arg non-nil means grow sideways ARG columns.")
+From program, optional second arg non-nil means grow sideways ARG columns.\n\
+Interactively, if an argument is not given, make the window one line bigger.")
(arg, side)
register Lisp_Object arg, side;
{
DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 2, "p",
"Make current window ARG lines smaller.\n\
-From program, optional second arg non-nil means shrink sideways arg columns.")
+From program, optional second arg non-nil means shrink sideways arg columns.\n\
+Interactively, if an argument is not given, make the window one line smaller.")
(arg, side)
register Lisp_Object arg, side;
{
}
else if (XFASTINT (w->height) > 1)
{
+ /* Distribute the additional lines of the mini-window
+ among the other windows. */
Lisp_Object window;
XSETWINDOW (window, w);
enlarge_window (window, 1 - XFASTINT (w->height), 0);
hscroll = XINT (w->hscroll) + XINT (arg);
result = Fset_window_hscroll (selected_window, make_number (hscroll));
- if (!NILP (Finteractive_p ()))
+ if (interactive_p (0))
w->min_hscroll = w->hscroll;
return result;
hscroll = XINT (w->hscroll) - XINT (arg);
result = Fset_window_hscroll (selected_window, make_number (hscroll));
- if (!NILP (Finteractive_p ()))
+ if (interactive_p (0))
w->min_hscroll = w->hscroll;
return result;
SET_TEXT_POS_FROM_MARKER (start, w->start);
start_display (&it, w, start);
move_it_vertically (&it, height);
-
- if (old_buffer)
- set_buffer_internal (old_buffer);
-
- bottom_y = it.current_y + it.max_ascent + it.max_descent;
-
- if (bottom_y > it.current_y && bottom_y <= it.last_visible_y)
- /* Hit a line without a terminating newline. */
- it.vpos++;
+ bottom_y = line_bottom_y (&it);
/* Add in empty lines at the bottom of the window. */
if (bottom_y < height)
{
- struct frame *f = XFRAME (w->frame);
- int rest = height - bottom_y;
- int lines = rest / CANON_Y_UNIT (f);
- it.vpos += lines;
+ int uy = CANON_Y_UNIT (it.f);
+ it.vpos += (height - bottom_y + uy - 1) / uy;
}
+ if (old_buffer)
+ set_buffer_internal (old_buffer);
+
return it.vpos;
}
XSETINT (arg, XINT (arg) + lines);
}
+ /* Skip past a partially visible first line. */
if (w->vscroll)
- /* Skip past a partially visible first line. */
XSETINT (arg, XINT (arg) + 1);
return Fvertical_motion (arg, window);
void
syms_of_window ()
{
- Qleft_bitmap_area = intern ("left-bitmap-area");
- staticpro (&Qleft_bitmap_area);
- Qright_bitmap_area = intern ("right-bitmap-area");
- staticpro (&Qright_bitmap_area);
+ Qleft_fringe = intern ("left-fringe");
+ staticpro (&Qleft_fringe);
+ Qright_fringe = intern ("right-fringe");
+ staticpro (&Qright_fringe);
Qwindow_size_fixed = intern ("window-size-fixed");
staticpro (&Qwindow_size_fixed);