UI::WaitForEvent — Waits for user input and returns an event map. Returns ID `timeout if no input is available for timeout milliseconds.
WaitForEvent() is an extended combination of UserInput() and TimeoutUserInput(): It waits until user input is available or until the (millisecond) timeout is expired. It returns an event map rather than just a simple ID.
In the case of timeout, it returns a map with a timeout event.
The timeout argument is optional. If it isn't specified, WaitForEvent() (like UserInput()) keeps waiting until user input is available.
Use WaitForEvent() for more fine-grained control of events. It is useful primarily to tell the difference between different types of events of the same widget - for example, if different actions should be performed upon selecting an item in a SelectionBox or a Table widget. Notice that you still need the notify option to get those events in the first place.
On the downside, using WaitForEvent() means accessing the ID that caused an event requires a map lookup.
Notice that you still need UI::QueryWidget() to get the contents of the widget that caused the event. In the general case you'll need to QueryWidget most widgets on-screen anyway so delivering that one value along with the event wouldn't help too much.
Important: Don't blindly rely on getting each and every individual event that you think should come. The UI keeps track of only one pending event (which is usually the last one that occured). If many events occur between individual WaitForEvent() calls, all but the last will be lost. Read the introduction for the answer why. It is relatively easy to programm defensively in a way that losing individual events doesn't matter: Also use QueryWidget() to get the status of all your widgets. Don't keep redundant information about widget status in your code. Ask them. Always.
// WaitForEvent.ycp // // Example for common usage of UI::WaitForEvent() { // Build dialog with a selection box and some buttons. // // Output goes to the log file: ~/.y2log for normal users // or /var/log/YaST2/y2log for root. integer timeout_millisec = 20 * 1000; UI::OpenDialog( `VBox( `SelectionBox(`id(`pizza ), `opt(`notify, `immediate ), "Select your Pi&zza:", [ `item(`id(`napoli ), "Napoli" ), `item(`id(`funghi ), "Funghi" ), `item(`id(`salami ), "Salami" ), `item(`id(`prociutto ), "Prosciutto" ), `item(`id(`stagioni ), "Quattro Stagioni" ), `item(`id(`chef ), "A la Chef", true ) ] ), `HBox( `PushButton(`id(`ok ), "&OK" ), `PushButton(`id(`cancel ), "&Cancel" ), `HSpacing(), `PushButton(`id(`details ), "&Details..." ) ) ) ); map event = $[]; any id = nil; // Event loop repeat { event = UI::WaitForEvent( timeout_millisec ); id = event["ID"]:nil; // We'll need this often - cache it if ( id == `pizza ) { if ( event["EventReason"]:nil == "Activated" ) { // Handle pizza "activate" (double click or space pressed) y2milestone( "Pizza activated" ); id = `details; // Handle as if "Details" button were clicked } else if ( event["EventReason"]:nil == "SelectionChanged" ) { // Handle pizza selection change y2milestone( "Pizza selected" ); } } if ( id == `details ) { y2milestone( "Show details" ); } if ( id == `timeout ) { // Handle timeout y2milestone( "Timeout detected by ID" ); } if ( event["EventType"]:nil == "TimeoutEvent" ) // Equivalent { // Handle timeout y2milestone( "Timeout detected by event type" ); // Open a popup dialog UI::OpenDialog( `VBox( `Label( "Not hungry?" ), `PushButton(`opt(`default ), "&OK" ) ) ); UI::TimeoutUserInput( 10 * 1000 ); // Automatically close after 10 seconds UI::CloseDialog(); } } until ( id == `ok || id == `cancel ); UI::CloseDialog(); }