@@ -39,6 +39,12 @@ public class Manager
39
39
40
40
private static readonly BlockingCollection < ExecutionState > _stateQueue ;
41
41
42
+ // Core icons used for the tray
43
+ private static readonly Icon _timedIcon = new ( Path . Combine ( AppDomain . CurrentDomain . BaseDirectory , "Assets/Awake/timed.ico" ) ) ;
44
+ private static readonly Icon _expirableIcon = new ( Path . Combine ( AppDomain . CurrentDomain . BaseDirectory , "Assets/Awake/expirable.ico" ) ) ;
45
+ private static readonly Icon _indefiniteIcon = new ( Path . Combine ( AppDomain . CurrentDomain . BaseDirectory , "Assets/Awake/indefinite.ico" ) ) ;
46
+ private static readonly Icon _disabledIcon = new ( Path . Combine ( AppDomain . CurrentDomain . BaseDirectory , "Assets/Awake/disabled.ico" ) ) ;
47
+
42
48
private static CancellationTokenSource _tokenSource ;
43
49
44
50
private static SettingsUtils ? _moduleSettings ;
@@ -135,7 +141,7 @@ internal static void SetIndefiniteKeepAwake(bool keepDisplayOn = false)
135
141
136
142
_stateQueue . Add ( ComputeAwakeState ( keepDisplayOn ) ) ;
137
143
138
- TrayHelper . SetShellIcon ( TrayHelper . HiddenWindowHandle , $ "{ Constants . FullAppName } [{ Resources . AWAKE_TRAY_TEXT_INDEFINITE } ]", new Icon ( Path . Combine ( AppDomain . CurrentDomain . BaseDirectory , "Assets/Awake/indefinite.ico" ) ) , TrayIconAction . Update ) ;
144
+ TrayHelper . SetShellIcon ( TrayHelper . HiddenWindowHandle , $ "{ Constants . FullAppName } [{ Resources . AWAKE_TRAY_TEXT_INDEFINITE } ]", _indefiniteIcon , TrayIconAction . Update ) ;
139
145
140
146
if ( IsUsingPowerToysConfig )
141
147
{
@@ -172,14 +178,23 @@ internal static void SetExpirableKeepAwake(DateTimeOffset expireAt, bool keepDis
172
178
Logger . LogInfo ( $ "Starting expirable log for { expireAt } ") ;
173
179
_stateQueue . Add ( ComputeAwakeState ( keepDisplayOn ) ) ;
174
180
175
- TrayHelper . SetShellIcon ( TrayHelper . HiddenWindowHandle , $ "{ Constants . FullAppName } [{ Resources . AWAKE_TRAY_TEXT_EXPIRATION } ]", new Icon ( Path . Combine ( AppDomain . CurrentDomain . BaseDirectory , "Assets/Awake/expirable.ico" ) ) , TrayIconAction . Update ) ;
181
+ TrayHelper . SetShellIcon ( TrayHelper . HiddenWindowHandle , $ "{ Constants . FullAppName } [{ Resources . AWAKE_TRAY_TEXT_EXPIRATION } - { expireAt } ]", _expirableIcon , TrayIconAction . Update ) ;
176
182
177
183
Observable . Timer ( expireAt - DateTimeOffset . Now ) . Subscribe (
178
184
_ =>
179
185
{
180
186
Logger . LogInfo ( $ "Completed expirable keep-awake.") ;
181
187
CancelExistingThread ( ) ;
182
- SetPassiveKeepAwake ( ) ;
188
+
189
+ if ( IsUsingPowerToysConfig )
190
+ {
191
+ SetPassiveKeepAwake ( ) ;
192
+ }
193
+ else
194
+ {
195
+ Logger . LogInfo ( "Exiting after expirable keep awake." ) ;
196
+ CompleteExit ( Environment . ExitCode ) ;
197
+ }
183
198
} ,
184
199
_tokenSource . Token ) ;
185
200
}
@@ -224,16 +239,40 @@ internal static void SetTimedKeepAwake(uint seconds, bool keepDisplayOn = true)
224
239
Logger . LogInfo ( $ "Timed keep awake started for { seconds } seconds.") ;
225
240
_stateQueue . Add ( ComputeAwakeState ( keepDisplayOn ) ) ;
226
241
227
- TrayHelper . SetShellIcon ( TrayHelper . HiddenWindowHandle , $ "{ Constants . FullAppName } [{ Resources . AWAKE_TRAY_TEXT_TIMED } ]", new Icon ( Path . Combine ( AppDomain . CurrentDomain . BaseDirectory , "Assets/Awake/timed.ico" ) ) , TrayIconAction . Update ) ;
242
+ TrayHelper . SetShellIcon ( TrayHelper . HiddenWindowHandle , $ "{ Constants . FullAppName } [{ Resources . AWAKE_TRAY_TEXT_TIMED } ]", _timedIcon , TrayIconAction . Update ) ;
228
243
229
- Observable . Timer ( TimeSpan . FromSeconds ( seconds ) ) . Subscribe (
230
- _ =>
231
- {
232
- Logger . LogInfo ( $ "Completed timed thread.") ;
233
- CancelExistingThread ( ) ;
234
- SetPassiveKeepAwake ( ) ;
235
- } ,
236
- _tokenSource . Token ) ;
244
+ var timerObservable = Observable . Timer ( TimeSpan . FromSeconds ( seconds ) ) ;
245
+ var intervalObservable = Observable . Interval ( TimeSpan . FromSeconds ( 1 ) ) . TakeUntil ( timerObservable ) ;
246
+
247
+ var combinedObservable = Observable . CombineLatest ( intervalObservable , timerObservable . StartWith ( 0 ) , ( elapsedSeconds , _ ) => elapsedSeconds + 1 ) ;
248
+
249
+ combinedObservable . Subscribe (
250
+ elapsedSeconds =>
251
+ {
252
+ var timeRemaining = seconds - ( uint ) elapsedSeconds ;
253
+ if ( timeRemaining >= 0 )
254
+ {
255
+ TrayHelper . SetShellIcon ( TrayHelper . HiddenWindowHandle , $ "{ Constants . FullAppName } [{ Resources . AWAKE_TRAY_TEXT_TIMED } ]\n { TimeSpan . FromSeconds ( timeRemaining ) . ToHumanReadableString ( ) } ", _timedIcon , TrayIconAction . Update ) ;
256
+ }
257
+ } ,
258
+ ( ) =>
259
+ {
260
+ Console . WriteLine ( "Completed timed thread." ) ;
261
+ CancelExistingThread ( ) ;
262
+
263
+ if ( IsUsingPowerToysConfig )
264
+ {
265
+ // If we're using PowerToys settings, we need to make sure that
266
+ // we just switch over the Passive Keep-Awake.
267
+ SetPassiveKeepAwake ( ) ;
268
+ }
269
+ else
270
+ {
271
+ Logger . LogInfo ( "Exiting after timed keep-awake." ) ;
272
+ CompleteExit ( Environment . ExitCode ) ;
273
+ }
274
+ } ,
275
+ _tokenSource . Token ) ;
237
276
238
277
if ( IsUsingPowerToysConfig )
239
278
{
@@ -264,9 +303,7 @@ internal static void SetTimedKeepAwake(uint seconds, bool keepDisplayOn = true)
264
303
/// Performs a clean exit from Awake.
265
304
/// </summary>
266
305
/// <param name="exitCode">Exit code to exit with.</param>
267
- /// <param name="exitSignal">Exit signal tracking the state.</param>
268
- /// <param name="force">Determines whether to force exit and post a quitting message.</param>
269
- internal static void CompleteExit ( int exitCode , ManualResetEvent ? exitSignal , bool force = false )
306
+ internal static void CompleteExit ( int exitCode )
270
307
{
271
308
SetPassiveKeepAwake ( updateSettings : false ) ;
272
309
@@ -277,22 +314,12 @@ internal static void CompleteExit(int exitCode, ManualResetEvent? exitSignal, bo
277
314
278
315
// Close the message window that we used for the tray.
279
316
Bridge . SendMessage ( TrayHelper . HiddenWindowHandle , Native . Constants . WM_CLOSE , 0 , 0 ) ;
280
- }
281
-
282
- if ( force )
283
- {
284
- Bridge . PostQuitMessage ( exitCode ) ;
285
- }
286
317
287
- try
288
- {
289
- exitSignal ? . Set ( ) ;
290
318
Bridge . DestroyWindow ( TrayHelper . HiddenWindowHandle ) ;
291
319
}
292
- catch ( Exception ex )
293
- {
294
- Logger . LogError ( $ "Exit signal error ${ ex } ") ;
295
- }
320
+
321
+ Bridge . PostQuitMessage ( exitCode ) ;
322
+ Environment . Exit ( exitCode ) ;
296
323
}
297
324
298
325
/// <summary>
@@ -350,7 +377,7 @@ internal static void SetPassiveKeepAwake(bool updateSettings = true)
350
377
351
378
CancelExistingThread ( ) ;
352
379
353
- TrayHelper . SetShellIcon ( TrayHelper . HiddenWindowHandle , $ "{ Constants . FullAppName } [{ Resources . AWAKE_TRAY_TEXT_OFF } ]", new Icon ( Path . Combine ( AppDomain . CurrentDomain . BaseDirectory , "Assets/Awake/disabled.ico" ) ) , TrayIconAction . Update ) ;
380
+ TrayHelper . SetShellIcon ( TrayHelper . HiddenWindowHandle , $ "{ Constants . FullAppName } [{ Resources . AWAKE_TRAY_TEXT_OFF } ]", _disabledIcon , TrayIconAction . Update ) ;
354
381
355
382
if ( IsUsingPowerToysConfig && updateSettings )
356
383
{
0 commit comments