From 0cbab19e6e5147fda4c89dcadd2826a35857b5ce Mon Sep 17 00:00:00 2001 From: Martin Rudalics Date: Thu, 26 Dec 2013 12:31:42 +0100 Subject: [PATCH] Some more tinkering with Bug#16051. * window.c (resize_frame_windows): Don't let the size of the root window drop below the frame's default character size. Never ever delete any subwindows - let the window manager do the clipping. * w32fns.c (x_set_tool_bar_lines): Rewrite calculation of number of toolbar lines needed when they exceed the height of the root window. (unwind_create_frame_1): New function. (Fx_create_frame): Generally inhibit calling the window configuration change hook here. Remove extra call to change_frame_size - it's not needed when we don't run the configuration change hook. --- src/ChangeLog | 17 +++++++++++++++++ src/w32fns.c | 43 +++++++++++++++++++++++-------------------- src/window.c | 43 ++++++++++++++++++++++++------------------- 3 files changed, 64 insertions(+), 39 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 70df9cd364..053a498392 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,20 @@ +2013-12-26 Martin Rudalics + + Some more tinkering with Bug#16051. + * window.c (resize_frame_windows): Don't let the size of the + root window drop below the frame's default character size. + Never ever delete any subwindows - let the window manager do the + clipping. + + * w32fns.c (x_set_tool_bar_lines): Rewrite calculation of number + of toolbar lines needed when they exceed the height of the root + window. + (unwind_create_frame_1): New function. + (Fx_create_frame): Generally inhibit calling the window + configuration change hook here. Remove extra call to + change_frame_size - it's not needed when we don't run the + configuration change hook. + 2013-12-26 Paul Eggert Fix core dumps with gcc -fsanitize=address and GNU/Linux. diff --git a/src/w32fns.c b/src/w32fns.c index 02850d8954..9536b14653 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -1683,15 +1683,19 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) /* DELTA is in pixels now. */ delta = (nlines - FRAME_TOOL_BAR_LINES (f)) * unit; - /* Don't resize the tool-bar to more than we have room for. FIXME: - This must use window_sizable eventually !!!!!!!!!!!! */ + /* Don't resize the tool-bar to more than we have room for. Note: The + calculations below and the subsequent call to resize_frame_windows + are inherently flawed because they can make the toolbar higher than + the containing frame. */ if (delta > 0) { root_height = WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f))); if (root_height - delta < unit) { delta = root_height - unit; - nlines = (root_height / unit) + min (1, (root_height % unit)); + /* When creating a new frame and toolbar mode is enabled, we + need at least one toolbar line. */ + nlines = max (FRAME_TOOL_BAR_LINES (f) + delta / unit, 1); } } @@ -4270,6 +4274,12 @@ do_unwind_create_frame (Lisp_Object frame) unwind_create_frame (frame); } +static void +unwind_create_frame_1 (Lisp_Object val) +{ + inhibit_lisp_code = val; +} + static void x_default_font_parameter (struct frame *f, Lisp_Object parms) { @@ -4377,7 +4387,7 @@ This function is an internal primitive--use `make-frame' instead. */) frame = Qnil; GCPRO4 (parameters, parent, name, frame); tem = x_get_arg (dpyinfo, parameters, Qminibuffer, "minibuffer", "Minibuffer", - RES_TYPE_SYMBOL); + RES_TYPE_SYMBOL); if (EQ (tem, Qnone) || NILP (tem)) f = make_frame_without_minibuffer (Qnil, kb, display); else if (EQ (tem, Qonly)) @@ -4407,10 +4417,17 @@ This function is an internal primitive--use `make-frame' instead. */) if (! STRINGP (f->icon_name)) fset_icon_name (f, Qnil); -/* FRAME_DISPLAY_INFO (f) = dpyinfo; */ + /* FRAME_DISPLAY_INFO (f) = dpyinfo; */ /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */ record_unwind_protect (do_unwind_create_frame, frame); + + /* Avoid calling window-configuration-change-hook; otherwise we could + get into all kinds of nasty things like an infloop in next_frame or + violating a (height >= 0) assertion in window_box_height. */ + record_unwind_protect (unwind_create_frame_1, inhibit_lisp_code); + inhibit_lisp_code = Qt; + #ifdef GLYPH_DEBUG image_cache_refcount = FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; @@ -4464,7 +4481,7 @@ This function is an internal primitive--use `make-frame' instead. */) Lisp_Object value; value = x_get_arg (dpyinfo, parameters, Qinternal_border_width, - "internalBorder", "InternalBorder", RES_TYPE_NUMBER); + "internalBorder", "InternalBorder", RES_TYPE_NUMBER); if (! EQ (value, Qunbound)) parameters = Fcons (Fcons (Qinternal_border_width, value), parameters); @@ -4505,20 +4522,6 @@ This function is an internal primitive--use `make-frame' instead. */) happen. */ init_frame_faces (f); - /* PXW: This is a duplicate from below. We have to do it here since - otherwise x_set_tool_bar_lines will work with the character sizes - installed by init_frame_faces while the frame's pixel size is still - calculated from a character size of 1 and we subsequently hit the - eassert (height >= 0) assertion in window_box_height. The - non-pixelwise code apparently worked around this because it had one - frame line vs one toolbar line which left us with a zero root - window height which was obviously wrong as well ... */ - width = FRAME_TEXT_WIDTH (f); - height = FRAME_TEXT_HEIGHT (f); - FRAME_TEXT_HEIGHT (f) = 0; - SET_FRAME_WIDTH (f, 0); - change_frame_size (f, width, height, 1, 0, 0, 1); - /* The X resources controlling the menu-bar and tool-bar are processed specially at startup, and reflected in the mode variables; ignore them here. */ diff --git a/src/window.c b/src/window.c index 9939ec1d8f..9bc95224f7 100644 --- a/src/window.c +++ b/src/window.c @@ -4040,31 +4040,34 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise) int old_pixel_size = horflag ? r->pixel_width : r->pixel_height; /* new_size is the new size of the frame's root window. */ int new_size, new_pixel_size; + int unit = horflag ? FRAME_COLUMN_WIDTH (f) : FRAME_LINE_HEIGHT (f); + /* Don't let the size drop below one unit. This is more comforting + when we are called from x_set_tool_bar_lines since the latter may + have implicitly given us a zero or negative height. */ if (pixelwise) { - new_pixel_size - = (horflag - ? size - : (size - - FRAME_TOP_MARGIN_HEIGHT (f) - - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f)) - ? FRAME_LINE_HEIGHT (f) : 0))); - new_size = new_pixel_size / (horflag - ? FRAME_COLUMN_WIDTH (f) - : FRAME_LINE_HEIGHT (f)); + new_pixel_size = max (horflag + ? size + : (size + - FRAME_TOP_MARGIN_HEIGHT (f) + - ((FRAME_HAS_MINIBUF_P (f) + && !FRAME_MINIBUF_ONLY_P (f)) + ? FRAME_LINE_HEIGHT (f) : 0)), + unit); + new_size = new_pixel_size / unit; } else { - new_size= (horflag - ? size - : (size - - FRAME_TOP_MARGIN (f) - - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f)) - ? 1 : 0))); - new_pixel_size = new_size * (horflag - ? FRAME_COLUMN_WIDTH (f) - : FRAME_LINE_HEIGHT (f)); + new_size = max (horflag + ? size + : (size + - FRAME_TOP_MARGIN (f) + - ((FRAME_HAS_MINIBUF_P (f) + && !FRAME_MINIBUF_ONLY_P (f)) + ? 1 : 0)), + 1); + new_pixel_size = new_size * unit; } r->top_line = FRAME_TOP_MARGIN (f); @@ -4124,6 +4127,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise) window_resize_apply (r, horflag); window_pixel_to_total (r->frame, horflag ? Qt : Qnil); } +#if 0 /* Let's try without killing other windows. */ else { /* We lost. Delete all windows but the frame's @@ -4141,6 +4145,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise) XWINDOW (root)->pixel_height = new_pixel_size; } } +#endif /* 0 */ } } } -- 2.20.1