private void Navigate(int attempts = ScreenCapturePanel.DEFAULT_CAPTURE_MAX_RETRY_ATTEMPTS) { // this is needed for a weird case where this panel has never been made visible before and // the capture timer is asking for capture, without being made visible the WebView will start but // never completes, so we conditionally make this visible to allow the WebView to render which // will unblock its navigation. Action doNavigate = () => { this.logger.Verbose("Navigating to {0} for {1}", this.Location.Text, this.Config.PrettyName); this.SafeViewport.Navigate(this.Location.Text); }; if (!hasBeenVisible && !this.IsVisible) { this.logger.Info("Panel {0} is being asked to navigate, but it is not visible, forcing visibility", this.Config.PrettyName); if (this.requestFocus(this)) { this.hasBeenVisible = true; TimerUtility.RunDelayedAction(() => { this.releaseFocus(this); // now we navigate as usual, navigate completion will acquire its own focus request. doNavigate(); }, TimeSpan.FromMilliseconds(2000)); } else if (attempts > 0) { this.logger.Warn($"Tried to force visibility for Panel {this.Config.PrettyName} but another panel is visible, {attempts} retry attempts remaining..."); TimerUtility.RunDelayedAction(() => this.Navigate(attempts - 1), TimeSpan.FromMilliseconds(2000)); } else { this.logger.Warn($"Tried to force visibility for Panel {this.Config.PrettyName} but another panel is visible, aborting..."); this.CleanupCaptureRun(success: false); } } else { doNavigate(); } }
private void Viewport_NavigationCompletedImpl(int attempts = ScreenCapturePanel.DEFAULT_CAPTURE_MAX_RETRY_ATTEMPTS) { this.logger.Verbose($"running delayed capture with settle time of {this.appConfig.DefaultPageSettleDelay}..."); // we introduce an artificial delay before processing the capture. // this is DUMB!, there's no definitive way to know if the page has "settled". TimerUtility.RunDelayedAction(() => { // note: removed && this.IsVisible() check here, maybe that is necessary? if (this.requestFocus(this)) { // delay one more tick so we give the control time to render TimerUtility.RunSafeDelayedAction(() => { this.HandleScreenCapture(); }, TimeSpan.FromMilliseconds(2000), (error) => { // HandleScreenCapture should be safe. no-op if (this.IsCaptureInProgress) { this.CleanupCaptureRun(success: false); } }); } else if (attempts > 0) { this.logger.Warn($"Panel {this.Config.PrettyName} attempting to perform screen capture, but another panel already is visible, will retry {attempts} attempts..."); // TODO: randomize the retry time? this.Viewport_NavigationCompletedImpl(attempts - 1); } else { // could not get focus or we ran out of attempts this.logger.Error($"Panel {this.Config.PrettyName} failed to get focus after {ScreenCapturePanel.DEFAULT_CAPTURE_MAX_RETRY_ATTEMPTS} attempts"); this.CleanupCaptureRun(success: false); } }, this.appConfig.DefaultPageSettleDelay); }
private void Viewport_NewWindowRequested(object sender, WebViewControlNewWindowRequestedEventArgs e) { this.logger.Info($"New window requested... for {e.Uri}, navigating to location in the current view"); TimerUtility.RunDelayedAction(() => this.SafeViewport.Navigate(e.Uri), TimeSpan.FromMilliseconds(2000)); }