Snap SDK
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 guide them to help them take control of their entire desktop. Grouped windows can be moved, minimized, switched to, and restored 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 through npm.
Download the Snap SDK client
The Snap SDK client library is an npm package that provides JavaScript/TypeScript Snap SDK APIs. As a developer, you must have npm installed in order to use it.
To download and install the Snap SDK 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.
Include the Snap SDK service
Snap SDK is a two-part system consisting of the client, described above, and the service which is a standalone executable file (OpenFinSnap.exe) that operates on the local computer.
A compatible version of the Snap SDK service is automatically fetched by the client library (1.1+), or it can be specified and downloaded by creating an appAssets
entry in the platform manifest.
Note
This is only required if you do not want to use the default version, or if you deploy to environments where access to cdn.openfin.co is not available. If you need to host the asset on your own infrastructure, set the
src
property to the internal URL where asset is located.
This entry instructs your platform to download a specific version of the Snap SDK service if it does not already exist on your computer:
"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.
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.
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 method starts the Snap SDK service as a hidden application. OpenFinSnap.exe appears in the Windows Task Manager.
You can pass various server options to the start()
method to control aspects of server behavior, including control over taskbar icons, performance trade-offs, and UI options.
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:
Event | Description |
---|---|
client-registered / client-unregistered | Inform when a new window has been registered or unregistered with Snap SDK. |
clients-attached / client-detached | Inform when windows have been snapped together or unsnapped from the window group. |
client-activated / client-deactivated | Inform when a window has been activated or deactivated. |
move-size-completed | Inform when a window and its attached windows were moved or were resized. |
groups-changed | Inform 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 your application 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 several properties:
appAssetInfo
: optional object containingalias
andversion
strings for the executable to launchargs
: optional string array of command line argumentsclientId
: optional unique string to identify the client windowcwd
: optional working directorypath
: path to the executable file; ifappAssetInfo
is provided, this is the target name of the assetstrategy
: optional LaunchStrategy to identify the native application's main window. The default isDelayStrategy
, which waits for a specified time period. UseCombinedStrategy
for multi-process, multi-window applications.
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 objects can be used. Each strategy interface has a corresponding type
property.
-
WaitForWindowNameStrategy
waits until the process opens a window with a title that matches a regular expression rule. If the strategy doesn't find a matching window within the specified timeout period, the process fails. -
WaitForWindowClassStrategy
waits for a window whose underlying WIN32 Window Class matches a regular expression rule. If the strategy doesn't find a matching window within the specified timeout period, the process fails. -
The
DelayStrategy
delays for the specified time period, and then grabs the first window available. -
The
CombinedStrategy
combines the other strategies, so that you can specify any combination of window name, window class, and delay timeout. You can also specify the number of windows to expect and whether to look for windows from multiple processes
The following example shows using a WaitForWindowNameStrategy
object 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 does not automatically launch the windows that are participating in that snapshot. It is your responsibility as the Platform Developer to launch any of the native applications that are to be used within any given snapshot.
Some applications that consist of windows across multiple processes are not currently compatible with Snap SDK
See also
Updated 12 days ago