Glue42 Desktop

Release date: 26.06.2023

Components Version
Electron 24.4.1
Chromium 112.0.5615.204
Node.js 18.14.0

New Features


Notification Settings

The Notification Panel now has a "Settings" button that opens a menu with notification settings. You can use it to enable or disable notifications globally or per app, and to configure notification toast stacking:

Notification Settings

Notification Toast Stacks

Notification toasts can now be stacked in groups by app or by severity in order to improve user experience and save space on the screen. When you hover over a notification stack, it expands and displays all notification toasts in it. You can then interact with the notifications in it, clear the entire stack, or let it collapse by moving the mouse away from it:

Notification Stacks

Glue42 Window Groups


To show or hide a window group, use the show() and hide() methods of a Group instance. To check the visibility of a group, use the isVisible property. To get notified when the visibility of a group changes, use the onVisibilityChanged() method:

// Checking the visibility of a window group.
const isVisible = myGroup.isVisible;

if (isVisible) {
    // Hiding a window group.
    await myGroup.hide();
} else {
    // Optional flag indicating whether to activate the window group
    // and focus the last focused window in it.
    const activate = true;

    // Showing a window group.

const handler = group => console.log(`Visibility of group with ID "${}" has changed.`);
// Subscribing for changes of the visibility of a window group.
const unsubscribe = myGroup.onVisibilityChanged(handler);


To hibernate or resume a window group, use the hibernate() and resume() methods, and to get notified when a group is hibernated or resumed, use the onHibernated() and onResumed() methods on top level of the Groups API. To check whether a group is hibernated, use the isHibernated property of a Group object.

The following example demonstrates how to hibernate and resume window groups, check for the hibernation state of a group, and subscribe for hibernating and resuming events:

// Checking whether the window group is hibernated.
const isHibernated = myGroup.isHibernated;

if (isHibernated) {
    // Optional flag indicating whether to activate the window group
    // and focus the last focused window in it.
    const activate = true;

    // Resuming a window group.
    await, activate);
} else {
    // Hibernating a window group.

// Note that the callback for `onHibernated()` receives only the group ID as an argument,
// while the callback for `onResumed()` receives the entire `Group` object.
const hibernateHandler = groupId => console.log(`Group with ID "${groupId}" is hibernated.`);
const resumeHandler = group => console.log(`Group with ID "${}" is resumed.`);
// Subscribing for group hibernation and resuming events.
const unsubHibernate =;
const unsubResume =;

Tab Navigation

You can now jump to the next or the previous window in a tab group by using keyboard shortcuts:

Tab Navigation

Shortcut Description
CTRL + TAB Jump to next tab.
CTRL + SHIFT + TAB Jump to previous tab.
CTRL + PgDn Jump to next tab.
CTRL + PgUp Jump to previous tab.

Workspaces API

Added an onWindowSelected() method for handling the event of selecting a window in a Workspace. The method is available both on an API level and on the Workspace object:

const handler = w => console.log(`Workspace window "${w.title}" was selected in Workspace "${w.workspace.title}".`);
const unsubscribe = await glue.workspaces.onWindowSelected(handler);

Cascading Windows Programmatically

Glue42 Windows or instances of the same Glue42 app can now be opened programmatically in a cascade by using the cascade property of the WindowCreateOptions or the ApplicationStartOptions objects respectively:

const name = "Glue42 Docs";
const url = "";
const options = {
    cascade: { offset: 30 }

// Using the Window Management API.
await, url, options);

// Using the App Management API.
await glue.appManager.application(name).start(null, options);

Cascading Windows

Refreshing Layouts

You can now use the forceRefresh() method of the Layouts API to refresh programmatically the Layout list available to the user when using a REST service or a Glue42 Server as a Layout store:

await glue.layouts.forceRefresh();

Persisting Current URLs

You can now persist the current URL of a web app when saving and restoring Layouts - App Default, Global Layouts, or Workspaces. This allows users to automatically restore the last saved navigation state of web apps. To instruct Glue42 Enterprise to save the current URLs of web apps, use the "saveCurrentUrlInLayout" property of the "windows" top-level key in the system.json system configuration file. The following example demonstrates how to configure Glue42 Enterprise on a system level to save the current URLs of web apps only when they participate in a Workspace or a Global Layout:

    "windows": {
        "saveCurrentUrlInLayout": ["Global", "Workspace"]

You can also specify this setting on an app level by using the "saveCurrentUrlInLayout" property of the "details" top-level key in the app configuration file for web apps, which will override the global system configuration:

    "details": {
        "saveCurrentUrlInLayout": false

Accessing Environment Variables

To allow an app to access the environment variables for the Glue42 process, use the "allowEnvVars" property of the "details" top-level key in the app configuration:

    "details": {
        "allowEnvVars": true

The available environment variables can then be accessed programmatically through the env property of the glue42gd object attached to the global window object:

// The `env` property is an object containing all environment variables as properties.
const envVars = glue42gd.env;

Object.entries(envVars).forEach((envVar) => {
    const [envVarName, envVarValue] = envVar;

    console.log(`${envVarName}: "${envVarValue}"`);

Request Headers Manipulation

Your Glue42 enabled apps can be allowed to manipulate the headers for all or specific web requests. To allow an app to manipulate request headers, use the "allowHeadersManipulation" top-level key of the app configuration:

    "allowHeadersManipulation": true

The API for manipulating request headers is accessible through the customHeaders property of the glue42gd object attached to the global window object. The following example demonstrates how to set, get and remove custom headers for specific requests:

// Custom header that will be appended to the request.
const header = { "My-Custom-Header": "custom-header-value" };
// Filter describing to which requests to append the custom header.
// The header will be appended only to requests for the specified resource types,
// made to the specified URLs, and originating from the main frame of the specified app.
const filter = {
    urls: ["*"],
    applications: ["my-app"],
    types: ["mainFrame", "image", "stylesheet"]

// Setting a custom header.
const headerId = await glue42gd.customHeaders.set(header, filter);
// Getting a collection of all existing custom headers.
const allCustomHeaders = await glue42gd.customHeaders.getAll();
// Removing a custom header by ID.
await glue42gd.customHeaders.remove(headerId);

Gilding Executable Configuration

It's now possible to provide different configuration files for the gilding executable of Glue42 Enterprise that are to be used for the different environments and regions in which Glue42 Enterprise runs. The default gilding.json file holds configuration settings for the thin executable wrapper (gilding executable) around the actual Glue42 Enterprise executable file. Using different versions of the gilding.json file allows you to supply remote configurations for Glue42 Enterprise from different endpoints when using a REST service or a Glue42 Server.

To provide a configuration file for the gilding executable as a command line argument, use the --gildingConfigFile=<file name> argument, where <file name> must be replaced with the name of your configuration file:

tick42-glue-desktop.exe --gildingConfigFile=gilding-DEV.json

You can also create different versions of the gilding.json file, named by using the gilding-<environment>-<region>.json pattern, where <environment> and <region> must be replaced with the environment and region in which Glue42 Enterprise will run. For instance, if a file is named gilding-DEV-EMEA.json, the configuration in it will be used when Glue42 Enterprise is started with the following system settings:

// In `system.json`.
    "env": "DEV",
    "region": "EMEA"

For more details on running Glue42 Enterprise in different environments and regions, see the How to Rebrand Glue42 > Functionality > Environments & Regions section.

Improvements and Bug Fixes

  • Upgraded to Electron 24.4.1 (Chromium 112).

  • Improved loading apps with preload scripts.

  • Improved handling of slowly loading apps in Web Groups.

  • Improved handling click events for the customizable Web Group zones.

  • Fixed a bug where the system log level reverts to "info".

  • Fixed a bug where in a specific case shared context updates weren't announced to the subscriber.

Glue42 Connectors

Breaking Changes

Bloomberg Connector

There is a breaking change in the @glue42/bbg-market-data library. It's no longer possible to pass a string value to the session property of the OpenRequestOptions or the OpenSubscriptionRequestOptions objects when using a custom session for a request:

// This is deprecated.
const requestOptions: OpenSubscriptionRequestOptions = { session: "MyCustomSession" };;

To create a custom session, you can use the create() method of the sessions object of the API, optionally providing custom session settings:

import Glue from "@glue42/desktop";
import BBGMarketData, { BBGMarketDataAPI, SessionOptions, SessionSettings, SessionIdentityOptions } from "@glue42/bbg-market-data";

const glue = await Glue();
const bbgMarketData: BBGMarketDataAPI = BBGMarketData(glue.interop);

const options: SessionOptions = {
    // Your custom Bloomberg session options.

const identityOptions: SessionIdentityOptions = {
    // Your custom Bloomberg session identity options.

const sessionSettings: SessionSettings = {

// Sessions settings are optional.
const customSession: BloombergSession = await bbgMarketData.sessions.create(sessionSettings);
const request = bbgMarketData.createHistoricalDataRequest({...});{ session: customSession });

// You can also use the custom session for other requests.