mirror of
https://github.com/atom/atom.git
synced 2026-01-23 13:58:08 -05:00
Store project directory paths as state on AtomWindow in browser process
Fixes #9574 Previously, we were storing the project directory paths as the `initialPaths` key in load settings, which were accessed in the browser process by reading the URL hash. However, this URL hash was not always available, subjecting us to timing issues when opening multiple files in the same folder in rapid succession. We now store the project directory paths directly on AtomWindow instances on creation, then RPC changes from the render process to the browser process with a custom code path. Shout out to :airplane::finnadie:’d @as-cii on this for pairing with me.
This commit is contained in:
@@ -151,7 +151,7 @@ describe "AtomEnvironment", ->
|
||||
[dir1, dir2] = [temp.mkdirSync("dir1-"), temp.mkdirSync("dir2-")]
|
||||
|
||||
loadSettings = _.extend atom.getLoadSettings(),
|
||||
initialPaths: [dir1]
|
||||
projectDirectoryPaths: [dir1]
|
||||
windowState: null
|
||||
|
||||
spyOn(atom, 'getLoadSettings').andCallFake -> loadSettings
|
||||
@@ -165,7 +165,7 @@ describe "AtomEnvironment", ->
|
||||
atom.loadStateSync()
|
||||
expect(atom.state.stuff).toBeUndefined()
|
||||
|
||||
loadSettings.initialPaths = [dir2, dir1]
|
||||
loadSettings.projectDirectoryPaths = [dir2, dir1]
|
||||
atom.state = {}
|
||||
atom.loadStateSync()
|
||||
expect(atom.state.stuff).toBe("cool")
|
||||
@@ -173,7 +173,7 @@ describe "AtomEnvironment", ->
|
||||
describe "openInitialEmptyEditorIfNecessary", ->
|
||||
describe "when there are no paths set", ->
|
||||
beforeEach ->
|
||||
spyOn(atom, 'getLoadSettings').andReturn(initialPaths: [])
|
||||
spyOn(atom, 'getLoadSettings').andReturn(projectDirectoryPaths: [])
|
||||
|
||||
it "opens an empty buffer", ->
|
||||
spyOn(atom.workspace, 'open')
|
||||
@@ -191,7 +191,7 @@ describe "AtomEnvironment", ->
|
||||
|
||||
describe "when the project has a path", ->
|
||||
beforeEach ->
|
||||
spyOn(atom, 'getLoadSettings').andReturn(initialPaths: ['something'])
|
||||
spyOn(atom, 'getLoadSettings').andReturn(projectDirectoryPaths: ['something'])
|
||||
spyOn(atom.workspace, 'open')
|
||||
|
||||
it "does not open an empty buffer", ->
|
||||
|
||||
@@ -4,7 +4,7 @@ remote = require 'remote'
|
||||
shell = require 'shell'
|
||||
webFrame = require 'web-frame'
|
||||
{Disposable} = require 'event-kit'
|
||||
{getWindowLoadSettings, setWindowLoadSettings} = require './window-load-settings-helpers'
|
||||
getWindowLoadSettings = require './get-window-load-settings'
|
||||
|
||||
module.exports =
|
||||
class ApplicationDelegate
|
||||
@@ -80,10 +80,8 @@ class ApplicationDelegate
|
||||
setRepresentedFilename: (filename) ->
|
||||
ipc.send("call-window-method", "setRepresentedFilename", filename)
|
||||
|
||||
setRepresentedDirectoryPaths: (paths) ->
|
||||
loadSettings = getWindowLoadSettings()
|
||||
loadSettings['initialPaths'] = paths
|
||||
setWindowLoadSettings(loadSettings)
|
||||
setProjectDirectoryPaths: (paths) ->
|
||||
ipc.send("window-command", "set-project-directory-paths", paths)
|
||||
|
||||
setAutoHideWindowMenuBar: (autoHide) ->
|
||||
ipc.send("call-window-method", "setAutoHideMenuBar", autoHide)
|
||||
@@ -124,7 +122,7 @@ class ApplicationDelegate
|
||||
else
|
||||
params = _.clone(params)
|
||||
params.title ?= 'Save File'
|
||||
params.defaultPath ?= getWindowLoadSettings().initialPaths[0]
|
||||
params.defaultPath ?= getWindowLoadSettings().projectDirectoryPaths[0]
|
||||
dialog = remote.require('dialog')
|
||||
dialog.showSaveDialog remote.getCurrentWindow(), params
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ Model = require './model'
|
||||
WindowEventHandler = require './window-event-handler'
|
||||
StylesElement = require './styles-element'
|
||||
StorageFolder = require './storage-folder'
|
||||
{getWindowLoadSettings} = require './window-load-settings-helpers'
|
||||
getWindowLoadSettings = require './get-window-load-settings'
|
||||
registerDefaultCommands = require './register-default-commands'
|
||||
|
||||
DeserializerManager = require './deserializer-manager'
|
||||
@@ -651,7 +651,7 @@ class AtomEnvironment extends Model
|
||||
|
||||
openInitialEmptyEditorIfNecessary: ->
|
||||
return unless @config.get('core.openEmptyEditorOnStart')
|
||||
if @getLoadSettings().initialPaths?.length is 0 and @workspace.getPaneItems().length is 0
|
||||
if @getLoadSettings().projectDirectoryPaths?.length is 0 and @workspace.getPaneItems().length is 0
|
||||
@workspace.open(null)
|
||||
|
||||
installUncaughtErrorHandler: ->
|
||||
@@ -753,7 +753,7 @@ class AtomEnvironment extends Model
|
||||
# Notify the browser project of the window's current project path
|
||||
watchProjectPath: ->
|
||||
@disposables.add @project.onDidChangePaths =>
|
||||
@applicationDelegate.setRepresentedDirectoryPaths(@project.getPaths())
|
||||
@applicationDelegate.setProjectDirectoryPaths(@project.getPaths())
|
||||
|
||||
setDocumentEdited: (edited) ->
|
||||
@applicationDelegate.setWindowDocumentEdited?(edited)
|
||||
@@ -789,7 +789,7 @@ class AtomEnvironment extends Model
|
||||
|
||||
startTime = Date.now()
|
||||
|
||||
if stateKey = @getStateKey(@getLoadSettings().initialPaths)
|
||||
if stateKey = @getStateKey(@getLoadSettings().projectDirectoryPaths)
|
||||
if state = @getStorageFolder().load(stateKey)
|
||||
@state = state
|
||||
|
||||
|
||||
@@ -437,9 +437,8 @@ class AtomApplication
|
||||
return if @quitting
|
||||
states = []
|
||||
for window in @windows
|
||||
unless window.isSpec
|
||||
if loadSettings = window.getLoadSettings()
|
||||
states.push(initialPaths: loadSettings.initialPaths)
|
||||
if not window.isSpec and window.projectDirectoryPaths?
|
||||
states.push(projectDirectoryPaths: window.projectDirectoryPaths)
|
||||
if states.length > 0 or allowEmpty
|
||||
@storageFolder.store('application.json', states)
|
||||
|
||||
@@ -447,7 +446,7 @@ class AtomApplication
|
||||
if (states = @storageFolder.load('application.json'))?.length > 0
|
||||
for state in states
|
||||
@openWithOptions(_.extend(options, {
|
||||
pathsToOpen: state.initialPaths
|
||||
pathsToOpen: state.projectDirectoryPaths
|
||||
urlsToOpen: []
|
||||
devMode: @devMode
|
||||
safeMode: @safeMode
|
||||
|
||||
@@ -55,14 +55,15 @@ class AtomWindow
|
||||
@constructor.includeShellLoadTime = false
|
||||
loadSettings.shellLoadTime ?= Date.now() - global.shellStartTime
|
||||
|
||||
loadSettings.initialPaths =
|
||||
loadSettings.projectDirectoryPaths =
|
||||
for {pathToOpen} in locationsToOpen when pathToOpen
|
||||
if fs.statSyncNoException(pathToOpen).isFile?()
|
||||
path.dirname(pathToOpen)
|
||||
else
|
||||
pathToOpen
|
||||
|
||||
loadSettings.initialPaths.sort()
|
||||
loadSettings.projectDirectoryPaths.sort()
|
||||
@setProjectDirectoryPaths(loadSettings.projectDirectoryPaths)
|
||||
|
||||
@browserWindow.loadSettings = loadSettings
|
||||
@browserWindow.once 'window:loaded', =>
|
||||
@@ -87,12 +88,9 @@ class AtomWindow
|
||||
slashes: true
|
||||
hash: encodeURIComponent(JSON.stringify(loadSettings))
|
||||
|
||||
getLoadSettings: ->
|
||||
if @browserWindow.webContents? and not @browserWindow.webContents.isLoading()
|
||||
hash = url.parse(@browserWindow.webContents.getUrl()).hash.substr(1)
|
||||
JSON.parse(decodeURIComponent(hash))
|
||||
setProjectDirectoryPaths: (@projectDirectoryPaths) ->
|
||||
|
||||
hasProjectPath: -> @getLoadSettings().initialPaths?.length > 0
|
||||
hasProjectPath: -> @projectDirectoryPaths?.length > 0
|
||||
|
||||
setupContextMenu: ->
|
||||
ContextMenu = require './context-menu'
|
||||
@@ -106,7 +104,7 @@ class AtomWindow
|
||||
true
|
||||
|
||||
containsPath: (pathToCheck) ->
|
||||
@getLoadSettings()?.initialPaths?.some (projectPath) ->
|
||||
@projectDirectoryPaths?.some (projectPath) ->
|
||||
if not projectPath
|
||||
false
|
||||
else if not pathToCheck
|
||||
@@ -121,6 +119,8 @@ class AtomWindow
|
||||
false
|
||||
|
||||
handleEvents: ->
|
||||
@browserWindow.on 'set-project-directory-paths', @setProjectDirectoryPaths.bind(this)
|
||||
|
||||
@browserWindow.on 'closed', =>
|
||||
global.atomApplication.removeWindow(this)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ _ = require 'underscore-plus'
|
||||
|
||||
windowLoadSettings = null
|
||||
|
||||
exports.getWindowLoadSettings = ->
|
||||
module.exports = ->
|
||||
windowLoadSettings ?= JSON.parse(window.decodeURIComponent(window.location.hash.substr(1)))
|
||||
clone = _.deepClone(windowLoadSettings)
|
||||
|
||||
@@ -14,7 +14,3 @@ exports.getWindowLoadSettings = ->
|
||||
remote.getCurrentWindow().loadSettings.windowState = value
|
||||
|
||||
clone
|
||||
|
||||
exports.setWindowLoadSettings = (settings) ->
|
||||
windowLoadSettings = settings
|
||||
location.hash = encodeURIComponent(JSON.stringify(settings))
|
||||
@@ -2,7 +2,7 @@
|
||||
module.exports = ({blobStore}) ->
|
||||
path = require 'path'
|
||||
require './window'
|
||||
{getWindowLoadSettings} = require './window-load-settings-helpers'
|
||||
getWindowLoadSettings = require './get-window-load-settings'
|
||||
|
||||
{resourcePath, isSpec, devMode} = getWindowLoadSettings()
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ module.exports = ({blobStore}) ->
|
||||
try
|
||||
path = require 'path'
|
||||
ipc = require 'ipc'
|
||||
{getWindowLoadSettings} = require './window-load-settings-helpers'
|
||||
getWindowLoadSettings = require './get-window-load-settings'
|
||||
AtomEnvironment = require '../src/atom-environment'
|
||||
ApplicationDelegate = require '../src/application-delegate'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user