📘

Note

The Snap SDK is not yet released to the general public. If you want to gain access to the NPM packages for this feature, please contact your OpenFin account representative.

OpenFin’s core layout capabilities allow end users and developers to compose sophisticated collections of multiple web applications in a single window. This key capability means that users can run applications side by side, even if those apps are produced by different teams or different vendors, without the need to toggle between windows to get tasks done.

With Snap SDK, OpenFin extends its layout capabilities to snapping windows together, allowing them to be grouped to behave like a single window. One of the most powerful aspects of Snap SDK is that this ability to create window groups is not restricted to OpenFin windows. With Snap SDK it is possible to group almost any window on the desktop. For example, it’s possible to group:

  • Excel with a pricing app running in an OpenFin window
  • All of your OpenFin Platform Windows or ‘classic’ OpenFin Windows
  • A custom in-house developed application written in .net with new features delivered as web content running in an OpenFin Window
  • A whole collection of native applications, even if none of them are OpenFin windows

Developers choose which applications’ windows should participate in snapping. They can either programmatically attach windows or let the user do it themselves, in which case OpenFin’s intuitive grouping overlays will guide them to help them take control of their entire desktop. Grouped windows can be moved, minimized, restored, and switched to as a single unit, making it easier than ever for users to manage their desktop. All user actions with grouping/ungrouping are also available as events, allowing developers to save/restore state as needed.

Snap SDK is designed from the ground up to be performant, intuitive and robust. Snap SDK does not conflict with Windows ® Snap layout in Windows® 10 and 11, and integrates intuitively with the Windows® Taskbar and window switching through alt/win-tab hotkeys. The technology powering Snap SDK under the hood is written in the Rust programming language to maximize security and performance. However, this is completely abstracted from developers through our ergonomic and fully typed JavaScript package available in NPM.

Include the Snap SDK service

Snap SDK is a two-part system consisting of a service, which operates on the local computer, and a client, controlled by the Snap SDK APIs. The service is a standalone executable file (OpenFinSnap.exe), available from the OpenFin Content Delivery Network. The client is available through NPM and provides JavaScript/TypeScript Snap SDK APIs.

The Snap SDK service can be downloaded by creating an appAssets entry in the platform manifest. This entry instructs your platform to download the Snap SDK service if it does not already exist on your computer. This is the simplest method of adding the Snap SDK service to your OpenFin Platform.

To automatically download the OpenFin Snap SDK service component, add the following to your application or platform manifest file:

"appAssets": [
  {
    "src": "https://cdn.openfin.co/release/snap/SNAP_SDK_VERSION/snap.zip",
    "alias": "openfin-snap",
    "version": "SNAP_SDK_VERSION",
    "target": "OpenFinSnap.exe",
    "mandatory": true
  }
]

Replace both occurrences of "SNAP_SDK_VERSION" with the version number of OpenFin Snap SDK service you want to use.

📘

Note

To automatically download the Snap SDK service software, you must have access to cdn.openfin.co. Alternatively, the asset could be hosted on your infrastructure and the src property set to your custom URL.

The Snap SDK client libraries are flexible enough to allow you to deploy the Snap SDK service through any other mechanism that works for your users. For example, you may wish to deploy the executable to your desktops using Microsoft SCCM rather than having it dynamically downloaded by OpenFin. In this case, when using the client to start the server, you can specify the executable’s path on the local system.

Download the Snap SDK client

The Snap SDK client library is an NPM package. To download and install the NPM package, issue the following command in your OpenFin project directory:

npm install @openfin/snap-sdk@SNAP_SDK_VERSION

Replace "SNAP_SDK_VERSION" with the version number of OpenFin Snap SDK you want to use.

Add Snap SDK code to your OpenFin application or platform

Import the client library in your platform provider file:

let snapServer: Snap.SnapServer | undefined;
...
// Set the OpenFin Snap SDK server ID to the platform UUID.
snapServer = new Snap.SnapServer(fin.me.identity.uuid);

Start Snap SDK Server

Start the SnapServer object with the following code:

// Download and start OpenFin Snap SDK.
await snapServer.start()

This will cause appAssets to download the specified version of the OpenFinSnap.exe file if it is not already downloaded, then OpenFinSnap.exe will start and appear in the Windows Task Manager.

Register OpenFIn Platform windows with Snap SDK

Snap SDK doesn't manage every window on the system by default. It manages only those windows that are registered with Snap SDK.

To register your OpenFin platform windows with Snap SDK, there are two ways to do it:

Method one: Start a new window and explicitly register it with Snap SDK by using the registerWindow function:

// Get an OpenFin window to register with Snap SDK.
// In this example, we use the platform provider window.
const win = fin.Window.getCurrentSync();
const nativeId = await win.getNativeId();

// Register the platform window with OpenFin Snap SDK.
await snapServer.registerWindow(fin.me.identity.uuid, nativeId);

Method two: Automatically register any newly created platform windows with Snap SDK by using the enableAutoWindowRegistration function. This automatically performs the tasks in Method one for each new platform window.

await snapServer.enableAutoWindowRegistration();

Listen to window events for snapped windows

Snap SDK injects code into each window to inspect and make available several WIN32 window messages as events in your platform. These events are made available from OpenFin windows as well as from native application windows.

The events are:

EventDescription
client-registered / client-unregisteredInform when a new window has been registered or unregistered with Snap SDK.
clients-attached / client-detachedInform when windows have been snapped together or unsnapped from the window group.
client-activated / client-deactivatedInform when a window has been activated or deactivated.
move-size-completedInform when a window and its attached windows were moved or were resized.
groups-changedInform when any window groups have been modified.

An example of a client-activated event handler:

snapServer.addEventListener("client-activated", (event: Snap.ClientActivatedEvent) => {
  console.log(`Client Activated: ${JSON.stringify(event)}`);
});

Attach and detach windows from window groups with Snap SDK

To attach a window to a window group using the UI, you click and drag a window to a window group. To detach a window from a window group, you shift-click and drag a window away from a window group.

To programmatically attach a window to a window group, use the attachWindows function:

// Attach myWindowId to the specified window group.
await snapServer.attachWindows(fin.me.identity.uuid, myWindowId, "right", 0);

To programmatically detach a window from a window group, use the detachFromGroup function:

await snapServer.detachFromGroup(myWindowId);

Snapshots with Snap SDK

OpenFin snapshots are stored in the platform manifest. Snap SDK adds decorations (Snap SDK-specific JSON properties) to the platform manifest to describe Snap SDK managed windows and their relationship to a window group. This adds extra steps to creating and applying snapshots.

To create a Snap SDK snapshot, first call the base or prototype getSnapshot function, then call decorateSnapshot to add the Snap SDK decorations to the snapshot.

To apply a snapshot, first call the prepareToApplySnapshot function to inform the platform that it will soon apply a Snap SDK decorated snapshot. Next, apply the snapshot in the usual way. Finally, apply the Snap SDK decorations to the snapshot.

 // Setup OpenFin snapshot integration
  fin.Platform.init({
    overrideCallback: async (PlatformProvider, ...overrideArgs) => {
      try {
        class WithSnap extends PlatformProvider {
          async getSnapshot(...args: [undefined, OpenFin.ClientIdentity]): Promise<OpenFin.Snapshot> {

            // Create the platform snapshot.
            const snapshot = await super.getSnapshot(...args);

            // Add the Snap SDK properties to the platform snapshot.
            const snapSnapshot = await snapServer.decorateSnapshot(snapshot);

            return snapSnapshot;
          }
          async applySnapshot(...args: [OpenFin.ApplySnapshotPayload, OpenFin.ClientIdentity]): Promise<void> {

            // Prepare Snap SDK to return a snapshot.
            await snapServer.prepareToApplySnapshot();

            // Apply the main snapshot.
            await super.applySnapshot(...args);

            // Apply the Snap SDK decorations to the snapshot.
            await snapServer.applySnapshot(args[0].snapshot);
          }
        }
        return new WithSnap(...overrideArgs);
      } catch (error) {
        return new PlatformProvider();
      }
    },
  });

Native windows in Snap SDK

Native application support allows applications, like Excel, to join and participate in a window group. Native applications can be added to groups and then be moved, minimized, restored and switched to as a single group.

For a native application to participate with Snap SDK, Snap SDK must launch the application. This is accomplished by using the launch function and its parameter, LaunchOptions.

The LaunchOptions object contains four properties: The path to the executable file, a unique string clientId, a string array of command line args, and an optional strategy to identify the native application's main window.

Here is a simple example of a launch function to launch Windows 10 Notepad and open mydocument.txt:

// Launch Windows 10 Notepad managed by Snap SDK.
const launchResult = await snapServer?.launch({
  'C:\\Windows\\System32\\notepad.exe',   // Path to Notepad.
  'notepad-#1',                           // Unique client ID string.
  ['c:\\mydocs\mydocument.txt']           // Array of string arguments to be passed.
});

One of the challenges of integrating native applications with Snap SDK is that OpenFin platforms have the concept of a main window, and native applications on Windows do not have that concept. So, Snap SDK must find the main application window on its own.

To accomplish this, various strategy types can be used. Starting in Snap SDK version 0.1.0, there are three strategies: waitForWindowOfName, waitForWindowOfClass, and delay.

The waitForWindowOfName strategy waits until the process opens a window with a window title that matches a regular expression rule. If the strategy doesn't find a matching window within the specified timeout period, the process fails.

The waitForWindowOfClass strategy waits for a window whose underlying WIN32 Window Class that matches a regular expression rule. If the strategy doesn't find a matching window within the specified timeout period, the process fails.

The delay strategy will delay for the specified time period, then grab the first window available.

More strategies are expected in future releases of OpenFin Snap SDK.

This is an example of using the waitForWindowOfName strategy to identify the main window of a custom process:

const launchResult = await snapServer?.launch({
  'my_custom_process.exe',                // Path to custom process.
  'my-random-process-#1',                 // Unique client ID string.
  [],                                     // Empty array to indicate a strategy will be used.
  {
    type: 'waitForWindowOfName',          // Strategy to use to identify the "main window."
    timeoutMs: 15000,                     // Timeout in milliseconds.
    matchRegex: '^My Process Title',      // Regular expression to match title of "main window."
  }
});

Native window limitations

While it is possible to save snapshot details containing snapped windows, applying a snapshot will not automatically launch the windows that are participating in that snapshot. It is currently the responsibility of the Platform Developer to launch any of the native applications that will be used within any given snapshot.

Some applications that consist of windows across multiple processes are not currently compatible with Snap SDK

See also

OpenFin Snap SDK API Reference