From 601c6f16a560dc2b891dd68faa61abcffddece9b Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Fri, 26 May 2017 16:46:27 +0300 Subject: [PATCH 01/22] WIP --- .gitignore | 2 + packages/api-specification/api/application.ts | 20 + packages/api-specification/api/common.ts | 12 + packages/api-specification/api/info.ts | 13 + packages/api-specification/api/messages.ts | 6 + .../api-specification/api/notifications.ts | 70 ++++ packages/api-specification/api/ssf.ts | 46 +++ packages/api-specification/api/system.ts | 83 ++++ packages/api-specification/api/windows.ts | 366 ++++++++++++++++++ 9 files changed, 618 insertions(+) create mode 100644 packages/api-specification/api/application.ts create mode 100644 packages/api-specification/api/common.ts create mode 100644 packages/api-specification/api/info.ts create mode 100644 packages/api-specification/api/messages.ts create mode 100644 packages/api-specification/api/notifications.ts create mode 100644 packages/api-specification/api/ssf.ts create mode 100644 packages/api-specification/api/system.ts create mode 100644 packages/api-specification/api/windows.ts diff --git a/.gitignore b/.gitignore index bd3c05d..f1b33c5 100644 --- a/.gitignore +++ b/.gitignore @@ -82,3 +82,5 @@ lib/ #gh-pages /docs/_site + +.idea/ diff --git a/packages/api-specification/api/application.ts b/packages/api-specification/api/application.ts new file mode 100644 index 0000000..faf4155 --- /dev/null +++ b/packages/api-specification/api/application.ts @@ -0,0 +1,20 @@ + +export interface ApplicationAPI { + config: ApplicationConfig; + + /** Sets the counter badge for current app. Setting the count to 0 will hide the badge.*/ + setBadgeCount(count: number): boolean; + + /** The current value displayed in the counter badge.*/ + getBadgeCount():number; + + /** Returns an array containing the command line arguments passed when application was launched */ + argv: string[]; +} + +export interface ApplicationConfig { + name: string; + url: string; + uuid: string; + autoShow: boolean; +} \ No newline at end of file diff --git a/packages/api-specification/api/common.ts b/packages/api-specification/api/common.ts new file mode 100644 index 0000000..f27a716 --- /dev/null +++ b/packages/api-specification/api/common.ts @@ -0,0 +1,12 @@ +// contains common types +export interface Rectangle { + x: number; + y: number; + width: number; + height: number; +} + +export interface Size{ + width: number; + height: number; +} \ No newline at end of file diff --git a/packages/api-specification/api/info.ts b/packages/api-specification/api/info.ts new file mode 100644 index 0000000..03170e5 --- /dev/null +++ b/packages/api-specification/api/info.ts @@ -0,0 +1,13 @@ +export interface SSFInfo{ + /** Version of the API **/ + apiVersion: string; + + /** Container information **/ + container: ContainerInfo; +} + +export interface ContainerInfo { + name: string; + version: string; + capabilities: string[]; +} \ No newline at end of file diff --git a/packages/api-specification/api/messages.ts b/packages/api-specification/api/messages.ts new file mode 100644 index 0000000..bbb36c1 --- /dev/null +++ b/packages/api-specification/api/messages.ts @@ -0,0 +1,6 @@ +// Revise - are we ok with bus pub/sub (the current model) or we want RPC +export interface MessagesAPI{ + send(windowId: string, topic: string, message: string|object): void; + subscribe(windowId: string, topic: string, listener: Function): void; + unsubscribe(windowId: string, topic: string, listener: Function): void; +} \ No newline at end of file diff --git a/packages/api-specification/api/notifications.ts b/packages/api-specification/api/notifications.ts new file mode 100644 index 0000000..ecd4dea --- /dev/null +++ b/packages/api-specification/api/notifications.ts @@ -0,0 +1,70 @@ +/** + * Currently following HTML5 notification specs + * + * Imported from typescript definition files + * https://github.com/Microsoft/TSJS-lib-generator/blob/cd60588b72a9188e89346b3c440a76508b4c0e76/baselines/dom.generated.d.ts#L8360-L8381 + */ +export interface NotificationsAPI { + permission: NotificationPermission; + maxActions: number; + + requestPermission(): Promise; +} + +export type NotificationPermission = "default" | "denied" | "granted"; + +export type NotificationDirection = "auto" | "ltr" | "rtl"; + +export interface NotificationPermissionCallback { + (permission: NotificationPermission): void; +} + +export interface NotificationOptions { + dir?: NotificationDirection; + lang?: string; + body?: string; + tag?: string; + image?: string; + icon?: string; + badge?: string; + sound?: string; + vibrate?: number | number[], + timestamp?: number, + renotify?: boolean; + silent?: boolean; + requireInteraction?: boolean; + data?: any; + actions?: NotificationAction[] +} + +export interface NotificationAction { + action: string; + title: string; + icon?: string; +} + +declare class Notification extends EventTarget { + constructor(title: string, options?: NotificationOptions); + + onclick: EventListenerOrEventListenerObject; + onerror: EventListenerOrEventListenerObject; + + close(): void; + + readonly title: string; + readonly dir: NotificationDirection; + readonly lang: string; + readonly body: string; + readonly tag: string; + readonly image: string; + readonly icon: string; + readonly badge: string; + readonly sound: string; + readonly vibrate: number[]; + readonly timestamp: number; + readonly renotify: boolean; + readonly silent: boolean; + readonly requireInteraction: boolean; + readonly data: any; + readonly actions: NotificationAction[] +} \ No newline at end of file diff --git a/packages/api-specification/api/ssf.ts b/packages/api-specification/api/ssf.ts new file mode 100644 index 0000000..e808c64 --- /dev/null +++ b/packages/api-specification/api/ssf.ts @@ -0,0 +1,46 @@ +import {SystemAPI} from "./system"; +import {WindowsAPI} from "./windows"; +import {MessagesAPI} from "./messages"; +import {NotificationsAPI} from "./notifications"; +import {ApplicationAPI} from "./application"; +import {SSFInfo} from "./info"; + +/** + * Describes the ssf object as exposed to clients applications + * + * SSF object groups different APIs, where specific API methods can be access using the corresponding sub-object, e.g. + * to access window manage API : + * + * ssf.windows.open({name:'search', url: 'http://google.com'}); + */ +export interface SSF { + /** + * Window management API - create, discover and manage windows + */ + windows: WindowsAPI; + + /** + * Messaging API - communicate with other windows + */ + messages: MessagesAPI; + + /** + * Notifications API - publish notifications to the user + */ + notifications: NotificationsAPI; + + /** + * Application API - access application specific information + */ + application: ApplicationAPI; + + /** + * System API - access system specific stuff, like displays, user activity, os information, etc. + */ + system : SystemAPI; + + /** + * Info API - general info about the API and the host container + */ + info: SSFInfo; +} diff --git a/packages/api-specification/api/system.ts b/packages/api-specification/api/system.ts new file mode 100644 index 0000000..29006dc --- /dev/null +++ b/packages/api-specification/api/system.ts @@ -0,0 +1,83 @@ +import {Rectangle, Size} from "./common"; + +export interface SystemAPI { + /** + * Info about all displays available + */ + displays: () => DisplayInfo[]; + + /** + * Capture + * @param options + */ + capture: (options?: CaptureOptions) => Promise; + + /** + * Capture specific display + * @param displayId + * @param options + */ + captureDisplay: (displayId: number, options?: CaptureOptions) => Promise; + + /** + * Capture specific window + * @param windowId + * @param options + */ + captureWindow: (windowId: string, options?: CaptureOptions) => Promise; + + /** + * Capture all windows in a separate images + * @param options + */ + captureAllWindows: (options?: CaptureOptions) => Promise; + + /** + * Whenever user activity occurs (keyboard or mouse input) the callback will be invoked. + * If additional activity occurs within the period given by the 'throttle', then the callback will be + * invoked at time: X + throttle (where X is the time of last activity report send). + */ + onUserActivity(callback: ()=> void, throtle: number); + + /** Operating system information */ + os: OperatingSystemInfo; +} + +export interface DisplayInfo { + /** Unique identifier associated with the display. */ + id: number; + + /** Can be 0, 90, 180, 270, represents screen rotation in clock-wise degrees. */ + rotation: number; + + /** Output device's pixel scale factor. */ + scaleFactor: number; + + /** True if this is the primary display */ + primary: boolean; + + bounds: Rectangle; + size: Size; + workArea: Rectangle; + workAreaSize: Size; +} + +export interface OperatingSystemInfo{ + platform: 'Windows' | 'OSX' | 'Linux'; + version: string; + is64bit: boolean; +} + +export interface CaptureOptions { + captureSize: Size; +} + +export interface WindowImageData { + windowId: string; + image: ImageData; +} + +export interface ImageData { + type: string; + data: string; +} diff --git a/packages/api-specification/api/windows.ts b/packages/api-specification/api/windows.ts new file mode 100644 index 0000000..393595d --- /dev/null +++ b/packages/api-specification/api/windows.ts @@ -0,0 +1,366 @@ +import {Rectangle} from "./common"; + +export interface WindowsAPI { + + /** Returns the current window */ + current: Window; + + /** Returns all windows in the application */ + all: Window[]; + + /** Opens a new window */ + open(options: WindowOptions): Promise; + + /** Receive notifications when a new window is opened */ + onWindowOpened(callback: (window: Window) => void); + + /** Receive notifications when a window was closed */ + onWindowClosed(callback: (window: Window) => void); +} + +export interface WindowOptions { + /** + * Default window title. + */ + name: string; + /** + * URL that this window loads. + */ + url: string; + /** + * Window’s height in pixels. + */ + height: number; + /** + * Window’s width in pixels. + */ + width: number; + /** + * Window’s left offset from screen. + */ + x: number; + /** + * Window’s top offset from screen. + */ + y: number; + /** + * Window’s maximum width. + */ + maxWidth: number; + /** + * Window’s minimum width. + */ + minWidth: number; + /** + * Window’s maximum height. + */ + maxHeight: number; + /** + * Window’s minimum height. + */ + minHeight: number; + /** + * Whether the window should always stay on top of other windows. Default is false. + */ + alwaysOnTop: boolean; + /** + * Window’s background color as Hexadecimal value. + */ + backgroundColor: string; + /** + * Whether the window is a child of the current window. Default is false. + */ + child: boolean; + /** + * Show window in the center of the screen. + */ + center: boolean; + /** + * If false, creates a frameless window. Default is true. + */ + frame: boolean; + /** + * Whether window should have a shadow. This is only implemented on macOS. Default is true. + */ + hasShadow: boolean; + /** + * Whether window is maximizable. Default is true. + */ + maximizable: boolean; + /** + * Whether window is minimizable. Default is true. + */ + minimizable: boolean; + /** + * Whether window is resizable. Default is true. + */ + resizable: boolean + /** + * Whether window should be shown when created. Default is true. + */ + show: boolean; + /** + * Whether to show the window in taskbar. Default is false. + */ + skipTaskbar: boolean; + /** + * Makes the window transparent. Default is false. + */ + transparent: boolean; +} + +export interface Window { + + constructor(options: WindowOptions); + + /** + * Removes focus from the window. + * @returns {Promise} A promise which resolves to nothing when the function has completed. + */ + blur(): Promise; + + /** + * Closes the window. + * @returns {Promise} A promise which resolves to nothing when the function has completed. + */ + close(): Promise; + + /** + * Flashes the window's frame and taskbar icon. + * @param {boolean} flag - Flag to start or stop the window flashing. + * @returns {Promise} A promise which resolves to nothing when the function has completed. + */ + flashFrame(flag: boolean): Promise; + + /** + * Focuses the window. + * @returns {Promise} A promise which resolves to nothing when the function has completed. + */ + focus(): Promise; + + /** + * Returns the bounds of the window. + * @returns {Promise} A promise that resolves to an object specifying the bounds of the window. + */ + getBounds(): Promise; + + /** + * Get the child windows of the window. + * @returns {Window[]} A promise that resolves to an array of child windows. + */ + getChildWindows(): ReadonlyArray; + + /** + * Get the maximum size of the window. + * @returns {Promise} A promise that resolves to an array containing the maximum width and height of the window. + */ + getMaximumSize(): Promise>; + + /** + * Get the minimum size of the window. + * @returns {Promise} A promise that resolves to an array containing the minimum width and height of the window. + */ + getMinimumSize(): Promise>; + + /** + * Get the parent of the window. Null will be returned if the window has no parent. + * @returns {Promise} The parent window. + */ + getParentWindow(): Promise; + + /** + * Get the position of the window. + * @returns {Promise} A promise that resolves to an array of integers containing the x and y coordinates of the window. + */ + getPosition(): Promise>; + + /** + * Get the width and height of the window. + * @returns {Promise} A promise that resolves to an array of integers containing the width and height of the window. + */ + getSize(): Promise>; + + /** + * Get the title of the window + * @returns {Promise} The title of the window. + */ + getTitle(): Promise; + + /** + * Check if the window has a shadow. + * @returns {Promise} A promise that resolves to a boolean stating if the window has a shadow. + */ + hasShadow(): Promise; + + /** + * Hides the window. + * @returns {Promise} A promise that resolves to nothing when the window has hidden. + */ + hide(): Promise; + + /** + * Check if the window is always on top of all other windows. + * @returns {Promise} A promise that resolves to a boolean stating if the window is always on top. + */ + isAlwaysOnTop(): Promise; + + /** + * Check if the window can be maximized. + * @returns {Promise} A promise that resolves to a boolean stating if the window can be maximized. + */ + isMaximizable(): Promise; + + /** + * Check if the window is currently maximized. + * @returns {Promise} A promise that resolves to a boolean stating if the window is maximized. + */ + isMaximized(): Promise; + + /** + * Check if the window can be minimized. + * @returns {Promise} A promise that resolves to a boolean stating if the window can be minimized. + */ + isMinimizable(): Promise; + + /** + * Check if the window is currently minimized. + * @returns {Promise} A promise that resolves to a boolean stating if the window is minimized. + */ + isMinimized(): Promise; + + /** + * Check if the window can be resized. + * @returns {Promise} A promise that resolves to a boolean stating if the window can be resized. + */ + isResizable(): Promise; + + /** + * Load a new URL in the window. + * @param {string} url - The URL to load in the window. + * @returns {Promise} A promise that resolves when the window method succeeds. + */ + loadURL(url: string): Promise; + + /** + * Reload the window. + * @returns {Promise} A promise that resolves when the window method succeeds. + */ + reload(): Promise; + + /** + * Restores the window to the previous state. + * @returns {Promise} A promise that resolves to nothing when the window method succeeds. + */ + restore(): Promise; + + /** + * Sets the window to always be on top of other windows. + * @param {boolean} alwaysOnTop - Sets if the window is always on top. + * @returns {Promise} A promise that resolves to nothing when the option is set. + */ + setAlwaysOnTop(alwaysOnTop: boolean): Promise; + + /** + * Sets the window to always be on top of other windows. + * @param {Rectangle} bounds - Sets the bounds of the window. + * @returns {Promise} A promise that resolves to nothing when the option is set. + */ + setBounds(bounds: Rectangle): Promise; + + /** + * Sets the window icon. + * @param {string} icon - The url to the image. + * @returns {Promise} A promise that resolves to nothing when the option has been set. + */ + setIcon(icon: string): Promise; + + /** + * Sets if the window can be maximized. + * @param {boolean} maximizable - Set if the window can be maximized. + * @returns {Promise} A promise that resolves to nothing when the option has been set. + */ + setMaximizable(maximizable: boolean): Promise; + + /** + * Sets the windows maximum size. + * @param {Number} maxWidth - The maximum width of the window. + * @param {Number} maxHeight - The maximum height of the window. + * @returns {Promise} A promise that resolves to nothing when the option has been set. + */ + setMaximumSize(maxWidth: number, maxHeight: number): Promise; + + /** + * Sets if the window can be minimized. + * @param {boolean} minimizable - Set if the window can be minimized. + * @returns {Promise} A promise that resolves to nothing when the option has been set. + */ + setMinimizable(minimizable: boolean): Promise; + + /** + * Sets the windows minimum size. + * @param {Number} minWidth - The minimum width of the window. + * @param {Number} minHeight - The minimum height of the window. + * @returns {Promise} A promise that resolves to nothing when the option has been set. + */ + setMinimumSize(minWidth: number, minHeight: number): Promise; + + /** + * Sets the windows position. + * @param {Number} x - The x position of the window. + * @param {Number} y - The y position of the window. + * @returns {Promise} A promise that resolves to nothing when the option has been set. + */ + setPosition(x: number, y: number): Promise; + + /** + * Sets if the window is resizable. + * @param {boolean} resizable - If the window can be resized. + * @returns {Promise} A promise that resolves to nothing when the option has been set. + */ + setResizable(resizable: boolean): Promise; + + /** + * Sets the width and height of the window. + * @param {number} width - The width of the window. + * @param {number} height - The height of the window. + * @returns {Promise} A promise that resolves to nothing when the option has been set. + */ + setSize(width: number, height: number): Promise; + + /** + * Sets if the window is shown in the taskbar. + * @param {boolean} skipTaskbar - If the window is shown in the taskbar. + * @returns {Promise} A promise that resolves to nothing when the option has been set. + */ + setSkipTaskbar(skipTaskbar: boolean): Promise; + + /** + * Show the window. + * @returns {Promise} A promise that resolves to nothing when the window is showing. + */ + show(): Promise; + + /** + * Maximize the window. + * @returns {Promise} A promise that resolves to nothing when the window has maximized. + */ + maximize(): Promise; + + /** + * Minimize the window. + * @returns {Promise} A promise that resolves to nothing when the window has minimized. + */ + minimize(): Promise; + + /** + * Unmaximize the window. + * @returns {Promise} A promise that resolves to nothing when the window has unmaximized. + */ + unmaximize(): Promise; + + /** + * Send a message to the window. + * @param {string|object} message - The message to send to the window. Can be any serializable object. + */ + postMessage(message: string | Object): void; +} \ No newline at end of file From 9d2df4c790e47055fc6a947603901c21fceb6bc4 Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Fri, 26 May 2017 17:56:13 +0300 Subject: [PATCH 02/22] comment update --- packages/api-specification/api/ssf.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/api-specification/api/ssf.ts b/packages/api-specification/api/ssf.ts index e808c64..7b1382e 100644 --- a/packages/api-specification/api/ssf.ts +++ b/packages/api-specification/api/ssf.ts @@ -9,7 +9,7 @@ import {SSFInfo} from "./info"; * Describes the ssf object as exposed to clients applications * * SSF object groups different APIs, where specific API methods can be access using the corresponding sub-object, e.g. - * to access window manage API : + * to access window management API : * * ssf.windows.open({name:'search', url: 'http://google.com'}); */ @@ -35,7 +35,7 @@ export interface SSF { application: ApplicationAPI; /** - * System API - access system specific stuff, like displays, user activity, os information, etc. + * System API - access system specific stuff,e.g. display information, user activity, os information... */ system : SystemAPI; From c5ec81dac271dfae2f316cd83ad840f5f689eab9 Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Fri, 26 May 2017 18:11:45 +0300 Subject: [PATCH 03/22] typo --- packages/api-specification/api/ssf.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/api-specification/api/ssf.ts b/packages/api-specification/api/ssf.ts index 7b1382e..8969bd9 100644 --- a/packages/api-specification/api/ssf.ts +++ b/packages/api-specification/api/ssf.ts @@ -8,7 +8,7 @@ import {SSFInfo} from "./info"; /** * Describes the ssf object as exposed to clients applications * - * SSF object groups different APIs, where specific API methods can be access using the corresponding sub-object, e.g. + * SSF object groups different APIs, where specific API methods can be accessed using the corresponding sub-object, e.g. * to access window management API : * * ssf.windows.open({name:'search', url: 'http://google.com'}); From 618fff7ffceca1f98290f797d853c736357bbb28 Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Fri, 26 May 2017 18:17:22 +0300 Subject: [PATCH 04/22] comment --- packages/api-specification/api/messages.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/api-specification/api/messages.ts b/packages/api-specification/api/messages.ts index bbb36c1..6c8d9e2 100644 --- a/packages/api-specification/api/messages.ts +++ b/packages/api-specification/api/messages.ts @@ -1,4 +1,8 @@ -// Revise - are we ok with bus pub/sub (the current model) or we want RPC +// ⚠ TODO Revise - are we ok with bus pub/sub (the current model) or we want to propose AGM like RPC + +/** + * Currently this is based on OpenFin bus + */ export interface MessagesAPI{ send(windowId: string, topic: string, message: string|object): void; subscribe(windowId: string, topic: string, listener: Function): void; From 05996d36be356587ab289f727958402e6fc94a48 Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Sat, 27 May 2017 00:07:02 +0300 Subject: [PATCH 05/22] WIP --- packages/api-specification/api/common.ts | 6 +- packages/api-specification/api/info.ts | 11 +- packages/api-specification/api/system.ts | 13 +- packages/api-specification/api/windows.ts | 230 +++++++--------------- 4 files changed, 86 insertions(+), 174 deletions(-) diff --git a/packages/api-specification/api/common.ts b/packages/api-specification/api/common.ts index f27a716..62cf2bb 100644 --- a/packages/api-specification/api/common.ts +++ b/packages/api-specification/api/common.ts @@ -1,7 +1,7 @@ // contains common types -export interface Rectangle { - x: number; - y: number; +export interface Bounds { + top: number; + left: number; width: number; height: number; } diff --git a/packages/api-specification/api/info.ts b/packages/api-specification/api/info.ts index 03170e5..011cb68 100644 --- a/packages/api-specification/api/info.ts +++ b/packages/api-specification/api/info.ts @@ -7,7 +7,16 @@ export interface SSFInfo{ } export interface ContainerInfo { + /** Name of the container */ name: string; + + /** Version of the container */ version: string; - capabilities: string[]; + + /** + * Capabilities supported by the container. + * Expressed as object where each property is a capability and the value + * is the level of support in the container + */ + capabilities: {[key:string]: string}; } \ No newline at end of file diff --git a/packages/api-specification/api/system.ts b/packages/api-specification/api/system.ts index 29006dc..b3ff447 100644 --- a/packages/api-specification/api/system.ts +++ b/packages/api-specification/api/system.ts @@ -1,4 +1,4 @@ -import {Rectangle, Size} from "./common"; +import {Bounds, Size} from "./common"; export interface SystemAPI { /** @@ -56,10 +56,11 @@ export interface DisplayInfo { /** True if this is the primary display */ primary: boolean; - bounds: Rectangle; - size: Size; - workArea: Rectangle; - workAreaSize: Size; + /** Bounds of the display **/ + bounds: Bounds; + + /** Working area of the display */ + workingArea: Bounds; } export interface OperatingSystemInfo{ @@ -80,4 +81,4 @@ export interface WindowImageData { export interface ImageData { type: string; data: string; -} +} \ No newline at end of file diff --git a/packages/api-specification/api/windows.ts b/packages/api-specification/api/windows.ts index 393595d..76206a8 100644 --- a/packages/api-specification/api/windows.ts +++ b/packages/api-specification/api/windows.ts @@ -1,4 +1,4 @@ -import {Rectangle} from "./common"; +import {Bounds} from "./common"; export interface WindowsAPI { @@ -23,86 +23,93 @@ export interface WindowOptions { * Default window title. */ name: string; + /** * URL that this window loads. */ url: string; + /** - * Window’s height in pixels. - */ - height: number; - /** - * Window’s width in pixels. - */ - width: number; - /** - * Window’s left offset from screen. - */ - x: number; - /** - * Window’s top offset from screen. + * Window initial bounds. Can contain partial bounds (e.g width only) and be + * combined with center */ - y: number; + bounds: Bounds; + /** * Window’s maximum width. */ maxWidth: number; + /** * Window’s minimum width. */ minWidth: number; + /** * Window’s maximum height. */ maxHeight: number; + /** * Window’s minimum height. */ minHeight: number; + /** * Whether the window should always stay on top of other windows. Default is false. */ alwaysOnTop: boolean; + /** * Window’s background color as Hexadecimal value. */ backgroundColor: string; + /** * Whether the window is a child of the current window. Default is false. */ child: boolean; + /** * Show window in the center of the screen. */ center: boolean; + /** * If false, creates a frameless window. Default is true. */ frame: boolean; + /** * Whether window should have a shadow. This is only implemented on macOS. Default is true. */ hasShadow: boolean; + /** * Whether window is maximizable. Default is true. */ maximizable: boolean; + /** * Whether window is minimizable. Default is true. */ minimizable: boolean; + /** * Whether window is resizable. Default is true. */ resizable: boolean + /** * Whether window should be shown when created. Default is true. */ show: boolean; + /** * Whether to show the window in taskbar. Default is false. */ skipTaskbar: boolean; + /** * Makes the window transparent. Default is false. */ @@ -114,125 +121,100 @@ export interface Window { constructor(options: WindowOptions); /** - * Removes focus from the window. - * @returns {Promise} A promise which resolves to nothing when the function has completed. - */ - blur(): Promise; - - /** - * Closes the window. - * @returns {Promise} A promise which resolves to nothing when the function has completed. - */ - close(): Promise; - - /** - * Flashes the window's frame and taskbar icon. - * @param {boolean} flag - Flag to start or stop the window flashing. - * @returns {Promise} A promise which resolves to nothing when the function has completed. + * Get or set the bounds of the window. */ - flashFrame(flag: boolean): Promise; + bounds: Bounds; /** - * Focuses the window. - * @returns {Promise} A promise which resolves to nothing when the function has completed. + * Get or set if the window has a shadow. */ - focus(): Promise; + hasShadow: boolean; /** - * Returns the bounds of the window. - * @returns {Promise} A promise that resolves to an object specifying the bounds of the window. + * Get or set the maximum size of the window. */ - getBounds(): Promise; + maximumSize: Bounds; /** - * Get the child windows of the window. - * @returns {Window[]} A promise that resolves to an array of child windows. + * Get or set the minimum size of the window. */ - getChildWindows(): ReadonlyArray; + minimumSize: Bounds; /** - * Get the maximum size of the window. - * @returns {Promise} A promise that resolves to an array containing the maximum width and height of the window. + * Get or set the title of the window */ - getMaximumSize(): Promise>; + title: string; /** - * Get the minimum size of the window. - * @returns {Promise} A promise that resolves to an array containing the minimum width and height of the window. + * Get or set if the window is always on top of all other windows. */ - getMinimumSize(): Promise>; + alwaysOnTop: boolean; /** - * Get the parent of the window. Null will be returned if the window has no parent. - * @returns {Promise} The parent window. + * Get or set if the window can be maximized. */ - getParentWindow(): Promise; + maximizable: boolean; /** - * Get the position of the window. - * @returns {Promise} A promise that resolves to an array of integers containing the x and y coordinates of the window. + * Get or set if the window can be minimized. */ - getPosition(): Promise>; + minimizable: boolean; /** - * Get the width and height of the window. - * @returns {Promise} A promise that resolves to an array of integers containing the width and height of the window. + * Get or set if the window can be re-sized. */ - getSize(): Promise>; + resizable: boolean; /** - * Get the title of the window - * @returns {Promise} The title of the window. + * Get or set if the window is shown in the taskbar. */ - getTitle(): Promise; + skipTaskbar: boolean; /** - * Check if the window has a shadow. - * @returns {Promise} A promise that resolves to a boolean stating if the window has a shadow. + * Removes focus from the window. + * @returns {Promise} A promise which resolves to nothing when the function has completed. */ - hasShadow(): Promise; + blur(): Promise; /** - * Hides the window. - * @returns {Promise} A promise that resolves to nothing when the window has hidden. + * Closes the window. + * @returns {Promise} A promise which resolves to nothing when the function has completed. */ - hide(): Promise; + close(): Promise; /** - * Check if the window is always on top of all other windows. - * @returns {Promise} A promise that resolves to a boolean stating if the window is always on top. + * Flashes the window's frame and taskbar icon. + * @param {boolean} flag - Flag to start or stop the window flashing. + * @returns {Promise} A promise which resolves to nothing when the function has completed. */ - isAlwaysOnTop(): Promise; + flashFrame(flag: boolean): Promise; /** - * Check if the window can be maximized. - * @returns {Promise} A promise that resolves to a boolean stating if the window can be maximized. + * Focuses the window. + * @returns {Promise} A promise which resolves to nothing when the function has completed. */ - isMaximizable(): Promise; + focus(): Promise; /** - * Check if the window is currently maximized. - * @returns {Promise} A promise that resolves to a boolean stating if the window is maximized. + * Get the child windows of the window. */ - isMaximized(): Promise; + getChildWindows(): Window[]; /** - * Check if the window can be minimized. - * @returns {Promise} A promise that resolves to a boolean stating if the window can be minimized. + * Get the parent of the window. Null will be returned if the window has no parent. */ - isMinimizable(): Promise; + getParentWindow(): Window; /** - * Check if the window is currently minimized. - * @returns {Promise} A promise that resolves to a boolean stating if the window is minimized. + * Returns the current state of the window - normal, maximized or minimized */ - isMinimized(): Promise; + getState(): "normal" | "maximized" | "minimized"; /** - * Check if the window can be resized. - * @returns {Promise} A promise that resolves to a boolean stating if the window can be resized. + * Hides the window. + * @returns {Promise} A promise that resolves to nothing when the window has hidden. */ - isResizable(): Promise; + hide(): Promise; /** * Load a new URL in the window. @@ -248,25 +230,11 @@ export interface Window { reload(): Promise; /** - * Restores the window to the previous state. + * Restores the window to normal state. * @returns {Promise} A promise that resolves to nothing when the window method succeeds. */ restore(): Promise; - /** - * Sets the window to always be on top of other windows. - * @param {boolean} alwaysOnTop - Sets if the window is always on top. - * @returns {Promise} A promise that resolves to nothing when the option is set. - */ - setAlwaysOnTop(alwaysOnTop: boolean): Promise; - - /** - * Sets the window to always be on top of other windows. - * @param {Rectangle} bounds - Sets the bounds of the window. - * @returns {Promise} A promise that resolves to nothing when the option is set. - */ - setBounds(bounds: Rectangle): Promise; - /** * Sets the window icon. * @param {string} icon - The url to the image. @@ -274,66 +242,6 @@ export interface Window { */ setIcon(icon: string): Promise; - /** - * Sets if the window can be maximized. - * @param {boolean} maximizable - Set if the window can be maximized. - * @returns {Promise} A promise that resolves to nothing when the option has been set. - */ - setMaximizable(maximizable: boolean): Promise; - - /** - * Sets the windows maximum size. - * @param {Number} maxWidth - The maximum width of the window. - * @param {Number} maxHeight - The maximum height of the window. - * @returns {Promise} A promise that resolves to nothing when the option has been set. - */ - setMaximumSize(maxWidth: number, maxHeight: number): Promise; - - /** - * Sets if the window can be minimized. - * @param {boolean} minimizable - Set if the window can be minimized. - * @returns {Promise} A promise that resolves to nothing when the option has been set. - */ - setMinimizable(minimizable: boolean): Promise; - - /** - * Sets the windows minimum size. - * @param {Number} minWidth - The minimum width of the window. - * @param {Number} minHeight - The minimum height of the window. - * @returns {Promise} A promise that resolves to nothing when the option has been set. - */ - setMinimumSize(minWidth: number, minHeight: number): Promise; - - /** - * Sets the windows position. - * @param {Number} x - The x position of the window. - * @param {Number} y - The y position of the window. - * @returns {Promise} A promise that resolves to nothing when the option has been set. - */ - setPosition(x: number, y: number): Promise; - - /** - * Sets if the window is resizable. - * @param {boolean} resizable - If the window can be resized. - * @returns {Promise} A promise that resolves to nothing when the option has been set. - */ - setResizable(resizable: boolean): Promise; - - /** - * Sets the width and height of the window. - * @param {number} width - The width of the window. - * @param {number} height - The height of the window. - * @returns {Promise} A promise that resolves to nothing when the option has been set. - */ - setSize(width: number, height: number): Promise; - - /** - * Sets if the window is shown in the taskbar. - * @param {boolean} skipTaskbar - If the window is shown in the taskbar. - * @returns {Promise} A promise that resolves to nothing when the option has been set. - */ - setSkipTaskbar(skipTaskbar: boolean): Promise; - /** * Show the window. * @returns {Promise} A promise that resolves to nothing when the window is showing. @@ -352,15 +260,9 @@ export interface Window { */ minimize(): Promise; - /** - * Unmaximize the window. - * @returns {Promise} A promise that resolves to nothing when the window has unmaximized. - */ - unmaximize(): Promise; - /** * Send a message to the window. * @param {string|object} message - The message to send to the window. Can be any serializable object. */ - postMessage(message: string | Object): void; + sendMessage(message: string | object): Promise; } \ No newline at end of file From 692cffe1ff2fa74a059aa31387088fee27bf3335 Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Sat, 27 May 2017 02:01:43 +0300 Subject: [PATCH 06/22] messages update --- packages/api-specification/api/messages.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/api-specification/api/messages.ts b/packages/api-specification/api/messages.ts index 6c8d9e2..8575337 100644 --- a/packages/api-specification/api/messages.ts +++ b/packages/api-specification/api/messages.ts @@ -4,7 +4,9 @@ * Currently this is based on OpenFin bus */ export interface MessagesAPI{ - send(windowId: string, topic: string, message: string|object): void; - subscribe(windowId: string, topic: string, listener: Function): void; + send(destinationUuid: string, topic: string, message: string|object): void; + publish(topic: string, message: string|object); + + subscribe(destinationUuid: string, topic: string, listener: Function): void; unsubscribe(windowId: string, topic: string, listener: Function): void; } \ No newline at end of file From dc3e0ec844419a5a449541ee17ddf54faa60a20a Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Sat, 27 May 2017 11:38:24 +0300 Subject: [PATCH 07/22] updated openfin link --- packages/api-specification/api/messages.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/api-specification/api/messages.ts b/packages/api-specification/api/messages.ts index 8575337..74ac170 100644 --- a/packages/api-specification/api/messages.ts +++ b/packages/api-specification/api/messages.ts @@ -1,7 +1,6 @@ -// ⚠ TODO Revise - are we ok with bus pub/sub (the current model) or we want to propose AGM like RPC - /** - * Currently this is based on OpenFin bus + * Currently this is based on OpenFin InterApplicationBus + * http://cdn.openfin.co/jsdocs/stable/fin.desktop.InterApplicationBus.html */ export interface MessagesAPI{ send(destinationUuid: string, topic: string, message: string|object): void; From 3499feb2f369512f86ec48ebce164103febd5b50 Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Sun, 28 May 2017 10:00:47 +0300 Subject: [PATCH 08/22] WIP --- packages/api-specification/api/common.ts | 8 +++ packages/api-specification/api/confluence.md | 60 ++++++++++++++++++++ packages/api-specification/api/windows.ts | 37 +++++++++--- 3 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 packages/api-specification/api/confluence.md diff --git a/packages/api-specification/api/common.ts b/packages/api-specification/api/common.ts index 62cf2bb..e65ae53 100644 --- a/packages/api-specification/api/common.ts +++ b/packages/api-specification/api/common.ts @@ -9,4 +9,12 @@ export interface Bounds { export interface Size{ width: number; height: number; +} + +/** + * Function returned from event subscription functions (e.g. onWindowBoundsChanged). + * Executing it will remove the event handler. + */ +export interface UnsubscribeFunction { + (): void; } \ No newline at end of file diff --git a/packages/api-specification/api/confluence.md b/packages/api-specification/api/confluence.md new file mode 100644 index 0000000..fa86bc7 --- /dev/null +++ b/packages/api-specification/api/confluence.md @@ -0,0 +1,60 @@ +## [Activate API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/Activate+API) + +> This api allows a window to be move to the front and given focus. This API is needed since JS web apps have no capability to perform such a function. + +The API proposal introduces window management section that enables the user to create, discover and manage windows. +It also defines a window object that has a set of properties and methods. + +One of these methods is activate that will bring the window to front and focus it: +```javascript +// activate my window +var myWindow = ssf.windows.current; +myWindow.activate(); + +// activate some other window +var someWindow = ssf.windows.getById('4'); +someWindow.activate(); +``` + +## [RegisterBoundsChange API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/RegisterBoundsChange+API) +> This API allows JS web app to register a callback that will be notified whenever any child window's size or position changes. The primary motivation is to support a feature called "saved layout". This feature allows the symphony web app to save the size and location of child windows and restore them when the app is restarted (or refreshed). + +Using the windows API the application can subscribe for +```javascript +ssf.windows.onWindowBoundsChanged(function(window, bounds){ + +}) +``` + +Or it can subscribe for each window individually +```javascript +someWindow.on('boundsChanged', function(bounds){ + +}); +``` + +Or it can iterate the windows when the layout should be saved +```javascript +ssf.windows.all.forEach(function(window){ + var boundsToSave = window.bounds; +}); +``` +## [Activity API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/Activity+API) +> The application needs to be informed if activity (keyboard or mouse input) has occurred. + +Another section in the proposal is system API that allows the application to access system specific stuff. + + +```javascript +ssf.system.onUserActivity(function(){ + +}, 1000); +``` + +## ScreenSnippet API + +## getMediaSources API + +## BadgeCount API +## Notification API +## Version API \ No newline at end of file diff --git a/packages/api-specification/api/windows.ts b/packages/api-specification/api/windows.ts index 76206a8..aec4181 100644 --- a/packages/api-specification/api/windows.ts +++ b/packages/api-specification/api/windows.ts @@ -1,4 +1,4 @@ -import {Bounds} from "./common"; +import {Bounds, UnsubscribeFunction} from "./common"; export interface WindowsAPI { @@ -8,14 +8,34 @@ export interface WindowsAPI { /** Returns all windows in the application */ all: Window[]; - /** Opens a new window */ + /** + * The window that is focused in this application, otherwise returns null + */ + focusedWindow: Window; + + /** + getById(windowId: string): Window; + + /** Opens a new window */ open(options: WindowOptions): Promise; - /** Receive notifications when a new window is opened */ - onWindowOpened(callback: (window: Window) => void); + /** + * Receive notifications when a new window is opened + * @returns Function Execute the function to unsubscribe + */ + onWindowOpened(callback: (window: Window) => void): UnsubscribeFunction; + + /** + * Receive notifications when a window was closed + * @returns Function Execute the function to unsubscribe + */ + onWindowClosed(callback: (window: Window) => void): UnsubscribeFunction; - /** Receive notifications when a window was closed */ - onWindowClosed(callback: (window: Window) => void); + /** + * Subscribe for bounds changed event for all windows + * @returns Function Execute the function to unsubscribe + */ + onWindowBoundsChanged(callback: (window: Window, bounds: Bounds) => void): UnsubscribeFunction; } export interface WindowOptions { @@ -190,10 +210,11 @@ export interface Window { flashFrame(flag: boolean): Promise; /** - * Focuses the window. + * Activates the window. This will bring the window to front or restore it if minimized. + * If focus flag is true (default) the window will also receive input focus. * @returns {Promise} A promise which resolves to nothing when the function has completed. */ - focus(): Promise; + activate(focus?: boolean): Promise; /** * Get the child windows of the window. From ec4242995ae49d08d5615bd16838526fde0b6262 Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Sun, 28 May 2017 14:24:54 +0300 Subject: [PATCH 09/22] WIP --- packages/api-specification/api/application.ts | 5 +- packages/api-specification/api/confluence.md | 46 +++++++++++++++---- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/packages/api-specification/api/application.ts b/packages/api-specification/api/application.ts index faf4155..d3210a6 100644 --- a/packages/api-specification/api/application.ts +++ b/packages/api-specification/api/application.ts @@ -1,12 +1,11 @@ - export interface ApplicationAPI { config: ApplicationConfig; /** Sets the counter badge for current app. Setting the count to 0 will hide the badge.*/ - setBadgeCount(count: number): boolean; + setBadgeCount(count: number); /** The current value displayed in the counter badge.*/ - getBadgeCount():number; + getBadgeCount(): number; /** Returns an array containing the command line arguments passed when application was launched */ argv: string[]; diff --git a/packages/api-specification/api/confluence.md b/packages/api-specification/api/confluence.md index fa86bc7..753b76e 100644 --- a/packages/api-specification/api/confluence.md +++ b/packages/api-specification/api/confluence.md @@ -26,14 +26,14 @@ ssf.windows.onWindowBoundsChanged(function(window, bounds){ }) ``` -Or it can subscribe for each window individually +or it can subscribe for each window individually ```javascript someWindow.on('boundsChanged', function(bounds){ }); ``` -Or it can iterate the windows when the layout should be saved +or it can iterate the windows when the layout should be saved ```javascript ssf.windows.all.forEach(function(window){ var boundsToSave = window.bounds; @@ -44,17 +44,47 @@ ssf.windows.all.forEach(function(window){ Another section in the proposal is system API that allows the application to access system specific stuff. - +The application can subscribe for user activity events: ```javascript ssf.system.onUserActivity(function(){ }, 1000); ``` -## ScreenSnippet API +## [ScreenSnippet API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/ScreenSnippet+API) +> The ScreenSnippet API is used to capture a snippet of their desktop (unconstrained by the host application window) and highlight portions of this snippet so it can then be consumed by the host application. This functionality is similar to the Windows Screen Snippet tool when used in rectangle capture mode. This lets a user captures portions of the Windows Desktop, highlight aspects of the image and then save this image for sharing. + +```javascript + +``` +## [getMediaSources API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/getMediaSources+API) +> In order to support screen sharing the client api needs enumerate screens and windows. +> This api provided a list of screens (each monitor) and list of windows available; providing title, id and thumbnail. This api is essentially equivalent of electron api: https://electron.atom.io/docs/api/desktop-capturer/#desktopcapturergetsourcesoptions-callback + +```javascript + +``` +## [BadgeCount API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/BadgeCount+API) +> Display a number on the application icon in the desktop tray... usually to indicate number of unread messages for given application. + +There is application section that provides information about application config and allows +interactions with app specific functionalities like badgeCounts + +// TODO is this per application or per window???? + +```javascript +ssf.application.setBadgeCount(11); +``` +## [Notification API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/Notification+API) +>The Notifications API is used to configure and display desktop notifications to the user. It is exposed as an extension to the HTML5 Notification API, providing additional functionality that is useful for financial desktop applications. +> +>The exact visual style and the extent of the OS-level integration is container dependent and hence out-of-scope of this specification. + +## [Version API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/Version+API) +> This API allows the JS web app to interrogate the container to find version support information. One possible use case is to get ssf API version supported so that in future it is possible to deprecate older containers that do not support latest version of API. Another possible use case is for logging purposes to help support track down issues. -## getMediaSources API +There is an info section in the API that provides the api version and also container information (version, capabilities, etc) -## BadgeCount API -## Notification API -## Version API \ No newline at end of file +```javascript +var apiVersion = ssf.info.apiVersion; +``` \ No newline at end of file From 336f251dfa2946b9d80c6becd886453806b07390 Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Sun, 28 May 2017 23:07:49 +0300 Subject: [PATCH 10/22] WIP --- packages/api-specification/api/confluence.md | 22 +++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/api-specification/api/confluence.md b/packages/api-specification/api/confluence.md index 753b76e..5b8d2d4 100644 --- a/packages/api-specification/api/confluence.md +++ b/packages/api-specification/api/confluence.md @@ -26,14 +26,14 @@ ssf.windows.onWindowBoundsChanged(function(window, bounds){ }) ``` -or it can subscribe for each window individually +or subscribe for each window individually ```javascript someWindow.on('boundsChanged', function(bounds){ }); ``` -or it can iterate the windows when the layout should be saved +or iterate the windows when the layout should be saved ```javascript ssf.windows.all.forEach(function(window){ var boundsToSave = window.bounds; @@ -51,17 +51,25 @@ ssf.system.onUserActivity(function(){ }, 1000); ``` -## [ScreenSnippet API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/ScreenSnippet+API) -> The ScreenSnippet API is used to capture a snippet of their desktop (unconstrained by the host application window) and highlight portions of this snippet so it can then be consumed by the host application. This functionality is similar to the Windows Screen Snippet tool when used in rectangle capture mode. This lets a user captures portions of the Windows Desktop, highlight aspects of the image and then save this image for sharing. +## [getMediaSources API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/getMediaSources+API) +> In order to support screen sharing the client api needs enumerate screens and windows. +> This api provided a list of screens (each monitor) and list of windows available; providing title, id and thumbnail. This api is essentially equivalent of electron api: https://electron.atom.io/docs/api/desktop-capturer/#desktopcapturergetsourcesoptions-callback ```javascript ``` -## [getMediaSources API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/getMediaSources+API) -> In order to support screen sharing the client api needs enumerate screens and windows. -> This api provided a list of screens (each monitor) and list of windows available; providing title, id and thumbnail. This api is essentially equivalent of electron api: https://electron.atom.io/docs/api/desktop-capturer/#desktopcapturergetsourcesoptions-callback + +## [ScreenSnippet API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/ScreenSnippet+API) +> The ScreenSnippet API is used to capture a snippet of their desktop (unconstrained by the host application window) and highlight portions of this snippet so it can then be consumed by the host application. This functionality is similar to the Windows Screen Snippet tool when used in rectangle capture mode. This lets a user captures portions of the Windows Desktop, highlight aspects of the image and then save this image for sharing. ```javascript +ssf.system.capture(); + +ssf.system.captureDisplay(); + +ssf.system.captureWindow(); + +ssf.system.captureAllWindows(); ``` ## [BadgeCount API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/BadgeCount+API) From 4ef36d092cc700f1b73f65210a0eaf4ab73af12a Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Sun, 28 May 2017 23:45:49 +0300 Subject: [PATCH 11/22] Updates --- packages/api-specification/api/confluence.md | 38 ++++++++++++-------- packages/api-specification/api/system.ts | 31 ++++++++++------ packages/api-specification/api/windows.ts | 7 ++++ 3 files changed, 52 insertions(+), 24 deletions(-) diff --git a/packages/api-specification/api/confluence.md b/packages/api-specification/api/confluence.md index 5b8d2d4..dd9f506 100644 --- a/packages/api-specification/api/confluence.md +++ b/packages/api-specification/api/confluence.md @@ -1,6 +1,6 @@ ## [Activate API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/Activate+API) -> This api allows a window to be move to the front and given focus. This API is needed since JS web apps have no capability to perform such a function. +> This api alseparateindow to be move to the front and given focus. This API is needed since JS web apps have no capability to perform such a function. The API proposal introduces window management section that enables the user to create, discover and manage windows. It also defines a window object that has a set of properties and methods. @@ -51,35 +51,45 @@ ssf.system.onUserActivity(function(){ }, 1000); ``` -## [getMediaSources API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/getMediaSources+API) +## [getMediaSources API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/getMediaSources+API) and [ScreenSnippet API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/ScreenSnippet+API) > In order to support screen sharing the client api needs enumerate screens and windows. > This api provided a list of screens (each monitor) and list of windows available; providing title, id and thumbnail. This api is essentially equivalent of electron api: https://electron.atom.io/docs/api/desktop-capturer/#desktopcapturergetsourcesoptions-callback -```javascript - -``` - -## [ScreenSnippet API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/ScreenSnippet+API) > The ScreenSnippet API is used to capture a snippet of their desktop (unconstrained by the host application window) and highlight portions of this snippet so it can then be consumed by the host application. This functionality is similar to the Windows Screen Snippet tool when used in rectangle capture mode. This lets a user captures portions of the Windows Desktop, highlight aspects of the image and then save this image for sharing. - +Using the system API the user can enumerate the displays and capture any of them ```javascript -ssf.system.capture(); +// capture all screens +ssf.system.capture().then(function(image){ + +}); -ssf.system.captureDisplay(); +// capture each screen as separate image +ssf.system.captureAllDisplays().then(function(images) { + +}); -ssf.system.captureWindow(); +// capture specific display only +ssf.system.displays[0].capture(); -ssf.system.captureAllWindows(); +// Capture all windows as separate images with custom size +ssf.system.captureAllWindows({imageSize: {width: 100, height: 100}}) + .then(function(images){ + + }); +// capture specific window only +ssf.system.captureWindow(windowId); +// same as +var window = ... +window.capture(); ``` + ## [BadgeCount API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/BadgeCount+API) > Display a number on the application icon in the desktop tray... usually to indicate number of unread messages for given application. There is application section that provides information about application config and allows interactions with app specific functionalities like badgeCounts -// TODO is this per application or per window???? - ```javascript ssf.application.setBadgeCount(11); ``` diff --git a/packages/api-specification/api/system.ts b/packages/api-specification/api/system.ts index b3ff447..0c2888a 100644 --- a/packages/api-specification/api/system.ts +++ b/packages/api-specification/api/system.ts @@ -4,20 +4,22 @@ export interface SystemAPI { /** * Info about all displays available */ - displays: () => DisplayInfo[]; + displays: () => Display[]; /** * Capture * @param options */ - capture: (options?: CaptureOptions) => Promise; + capture: (options?: CaptureOptions) => Promise; /** * Capture specific display * @param displayId * @param options */ - captureDisplay: (displayId: number, options?: CaptureOptions) => Promise; + captureDisplay: (displayId: number, options?: CaptureOptions) => Promise; + + captureAllDisplays: (options?: CaptureOptions) => Promise; /** * Capture specific window @@ -39,11 +41,13 @@ export interface SystemAPI { */ onUserActivity(callback: ()=> void, throtle: number); - /** Operating system information */ + /** + * Operating system information + */ os: OperatingSystemInfo; } -export interface DisplayInfo { +export interface Display { /** Unique identifier associated with the display. */ id: number; @@ -61,6 +65,8 @@ export interface DisplayInfo { /** Working area of the display */ workingArea: Bounds; + + capture(): Promise; } export interface OperatingSystemInfo{ @@ -70,15 +76,20 @@ export interface OperatingSystemInfo{ } export interface CaptureOptions { - captureSize: Size; + imageSize: Size; +} + +export interface DisplayImageData extends Base64ImageData{ + display: Display; } -export interface WindowImageData { - windowId: string; - image: ImageData; +export interface WindowImageData extends Base64ImageData { + window: Window; } -export interface ImageData { +export interface Base64ImageData { type: string; data: string; + width: number; + height: number; } \ No newline at end of file diff --git a/packages/api-specification/api/windows.ts b/packages/api-specification/api/windows.ts index aec4181..0d6b54b 100644 --- a/packages/api-specification/api/windows.ts +++ b/packages/api-specification/api/windows.ts @@ -1,4 +1,5 @@ import {Bounds, UnsubscribeFunction} from "./common"; +import {Base64ImageData, CaptureOptions} from "./system"; export interface WindowsAPI { @@ -216,6 +217,12 @@ export interface Window { */ activate(focus?: boolean): Promise; + /** + * Captures an image of the window + * @param options + */ + capture(options?: CaptureOptions): Promise; + /** * Get the child windows of the window. */ From 79ce8b60c341fcf08a062a62cd8a01a9a67503bc Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Sun, 28 May 2017 23:52:43 +0300 Subject: [PATCH 12/22] Updates --- packages/api-specification/api/application.ts | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/packages/api-specification/api/application.ts b/packages/api-specification/api/application.ts index d3210a6..a7cb4cf 100644 --- a/packages/api-specification/api/application.ts +++ b/packages/api-specification/api/application.ts @@ -1,14 +1,28 @@ export interface ApplicationAPI { - config: ApplicationConfig; + /** + * Returns an array containing the command line arguments passed when application was launched + */ + argv: string[]; - /** Sets the counter badge for current app. Setting the count to 0 will hide the badge.*/ - setBadgeCount(count: number); + /** + * Application configuration object (as defined in app.json file) + */ + config: ApplicationConfig; - /** The current value displayed in the counter badge.*/ + /** + * The current value displayed in the counter badge. + */ getBadgeCount(): number; - /** Returns an array containing the command line arguments passed when application was launched */ - argv: string[]; + /** + * Sets the counter badge for current app. Setting the count to 0 will hide the badge. + */ + setBadgeCount(count: number); + + /** + * Shutdown the application + */ + shutdown: () => void; } export interface ApplicationConfig { From 017c6412a0fdaaac1e9437d0c3a1dd1c2fbae641 Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Mon, 29 May 2017 09:02:58 +0300 Subject: [PATCH 13/22] WIP --- packages/api-specification/api/confluence.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/api-specification/api/confluence.md b/packages/api-specification/api/confluence.md index dd9f506..c6a5b87 100644 --- a/packages/api-specification/api/confluence.md +++ b/packages/api-specification/api/confluence.md @@ -1,6 +1,7 @@ ## [Activate API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/Activate+API) -> This api alseparateindow to be move to the front and given focus. This API is needed since JS web apps have no capability to perform such a function. +> This api allows a window to be move to the front and given focus. This API is needed since JS web apps have no capability to perform such a function. +> An example use case might be: the main window might be minimized (or otherwise hidden) and the notification shows that the user then clicks on. The web app needs to ability to bring the window to the foreground and give focus. The API proposal introduces window management section that enables the user to create, discover and manage windows. It also defines a window object that has a set of properties and methods. From 5e6e4cd9cf2a3088c4f2e4217b6dd4de98bae497 Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Mon, 29 May 2017 09:06:47 +0300 Subject: [PATCH 14/22] WIP --- packages/api-specification/api/confluence.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/api-specification/api/confluence.md b/packages/api-specification/api/confluence.md index c6a5b87..6daa33c 100644 --- a/packages/api-specification/api/confluence.md +++ b/packages/api-specification/api/confluence.md @@ -99,6 +99,10 @@ ssf.application.setBadgeCount(11); > >The exact visual style and the extent of the OS-level integration is container dependent and hence out-of-scope of this specification. +The notification API that we propose is following the HTML5 notifications standard (https://developer.mozilla.org/en-US/docs/Web/API/notification) + +If we need any extensions these can be added on top of it. + ## [Version API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/Version+API) > This API allows the JS web app to interrogate the container to find version support information. One possible use case is to get ssf API version supported so that in future it is possible to deprecate older containers that do not support latest version of API. Another possible use case is for logging purposes to help support track down issues. From ca5ae28ccfda3d64a13ad92c1ebcff309c244a2c Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Wed, 31 May 2017 11:23:39 +0300 Subject: [PATCH 15/22] WIP --- packages/api-specification/api/confluence.md | 8 ++-- packages/api-specification/api/messages.ts | 13 +++--- packages/api-specification/api/system.ts | 7 ---- packages/api-specification/api/windows.ts | 44 +++++++++++++------- packages/api-specification/interface.ts | 5 +++ 5 files changed, 42 insertions(+), 35 deletions(-) diff --git a/packages/api-specification/api/confluence.md b/packages/api-specification/api/confluence.md index 6daa33c..a9dd0a7 100644 --- a/packages/api-specification/api/confluence.md +++ b/packages/api-specification/api/confluence.md @@ -37,7 +37,7 @@ someWindow.on('boundsChanged', function(bounds){ or iterate the windows when the layout should be saved ```javascript ssf.windows.all.forEach(function(window){ - var boundsToSave = window.bounds; + var boundsToSave = window.getBounds(); }); ``` ## [Activity API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/Activity+API) @@ -78,10 +78,8 @@ ssf.system.captureAllWindows({imageSize: {width: 100, height: 100}}) }); -// capture specific window only -ssf.system.captureWindow(windowId); -// same as -var window = ... +// Capture specific window (this goes throught the window API) +var window = ssf.windows.current; window.capture(); ``` diff --git a/packages/api-specification/api/messages.ts b/packages/api-specification/api/messages.ts index 74ac170..3fd723f 100644 --- a/packages/api-specification/api/messages.ts +++ b/packages/api-specification/api/messages.ts @@ -1,11 +1,10 @@ /** - * Currently this is based on OpenFin InterApplicationBus - * http://cdn.openfin.co/jsdocs/stable/fin.desktop.InterApplicationBus.html + * Currently this is based on OpenFin InterApplicationBus - http://cdn.openfin.co/jsdocs/stable/fin.desktop.InterApplicationBus.html + * + * TBD - Request/response and streaming */ export interface MessagesAPI{ - send(destinationUuid: string, topic: string, message: string|object): void; - publish(topic: string, message: string|object); - - subscribe(destinationUuid: string, topic: string, listener: Function): void; - unsubscribe(windowId: string, topic: string, listener: Function): void; + send(windowId: string, topic :string, message: string|object): void; + subscribe(windowId: string, topic :string, listener: Function): void; + unsubscribe(windowId: string, topic :string, listener: Function): void; } \ No newline at end of file diff --git a/packages/api-specification/api/system.ts b/packages/api-specification/api/system.ts index 0c2888a..ba37f8e 100644 --- a/packages/api-specification/api/system.ts +++ b/packages/api-specification/api/system.ts @@ -21,13 +21,6 @@ export interface SystemAPI { captureAllDisplays: (options?: CaptureOptions) => Promise; - /** - * Capture specific window - * @param windowId - * @param options - */ - captureWindow: (windowId: string, options?: CaptureOptions) => Promise; - /** * Capture all windows in a separate images * @param options diff --git a/packages/api-specification/api/windows.ts b/packages/api-specification/api/windows.ts index 0d6b54b..8610dfc 100644 --- a/packages/api-specification/api/windows.ts +++ b/packages/api-specification/api/windows.ts @@ -1,5 +1,6 @@ import {Bounds, UnsubscribeFunction} from "./common"; import {Base64ImageData, CaptureOptions} from "./system"; +import EventEmitter = NodeJS.EventEmitter; export interface WindowsAPI { @@ -39,6 +40,7 @@ export interface WindowsAPI { onWindowBoundsChanged(callback: (window: Window, bounds: Bounds) => void): UnsubscribeFunction; } +/** Window options used to open a new window **/ export interface WindowOptions { /** * Default window title. @@ -137,29 +139,29 @@ export interface WindowOptions { transparent: boolean; } -export interface Window { +/** + * A window running in the container. + * It implements EventEmitter which means users can subscribe for events using on, once , addEventListener etc. + * The list of events is in WindowsEvents structure; + */ +export interface Window extends EventEmitter { - constructor(options: WindowOptions); + /** Get or set the max width of the window. Might be undefined if no restrictions applied**/ + maxWidth?: number; - /** - * Get or set the bounds of the window. - */ - bounds: Bounds; + /** Get or set the min width of the window. Might be undefined if no restrictions applied**/ + minWidth?: number; - /** - * Get or set if the window has a shadow. - */ - hasShadow: boolean; + /** Get or set the max height of the window. Might be undefined if no restrictions applied**/ + maxHeight: number; - /** - * Get or set the maximum size of the window. - */ - maximumSize: Bounds; + /** Get or set the min height of the window. Might be undefined if no restrictions applied**/ + minHeight: number; /** - * Get or set the minimum size of the window. + * Get or set if the window has a shadow. */ - minimumSize: Bounds; + hasShadow: boolean; /** * Get or set the title of the window @@ -223,6 +225,9 @@ export interface Window { */ capture(options?: CaptureOptions): Promise; + /** Get the bounds of the window */ + getBounds(): Bounds; + /** * Get the child windows of the window. */ @@ -263,6 +268,9 @@ export interface Window { */ restore(): Promise; + /** Set new bounds */ + setBounds(bounds: Bounds); + /** * Sets the window icon. * @param {string} icon - The url to the image. @@ -293,4 +301,8 @@ export interface Window { * @param {string|object} message - The message to send to the window. Can be any serializable object. */ sendMessage(message: string | object): Promise; +} + +export interface WindowEvents { + } \ No newline at end of file diff --git a/packages/api-specification/interface.ts b/packages/api-specification/interface.ts index e92bd53..f7217d4 100644 --- a/packages/api-specification/interface.ts +++ b/packages/api-specification/interface.ts @@ -395,6 +395,11 @@ declare namespace ssf { static unsubscribe(windowId: string, topic :string, listener: Function): void; } + interface Interop{ + + + } + class ScreenSnippet { capture(): Promise; } From 24c1dc7e863e7d4c41d99c289e19defdc13fe66e Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Wed, 31 May 2017 12:47:44 +0300 Subject: [PATCH 16/22] updated --- packages/api-specification/api/windows.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/api-specification/api/windows.ts b/packages/api-specification/api/windows.ts index 8610dfc..1488975 100644 --- a/packages/api-specification/api/windows.ts +++ b/packages/api-specification/api/windows.ts @@ -303,6 +303,11 @@ export interface Window extends EventEmitter { sendMessage(message: string | object): Promise; } -export interface WindowEvents { - -} \ No newline at end of file +/** To be extended **/ +export type WindowEvents = + 'moved'| + 'resized'| + 'closed'| + 'focused' | + 'maximized' | + 'minimized'; \ No newline at end of file From 397ab4f49c966b01e831da6b57090d02ad1bfb5c Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Wed, 31 May 2017 13:13:35 +0300 Subject: [PATCH 17/22] readme --- packages/api-specification/api/readme.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 packages/api-specification/api/readme.md diff --git a/packages/api-specification/api/readme.md b/packages/api-specification/api/readme.md new file mode 100644 index 0000000..c0cac94 --- /dev/null +++ b/packages/api-specification/api/readme.md @@ -0,0 +1,6 @@ +This is an attempt to define an API that + +This is an initial version that aims to start a discussion - some parts of it are not fully defined (e.g. window events) and some +upcoming parts are just mentioned in comments (e.g. interop). + +This also contains a [document](./confluence.md) describing how it maps to the API described in confluence. \ No newline at end of file From a1c780d459dc3274968d2691c3ee13ede43b9e94 Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Wed, 31 May 2017 13:16:45 +0300 Subject: [PATCH 18/22] updated readme.md --- packages/api-specification/api/readme.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/api-specification/api/readme.md b/packages/api-specification/api/readme.md index c0cac94..5589146 100644 --- a/packages/api-specification/api/readme.md +++ b/packages/api-specification/api/readme.md @@ -1,6 +1,9 @@ -This is an attempt to define an API that +This is an attempt to define an API that tries to unify what we currently have in ContainerJS, [the working group](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/Proposed+Standard+API+Specifications) +and things that Tick42 are usefull based on our experience. This is an initial version that aims to start a discussion - some parts of it are not fully defined (e.g. window events) and some upcoming parts are just mentioned in comments (e.g. interop). -This also contains a [document](./confluence.md) describing how it maps to the API described in confluence. \ No newline at end of file +This also contains a [document](./confluence.md) describing how it maps to the API described in confluence. + +The starting point when reading the code should be [ssf.ts](./ssf.ts) file that describes the ssf root object as exposed to clients applications. \ No newline at end of file From 98491cd35c8084a69b859438354f788daa9424fd Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Wed, 31 May 2017 13:17:47 +0300 Subject: [PATCH 19/22] updated readme --- packages/api-specification/api/readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/api-specification/api/readme.md b/packages/api-specification/api/readme.md index 5589146..fb63869 100644 --- a/packages/api-specification/api/readme.md +++ b/packages/api-specification/api/readme.md @@ -1,9 +1,9 @@ -This is an attempt to define an API that tries to unify what we currently have in ContainerJS, [the working group](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/Proposed+Standard+API+Specifications) -and things that Tick42 are usefull based on our experience. +This is an attempt to define an API that tries to unify what we currently have in ContainerJS, [the working group APIs](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/Proposed+Standard+API+Specifications) +and things that we at Tick42 think are useful based on our experience. This is an initial version that aims to start a discussion - some parts of it are not fully defined (e.g. window events) and some upcoming parts are just mentioned in comments (e.g. interop). -This also contains a [document](./confluence.md) describing how it maps to the API described in confluence. +This also contains a [document](./confluence.md) describing how to map the [confluence API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/Proposed+Standard+API+Specifications) to the current API. The starting point when reading the code should be [ssf.ts](./ssf.ts) file that describes the ssf root object as exposed to clients applications. \ No newline at end of file From 96bd363b61a25b02ec3b30b7ed6d6787ba5ff4ba Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Wed, 31 May 2017 13:26:16 +0300 Subject: [PATCH 20/22] Revert "WIP" This reverts commit ca5ae28ccfda3d64a13ad92c1ebcff309c244a2c. # Conflicts: # packages/api-specification/api/windows.ts --- packages/api-specification/interface.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/api-specification/interface.ts b/packages/api-specification/interface.ts index f7217d4..e92bd53 100644 --- a/packages/api-specification/interface.ts +++ b/packages/api-specification/interface.ts @@ -395,11 +395,6 @@ declare namespace ssf { static unsubscribe(windowId: string, topic :string, listener: Function): void; } - interface Interop{ - - - } - class ScreenSnippet { capture(): Promise; } From 8c17293b8676085398ee2a15d254adef562c98ea Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Wed, 31 May 2017 13:29:13 +0300 Subject: [PATCH 21/22] max* to be optional --- packages/api-specification/api/windows.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/api-specification/api/windows.ts b/packages/api-specification/api/windows.ts index 1488975..2fd9d9b 100644 --- a/packages/api-specification/api/windows.ts +++ b/packages/api-specification/api/windows.ts @@ -153,10 +153,10 @@ export interface Window extends EventEmitter { minWidth?: number; /** Get or set the max height of the window. Might be undefined if no restrictions applied**/ - maxHeight: number; + maxHeight?: number; /** Get or set the min height of the window. Might be undefined if no restrictions applied**/ - minHeight: number; + minHeight?: number; /** * Get or set if the window has a shadow. From 2da00912a6bd647746b41618e446f3c2aa1fd156 Mon Sep 17 00:00:00 2001 From: Kiril Popov Date: Wed, 31 May 2017 13:31:46 +0300 Subject: [PATCH 22/22] most thigns in WindowOptions should be optional --- packages/api-specification/api/windows.ts | 34 +++++++++++------------ 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/api-specification/api/windows.ts b/packages/api-specification/api/windows.ts index 2fd9d9b..73bb9f6 100644 --- a/packages/api-specification/api/windows.ts +++ b/packages/api-specification/api/windows.ts @@ -56,87 +56,87 @@ export interface WindowOptions { * Window initial bounds. Can contain partial bounds (e.g width only) and be * combined with center */ - bounds: Bounds; + bounds?: Bounds; /** * Window’s maximum width. */ - maxWidth: number; + maxWidth?: number; /** * Window’s minimum width. */ - minWidth: number; + minWidth?: number; /** * Window’s maximum height. */ - maxHeight: number; + maxHeight?: number; /** * Window’s minimum height. */ - minHeight: number; + minHeight?: number; /** * Whether the window should always stay on top of other windows. Default is false. */ - alwaysOnTop: boolean; + alwaysOnTop?: boolean; /** * Window’s background color as Hexadecimal value. */ - backgroundColor: string; + backgroundColor?: string; /** * Whether the window is a child of the current window. Default is false. */ - child: boolean; + child?: boolean; /** * Show window in the center of the screen. */ - center: boolean; + center?: boolean; /** * If false, creates a frameless window. Default is true. */ - frame: boolean; + frame?: boolean; /** * Whether window should have a shadow. This is only implemented on macOS. Default is true. */ - hasShadow: boolean; + hasShadow?: boolean; /** * Whether window is maximizable. Default is true. */ - maximizable: boolean; + maximizable?: boolean; /** * Whether window is minimizable. Default is true. */ - minimizable: boolean; + minimizable?: boolean; /** * Whether window is resizable. Default is true. */ - resizable: boolean + resizable?: boolean /** * Whether window should be shown when created. Default is true. */ - show: boolean; + show?: boolean; /** * Whether to show the window in taskbar. Default is false. */ - skipTaskbar: boolean; + skipTaskbar?: boolean; /** * Makes the window transparent. Default is false. */ - transparent: boolean; + transparent?: boolean; } /**