Snap SDK
HERE Core Snap SDK works with the Windows operating system only.
The layout capabilities of HERE Core platforms allow end users and developers to compose collections of multiple web apps in a single window. This primary capability means that users can run apps 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, HERE 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 HERE Core windows. With Snap SDK it is possible to group almost any window on the desktop.
Key features:
- Group almost any desktop window, not just HERE Core windows
- Move, minimize, restore, and switch between grouped windows as a single unit
- Resize windows when grouping so they align with targeted windows
- Works with desktop applications (Excel, custom .NET apps, etc.)
- Compatible with Windows® Snap layout in Windows® 10 and 11
- Integrates with the Windows® Taskbar and window switching through alt/win-tab hotkeys.
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 the Snap SDK’s grouping overlays guide them to attach windows. Grouped windows can be moved, minimized, restored, and switched to as a single unit. All user actions with grouping or ungrouping are also available as events, allowing developers to save and restore state as needed.
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 TypeScript package available in the npm registry.
Download the Snap SDK client
The Snap SDK client library is an npm package that provides TypeScript Snap SDK APIs. As a developer, you must have Node.js installed in order to use it. To download and install the Snap SDK package, issue the following command in your Here Core project directory:
npm install @openfin/snap-sdk@SNAP_SDK_VERSION
You can also use yarn to install the client.
yarn add @openfin/snap-sdk@SNAP_SDK_VERSION
You need to specify @SNAP_SDK_VERSION
if you want a particular version. If you don't, the current version is installed.
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
Specifying
SNAP_SDK_VERSION
is required only if you do not want to use the default version, or if you deploy to environments where access to the HERE CDN is not available.
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
}
]
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 HERE Core. 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 Here Core app or platform
Import the client library in your platform provider file:
const snapServer: Snap.SnapServer | undefined;
...
// Set the Here Snap SDK server ID to the platform UUID.
snapServer = new Snap.SnapServer(fin.me.identity.uuid);
Start Snap SDK Server
Start the SnapServer object. The start method takes an optional ServerOptions
object.
// Download and start Here Snap SDK.
await snapServer.start({
theme: 'snap-light1',
taskbarIcon: 'http://here.io/favicon.ico',
taskbarIconGroup: 'openfin_apps_group.my-group',
hideTaskbarEntry: true,
keyToStick: true
})
This method starts the Snap SDK service as a hidden application.
OpenFinSnap.exe
appears in the Windows Task Manager.
Register Here Core 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 Here Core 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 a Here Core 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 Here 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 Here Core windows as well as from native application windows.
The events are:
Event Name | Handler | Description |
---|---|---|
client-registered / client-unregistered | ClientRegisteredEvent / ClientUnRegisteredEvent | Inform when a new window has been registered or unregistered with Snap SDK. |
clients-attached / client-detached | ClientsAttachedEvent / ClientDetachedEvent | Inform when windows have been snapped together or unsnapped from the window group. |
client-activated / client-deactivated | ClientActivatedEvent / ClientDeactivatedEvent | Inform when a window has been activated or deactivated. |
move-size-completed | MoveSizeCompletedEvent | Inform when a window and its attached windows were moved or were resized. |
groups-changed | GroupsChangedEvent | 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. Overlays guide users to the desired side.
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
Here Core snapshots can be 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:
-
Call getSnapshot.
-
Call decorateSnapshot to add the Snap SDK decorations to the snapshot.
To apply a snapshot:
-
Call prepareToApplySnapshot to inform the platform that it will soon apply a Snap SDK decorated snapshot.
-
Apply the snapshot in the usual way.
-
Apply the Snap SDK decorations to the snapshot.
While it is possible to save snapshot details containing snapped windows, applying a snapshot does not automatically launch the windows participating in that snapshot. It is the responsibility of the platform developer to launch the desktop applications within a snapshot.
// Set up Here Core 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();
}
},
});
Desktop application windows in Snap SDK
Desktop application support enables applications, such as Excel, to snap to a window group.
For a desktop application to participate with Snap SDK, Snap SDK must launch the application. This is accomplished by calling launch, passing in 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 Excel and open my-spreadsheet.txt
:
// Launch Windows 10 Excel managed by Snap SDK.
const launchResult = await snapServer?.launch({
'C:\\Windows\\System32\\excel.exe', // Path to Excel.
'excel-#1', // Unique client ID string.
['c:\\my-docs\my-spreadsheet.txt'] // Array of string arguments to be passed.
});
In addition to launching with an executable, you can also launch with an associated file (for example, a .jar
file). To do so, replace the executable's path shown with the absolute path of the associated file.
The HERE Core platform has the concept of a main window, and desktop 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.
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."
}
});