@@ -264,7 +264,7 @@ static int callAndWait(long[] ppv, ToIntFunction<IUnknown> callable) {
264
264
phr [0 ] = callable .applyAsInt (completion );
265
265
// "completion" callback may be called asynchronously,
266
266
// so keep processing next OS message that may call it
267
- processOSMessagesUntil (() -> phr [0 ] != COM .S_OK || ppv [0 ] != 0 , Display .getCurrent ());
267
+ processOSMessagesUntil (() -> phr [0 ] != COM .S_OK || ppv [0 ] != 0 , Optional . empty (), Display .getCurrent ());
268
268
completion .Release ();
269
269
return phr [0 ];
270
270
}
@@ -282,7 +282,7 @@ int callAndWait(String[] pstr, ToIntFunction<IUnknown> callable) {
282
282
phr [0 ] = callable .applyAsInt (completion );
283
283
// "completion" callback may be called asynchronously,
284
284
// so keep processing next OS message that may call it
285
- processOSMessagesUntil (() -> phr [0 ] != COM .S_OK || pstr [0 ] != null , browser .getDisplay ());
285
+ processOSMessagesUntil (() -> phr [0 ] != COM .S_OK || pstr [0 ] != null , Optional . empty (), browser .getDisplay ());
286
286
completion .Release ();
287
287
return phr [0 ];
288
288
}
@@ -318,9 +318,8 @@ void releaseWebViews() {
318
318
}
319
319
320
320
class WebViewProvider {
321
-
322
321
private CompletableFuture <WebViewWrapper > webViewWrapperFuture = wakeDisplayAfterFuture (new CompletableFuture <>());
323
- private CompletableFuture <Void > lastWebViewTask = webViewWrapperFuture .thenRun (() -> {});;
322
+ private CompletableFuture <Void > lastWebViewTask = webViewWrapperFuture .thenRun (() -> {});
324
323
325
324
ICoreWebView2 initializeWebView (ICoreWebView2Controller controller ) {
326
325
long [] ppv = new long [1 ];
@@ -333,7 +332,12 @@ ICoreWebView2 initializeWebView(ICoreWebView2Controller controller) {
333
332
webViewWrapper .webView_11 = initializeWebView_11 (webView );
334
333
webViewWrapper .webView_12 = initializeWebView_12 (webView );
335
334
webViewWrapper .webView_13 = initializeWebView_13 (webView );
336
- webViewWrapperFuture .complete (webViewWrapper );
335
+ boolean success = webViewWrapperFuture .complete (webViewWrapper );
336
+ // Release the webViews if the webViewWrapperFuture has already timed out and completed exceptionally
337
+ if (!success && webViewWrapperFuture .isCompletedExceptionally ()) {
338
+ webViewWrapper .releaseWebViews ();
339
+ return null ;
340
+ }
337
341
return webView ;
338
342
}
339
343
@@ -392,13 +396,13 @@ private ICoreWebView2_13 initializeWebView_13(ICoreWebView2 webView) {
392
396
393
397
private WebViewWrapper getWebViewWrapper (boolean waitForPendingWebviewTasksToFinish ) {
394
398
if (waitForPendingWebviewTasksToFinish ) {
395
- processOSMessagesUntil (lastWebViewTask ::isDone , browser .getDisplay ());
399
+ processOSMessagesUntil (lastWebViewTask ::isDone , Optional . empty (), browser .getDisplay ());
396
400
}
397
401
return webViewWrapperFuture .join ();
398
402
}
399
403
400
404
private WebViewWrapper getWebViewWrapper () {
401
- processOSMessagesUntil (webViewWrapperFuture ::isDone , browser .getDisplay ());
405
+ processOSMessagesUntil (webViewWrapperFuture ::isDone , Optional . of (() -> webViewWrapperFuture . completeExceptionally ( createTimeOutException ())), browser .getDisplay ());
402
406
return webViewWrapperFuture .join ();
403
407
}
404
408
@@ -483,7 +487,7 @@ private <T> CompletableFuture<T> wakeDisplayAfterFuture(CompletableFuture<T> fut
483
487
* events for initialization. Thus, this method does not implement an ordinary
484
488
* readAndDispatch loop, but waits for an OS event to be processed.
485
489
*/
486
- private static void processOSMessagesUntil (Supplier <Boolean > condition , Display display ) {
490
+ private static void processOSMessagesUntil (Supplier <Boolean > condition , Optional < Runnable > timeoutHandler , Display display ) {
487
491
MSG msg = new MSG ();
488
492
AtomicBoolean timeoutOccurred = new AtomicBoolean ();
489
493
// The timer call also wakes up the display to avoid being stuck in display.sleep()
@@ -496,10 +500,15 @@ private static void processOSMessagesUntil(Supplier<Boolean> condition, Display
496
500
}
497
501
}
498
502
if (!condition .get ()) {
499
- SWT .error (SWT .ERROR_UNSPECIFIED , null , " Waiting for Edge operation to terminate timed out" );
503
+ timeoutHandler .ifPresent (Runnable ::run );
504
+ throw createTimeOutException ();
500
505
}
501
506
}
502
507
508
+ private static SWTException createTimeOutException () {
509
+ return new SWTException (SWT .ERROR_UNSPECIFIED , " Waiting for Edge operation to terminate timed out" );
510
+ }
511
+
503
512
static ICoreWebView2CookieManager getCookieManager () {
504
513
WebViewEnvironment environmentWrapper = webViewEnvironments .get (Display .getCurrent ());
505
514
if (environmentWrapper == null ) {
@@ -641,7 +650,10 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
641
650
switch (result ) {
642
651
case COM .S_OK :
643
652
new IUnknown (pv ).AddRef ();
644
- setupBrowser (result , pv );
653
+ boolean success = setupBrowser (result , pv );
654
+ if (!success ) {
655
+ initializationRollback .run ();
656
+ }
645
657
break ;
646
658
case COM .E_WRONG_THREAD :
647
659
initializationAbortion .run ();
@@ -665,10 +677,13 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
665
677
});
666
678
}
667
679
668
- void setupBrowser (int hr , long pv ) {
680
+ boolean setupBrowser (int hr , long pv ) {
669
681
long [] ppv = new long [] {pv };
670
682
controller = new ICoreWebView2Controller (ppv [0 ]);
671
683
final ICoreWebView2 webView = webViewProvider .initializeWebView (controller );
684
+ if (webView == null ) {
685
+ return false ;
686
+ }
672
687
webView .get_Settings (ppv );
673
688
settings = new ICoreWebView2Settings (ppv [0 ]);
674
689
@@ -768,6 +783,7 @@ void setupBrowser(int hr, long pv) {
768
783
if (browser .isFocusControl ()) {
769
784
browserFocusIn (new Event ());
770
785
}
786
+ return true ;
771
787
}
772
788
773
789
void browserDispose (Event event ) {
0 commit comments