Windows
Overview
The Window Management API is accessible via the io.windows
object.
See the JavaScript Window Management examples on GitHub.
Runtime Configuration
To configure global io.Connect Windows settings at runtime, use the configure()
method:
const config = {
hideGroupCaption: true,
showExtractButton: true
};
await io.windows.configure(config);
The configure()
method accepts a WindowsConfiguration
object as a required argument which has the following properties:
Property | Type | Description |
---|---|---|
hideGroupCaption |
boolean |
If true , will show the caption of io.Connect Window groups. |
showStickyButton |
boolean |
If true , will show the "Sticky" button. |
showExtractButton |
boolean |
If true , will show the "Extract" button. |
showFeedbackButton |
boolean |
If true , will show the "Feedback" button. |
sticky |
boolean |
If true , will allow io.Connect Windows to stick together and form groups. |
approachingDistance |
number |
Sets the distance in pixels at which the approaching edges of io.Connect Windows will be highlighted indicating that the windows will be snapped together. |
autoAlign |
boolean |
If true , the size of the io.Connect Window will be aligned automatically to the neighboring windows when adding it to another window or a window group. |
For more details on configuring io.Connect Windows, see the Developers > Configuration > io.Connect Windows section.
Opening Windows
To open a new io.Connect Window, use the open()
method:
const name = "io-connect-docs";
const url = "https://docs.interop.io";
// Specify location for the new window.
const options = {
top: 200,
left: 200
};
const ioConnectWindow = await io.windows.open(name, url, options);
The name
and url
arguments are required. The window name
must be unique. The third argument is an optional WindowCreateOptions
object which specifies various settings for the new io.Connect Window - bounds, styles, mode, button settings and more.
For more details, see the Window Settings section.
Handling the Browser window.open()
To control the behavior of the browser window.open()
method when opening child windows, use the "nativeWindowOpen"
configuration property, available both on a global level under the "windows"
top-level key in the system.json
system configuration file, and on app level under the "details"
top-level key in the app definition.
The following example demonstrates how to configure io.Connect Desktop to open windows created with window.open()
in the default browser:
{
"windows": {
"nativeWindowOpen": "browser"
}
}
The "nativeWindowOpen"
property accepts either a string or an object as a value.
The possible string values for the "nativeWindowOpen"
property are:
Value | Description |
---|---|
"browser" |
Windows created with window.open() will be opened in the default browser. |
"off" |
Opening windows with window.open() is disabled. |
"window" |
Default. Windows created with window.open() will be opened as io.Connect Windows. |
The "nativeWindowOpen"
object has the following properties:
Property | Type | Description |
---|---|---|
"mode" |
string |
Must be set to "window" . |
"outlivesOpener" |
boolean |
If true , will prevent child windows from being closed when their parent is closed. |
By default, child windows created with the window.open()
method from an io.Connect Window share the lifetime of their parent window. To prevent this behavior, set the "outlivesOpener"
property to true
:
{
"windows": {
"nativeWindowOpen": {
"mode": "window",
"outlivesOpener": true
}
}
}
When child windows are opened as io.Connect Windows on the same domain as the parent window, you can control them with the Window
Web API:
const newWindow = window.open("http://localhost:4242/clientlist/index.html");
newWindow.close();
Window Options
Available since io.Connect Desktop 9.1
When using the browser window.open()
method for opening child windows in io.Connect Windows (i.e., when "nativeWindowOpen"
is set to "window"
or to an object whose "mode"
property is set to "window"
), you can pass io.Connect Window options as a third argument:
const url = "https://example.com";
// io.Connect Window options as a comma-separated string with `name=value` pairs.
const options = "mode=frameless, hasSizeAreas=true, width=300, height=500";
window.open(url, undefined, options);
The following table lists the available options:
Option | Type | Description |
---|---|---|
hasSizeAreas |
boolean |
If false , the window won't have resizing areas and the user won't be able to resize it by dragging its borders. Defaults to true for the io.Connect HTML, flat and tab windows. Defaults to false for the io.Connect frameless windows. |
height |
number |
Height in pixels for the new window. |
hidden |
boolean |
If true , the window will start as a hidden window. |
left |
number |
Distance in pixels of the top left window corner from the left edge of the screen. |
maxHeight |
number |
Maximum height in pixels for the new window. Available since io.Connect Desktop 9.3. |
maxWidth |
number |
Maximum width in pixels for the new window. Available since io.Connect Desktop 9.3. |
minHeight |
number |
Minimum height in pixels for the new window. Available since io.Connect Desktop 9.3. |
minWidth |
number |
Minimum width in pixels for the new window. Available since io.Connect Desktop 9.3. |
mode |
"flat" | "tab" | "html" | "frameless" |
io.Connect Window mode. |
outlivesOpener |
boolean |
If true , will prevent child windows from being closed when their parent is closed. |
top |
number |
Distance in pixels of the top left window corner from the top edge of the screen. |
width |
number |
Width in pixels for the new window. |
Opening PDF Files
To open a PDF file in an io.Connect Window, use the open()
method. Pass the URL to the PDF file and optionally specify parameters in the URL for opening the PDF file:
// This will open the PDF file with the PDF toolbar turned off.
const PDF_URL = "https://url-to-pdf.com/file-name.pdf#toolbar=0";
await io.windows.open("PDF File", PDF_URL);
To specify parameters in the URL, use the following template:
<URL to PDF file>#<parameter>=<value>
To specify multiple parameters in the URL, use &
to separate them:
<URL to PDF file>#<parameter>=<value>&<parameter>=<value>&<parameter>=<value>
⚠️ Note that
#
,&
and=
are special characters which you must not use in parameter values because they can't be escaped.
The following example will display page 3 of the PDF file, hide the PDF toolbar, set the zoom factor to 150% and scroll the page vertically and horizontally by 100px (pixels are relative to the zoom factor):
const PDF_URL = "https://url-to-pdf.com/file-name.pdf#page=3&toolbar=0&zoom=150,100,100";
await io.windows.open("PDF File", PDF_URL);
The following table lists all supported URL parameters for opening PDF files:
Parameter | Description | Examples |
---|---|---|
page |
Specifies which page to display. Accepts an integer as a value. The first page of the document has a value of 1. | To open the PDF file to page 3, use page=3 . |
toolbar |
Whether to enable or disable the PDF toolbar. Accepts 0 or 1 as values. | To hide the PDF toolbar, use toolbar=0 . |
zoom |
Specifies the zoom factor and also the vertical and horizontal scroll position of the page in regard to the top left corner of the window. Accepts integer or floating point values. | To set the zoom factor to 150.5%, use zoom=150.5 . To set the zoom factor to 120% and scroll the page 200px vertically and 100px horizontally, use zoom=120,200,100 . |
view |
Specifies the view mode of the page using values defined in the PDF language specification. See the possible values in the next table. Use the page parameter before view . |
To fit the page in the window, use view=Fit . To fit the page vertically, use view=FitV . To fit the page horizontally and scroll it 200px vertically, use view=FitH,200 . |
The following table lists the possible values for the view
parameter:
Value | Description | Example |
---|---|---|
Fit |
Fits the entire page horizontally and vertically in the window. If the vertical and horizontal magnification factors are different, the smaller one will be used for fitting the page. In the other dimension the page will be centered. | view=Fit |
FitV |
Fits the page vertically in the window. | view=FitV |
FitH |
Fits the page horizontally in the window. | view=FitH |
FitV,<left> |
Fits the page vertically and scrolls it horizontally from the left edge of the window with the specified integer or floating point value. | view=FitV,200 |
FitH,<top> |
Fits the page horizontally and scrolls it vertically from the top edge of the window with the specified integer or floating point value. | view=FitH,200 |
Window Settings
Provide window settings per window by:
- using the app definition settings:
{
"type": "window",
"name": "io-connect-docs",
"details": {
"url": "https://docs.interop.io",
"height": 640,
"width": 560,
"left": 100,
"top": 100,
"mode": "flat",
"title": "io.Connect Documentation",
"backgroundColor": "#1a2b30",
"focus": false
}
}
- passing a
WindowCreateOptions
object to theopen()
method:
const name = "io-connect-docs";
const url = "https://docs.interop.io";
// Specify location for the new window.
const options = {
height: 640,
width: 560,
left: 100,
top: 100,
mode: "flat",
title: "io.Connect Documentation",
backgroundColor: "#1a2b30",
focus: false
};
const ioConnectWindow = await io.windows.open(name, url, options);
All available window settings that can be passed via configuration or at runtime are described in the app definition schema under the "windows"
key and in the WindowCreateOptions
object.
The following sections provide examples of using only some of the many available window settings.
Mode
Three window modes are supported for web apps - flat, tab and HTML. Specify the window mode in the WindowCreateOptions
object when opening a new io.Connect Window:
const name = "io.Connect Docs";
const url = "https://docs.interop.io";
// Specify window mode.
const options = {
mode: "tab"
};
const ioConnectWindow = await io.windows.open(name, url, options);
Relative Position
Position a new io.Connect Window relatively to an already existing io.Connect Window by providing the ID of the existing window and the relative direction:
const clientsWindow = io.windows.find("clientlist");
const name = "clientportfolio";
const url = "http://localhost:22080/clientportfolio/index.html";
// Provide the existing window ID and the relative direction.
const options = {
relativeTo: clientsWindow.id,
relativeDirection: "right"
};
await io.windows.open(name, url, options);
And the result:
Taskbar Icon
To specify an icon for the io.Connect Window, provide an image as a Base64 encoded string in the WindowCreateOptions
object:
const name = "io.Connect Docs";
const url = "https://docs.interop.io";
// Specify taskbar icon.
const options = {
base64ImageSource: "R0lGODlhPQBEAPeoAJosM//AwO/AwH..."
};
const ioConnectWindow = await io.windows.open(name, url, options);
To get the taskbar icon of the current window:
const myWindow = io.windows.my();
const icon = await myWindow.getIcon();
To change the taskbar icon of the current window:
const myWindow = io.windows.my();
// Image encoded as a Base64 string.
const newIcon = "R0lGODlhPQBEAPeoAJosM//AwO/AwH...";
await myWindow.setIcon(newIcon);
Downloads
To define the window behavior when downloading files, use the downloadSettings
property of the WindowCreateOptions
object. It accepts a DownloadSettings
object as a value:
const name = "Downloads";
const url = "https://example.com/downloads/test-file.zip";
// Specify window download behavior.
const options = {
downloadSettings: {
autoSave: true,
autoOpenDownload: true
}
};
const ioConnectWindow = await io.windows.open(name, url, options);
For details on downloading programmatically, see the Window Operations > Download section.
For details on configuring the window download behavior globally or per app, see the see the Developers > Configuration > System > Window Settings > Downloads and the Developers > Configuration > Application > Downloads sections.
Cascading Windows
io.Connect Windows that are instances of the same app can be opened in a cascade. Each new window is offset from the previously opened window by a specified distance:
To cascade windows programmatically, use the cascade
property of the WindowCreateOptions
object. It accepts an object as a value, which you can use to enable or disable cascading and specify offset for the cascaded windows:
const name = "io.Connect Docs";
const url = "https://docs.interop.io";
const options = {
cascade: { offset: 30 }
};
const ioConnectWindow = await io.windows.open(name, url, options);
The cascade
object has the following properties:
Property | Type | Description |
---|---|---|
enabled |
boolean |
If true (default), will enable cascading windows. |
offset |
number |
Offset in pixels for the cascaded window. |
⚠️ Note that cascading windows programmatically will override any cascade settings specified in the system configuration or the app definition.
Finding Windows
All functions for finding io.Connect Windows return an IOConnectWindow
object (or a collection of such objects).
Listing
To obtain a collection of all io.Connect Windows, use the list()
method:
const allIOConnectWindows = io.windows.list();
Current Window
To get a reference to the current window, use the my()
method:
const currentWindow = io.windows.my();
⚠️ Note that the
my()
method by design won't work (will returnundefined
) when used in special apps like the Workspaces App or the Web Group App, and also in Node.js apps.
By Name
To find a window by name, use the find()
method:
const name = "io-connect-docs";
const ioConnectWindow = io.windows.find(name);
By ID
To find a window by ID, use the findById()
method:
const ID = "2506_04";
const ioConnectWindow = io.windows.findById(ID);
Auto Arranging Windows
Available since io.Connect Desktop 9.1
io.Connect Windows can be auto arranged programmatically in a grid on the screen. Auto arrangement is enabled by default. To disable it for an app, set the "allowAutoArrange"
top-level property in the app definition to false
:
{
"allowAutoArrange": false
}
To auto arrange the io.Connect Windows located on a given display, or to restore their previous states, use the autoArrange()
method and optionally pass a display ID specifying the display whose windows to arrange:
const displayID = 26573;
await io.windows.autoArrange(displayID);
⚠️ Note that windows with special functionality like docked windows and Workspaces don't participate in auto arranging.
The following demonstrates auto arranging and restoring programmatically the windows on a given display:
All windows on the specified display will be auto arranged in a grid. If the method is invoked a second time and the user hasn't broken manually the arrangement, the windows will be restored to their previous states. If you don't specify a display ID, the windows on the display where the io.Connect shell app (Floating Toolbar or Launchpad) is located will be auto arranged.
Window Operations
The Window Management API enables you to control an IOConnectWindow
instance programmatically. Access or change various window settings using the provided properties and methods.
Stickiness
The io.Connect Window stickiness enables users to easily organize the windows on their desktop in visual groups. Window stickiness is enabled by default, but can be controlled programmatically and by enabling the "Sticky" button for end users.
To set the stickiness or the visibility of the "Sticky" button programmatically on a global level, use the configure()
method. Pass a WindowsConfiguration
object as a required argument:
// Required object with configuration settings.
const windowsConfig = {
// Turn off the stickiness and hide the "Sticky" button globally.
sticky: false,
showStickyButton: false
};
await io.windows.configure(windowsConfig);
To set the stickiness of an io.Connect Window instance, use the setSticky()
method and pass a Boolean value as an argument:
const myWindow = io.windows.my();
// Turn off the stickiness for the current window.
await myWindow.setSticky(false);
To check whether the window is sticky, use the isSticky
property of an IOConnectWindow
instance:
// Returns a Boolean value.
const isSticky = myWindow.isSticky;
For details on how to enable or disable the "Sticky" button globally or per app, see the Developers > Configuration > System > Window Settings > Sticky Button and the Developers > Configuration > Application > Sticky Button sections respectively.
Title
To get the title of an io.Connect Window, use the title
property or the getTitle()
method of an IOConnectWindow
instance:
const title = myWindow.title;
// or
const winTitle = await myWindow.getTitle();
To set the title of a window, use the setTitle()
method:
await myWindow.setTitle("New Title");
Bounds
The bounds of a window describe its position (top and left coordinates) and size (width and height) on the screen.
⚠️ Note that if your app logic includes both zooming a window and retrieving its size with the
window.innerHeight
orwindow.innerWidth
DOM properties, you have to consider the fact that the browser will report adjusted size values based on the zoom factor. In such cases, it's recommended to usewindow.outerHeight
andwindow.outerWidth
, or thebounds
property of anIOConnectWindow
instance.
To get the bounds of an io.Connect Window, use the bounds
property or the getBounds()
method of an IOConnectWindow
instance:
const bounds = myWindow.bounds;
// or
const winBounds = await myWindow.getBounds();
To move or resize an io.Connect Window, use the moveTo()
, resizeTo()
or moveResize()
methods.
To move a window:
// Top and left coordinates (in pixels) for the top-left window corner.
await myWindow.moveTo(200, 300);
To resize a window:
// Width and height (in pixels) for the window.
await myWindow.resizeTo(300, 400);
To move and/or resize a window:
// New bounds for the window. All properties are optional.
const bounds = {
top: 200,
left: 300,
width: 300,
height: 400
};
await myWindow.moveResize(bounds);
Channel
To get the name of the Channel to which the window is currently joined, use the getChannel()
method of an IOConnectWindow
instance:
const channelName = await myWindow.getChannel();
if (channelName) {
// Use the Channels API to manipulate the Channel context.
};
Once you have the name of the Channel to which the window is currently joined, you can use the Channels API to manipulate the Channel context.
Placement
The placement feature of the Window Management API provides a way for an io.Connect Window to occupy a specific position on the screen. This position can be set only once - initially, on window creation, or can be kept throughout the entire lifetime of the window. The placement feature solves the problem of reacting adequately to changes of the screen resolution or the size of the app virtualization window hosting the io.Connect Window, ensuring that the io.Connect Window always stays at the desired screen position and with the desired dimensions. This is especially useful if you are developing a toolbar or a notifications panel that shouldn't be resized by the users and must always stay at the same position on the screen.
Window placement can be controlled programmatically and through the app definition.
To get the current placement settings for a window, use the placementSettings
property of an IOConnectWindow
instance:
const placementSettings = myWindow.placementSettings;
To place a window at a specific position on the screen, use the place()
method of an IOConnectWindow
instance and pass a PlacementSettings
object as an argument.
The following example shows how to place the window at the top of the screen, stretched horizontally (horizontalAlignment
defaults to "stretch"
when verticalAlignment
is set, see the Placement Settings table below) and with height set to 40 pixels. The snapped
property is set to true
in order to instruct io.Connect Desktop that this io.Connect Window must always occupy that position, even when the screen resolution changes or the app virtualization window hosting it is resized:
const settings = {
snapped: true,
verticalAlignment: "top",
height: 40
};
await myWindow.place(settings);
⚠️ Note that the settings specified in the
place()
method won't be merged with the existing placement settings (if any), but will entirely overwrite them.
The PlacementSettings
object has the following properties:
Property | Type | Description |
---|---|---|
snapped |
boolean |
Required. If true , the io.Connect Window will remain snapped to the specified screen position even in cases of resolution changes, window visibility changes or when the app virtualization window hosting the io.Connect Window has been resized. However, this doesn't include any API calls or manual user interaction which affect the window placement or bounds. If false , the window will be positioned at the specified screen location only once when created. |
verticalAlignment |
"top" | "bottom" | "center" | "stretch" |
Defines a vertical alignment configuration. If horizontalAlignment is set, then verticalAlignment will default to "stretch" . |
horizontalAlignment |
"left" | "right" | "center" | "stretch" |
Defines a horizontal alignment configuration. If verticalAlignment is set, then horizontalAlignment will default to "stretch" . |
width |
number | string |
Defines the window width. Use a number to define the value in pixels, or use a string to define the value in pixels or in percentage of the screen - e.g., "10px" or "10%" . |
height |
number | string |
Defines the window height. Use a number to define the value in pixels, or use a string to define the value in pixels or in percentage of the screen - e.g., "10px" or "10%" . |
display |
Display | "current" |
Defines the current display. |
top |
number | string |
Top margin for the placed window. Use a number to define the value in pixels, or use a string to define the value in pixels or in percentage of the screen - e.g., "10px" or "10%" . |
left |
number | string |
Left margin for the placed window. Use a number to define the value in pixels, or use a string to define the value in pixels or in percentage of the screen - e.g., "10px" or "10%" . |
right |
number | string |
Right margin for the placed window. Use a number to define the value in pixels, or use a string to define the value in pixels or in percentage of the screen - e.g., "10px" or "10%" . |
bottom |
number | string |
Bottom margin for the placed window. Use a number to define the value in pixels, or use a string to define the value in pixels or in percentage of the screen - e.g., "10px" or "10%" . |
For details on how to specify placement settings through the app definition, see the Developers > Configuration > Application > Placement section.
Docking
Available since io.Connect Desktop 9.1
io.Connect Windows can be docked to a specified edge on the screen. Docking is supported only for HTML and frameless windows and is disabled by default.
⚠️ Note that if you want to dock your window, it's strongly recommended to define it as a frameless window instead of an HTML one. The implementation for supporting frameless windows is much more lightweight and is less likely to cause issues with special window functionalities like docking.
⚠️ Note that by design docked windows don't participate in Global Layouts.
To enable docking and specify docking placement settings, use the "docking"
property of the "details"
top-level key in the app definition:
{
"details": {
"docking": {
"enabled": true
}
}
}
For more details on how to specify docking settings through the app definition, see the Developers > Configuration > Application > Docking section.
To dock an io.Connect Window, use the dock()
method and pass a DockingOptions
object as a required argument:
const options = {
position: "top",
claimScreenArea: true
};
const dockingPlacement = await myWindow.dock();
The DockingOptions
object has the following properties:
Property | Type | Description |
---|---|---|
claimScreenArea |
boolean |
If true , the docked window will claim the area it occupies on the screen, in effect, reducing the working area of the screen. |
position |
"top" | "bottom" | "left" | "right" |
Required. Position of the docked window on the screen - top, bottom, left or right. |
The dock()
method resolves with a DockingPlacement
object with the following properties:
Property | Type | Description |
---|---|---|
claimScreenArea |
boolean |
If true , the docked window claims the area it occupies on the screen, in effect, reducing the working area of the screen. |
docked |
boolean |
Required. If true , the window is docked. |
position |
"top" | "bottom" | "left" | "right" |
Required. Position of the docked window on the screen - top, bottom, left or right. |
To get the current docking placement of the window, use the getDockingPlacement()
method:
const dockingPlacement = await myWindow.getDockingPlacement();
Clone
Available since io.Connect Desktop 9.2
⚠️ Note that this feature is available only for web groups.
Cloning allows you to duplicate io.Connect Windows with their current state. Windows can be cloned programmatically or by enabling the "Clone" button for end users. If the cloned window is a tab window, it will be added to the same tab group. All other types of windows will be cascaded:
To clone a window, use the clone()
method of an IOConnectWindow
instance and optionally pass an ApplicationStartOptions
object as an argument:
// Optional settings for the cloned window.
const options = { mode: "flat" };
await myWindow.clone(options);
For details on how to enable or disable the "Clone" button globally or per app, see the Developers > Configuration > System > Window Settings > Clone Button and the Developers > Configuration > Application > Clone Button sections respectively.
Visibility
To check whether an io.Connect Window is visible, use the isVisible()
property of an IOConnectWindow
instance:
const isWindowVisible = myWindow.isVisible;
To change the window visibility, use the show()
, hide()
or setVisible()
methods of an IOConnectWindow
instance.
To hide a window:
await myWindow.hide();
To make a window visible:
await myWindow.show();
To change the window visibility:
// Hide the window.
await myWindow.setVisible(false);
// Show the window.
await myWindow.setVisible(true);
State
To get the io.Connect Window state (normal, maximized or minimized), use the state
property of an IOConnectWindow
instance:
const windowState = myWindow.state;
switch (windowState) {
case "normal":
// ...
break;
case "maximized":
// ...
break;
case "minimized":
// ...
break;
};
Use the maximize()
, minimize()
and restore()
methods to change the window state.
To maximize a window:
await myWindow.maximize();
To minimize a window:
await myWindow.minimize();
To restore a minimized or maximized window:
await myWindow.restore();
To check whether the window is in a collapsed state, use the isCollapsed
property:
const isWindowCollapsed = myWindow.isCollapsed;
Use the collapse()
and expand()
methods to collapse and expand a window:
// Collapse a window.
await myWindow.collapse();
// Expand a window.
await myWindow.expand();
Close
To close an io.Connect Window, use the close()
method of an IOConnectWindow
instance:
await myWindow.close();
The close()
method accepts a CloseOptions
object as an argument in which you can specify whether to allow the window to prevent closing and whether to show a confirmation dialog to the user:
const options = {
// Both options are set to `false` by default.
allowPrevent: true,
showDialog: true
};
await myWindow.close(options);
⚠️ Note that the
close()
method will override all window prevent close settings - e.g., if theclose()
method is invoked without any options in order to close a window that itself prevents closing with theonClosing()
event handler, that window will be closed immediately and a confirmation dialog won't be shown to the user.
Focus
To check whether an io.Connect Window is on focus, use the isFocused
property of an IOConnectWindow
instance:
const isWindowFocused = myWindow.isFocused;
To bring a window on focus, use the focus()
method:
await myWindow.focus();
Zoom
To get the zoom factor of an io.Connect Window, use the zoomFactor
property of an IOConnectWindow
instance:
const windowZoomFactor = myWindow.zoomFactor;
Use the zoomIn()
, zoomOut()
and setZoomFactor()
methods to change the window zoom factor.
To increment or decrement the zoom factor by one step, as defined in the system configuration:
// Zoom in by one step.
await myWindow.zoomIn();
// Zoom out by one step.
await myWindow.zoomOut();
To set the zoom factor:
// The specified zoom factor must be a valid factor value
// defined in the system configuration.
await myWindow.setZoomFactor(125);
⚠️ Note that if your app logic includes both zooming a window and retrieving its size with the
window.innerHeight
orwindow.innerWidth
DOM properties, you have to consider the fact that the browser will report adjusted size values based on the zoom factor. In such cases, it's recommended to usewindow.outerHeight
andwindow.outerWidth
, or thebounds
property of anIOConnectWindow
instance.
Z-Order
To set a window on top of the z-order, use the setOnTop()
method of an IOConnectWindow
instance:
await myWindow.setOnTop(true);
⚠️ Note that using a Boolean value as an argument allows the io.Connect Window to be on top only until the window is visible and not joined to an io.Connect Window group. If the window is hidden programmatically or the user snaps it to another io.Connect Window or window group, it will no longer be on top of the z-order when it becomes visible or when the user tears it off from the group.
Passing "always"
as an argument to the setOnTop()
method will instruct the window to remain permanently on top of the z-order, regardless of changes to its visibility or whether it joins or leaves an io.Connect Window group. If you join a window that is set to always be on top to a window or a group of windows which aren't, it will temporarily lose its always on top setting. When the window is extracted from the group, it will again be always on top:
await myWindow.setOnTop("always");
Snap
To snap an io.Connect Window programmatically to another io.Connect Window or window group, use the snap()
method of an IOConnectWindow
instance. Provide the ID or the IOConnectWindow
instance of the target window to which to snap the current window, and optionally provide a RelativeDirection
:
const targetID = "17508_3";
const direction = "bottom";
await myWindow.snap(targetID, direction);
⚠️ Note that the size of the snapped window (width and/or height) will be aligned automatically to the size of the window or the window group to which it was snapped.
To preserve the original size of the snapped io.Connect Window, pass a SnappingOptions
object as an argument instead. Use the autoAlign
property to specify the desired behavior:
const targetID = "17508_3";
const options = {
direction: "bottom",
// The original size of the window will be preserved.
autoAlign: false
};
await myWindow.snap(targetID, options);
To print a web page opened in an io.Connect Window, use the print()
method. It accepts a PrintOptions
object as an optional argument:
const printOptions = {
silent: true,
landscape: true,
copies: 2,
pageSize: "A4"
};
await myWindow.print(printOptions);
To print a web page as a PDF file, use the printToPDF()
method. It accepts a PrintToPDFOptions
object as an optional argument:
const printOptions = {
silent: true,
autoSave: true,
copies: 2,
pageRanges: [{ from: 0, to: 10 }, { from: 12, to: 15 }],
pageSize: "A4"
};
await myWindow.printToPDF(printOptions);
For details on how to specify global or per app settings for printing, see the Developers > Configuration > System > Window Settings > Printing and the Developers > Configuration > Application > Printing sections.
Download
To download a file, use the download()
method. Pass a URL to the file to download and an optional DownloadOptions
object:
const url = "https://example.com/logo.png";
// Optional download settings.
const options = {
autoOpenDownload: true,
// The file extension is taken from the downloaded file.
name: "my-logo"
};
const { path, size, url } = await myWindow.download(url, options);
console.log(`Download path: ${path}, File size: ${size}, URL: ${url}`);
The method returns a DownloadResult
object containing the path to the downloaded file, the file size and the download URL.
For details on how to configure the window download behavior at runtime, see the Window Settings section.
For details on configuring the window download behavior globally or per app, see the see the Developers > Configuration > System > Window Settings > Downloads and the Developers > Configuration > Application > Downloads sections.
Native File Drag & Drop
The startDrag
method of the IOConnectWindow
object allows you to save files from a web page to the OS when the user starts dragging a web page element. This is based on the Electron Native File Drag & Drop functionality. You can use this method as a handler for the "dragstart"
event when the user starts to drag a web page element.
The startDrag
method accepts a StartDragOptions
object specifying options for the file to save:
const myDraggableElement = document.getElementById("draggable");
const myDragHandler = (event) => {
event.preventDefault();
// Options for the file to save.
const dragOptions = {
type: "file",
data: "file-data-as-a-string",
filename: "my-file.txt"
};
// Save the file to the OS when the users starts dragging the element.
await myWindow.startDrag(dragOptions);
};
myDraggableElement.addEventListener(myDragHandler);
Show Dialogs
The showDialog()
method of the IOConnectWindow
object allows you to show dialogs at runtime. It accepts a DialogOptions
object as an argument in which you can specify dialog options - select a predefined io.Connect dialog type and fine-tune it, or create a completely customized one. The only required options are type
and message
for the dialog to show.
Predefined Dialogs
The following dialog types are available:
Dialog Type | Description |
---|---|
"YesNo" |
Contains "Yes" and "No" buttons. |
"YesNoCancel" |
Contains "Yes", "No" and "Cancel" buttons. |
"OkCancel" |
Contains "OK" and "Cancel" buttons. |
"Ok" |
Contains an "OK" button. |
"SingleInputDialog" |
Contains an input field, "Save" and "Don't Save" buttons. |
The following example demonstrates using a predefined io.Connect dialog:
const myDialog = {
type: "SingleInputDialog",
title: "Email Required",
message: "Please, provide your email address:",
inputPlaceholder: "john.doe@example.com",
inputPattern: "[a-z0-9]@my-org.com",
inputPatternErrorMessage: "Invalid email address!"
};
await myWindow.showDialog(myDialog);
Custom Dialogs
The following example demonstrates creating a custom dialog using the options provided in the DialogOptions
object:
const myDialog = {
type: "MyCustomDialog",
title: "Custom Title",
message: "Custom Message",
showTimer: true,
timerDuration: 5,
size: { height: 158 },
showAffirmativeButton: true,
affirmativeButtonName: "Confirm"
};
await myWindow.showDialog(myDialog);
Dialog Mode
The DialogOptions
object has an optional mode
property which determines the blocking behavior of the dialog. The mode
property is of type DialogMode
which is an enumeration with two possible values:
Value | Description |
---|---|
"WindowContainer" |
Only the container (a Workspaces Frame, or an io.Connect Window group) of the window that is showing the dialog will be blocked for user interaction. All windows within a blocked container are blocked too. |
"Global" |
All visible containers (including frameless io.Connect Windows) will be blocked for user interaction. |
const myDialog = {
type: "MyCustomDialog",
title: "Custom Title",
message: "Custom Message",
// Will block all visible window containers for user interaction.
mode: "Global"
};
await myWindow.showDialog(myDialog);
Functionality
To provide functionality to the dialog buttons or react when the user closes the dialog, use the DialogResult
object returned from showing the dialog. The result is returned when the user clicks on a dialog button or closes the dialog.
The following example demonstrates showing a predefined io.Connect dialog with "OK" and "Cancel" buttons and responding to the user interaction:
const myDialog = {
type: "OkCancel",
title: "My Dialog Title",
message: "My dialog message."
};
const handleDialogResult = (action, button) => {
if (action === "closed") {
// React to user closing the dialog.
console.log("Dialog closed.");
return;
} else {
if (button === "affirmative") {
// React to user clicking the "OK" button.
console.log("OK button clicked.");
} else {
// React to user clicking the "Cancel" button.
console.log("Cancel button clicked.");
};
};
};
const { action, button } = await myWindow.showDialog(myDialog);
handleDialogResult(action, button);
Tab Flash
To make the tab of a window in a tab group flash, use the flashTab()
method of an IOConnectWindow
instance. Pass a Boolean value to make the tab start or stop flashing:
// Start flashing the window tab.
await myWindow.flashTab(true);
The tab will stop flashing automatically when the user clicks on it to focus the tab window. Making a window tab flash may be useful if you want to prompt the user to take action in a window that is currently behind other tabbed windows.
Pinning & Unpinning Tabs
Available since io.Connect Desktop 9.5
⚠️ Note that this feature is available only for tab windows in web groups.
The tabs of io.Connect Windows in web groups can be pinned. Pinned tabs are placed before the regular tab windows and they contain only the window title. Pinned tab windows don't have a "Close" button, effectively preventing the user from closing them:
To check whether a tab window is pinned, use the isPinned
property of an IOConnectWindow
instance:
const isPinned = myWindow.isPinned;
console.log(`The tab window is ${isPinned ? "pinned": "not pinned."}.`);
To pin and unpin tab windows, use the pin()
and unpin()
methods:
// Pins the tab of the current window.
await myWindow.pin();
// Unpins the tab of the current window, reverting it to a normal tab with a "Close" button.
await myWindow.unpin();
For details on how to pin tab windows via app definition, see the Developers > Configuration > Application > Pinning Tab Windows section.
Workspace Drop
Available since io.Connect Desktop 9.5
To check whether the current window can be dropped in a Workspace, use the allowWorkspaceDrop
property of an IOConnectWindow
instance:
const canBeDropped = myWindow.allowWorkspaceDrop;
To specify whether an io.Connect Window can be dropped in a Workspace, use the setAllowWorkspaceDrop()
method. It accepts a Boolean value as an argument determining whether the user will be able to drop the current window in a Workspace:
// Preventing the user from dropping the window in a Workspace.
await myWindow.setAllowWorkspaceDrop(false);
Execute Code
Available since io.Connect Desktop 9.5
Executing JavaScript code within the context of the current or another io.Connect Window is disabled by default. To enable it, set the "allowScriptExecution"
top-level key in the app definition to true
:
{
"allowScriptExecution": true
}
To execute code in the context of an io.Connect Window, use the executeCode()
method of an IOConnectWindow
instance. It accepts as a required argument the code to execute provided as a string. The method resolves with the result returned from the executed code, or rejects if the result of the code is a rejected Promise
:
// Find the io.Connect Window in which you want to execute the code.
const ID = "2506_04";
const ioConnectWindow = io.windows.findById(ID);
// Provide the code to execute as a string.
const myCode = "(() => { return 42; })()";
const result = await ioConnectWindow.executeCode(myCode);
console.log(result);
Context
Each io.Connect Window has a dedicated context. The window context is a JavaScript object which may contain any information regarding the window instance in the form of key/value pairs.
Contexts can be set/passed initially on window creation and updated at runtime. Context changes can be tracked by subscribing to an event which fires when the window context has been updated (see Window Events).
⚠️ Note that saving large volumes of custom data as window context (e.g., thousands of lines of table data) can lead to significant delays. A user usually has several (in some cases - many) running apps and/or Workspaces (which can also contain many apps) and if one or more of the apps saves large amounts of context data, this will significantly slow down the saving process (e.g., on shutdown or when saving a Layout). Saving custom context works best with smaller amounts of data. If your app needs to save large amounts of data, you have to think about how to design this process better - for instance, you may store IDs, indices, etc., as context data, save the actual data to a database and when you restore the app, fetch the data using the data IDs saved as window context.
Get
To get the context of an io.Connect Window, use the getContext()
method of an IOConnectWindow
instance:
const winContext = await myWindow.getContext();
Update
To update the context of an io.Connect Window, use the updateContext()
method of an IOConnectWindow
instance:
const newContext = { io: 4242 };
await myWindow.udpateContext(newContext);
This method will update the current context object with the provided properties and values, adding any new properties and updating the values of existing ones.
Set
To open an io.Connect Window with initially set context, use the context
property of the WindowCreateOptions
object:
const name = "io.Connect Docs";
const url = "https://docs.interop.io";
// Specify window context.
const options = {
context: { io: 42 }
};
const ioConnectWindow = await io.windows.open(name, url, options);
To replace the current window context, use the setContext()
method of an IOConnectWindow
instance:
const newContext = { io: 42 };
const winContext = await myWindow.setContext(newContext);
This method will completely overwrite the existing context object, replacing its current value with the specified one.
Events
Methods for tracking io.Connect Window events are available at top-level of the Window Management API and on the IOConnectWindow
instance. Below are described some of the available window events with examples of how to handle them.
Most of the window event methods return an unsubscribe function which you can use to stop tracking the respective event.
Window Added or Removed
To get notified when io.Connect Windows are opened and closed, use the onWindowAdded()
and onWindowRemoved()
methods of the Window Management API and pass handlers for the respective events:
const handlers = {
onAdded: (ioConnectWindow) => {
console.log(`Window added: ${ioConnectWindow.name}`);
},
onRemoved: (ioConnectWindow) => {
console.log(`Window removed: ${ioConnectWindow.name}`);
}
};
io.windows.onWindowAdded(handlers.onAdded);
io.windows.onWindowRemoved(handlers.onRemoved);
Arrangement Change
Available since io.Connect Desktop 9.1
To get notified when the arrangement of io.Connect Windows changes, use the onArrangementChanged()
method:
const handler = ({ areWindowsArranged, displayId }) => {
console.log(`The windows on display ${displayId} are ${areWindowsArranged ? "arranged" : "restored (or arrangement was broken by user)"}.`)
};
io.windows.onArrangementChanged(handler);
⚠️ Note that the
onArrangementChanged()
method notifies about changes in the arrangement state of io.Connect Windows arranged or restored to their previous states on a given display by using theautoArrange()
method. TheareWindowsArranged
flag will betrue
when the windows are arranged initially. If the event is fired because the windows have been restored to their previous states, or because the user has broken manually the window arrangement, thenareWindowsArranged
will befalse
.
Bounds Change
To get notified when the bounds of io.Connect Window change, use the onBoundsChanged()
method of an IOConnectWindow
instance and pass an event handler:
const handler = (ioConnectWindow) => {
console.log(`Window bounds: ${JSON.stringify(ioConnectWindow.bounds)}`);
};
myWindow.onBoundsChanged(handler);
Use this event to get notifications every time the position or the size of the window changes.
Placement Change
To get notified when the placement settings of an io.Connect Window change, use the onPlacementSettingsChanged()
method of an IOConnectWindow
instance and pass an event handler:
const handler = (ioConnectWindow) => {
console.log(`Window placement settings: ${JSON.stringify(ioConnectWindow.placementSettings)}`);
};
myWindow.onPlacementSettingsChanged(handler);
⚠️ Note that the
onPlacementSettingsChanged()
method notifies about runtime updates of the window placement settings, not the window bounds. To track changes of the window bounds (e.g., when the user resizes or moves the window, or when the window is moved or resized programmatically) use theonBoundsChanged()
method.
Docking Change
Available since io.Connect Desktop 9.1
To get notified when the docking placement of an io.Connect Window changes, use the onDockingChanged()
method of an IOConnectWindow
instance and pass an event handler:
const handler = (ioConnectWindow, dockingPlacement) => {
const isDocked = dockingPlacement.docked;
console.log(isDocked ? `Window was docked at the ${dockingPlacement.position} of the screen.` : "Window was undocked.")
};
myWindow.onDockingChanged(handler);
Context Update
To get notified when the context of an io.Connect Window is updated, use the onContextUpdated()
method of an IOConnectWindow
instance and pass an event handler:
const handler = (context, ioConnectWindow) => {
console.log(`The context of "${ioConnectWindow.name}" has been updated: ${JSON.stringify(context)}`);
};
myWindow.onContextUpdated(handler);
Close & Refresh
To get notified when an io.Connect Window is about to be refreshed or closed, use its onClosing()
and onRefreshing()
methods.
The close and refresh handlers can be enabled or disabled globally through the system configuration of io.Connect Desktop or individually for each window in its respective app definition file. You can also specify a timeout in milliseconds for their execution.
Handlers Configuration
To configure the close and refresh handlers globally for all windows, go to the system.json
file located in %LocalAppData%/interop.io/io.Connect Desktop/Desktop/config
and edit the "refreshHandlers"
and "closeHandlers"
properties under the "windows"
top-level key:
{
"windows": {
"refreshHandlers": {
"enabled": true,
"timeout": 2000
},
"closeHandlers": {
"enabled": true,
"timeout": 2000
}
}
}
To configure close and refresh handlers only for specific windows, modify the "details"
property in each respective app definition file:
{
"details": {
"refreshHandlers": {
"enabled": false,
"timeout": 2000
},
"closeHandlers": {
"enabled": true,
"timeout": 2000
}
}
}
Window Close Handler
The onClosing()
method allows you to execute code before the window is closed. The event handler can be asynchronous and will be awaited up to the configured timeout:
const handler = async () => {
await asyncOperation();
};
myWindow.onClosing(handler);
Preventing Window Close
The handler passed to the onClosing()
method accepts as an argument a prevent()
function that can be used to prevent closing the window. The prevent()
function accepts as an argument a PreventClosingOptions
object in which you can specify whether to show a confirmation dialog to the user:
const handler = async (prevent) => {
const options = { showDialog: false };
prevent(options);
};
myWindow.onClosing(handler);
Window Refresh Handler
The onRefreshing()
method allows you to execute code before the window is refreshed. The event handler can be asynchronous and will be awaited up to the configured timeout:
const handler = async () => {
await asyncOperation();
};
myWindow.onRefreshing(handler);
Preventing Page Refresh
To prevent page refresh, use the prevent()
function that is passed as an argument to the onRefreshing()
handler:
const handler = (prevent) => {
const inputField = document.getElementById("input-field");
const shouldNotRefresh = inputField.value !== "" ? true : false;
if (shouldNotRefresh) {
prevent();
};
};
myWindow.onRefreshing(handler);
Navigating
To get notified when an io.Connect Window is about to navigate to a new address, use its onNavigating()
method. Pass a handler for the event which will receive as an argument an object containing the new address in its newUrl
property:
const handler = (info) => {
console.log(`Navigating to: ${info.newUrl}`);
};
myWindow.onNavigating(handler);
Window Groups
io.Connect Windows can be snapped together. One or more windows stuck together form a Group
.
The Window Management API offers methods for managing io.Connect Window groups. The Groups API is accessible via the io.windows.groups
object.
Finding Groups
Listing
To get a collection of all window groups, use the list()
method:
const allGroups = io.windows.groups.list();
Current Group
To get the group of the current window, use the group
property of an IOConnectWindow
instance or the my
property of the Groups API:
const myGroup = myWindow.group;
// or
const group = io.windows.groups.my;
By Window
To find an io.Connect Window group by a window ID or an IOConnectWindow
object, use the findGroupByWindow()
method:
const ioConnectWindow = io.windows.find("clientlist");
const windowID = ioConnectWindow.id;
const group = io.windows.groups.findGroupByWindow(windowID);
// or
const winGroup = io.windows.groups.findGroupByWindow(ioConnectWindow);
Creating Groups
Available since io.Connect Desktop 9.3
To create window groups, use the create()
method and pass a CreateGroupsOptions
object as a required argument. The following example demonstrates creating a minimized group consisting of two windows with specified bounds, one of which is tabbed and contains two apps, and the other is flat. Two of the loaded apps will be joined to a Channel and a context object will be attached to the created group:
const options = {
// List of window groups that will be created.
groups: [
{
title: "My Group",
state: "minimized",
// List of io.Connect Windows that will participate in the group.
frames: [
{
mode: "tab",
bounds: { top: 0, left: 0, width: 500, height: 700 },
// Apps to be loaded in the io.Connect Windows. It's only required to provide the app name,
// but you can also specify additional window settings.
applications: [ { name: "my-app", channelSelector: { enabled: true, channelId: "Red" } }, { name: "my-other-app"} ]
},
{
mode: "flat",
bounds: { top: 0, left: 500, width: 400, height: 700 },
applications: [ { name: "my-third-app", channelSelector: { enabled: true, channelId: "Red" } } ]
}
]
}
],
// Context that will be attached to all created groups.
context: { io: 42 }
};
const groups = await io.windows.groups.create(options);
Closing Groups
Available since io.Connect Desktop 9.3
To close a window group, use the close()
method and pass as a required argument either the Group
object, or the ID of the group to be closed:
// Closing a group by ID.
await io.windows.groups.close(myGroup.id);
The close()
method accepts a CloseOptions
object as a second argument in which you can specify whether to allow the window group to prevent closing and whether to show a confirmation dialog to the user:
const options = {
// Both options are set to `false` by default.
allowPrevent: true,
showDialog: true
};
await io.windows.groups.close(myGroup.id, options);
Group Operations
Title
To get the title of an io.Connect Window group, use the getTitle()
method of a Group
instance:
const groupTitle = await myGroup.getTitle();
To set the title of a window group, use the setTitle()
method of a Group
instance:
await myGroup.setTitle("New Title");
State
To maximize an io.Connect Window group, use the maximize()
method of a Group
instance:
myGroup.maximize();
To restore a window group, use the restore()
method of a Group
instance:
myGroup.restore();
Group Header
To check whether the header of an io.Connect Window group is visible, use the isHeaderVisible
property of a Group
instance:
const isGroupHeaderVisible = myGroup.isHeaderVisible;
To hide the header of a window group, use the hideHeader()
method of a Group
instance:
await myGroup.hideHeader();
To hide the header of a window group, use the showHeader()
method of a Group
instance:
await myGroup.showHeader();
For details on configuring group header visibility, see the Developers > Configuration > System > Window Settings > Group Header section, the Developers > Configuration > Application > Group Header section, and the Developers > Configuration > io.Connect Windows > io.Connect Window Properties > Group Header section.
Visibility
To check the visibility of a group, use the isVisible
property of a Group
instance:
const isVisible = myGroup.isVisible;
To hide a window group, use the hide()
method of a Group
instance:
await myGroup.hide();
To show a previously hidden window group, use the show()
method of a Group
instance. You can also pass an optional Boolean flag indicating whether to activate the group and focus the last focused window in it:
await myGroup.show(true);
Hibernation
io.Connect Window groups can be hibernated and resumed to save system resources. By default, the app windows participating in the group will be closed and the entire Group
object will be destroyed when a window group is hibernated. When the group is resumed, it will have a new ID and a new Group
object will be created. This is due to the fact that the io.Connect Window groups by design are temporary, and unlike Layouts and Workspaces, aren't meant to be persisted. To be able to preserve and use the original Group
object when hibernating and resuming window groups, you must set the "closeOnHibernate"
property of the "applications"
top-level key to false
in the system.json
system configuration file of io.Connect Desktop. Otherwise, each time a group is resumed, it will have a new ID:
{
"applications": {
"closeOnHibernate": false
}
}
To check whether a group is hibernated, use the isHibernated
property of a Group
object:
const isHibernated = myGroup.isHibernated;
To hibernate a window group, use the hibernate()
method on top level of the Groups API and pass the group ID as an argument:
await io.windows.groups.hibernate(myGroup.id);
To resume a window group, use theresume()
method on top level of the Groups API and pass the group ID as an argument. You can also pass an optional Boolean flag as a second argument indicating whether to activate the group and focus the last focused window in it:
await io.windows.groups.resume(myGroup.id, true);
Finding Windows in Groups
To get a collection of all io.Connect Windows participating in an io.Connect Window group, use the windows
property of a Group
instance:
const allGroupWindows = myGroup.windows;
To find a window in an io.Connect Window group by window ID, use the find()
method of a Group
instance:
const windowID = "25406_2";
const ioConnectWindow = myGroup.find(windowID);
Ungrouping Windows
To extract a window from an io.Connect Window group, use the ungroup()
method of an IOConnectWindow
instance and pass an optional UngroupOptions
object as an argument:
const options = {
bounds: {
width: 400,
height: 300
},
focus: true
};
const ioConnectWindow = await myWindow.ungroup(options);
If you don't specify any options for ungroup()
, the window will be moved up and to the right by default after being ungrouped:
Using the ungroup()
method on a tab window will extract the entire tab group:
Close
Available since io.Connect Desktop 9.3
To close a window group, use the close()
method of a Group
instance:
await myGroup.close();
The close()
method accepts a CloseOptions
object as an argument in which you can specify whether to allow the window group to prevent closing and whether to show a confirmation dialog to the user:
const options = {
// Both options are set to `false` by default.
allowPrevent: true,
showDialog: true
};
await myGroup.close(options);
Window Neighbors
To get the neighbors of a window in an io.Connect Window group, use the topNeighbours
, leftNeighbours
, rightNeighbours
and bottomNeighbours
properties of an IOConnectWindow
instance:
const topNeighbours = myWindow.topNeighbours;
const leftNeighbours = myWindow.leftNeighbours;
const rightNeighbours = myWindow.rightNeighbours;
const bottomNeighbours = myWindow.bottomNeighbours;
An empty collection will be returned if the window doesn't have any neighbor windows in the respective direction.
Group Events
The Groups API offers several methods for tracking group events, both on top level of the API and on the Group
instance.
The group event methods return an unsubscribe function which you can use to stop tracking the respective event.
Group Added or Removed
To get notified when window groups are added or removed from the io.Connect framework, use the onGroupAdded()
and onGroupRemoved()
methods on top level of the Groups API:
const handlers = {
onAdded: ioConnectGroup => console.log(`Group with ID "${ioConnectWindow.id}" added.`),
onRemoved: ioConnectGroup => console.log(`Group with ID "${ioConnectWindow.id}" removed.`)
};
io.windows.groups.onGroupAdded(handlers.onAdded);
io.windows.groups.onGroupRemoved(handlers.onRemoved);
Window Added or Removed
To get notified when windows are added or removed from an io.Connect Window group, use the onWindowAdded()
and onWindowRemoved()
methods of a Group
instance and pass handlers for the respective events:
const handlers = {
onAdded: (ioConnectGroup, ioConnectWindow) => console.log(`Window "${ioConnectWindow.title}" added to group with ID "${ioConnectGroup.id}".`),
onRemoved: (ioConnectGroup, ioConnectWindow) => console.log(`Window "${ioConnectWindow.title}" removed from group with ID "${ioConnectGroup.id}".`)
};
myGroup.onWindowAdded(handlers.onAdded);
myGroup.onWindowRemoved(handlers.onRemoved);
Header Visibility
To get notified for changes in the visibility of the header of an io.Connect Window group, use the onHeaderVisibilityChanged()
method of a Group
instance and pass an event handler:
const handler = ioConnectGroup => console.log(`Header visibility of group with ID "${ioConnectGroup.id}" has changed.`);
myGroup.onHeaderVisibilityChanged(handler);
Group Visibility
To get notified for changes in the visibility of window groups, use the onVisibilityChanged()
method of a Group
instance:
const handler = group => console.log(`Visibility of group with ID "${group.id}" has changed.`);
myGroup.onVisibilityChanged(handler);
Hibernation
To get notified when window groups are hibernated or resumed, use the onHibernated()
and onResumed()
methods on top level of the Groups API:
// The callback for `onHibernated()` receives only the group ID as an argument,
// while the callback for `onResumed()` receives the entire `Group` object.
const handlers = {
onHibernated: groupId => console.log(`Group with ID "${groupId}" is hibernated.`),
onResumed: group => console.log(`Group with ID "${group.id}" is resumed.`)
};
io.windows.groups.onHibernated(handlers.onHibernated);
io.windows.groups.onResumed(handlers.onResumed);
Close
Available since io.Connect Desktop 9.2
⚠️ Note that this feature is available only for web groups.
To get notified when a window group is about to be closed, use the onClosing()
method of a Group
instance. The handler passed to the onClosing()
method will be awaited up to 30 seconds before the window group is closed. It accepts as an argument a prevent()
function that can be used to prevent closing the group. The prevent()
function accepts as an argument a PreventClosingOptions
object in which you can specify whether to show a confirmation dialog to the user:
const handler = async (prevent) => {
const options = { showDialog: false };
prevent(options);
};
myGroup.onClosing(handler);
Tab Windows
To open an io.Connect Window as a tab window, set the mode
property of the WindowCreateOptions
object to "tab"
:
const name = "io-connect-docs";
const url = "https://docs.interop.io";
// Set `mode` to "tab".
const options = {
mode: "tab"
};
const ioConnectWindow = await io.windows.open(name, url, options);
Tab Group
Use the tabGroupId
property of the WindowCreateOptions
object to specify a tab group for the tab window. Tab windows with identical tabGroupId
value will be opened in the same tab group:
const name = "io-connect-docs";
const url = "https://docs.interop.io";
// Specify a tab group.
const options = {
tabGroupId: "my-tab-group"
};
const ioConnectWindow = await io.windows.open(name, url, options);
Use the tabGroupId
property of an IOConnectWindow
instance to retrieve the tab group ID of a window:
const tabGroup = myWindow.tabGroupId;
Attaching & Detaching Tabs
To attach a tab to an existing tab window, use the attachTab()
method of an IOConnectWindow
instance. Pass a window ID or an IOConnectWindow
object as a first argument:
const name = "io-connect-docs";
const url = "https://docs.interop.io";
const options = {
mode: "tab"
};
const newTab = await io.windows.open(name, url, options);
// Attach a new tab window to an existing tab window.
// It is assumed that `myWindow` is a tab window.
await myWindow.attachTab(newTab);
To detach a tab from a tab group, use the detachTab()
method of an IOConnectWindow
instance. The detachTab()
method accepts a DetachOptions
object as an optional argument. Use it to specify bounds and other options for the detached tab:
const detachOptions = {
bounds: {
top: 200,
left: 200,
height: 400,
width: 300
}
};
// Detach `myWindow` from the tab group.
// It is assumed that `myWindow` is a tab window.
await myWindow.detachTab(detachOptions);
Frame Buttons
The Window Management API allows placing custom buttons in the frame area of the window and handling clicks on them.
Frame button in a flat window:
Frame button in a tab window:
Frame button in an HTML window:
Adding Buttons
To add or replace an existing frame button, use the addFrameButton()
method of an IOConnectWindow
instance. It accepts a ButtonInfo
object as a required first argument. The buttonId
(must be unique) and the imageBase64
(button image encoded as a Base64 string) properties of the ButtonInfo
object are required:
const buttonInfo = {
buttonId: "search-button",
tooltip: "Search",
order: 1,
imageBase64: "iVBORw0KGgoAAAAN..."
}
await myWindow.addFrameButton(buttonInfo);
Use the order
property to control the position of the buttons in the frame, and the tooltip
property to provide concise information about the frame button to the user.
Removing Buttons
To remove a frame button, use the the removeFrameButton()
method of an IOConnectWindow
instance and pass the ID of the button to remove:
const buttonID = "search-button";
await myWindow.removeFrameButton(buttonID);
Button Events
The frame button event methods return an unsubscribe function that you can use to stop tracking the respective event.
To track frame button clicks, use the onFrameButtonClicked()
method of an IOConnectWindow
instance and pass an event handler:
const clickHandler = (buttonInfo, ioConnectWindow) => {
if (buttonInfo.buttonId === "search-button") {
console.log(`The Search button of "${ioConnectWindow.name}" was clicked.`);
};
};
myWindow.onFrameButtonClicked(clickHandler);
To track adding or removing frame buttons, use the onFrameButtonAdded()
and onFrameButtonRemoved()
methods of an IOConnectWindow
instance and pass handlers for the respective events:
const handlers = {
onAdded: (buttonInfo, ioConnectWindow) => {
console.log(`Frame button with ID "${buttonInfo.buttonId}" was added to "${ioConnectWindow.name}".`);
},
onRemoved: (buttonInfo, ioConnectWindow) => {
console.log(`Frame button with ID "${buttonInfo.buttonId}" was removed from "${ioConnectWindow.name}".`);
}
};
myWindow.onFrameButtonAdded(handlers.onAdded);
myWindow.onFrameButtonRemoved(handlers.onRemoved);
Flydown Windows
Flydown windows are helper windows which can be easily configured to appear on hover on an area in your window. This spares you the need to write boilerplate code for showing and hiding additional windows. Flydowns work with existing windows - first, create a window and keep it hidden, and then use that window to create a flydown.
See the JavaScript Flydown example on GitHub.
The delay times for showing and hiding flydown windows can be set using the global io.Connect Window configuration.
Basic Configuration
To create a flydown window, use the createFlydown()
method. You can call it either through io.windows.createFlydown()
or directly on a window instance. The method accepts targetWindowId
and a FlydownOptions
object as arguments. If you call createFlydown()
on a window instance, pass only a FlydownOptions
object as an argument, since the current window will be used as a target for the created flydown window.
The following snippet shows how to use flydown windows in the most basic case when you need to show a flydown on hover on a button in an app. First, create a window which you will use as a flydown and then create the actual flydown. Open a window for a flydown with the open()
method and pass hidden: true
in the configuration object, or use a hidden app which has been auto started or started before creating the flydown. Use the createFlydown()
method to create a flydown:
// Open a hidden window to be used as a flydown.
const name = "myFlydown";
const url = "http://localhost:22080/myFlydown";
const options = { hidden: true };
const myFlydownWindow = await io.windows.open(name, url, options);
// Define a unique zone identifier for each zone that will trigger the flydown.
const myWindowID = io.windows.find("MyWindow").id;
const zoneID = "uniqueZoneIdentifier";
const flydownWindowID = myFlydownWindow.id;
const buttonBounds = { left:42, top:42, height:42, width:42 };
const flydownOptions = {
windowId: flydownWindowID,
// The flydown will appear at this position relative to the target (zone).
targetLocation: "bottom",
size: {
width: 200,
height: 200
},
zones: [
{
id: zoneID,
// The flydown will appear on hover within these bounds.
bounds: buttonBounds,
flydownSize: {
width: 300,
height: 400
}
}
]
};
// Create the actual flydown.
const flydown = await io.windows.createFlydown(myWindowID, flydownOptions);
Property | Description |
---|---|
targetWindowId |
The ID of the target window for which the flydown will be created. Not needed when you call createFlydown() on a window instance. |
windowId |
The ID of the window which will be used as a flydown window. |
targetLocation |
The location ("bottom" , "top" , "left" , "right" or "none" ) where the flydown will appear relative to the defined flydown zone. If "none" is passed, the flydown will appear at { left: 0, top: 0 } of the flydown trigger zone. |
size |
The size of the rendered flydown window (width and height ). Can be an object with a specific size or a callback that calculates the size. |
zones |
An array of defined FlydownZone objects which when triggered will show a flydown window. |
id |
A unique zone ID. |
bounds |
Bounds of the zone which can trigger a flydown window. These bounds are relative to the target window - the coordinates { left: 0, top: 0 } correspond to the top left corner of the target window, rather than the top left corner of the monitor. |
flydownSize |
Either the desired size of the flydown or a callback invoked before the flydown is shown in order to calculate the flydown size or cancel the flydown. |
The properties targetLocation
and windowId
can be set both in the FlydownOptions
object and/or in each FlydownZone
object within the zones
array. The values set in the FlydownOptions
object will be used as default values if no such value is specified in a FlydownZone
object. If you specify a value for any of these properties both in the FlydownOptions
object and in a FlydownZone
object, the one in the FlydownZone
object will have higher priority than the one in the FlydownOptions
object.
The size of the flydown window, however, is handled a little differently. Since its value can be either a size object or a callback for calculating the size (see Dynamic Size Calculation), there are several cases if you set the flydown size both in the FlydownOptions
object (the size
property) and in a FlydownZone
object (the flydownSize
property). In any case, the values in the FlydownZone
object have higher priority, except when you pass a callback in the FlydownOptions
object and specific size in the FlydownZone
object - then the callback in the FlydownOptions
object will be taken into account.
Flydown Active Area
To create a flydown window which is triggered by a particular area within your app and remains active (visible) as long as the user stays within a certain range of the app window, use the activeArea
property in the options object.
// Range where the flydown will remain active - values are relative to the target window.
const activeArea = { left: 20, top: 20, height: 60, width: 60 };
const flydownOptions = {
windowId: flydownWindowID,
// The flydown will appear at this position relative to the target (zone).
targetLocation: "bottom",
size: {
width: 200,
height: 200
},
// The flydown won't disappear while the user is hovering within that range.
activeArea: activeArea,
zones: [
{
id: zoneID,
// The flydown will appear on hover within these bounds.
bounds: buttonBounds,
flydownSize: {
width: 300,
height: 400
}
}
]
};
const flydown = await io.windows.createFlydown(MyWindowID, flydownOptions);
Dynamic Size Calculation
To change the size of your flydown window at runtime, pass a callback function to the size
property in the FlydownOptions
object (or to the flydownSize
property in the FlydownZone
object) instead of a specific size:
const myWindow = io.windows.my();
const flydownOptions = {
windowId: flydownWindowID,
targetLocation: "bottom",
size: (data, cancel) => {
// Make calculations here...
return {
width,
height
}
},
zones: [
{
id: zoneID,
bounds: buttonBounds
}
]
};
// The `targetWindowId` property is omitted, as `createFlydown()` is called on a window instance.
const flydown = await myWindow.createFlydown(flydownOptions);
The callback function receives two arguments - data
and cancel
. The data
argument is an object with the following properties:
Property | Description |
---|---|
zoneId |
The ID of the zone which has triggered the flydown. |
flydownWindowId |
The ID of the window used as a flydown. |
flydownWindowBounds |
The initial bounds of the flydown if set before the callback is invoked. If not set, this defaults to { left: 0, top: 0, height: 200, width: 200} . |
Canceling Flydowns
The cancel
argument of the callback that can be passed to the size
property (or the flydownSize
property) is a function that you can use to cancel the flydown:
// Condition on which to cancel the flydown.
const shouldBeCanceled = true;
const flydownOptions = {
windowId: flydownWindowID,
targetLocation: "bottom",
size: (data, cancel) => {
if (shouldBeCanceled) {
cancel();
}
return {
width: 200,
height: 200
}
},
zones: [
{
id: zoneID,
bounds: buttonBounds
}
]
};
const flydown = await myWindow.createFlydown(flydownOptions);
⚠️ Note that this callback isn't the place to make heavy calculations - you must return a response within 100 ms. Return a
Promise
from the callback if your logic is asynchronous.
The Flydown
object has a destroy
property that you can use to destroy the zones that trigger the flydowns. This will only remove the flydown trigger zones and not the actual windows used as flydowns:
const flydownOptions = {
windowId: flydownWindowID,
targetLocation: "bottom",
size: (data, cancel) => {
if (shouldBeCanceled) {
cancel();
}
return {
width: 200,
height: 200
}
},
zones: [
{
id: zoneID,
bounds: buttonBounds
}
]
};
const flydown = await myWindow.createFlydown(flydownOptions);
// Remove the flydown trigger zones.
await flydown.destroy();
Popup Windows
Popup windows are helper windows that can appear when the user clicks an area in your app.
See the JavaScript Popup example on GitHub.
Implementing the behavior of popup windows can be a very tedious task. You must handle all cases in which the popup may go out of screen, handle user input from multiple windows which may involve confusion with timeouts and potential race conditions. While not impossible, it is an endeavor prone to many errors, while the end result most often is unreliable. The showPopup()
method handles all these problems and almost no additional code is required to make it work smoothly in all cases. You can call showPopup()
either through io.windows.showPopup()
or directly on a window instance. This method accepts targetWindowId
and a PopupOptions
object as arguments. If you call showPopup()
directly on a window instance, don't pass a targetWindowId
, as the ID of the current window will be used to create the popup window.
As with the Flydown Windows, create a window which you will use as a popup and after that create the actual popup.Open a window for a popup with the open()
method and pass hidden: true
in the configuration object, or use a hidden app which has been auto started or started before creating the popup. Use the showPopup()
method to create a popup.
The following snippet demonstrates the steps to follow to create a popup for a window:
// Open a window to use as a popup.
const name = "myPopup";
const url = "http://localhost:22080/myPopup";
const options = { hidden: true };
const myPopupWindow = await io.windows.open(name, url, options);
const myWindowID = io.windows.find("MyWindow").id;
// Area which will trigger the popup when the user clicks on it.
const buttonBounds = { left: 42, top: 42, width: 42, height: 42 };
const popupOptions = {
windowId: myPopupWindow.id,
targetBounds: buttonBounds,
size: {
width: 100,
height: 200
},
targetLocation: "bottom"
};
// Create the popup.
const popup = await io.windows.showPopup(myWindowID, popupOptions);
Property | Description |
---|---|
targetWindowId |
The ID of the target window for which the popup will be created. Not needed when you call showPopup() on a window instance. |
windowId |
The ID of the window which will be used as a popup window. |
targetBounds |
The bounds of the area around which the popup window will appear. |
size |
The size of the rendered popup window (width and height ). |
targetLocation |
The location ("bottom" , "top" , "left" , "right" or "none" ) where the popup will appear relative to the defined popup area (targetBounds ). If "none" is passed, the popup will appear at { left: 0, top: 0 } of the popup area. |
Reference
For a complete list of the available Window Management API methods and properties, see the Window Management API Reference Documentation.