all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Eli Zaretskii <eliz@gnu.org>
To: martin rudalics <rudalics@gmx.at>
Cc: jarekczek@poczta.onet.pl, 16051@debbugs.gnu.org
Subject: bug#16051: 24.3.50; Emacs hang - resize frame manually
Date: Mon, 23 Dec 2013 18:57:49 +0200	[thread overview]
Message-ID: <83zjnr7bea.fsf@gnu.org> (raw)
In-Reply-To: <52B5CC35.10404@gmx.at>

> Date: Sat, 21 Dec 2013 18:13:25 +0100
> From: martin rudalics <rudalics@gmx.at>
> CC: Jarek Czekalski <jarekczek@poczta.onet.pl>, 16051@debbugs.gnu.org
> 
>  > I don't think it's important, certainly not extremely important.  You
>  > can hang Emacs with as little as '(while t)'.  Users who do
>  > unreasonable things should expect trouble, because Emacs gives them a
>  > lot of rope to hang themselves.
> 
> If I do drag _very_ fast as described by the OP, Emacs reliably crashes
> here as:
> 
> 
> #0  terminate_due_to_signal (sig=22, backtrace_limit=2147483647) at emacs.c:351
> #1  0x0116400a in die (msg=0x14763e0 "row >= 0 && row < matrix->nrows", file=0x147618c "dispnew.c", line=1369) at alloc.c:6742
> #2  0x01004ed3 in matrix_row (matrix=0x36e2800, row=7) at dispnew.c:1369
> #3  0x01040eaa in hscroll_window_tree (window=...) at xdisp.c:12610
> #4  0x01041398 in hscroll_windows (window=...) at xdisp.c:12737
> #5  0x010437bd in redisplay_internal () at xdisp.c:13631
> #6  0x01044126 in redisplay_preserve_echo_area (from_where=11) at xdisp.c:13856

It turns out this bug has 3 separate parts.  2 of them are very clear
and uncontroversial, so I simply fixed them; see revision 115718 on
the trunk.  After that, there are no more assertion violations like
above, and no hangs, and it is much harder to cause a redisplay loop.
Also, the only redisplay loops I can trigger are immediately
interrupted by C-g.  But since such loops can still be triggered,
there's another part to this riddle.  

Here, the problem and the solution seem clear to me, but since the
code is quite deliberately doing what it does, I'd like to ask Martin
about the underlying logic.  I'm talking about this part of
redisplay_tool_bar:

	  if (change_height_p)
	    {
	      int new_lines = ((new_height + FRAME_LINE_HEIGHT (f) - 1)
			       / FRAME_LINE_HEIGHT (f));

	      XSETFRAME (frame, f);
	      Fmodify_frame_parameters (frame,
					list1 (Fcons (Qtool_bar_lines,
						      make_number (new_lines))));
	      /* Always do that now.  */
	      clear_glyph_matrix (w->desired_matrix);
	      f->n_tool_bar_rows = nrows;
	      f->fonts_changed = 1;
	      return 1;
	    }

Why does it make sense to "always do that"?  Suppose new_lines is
exactly equal to the current number of canonical lines used by the
tool-bar window (it can happen even if pixel sizes are different, due
to integer truncation).  Or suppose you are asking for N lines, but
don't get it because the frame is too small.  Why set the
fonts_changed flag in those cases?  That flag causes redisplay to give
up, abandon the current glyph matrices, and retry anew.  What happens
with those endless cycles is precisely that: redisplay_tool_bar sets
the fonts_changed flag, which causes redisplay_internal to retry,
which again calls redisplay_tool_bar, which again sets the flag,
etc., ad nauseam.

If there is some reasoning behind this "always do that" logic, please
describe it.  Otherwise, I propose the patch below, which cures the
problem altogether for me; if you agree, I will install it.

As an aside, I stared for a long time at this part of
w32fns.c:x_set_tool_bar_lines (which is part of the issue, because it
is called by modify-frame-parameters, when the tool-bar-lines
parameter is changed), and I still don't get why it does what it does:

      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));
	}

First, delta is recomputed, but the result is never used.  More
importantly, you assign to nlines a value that is the size of the root
window _plus_ one line?  Did you mean minus instead?

Finally, the corresponding xfns.c implementation still works in lines,
not in pixels, as w32fns.c did before your pixelwise changes.  Is this
disparity on purpose or an oversight?

Here's the patch I propose to solve the last part of this bug.  It
abandons the "do it always" method, and only changes the
tool-bar-lines parameter and sets the fonts_changed flag if the
required height of the tool bar differs from the current height by at
least 1 canonical line, and if it is smaller than the maximum number
of lines any window can get on this frame.

--- src/xdisp.c~1	2013-12-23 18:20:09.678832900 +0200
+++ src/xdisp.c	2013-12-23 18:50:56.993834000 +0200
@@ -12289,18 +12289,24 @@ redisplay_tool_bar (struct frame *f)
 
 	  if (change_height_p)
 	    {
+	      int old_lines = WINDOW_TOTAL_LINES (w);
 	      int new_lines = ((new_height + FRAME_LINE_HEIGHT (f) - 1)
 			       / FRAME_LINE_HEIGHT (f));
+	      int max_lines =
+		WINDOW_TOTAL_LINES (XWINDOW (FRAME_ROOT_WINDOW (f))) - 1;
 
-	      XSETFRAME (frame, f);
-	      Fmodify_frame_parameters (frame,
-					list1 (Fcons (Qtool_bar_lines,
-						      make_number (new_lines))));
-	      /* Always do that now.  */
-	      clear_glyph_matrix (w->desired_matrix);
-	      f->n_tool_bar_rows = nrows;
-	      f->fonts_changed = 1;
-	      return 1;
+	      if (new_lines <= max_lines
+		  && eabs (new_lines - old_lines) >= 1)
+		{
+		  XSETFRAME (frame, f);
+		  Fmodify_frame_parameters (frame,
+					    list1 (Fcons (Qtool_bar_lines,
+							  make_number (new_lines))));
+		  clear_glyph_matrix (w->desired_matrix);
+		  f->n_tool_bar_rows = nrows;
+		  f->fonts_changed = 1;
+		  return 1;
+		}
 	    }
 	}
     }





  parent reply	other threads:[~2013-12-23 16:57 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-04 14:40 bug#16051: 24.3.50; Emacs hang - resize frame manually Drew Adams
2013-12-04 17:56 ` Eli Zaretskii
2013-12-05 14:03   ` martin rudalics
2013-12-05 17:52     ` Eli Zaretskii
2013-12-05 17:59       ` martin rudalics
2013-12-05 18:21         ` Eli Zaretskii
2013-12-05 18:27           ` martin rudalics
2013-12-05 18:30           ` Eli Zaretskii
2013-12-06 14:32             ` martin rudalics
2013-12-06 15:31               ` Eli Zaretskii
2013-12-06 16:21                 ` martin rudalics
2013-12-06 18:16                   ` Eli Zaretskii
2013-12-06 18:57                     ` martin rudalics
2013-12-06 19:07                       ` Eli Zaretskii
2013-12-07 12:25                         ` martin rudalics
2013-12-07 12:31                           ` martin rudalics
2013-12-07 13:12                           ` Eli Zaretskii
2013-12-07 14:23                             ` martin rudalics
2013-12-07 15:18                               ` Eli Zaretskii
2013-12-07 15:47                                 ` martin rudalics
2013-12-07 16:28                                   ` Eli Zaretskii
2013-12-07 17:00                                   ` Dani Moncayo
2013-12-07 17:36                                     ` martin rudalics
     [not found]                                 ` <<52A342F7.1070707@gmx.at>
     [not found]                                   ` <<83siu4zkuh.fsf@gnu.org>
2013-12-07 20:37                                     ` Drew Adams
2014-12-25 10:55   ` martin rudalics
2013-12-21 13:44 ` Jarek Czekalski
2013-12-21 15:12   ` Eli Zaretskii
2013-12-21 15:16     ` Eli Zaretskii
2013-12-21 15:46     ` Jarek Czekalski
2013-12-21 16:19       ` Eli Zaretskii
2013-12-21 17:13         ` martin rudalics
2013-12-21 18:48           ` Eli Zaretskii
2013-12-21 19:40             ` martin rudalics
2013-12-23 16:57           ` Eli Zaretskii [this message]
2013-12-23 18:44             ` martin rudalics
2013-12-23 19:31               ` Eli Zaretskii
2013-12-23 20:02                 ` martin rudalics
2013-12-23 20:18                   ` Eli Zaretskii
2013-12-24 10:14                     ` martin rudalics
2013-12-24 17:34                       ` Eli Zaretskii
2013-12-24 18:45                         ` martin rudalics
2013-12-24 18:55                           ` Eli Zaretskii
2013-12-26 11:51                             ` martin rudalics
2013-12-26 17:30                               ` Eli Zaretskii
2013-12-26 18:04                                 ` martin rudalics
2013-12-26 18:47                                   ` Eli Zaretskii
2013-12-26 19:56                                     ` martin rudalics
     [not found] <<3eea48d4-9267-45fa-84c8-3eb9c9290558@default>
     [not found] ` <<83siu833gc.fsf@gnu.org>
2013-12-04 18:45   ` Drew Adams

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=83zjnr7bea.fsf@gnu.org \
    --to=eliz@gnu.org \
    --cc=16051@debbugs.gnu.org \
    --cc=jarekczek@poczta.onet.pl \
    --cc=rudalics@gmx.at \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.