diff --git a/SafeExamBrowser.Configuration/ConfigurationData/DataProcessor.cs b/SafeExamBrowser.Configuration/ConfigurationData/DataProcessor.cs
index 4df1819c..45790129 100644
--- a/SafeExamBrowser.Configuration/ConfigurationData/DataProcessor.cs
+++ b/SafeExamBrowser.Configuration/ConfigurationData/DataProcessor.cs
@@ -74,6 +74,11 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
{
settings.Proctoring.WindowVisibility = WindowVisibility.Hidden;
}
+
+ if (settings.Proctoring.Zoom.Enabled && !settings.Proctoring.Zoom.ReceiveVideo)
+ {
+ settings.Proctoring.WindowVisibility = WindowVisibility.Hidden;
+ }
}
private void RemoveLegacyBrowsers(AppSettings settings)
diff --git a/SafeExamBrowser.Proctoring/ProctoringController.cs b/SafeExamBrowser.Proctoring/ProctoringController.cs
index 8ab3c461..f73ab60e 100644
--- a/SafeExamBrowser.Proctoring/ProctoringController.cs
+++ b/SafeExamBrowser.Proctoring/ProctoringController.cs
@@ -185,7 +185,14 @@ namespace SafeExamBrowser.Proctoring
if (settings.WindowVisibility == WindowVisibility.AllowToShow || settings.WindowVisibility == WindowVisibility.Hidden)
{
- window.Hide();
+ if (settings.Zoom.Enabled)
+ {
+ window.HideWithDelay();
+ }
+ else
+ {
+ window.Hide();
+ }
}
IconResource = new XamlIconResource { Uri = new Uri("pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/ProctoringNotification_Active.xaml") };
diff --git a/SafeExamBrowser.UserInterface.Contracts/Proctoring/IProctoringWindow.cs b/SafeExamBrowser.UserInterface.Contracts/Proctoring/IProctoringWindow.cs
index cb1e8ce9..bae9b51f 100644
--- a/SafeExamBrowser.UserInterface.Contracts/Proctoring/IProctoringWindow.cs
+++ b/SafeExamBrowser.UserInterface.Contracts/Proctoring/IProctoringWindow.cs
@@ -15,6 +15,12 @@ namespace SafeExamBrowser.UserInterface.Contracts.Proctoring
///
public interface IProctoringWindow : IWindow
{
+ ///
+ /// First moves the window to the background and then hides it after a timeout. This might be necessary to allow the meeting client to
+ /// finish its initialization work and start the microphone as well as the camera before being hidden.
+ ///
+ void HideWithDelay();
+
///
/// Sets the window title to the given value.
///
diff --git a/SafeExamBrowser.UserInterface.Desktop/Windows/ProctoringWindow.xaml.cs b/SafeExamBrowser.UserInterface.Desktop/Windows/ProctoringWindow.xaml.cs
index 1a554407..7892d226 100644
--- a/SafeExamBrowser.UserInterface.Desktop/Windows/ProctoringWindow.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Desktop/Windows/ProctoringWindow.xaml.cs
@@ -7,6 +7,7 @@
*/
using System.ComponentModel;
+using System.Threading.Tasks;
using System.Windows;
using SafeExamBrowser.UserInterface.Contracts.Proctoring;
using SafeExamBrowser.UserInterface.Contracts.Windows;
@@ -59,6 +60,12 @@ namespace SafeExamBrowser.UserInterface.Desktop.Windows
Dispatcher.Invoke(base.Hide);
}
+ public void HideWithDelay()
+ {
+ Dispatcher.Invoke(() => this.MoveToBackground());
+ Task.Delay(10000).ContinueWith(_ => Hide());
+ }
+
public void SetTitle(string title)
{
Dispatcher.Invoke(() => Title = title ?? "");
diff --git a/SafeExamBrowser.UserInterface.Mobile/Windows/ProctoringWindow.xaml.cs b/SafeExamBrowser.UserInterface.Mobile/Windows/ProctoringWindow.xaml.cs
index cc58b86d..92a39782 100644
--- a/SafeExamBrowser.UserInterface.Mobile/Windows/ProctoringWindow.xaml.cs
+++ b/SafeExamBrowser.UserInterface.Mobile/Windows/ProctoringWindow.xaml.cs
@@ -7,6 +7,7 @@
*/
using System.ComponentModel;
+using System.Threading.Tasks;
using System.Windows;
using SafeExamBrowser.UserInterface.Contracts.Proctoring;
using SafeExamBrowser.UserInterface.Contracts.Windows;
@@ -59,6 +60,12 @@ namespace SafeExamBrowser.UserInterface.Mobile.Windows
Dispatcher.Invoke(base.Hide);
}
+ public void HideWithDelay()
+ {
+ Dispatcher.Invoke(() => this.MoveToBackground());
+ Task.Delay(10000).ContinueWith(_ => Hide());
+ }
+
public void SetTitle(string title)
{
Dispatcher.Invoke(() => Title = title ?? "");
diff --git a/SafeExamBrowser.UserInterface.Shared/Utilities/WindowExtensions.cs b/SafeExamBrowser.UserInterface.Shared/Utilities/WindowExtensions.cs
index 6258af4b..2ba3a97b 100644
--- a/SafeExamBrowser.UserInterface.Shared/Utilities/WindowExtensions.cs
+++ b/SafeExamBrowser.UserInterface.Shared/Utilities/WindowExtensions.cs
@@ -20,8 +20,11 @@ namespace SafeExamBrowser.UserInterface.Shared.Utilities
private const uint MF_GRAYED = 0x00000001;
private const uint MF_ENABLED = 0x00000000;
private const uint SC_CLOSE = 0xF060;
+ private const uint SWP_SHOWWINDOW = 0x0040;
private const int WS_SYSMENU = 0x80000;
+ private static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
+
public static void DisableCloseButton(this Window window)
{
var helper = new WindowInteropHelper(window);
@@ -41,6 +44,17 @@ namespace SafeExamBrowser.UserInterface.Shared.Utilities
SetWindowLong(helper.Handle, GWL_STYLE, style);
}
+ public static void MoveToBackground(this Window window)
+ {
+ var helper = new WindowInteropHelper(window);
+ var x = (int) window.TransformFromPhysical(window.Left, 0).X;
+ var y = (int) window.TransformFromPhysical(0, window.Top).Y;
+ var width = (int) window.TransformFromPhysical(window.Width, 0).X;
+ var height = (int) window.TransformFromPhysical(0, window.Height).Y;
+
+ SetWindowPos(helper.Handle, HWND_BOTTOM, x, y, width, height, SWP_SHOWWINDOW);
+ }
+
[DllImport("user32.dll")]
private static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);
@@ -52,5 +66,8 @@ namespace SafeExamBrowser.UserInterface.Shared.Utilities
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
+
+ [DllImport("user32.dll")]
+ private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
}
}