custom-electron-titlebar 4.2.7 → 4.4.0

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.
Files changed (77) hide show
  1. package/README.md +43 -19
  2. package/index.d.mts +684 -0
  3. package/index.d.ts +684 -3
  4. package/index.js +5225 -175
  5. package/index.js.map +1 -0
  6. package/index.mjs +5227 -0
  7. package/index.mjs.map +1 -0
  8. package/main/index.d.mts +21 -0
  9. package/main/index.d.ts +21 -3
  10. package/main/index.js +793 -175
  11. package/main/index.js.map +1 -0
  12. package/main/index.mjs +785 -0
  13. package/main/index.mjs.map +1 -0
  14. package/package.json +56 -33
  15. package/theme/base.css +425 -0
  16. package/theme/mac.css +0 -0
  17. package/theme/win.css +0 -0
  18. package/base/browser/browser.d.ts +0 -26
  19. package/base/browser/browser.js +0 -317
  20. package/base/browser/event.d.ts +0 -12
  21. package/base/browser/event.js +0 -215
  22. package/base/browser/keyboardEvent.d.ts +0 -38
  23. package/base/browser/keyboardEvent.js +0 -464
  24. package/base/browser/mouseEvent.d.ts +0 -61
  25. package/base/browser/mouseEvent.js +0 -327
  26. package/base/browser/touch.d.ts +0 -39
  27. package/base/browser/touch.js +0 -454
  28. package/base/common/arrays.d.ts +0 -10
  29. package/base/common/arrays.js +0 -210
  30. package/base/common/async.d.ts +0 -35
  31. package/base/common/async.js +0 -280
  32. package/base/common/charCode.d.ts +0 -405
  33. package/base/common/charCode.js +0 -9
  34. package/base/common/color.d.ts +0 -159
  35. package/base/common/color.js +0 -708
  36. package/base/common/decorators.d.ts +0 -6
  37. package/base/common/decorators.js +0 -300
  38. package/base/common/dom.d.ts +0 -221
  39. package/base/common/dom.js +0 -1478
  40. package/base/common/event.d.ts +0 -213
  41. package/base/common/event.js +0 -804
  42. package/base/common/iterator.d.ts +0 -69
  43. package/base/common/iterator.js +0 -381
  44. package/base/common/keyCodes.d.ts +0 -478
  45. package/base/common/keyCodes.js +0 -479
  46. package/base/common/lifecycle.d.ts +0 -17
  47. package/base/common/lifecycle.js +0 -258
  48. package/base/common/linkedList.d.ts +0 -17
  49. package/base/common/linkedList.js +0 -319
  50. package/base/common/platform.d.ts +0 -36
  51. package/base/common/platform.js +0 -314
  52. package/base/common/strings.d.ts +0 -23
  53. package/base/common/strings.js +0 -273
  54. package/consts.d.ts +0 -58
  55. package/consts.js +0 -317
  56. package/main/attach-titlebar-to-window.d.ts +0 -3
  57. package/main/attach-titlebar-to-window.js +0 -210
  58. package/main/setup-titlebar.d.ts +0 -2
  59. package/main/setup-titlebar.js +0 -255
  60. package/menubar/index.d.ts +0 -86
  61. package/menubar/index.js +0 -1121
  62. package/menubar/menu/index.d.ts +0 -46
  63. package/menubar/menu/index.js +0 -566
  64. package/menubar/menu/item.d.ts +0 -67
  65. package/menubar/menu/item.js +0 -575
  66. package/menubar/menu/separator.d.ts +0 -11
  67. package/menubar/menu/separator.js +0 -213
  68. package/menubar/menu/submenu.d.ts +0 -32
  69. package/menubar/menu/submenu.js +0 -372
  70. package/menubar/menubar-options.d.ts +0 -47
  71. package/menubar/menubar-options.js +0 -9
  72. package/titlebar/index.d.ts +0 -104
  73. package/titlebar/index.js +0 -696
  74. package/titlebar/options.d.ts +0 -84
  75. package/titlebar/options.js +0 -9
  76. package/titlebar/themebar.d.ts +0 -20
  77. package/titlebar/themebar.js +0 -267
package/main/index.mjs ADDED
@@ -0,0 +1,785 @@
1
+ // src/base/common/color.ts
2
+ function roundFloat(number, decimalPoints) {
3
+ const decimal = Math.pow(10, decimalPoints);
4
+ return Math.round(number * decimal) / decimal;
5
+ }
6
+ var RGBA = class {
7
+ constructor(r, g, b, a = 1) {
8
+ this.r = Math.min(255, Math.max(0, r)) | 0;
9
+ this.g = Math.min(255, Math.max(0, g)) | 0;
10
+ this.b = Math.min(255, Math.max(0, b)) | 0;
11
+ this.a = roundFloat(Math.max(Math.min(1, a), 0), 3);
12
+ }
13
+ static equals(a, b) {
14
+ return a.r === b.r && a.g === b.g && a.b === b.b && a.a === b.a;
15
+ }
16
+ };
17
+ var HSLA = class _HSLA {
18
+ constructor(h, s, l, a) {
19
+ this.h = Math.max(Math.min(360, h), 0) | 0;
20
+ this.s = roundFloat(Math.max(Math.min(1, s), 0), 3);
21
+ this.l = roundFloat(Math.max(Math.min(1, l), 0), 3);
22
+ this.a = roundFloat(Math.max(Math.min(1, a), 0), 3);
23
+ }
24
+ static equals(a, b) {
25
+ return a.h === b.h && a.s === b.s && a.l === b.l && a.a === b.a;
26
+ }
27
+ /**
28
+ * Converts an RGB color value to HSL. Conversion formula
29
+ * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
30
+ * Assumes r, g, and b are contained in the set [0, 255] and
31
+ * returns h in the set [0, 360], s, and l in the set [0, 1].
32
+ */
33
+ static fromRGBA(rgba) {
34
+ const r = rgba.r / 255;
35
+ const g = rgba.g / 255;
36
+ const b = rgba.b / 255;
37
+ const a = rgba.a;
38
+ const max = Math.max(r, g, b);
39
+ const min = Math.min(r, g, b);
40
+ let h = 0;
41
+ let s = 0;
42
+ const l = (min + max) / 2;
43
+ const chroma = max - min;
44
+ if (chroma > 0) {
45
+ s = Math.min(l <= 0.5 ? chroma / (2 * l) : chroma / (2 - 2 * l), 1);
46
+ switch (max) {
47
+ case r:
48
+ h = (g - b) / chroma + (g < b ? 6 : 0);
49
+ break;
50
+ case g:
51
+ h = (b - r) / chroma + 2;
52
+ break;
53
+ case b:
54
+ h = (r - g) / chroma + 4;
55
+ break;
56
+ }
57
+ h *= 60;
58
+ h = Math.round(h);
59
+ }
60
+ return new _HSLA(h, s, l, a);
61
+ }
62
+ static _hue2rgb(p, q, t) {
63
+ if (t < 0) {
64
+ t += 1;
65
+ }
66
+ if (t > 1) {
67
+ t -= 1;
68
+ }
69
+ if (t < 1 / 6) {
70
+ return p + (q - p) * 6 * t;
71
+ }
72
+ if (t < 1 / 2) {
73
+ return q;
74
+ }
75
+ if (t < 2 / 3) {
76
+ return p + (q - p) * (2 / 3 - t) * 6;
77
+ }
78
+ return p;
79
+ }
80
+ /**
81
+ * Converts an HSL color value to RGB. Conversion formula
82
+ * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
83
+ * Assumes h in the set [0, 360] s, and l are contained in the set [0, 1] and
84
+ * returns r, g, and b in the set [0, 255].
85
+ */
86
+ static toRGBA(hsla) {
87
+ const h = hsla.h / 360;
88
+ const { s, l, a } = hsla;
89
+ let r, g, b;
90
+ if (s === 0) {
91
+ r = g = b = l;
92
+ } else {
93
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
94
+ const p = 2 * l - q;
95
+ r = _HSLA._hue2rgb(p, q, h + 1 / 3);
96
+ g = _HSLA._hue2rgb(p, q, h);
97
+ b = _HSLA._hue2rgb(p, q, h - 1 / 3);
98
+ }
99
+ return new RGBA(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), a);
100
+ }
101
+ };
102
+ var HSVA = class _HSVA {
103
+ constructor(h, s, v, a) {
104
+ this.h = Math.max(Math.min(360, h), 0) | 0;
105
+ this.s = roundFloat(Math.max(Math.min(1, s), 0), 3);
106
+ this.v = roundFloat(Math.max(Math.min(1, v), 0), 3);
107
+ this.a = roundFloat(Math.max(Math.min(1, a), 0), 3);
108
+ }
109
+ static equals(a, b) {
110
+ return a.h === b.h && a.s === b.s && a.v === b.v && a.a === b.a;
111
+ }
112
+ // from http://www.rapidtables.com/convert/color/rgb-to-hsv.htm
113
+ static fromRGBA(rgba) {
114
+ const r = rgba.r / 255;
115
+ const g = rgba.g / 255;
116
+ const b = rgba.b / 255;
117
+ const cmax = Math.max(r, g, b);
118
+ const cmin = Math.min(r, g, b);
119
+ const delta = cmax - cmin;
120
+ const s = cmax === 0 ? 0 : delta / cmax;
121
+ let m;
122
+ if (delta === 0) {
123
+ m = 0;
124
+ } else if (cmax === r) {
125
+ m = ((g - b) / delta % 6 + 6) % 6;
126
+ } else if (cmax === g) {
127
+ m = (b - r) / delta + 2;
128
+ } else {
129
+ m = (r - g) / delta + 4;
130
+ }
131
+ return new _HSVA(Math.round(m * 60), s, cmax, rgba.a);
132
+ }
133
+ // from http://www.rapidtables.com/convert/color/hsv-to-rgb.htm
134
+ static toRGBA(hsva) {
135
+ const { h, s, v, a } = hsva;
136
+ const c = v * s;
137
+ const x = c * (1 - Math.abs(h / 60 % 2 - 1));
138
+ const m = v - c;
139
+ let [r, g, b] = [0, 0, 0];
140
+ if (h < 60) {
141
+ r = c;
142
+ g = x;
143
+ } else if (h < 120) {
144
+ r = x;
145
+ g = c;
146
+ } else if (h < 180) {
147
+ g = c;
148
+ b = x;
149
+ } else if (h < 240) {
150
+ g = x;
151
+ b = c;
152
+ } else if (h < 300) {
153
+ r = x;
154
+ b = c;
155
+ } else if (h < 360) {
156
+ r = c;
157
+ b = x;
158
+ }
159
+ r = Math.round((r + m) * 255);
160
+ g = Math.round((g + m) * 255);
161
+ b = Math.round((b + m) * 255);
162
+ return new RGBA(r, g, b, a);
163
+ }
164
+ };
165
+ var _Color = class _Color {
166
+ static fromHex(hex) {
167
+ return _Color.Format.CSS.parseHex(hex) || _Color.RED;
168
+ }
169
+ get hsla() {
170
+ if (this._hsla) {
171
+ return this._hsla;
172
+ } else {
173
+ return HSLA.fromRGBA(this.rgba);
174
+ }
175
+ }
176
+ get hsva() {
177
+ if (this._hsva) {
178
+ return this._hsva;
179
+ }
180
+ return HSVA.fromRGBA(this.rgba);
181
+ }
182
+ constructor(arg) {
183
+ if (!arg) {
184
+ throw new Error("Color needs a value");
185
+ } else if (arg instanceof RGBA) {
186
+ this.rgba = arg;
187
+ } else if (arg instanceof HSLA) {
188
+ this._hsla = arg;
189
+ this.rgba = HSLA.toRGBA(arg);
190
+ } else if (arg instanceof HSVA) {
191
+ this._hsva = arg;
192
+ this.rgba = HSVA.toRGBA(arg);
193
+ } else {
194
+ throw new Error("Invalid color ctor argument");
195
+ }
196
+ }
197
+ equals(other) {
198
+ return !!other && RGBA.equals(this.rgba, other.rgba) && HSLA.equals(this.hsla, other.hsla) && HSVA.equals(this.hsva, other.hsva);
199
+ }
200
+ /**
201
+ * http://www.w3.org/TR/WCAG20/#relativeluminancedef
202
+ * Returns the number in the set [0, 1]. O => Darkest Black. 1 => Lightest white.
203
+ */
204
+ getRelativeLuminance() {
205
+ const R = _Color._relativeLuminanceForComponent(this.rgba.r);
206
+ const G = _Color._relativeLuminanceForComponent(this.rgba.g);
207
+ const B = _Color._relativeLuminanceForComponent(this.rgba.b);
208
+ const luminance = 0.2126 * R + 0.7152 * G + 0.0722 * B;
209
+ return roundFloat(luminance, 4);
210
+ }
211
+ static _relativeLuminanceForComponent(color) {
212
+ const c = color / 255;
213
+ return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
214
+ }
215
+ /**
216
+ * http://www.w3.org/TR/WCAG20/#contrast-ratiodef
217
+ * Returns the contrast ration number in the set [1, 21].
218
+ */
219
+ getContrastRatio(another) {
220
+ const lum1 = this.getRelativeLuminance();
221
+ const lum2 = another.getRelativeLuminance();
222
+ return lum1 > lum2 ? (lum1 + 0.05) / (lum2 + 0.05) : (lum2 + 0.05) / (lum1 + 0.05);
223
+ }
224
+ /**
225
+ * http://24ways.org/2010/calculating-color-contrast
226
+ * Return 'true' if darker color otherwise 'false'
227
+ */
228
+ isDarker() {
229
+ const yiq = (this.rgba.r * 299 + this.rgba.g * 587 + this.rgba.b * 114) / 1e3;
230
+ return yiq < 128;
231
+ }
232
+ /**
233
+ * http://24ways.org/2010/calculating-color-contrast
234
+ * Return 'true' if lighter color otherwise 'false'
235
+ */
236
+ isLighter() {
237
+ const yiq = (this.rgba.r * 299 + this.rgba.g * 587 + this.rgba.b * 114) / 1e3;
238
+ return yiq >= 128;
239
+ }
240
+ isLighterThan(another) {
241
+ const lum1 = this.getRelativeLuminance();
242
+ const lum2 = another.getRelativeLuminance();
243
+ return lum1 > lum2;
244
+ }
245
+ isDarkerThan(another) {
246
+ const lum1 = this.getRelativeLuminance();
247
+ const lum2 = another.getRelativeLuminance();
248
+ return lum1 < lum2;
249
+ }
250
+ lighten(factor) {
251
+ return new _Color(new HSLA(this.hsla.h, this.hsla.s, this.hsla.l + this.hsla.l * factor, this.hsla.a));
252
+ }
253
+ darken(factor) {
254
+ return new _Color(new HSLA(this.hsla.h, this.hsla.s, this.hsla.l - this.hsla.l * factor, this.hsla.a));
255
+ }
256
+ transparent(factor) {
257
+ const { r, g, b, a } = this.rgba;
258
+ return new _Color(new RGBA(r, g, b, a * factor));
259
+ }
260
+ isTransparent() {
261
+ return this.rgba.a === 0;
262
+ }
263
+ isOpaque() {
264
+ return this.rgba.a === 1;
265
+ }
266
+ opposite() {
267
+ return new _Color(new RGBA(255 - this.rgba.r, 255 - this.rgba.g, 255 - this.rgba.b, this.rgba.a));
268
+ }
269
+ blend(c) {
270
+ const rgba = c.rgba;
271
+ const thisA = this.rgba.a;
272
+ const colorA = rgba.a;
273
+ const a = thisA + colorA * (1 - thisA);
274
+ if (a < 1e-6) {
275
+ return _Color.TRANSPARENT;
276
+ }
277
+ const r = this.rgba.r * thisA / a + rgba.r * colorA * (1 - thisA) / a;
278
+ const g = this.rgba.g * thisA / a + rgba.g * colorA * (1 - thisA) / a;
279
+ const b = this.rgba.b * thisA / a + rgba.b * colorA * (1 - thisA) / a;
280
+ return new _Color(new RGBA(r, g, b, a));
281
+ }
282
+ flatten(...backgrounds) {
283
+ const background = backgrounds.reduceRight((accumulator, color) => {
284
+ return _Color._flatten(color, accumulator);
285
+ });
286
+ return _Color._flatten(this, background);
287
+ }
288
+ static _flatten(foreground, background) {
289
+ const backgroundAlpha = 1 - foreground.rgba.a;
290
+ return new _Color(new RGBA(
291
+ backgroundAlpha * background.rgba.r + foreground.rgba.a * foreground.rgba.r,
292
+ backgroundAlpha * background.rgba.g + foreground.rgba.a * foreground.rgba.g,
293
+ backgroundAlpha * background.rgba.b + foreground.rgba.a * foreground.rgba.b
294
+ ));
295
+ }
296
+ toString() {
297
+ return "" + _Color.Format.CSS.format(this);
298
+ }
299
+ static getLighterColor(of, relative, factor) {
300
+ if (of.isLighterThan(relative)) {
301
+ return of;
302
+ }
303
+ factor = factor || 0.5;
304
+ const lum1 = of.getRelativeLuminance();
305
+ const lum2 = relative.getRelativeLuminance();
306
+ factor = factor * (lum2 - lum1) / lum2;
307
+ return of.lighten(factor);
308
+ }
309
+ static getDarkerColor(of, relative, factor) {
310
+ if (of.isDarkerThan(relative)) {
311
+ return of;
312
+ }
313
+ factor = factor || 0.5;
314
+ const lum1 = of.getRelativeLuminance();
315
+ const lum2 = relative.getRelativeLuminance();
316
+ factor = factor * (lum1 - lum2) / lum1;
317
+ return of.darken(factor);
318
+ }
319
+ };
320
+ _Color.WHITE = new _Color(new RGBA(255, 255, 255, 1));
321
+ _Color.BLACK = new _Color(new RGBA(0, 0, 0, 1));
322
+ _Color.RED = new _Color(new RGBA(255, 0, 0, 1));
323
+ _Color.BLUE = new _Color(new RGBA(0, 0, 255, 1));
324
+ _Color.GREEN = new _Color(new RGBA(0, 255, 0, 1));
325
+ _Color.CYAN = new _Color(new RGBA(0, 255, 255, 1));
326
+ _Color.LIGHTGREY = new _Color(new RGBA(211, 211, 211, 1));
327
+ _Color.TRANSPARENT = new _Color(new RGBA(0, 0, 0, 0));
328
+ var Color = _Color;
329
+ ((Color2) => {
330
+ let Format;
331
+ ((Format2) => {
332
+ let CSS;
333
+ ((CSS2) => {
334
+ function formatRGB(color) {
335
+ if (color.rgba.a === 1) {
336
+ return `rgb(${color.rgba.r}, ${color.rgba.g}, ${color.rgba.b})`;
337
+ }
338
+ return Color2.Format.CSS.formatRGBA(color);
339
+ }
340
+ CSS2.formatRGB = formatRGB;
341
+ function formatRGBA(color) {
342
+ return `rgba(${color.rgba.r}, ${color.rgba.g}, ${color.rgba.b}, ${+color.rgba.a.toFixed(2)})`;
343
+ }
344
+ CSS2.formatRGBA = formatRGBA;
345
+ function formatHSL(color) {
346
+ if (color.hsla.a === 1) {
347
+ return `hsl(${color.hsla.h}, ${(color.hsla.s * 100).toFixed(2)}%, ${(color.hsla.l * 100).toFixed(2)}%)`;
348
+ }
349
+ return Color2.Format.CSS.formatHSLA(color);
350
+ }
351
+ CSS2.formatHSL = formatHSL;
352
+ function formatHSLA(color) {
353
+ return `hsla(${color.hsla.h}, ${(color.hsla.s * 100).toFixed(2)}%, ${(color.hsla.l * 100).toFixed(2)}%, ${color.hsla.a.toFixed(2)})`;
354
+ }
355
+ CSS2.formatHSLA = formatHSLA;
356
+ function _toTwoDigitHex(n) {
357
+ const r = n.toString(16);
358
+ return r.length !== 2 ? "0" + r : r;
359
+ }
360
+ function formatHex(color) {
361
+ return `#${_toTwoDigitHex(color.rgba.r)}${_toTwoDigitHex(color.rgba.g)}${_toTwoDigitHex(color.rgba.b)}`;
362
+ }
363
+ CSS2.formatHex = formatHex;
364
+ function formatHexA(color, compact = false) {
365
+ if (compact && color.rgba.a === 1) {
366
+ return Color2.Format.CSS.formatHex(color);
367
+ }
368
+ return `#${_toTwoDigitHex(color.rgba.r)}${_toTwoDigitHex(color.rgba.g)}${_toTwoDigitHex(color.rgba.b)}${_toTwoDigitHex(Math.round(color.rgba.a * 255))}`;
369
+ }
370
+ CSS2.formatHexA = formatHexA;
371
+ function format(color) {
372
+ if (!color) {
373
+ return null;
374
+ }
375
+ if (color.isOpaque()) {
376
+ return Color2.Format.CSS.formatHex(color);
377
+ }
378
+ return Color2.Format.CSS.formatRGBA(color);
379
+ }
380
+ CSS2.format = format;
381
+ function parseHex(hex) {
382
+ if (!hex) {
383
+ return null;
384
+ }
385
+ const length = hex.length;
386
+ if (length === 0) {
387
+ return null;
388
+ }
389
+ if (hex.charCodeAt(0) !== 35 /* Hash */) {
390
+ return null;
391
+ }
392
+ if (length === 7) {
393
+ const r = 16 * _parseHexDigit(hex.charCodeAt(1)) + _parseHexDigit(hex.charCodeAt(2));
394
+ const g = 16 * _parseHexDigit(hex.charCodeAt(3)) + _parseHexDigit(hex.charCodeAt(4));
395
+ const b = 16 * _parseHexDigit(hex.charCodeAt(5)) + _parseHexDigit(hex.charCodeAt(6));
396
+ return new Color2(new RGBA(r, g, b, 1));
397
+ }
398
+ if (length === 9) {
399
+ const r = 16 * _parseHexDigit(hex.charCodeAt(1)) + _parseHexDigit(hex.charCodeAt(2));
400
+ const g = 16 * _parseHexDigit(hex.charCodeAt(3)) + _parseHexDigit(hex.charCodeAt(4));
401
+ const b = 16 * _parseHexDigit(hex.charCodeAt(5)) + _parseHexDigit(hex.charCodeAt(6));
402
+ const a = 16 * _parseHexDigit(hex.charCodeAt(7)) + _parseHexDigit(hex.charCodeAt(8));
403
+ return new Color2(new RGBA(r, g, b, a / 255));
404
+ }
405
+ if (length === 4) {
406
+ const r = _parseHexDigit(hex.charCodeAt(1));
407
+ const g = _parseHexDigit(hex.charCodeAt(2));
408
+ const b = _parseHexDigit(hex.charCodeAt(3));
409
+ return new Color2(new RGBA(16 * r + r, 16 * g + g, 16 * b + b));
410
+ }
411
+ if (length === 5) {
412
+ const r = _parseHexDigit(hex.charCodeAt(1));
413
+ const g = _parseHexDigit(hex.charCodeAt(2));
414
+ const b = _parseHexDigit(hex.charCodeAt(3));
415
+ const a = _parseHexDigit(hex.charCodeAt(4));
416
+ return new Color2(new RGBA(16 * r + r, 16 * g + g, 16 * b + b, (16 * a + a) / 255));
417
+ }
418
+ return null;
419
+ }
420
+ CSS2.parseHex = parseHex;
421
+ function _parseHexDigit(charCode) {
422
+ switch (charCode) {
423
+ case 48 /* Digit0 */:
424
+ return 0;
425
+ case 49 /* Digit1 */:
426
+ return 1;
427
+ case 50 /* Digit2 */:
428
+ return 2;
429
+ case 51 /* Digit3 */:
430
+ return 3;
431
+ case 52 /* Digit4 */:
432
+ return 4;
433
+ case 53 /* Digit5 */:
434
+ return 5;
435
+ case 54 /* Digit6 */:
436
+ return 6;
437
+ case 55 /* Digit7 */:
438
+ return 7;
439
+ case 56 /* Digit8 */:
440
+ return 8;
441
+ case 57 /* Digit9 */:
442
+ return 9;
443
+ case 97 /* a */:
444
+ return 10;
445
+ case 65 /* A */:
446
+ return 10;
447
+ case 98 /* b */:
448
+ return 11;
449
+ case 66 /* B */:
450
+ return 11;
451
+ case 99 /* c */:
452
+ return 12;
453
+ case 67 /* C */:
454
+ return 12;
455
+ case 100 /* d */:
456
+ return 13;
457
+ case 68 /* D */:
458
+ return 13;
459
+ case 101 /* e */:
460
+ return 14;
461
+ case 69 /* E */:
462
+ return 14;
463
+ case 102 /* f */:
464
+ return 15;
465
+ case 70 /* F */:
466
+ return 15;
467
+ }
468
+ return 0;
469
+ }
470
+ })(CSS = Format2.CSS || (Format2.CSS = {}));
471
+ })(Format = Color2.Format || (Color2.Format = {}));
472
+ })(Color || (Color = {}));
473
+
474
+ // src/base/common/platform.ts
475
+ var _isWindows = false;
476
+ var _isMacintosh = false;
477
+ var _isLinux = false;
478
+ var _isFreeBSD = false;
479
+ var _isNative = false;
480
+ var _isWeb = false;
481
+ var isElectronRenderer = typeof process !== "undefined" && typeof process.versions !== "undefined" && typeof process.versions.electron !== "undefined" && process.type === "renderer";
482
+ if (typeof navigator === "object" && !isElectronRenderer) {
483
+ const userAgent = navigator.userAgent;
484
+ _isWindows = userAgent.indexOf("Windows") >= 0;
485
+ _isMacintosh = userAgent.indexOf("Macintosh") >= 0;
486
+ _isLinux = userAgent.indexOf("Linux") >= 0;
487
+ _isFreeBSD = userAgent.indexOf("FreeBSD") >= 0;
488
+ _isWeb = true;
489
+ } else if (typeof process === "object") {
490
+ _isWindows = process.platform === "win32";
491
+ _isMacintosh = process.platform === "darwin";
492
+ _isLinux = process.platform === "linux";
493
+ _isFreeBSD = process.platform === "freebsd";
494
+ _isNative = true;
495
+ }
496
+ var _platform = 0 /* Web */;
497
+ if (_isNative) {
498
+ if (_isMacintosh) {
499
+ _platform = 1 /* Mac */;
500
+ } else if (_isWindows) {
501
+ _platform = 4 /* Windows */;
502
+ } else if (_isLinux) {
503
+ _platform = 2 /* Linux */;
504
+ } else if (_isFreeBSD) {
505
+ _platform = 3 /* FreeBSD */;
506
+ }
507
+ }
508
+ var isMacintosh = _isMacintosh;
509
+ var _wl = _isWindows ? 1 /* Windows */ : 3 /* Linux */ | 4 /* FreeBSD */;
510
+
511
+ // src/consts.ts
512
+ var INACTIVE_FOREGROUND_DARK = Color.fromHex("#222222");
513
+ var ACTIVE_FOREGROUND_DARK = Color.fromHex("#333333");
514
+ var INACTIVE_FOREGROUND = Color.fromHex("#EEEEEE");
515
+ var ACTIVE_FOREGROUND = Color.fromHex("#FFFFFF");
516
+ var DEFAULT_ITEM_SELECTOR = Color.fromHex("#0000001F");
517
+ var IS_MAC_BIGSUR_OR_LATER = isMacintosh && parseInt(process.getSystemVersion().split(".")[0]) >= 11;
518
+ var WINDOW_MIN_WIDTH = 400;
519
+ var WINDOW_MIN_HEIGHT = 270;
520
+
521
+ // src/main/attach-titlebar-to-window.ts
522
+ var attachedWindows = /* @__PURE__ */ new WeakMap();
523
+ var attach_titlebar_to_window_default = (browserWindow, options = {}) => {
524
+ const existingDetach = attachedWindows.get(browserWindow);
525
+ if (existingDetach) {
526
+ return existingDetach;
527
+ }
528
+ const [windowWidth, windowHeight] = browserWindow.getSize();
529
+ const minWidth = Number.isFinite(options.minWidth) ? Math.max(0, Math.floor(options.minWidth)) : Math.max(windowWidth, WINDOW_MIN_WIDTH);
530
+ const minHeight = Number.isFinite(options.minHeight) ? Math.max(0, Math.floor(options.minHeight)) : Math.max(windowHeight, WINDOW_MIN_HEIGHT);
531
+ browserWindow.setMinimumSize(minWidth, minHeight);
532
+ const emit = (channel, value) => {
533
+ if (!browserWindow.isDestroyed()) {
534
+ browserWindow.webContents.send(channel, value);
535
+ }
536
+ };
537
+ const onEnterFullScreen = () => emit("window-fullscreen", true);
538
+ const onLeaveFullScreen = () => emit("window-fullscreen", false);
539
+ const onFocus = () => emit("window-focus", true);
540
+ const onBlur = () => emit("window-focus", false);
541
+ const onMaximize = () => emit("window-maximize", true);
542
+ const onUnmaximize = () => emit("window-maximize", false);
543
+ browserWindow.on("enter-full-screen", onEnterFullScreen);
544
+ browserWindow.on("leave-full-screen", onLeaveFullScreen);
545
+ browserWindow.on("focus", onFocus);
546
+ browserWindow.on("blur", onBlur);
547
+ browserWindow.on("maximize", onMaximize);
548
+ browserWindow.on("unmaximize", onUnmaximize);
549
+ const detach = () => {
550
+ browserWindow.removeListener("enter-full-screen", onEnterFullScreen);
551
+ browserWindow.removeListener("leave-full-screen", onLeaveFullScreen);
552
+ browserWindow.removeListener("focus", onFocus);
553
+ browserWindow.removeListener("blur", onBlur);
554
+ browserWindow.removeListener("maximize", onMaximize);
555
+ browserWindow.removeListener("unmaximize", onUnmaximize);
556
+ attachedWindows.delete(browserWindow);
557
+ };
558
+ attachedWindows.set(browserWindow, detach);
559
+ browserWindow.once("closed", detach);
560
+ return detach;
561
+ };
562
+
563
+ // src/main/setup-titlebar.ts
564
+ import {
565
+ BrowserWindow,
566
+ Menu,
567
+ ipcMain
568
+ } from "electron";
569
+
570
+ // src/types/ipc-contract.ts
571
+ var IpcChannels = {
572
+ // Async (invoke/handle)
573
+ GET_WINDOW_MAXIMIZED: "window-event:is-maximized",
574
+ UPDATE_WINDOW_CONTROLS: "update-window-controls",
575
+ REQUEST_MENU_ICON: "menu-icon:request",
576
+ REQUEST_APPLICATION_MENU: "request-application-menu",
577
+ // Fire-and-forget (send/on)
578
+ WINDOW_EVENT: "window-event",
579
+ MENU_EVENT: "menu-event",
580
+ SET_MINIMUM_SIZE: "window-set-minimumSize",
581
+ GET_THEME_CONFIG: "theme-config:get"
582
+ };
583
+
584
+ // src/main/setup-titlebar.ts
585
+ var titlebarSetupDone = false;
586
+ var cachedThemeConfig = null;
587
+ var setup_titlebar_default = () => {
588
+ if (process.type !== "browser") return;
589
+ if (titlebarSetupDone) return;
590
+ titlebarSetupDone = true;
591
+ ipcMain.handle(
592
+ IpcChannels.REQUEST_APPLICATION_MENU,
593
+ async () => JSON.parse(
594
+ JSON.stringify(
595
+ Menu.getApplicationMenu(),
596
+ (key, value) => key !== "commandsMap" && key !== "menu" ? value : void 0
597
+ )
598
+ )
599
+ );
600
+ ipcMain.on(
601
+ IpcChannels.WINDOW_EVENT,
602
+ (event, eventName) => {
603
+ const window = BrowserWindow.fromWebContents(event.sender);
604
+ if (!window) return;
605
+ switch (eventName) {
606
+ case "window-minimize":
607
+ window.minimize();
608
+ break;
609
+ case "window-maximize":
610
+ window.isMaximized() ? window.unmaximize() : window.maximize();
611
+ break;
612
+ case "window-close":
613
+ window.close();
614
+ break;
615
+ }
616
+ }
617
+ );
618
+ ipcMain.on(
619
+ IpcChannels.MENU_EVENT,
620
+ (event, commandId) => {
621
+ const item = getMenuItemByCommandId(commandId, Menu.getApplicationMenu());
622
+ if (item)
623
+ item.click(
624
+ void 0,
625
+ BrowserWindow.fromWebContents(event.sender),
626
+ event.sender
627
+ );
628
+ }
629
+ );
630
+ ipcMain.on(
631
+ IpcChannels.SET_MINIMUM_SIZE,
632
+ (event, width, height) => {
633
+ const window = BrowserWindow.fromWebContents(event.sender);
634
+ if (!window) return;
635
+ const normalizedWidth = Number.isFinite(width) ? Math.max(0, Math.floor(width)) : 0;
636
+ const normalizedHeight = Number.isFinite(height) ? Math.max(0, Math.floor(height)) : 0;
637
+ window.setMinimumSize(normalizedWidth, normalizedHeight);
638
+ }
639
+ );
640
+ ipcMain.handle(
641
+ IpcChannels.REQUEST_MENU_ICON,
642
+ async (event, commandId) => {
643
+ const item = getMenuItemByCommandId(commandId, Menu.getApplicationMenu());
644
+ if (item && item.icon && typeof item.icon !== "string") {
645
+ return item.icon.toDataURL();
646
+ }
647
+ return null;
648
+ }
649
+ );
650
+ ipcMain.handle(
651
+ IpcChannels.GET_WINDOW_MAXIMIZED,
652
+ (event) => {
653
+ const window = BrowserWindow.fromWebContents(event.sender);
654
+ return window ? window.isMaximized() : false;
655
+ }
656
+ );
657
+ ipcMain.handle(
658
+ IpcChannels.UPDATE_WINDOW_CONTROLS,
659
+ (event, args) => {
660
+ return updateWindowControls(event, args);
661
+ }
662
+ );
663
+ ipcMain.on(
664
+ IpcChannels.UPDATE_WINDOW_CONTROLS,
665
+ (event, args) => {
666
+ event.returnValue = updateWindowControls(event, args);
667
+ }
668
+ );
669
+ ipcMain.handle(IpcChannels.GET_THEME_CONFIG, async () => {
670
+ return cachedThemeConfig;
671
+ });
672
+ };
673
+ function setThemeConfig(config) {
674
+ cachedThemeConfig = config;
675
+ }
676
+ function updateWindowControls(event, args) {
677
+ const window = BrowserWindow.fromWebContents(event.sender);
678
+ try {
679
+ if (window) window.setTitleBarOverlay(args);
680
+ return true;
681
+ } catch (_) {
682
+ return false;
683
+ }
684
+ }
685
+ function getMenuItemByCommandId(commandId, menu) {
686
+ if (!menu) return void 0;
687
+ for (const item of menu.items) {
688
+ if (item.submenu) {
689
+ const submenuItem = getMenuItemByCommandId(commandId, item.submenu);
690
+ if (submenuItem) return submenuItem;
691
+ } else if (item.commandId === commandId) return item;
692
+ }
693
+ return void 0;
694
+ }
695
+
696
+ // src/main/index.ts
697
+ import * as fs from "fs/promises";
698
+
699
+ // src/titlebar/theme-config.ts
700
+ var TITLEBAR_THEME_CONFIG_VERSION = 1;
701
+ function asRecord(input) {
702
+ if (!input || typeof input !== "object" || Array.isArray(input)) {
703
+ return null;
704
+ }
705
+ return input;
706
+ }
707
+ function asString(input) {
708
+ if (typeof input !== "string") {
709
+ return void 0;
710
+ }
711
+ const value = input.trim();
712
+ return value.length ? value : void 0;
713
+ }
714
+ function asFiniteNumber(input) {
715
+ if (typeof input !== "number" || !Number.isFinite(input)) {
716
+ return void 0;
717
+ }
718
+ return input;
719
+ }
720
+ function sanitizeColors(input) {
721
+ const source = asRecord(input);
722
+ if (!source) {
723
+ return void 0;
724
+ }
725
+ const colors = {
726
+ titlebar: asString(source.titlebar),
727
+ titlebarForeground: asString(source.titlebarForeground),
728
+ menuBar: asString(source.menuBar),
729
+ menuItemSelection: asString(source.menuItemSelection),
730
+ menuSeparator: asString(source.menuSeparator),
731
+ svg: asString(source.svg)
732
+ };
733
+ const hasAnyColor = !!(colors.titlebar || colors.titlebarForeground || colors.menuBar || colors.menuItemSelection || colors.menuSeparator || colors.svg);
734
+ return hasAnyColor ? colors : void 0;
735
+ }
736
+ function normalizeThemeConfig(input) {
737
+ const warnings = [];
738
+ const source = asRecord(input);
739
+ if (!source) {
740
+ return { config: null, warnings: ["Theme config must be a JSON object."] };
741
+ }
742
+ const requestedVersion = asFiniteNumber(source.version);
743
+ if (requestedVersion !== void 0 && requestedVersion !== TITLEBAR_THEME_CONFIG_VERSION) {
744
+ warnings.push(`Theme config version ${requestedVersion} is not fully supported. Falling back to v${TITLEBAR_THEME_CONFIG_VERSION} compatible fields.`);
745
+ }
746
+ const config = {
747
+ fontFamily: asString(source.fontFamily),
748
+ fontSize: asFiniteNumber(source.fontSize),
749
+ colors: sanitizeColors(source.colors)
750
+ };
751
+ const hasConfig = !!(config.fontFamily || config.fontSize !== void 0 || config.colors);
752
+ if (!hasConfig) {
753
+ return { config: null, warnings: warnings.concat("No supported theme fields found in config.") };
754
+ }
755
+ return { config, warnings };
756
+ }
757
+
758
+ // src/main/index.ts
759
+ async function setupTitlebarAndAttachToWindow(browserWindow, options = {}) {
760
+ if (options.setupGlobal !== false) {
761
+ setup_titlebar_default();
762
+ }
763
+ if (options.themeConfigPath) {
764
+ try {
765
+ const raw = await fs.readFile(options.themeConfigPath, "utf8");
766
+ const parsed = JSON.parse(raw);
767
+ const normalized = normalizeThemeConfig(parsed);
768
+ if (normalized.warnings.length) {
769
+ console.warn(`[custom-electron-titlebar] Theme config from ${options.themeConfigPath}:`, normalized.warnings.join("; "));
770
+ }
771
+ if (normalized.config) {
772
+ setThemeConfig(normalized.config);
773
+ }
774
+ } catch (err) {
775
+ console.error(`[custom-electron-titlebar] Failed to load theme config from ${options.themeConfigPath}:`, err);
776
+ }
777
+ }
778
+ return attach_titlebar_to_window_default(browserWindow, options);
779
+ }
780
+ export {
781
+ attach_titlebar_to_window_default as attachTitlebarToWindow,
782
+ setup_titlebar_default as setupTitlebar,
783
+ setupTitlebarAndAttachToWindow
784
+ };
785
+ //# sourceMappingURL=index.mjs.map