I have an electron app that runs in the menubar.
Code is currently heavily based on an existing pomodoro app (https://github.com/G07cha/pomodoro)
When the timer hits a certain point, it opens up a message box:
ipc.on('end-timer', function() {
$('.timer').circleProgress('value', 1);
var isRelaxTime = remote.getGlobal('isRelaxTime');
dialog.showMessageBox({
type: 'info',
title: 'Pomodoro',
message: (isRelaxTime) ? 'Timer ended it\'s time to relax' : 'Back to work',
buttons: ['OK'],
noLink: true
}, function() {
if(isRelaxTime) {
$('.timer').circleProgress({fill: { gradient: ["blue", "skyblue"]}});
} else {
$('#counter').text(remote.getGlobal('pomodoroCount'));
$('.timer').circleProgress({fill: { gradient: ["orange", "yellow"]}});
}
ipc.send('start-timer');
});
});
Is it possible to open a new window instead of the message box, and make it full screen?
Basically, making sure the user sees it and it fills the screen when the timer is up and allowing customization of the page that comes up with css and such.
It depends if you want to fire a new renderer from an existing renderer or if you want to spin it up from the Main Process.
Either way its as easy as creating a new BrowserWindow instance and loading a URL to an HTMl file you want to load.
If you want to spin up a renderer from an existing renderer you will need to require the remote module first. Here is an example:
const remote = require('remote');
// create a new BrowserWindow and pass it an object of options
var msgWindow = new remote.BrowserWindow({
// full width & height of monitor without going into kiosk mode
width: remote.screen.getPrimaryDisplay().size.width,
height: remote.screen.getPrimaryDisplay().size.height
//, other options
});
// load your message file into new browserwindow
msgWindow.loadURL('file://' + __dirname + '/index.html');
// set variable to null when window is closed to clean it up
msgWindow.on('close', () => {
msgWindow = null;
});
If you did this from the the Main Process, then replace const remote = require('remote'); with:
const electron = require('electron');
const BrowserWindow = electron.BrowserWindow;
Related
So I'm experiencing issue when I'm trying to make a window transparent. I made tranparent: true, frame: false but it doesn't really work. It removes the frame and stuff but doesn't do what I want till the end. I want it to be like really transparent. What I get is a: frameless window which is not transparent.
Help would be appreciated. Some code:
main.js
// main.js
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')
const { maxHeaderSize } = require('http')
const path = require('path')
function createWindow () {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: maxHeaderSize,
height: maxHeaderSize,
transparent:true,
frame: false
})
// and load the index.html of the app.
mainWindow.loadFile('bodycam.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.whenReady().then(() => {
function onAppReady() {
createWindow()
app.on('activate', function () {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
}
setTimeout(onAppReady, 300)
})
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
// In this file you can include the rest of your app's specific main process
some part of the code (that affects html body) from style.css (that's being linked with bodycam.html)
body {
margin: 0px auto;
overflow: hidden;
font-family: 'Share Tech Mono', monospace;
font-size: 13px;
}
Why you are facing this issue
In your case, you are facing this issue because you are trying to define the size of the window from the maxHeaderSize value, wich comes from the http Node API. And this... Actually makes no sense. The value of maxHEaderSize is probably way bigger than the size of your screen. Electron seems to be suffering when creating a transparent window that big.
How to fix
You just need to remove that crazy value when creating your BrowserWindow. For example :
const mainWindow = new BrowserWindow({
transparent: true,
frame: false,
})
If you want to set your window at the same size of your screen, you can use the fullscreen option :
const mainWindow = new BrowserWindow({
transparent: true,
frame: false,
fullscreen: true,
})
Finally, if you want your user to be able to "click throught the window", you probably will be interested in the setIgnoreMouseEvents method :
const mainWindow = new BrowserWindow({
transparent: true,
frame: false,
fullscreen: true,
})
mainWindow.setIgnoreMouseEvents(true)
I created a sample application using samsung tv sdk and added video player with the bellow code.but it does not playing my video
SceneScene1.prototype.initialize = function () {
alert("SceneScene1.initialize()");
// this function will be called only once when the scene manager show this scene first time
// initialize the scene controls and styles, and initialize your variables here
// scene HTML and CSS will be loaded before this function is called
sf.service.VideoPlayer.init({
onend:function(){
sf.service.VideoPlayer.setFullScreen(false);
}
});
sf.service.VideoPlayer.setKeyHandler(sf.key.RETURN,
function(){
sf.service.VideoPlayer.setFullScreen(false);
});
var vLeft = parseInt($("#svecVideo_y5ww").css('left'));
var vTop = parseInt($("#svecVideo_y5ww").css('top'));
var vHeight = parseInt($("#svecVideo_y5ww").css('height'));
var vWidth = parseInt($("#svecVideo_y5ww").css('width'));
sf.service.VideoPlayer.setPosition({
left:vLeft,
top:vTop,
width:vWidth,
height:vHeight
});
sf.service.VideoPlayer.show();
sf.service.VideoPlayer.play({
url: 'http://media.w3.org/2010/05/sintel/trailer.mp4',
fullScreen: false,
title: 'Samsung movie',
startTime: 5,
liveStream: false,
timeString: true,
authHeader: 'none'
});
};
and if we try to inspect using web inspector.it shows the bellow errors
Service is unavailable due to network or service interference.
The file can't be played because the format isn't supported.
Unable to play the file. Please check it and try again later.
i tried with different files,and shows the same error
I am have been able to open a new window when i click a button, however, its a new pop up window. How can I have the new window open up in place of the main window?
var app = require('app')
var BrowserWindow = require('browser-window')
var ipc = require('ipc')
app.on('ready', function () {
var mainWindow = new BrowserWindow ({
width: 800,
height: 600
})
mainWindow.loadURL('file://' + __dirname + '/main.html')
//mainWindow.openDevTools() //opens inspect console
var prefsWindow = new BrowserWindow ({
width: 400,
height: 400,
show: false
})
prefsWindow.loadURL('file://' + __dirname + '/prefs.html')
With the code above, a new window pops up. Ive attached a screenshot to show what I mean.
popup window
Instead of that popup window, i want 'prefs' to replace the main window (and other options to replace the main window once added).
Instead of creating a new window, just load the prefs.html into the mainWindow. Your old content (main.html) will get replaced without additional windows opening.
When the respective button is placed inside the main.html you will need to apply this loading via the ipc remote module.
Following this SO answer for Electron 0.35.0 and above:
// In main process.
const ipcMain = require('electron').ipcMain;
// in main process, outside of app.on:
ipc.on('load-page', (event, arg) => {
mainWindow.loadURL(arg);
});
// In renderer process (web page).
const ipc = require('electron').ipcRenderer;
Loading the new page can then be performed as follows:
ipc.send('load-page', 'file://' + __dirname + '/prefs.html');
In case anyone interested, this is what I did.
assuming I have login form and after signing in I wanted to show the main window where things will happen.
setup your index.js
const electron = require('electron');
const url = require('url');
const path = require('path');
const { app, BrowserWindow } = electron;
let loginWindow;
var mainIndex = '../../index.html'; //the login window
var directoryHtml = '../html/'; //directory of where my html file is, the main window is here except the login window
var iconPath = '../../images/logo.png'; //replace with your own logo
let { ipcMain } = electron;
var newWindow = null;
app.on('ready', function () {
loginWindow = new BrowserWindow({//1. create new Window
height: 600, width: 450,
minHeight: 600, minWidth: 450, //set the minimum height and width
icon: __dirname + iconPath,
frame: false, //I had my own style of title bar, so I don't want to show the default
backgroundColor: '#68b7ad', //I had to set back color to window in case the white screen show up
show: false //to prevent the white screen when loading the window, lets not show it first
});
loginWindow.loadURL(url.format({ //2. Load HTML into Window
pathname: path.join(__dirname, mainIndex),
protocol: 'file',
slashes: true
}));
loginWindow.once('ready-to-show', () => {
loginWindow.show() //to prevent the white screen when loading the window, lets show it when it is ready
})
});
//dynamically resize window when this function is called
ipcMain.on('resize', function (e, x, y) {
loginWindow.setSize(x, y);
});
/** start of showing new window and close the login window **/
ipcMain.on('newWindow', function (e, filenName) {
if(newWindow){
newWindow.focus(); //focus to new window
return;
}
newWindow = new BrowserWindow({//1. create new Window
height: 600, width: 800,
minHeight: 600, minWidth: 800,
icon: __dirname + iconPath,
frame: false,
backgroundColor: '#68b7ad',
show: false
});
newWindow.loadURL(url.format({ //2. Load HTML into new Window
pathname: path.join(__dirname, directoryHtml + filenName),
protocol: 'file',
slashes: true
}));
newWindow.once('ready-to-show', () => { //when the new window is ready, show it up
newWindow.show()
})
newWindow.on('closed', function() { //set new window to null when we're done
newWindow = null
})
loginWindow.close(); //close the login window(the first window)
});
/** end of showing new window and closing the old one **/
app.on('closed', function () {
loginWindow = null;
});
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (loginWindow === null) {
createWindow()
}
})
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Login Window</title>
</head>
<body>
<h1>Login</h1>
<!-- . . . . -->
<button id="btn-login" onclick="loginNow()"></button>
<!-- . . . . -->
<script>
function loginNow(){
//.....
//assuming the authentication is valid, we want to show now the new window which will be our main window
const { ipcRenderer } = require('electron'); //require electron
//using ipcRenderer, let's call the function in index.js where the function name is `newWindow`,
//the `main.html` is the new html file I want to show, use your own.
ipcRenderer.send('newWindow','main.html');
}
</script>
</body>
</html>
I don't if this is the right way to do it, and I don't know the disadvantage of doing it like this but I hope none. hope this help someone.
You have a few options.
You could just call prefsWindow.focus() to ensure the second window is on top of the first.
You could hide or close the main window with mainWindow.hide() or mainWindow.destroy(), leaving only the second window open. Then reopen it when your done.
Or instead of having two windows, you could just load your prefs page into the first window, and when done back to the main page.
I had faced a similar issue when creating an application that foremost required authentication before accessing the actual content. So the first and main page of the application was a login form. After the login was successful, a new page should load instead where the actual content was suppossed to be. To do so, i have done the following:
In main.js or index.js how you'd name it, instead of loading the second window at the start and then show it, i load it inside an IPC event listener. So it loads the page when the IPC listener receives a certain event.
const {ipcMain} = require('electron');
ipcMain.on('login', (event, arg) => {
loginPage.loadURL(url.format({
pathname: path.join(__dirname, 'mainpage.html'),
protocol: 'file',
slashes: true
}));
});
Note, that loginPage is my main window that gets created on app.on() and mainpage is the second page that gets created after a successful login.
Then in my loginPage.html, after i verify the login, if it's successful i send that IPC renderer message back to the main process. Which is fairly simple to do:
var ipc = require('electron').ipcRenderer;
ipc.send('login', 'an-argument');
Above method should work. I am just a beginner so i cannot say if it's the best way to do this or if it has any unwanted implication that are not immediately seen, but it's worked out for me so you might as well give it a try.
I was fighting the same issue as you did until I found a simple solution.
Here's the JS code:
const electron = require('electron');
let rootPath = "src/Page/index.html" //Path to the html file
LoadNewWindowInCurrent(rootPath); //Opens new html file in current window
//Here's the ready function for you to use
function LoadNewWindowInCurrent (PathToHtml){
let localWindow = electron.remote.getCurrentWindow();
localWindow.LoadFile(PathToHtml);
}
I am creating a famo.us app in which header footer and content area is there. In content area different views are rendering using RenderController on action of each other and in each view different sub views are there. Events are communicating through java script using document.dispatchEvent() and addEventLiserner() method instead of famo.us events. I just want to ask that whether it is worth using this listener functions.
As I have tried through famous events like setInputHandler, setOnputHandler, emit , addListener, pipe given in famo.us documentation, But I cannot able to communicate using this.
The main question is the static app created by me is taking huge time when loaded from server and animations are running very slowly. Is there any solution for this.
Actually code is too long dummy example is below. I am creating an application having header footer and content view. In Content view I am rendering different views using renderController.
Content View
define(function(require, exports, module) {
var View = require('famous/core/View');
var Surface = require('famous/core/Surface');
var LoginView = require('views/login/LoginView');
var AccountsView = require('views/login/AccountsView'); //need to call on login
function ContentView() {
View.apply(this, arguments);
var renderController = new RenderController({
inTransition: {curve: Easing.easeOut, duration: 1000},
outTransition: {curve: Easing.easeIn, duration: 1000},
overlap: true,
});
var loginview = new LoginView();
renderController.show(loginview); //rendered initially
this.add(renderController);
document.addEventListener("showAccountsView",function(){
var accoutsView = new AccountsView()
renderController.show(accoutsView);
}.bind(this));
}
});
Login View
define(function(require, exports, module) {
var View = require('famous/core/View');
var Surface = require('famous/core/Surface');
var InputSurface = require("famous/surfaces/InputSurface");
function LoginView() {
View.apply(this, arguments);
var loginBoxContainer = new ContainerSurface({
classes:["backfaceVisibility"],
size:[undefined,295],
properties: {
overflow: 'hidden',
padding:'0 10px'
}
});
this.add(loginBoxContainer);
var userInput = new InputSurface({
size: [undefined, 45],
});
var userInputModifier = new StateModifier({
transform: Transform.translate(0,53,1)
});
var pwdInput = new InputSurface({
classes:["pwdInput"],
size: [undefined, 45],
});
var pwdInputModifier = new StateModifier({
transform: Transform.translate(0,100,1)
});
loginBoxContainer.add(userInputModifier).add(userInput);
loginBoxContainer.add(pwdInputModifier).add(pwdInput);
var submit = new Surface({
content:["Submit"],
size:[100,30],
});
submit.on("click",function(){
document.dispatchEvent(new Event("showAccountsView"));
});
loginBoxContainer.add(submit);
}
});
I have to render different view on clicking ligin submit button. I have used dispatchEvent and addEventListener of Javascript to make communication between two files. I want to use famous events. I have tried various ways using setInputHandler, setOnputHandler, emit , addListener, pipebut could not able to do that as data and listener functions cannot calling. Please explain..
Inside LoginView, replace this code:
submit.on("click",function(){
document.dispatchEvent(new Event("showAccountsView"));
});
with:
submit.on("click",function(){
this._eventOutput.emit('showAccountsView', { data: someValue });
});
In ContentView, replace:
document.addEventListener("showAccountsView",function(){
var accoutsView = new AccountsView()
renderController.show(accoutsView);
}.bind(this));
with:
loginView.on('showAccountsView', function(data){
var accoutsView = new AccountsView()
renderController.show(accoutsView);
}.bind(this));
I am new and I saw similar questions but quite old and without solution. All I want is to open new window inside activeTab and preserve the tab group. Unfortunately my code opens new window but does not keep the tabs, the window is just full screen.
I would greatly appreciate if someone could confirm if what I want to achieve is possible at all. Maybe with views somehow... Once again it should work for android. Here is the code:
// this sets the background color of the master UIView (when there are no windows/tab groups on it)
Titanium.UI.setBackgroundColor('#000');
// create tab group
var tabGroup = Titanium.UI.createTabGroup();
//
// create base UI tab and root window
//
var win1 = Titanium.UI.createWindow({
title:'Tab 1',
backgroundColor:'#fff'
});
var tab1 = Titanium.UI.createTab({
icon:'KS_nav_views.png',
title:'Tab 1',
window:win1
});
//
// create controls tab and root window
//
var win2 = Titanium.UI.createWindow({
title:'Tab 2',
backgroundColor:'#fff'
});
var tab2 = Titanium.UI.createTab({
icon:'KS_nav_ui.png',
title:'Tab 2',
window:win2
});
var label2 = Titanium.UI.createLabel({
color:'#999',
text:'I am Window 2',
font:{fontSize:20,fontFamily:'Helvetica Neue'},
textAlign:'center',
width:'auto'
});
win2.add(label2);
var data = [
{title:"Sample 1",color:'black',hasChild:true,font:{fontSize:16,fontWeight:'bold'}},
{title:"Sample 2",color:'black',hasChild:true,font:{fontSize:16,fontWeight:'bold'}}
];
var table = Titanium.UI.createTableView({
data:data,
separatorColor: '#ccc',
backgroundColor:'#fff'
});
win1.add(table);
// create table view event listener
table.addEventListener('click', function(e)
{
var win = Titanium.UI.createWindow({
url:'windows/main.js'
});
// this simply opens the new created window but full screen and without original tab group.
tabGroup.activeTab.open(win,{animated:true});
});
//
// add tabs
//
tabGroup.addTab(tab1);
tabGroup.addTab(tab2);
// open tab group
tabGroup.open();
There is currently no way to do that on android:
http://developer.appcelerator.com/question/145471/application-with-strange-navigation-how-to-implement-it#answer-252500
here you can find a demo of my solution...
http://sharesend.com/kbkasavo
hope this helps
You have to create navigation group for each tab windows.
For example
//Here's the first window...
var first = Ti.UI.createWindow({
backgroundColor:"#fff",
title:"My App"
});
Next, we’ll create a NavigationGroup. This is an iPhone-only component that controls a stack of windows (reference doc) – we’ll pass it our first window to use as its initially viewable window:
//Here's the nav group that will hold them both...
var firstnavGroup = Ti.UI.iPhone.createNavigationGroup({
window:first
});
//This is the main window of the application
var mainfirst = Ti.UI.createWindow();
mainfirst.add(firstnavGroup);
then assing this mainfirst window to tab.
Repeat this prosess for all tabs
Now when you need to open new window then you have to write
var second = Ti.UI.createWindow({
background:"#fff",
title:"Child Window"
});
firstnavGroup.open(second);
I hope this will help you.