@@ -102,42 +102,42 @@ public class Bootstrap implements Runnable {
102
102
private static @ Getter String appUrl ;
103
103
private static @ Getter boolean isDev ;
104
104
105
+ private static volatile boolean isShuttingDown = false ;
106
+
105
107
public static void main (String [] args ) throws Exception {
106
108
System .setProperty ("saucer.java.help.dependencies" , "https://casterlabs.co/caffeinated/dependencies" );
107
109
Bootstrap .class .getClassLoader ().setDefaultAssertionStatus (true );
108
110
109
- SaucerApp .initialize ("co.casterlabs.caffeinated" , () -> {
110
- System .out .println (" > System.out.println(\" Hello World!\" );\n Hello World!\n \n " );
111
+ SaucerApp .initialize ("co.casterlabs.caffeinated" );
112
+ System .out .println (" > System.out.println(\" Hello World!\" );\n Hello World!\n \n " );
111
113
112
- NativeBootstrap nb = null ;
113
- switch (Platform .osDistribution ) {
114
- case LINUX :
115
- nb = new LinuxBootstrap ();
116
- break ;
114
+ NativeBootstrap nb = null ;
115
+ switch (Platform .osDistribution ) {
116
+ case LINUX :
117
+ nb = new LinuxBootstrap ();
118
+ break ;
117
119
118
- case MACOS :
119
- nb = new MacOSBootstrap ();
120
- break ;
120
+ case MACOS :
121
+ nb = new MacOSBootstrap ();
122
+ break ;
121
123
122
- case WINDOWS_NT :
123
- nb = new WindowsBootstrap ();
124
- break ;
124
+ case WINDOWS_NT :
125
+ nb = new WindowsBootstrap ();
126
+ break ;
125
127
126
- default :
127
- break ;
128
- }
128
+ default :
129
+ break ;
130
+ }
129
131
130
- assert nb != null : "Unsupported platform: " + Platform .osDistribution ;
132
+ assert nb != null : "Unsupported platform: " + Platform .osDistribution ;
131
133
132
- try {
133
- nb .init ();
134
- } catch (Exception e ) {
135
- e .printStackTrace ();
136
- SaucerApp .quit ();
137
- }
134
+ try {
135
+ nb .init ();
136
+ } catch (Exception e ) {
137
+ e .printStackTrace ();
138
+ }
138
139
139
- new CommandLine (new Bootstrap ()).execute (args ); // Calls #run()
140
- });
140
+ new CommandLine (new Bootstrap ()).execute (args ); // Calls #run()
141
141
}
142
142
143
143
@ SneakyThrows
@@ -182,14 +182,12 @@ public void onTrigger() {
182
182
}
183
183
}.start ();
184
184
185
- AsyncTask .create (() -> {
186
- try {
187
- this .startApp ();
188
- } catch (Exception e ) {
189
- e .printStackTrace ();
190
- shutdown ();
191
- }
192
- });
185
+ try {
186
+ this .startApp ();
187
+ } catch (Exception e ) {
188
+ e .printStackTrace ();
189
+ shutdown ();
190
+ }
193
191
}
194
192
195
193
private static void writeAppFile (@ NonNull String filename , byte [] bytes ) throws IOException {
@@ -259,25 +257,18 @@ private void startApp() throws Exception {
259
257
260
258
boolean traySupported = TrayHandler .tryCreateTray ();
261
259
262
- SaucerApp .dispatch (() -> {
263
- Saucer .registerCustomScheme ("app" );
264
-
265
- saucer = Saucer .create (preferences );
260
+ Saucer .registerCustomScheme ("app" );
261
+ saucer = Saucer .create (preferences ); // LOCKS HERE?
266
262
267
- saucer .window ().setTitle ("Casterlabs-Caffeinated" );
268
- saucer .bridge ().defineObject ("Caffeinated" , app );
263
+ saucer .window ().setTitle ("Casterlabs-Caffeinated" );
264
+ saucer .bridge ().defineObject ("Caffeinated" , app );
269
265
270
- saucer .webview ().setContextMenuAllowed (false );
266
+ saucer .webview ().setContextMenuAllowed (false );
271
267
272
- saucer .webview ().setSchemeHandler (AppSchemeHandler .INSTANCE );
273
- saucer .webview ().setUrl (appUrl );
268
+ saucer .webview ().setSchemeHandler (AppSchemeHandler .INSTANCE );
269
+ saucer .webview ().setUrl (appUrl );
274
270
275
- saucer .window ().show ();
276
- });
277
-
278
- try {
279
- ReflectionLib .setValue (CaffeinatedApp .getInstance (), "saucer" , saucer );
280
- } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ignored ) {}
271
+ saucer .window ().show ();
281
272
282
273
TrayHandler .updateShowCheckbox (true );
283
274
@@ -337,13 +328,25 @@ public boolean shouldAvoidClosing() {
337
328
}
338
329
});
339
330
340
- logger .info ("Starting app..." );
341
- app .init (traySupported );
331
+ AsyncTask .create (() -> {
332
+ logger .info ("Starting app..." );
333
+ try {
334
+ ReflectionLib .setValue (CaffeinatedApp .getInstance (), "saucer" , saucer );
335
+ app .init (traySupported );
336
+
337
+ // If all of that succeeds, we write a file to let the updater know that
338
+ // everything's okay.
339
+ writeAppFile (".build_ok" , null );
340
+ logger .info ("Everything is running and everything is happy :D" );
341
+ } catch (Throwable t ) {
342
+ logger .severe ("Unable to start the app: %s" , t );
343
+ shutdown ();
344
+ }
345
+ });
342
346
343
- // If all of that succeeds, we write a file to let the updater know that
344
- // everything's okay.
345
- writeAppFile (".build_ok" , null );
346
- logger .info ("Everything is running and everything is happy :D" );
347
+ logger .info ("Calling run() loop..." );
348
+ SaucerApp .run ();
349
+ logger .info ("run() loop exited." );
347
350
}
348
351
349
352
private void onBridgeEvent (String type , JsonObject data ) {
@@ -381,46 +384,50 @@ public static void shutdown() {
381
384
}
382
385
383
386
private static void shutdown (boolean force , boolean relaunch , boolean isReset ) {
384
- if (CaffeinatedApp .getInstance ().canCloseUI () || force ) {
385
- logger .info ("Shutting down." );
387
+ if (!CaffeinatedApp .getInstance ().canCloseUI () && !force ) {
388
+ saucer .window ().focus ();
389
+ }
386
390
387
- // Hide the window IMMEDIATELY.
388
- saucer .window ().hide ();
389
- CaffeinatedApp .getInstance ().getUI ().navigate ("/blank" );
391
+ if (isShuttingDown ) return ;
392
+ isShuttingDown = true ; // Loop prevention.
390
393
391
- // Local Server
394
+ logger .info ("Shutting down." );
395
+
396
+ // Hide the window IMMEDIATELY.
397
+ saucer .window ().hide ();
398
+ CaffeinatedApp .getInstance ().getUI ().navigate ("/blank" );
399
+
400
+ // Local Server
401
+ try {
402
+ localServer .close ();
403
+ } catch (IOException e ) {
404
+ e .printStackTrace ();
405
+ }
406
+
407
+ // App
408
+ CaffeinatedApp .getInstance ().shutdown ();
409
+
410
+ // UI
411
+ TrayHandler .destroy ();
412
+ saucer .close ();
413
+ SaucerApp .quit ();
414
+
415
+ // Exit.
416
+ if (isReset ) {
392
417
try {
393
- localServer .close ();
418
+ Files .walk (new File (CaffeinatedApp .APP_DATA_DIR ).toPath ())
419
+ .sorted (Comparator .reverseOrder ())
420
+ .map (Path ::toFile )
421
+ .forEach (File ::delete );
394
422
} catch (IOException e ) {
395
423
e .printStackTrace ();
396
424
}
425
+ }
397
426
398
- // App
399
- CaffeinatedApp .getInstance ().shutdown ();
400
-
401
- // UI
402
- TrayHandler .destroy ();
403
- saucer .close ();
404
-
405
- // Exit.
406
- if (isReset ) {
407
- try {
408
- Files .walk (new File (CaffeinatedApp .APP_DATA_DIR ).toPath ())
409
- .sorted (Comparator .reverseOrder ())
410
- .map (Path ::toFile )
411
- .forEach (File ::delete );
412
- } catch (IOException e ) {
413
- e .printStackTrace ();
414
- }
415
- }
416
-
417
- if (relaunch ) {
418
- relaunch ();
419
- } else {
420
- System .exit (0 );
421
- }
427
+ if (relaunch ) {
428
+ relaunch ();
422
429
} else {
423
- saucer . window (). focus ( );
430
+ System . exit ( 0 );
424
431
}
425
432
}
426
433
0 commit comments