@domicile-desktop/system-backlight 0.0.0-alpha-5166c4cfb4be → 0.0.0-alpha-477cb1552fdc

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.
@@ -17,6 +17,9 @@ export type BrightnessWatch = {
17
17
  * and comes back is reported again.
18
18
  * - Runs `udevadm` from the compositor's `PATH`. Works while the desktop is
19
19
  * locked.
20
+ * - Runs `udevadm` again under the next compositor when the compositor exits,
21
+ * and reads then. See "A compositor restart" in
22
+ * docs/architecture/ENGINE-FORK.md.
20
23
  */
21
24
  export declare const watchBrightness: (host: WatchHost, onLevel: (level: number) => void, every?: typeof everyInterval) => Promise<Result<BrightnessWatch, SystemError>>;
22
25
  /** Calls `tick` every `ms`, until the returned function is called. */
@@ -23,6 +23,9 @@ const BACKSTOP_MS = 120_000;
23
23
  * and comes back is reported again.
24
24
  * - Runs `udevadm` from the compositor's `PATH`. Works while the desktop is
25
25
  * locked.
26
+ * - Runs `udevadm` again under the next compositor when the compositor exits,
27
+ * and reads then. See "A compositor restart" in
28
+ * docs/architecture/ENGINE-FORK.md.
26
29
  */
27
30
  export const watchBrightness = async (host, onLevel, every = everyInterval) => (await host.spawn(UDEVADM)).map((udevadm) => {
28
31
  const watch = {
@@ -30,17 +33,18 @@ export const watchBrightness = async (host, onLevel, every = everyInterval) => (
30
33
  reading: Promise.resolve(),
31
34
  shown: undefined,
32
35
  stopped: false,
36
+ udevadm,
33
37
  };
34
38
  const reread = () => {
35
- watch.reading = watch.reading.then(() => readOnce(host, watch, udevadm, onLevel));
39
+ watch.reading = watch.reading.then(() => readOnce(host, watch, onLevel));
36
40
  };
37
41
  reread();
38
42
  const stopClock = every(BACKSTOP_MS, reread);
39
43
  return {
40
- ended: ended(udevadm, watch, reread, stopClock),
44
+ ended: ended(host, watch, reread, stopClock),
41
45
  stop: () => {
42
46
  watch.stopped = true;
43
- udevadm.kill();
47
+ watch.udevadm.kill();
44
48
  },
45
49
  };
46
50
  });
@@ -51,13 +55,16 @@ const everyInterval = (ms, tick) => {
51
55
  clearInterval(id);
52
56
  };
53
57
  };
54
- const readOnce = async (host, watch, udevadm, onLevel) => {
58
+ const readOnce = async (host, watch, onLevel) => {
55
59
  const read = await readBacklight(host);
56
60
  if (!watch.stopped && watch.failure === undefined) {
57
61
  read.match({
62
+ // udevadm ends with it, and the read after the next one starts stands in.
58
63
  Err: (error) => {
59
- watch.failure = error;
60
- udevadm.kill();
64
+ if (error.kind !== SystemErrorKind.CompositorGone) {
65
+ watch.failure = error;
66
+ watch.udevadm.kill();
67
+ }
61
68
  },
62
69
  Ok: (backlight) => {
63
70
  const level = backlight.map(levelOf);
@@ -73,14 +80,41 @@ const readOnce = async (host, watch, udevadm, onLevel) => {
73
80
  });
74
81
  }
75
82
  };
76
- /** Reads `udevadm`'s lines until it exits, then says why it did. */
77
- const ended = async (udevadm, watch, reread, stopClock) => {
78
- await eachLine(udevadm.stdout, (line) => {
79
- if (line.startsWith("KERNEL[")) {
80
- reread();
83
+ /**
84
+ * Reads `udevadm`'s lines until it exits, then says why it did. One the
85
+ * compositor took with it is started again.
86
+ */
87
+ const ended = async (host, watch, reread, stopClock) => {
88
+ let exit;
89
+ for (;;) {
90
+ await eachLine(watch.udevadm.stdout, (line) => {
91
+ if (line.startsWith("KERNEL[")) {
92
+ reread();
93
+ }
94
+ });
95
+ exit = await watch.udevadm.exited;
96
+ if (watch.stopped || watch.failure !== undefined || !isGone(exit)) {
97
+ break;
81
98
  }
82
- });
83
- const exit = await udevadm.exited;
99
+ const next = await respawn(host);
100
+ const running = next.match({
101
+ Err: (error) => {
102
+ exit = Err(error);
103
+ return false;
104
+ },
105
+ Ok: (udevadm) => {
106
+ watch.udevadm = udevadm;
107
+ if (watch.stopped) {
108
+ udevadm.kill();
109
+ }
110
+ reread();
111
+ return true;
112
+ },
113
+ });
114
+ if (!running) {
115
+ break;
116
+ }
117
+ }
84
118
  stopClock();
85
119
  await watch.reading;
86
120
  if (watch.failure !== undefined) {
@@ -109,6 +143,19 @@ const eachLine = async (stream, onLine) => {
109
143
  }
110
144
  }
111
145
  };
146
+ /** udevadm under the next compositor, past any that exits before it starts. */
147
+ const respawn = async (host) => {
148
+ for (;;) {
149
+ const next = await host.spawn(UDEVADM);
150
+ if (!isGone(next)) {
151
+ return next;
152
+ }
153
+ }
154
+ };
155
+ const isGone = (answer) => answer.match({
156
+ Err: (error) => error.kind === SystemErrorKind.CompositorGone,
157
+ Ok: () => false,
158
+ });
112
159
  const unexpectedExit = ({ code, signal }) => ({
113
160
  kind: SystemErrorKind.Other,
114
161
  message: code === undefined
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "dependencies": {
3
3
  "@cprussin/option-result": "^2.0.1",
4
- "@domicile-desktop/sdk": "0.0.0-alpha-5166c4cfb4be",
4
+ "@domicile-desktop/sdk": "0.0.0-alpha-477cb1552fdc",
5
5
  "zod": "^4.5.4"
6
6
  },
7
7
  "description": "Screen brightness for a Domicile shell: reads /sys/class/backlight, watches it and sets it through logind, on @domicile-desktop/sdk/system.",
@@ -45,5 +45,5 @@
45
45
  "test:unit": "bun test"
46
46
  },
47
47
  "type": "module",
48
- "version": "0.0.0-alpha-5166c4cfb4be"
48
+ "version": "0.0.0-alpha-477cb1552fdc"
49
49
  }