X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/de509a6071aa4d046e666860468bb7d8bf134e02..ef264c42097f5317044f6a85f895588184c2dbdd:/src/window.c diff --git a/src/window.c b/src/window.c index ca4c41f5e7..5b0d8f4375 100644 --- a/src/window.c +++ b/src/window.c @@ -1,7 +1,8 @@ /* Window creation, deletion and examination for GNU Emacs. Does not include redisplay. Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -799,7 +800,7 @@ coordinates_in_window (w, x, y) if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) || WINDOW_RIGHTMOST_P (w)) { - if (!WINDOW_LEFTMOST_P (w) && abs (*x - x0) < grabbable_width) + if (!WINDOW_LEFTMOST_P (w) && eabs (*x - x0) < grabbable_width) { /* Convert X and Y to window relative coordinates. Vertical border is at the left edge of window. */ @@ -810,7 +811,7 @@ coordinates_in_window (w, x, y) } else { - if (abs (*x - x1) < grabbable_width) + if (eabs (*x - x1) < grabbable_width) { /* Convert X and Y to window relative coordinates. Vertical border is at the right edge of window. */ @@ -858,7 +859,7 @@ coordinates_in_window (w, x, y) if (!w->pseudo_window_p && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w) && !WINDOW_RIGHTMOST_P (w) - && (abs (*x - right_x) < grabbable_width)) + && (eabs (*x - right_x) < grabbable_width)) { /* Convert X and Y to window relative coordinates. Vertical border is at the right edge of window. */ @@ -2670,12 +2671,12 @@ window_fixed_size_p (w, width_p, check_siblings_p) { Lisp_Object child; - for (child = w->prev; !NILP (child); child = XWINDOW (child)->prev) + for (child = w->prev; WINDOWP (child); child = XWINDOW (child)->prev) if (!window_fixed_size_p (XWINDOW (child), width_p, 0)) break; if (NILP (child)) - for (child = w->next; !NILP (child); child = XWINDOW (child)->next) + for (child = w->next; WINDOWP (child); child = XWINDOW (child)->next) if (!window_fixed_size_p (XWINDOW (child), width_p, 0)) break; @@ -2690,9 +2691,8 @@ window_fixed_size_p (w, width_p, check_siblings_p) } /* Return the minimum size for leaf window W. WIDTH_P non-zero means - take into account fringes and the scrollbar of W. WIDTH_P zero - means take into account mode-line and header-line of W. Return 1 - for the minibuffer. */ + take into account fringes and the scrollbar of W. WIDTH_P zero means + take into account mode-line of W. Return 1 for the minibuffer. */ static int window_min_size_2 (w, width_p) @@ -2711,8 +2711,11 @@ window_min_size_2 (w, width_p) else size = max (window_min_height, (MIN_SAFE_WINDOW_HEIGHT - + (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0) - + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0 ))); + /* Don't count the header-line here. It would break + splitting a window with a header-line when the new + window shall have a height of two (calculator does + that). */ + + (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0))); return size; } @@ -3304,6 +3307,25 @@ Fset_window_buffer_unwind (obuf) EXFUN (Fset_window_fringes, 4); EXFUN (Fset_window_scroll_bars, 4); +void +run_window_configuration_change_hook (struct frame *f) +{ + if (! NILP (Vwindow_configuration_change_hook) + && ! NILP (Vrun_hooks)) + { + int count = SPECPDL_INDEX (); + if (SELECTED_FRAME () != f) + { + Lisp_Object frame; + XSETFRAME (frame, f); + record_unwind_protect (Fselect_frame, Fselected_frame ()); + Fselect_frame (frame); + } + call1 (Vrun_hooks, Qwindow_configuration_change_hook); + unbind_to (count, Qnil); + } +} + /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero means it's allowed to run hooks. See make_frame for a case where it's not allowed. KEEP_MARGINS_P non-zero means that the current @@ -3318,6 +3340,7 @@ set_window_buffer (window, buffer, run_hooks_p, keep_margins_p) struct window *w = XWINDOW (window); struct buffer *b = XBUFFER (buffer); int count = SPECPDL_INDEX (); + int samebuf = EQ (buffer, w->buffer); w->buffer = buffer; @@ -3336,16 +3359,28 @@ set_window_buffer (window, buffer, run_hooks_p, keep_margins_p) XSETFASTINT (w->window_end_vpos, 0); bzero (&w->last_cursor, sizeof w->last_cursor); w->window_end_valid = Qnil; - w->hscroll = w->min_hscroll = make_number (0); - w->vscroll = 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), - buffer); - w->start_at_line_beg = Qnil; - w->force_start = Qnil; - XSETFASTINT (w->last_modified, 0); - XSETFASTINT (w->last_overlay_modified, 0); + if (!(keep_margins_p && samebuf)) + { /* If we're not actually changing the buffer, Don't reset hscroll and + vscroll. This case happens for example when called from + change_frame_size_1, where we use a dummy call to + Fset_window_buffer on the frame's selected window (and no other) + just in order to run window-configuration-change-hook. + Resetting hscroll and vscroll here is problematic for things like + image-mode and doc-view-mode since it resets the image's position + whenever we resize the frame. */ + w->hscroll = w->min_hscroll = make_number (0); + w->vscroll = 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), + buffer); + w->start_at_line_beg = Qnil; + w->force_start = Qnil; + XSETFASTINT (w->last_modified, 0); + XSETFASTINT (w->last_overlay_modified, 0); + } + /* Maybe we could move this into the `if' but it's not obviously safe and + I doubt it's worth the trouble. */ windows_or_buffers_changed++; /* We must select BUFFER for running the window-scroll-functions. @@ -3392,10 +3427,7 @@ set_window_buffer (window, buffer, run_hooks_p, keep_margins_p) if (! NILP (Vwindow_scroll_functions)) run_hook_with_args_2 (Qwindow_scroll_functions, window, Fmarker_position (w->start)); - - if (! NILP (Vwindow_configuration_change_hook) - && ! NILP (Vrun_hooks)) - call1 (Vrun_hooks, Qwindow_configuration_change_hook); + run_window_configuration_change_hook (XFRAME (WINDOW_FRAME (w))); } unbind_to (count, Qnil); @@ -4291,10 +4323,10 @@ enlarge_window (window, delta, horiz_flag) /* Find the total we can get from other siblings without deleting them. */ maximum = 0; - for (next = p->next; ! NILP (next); next = XWINDOW (next)->next) + for (next = p->next; WINDOWP (next); next = XWINDOW (next)->next) maximum += (*sizefun) (next) - window_min_size (XWINDOW (next), horiz_flag, 0, 0); - for (prev = p->prev; ! NILP (prev); prev = XWINDOW (prev)->prev) + for (prev = p->prev; WINDOWP (prev); prev = XWINDOW (prev)->prev) maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev), horiz_flag, 0, 0); @@ -4442,10 +4474,10 @@ enlarge_window (window, delta, horiz_flag) Lisp_Object s; int n = 1; - for (s = w->next; !NILP (s); s = XWINDOW (s)->next) + for (s = w->next; WINDOWP (s); s = XWINDOW (s)->next) if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0)) ++n; - for (s = w->prev; !NILP (s); s = XWINDOW (s)->prev) + for (s = w->prev; WINDOWP (s); s = XWINDOW (s)->prev) if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0)) ++n; @@ -4701,7 +4733,7 @@ shrink_window_lowest_first (w, height) /* Find the last child. We are taking space from lowest windows first, so we iterate over children from the last child backwards. */ - for (child = w->vchild; !NILP (child); child = XWINDOW (child)->next) + for (child = w->vchild; WINDOWP (child); child = XWINDOW (child)->next) last_child = child; /* Assign new heights. We leave only MIN_SAFE_WINDOW_HEIGHT. */ @@ -5497,7 +5529,7 @@ scroll_command (n, direction) { int count = SPECPDL_INDEX (); - xassert (abs (direction) == 1); + xassert (eabs (direction) == 1); /* If selected window's buffer isn't current, make it current for the moment. But don't screw up if window_scroll gets an error. */ @@ -6049,10 +6081,8 @@ 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; Lisp_Object selected_frame; Lisp_Object current_window; Lisp_Object current_buffer; @@ -6060,19 +6090,25 @@ struct save_window_data Lisp_Object minibuf_selected_window; Lisp_Object root_window; Lisp_Object focus_frame; - /* Record the values of window-min-width and window-min-height - so that window sizes remain consistent with them. */ - Lisp_Object min_width, min_height; /* A vector, each of whose elements is a struct saved_window for one window. */ Lisp_Object saved_windows; + + /* All fields above are traced by the GC. + From `fame-cols' down, the fields are ignored by the GC. */ + + int frame_cols, frame_lines, frame_menu_bar_lines; + int frame_tool_bar_lines; + /* Record the values of window-min-width and window-min-height + so that window sizes remain consistent with them. */ + int min_width, min_height; }; /* This is saved as a Lisp_Vector */ 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; @@ -6205,18 +6241,20 @@ the return value is nil. Otherwise the value is t. */) if it runs during this. */ BLOCK_INPUT; - if (XFASTINT (data->frame_lines) != previous_frame_lines - || XFASTINT (data->frame_cols) != previous_frame_cols) - change_frame_size (f, XFASTINT (data->frame_lines), - XFASTINT (data->frame_cols), 0, 0, 0); + if (data->frame_lines != previous_frame_lines + || data->frame_cols != previous_frame_cols) + change_frame_size (f, data->frame_lines, + data->frame_cols, 0, 0, 0); #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS) - if (XFASTINT (data->frame_menu_bar_lines) + if (data->frame_menu_bar_lines != previous_frame_menu_bar_lines) - x_set_menu_bar_lines (f, data->frame_menu_bar_lines, make_number (0)); + x_set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines), + make_number (0)); #ifdef HAVE_WINDOW_SYSTEM - if (XFASTINT (data->frame_tool_bar_lines) + if (data->frame_tool_bar_lines != previous_frame_tool_bar_lines) - x_set_tool_bar_lines (f, data->frame_tool_bar_lines, make_number (0)); + x_set_tool_bar_lines (f, make_number (data->frame_tool_bar_lines), + make_number (0)); #endif #endif @@ -6450,8 +6488,8 @@ the return value is nil. Otherwise the value is t. */) Fset_buffer (new_current_buffer); /* Restore the minimum heights recorded in the configuration. */ - window_min_height = XINT (data->min_height); - window_min_width = XINT (data->min_width); + window_min_height = data->min_height; + window_min_width = data->min_width; Vminibuf_scroll_window = data->minibuf_scroll_window; minibuf_selected_window = data->minibuf_selected_window; @@ -6652,7 +6690,6 @@ redirection (see `redirect-frame-focus'). */) register Lisp_Object tem; register int n_windows; register struct save_window_data *data; - register struct Lisp_Vector *vec; register int i; FRAME_PTR f; @@ -6662,13 +6699,13 @@ redirection (see `redirect-frame-focus'). */) f = XFRAME (frame); n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f))); - vec = allocate_other_vector (VECSIZE (struct save_window_data)); - data = (struct save_window_data *)vec; + data = ALLOCATE_PSEUDOVECTOR (struct save_window_data, frame_cols, + PVEC_WINDOW_CONFIGURATION); - XSETFASTINT (data->frame_cols, FRAME_COLS (f)); - XSETFASTINT (data->frame_lines, FRAME_LINES (f)); - XSETFASTINT (data->frame_menu_bar_lines, FRAME_MENU_BAR_LINES (f)); - XSETFASTINT (data->frame_tool_bar_lines, FRAME_TOOL_BAR_LINES (f)); + data->frame_cols = FRAME_COLS (f); + data->frame_lines = FRAME_LINES (f); + data->frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f); + data->frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f); data->selected_frame = selected_frame; data->current_window = FRAME_SELECTED_WINDOW (f); XSETBUFFER (data->current_buffer, current_buffer); @@ -6676,8 +6713,8 @@ redirection (see `redirect-frame-focus'). */) 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); - XSETINT (data->min_width, window_min_width); + data->min_height = window_min_height; + data->min_width = window_min_width; tem = Fmake_vector (make_number (n_windows), Qnil); data->saved_windows = tem; for (i = 0; i < n_windows; i++) @@ -7184,11 +7221,11 @@ compare_window_configurations (c1, c2, ignore_positions) sw1 = XVECTOR (d1->saved_windows); sw2 = XVECTOR (d2->saved_windows); - if (! EQ (d1->frame_cols, d2->frame_cols)) + if (d1->frame_cols != d2->frame_cols) return 0; - if (! EQ (d1->frame_lines, d2->frame_lines)) + if (d1->frame_lines != d2->frame_lines) return 0; - if (! EQ (d1->frame_menu_bar_lines, d2->frame_menu_bar_lines)) + if (d1->frame_menu_bar_lines != d2->frame_menu_bar_lines) return 0; if (! EQ (d1->selected_frame, d2->selected_frame)) return 0; @@ -7210,9 +7247,9 @@ compare_window_configurations (c1, c2, ignore_positions) if everything else compares equal. */ if (! EQ (d1->focus_frame, d2->focus_frame)) return 0; - if (! EQ (d1->min_width, d2->min_width)) + if (d1->min_width != d2->min_width) return 0; - if (! EQ (d1->min_height, d2->min_height)) + if (d1->min_height != d2->min_height) return 0; /* Verify that the two confis have the same number of windows. */