The XMANAGER procedure provides the main event loop and management for widgets created using IDL. Calling XMANAGER "registers" a widget program with the XMANAGER event handler. XMANAGER takes control of event processing until all widgets have been destroyed.
Beginning with IDL version 5.0, IDL supports an active command line that allows the IDL command input line to continue accepting input while properly configured widget applications are running. See A Note About Blocking in XMANAGER for a more detailed explanation of the active command line.
This routine is written in the IDL language. Its source code can be found in the file xmanager.pro in the lib subdirectory of the IDL distribution.
| Warning |
XMANAGER [, Name, ID] [, /CATCH] [, CLEANUP=string] [, EVENT_HANDLER=`procedure_name'] [, GROUP_LEADER=widget_id] [, /JUST_REG] [, /NO_BLOCK]
A string that contains the name of the routine that creates the widget (i.e., the name of the widget creation routine that is calling XMANAGER).
| Note |
The widget ID of the top-level base that is the root of the widget hierarchy being to be managed.
This keyword is obsolete and is included in XMANAGER for compatibility with existing code only. Its functionality has been replaced by the TIMER keyword to the WIDGET_CONTROL procedure.
Set this keyword to cause XMANAGER to catch any errors, using the CATCH procedure, when dispatching widget events. If the CATCH keyword is set equal to zero, execution halts and IDL provides traceback information when an error is detected. This keyword is set by default (errors are caught and processing continues).
Do not specify either the Name or ID argument to XMANAGER when specifying the CATCH keyword (they are ignored). CATCH turns error catching on and off for all applications managed by XMANAGER. When CATCH is specified, XMANAGER changes its error-catching behavior and returns immediately, without taking any other action.
| Note |
Set this keyword to a string that contains the name of the routine to be called when the widget program dies. If this keyword is not specified, the routine (if any) specified for the program's top-level base by the KILL_NOTIFY keyword to WIDGET_BASE or WIDGET_CONTROL is used.
The routine specified by CLEANUP becomes the KILL_NOTIFY routine for the widget application, overriding any cleanup routines that have been set previously via the KILL_NOTIFY keyword to WIDGET_BASE or WIDGET_CONTROL.
| Note |
The cleanup routine is called with the widget identifier as its only argument.
Set this keyword to a string that contains the name of a routine to be called when a widget event occurs in the widget program being registered. If this keyword is not supplied, XMANAGER will construct a default name by adding the "_event" suffix to the Name argument. See the example below for a more detailed explanation.
The widget ID of the group leader for the widget being processed. When the leader dies either by the users actions or some other routine, all widgets that have that leader will also die.
For example, a widget that views a help file for a demo widget would have that demo widget as its leader. When the help widget is registered, it sets the keyword GROUP_LEADER to the widget ID of the demo widget. If the demo widget were destroyed, the help widget led by it would be killed by the XMANAGER.
Set this keyword to indicate that XMANAGER should just register the widget and return immediately. This keyword is useful if you want to register a group of related top-level widgets before beginning event processing and one or more of the registered widgets requests that XMANAGER block event processing. (Note that in this case a later call to XMANAGER without the JUST_REG keyword is necessary to begin blocking.)
(See A Note About Blocking in XMANAGER for further discussion of the active command line.)
| Warning |
Set this keyword to tell XMANAGER that the registering client does not require XMANAGER to block if active command line event processing is available. If active command line event processing is available and every current XMANAGER client specifies NO_BLOCK, then XMANAGER will not block and the user will have access to the command line while widget applications are running.
| Note |
It is important to understand the result of making nested calls to XMANAGER. XMANAGER can only block event processing for one client at a time. In applications involving multiple calls to XMANAGER (either directly or via calls to other routines that call XMANAGER, such as XLOADCT), blocking occurs only for the outermost call to XMANAGER, unless XMANAGER is told not to block in that call. If an application contains two calls to XMANAGER, the second call cannot block unless the first call sets the NO_BLOCK keyword. If an application contains a call to XMANAGER, followed by a call to XLOADCT, XLOADCT will not block unless the NO_BLOCK keyword was set in the call to XMANAGER (and the BLOCK keyword to XLOADCT is set). Consider the following example:
PRO blocking_example_event, event ; The following call blocks only if the NO_BLOCK keyword to ; XMANAGER is set: XLOADCT, /BLOCK END PRO blocking_example base=WIDGET_BASE(/COLUMN) button1=WIDGET_BUTTON(base,VALUE='Run XLOADCT') WIDGET_CONTROL,base, /REALIZE XMANAGER,'blocking_example', base, /NO_BLOCK END
If the NO_BLOCK keyword to XMANAGER was not set in the above example, XLOADCT would not block, even though the BLOCK keyword was set. Setting the NO_BLOCK keyword to XMANAGER prevents XMANAGER from blocking, thereby allowing the subsequent call to XMANAGER (via XLOADCT) to block.
| Warning |
By default, IDL widget application blocking is enabled. Unless you take the appropriate steps, widget applications will block all other processing from occurring in IDL. Keeping the following issues in mind when writing widget applications will give you the best chance to create applications that coexist with other applications and the IDL command line.
Beginning with IDL version 5.0, most versions of IDL's command-processing front-end are able to support an active command line while running properly constructed widget applications. What this means is that-provided the widget application is properly configured-the IDL command input line is available for input while a widget application is running and widget events are being processed.
There are currently 3 separate IDL command-processing front-end implementations:
Note that widget applications must be well-behaved with respect to blocking widget event processing. Since in most cases XMANAGER is used to handle widget event processing, this means that in order for the command line to remain active, all widget applications must be run with the NO_BLOCK keyword to XMANAGER set. (Note that since NO_BLOCK is not the default, it is quite likely that some application will block.) If a single application runs in blocking mode, the command line will be inaccessible until the blocking application exits. When a blocking application exits, the IDL command line will once again become active.
Although their names imply a similar function, the JUST_REG and NO_BLOCK keywords perform very different services. It is important to understand what they do and how they differ.
The JUST_REG keyword tells XMANAGER that it should simply register a client and then return immediately. The result is that the client becomes known to XMANAGER, and that future calls to XMANAGER will take this client into account. Therefore, JUST_REG only controls how the registering call to XMANAGER should behave. The client can still be registered as requiring XMANAGER to block by setting NO_BLOCK=0. In this case, future calls to XMANAGER will block.
| Note |
The NO_BLOCK keyword tells XMANAGER that the registered client does not require XMANAGER to block if the command-processing front-end is able to support active command line event processing. XMANAGER remembers this attribute of the client until the client exits, even after the call to XMANAGER that registered the client returns. NO_BLOCK is just a "vote" on how XMANAGER should behave-the final decision is made by XMANAGER by considering the NO_BLOCK attributes of all of its current clients as well as the ability of the command-processing front-end in use to support the active command line.
The issue of blocking in XMANAGER requires some explanation. IDL widget events are not processed until the WIDGET_EVENT function is called to handle them. Otherwise, they are queued by IDL indefinitely. Knowing how and when to call WIDGET_EVENT is the primary service provided by XMANAGER.
There are two ways blocking is typically handled:
XMANAGER will block unless the following conditions are met:
In general, we suggest that new widget applications be written with XMANAGER blocking disabled (that is, with the NO_BLOCK keyword set), unless the widget application will be run on IDL Runtime.
| Note |
Since a widget application that does block event processing for itself will block event processing for all other widget applications (and the IDL command line) as well, we suggest that older widget applications be upgraded to take advantage of the new, non-blocking behavior by adding the NO_BLOCK keyword to most calls to XMANAGER.
The following code creates a widget named EXAMPLE that is just a base widget with a "Done" button and registers it with the XMANAGER. Widgets being registered with the XMANAGER must provide at least two routines. The first routine creates the widget and registers it with the manager and the second routine processes the events that occur within that widget. An example widget is supplied below that uses only two routines. A number of other "Simple Widget Examples", can be viewed by entering WEXMASTER at the IDL prompt. These simple programs demonstrate many aspects of widget programming.
The following lines of code would be saved in a single file, named example.pro:
; Begin the event handler routine for the EXAMPLE widget: PRO example_event, ev ; The uservalue is retrieved from a widget when an event occurs: WIDGET_CONTROL, ev.id, GET_UVALUE = uv ; If the event occurred in the Done button, kill the widget ; example: if (uv eq 'DONE') THEN WIDGET_CONTROL, ev.top, /DESTROY ; End of the event handler part: END ; This is the routine that creates the widget and registers it with ; the XMANAGER: PRO example ; Create the top-level base for the widget: base = WIDGET_BASE(TITLE='Example') ; Create the Done button and set its uservalue to "DONE": done = WIDGET_BUTTON(base, VALUE = 'Done', UVALUE = 'DONE') ; Realize the widget (i.e., display it on screen): WIDGET_CONTROL, base, /REALIZE ; Register the widget with the XMANAGER, leaving the IDL command ; line active: XMANAGER, 'example', base, /NO_BLOCK ; End of the widget creation part: END
First the event handler routine is listed. The handler routine has the same name as the main routine with the characters "_event" added. If you would like to use another event handler name, you would need to pass its name to XMANAGER using the EVENT_HANDLER keyword.
Notice that the event routine is listed before the main routine. If you include both the event routine and the main routine in a single .pro file with the name of the main routine (a common practice), this is necessary to ensure that the event routine is compiled. If the event routine were placed after the main routine in the file, IDL would compile and execute the main routine - and the compiler would exit - before the event routine was compiled. Alternatively, you can save your event routine in its own file with its own name (which in the above example would be example_event.pro), and IDL will compile the routine when it is required.
Notice also the NO_BLOCK keyword to XMANAGER has been included. This allows IDL to continue processing events and accepting input at the command prompt while the example widget application is running.
Introduced: Pre 4.0
XMTOOL, XREGISTERED, Creating Widget Applications.