From 03dd26597b56ef50fab70066aae0aabdb1fe5d97 Mon Sep 17 00:00:00 2001 From: hristoterezov Date: Thu, 6 Jul 2017 21:48:03 -0500 Subject: [PATCH 1/2] ref: Extract remote control and SS to jitsi-meet-electron-utils --- README.md | 4 - modules/remotecontrol/constants.js | 28 -- modules/remotecontrol/index.js | 241 ------------------ modules/screensharing/index.js | 33 --- node_addons/sourceId2Coordinates/binding.gyp | 27 -- node_addons/sourceId2Coordinates/index.js | 22 -- node_addons/sourceId2Coordinates/package.json | 17 -- node_addons/sourceId2Coordinates/src/index.cc | 37 --- .../src/sourceId2Coordinates.cc | 45 ---- .../src/sourceId2Coordinates.h | 7 - package.json | 4 +- windows/jitsi-meet/render.js | 21 +- 12 files changed, 7 insertions(+), 479 deletions(-) delete mode 100644 modules/remotecontrol/constants.js delete mode 100644 modules/remotecontrol/index.js delete mode 100644 modules/screensharing/index.js delete mode 100644 node_addons/sourceId2Coordinates/binding.gyp delete mode 100644 node_addons/sourceId2Coordinates/index.js delete mode 100644 node_addons/sourceId2Coordinates/package.json delete mode 100644 node_addons/sourceId2Coordinates/src/index.cc delete mode 100644 node_addons/sourceId2Coordinates/src/sourceId2Coordinates.cc delete mode 100644 node_addons/sourceId2Coordinates/src/sourceId2Coordinates.h diff --git a/README.md b/README.md index 430f630..b20f0f1 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,6 @@ from config.js ```bash npm install ``` -Since node_addons/sourceId2Coordinates add-on is local dependency, every code change requires increasing the version in its package.json. To rebuild the add-on if it is already installed execute: -```bash -npm update -``` ## Statring the application ```bash diff --git a/modules/remotecontrol/constants.js b/modules/remotecontrol/constants.js deleted file mode 100644 index edd2e6b..0000000 --- a/modules/remotecontrol/constants.js +++ /dev/null @@ -1,28 +0,0 @@ -module.exports = { - /** - * Types of remote-control events. - */ - EVENTS: { - mousemove: "mousemove", - mousedown: "mousedown", - mouseup: "mouseup", - mousedblclick: "mousedblclick", - mousescroll: "mousescroll", - keydown: "keydown", - keyup: "keyup", - stop: "stop", - supported: "supported" - }, - - /** - * Types of remote-control requests. - */ - REQUESTS: { - start: "start" - }, - - /** - * The name of remote control messages. - */ - REMOTE_CONTROL_MESSAGE_NAME: "remote-control" -}; diff --git a/modules/remotecontrol/index.js b/modules/remotecontrol/index.js deleted file mode 100644 index 4efcdad..0000000 --- a/modules/remotecontrol/index.js +++ /dev/null @@ -1,241 +0,0 @@ -let robot = require("robotjs"); -const sourceId2Coordinates = require("sourceId2Coordinates"); -const electron = require("electron"); -const constants = require("../../modules/remotecontrol/constants"); -const { EVENTS, REQUESTS, REMOTE_CONTROL_MESSAGE_NAME } = constants; - -/** - * Attaching to the window for debug purposes. - * We should remove this in production. - */ -window.robot = robot; - -/** - * Mouse button mapping between the values in remote control mouse event and - * robotjs methods. - */ -const MOUSE_BUTTONS = { - 1: "left", - 2: "middle", - 3: "right" -}; - -/** - * Mouse actions mapping between the values in remote control mouse event and - * robotjs methods. - */ -const MOUSE_ACTIONS_FROM_EVENT_TYPE = { - "mousedown": "down", - "mouseup": "up" -}; - -/** - * Key actions mapping between the values in remote control key event and - * robotjs methods. - */ -const KEY_ACTIONS_FROM_EVENT_TYPE = { - "keydown": "down", - "keyup": "up" -}; - -/** - * The status ("up"/"down") of the mouse button. - * FIXME: Assuming that one button at a time can be pressed. Haven't noticed - * any issues but maybe we should store the status for every mouse button - * that we are processing. - */ -let mouseButtonStatus = "up"; - -/** - * Parses the remote control events and executes them via robotjs. - */ -class RemoteControl { - /** - * Constructs new instance and initializes the remote control functionality. - * - * @param {Postis} channel the postis channel. - */ - constructor(channel) { - // TODO: if no channel is passed, create one. - this.channel = channel; - this.channel.ready(() => { - this.channel.listen('message', message => { - const { name } = message.data; - if(name === REMOTE_CONTROL_MESSAGE_NAME) { - this.onRemoteControlMessage(message); - } - }); - this.sendEvent({ type: EVENTS.supported }); - }); - } - - /** - * Disposes the remote control functionality. - */ - dispose() { - this.channel = null; - this.stop(); - } - - /** - * Handles remote control start messages. - * - * @param {number} id - the id of the request that will be used for the - * response. - * @param {string} sourceId - The source id of the desktop sharing stream. - */ - start(id, sourceId) { - const displays = electron.screen.getAllDisplays(); - - switch(displays.length) { - case 0: - this.display = undefined; - break; - case 1: - // On Linux probably we'll end up here even if there are - // multiple monitors. - this.display = displays[0]; - break; - // eslint-disable-next-line no-case-declarations - default: // > 1 display - const coordinates = sourceId2Coordinates(sourceId); - if(coordinates) { - // Currently sourceId2Coordinates will return undefined for - // any OS except Windows. This code will be executed only on - // Windows. - const { x, y } = coordinates; - this.display = electron.screen.getDisplayNearestPoint({ - x: x + 1, - y: y + 1 - }); - } else { - // On Mac OS the sourceId = 'screen' + displayId. - // Try to match displayId with sourceId. - const displayId = Number(sourceId.replace('screen:', '')); - this.display - = displays.find(display => display.id === displayId); - } - } - - const response = { - id, - type: 'response' - }; - - if(this.display) { - response.result = true; - } else { - response.error - = 'Error: Can\'t detect the display that is currently shared'; - } - - this.sendMessage(response); - } - - /** - * Stops processing the events. - */ - stop() { - this.display = undefined; - } - - /** - * Executes the passed message. - * @param {Object} message the remote control message. - */ - onRemoteControlMessage(message) { - const { id, data } = message; - - // If we haven't set the display prop. We haven't received the remote - // control start message or there was an error associating a display. - if(!this.display - && data.type != REQUESTS.start) { - return; - } - switch(data.type) { - case EVENTS.mousemove: { - const { width, height, x, y } = this.display.workArea; - const destX = data.x * width + x; - const destY = data.y * height + y; - if(mouseButtonStatus === "down") { - robot.dragMouse(destX, destY); - } else { - robot.moveMouse(destX, destY); - } - break; - } - case EVENTS.mousedown: - case EVENTS.mouseup: { - mouseButtonStatus - = MOUSE_ACTIONS_FROM_EVENT_TYPE[data.type]; - robot.mouseToggle( - mouseButtonStatus, - (data.button - ? MOUSE_BUTTONS[data.button] : undefined)); - break; - } - case EVENTS.mousedblclick: { - robot.mouseClick( - (data.button - ? MOUSE_BUTTONS[data.button] : undefined), - true); - break; - } - case EVENTS.mousescroll:{ - //FIXME: implement horizontal scrolling - if(data.y !== 0) { - robot.scrollMouse( - Math.abs(data.y), - data.y > 0 ? "down" : "up" - ); - } - break; - } - case EVENTS.keydown: - case EVENTS.keyup: { - robot.keyToggle( - data.key, - KEY_ACTIONS_FROM_EVENT_TYPE[data.type], - data.modifiers); - break; - } - case REQUESTS.start: { - this.start(id, data.sourceId); - break; - } - case EVENTS.stop: { - this.stop(); - break; - } - default: - console.error("Unknown event type!"); - } - } - - /** - * Sends remote control event to the controlled participant. - * - * @param {Object} event the remote control event. - */ - sendEvent(event) { - const remoteControlEvent = Object.assign( - { name: REMOTE_CONTROL_MESSAGE_NAME }, - event - ); - this.sendMessage({ data: remoteControlEvent }); - } - - /** - * Sends a message to Jitsi Meet. - * - * @param {Object} message the message to be sent. - */ - sendMessage(message) { - this.channel.send({ - method: 'message', - params: message - }); - } -} - -module.exports = RemoteControl; diff --git a/modules/screensharing/index.js b/modules/screensharing/index.js deleted file mode 100644 index e1be677..0000000 --- a/modules/screensharing/index.js +++ /dev/null @@ -1,33 +0,0 @@ -const electron = require("electron"); - -/** - * Get sources available for screensharing. The callback is invoked - * with an array of DesktopCapturerSources. - * - * @param {Function} callback - The success callback. - * @param {Function} errorCallback - The callback for errors. - * @param {Object} options - Configuration for getting sources. - * @param {Array} options.types - Specify the desktop source types to get, - * with valid sources being "window" and "screen". - * @param {Object} options.thumbnailSize - Specify how big the preview - * images for the sources should be. The valid keys are height and width, - * e.g. { height: number, width: number}. By default electron will return - * images with height and width of 150px. - */ -function obtainDesktopStreams(callback, errorCallback, options = {}) { - electron.desktopCapturer.getSources(options, - (error, sources) => { - if (error) { - errorCallback(error); - return; - } - - callback(sources); - }); -} - -module.exports = function setupScreenSharingForWindow(pWindow) { - pWindow.JitsiMeetElectron = { - obtainDesktopStreams - }; -}; diff --git a/node_addons/sourceId2Coordinates/binding.gyp b/node_addons/sourceId2Coordinates/binding.gyp deleted file mode 100644 index 4f3d0f6..0000000 --- a/node_addons/sourceId2Coordinates/binding.gyp +++ /dev/null @@ -1,27 +0,0 @@ -{ - 'targets': [{ - 'target_name': 'sourceId2Coordinates', - 'include_dirs': [ - "|undefined} - The x and y coordinates of the - * top left corner of the desktop. Currently works only for windows. Returns - * undefined for Mac OS, Linux. - */ -module.exports = function(sourceID) { - // On windows the source id will have the following format "0:desktop_id". - // we need the "desktop_id" only to get the coordinates. - const idArr = sourceID.split(":"); - const id = Number(idArr.length > 1 ? idArr[1] : sourceID); - if(id) { - return sourceId2Coordinates(id); - } - return undefined; -}; diff --git a/node_addons/sourceId2Coordinates/package.json b/node_addons/sourceId2Coordinates/package.json deleted file mode 100644 index fce1579..0000000 --- a/node_addons/sourceId2Coordinates/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "sourceId2Coordinates", - "version": "0.0.3", - "description": "Native addon that returns the coordinates of desktop using the passed source id", - "main": "index.js", - "scripts": { - "install": "node-gyp rebuild" - }, - "keywords": [ - "Util", - "WebRTC" - ], - "gypfile": true, - "dependencies": { - "nan": "^2.2.1" - } -} diff --git a/node_addons/sourceId2Coordinates/src/index.cc b/node_addons/sourceId2Coordinates/src/index.cc deleted file mode 100644 index 5820d4c..0000000 --- a/node_addons/sourceId2Coordinates/src/index.cc +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include -#include -#include -#include "sourceId2Coordinates.h" - -using namespace v8; - -NAN_METHOD(sourceId2Coordinates) -{ - const int sourceID = info[0]->Int32Value(); - Local obj = Nan::New(); - Point coordinates; - if(!sourceId2Coordinates(sourceID, &coordinates)) - { // return undefined if sourceId2Coordinates function fail. - info.GetReturnValue().Set(Nan::Undefined()); - } - else - { // return the coordinates if sourceId2Coordinates function succeed. - Nan::Set(obj, Nan::New("x").ToLocalChecked(), Nan::New(coordinates.x)); - Nan::Set(obj, Nan::New("y").ToLocalChecked(), Nan::New(coordinates.y)); - info.GetReturnValue().Set(obj); - } -} - -NAN_MODULE_INIT(Init) -{ - Nan::Set( - target, - Nan::New("sourceId2Coordinates").ToLocalChecked(), - Nan::GetFunction(Nan::New(sourceId2Coordinates)) - .ToLocalChecked() - ); - NAN_EXPORT(target, sourceId2Coordinates); -} - -NODE_MODULE(sourceId2CoordinatesModule, Init) diff --git a/node_addons/sourceId2Coordinates/src/sourceId2Coordinates.cc b/node_addons/sourceId2Coordinates/src/sourceId2Coordinates.cc deleted file mode 100644 index 8f2d1f3..0000000 --- a/node_addons/sourceId2Coordinates/src/sourceId2Coordinates.cc +++ /dev/null @@ -1,45 +0,0 @@ -#if defined(IS_WINDOWS) -#include -#endif - -#include "sourceId2Coordinates.h" - -/** - * Tries to get the coordinates of a desktop from passed sourceId - * (which identifies a desktop sharing source). Used to match the source id to a - * screen in Electron. - * - * Returns true on success and false on failure. - * - * NOTE: Works on windows only because on the other platforms there is an easier - * way to match the source id and the screen. - */ -bool sourceId2Coordinates(int sourceId, Point* res) -{ -#if defined(IS_WINDOWS) - DISPLAY_DEVICE device; - device.cb = sizeof(device); - - if (!EnumDisplayDevices(NULL, sourceId, &device, 0) // device not found - || !(device.StateFlags & DISPLAY_DEVICE_ACTIVE))// device is not active - { - return false; - } - - DEVMODE deviceSettings; - deviceSettings.dmSize = sizeof(deviceSettings); - deviceSettings.dmDriverExtra = 0; - if(!EnumDisplaySettingsEx(device.DeviceName, ENUM_CURRENT_SETTINGS, - &deviceSettings, 0)) - { - return false; - } - - res->x = deviceSettings.dmPosition.x; - res->y = deviceSettings.dmPosition.y; - - return true; -#else - return false; -#endif -} diff --git a/node_addons/sourceId2Coordinates/src/sourceId2Coordinates.h b/node_addons/sourceId2Coordinates/src/sourceId2Coordinates.h deleted file mode 100644 index 5425b75..0000000 --- a/node_addons/sourceId2Coordinates/src/sourceId2Coordinates.h +++ /dev/null @@ -1,7 +0,0 @@ -struct Point { - int x; - int y; - Point(): x(0), y(0) {}; -}; - -bool sourceId2Coordinates(int sourceId, Point* res); diff --git a/package.json b/package.json index 0d1085c..992aea1 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,7 @@ "readmeFilename": "README.md", "license": "Apache-2.0", "dependencies": { - "sourceId2Coordinates": "file:./node_addons/sourceId2Coordinates", - "robotjs": "jitsi/robotjs#jitsi", - "postis": "^2.2.0" + "jitsi-meet-electron-utils": "jitsi/jitsi-meet-electron-utils" }, "devDependencies": { "electron": "1.4.13", diff --git a/windows/jitsi-meet/render.js b/windows/jitsi-meet/render.js index 9b67aa2..0a5284c 100644 --- a/windows/jitsi-meet/render.js +++ b/windows/jitsi-meet/render.js @@ -1,14 +1,11 @@ /* global process */ -const RemoteControl = require("../../modules/remotecontrol"); -let postis = require("postis"); -const setupScreenSharingForWindow = require("../../modules/screensharing"); +const utils = require("jitsi-meet-electron-utils"); +const { + RemoteControl, + setupScreenSharingForWindow +} = utils; const config = require("../../config.js"); -/** - * The postis channel. - */ -let channel; - /** * The remote control instance. */ @@ -32,18 +29,12 @@ document.body.appendChild(iframe); function onload() { setupScreenSharingForWindow(iframe.contentWindow); iframe.contentWindow.onunload = onunload; - channel = postis({ - window: iframe.contentWindow, - windowForEventListening: window - }); - remoteControl = new RemoteControl(channel); + remoteControl = new RemoteControl(iframe); } /** * Clears the postis objects and remoteControl. */ function onunload() { - channel.destroy(); - channel = null; remoteControl.dispose(); } From b23da5db66151b4b7740197e53188081b442edd0 Mon Sep 17 00:00:00 2001 From: hristoterezov Date: Mon, 10 Jul 2017 15:37:30 -0500 Subject: [PATCH 2/2] doc: Add section about using jitsi-meet-electron-utils from source --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index b20f0f1..3eb11e4 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,25 @@ from config.js npm install ``` +## Working with the [jitsi-meet-electron-utils](https://github.com/jitsi/jitsi-meet-electron-utils) sources +By default the jitsi-meet-electron-utils is build from its git repository sources. The default dependency path in package.json is : +```json +"jitsi-meet-electron-utils": "jitsi/jitsi-meet-electron-utils" +``` + +To work with local copy you must change the path to: +```json +"jitsi-meet-electron-utils": "file:///Users/name/jitsi-meet-electron-utils-copy", +``` + +To make the project you must force it to take the sources as `npm update` will not do it. +```bash +npm install jitsi-meet-electron-utils --force +node_modules/.bin/electron-rebuild +``` + +NOTE: Also check jitsi-meet-electron-utils's [README](https://github.com/jitsi/jitsi-meet-electron-utils/blob/master/README.md) to see how to configure your environment. + ## Statring the application ```bash npm start