XMANAGER
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 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.
Note: Although this routine is written in the IDL language, it may change in the future in its internal implementation. For future upgradability, it is best not to modify or even worry about what this routine does internally.
Syntax
XMANAGER [, Name, ID] [, /CATCH] [, CLEANUP=string] [, EVENT_HANDLER=‘procedure_name’] [, GROUP_LEADER=widget_id] [, /JUST_REG] [, /NO_BLOCK]
Arguments
Name
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 Name argument is stored in a COMMON block for use by the XREGISTERED routine. The stored name is case-sensitive.
ID
The widget ID of the top-level base that is the root of the widget hierarchy being to be managed.
Keywords
CATCH
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: Beginning with IDL version 5.0, the default behavior of XMANAGER is to catch errors and continue processing events. In versions of IDL prior to version 5.0, XMANAGER halted when an error was detected. This change in default behavior was necessary in order to allow multiple widget applications (all being managed by XMANAGER) to coexist peacefully. When CATCH is set equal to zero, (the old behavior), any error halts XMANAGER, and thus halts event processing for all running widget applications.
Note also that CATCH is only effective if XMANAGER is blocking to dispatch errors. If event dispatching for an active IDL command line is in use, the CATCH keyword has no effect.
The CATCH=0 setting (errors are not caught and processing halts in XMANAGER when an error is detected) is intended as a debugging aid. Finished programs should not set CATCH=0.
CLEANUP
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: Specifying a routine for the widget application’s top-level base via the KILL_NOTIFY keyword to WIDGET_CONTROL after the call to XMANAGER will override the value of the CLEANUP keyword.
The cleanup routine is called with the widget identifier as its only argument.
EVENT_HANDLER
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.
GROUP_LEADER
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.
JUST_REG
Set this keyword to indicate that XMANAGER should just register the widget and return immediately. This keyword is useful 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.)
Note: JUST_REG is not the same as NO_BLOCK. See JUST_REG vs. NO_BLOCK for additional details.
NO_BLOCK
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.
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.
Note: NO_BLOCK is not the same as JUST_REG. See JUST_REG vs. NO_BLOCK for additional details.
A Note About Blocking in XMANAGER
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.
Active 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 line is available for input while a widget application is running and widget events are being processed.
There are currently 2 separate IDL command-processing front-end implementations:
- The IDL Workbench
- UNIX plain tty
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.
JUST_REG vs. NO_BLOCK
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 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.
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.
Blocking vs. Non-blocking Applications
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:
- The first call to XMANAGER processes events by calling WIDGET_EVENT as necessary until no managed widgets remain on the screen. This is referred to as “blocking” because XMANAGER does not return to the caller until it is done, and the IDL command line is not available.
- XMANAGER does not block, and instead, the part of IDL that reads command input also watches for widget events and calls WIDGET_EVENT as necessary while also reading command input. This is referred to as “non-blocking” or “active command line” mode.
XMANAGER will block unless the following conditions are met:
- All registered widget applications have the NO_BLOCK keyword to XMANAGER set.
- No modal dialogs are displayed. (Modal dialogs always block until dismissed.)
In general, we suggest that new widget applications be written with XMANAGER blocking disabled (that is, with the NO_BLOCK keyword set).
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.
Examples
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
. Compile the file and enter example
at the IDL command line to run the code.
; 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', XSIZE=100, YSIZE=100)
; Create the Done button and set its uservalue to "DONE":
done = WIDGET_BUTTON(base, VALUE = 'Done', UVALUE = 'DONE', $
, XSIZE=100, YSIZE=100)
; 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.
Version History
Pre-4.0 |
Introduced |
Pre-6.2 |
Deprecated BACKGROUND and MODAL |