在Chrome App中创建窗口在启动时忽略边界

Creating windows in Chrome App ignores bounds when launching?

本文关键字:边界 启动 窗口 Chrome App 创建      更新时间:2023-09-26

我使用background.js脚本创建新窗口,但是当我使用chrome.app.window.create方法并将其参数传递给CreateWindowOptions对象时设置界限时,第一次使用,但每当我重新启动应用程序时都会忽略。

在OSX上,似乎在窗口的outerBounds对象上创建回调后调用setPositionsetSize方法,应用程序将响应我尝试设置的边界。然而,这似乎在Windows 10上根本不起作用。

当应用程序关闭时,我创建的窗口似乎不知何故持续存在。我不知道如何清除它们,特别是当用户关闭应用程序时,使用菜单或操作系统退出。是否有某种方法可以确保销毁或清除这些窗口,或强制Chrome应用程序设置我设置的边界,而不恢复到以前的一些状态?

我创建的窗口正在运行PixiJS,如果这有任何不同的话。当关闭事件被触发时,我确实在窗口上调用了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应用程序正在停产,但由于项目时间安排,我必须完成这个应用程序,然后寻找移植到电子或替代

当你创建一个窗口并在CreateWindowOptions对象中设置id属性时,该窗口的最后已知边界将由Chrome Apps平台保存,并使用下一个窗口创建相同的id。

以下是id属性的文档描述:

Id标识窗口。这将用于记住大小和窗口的位置,并在窗口中恢复该几何形状随后打开相同的id。如果创建了具有给定id的窗口当具有相同id的另一个窗口已经存在时,当前的打开的窗口将被聚焦,而不是创建一个新窗口。

outerBounds属性的描述下:

的初始位置、初始大小和约束条件窗口(包括窗口装饰,如标题栏和帧)。如果还指定了id,并且具有匹配id的窗口具有如前所述,将使用记住的边界。

因此,解决方案是省略id属性。如果你,像我一样,需要在脚本中对该窗口做进一步的事情,那么使用create window回调为该函数的返回参数分配一个变量。

例如:

var myWindow;
chrome.app.window.create( "window.html", options, function( obj ) {
    myWindow = obj;
    // Do Stuff with myWindow
} );

我想即使尝试在回调后设置窗口的大小和位置也不是完全可靠的,当我尝试在Windows 10下做一些时,这是显而易见的。

唯一剩下的未知我是哪里是谷歌Chrome应用程序存储所有这些窗口数据,当你给窗口一个id?有没有办法清除(除了卸载应用程序)?