latex-stickies 1.3.6 → 1.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/bin/latex-stickies.js +23 -17
- package/package.json +2 -1
- package/scripts/brand-electron.js +166 -120
- package/src/main.js +26 -10
- package/src/store.js +10 -1
package/README.md
CHANGED
|
@@ -24,7 +24,10 @@ latex-stickies
|
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
Requires Node 22.12 or newer. The first run downloads the Electron runtime
|
|
27
|
-
(~230 MB), so give it a minute; later launches are instant. On a Mac
|
|
27
|
+
(~230 MB), so give it a minute; later launches are instant. On a Mac it also
|
|
28
|
+
keeps a copy of the runtime carrying this app's name and icon in
|
|
29
|
+
`~/Library/Application Support/latex-stickies/` -- on APFS that is a
|
|
30
|
+
copy-on-write clone, so it costs almost no disk. On a Mac you can
|
|
28
31
|
download a `.dmg` from [Releases](https://github.com/kev-nj/latex-stickies/releases)
|
|
29
32
|
instead and skip Node entirely.
|
|
30
33
|
|
|
@@ -146,6 +149,7 @@ npm test # unit suites
|
|
|
146
149
|
npm run vendor # rebuild the bundled libraries
|
|
147
150
|
npm run icon # rebuild the app icon from assets/icon-master.png
|
|
148
151
|
npm run demo # re-record assets/demo.gif from the real app (needs ffmpeg)
|
|
152
|
+
npm run verify # install the packed tarball and check what a user gets
|
|
149
153
|
npm run dist # build a macOS .app and .dmg
|
|
150
154
|
```
|
|
151
155
|
|
|
@@ -158,6 +162,7 @@ node scripts/smoke.js --lifecycle # closing every note behaves per platform
|
|
|
158
162
|
node scripts/render-check.js # the first-run note renders correctly
|
|
159
163
|
node scripts/ghost-check.js # autocomplete suggests, and Tab accepts
|
|
160
164
|
node scripts/snapshot-check.js # a long note is captured whole
|
|
165
|
+
node scripts/verify-install.js # the install path, end to end (macOS)
|
|
161
166
|
```
|
|
162
167
|
|
|
163
168
|
The renderer loads over `file://` under a strict content-security policy, so
|
package/bin/latex-stickies.js
CHANGED
|
@@ -10,26 +10,32 @@
|
|
|
10
10
|
const { spawn } = require('child_process');
|
|
11
11
|
const path = require('path');
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
// Brand before resolving anything: this returns the path to a copy of the
|
|
14
|
+
// Electron shell carrying our name and icon, kept outside node_modules so it
|
|
15
|
+
// survives npx cache churn and npm ci. Falls back to the plain shell, which
|
|
16
|
+
// runs identically and only looks wrong in the Dock.
|
|
17
|
+
//
|
|
18
|
+
// postinstall cannot be relied on for this -- npm 11 warns about install
|
|
19
|
+
// scripts by default and blocks them outright for global installs, and plenty
|
|
20
|
+
// of people and companies turn them off.
|
|
21
|
+
let electron = null;
|
|
14
22
|
try {
|
|
15
|
-
electron = require('electron');
|
|
16
|
-
} catch (
|
|
17
|
-
console.error(
|
|
18
|
-
'Could not find the Electron runtime.\n' +
|
|
19
|
-
'Reinstall with: npm install -g latex-stickies'
|
|
20
|
-
);
|
|
21
|
-
process.exit(1);
|
|
23
|
+
electron = require('../scripts/brand-electron.js').ensure();
|
|
24
|
+
} catch (err) {
|
|
25
|
+
console.error(`could not brand the app: ${err.message}`);
|
|
22
26
|
}
|
|
23
27
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
if (!electron) {
|
|
29
|
+
try {
|
|
30
|
+
electron = require('electron');
|
|
31
|
+
} catch (_) {
|
|
32
|
+
console.error(
|
|
33
|
+
'Could not find the Electron runtime.\n' +
|
|
34
|
+
'Reinstall with: npm install -g latex-stickies'
|
|
35
|
+
);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
33
39
|
|
|
34
40
|
const appDir = path.join(__dirname, '..');
|
|
35
41
|
const child = spawn(electron, [appDir, ...process.argv.slice(2)], {
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "latex-stickies",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.8",
|
|
4
4
|
"description": "Sticky notes for your desktop that render LaTeX and Markdown.",
|
|
5
5
|
"main": "src/main.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"start": "electron .",
|
|
8
8
|
"test": "node scripts/test.js",
|
|
9
|
+
"verify": "node scripts/verify-install.js",
|
|
9
10
|
"vendor": "node scripts/vendor.js",
|
|
10
11
|
"icon": "node scripts/make-icon.js",
|
|
11
12
|
"demo": "node scripts/make-demo.js",
|
|
@@ -1,152 +1,198 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* Gives the
|
|
3
|
+
* Gives this app its own macOS bundle, so the Dock shows our name and icon.
|
|
4
4
|
*
|
|
5
|
-
* Run from source or from npm there is no .app
|
|
6
|
-
*
|
|
7
|
-
* "Electron" and wears the atom logo. app.setName() cannot
|
|
8
|
-
*
|
|
5
|
+
* Run from source or from npm there is no .app of our own: macOS takes the
|
|
6
|
+
* Dock name and icon from the Electron shell being launched, which is called
|
|
7
|
+
* "Electron" and wears the atom logo. app.setName() cannot help -- the Dock
|
|
8
|
+
* reads the bundle before any of our code runs.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
10
|
+
* So the shell is cloned to a stable path of our own and branded there:
|
|
11
|
+
*
|
|
12
|
+
* ~/Library/Application Support/latex-stickies/LaTeX Stickies.app
|
|
13
|
+
*
|
|
14
|
+
* Cloning rather than editing node_modules in place, for three reasons. npx
|
|
15
|
+
* installs under a fresh cache hash every time, so in-place work is redone
|
|
16
|
+
* constantly and thrown away by any cache prune or npm ci. A path macOS has
|
|
17
|
+
* already registered as "Electron" tends to keep serving that name back from
|
|
18
|
+
* the LaunchServices database however correct the plist becomes -- a path it
|
|
19
|
+
* has never seen has no such record. And `npm update electron` would silently
|
|
20
|
+
* revert every rename we made.
|
|
21
|
+
*
|
|
22
|
+
* On APFS the clone is copy-on-write: near-instant, and it costs almost no
|
|
23
|
+
* disk until the files diverge.
|
|
24
|
+
*
|
|
25
|
+
* Everything here is best-effort. A wrong name in the Dock is a blemish; a
|
|
26
|
+
* failed launch is not, so any error falls back to the unbranded shell.
|
|
15
27
|
*/
|
|
16
28
|
const { execFileSync } = require('child_process');
|
|
29
|
+
const crypto = require('crypto');
|
|
17
30
|
const fs = require('fs');
|
|
31
|
+
const os = require('os');
|
|
18
32
|
const path = require('path');
|
|
19
33
|
|
|
20
34
|
const NAME = 'LaTeX Stickies';
|
|
21
35
|
/**
|
|
22
36
|
* Our own bundle identifier, matching the packaged builds.
|
|
23
37
|
*
|
|
24
|
-
* The
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* "Electron", however carefully this script renames our copy. Taking our own
|
|
29
|
-
* identifier is what stops the collision; renaming alone cannot.
|
|
38
|
+
* The shell ships as com.github.Electron, and LaunchServices keys its database
|
|
39
|
+
* by identifier as well as by path -- so on a machine that has seen any other
|
|
40
|
+
* Electron, that shared identifier can resolve to someone else's record and
|
|
41
|
+
* serve its name, "Electron", however carefully this bundle is renamed.
|
|
30
42
|
*/
|
|
31
43
|
const APP_ID = 'com.kevinjusak.latexsticky';
|
|
32
44
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
const ROOT = path.join(__dirname, '..');
|
|
46
|
+
const ICON = path.join(ROOT, 'build', 'icon.icns');
|
|
47
|
+
|
|
48
|
+
/** Overridable so a test can brand somewhere disposable. */
|
|
49
|
+
const HOME = process.env.LATEX_STICKIES_APP_DIR
|
|
50
|
+
|| path.join(os.homedir(), 'Library', 'Application Support', 'latex-stickies');
|
|
51
|
+
const TARGET = path.join(HOME, `${NAME}.app`);
|
|
52
|
+
const STAMP = path.join(HOME, '.branded.json');
|
|
53
|
+
|
|
54
|
+
const LSREGISTER = '/System/Library/Frameworks/CoreServices.framework/Frameworks'
|
|
55
|
+
+ '/LaunchServices.framework/Support/lsregister';
|
|
56
|
+
|
|
57
|
+
const run = (cmd, args, opts = {}) =>
|
|
58
|
+
execFileSync(cmd, args, { stdio: 'ignore', timeout: 120000, ...opts });
|
|
59
|
+
|
|
60
|
+
/** The Electron shell npm installed, and the version we would be cloning. */
|
|
61
|
+
function source() {
|
|
62
|
+
const dir = path.dirname(require.resolve('electron/package.json', { paths: [ROOT] }));
|
|
63
|
+
const binary = require(path.join(dir, 'index.js'));
|
|
64
|
+
// .../Electron.app/Contents/MacOS/Electron -> .../Electron.app
|
|
65
|
+
const app = path.resolve(path.dirname(binary), '..', '..');
|
|
66
|
+
const { version } = JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf8'));
|
|
67
|
+
return { app, version };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const sha = (file) => crypto.createHash('sha256').update(fs.readFileSync(file)).digest('hex');
|
|
71
|
+
|
|
72
|
+
/** What the branded copy was built from, so it can be rebuilt when that moves. */
|
|
73
|
+
function stamp(version) {
|
|
74
|
+
return JSON.stringify({
|
|
75
|
+
electron: version,
|
|
76
|
+
icon: fs.existsSync(ICON) ? sha(ICON) : '',
|
|
77
|
+
name: NAME,
|
|
78
|
+
id: APP_ID,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function isCurrent(version) {
|
|
42
83
|
try {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
84
|
+
return fs.existsSync(path.join(TARGET, 'Contents', 'MacOS', NAME))
|
|
85
|
+
&& fs.readFileSync(STAMP, 'utf8') === stamp(version);
|
|
86
|
+
} catch (_) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function setPlist(plist, key, value) {
|
|
92
|
+
try {
|
|
93
|
+
run('plutil', ['-replace', key, '-string', value, plist]);
|
|
94
|
+
} catch (_) {
|
|
95
|
+
run('plutil', ['-insert', key, '-string', value, plist]);
|
|
96
|
+
}
|
|
50
97
|
}
|
|
51
98
|
|
|
52
|
-
|
|
53
|
-
|
|
99
|
+
/**
|
|
100
|
+
* Builds the branded copy.
|
|
101
|
+
*
|
|
102
|
+
* The executable is renamed as well as the plist keys: macOS takes the Dock
|
|
103
|
+
* label from the running executable, which is why packaged builds have always
|
|
104
|
+
* been right -- electron-builder renames it -- and every npm install was not.
|
|
105
|
+
*/
|
|
106
|
+
function build(app, version) {
|
|
107
|
+
fs.mkdirSync(HOME, { recursive: true });
|
|
108
|
+
fs.rmSync(TARGET, { recursive: true, force: true });
|
|
54
109
|
|
|
55
|
-
|
|
110
|
+
// -c asks APFS for a copy-on-write clone; plain copy on any filesystem
|
|
111
|
+
// that cannot, which is slower but correct.
|
|
56
112
|
try {
|
|
57
|
-
|
|
58
|
-
// .../Electron.app/Contents/MacOS/Electron -> .../Electron.app
|
|
59
|
-
appPath = path.resolve(path.dirname(binary), '..', '..');
|
|
113
|
+
run('cp', ['-cR', app, TARGET]);
|
|
60
114
|
} catch (_) {
|
|
61
|
-
|
|
115
|
+
run('cp', ['-R', app, TARGET]);
|
|
62
116
|
}
|
|
63
117
|
|
|
64
|
-
const plist = path.join(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
118
|
+
const plist = path.join(TARGET, 'Contents', 'Info.plist');
|
|
119
|
+
setPlist(plist, 'CFBundleName', NAME);
|
|
120
|
+
setPlist(plist, 'CFBundleDisplayName', NAME);
|
|
121
|
+
setPlist(plist, 'CFBundleIdentifier', APP_ID);
|
|
122
|
+
setPlist(plist, 'CFBundleExecutable', NAME);
|
|
123
|
+
|
|
124
|
+
const from = path.join(TARGET, 'Contents', 'MacOS', 'Electron');
|
|
125
|
+
const to = path.join(TARGET, 'Contents', 'MacOS', NAME);
|
|
126
|
+
if (fs.existsSync(from)) fs.renameSync(from, to);
|
|
127
|
+
|
|
128
|
+
// The bundle icon is what Finder, Cmd-Tab and the Dock show before the app
|
|
129
|
+
// is running; app.dock.setIcon() cannot stand in for it.
|
|
130
|
+
const icon = path.join(TARGET, 'Contents', 'Resources', 'electron.icns');
|
|
131
|
+
if (fs.existsSync(ICON) && fs.existsSync(icon)) fs.copyFileSync(ICON, icon);
|
|
132
|
+
|
|
133
|
+
// Re-signing is required: any edit under Contents/ invalidates the ad-hoc
|
|
134
|
+
// signature, and macOS will not launch a bundle whose signature does not
|
|
135
|
+
// match its contents. Only the outer bundle was touched, so the helpers keep
|
|
136
|
+
// their own signatures -- and --preserve-metadata keeps whatever
|
|
137
|
+
// entitlements the stock build shipped with, which --deep would discard.
|
|
138
|
+
run('codesign', [
|
|
139
|
+
'--force',
|
|
140
|
+
'--preserve-metadata=entitlements,requirements,flags',
|
|
141
|
+
'--sign', '-', TARGET,
|
|
142
|
+
]);
|
|
143
|
+
run('codesign', ['--verify', TARGET]);
|
|
144
|
+
|
|
145
|
+
// Evict any record for this path before registering it, since lsregister -f
|
|
146
|
+
// refreshes an entry but does not replace a stale one.
|
|
147
|
+
try { run(LSREGISTER, ['-u', TARGET]); } catch (_) { /* nothing registered */ }
|
|
148
|
+
try { run(LSREGISTER, ['-f', TARGET]); } catch (_) { /* only the cache */ }
|
|
149
|
+
|
|
150
|
+
fs.writeFileSync(STAMP, stamp(version));
|
|
151
|
+
return to;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* The binary to launch: the branded copy, or null to fall back to the shell.
|
|
156
|
+
*/
|
|
157
|
+
function ensure() {
|
|
158
|
+
if (process.platform !== 'darwin') return null;
|
|
159
|
+
|
|
160
|
+
let app;
|
|
161
|
+
let version;
|
|
162
|
+
try {
|
|
163
|
+
({ app, version } = source());
|
|
164
|
+
} catch (err) {
|
|
165
|
+
report(`could not find the Electron runtime to brand (${first(err)})`);
|
|
166
|
+
return null;
|
|
88
167
|
}
|
|
89
168
|
|
|
90
|
-
const backup = fs.readFileSync(plist);
|
|
91
169
|
try {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
['CFBundleExecutable', NAME],
|
|
97
|
-
];
|
|
98
|
-
for (const [key, value] of fields) {
|
|
99
|
-
try {
|
|
100
|
-
execFileSync('plutil', ['-replace', key, '-string', value, plist]);
|
|
101
|
-
} catch (_) {
|
|
102
|
-
execFileSync('plutil', ['-insert', key, '-string', value, plist]);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Rename the executable too. macOS takes the Dock label from the running
|
|
107
|
-
// executable, not only from the plist -- which is why the packaged builds
|
|
108
|
-
// have always shown the right name (electron-builder renames it) while
|
|
109
|
-
// every npm install showed "Electron" however the plist was rewritten.
|
|
110
|
-
const oldBinary = path.join(appPath, 'Contents', 'MacOS', 'Electron');
|
|
111
|
-
if (fs.existsSync(oldBinary) && !fs.existsSync(binary)) {
|
|
112
|
-
fs.renameSync(oldBinary, binary);
|
|
113
|
-
}
|
|
114
|
-
// require('electron') reads this file for the path it returns, so it has
|
|
115
|
-
// to follow the rename or every launcher breaks.
|
|
116
|
-
const pathTxt = path.join(path.dirname(appPath), '..', 'path.txt');
|
|
117
|
-
if (fs.existsSync(pathTxt)) {
|
|
118
|
-
fs.writeFileSync(pathTxt, `Electron.app/Contents/MacOS/${NAME}`);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// The bundle icon is what shows before the app can set its own.
|
|
122
|
-
const icon = path.join(__dirname, '..', 'build', 'icon.icns');
|
|
123
|
-
const target = path.join(appPath, 'Contents', 'Resources', 'electron.icns');
|
|
124
|
-
if (fs.existsSync(icon) && fs.existsSync(target)) fs.copyFileSync(icon, target);
|
|
125
|
-
|
|
126
|
-
// Required: the edits above invalidate the ad-hoc signature, and macOS
|
|
127
|
-
// refuses to launch a bundle whose signature does not match its contents.
|
|
128
|
-
execFileSync('codesign', ['--force', '--deep', '--sign', '-', appPath], {
|
|
129
|
-
stdio: 'ignore',
|
|
130
|
-
});
|
|
131
|
-
execFileSync('codesign', ['--verify', appPath], { stdio: 'ignore' });
|
|
132
|
-
|
|
133
|
-
refreshLaunchServices(appPath);
|
|
134
|
-
|
|
135
|
-
console.log(`named the Electron shell "${NAME}"`);
|
|
170
|
+
if (isCurrent(version)) return path.join(TARGET, 'Contents', 'MacOS', NAME);
|
|
171
|
+
const binary = build(app, version);
|
|
172
|
+
report(`branded ${TARGET}`, true);
|
|
173
|
+
return binary;
|
|
136
174
|
} catch (err) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
} catch (_) { /* leave it as found */ }
|
|
143
|
-
console.log(`could not rename the Electron shell (${err.message.split('\n')[0]})`);
|
|
175
|
+
// Leave nothing half-built: a bundle with a broken signature will not
|
|
176
|
+
// launch at all, which is far worse than the wrong name.
|
|
177
|
+
fs.rmSync(TARGET, { recursive: true, force: true });
|
|
178
|
+
report(`could not brand the app (${first(err)})`);
|
|
179
|
+
return null;
|
|
144
180
|
}
|
|
145
181
|
}
|
|
146
182
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
183
|
+
const first = (err) => String(err && err.message).split('\n')[0];
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Failures are reported, successes only when asked.
|
|
187
|
+
*
|
|
188
|
+
* A silent failure is what made this so hard to diagnose from a user's
|
|
189
|
+
* terminal: "the Dock still says Electron" looked identical whether branding
|
|
190
|
+
* had failed, had never run, or had worked on a bundle nobody was launching.
|
|
191
|
+
*/
|
|
192
|
+
function report(message, quiet = false) {
|
|
193
|
+
if (!quiet || process.env.LATEX_STICKIES_VERBOSE) console.log(message);
|
|
152
194
|
}
|
|
195
|
+
|
|
196
|
+
module.exports = { ensure, TARGET, NAME, APP_ID };
|
|
197
|
+
|
|
198
|
+
if (require.main === module) ensure();
|
package/src/main.js
CHANGED
|
@@ -473,11 +473,23 @@ let quitting = false;
|
|
|
473
473
|
*/
|
|
474
474
|
function prepareToExit() {
|
|
475
475
|
quitting = true;
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
476
|
+
// Nothing here may throw. The caller's next statement is process.exit(), and
|
|
477
|
+
// an exception thrown on the way out skips it -- leaving exactly the
|
|
478
|
+
// invisible, unreachable process this whole path exists to prevent. Saving
|
|
479
|
+
// is worth attempting; it is not worth staying alive for.
|
|
480
|
+
try {
|
|
481
|
+
if (stopWatchingNotes) {
|
|
482
|
+
stopWatchingNotes();
|
|
483
|
+
stopWatchingNotes = null;
|
|
484
|
+
}
|
|
485
|
+
} catch (err) {
|
|
486
|
+
console.error('could not stop watching the notes folder', err);
|
|
487
|
+
}
|
|
488
|
+
try {
|
|
489
|
+
store.saveNow();
|
|
490
|
+
} catch (err) {
|
|
491
|
+
console.error('could not save on the way out', err);
|
|
479
492
|
}
|
|
480
|
-
store.saveNow();
|
|
481
493
|
}
|
|
482
494
|
|
|
483
495
|
function watchNotesFolder() {
|
|
@@ -490,12 +502,16 @@ function watchNotesFolder() {
|
|
|
490
502
|
}
|
|
491
503
|
|
|
492
504
|
app.whenReady().then(async () => {
|
|
493
|
-
// Run from npm there is no .app bundle to carry the icon, so
|
|
494
|
-
// the generic Electron atom in the Dock. Set it explicitly.
|
|
495
|
-
//
|
|
496
|
-
//
|
|
497
|
-
//
|
|
498
|
-
|
|
505
|
+
// Run from npm there is no .app bundle of our own to carry the icon, so
|
|
506
|
+
// macOS would show the generic Electron atom in the Dock. Set it explicitly.
|
|
507
|
+
//
|
|
508
|
+
// Keyed on the file existing, not on app.isPackaged. Naming the Dock entry
|
|
509
|
+
// means renaming the executable inside the vendored Electron.app, and
|
|
510
|
+
// isPackaged is derived from that executable's name -- so an npm install
|
|
511
|
+
// started reporting itself as packaged, this branch stopped running, and
|
|
512
|
+
// fixing the name cost the icon. A packaged build has no build/ directory
|
|
513
|
+
// inside it, which is the same condition, tested directly.
|
|
514
|
+
if (process.platform === 'darwin' && app.dock && fs.existsSync(ICON)) {
|
|
499
515
|
try {
|
|
500
516
|
const image = nativeImage.createFromBuffer(fs.readFileSync(ICON));
|
|
501
517
|
if (!image.isEmpty()) app.dock.setIcon(image);
|
package/src/store.js
CHANGED
|
@@ -20,7 +20,16 @@ const { app } = require('electron');
|
|
|
20
20
|
const fs = require('fs');
|
|
21
21
|
const path = require('path');
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Where the notes live.
|
|
25
|
+
*
|
|
26
|
+
* The override exists for harnesses. On macOS Electron resolves the documents
|
|
27
|
+
* folder through the OS rather than $HOME, so a test that redirects HOME still
|
|
28
|
+
* reads and writes the real notes -- which is how a verification run ended up
|
|
29
|
+
* touching them.
|
|
30
|
+
*/
|
|
31
|
+
const DIR = process.env.LATEX_STICKIES_NOTES_DIR
|
|
32
|
+
|| path.join(app.getPath('documents'), 'LaTeX Stickies');
|
|
24
33
|
const INDEX = path.join(DIR, '.stickies.json');
|
|
25
34
|
/** The old single-file store, migrated from once and then left alone. */
|
|
26
35
|
const LEGACY = path.join(app.getPath('userData'), 'notes.json');
|