Is there a way to see if your app is in the foreground or not in windows 10. I'm trying to alert the user to event using toast but rather not have it popup when the app is already in view. I'm using html/js.
Thanks
You need to listen for this event:
document.addEventListener('visibilitychange', function ()
{
var state = document.visibilityState; // 'hidden' or 'visible'
});
You can store the current state and decide whether to show your toast message based on that.
Update: changed msvisiblitychange to visibilitychange, if you are pre-Win10 you may still need the 'ms' prefix
Related
I'm working on a simple link sharing extension (pinboard, readability, delicious, etc), and have a question about how to properly deal with a context menu item. In my non-persistent background page I call chrome.contextMenus.create and chrome.contextMenus.onClicked.addListener to setup/respond to the context menu.
The context menu entry works as expected. But the background page is showing the following error (right after it starts and before I've used the entry) :
contextMenus.create: Cannot create item with duplicate id id_share_link at chrome-extension://.../share.js:52:30 lastError:29 set
This made me realize that at no point do I remove the item or the listener. Knowing little about javascript and extensions, I'm left wondering if I'm doing everything correctly. I'm assuming this top-level code is going to re-execute every time the background page is invoked. So there are going to be redundant calls to create and addListener (and hence the error I see being logged).
I clearly can't do cleanup in response to suspend, as these calls need to be present to wake up the background script.
Should I be handling things differently?
If you want to use an event page, ie a non-persistent background page, as you call it, you should register a context menu via contextMenus.create in the event handler of runtime.onInstalled, as these context menu registrations ”persist“ anyways.
You have to add the listener-function for the contextMenus.onClicked event every time the event page gets reloaded, though, as the registration of your wish to listen on that event persists, while the handler callback itself does not. So generally don't call contextMenus.onClicked.addListener from runtime.onInstalled, but from top level or other code, that is guaranteed to be executed each time the event page loads.[1]
You can handle it one of two ways:
You can add the context menu and the listeners on install using:
chrome.runtime.onInstalled.addListener(function() {
/* Add context menu and listener */
});
You can remove the context menu and listener, and then re-add it each time the file is called.
[solution may no longer be the case, read comment]
runtime.onInstalled is not triggered if you disable/enable your extension.
My solution is to always add menu items and swallow errors:
'use strict';
{
let seqId = 0;
const createMenuLinkEntry = (title, tab2url) => {
const id = (++seqId).toString();
chrome.contextMenus.create({
id: id,
title: title,
contexts: ['browser_action'],
}, () => {
const err = chrome.runtime.lastError;
if(err) {
console.warn('Context menu error ignored:', err);
}
});
};
createMenuLinkEntry('Go to Google', (tab) => 'https://google.com');
createMenuLinkEntry('Go to GitHub', (tab) => 'https://github.com');
} // namespace
I have made a desktop application using electron + node.js.
Sometimes Windows does automatic updates and restarts the OS.
I want to prevent Windows 10 from restarting until the data is saved (database is online so it takes some time to store data) in software.
Right now, I am using the below code to prevent the window from closing. After data save I am calling ipcMain.on('',function()) method and make lockwindow to true then i am calling window close method.
It is working when normally window close or use shortcut keys for a close window.
But this event is not emitted in case of force close or studown/restart
mainWindow.on('close', event => {
if (lockWindow) {
mainWindow.webContents.send('save', '');
mainWindow.webContents.once('dom-ready', () => {
mainWindow.webContents.send('save', '');
});
event.preventDefault();
createdialogWindow();
} else
mainWindow = null
})
Thank You.
Have a look at window events, specifically close and beforeunload.
You will have only limited time before the system restarts itself anyway.
If the OS or the user decides to kill your app, this is what is going to happen anyway (you can also upset / anger user for not playing nicely).
Lastly, would you like your application to be the reason why some crucial security updates did not install?
HTH
I implemented chrome extension which using chrome.desktopCapture.chooseDesktopMedia to retrieve screen id.
This is my background script:
chrome.runtime.onConnect.addListener(function (port) {
port.onMessage.addListener(messageHandler);
// listen to "content-script.js"
function messageHandler(message) {
if(message == 'get-screen-id') {
chrome.desktopCapture.chooseDesktopMedia(['screen', 'window'], port.sender.tab, onUserAction);
}
}
function onUserAction(sourceId) {
//Access denied
if(!sourceId || !sourceId.length) {
return port.postMessage('permission-denie');
}
port.postMessage({
sourceId: sourceId
});
}
});
I need to get shared monitor info(resolution, landscape or portrait).
My question is: If customer using more than one monitor, how can i determine which monitor he picked?
Can i add for example "system.display" permissions to my extension and get picked monitor info from "chrome.system.display.getInfo"?
You are right. You could add system.display permission and call chrome.system.display.getDisplayLayout(callbackFuncion(DisplayLayout)) and handle the DisplayLayout.position in the callback to get the layout and the chrome.system.display.getInfo to handle the array of displayInfo in the callback. You should look for 'isPrimary' value
This is a year old question, but I came across it since I was after the same information and I finally managed to figure how you can identify which monitor the user selected for screen-sharing in Chrome.
First of all: this information will not come from the extension that you probably built for screen-sharing in Chrome, because:
The chrome.desktopCapture.chooseDesktopMedia API callback only returns a sourceId, which is a string that represents a stream id, that you can then use to call the getMediaSource API to build the media stream.
The chrome.system.display.getInfo will give you a list of the displays, yes, but from that info you can't tell which one is being shared, and there is no way to match the sourceId with any of the fields returned for each display.
So... the solution I've found comes from the MediaStream object itself. Once you have the stream, after calling getMediaSource, you need to get the video track, and in there you will find a property called "label". This label gives you an idea of which screen the user picked.
You can get the video track with something like:
const videoTrack = mediaStream.getVideoTracks()[0];
(Check the getVideoTracks API here: https://developer.mozilla.org/en-US/docs/Web/API/MediaStream/getVideoTracks).
If you print that object, you will see the "label" field. In Chrome screen 1 shows as "0:0", whereas screen 2 shows as "1:0", and I assume screen i would be "i-1:0" (I've only tested with 2 screens).
Here is a capture of that object printed in the console:
And not only works for Chrome, but for other browsers that implement it! In Firefox they show up as "Screen i":
Also, if you check Chrome chrome://webrtc-internals you'll see this is what they show in the addStream event:
And that's it! It's not ideal, since this is a label, more than a real screen identifier, but well, it's something to work with. Once you have the screen identified, in Chrome you can work with the chrome.system.display.getInfo to get information for that display.
I am using the https://github.com/mikaelbr/node-notifier package to show notifications in shell.
This is my code:
var notifier = require('node-notifier');
var path = require('path');
notifier.notify({
title: 'My awesome title',
message: 'Hello from node, Mr. User!',
icon: path.join(__dirname, 'coulson.jpg'), // absolute path (not balloons)
sound: true, // Only Notification Center or Windows Toasters
wait: true // wait with callback until user action is taken on notification
}, function (err, response) {
// response is response from notification
});
notifier.on('click', function (notifierObject, options) {
// Happens if `wait: true` and user clicks notification
});
notifier.on('timeout', function (notifierObject, options) {
// Happens if `wait: true` and notification closes
});
The notification comes like this:
As you can see a terminal icon is coming before the name.
Can you help me how to remove that icon?
It is known issue with node-notifier.
From issue #71:
mikaelbr:
No, I'm afraid that's how the notification work, as it's the terminal that initiates the message. The only way to avoid this is to use your custom terminal-notifier where the Terminal icon is swapped for your own. It's not a big task, and you can easily set customPath for notification center reporter.
kurisubrooks:
This happens because of the way notifications in OS X work. The notification will show the referring app icon, and because we're using terminal-notifier to push notifications, we have the icon of terminal-notifier.
To work around this, you'll need to compile terminal-notifier with your own app.icns. Download the source, change out the AppIcon bundle with your own in Xcode, recompile terminal-notifier and pop it into node-notifier. (/node-notifier/vendor/terminal-notifier.app)
Now that you have your own terminal-notifier inside node-notifier, remove all the icon references from your OS X Notification Center code, and run the notification as if it has no icon. If the old app icon is showing in your notifications, you need to clear your icon cache. (Google how to do this)
Another valuable comment from mikaelb:
That's correct. But keep in mind, node-notifier uses a fork of terminal-notifier (github.com/mikaelbr/terminal-notifier) to add option to wait for notification to finish, so this should be used to add your own icon. A easy way to do it is to copy/paste from the vendor-folder and use customPath to point to your own vendor.
I tried #Aleksandr M's steps but it didn't seem to work for me. Maybe I didn't understand the steps well enough. Here's how it worked for me.
I cloned https://github.com/mikaelbr/terminal-notifier . Then opened the project with xcode and deleted the Terminal.icns file and replaced it with my custom icon Myicon.icns.
Then edited terminal-notifier/Terminal Notifier/Terminal Notifier-Info.plist by setting the key icon file to Myicon.
After doing this, simply building the project did NOT work. I had to change the values of the build version and build identifier (any new value would do) see this.
Afterwards I just built the project with xcode and then copied the built .app file (you can find it by clicking the Products directory of the project from xcode Products > right click the file > show in finder) to my electron project
e.g your final path may look like this. electron-project/vendor/terminal-notifier.app.
Then I set customPath as #Aleksandr M suggested.
Here's what mine looked like
var notifier = new NotificationCenter({
customPath: 'vendor/terminal-notifier.app/Contents/MacOS/terminal-notifier'
});
And THEN it worked! 🙂
This solved my problem and you only need to have your icns file ready:
run this command in terminal after downloading :customise-terminal-notifier
** path/customise-terminal-notifier-master/customise-terminal-notifier -i path/Terminal.icns -b com.bundle.identifier
I create an app that must detect when the lights(LEDs) changes their status (on->off or off->on) monitor this to a site.I create this app in client side with node.js and use rpi.GPIO package from here.
But I can't use change event in this package
here is my code:
var gpio = require('rpi-gpio');
function alert()
{
console.log("detected !");
}
gpio.on('change', function(channel, value)
{
//send monitoring data to server for monitor on site
});
gpio.setup(7, gpio.DIR_IN, alert);
change event never called !! even if I change the state of LED.
is there any way to do this without use setInterval ?
I realize that this two years old, but in case some people come by for answers.
Notice that in your setup you just specified pin 7 as input and a callback, you need to also specify the edge a pin must trigger an interrupt.
gpio.setup(7, gpio.DIR_IN, gpio.EDGE_BOTH, alert);
You can use EDGE_NONE, EDGE_RISING, EDGE_FALLING, and EDGE_BOTH, default is EDGE_NONE.
I'm not sure why it's not working, but you could also consider onoff package.