Ask Reuben
TopMost Normal Window
What is the Topmost Normal Window?
Why can I only see one window?
Why can I only see two windows?
The phrase “Topmost Normal Window” is one that will be familiar to Genero developers who used the various incarnations of the Genero Web Client from around 2008 or so. For those Genero developers who have stuck solely with the Genero Desktop Client, this maybe a new concept as they move to 4.00 and Universal Rendering.
The concept is that instead of displaying every window and allowing the user to move/resize these windows independently, at most only two windows will be rendered. They are …
- the topmost normal window
- the topmost modal window (if it is was opened after the topmost normal window)
For most ISV’s who have moved to the web as being their preferred front-end , this is seen as something in keeping with a typical web interface, and they have transformed their Genero applications to work within this framework.
Before I explain further I will first explain what a modal window is. The Wikipedia description is quite good
A modal window creates a mode that disables user interaction with the main window but keeps it visible, with the modal window as a child window in front of it. Users must interact with the modal window before they can return to the parent window. This avoids interrupting the workflow on the main window.
In Genero speak, a modal window opens with a dialog, typically a MENU, but can be any other dialog such DISPLAY ARRAY, INPUT, and the user completes that dialog before returning to the dialog that there were in before the modal window was opened.
In Genero, a modal window is determined by Presentation Styles and in particular the windowType Style Attribute. In FGLDIR/lib/default.4st, you will some entries…
StyleAttribute name="windowType" value="modal"
… and this is used in Styles such as…
Style name="Window.dialog"
… If you have OPEN WINDOW … STYLE=”dialog”, this is the signal to open a window as a modal window. Due to this entry in the Stylesheet then where you see STYLE=”dialog” in your code, this is a modal window.
You should also note that effectively MENU … STYLE=”dialog” is opening a modal window, as is PROMPT , and utility functions such as FGL_WINMESSAGE, FGL_WINQUESTION etc.
A normal window is the base for the users workflow. It is where the value for windowType Style Attribute is “normal”. This is also the default value so does not normally need to be explicitly stated.
To see the differences between Desktop rendering and Universal Rendering with its Topmost Normal Window concept, run the example code at the end of this article. This program allows you to open multiple windows and to choose wether each window is opened as normal or as modal (STYLE=dialog).
For the screenshots below, I pressed normal, normal, dialog, dialog to open 4 windows.
In the 3.21 GDC, after some resizing and dragging, I can see all 4 windows, the two normal windows W1, W2, and two modal windows W3, W4 …
With 4.00 and Universal Rendering I can only see W2, the topmost normal window, and W4 the topmost modal window.
To see window W1, I have to click on the Window List icon in the top left corner and that will allow me to select and view the other normal windows.
Ideally there is only ever one modal window in the stack of windows, however there is nothing stopping you opening multiple modal windows, if you do you will only ever see the topmost modal window. There is also nothing stopping you opening a normal window from a modal window, if you do that you will see the new topmost normal window only.
As there is only ever one normal window (the top most normal window) displayed in the window container, this window is full size within the container and has no ability to be resized other than what you can do with the window container (the GDC window, the browser tab, the mobile device). The topmost modal window is sized based on its content, rendered as a window and can be dragged and resized.
As I said at the beginning of the article, most ISV’s who have been using Web Client for a number of years now will be familiar with this Topmost Normal Window concept. They have adapted their application to fit and as a result their application looks like any other web application. Instead of layer upon layer of independent window, they have one window at the base of their rendering where the user does most of their workflow, and when a user selects certain actions, a modal window maybe displayed above this normal window, and then when the user finishes in this modal window they are returned to the normal window and their workflow within this window.
#! askreuben187.4gl MAIN DEFINE depth INTEGER DEFINE choice STRING LET depth = 0 WHILE TRUE IF depth < 0 THEN EXIT WHILE END IF LET choice = get_choice(depth) IF choice ="normal" OR choice="dialog" THEN LET depth = depth + 1 CASE depth WHEN 1 OPEN WINDOW w1 WITH FORM "askreuben187" ATTRIBUTES(STYLE = choice) WHEN 2 OPEN WINDOW w2 WITH FORM "askreuben187" ATTRIBUTES(STYLE = choice) WHEN 3 OPEN WINDOW w3 WITH FORM "askreuben187" ATTRIBUTES(STYLE = choice) WHEN 4 OPEN WINDOW w4 WITH FORM "askreuben187" ATTRIBUTES(STYLE = choice) WHEN 5 OPEN WINDOW w5 WITH FORM "askreuben187" ATTRIBUTES(STYLE = choice) WHEN 6 OPEN WINDOW w6 WITH FORM "askreuben187" ATTRIBUTES(STYLE = choice) END CASE DISPLAY depth TO depth DISPLAY choice TO style CONTINUE WHILE END IF IF choice = "close_window" THEN CASE depth WHEN 1 CLOSE WINDOW w1 WHEN 2 CLOSE WINDOW w2 WHEN 3 CLOSE WINDOW w3 WHEN 4 CLOSE WINDOW w4 WHEN 5 CLOSE WINDOW w5 WHEN 6 CLOSE WINDOW w6 END CASE LET depth = depth - 1 CONTINUE WHILE END IF END WHILE END MAIN FUNCTION get_choice(depth INTEGER) MENU "" BEFORE MENU CALL DIALOG.setActionActive("normal", depth < 6) CALL DIALOG.setActionActive("dialog", depth < 6) ON ACTION normal RETURN "normal" ON ACTION dialog RETURN "dialog" ON ACTION close_window RETURN "close_window" END MENU RETURN "close_window" END FUNCTION
#! askreuben187.per LAYOUT GRID { Depth [f01 ] Style [f02 ] } END END ATTRIBUTES f01 = formonly.depth; f02 = formonly.style;