On Fri, Jan 12, 2024 at 03:07:04 +0000, Michael Gold wrote: > I sometimes notice this if I navigate into a large directory, and resize > the window while the "spinner" is animating at the top-right corner. It > can be difficult to reproduce once Linux has the data cached.
It looks like the spinner--rotate_dash()--is actually the culprit. That
calls mc_refresh(), which empties sigwinch_pipe before do_nc() makes its
first dlg_run() call:
(gdb) bt
#0 tty_flush_winch () at ./lib/tty/tty.c:224
#1 0x00005555556567fb in dialog_change_screen_size () at
./lib/widget/dialog-switch.c:426
#2 0x0000555555656781 in mc_refresh () at
./lib/widget/dialog-switch.c:411
#3 0x000055555558f98e in rotate_dash (show=1) at
./src/filemanager/layout.c:1087
#4 0x000055555559995c in panel_dir_list_callback (state=DIR_READ,
data=0x555555704ac0) at ./src/filemanager/panel.c:4359
#5 0x00005555555fdff7 in dir_list_load (list=0x555555801688,
vpath=0x5555557f5020, sort=0x5555555fccec <sort_name>, sort_op=0x555555801760,
filter=0x5555558017c0) at ./src/filemanager/dir.c:670
#6 0x000055555559a1b7 in panel_sized_with_dir_new
(panel_name=0x5555556784aa "New Right Panel", y=0, x=0, lines=0, cols=0,
vpath=0x0) at ./src/filemanager/panel.c:4612
#7 0x000055555558d975 in panel_sized_new (panel_name=0x5555556784aa
"New Right Panel", y=0, x=0, lines=0, cols=0) at
../../src/filemanager/panel.h:272
#8 0x000055555558ed29 in restore_into_right_dir_panel (idx=1,
last_was_panel=0, y=0, x=0, lines=0, cols=0) at ./src/filemanager/layout.c:668
#9 0x000055555558fca3 in create_panel (num=1, type=view_listing) at
./src/filemanager/layout.c:1189
#10 0x000055555558279a in create_panels () at
./src/filemanager/filemanager.c:658
#11 0x0000555555582ee3 in create_file_manager () at
./src/filemanager/filemanager.c:911
#12 0x0000555555584bed in do_nc () at
./src/filemanager/filemanager.c:1840
#13 0x0000555555570a92 in main (argc=1, argv=0x7fffffffe248) at
./src/main.c:458
(gdb)
It's dlg_run() that will put the file browser into the top_dlg list; but
top_dlg is still empty in the above backtrace, so no MSG_RESIZE messages
are sent. If SIGWINCH comes at the "expected" time, I see this:
(gdb) bt
#0 send_message (w=0x5555557f5a80, sender=0x0, msg=MSG_RESIZE, parm=0,
data=0x0) at ../../lib/widget/widget-common.h:250
#1 0x0000555555655e79 in dialog_switch_resize (d=0x5555557f5a80) at
./lib/widget/dialog-switch.c:136
#2 0x00005555556568cc in dialog_change_screen_size () at
./lib/widget/dialog-switch.c:447
#3 0x0000555555657020 in frontend_dlg_run (h=0x5555557f5a80) at
./lib/widget/dialog.c:293
#4 0x0000555555657ac2 in dlg_run (h=0x5555557f5a80) at
./lib/widget/dialog.c:574
#5 0x0000555555584bff in do_nc () at
./src/filemanager/filemanager.c:1841
#6 0x0000555555570a92 in main (argc=1, argv=0x7fffffffe248) at
./src/main.c:458
(gdb)
Simply sticking a "return" at the top of rotate_dash() makes the problem
unreproducible, and gives me a PASS from the test case. Something like
a global 'is_ready' flag might be a better way to do it; or just ensure
dialog_change_screen_size() doesn't flush the pipe if the dialog list is
empty.
While debugging this, I noticed a related bug in toggle_subshell(),
which has this code:
was_sigwinch = tty_got_winch ();
tty_flush_winch ();
If a SIGWINCH were handled after setting was_sigwinch to 0 but before
flushing the pipe, the SIGWINCH would be missed. I never saw it happen,
but it could be easily fixed by replacing that code with:
was_sigwinch = tty_flush_winch ();
and making that function return the appropriate boolean value.
-- Michael
signature.asc
Description: PGP signature

