Creating windows in Chrome App ignores bounds when launching?

时间:2016-08-31 18:22:51

标签: javascript google-chrome-app pixi.js

I use the background.js script to create new windows, but when I set the bounds when using the chrome.app.window.create method and pass it parameters for the CreateWindowOptions object the are used the first time, but ignored whenever I relaunch the app.

On OSX, it seems that calling the methods setPosition and setSize after the create callback on the window's outerBounds object the app will then respond to the bounds I try to set. However, this doesn't appear to work on Windows 10 at all.

It seems somehow the windows I create persist when the app is closed. I'm not sure how to clear them, especially if the user closes the app uses the menu or OS to quit. Is there some way to make sure to destroy or clear these windows, or force the Chrome App to set the bounds I set without reverting to some previous state?

The windows I create are running PixiJS if that makes any difference. I do call a destroy method on the windows when the close event is triggered, but that has no affect.

Here's my background script:

(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 ));

Disclaimer: I know that Chrome Apps are being discontinued, but due to project timings I've got to finish this app off and then look to port to Electron or alternative.

1 个答案:

答案 0 :(得分:2)

当您创建一个窗口并在id对象中设置CreateWindowOptions属性时,Chrome应用平台将保存该窗口的最后已知边界,然后使用下一个窗口创建一个窗口同样的身份。

以下是id属性文档中的说明:

  

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

outerBounds属性的描述中:

  

用于指定初始位置,初始大小和约束   窗口(包括窗口装饰,如标题栏和   帧)。如果还指定了id并且具有匹配id的窗口具有   之前已经显示过,记住的边界将被改为使用。

因此,解决方案是省略id属性。如果您和我一样需要在脚本中使用该窗口做更多事情,那么使用创建窗口回调为该函数返回参数赋值变量。

例如:

var myWindow;

chrome.app.window.create( "window.html", options, function( obj ) {

    myWindow = obj;

    // Do Stuff with myWindow

} );

我想甚至在回调之后尝试设置窗口的大小和位置都不是完全证明的,这在我尝试在Windows 10下进行时很明显。

我唯一不知道的是,当您向Windows提供ID时,Google Chrome Apps会存储所有这些窗口数据吗?有没有办法清除(除了卸载应用程序)?