Identifiying primary electron window - electron

I have some code that is shared between multiple renderers in Electron. I want those renderers to know whether they are the main window or one of the child windows. I'm wondering if there's a quick way for an renderer to know what it's ID is.
Currently I am using the following to determine when a renderer is the main one or not.
In renderer javascript
import { ipcRenderer } from 'electron';
const isMainRenderer = ipcRenderer.sendSync('main-renderer-check');
In main/background javascript
ipcMain.on('main-renderer-check', (event) => {
event.returnValue = event.sender.id === 2;
});
This works, but it seems a bit of a convoluted way to work this out.
Is there another way that is more direct?

According to Electron's documentation on ipcRenderer, the event.sender.id property is equal to the ID of the webContents from which the message originated.
Therefore it should be possible to retrieve the current window's unique ID via its WebContents using Electron's remote module:
import { remote } from 'electron';
const isMainRenderer = remote.getCurrentWebContents ().id === 2;

Related

How to call a function is renderer.js/main.js from web page in electron

Newbie to electron here, I have built a simple web application with React JS and able to view it in a window by calling
window.loadFile('./build/index.html');
Now i would want to call a function located in say renderer.js/main.js which should read file system and return data to the web application.
I have already tried this in renderer.js
const { ipcRenderer } = require('electron');
document.getElementById('#button').addEventListener('click', function (event) {
//read file contents
console.log('file contents');
});
But there are 2 issues around here
The control is from the renderer.js, instead i would want the
control to be on the web page of React.
The data that is read should be returned back to web page, so that it can be displayed in the web page.
You should be able to import/require ipcRenderer directly on your react component scripts and maybe load the file on a lifecycle hook. The 'renderer.js' is just one way to execute client side javascript on the (electron-)web page but any other way also does the trick.
If you can't import or require electron from the webapp (I didn't play with the electron-react-boilerplate yet), then you could write a so called preload script, load that when you create the browser window (see that documentation) and put the ipcRenderer on window like so:
const {ipcRenderer} = require('electron')
window.ipcRenderer = ipcRenderer
Then you can access it from the react app.
You could directly use fs inside the event listener
const { ipcRenderer } = require('electron');
const fs = require("fs");
document.getElementById('#button').addEventListener('click', function (event) {
console.log(fs.readFileSync("some/file/path", "utf8"));
});
Electron exposes full access to Node.js both on main and renderer process
https://www.electronjs.org/docs/tutorial/application-architecture#using-nodejs-apis
You are building your electron renderer using React.
Please check this to clear what main process is and renderer is.
how to communicate between react and electron
This is the answer I posted before. Feel free to check this.
And here is the pre-requirement.
let mainWindow = new BrowserWindow(
{
width: 800,
height: 600,
webPreferences:{
nodeIntegration:true
}
});
You should enable the nodeIntegration flag when you are creating the BrowserWindow. So that you can use any Nodejs API at your renderer

Electron framework window management for refresh not working

i've created a program in electron where:
When i a button in one window sends a ipc to the main window and check if the window exist and refresh the window, but its not working.
Maybe i missed something in the documentation but i don't find anything about how to check if a window is null or undefined (Already tried to check if is null and others none values).
Thanks for the attention.
Code
Error
I think this is a scope issue. Please ensure the window variable is reachable by your code. Something like this should work:
var mywindow = null; //global def
app.once("ready", function() {
mywindow = new BrowserWindow({...});
mywindow.loadURL(...);
});
ipc.on('something_refresh', function(evt) {
mywindow.reload(); //this works for me
});

How do I subscribe to a "window move" event in the Atom edtor?

I want to subscribe to the window moving event that electron provides, but I don't know how to code it in an atom package.
When I was reading the electron docs I found an example that I think is similar to what I want:
const {BrowserWindow} = require('electron')
let win = new BrowserWindow()
win.on('move', (e) => {
// . . .
})
But this appears to require creating a new electron window, and I don't know how to get the current BrowserWindow in an existing atom window.
I also can hook into the window.onresize event in atom, but there is no window.onmove.
Lastly, I found a way to get the window position in the atom docs, but I don't know how that would be useful without polling.
First, we should note that according to the official documentation, there are two events, move and moved. The latter is labeled as MacOS only.
In order to listen to the event need to fetch the current window. On the client side this can be done like this
const electron = require('electron');
const currentWindow = electron.remote.getCurrentWindow();
currentWindow.on('move', function() {
// Do move event action
});
On the application side there is no remote, so the window is fetched this way
const { BrowserWindow } = require('electron');
const currentWindow = BrowserWindow.getFocusedWindow();
currentWindow.on('move', function() {
// Do move event action
});

How add react-relay component to the storybook?

I am trying create a storybook for my react-realy app, but i don't know how to set mockup data for that component. For simple a component it is ok, because i can use dummy UI component vs Container approach, but i can't use this for nested relay components, for example there is a UserList component, which i want add to storybook, i can split relay fragment part to container and UI part to the component, but what if UserList children are too relay component? I can't split their when they are a part of the composition of UserList?
Is there some solution for add relay components to the storybook?
I created a NPM package called use-relay-mock-environment, which is based on relay-test-utils which allows you to make Storybook stories out of your Relay components.
It allows nesting of Relay components, so you can actually make stories for full pages made out of Relay components. Here's an example:
// MyComponent.stories.(js | jsx | ts | tsx)
import React from 'react';
import { RelayEnvironmentProvider } from 'react-relay';
import createRelayMockEnvironmentHook from 'use-relay-mock-environment';
import MyComponent from './MyComponentQuery';
const useRelayMockEnvironment = createRelayMockEnvironmentHook({
// ...Add global options here (optional)
});
export default {
title: 'MyComponent',
component: MyComponent,
};
export const Default = () => {
const environment = useRelayMockEnvironment({
// ...Add story specific options here (optional)
});
return (
<RelayEnvironmentProvider environment={environment}>
<MyComponent />
</RelayEnvironmentProvider>
);
};
export const Loading = () => {
const environment = useRelayMockEnvironment({
forceLoading: true
});
return (
<RelayEnvironmentProvider environment={environment}>
<MyComponent />
</RelayEnvironmentProvider>
);
};
You can also add <RelayEnvironmentProvider /> as a decorator, but I recommend not doing that if you want to create multiple stories for different states/mock data. In the above example I show 2 stories, the Default one, and a Loading one.
Not only that, it requires minimal coding, where you don't need to add the #relay-test-operation directive to your query, and the mocked data is automatically generated for you using faker.js, allowing you to focus on what matters, which is building great UI.
Feel free to review the source code here if you want to implement something similar: https://github.com/richardguerre/use-relay-mock-environment.
Note: it's still in its early days, so some things might change, but would love some feedback!
I also created relay-butler, which is a CLI that takes in GraphQL fragments and outputs Relay components, including a auto-generated query component that wraps the fragment component, and Storybook stories (the Default and Loading ones by default) that wrap that query component. And literally within minutes, I can create beautiful Relay components that are "documented" within Storybook.
Would also love some feedback for it!

PointerLock with dart

Is there a way to lock the cursor with dart that works on Firefox and Chrome?
I tried:
void lock(event)
{
var canvas = document.querySelector('canvas');
canvas.requestPointerLock();
}
in a mousedown-event listener
document.addEventListener('mousedown', lock, false);
I also tried
renderer.canvas.requestPointerLock();
where renderer is a WebGLRenderer from the three.dart package.
The problem is this works only in Chromium.
I looked up the following crossbrowser-solution for js, but this doesn't work in dart.
canvas.requestPointerLock = canvas.requestPointerLock ||
canvas.mozRequestPointerLock ||
canvas.webkitRequestPointerLock;
Is there a way to do the pointer lock in dart, or do I need to find a way to execute the javascript above from dart?
There is an open issue for this https://dartbug.com/4463
I think the problem in your code code using prefixes is that canvas.requestPointerLock, canvas.mozRequestPointerLock, canvas.webkitRequestPointerLock don't return false if they don't exist (or true if it does). You have to get the current browser by other means and then call the prefixed method.

Resources