在 Chrome 中创建 windows 应用程序在启动时忽略边界?
Creating windows in Chrome App ignores bounds when launching?
我使用 background.js
脚本创建新的 windows,但是当我使用 chrome.app.window.create
方法设置边界并为 CreateWindowOptions
对象传递参数时它们是第一次使用,但每次我重新启动应用程序时都会被忽略。
在 OSX 上,似乎在 window 的 outerBounds 对象上创建回调后调用方法 setPosition
和 setSize
应用程序将响应到我试图设定的界限。但是,这似乎根本不适用于 Windows 10。
似乎我创建的 windows 在应用程序关闭时仍然存在。我不确定如何清除它们,尤其是当用户关闭应用程序时使用菜单或 OS 退出。有什么方法可以确保销毁或清除这些 windows,或强制 Chrome 应用程序设置我设置的边界而不恢复到以前的某个状态?
我创建的 windows 是 运行 PixiJS 如果这有什么区别的话。当关闭事件被触发时,我确实在 windows 上调用了一个 destroy 方法,但这没有影响。
这是我的背景脚本:
(function( global ) {
"use strict";
/* ----- VARS ----- */
var displayInfo;
var isMultiDisplay;
var controlDisplayIndex;
var controlBounds;
var controlLoaded;
var controlWindow;
var gameDisplayIndex;
var gameBounds;
var gameLoaded;
var gameWindow;
/* ----- CONSTANTS ----- */
var CONTROL_WIDTH = 1920;
var CONTROL_HEIGHT = 1080;
var GAME_WIDTH = 2160;
var GAME_HEIGHT = 3840;
var FRAME_OPTIONS = {
type: "none"
};
/* ----- FUNCTIONS ----- */
function init() {
console.log( "background.js: init" );
console.info( "background.js: ", chrome.app.window.getAll() );
isMultiDisplay = false;
controlLoaded = false;
gameLoaded = false;
loadDisplayInfo();
};
function loadDisplayInfo() {
console.log( "background.js: loadDisplayInfo" );
chrome.system.display.getInfo( onDisplayInfo );
};
function createWindows() {
console.log( "background.js: createWindows" );
isMultiDisplay = ( displayInfo.length > 0 );
if ( isMultiDisplay ) {
var i = 0;
var length = 2;
for ( i; i < length; i++ ) {
if ( displayInfo[i].isPrimary )
controlDisplayIndex = i;
else
gameDisplayIndex = i;
}
gameBounds = {
height: displayInfo[ gameDisplayIndex ].workArea.height,
left: displayInfo[ gameDisplayIndex ].workArea.left,
top: displayInfo[ gameDisplayIndex ].workArea.top,
width: displayInfo[ gameDisplayIndex ].workArea.width
};
controlBounds = {
height: displayInfo[ controlDisplayIndex ].workArea.height,
left: displayInfo[ controlDisplayIndex ].workArea.left,
top: displayInfo[ controlDisplayIndex ].workArea.top,
width: displayInfo[ controlDisplayIndex ].workArea.width
};
} else {
// This assumes single monitor is in landscape.
gameBounds = {
top: displayInfo[0].workArea.top,
left: displayInfo[0].workArea.left,
height: displayInfo[0].workArea.height,
width: Math.floor( displayInfo[0].workArea.height * GAME_WIDTH / GAME_HEIGHT )
};
controlBounds = {
top: displayInfo[0].workArea.top,
left: displayInfo[0].workArea.left + gameBounds.width,
width: gameBounds.width,
height: Math.floor( gameBounds.width * CONTROL_HEIGHT / CONTROL_WIDTH )
};
}
console.info( "Game Bounds:", gameDisplayIndex, gameBounds.left, gameBounds.top, gameBounds.width, gameBounds.height );
console.info( "Control Bounds:", controlDisplayIndex, controlBounds.left, controlBounds.top, controlBounds.width, controlBounds.height );
var state = ( isMultiDisplay ) ? "fullscreen" : "normal";
// Game
chrome.app.window.create( "window-game.html", {
id: "gameWindow",
bounds: gameBounds,
frame: FRAME_OPTIONS,
resizable: true,
state: state
}, onGameWindowCreated );
// Control
chrome.app.window.create( "window-control.html", {
id: "controlWindow",
bounds: controlBounds,
frame: FRAME_OPTIONS,
resizable: true,
state: state
}, onControlWindowCreated );
};
/* ----- EVENT LISTENERS ----- */
function onLaunched() {
console.log( "background.js: onLaunched" );
init();
};
function onDisplayInfo( info ) {
console.log( "background.js: onDisplayInfo" );
displayInfo = info;
createWindows();
};
function onControlWindowCreated( obj ) {
console.log( "background.js: onControlWindowCreated", obj.id );
controlLoaded = true;
controlWindow = obj;
controlWindow.outerBounds.setPosition( controlBounds.left, controlBounds.top );
controlWindow.outerBounds.setSize( controlBounds.width, controlBounds.height );
if ( isMultiDisplay ) controlWindow.fullscreen();
//console.info( controlWindow.innerBounds.width, controlWindow.innerBounds.height );
//console.info( controlWindow.outerBounds.width, controlWindow.outerBounds.height );
controlWindow.onClosed.addListener( onControlWindowClosed );
};
function onControlWindowClosed() {
console.log( "background.js: onControlWindowClosed" );
controlWindow.onClosed.removeListener( onControlWindowClosed );
controlWindow.destroy();
controlWindow = undefined;
};
function onGameWindowCreated( obj ) {
console.log( "background.js: onGameWindowCreated", obj.id );
gameLoaded = true;
gameWindow = obj;
gameWindow.outerBounds.setPosition( gameBounds.left, gameBounds.top );
gameWindow.outerBounds.setSize( gameBounds.width, gameBounds.height );
if ( isMultiDisplay ) gameWindow.fullscreen();
//console.info( gameWindow.innerBounds.width, gameWindow.innerBounds.height );
//console.info( gameWindow.outerBounds.width, gameWindow.outerBounds.height );
gameWindow.onClosed.addListener( onGameWindowClosed );
};
function onGameWindowClosed() {
console.log( "background.js: onGameWindowClosed" );
gameWindow.onClosed.removeListener( onGameWindowClosed );
gameWindow.destroy();
gameWindow = undefined;
};
/* ----- CALL ----- */
chrome.app.runtime.onLaunched.addListener( onLaunched );
}( this ));
免责声明:我知道 Chrome 应用程序正在停产,但由于项目时间安排,我必须完成此应用程序,然后再考虑移植到 Electron 或替代方案。
当您创建 window 并在 CreateWindowOptions
对象中设置 id
属性 时,将保存该 window 的最后已知边界通过 Chrome Apps 平台并使用下一个 window 创建了相同的 ID。
这是 id
属性 上文档的描述:
Id to identify the window. This will be used to remember the size and
position of the window and restore that geometry when a window with
the same id is later opened. If a window with a given id is created
while another window with the same id already exists, the currently
opened window will be focused instead of creating a new window.
并根据outerBounds
的描述属性:
Used to specify the initial position, initial size and constraints of
the window (including window decorations such as the title bar and
frame). If an id is also specified and a window with a matching id has
been shown before, the remembered bounds will be used instead.
所以,解决方案是省略id
属性。如果你像我一样,需要在你的脚本中对 window 做进一步的事情,那么使用 create window 回调来为那个函数 return 参数分配一个变量。
例如:
var myWindow;
chrome.app.window.create( "window.html", options, function( obj ) {
myWindow = obj;
// Do Stuff with myWindow
} );
我想即使在回调之后尝试设置 window 的大小和位置也不是完全可靠的,正如我在 Windows 10 下尝试做一些事情时所证明的那样。
我唯一不知道的是,当您给 windows 一个 ID 时,Google Chrome 存储所有这些 window 数据的应用在哪里?有没有办法清除它(除了卸载应用程序)?
我使用 background.js
脚本创建新的 windows,但是当我使用 chrome.app.window.create
方法设置边界并为 CreateWindowOptions
对象传递参数时它们是第一次使用,但每次我重新启动应用程序时都会被忽略。
在 OSX 上,似乎在 window 的 outerBounds 对象上创建回调后调用方法 setPosition
和 setSize
应用程序将响应到我试图设定的界限。但是,这似乎根本不适用于 Windows 10。
似乎我创建的 windows 在应用程序关闭时仍然存在。我不确定如何清除它们,尤其是当用户关闭应用程序时使用菜单或 OS 退出。有什么方法可以确保销毁或清除这些 windows,或强制 Chrome 应用程序设置我设置的边界而不恢复到以前的某个状态?
我创建的 windows 是 运行 PixiJS 如果这有什么区别的话。当关闭事件被触发时,我确实在 windows 上调用了一个 destroy 方法,但这没有影响。
这是我的背景脚本:
(function( global ) {
"use strict";
/* ----- VARS ----- */
var displayInfo;
var isMultiDisplay;
var controlDisplayIndex;
var controlBounds;
var controlLoaded;
var controlWindow;
var gameDisplayIndex;
var gameBounds;
var gameLoaded;
var gameWindow;
/* ----- CONSTANTS ----- */
var CONTROL_WIDTH = 1920;
var CONTROL_HEIGHT = 1080;
var GAME_WIDTH = 2160;
var GAME_HEIGHT = 3840;
var FRAME_OPTIONS = {
type: "none"
};
/* ----- FUNCTIONS ----- */
function init() {
console.log( "background.js: init" );
console.info( "background.js: ", chrome.app.window.getAll() );
isMultiDisplay = false;
controlLoaded = false;
gameLoaded = false;
loadDisplayInfo();
};
function loadDisplayInfo() {
console.log( "background.js: loadDisplayInfo" );
chrome.system.display.getInfo( onDisplayInfo );
};
function createWindows() {
console.log( "background.js: createWindows" );
isMultiDisplay = ( displayInfo.length > 0 );
if ( isMultiDisplay ) {
var i = 0;
var length = 2;
for ( i; i < length; i++ ) {
if ( displayInfo[i].isPrimary )
controlDisplayIndex = i;
else
gameDisplayIndex = i;
}
gameBounds = {
height: displayInfo[ gameDisplayIndex ].workArea.height,
left: displayInfo[ gameDisplayIndex ].workArea.left,
top: displayInfo[ gameDisplayIndex ].workArea.top,
width: displayInfo[ gameDisplayIndex ].workArea.width
};
controlBounds = {
height: displayInfo[ controlDisplayIndex ].workArea.height,
left: displayInfo[ controlDisplayIndex ].workArea.left,
top: displayInfo[ controlDisplayIndex ].workArea.top,
width: displayInfo[ controlDisplayIndex ].workArea.width
};
} else {
// This assumes single monitor is in landscape.
gameBounds = {
top: displayInfo[0].workArea.top,
left: displayInfo[0].workArea.left,
height: displayInfo[0].workArea.height,
width: Math.floor( displayInfo[0].workArea.height * GAME_WIDTH / GAME_HEIGHT )
};
controlBounds = {
top: displayInfo[0].workArea.top,
left: displayInfo[0].workArea.left + gameBounds.width,
width: gameBounds.width,
height: Math.floor( gameBounds.width * CONTROL_HEIGHT / CONTROL_WIDTH )
};
}
console.info( "Game Bounds:", gameDisplayIndex, gameBounds.left, gameBounds.top, gameBounds.width, gameBounds.height );
console.info( "Control Bounds:", controlDisplayIndex, controlBounds.left, controlBounds.top, controlBounds.width, controlBounds.height );
var state = ( isMultiDisplay ) ? "fullscreen" : "normal";
// Game
chrome.app.window.create( "window-game.html", {
id: "gameWindow",
bounds: gameBounds,
frame: FRAME_OPTIONS,
resizable: true,
state: state
}, onGameWindowCreated );
// Control
chrome.app.window.create( "window-control.html", {
id: "controlWindow",
bounds: controlBounds,
frame: FRAME_OPTIONS,
resizable: true,
state: state
}, onControlWindowCreated );
};
/* ----- EVENT LISTENERS ----- */
function onLaunched() {
console.log( "background.js: onLaunched" );
init();
};
function onDisplayInfo( info ) {
console.log( "background.js: onDisplayInfo" );
displayInfo = info;
createWindows();
};
function onControlWindowCreated( obj ) {
console.log( "background.js: onControlWindowCreated", obj.id );
controlLoaded = true;
controlWindow = obj;
controlWindow.outerBounds.setPosition( controlBounds.left, controlBounds.top );
controlWindow.outerBounds.setSize( controlBounds.width, controlBounds.height );
if ( isMultiDisplay ) controlWindow.fullscreen();
//console.info( controlWindow.innerBounds.width, controlWindow.innerBounds.height );
//console.info( controlWindow.outerBounds.width, controlWindow.outerBounds.height );
controlWindow.onClosed.addListener( onControlWindowClosed );
};
function onControlWindowClosed() {
console.log( "background.js: onControlWindowClosed" );
controlWindow.onClosed.removeListener( onControlWindowClosed );
controlWindow.destroy();
controlWindow = undefined;
};
function onGameWindowCreated( obj ) {
console.log( "background.js: onGameWindowCreated", obj.id );
gameLoaded = true;
gameWindow = obj;
gameWindow.outerBounds.setPosition( gameBounds.left, gameBounds.top );
gameWindow.outerBounds.setSize( gameBounds.width, gameBounds.height );
if ( isMultiDisplay ) gameWindow.fullscreen();
//console.info( gameWindow.innerBounds.width, gameWindow.innerBounds.height );
//console.info( gameWindow.outerBounds.width, gameWindow.outerBounds.height );
gameWindow.onClosed.addListener( onGameWindowClosed );
};
function onGameWindowClosed() {
console.log( "background.js: onGameWindowClosed" );
gameWindow.onClosed.removeListener( onGameWindowClosed );
gameWindow.destroy();
gameWindow = undefined;
};
/* ----- CALL ----- */
chrome.app.runtime.onLaunched.addListener( onLaunched );
}( this ));
免责声明:我知道 Chrome 应用程序正在停产,但由于项目时间安排,我必须完成此应用程序,然后再考虑移植到 Electron 或替代方案。
当您创建 window 并在 CreateWindowOptions
对象中设置 id
属性 时,将保存该 window 的最后已知边界通过 Chrome Apps 平台并使用下一个 window 创建了相同的 ID。
这是 id
属性 上文档的描述:
Id to identify the window. This will be used to remember the size and position of the window and restore that geometry when a window with the same id is later opened. If a window with a given id is created while another window with the same id already exists, the currently opened window will be focused instead of creating a new window.
并根据outerBounds
的描述属性:
Used to specify the initial position, initial size and constraints of the window (including window decorations such as the title bar and frame). If an id is also specified and a window with a matching id has been shown before, the remembered bounds will be used instead.
所以,解决方案是省略id
属性。如果你像我一样,需要在你的脚本中对 window 做进一步的事情,那么使用 create window 回调来为那个函数 return 参数分配一个变量。
例如:
var myWindow;
chrome.app.window.create( "window.html", options, function( obj ) {
myWindow = obj;
// Do Stuff with myWindow
} );
我想即使在回调之后尝试设置 window 的大小和位置也不是完全可靠的,正如我在 Windows 10 下尝试做一些事情时所证明的那样。
我唯一不知道的是,当您给 windows 一个 ID 时,Google Chrome 存储所有这些 window 数据的应用在哪里?有没有办法清除它(除了卸载应用程序)?