Detect when Electron app is moved to different monitor/display - electron

I'm building an Electron app, and the way I have the window sizes configured is to base itself on % of the monitor/display dimension.
However I quickly noticed an issue when the user has more than one monitor. The initial window dimensions are calculated and never re-calculated for when the user changes to the second monitor, and due to this in the case that the monitors aren't the same dimension, the window has the wrong size on the other monitor.
Essentially what I'm looking for here is any sort of event which will detect when the user changes the monitor he/she is using the app on, and in this way I will be able to re-calculate the window size based on the new monitor dimension.

You can use the move event of the BrowserWindow in combination with the screen API like such:
const {app, BrowserWindow} = require("electron");
let mainWindow;
app.on("ready", function() {
mainWindow = new BrowserWindow();
// Screen module must be imported after app is ready (as per docs)
const {screen} = require("electron");
mainWindow.on("move", () => {
const bounds = mainWindow.getBounds();
const currentDisplay = screen.getDisplayNearestPoint({x: bounds.x, y: bounds.y});
// Perform your actions here..
console.log(currentDisplay);
});
});
In the event handler, you can then obtain the display metrics and perform any actions you need based on that.
Note that the move event fires very frequently. You may check out the moved event or implement some form of debouncing yourself if needed.

Related

How can I update an electron BrowserWindow icon after the window is already opened?

With the electron api, I can set the window's icon when calling the BrowserWindow constructor, like this:
mainWindow = new BrowserWindow({
icon: __dirname + '/electric-glowing-bear.png');
Unfortunately, I haven't been able to figure out how to update the icon after the fact. There seems to be a way to update the dock icon on Mac OS X, however, I am running Linux.
The purpose of this is so that I can 'badge' the icon with a number to indicate unread messages are waiting.
The only workaround I have found so far is to use a Tray icon, however, I would prefer to show the unread count in the dock / taskbar.
You can set BrowserWindow icon when creating windows at like this.
const {BrowserWindow} = require('electron')
let mainWindow = new BrowserWindow({icon: icon})
You can change BrowserWindow icon anytime like this.
mainWindow.setIcon(changeicon);
You can Taskbar icon overlay numbering anytime like this.
mainWindow.setOverlayIcon(overlayicon, description)
Windows overlay NativeImage - the icon to display on the bottom right corner of the taskbar icon. If this parameter is null, the overlay is cleared
description String - a description that will be provided to Accessibility screen readers
Sets a 16 x 16 pixel overlay onto the current taskbar icon, usually used to convey some sort of application status or to passively notify the user.
this should work as long as you have the appropriate files in place
const os = require('os'); // top of file
switch (os.platform()) {
case 'darwin':
mainWindow.setIcon('src/app/assets/icons/icon.icns');
break;
case 'win32':
mainWindow.setIcon('src/app/assets/icons/icon.ico');
break;
default:
mainWindow.setIcon('src/app/assets/icons/icon.png');
break;
}
Unfortunately this does not seem to be possible currently, at least not on Linux.

Angular Material: How to display one toast after another one is displayed while keeping both on screen?

I'm using $mdToast (Angular Material framework) directive to show several status messages in my Angular(-Material) web app.
When the user signs-in, if the login is successful a toast is shown by calling:
$scope.showToastMessage = function() {
var toast = $mdToast.simple()
.content("Login successful);
.action('OK')
.highlightAction(false)
.position($scope.getToastPosition());
$mdToast.show(toast).then(function(toast) {
//...
}
});
};
After login success I need to make another check (e.g. valid session cookie) and show another toast message without overriding the previous one and after the previous one is actually showed.
The issues I get here are:
the second toast is shown before the new one (probably due to $mdTost's async nature)
this second toast is shown for less than one second and then disappears leaving on screen only the first one (basicly the second one is shown first and then hidden when the first one appears)
A solution could be either:
creating the second toast inside then .then callback: this doesn't work either because requires the user interventions to press the "OK" action button
calling $mdToast.updateContent(); (https://material.angularjs.org/#/api/material.components.toast/service/$mdToast) which would overwrite previous toast message (this is not the best solution but would be fine either) but I can't figure out how:
(1) choose a specific toast shown on screen (let's suppose I have several toasts shown by different calls) , and
(2) update the toast message after a delay (let's say 3 seconds) in order to show to make the user undersand that the login was successful but there is some other information.
Any clue?
I was not sure if you wanted to show both toasts at the same time or not. If you wanted to show the sequentially you can put the second call to toast inside of the then because the action (OK) resolves the promise of the first toast. This is what I've tried:
var toast = $mdToast.simple()
.content('top left')
.action('OK')
.highlightAction(false)
.position($scope.getToastPosition());
var toast2 = $mdToast.simple()
.content('Checking some other things')
.highlightAction(false)
.position('top left');
$mdToast.show(toast).then(function() {
$mdToast.show(toast2);
});
See this CodePen.

onMouseMove listener only starts receiving events after cursor leaves and re-enters the document

I have CanvasElement which requests pointer lock on click, and then repeatedly passes movementX and movementY to a function using an onMouseMove listener (I'm testing first person controls).
It works fine the first time (immediately after page load), but if I press escape and click the canvas again it successfully locks the cursor but doesn't generate a MouseEvent to pass to the onMouseMove listener.
If I press escape and move the mouse outside of the document (anywhere that's not governed by the markup), move it back into the document and click the canvas, everything works perfectly again.
Any ideas what's causing this odd behaviour?
_canvas.onMouseMove.listen((MouseEvent e) {
if (document.pointerLockElement == _canvas) {
print(e.movement); // debug print
orientateCamera(e.movement);
}
});
_canvas.onClick.listen((e) {
if (document.pointerLockElement == null) {
_canvas.requestPointerLock();
}
});
All the described behaviour is contained within these lines of code.
I have no idea what element.requestPointerLock() does but
MDN - Element.requestPointerLock states that you should listen to pointerlockchange and pointerlockerror to see if the request was successful. There is also a document.exitPointerLock() which you don't seem to use.
MDN Pointer Lock API seems to be a good introduction.

Alternativa3d Change Resolution for iOS in Flash Builder

I have a problem. I did the first example (Alternativa for dummies part I) and it runs fine but only fills 1/4 of the screen when using Air for iOS. How can I change the resolution?
Here is a screenshot:
http://tinypic.com/r/34yo86q/6
Are you using this code to set up the camera?
camera.view= new View (stage.stageWidth, stage.stageHeight);
The problem comes from the fact that those values are not constant during the whole life of the app. When the app starts, it's possible that the stage resizes, and thus you wouldn't be getting the right values.
First you could set those properties (I do this in 99% of my AS3 projects).
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
Then add an event listener for stage resize, and in the handler write the stageWidth and stageHeight values to some vars you could then use to init Alternativa's camera. Or maybe wait for the event to trigger before setting up the camera.
stage.addEventListener(Event.RESIZE, checkSize);
The handler
public function checkSize(e:Event):void {
realWidth = stage.stageWidth;
realHeight= stage.stageHeight;
}
Here is Adobe's documentation on the event, with examples on how to use it.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Stage.html#event:resize

XNA loading/splash screen on game start

I'm trying to have a loading screen that pops up as soon as you run that executable that launches the game, whilst the game loads I want to display an image on the desktop much like how Gamemaker allows you to have a loading image.
I've had a brief look around and most people want an image to be shown whilst they load content which is not what I want, or perhaps it is... =P
My guess would be to set the game window borderless at the start, load the splash screen, draw it, then begin all the main loading (Specifically loading DirectInput through SlimDX takes a while). However would this support having a transparent/irregular shaped image? E.G if I wanted a borderless circle to be displayed whilst the game loads, would that be possible?
Thanks.
It's very simple. Just implement System.Threading and you're done.
Here's how it works, first add:
using System.Threading;
to the top of your class, then add the following things:
//the enum for state types
enum GameState
{
Loading,
StartMenu
}
//Init our gameState enum as variable
GameState gameState;
protected override void LoadContent()
{
gameState = GameState.Loading;
spriteBatch = new SpriteBatch(GraphicsDevice);
device = GraphicsDevice;
Window.Title = "Your Window";
//Other stuff that you had here before, now go in LoadGame()
loadingscreen = Content.Load<Texture2D>("loading");
Thread bgLoad = new Thread(new ThreadStart(LoadGame));
bgLoad.IsBackground = true;
bgLoad.Start();
}
public void LoadGame()
{
//Loading stuff here
gameState = GameState.StartMenu; //or GameState.Playing
}
and then put a loading texture in your Content Project
If I understand you correctly, you essentially want to have a window opened that is not full screen that also lacks the regular border and buttons that accompanies a window.
I can't test this but this should be a good start.
Here!
I would start by creating a bare bones Game1 class that can track an image and keep track of time for a timer.
Later you could add logic that actually tracks the loading of assets in the main program.
To start I'd just test it for a fixed time like 3 seconds.

Resources