Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
09b6468f
V
vscode
项目概览
掘金者说
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
09b6468f
编写于
11月 29, 2016
作者:
B
Benjamin Pasero
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
introduce shutdown reason (fixes #15509)
上级
4721762a
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
76 addition
and
42 deletion
+76
-42
src/vs/code/electron-main/lifecycle.ts
src/vs/code/electron-main/lifecycle.ts
+15
-8
src/vs/code/electron-main/windows.ts
src/vs/code/electron-main/windows.ts
+3
-3
src/vs/platform/lifecycle/common/lifecycle.ts
src/vs/platform/lifecycle/common/lifecycle.ts
+16
-8
src/vs/test/utils/servicesTestUtils.ts
src/vs/test/utils/servicesTestUtils.ts
+0
-1
src/vs/workbench/services/backup/common/backup.ts
src/vs/workbench/services/backup/common/backup.ts
+2
-1
src/vs/workbench/services/backup/node/backupService.ts
src/vs/workbench/services/backup/node/backupService.ts
+29
-3
src/vs/workbench/services/lifecycle/electron-browser/lifecycleService.ts
...h/services/lifecycle/electron-browser/lifecycleService.ts
+5
-12
src/vs/workbench/services/textfile/browser/textFileService.ts
...vs/workbench/services/textfile/browser/textFileService.ts
+4
-4
src/vs/workbench/services/textfile/test/textFileService.test.ts
.../workbench/services/textfile/test/textFileService.test.ts
+2
-2
未找到文件。
src/vs/code/electron-main/lifecycle.ts
浏览文件 @
09b6468f
...
...
@@ -16,6 +16,13 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'
export
const
ILifecycleService
=
createDecorator
<
ILifecycleService
>
(
'
lifecycleService
'
);
export
enum
UnloadReason
{
CLOSE
,
QUIT
,
RELOAD
,
LOAD
}
export
interface
ILifecycleService
{
_serviceBrand
:
any
;
...
...
@@ -33,7 +40,7 @@ export interface ILifecycleService {
ready
():
void
;
registerWindow
(
vscodeWindow
:
IVSCodeWindow
):
void
;
unload
(
vscodeWindow
:
IVSCodeWindow
):
TPromise
<
boolean
/* veto */
>
;
unload
(
vscodeWindow
:
IVSCodeWindow
,
reason
:
UnloadReason
):
TPromise
<
boolean
/* veto */
>
;
quit
(
fromUpdate
?:
boolean
):
TPromise
<
boolean
/* veto */
>
;
}
...
...
@@ -126,7 +133,7 @@ export class LifecycleService implements ILifecycleService {
// Otherwise prevent unload and handle it from window
e
.
preventDefault
();
this
.
unload
(
vscodeWindow
).
done
(
veto
=>
{
this
.
unload
(
vscodeWindow
,
UnloadReason
.
CLOSE
).
done
(
veto
=>
{
if
(
!
veto
)
{
this
.
windowToCloseRequest
[
windowId
]
=
true
;
vscodeWindow
.
win
.
close
();
...
...
@@ -138,7 +145,7 @@ export class LifecycleService implements ILifecycleService {
});
}
public
unload
(
vscodeWindow
:
IVSCodeWindow
):
TPromise
<
boolean
/* veto */
>
{
public
unload
(
vscodeWindow
:
IVSCodeWindow
,
reason
:
UnloadReason
):
TPromise
<
boolean
/* veto */
>
{
// Always allow to unload a window that is not yet ready
if
(
vscodeWindow
.
readyState
!==
ReadyState
.
READY
)
{
...
...
@@ -149,14 +156,14 @@ export class LifecycleService implements ILifecycleService {
return
new
TPromise
<
boolean
>
((
c
)
=>
{
const
oneTimeEventToken
=
this
.
oneTimeListenerTokenGenerator
++
;
const
o
neTimeOkEvent
=
'
vscode:ok
'
+
oneTimeEventToken
;
const
oneTimeCancelEvent
=
'
vscode:cancel
'
+
oneTimeEventToken
;
const
o
kChannel
=
`vscode:ok
${
oneTimeEventToken
}
`
;
const
cancelChannel
=
`vscode:cancel
${
oneTimeEventToken
}
`
;
ipc
.
once
(
o
neTimeOkEvent
,
()
=>
{
ipc
.
once
(
o
kChannel
,
()
=>
{
c
(
false
);
// no veto
});
ipc
.
once
(
oneTimeCancelEvent
,
()
=>
{
ipc
.
once
(
cancelChannel
,
()
=>
{
// Any cancellation also cancels a pending quit if present
if
(
this
.
pendingQuitPromiseComplete
)
{
...
...
@@ -168,7 +175,7 @@ export class LifecycleService implements ILifecycleService {
c
(
true
);
// veto
});
vscodeWindow
.
send
(
'
vscode:beforeUnload
'
,
{
okChannel
:
oneTimeOkEvent
,
cancelChannel
:
oneTimeCancelEvent
,
quitRequested
:
this
.
quitRequested
});
vscodeWindow
.
send
(
'
vscode:beforeUnload
'
,
{
okChannel
,
cancelChannel
,
reason
:
this
.
quitRequested
?
UnloadReason
.
QUIT
:
reason
});
});
}
...
...
src/vs/code/electron-main/windows.ts
浏览文件 @
09b6468f
...
...
@@ -20,7 +20,7 @@ import { IStorageService } from 'vs/code/electron-main/storage';
import
{
IPath
,
VSCodeWindow
,
IWindowConfiguration
,
IWindowState
as
ISingleWindowState
,
defaultWindowState
,
ReadyState
}
from
'
vs/code/electron-main/window
'
;
import
{
ipcMain
as
ipc
,
app
,
screen
,
BrowserWindow
,
dialog
}
from
'
electron
'
;
import
{
IPathWithLineAndColumn
,
parseLineAndColumnAware
}
from
'
vs/code/electron-main/paths
'
;
import
{
ILifecycleService
}
from
'
vs/code/electron-main/lifecycle
'
;
import
{
ILifecycleService
,
UnloadReason
}
from
'
vs/code/electron-main/lifecycle
'
;
import
{
IConfigurationService
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
ILogService
}
from
'
vs/code/electron-main/log
'
;
import
{
getPathLabel
}
from
'
vs/base/common/labels
'
;
...
...
@@ -273,7 +273,7 @@ export class WindowsManager implements IWindowsMainService {
public
reload
(
win
:
VSCodeWindow
,
cli
?:
ParsedArgs
):
void
{
// Only reload when the window has not vetoed this
this
.
lifecycleService
.
unload
(
win
).
done
(
veto
=>
{
this
.
lifecycleService
.
unload
(
win
,
UnloadReason
.
RELOAD
).
done
(
veto
=>
{
if
(
!
veto
)
{
win
.
reload
(
cli
);
}
...
...
@@ -762,7 +762,7 @@ export class WindowsManager implements IWindowsMainService {
}
// Only load when the window has not vetoed this
this
.
lifecycleService
.
unload
(
vscodeWindow
).
done
(
veto
=>
{
this
.
lifecycleService
.
unload
(
vscodeWindow
,
UnloadReason
.
LOAD
).
done
(
veto
=>
{
if
(
!
veto
)
{
// Load it
...
...
src/vs/platform/lifecycle/common/lifecycle.ts
浏览文件 @
09b6468f
...
...
@@ -20,7 +20,22 @@ export const ILifecycleService = createDecorator<ILifecycleService>('lifecycleSe
*/
export
interface
ShutdownEvent
{
veto
(
value
:
boolean
|
TPromise
<
boolean
>
):
void
;
quitRequested
:
boolean
;
reason
:
ShutdownReason
;
}
export
enum
ShutdownReason
{
/** Window is closed */
CLOSE
,
/** Application is quit */
QUIT
,
/** Window is reloaded */
RELOAD
,
/** Other configuration loaded into window */
LOAD
}
/**
...
...
@@ -37,12 +52,6 @@ export interface ILifecycleService {
*/
willShutdown
:
boolean
;
/**
* A flag indications if the application is in the process of quitting all windows. This will be
* set before the onWillShutdown event is fired and reverted to false afterwards.
*/
quitRequested
:
boolean
;
/**
* Fired before shutdown happens. Allows listeners to veto against the
* shutdown.
...
...
@@ -59,7 +68,6 @@ export interface ILifecycleService {
export
const
NullLifecycleService
:
ILifecycleService
=
{
_serviceBrand
:
null
,
willShutdown
:
false
,
quitRequested
:
false
,
onWillShutdown
:
()
=>
({
dispose
()
{
}
}),
onShutdown
:
()
=>
({
dispose
()
{
}
})
};
\ No newline at end of file
src/vs/test/utils/servicesTestUtils.ts
浏览文件 @
09b6468f
...
...
@@ -708,7 +708,6 @@ export class TestLifecycleService implements ILifecycleService {
public
_serviceBrand
:
any
;
public
willShutdown
:
boolean
;
public
quitRequested
:
boolean
;
private
_onWillShutdown
=
new
Emitter
<
ShutdownEvent
>
();
private
_onShutdown
=
new
Emitter
<
void
>
();
...
...
src/vs/workbench/services/backup/common/backup.ts
浏览文件 @
09b6468f
...
...
@@ -10,6 +10,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
ITextFileEditorModelManager
}
from
'
vs/workbench/services/textfile/common/textfiles
'
;
import
{
IResolveContentOptions
,
IUpdateContentOptions
}
from
'
vs/platform/files/common/files
'
;
import
{
ShutdownReason
}
from
'
vs/platform/lifecycle/common/lifecycle
'
;
export
const
IBackupService
=
createDecorator
<
IBackupService
>
(
'
backupService
'
);
export
const
IBackupFileService
=
createDecorator
<
IBackupFileService
>
(
'
backupFileService
'
);
...
...
@@ -29,7 +30,7 @@ export interface IBackupService {
_serviceBrand
:
any
;
isHotExitEnabled
:
boolean
;
backupBeforeShutdown
(
dirtyToBackup
:
Uri
[],
textFileEditorModelManager
:
ITextFileEditorModelManager
,
quitRequested
:
boolea
n
):
TPromise
<
IBackupResult
>
;
backupBeforeShutdown
(
dirtyToBackup
:
Uri
[],
textFileEditorModelManager
:
ITextFileEditorModelManager
,
reason
:
ShutdownReaso
n
):
TPromise
<
IBackupResult
>
;
cleanupBackupsBeforeShutdown
():
TPromise
<
void
>
;
}
...
...
src/vs/workbench/services/backup/node/backupService.ts
浏览文件 @
09b6468f
...
...
@@ -17,6 +17,7 @@ import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/un
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
IEnvironmentService
}
from
'
vs/platform/environment/common/environment
'
;
import
{
IWindowsService
}
from
'
vs/platform/windows/common/windows
'
;
import
{
ShutdownReason
}
from
'
vs/platform/lifecycle/common/lifecycle
'
;
export
class
BackupService
implements
IBackupService
{
...
...
@@ -95,21 +96,46 @@ export class BackupService implements IBackupService {
return
!
this
.
environmentService
.
isExtensionDevelopment
&&
this
.
configuredHotExit
&&
!!
this
.
contextService
.
getWorkspace
();
}
public
backupBeforeShutdown
(
dirtyToBackup
:
Uri
[],
textFileEditorModelManager
:
ITextFileEditorModelManager
,
quitRequested
:
boolea
n
):
TPromise
<
IBackupResult
>
{
public
backupBeforeShutdown
(
dirtyToBackup
:
Uri
[],
textFileEditorModelManager
:
ITextFileEditorModelManager
,
reason
:
ShutdownReaso
n
):
TPromise
<
IBackupResult
>
{
if
(
!
this
.
isHotExitEnabled
)
{
return
TPromise
.
as
({
didBackup
:
false
});
}
return
this
.
windowsService
.
getWindowCount
().
then
(
windowCount
=>
{
// When quit is requested skip the confirm callback and attempt to backup all workspaces.
// When quit is not requested the confirm callback should be shown when the window being
// closed is the only VS Code window open, except for on Mac where hot exit is only
// ever activated when quit is requested.
if
(
!
quitRequested
&&
(
windowCount
>
1
||
platform
.
isMacintosh
))
{
let
doBackup
:
boolean
;
switch
(
reason
)
{
case
ShutdownReason
.
CLOSE
:
if
(
windowCount
>
1
||
platform
.
isMacintosh
)
{
doBackup
=
false
;
// do not backup if a window is closed that does not cause quitting of the application
}
else
{
doBackup
=
true
;
// backup if last window is closed on win/linux where the application quits right after
}
break
;
case
ShutdownReason
.
QUIT
:
doBackup
=
true
;
// backup because next start we restore all backups
break
;
case
ShutdownReason
.
RELOAD
:
doBackup
=
true
;
// backup because after window reload, backups restore
break
;
case
ShutdownReason
.
LOAD
:
doBackup
=
false
;
// do not backup because we are switching contexts
break
;
}
if
(
!
doBackup
)
{
return
TPromise
.
as
({
didBackup
:
false
});
}
// Backup
and hot exit
// Backup
return
this
.
backupAll
(
dirtyToBackup
,
textFileEditorModelManager
).
then
(()
=>
{
return
{
didBackup
:
true
};
});
// we did backup
});
}
...
...
src/vs/workbench/services/lifecycle/electron-browser/lifecycleService.ts
浏览文件 @
09b6468f
...
...
@@ -7,7 +7,7 @@
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
Severity
from
'
vs/base/common/severity
'
;
import
{
toErrorMessage
}
from
'
vs/base/common/errorMessage
'
;
import
{
ILifecycleService
,
ShutdownEvent
}
from
'
vs/platform/lifecycle/common/lifecycle
'
;
import
{
ILifecycleService
,
ShutdownEvent
,
ShutdownReason
}
from
'
vs/platform/lifecycle/common/lifecycle
'
;
import
{
IMessageService
}
from
'
vs/platform/message/common/message
'
;
import
{
IWindowIPCService
}
from
'
vs/workbench/services/window/electron-browser/windowService
'
;
import
{
ipcRenderer
as
ipc
}
from
'
electron
'
;
...
...
@@ -21,7 +21,6 @@ export class LifecycleService implements ILifecycleService {
private
_onShutdown
=
new
Emitter
<
void
>
();
private
_willShutdown
:
boolean
;
private
_quitRequested
:
boolean
;
constructor
(
@
IMessageService
private
messageService
:
IMessageService
,
...
...
@@ -34,10 +33,6 @@ export class LifecycleService implements ILifecycleService {
return
this
.
_willShutdown
;
}
public
get
quitRequested
():
boolean
{
return
this
.
_quitRequested
;
}
public
get
onWillShutdown
():
Event
<
ShutdownEvent
>
{
return
this
.
_onWillShutdown
.
event
;
}
...
...
@@ -50,13 +45,11 @@ export class LifecycleService implements ILifecycleService {
const
windowId
=
this
.
windowService
.
getWindowId
();
// Main side indicates that window is about to unload, check for vetos
ipc
.
on
(
'
vscode:beforeUnload
'
,
(
event
,
reply
:
{
okChannel
:
string
,
cancelChannel
:
string
,
quitRequested
:
boolea
n
})
=>
{
ipc
.
on
(
'
vscode:beforeUnload
'
,
(
event
,
reply
:
{
okChannel
:
string
,
cancelChannel
:
string
,
reason
:
ShutdownReaso
n
})
=>
{
this
.
_willShutdown
=
true
;
this
.
_quitRequested
=
reply
.
quitRequested
;
// trigger onWillShutdown events and veto collecting
this
.
onBeforeUnload
(
reply
.
quitRequested
).
done
(
veto
=>
{
this
.
_quitRequested
=
false
;
this
.
onBeforeUnload
(
reply
.
reason
).
done
(
veto
=>
{
if
(
veto
)
{
this
.
_willShutdown
=
false
;
// reset this flag since the shutdown has been vetoed!
ipc
.
send
(
reply
.
cancelChannel
,
windowId
);
...
...
@@ -68,14 +61,14 @@ export class LifecycleService implements ILifecycleService {
});
}
private
onBeforeUnload
(
quitRequested
:
boolea
n
):
TPromise
<
boolean
>
{
private
onBeforeUnload
(
reason
:
ShutdownReaso
n
):
TPromise
<
boolean
>
{
const
vetos
:
(
boolean
|
TPromise
<
boolean
>
)[]
=
[];
this
.
_onWillShutdown
.
fire
({
veto
(
value
)
{
vetos
.
push
(
value
);
},
quitRequested
reason
});
if
(
vetos
.
length
===
0
)
{
...
...
src/vs/workbench/services/textfile/browser/textFileService.ts
浏览文件 @
09b6468f
...
...
@@ -14,7 +14,7 @@ import objects = require('vs/base/common/objects');
import
Event
,
{
Emitter
}
from
'
vs/base/common/event
'
;
import
{
IResult
,
ITextFileOperationResult
,
ITextFileService
,
IRawTextContent
,
IAutoSaveConfiguration
,
AutoSaveMode
,
SaveReason
,
ITextFileEditorModelManager
,
ITextFileEditorModel
,
ISaveOptions
}
from
'
vs/workbench/services/textfile/common/textfiles
'
;
import
{
ConfirmResult
}
from
'
vs/workbench/common/editor
'
;
import
{
ILifecycleService
}
from
'
vs/platform/lifecycle/common/lifecycle
'
;
import
{
ILifecycleService
,
ShutdownReason
}
from
'
vs/platform/lifecycle/common/lifecycle
'
;
import
{
IWorkspaceContextService
}
from
'
vs/platform/workspace/common/workspace
'
;
import
{
IFileService
,
IResolveContentOptions
,
IFilesConfiguration
,
IFileOperationResult
,
FileOperationResult
,
AutoSaveConfiguration
}
from
'
vs/platform/files/common/files
'
;
import
{
IConfigurationService
}
from
'
vs/platform/configuration/common/configuration
'
;
...
...
@@ -101,7 +101,7 @@ export abstract class TextFileService implements ITextFileService {
private
registerListeners
():
void
{
// Lifecycle
this
.
lifecycleService
.
onWillShutdown
(
event
=>
event
.
veto
(
this
.
beforeShutdown
(
event
.
quitRequested
)));
this
.
lifecycleService
.
onWillShutdown
(
event
=>
event
.
veto
(
this
.
beforeShutdown
(
event
.
reason
)));
this
.
lifecycleService
.
onShutdown
(
this
.
dispose
,
this
);
// Configuration changes
...
...
@@ -113,7 +113,7 @@ export abstract class TextFileService implements ITextFileService {
this
.
toUnbind
.
push
(
this
.
editorGroupService
.
onEditorsChanged
(()
=>
this
.
onEditorFocusChanged
()));
}
private
beforeShutdown
(
quitRequested
:
boolea
n
):
boolean
|
TPromise
<
boolean
>
{
private
beforeShutdown
(
reason
:
ShutdownReaso
n
):
boolean
|
TPromise
<
boolean
>
{
// Dirty files need treatment on shutdown
const
dirty
=
this
.
getDirty
();
...
...
@@ -135,7 +135,7 @@ export abstract class TextFileService implements ITextFileService {
// If hot exit is enabled, backup dirty files and allow to exit without confirmation
if
(
this
.
backupService
.
isHotExitEnabled
)
{
return
this
.
backupService
.
backupBeforeShutdown
(
dirty
,
this
.
models
,
quitRequested
).
then
(
result
=>
{
return
this
.
backupService
.
backupBeforeShutdown
(
dirty
,
this
.
models
,
reason
).
then
(
result
=>
{
if
(
result
.
didBackup
)
{
return
this
.
noVeto
({
cleanUpBackups
:
false
});
// no veto and no backup cleanup (since backup was successful)
}
...
...
src/vs/workbench/services/textfile/test/textFileService.test.ts
浏览文件 @
09b6468f
...
...
@@ -6,7 +6,7 @@
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
*
as
assert
from
'
assert
'
;
import
{
ILifecycleService
,
ShutdownEvent
}
from
'
vs/platform/lifecycle/common/lifecycle
'
;
import
{
ILifecycleService
,
ShutdownEvent
,
ShutdownReason
}
from
'
vs/platform/lifecycle/common/lifecycle
'
;
import
{
workbenchInstantiationService
,
TestLifecycleService
,
TestTextFileService
,
onError
,
toResource
}
from
'
vs/test/utils/servicesTestUtils
'
;
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
TextFileEditorModel
}
from
'
vs/workbench/services/textfile/common/textFileEditorModel
'
;
...
...
@@ -28,7 +28,7 @@ class ServiceAccessor {
class
ShutdownEventImpl
implements
ShutdownEvent
{
public
value
:
boolean
|
TPromise
<
boolean
>
;
public
quitRequested
:
boolean
=
false
;
public
reason
=
ShutdownReason
.
CLOSE
;
veto
(
value
:
boolean
|
TPromise
<
boolean
>
):
void
{
this
.
value
=
value
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录