I wanted to start an application which uses the terminal directly from YaST. The pseudo code for the texmode case looks like this:
# close the UI so the terminal can be used by another application
UI.CloseUI
# this starts an interactive Ruby shell (it reads/writes to the terminal)
require "irb"
IRB.start
# restore the UI back
UI.OpenUI
Unfortunately that does not work properly, the ncurses UI is still running in parallel to the IRB session and the terminal is garbled. Moreover the keypresses are randomly read by the UI or IRB resulting in unexpected and uncontrollable behavior. See the screencast below.
The Fix
The code snippet above is basically the same what the runInTerminal() ncurses call does, basically it is:
closeUI();
ret = system( cmd.c_str() );
openUI();
return ret;
And that call works properly, there is no collision and the screen is correctly refreshed after the command is finished. The difference is that the system() call is synchronous, the UI is blocked until it returns. So no collision is possible.
We need to behave similarly also when the closeUI()/openUI() calls are called externally (which do not block the UI processing in between). So this fix skips calling the idleInput() method of the toplevel dialog after the closeUI() call. It is enabled back after the openUI() call.
Testing
I tested the fix with a DUD applied to the latest Tumbleweed image.
Original (Broken) State
Without the fix the UI thread is still reading from the terminal and collides with the started application, as you can see some input is read by IRB, some by ncurses UI (like the numbers which are displayed in blue). After closing the application the UI is left broken.
With the Fix
With the fix there is no collision, the application works as expected, also after closing the application the UI is displayed properly.
The Problem
I wanted to start an application which uses the terminal directly from YaST. The pseudo code for the texmode case looks like this:
Unfortunately that does not work properly, the ncurses UI is still running in parallel to the IRB session and the terminal is garbled. Moreover the keypresses are randomly read by the UI or IRB resulting in unexpected and uncontrollable behavior. See the screencast below.
The Fix
The code snippet above is basically the same what the runInTerminal() ncurses call does, basically it is:
And that call works properly, there is no collision and the screen is correctly refreshed after the command is finished. The difference is that the
system()
call is synchronous, the UI is blocked until it returns. So no collision is possible.We need to behave similarly also when the
closeUI()
/openUI()
calls are called externally (which do not block the UI processing in between). So this fix skips calling theidleInput()
method of the toplevel dialog after thecloseUI()
call. It is enabled back after theopenUI()
call.Testing
I tested the fix with a DUD applied to the latest Tumbleweed image.
Original (Broken) State
Without the fix the UI thread is still reading from the terminal and collides with the started application, as you can see some input is read by IRB, some by ncurses UI (like the numbers which are displayed in blue). After closing the application the UI is left broken.
With the Fix
With the fix there is no collision, the application works as expected, also after closing the application the UI is displayed properly.