Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NW2: Size and position are not retained in 0.44.1 after app restart on macOS #7370

Closed
arudnev opened this issue Feb 11, 2020 · 10 comments
Closed

Comments

@arudnev
Copy link

arudnev commented Feb 11, 2020

Related to #7322 (covers Linux and Windows), #7230

NWJS Version : 0.44.1
Operating System : macOS Catalina (10.15.3)

Expected behavior

Window size and position should be retained after app restart.

Actual behavior

Window is centered and has default window size after app restart in nw2 mode.

When running with --disable-features=nw2 the app retains size and position if quit via Cmd+Q or by pressing close button on window frame, but does not remember size or position if quit via Quit menu item on dock item.

The issue with saving size and position in nw1 mode might be related to the following error that is being logged in that case (quit via Quit menu item on dock item when Devtools are not opened):

~/Downloads/nwjs-sdk-v0.44.1-osx-x64/nwjs.app/Contents/MacOS/nwjs --disable-features=nw2

[28842:775:0211/134524.631842:FATAL:keep_alive_registry.cc(105)] Check failed: !is_shutting_down_.
0   nwjs Framework                      0x00000001046a4969 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 15158777
1   nwjs Framework                      0x00000001045d3143 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 14300627
2   nwjs Framework                      0x00000001045e73bb v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 14383179
3   nwjs Framework                      0x000000010287f6bd ChromeMain + 30612237
4   nwjs Framework                      0x000000010419ff14 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 9896868
5   nwjs Framework                      0x00000001040cdd36 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 9036230
6   AppKit                              0x00007fff295e7980 -[NSApplication _terminateFromSender:askIfShouldTerminate:saveWindows:] + 126
7   AppKit                              0x00007fff295e788b __52-[NSApplication(NSAppleEventHandling) _handleAEQuit]_block_invoke + 46
8   AppKit                              0x00007fff2962f91c ___NSMainRunLoopPerformBlockInModes_block_invoke + 25
9   CoreFoundation                      0x00007fff2bfcc7ab __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
10  CoreFoundation                      0x00007fff2bfcc6ed __CFRunLoopDoBlocks + 379
11  CoreFoundation                      0x00007fff2bfcb731 __CFRunLoopRun + 1257
12  CoreFoundation                      0x00007fff2bfcabd3 CFRunLoopRunSpecific + 499
13  HIToolbox                           0x00007fff2ab2065d RunCurrentEventLoopInMode + 292
14  HIToolbox                           0x00007fff2ab202a9 ReceiveNextEventCommon + 356
15  HIToolbox                           0x00007fff2ab20127 _BlockUntilNextEventMatchingListInModeWithFilter + 64
16  AppKit                              0x00007fff29190ba4 _DPSNextEvent + 990
17  AppKit                              0x00007fff2918f380 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1352
18  nwjs Framework                      0x0000000104113a90 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 9322272
19  nwjs Framework                      0x00000001046b3b0a v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 15220634
20  nwjs Framework                      0x00000001041139c9 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 9322073
21  AppKit                              0x00007fff2918109e -[NSApplication run] + 658
22  nwjs Framework                      0x00000001046bbe8c v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 15254300
23  nwjs Framework                      0x00000001046ba432 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 15247554
24  nwjs Framework                      0x000000010464ec98 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 14807336
25  nwjs Framework                      0x000000010461a689 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 14592793
26  nwjs Framework                      0x000000010411bcb3 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 9355587
27  nwjs Framework                      0x0000000101e1b70b ChromeMain + 19716955
28  nwjs Framework                      0x0000000101e1d612 ChromeMain + 19724898
29  nwjs Framework                      0x0000000101e18695 ChromeMain + 19704549
30  nwjs Framework                      0x0000000103eea6dd v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 7056237
31  nwjs Framework                      0x0000000103eea3e9 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 7055481
32  nwjs Framework                      0x000000010718f20c v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 60159644
33  nwjs Framework                      0x0000000103ee95e8 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 7051896
34  nwjs Framework                      0x0000000100b4dcc7 ChromeMain + 279
35  nwjs                                0x0000000100a7e384 main + 372
36  libdyld.dylib                       0x00007fff636707fd start + 1

[0211/134524.640423:WARNING:process_memory_mac.cc(93)] mach_vm_read(0x7ffeef182000, 0x2000): (os/kern) invalid address (1)
[0211/134524.743380:WARNING:system_snapshot_mac.cc(42)] sysctlbyname kern.nx: No such file or directory (2)
[0211/134524.755661:WARNING:crash_report_exception_handler.cc(239)] UniversalExceptionRaise: (os/kern) failure (5)

[1]    28842 trace trap  ~/Downloads/nwjs-sdk-v0.44.1-osx-x64/nwjs.app/Contents/MacOS/nwjs

How to reproduce

Running vanilla sdk build on macOS in nw2 and nw1 modes without opening Devtools and checking that size and position are retained after quit (might behave differently for Cmd+Q, close button on window frame and Quit menu item on dock icon) should be enough to reproduce

@rogerwang
Copy link
Member

It should be retained when the window has id property: https://nwjs.readthedocs.io/en/latest/References/Manifest%20Format/#id

Otherwise it's undefined behavior.

@gpetrov
Copy link

gpetrov commented Feb 18, 2020

@rogerwang When other windows are opened with window.open and an ID is given - their position isn't retained. This was the case with NW1

@arudnev
Copy link
Author

arudnev commented Feb 19, 2020

@rogerwang, I just tested latest nightly build with the following setup:

rm -rf "${HOME}/Library/Application Support/nwjs-test" && \
cd /tmp && rm -rf nwjs-test && mkdir nwjs-test && cd nwjs-test && \
echo '{"name": "nwjs-test", "main": "index.html", "window": {"id": "test", "title": "size and position test", "position": "center", "width": 200, "height": 200, "max_width": 500, "max_height": 500}}' > package.json && \
echo "test" > index.html && \
~/Downloads/nwjs-sdk-v0.44.2-osx-x64/nwjs.app/Contents/MacOS/nwjs .

nwjs-size-and-position-test.zip

You are right, after I add id to window it attempts to retain size, but it seems that position is not retained, it always goes back to "center".

It seems that position is retained if I don't specify initial value, but then window is positioned somewhere in the top left corner of the screen on the first start.

Also, if I increase windows size to max (500 x 500 in this case) by dragging right bottom corner of the window, then close the window and restart the app the window will be opened maximized to the size of the screen, will not be within those 500 x 500 limits that are set.

Same goes with this (position is retained, but by default it's in top left corner):

nw.Window.open('index.html', {id: 'dialog', max_width: 500, max_height: 500})

and this (position is not retained):

nw.Window.open('index.html', {id: 'dialog', position: 'center', max_width: 500, max_height: 500})

In both cases if I stretch window to the max_width / max_height it shows as maximized to full size of the screen after re-open.

My expectation was that "position" there would be used as initial value and on subsequent calls to Window.open it would be retained and then after re-open window is not maximized.

I never noticed link to https://developer.chrome.com/apps/app_window#type-CreateWindowOptions in https://nwjs.readthedocs.io/en/latest/References/Window/#windowopenurl-options-callback, I'm wondering if we should just use innerBounds / outerBounds instead of min/max_width/height...

@rogerwang
Copy link
Member

It's expected that the function call parameter (position) overrides the default value, isn't it?

@arudnev
Copy link
Author

arudnev commented Feb 25, 2020

I have not thought about all possible use cases, but the way it worked in nw1 mode seemed logical to me on the use cases where we called nw.Window.open.

So, in nw1 mode the parameters are used to size and position the window for the first open, but on subsequent open previously saved size and position would be used instead of provided options.
Somewhat similar behavior to what's in documentation for innerBounds / 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.

In particular, if window is opened like this:

nw.Window.open('index.html', {id: 'dialog', position: 'center', width:200, height:200, max_width: 500, max_height: 500})

and then user changes size and position of that window it would retain previously saved size and position on subsequent open, which is not the case in nw2 mode.

If we could use innerBounds / outerBounds with behavior defined in referenced https://developer.chrome.com/apps/app_window#type-CreateWindowOptions and have position / width / height parameters to have different behavior (i.e. override previous user selection with values of parameter of the call) that would be fine, but it does not look like innerBounds / outerBounds are accepted as the options (it errors out with something like this: Uncaught TypeError: Error in invocation of nw.Window.open(string url, optional nw.Window.CreateWindowOptions options, optional function callback): Error at parameter 'options': Unexpected property: 'innerBounds'.)

If we want to override user selection we probably can always go with some implementation that does not use id and instead tracks and periodically persists size and position after resize and move by user, then intelligently calculates values that should be used for next open based on previously saved state and whatever other considerations that should be taken into account.
But having implementation that uses initial values on first open and then goes back to last known values on re-open of window with the same id while ignoring current values of the parameters seems like approach that should cover most frequently desired behavior.

@rogerwang
Copy link
Member

This is fixed in git and will be available in the next nightly build.

@arudnev
Copy link
Author

arudnev commented Feb 27, 2020

@rogerwang, I've just tested http://dl.nwjs.io/live-build/nw44/20200227-162000/8a3755e42/, it seems that it restores to previous size and position with the exception of one case that I mentioned above.

If you increase windows size to max (500 x 500 in this case) by dragging right bottom corner of the window, then close the window and restart the app the window will be opened maximized to the size of the screen, will not be within those 500 x 500 limits that are set.

It can be demonstrated either via attached example or simply by running something like this in dev tools, then expanding window to 500 x 500, closing and re-running the code:

nw.Window.open('data:,test', {id: 'dialog', position: 'center', width:200, height: 200, max_width: 500, max_height: 500})

Also, for some reason initial position of the window is not centered vertically, only horizontally. So, if I run the following it shows window centered around 1/3 of screen hight, closer to the top of the screen.

rm -rf "${HOME}/Library/Application Support/nwjs-test" && \
cd /tmp && rm -rf nwjs-test && mkdir nwjs-test && cd nwjs-test && \
echo '{"name": "nwjs-test", "main": "index.html", "window": {"id": "test", "title": "size and position test", "position": "center", "width": 200, "height": 200, "max_width": 500, "max_height": 500}}' > package.json && \
echo "test" > index.html && \
~/Downloads/nwjs-sdk-v0.44.4-osx-x64/nwjs.app/Contents/MacOS/nwjs .

@arudnev
Copy link
Author

arudnev commented Feb 27, 2020

I actually did not notice this before, but it seems that not centering window vertically is present in nw1 as well, going back all the way to 0.42.x (I have not checked with earlier versions).

The defect were window is expanded to max bounds and then shows maximized on re-open is not present in nw1 mode, only in nw2.

@rogerwang
Copy link
Member

@arudnev I just fixed the maximize issue. For the position problem, please file another issue for it.

@arudnev
Copy link
Author

arudnev commented Feb 28, 2020

@rogerwang, thanks for the fix, I'll test it once nightly build is available.

I've created #7402 for the issue with vertical centering

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants