i just started to make a new app by electron and find out after adding a new feature in my app, a very hard to notice white(or maybe transparent) gap added in very right side of the window.
More explanation: I made an application that fetch something from server and after some manipulation, will display them in main window. The application just has 1 window (its quite simple app) and this is configuration for window that i added into main js "Before" gap shows up:
mainWindow = new BrowserWindow({
show : false,
width : 820,
height : 520,
frame : false,
resizable : false,
title : "blah blah blah"
})
After that i decided to expand the app and cache last location of the window before user try to close window so in next time that user will open the app, the window will at the same prev place. So i added some extra function to catch window "x" and "y" and save them into a "json" file in "appData". I changed window config to this one:
mainWindow = new BrowserWindow({
show : false,
width : 820,
height : 520,
frame : false,
resizable : false,
title : "blah blah blah",
x : {get x from storage},//this is pseudo
y : {get y from storage}//this is pseudo
})
Now a small gap appears in right side as shown in pictures below. More explanation in pictures caption.
HTML:
<body>
<div class="hello-rob">
<div class="nav"></div>
</div>
</body>
CSS:
body,
html {
position: relative;
width: 820px;
font-weight: normal;
-webkit-font-smoothing: antialiased;
height: 100%;
overflow: hidden;
-webkit-user-select: none;
}
caption: Css width set to "820px" same as window "width" in main. js, as you can see there is almost "2-3px" white gap (i marked with a circle)
caption: If i comment the css width, then the window will expand to its real width that is "822.4px"
caption: When i comment "x" and "y" in main.js and css "width" presence, every thing seems fine.
P.S: i don't think this issue its just about "x" and "y" that set in main.js and regardless of that the main problem is:
Why and how the window is bigger than what we set for it in main.js and in css?
electron v1.7.11
Windows 10 64bit
Please note:
This is not a "permanent solution", this is just a temporary hotfix before electron team diagnose what is the main cause of this behavior by electron.js.
Thanks to #mplungjan and #Mike to reminding me to read documentation once again
I tried to watch/trace "window size" in every moment so that i can find out inside the electron core "window size" is inaccurate or no, something in renderer.js is involve?!
Based on this results (from main.js), its obvious changes happen in main.js part.
This is main.js console (when extra gap is evident):
[ 823, 522 ]// console.log(mainWindow.getSize());
[ 822, 521 ]// console.log(mainWindow.getContentSize());
{ x: 680, y: 101, width: 823, height: 522 }// console.log(mainWindow.getBounds());
From the results you can see electron uses setSize, getSize to demonstrate window size and obviously its not accurate because the window's size should be "820px" * "520px".
How to fix this: (please consider big part of codes below are not new, new tricky-lines has a comment)
function createWindow(){
mainWindow = new BrowserWindow({
show : false,
width : 820,
height : 520,
frame : false,
resizable : false,
title : "blah blah blah",
x : {get x from storage},//this is pseudo
y : {get y from storage}//this is pseudo
minWidth: 820,// new
maxWidth: 820,// new
minHeight: 520,// new
maxHeight: 520// new
})
// in this function i called console.log()
mainWindow.once('ready-to-show', () => {
mainWindow.show();
mainWindow.setSize(820,520);// new (i didn't checked but maybe before `mainWindow.show();` is better to place this line of code)
})
}
app.on('ready', () => {
createWindow()
})
Another test to check the effect of changes:
[ 820, 520 ]// console.log(mainWindow.getSize());
[ 820, 520 ]// console.log(mainWindow.getContentSize());
{ x: 680, y: 100, width: 820, height: 520 }// console.log(mainWindow.getBounds());
And the gap no longer exists.
P.S: personally i don't like this kind of solutions, so if any one else was able to represent a better solution i'll accept it as an answer.
Related
so I am working on a small feature. Basically, it adds a border to the desktop. So far, I got the design and everything down, but the two windows (two monitors) layer over everything else. So I can’t click anything on my computer because the borders (which have a transparent background) are over everything.
Example:
https://user-images.githubusercontent.com/43588940/46045103-819c4480-c0d1-11e8-92ce-6c36b4ec6cc9.png
As you can see, the borders work but I can’t click anything on my desktop because it is blocking it.
So my question is, how can I link these borders to the desktop? Sort of like a desktop gadget. I just want it to stay in the background, so it isnt blocking all the computer functions.
Also, I can't click through the border because it is a transparent window and electron doesnt support clicking through transparent windows (feelsbadman). So I'm kinda screwed i just want borders on my desktop with this lol
My code:
const electron = require('electron')
const { app, BrowserWindow, globalShortcut } = require('electron')
let win
function runGouge() {
```
let displays = electron.screen.getAllDisplays();
let externalDisplay = displays.find((display) => {
return display.bounds.x !== 0 || display.bounds.y !== 0
})
win = new BrowserWindow({
name: "Gouge4 ",
width: 400,
frame: false,
toolbar: false,
transparent: true,
show: false,
parent: "explorer.exe",
x: externalDisplay.bounds.x + 50,
y: externalDisplay.bounds.y + 50
})
win.setMenu(null);
//win.webContents.openDevTools();
win.maximize();
win.show();
win.loadFile('index.html');
win.setSkipTaskbar(true);
win.showInactive();
win.center();
win2 = new BrowserWindow({
name: "Gouge2",
frame: false,
toolbar: false,
transparent: true,
show: false,
})
win2.setMenu(null);
//win2.webContents.openDevTools();
win2.setIgnoreMouseEvents;
win2.maximize();
win2.show();
win2.loadFile('index_blank.html');
win2.setSkipTaskbar(true);
win2.showInactive();
win2.center();
```
}
app.on('ready', runGouge);
Why not just use HTML to generate the border? You can create 3 divs, position one to the bottom (position: absolute; bottom: 0), float one to the left (float: left) & one to the right (float: right).
The first div will have background-color: purple, and the other two will have a gradient background-image: linear-gradient(rgba(0, 0, 0, 0), purple)
This will ensure that the bounding boxes of all of these elements will be confined and won't interfere with your site's functionality. To overlay them all you just set the z-index to be higher than all the other elements in your site.
You can disable mouse events on your BrowserWindow with setIgnoreMouseEvents. That means every event will be forwarded to the window behind that - won't block.
For example:
const {app, BrowserWindow} = require('electron')
const path = require('path')
app.once('ready', () => {
let win = new BrowserWindow({
frame: false,
focusable: false,
transparent: true,
alwaysOnTop: true,
fullscreen: true
})
win.loadURL(path.join(__dirname, 'background-frame.html'))
win.setIgnoreMouseEvents(true)
})
I've chosen properties for BrowserWindow which I think fit a window you described but it's up to you
I am using a small script (full code at the bottom of the question) to create a BorderLayout - top, left, right and center. I fill those parts with sap.ui.commons.layout.BorderLayoutAreas (as shown in this examples.)
My main problem is that I want this Layout to fit the whole Browser screen, being resized if the broswer windows is resized. For that the BorderLayout has the properties width and height for which I set a size. But it doesn't work as expected. For example If I replace the width with 100% or auto the application width is always adjusted correctly and fills the browser (in width). For some reason this does not work for the height. As soon as I enter something different from a pixel value (e. g. 900px) all controles dissapear and the window is empty.
Am I using it wrong or is there another way to fith the whole application to the screen?
<!DOCTYPE html>
<html>
<meta http_equiv='X-UA-Compatible' content='IE=edge'/>
<title>OpenUI5 Demo</title>
<script id='sap-ui-bootstrap'
src='/js/openui5/resources/sap-ui-core.js'
data-sap-ui-theme='sap_bluecrystal'
data-sap-ui-libs='sap.ui.commons'></script>
<script>
var oBorderLayout1 = new sap.ui.commons.layout.BorderLayout("BorderLayout1", {
width : "100%",
height : "100%", // THE APPLICATION ONLY WORKS WHEN THIS LINE IS SET TO A PIXEL (e. g. "300px") VALUE
top : new sap.ui.commons.layout.BorderLayoutArea({
size : "20%",
contentAlign : "center",
visible : true,
content : [new sap.ui.commons.TextView({
text : 'Top Area',
design : sap.ui.commons.TextViewDesign.Bold
})]
}),
bottom : new sap.ui.commons.layout.BorderLayoutArea({
size : "20%",
contentAlign : "center",
visible : true,
content : [new sap.ui.commons.TextView({
text : 'Bottom Area',
design : sap.ui.commons.TextViewDesign.Bold
})]
}),
begin : new sap.ui.commons.layout.BorderLayoutArea({
size : "20%",
contentAlign : "center",
visible : true,
content : [new sap.ui.commons.TextView({
text : 'Begin Area',
design : sap.ui.commons.TextViewDesign.Bold
})]
}),
center : new sap.ui.commons.layout.BorderLayoutArea({
contentAlign : "center",
visible : true,
content : [new sap.ui.commons.TextView({
text : 'Center Area',
design : sap.ui.commons.TextViewDesign.Bold
})]
}),
end : new sap.ui.commons.layout.BorderLayoutArea({
size : "20%",
contentAlign : "center",
visible : true,
content : [new sap.ui.commons.TextView({
text : 'End Area',
design : sap.ui.commons.TextViewDesign.Bold
})]
})
});
oBorderLayout1.placeAt("body");
</script>
<body>
<div id='body'></div>
</body>
</html>
this is a very basic CSS topic and not at all related to UI5:
In CSS percentage heights only work if the height of the parent element is defined. Either as an absolute value, or as a relative value, but the parent of it is absolute-height etc.
Elements with no height basically say "I am as tall as my content" and when the content then has 100% height, it says "I am as tall as my parent", so that's a shortcut/deadlock and the height collapses to zero.
Also note that the <html> and <body> root elements also have no fixed height by default, so they also behave the same way.
So the easy solution to make 100% height work is to set the height of the parent to a fixed value or to set ALL the parents up to the very root of the page to 100% height - in your example:
<style>
html, body, #body { height: 100%; }
<style>
See jsbin for a running version:
http://jsbin.com/bonacohefu/1/edit
It seems like this is a bug, if you look into the API it says that the default for width and height is 100% but it doesnt seem to work for the height property.
I added it to a test page, and it had the same behavior as your example.
I'm creating a Chrome packaged app that has two pages [for now]. And by pages a mean actual .html files. One is called login.html and the another is index.html.
Now everything related to the user is stored in chrome.storage.local.
Here is the code for launching the pages in chrome.js.
chrome.app.runtime.onLaunched.addListener(function () {
var dimensions = getDimensions(screen),
positions = getPositions(screen);
chrome.storage.local.get('login', function (result) {
if(result.login.status === "loggedOut") {
chrome.app.window.create('login.html', {
id: 'loginWindow',
'bounds': {
'width': 400,
'height': 600
},
minWidth: 400,
minHeight: 600,
maxWidth: 400,
maxHeight: 600,
frame: 'none'
});
} else {
chrome.app.window.create('index.html', {
id: 'mainWindow',
'bounds': {
'top': positions.top,
'left': positions.left,
'width': dimensions.width,
'height': dimensions.height
},
minWidth: dimensions.width,
minHeight: dimensions.height,
maxWidth: dimensions.width,
maxHeight: dimensions.height,
frame: 'none'
});
}
});
});
Now because chrome.storage.local.get login.status === loggedOut it pops the login page with the login form. So how do I proceed when the user puts the correct credentials. How do I close the login window and then open the main. The code above is just to open the index.html next time and not showing the login again.
I have done the code to check the credentials and that works, but I want to now close the login form window and open a new index.html with the same bounds, max-, minwidths and heights as you can see in the code above.
Here is what I'm looking for: [this is now in login.js which is called inside login.html]
if(login === success) {
// close login window and goto mainWindow
} else {
// Username or password is wrong
}
Thanks in advance!
What you have to do to accomplish this is to add this tho check if changes happen inside the chrome.storage.local.
chrome.storage.onChanged.addListener(function(changes, namespace) {
chrome.storage.local.get('login', function (result) {
if (result.login.status === "loggedIn") {
chrome.app.window.get('loginWindow').close();
chrome.app.window.create('index.html', {
id: 'mainWindow',
'bounds': {
'top': positions.top,
'left': positions.left,
'width': dimensions.width,
'height': dimensions.height
},
minWidth: dimensions.width,
minHeight: dimensions.height,
maxWidth: dimensions.width,
maxHeight: dimensions.height,
frame: 'none'
});
}
});
});
Of course you could use those changes and namespaces but I chose to leave them out.
MiroRauhala has answered your direct question, but maybe you should rethink how your app is structured.
Chrome apps don't have navigation like a normal site does. They have windows, and each window corresponds to a different html page. Instead of closing one window and opening a new one up with the exact same bounds, you could just have different divs within the one document which you hide and show as necessary.
I think changing your structure will lead to a simpler app in the long run.
If you do go with the separate window approach you will need to be careful. For example, if you add an id to a window and specify bounds, the bounds are only applied the first time it is shown. Afterwards it remembers the bounds. You can get around that by creating it hidden, then moving it, then showing it. You might run into other things like this as you're using the chrome apps platform in a way it wasn't designed for.
I've modified a template that had Fancybox already installed and functioning; I'm having problems with my gallery windows being too big on smaller screens. Currently I have a large image and then a decent block of text below. After modifying the code in the 'main.js' file, I can get the window to fit inside a browser window on a non-Retina Macbook Pro and larger screens, but on a Macbook Air 11" the window gets cut off on the bottom (I know it's about pixels and not screen size, I just don't have the numbers on hand). It's not an issue on a phone because I can scroll the window up with a finger.
One solution would be to enable scrolling inside the windows, but if that is possible then I haven't been able to make it work. Maybe they should be iframes and not gallery windows? If so I would need advice on how to implement that (the template did not come with any iframe examples beyond links to videos).
Here's the site: Weirdsmobile
Click on any of the tiles in the "Projects" section to see a Fancybox window.
Here is all the javascript code; I got advice to add the fitToView: false and maxWidth: "95%" because the window initially did not fit on a phone screen. I then added
maxHeight: "60%" to try and shrink it to fit, otherwise the full window is too large; but on smaller screens that % is still too high.
BRUSHED.fancyBox = function(){
if($('.fancybox').length > 0 || $('.fancybox-media').length > 0 || $('.fancybox-various').length > 0){
$(".fancybox").fancybox({
fitToView: false, // so we can get all the length of the title
maxWidth: "95%", // will make it responsive; adjust to your needs
maxHeight: "60%",
padding : 0,
beforeShow: function () {
this.title = $(this.element).attr('title');
this.title = '<h4>' + this.title + '</h4>' + '<p>' + $(this.element).parent().find('img').attr('alt') + '</p>';
},
helpers : {
title : { type: 'inside' },
}
});
$('.fancybox-media').fancybox({
openEffect : 'none',
closeEffect : 'none',
helpers : {
media : {}
}
});
}
}
I'm trying out a relatively new JavaScript/jQuery UI library, w2ui. I've got a layout working in my LAMP application, but I am wondering how to make the layout div take the full height of the screen. Here's a demo of a resizable layout from the official site.
Here is the HTML div which will become my layout container:
<div
id="layout"
style="width: 100%; height: 600px; margin-bottom: 10px;"
></div>
That works with '600px' as a height, but not '100%', which makes it invisible.
And the JavaScript (a few bits removed just for brevity):
var pstyle = 'border: 1px solid #dfdfdf; padding: 5px;';
$('#layout').w2layout({
name: 'layout',
panels: [
{ type: 'top', size: 50, resizable: true, style: pstyle, content: 'top' },
{
type: 'left', size: 800, resizable: true, style: pstyle, content: 'tab1'
},
{ type: 'main', style: pstyle, content: 'main' },
{ type: 'right', size: 200, resizable: true, style: pstyle, content: 'right' }
]
});
The layout docs don't mention setting a % height, though it's early days! Perhaps this question will act as a prompt.
One solution would be to read the Y dimension of the top of the layout, and then subtract this from the screen height, and then create the layout of that height. That would probably work, but if the screen resized I'd have to recalculate and reset the height, which is a bit hacky.
Here's the hacky solution, which I'll use for now; however, a better one would be worth working towards. To be fair, this works excellently in Firefox/OSX, and so is fine whilst I am in a development phase.
New HTML:
<!-- Here's the panel system -->
<div id="layout-container" style="height:700px;">
<div id="layout" style="width: 100%; height: 100%;"></div>
</div>
Additional JavaScript, executed prior to the code in the question (props to this answer for the resize stuff):
function setLayoutContainerHeight()
{
// Get top position of layout container, subtract from screen height, subtract a bit for padding
var y = $('#layout-container').position().top;
var layoutHeight = $(window).height() - y - 10;
$('#layout-container').css('height', layoutHeight + 'px');
}
// Whenever the window changes size, recalculate the layout container height
setLayoutContainerHeight();
$(window).resize(setLayoutContainerHeight);
Update: the author this library has very kindly offered several ways to achieve a full-height layout, all of which are better than my hack!