emacs-pretest-bug
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Multiple runs of menu-bar-update-hook


From: Marshall, Simon
Subject: RE: Multiple runs of menu-bar-update-hook
Date: Mon, 7 Aug 2006 17:39:26 +0100

>     > This patch should get rid of that.  Does it?
> 
>     Yes, it does seem to, there are multiple runs but they only occur in
one
>     frame.
> 
> Would someone please debug the inside of update_menu_bar as I suggested?

OK, I made a start.

src/emacs -Q
C-x 5 2

I put breakpoints on the 2 places where Qmenu_bar_update_hook is run, then
continued.  In one of the frames, I did a mouse-1.  Recall that this will
run menu-bar-update-hook twice.  Emacs stopped like this:

(dbx) where
=>[1] update_menu_bar(f = 0x964400, save_match_data = 0, hooks_run = 0),
line 9195 in "xdisp.c"
  [2] prepare_menu_bars(), line 9073 in "xdisp.c"
  [3] redisplay_internal(preserve_echo_area = 0), line 10902 in "xdisp.c"
  [4] redisplay(), line 10491 in "xdisp.c"
  [5] read_char(commandflag = 0, nmaps = 0, maps = (nil), prev_event =
541825072, used_mouse_menu = (nil), end_time = (nil)), line 2555 in
"keyboard.c"
  [6] read_filtered_event(no_switch_frame = 0, ascii_required = 0,
error_nonascii = 0, input_method = 0, seconds = 541825024), line 496 in
"lread.c"
  [7] Fread_event(prompt = 541825024, inherit_input_method = 541825024,
seconds = 541825024), line 600 in "lread.c"
  [8] Ffuncall(nargs = 1, args = 0xffbed028), line 2989 in "eval.c"
  [9] Fbyte_code(bytestr = 1614550844, vector = -2143545516, maxdepth = 6),
line 679 in "bytecode.c"
  [10] Feval(form = -1606674644), line 2320 in "eval.c"
  [11] Fprogn(args = -1606674652), line 435 in "eval.c"
  [12] Ftrack_mouse(args = -1606674652), line 3498 in "keyboard.c"
  [13] Feval(form = -1606674660), line 2260 in "eval.c"
  [14] Fprogn(args = -1606674668), line 435 in "eval.c"
  [15] funcall_lambda(fun = -1606674684, nargs = 0, arg_vector =
0xffbed69c), line 3162 in "eval.c"
  [16] Ffuncall(nargs = 1, args = 0xffbed698), line 3039 in "eval.c"
  [17] Fbyte_code(bytestr = 1614550400, vector = -2143545968, maxdepth = 6),
line 679 in "bytecode.c"
  [18] funcall_lambda(fun = -2143546036, nargs = 2, arg_vector =
0xffbed98c), line 3171 in "eval.c"
  [19] Ffuncall(nargs = 3, args = 0xffbed988), line 3028 in "eval.c"
  [20] Fbyte_code(bytestr = 1614549296, vector = -2143547072, maxdepth = 5),
line 679 in "bytecode.c"
  [21] funcall_lambda(fun = -2143547128, nargs = 1, arg_vector =
0xffbedc9c), line 3171 in "eval.c"
  [22] Ffuncall(nargs = 2, args = 0xffbedc98), line 3028 in "eval.c"
  [23] Fcall_interactively(function = 544224072, record_flag = 541825024,
keys = -2142470144), line 880 in "callint.c"
  [24] Fcommand_execute(cmd = 544224072, record_flag = 541825024, keys =
541825024, special = 541825024), line 9786 in "keyboard.c"
  [25] command_loop_1(), line 1790 in "keyboard.c"
  [26] internal_condition_case(bfun = 0x1bba38 = &command_loop_1(), handlers
= 541881992, hfun = 0x1bb068 = &cmd_error(Lisp_Object data)), line 1469 in
"eval.c"
  [27] command_loop_2(), line 1326 in "keyboard.c"
  [28] internal_catch(tag = 541883392, func = 0x1bb650 = &command_loop_2(),
arg = 541825024), line 1210 in "eval.c"
  [29] command_loop(), line 1305 in "keyboard.c"
  [30] recursive_edit_1(), line 1003 in "keyboard.c"
  [31] Frecursive_edit(), line 1064 in "keyboard.c"
  [32] main(argc = 2, argv = 0xffbee444), line 1794 in "emacs.c"
(dbx) print windows_or_buffers_changed
windows_or_buffers_changed = 1
(dbx) print update_mode_lines
update_mode_lines = 0
(dbx) cont
(dbx) where
=>[1] update_menu_bar(f = 0x964400, save_match_data = 0, hooks_run = 0),
line 9195 in "xdisp.c"
  [2] prepare_menu_bars(), line 9073 in "xdisp.c"
  [3] redisplay_internal(preserve_echo_area = 0), line 10902 in "xdisp.c"
  [4] redisplay(), line 10491 in "xdisp.c"
  [5] read_char(commandflag = 1, nmaps = 2, maps = 0xffbedd50, prev_event =
541825024, used_mouse_menu = 0xffbeddcc, end_time = (nil)), line 2555 in
"keyboard.c"
  [6] read_key_sequence(keybuf = 0xffbedf38, bufsize = 30, prompt =
541825024, dont_downcase_last = 0, can_return_switch_frame = 1,
fix_current_buffer = 1), line 8893 in "keyboard.c"
  [7] command_loop_1(), line 1536 in "keyboard.c"
  [8] internal_condition_case(bfun = 0x1bba38 = &command_loop_1(), handlers
= 541881992, hfun = 0x1bb068 = &cmd_error(Lisp_Object data)), line 1469 in
"eval.c"
  [9] command_loop_2(), line 1326 in "keyboard.c"
  [10] internal_catch(tag = 541883392, func = 0x1bb650 = &command_loop_2(),
arg = 541825024), line 1210 in "eval.c"
  [11] command_loop(), line 1305 in "keyboard.c"
  [12] recursive_edit_1(), line 1003 in "keyboard.c"
  [13] Frecursive_edit(), line 1064 in "keyboard.c"
  [14] main(argc = 2, argv = 0xffbee444), line 1794 in "emacs.c"
(dbx) print windows_or_buffers_changed
windows_or_buffers_changed = 1
(dbx) print update_mode_lines
update_mode_lines = 1

Note that in both cases, windows_or_buffers_changed==1.  I put a watchpoint
on this.

(dbx) print &windows_or_buffers_changed
&windows_or_buffers_changed = 0x4a1e84
(dbx) stop access wb 0x4a1e85, sizeof(int)

When I mouse-1 in a *scratch* frame, I get:

(dbx) where
=>[1] modify_overlay(buf = 0x4c2c00, start = 35, end = 35), line 3654 in
"buffer.c"
  [2] Fmove_overlay(overlay = 1079994044, beg = 35, end = 35, buffer =
-2142491648), line 3744 in "buffer.c"
  [3] Ffuncall(nargs = 4, args = 0xffbed3b0), line 2993 in "eval.c"
  [4] Fbyte_code(bytestr = 1614549960, vector = -2143546408, maxdepth = 4),
line 679 in "bytecode.c"
  [5] funcall_lambda(fun = -2143546480, nargs = 4, arg_vector = 0xffbed69c),
line 3171 in "eval.c"
  [6] Ffuncall(nargs = 5, args = 0xffbed698), line 3028 in "eval.c"
  [7] Fbyte_code(bytestr = 1614550400, vector = -2143545968, maxdepth = 6),
line 679 in "bytecode.c"
  [8] funcall_lambda(fun = -2143546036, nargs = 2, arg_vector = 0xffbed98c),
line 3171 in "eval.c"
  [9] Ffuncall(nargs = 3, args = 0xffbed988), line 3028 in "eval.c"
  [10] Fbyte_code(bytestr = 1614549296, vector = -2143547072, maxdepth = 5),
line 679 in "bytecode.c"
  [11] funcall_lambda(fun = -2143547128, nargs = 1, arg_vector =
0xffbedc9c), line 3171 in "eval.c"
  [12] Ffuncall(nargs = 2, args = 0xffbedc98), line 3028 in "eval.c"
  [13] Fcall_interactively(function = 544224072, record_flag = 541825024,
keys = -2142470144), line 880 in "callint.c"
  [14] Fcommand_execute(cmd = 544224072, record_flag = 541825024, keys =
541825024, special = 541825024), line 9786 in "keyboard.c"
  [15] command_loop_1(), line 1790 in "keyboard.c"
  [16] internal_condition_case(bfun = 0x1bba38 = &command_loop_1(), handlers
= 541881992, hfun = 0x1bb068 = &cmd_error(Lisp_Object data)), line 1469 in
"eval.c"
  [17] command_loop_2(), line 1326 in "keyboard.c"
  [18] internal_catch(tag = 541883392, func = 0x1bb650 = &command_loop_2(),
arg = 541825024), line 1210 in "eval.c"
  [19] command_loop(), line 1305 in "keyboard.c"
  [20] recursive_edit_1(), line 1003 in "keyboard.c"
  [21] Frecursive_edit(), line 1064 in "keyboard.c"
  [22] main(argc = 2, argv = 0xffbee444), line 1794 in "emacs.c"
(dbx) 

which is at this point:

static void
modify_overlay (buf, start, end)
     struct buffer *buf;
     EMACS_INT start, end;
{
  if (start > end)
    {
      int temp = start;
      start = end;
      end = temp;
    }

  BUF_COMPUTE_UNCHANGED (buf, start, end);

  /* If this is a buffer not in the selected window,
     we must do other windows.  */
  if (buf != XBUFFER (XWINDOW (selected_window)->buffer))
    windows_or_buffers_changed = 1;
  /* If multiple windows show this buffer, we must do other windows.  */
  else if (buffer_shared > 1)
==>    windows_or_buffers_changed = 1;
  /* If we modify an overlay at the end of the buffer, we cannot
     be sure that window end is still valid.  */
  else if (end >= ZV && start <= ZV)
    windows_or_buffers_changed = 1;

  ++BUF_OVERLAY_MODIFF (buf);
}

Naturally, buffer_shared == 2.  I also checked to see why update_mode_lines
= 1 in the second instance that Qmenu_bar_update_hook is run:

(dbx) print &update_mode_lines
&update_mode_lines = 0x4a10b8
(dbx) stop access wa 0x4a10b8, sizeof(int) -if update_mode_lines!=0
(dbx) cont
(dbx) cont
(dbx) where
=>[1] redisplay_internal(preserve_echo_area = 0), line 10905 in "xdisp.c"
  [2] redisplay(), line 10491 in "xdisp.c"
  [3] read_char(commandflag = 0, nmaps = 0, maps = (nil), prev_event =
541825072, used_mouse_menu = (nil), end_time = (nil)), line 2555 in
"keyboard.c"
  [4] read_filtered_event(no_switch_frame = 0, ascii_required = 0,
error_nonascii = 0, input_method = 0, seconds = 541825024), line 496 in
"lread.c"
  [5] Fread_event(prompt = 541825024, inherit_input_method = 541825024,
seconds = 541825024), line 600 in "lread.c"
  [6] Ffuncall(nargs = 1, args = 0xffbed028), line 2989 in "eval.c"
  [7] Fbyte_code(bytestr = 1614550844, vector = -2143545516, maxdepth = 6),
line 679 in "bytecode.c"
  [8] Feval(form = -1606674644), line 2320 in "eval.c"
  [9] Fprogn(args = -1606674652), line 435 in "eval.c"
  [10] Ftrack_mouse(args = -1606674652), line 3498 in "keyboard.c"
  [11] Feval(form = -1606674660), line 2260 in "eval.c"
  [12] Fprogn(args = -1606674668), line 435 in "eval.c"
  [13] funcall_lambda(fun = -1606674684, nargs = 0, arg_vector =
0xffbed69c), line 3162 in "eval.c"
  [14] Ffuncall(nargs = 1, args = 0xffbed698), line 3039 in "eval.c"
  [15] Fbyte_code(bytestr = 1614550400, vector = -2143545968, maxdepth = 6),
line 679 in "bytecode.c"
  [16] funcall_lambda(fun = -2143546036, nargs = 2, arg_vector =
0xffbed98c), line 3171 in "eval.c"
  [17] Ffuncall(nargs = 3, args = 0xffbed988), line 3028 in "eval.c"
  [18] Fbyte_code(bytestr = 1614549296, vector = -2143547072, maxdepth = 5),
line 679 in "bytecode.c"
  [19] funcall_lambda(fun = -2143547128, nargs = 1, arg_vector =
0xffbedc9c), line 3171 in "eval.c"
  [20] Ffuncall(nargs = 2, args = 0xffbedc98), line 3028 in "eval.c"
  [21] Fcall_interactively(function = 544224072, record_flag = 541825024,
keys = -2142470144), line 880 in "callint.c"
  [22] Fcommand_execute(cmd = 544224072, record_flag = 541825024, keys =
541825024, special = 541825024), line 9786 in "keyboard.c"
  [23] command_loop_1(), line 1790 in "keyboard.c"
  [24] internal_condition_case(bfun = 0x1bba38 = &command_loop_1(), handlers
= 541881992, hfun = 0x1bb068 = &cmd_error(Lisp_Object data)), line 1469 in
"eval.c"
  [25] command_loop_2(), line 1326 in "keyboard.c"
  [26] internal_catch(tag = 541883392, func = 0x1bb650 = &command_loop_2(),
arg = 541825024), line 1210 in "eval.c"
  [27] command_loop(), line 1305 in "keyboard.c"
  [28] recursive_edit_1(), line 1003 in "keyboard.c"
  [29] Frecursive_edit(), line 1064 in "keyboard.c"
  [30] main(argc = 2, argv = 0xffbee444), line 1794 in "emacs.c"
(dbx) 

which is at this bit of code:

  if (windows_or_buffers_changed)
    update_mode_lines++;

ie, update_mode_lines is only set because windows_or_buffers_change has
already been set.

Is this the kind of debugging you wanted - does it help?  I recall you
saying in an earlier email that there were optimisations what would fail if
a buffer was displayed in more than one window.  I guess this is what is
happening here?

Earlier I made the point that Qmenu_bar_update_hook is already run when I
mouse-1 on the menu bar.  I suggested that it seemed reasonable to run it at
that time and other specific times only (such as when switching buffers or
windows), rather than during redisplay.  No-one came out and said it was mad
or stupid, so would dealing with the menu bar that way be better than
dealing with it during redisplay and fixing the existing code?

How can I help?  Simon.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]