That looks like it might just do the trick.
Ok, I read your dad's post.
When a script is run from a screen control or G code via mcGcodeExecute/Wait(), it will lock the GUI for the duration of the script. Why? Because the button click event is the action that causes the script to run. And it needs to complete. The application event loop only processes one event at a time. Screen updates are also events.
Say you are the application event loop and I am the user of the machine control. I'm not telling you to do anything at the moment, so you are spending your time running around the screen and updating DROs and such. But all of a sudden, I press a button that basically says "Cbyrdtopper, go do this script task". So you go running off to do the script. So who is updating the DROs now? Nobody.
So what mechanism(s) can we use to make this better?
1) Use the PLC script. Most buttons scripts should be short and sweet without loops or calls to code that has loops in it. If a long running task is needed it is better to just set a variable to initiate the action in the button script. Then a state machine (that watches that variable) can be implemented to process the task in the PLC script.
2) Hand the action off to the interpreter. An example of this is the MDI. You type some G code in and hit cycle start. The cycle start button just starts the interpreter and comes back immediately. So the GUI is functional and screen updates happen. But the state of the machine has changed from idle to MDIrunning. So you can now wait on the state to transistion back to idle. The other use of the interpreter is to let it do the complete action (via Macro B), as you are discovering.
Otherwise, you will need to get into advance LUA programming and use coroutines. That isn't a road that is easily traveled.