Fix window size initialization

This commit is contained in:
1024jp 2022-02-14 22:23:35 +09:00
parent 00ae29f1da
commit 0be295185f
5 changed files with 64 additions and 31 deletions

View File

@ -13,6 +13,7 @@ Change Log
### Fixes
- Fix an issue that the initial position of the side pane was occasionally stacked under the window toolbar.
- [beta] Fix initial window size.

View File

@ -68,11 +68,10 @@ final class DocumentWindowController: NSWindowController, NSWindowDelegate {
let width = UserDefaults.standard[.windowWidth]
let height = UserDefaults.standard[.windowHeight]
if let window = self.window, width > 0 || height > 0 {
let contentSize = NSSize(width: width >= window.minSize.width ? width : window.frame.width,
height: height >= window.minSize.height ? height : window.frame.height)
window.setContentSize(contentSize)
let frameSize = NSSize(width: width > window.minSize.width ? width : window.frame.width,
height: height > window.minSize.height ? height : window.frame.height)
window.setFrame(.init(origin: window.frame.origin, size: frameSize), display: false)
}
(self.contentViewController as! WindowContentViewController).restoreAutosavingState()
// observe appearance setting change
self.appearanceModeObserver = UserDefaults.standard.publisher(for: .documentAppearance, initial: true)

View File

@ -8,7 +8,7 @@
//
// ---------------------------------------------------------------------------
//
// © 2018-2020 1024jp
// © 2018-2022 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -25,7 +25,26 @@
import AppKit
extension NSSplitView {
extension NSSplitViewController {
/// rsestore visibility of inspector
func restoreAutosavingState() {
assert(self.isViewLoaded)
assert(self.view.window == nil)
guard let states = self.splitView.autosavingSubviewStates else { return }
for (index, state) in states.enumerated() {
self.splitViewItems[safe: index]?.isCollapsed = state.isCollapsed
self.splitView.setPosition(state.frame.maxX, ofDividerAt: index)
}
}
}
private extension NSSplitView {
struct AutosavingSubviewState {
@ -40,7 +59,9 @@ extension NSSplitView {
guard
let autosaveName = self.autosaveName,
let subviewFrames = UserDefaults.standard.stringArray(forKey: "NSSplitView Subview Frames " + autosaveName)
else { return nil }
else { return nil }
assert(subviewFrames.count == self.arrangedSubviews.count)
return subviewFrames.map { string in
let components = string.components(separatedBy: ", ")

View File

@ -8,7 +8,7 @@
//
// ---------------------------------------------------------------------------
//
// © 2016-2021 1024jp
// © 2016-2022 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -115,6 +115,7 @@ final class SidebarViewController: NSTabViewController {
if self.isViewLoaded { // avoid storing initial state (set in the storyboard)
UserDefaults.standard[.selectedInspectorPaneIndex] = selectedTabViewItemIndex
self.invalidateRestorableState()
}
}
}

View File

@ -8,7 +8,7 @@
//
// ---------------------------------------------------------------------------
//
// © 2016-2020 1024jp
// © 2016-2022 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -28,8 +28,17 @@ import Cocoa
final class WindowContentViewController: NSSplitViewController {
// MARK: Enums
private enum SerializationKey {
static let isSidebarShown = "isSidebarShown"
}
// MARK: Private Properties
private var sidebarObserver: AnyCancellable?
private var sidebarSelectionObserver: AnyCancellable?
@IBOutlet private weak var documentViewItem: NSSplitViewItem?
@ -45,8 +54,12 @@ final class WindowContentViewController: NSSplitViewController {
super.viewDidLoad()
self.restoreAutosavingState()
// set behavior to glow window size on sidebar toggling rather than opening sidebar inward
self.sidebarViewItem?.collapseBehavior = .preferResizingSplitViewWithFixedSiblings
self.sidebarObserver = self.sidebarViewItem?.publisher(for: \.isCollapsed, options: .initial)
.sink { [weak self] _ in self?.invalidateRestorableState() }
// synchronize sidebar pane among window tabs
self.sidebarSelectionObserver = self.sidebarViewController?.publisher(for: \.selectedTabViewItemIndex)
@ -57,6 +70,26 @@ final class WindowContentViewController: NSSplitViewController {
}
/// restore UI state
override func restoreState(with coder: NSCoder) {
super.restoreState(with: coder)
if coder.containsValue(forKey: SerializationKey.isSidebarShown) {
self.isSidebarShown = coder.decodeBool(forKey: SerializationKey.isSidebarShown)
}
}
/// store UI state
override func encodeRestorableState(with coder: NSCoder, backgroundQueue queue: OperationQueue) {
super.encodeRestorableState(with: coder, backgroundQueue: queue)
coder.encode(self.isSidebarShown, forKey: SerializationKey.isSidebarShown)
}
/// view is ready to display
override func viewDidAppear() {
@ -127,28 +160,6 @@ final class WindowContentViewController: NSSplitViewController {
}
/// rsestore visibility of inspector but keeping the window width
func restoreAutosavingState() {
assert(self.sidebarViewItem!.isCollapsed)
assert(self.sidebarViewItem == self.splitViewItems[1])
assert(self.isViewLoaded)
assert(!self.view.window!.isVisible)
guard let sidebarViewItem = self.sidebarViewItem else { return assertionFailure() }
guard self.splitView.autosavingSubviewStates?[safe: 1]?.isCollapsed == false else { return }
let originalSize = self.view.frame.size
sidebarViewItem.isCollapsed = false
// adjust contentView shape
let newWidth = originalSize.width + sidebarViewItem.viewController.view.frame.width
self.view.window?.setContentSize(NSSize(width: newWidth, height: originalSize.height))
self.splitView.setPosition(originalSize.width, ofDividerAt: 0)
}
// MARK: Action Messages