mirror of
https://github.com/gosticks/vscode-vibrancy-continued.git
synced 2025-10-16 12:05:38 +00:00
try fix win10 drag delay
This commit is contained in:
parent
636565fdba
commit
da3dd1eb9d
355
.gitignore
vendored
355
.gitignore
vendored
@ -5,357 +5,4 @@ test
|
||||
firstload.lock
|
||||
*.vsix
|
||||
yarn.lock
|
||||
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
/build
|
||||
39
binding.gyp
Normal file
39
binding.gyp
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"targets": [
|
||||
{
|
||||
"target_name": "vibrancy",
|
||||
"conditions":[
|
||||
["OS=='win'", {
|
||||
"sources": [
|
||||
"native/vibrancy.cc"
|
||||
]
|
||||
}]
|
||||
],
|
||||
"cflags": [
|
||||
"-O3"
|
||||
],
|
||||
"include_dirs": [
|
||||
"<!@(node -p \"require('node-addon-api').include\")"
|
||||
],
|
||||
"defines": [
|
||||
"NAPI_DISABLE_CPP_EXCEPTIONS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target_name": "displayconfig",
|
||||
"cflags!": ["-fno-exceptions"],
|
||||
"cflags_cc!": ["-fno-exceptions"],
|
||||
"conditions": [
|
||||
["OS=='win'", {
|
||||
"sources": ["native/displayconfig.cc"]
|
||||
}],
|
||||
],
|
||||
"include_dirs": [
|
||||
"<!@(node -p \"require('node-addon-api').include\")"
|
||||
],
|
||||
'defines': [
|
||||
'NAPI_DISABLE_CPP_EXCEPTIONS'
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
20
extension/i18n.js
Normal file
20
extension/i18n.js
Normal file
@ -0,0 +1,20 @@
|
||||
var fs = require('mz/fs');
|
||||
var vscode = require('vscode');
|
||||
var path = require('path');
|
||||
|
||||
const i18nMessages = {
|
||||
'en': JSON.parse(fs.readFileSync(path.join(__dirname, '../package.nls.json'))),
|
||||
'zh-cn': JSON.parse(fs.readFileSync(path.join(__dirname, '../package.nls.zh-CN.json'))),
|
||||
'ja': JSON.parse(fs.readFileSync(path.join(__dirname, '../package.nls.ja.json')))
|
||||
};
|
||||
const defaultLocale = 'en';
|
||||
const locale = (vscode.env.language || defaultLocale).toLowerCase();
|
||||
const localize = (info) => {
|
||||
if (locale in i18nMessages && info in i18nMessages[locale]) {
|
||||
return i18nMessages[locale][info]
|
||||
} else {
|
||||
return i18nMessages[defaultLocale][info]
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = localize;
|
||||
@ -1,397 +1,276 @@
|
||||
var vscode = require('vscode');
|
||||
var fs = require('mz/fs');
|
||||
var path = require('path');
|
||||
var lockPath = path.join(__dirname, '../firstload.lock');
|
||||
|
||||
const i18nMessages = {
|
||||
'en': JSON.parse(fs.readFileSync(path.join(__dirname, 'extension.nls.json'))),
|
||||
'zh-cn': JSON.parse(fs.readFileSync(path.join(__dirname, 'extension.nls.zh-CN.json'))),
|
||||
'ja': JSON.parse(fs.readFileSync(path.join(__dirname, 'extension.nls.ja.json')))
|
||||
};
|
||||
const defaultLocale = 'en';
|
||||
const locale = (vscode.env.language || defaultLocale).toLowerCase();
|
||||
const localize = (info) => {
|
||||
if (locale in i18nMessages && info in i18nMessages[locale]) {
|
||||
return i18nMessages[locale][info]
|
||||
} else {
|
||||
return i18nMessages[defaultLocale][info]
|
||||
}
|
||||
}
|
||||
|
||||
let os = 'macos';
|
||||
if (/^win/.test(process.platform)) {
|
||||
if (require('os').release().split(".").map(Number)[0] === 10) {
|
||||
os = 'win10';
|
||||
} else {
|
||||
os = 'win7';
|
||||
}
|
||||
}
|
||||
|
||||
var themeStylePaths = {
|
||||
'Default Dark': '../themes/Default Dark.css',
|
||||
'Dark (Only Subbar)': '../themes/Dark (Only Subbar).css',
|
||||
'Default Light': '../themes/Default Light.css',
|
||||
}
|
||||
|
||||
const themeConfigPaths = {
|
||||
'Default Dark': '../themes/Default Dark.json',
|
||||
'Dark (Only Subbar)': '../themes/Dark (Only Subbar).json',
|
||||
'Default Light': '../themes/Default Light.json',
|
||||
}
|
||||
|
||||
var defaultTheme = 'Default Dark';
|
||||
|
||||
function getCurrentTheme(config) {
|
||||
return config.theme in themeStylePaths ? config.theme : defaultTheme;
|
||||
}
|
||||
|
||||
async function changeTerminalRendererType() {
|
||||
// This is a hacky way to display the restart prompt
|
||||
let v = vscode.workspace.getConfiguration().inspect("terminal.integrated.rendererType");
|
||||
if (v !== undefined) {
|
||||
if (!v.globalValue) {
|
||||
await vscode.workspace.getConfiguration().update("terminal.integrated.rendererType", "dom", vscode.ConfigurationTarget.Global);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// async function promptRestart() {
|
||||
// let v = vscode.workspace.getConfiguration().inspect("window.titleBarStyle");
|
||||
// if (v !== undefined) {
|
||||
// let value = vscode.workspace.getConfiguration().get("window.titleBarStyle");
|
||||
// vscode.workspace.getConfiguration().update("window.titleBarStyle", value === "native" ? "custom" : "native", vscode.ConfigurationTarget.Global);
|
||||
// vscode.workspace.getConfiguration().update("window.titleBarStyle", v.globalValue, vscode.ConfigurationTarget.Global);
|
||||
// }
|
||||
// }
|
||||
|
||||
async function checkColorTheme() {
|
||||
const currentTheme = getCurrentTheme(vscode.workspace.getConfiguration("vscode_vibrancy"));
|
||||
const themeConfig = require(path.join(__dirname, themeConfigPaths[currentTheme]));
|
||||
const target = themeConfig.colorTheme;
|
||||
const currentColorTheme = vscode.workspace.getConfiguration().get("workbench.colorTheme");
|
||||
if (target !== currentColorTheme) {
|
||||
const message = localize('messages.recommendedColorTheme').replace('%1', currentColorTheme).replace('%2', target);
|
||||
await vscode.window.showInformationMessage(message, localize('messages.changeColorThemeIde'), localize('messages.noIde'))
|
||||
.then(async (msg) => {
|
||||
if (msg === localize('messages.changeColorThemeIde')) {
|
||||
await vscode.workspace.getConfiguration().update("workbench.colorTheme", target, vscode.ConfigurationTarget.Global);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function deepEqual(obj1, obj2) {
|
||||
|
||||
if(obj1 === obj2) // it's just the same object. No need to compare.
|
||||
return true;
|
||||
|
||||
if(isPrimitive(obj1) && isPrimitive(obj2)) // compare primitives
|
||||
return obj1 === obj2;
|
||||
|
||||
if(Object.keys(obj1).length !== Object.keys(obj2).length)
|
||||
return false;
|
||||
|
||||
// compare objects with same number of keys
|
||||
for(let key in obj1)
|
||||
{
|
||||
if(!(key in obj2)) return false; //other object doesn't have this prop
|
||||
if(!deepEqual(obj1[key], obj2[key])) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function hexToRgb(hex) {
|
||||
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
return result ? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16)
|
||||
} : null;
|
||||
}
|
||||
|
||||
//check if value is primitive
|
||||
function isPrimitive(obj)
|
||||
{
|
||||
return (obj !== Object(obj));
|
||||
}
|
||||
|
||||
function isFirstload() {
|
||||
try {
|
||||
fs.readFileSync(lockPath);
|
||||
return false
|
||||
} catch (err) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
function lockFirstload() {
|
||||
fs.writeFileSync(lockPath, '', () => {});
|
||||
}
|
||||
|
||||
function injectHTML(config, currentTheme, themeConfig) {
|
||||
var type = config.type;
|
||||
if (type === 'auto') {
|
||||
type = themeConfig.type[os];
|
||||
}
|
||||
|
||||
let opacity = config.opacity;
|
||||
|
||||
if (opacity < 0) {
|
||||
opacity = themeConfig.opacity[os]
|
||||
}
|
||||
|
||||
if (os === 'win10') {
|
||||
opacity = 0;
|
||||
}
|
||||
|
||||
const backgroundRGB = hexToRgb(themeConfig.background);
|
||||
|
||||
const HTML = [
|
||||
`
|
||||
<style>
|
||||
html {
|
||||
background: rgba(${backgroundRGB.r},${backgroundRGB.g},${backgroundRGB.b},${opacity}) !important;
|
||||
}
|
||||
</style>
|
||||
`,
|
||||
...config.imports.map(function (x) {
|
||||
if (!x) return;
|
||||
if (typeof x === 'string') {
|
||||
x = x.replace('%theme-style%', path.join(__dirname, themeStylePaths[currentTheme]));
|
||||
x = x.replace('$theme-style$', path.join(__dirname, themeStylePaths[currentTheme]));
|
||||
x = new URL(x, 'file://').href;
|
||||
|
||||
if (!x.startsWith('file://')) {
|
||||
x = 'file://' + x;
|
||||
}
|
||||
|
||||
if (/^.*\.js$/.test(x)) return '<script src="' + x + '"></script>';
|
||||
if (/^.*\.css$/.test(x)) return '<link rel="stylesheet" href="' + x + '"/>';
|
||||
}
|
||||
})
|
||||
]
|
||||
|
||||
return HTML.join('')
|
||||
}
|
||||
|
||||
const macosType = [
|
||||
"appearance-based",
|
||||
"light",
|
||||
"dark",
|
||||
"titlebar",
|
||||
"selection",
|
||||
"menu",
|
||||
"popover",
|
||||
"sidebar",
|
||||
"medium-light",
|
||||
"ultra-dark"
|
||||
];
|
||||
|
||||
const windowsType = [
|
||||
"dwm",
|
||||
"acrylic"
|
||||
];
|
||||
|
||||
function injectJS(config, currentTheme, themeConfig) {
|
||||
var type = config.type;
|
||||
if (type !== 'auto') {
|
||||
if (os === 'win10' || os === 'win7' && !windowsType.includes(type)) type = 'auto';
|
||||
if (os === 'macos' && !macosType.includes(type)) type = 'auto';
|
||||
}
|
||||
if (type === 'auto') {
|
||||
type = themeConfig.type[os];
|
||||
}
|
||||
|
||||
let opacity = config.opacity;
|
||||
|
||||
if (opacity < 0) {
|
||||
opacity = themeConfig.opacity[os]
|
||||
}
|
||||
|
||||
return `
|
||||
const electron = require('electron');
|
||||
|
||||
electron.app.on('browser-window-created', (event, window) => {
|
||||
window.webContents.on('dom-ready', () => {
|
||||
window.setBackgroundColor('#00000000');
|
||||
|
||||
${os !== 'macos' ?
|
||||
`require("child_process")
|
||||
.spawn(${JSON.stringify(__dirname + '\\blur-cli.exe')}, [new Uint32Array(window.getNativeWindowHandle().buffer)[0], '--type', ${JSON.stringify(type)}, '--enable', 'true', '--color', '${themeConfig.background}', '--opacity', ${JSON.stringify(opacity)}]);` :
|
||||
`window.setVibrancy(${JSON.stringify(type)});`
|
||||
}
|
||||
|
||||
// hack
|
||||
const width = window.getBounds().width;
|
||||
window.setBounds({
|
||||
width: width + 1,
|
||||
});
|
||||
window.setBounds({
|
||||
width,
|
||||
});
|
||||
|
||||
window.webContents.executeJavaScript(${JSON.stringify("document.body.innerHTML += " + JSON.stringify(injectHTML(config, currentTheme, themeConfig)))})
|
||||
});
|
||||
})
|
||||
`
|
||||
}
|
||||
|
||||
function activate(context) {
|
||||
console.log('vscode-vibrancy is active!');
|
||||
|
||||
process.on('uncaughtException', function (err) {
|
||||
if (/ENOENT|EACCES|EPERM/.test(err.code)) {
|
||||
vscode.window.showInformationMessage(localize('messages.admin'));
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
var isWin = /^win/.test(process.platform);
|
||||
var appDir = path.dirname(require.main.filename);
|
||||
|
||||
var HTMLFile = appDir + (isWin ? '\\vs\\code\\electron-browser\\workbench\\workbench.html' : '/vs/code/electron-browser/workbench/workbench.html');
|
||||
var JSFile = appDir + (isWin ? '\\main.js' : '/main.js');
|
||||
|
||||
async function installJS() {
|
||||
const config = vscode.workspace.getConfiguration("vscode_vibrancy");
|
||||
const currentTheme = getCurrentTheme(config);
|
||||
const themeConfig = require(path.join(__dirname, themeConfigPaths[currentTheme]));
|
||||
|
||||
const JS = await fs.readFile(JSFile, 'utf-8');
|
||||
const newJS = JS.replace(/\/\* !! VSCODE-VIBRANCY-START !! \*\/[\s\S]*?\/\* !! VSCODE-VIBRANCY-END !! \*\//, '')
|
||||
+ '\n/* !! VSCODE-VIBRANCY-START !! */\n(function(){' + injectJS(config, currentTheme, themeConfig) + '})()\n/* !! VSCODE-VIBRANCY-END !! */\n';
|
||||
await fs.writeFile(JSFile, newJS, 'utf-8');
|
||||
}
|
||||
|
||||
async function uninstallJS() {
|
||||
const JS = await fs.readFile(JSFile, 'utf-8');
|
||||
const needClean = /\/\* !! VSCODE-VIBRANCY-START !! \*\/[\s\S]*?\/\* !! VSCODE-VIBRANCY-END !! \*\//.test(JS);
|
||||
if (needClean) {
|
||||
const newJS = JS
|
||||
.replace(/\/\* !! VSCODE-VIBRANCY-START !! \*\/[\s\S]*?\/\* !! VSCODE-VIBRANCY-END !! \*\//, '')
|
||||
await fs.writeFile(JSFile, newJS, 'utf-8');
|
||||
}
|
||||
}
|
||||
|
||||
async function uninstallHTML() {
|
||||
const HTML = await fs.readFile(HTMLFile, 'utf-8');
|
||||
const needClean = /<!-- !! VSCODE-VIBRANCY-START !! -->[\s\S]*?<!-- !! VSCODE-VIBRANCY-END !! -->/.test(HTML);
|
||||
if (needClean) {
|
||||
const newHTML = HTML
|
||||
.replace(/<!-- !! VSCODE-VIBRANCY-START !! -->[\s\S]*?<!-- !! VSCODE-VIBRANCY-END !! -->/, '')
|
||||
.replace(/<meta.*http-equiv="Content-Security-Policy".*>/, '');
|
||||
await fs.writeFile(HTMLFile, newHTML, 'utf-8');
|
||||
}
|
||||
}
|
||||
|
||||
function enabledRestart() {
|
||||
vscode.window.showInformationMessage(localize('messages.enabled'), { title: localize('messages.reloadIde') })
|
||||
// .then(function (msg) {
|
||||
// msg && promptRestart();
|
||||
// });
|
||||
}
|
||||
|
||||
function disabledRestart() {
|
||||
vscode.window.showInformationMessage(localize('messages.disabled'), { title: localize('messages.restartIde') })
|
||||
// .then(function (msg) {
|
||||
// msg && promptRestart();
|
||||
// });
|
||||
}
|
||||
|
||||
// #### main commands ######################################################
|
||||
|
||||
async function Install(autoreload) {
|
||||
try {
|
||||
await fs.stat(JSFile);
|
||||
await changeTerminalRendererType()
|
||||
} catch (error) {
|
||||
vscode.window.showInformationMessage(localize('messages.smthingwrong') + error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
try {
|
||||
await installJS();
|
||||
} catch (error) {
|
||||
vscode.window.showInformationMessage(localize('messages.admin'));
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function Uninstall() {
|
||||
try {
|
||||
await fs.stat(JSFile);
|
||||
await fs.stat(HTMLFile);
|
||||
} catch(error) {
|
||||
vscode.window.showInformationMessage(localize('messages.smthingwrong') + error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
try {
|
||||
await uninstallHTML();
|
||||
await uninstallJS();
|
||||
} catch(error) {
|
||||
vscode.window.showInformationMessage(localize('messages.admin'));
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function Update() {
|
||||
await Uninstall();
|
||||
await Install();
|
||||
}
|
||||
|
||||
var installVibrancy = vscode.commands.registerCommand('extension.installVibrancy', async () => {
|
||||
await Install();
|
||||
enabledRestart();
|
||||
});
|
||||
var uninstallVibrancy = vscode.commands.registerCommand('extension.uninstallVibrancy', async () => {
|
||||
await Uninstall()
|
||||
disabledRestart();
|
||||
});
|
||||
var updateVibrancy = vscode.commands.registerCommand('extension.updateVibrancy', async () => {
|
||||
await Update();
|
||||
enabledRestart();
|
||||
});
|
||||
|
||||
context.subscriptions.push(installVibrancy);
|
||||
context.subscriptions.push(uninstallVibrancy);
|
||||
context.subscriptions.push(updateVibrancy);
|
||||
|
||||
if (isFirstload()) {
|
||||
vscode.window.showInformationMessage(localize('messages.firstload'), { title: localize('messages.installIde') })
|
||||
.then(async (msg) => {
|
||||
if (msg) {
|
||||
await Update();
|
||||
await checkColorTheme();
|
||||
enabledRestart();
|
||||
}
|
||||
});
|
||||
lockFirstload();
|
||||
}
|
||||
|
||||
var lastConfig = vscode.workspace.getConfiguration("vscode_vibrancy");
|
||||
|
||||
vscode.workspace.onDidChangeConfiguration(() => {
|
||||
newConfig = vscode.workspace.getConfiguration("vscode_vibrancy");
|
||||
if (!deepEqual(lastConfig, newConfig)) {
|
||||
lastConfig = newConfig;
|
||||
vscode.window.showInformationMessage(localize('messages.configupdate'), { title: localize('messages.reloadIde') })
|
||||
.then(async (msg) => {
|
||||
if (msg) {
|
||||
await Update();
|
||||
if (newConfig.theme !== vscode.workspace.getConfiguration("vscode_vibrancy")) {
|
||||
await checkColorTheme();
|
||||
}
|
||||
promptRestart();
|
||||
}
|
||||
});
|
||||
lockFirstload();
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.activate = activate;
|
||||
|
||||
// this method is called when your extension is deactivated
|
||||
function deactivate() { }
|
||||
exports.deactivate = deactivate;
|
||||
var vscode = require('vscode');
|
||||
var fs = require('mz/fs');
|
||||
var fsExtra = require('fs-extra');
|
||||
var path = require('path');
|
||||
var lockPath = path.join(__dirname, '../firstload.lock');
|
||||
|
||||
/**
|
||||
* @type {(info: string) => string}
|
||||
*/
|
||||
const localize = require('./i18n');
|
||||
|
||||
/**
|
||||
* @type {'unknown' | 'win10' | 'macos'}
|
||||
*/
|
||||
const os = require('./platform');
|
||||
|
||||
var themeStylePaths = {
|
||||
'Default Dark': '../themes/Default Dark.css',
|
||||
'Dark (Only Subbar)': '../themes/Dark (Only Subbar).css',
|
||||
'Default Light': '../themes/Default Light.css',
|
||||
}
|
||||
|
||||
const themeConfigPaths = {
|
||||
'Default Dark': '../themes/Default Dark.json',
|
||||
'Dark (Only Subbar)': '../themes/Dark (Only Subbar).json',
|
||||
'Default Light': '../themes/Default Light.json',
|
||||
}
|
||||
|
||||
var defaultTheme = 'Default Dark';
|
||||
|
||||
function getCurrentTheme(config) {
|
||||
return config.theme in themeStylePaths ? config.theme : defaultTheme;
|
||||
}
|
||||
|
||||
async function changeTerminalRendererType() {
|
||||
let v = vscode.workspace.getConfiguration().inspect("terminal.integrated.rendererType");
|
||||
if (v !== undefined) {
|
||||
if (!v.globalValue) {
|
||||
await vscode.workspace.getConfiguration().update("terminal.integrated.rendererType", "dom", vscode.ConfigurationTarget.Global);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function checkColorTheme() {
|
||||
const currentTheme = getCurrentTheme(vscode.workspace.getConfiguration("vscode_vibrancy"));
|
||||
const themeConfig = require(path.join(__dirname, themeConfigPaths[currentTheme]));
|
||||
const target = themeConfig.colorTheme;
|
||||
const currentColorTheme = vscode.workspace.getConfiguration().get("workbench.colorTheme");
|
||||
if (target !== currentColorTheme) {
|
||||
const message = localize('messages.recommendedColorTheme').replace('%1', currentColorTheme).replace('%2', target);
|
||||
await vscode.window.showInformationMessage(message, localize('messages.changeColorThemeIde'), localize('messages.noIde'))
|
||||
.then(async (msg) => {
|
||||
if (msg === localize('messages.changeColorThemeIde')) {
|
||||
await vscode.workspace.getConfiguration().update("workbench.colorTheme", target, vscode.ConfigurationTarget.Global);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function deepEqual(obj1, obj2) {
|
||||
|
||||
if (obj1 === obj2) // it's just the same object. No need to compare.
|
||||
return true;
|
||||
|
||||
if (isPrimitive(obj1) && isPrimitive(obj2)) // compare primitives
|
||||
return obj1 === obj2;
|
||||
|
||||
if (Object.keys(obj1).length !== Object.keys(obj2).length)
|
||||
return false;
|
||||
|
||||
// compare objects with same number of keys
|
||||
for (let key in obj1) {
|
||||
if (!(key in obj2)) return false; //other object doesn't have this prop
|
||||
if (!deepEqual(obj1[key], obj2[key])) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//check if value is primitive
|
||||
function isPrimitive(obj) {
|
||||
return (obj !== Object(obj));
|
||||
}
|
||||
|
||||
function isFirstload() {
|
||||
try {
|
||||
fs.readFileSync(lockPath);
|
||||
return false
|
||||
} catch (err) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
function lockFirstload() {
|
||||
fs.writeFileSync(lockPath, '', () => { });
|
||||
}
|
||||
|
||||
function activate(context) {
|
||||
console.log('vscode-vibrancy is active!');
|
||||
|
||||
var isWin = /^win/.test(process.platform);
|
||||
var appDir = path.dirname(require.main.filename);
|
||||
|
||||
var HTMLFile = appDir + '/vs/code/electron-browser/workbench/workbench.html';
|
||||
var JSFile = appDir + '/main.js';
|
||||
|
||||
var runtimeVersion = 'v1';
|
||||
var runtimeDir = appDir + '/vscode-vibrancy-runtime-' + runtimeVersion;
|
||||
|
||||
async function installRuntime() {
|
||||
if (!isWin) return;
|
||||
|
||||
if (fs.existsSync(runtimeDir)) return;
|
||||
|
||||
await fs.mkdir(runtimeDir);
|
||||
await fsExtra.copy(path.resolve(__dirname, '../runtime'), path.resolve(runtimeDir));
|
||||
}
|
||||
|
||||
async function installJS() {
|
||||
const config = vscode.workspace.getConfiguration("vscode_vibrancy");
|
||||
const currentTheme = getCurrentTheme(config);
|
||||
const themeConfig = require(path.resolve(__dirname, themeConfigPaths[currentTheme]));
|
||||
const themeCSS = await fs.readFile(path.join(__dirname, themeStylePaths[currentTheme]), 'utf-8');
|
||||
|
||||
const JS = await fs.readFile(JSFile, 'utf-8');
|
||||
|
||||
const injectData = {
|
||||
os: os,
|
||||
config: config,
|
||||
theme: themeConfig,
|
||||
themeCSS: themeCSS
|
||||
}
|
||||
|
||||
const base = __filename;
|
||||
|
||||
const newJS = JS.replace(/\/\* !! VSCODE-VIBRANCY-START !! \*\/[\s\S]*?\/\* !! VSCODE-VIBRANCY-END !! \*\//, '')
|
||||
+ '\n/* !! VSCODE-VIBRANCY-START !! */\n;(function(){\n'
|
||||
+ `if (!require(\'fs\').existsSync(${JSON.stringify(base)})) return;\n`
|
||||
+ `global.vscode_vibrancy_plugin = ${JSON.stringify(injectData)}; try{ require(${JSON.stringify(runtimeDir)}); } catch (err) {console.error(err)}\n`
|
||||
+ '})()\n/* !! VSCODE-VIBRANCY-END !! */';
|
||||
await fs.writeFile(JSFile, newJS, 'utf-8');
|
||||
}
|
||||
|
||||
async function uninstallJS() {
|
||||
const JS = await fs.readFile(JSFile, 'utf-8');
|
||||
const needClean = /\/\* !! VSCODE-VIBRANCY-START !! \*\/[\s\S]*?\/\* !! VSCODE-VIBRANCY-END !! \*\//.test(JS);
|
||||
if (needClean) {
|
||||
const newJS = JS
|
||||
.replace(/\/\* !! VSCODE-VIBRANCY-START !! \*\/[\s\S]*?\/\* !! VSCODE-VIBRANCY-END !! \*\//, '')
|
||||
await fs.writeFile(JSFile, newJS, 'utf-8');
|
||||
}
|
||||
}
|
||||
|
||||
async function uninstallHTML() {
|
||||
const HTML = await fs.readFile(HTMLFile, 'utf-8');
|
||||
const needClean = /<!-- !! VSCODE-VIBRANCY-START !! -->[\s\S]*?<!-- !! VSCODE-VIBRANCY-END !! -->/.test(HTML);
|
||||
if (needClean) {
|
||||
const newHTML = HTML
|
||||
.replace(/<!-- !! VSCODE-VIBRANCY-START !! -->[\s\S]*?<!-- !! VSCODE-VIBRANCY-END !! -->/, '')
|
||||
.replace(/<meta.*http-equiv="Content-Security-Policy".*>/, '');
|
||||
await fs.writeFile(HTMLFile, newHTML, 'utf-8');
|
||||
}
|
||||
}
|
||||
|
||||
function enabledRestart() {
|
||||
vscode.window.showInformationMessage(localize('messages.enabled'), { title: localize('messages.restartIde') });
|
||||
}
|
||||
|
||||
function disabledRestart() {
|
||||
vscode.window.showInformationMessage(localize('messages.disabled'), { title: localize('messages.restartIde') });
|
||||
}
|
||||
|
||||
// #### main commands ######################################################
|
||||
|
||||
async function Install() {
|
||||
|
||||
if (os === 'unknown') {
|
||||
vscode.window.showInformationMessage(localize('messages.unsupported'));
|
||||
throw new Error('unsupported');
|
||||
}
|
||||
|
||||
try {
|
||||
await fs.stat(JSFile);
|
||||
await changeTerminalRendererType()
|
||||
} catch (error) {
|
||||
vscode.window.showInformationMessage(localize('messages.smthingwrong') + error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
try {
|
||||
await installRuntime();
|
||||
await installJS();
|
||||
} catch (error) {
|
||||
vscode.window.showInformationMessage(localize('messages.smthingwrong') + error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function Uninstall() {
|
||||
try {
|
||||
await fs.stat(JSFile);
|
||||
await fs.stat(HTMLFile);
|
||||
} catch (error) {
|
||||
vscode.window.showInformationMessage(localize('messages.smthingwrong') + error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
try {
|
||||
// uninstall old version
|
||||
await uninstallHTML();
|
||||
await uninstallJS();
|
||||
} catch (error) {
|
||||
vscode.window.showInformationMessage(localize('messages.smthingwrong') + error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function Update() {
|
||||
await Uninstall();
|
||||
await Install();
|
||||
}
|
||||
|
||||
var installVibrancy = vscode.commands.registerCommand('extension.installVibrancy', async () => {
|
||||
await Install();
|
||||
enabledRestart();
|
||||
});
|
||||
var uninstallVibrancy = vscode.commands.registerCommand('extension.uninstallVibrancy', async () => {
|
||||
await Uninstall()
|
||||
disabledRestart();
|
||||
});
|
||||
var updateVibrancy = vscode.commands.registerCommand('extension.updateVibrancy', async () => {
|
||||
await Update();
|
||||
enabledRestart();
|
||||
});
|
||||
|
||||
context.subscriptions.push(installVibrancy);
|
||||
context.subscriptions.push(uninstallVibrancy);
|
||||
context.subscriptions.push(updateVibrancy);
|
||||
|
||||
if (isFirstload()) {
|
||||
vscode.window.showInformationMessage(localize('messages.firstload'), { title: localize('messages.installIde') })
|
||||
.then(async (msg) => {
|
||||
if (msg) {
|
||||
await Update();
|
||||
await checkColorTheme();
|
||||
enabledRestart();
|
||||
}
|
||||
});
|
||||
lockFirstload();
|
||||
}
|
||||
|
||||
var lastConfig = vscode.workspace.getConfiguration("vscode_vibrancy");
|
||||
|
||||
vscode.workspace.onDidChangeConfiguration(() => {
|
||||
newConfig = vscode.workspace.getConfiguration("vscode_vibrancy");
|
||||
if (!deepEqual(lastConfig, newConfig)) {
|
||||
lastConfig = newConfig;
|
||||
vscode.window.showInformationMessage(localize('messages.configupdate'), { title: localize('messages.reloadIde') })
|
||||
.then(async (msg) => {
|
||||
if (msg) {
|
||||
await Update();
|
||||
if (newConfig.theme !== vscode.workspace.getConfiguration("vscode_vibrancy")) {
|
||||
await checkColorTheme();
|
||||
}
|
||||
enabledRestart();
|
||||
}
|
||||
});
|
||||
lockFirstload();
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.activate = activate;
|
||||
|
||||
// this method is called when your extension is deactivated
|
||||
function deactivate() { }
|
||||
exports.deactivate = deactivate;
|
||||
11
extension/platform.js
Normal file
11
extension/platform.js
Normal file
@ -0,0 +1,11 @@
|
||||
let os = 'unknown';
|
||||
if (/^win/.test(process.platform)) {
|
||||
if (require('os').release().split(".").map(Number)[0] === 10) {
|
||||
os = 'win10';
|
||||
}
|
||||
}
|
||||
if (process.platform === 'darwin') {
|
||||
os = 'macos';
|
||||
}
|
||||
|
||||
module.exports = os;
|
||||
1050
native/displayconfig.cc
Normal file
1050
native/displayconfig.cc
Normal file
File diff suppressed because it is too large
Load Diff
124
native/vibrancy.cc
Normal file
124
native/vibrancy.cc
Normal file
@ -0,0 +1,124 @@
|
||||
#include <napi.h>
|
||||
#include <dwmapi.h>
|
||||
|
||||
enum AccentState {
|
||||
ACCENT_DISABLED = 0,
|
||||
ACCENT_ENABLE_GRADIENT = 1,
|
||||
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
|
||||
ACCENT_ENABLE_BLURBEHIND = 3,
|
||||
ACCENT_ENABLE_ACRYLICBLURBEHIND = 4,
|
||||
ACCENT_ENABLE_HOSTBACKDROP = 5, // RS5 1809
|
||||
ACCENT_INVALID_STATE = 6
|
||||
};
|
||||
|
||||
enum WindowCompositionAttribute {
|
||||
WCA_ACCENT_POLICY = 19
|
||||
};
|
||||
|
||||
struct AccentPolicy {
|
||||
AccentState accentState;
|
||||
int accentFlags;
|
||||
int gradientColor;
|
||||
int animationId;
|
||||
};
|
||||
|
||||
struct WindowCompositionAttributeData {
|
||||
WindowCompositionAttribute attribute;
|
||||
PVOID pData;
|
||||
ULONG dataSize;
|
||||
};
|
||||
|
||||
typedef BOOL(WINAPI
|
||||
*pSetWindowCompositionAttribute)(HWND, WindowCompositionAttributeData*);
|
||||
|
||||
const HINSTANCE hModule = LoadLibrary(TEXT("user32.dll"));
|
||||
|
||||
void setVibrancy(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
try {
|
||||
if (info.Length() == 0) {
|
||||
Napi::TypeError::New(env, "WINDOW_NOT_GIVEN").ThrowAsJavaScriptException();
|
||||
return;
|
||||
}
|
||||
if (info.Length() != 6) {
|
||||
Napi::TypeError::New(env, "PARAMETER_ERROR").ThrowAsJavaScriptException();
|
||||
return;
|
||||
}
|
||||
if (!info[0].IsNumber()) {
|
||||
Napi::TypeError::New(env, "UNKNOWN").ThrowAsJavaScriptException();
|
||||
return;
|
||||
}
|
||||
HWND hWnd = (HWND) info[0].As<Napi::Number>().Int64Value();
|
||||
int isRS4OrGreater = info[1].As<Napi::Number>().Int32Value();
|
||||
|
||||
int redValue = info[2].As<Napi::Number>().Int32Value();
|
||||
int greenValue = info[3].As<Napi::Number>().Int32Value();
|
||||
int blueValue = info[4].As<Napi::Number>().Int32Value();
|
||||
int alphaValue = info[5].As<Napi::Number>().Int32Value();
|
||||
|
||||
if (hModule) {
|
||||
const pSetWindowCompositionAttribute SetWindowCompositionAttribute = (pSetWindowCompositionAttribute) GetProcAddress(
|
||||
hModule, "SetWindowCompositionAttribute");
|
||||
if (SetWindowCompositionAttribute) {
|
||||
int gradientColor = (alphaValue<<24) + (blueValue<<16) + (greenValue<<8) + (redValue);
|
||||
AccentState blurType = isRS4OrGreater == 1 ? ACCENT_ENABLE_ACRYLICBLURBEHIND : ACCENT_ENABLE_BLURBEHIND;
|
||||
AccentPolicy policy = {blurType, 2, gradientColor, 0};
|
||||
WindowCompositionAttributeData data = {WCA_ACCENT_POLICY, &policy, sizeof(AccentPolicy)};
|
||||
SetWindowCompositionAttribute(hWnd, &data);
|
||||
} else {
|
||||
Napi::Error::New(env, "FAIL_LOAD_DLL").ThrowAsJavaScriptException();
|
||||
return;
|
||||
}
|
||||
FreeLibrary(hModule);
|
||||
} else {
|
||||
Napi::Error::New(env, "FAIL_LOAD_DLL").ThrowAsJavaScriptException();
|
||||
return;
|
||||
}
|
||||
} catch (const char *ex) {
|
||||
Napi::Error::New(env, "UNKNOWN").ThrowAsJavaScriptException();
|
||||
}
|
||||
}
|
||||
|
||||
void disableVibrancy(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
try {
|
||||
if (info.Length() != 1) {
|
||||
Napi::TypeError::New(env, "WINDOW_NOT_GIVEN").ThrowAsJavaScriptException();
|
||||
return;
|
||||
}
|
||||
if (!info[0].IsNumber()) {
|
||||
Napi::TypeError::New(env, "UNKNOWN").ThrowAsJavaScriptException();
|
||||
return;
|
||||
}
|
||||
HWND hWnd = (HWND) info[0].As<Napi::Number>().Int64Value();
|
||||
if (hModule) {
|
||||
const pSetWindowCompositionAttribute SetWindowCompositionAttribute = (pSetWindowCompositionAttribute) GetProcAddress(
|
||||
hModule, "SetWindowCompositionAttribute");
|
||||
if (SetWindowCompositionAttribute) {
|
||||
AccentPolicy policy = {ACCENT_DISABLED, 0, 0, 0};
|
||||
WindowCompositionAttributeData data = {WCA_ACCENT_POLICY, &policy, sizeof(AccentPolicy)};
|
||||
SetWindowCompositionAttribute(hWnd, &data);
|
||||
} else {
|
||||
Napi::Error::New(env, "FAIL_LOAD_DLL").ThrowAsJavaScriptException();
|
||||
return;
|
||||
}
|
||||
FreeLibrary(hModule);
|
||||
} else {
|
||||
Napi::Error::New(env, "FAIL_LOAD_DLL").ThrowAsJavaScriptException();
|
||||
return;
|
||||
}
|
||||
} catch (const char *ex) {
|
||||
Napi::Error::New(env, "UNKNOWN").ThrowAsJavaScriptException();
|
||||
}
|
||||
}
|
||||
|
||||
Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
||||
exports.Set(Napi::String::New(env, "setVibrancy"),
|
||||
Napi::Function::New(env, setVibrancy));
|
||||
exports.Set(Napi::String::New(env, "disableVibrancy"),
|
||||
Napi::Function::New(env, disableVibrancy));
|
||||
return exports;
|
||||
}
|
||||
|
||||
NODE_API_MODULE(vibrancy, Init
|
||||
)
|
||||
829
package-lock.json
generated
829
package-lock.json
generated
@ -1,14 +1,502 @@
|
||||
{
|
||||
"name": "vscode-vibrancy",
|
||||
"version": "1.0.9",
|
||||
"version": "1.0.10-alpha",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"abbrev": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||
"dev": true
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
}
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"dev": true
|
||||
},
|
||||
"any-promise": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
|
||||
"integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
|
||||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
|
||||
"dev": true
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
|
||||
"integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"delegates": "^1.0.0",
|
||||
"readable-stream": "^2.0.6"
|
||||
}
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
|
||||
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safer-buffer": "~2.1.0"
|
||||
}
|
||||
},
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
||||
"dev": true
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
|
||||
"dev": true
|
||||
},
|
||||
"at-least-node": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
|
||||
"integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
|
||||
"dev": true
|
||||
},
|
||||
"aws4": {
|
||||
"version": "1.11.0",
|
||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
|
||||
"integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
|
||||
"dev": true
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"dev": true
|
||||
},
|
||||
"bcrypt-pbkdf": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
|
||||
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tweetnacl": "^0.14.3"
|
||||
}
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
|
||||
"dev": true
|
||||
},
|
||||
"chownr": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
|
||||
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
|
||||
"dev": true
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
|
||||
"dev": true
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
|
||||
"dev": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||
"dev": true
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
||||
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
||||
"dev": true
|
||||
},
|
||||
"delegates": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
|
||||
"dev": true
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"env-paths": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz",
|
||||
"integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==",
|
||||
"dev": true
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
||||
"dev": true
|
||||
},
|
||||
"extsprintf": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
|
||||
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||
"dev": true
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
|
||||
"dev": true
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
||||
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
|
||||
"dev": true
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
|
||||
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz",
|
||||
"integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==",
|
||||
"requires": {
|
||||
"at-least-node": "^1.0.0",
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"fs-minipass": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
|
||||
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minipass": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true
|
||||
},
|
||||
"gauge": {
|
||||
"version": "2.7.4",
|
||||
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
|
||||
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aproba": "^1.0.3",
|
||||
"console-control-strings": "^1.0.0",
|
||||
"has-unicode": "^2.0.0",
|
||||
"object-assign": "^4.1.0",
|
||||
"signal-exit": "^3.0.0",
|
||||
"string-width": "^1.0.1",
|
||||
"strip-ansi": "^3.0.1",
|
||||
"wide-align": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"getpass": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
||||
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
|
||||
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw=="
|
||||
},
|
||||
"har-schema": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
||||
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
|
||||
"dev": true
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "5.1.5",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
|
||||
"integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.12.3",
|
||||
"har-schema": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-unicode": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
|
||||
"dev": true
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
|
||||
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"jsprim": "^1.2.2",
|
||||
"sshpk": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"is-typedarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
|
||||
"dev": true
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||
"dev": true
|
||||
},
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
|
||||
"dev": true
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
|
||||
"dev": true
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
||||
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
|
||||
"dev": true
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
|
||||
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
|
||||
"dev": true
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
|
||||
"dev": true
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"universalify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"jsprim": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
||||
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0",
|
||||
"extsprintf": "1.3.0",
|
||||
"json-schema": "0.2.3",
|
||||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.44.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
|
||||
"integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
|
||||
"dev": true
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.27",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
|
||||
"integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mime-db": "1.44.0"
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"minipass": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz",
|
||||
"integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"minizlib": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
|
||||
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minipass": "^3.0.0",
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
|
||||
"dev": true
|
||||
},
|
||||
"mz": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
|
||||
@ -19,11 +507,258 @@
|
||||
"thenify-all": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node-addon-api": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz",
|
||||
"integrity": "sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw==",
|
||||
"dev": true
|
||||
},
|
||||
"node-gyp": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz",
|
||||
"integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"env-paths": "^2.2.0",
|
||||
"glob": "^7.1.4",
|
||||
"graceful-fs": "^4.2.3",
|
||||
"nopt": "^5.0.0",
|
||||
"npmlog": "^4.1.2",
|
||||
"request": "^2.88.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"semver": "^7.3.2",
|
||||
"tar": "^6.0.2",
|
||||
"which": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"nopt": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
|
||||
"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"abbrev": "1"
|
||||
}
|
||||
},
|
||||
"npmlog": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
|
||||
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"are-we-there-yet": "~1.1.2",
|
||||
"console-control-strings": "~1.1.0",
|
||||
"gauge": "~2.7.3",
|
||||
"set-blocking": "~2.0.0"
|
||||
}
|
||||
},
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
|
||||
"dev": true
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
|
||||
"dev": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true
|
||||
},
|
||||
"performance-now": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
|
||||
"dev": true
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
|
||||
"dev": true
|
||||
},
|
||||
"psl": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
|
||||
"integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
|
||||
"dev": true
|
||||
},
|
||||
"punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
||||
"dev": true
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
|
||||
"dev": true
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"request": {
|
||||
"version": "2.88.2",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
|
||||
"integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aws-sign2": "~0.7.0",
|
||||
"aws4": "^1.8.0",
|
||||
"caseless": "~0.12.0",
|
||||
"combined-stream": "~1.0.6",
|
||||
"extend": "~3.0.2",
|
||||
"forever-agent": "~0.6.1",
|
||||
"form-data": "~2.3.2",
|
||||
"har-validator": "~5.1.3",
|
||||
"http-signature": "~1.2.0",
|
||||
"is-typedarray": "~1.0.0",
|
||||
"isstream": "~0.1.2",
|
||||
"json-stringify-safe": "~5.0.1",
|
||||
"mime-types": "~2.1.19",
|
||||
"oauth-sign": "~0.9.0",
|
||||
"performance-now": "^2.1.0",
|
||||
"qs": "~6.5.2",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"tough-cookie": "~2.5.0",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"uuid": "^3.3.2"
|
||||
}
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "^7.1.3"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"dev": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"dev": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.3.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
|
||||
"integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
|
||||
"dev": true
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
|
||||
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
|
||||
"dev": true
|
||||
},
|
||||
"sshpk": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
|
||||
"integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asn1": "~0.2.3",
|
||||
"assert-plus": "^1.0.0",
|
||||
"bcrypt-pbkdf": "^1.0.0",
|
||||
"dashdash": "^1.12.0",
|
||||
"ecc-jsbn": "~0.1.1",
|
||||
"getpass": "^0.1.1",
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.0.2",
|
||||
"tweetnacl": "~0.14.0"
|
||||
}
|
||||
},
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
"strip-ansi": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"tar": {
|
||||
"version": "6.0.5",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz",
|
||||
"integrity": "sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chownr": "^2.0.0",
|
||||
"fs-minipass": "^2.0.0",
|
||||
"minipass": "^3.0.0",
|
||||
"minizlib": "^2.1.1",
|
||||
"mkdirp": "^1.0.3",
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"thenify": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz",
|
||||
@ -39,6 +774,98 @@
|
||||
"requires": {
|
||||
"thenify": ">= 3.1.0 < 4"
|
||||
}
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
|
||||
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"psl": "^1.1.28",
|
||||
"punycode": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
|
||||
"dev": true
|
||||
},
|
||||
"universalify": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
|
||||
"integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug=="
|
||||
},
|
||||
"uri-js": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz",
|
||||
"integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||
"dev": true
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
|
||||
"dev": true
|
||||
},
|
||||
"verror": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
|
||||
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"core-util-is": "1.0.2",
|
||||
"extsprintf": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"wide-align": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
|
||||
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^1.0.2 || 2"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
17
package.json
17
package.json
@ -2,7 +2,7 @@
|
||||
"name": "vscode-vibrancy",
|
||||
"displayName": "Vibrancy",
|
||||
"description": "Vibrancy Effect for Visual Studio Code",
|
||||
"version": "1.0.9",
|
||||
"version": "1.0.10-alpha",
|
||||
"publisher": "eyhn",
|
||||
"author": {
|
||||
"email": "cneyhn@gmail.com",
|
||||
@ -10,7 +10,7 @@
|
||||
"url": "https://eyhn.in"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.41.0"
|
||||
"vscode": "^1.52.1"
|
||||
},
|
||||
"categories": [
|
||||
"Other",
|
||||
@ -31,7 +31,7 @@
|
||||
"activationEvents": [
|
||||
"*"
|
||||
],
|
||||
"main": "./src/extension",
|
||||
"main": "./extension/index.js",
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
@ -56,7 +56,6 @@
|
||||
"default": "auto",
|
||||
"enum": [
|
||||
"auto",
|
||||
"dwm",
|
||||
"acrylic",
|
||||
"appearance-based",
|
||||
"light",
|
||||
@ -71,7 +70,6 @@
|
||||
],
|
||||
"enumDescriptions": [
|
||||
"%configuration.type.auto.description%",
|
||||
"%configuration.type.dwm.description%",
|
||||
"%configuration.type.acrylic.description%",
|
||||
"%configuration.type.appearance-based.description%",
|
||||
"%configuration.type.light.description%",
|
||||
@ -110,8 +108,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"devDependencies": {},
|
||||
"scripts": {
|
||||
"build-win10": "node-gyp rebuild"
|
||||
},
|
||||
"dependencies": {
|
||||
"fs-extra": "^9.0.1",
|
||||
"mz": "^2.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"node-gyp": "^7.1.2",
|
||||
"node-addon-api": "^3.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
{
|
||||
"configuration.type.description": "すりガラス効果の適用方法を制御します。",
|
||||
"configuration.type.auto.description": "自動",
|
||||
"configuration.type.dwm.description": "(Windows 7 のみ) Windows のデフォルトのブラー効果を使用します",
|
||||
"configuration.type.acrylic.description": "(Windows 10 のみ) Fluent Design のブラー効果を使用します",
|
||||
"configuration.type.appearance-based.description": "(MacOS のみ)",
|
||||
"configuration.type.light.description": "(MacOS のみ)",
|
||||
@ -18,5 +17,19 @@
|
||||
"configuration.imports.description": "インポートする CSS/JS ファイルのパスを指定します。",
|
||||
"extension.installVibrancy.title": "Vibrancy を有効化",
|
||||
"extension.uninstallVibrancy.title": "Vibrancy を無効化",
|
||||
"extension.updateVibrancy.title": "Vibrancy を再読み込み"
|
||||
"extension.updateVibrancy.title": "Vibrancy を再読み込み",
|
||||
|
||||
"messages.admin": "変更を適用するには、Visual Studio Code を管理者として実行してください。",
|
||||
"messages.firstload": "Vibrancy へようこそ。はじめに README をご覧ください。ボタンをクリックして、インストールを開始します。",
|
||||
"messages.configupdate": "設定が変更されました。反映させるには、再読み込みします。",
|
||||
"messages.enabled": "Vibrancy が有効化されました。設定は再起動の後に反映されます。もし Visual Studio Code が破損を検出した場合、\"今後表示しない\" をクリックします。詳細については README をご確認ください。",
|
||||
"messages.disabled": "Vibrancy が無効化されました。再起動することで、元の状態に戻ります。",
|
||||
"messages.already_disabled": "Vibrancy は既に無効です。",
|
||||
"messages.smthingwrong": "問題が発生しました: ",
|
||||
"messages.recommendedColorTheme": "現在の配色テーマは \"%1\" ですが、選択された Vibrancy テーマには \"%2\" を推奨します。",
|
||||
"messages.restartIde": "Visual Studio Code を再起動",
|
||||
"messages.installIde": "Vibrancy をインストール",
|
||||
"messages.reloadIde": "再読み込み",
|
||||
"messages.changeColorThemeIde": "配色テーマを変更する",
|
||||
"messages.noIde": "いいえ"
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
{
|
||||
"configuration.type.description": "Native method of Vibrancy Effect",
|
||||
"configuration.type.auto.description": "Automatically switch with system version",
|
||||
"configuration.type.dwm.description": "(Windows 7 only) Windows default window blur",
|
||||
"configuration.type.acrylic.description": "(Windows 10 only) Fluent design blur",
|
||||
"configuration.type.appearance-based.description": "(MacOS only)",
|
||||
"configuration.type.light.description": "(MacOS only)",
|
||||
@ -18,5 +17,19 @@
|
||||
"configuration.imports.description": "Import CSS/JS files, as file paths.",
|
||||
"extension.installVibrancy.title": "Enable Vibrancy",
|
||||
"extension.uninstallVibrancy.title": "Disable Vibrancy",
|
||||
"extension.updateVibrancy.title": "Reload Vibrancy"
|
||||
"extension.updateVibrancy.title": "Reload Vibrancy",
|
||||
|
||||
"messages.firstload": "Welcome to use Vibrancy. Please read the README first. Click the button below to install.",
|
||||
"messages.configupdate": "Config is changed, do you want to reload.",
|
||||
"messages.enabled": "Vibrancy enabled. Restart to take effect. If Code complains about it is corrupted, CLICK DON\"T SHOW AGAIN. See README for more detail.",
|
||||
"messages.disabled": "Vibrancy disabled and reverted to default. Restart to take effect.",
|
||||
"messages.already_disabled": "Vibrancy already disabled.",
|
||||
"messages.smthingwrong": "Something went wrong: ",
|
||||
"messages.unsupported": "Unsupported operating system, only macos and win10 are supported",
|
||||
"messages.recommendedColorTheme": "Your current color theme is \"%1\" and the Vibrancy theme is designed for \"%2\"!",
|
||||
"messages.restartIde": "Restart Visual Studio Code",
|
||||
"messages.installIde": "Install Vibrancy",
|
||||
"messages.reloadIde": "Reload",
|
||||
"messages.changeColorThemeIde": "Change The Color Theme",
|
||||
"messages.noIde": "No"
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
{
|
||||
"configuration.type.description":"设置毛玻璃效果的类型。",
|
||||
"configuration.type.auto.description": "自动",
|
||||
"configuration.type.dwm.description": "(仅限 Windows 7) Windows default window blur",
|
||||
"configuration.type.acrylic.description": "(仅限 Windows 10) Fluent design blur",
|
||||
"configuration.type.appearance-based.description": "(仅限 MacOS)",
|
||||
"configuration.type.light.description": "(仅限 MacOS)",
|
||||
@ -18,5 +17,19 @@
|
||||
"configuration.imports.description": "自定义 CSS 或 JS 文件的路径。",
|
||||
"extension.installVibrancy.title": "安装毛玻璃效果",
|
||||
"extension.uninstallVibrancy.title": "卸载毛玻璃效果",
|
||||
"extension.updateVibrancy.title": "重新安装毛玻璃效果"
|
||||
"extension.updateVibrancy.title": "重新安装毛玻璃效果",
|
||||
|
||||
"messages.firstload": "欢迎使用 Vibrancy,请先阅读 README,单击下面的按钮进行安装。",
|
||||
"messages.configupdate": "配置已更改,是否要重新加载。",
|
||||
"messages.enabled": "已安装毛玻璃效果,重启后才能生效。如果 VSCode 提示”安装似乎损坏“,请点击“不再提示”。有关详细信息,请参阅自述文件。",
|
||||
"messages.disabled": "毛玻璃已卸载并恢复为默认值。重启才能生效。",
|
||||
"messages.already_disabled": "毛玻璃已经禁用。",
|
||||
"messages.smthingwrong": "发生了预料之外的错误: ",
|
||||
"messages.unsupported": "操作系统不支持,仅支持 macos 和 win10。",
|
||||
"messages.recommendedColorTheme": "你当前的颜色主题是 \"%1\" ,而你的毛玻璃主题是为 \"%2\" 设计的!",
|
||||
"messages.restartIde": "重启 Visual Studio Code",
|
||||
"messages.installIde": "安装毛玻璃效果",
|
||||
"messages.reloadIde": "重新加载",
|
||||
"messages.changeColorThemeIde": "改变颜色主题",
|
||||
"messages.noIde": "不要"
|
||||
}
|
||||
725
runtime/displayconfig.js
Normal file
725
runtime/displayconfig.js
Normal file
@ -0,0 +1,725 @@
|
||||
"use strict";
|
||||
const addon = require('./displayconfig.node');
|
||||
|
||||
/**
|
||||
* Represents a numeric error code returned from the Win32 API.
|
||||
*
|
||||
* @member {number} code is the exact numeric code returned by the Win32 API.
|
||||
*/
|
||||
class Win32Error extends Error {
|
||||
constructor(code) {
|
||||
super(`Win32 error code ${code}`);
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.Win32Error = Win32Error;
|
||||
|
||||
/**
|
||||
* @typedef AdapterId
|
||||
* @type {object}
|
||||
* @property {number} LowPart
|
||||
* @property {number} HighPart
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef DisplayConfigFractional
|
||||
* @type {object}
|
||||
* @property {number} Numerator
|
||||
* @property {number} Denominator
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef SourcePathInfo
|
||||
* @type {object}
|
||||
* @property {AdapterId} adapterId
|
||||
* @property {number} id
|
||||
* @property {number} statusFlags
|
||||
* @property {number} modeInfoIdx
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef TargetPathInfo
|
||||
* @type {object}
|
||||
* @property {AdapterId} adapterId
|
||||
* @property {number} id
|
||||
* @property {number} statusFlags
|
||||
* @property {string} outputTechnology
|
||||
* @property {number} rotation
|
||||
* @property {string} scaling
|
||||
* @property {DisplayConfigFractional} refreshRate
|
||||
* @property {string} scanlineOrdering
|
||||
* @property {number} targetAvailable
|
||||
* @property {number} modeInfoIdx
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef PathInfoValue
|
||||
* @type {object}
|
||||
* @property {number} flags
|
||||
* @property {SourcePathInfo} sourceInfo
|
||||
* @property {TargetPathInfo} targetInfo
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef PathInfo
|
||||
* @type {object}
|
||||
* @property {PathInfoValue} value
|
||||
* @property {Buffer} buffer
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef DisplayConfigPosition
|
||||
* @type {object}
|
||||
* @property {number} x
|
||||
* @property {number} y
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef SourceMode
|
||||
* @type {object}
|
||||
* @property {number} width
|
||||
* @property {number} height
|
||||
* @property {number} pixelFormat
|
||||
* @property {DisplayConfigPosition} position
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef SourceModeInfo
|
||||
* @type {object}
|
||||
* @property {AdapterId} adapterId
|
||||
* @property {number} id
|
||||
* @property {"source"} infoType
|
||||
* @property {SourceMode} sourceMode
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef PixelRate
|
||||
* @type {object}
|
||||
* @property {number} lowPart
|
||||
* @property {number} highPart
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef DisplayConfigSize
|
||||
* @type {object}
|
||||
* @property {number} cx
|
||||
* @property {number} cy
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef TargetVideoSignalInfo
|
||||
* @type {object}
|
||||
* @property {PixelRate} pixelRate
|
||||
* @property {DisplayConfigFractional} hSyncFreq
|
||||
* @property {DisplayConfigFractional} vSyncFreq
|
||||
* @property {DisplayConfigSize} activeSize
|
||||
* @property {DisplayConfigSize} totalSize
|
||||
* @property {number} videoStandard
|
||||
* @property {string} scanlineOrdering
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef TargetMode
|
||||
* @type {object}
|
||||
* @property {TargetVideoSignalInfo} targetVideoSignalInfo
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef TargetModeInfo
|
||||
* @type {object}
|
||||
* @property {AdapterId} adapterId
|
||||
* @property {number} id
|
||||
* @property {"target"} infoType
|
||||
* @property {TargetMode} targetMode
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef ModeInfoValue
|
||||
* @type {SourceModeInfo | TargetModeInfo}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef ModeInfo
|
||||
* @type {object}
|
||||
* @property {ModeInfoValue} value
|
||||
* @property {Buffer} buffer
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef NameInfo
|
||||
* @type {object}
|
||||
* @property {AdapterId} adapterId
|
||||
* @property {number} id
|
||||
* @property {string} outputTechnology
|
||||
* @property {number} edidManufactureId
|
||||
* @property {number} edidProductCodeId
|
||||
* @property {number} connectorInstance
|
||||
* @property {string} monitorFriendlyDeviceName
|
||||
* @property {string} monitorDevicePath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef QueryDisplayConfigResults
|
||||
* @type {object}
|
||||
* @property {PathInfo[]} pathArray
|
||||
* @property {ModeInfo[]} modeInfoArray
|
||||
* @property {NameInfo[]} nameArray
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieves low-level information from the Win32 API QueryDisplayConfig.
|
||||
*
|
||||
* The output of this function somewhat matches the "output" values of
|
||||
* QueryDisplayConfig, as documented at
|
||||
* https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-querydisplayconfig,
|
||||
* in the pathArray and modeInfoArray results.
|
||||
*
|
||||
* Additionally, this function uses the DisplayConfigGetDeviceInfo function over
|
||||
* all resolved displays to return the names, output technology, and manufacturer IDs
|
||||
* in the nameArray results.
|
||||
*
|
||||
* @returns {Promise<QueryDisplayConfigResults>}
|
||||
* A Promise, resolving to { pathArray: [...], modeInfoArray: [...], nameArray: [...] },
|
||||
* or rejecting with a {@link Win32Error} if something goes wrong.
|
||||
*/
|
||||
module.exports.queryDisplayConfig = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const ran = addon.win32_queryDisplayConfig((err, result) => {
|
||||
if (err !== null) {
|
||||
reject(new Win32Error(err));
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
if (!ran) {
|
||||
resolve(undefined);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef ConfigId
|
||||
* @type {object}
|
||||
* @property {AdapterId} adapterId
|
||||
* @property {number} id
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef ExtractedDisplayConfig
|
||||
* @type {object}
|
||||
* @property {string} displayName The "friendly name" of the relevant display
|
||||
* @property {string} devicePath The Windows NT device path of the relevant display
|
||||
* @property {ConfigId} sourceConfigId
|
||||
* @property {ConfigId} targetConfigId
|
||||
* @property {boolean} inUse Whether this configuration is currently being used
|
||||
* @property {string} outputTechnology
|
||||
* @property {number} rotation
|
||||
* @property {string} scaling
|
||||
* @property {SourceMode} sourceMode
|
||||
* @property {TargetVideoSignalInfo | undefined} targetVideoSignalInfo
|
||||
* @property {Buffer} pathBuffer A Buffer containing the exact DISPLAYCONFIG_PATH_INFO struct
|
||||
* returned by QueryDisplayConfig for this configuration
|
||||
* @property {Buffer} sourceModeBuffer A Buffer containing the exact DISPLAYCONFIG_MODE_INFO
|
||||
* source struct returned by QueryDisplayConfig for this configuration
|
||||
* @property {Buffer | undefined} targetModeBuffer A Buffer containing the exact DISPLAYCONFIG_MODE_INFO
|
||||
* target struct returned by QueryDisplayConfig for this configuration
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieves higher-level information from the Win32 API QueryDisplayConfig.
|
||||
*
|
||||
* Unlike {@link queryDisplayConfig}, this function pulls all relevant information
|
||||
* about a device/mode pairing into a single object.
|
||||
*
|
||||
* @returns {Promise<ExtractedDisplayConfig>} A Promise, resolving to display configuration information
|
||||
* or rejecting with a {@link Win32Error} if something goes wrong.
|
||||
*/
|
||||
module.exports.extractDisplayConfig = async () => {
|
||||
const config = await module.exports.queryDisplayConfig();
|
||||
const ret = [];
|
||||
for (const { value, buffer: pathBuffer } of config.pathArray) {
|
||||
let inUse = value.flags & (1 === 1) ? true : false;
|
||||
const { sourceInfo, targetInfo } = value;
|
||||
|
||||
const {
|
||||
modeInfoIdx: sourceModeIdx,
|
||||
adapterId: sourceAdapterId,
|
||||
id: sourceId,
|
||||
} = sourceInfo;
|
||||
const {
|
||||
adapterId,
|
||||
id,
|
||||
outputTechnology,
|
||||
rotation,
|
||||
scaling,
|
||||
modeInfoIdx: targetModeIdx,
|
||||
} = targetInfo;
|
||||
|
||||
const sourceConfigId = {
|
||||
adapterId: sourceAdapterId,
|
||||
id: sourceId,
|
||||
};
|
||||
const targetConfigId = {
|
||||
adapterId,
|
||||
id,
|
||||
};
|
||||
|
||||
const displayNameEntry = config.nameArray.find(
|
||||
(n) =>
|
||||
n.adapterId.LowPart === adapterId.LowPart &&
|
||||
n.adapterId.HighPart === adapterId.HighPart &&
|
||||
n.id === id &&
|
||||
n.outputTechnology &&
|
||||
outputTechnology &&
|
||||
n.monitorDevicePath.length > 0
|
||||
);
|
||||
|
||||
if (displayNameEntry === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const sourceMode = config.modeArray[sourceModeIdx];
|
||||
const targetMode = config.modeArray[targetModeIdx];
|
||||
if (sourceMode === undefined) {
|
||||
continue;
|
||||
}
|
||||
if (targetMode === undefined) {
|
||||
// When we can't find the target mode, but _can_
|
||||
// find the source mode, that just means the monitor is off.
|
||||
inUse = false;
|
||||
}
|
||||
|
||||
const sourceModeValue = sourceMode.value;
|
||||
if (sourceModeValue.infoType !== "source") {
|
||||
continue;
|
||||
}
|
||||
|
||||
const { monitorFriendlyDeviceName, monitorDevicePath } = displayNameEntry;
|
||||
const output = {
|
||||
displayName: monitorFriendlyDeviceName,
|
||||
devicePath: monitorDevicePath,
|
||||
sourceConfigId,
|
||||
targetConfigId,
|
||||
inUse,
|
||||
outputTechnology,
|
||||
rotation,
|
||||
scaling,
|
||||
sourceMode: sourceModeValue.sourceMode,
|
||||
pathBuffer,
|
||||
sourceModeBuffer: sourceMode.buffer,
|
||||
};
|
||||
|
||||
if (targetMode !== undefined) {
|
||||
const targetModeValue = targetMode.value;
|
||||
if (targetModeValue.infoType === "target") {
|
||||
output.targetVideoSignalInfo =
|
||||
targetModeValue.targetMode.targetVideoSignalInfo;
|
||||
output.targetModeBuffer = targetMode.buffer;
|
||||
}
|
||||
}
|
||||
|
||||
ret.push(output);
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
async function win32_toggleEnabledDisplays(args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const ran = addon.win32_toggleEnabledDisplays(args, (_, errorCode) => {
|
||||
if (errorCode === 0) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(new Win32Error(errorCode));
|
||||
}
|
||||
});
|
||||
if (!ran) {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef ToggleEnabledDisplaysArgs
|
||||
* @type {object}
|
||||
* @property {string[]} enablePaths Exact Windows NT device paths of the displays to enable
|
||||
* @property {string[]} disablePaths Exact Windows NT device paths of the displays to disable
|
||||
* @property {boolean} persistent Whether to save this configuration as the default configuration
|
||||
*/
|
||||
|
||||
/**
|
||||
* Toggles enabled/disabled state of the given displays.
|
||||
*
|
||||
* If "persistent", then this is saved between restarts.
|
||||
*
|
||||
* @param {ToggleEnabledDisplaysArgs} args
|
||||
*/
|
||||
module.exports.toggleEnabledDisplays = async (args) => {
|
||||
const { persistent, enable: enablePaths, disable: disablePaths } = args;
|
||||
const enable = [];
|
||||
const disable = [];
|
||||
|
||||
const displayConfig = await module.exports.extractDisplayConfig();
|
||||
for (const { devicePath, targetConfigId } of displayConfig) {
|
||||
if (Array.isArray(enablePaths) && enablePaths.indexOf(devicePath) >= 0) {
|
||||
enable.push(targetConfigId);
|
||||
}
|
||||
if (Array.isArray(disablePaths) && disablePaths.indexOf(devicePath) >= 0) {
|
||||
disable.push(targetConfigId);
|
||||
}
|
||||
}
|
||||
|
||||
await win32_toggleEnabledDisplays({ enable, disable, persistent });
|
||||
};
|
||||
|
||||
function setSubtract(left, right) {
|
||||
const ret = new Set();
|
||||
for (const entry of left) {
|
||||
if (!right.has(entry)) {
|
||||
ret.add(entry);
|
||||
}
|
||||
}
|
||||
return Array.from(ret);
|
||||
}
|
||||
|
||||
function devicePathLookupForEnabledDisplayConfig(conf) {
|
||||
const ret = {};
|
||||
for (const entry of conf) {
|
||||
if (entry.inUse && entry.targetModeBuffer === undefined) {
|
||||
continue;
|
||||
}
|
||||
if (ret[entry.devicePath] !== undefined) {
|
||||
continue;
|
||||
}
|
||||
ret[entry.devicePath] = entry;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef DisplayRestorationConfigurationEntry
|
||||
* @type {object}
|
||||
* @property {string} devicePath
|
||||
* @property {string} pathBuffer A Base-64 encoded binary blob representing
|
||||
* a DISPLAYCONFIG_PATH_INFO instance for the given devicePath
|
||||
* @property {string} sourceModeBuffer A Base-64 encoded binary blob representing
|
||||
* a DISPLAYCONFIG_MODE_INFO source instance for the given devicePath
|
||||
* @property {string} targetModeBuffer A Base-64 encoded binary blob representing
|
||||
* a DISPLAYCONFIG_MODE_INFO target instance for the given devicePath
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns a display configuration suitable for restoration with {@link restoreDisplayConfig}.
|
||||
*
|
||||
* @returns {DisplayRestorationConfigurationEntry[]}
|
||||
*/
|
||||
module.exports.displayConfigForRestoration = async () => {
|
||||
const currentConfig = await module.exports.extractDisplayConfig();
|
||||
const ret = [];
|
||||
|
||||
for (const entry of currentConfig) {
|
||||
if (!entry.inUse || entry.targetModeBuffer === undefined) {
|
||||
continue;
|
||||
}
|
||||
const {
|
||||
devicePath,
|
||||
pathBuffer,
|
||||
sourceModeBuffer,
|
||||
targetModeBuffer,
|
||||
} = entry;
|
||||
ret.push({
|
||||
devicePath,
|
||||
pathBuffer: pathBuffer.toString("base64"),
|
||||
sourceModeBuffer: sourceModeBuffer.toString("base64"),
|
||||
targetModeBuffer: targetModeBuffer.toString("base64"),
|
||||
});
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
async function win32_restoreDisplayConfig(configs, persistent) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const ran = addon.win32_restoreDisplayConfig(
|
||||
configs,
|
||||
(_, errorCode) => {
|
||||
if (errorCode === 0) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(new Win32Error(errorCode));
|
||||
}
|
||||
},
|
||||
persistent
|
||||
);
|
||||
if (!ran) {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef RestoreDisplayConfigArgs
|
||||
* @type {object}
|
||||
* @property {DisplayRestorationConfigurationEntry[]} config
|
||||
* @property {boolean} persistent Whether to save this configuration as the default configuration
|
||||
*/
|
||||
|
||||
/**
|
||||
* Restores a display configuration derived from {@link displayConfigForRestoration}.
|
||||
*
|
||||
* If the given configuration refers to enabled displays that are not currently attached,
|
||||
* this function simply enables the displays known to the given configuration and
|
||||
* disables all attached displays not known to the given configuration. Otherwise,
|
||||
* the given configuration is applied to the display set.
|
||||
*
|
||||
* @param {RestoreDisplayConfigArgs} args
|
||||
*/
|
||||
module.exports.restoreDisplayConfig = async (args) => {
|
||||
const devicePathNames = args.config
|
||||
.filter(({ targetModeBuffer }) => targetModeBuffer !== undefined)
|
||||
.map(({ devicePath }) => devicePath);
|
||||
const currentConfig = await module.exports.extractDisplayConfig();
|
||||
|
||||
const givenAsSet = new Set(currentConfig.map(({ devicePath }) => devicePath));
|
||||
const expectedEnabledAsSet = new Set(devicePathNames);
|
||||
|
||||
const missingEnabled = setSubtract(expectedEnabledAsSet, givenAsSet);
|
||||
|
||||
// Here's the idea behind this:
|
||||
// We have a set of monitors we want enabled, and a set of monitors that are enabled.
|
||||
// Ideally, these should be identical sets. But it's also possible that
|
||||
//
|
||||
// 1. The current state has strictly more enabled monitors than the expected state
|
||||
// 2. The current state has strictly fewer enabled monitors than the expected state
|
||||
// 3. The current state has some monitors that are missing, and some that are unexpected.
|
||||
//
|
||||
// What we're about to do here is coerce the monitor state to the expected state; if more
|
||||
// monitors are enabled or disabled in the given state then that's fine, we're correcting
|
||||
// that away. The trick here is that the monitors in the expected state we _do_ want to
|
||||
// enable have to exist in the first place (we don't care about the ones we want to disable,
|
||||
// missing is also disabled if you squint hard enough).
|
||||
if (missingEnabled.length === 0) {
|
||||
const pathLookup = devicePathLookupForEnabledDisplayConfig(currentConfig);
|
||||
const coercedState = [];
|
||||
for (const entry of args.config) {
|
||||
if (entry.targetModeBuffer === undefined) {
|
||||
continue;
|
||||
}
|
||||
const currentConfigEntry = pathLookup[entry.devicePath];
|
||||
if (currentConfigEntry === undefined) {
|
||||
continue;
|
||||
}
|
||||
const { sourceConfigId, targetConfigId } = currentConfigEntry;
|
||||
const { pathBuffer, sourceModeBuffer, targetModeBuffer } = entry;
|
||||
coercedState.push({
|
||||
sourceConfigId,
|
||||
targetConfigId,
|
||||
pathBuffer: Buffer.from(pathBuffer, "base64"),
|
||||
sourceModeBuffer: Buffer.from(sourceModeBuffer, "base64"),
|
||||
targetModeBuffer: Buffer.from(targetModeBuffer, "base64"),
|
||||
});
|
||||
}
|
||||
|
||||
await win32_restoreDisplayConfig(coercedState, args.persistent);
|
||||
} else {
|
||||
const seen = new Set();
|
||||
const enable = [];
|
||||
const disable = [];
|
||||
|
||||
const notInUse = args.config
|
||||
.filter(({ targetModeBuffer }) => targetModeBuffer === undefined)
|
||||
.map(({ devicePath }) => devicePath);
|
||||
|
||||
for (const devicePathName of devicePathNames) {
|
||||
if (!seen.has(devicePathName) && givenAsSet.has(devicePathName)) {
|
||||
enable.push(devicePathName);
|
||||
seen.add(devicePathName);
|
||||
}
|
||||
}
|
||||
for (const devicePathName of notInUse) {
|
||||
if (!seen.has(devicePathName) && givenAsSet.has(devicePathName)) {
|
||||
disable.push(devicePathName);
|
||||
seen.add(devicePathName);
|
||||
}
|
||||
}
|
||||
|
||||
await module.exports.toggleEnabledDisplays({
|
||||
enable,
|
||||
disable,
|
||||
persistent: args.persistent,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
let currentDisplayConfig;
|
||||
const displayChangeCallbacks = new Set();
|
||||
|
||||
async function updateDisplayStateAndNotifyCallbacks() {
|
||||
try {
|
||||
currentDisplayConfig = await module.exports.extractDisplayConfig();
|
||||
for (const callback of Array.from(displayChangeCallbacks)) {
|
||||
callback(null, currentDisplayConfig);
|
||||
}
|
||||
} catch (e) {
|
||||
for (const callback of Array.from(displayChangeCallbacks)) {
|
||||
callback(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let currentDisplayConfigPromise = updateDisplayStateAndNotifyCallbacks();
|
||||
|
||||
function setupListenForDisplayChanges() {
|
||||
addon.win32_listenForDisplayChanges((err) => {
|
||||
if (err === null) {
|
||||
currentDisplayConfigPromise = currentDisplayConfigPromise.then(() =>
|
||||
updateDisplayStateAndNotifyCallbacks()
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a display change listener.
|
||||
*
|
||||
* This function will be called immediately upon registration, receiving the
|
||||
* current display configuration. It will also be called every time the display
|
||||
* configuration changes in Windows, e.g. when users attach or rearrange new
|
||||
* displays, or alter the output resolution of already-attached displays.
|
||||
*
|
||||
* Note that the Node event loop will continue executing if any outstanding change
|
||||
* listeners are registered, precluding graceful shutdown. Use {@link removeDisplayChangeListener}
|
||||
* to remove outstanding display change listeners and clear the event loop.
|
||||
*
|
||||
* @param {function(Error | null, ExtractedDisplayConfig | undefined): void} listener
|
||||
* @returns {function(Error | null, ExtractedDisplayConfig | undefined): void} the listener argument as passed
|
||||
*/
|
||||
module.exports.addDisplayChangeListener = (listener) => {
|
||||
if (displayChangeCallbacks.size === 0) {
|
||||
setupListenForDisplayChanges();
|
||||
}
|
||||
|
||||
displayChangeCallbacks.add(listener);
|
||||
|
||||
if (currentDisplayConfig !== undefined) {
|
||||
listener(null, currentDisplayConfig);
|
||||
}
|
||||
|
||||
return listener;
|
||||
};
|
||||
|
||||
/**
|
||||
* De-registers a display change listener.
|
||||
*
|
||||
* De-registering all display change listeners clears the event loop of pending
|
||||
* work started by {@link addDisplayChangeListener} to allow for a graceful shutdown.
|
||||
*
|
||||
* @param {function(Error | null, ExtractedDisplayConfig | undefined): void} listener previously passed to {@link addDisplayChangeListener}
|
||||
*/
|
||||
module.exports.removeDisplayChangeListener = (listener) => {
|
||||
displayChangeCallbacks.delete(listener);
|
||||
if (displayChangeCallbacks.size === 0) {
|
||||
addon.win32_stopListeningForDisplayChanges();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Establishes a context for determining the vertical refresh rate.
|
||||
*
|
||||
* Active instances of this class will establish perpetual work on the event loop,
|
||||
* as the internals use {@link addDisplayChangeListener} to react to display changes.
|
||||
*
|
||||
* In order to clear the relevant work on the Node event loop, you must call
|
||||
* {@link VerticalRefreshRateContext.close} when you are finished using this context.
|
||||
*/
|
||||
class VerticalRefreshRateContext {
|
||||
constructor() {
|
||||
let readyPromiseResolver;
|
||||
let readyPromiseResolved = false;
|
||||
|
||||
this.readyPromise = new Promise((resolve) => {
|
||||
readyPromiseResolver = () => {
|
||||
if (readyPromiseResolved) return;
|
||||
readyPromiseResolved = true;
|
||||
resolve();
|
||||
};
|
||||
});
|
||||
this.geometry = [];
|
||||
|
||||
const computeDisplayGeometryFromConfig = (err, conf) => {
|
||||
if (err !== null) {
|
||||
return;
|
||||
}
|
||||
const geom = [];
|
||||
|
||||
for (const { sourceMode, targetVideoSignalInfo, inUse } of conf) {
|
||||
if (!inUse) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const { width, height, position } = sourceMode;
|
||||
const { vSyncFreq } = targetVideoSignalInfo;
|
||||
// 30Hz is a safe guess for broken vSyncFreq outputs, I think...
|
||||
const vRefreshRate =
|
||||
vSyncFreq.Numerator === 0 || vSyncFreq.Denominator === 0
|
||||
? 30
|
||||
: vSyncFreq.Numerator / vSyncFreq.Denominator;
|
||||
const top = position.y;
|
||||
const bottom = position.y + height;
|
||||
const left = position.x;
|
||||
const right = position.x + width;
|
||||
|
||||
geom.push({ top, bottom, left, right, vRefreshRate });
|
||||
}
|
||||
|
||||
this.geometry = geom;
|
||||
readyPromiseResolver();
|
||||
};
|
||||
|
||||
this.changeListener = module.exports.addDisplayChangeListener(
|
||||
computeDisplayGeometryFromConfig
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the vertical refresh rate of the displays at a given display point.
|
||||
*
|
||||
* If any displays overlap at the given display point, the return result will
|
||||
* be the minimum of the vertical refresh rates of each physical device displaying
|
||||
* at that effective point.
|
||||
*
|
||||
* This method is asynchronous due to the implementation of addDisplayChangeListener;
|
||||
* it waits for a valid display configuration to be captured before returning the
|
||||
* best possible refresh rate.
|
||||
*
|
||||
* @param {number} x The vertical offset of the display point
|
||||
* @param {number} y The horizontal offset of the display point
|
||||
*
|
||||
* @returns {number | undefined} The vertical refresh rate at the given display point,
|
||||
* or undefined if the given display point is out of bounds of the available display space.
|
||||
*/
|
||||
async findVerticalRefreshRateForDisplayPoint(x, y) {
|
||||
await this.readyPromise;
|
||||
|
||||
let ret;
|
||||
for (const { top, bottom, left, right, vRefreshRate } of this.geometry) {
|
||||
if (left <= x && x < right && top <= y && y < bottom) {
|
||||
ret = ret === undefined ? vRefreshRate : Math.min(ret, vRefreshRate);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects this instance from display change events.
|
||||
*
|
||||
* Disconnecting the instance from display change events will clear relevant
|
||||
* work items off of the event loop as per {@link removeDisplayChangeListener}.
|
||||
*/
|
||||
close() {
|
||||
module.exports.removeDisplayChangeListener(this.changeListener);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.VerticalRefreshRateContext = VerticalRefreshRateContext;
|
||||
BIN
runtime/displayconfig.node
Normal file
BIN
runtime/displayconfig.node
Normal file
Binary file not shown.
136
runtime/index.js
Normal file
136
runtime/index.js
Normal file
@ -0,0 +1,136 @@
|
||||
const electron = require('electron');
|
||||
|
||||
/**
|
||||
* @type {{ os: string, config: any, themeCSS: string, theme: any }}
|
||||
*/
|
||||
const app = global.vscode_vibrancy_plugin;
|
||||
|
||||
const macosType = [
|
||||
"appearance-based",
|
||||
"light",
|
||||
"dark",
|
||||
"titlebar",
|
||||
"selection",
|
||||
"menu",
|
||||
"popover",
|
||||
"sidebar",
|
||||
"medium-light",
|
||||
"ultra-dark"
|
||||
];
|
||||
|
||||
const windowsType = [
|
||||
"acrylic"
|
||||
];
|
||||
|
||||
function hexToRgb(hex) {
|
||||
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
return result ? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16)
|
||||
} : null;
|
||||
}
|
||||
|
||||
electron.app.on('browser-window-created', (_, window) => {
|
||||
var type = app.config.type;
|
||||
if (type !== 'auto') {
|
||||
if (app.os === 'win10' && !windowsType.includes(type)) type = 'auto';
|
||||
if (app.os === 'macos' && !macosType.includes(type)) type = 'auto';
|
||||
}
|
||||
if (type === 'auto') {
|
||||
type = app.theme.type[app.os];
|
||||
}
|
||||
|
||||
let opacity = app.config.opacity;
|
||||
// if opacity < 0, use the theme default opacity
|
||||
if (opacity < 0) {
|
||||
opacity = app.theme.opacity[app.os]
|
||||
}
|
||||
|
||||
const backgroundRGB = hexToRgb(app.theme.background);
|
||||
|
||||
if (app.os === 'win10') {
|
||||
const bindings = require('./vibrancy.js');
|
||||
bindings.setVibrancy(window.getNativeWindowHandle().readInt32LE(0), 1, backgroundRGB.r, backgroundRGB.g, backgroundRGB.b, 0);
|
||||
const win10refresh = require('./win10refresh.js');
|
||||
win10refresh(window, 60);
|
||||
|
||||
window.webContents.once('dom-ready', () => {
|
||||
const currentURL = window.webContents.getURL();
|
||||
|
||||
if (!currentURL.includes('workbench.html')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (window.isMaximized()) {
|
||||
window.unmaximize();
|
||||
window.maximize();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (app.os === 'macos') {
|
||||
window.setVibrancy(type);
|
||||
}
|
||||
|
||||
window.webContents.on('dom-ready', () => {
|
||||
const currentURL = window.webContents.getURL();
|
||||
|
||||
if (!currentURL.includes('workbench.html')) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.setBackgroundColor('#00000000');
|
||||
|
||||
window.webContents.executeJavaScript("document.body.innerHTML += " + JSON.stringify(HTML()))
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function HTML() {
|
||||
if (app.os === 'unknown') return '';
|
||||
|
||||
var type = app.config.type;
|
||||
if (type === 'auto') {
|
||||
type = app.theme.type[app.os];
|
||||
}
|
||||
|
||||
let opacity = app.config.opacity;
|
||||
|
||||
if (opacity < 0) {
|
||||
opacity = app.theme.opacity[app.os]
|
||||
}
|
||||
|
||||
const backgroundRGB = hexToRgb(app.theme.background);
|
||||
|
||||
const HTML = [
|
||||
`
|
||||
<style>
|
||||
html {
|
||||
background: rgba(${backgroundRGB.r},${backgroundRGB.g},${backgroundRGB.b},${opacity}) !important;
|
||||
}
|
||||
</style>
|
||||
`,
|
||||
`
|
||||
<style>
|
||||
${app.themeCSS}
|
||||
</style>
|
||||
`,
|
||||
...app.config.imports.map(function (x) {
|
||||
if (!x) return '';
|
||||
if (typeof x === 'string') {
|
||||
x = new URL(x, 'file://').href;
|
||||
|
||||
if (!x.startsWith('file://')) {
|
||||
x = 'file://' + x;
|
||||
}
|
||||
|
||||
if (/^.*\.js$/.test(x)) return '<script src="' + x + '"></script>';
|
||||
if (/^.*\.css$/.test(x)) return '<link rel="stylesheet" href="' + x + '"/>';
|
||||
}
|
||||
return '';
|
||||
})
|
||||
]
|
||||
|
||||
return HTML.join('')
|
||||
}
|
||||
3
runtime/vibrancy.js
Normal file
3
runtime/vibrancy.js
Normal file
@ -0,0 +1,3 @@
|
||||
const addon = require('./vibrancy.node');
|
||||
|
||||
module.exports = addon;
|
||||
BIN
runtime/vibrancy.node
Normal file
BIN
runtime/vibrancy.node
Normal file
Binary file not shown.
260
runtime/win10refresh.js
Normal file
260
runtime/win10refresh.js
Normal file
@ -0,0 +1,260 @@
|
||||
const {VerticalRefreshRateContext} = require('./displayconfig')
|
||||
const electron = require('electron')
|
||||
const process = require('process')
|
||||
|
||||
function sleep(duration) {
|
||||
return new Promise(resolve => setTimeout(resolve, duration));
|
||||
}
|
||||
|
||||
function areBoundsEqual(left, right) {
|
||||
return left.height === right.height
|
||||
&& left.width === right.width
|
||||
&& left.x === right.x
|
||||
&& left.y === right.y;
|
||||
}
|
||||
|
||||
const billion = 1000 * 1000 * 1000;
|
||||
|
||||
function hrtimeDeltaForFrequency(freq) {
|
||||
return BigInt(Math.ceil(billion / freq));
|
||||
}
|
||||
|
||||
let disableJitterFix = false
|
||||
|
||||
// Detect if cursor is near the screen edge. Used to disable the jitter fix in 'move' event.
|
||||
function isInSnapZone() {
|
||||
const point = electron.screen.getCursorScreenPoint()
|
||||
const display = electron.screen.getDisplayNearestPoint(point)
|
||||
|
||||
// Check if cursor is near the left/right edge of the active display
|
||||
return (point.x > display.bounds.x - 20 && point.x < display.bounds.x + 20) || (point.x > display.bounds.x + display.bounds.width - 20 && point.x < display.bounds.x + display.bounds.width + 20);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unfortunately, we have to re-implement moving and resizing.
|
||||
* Enabling vibrancy slows down the window's event handling loop to the
|
||||
* point building a mouse event backlog. If you just handle these events
|
||||
* in the backlog without taking the time difference into consideration,
|
||||
* you end up with visible movement lag.
|
||||
* We tried pairing 'will-move' with 'move', but Electron actually sends the
|
||||
* 'move' events _before_ Windows actually commits to the operation. There's
|
||||
* likely some queuing going on that's getting backed up. This is not the case
|
||||
* with 'will-resize' and 'resize', which need to use the default behavior
|
||||
* for compatibility with soft DPI scaling.
|
||||
* The ideal rate of moving and resizing is based on the vertical sync
|
||||
* rate: if your display is only fully updating at 120 Hz, we shouldn't
|
||||
* be attempting to reset positions or sizes any faster than 120 Hz.
|
||||
* If we were doing this in a browser context, we would just use
|
||||
* requestAnimationFrame and call it a day. But we're not inside of a
|
||||
* browser context here, so we have to resort to clever hacks.
|
||||
* This VerticalRefreshRateContext maps a point in screen space to the
|
||||
* vertical sync rate of the display(s) actually handing that point.
|
||||
* It handles multiple displays with varying vertical sync rates,
|
||||
* and changes to the display configuration while this process is running.
|
||||
*/
|
||||
module.exports = function win10refresh(win, maximumRefreshRate) {
|
||||
if (!('__electron_acrylic_window__' in win)) {
|
||||
win.__electron_acrylic_window__ = {};
|
||||
}
|
||||
|
||||
const refreshCtx = new VerticalRefreshRateContext()
|
||||
|
||||
function getRefreshRateAtCursor(cursor) {
|
||||
cursor = cursor || electron.screen.getCursorScreenPoint()
|
||||
return refreshCtx.findVerticalRefreshRateForDisplayPoint(cursor.x, cursor.y)
|
||||
}
|
||||
|
||||
// Ensure all movement operation is serialized, by setting up a continuous promise chain
|
||||
// All movement operation will take the form of
|
||||
//
|
||||
// boundsPromise = boundsPromise.then(() => { /* work */ })
|
||||
//
|
||||
// So that there are no asynchronous race conditions.
|
||||
let pollingRate
|
||||
let doFollowUpQuery = false, isMoving = false, shouldMove = false
|
||||
let moveLastUpdate = BigInt(0), resizeLastUpdate = BigInt(0)
|
||||
let lastWillMoveBounds, lastWillResizeBounds,
|
||||
desiredMoveBounds
|
||||
let boundsPromise = Promise.race([
|
||||
getRefreshRateAtCursor(electron.screen.getCursorScreenPoint()).then(rate => {
|
||||
pollingRate = rate || 30
|
||||
doFollowUpQuery = true
|
||||
}),
|
||||
// Establishing the display configuration can fail; we can't
|
||||
// just block forever if that happens. Instead, establish
|
||||
// a fallback polling rate and hope for the best.
|
||||
sleep(2000).then(() => {
|
||||
pollingRate = pollingRate || 30
|
||||
})
|
||||
])
|
||||
|
||||
async function doFollowUpQueryIfNecessary(cursor) {
|
||||
if (doFollowUpQuery) {
|
||||
const rate = await getRefreshRateAtCursor(cursor)
|
||||
if (rate != pollingRate) console.log(`New polling rate: ${rate}`)
|
||||
pollingRate = rate || 30
|
||||
}
|
||||
}
|
||||
|
||||
function setWindowBounds(bounds) {
|
||||
if (win.isDestroyed()) return
|
||||
win.setBounds(bounds)
|
||||
desiredMoveBounds = win.getBounds()
|
||||
}
|
||||
|
||||
function currentTimeBeforeNextActivityWindow(lastTime, forceFreq) {
|
||||
return process.hrtime.bigint() <
|
||||
lastTime + hrtimeDeltaForFrequency(forceFreq || pollingRate || 30)
|
||||
}
|
||||
|
||||
function guardingAgainstMoveUpdate(fn) {
|
||||
if (pollingRate === undefined || !currentTimeBeforeNextActivityWindow(moveLastUpdate)) {
|
||||
moveLastUpdate = process.hrtime.bigint()
|
||||
fn()
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
win.on('will-move', (e, newBounds) => {
|
||||
if (win.__electron_acrylic_window__.opacityInterval) return
|
||||
// We get a _lot_ of duplicate bounds sent to us in this event.
|
||||
// This messes up our timing quite a bit.
|
||||
if (lastWillMoveBounds !== undefined && areBoundsEqual(lastWillMoveBounds, newBounds)) {
|
||||
e.preventDefault()
|
||||
return
|
||||
}
|
||||
if (lastWillMoveBounds) {
|
||||
newBounds.width = lastWillMoveBounds.width
|
||||
newBounds.height = lastWillMoveBounds.height
|
||||
}
|
||||
lastWillMoveBounds = newBounds
|
||||
// If we're asked to perform some move update and it's under
|
||||
// the refresh speed limit, we can just do it immediately.
|
||||
// This also catches moving windows with the keyboard.
|
||||
const didOptimisticMove = !isMoving && guardingAgainstMoveUpdate(() => {
|
||||
// Do nothing, the default behavior of the event is exactly what we want.
|
||||
desiredMoveBounds = undefined
|
||||
})
|
||||
if (didOptimisticMove) {
|
||||
boundsPromise = boundsPromise.then(doFollowUpQueryIfNecessary)
|
||||
return
|
||||
}
|
||||
e.preventDefault()
|
||||
|
||||
// Track if the user is moving the window
|
||||
if (win.__electron_acrylic_window__.moveTimeout) clearTimeout(win.__electron_acrylic_window__.moveTimeout)
|
||||
win.__electron_acrylic_window__.moveTimeout = setTimeout(() => {
|
||||
shouldMove = false
|
||||
}, 1000 / Math.min(pollingRate, maximumRefreshRate))
|
||||
|
||||
// Disable next event ('move') if cursor is near the screen edge
|
||||
disableJitterFix = isInSnapZone()
|
||||
|
||||
// Start new behavior if not already
|
||||
if (!shouldMove) {
|
||||
shouldMove = true
|
||||
|
||||
if (isMoving) return false
|
||||
isMoving = true
|
||||
|
||||
// Get start positions
|
||||
const basisBounds = win.getBounds()
|
||||
const basisCursor = electron.screen.getCursorScreenPoint()
|
||||
|
||||
// Handle polling at a slower interval than the setInterval handler
|
||||
function handleIntervalTick(moveInterval) {
|
||||
boundsPromise = boundsPromise.then(() => {
|
||||
if (!shouldMove) {
|
||||
isMoving = false
|
||||
clearInterval(moveInterval)
|
||||
return
|
||||
}
|
||||
|
||||
const cursor = electron.screen.getCursorScreenPoint()
|
||||
const didIt = guardingAgainstMoveUpdate(() => {
|
||||
// Set new position
|
||||
if (lastWillResizeBounds && lastWillResizeBounds.width) setWindowBounds({
|
||||
x: Math.floor(basisBounds.x + (cursor.x - basisCursor.x)),
|
||||
y: Math.floor(basisBounds.y + (cursor.y - basisCursor.y)),
|
||||
width: Math.floor(lastWillResizeBounds.width / electron.screen.getDisplayMatching(basisBounds).scaleFactor),
|
||||
height: Math.floor(lastWillResizeBounds.height / electron.screen.getDisplayMatching(basisBounds).scaleFactor)
|
||||
})
|
||||
else setWindowBounds({
|
||||
x: Math.floor(basisBounds.x + (cursor.x - basisCursor.x)),
|
||||
y: Math.floor(basisBounds.y + (cursor.y - basisCursor.y)),
|
||||
width: Math.floor(lastWillMoveBounds.width / electron.screen.getDisplayMatching(basisBounds).scaleFactor),
|
||||
height: Math.floor(lastWillMoveBounds.height / electron.screen.getDisplayMatching(basisBounds).scaleFactor)
|
||||
})
|
||||
})
|
||||
if (didIt) {
|
||||
return doFollowUpQueryIfNecessary(cursor)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Poll at 600hz while moving window
|
||||
const moveInterval = setInterval(() => handleIntervalTick(moveInterval), 1000 / 600)
|
||||
}
|
||||
})
|
||||
|
||||
win.on('move', (e) => {
|
||||
if (disableJitterFix) {
|
||||
return false
|
||||
}
|
||||
if (isMoving || win.isDestroyed()) {
|
||||
e.preventDefault()
|
||||
return false
|
||||
}
|
||||
// As insane as this sounds, Electron sometimes reacts to prior
|
||||
// move events out of order. Specifically, if you have win.setBounds()
|
||||
// twice, then for some reason, when you exit the move state, the second
|
||||
// call to win.setBounds() gets reverted to the first call to win.setBounds().
|
||||
//
|
||||
// Again, it's nuts. But what we can do in this circumstance is thwack the
|
||||
// window back into place just to spite Electron. Yes, there's a shiver.
|
||||
// No, there's not much we can do about it until Electron gets their act together.
|
||||
if (desiredMoveBounds !== undefined) {
|
||||
const forceBounds = desiredMoveBounds
|
||||
desiredMoveBounds = undefined
|
||||
win.setBounds({
|
||||
x: Math.floor(forceBounds.x),
|
||||
y: Math.floor(forceBounds.y),
|
||||
width: Math.floor(forceBounds.width),
|
||||
height: Math.floor(forceBounds.height)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
win.on('will-resize', (e, newBounds) => {
|
||||
if (lastWillResizeBounds !== undefined && areBoundsEqual(lastWillResizeBounds, newBounds)) {
|
||||
e.preventDefault()
|
||||
return
|
||||
}
|
||||
|
||||
lastWillResizeBounds = newBounds
|
||||
|
||||
// 60 Hz ought to be enough... for resizes.
|
||||
// Some systems have trouble going 120 Hz, so we'll just take the lower
|
||||
// of the current pollingRate and 60 Hz.
|
||||
if (pollingRate !== undefined &&
|
||||
currentTimeBeforeNextActivityWindow(resizeLastUpdate, Math.min(pollingRate, maximumRefreshRate))) {
|
||||
e.preventDefault()
|
||||
return false
|
||||
}
|
||||
// We have to count this twice: once before the resize,
|
||||
// and once after the resize. We actually don't have any
|
||||
// timing control around _when_ the resize happened, so
|
||||
// we have to be pessimistic.
|
||||
resizeLastUpdate = process.hrtime.bigint()
|
||||
})
|
||||
|
||||
win.on('resize', () => {
|
||||
resizeLastUpdate = process.hrtime.bigint()
|
||||
boundsPromise = boundsPromise.then(doFollowUpQueryIfNecessary)
|
||||
})
|
||||
|
||||
// Close the VerticalRefreshRateContext so Node can exit cleanly
|
||||
win.on('closed', refreshCtx.close)
|
||||
}
|
||||
BIN
src/blur-cli.exe
BIN
src/blur-cli.exe
Binary file not shown.
@ -1,31 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29201.188
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blur-cli", "blur-cli\blur-cli.vcxproj", "{B7685D5D-1C32-4988-A15A-44EEACC7F20E}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B7685D5D-1C32-4988-A15A-44EEACC7F20E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B7685D5D-1C32-4988-A15A-44EEACC7F20E}.Debug|x64.Build.0 = Debug|x64
|
||||
{B7685D5D-1C32-4988-A15A-44EEACC7F20E}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B7685D5D-1C32-4988-A15A-44EEACC7F20E}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B7685D5D-1C32-4988-A15A-44EEACC7F20E}.Release|x64.ActiveCfg = Release|x64
|
||||
{B7685D5D-1C32-4988-A15A-44EEACC7F20E}.Release|x64.Build.0 = Release|x64
|
||||
{B7685D5D-1C32-4988-A15A-44EEACC7F20E}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B7685D5D-1C32-4988-A15A-44EEACC7F20E}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {E9D6A7A8-34A9-49E0-AA23-2F49D5D65842}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@ -1,127 +0,0 @@
|
||||
#include "pch.h"
|
||||
#include <dwmapi.h>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
struct ACCENTPOLICY {
|
||||
int nAccentState;
|
||||
int nFlags;
|
||||
int nColor;
|
||||
int nAnimationId;
|
||||
};
|
||||
struct WINCOMPATTRDATA {
|
||||
int nAttribute;
|
||||
PVOID pData;
|
||||
ULONG ulDataSize;
|
||||
};
|
||||
|
||||
enum AccentTypes {
|
||||
ACCENT_DISABLE = 0,
|
||||
ACCENT_ENABLE_GRADIENT = 1,
|
||||
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
|
||||
ACCENT_ENABLE_BLURBEHIND = 3,
|
||||
ACCENT_ENABLE_ACRYLIC = 4
|
||||
};
|
||||
|
||||
enum BlurTypes {
|
||||
DWM_BLUR = 0,
|
||||
ACRYLIC_BLUR = 1
|
||||
};
|
||||
|
||||
char* getCmdOption(char ** begin, char ** end, const std::string & option)
|
||||
{
|
||||
char ** itr = std::find(begin, end, option);
|
||||
if (itr != end && ++itr != end)
|
||||
{
|
||||
return *itr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool cmdOptionExists(char** begin, char** end, const std::string& option)
|
||||
{
|
||||
return std::find(begin, end, option) != end;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[], char *envp[])
|
||||
{
|
||||
HWND handle = NULL;
|
||||
int blurtype = DWM_BLUR;
|
||||
double opacity = 0.86;
|
||||
bool enable = true;
|
||||
int color = 0x1e1e1e;
|
||||
|
||||
handle = (HWND)atoi(argv[1]);
|
||||
|
||||
if (cmdOptionExists(argv, argv + argc, "--type")) {
|
||||
char* value_str = getCmdOption(argv, argv + argc, "--type");
|
||||
if (strcmp(value_str, "acrylic") == 0) {
|
||||
blurtype = ACRYLIC_BLUR;
|
||||
}
|
||||
else if (strcmp(value_str, "dwm") == 0) {
|
||||
blurtype = DWM_BLUR;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmdOptionExists(argv, argv + argc, "--enable")) {
|
||||
char* value_str = getCmdOption(argv, argv + argc, "--enable");
|
||||
if (strcmp(value_str, "false") == 0) {
|
||||
enable = false;
|
||||
}
|
||||
else if (strcmp(value_str, "true") == 0) {
|
||||
enable = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmdOptionExists(argv, argv + argc, "--opacity")) {
|
||||
char* value_str = getCmdOption(argv, argv + argc, "--opacity");
|
||||
opacity = atof(value_str);
|
||||
}
|
||||
|
||||
if (cmdOptionExists(argv, argv + argc, "--color")) {
|
||||
char* value_str = getCmdOption(argv, argv + argc, "--color");
|
||||
char* ptr;
|
||||
color = strtol(value_str, &ptr, 16);
|
||||
}
|
||||
|
||||
if (blurtype == DWM_BLUR) {
|
||||
// Create and populate the Blur Behind structure
|
||||
DWM_BLURBEHIND bb = { 0 };
|
||||
|
||||
// Enable Blur Behind and apply to the entire client area
|
||||
bb.dwFlags = DWM_BB_ENABLE;
|
||||
bb.fEnable = enable;
|
||||
bb.hRgnBlur = NULL;
|
||||
|
||||
const HRESULT returnValue = DwmEnableBlurBehindWindow(handle, &bb);
|
||||
|
||||
return SUCCEEDED(returnValue) ? 0 : 1;
|
||||
}
|
||||
else if (blurtype == ACRYLIC_BLUR) {
|
||||
const HINSTANCE hModule = LoadLibrary(TEXT("user32.dll"));
|
||||
int result = 1;
|
||||
if (hModule) {
|
||||
typedef BOOL(WINAPI*pSetWindowCompositionAttribute)(HWND,
|
||||
WINCOMPATTRDATA*);
|
||||
const pSetWindowCompositionAttribute
|
||||
SetWindowCompositionAttribute =
|
||||
(pSetWindowCompositionAttribute)GetProcAddress(
|
||||
hModule,
|
||||
"SetWindowCompositionAttribute");
|
||||
|
||||
// Only works on Win10
|
||||
if (SetWindowCompositionAttribute) {
|
||||
ACCENTPOLICY policy =
|
||||
{ enable ? ACCENT_ENABLE_ACRYLIC
|
||||
: ACCENT_DISABLE , 2, ((UINT)(opacity * 255.0) << 24) | color, 0 };
|
||||
WINCOMPATTRDATA data = { 19, &policy, sizeof(ACCENTPOLICY) };
|
||||
if (SetWindowCompositionAttribute(handle, &data))
|
||||
result = 0;
|
||||
else
|
||||
result = 1;
|
||||
}
|
||||
FreeLibrary(hModule);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,172 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{B7685D5D-1C32-4988-A15A-44EEACC7F20E}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>blurcli</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="blur-cli.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@ -1,30 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="blur-cli.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -1,5 +0,0 @@
|
||||
// pch.cpp: 与预编译标头对应的源文件;编译成功所必需的
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
// 一般情况下,忽略此文件,但如果你使用的是预编译标头,请保留它。
|
||||
@ -1,14 +0,0 @@
|
||||
// 入门提示:
|
||||
// 1. 使用解决方案资源管理器窗口添加/管理文件
|
||||
// 2. 使用团队资源管理器窗口连接到源代码管理
|
||||
// 3. 使用输出窗口查看生成输出和其他消息
|
||||
// 4. 使用错误列表窗口查看错误
|
||||
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
|
||||
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
|
||||
|
||||
#ifndef PCH_H
|
||||
#define PCH_H
|
||||
|
||||
// TODO: 添加要在此处预编译的标头
|
||||
|
||||
#endif //PCH_H
|
||||
@ -1,15 +0,0 @@
|
||||
{
|
||||
"messages.admin": "変更を適用するには、Visual Studio Code を管理者として実行してください。",
|
||||
"messages.firstload": "Vibrancy へようこそ。はじめに README をご覧ください。ボタンをクリックして、インストールを開始します。",
|
||||
"messages.configupdate": "設定が変更されました。反映させるには、再読み込みします。",
|
||||
"messages.enabled": "Vibrancy が有効化されました。設定は再起動の後に反映されます。もし Visual Studio Code が破損を検出した場合、\"今後表示しない\" をクリックします。詳細については README をご確認ください。",
|
||||
"messages.disabled": "Vibrancy が無効化されました。再起動することで、元の状態に戻ります。",
|
||||
"messages.already_disabled": "Vibrancy は既に無効です。",
|
||||
"messages.smthingwrong": "問題が発生しました: ",
|
||||
"messages.recommendedColorTheme": "現在の配色テーマは \"%1\" ですが、選択された Vibrancy テーマには \"%2\" を推奨します。",
|
||||
"messages.restartIde": "Visual Studio Code を再起動",
|
||||
"messages.installIde": "Vibrancy をインストール",
|
||||
"messages.reloadIde": "再読み込み",
|
||||
"messages.changeColorThemeIde": "配色テーマを変更する",
|
||||
"messages.noIde": "いいえ"
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
{
|
||||
"messages.admin": "Run VS Code with admin privileges so the changes can be applied.",
|
||||
"messages.firstload": "Welcome to use Vibrancy. Please read the README first. Click the button below to install.",
|
||||
"messages.configupdate": "Config is changed, do you want to reload.",
|
||||
"messages.enabled": "Vibrancy enabled. Restart to take effect. If Code complains about it is corrupted, CLICK DON\"T SHOW AGAIN. See README for more detail.",
|
||||
"messages.disabled": "Vibrancy disabled and reverted to default. Restart to take effect.",
|
||||
"messages.already_disabled": "Vibrancy already disabled.",
|
||||
"messages.smthingwrong": "Something went wrong: ",
|
||||
"messages.recommendedColorTheme": "Your current color theme is \"%1\" and the Vibrancy theme is designed for \"%2\"!",
|
||||
"messages.restartIde": "Restart Visual Studio Code",
|
||||
"messages.installIde": "Install Vibrancy",
|
||||
"messages.reloadIde": "Reload",
|
||||
"messages.changeColorThemeIde": "Change The Color Theme",
|
||||
"messages.noIde": "No"
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
{
|
||||
"messages.admin": "无法写入文件,请使用管理员权限运行 VSCode。",
|
||||
"messages.firstload": "欢迎使用 Vibrancy,请先阅读 README,单击下面的按钮进行安装。",
|
||||
"messages.configupdate": "配置已更改,是否要重新加载。",
|
||||
"messages.enabled": "已安装毛玻璃效果,重启后才能生效。如果 VSCode 提示”安装似乎损坏“,请点击“不再提示”。有关详细信息,请参阅自述文件。",
|
||||
"messages.disabled": "毛玻璃已卸载并恢复为默认值。重启才能生效。",
|
||||
"messages.already_disabled": "毛玻璃已经禁用。",
|
||||
"messages.smthingwrong": "发生了预料之外的错误: ",
|
||||
"messages.recommendedColorTheme": "你当前的颜色主题是 \"%1\" ,而你的毛玻璃主题是为 \"%2\" 设计的!",
|
||||
"messages.restartIde": "重启 Visual Studio Code",
|
||||
"messages.installIde": "安装毛玻璃效果",
|
||||
"messages.reloadIde": "重新加载",
|
||||
"messages.changeColorThemeIde": "改变颜色主题",
|
||||
"messages.noIde": "不要"
|
||||
}
|
||||
@ -1,12 +1,10 @@
|
||||
{
|
||||
"type": {
|
||||
"win7": "dwm",
|
||||
"win10": "acrylic",
|
||||
"macos": "ultra-dark"
|
||||
},
|
||||
"background": "1e1e1e",
|
||||
"opacity": {
|
||||
"win7": 0.3,
|
||||
"win10": 0.8,
|
||||
"macos": 0.3
|
||||
},
|
||||
|
||||
@ -1,12 +1,10 @@
|
||||
{
|
||||
"type": {
|
||||
"win7": "dwm",
|
||||
"win10": "acrylic",
|
||||
"macos": "ultra-dark"
|
||||
},
|
||||
"background": "1e1e1e",
|
||||
"opacity": {
|
||||
"win7": 0.3,
|
||||
"win10": 0.8,
|
||||
"macos": 0.3
|
||||
},
|
||||
|
||||
@ -85,19 +85,22 @@ body {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.monaco-workbench .activitybar>.content :not(.monaco-menu)>.monaco-action-bar .action-label.codicon {
|
||||
color: #616161 !important;
|
||||
}
|
||||
|
||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:hover .action-label.codicon {
|
||||
color: #000 !important;
|
||||
}
|
||||
|
||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.checked .active-item-indicator:before {
|
||||
border-left-color: #616161 !important;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.sidebar {
|
||||
background-color: rgba(228, 230, 241, 0.3) !important;
|
||||
}
|
||||
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item .action-label {
|
||||
background-color: #616161 !important;
|
||||
}
|
||||
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item:hover .action-label {
|
||||
background-color:#000 !important;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.statusbar {
|
||||
color: #616161 !important;
|
||||
}
|
||||
|
||||
@ -1,12 +1,10 @@
|
||||
{
|
||||
"type": {
|
||||
"win7": "dwm",
|
||||
"win10": "acrylic",
|
||||
"macos": "medium-light"
|
||||
},
|
||||
"background": "ffffff",
|
||||
"opacity": {
|
||||
"win7": 0.3,
|
||||
"win10": 0.8,
|
||||
"macos": 0.3
|
||||
},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user