Character User Interface (FMLI and ETI)
Programming Tips and Known Problems
Automatic Function Key Downloading
The FMLI interface relies heavily on the use of a terminal's keyboard function keys F1 through F8 but these keys are not available on some terminals or are not designed in a way that the System V terminfo(4) database can work with cleanly. To help in these situations, FMLI provides equivalent 2-character sequences to achieve the same effect: CTRL-f 1 though CTRL-f 8. Sometimes, however, new users of an FMLI application do not know about these equivalent character sequences, and are unable to use the screen-labeled function keys of the interface, a rather frustrating situation for such new users.
FMLI 4.0 provides a partial fix to this problem of new users, at a possible slight inconvenience to some experienced users, on some terminals. If a terminal, as defined in its terminfo entry, does not have default escape sequences for its function keys but can download strings into its function keys (this is the case, for example, on the AT&T 5620 and 630 terminals), then FMLI attempts to download the equivalent 2-character sequences into the function keys. This occurs, by default, when fmli if first invoked and each time that the user returns from any full-screen activity, such as those initiated with the run or unix-system commands. For terminals not fitting this description, no downloading is done.
NOTE: Referencing a terminfo entry for the AT&T 5620 Terminal from an old (pre-Release 4.0) terminfo database, will cause the FMLI default escape sequences for the function keys to be incorrectly downloaded. Not all escape sequences will be downloaded, and garbage may be output to the screen. This can occur if a user maintains a private variant of the terminfo entry. A user can set LOADPFK=NO in the environment to avoid this problem.
For new users this default behavior is helpful, but for an experienced user who has already placed other strings into the function keys, this is inconvenient, as the FMLI character sequences replace the user's own, and FMLI cannot restore the user's automatically.
Using the LOADPFK Environment Variable to Disable Downloading
The environment variable LOADPFK can be used to specify that this downloading not be done. Setting LOADPFK=NO in the environment before invoking fmli prevents this downloading from occurring, at any time.
Using a Shell Script to Restore Your Function Key Settings
Users who have entered strings in their function keys on this type of terminal may find a shell script to restore their stings useful; this script uses the tput utility to download function key strings:
tpu pfx 1 'string-for-function-key-1'
<pu pfx 2 'string-for-function-key-2'
<pu pfx 3 'string-for-function-key-3'
<pu pfx 4 'string-for-function-key-4'
<pu pfx 5 'string-for-function-key-5'
<pu pfx 6 'string-for-function-key-6'
<pu pfx 7 'string-for-function-key-7'
<pu pfx 8 'string-for-function-key-8'
Downloading FMLI Sequences More Efficiently
Even when the user wants the FMLI sequences downloaded, it is more efficient to do it only once if no program run from the FMLI application changes the function key settings (most programs do not); any possible delays required to download the sequences occur just once this way, instead of at the beginning of the application and every time a full-screen activity is run. This can be done using tput as above, but with the FMLI 2-character sequences; however, it is more easily done by the command sequence:
fmli any-FMLI-frame-file # then exit immediately
LOADPFK=NO fmli real-application-menu-name
The first invocation of FMLI downloads the equivalent 2-character sequences. You then exit from that invocation and call it again, with LOADPFK=NO, to have your application run a little more efficiently.
Validation of Form Fields
Inter-dependent Field Validation
FMLI validates all fields that have not been navigated to when a form is saved (the SAVE SLK is pressed, causing the done descriptor to be evaluated). This is not always sufficient for inter-field validations. For example, assume two inter-related fields on a form. The first field that appears will not have the interfield validation specified since the validation cannot be done until the second field is set. This works fine for the case in which the first field and then the second field is set or if the second field is not set (it will be checked on saving). Putting a minimal validation on the first field handles the case where neither field is set before leaving. The problem occurs if the user enters the first around to the first field and re-sets it: the inter-field validation is not re-done so the fields may not be valid. The application developer must allow for this and code the done descriptor accordingly.
Using Global Variables Across Frames
Developers should be aware that information stored in FMLI variables via the set utility or the argument passing mechanism ($ARGn) may not be valid at the time it is used even if it was validated at the time it was set. This can occur when variables set from data in one frame are used in the processing activity of another frame. If the use of a variable containing invalid data could seriously corrupt or compromise the system it must be re-validated at the time it is used.
Developer-set variables are known to all frames in an FMLI session--there is no "frame scoping" of variables, no way to make a variable known only to the frame it is set in. This results in the classic programming issues around global variables.
Here are two scenarios that can result in the value of a variable no longer being valid.
Scenario 1
The done descriptor of Form.1 sets a variable set -1 FOO=$F1, the value of field one, and opens Form.1a. The user enters data in Form1 and presses the SAVE SLK; Form.1a opens and becomes the current frame. The user now changes her/his mind, navigates back to Form.1 and enters a new value in field one. If instead of pressing the SAVE SLK for Form.1 again, the user navigates to Form.1a, when the user saves Form.1a it will not know the value in Form.1 has changed and any action in Form.1a based on the value of FOO will be different from what the user expects. The user's error of not pressing SAVE after changing Form.1 will not be detected.
Scenario 2
The done descriptor of Form.1 opens Form.1a passing the value of $F1 as the first argument (as in open Form.1a $F1). Assume this value is a user ID that Form.1 validated. Now the user navigates to another menu and deletes the user, then navigates back to Form.1a. Now the value of ARG1 is not a valid user ID even thought Form.1 validated it.
Commands
- If an FMLI application initiates a call to a UNIX system command (e.g., action='unix_command'nop) and the interrupt descriptor evaluates to FALSE for that action descriptor, (see "Interrupt Signal Handling" in Chapter 2), users will not be able to do other tasks until the command completes even if the command could be interrupted. If the command takes a considerable amount of time to execute, the application writer may want the command to execute in the background.
- Since FMLI does not recognize the shell background symbol & , the shell built-in command must be used (e.g. action='shell "unix_command> /dev/null &" 'nop). If you want the user to continue to be able to interact with the application while the background job is running, the output of an executable run by shell in the background must be redirected: to a file if you want to save the output, or to /dev/null if you don't want to save it (or if there is no output), otherwise your application may appear to be hung until the background job finishes processing. The application writer may also wish to explore the co-processing facility coproc(1F) which establishes a pipe between FMLI and another independent UNIX process.
Co-processing Functions
- When writing programs to use as co-processes, the following tips may be useful. If the co-process program is written in C language, be sure to flush ouput after writing to the pipe. (Currently, awk(1) and sed(1) cannot be used in a co-process program because they do not flush after lines of output.) Shell scripts are well-mannered, but slow. C language is recommended. If possible, use the default send_string, rpath and wpath. In most cases, expect_string has to be specified. This, of course, depends on the co-process.
Forms
- Choices for a form field can be specified using the rmenu descriptor. If the value of rmenu is a list of items enclosed in brackets, there must be at least one white-space character that separates the brackets from the item list (e.g., rmenu={ "item 1" "item 2" "item 3"}).
- If a definition of the rmenu descriptor degenerates to an empty list (rmenu={}), the value of choicemsg is displayed--your definition if you have defined one, or the FMLI default message There are no choices available. If you define choicemsg and there might not be any choices, be sure the message is appropriate to the "empty list" case.
- There must be at leasts one active field visible in a form. If you open a form with all fields defined as inactive, or show=FALSE, fmli does not display the frame.
- Field n in a form frame cannot reference field m, where m is greater than not reference the value of a field that is defined later in the form definition file because that field may not have been evaluated at the time you reference it.
- Care should be taken that no page of a form is bigger than the first page. If a second, or subsequent page of a form is larger than the first page, it may be displayed in a new frame in a location other than the location of the first page. The new frame may have an incremented frame ID number. This can be confusing the users.
If a second, or subsequent page of a form is defined to be larger than can be displayed on the terminal being used, it is not displayed at all (e.g., if rows=25 is defined, and the terminal being used only has 24 rows available for display).
Menus
- The precise rules for how rows and columns are determined in menus are given in the following table. This table should only need to be used in exceptional cases (for example, when a developer has coded "unreasonable" values for the rows and columns descriptor in a menu definition file. In general, the number of columns in a menu is determined before the number of rows, and columns specified with the columns descriptor takes precedence if there is a conflict with the number or rows requested. The number of rows is usually the minimum of the three variables aR (available rows), sR (specified rows), and nR (needed rows).
The table entries for the two cases when columns is specified and description is not imply that menu items are truncated to fit in the column size determined fro sC. Thus, the columns descriptor should not be specified for menus that are dynamically generated, when there is no way to guarantee that such a menu will not have truncated items.
Descriptors set?
|
Step 1
|
Step 2
|
Step 3
|
D
|
r
|
c
|
pC
|
pR
|
uC
|
uR |
yes
|
no
|
no
|
not needed
|
not needed
|
1
|
min(10,nR) |
yes
|
no
|
yes
|
"
|
"
|
1*
|
" |
yes
|
yes
|
no
|
"
|
"
|
1
|
min(aR,nR,sR |
yes
|
yes
|
yes
|
"
|
"
|
1*
|
" |
no
|
no
|
no
|
_**
|
_**
|
_**
|
_** |
no
|
no
|
yes
|
if sC > mC, 1; otherwise, sC***
|
((tI-1) mod pC)+1
|
if pR > aR, 1: otherwise, pC
|
if pR > aR, min (aR,10); otherwise, pR |
no
|
yes
|
no
|
((tI-1) mod pR)+1t
|
min(aR,nR,sR)t
|
if pC>fC, 1; otherwise, pC
|
pR |
no
|
yes
|
yes
|
if sC > mC, 1; otherwise, sC***
|
((tI-1) mod pC)+1
|
if pR> aR, 1; otherwise, pC
|
if pR>aR, min (aR,sR); otherwise, pRtt |
Footnotes
*
|
columns descriptor is ignored |
*
|
columns descriptor is ignored |
**
|
the algorithm attempts to open a menu with a 3:1 aspect ratio of width to height |
***
|
menu items are truncated if they are too long to fit; equal-width columns are kept after truncation. |
+
|
step 1 and step 2 are reversed for this case (pR must be computed first) |
++
|
rows descriptor is ignored |
Legend
d
|
description descriptor |
r
|
rows descriptor |
c
|
columns descriptor |
sR
|
(specified rows) the value coded with the rows descriptor |
aR
|
(available rows) the number of rows that frames can occupy on the terminal screen |
nR
|
(needed rows) the number of rows needed to open the menu--for single column menus this equals tI |
pR
|
(probable rows) the number of rows needed to open the menu, as determined from the first (preliminary) calculations |
uR
|
(used rows) the number of rows used to open the menu, after all steps are done |
tI
|
(total items) the total number of menu items for the menu (the number of menu descriptors) |
sC
|
(specified columns) the value coded with the columns descriptor |
fC
|
(fittable columns) the number of columns that can fit on the screen, given the screen width and the length of the longest menu item; equals (screen Width-2) mod (maxItem Width+1); this is a "maximum" value--the maximum fittable columns |
mC
|
(max columns) the maximum number of columns that could fit on the screen if each column were only 1 character wise; equals (screen Width-3) mod 2 |
pC
|
(probable columns) the number of columns needed to open the menu, as determined from the first (preliminary) calculations |
uC
|
(used columns) the number of columns used to open the menu, after all steps are done |
Text
- The SCROLL-DOWN key displays the complete final page of a text frame, even if much of it was already visible. The SCROLL-UP key displays the entire first page of a text object, even if most of it was already visible. The action SCROLL-DOWN might be a surprise to users if they are not also aware that the scroll down icon has disappeared, signaling that they are at the end of the text.
Backquoted Expressions
- Backquoted expressions that appear on a line by themselves are evaluated before any descriptors are parsed. That is, they are evaluated before the frame if fully current. Thus, the following can occur:if a stand-alone backquoted expression produces output to the message line, it may appear before the frame being parsed is posted. This delay may or may not be significant and depends on the complexity of the frame definition file.
- message -f statements in stand-alone backquoted expressions are ignored.
- the built-in function getfrm, if used in a stand-alone backquoted expression, may be parsed before the frame ID it is supposed to return is available.
- If a command run in a backquoted expression changes the stty(1) setting the FMLI session may be corrupted. Frames may not display correctly and the command line may not function (the latter occurs if RETURN is mapped to LINEFEED or to RETURN LINEFEED.
- If a daemon process is stared via a shell script that FMLI code invokes in a backquoted expression, FMLI waits for this process until the UNIX system clears up zombies. While waiting, FMLI appears to be locked because the backquoted command that was exec'd created a child whose stdout is still connected to FMLI via a pipe. When the command becomes a zombie, FMLI continues reading the pipe that the (daemon) child still has open. FMLI does not know if its grandchildren are going to be daemons or if they are going to write to the pipe. To preserve the ability of grandchildren to output to FMLI, the following fix must be placed in the script executed by the backquoted expression, to redirect the stdout of the daemon:
nohup my_daemon > /dev/null &
Color
- Some color devices may reverse a color request. For example, highlight_bar=red and highlight_bar_text=green may be displayed as "red on green" rather than "green on read." If this happens, set highlight_bar=green and highlight_bar_text=red to produce the proper color combination. This solution will, of course, cause the problem on devices that handle color requests as expected.
Message Line
- When the checkworld command is executed explicitly, or when a SIGALRM occurs after MAILCHECK seconds, the message line may clear. Because the reason the message line clears may not be apparent to users, documents about your application should include an explanation of this behavior.
Syntax
- In general, FMLI does not generate messages on syntax errors. However, some of the built-in functions, such as fmlgrep and fmlcut, and the if-then-else statement, generate their own syntax error messages. Developers should be aware that the absence of an error message does not necessarily mean that there is not a syntax error in their code.
- When creating a new form, menu, or text frame, all quotes and backquotes must match. Quoting mismatches may cause unpredictable results: the frame may never appear, or appear incorrectly.
- Prior to FMLI Release 4.0, only the $ notation existed for variable evaluation, and that notation exhibited the behavior now defined for $!. For previously written FMLI applications now being run under FMLI Release 4.0, a Boolean descriptor, use_incorrect_pre4.0_behavior can be set in the initialization file, which causes fmli to ignore the $! notation and interpret $ in the way defined above for $!. The default value (if not defined in the initialization file) for use_incorrect_pre4.0_behavior is FALSE.
Miscellaneous
- The FMLI Interpreter does not use EOF to exit a program. The assumption is that applications are interactive and at some point allow the user to select an item that evaluates to the exit command. Otherwise, the FMLI application will run indefinitely. Thus, if the input to fmli is to come from a file, the file must include the exit command.
- If you are running FMLI on a system with the shell job control feature, you can interrupt an FMLI application using the CTRL-z key and resume it with the fg utility.
- In late negotiations last night, the mouse consortium agreed to work with FMLI under some circumstances! When FMLI runs in an xterm window under AT&T's XWIN X Window SystemTM implementation, a mouse device works with the interface in a limited way. The SELECT mouse button can be used to make a frame current, select a menu item, or press a SLK. Try it to see how it works.
Known Problems
Initialization
- If you re-initialize the FMLI application with a new background color, text in the banner line is shifted one character to the right. To avoid this problem, force the banner to be re-evaluated by including the banner descriptors in the new initialization file.
- The slk_bar and slk_text descriptors do not work correctly. The background of the screen labeled keys is the color defined for highlight_bar_text and the text on these keys is the color defined for highlight_bar.
Screen Appearance
- Frames in the work area of the screen sometimes overlap such that one or more frames appear to be above or below another. The current frame is always above any frame with which it shares screen coordinates. Formerly, frames that were above other frames were probably more recently current than those below. In this release, noncurrent frames may restack when certain operations, not directly involving these frames, are performed. For instance, deleting a frame may cause the prior current frame, which was completely visible, to be completely obscured. This can also sometimes be observed when a frame is opened.
- Sometimes the scroll box on the right border of a frame remains highlighted even when the frame is no longer current.
Message Line
- When a mouse is used to navigate to a new frame and the mouse is pointing within the frame title or its scroll bar, the item message or field message for the current item or field may flash on the message line.
Command Line
- If you navigate to the command line from the Command Menu, the current item from the menu displays on the command line; if you backspace to type something else shorter than the original item, the resulting command is unrecognized.
- Shell file name expansion is not recognized with FMLI commands on the command line; for example, you cannot type the command open Menu.* to attempt to open all the menus in the current directory. However, it does work with UNIX utilities passed to a shell with the ! prefix, as in !vi Menu.*.
Screen Labels for Function Keys
- The only way to get the commands prev-frm, next-frm, prevpage, and nextpage to work on an application-defined SLK is to make the label of the SLK (using the name descriptor) the same as the command name. Also, if the SLK label is set to one of these (case irrelevant), that is the command that will be executed by that application-defined SLK, no matter what the action descriptor is coded to.
Forms
Multi-page forms
- An attempt to access a form page that has no active (inactive=true) or shown (show=false) fields causes the cursor to be positioned on the first field (inactive or "not shown" field) and input to the field is allowed.
- If a second or subsequent page of a form is larger than the first page and the begrow or begcol descriptors are used, the values for these descriptors are ignored for that page.
- Sometimes on multi-page forms, the scroll indicators (^ and v) may not be shown when and after any page after the first is displayed.
Form Field Validation
- If a form is updated using the update command in an application, without being closed, the validations defined for that form may not be performed thereafter.
- The valid descriptor of the current field is not evaluated if CTRL-e is used to navigate to the last field of the form; fields skipped by the navigation are, however, validated when the form is saved.
Horizontally Scrollable Form Fields
- Once you have typed enough characters into a 1-row (horizontally) scrollable field to cause that field to scroll, backspacing in the field followed by typing enough additional characters to put the cursor past where the scrolling should begin again, causes corruption of the field boundaries and may cause a core dump at a later time.
Other Form Problems
- The show, value, and inactive descriptors are not re-evaluated for a field, when a SLK is pressed, unless the RETURN key has been pressed after the data is entered in the field.
- When an application-defined SLK is pressed after a value has been entered in a field, the new value of the field is not set in the field variable (Fn) unless the RETURN key has also been pressed. This is particularly relevant for forms with only 1 field in them.
- If a left bracket [ is entered into a field that has a descriptor coded with the statement if [ -z "Fn" ]; in a backquoted expression, the message [] imbalance is improperly issued. If the use_incorrect_pre_4.0_behavior descriptor is also set to true, this problem may cause a core dump.
- If an active form field is dynamically made to be inactive, then underlining is retained on those characters of the field that already have data typed in them.
- The field variable (Fn) of a field that has the noecho descriptor set to true may be set to garbage when the form containing that field is reopened.
- The built-in variable Form_Choice is not unset each time that a choices menu is opened. Thus, an old value may still be present if a choices menu is posted but an item therein not selected.
- For forms that do not close when saved, if you type a new value in a field immediately after having saved that form, the old value in the field variable is not cleared; any characters from the old value that are not typed over with new characters remain set in the field variable.
Text Frames
- The regex built-in utility used in a text descriptor, with a template argument that cat's a file containing tabs and newlines, does not preserve the tabs and newlines in the opened text frame.
- A text frame with wrap=true set may lose its correct wrapping if the update command is issued for it.
- If the rows descriptor of a text frame is reduced after the frame is opened and the frame is later updated, the display of the frame will be corrupted.
- The header in a text frame is truncated if it is longer than the columns descriptor specified, even if the title of the frame causes the actual size of the frame to be big enough to hold the header.
- If the header descriptor contains sufficient newlines, a text frame can be composed entirely of header and no text appears. Sometimes, the display may also be corrupted.
Commands
- Any application-defined command whose name is lexically greater than update cannot be added to the Commands Menu by being defined in the commands file; it will be ignored.
- When the run command is typed on the command line, the arguments are parsed incorrectly, as shell operators are passed to the command as arguments. For example, run date > filename results in the date command failing.
- When an FMLI command is disabled in the commands file, as in
name=update
action=nop
this disables it throughout the interface. There is no way to remove it from the Commands Menu and still leave it available for use in the application code itself.
- The reset command does not work in the done descriptor of a form.
- When a second set of SLKs are defined, the togslk command issued from the command line works once, to switch from the first set to the second, but subsequent executions of it are ignored.
- If the rmenu descriptor defines consecutive choices as identical (which shouldn't be done, as it serves no purpose), toggling the choices using the CHOICES function key prevents those choices after the duplicated one from being reachable.
Built-in Utilities
regex
- The regex built-in utility used in a text descriptor, with a template argument that cat's file containing tabs and newlines, does not preserve the tabs and newlines in the opened text frame.
- If the pattern [a-zA-z_/] is used, the characters _/ are not recognized; but if those characters are moved before any ranges, as in [_/a-zA-Z], then they are recognized.
readfile
- The longline utility cannot be used to determine the longest line of a header read with the readfile utility if the text descriptor also contains a readfile.
- If a menu contains a readfile in a backquoted expression on a line by itself and the file read contains a series of backquoted expressions on lines by themselves, the first one of those line is ignored. Making the first line a blank or a comment will get around this.
Co-processing Utilities
- The frame border of a form may not complete until input is provided from the keyboard when co-processing is used.
- Input and output strings from co-processing should not use non-alphabetic printable characters, as the FMLI special characters are not correctly transmitted.
- When the reread descriptor is used with co-processing and the vsig utility causes the re-read to occur frequently, the FMLI process may grow out of memory space.
if then else
- Omitting the terminating fi causes the remainder of a frame definition file to be incorrectly parsed.
- The standard output of if then else cannot be redirected using the > operator. However, individual parts of the statement (the then part and the else part) can be.
- The $$ operator is sometimes incompatible with if then else. In particular, an if then else following a $$ causes the if to parse incorrectly.
- A null statement following a then followed by an else can cause a syntax error.
- An output redirection in the un-executed then or else part of an if then else statement is evaluated, creating an empty output file, even though the command portion is not executed. In this case, the file being re-directed to should be different in the then and else parts of the statement.
- Long if then elif then elif . . . statements (attempting to do a reasonable case statement0 may fail without explanation.
Other Built-in Utility Problems
- The fmlcut built-in utility reads standard input piped to it, but does not read a file redirected using <.
- Some built-in utilities, like fmlgrep, do not write their error output to the standard error stream, but display it on the message line or at the current cursor position.
- The standard error output of built-in utilities, when written to, cannot be re-directed using the 2> redirection operator.
Descriptors
- The init descriptor for a frame is not evaluated first, although it should be. In forms, the value descriptors are evaluated first, followed by the page, show, and inactive descriptors for each field; in menus, the show descriptors for items are evaluated first. If an application uses backquoted expressions in these descriptors, this ordering must be taken into consideration; init cannot be relied on to be evaluated first.
- The frame descriptor lifetime=shortterm causes a frame to be canceled when the frame is navigated away from. However, this even happens when that navigation is to a help frame for the short-term frame, a choices menu for a field on the frame, or to the command line (e.g., to check the release of FMLI being used); this makes short-term frames less useful than they should be.
- When the reread descriptor is used with co-processing and the vsig utility causes the re-read to occur frequently, the FMLI process may grow out of memory space.
- The permanentmsg descriptor available in the initialization file incorrectly takes precedence over a framemsg descriptor in a frame file.
- The close descriptors of initial objects are not evaluated when the application is exited, although the close descriptors of non-initial objects are evaluated.
Interrupt Facility
- If an interrupt is generated by the user just as a frame is being displayed, corruption may occur. Use the refresh command to redraw the screen.
- If interrupts are enabled in a text frame and the oninterrupt descriptor does not evaluate to a valid command, then an interrupt generated just after the frame is canceled causes the frame to be canceled, when the result should just be a beep, the standard action when the close descriptor does not evaluate to a valid command.
- If interrupts are enabled and the oninterrupt descriptor in effect does not evaluate to a valid command, then an interrupt generated when an application-defined command is being executed causes the current frame to close.
Miscellaneous
- Broadcast messaged from root (for example, ones sent using the wall(1) command) may not be readable while an FMLI application is running, and can corrupt the screen. Users of your FMLI application should be warned that this can happen and that they can access the command line with CTRL-j and execute the refresh command to redraw the screen.
- If there is more than one frame on the screen, and you move one of them with frm-mgmt, and then move the initial frame, there is a chance the initial frame will lose a column of text. To clean up the frame, execute the refresh command.
- FMLI does not recognize EOF on its input stream, so the only way that piped input can cause an fmli execution to properly terminate if for a correct string issuing an exit command to reach FMLI at the right time (e.g., CTRL-j exit, when the operation to go to the command line is recognizable). If the 3exit is not executed, the FMLI session will hang and must be terminated with the kill(1) utility.
- FMLI 4.0 works with the shell job control feature of SVR4.0. However, an FMLI session cannot be successfully started in the background, using a command of the form
fmli Menu.1 &
- However, it can be started in the foreground, interrupted with the CTRL-Z key, and then put in the background using the bg utility.
- Characters that are special to FMLI (such as \) may require unreasonable and seemingly arbitrary escaping backslashes to be correctly assigned to variables or used as arguments.
- If FMLI is running in a dynamically resizable window (for example, under layers or exter), it will not recognize a new window size if the window is enlarged or shrunk, and this may cause corruption.