In some cases, MOC prints "TERMINAL TOO SMALL" when it's not

Steps to reproduce (checked against last stable in an Lubuntu 16.04 LTS live, and against last SVN in a Arch+i3 bleeding edge install):
1- Open MOC in a terminal window (of a reasonable size, e.g. 80x25).
2- Resize the window to a small size, e.g. 50x20.

Expected result: MOC prints "TERMINAL TOO SMALL"
Observed result: MOC continues working normally (with some visual glitches)

3- Resize the window again to a reasonable size

Expected result: MOC works normally
Observed result: MOC prints "TERMINAL TOO SMALL"

4- If a small window size is done now, the window will start working normally again

In short, after doing a resize operation, MOC checks if the terminal is too small against the old window size, not against the new window size.

NOTE: I suppose that some terminal emulators send multiple resize events during a single resize operation, which could mask the problem. The window resize needs to cause a single resize event (SIGWINCH).

Cause and proposed fix:

In the iface_resize function, check_term_size is called before endwin/refresh:

/* Handle screen resizing. */ void iface_resize () { check_term_size (&main_win, &info_win); validate_layouts (); endwin (); refresh (); main_win_resize (&main_win); info_win_resize (&info_win); iface_refresh_screen (); }

It appears that the variables COLS/LINES, which are checked inside check_term_size, are not updated until the endwin/refresh calls, so check_term_size checks against the old window size values, as observed.

So it appears that check_term_size (and also validate_layouts?) should be moved after the refresh call.

Additional resources:
Here's a minimal test case:

#include <ncurses.h> #include <signal.h> void on_sigwinch(int signum) { int old_lines = LINES, old_cols = COLS; endwin(); refresh(); clear(); printw("Got SIGWINCH\n"); printw("Old values LINES=%d COLS=%d\n", old_lines, old_cols); printw("Current values LINES=%d COLS=%d\n", LINES, COLS); refresh(); } int main() { signal(SIGWINCH, on_sigwinch); initscr(); printw("Resize the window...\n"); refresh(); getch(); endwin(); return 0; }

Sample video:


The "small screen" issue has been raised several times, but I need to run MOC on a GUI (which I don't have set up) to investigate what MOC on a small sized screen would look like. My initial feelings were that it wouldn't be useful and the limits originally set in the program were set to those values for a reason.

However, your analysis puts a different interpretation on it as a comparison against stale values. I'm therefore not sure if what was previously raised as a issue is actually the same as the bug which you are reporting (and will have to re-examine them in the light of this).

Unfortunately, the libraries here are now closed until the New Year, so it will be a couple of weeks before I can get to look at your video clip, but I do appreciate your having taken the time to capture it and to triage the problem.

But to come back to the issue others have raised (if it is still valid), I'm thinking (now that you've brought my focus back to it) that maybe once the screen size gets below a certain minimum size the MOC display changes to something more like a "status bar" and if that is in turn resized back above the minimum it returns to the full display. What information that status bar contains I'm not sure and may need to be configurable. Any thoughts on that?

I did a quick search before writing this post to find if this was already a known problem or caused by some bad configuration, and already found the other posts about making MOC work on small terminals. I believe this is an unrelated problem, which is that after the "TERMINAL TOO SMALL" message appears as expected, it takes multiple resize operations to get it to disappear because MOC uses the old window size during the first resize operation.

BTW, I was able to reproduce the problem in GNU screen and a tty, in case you're able to work with that; basically, create enough (and no more) vertical splits so that after opening MOC, it prints "TERMINAL TOO SMALL" as expected; now, with MOC still open, close one of the other vertical splits, so MOC should be able to display correctly. Instead, it stays at "TERMINAL TOO SMALL". And if you close and reopen MOC, it'll then work correctly.

I have the same bug here on the terminal iterm2 on MAC OS X.
It would be great to have such a "status bar" in terms of a small terminal.

Maybe it should depend on the lines to be displayed (or complete configurable with fields to be displayed in each "row")
4th row: Path and name of the playlist
3rd row: Volume and mixer
2nd row: time, song information, quality STEREO, ...
1st row: Title of the song

If you have more than 4 lines, you could display all 4 lines
if you have 3 lines, only 1-3 are shown
Basic status bar only with one line and the song title (and time)

I'm awaiting a response to my e-mail to "zealcharm" before committing the patch, but it is the holiday season after all. In the meantime, you could apply the patch given below if you need a solution.

Another idea I had to minimise a "status bar" even further was to have a single line (perhaps surrounded by a frame) in which the different status items are displayed in rotation.

As a heads up, I've been running a few days with the suggested change (see patch below) and it has fixed the problem, without any apparent negative effect.

Index: interface_elements.c =================================================================== --- interface_elements.c 2016-11-16 01:54:37.000000000 +0100 +++ interface_elements.c 2018-12-22 18:30:40.272022980 +0100 @@ -4151,10 +4151,10 @@ /* Handle screen resizing. */ void iface_resize () { - check_term_size (&main_win, &info_win); - validate_layouts (); endwin (); refresh (); + check_term_size (&main_win, &info_win); + validate_layouts (); main_win_resize (&main_win); info_win_resize (&info_win); iface_refresh_screen ();

This patch has been committed as r2993 (MOC 2.5) and r2994.


I just replied to your email, which got caught in GMail's spam filter. it's OK for me to include the (obviously trivial) patch in MOC - and for legalese, under its GPL license and credited as "Joan Bruguera Micó -".