# io.Connect Desktop 9.7

Source: https://docs.interop.io/desktop/getting-started/changelog/platform/9-7/index.html

## io.Connect Desktop 9.7

*Release date: 10.12.2024*

| Components | Version |
|------------|---------|
| Electron | [33.1.0](https://releases.electronjs.org/release/v33.1.0) |
| Chromium | 130.0.6723.91 |
| Node.js | 20.18.0 |

The following libraries are bundled with **io.Connect Desktop** 9.7 and will be used for [auto injection](https://docs.interop.io/desktop/getting-started/how-to/interop-enable-your-apps/javascript/index.md#auto_injection):

| Injected Library | Version |
|------------------|---------|
| [`@interopio/desktop`](https://www.npmjs.com/package/@interopio/desktop) | [6.10](https://docs.interop.io/desktop/getting-started/changelog/libraries/interopio-desktop/index.md#610-6100) |
| [`@interopio/fdc3`](https://www.npmjs.com/package/@interopio/fdc3) | 2.4 |

## New Features

> ### Multi Channel Mode
>
> **io.Connect Desktop** now provides experimental support for working with [multiple Channels](https://docs.interop.io/desktop/capabilities/data-sharing/channels/overview/index.md#channel_selector-types-multi) simultaneously:
>
> ![Multi Channels](https://docs.interop.io/desktop/images/channels/channel-selector-multi.mp4)
>
> > ⚠️ *Note that this functionality is still experimental and you should take into consideration the following:*
> >
> > - There may be hidden bugs.
> > - Currently, there is only a JavaScript API for working with multiple Channels.
> > - Using multiple Channels is available only for [web groups](https://docs.interop.io/desktop/capabilities/windows/window-management/overview/index.md#window_groups-web_groups).
> > - Currently, working with multiple Channels can be enabled only on system level and can't be controlled per app.
> > - There isn't backwards compatibility between the versions of the [`@interopio/desktop`](https://www.npmjs.com/package/@interopio/desktop) library that support only single Channels and the ones that support both single and multiple Channels. If you want to use multiple Channels, all apps using Channels must be upgraded to the latest version of the [`@interopio/desktop`](https://www.npmjs.com/package/@interopio/desktop) library.
> > - Currently, directional Channels aren't supported in multi Channel mode.
> > - [Supplementary methods for working with multiple Channels](https://docs.interop.io/desktop/getting-started/fdc3-compliance/index.md#channels-using_multiple_channels) have been added to the io.Connect JavaScript [FDC3 implementation](https://docs.interop.io/desktop/getting-started/fdc3-compliance/index.md#fdc3_implementations-javascript). These methods are specific io.Connect implementations and are outside the scope of the FDC3 standard. Their purpose is to enable working with multiple Channels in FDC3 apps.
>
> To enable the multi Channel Selector globally for all apps, use the `"type"` property of the `"channelSelector"` object under the `"windows"` top-level key in the `system.json` [system configuration](https://docs.interop.io/desktop/developers/configuration/system/index.md) file of **io.Connect Desktop**:
>
> ```json
> {
>     "windows": {
>         "channelSelector": {
>             "type": "multi"
>         }
>     }
> }
> ```
>
> #### Channels API
>
> Added new methods for working with multiple Channels - [`myChannels()`](https://docs.interop.io/desktop/reference/javascript/channels/api/index.md#API-myChannels), [`getMyChannels()`](https://docs.interop.io/desktop/reference/javascript/channels/api/index.md#API-getMyChannels) and [`onChannelsChanged()`](https://docs.interop.io/desktop/reference/javascript/channels/api/index.md#API-onChannelsChanged). These methods can be used both in single and in multi Channel mode:
>
> ```javascript
> // Retrieving the names of all currently joined Channels.
> const channelNames = await io.channels.myChannels();
>
> // Retrieving the contexts of all currently joined Channels.
> const channelContexts = await io.channels.getMyChannels();
>
> // Getting notified when the current window joins or leaves a Channel.
> // The handler receives as an argument a list of all currently joined Channels.
> const handler = (channelNames) => {
>     channelNames.forEach(console.log);
> };
>
> const unsubscribe = io.channels.onChannelsChanged(handler);
> ```
>
> > ⚠️ *Note that the [`my()`](https://docs.interop.io/desktop/reference/javascript/channels/api/index.md#API-my), [`getMy()`](https://docs.interop.io/desktop/reference/javascript/channels/api/index.md#API-getMy), and [`onChanged()`](https://docs.interop.io/desktop/reference/javascript/channels/api/index.md#API-onChanged) methods for working with single Channels aren't deprecated, but it's highly recommended to use the `myChannels()`, `getMyChannels()` and `onChannelsChanged()` methods instead, which support working both with single and multiple Channels.*
>
> Exposed a `mode` property which you can use to determine the current Channel mode (single or multi Channel):
>
> ```javascript
> const channelMode = io.channels.mode;
>
> if (channelMode === "single") {
>     // Handle Channel operations in single Channel mode.
> } else if (channelMode === "multi") {
>     // Handle Channel operations in multi Channel mode.
> }
> ```
>
> The [`leave()`](https://docs.interop.io/desktop/reference/javascript/channels/api/index.md#API-leave) method now accepts as an optional argument an object with optional `windowId` and `channel` properties which you can use to specify which window instance from which Channel to remove:
>
> ```javascript
> // Specifying a window instance to remove from a specific Channel.
> const options = {
>     windowId: win.id,
>     channel: "Red"
> };
>
> await io.channels.leave(options);
> ```
>
> #### Multiple Channels in FDC3 Apps
>
> The FDC3 standard doesn't provide out-of-the-box support for multiple Channels. To enable [FDC3 apps to work with multiple Channels](https://docs.interop.io/desktop/getting-started/fdc3-compliance/index.md#channels-using_multiple_channels), the io.Connect JavaScript [FDC3 implementation](https://docs.interop.io/desktop/getting-started/fdc3-compliance/index.md#fdc3_implementations-javascript) has been extended with the following supplementary methods:
>
> ```javascript
> // Retrieving all currently joined Channels.
> const currentChannels = await fdc3.getCurrentChannels();
>
> // Leaving a Channel by specified Channel ID.
> await fdc3.leave("Red");
>
> // Leaving all currently joined Channels.
> await fdc3.leaveCurrentChannels();
> ```
>
> The handler passed to the [`addContextListener()`](https://fdc3.finos.org/docs/api/ref/DesktopAgent#addcontextlistener) method now receives as a third optional argument a Channel ID. You can use it to determine the Channel from which comes the context update:
>
> ```javascript
> const contextType = "Contact";
> const handler = (context, metadata, channelId) => {
>     console.log(`Received updates from Channel ${channelId}.`);
> };
>
> await fdc3.addContextListener(contextType, handler);
> ```

> ### Splash Screen Windows Taskbar Icon
>
> You can now disable showing the Windows taskbar icon of the [splash screen](https://docs.interop.io/desktop/getting-started/how-to/rebrand-io-connect/user-interface/index.md#splash_screen). To instruct **io.Connect Desktop** to hide the splash screen Windows taskbar icon, use the `"showInTaskbar"` property of the `"splash"` top-level key in the `system.json` [system configuration](https://docs.interop.io/desktop/developers/configuration/system/index.md) file of **io.Connect Desktop**:
>
> ```json
> {
>     "splash": {
>         "showInTaskbar": false
>     }
> }
> ```

> ### Web Groups Tab Overflow
>
> Tabs in io.Connect web groups now decrease to a predefined minimum width before being grouped in an [overflow](https://docs.interop.io/desktop/capabilities/windows/window-management/overview/index.md#tab_overflow) dropdown menu:
>
> ![Tab Overflow](https://docs.interop.io/desktop/images/window-management/tab-overflow.mp4)
>
> To set the minimum tab width after which the tabs will be grouped in an overflow menu, you must have a [custom Web Group App](https://docs.interop.io/desktop/capabilities/windows/window-management/overview/index.md#extending_web_groups) and modify the following CSS variable in the `vars.css` file located in the default [style](https://docs.interop.io/desktop/capabilities/windows/window-management/overview/index.md#extending_web_groups-styles) assets distributed with the [`@interopio/groups-ui-react`](https://www.npmjs.com/package/@interopio/groups-ui-react) library:
>
> ```css
> /* Set the minimum tab width for tab overflow. */
> --t42-tab-bar-tab-overflowable-min-width: 96px
> ```

> ### Critical Preload Scripts & Injected Styles
>
> To define a [preload script](https://docs.interop.io/desktop/capabilities/more/features/index.md#preload_scripts) or an [injected CSS file](https://docs.interop.io/desktop/developers/configuration/system/index.md#window_settings-injecting_styles) as critical for your apps, use the `"critical"` property of the injected item definition. If set to `true`, failure to inject the preload script or the CSS file will be treated as a critical error.
>
> The following example demonstrates defining a critical preload script in the [app definition](https://docs.interop.io/desktop/developers/configuration/application/index.md) of an io.Connect app:
>
> ```json
> {
>     "details": {
>         "preloadScripts": {
>             "scripts": [
>                 {
>                     "url": "https://my-domain.com/my-script.js"
>                 }
>             ]
>         }
>     }
> }
> ```
>
> The following example demonstrates defining a critical CSS file globally for all io.Connect apps in the `system.json` [system configuration](https://docs.interop.io/desktop/developers/configuration/system/index.md) file of **io.Connect Desktop**:
>
> ```json
> {
>     "windows": {
>         "injectedStyles": {
>             "styles": [
>                 {
>                     "url": "https://my-org.com/my-styles.css",
>                     "critical": true
>                 }
>             ]
>         }
>     }
> }
> ```
>
> For development purposes, you can:
>
> - Clear the preload scripts cache manually by using the "Clear Preload Scripts Cache" option under the "Diagnostics" section in the **io.Connect Desktop** tray menu.
>
> - Use the `preloadScripts` property of the `iodesktop` object injected in the global `window` object to retrieve a list of objects describing the available preload scripts. Use the `regeneratePreloads()` method of the `iodesktop` object to clear the preload script cache:
>
> ```javascript
> // Retrieve a list of preload script definition objects.
> const preloads = iodesktop.preloadScripts;
>
> preloads.forEach(console.log);
>
> // Clear the preload script cache.
> await iodesktop.regeneratePreloads();
> ```

> ### Web Page Search Settings
>
> To enhance the user experience with the [Web Page Search](https://docs.interop.io/desktop/capabilities/more/features/index.md#web_page_search) feature, you can now provide settings for it. It's possible to enable and configure a window pool for the Web Page Search, which will ensure that there are available instances of it ready to be displayed whenever an additional instance is required. You can specify the number of windows to keep in the pool and the interval at which to create them. Keep in mind that each additional instance in the pool will require more memory. Usually, two instances are enough to provide a smooth user experience.
>
> To provide settings for the [Web Page Search](https://docs.interop.io/desktop/capabilities/more/features/index.md#web_page_search) feature of **io.Connect Desktop**, use the `"webPageSearch"` top-level key in the `system.json` [system configuration](https://docs.interop.io/desktop/developers/configuration/system/index.md) file of **io.Connect Desktop**:
>
> ```json
> {
>     "webPageSearch": {
>         "pool": {
>             "enabled": true,
>             "max": 3
>         }
>     }
> }
> ```
>
> The `"webPageSearch"` object has the following properties:
>
> | Property | Type | Description |
> |----------|------|-------------|
> | `"enabled"` | `boolean` | If `true` (default), will enable the search in page feature. |
> | `"pool"` | `object` | Settings for the window pool used for creating the Web Page Search window. If enabled, will allow you to specify how many windows to keep in the pool and at what interval to create them. Keep in mind that each additional instance in the pool will require more memory. Usually, two instances are enough to provide a smooth user experience. |
>
> The `"pool"` object has the following properties:
>
> | Property | Type | Description |
> |----------|------|-------------|
> | `"enabled"` | `boolean` | If `true`, will enable using a window pool for creating the Web Page Search window. Defaults to `false`. |
> | `"interval"` | `number` | Interval in milliseconds at which to prepare new window instances for the Web Page Search when the window pool needs to be filled. Defaults to `500`. |
> | `"max"` | `number` | Maximum number of instances to keep in the window pool for the Web Page Search. Keep in mind that each additional instance in the pool will require more memory. Usually, two instances are enough to provide a smooth user experience. Defaults to `2`. |

> ### File Access for Browser Extensions
>
> The `"extensions"` and `"devToolsExtensions"` top-level keys in the `system.json` [system configuration](https://docs.interop.io/desktop/developers/configuration/system/index.md) file of **io.Connect Desktop** used for defining [browser extensions](https://docs.interop.io/desktop/capabilities/more/features/index.md#browser_extensions) now accept as a value list of objects with the following properties:
>
> | Property | Type | Description |
> |----------|------|-------------|
> | `"allowFileAccess"` | `boolean` | If `true`, will allow the extension to read local files over the `file://` protocol and to inject content scripts in local pages. It's required to set this to `true` if you want to load an extension from a local file path. Defaults to `false`. |
> | `"path"` | `string` | Path to the extension. |
>
> The following example demonstrates how to allow access to the file system in order to load a Chrome extension from a local file path:
>
> ```json
> {
>     "extensions": [
>         {
>             "path": "C:/path-to-chrome-extension",
>             "allowFileAccess": true
>         }
>     ]
> }
> ```

> ### Window Navigation Timeout
>
> Added a `timeout` property to the [`LoadURLOptions`](https://docs.interop.io/desktop/reference/javascript/windows/loadurloptions/index.md) object passed as a second optional argument to the [`navigate()`](https://docs.interop.io/desktop/reference/javascript/windows/ioconnectwindow/index.md#IOConnectWindow-navigate) method of an [`IOConnectWindow`](https://docs.interop.io/desktop/reference/javascript/windows/ioconnectwindow/index.md) instance. Use this property to specify the interval in seconds to wait for the window to navigate:
>
> ```javascript
> const url = "https://example.com";
> const options = {
>     // Specify timeout in milliseconds. Defaults to 120.
>     timeout: 60
> };
>
> await myWindow.navigate(url, options);
> ```

## Improvements & Bug Fixes

> - Upgraded to Electron 33.1.0 (Chromium 130).
>
> - Improved collapse/expand behavior in io.Connect Window groups.
>
> - Improved dragging behavior for Workspace Frames to avoid UI issues in certain scenarios.
>
> - Fixed not saving properly window context for a hibernated app in a Layout.
