Windows

Overview

End users in large enterprises often have multi-monitor setups on which they arrange the necessary apps in the most convenient way for executing daily tasks. The io.Connect Desktop Layouts feature allows them to save and later restore the exact arrangement and context of their environment - windows, apps, Workspaces, and their bounds and context. Users can save multiple apps and Workspaces in different Layouts, each corresponding to a specific task or workflow. Restoring the saved Layout happens with a single click and saves time and effort for finding, launching and arranging the desired apps. It's also possible to choose a default Global Layout that io.Connect Desktop will load upon startup.

The Layouts library has the following capabilities:

  • importing, exporting, removing and getting Layouts;
  • saving and restoring Layouts;
  • hibernating and resuming Layouts (a quicker way to save and restore Layouts at the expense of system resources);
  • events related to adding, removing, changing or saving Layouts;

The io.Connect Desktop Layouts library supports different types of Layouts:

  • Global

This type of Layout can contain floating io.Connect Windows, io.Connect Window Groups, Workspaces. A Global Layout describes the bounds and context of all components participating in it.

  • App Default

The default Layout of an app instance describes the last saved window bounds, the window state (maximized, minimized, normal), whether the window is collapsed and the default window context.

  • Workspace

The Layout of a Workspace instance describes the arrangement of the Workspace elements, its bounds and the context of the apps participating in it.

Default Global Layout

A default Global Layout is an already saved arrangement of interop-enabled apps that is restored upon startup of io.Connect Desktop. Often users need the same set of starting apps when fulfilling daily routines. Setting up a default Global Layout will save them the time and effort they usually spend in finding, starting and arranging the required apps on system start or restart.

In the example below, you can see how the user first creates and then saves and restores a Layout. After that, the user sets the saved Layout as the default Global Layout which is restored upon restart of io.Connect Desktop:

Layouts

To disable automatic restore of the default Global Layout, use the "restoreDefaultGlobalOnStartup" property of the "layouts" top-level key in the system.json system configuration file of io.Connect Desktop:

{
    "layouts": {
        "restoreDefaultGlobalOnStartup": false
    }
}

The default Global Layout can be restored programmatically at a later stage if necessary, using the Layouts APIs:

const defaultLayout = await io.layouts.getDefaultGlobal();

if (defaultLayout) {
    await io.layouts.restore(defaultLayout);
};

Bypassing App Default Layouts

The App Default Layout contains information about:

  • the last saved window bounds - size and location;
  • the window state - maximized, minimized or normal and whether it's collapsed;
  • the default window context;

When an app is started for the first time by io.Connect Desktop, the size and the location of the app window are determined by the bounds set in the app definition file (or by the default bounds, if none are specified in the app definition). When the user moves or resizes the app window and closes it, the new bounds are automatically saved as an App Default Layout and the next time the app is started, its window will be loaded using these bounds.

Sometimes, it may be necessary to bypass the App Default Layout - e.g., if somehow the app window has been saved outside the visible monitor area, or you simply want your app to always start with certain bounds, state or context despite the user interactions.

To bypass the App Default Layout only once, press and hold the SHIFT key and click on the app in the io.Connect launcher to start it.

To instruct io.Connect Desktop to always ignore the App Default Layout for your app, use the "ignoreSavedLayout" top-level key in the app definition file:

{
    "ignoreSavedLayout": true
}

Layout Loader

The default loader for Global Layouts is an HTML file located in %LocalAppData%/interop.io/io.Connect Desktop/Desktop/assets/loader which you can replace with your own custom one or edit it directly.

To customize the Layout loader, use the "splash" property of the "layouts" top-level key in the system.json system configuration file of io.Connect Desktop.

The "splash" object has the following properties:

Property Type Description
"disabled" boolean If true, the Layout loader will be disabled.
"height" number Height in pixels for the Layout loader.
"title" string Title for the Layout loader.
"url" string URL pointing to the location of the Layout loader. Defaults to "file://%GDDIR%/assets/loader/index.html".
"width" number Width in pixels for the Layout loader.

The following example demonstrates how to provide a custom loader and settings for it:

{
    "layouts": {
        "splash": {
            "url": "https://example.com/my-custom-loader/index.html",
            "title": "My Custom Loader",
            "width": 500,
            "height": 300
        }
    }
}

Layout Stores

io.Connect Desktop can obtain Layouts from a local store, from a remote REST service, or from io.Manager.

In the standard io.Connect Desktop deployment model, Layouts aren't stored locally on the user machine, but are served remotely. If io.Connect Desktop is configured to use a remote Layout store, it will poll it periodically and discover new Layouts. The store implementation is usually connected to an entitlement system based on which different users can have different Layouts.

The settings for the Layout stores are defined in the system.json file of io.Connect Desktop located in %LocalAppData%/interop.io/io.Connect Desktop/Desktop/config, under the "layouts" top-level key, which accepts an object with a "store" property as a value.

The "store" object has the following properties:

Property Type Description
"rejectUnauthorized" boolean If true (default), SSL validation will be enabled for the REST server. Valid only in "rest" mode.
"restClientAuth" "no-auth" | "negotiate" | "kerberos" Authentication configuration. Defaults to "negotiate". Valid only in "rest" mode.
"restFetchInterval" number Interval in seconds at which to poll the REST service for updates. Default is 60. Valid only in "rest" mode.
"restURL" string URL pointing to the Layout store. Valid only in "rest" mode.
"type" "file" | "rest" | "server" Type of the Layout store. Set to "file" (default) to read Layouts from a local file. Set to "rest" to fetch Layouts from a REST service. Set to "server" to fetch Layouts from io.Manager.

Local

By default, the Layouts are saved to and loaded from a local Layout store located in the %LocalAppData%/interop.io/io.Connect Desktop/UserData/<ENV>-<REG>/layouts folder, where <ENV>-<REG> represents the environment and region of io.Connect Desktop (e.g., DEMO-INTEROP.IO). There you can store, customize and delete your Layout files locally.

To instruct io.Connect Desktop to manage Layouts as local files, set the "type" property of the "store" object to "file":

{
    "layouts" : {
        "store": {
            "type": "file"
        }
    }
}

REST

Layout definitions can also be obtained from remote Layout stores via a REST service.

For a reference implementation of a remote Layout definitions store, see the Node.js REST Config example. The user Layouts are stored in files with the same structure as local Layout files. This basic implementation doesn't take the user into account and returns the same set of data for all users. New Layouts are stored in files using the name of the Layout and there isn't validation for the name. The operation for removing a Layout isn't implemented and just logs to the console. For instructions on running the sample server on your machine, see the README file in the repository.

For a .NET implementation of a remote Layout definitions store, see the .NET REST Config example.

To configure a connection to the REST service providing the Layout store, set the "type" property of the "store" object to "rest":

{
    "layouts": {
        "store": {
            "type": "rest",
            "restURL": "http://localhost:8004/",
            "restFetchInterval": 20,
            "restClientAuth": "no-auth"
        }
    }
}

The remote store must return Layout definitions in the following response shape:

{
    "layouts": [
        // List of Layout definition objects.
        {}, {}
    ]
}

io.Manager

You can also use io.Manager for hosting and retrieving Layout stores. io.Manager is a complete server-side solution for providing data to io.Connect. To configure io.Connect Desktop to fetch Layouts from io.Manager, set the "type" property of the "store" to "server":

{
    "layouts" : {
        "store": {
            "type": "server"
        }
    }
}

⚠️ Note that when using io.Manager as a Layout store, Layout files aren't only fetched from the server, but are also saved on the server (e.g., when the user edits and saves an existing Layout).