tray.closeContextMenu() is not working in electron app macOS - javascript

tray.closeContextMenu() is not closing the tray menu. Which is stopping opening the app window.
const tray = new Tray(trayIcon.resize({ width: 16 }))
const contextMenu = Menu.buildFromTemplate([
{
label: 'Open App',
accelerator: 'Command+J',
click: () => {
window.showInactive()
}
}])
I gave accelerator to the open App option, so user might invoke the window using shortcut when they see keyboard shortcut in menu option. But when the tray menu is focused Iam unable to invoke that shortcut.
I'm registering keystrokes doing the below:
globalShortcut.register('Command+J', () => {
window.show();
})
So, before window.show() I'm trying to close tray.closeContextMenu() which is not working.

Related

Electron ApplicationMenu only works for last window when you have multiple windows

I'm tying to have Multiple windows in my Electron app and each window should have its own applicationMenu. But when I open a new window, the functionalities in application menu such as reload and openDevTools only works for last window that just opened.
Why this is happening?
Code example:
app.on('ready',() => {
createWindow();
});
ipcMain.on('open-new-window',() => {
createWindow();
});
function createWindow() {
const window = new BrowserWindow({
width:900,
height:700,
webPreferences: {
nodeIntegration: true
}
});
window.loadUrl('index.html');
const menu = Menu.buildFromTemplate([{
label: "dev",
submenu: [{
label: "Refresh HTML",
click: () => {
window.reload();
}
}]
}]);
Menu.setApplicationMenu(menu);
}
When i open a new window from ipcMain, the reload() function only works in last opened window. Whether i click "Refresh HTML" in the first window or the second.
You have only one piece of application menu, which (from docs)
will be set as each window's top menu
So, when you overwrite it, this is the expected behavior. Let's say
You create window #1. window variable will refer to #1, thus your application menu will reload that.
You create window #2. window refer to #2 and you overwrite application menu to reload #2 upon click
Clicking on #1's menu will reload #2 anyway
To resolve this, you can reload the current window with BrowserWindow.getFocusedWindow(), this way your MenuItem's function won't depend on the reference of window.
Try
click: () => {
BrowserWindow.getFocusedWindow().reload();
}

Electron opening every link in browser instead of electron itself

I wanted to open an external link not in electron but in the browser. Therefore I implemented this code:
document.addEventListener('click', function(event) {
if (event.target.tagName === 'A' && event.target.href.startsWith('http')) {
event.preventDefault();
shell.openExternal(event.target.href);
}
});
My problem is now that every link that I create, opens in the browser.
e.g.
foo <-wanted behaviour to open in browser
bar <- not wanted behaviour to open in browser
How can I get it to just open the external link in the browser?
is actually href="http://localhost:X000/#"
so the if condition is always true.
Replace your code with this and it should work:
const { app, shell, BrowserWindow } = require("electron");
// Create the browser window.
mainWindow = new BrowserWindow({
width: 1300,
height: 800,
});
// Load your React app or any other HTML which creates your Electron app content
mainWindow.loadFile("./build/index.html");
mainWindow.webContents.on("new-window", function(event, url) {
event.preventDefault();
// This will open a new Electron window to load the url.
shell.openExternal(url);
});

PWA: How to programmatically trigger : "Add to homescreen"? on iOS Safari

I released a server rendered progressive web app recently and everything works great so far.
However, Android using chrome shows a banner to download the app which is awesome, but it doesn't on iOS. Using Safari, a user needs a few clicks to get to the "Add to homescreen" feature which is bad.
So here I am, I'm satisfied with my PWA, but I would really love to be able to tell the user myself that this app can be added to homescreen.
As far as I can remember, I saw https://marvelapp.com/ doing it to add a prototype to the homescreen.
iOS - Safari currently don't support Web app install banner, like in Android - Chrome.
There is no way to programatically trigger install banner in Android as well, except for the case when you catch the beforeInstallPromot and use that to show the banner.
In the linked answer, you can check on the alternate option on how to show in app banner to guide user to add to home screen. Here is some code example for the same, which is iOS specific(look under #PROTIP 3).
For now, Apple doesn't give the possibility to make this "Add to home screen" experience easy.
You can provide a tooltip explanation to your users though, for IOs users:
Details explained here:
https://web.archive.org/web/20200809175125/https://www.netguru.com/codestories/few-tips-that-will-make-your-pwa-on-ios-feel-like-native
in the section: PROTIP 3: Create an “Add to home screen” popup yourself!
Please note that Chrome (on Android) is the only browser that auto-prompts the user to install your PWA. You should handle iOS & other Android browsers manually.
Statistics say (updated 2021) that the top 3 mobile browsers are Chrome, Safari & Samsung internet (<6%).
You can use this code to help you prompt:
// helps you detect mobile browsers (to show a relevant message as the process of installing your PWA changes from browser to browser)
var isMobile = {
Android: function () {
return navigator.userAgent.match(/Android/i);
},
BlackBerry: function () {
return navigator.userAgent.match(/BlackBerry/i);
},
iOS: function () {
return navigator.userAgent.match(/iPhone|iPad|iPod/i);
},
Opera: function () {
return navigator.userAgent.match(/Opera Mini/i);
},
Samsung: function () {
return navigator.userAgent.match(
/SAMSUNG|Samsung|SGH-[I|N|T]|GT-[I|N]|SM-[A|N|P|T|Z]|SHV-E|SCH-[I|J|R|S]|SPH-L/i,
);
},
Windows: function () {
return (
navigator.userAgent.match(/IEMobile/i) ||
navigator.userAgent.match(/WPDesktop/i)
);
},
any: function () {
return (
isMobile.Android() ||
isMobile.BlackBerry() ||
isMobile.iOS() ||
isMobile.Opera() ||
isMobile.Windows()
);
},
};
// use this to check if the user is already using your PWA - no need to prompt if in standalone
function isStandalone(): boolean {
const isStandalone = window.matchMedia("(display-mode: standalone)").matches;
if (document.referrer.startsWith("android-app://")) {
return true; // Trusted web app
} else if ("standalone" in navigator || isStandalone) {
return true;
}
return false;
}
As for installing instructions:
Chrome - auto
Safari - Press "Share" icon then "Add to home"
Samsung internet - An "Install" icon will be shown on the top bar (I didn't quite understand if the app should be registered in Samsung Store for it to show) OR press "Menu" on the bottom bar then "Add/install to home"
Other browsers - Press menu on the bottom/top bar then "Add/install to home"

Why is my Chrome extension screenshare window disappearing?

I am first getting into Chrome Extensions. I have a browser_action that uses default_popup to open a tiny HTML page with a button. The JS used on that page is:
document.addEventListener('DOMContentLoaded', () => {
var shareButton = document.getElementById('share');
shareButton.addEventListener('click', () => {
chrome.desktopCapture.chooseDesktopMedia(["screen","window"], (streamId, options) =>{
});
});
});
When I hit the button, I see the OS window pop to ask what I want to share for a fraction of a second before it instantly closes.

Get selected text from electron webview

How to get the selected text from a webview in an electron application?
I am using Angular with Electron. So I have a component which has a webview:
<webview id="foo" attr.src={{activeUrl}} style="height: 600px"></webview>
This is what I use for getting the selected text:
let rightClickPosition = null;
const menu = new Menu();
const menuItem = new MenuItem({
label: 'Get selected text',
click: () => {
// does not work for selected text in webview
console.log(window.getSelection().toString());
}
});
menu.append(menuItem);
window.addEventListener('contextmenu', (e) => {
e.preventDefault();
rightClickPosition = {x: e.x, y: e.y};
menu.popup(remote.getCurrentWindow());
}, false);
The problem: window.getSelection().toString() does not work for the selected text in the webview. It works only for the text outside the webview.
webView is special kind of tag in Electron. as document (https://electronjs.org/docs/api/webview-tag) says, Unlike an iframe, the webview runs in a separate process than your app. It doesn't have the same permissions as your web page and all interactions between your app and embedded content will be asynchronous..
Since it's different process and doesn't allow direct interaction, way you can communicate is using ipc between webview and outer frame. Check Electron's ipc to establish. Specifically you may interested in ipcRenderer.sendToHost for renderer host and webview.

Categories