javascript - 在 Chrome 应用程序中创建窗口在启动时会忽略边界?

标签 javascript google-chrome-app pixi.js

我使用 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 应用程序即将停产,但由于项目时间安排,我必须完成此应用程序,然后考虑移植到 Electron 或替代方案。

最佳答案

当您创建窗口并在 CreateWindowOptions 对象中设置 id 属性时,Chrome 应用平台将保存该窗口的最后一个已知边界,并使用接下来,将使用相同的 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 属性。如果您像我一样,需要在脚本中对该窗口执行进一步操作,则使用创建窗口回调将变量分配给该函数返回参数。

例如:

var myWindow;

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

    myWindow = obj;

    // Do Stuff with myWindow

} );

我猜想在回调后尝试设置窗口的大小和位置也不是完全可靠的,当我尝试在 Windows 10 下进行一些操作时,这一点很明显。

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

关于javascript - 在 Chrome 应用程序中创建窗口在启动时会忽略边界?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39256508/

相关文章:

javascript - 查看 JavaScript 文件时 Visual Studio 崩溃

javascript - jQuery - 将两个事件绑定(bind)到 AND 运算符

javascript - 跨文档/窗口 AngularJS 应用程序

javascript - 在 Chrome 应用中设置 XHR header 'Referer'

javascript - pixi.js 中鼠标激活 greensock 补间时出现错误

javascript - Angular <base href ="./path"> 忽略静态资源

javascript - JQuery 为文档就绪的嵌入字体提供了不正确的宽度

javascript - readAsText(file) 只读取目录中的最后一个文件

javascript - 在 PIXI.js 中正确制作简单图形的动画

javascript - PIXI 冲击波滤波器