Windows

Window Management

JavaScript

Opening Windows

The Window Management API can be accessed through glue.windows.

To open a new Glue42 browser window, use glue.windows.open().

Basically, your regular popup code window.open("url") becomes:

glue.windows.open("name", "url")

Below is the signature of the function:

// opens a new Glue42 Window
glue.windows.open(name: string,   // required window name, must be unique
  url: string,                    // required URL
  options?: WindowSettings,       // optional window style attributes
  success?: (window: GDWindow) => void,
  error?: (error: object) => void): Promise<GDWindow>;

Styles are documented in the Window Settings.

And here is an example of opening a Glue42 window:

glue.windows.open(
    "glue-docs",                            // window name
    "https://docs.glue42.com/",             // URL
    {
        top: 150,                           // bounds
        left: 150,
        allowClose: false,
        allowCollapse: true
    });

Relative Positions

When opening a new window, you can position it relatively to another window. Here is an example:

const clientWindow = ...;

// open a "portfolio" window relative to the "client" window
glue.windows.open("portfolio", "www.portfolio.com", {
    relativeTo: clientWindow.id,
    relativeDirection: "right"
});

And the result:

Opening a window relative to another window

Window Modes

Glue42 supports 3 different window modes: flat, tab and HTML. The window mode is controlled by the mode window setting, which can be specified in the application configuration settings or be part of the open a window/start an app call:

Application configuration settings:

{
    "title": "Client List",
    "type": "window",
    "name": "clientlist",
    "icon": "http://localhost:22080/resources/icons/client-list.ico",
    "details": {
        "url": "http://localhost:22080/index.html",
        "mode": "html"
    }
}

Open a window call:

glue.windows.open("portfolio", "www.portfolio.com", {
    mode: "tab"
});

Flat window

Flat windows have framework provided frame that includes tab header and buttons.

Image of a flat window

Tab window

Tab windows have framework provided frame that includes tab header and buttons. They can be tabbed with other tab windows.

Image of a tab window

HTML window

HTML windows do not have a frame - the HTML application is responsible for providing adequate user experience.

Image of an HTML window

Window Settings

The provided values will override the default values.

Name Type Description Default Supported By Runtime Update Support
allowClose bool If false, the window will not contain a close button true All Flat and HTML
allowTabClose bool If false, the tab header will not contain a close button true Tab None
allowCollapse bool If false, the window will not contain a collapse button true All Flat and HTML
allowForward bool If false, the window will not contain an activity related forward button true HTML None
allowMaximize bool If false, the window will not contain a maximize button true All Flat and HTML
allowMinimize bool If false, the window will not contain a minimize button true All Flat and HTML
allowUnstick bool If false, the window will not unstick from other windows true All None
allowLockUnlock bool If false, the window will not contain a lock/unlock button false All Flat and HTML
autoSnap bool If true, when moving the window operation ends, the window will snap to one of the approaching edges of another window (if any of the approaching edges are marked with red) true All None
autoAlign bool If true, a snapped window will adjust its bounds to the same width/height of the window it has stuck to, and/or will occupy the space between other windows (if any) true All None
base64ImageSource string Image as Base64 string that will be used as a taskbar icon for the window. The supported formats are png, ico, jpg, apng. - All All
borderColor string Can be a color name such as "Red", or a hex-encoded RGB or ARGB value - Flat None
buttonsVisibility string Controls the button visibility. Can be set to off, onFocus, onDemand or always. onDemand HTML None
collapseHeight number Defines the height of the window when collapsed System titlebar height Flat and HTML Flat and HTML
devToolsEnable bool If true, allows opening a developer console (using F12) for the new window true All None
downloadSettings Object Object that defines file download behavior in the window - All None
downloadSettings.autoSave bool If true, will auto save the file (without asking the user where to save it). If false, a system save dialog will appear. true All None
downloadSettings.autoOpenPath bool If true, will open the folder that contains the downloaded file after the download is completed false All None
downloadSettings.autoOpenDownload bool If true, will open the download file after the download is completed false All None
downloadSettings.enable bool If true, enables the window to download files true All None
downloadSettings.enableDownloadBar bool If true, a download bar tracking the progress will appear on the bottom of the window when downloading. If false, the download process will be invisible true All None
downloadSettings.path string Path where the downloaded file will be saved. Due to security reasons, it is only possible to provide two download paths: the Windows "Temp" or "Downloads" folder - All None
isCollapsed bool If true, the window will start collapsed false All None
isSticky bool If true, the window will stick to other Glue42 windows forming groups true All None
focus bool If false, the window will not be on focus when created true All All
hasMoveAreas bool If false, the window cannot be moved true Flat and HTML Flat
hasSizeAreas bool If false, the window cannot be resized by dragging its borders, maximizing, etc. true Flat and HTML Flat
hidden bool If true, the window will be started as a hidden window false All All
historyNavigationEnabled bool If true, this will allow the users to navigate back (CTRL+Left) and forward (CTRL+Right) through the web page history GLOBAL CONFIG All None
maxHeight number Specifies the maximum window height - All All
maxWidth number Specifies the maximum window width - All All
minHeight number Specifies the minimum window height - All All
minWidth number Specifies the minimum window width - All All
mode string Glue42 Window type. Possible values are flat, tab and html. flat - None
moveAreaThickness string How much of the window area is to be considered as a moving area (meaning you can move the window using it). The string value corresponds to the left, top, right and bottom borders. 0, 12, 0, 0 HTML None
moveAreaTopMargin string The Glue42 Window may contain a move area thickness top margin. The margin is related to the top border of moveAreaThickness only. The string value corresponds to the left, top, right and bottom 0, 0, 0, 0 HTML None
onTop bool If true, the window will appear on top of the z-order false All None
relativeTo string The ID of the window that will be used to relatively position the new window. Can be combined with relativeDirection - All None
relativeDirection string Direction (bottom, top, left, right) of positioning the window relatively to the relativeTo window. Considered only if relativeTo is supplied right All None
showInTaskbar bool If false, the window will not appear on the Windows taskbar true All None
showTitleBar bool Determines whether the window will have a title bar true Flat None
sizeAreaThickness string How much of the window area is to be considered as a sizing area (meaning you can resize the window using that area). The string value corresponds to the left, top, right and bottom borders 5, 5, 5, 5 HTML None
snappingEdges string Specifies the active Glue42 window snapping edges. Possible values are: top, left, right, bottom, all or any combination of them (e.g., left, right) all All None
startLocation string Specifies the start window location. Possible options are Automatic (The Glue42 Window decides where the window will be positioned) and CenterScreen Automatic All None
stickyFrameColor string Specifies the Glue42 window frame color. Accepts hex color as string (e.g. #666666) or named HTML colors (e.g. red) #666666 All All
stickyGroup string If set, the Glue42 window can only stick to windows that have the same group. Any All None
tabGroupId string Specifies the tab group ID. If two or more tab windows are defined with the same ID, they will be hosted in the same tab window Automatic Tab None
tabIndex number Specifies the tab position index. Tab windows in the same tab group are ordered by their position index. Use negative index to make the tab active. - Tab None
tabSelected bool Tab is selected false Tab None
tabTitle string The tab title "" Tab Tab
tabToolTip string The tab tooltip "" Tab Tab
title string Sets the window title. To work properly, there should be a title HTML tag in the page - All All
url string The URL of the app to be loaded in the new window - All All
useRandomFrameColor bool If true, this will set a random (from a predefined list of colors) frame color to the new window false All None
windowState string If set, the window will start in the specified state (maximized, minimized, normal) normal All All
windowName string The name of the window. - All None

You can provide window settings per window by:

  • using the application configuration settings:
{
    "title": "Client List",
    "type": "window",
    "name": "clientlist",
    "icon": "http://localhost:22080/resources/icons/client-list.ico",
    "details": {
        "url": "http://localhost:22080/index.html",
        "height": 640,
        "width": 560,
        "left": 100,
        "top": 100,
        "mode": "tab",
        "title": "Client List",
        "backgroundColor": "#1a2b30",
        "focus": false
    }
}
glue.windows.open("clientlist", "http://localhost:22080/index.html", {
    height: 640,
    width: 560,
    left: 100,
    top: 100,
    mode: "tab",
    title: "Client List",
    backgroundColor: "#1a2b30",
    focus: false
})

Taskbar Icon

Here is how to setup a taskbar icon:

glue.windows.open(
    "with-icon",
    "http://theverge.com",
    {
        width: 800,
        height: 600,
        base64ImageSource: "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"
    });

To get or change the taskbar icon of the window:

  • Get icon:
glue.windows.my().getIcon(console.log);
  • Change icon:
glue.windows.my().setIcon(myIconInBase64, (win) => console.log("Taskbar icon was changed"));

If you are using an online encoder, make sure the data you pass starts after this sequence of characters: "data:image/png;base64,"

Initiating Downloads

You can specify the downloadSettings arguments to set up the window behavior when downloading files. See all available options in Window Settings.

glue.windows.open(
    "tut1",
    "https://tick42.github.io/glue-docs/assets/files/js-glue-tutorial.zip",
    {
        downloadSettings: {
            autoSave: true,         // will auto save the file, without asking where to save it
            autoOpenDownload: true  // will open the downloaded file when the download is complete
        }
    },
    (openedWindow) => {
    },
    (error) => console.error)

Context

Each window has a dedicated context. This is a JavaScript object, which is a collection of named values.
Contexts can:

  • be set/passed initially on window creation (glue.windows.open());
  • be updated;
  • be subscribed to (for context updates);

Opening a Window with a Context

glue.windows.open(
    "win-name",
    window.location.href,
    {
        context: {   
            tick: 42    // here you can pass anything to the child window
        }
    });

Getting the Context of the Child Windows

const ctx = glue.windows.my().context;
console.log(ctx.tick);

Context Update

glue.windows.my().updateContext({
  test: 42
});
const ctx = glue.windows.my().context;
console.log(ctx.test);

Subscribing for Context Update

glue.windows.my().onContextUpdated((context, win) => console.log("Updated context:", context));

Move and Resize

To move or size a window use the moveResize() function.

glue.windows.my().moveResize({
    width: glue.windows.my().bounds.width + 100,
    top: glue.windows.my().bounds.top + 100
});

const bounds = glue.windows.my().bounds;
console.log(bounds);

Subscribing for Bounds Change

glue.windows.my().onBoundsChanged((win) => console.log("Bounds: ", win.bounds));

Window Close and Refresh Events

Glue42 Enterprise has exposed events for handling window closing and refreshing. The close/refresh handlers can be enabled/disabled and configured with a timeout globally for all windows in the system.json file, or can be applied only to specific windows from the respective application configuration file.

Handlers Configuration

  • You can configure close/refresh handlers globally for all windows from the system.json file, located in %LocalAppData\Tick42\GlueDesktop\config, under the windows top-level key:
"windows": {
    "refreshHandlers": {
        "enabled": true,
        "timeout": 2000
    },
    "closeHandlers": {
        "enabled": true,
        "timeout": 2000
    }
}
  • To configure close/refresh handlers only for specific windows, you have to modify the details property in each application configuration .json file for which you want to have such handlers:
"details": {
    "refreshHandlers": {
        "enabled": false,
        "timeout": 2000
    },
    "closeHandlers": {
        "enabled": true,
        "timeout": 2000
    }
}

Window Close Handler

The onClosing() event handler allows you to execute code before the window is closed. The callback that handles the event can be asynchronous and will be awaited up to the configured timeout.

  • Window closing event handler:
glue.windows.my().onClosing(async () => {
    await asyncOperation();
});

Window Refresh Handler

The onRefreshing() event handler allows you to execute code before the window is refreshed. The callback that handles the event can be asynchronous and will be awaited up to the configured timeout.

  • Window refreshing event handler:
glue.windows.my().onRefreshing(async () => {
    await asyncOperation();
});

Preventing Page Refresh

You can also prevent page refresh, if your business logic requires it. The refresh handler receives a function as a parameter which you can execute to prevent page refresh:

glue.windows.my().onRefreshing((prevent) => {

    const inputField = document.getElementById("input-field");
    let shouldNotRefresh = inputField.value !== "" ? true : false;

    if (shouldNotRefresh) {
        prevent();
    };
});

Glue42 Windows

Groups

Glue42 Windows allow the user to snap windows together. One or more windows stuck together form a group. Groups can be accessed from the Window Management API.

Group Operations

Listing All Groups

const allGroups = glue.windows.groups.list();

Finding the Group of a Window

const someWin = ...;
const group = someWindow.group;

Group Methods

    // restore the group
    restore(success?: (group: Group) => void, error?: (error: string) => void): void;

    // maximize the group
    maximize(success?: (group: Group) => void, error?: (error: string) => void): void;

    // shows the header of the group
    showHeader(success?: (group: Group) => void, error?: InvokeErrorHandler): Promise<Group>;

    // hides the header of the group
    hideHeader(success?: (group: Group) => void, error?: () => void): Promise<Group>;

    // will notify when the visibility of the header of the group has been changed
    onHeaderVisibilityChanged(callback: (group: Group) => void): UnsubscribeFunction;

    // will notify when a new window is added to the group
    onWindowAdded(callback: (group: Group) => void): UnsubscribeFunction;

    // will notify when a window is removed from the group
    onWindowRemoved(callback: (group: Group) => void): UnsubscribeFunction;

Neighbours

To get the neighbours of the window use topNeighbours, leftNeighbours, rightNeighbours, bottomNeighbours

Getting the neighbours:

const topNeighbours = glue.windows.my().topNeighbours;
const leftNeighbours = glue.windows.my().leftNeighbours;
const rightNeighbours = glue.windows.my().rightNeighbours;
const bottomNeighbours = glue.windows.my().bottomNeighbours;

Tab Windows

Tab windows can be created when you specify the mode attribute to tab during the creation of the window:

glue.windows.open(
    "yahoo",
    "http://www.yahoo.com/",
    {
        mode: "tab",              // this is what makes a window a tab window
        tabGroupId: "WebSites",   // use the same group to put several tab windows into it
        tabTitle: "Yahoo"         // you can specify a custom tab title
    });

Here is how to add another tab to the already created tab frame:

glue.windows.open(
    "msft",
    "http://www.microsoft.com/",
    {
        mode: "tab",
        tabGroupId: "WebSites",
        tabTitle: "Microsoft"
    });

Attaching tabs programmatically (only works for windows created as tabs):

(async () => {

// open first window
const win1 = await glue.windows.open(
    "win1",
    "https://www.yahoo.com",
    {
        mode: "tab"
    });

// open second window
const win2 = await glue.windows.open(
    "win2",
    "https://www.microsoft.com",
    {
        mode: "tab"
    });

// attach win1 to the win2 tab frame window
win2.attachTab(win1, 0)
})();

Frame Buttons

You can put extra buttons in the frame area of the window and handle clicks on them.

Adding a New Button

Use addFrameButton() to add a new button or to replace an existing one. Buttons are identified by their buttonId:

const myWindow = glue.windows.my();

myWindow.addFrameButton({
    buttonId: "search-button",
    tooltip: "Search",
    order: 1,
    imageBase64: "" // needs to be a valid base64-encoded image
});

Working example:

const myWindow = glue.windows.my();

myWindow.addFrameButton({
    buttonId: "search-button",
    tooltip: "Search",
    order: 1,
    imageBase64: ""
},
    (w) => console.log("Created a button"),
    console.error);

Removing Buttons

Use removeFrameButton() to remove a button from the frame by passing the buttonId:

const myWindow = glue.windows.my();

myWindow.removeFrameButton(
    "search-button",
    () => {
        // handle success
    }, (err) => {
        // handle error
    });

Handling Clicks

Use onFrameButtonClicked() to subscribe for button clicks:

const myWindow = glue.windows.my();
myWindow.onFrameButtonClicked((buttonInfo) => {
    if (buttonInfo.buttonId === "search-button") {
        console.log("Search button clicked")
    }
});

Monitoring Frame Button Events

You can subscribe for the button added/removed from the frame events:

const myWindow = glue.windows.my();
myWindow.onFrameButtonAdded((buttonInfo) => {
    // handle the button added event
});

myWindow.onFrameButtonRemoved((buttonInfo) => {
    // handle the button removed event
});

Button Order in Tab Windows

Keep in mind that other windows, pushed to the same tab frame, may also define custom buttons. To determine the order of the buttons, use the order property of the button definition, where the lowest value means a leftmost position.

Example:

const myWindow = glue.windows.my();

myWindow.addFrameButton({
    buttonId: "search-button",
    order: 1,
    tooltip: "Search for a party",
    imageBase64: "...",
},
    (window) => { },    // handle success
    (err) => { })       // handle error

myWindow.onFrameButtonClicked((buttonInfo) => {
    if (buttonInfo.buttonId === "search-button") {
        // handle clicks on the button
    }
});

Frame button in a flat window:

Button in a flat window

Frame button in a tab window:

Button in a tab window

Frame button in an HTML window:

Button in an HTML window

Finding Existing Windows

All functions for finding windows return a window object:

You can find a window by its name using find(name):

glue.windows.find(
  "windowName",
  (foundWindow) => foundWindow.close());

In some advanced scenarios (e.g., if you want to tile or cascade the windows in your application), you may want to obtain a list of all windows using glue.windows.list():

const allWindows = glue.windows.list();

The current window can be obtained by calling glue.windows.my():

const currentWindow = glue.windows.my();

In addition to retrieving current windows, you can subscribe for notifications when a window is created or closed by using the windowAdded() and windowRemoved() functions:

glue.windows.windowAdded((wnd) => console.log(`Window ${wnd.name} opened`));

glue.windows.windowRemoved((wnd) => console.log(`Window ${wnd.name} closed`));

Note that windowAdded() will be repeated for all currently opened windows, so you don't need to subscribe, then query the windows and merge the results in order not to miss an event.

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. Note that flydowns work with existing windows - first, you need to create a window and keep it hidden, and then you can use that window to create a flydown.

Flydown

See our JavaScript Flydown example on GitHub.

Basic Configuration

To create a flydown window, you have to use the createFlydown() method. You can call it either through glue.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, you only have to pass 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 application. First, you need to have a window which you will use as a flydown and after that you can create the actual flydown. You can open a window for a flydown with glue.windows.open() passing hidden: true in the configuration object, or you can use a hidden application which has been auto started or started before creating the flydown. Use the glue.windows.createFlydown() method to create a flydown:

const myFlydownWindow = await glue.windows.open(
    "myFlydown",
    "http://localhost:22080/myFlydown",
    {
        hidden: true
    });

// you need to define a unique zone identifier for each zone that will trigger the flydown
const myWindowId = glue.windows.find("MyWindow").id;
const zoneId = "uniqueZoneIdentifier";  
const flydownWinId = myFlydownWindow.id;
const buttonBounds = { left:42, top:42, height:42, width:42 };

glue.windows.createFlydown(
        myWindowId, // targetWindowId
        {
            windowId: flydownWinId,
            // 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
                    }  
                }
            ]
        });
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 zones 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, so 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 you can pass to it either a size object or a callback for calculating the size (see Dynamic Size Calculation), you can have 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

If you want 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 application window, you can 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 }; 

glue.windows.createFlydown(
        MyWindowId,
        {
            windowId: flydownWinId,
            // the flydown will appear at this position relative to the target(zone)
            targetLocation: "bottom",
            size: {
                width: 200,
                height: 200
            },
            // the flydown will not disappear while the user is within that range
            activeArea: activeArea,
            zones: [
                {
                    id: zoneId,
                    // the flydown will appear on hover within these bounds
                    bounds: buttonBounds,
                    flydownSize: {
                        width: 300,
                        height: 400
                    }  
                }
            ]
        });

Dynamic Size Calculation

If you need to change the size of your flydown window at runtime, you can 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 myWin = glue.windows.my();

// targetWindowId is omitted, as createFlydown() is called directly on a window instance
myWin.createFlydown(    
    {
        windowId: flydownWinId,
        targetLocation: "bottom",
        size: (data, cancel) => {
            // make some calculations here...
            return {
                width,
                height
            }
        },
        zones: [
            {
                id: zoneId,
                bounds: buttonBounds
            }
        ]
    });

The callback function receives two arguments - data and cancel. The data argument is an object holding the following properties:

Property Description
zoneId The ID of the zone which 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 you can use to cancel the flydown:

// condition on which to cancel the flydown
const shouldBeCanceled = true;

myWin.createFlydown(    
    {
        windowId: flydownWinId,
        targetLocation: "bottom",
        size: (data, cancel) => {
            if (shouldBeCanceled) {
                cancel();
            }
            return {
                width: 200,
                height: 200
            }
        },
        zones: [
            {
                id: zoneId,
                bounds: buttonBounds
            }
        ]
    });

Note: Keep in mind that this callback is not the place to make heavy calculations - you have only about 100 ms to return a response. You can also return a Promise from the callback if your logic is asynchronous.

The createFlydown() method returns a Promise which resolves with a Flydown object that 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:

let flydown;

myWin.createFlydown(    
    {
        windowId: flydownWinId,
        targetLocation: "bottom",
        size: (data, cancel) => {
            if (shouldBeCanceled) {
                cancel();
            }
            return {
                width: 200,
                height: 200
            }
        },
        zones: [
            {
                id: zoneId,
                bounds: buttonBounds
            }
        ]
    })
    .then(flydownObj => flydown = flydownObj)
    .catch(console.error);

// remove the flydown trigger zones
flydown.destroy();

Popup Windows

Popup windows are helper windows that can appear when the user clicks an area in your application. You can easily define their default behavior (to show on click, to disappear when focus is lost, etc.).

Popup

See our 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 can 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. All these problems are handled in the showPopup() method and almost no additional code is required to make it work smoothly in all cases. You can call showPopup() either through glue.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, you should not pass a targetWindowId, as the ID of the current window will be used to create the popup window.

As with the Flydown Windows, you need to have a window which you will use as a popup and after that you can create the actual popup. You can open a window for a popup with glue.windows.open() passing hidden: true in the configuration object, or you can use a hidden application 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 you need to follow to create a popup for a window:

// opening a window to use as a popup
const myPopupWindow = await glue.windows.open(
    "myPopup",
    "http://localhost:22080/myPopup",
    {
        hidden: true
    });

const myWinId = glue.windows.find("MyWindow").id;
// area which will trigger the popup when the user clicks inside it
const buttonBounds = { left: 42, top: 42, width: 42, height: 42 };

// creating the popup
glue.windows.showPopup(
    myWinId,
    {
        windowId: myPopupWindow.id,
        targetBounds: buttonBounds,
        size: {
            width: 100,
            height: 200
        },
        targetLocation: "bottom"
    });
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

Reference