Subject: bug#18136: 24.4.50; crash in redisplay when calling load-theme

From: martin rudalics <[email-masked]>
Date: Fri, 01 Aug 2014 10:57:06 +0200

> That will not work well (you can try and see yourself).  But the
 > opposite, i.e. having a 80-line frame on a 100-line terminal, is quite
 > usable.  In fact, some people seem to use that to have minibuffer-only
 > frames on a TTY.

Weird.  Such setting gets lost immediately when the terminal window is
resized.

 >    /* Add in menu bar lines, if any.  */
 >    matrix_dim.height += top_window_y;

Doesn't this add an extra glyph row?

 >> Can I call adjust_frame_size directly from init_display?
 >
 > If all the rest is a no-op, yes, why not?

You mean it must not call Lisp?

 >> IIUC FrameRows is the height of the terminal window and when I change
 >> the height of that window I want to change the height of the Emacs frame
 >> as well via handle_window_change_signal/change_frame_size.  This means I
 >> can set FrameCols where I do it now because whenever I change the size
 >> of the outer frame that of the frame's windows changes too.
 >
 > Sorry, you lost me here.  First, you use "window" in several
 > overloaded meanings, or so it seems.  And second, why are we suddenly
 > talking about SIGWINCH and its handling?  This is not the scenario in
 > which this bug happens.

Because adjust_frame_size has to handle SIGWINCH as well.

 >> Still it seems to me contrived to set FrameCols/FrameRows when adjusting
 >> the sizes of a frame's windows.
 >
 > How else will FrameCols/FrameRows be updated if the user calls
 > set-frame-size and its ilk?

I thought that FrameCols/FrameRows store the sizes of the terminal
window.  IIUC this means that `set-frame-size' makes us lie about the
terminal sizes.

 >> And setting FrameCols when called from init_display is certainly not
 >> TRT IMHO.
 >
 > If you are sure they are already set by then, OK.  Evidently, in this
 > case, the call to change_frame_size tried to decrease the frame size
 > by one line, so something is still out of sync somewhere.

Obviously.

 >>   > In any case, this begs the question: why do you at all call
 >>   > adjust_frame_size in this case, if the frame already has the required
 >>   > size?  I think the answer is that adjust_frame_size does something
 >>   > else: it calls adjust_frame_glyphs.  That call is required at
 >>   > init_display time for obvious reasons, but it is inside
 >>   > adjust_frame_size which is only called when the frame size changes,
 >>   > which sounds like a contradiction in the design.
 >>
 >> Think of turning off/on the menubar of a maximized frame.  In this case
 >> I do not change the size of the frame either.  Yet I have to call
 >> adjust_frame_glyphs.
 >
 > Is that supposed to be the answer to my question, or just say what I
 > said in other words?

A complement to what you said.

 > I can reproduce it with the current trunk on GNU/Linux where I invoke
 > "emacs -Q -nw" via PuTTY.  The resize is _after_ I invoke frame-height
 > the second time, which is already the sign of a problem.

Unfortunately, restoring the init_display change as you proposed earlier
by simply doing

=== modified file 'src/dispnew.c'
--- src/dispnew.c	2014-07-28 09:39:09 +0000
+++ src/dispnew.c	2014-08-01 08:23:58 +0000
@@ -6069,8 +6069,7 @@
      t->display_info.tty->top_frame = selected_frame;
      change_frame_size (XFRAME (selected_frame),
                         FrameCols (t->display_info.tty),
-                       FrameRows (t->display_info.tty)
-		       - FRAME_MENU_BAR_LINES (f), 0, 0, 1, 0);
+                       FrameRows (t->display_info.tty), 0, 0, 1, 0);

      /* Delete the initial terminal. */
      if (--initial_terminal->reference_count == 0

doesn't remove the cmcheckmagic abort here.  IUUC the problem is with
the deliberate mixture of frame and terminal sizes when using cursor
coordinates within term.c, like

           && curY (tty) == FrameRows (tty) - 1

and

       && curY (tty) + 1 == FRAME_LINES (f)

So far this can have worked only by some strange magic assuring that
FRAME_LINES always returns the same value as FrameRows.

 >> Wouldn't it be principally cleaner if we set FrameCols and FrameRows
 >> after calling get_tty_size only?
 >
 > You can't.  get_tty_size reports the _physical_ dimensions of the
 > terminal screen, so it cannot support set-frame-size and its ilk,
 > which leave the physical dimensions unaltered.

Does that mean `set-frame-size' should not set FrameCols/FrameRows?

I'm still too silly to understand this: Please tell me whether FrameRows
stands for the height of the terminal window as reported by get_tty_size
or for the height of the frame as set by `set-frame-size'?

martin