/// <summary> /// Compares the system screen list to the screens associated with Cairo windows, then creates or destroys windows as necessary. /// Only affects non-primary screens, as Cairo always opens on at least the primary screen. /// Runs at startup and when a WM_DISPLAYCHANGE message is received by the main MenuBar window. /// </summary> public static void ScreenSetup(bool skipChecks = false) { lock (screenSetupLock) { IsSettingScreens = true; List <string> sysScreens = new List <string>(); List <string> openScreens = new List <string>(); List <string> addedScreens = new List <string>(); List <string> removedScreens = new List <string>(); ResetScreenCache(); if (!skipChecks) { // enumerate screens if (Settings.EnableMenuBarMultiMon || !Settings.EnableTaskbar) { foreach (MenuBar bar in MenuBarWindows) { if (bar.Screen != null) { openScreens.Add(bar.Screen.DeviceName); } } } else if (Settings.EnableTaskbarMultiMon) { foreach (Taskbar bar in TaskbarWindows) { if (bar.Screen != null) { openScreens.Add(bar.Screen.DeviceName); } } } else { return; } foreach (var screen in System.Windows.Forms.Screen.AllScreens) { Trace.WriteLine(string.Format("{0} found at {1} with area {2}; primary? {3}", screen.DeviceName, screen.Bounds.ToString(), screen.WorkingArea.ToString(), screen.Primary.ToString())); sysScreens.Add(screen.DeviceName); } // figure out which screens have been added vs removed foreach (string name in sysScreens) { if (!openScreens.Contains(name)) { addedScreens.Add(name); } } foreach (string name in openScreens) { if (!sysScreens.Contains(name)) { removedScreens.Add(name); } } if (removedScreens.Count == sysScreens.Count) { // remove everything?! no way! return; } // close windows associated with removed screens foreach (string name in removedScreens) { // close taskbars Taskbar taskbarToClose = null; foreach (Taskbar bar in TaskbarWindows) { if (bar.Screen != null && bar.Screen.DeviceName == name) { taskbarToClose = bar; break; } } if (taskbarToClose != null) { taskbarToClose.Close(); TaskbarWindows.Remove(taskbarToClose); } // close menu bars MenuBar barToClose = null; foreach (MenuBar bar in MenuBarWindows) { if (bar.Screen != null && bar.Screen.DeviceName == name) { barToClose = bar; break; } } if (barToClose != null) { if (!barToClose.IsClosing) { barToClose.Close(); } MenuBarWindows.Remove(barToClose); } // close menu bar shadows MenuBarShadow barShadowToClose = null; foreach (MenuBarShadow bar in MenuBarShadowWindows) { if (bar.Screen != null && bar.Screen.DeviceName == name) { barShadowToClose = bar; break; } } if (barShadowToClose != null) { if (!barShadowToClose.IsClosing) { barShadowToClose.Close(); } MenuBarShadowWindows.Remove(barShadowToClose); } } // update screens of stale windows foreach (MenuBar bar in MenuBarWindows) { if (bar.Screen != null) { foreach (System.Windows.Forms.Screen screen in System.Windows.Forms.Screen.AllScreens) { if (screen.DeviceName == bar.Screen.DeviceName) { bar.Screen = screen; break; } } } } foreach (MenuBarShadow bar in MenuBarShadowWindows) { if (bar.Screen != null) { foreach (System.Windows.Forms.Screen screen in System.Windows.Forms.Screen.AllScreens) { if (screen.DeviceName == bar.Screen.DeviceName) { bar.Screen = screen; break; } } } } foreach (Taskbar bar in TaskbarWindows) { if (bar.Screen != null) { foreach (System.Windows.Forms.Screen screen in System.Windows.Forms.Screen.AllScreens) { if (screen.DeviceName == bar.Screen.DeviceName) { bar.Screen = screen; bar.setPosition(); break; } } } } } // open windows on newly added screens foreach (var screen in System.Windows.Forms.Screen.AllScreens) { if ((skipChecks && !screen.Primary) || addedScreens.Contains(screen.DeviceName)) { if (Settings.EnableMenuBarMultiMon) { // menu bars MenuBar newMenuBar = new MenuBar(screen); newMenuBar.Show(); MenuBarWindows.Add(newMenuBar); if (Settings.EnableMenuBarShadow) { // menu bar shadows MenuBarShadow newMenuBarShadow = new MenuBarShadow(newMenuBar, screen); newMenuBarShadow.Show(); MenuBarShadowWindows.Add(newMenuBarShadow); } } if (Settings.EnableTaskbarMultiMon && Settings.EnableTaskbar) { // taskbars Taskbar newTaskbar = new Taskbar(screen); newTaskbar.Show(); TaskbarWindows.Add(newTaskbar); } } // Set desktop work area for when Explorer isn't running if (IsCairoUserShell) { AppBarHelper.SetWorkArea(screen); } } IsSettingScreens = false; } }
/// <summary> /// Compares the system screen list to the screens associated with Cairo windows, then creates or destroys windows as necessary. /// Only affects non-primary screens, as Cairo always opens on at least the primary screen. /// Runs at startup and when a WM_DISPLAYCHANGE message is received by the main MenuBar window. /// </summary> public static void ScreenSetup(bool skipChecks = false) { lock (screenSetupLock) { CairoLogger.Instance.Debug("Beginning screen setup"); IsSettingScreens = true; bool shouldSetScreens = true; List <string> sysScreens = new List <string>(); List <string> openScreens = new List <string>(); List <string> addedScreens = new List <string>(); List <string> removedScreens = new List <string>(); ResetScreenCache(); if (screenState.Length == System.Windows.Forms.Screen.AllScreens.Length) { bool same = true; for (int i = 0; i < screenState.Length; i++) { System.Windows.Forms.Screen current = System.Windows.Forms.Screen.AllScreens[i]; if (!(screenState[i].Bounds == current.Bounds && screenState[i].DeviceName == current.DeviceName && screenState[i].Primary == current.Primary && screenState[i].WorkingArea == current.WorkingArea)) { same = false; break; } } if (same) { CairoLogger.Instance.Debug("Skipping screen setup due to no differences"); shouldSetScreens = false; } else { screenState = System.Windows.Forms.Screen.AllScreens; } } else { screenState = System.Windows.Forms.Screen.AllScreens; } if (shouldSetScreens) { if (!skipChecks) { // enumerate screens if (Settings.EnableMenuBarMultiMon || !Settings.EnableTaskbar) { foreach (MenuBar bar in MenuBarWindows) { if (bar.Screen != null) { openScreens.Add(bar.Screen.DeviceName); } } } else if (Settings.EnableTaskbarMultiMon) { foreach (Taskbar bar in TaskbarWindows) { if (bar.Screen != null) { openScreens.Add(bar.Screen.DeviceName); } } } else { return; } foreach (var screen in screenState) { CairoLogger.Instance.Debug(string.Format("{0} found at {1} with area {2}; primary? {3}", screen.DeviceName, screen.Bounds.ToString(), screen.WorkingArea.ToString(), screen.Primary.ToString())); sysScreens.Add(screen.DeviceName); } // figure out which screens have been added vs removed foreach (string name in sysScreens) { if (!openScreens.Contains(name)) { addedScreens.Add(name); } } foreach (string name in openScreens) { if (!sysScreens.Contains(name)) { removedScreens.Add(name); } } if (removedScreens.Count == sysScreens.Count) { // remove everything?! no way! return; } // close windows associated with removed screens foreach (string name in removedScreens) { CairoLogger.Instance.Debug("Removing windows associated with screen " + name); // close taskbars Taskbar taskbarToClose = null; foreach (Taskbar bar in TaskbarWindows) { if (bar.Screen != null && bar.Screen.DeviceName == name) { taskbarToClose = bar; break; } } if (taskbarToClose != null) { taskbarToClose.Close(); TaskbarWindows.Remove(taskbarToClose); } // close menu bars MenuBar barToClose = null; foreach (MenuBar bar in MenuBarWindows) { if (bar.Screen != null && bar.Screen.DeviceName == name) { CairoLogger.Instance.DebugIf(bar.Screen.Primary, "Closing menu bar on primary display"); barToClose = bar; break; } } if (barToClose != null) { if (!barToClose.IsClosing) { barToClose.Close(); } MenuBarWindows.Remove(barToClose); } // close menu bar shadows MenuBarShadow barShadowToClose = null; foreach (MenuBarShadow bar in MenuBarShadowWindows) { if (bar.Screen != null && bar.Screen.DeviceName == name) { barShadowToClose = bar; break; } } if (barShadowToClose != null) { if (!barShadowToClose.IsClosing) { barShadowToClose.Close(); } MenuBarShadowWindows.Remove(barShadowToClose); } } CairoLogger.Instance.Debug("Refreshing screen information for stale windows"); // update screens of stale windows foreach (MenuBar bar in MenuBarWindows) { if (bar.Screen != null) { foreach (System.Windows.Forms.Screen screen in screenState) { if (screen.DeviceName == bar.Screen.DeviceName) { bar.Screen = screen; break; } } } } foreach (MenuBarShadow bar in MenuBarShadowWindows) { if (bar.Screen != null) { foreach (System.Windows.Forms.Screen screen in screenState) { if (screen.DeviceName == bar.Screen.DeviceName) { bar.Screen = screen; break; } } } } foreach (Taskbar bar in TaskbarWindows) { if (bar.Screen != null) { foreach (System.Windows.Forms.Screen screen in screenState) { if (screen.DeviceName == bar.Screen.DeviceName) { bar.Screen = screen; bar.setPosition(); break; } } } } } // open windows on newly added screens foreach (var screen in screenState) { if ((skipChecks && !screen.Primary) || addedScreens.Contains(screen.DeviceName)) { CairoLogger.Instance.Debug("Opening windows on screen " + screen.DeviceName); if (Settings.EnableMenuBarMultiMon) { CairoLogger.Instance.DebugIf(screen.Primary, "Opening MenuBar on new primary display"); // menu bars MenuBar newMenuBar = new MenuBar(screen); newMenuBar.Show(); MenuBarWindows.Add(newMenuBar); if (Settings.EnableMenuBarShadow) { // menu bar shadows MenuBarShadow newMenuBarShadow = new MenuBarShadow(newMenuBar, screen); newMenuBarShadow.Show(); MenuBarShadowWindows.Add(newMenuBarShadow); } } if (Settings.EnableTaskbarMultiMon && Settings.EnableTaskbar) { // taskbars Taskbar newTaskbar = new Taskbar(screen); newTaskbar.Show(); TaskbarWindows.Add(newTaskbar); } } // Set desktop work area for when Explorer isn't running if (IsCairoUserShell) { AppBarHelper.SetWorkArea(screen); } } } IsSettingScreens = false; CairoLogger.Instance.Debug("Completed screen setup"); } }