SDA-3561 - Allow C2 / extensions to retrieve the native window handle (#1332)

This commit is contained in:
Robin Westberg 2022-01-31 09:01:20 +01:00 committed by GitHub
parent 53db596e7e
commit 76c4d4de7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 175 additions and 68 deletions

View File

@ -469,5 +469,19 @@ describe('main api handler', () => {
ipcMain.send(apiName.symphonyApi, value); ipcMain.send(apiName.symphonyApi, value);
expect(spy).toBeCalled(); expect(spy).toBeCalled();
}); });
it('should call `getNativeWindowHandle` correctly', () => {
const fromWebContentsMocked = {
getNativeWindowHandle: jest.fn(),
};
jest.spyOn(BrowserWindow, 'fromWebContents').mockImplementation(() => {
return fromWebContentsMocked;
});
const value = {
cmd: apiCmds.getNativeWindowHandle,
};
ipcMain.send(apiName.symphonyApi, value);
expect(fromWebContentsMocked.getNativeWindowHandle).toBeCalledTimes(1);
});
}); });
}); });

View File

@ -449,6 +449,14 @@ ipcMain.handle(
: false; : false;
} }
break; break;
case apiCmds.getNativeWindowHandle:
const browserWin = BrowserWindow.fromWebContents(
event.sender,
) as ICustomBrowserWindow;
if (browserWin && windowExists(browserWin)) {
return browserWin.getNativeWindowHandle();
}
break;
} }
return; return;
}, },

View File

@ -61,6 +61,7 @@ export enum apiCmds {
setBroadcastMessage = 'set-broadcast-message', setBroadcastMessage = 'set-broadcast-message',
handleSwiftSearchMessageEvents = 'handle-shift-search-message-events', handleSwiftSearchMessageEvents = 'handle-shift-search-message-events',
onSwiftSearchMessage = 'on-shift-search-message', onSwiftSearchMessage = 'on-shift-search-message',
getNativeWindowHandle = 'get-native-window-handle',
} }
export enum apiName { export enum apiName {

View File

@ -276,6 +276,11 @@
Full path to MSI <input type="text" id="update-file" /> Full path to MSI <input type="text" id="update-file" />
<br /> <br />
<button id="run-update">Update</button> <button id="run-update">Update</button>
<hr />
<p>Native Window Handle:</p>
<button id="get-window-handle">Get window handle</button>
<input type="text" id="text-window-handle" />
<hr /> <hr />
<br /> <br />
</body> </body>
@ -323,6 +328,7 @@
checkMediaPermission: 'check-media-permission', checkMediaPermission: 'check-media-permission',
restartApp: 'restart-app', restartApp: 'restart-app',
autoUpdate: 'auto-update', autoUpdate: 'auto-update',
getNativeWindowHandle: 'get-native-window-handle',
}; };
let requestId = 0; let requestId = 0;
@ -1176,5 +1182,25 @@
postMessage(apiCmds.restartApp); postMessage(apiCmds.restartApp);
} }
}); });
document
.getElementById('get-window-handle')
.addEventListener('click', () => {
const resultCallback = (handle) => {
const handleStr = [...handle]
.map((b) => b.toString(16).padStart(2, '0'))
.join('');
document.getElementById('text-window-handle').value = handleStr;
};
if (window.ssf) {
window.ssf.getNativeWindowHandle().then(resultCallback);
} else if (window.manaSSF) {
window.manaSSF.getNativeWindowHandle().then(resultCallback);
} else {
postRequest(apiCmds.getNativeWindowHandle, null, {
successCallback: resultCallback,
});
}
});
</script> </script>
</html> </html>

View File

@ -1,25 +1,25 @@
<html> <html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8" />
<title>Test pop-out window</title> <title>Test pop-out window</title>
<link rel="stylesheet" href="download-manager.css"> <link rel="stylesheet" href="download-manager.css" />
</head> </head>
Test Window has been opened Test Window has been opened
<p> <p>
<label for='tag'>tag:</label> <label for="tag">tag:</label>
<input type='text' id='tag' value=''/> <input type="text" id="tag" value="" />
</p> </p>
<button id="open-win">Open a new child window</button> <button id="open-win">Open a new child window</button>
<br> <br />
<br> <br />
<button id="open-in-browser">Open Symphony in browser</button> <button id="open-in-browser">Open Symphony in browser</button>
<br> <br />
<br> <br />
<a href="https://symphony.com" target="_blank">Open Symphony</a> <a href="https://symphony.com" target="_blank">Open Symphony</a>
<hr> <hr />
<textarea id="text-val" rows="4">Writes some thing to the file</textarea> <textarea id="text-val" rows="4">Writes some thing to the file</textarea>
<br /> <br />
<input type="button" id="download-file1" value="Download" /> <input type="button" id="download-file1" value="Download" />
@ -27,9 +27,10 @@ Test Window has been opened
<div id="footer" class="hidden"> <div id="footer" class="hidden">
<div id="download-manager-footer" class="download-bar"></div> <div id="download-manager-footer" class="download-bar"></div>
</div> </div>
<p>Badge Count:<p> <p>Badge Count:</p>
<button id='inc-badge'>increment badge count</button> <p>
<br> <button id="inc-badge">increment badge count</button>
<br />
<script> <script>
var badgeCount = 0; var badgeCount = 0;
@ -40,13 +41,20 @@ Test Window has been opened
if (window.ssf) { if (window.ssf) {
ssf.setBadgeCount(badgeCount); ssf.setBadgeCount(badgeCount);
} else { } else {
postMessage({ method: 'set-badge-count', data: badgeCount }, window.origin); postMessage(
{ method: 'set-badge-count', data: badgeCount },
window.origin,
);
} }
}); });
var openWinButton = document.getElementById('open-win'); var openWinButton = document.getElementById('open-win');
openWinButton.addEventListener('click', function () { openWinButton.addEventListener('click', function () {
win = window.open('childWin.html?x=200&y=200', 'childWin', 'height=500,width=500'); win = window.open(
'childWin.html?x=200&y=200',
'childWin',
'height=500,width=500',
);
}); });
var openInBrowser = document.getElementById('open-in-browser'); var openInBrowser = document.getElementById('open-in-browser');
@ -59,7 +67,10 @@ Test Window has been opened
*/ */
const download = (filename, text) => { const download = (filename, text) => {
const element = document.createElement('a'); const element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); element.setAttribute(
'href',
'data:text/plain;charset=utf-8,' + encodeURIComponent(text),
);
element.setAttribute('download', filename); element.setAttribute('download', filename);
element.style.display = 'none'; element.style.display = 'none';
@ -71,17 +82,53 @@ Test Window has been opened
}; };
// Start file download. // Start file download.
document.getElementById('download-file1').addEventListener('click', () => { document.getElementById('download-file1').addEventListener(
const filename = "hello.txt"; 'click',
const text = document.getElementById("text-val").value; () => {
const filename = 'hello.txt';
const text = document.getElementById('text-val').value;
download(filename, text); download(filename, text);
}, false); },
false,
);
document.getElementById('download-file2').addEventListener('click', () => { document.getElementById('download-file2').addEventListener(
const filename = "bye.txt"; 'click',
const text = document.getElementById("text-val").value; () => {
const filename = 'bye.txt';
const text = document.getElementById('text-val').value;
download(filename, text); download(filename, text);
}, false); },
false,
);
</script> </script>
</p>
<hr />
<p>Native Window Handle:</p>
<button id="get-window-handle">Get window handle</button>
<input type="text" id="text-window-handle" />
<script>
document
.getElementById('get-window-handle')
.addEventListener('click', () => {
const resultCallback = (handle) => {
const handleStr = [...handle]
.map((b) => b.toString(16).padStart(2, '0'))
.join('');
document.getElementById('text-window-handle').value = handleStr;
};
if (window.ssf) {
window.ssf.getNativeWindowHandle().then(resultCallback);
} else if (window.manaSSF) {
window.manaSSF.getNativeWindowHandle().then(resultCallback);
} else {
postRequest(apiCmds.getNativeWindowHandle, null, {
successCallback: resultCallback,
});
}
});
</script>
<hr />
<br />
</html> </html>

View File

@ -88,6 +88,7 @@ if (ssfWindow.ssf) {
setZoomLevel: ssfWindow.ssf.setZoomLevel, setZoomLevel: ssfWindow.ssf.setZoomLevel,
getZoomLevel: ssfWindow.ssf.getZoomLevel, getZoomLevel: ssfWindow.ssf.getZoomLevel,
supportedSettings: ssfWindow.ssf.supportedSettings, supportedSettings: ssfWindow.ssf.supportedSettings,
getNativeWindowHandle: ssfWindow.ssf.getNativeWindowHandle,
}); });
} }

View File

@ -730,6 +730,16 @@ export class SSFApi {
public supportedSettings(): string[] { public supportedSettings(): string[] {
return SUPPORTED_SETTINGS || []; return SUPPORTED_SETTINGS || [];
} }
/**
* Get native window handle of the window where the renderer is displayed
* @returns the platform-specific handle of the window.
*/
public getNativeWindowHandle(): Promise<Buffer> {
return ipcRenderer.invoke(apiName.symphonyApi, {
cmd: apiCmds.getNativeWindowHandle,
});
}
} }
/** /**