Zowe Desktop and window management
Zowe Desktop and window management
The Zoweâ„¢ Desktop is a web component of Zowe, which is an implementation of MVDWindowManagement
, the interface that is used to create a window manager.
The code for this software is in the zlux-app-manager
repository.
The interface for building an alternative window manager is in the zlux-platform
repository.
Window Management acts upon Windows, which are visualizations of an instance of an application plug-in. Application plug-ins are plug-ins of the type "application", and therefore the Zowe Desktop operates around a collection of plug-ins.
Note: Other objects and frameworks that can be utilized by application plug-ins, but not related to window management, such as application-to-application communication, Logging, URI lookup, and Auth are not described here.
Loading and presenting application plug-ins​
Upon loading the Zowe Desktop, a GET call is made to /plugins?type=application
.
The GET call returns a JSON list of all application plug-ins that are on the server, which can be accessed by the user. Application plug-ins can be composed of dataservices, web content, or both. Application plug-ins that have web content are presented in the Zowe Desktop UI.
The Zowe Desktop has a taskbar at the bottom of the page, where it displays each application plug-in as an icon with a description. The icon that is used, and the description that is presented are based on the application plug-in's PluginDefinition
's webContent
attributes.
Plug-in management​
Application plug-ins can gain insight into the environment in which they were spawned through the Plugin Manager. Use the Plugin Manager to determine whether a plug-in is present before you act upon the existence of that plug-in. When the Zowe Desktop is running, you can access the Plugin Manager through ZoweZLUX.PluginManager
The following are the functions you can use on the Plugin Manager:
- getPlugin(pluginID: string)
- Accepts a string of a unique plug-in ID, and returns the Plugin Definition Object (DesktopPluginDefinition) that is associated with it, if found.
Application management​
Application plug-ins within a Window Manager are created and acted upon in part by an Application Manager. The Application Manager can facilitate communication between application plug-ins, but formal application-to-application communication should be performed by calls to the Dispatcher. The Application Manager is not normally directly accessible by application plug-ins, instead used by the Window Manager.
The following are functions of an Application Manager:
Function | Description |
---|---|
spawnApplication(plugin: DesktopPluginDefinition, launchMetadata: any): Promise<MVDHosting.InstanceId>; | Opens an application instance into the Window Manager, with or without context on what actions it should perform after creation. |
killApplication(plugin:ZLUX.Plugin, appId:MVDHosting.InstanceId): void; | Removes an application instance from the Window Manager. |
showApplicationWindow(plugin: DesktopPluginDefinitionImpl): void; | Makes an open application instance visible within the Window Manager. |
isApplicationRunning(plugin: DesktopPluginDefinitionImpl): boolean; | Determines if any instances of the application are open in the Window Manager. |
Windows and Viewports​
When a user clicks an application plug-in's icon on the taskbar, an instance of the application plug-in is started and presented within a Viewport, which is encapsulated in a Window within the Zowe Desktop. Every instance of an application plug-in's web content within Zowe is given context and can listen on events about the Viewport and Window it exists within, regardless of whether the Window Manager implementation utilizes these constructs visually. It is possible to create a Window Manager that only displays one application plug-in at a time, or to have a drawer-and-panel UI rather than a true windowed UI.
When the Window is created, the application plug-in's web content is encapsulated dependent upon its framework type. The following are valid framework types:
- "angular2": The web content is written in Angular, and packaged with Webpack. Application plug-in framework objects are given through @injectables and imports.
- "iframe": The web content can be written using any framework, but is included through an iframe tag. Application plug-ins within an iframe can access framework objects through parent.RocketMVD and callbacks.
- "react": The web content is written in React, Typescript, and packaged with Webpack. App framework objects are provided via the ReactMVDResources object
In the case of the Zowe Desktop, this framework-specific wrapping is handled by the Plugin Manager.
Viewport Manager​
Viewports encapsulate an instance of an application plug-in's web content, but otherwise do not add to the UI (they do not present Chrome as a Window does). Each instance of an application plug-in is associated with a viewport, and operations to act upon a particular application plug-in instance should be done by specifying a viewport for an application plug-in, to differentiate which instance is the target of an action. Actions performed against viewports should be performed through the Viewport Manager.
The following are functions of the Viewport Manager:
Function | Description |
---|---|
createViewport(providers: ResolvedReflectiveProvider[]): MVDHosting.ViewportId; | Creates a viewport into which an application plug-in's webcontent can be embedded. |
registerViewport(viewportId: MVDHosting.ViewportId, instanceId: MVDHosting.InstanceId): void; | Registers a previously created viewport to an application plug-in instance. |
destroyViewport(viewportId: MVDHosting.ViewportId): void; | Removes a viewport from the Window Manager. |
`getApplicationInstanceId(viewportId: MVDHosting.ViewportId): MVDHosting.InstanceId | null;` |
Injection Manager​
When you create Angular application plug-ins, they can use injectables to be informed of when an action occurs. iframe application plug-ins indirectly benefit from some of these hooks due to the wrapper acting upon them, but Angular application plug-ins have direct access.
The following topics describe injectables that application plug-ins can use.
Plug-in definition​
@Inject(Angular2InjectionTokens.PLUGIN_DEFINITION) private pluginDefinition: ZLUX.ContainerPluginDefinition
Provides the plug-in definition that is associated with this application plug-in. This injectable can be used to gain context about the application plug-in. It can also be used by the application plug-in with other application plug-in framework objects to perform a contextual action.
Logger​
@Inject(Angular2InjectionTokens.LOGGER) private logger: ZLUX.ComponentLogger
Provides a logger that is named after the application plug-in's plugin definition ID.
Launch Metadata​
@Inject(Angular2InjectionTokens.LAUNCH_METADATA) private launchMetadata: any
If present, this variable requests the application plug-in instance to initialize with some context, rather than the default view.
Viewport Events​
@Inject(Angular2InjectionTokens.VIEWPORT_EVENTS) private viewportEvents: Angular2PluginViewportEvents
Presents hooks that can be subscribed to for event listening. Events include:
resized: Subject<{width: number, height: number}>
Fires when the viewport's size has changed.
Window Events​
@Inject(Angular2InjectionTokens.WINDOW_ACTIONS) private windowActions: Angular2PluginWindowActions
Presents hooks that can be subscribed to for event listening. The events include:
Event | Description |
---|---|
maximized: Subject<void> | Fires when the Window is maximized. |
minimized: Subject<void> | Fires when the Window is minimized. |
restored: Subject<void> | Fires when the Window is restored from a minimized state. |
moved: Subject<{top: number, left: number}> | Fires when the Window is moved. |
resized: Subject<{width: number, height: number}> | Fires when the Window is resized. |
titleChanged: Subject<string> | Fires when the Window's title changes. |
Window Actions​
@Inject(Angular2InjectionTokens.WINDOW_ACTIONS) private windowActions: Angular2PluginWindowActions
An application plug-in can request actions to be performed on the Window through the following:
Item | Description |
---|---|
close(): void | Closes the Window of the application plug-in instance. |
maximize(): void | Maximizes the Window of the application plug-in instance. |
minimize(): void | Minimizes the Window of the application plug-in instance. |
restore(): void | Restores the Window of the application plug-in instance from a minimized state. |
setTitle(title: string):void | Sets the title of the Window. |
setPosition(pos: {top: number, left: number, width: number, height: number}): void | Sets the position of the Window on the page and the size of the window. |
spawnContextMenu(xPos: number, yPos: number, items: ContextMenuItem[]): void | Opens a context menu on the application plug-in instance, which uses the Context Menu framework. |
registerCloseHandler(handler: () => Promise<void>): void | Registers a handler, which is called when the Window and application plug-in instance are closed. |
Framework API examples​
The following are examples of how you would access the Window Actions API to begin an App in maximized mode upon start-up.
Angular
- Import
Angular2InjectionTokens
from'pluginlib/inject-resources'
- Within the constructor of your App, in the arguments, do
@Optional() @Inject(Angular2InjectionTokens.WINDOW_ACTIONS) private windowActions: Angular2PluginWindowActions
- Then inside the constructor, check that window actions exist and then execute the action
if (this.windowActions) {
this.windowActions.maximize();
} - Depending on your App layout, certain UI elements may not have loaded so to wait for them to load, one may want to use something like Angular's NgOnInit directive.
React
-
Similar to how we do things in Angular, except the Window Actions (& other Zowe resources) are located in the
resources
object. So if we were using a React.Component, we could have a constructor withconstructor(props){ super(props); ... }
-
Then accessing Window Actions would be as simple as
this.props.resources.windowActions
IFrames
- Iframes are similar to Angular & React, but require a different import step. Instead to use Window Actions (& other Zowe resources), we have to import the Iframe adapter. The Iframe adapter is located in
zlux-app-manager/bootstrap/web/iframe-adapter.js
so something like a relative path in my JS code will suffice,
<script type="text/javascript" src="../../../org.zowe.zlux.bootstrap/web/iframe-adapter.js"></script>
- Then to use Window Actions would be as simple as
await windowActions.minimize();
NOTE: The Iframe adapter is not yet feature-complete. If you are attempting to use an event supported by Angular or React, but not yet supported in Iframes, try to use the window.parent.ZoweZLUX
object instead.