Missed window resize event if a resize happens during initialization (race condition)


MOC version: 

After some time noticing an sporadic glitch where MOC had a wrongly sized layout upon initialization, I decided to dive upon it.

My real reproduction scenario is that I often launch MOC using 'xfce4-terminal -e mocp --fullscreen', and maybe 1/30 times, this results in MOC not filling the screen, so the result can look something like this: https://i.imgur.com/QmZTWkF.png. For me this happens more often under load (e.g. compiling code).

After some investigation I have found that the cause of the problem is the following:

* It seems that this way of launching the application with xfce4-terminal this way causes both (1) the launch of MOC and (2) the resize to fullscreen to be executed in parallel, so the resize event can happen at any point during MOC's initialization process.

* There is a window during MOC's initialization where the ncurses user interface has already been initialized, but window resize events are not captured. This is in interface.c: after the call to windows_init (); but before the call to xsignal (SIGWINCH, sig_winch);, the user interface is initialized but resize events are not handled.

* So, if it just happens that the resize to fullscreen happens during this particular window, this is where the glitched layout happens.

It is quite easy to reproduce the problem consistently by placing a sleep() just before the call to xsignal (SIGWINCH, sig_winch); and then resizing the window while MOC is sleeping (when doing this, make sure that you make a "sudden" resize of the window like a maximize or fullscreen, since the first resize event interrupts the sleep call).

I tried fixing the problem by moving the call to xsignal (SIGWINCH, sig_winch); before the call to windows_init ();, and this solves the problem... 99% of the way. With this the interface can still launch randomly in the glitched layout, but it fixes itself after 1 second. The reason is that in this case the resize event is captured, but we must still wait 1 second for the call to pselect in interface_loop to timeout for the event to be handled (normally, a resize event is handled instantly because pselect fails with errno=EINTR when a resize happens and a SIGWINCH, but not in this case where the SIGWINCH happens outside a pselect call).

So, summarizing, this is quite a low priority problem that has an easy solution that converts it to a negligible priority problem. It'd be nice to see some more perfect resize handling logic, but it seems that this would need too much work for little gain. On the other hand I don't see moving xsignal (SIGWINCH, sig_winch); before the windows_init (); causing problems.

I replied to your post earlier today by e-mail, but previously my replies got caught in G-Mail's spam filer, so you may wish to check your spam folder if you have not received it.