Ejemplo n.º 1
0
        private void ProcessDisplayChanges(ScreenSetupReason reason)
        {
            lock (displaySetupLock)
            {
                IsSettingDisplays = true;

                while (pendingDisplayEvents > 0)
                {
                    if (HaveDisplaysChanged())
                    {
                        DisplaySetup(reason);
                    }
                    else
                    {
                        // if this is only a DPI change, screens will be the same but we still need to reposition
                        RefreshWindows(reason, false);
                        SetDisplayWorkAreas();
                    }

                    pendingDisplayEvents--;
                }

                IsSettingDisplays = false;
            }
        }
Ejemplo n.º 2
0
 private void setScreenProperties(ScreenSetupReason reason)
 {
     // process screen changes if we are on the primary display (or any display in the case of a DPI change, since only the changed display receives that message)
     // and the designated window. suppress this if we are shutting down (which can trigger this method on multi-dpi setups due to window movements)
     if ((Screen.Primary || reason == ScreenSetupReason.DpiChange) && processScreenChanges && !Startup.IsShuttingDown)
     {
         CairoLogger.Instance.Debug("AppBarWindow: Calling screen setup due to " + reason);
         WindowManager.Instance.NotifyDisplayChange(); // update Cairo window list based on new screen setup
     }
 }
Ejemplo n.º 3
0
 private void SetScreenProperties(ScreenSetupReason reason)
 {
     // process screen changes if we are on the primary display and the designated window
     // (or any display in the case of a DPI change, since only the changed display receives that message and not all windows receive it reliably)
     // suppress this if we are shutting down (which can trigger this method on multi-dpi setups due to window movements)
     if (((Screen.Primary && processScreenChanges) || reason == ScreenSetupReason.DpiChange) && !Startup.IsShuttingDown)
     {
         WindowManager.Instance.NotifyDisplayChange(reason); // update Cairo window list based on new screen setup
     }
 }
Ejemplo n.º 4
0
        private void RefreshWindows(ScreenSetupReason reason, bool displaysChanged)
        {
            CairoLogger.Instance.Debug("WindowManager: Refreshing screen information for existing windows");

            // TODO: Handle these as events in respective classes
            // update screens of stale windows
            if (Settings.Instance.EnableMenuBarMultiMon)
            {
                foreach (Screen screen in ScreenState)
                {
                    MenuBar bar = GetScreenWindow(MenuBarWindows, screen);

                    if (bar != null)
                    {
                        bar.Screen = screen;
                        bar.SetScreenPosition();
                    }
                }
            }
            else if (MenuBarWindows.Count > 0)
            {
                MenuBarWindows[0].Screen = Screen.PrimaryScreen;
                MenuBarWindows[0].SetScreenPosition();
            }

            if (Settings.Instance.EnableTaskbarMultiMon)
            {
                foreach (Screen screen in ScreenState)
                {
                    Taskbar bar = GetScreenWindow(TaskbarWindows, screen);

                    if (bar != null)
                    {
                        bar.Screen = screen;
                        bar.SetScreenPosition();
                    }
                }
            }
            else if (TaskbarWindows.Count > 0)
            {
                TaskbarWindows[0].Screen = Screen.PrimaryScreen;
                TaskbarWindows[0].SetScreenPosition();
            }

            // notify event subscribers
            WindowManagerEventArgs args = new WindowManagerEventArgs {
                DisplaysChanged = displaysChanged, Reason = reason
            };

            ScreensChanged?.Invoke(this, args);
        }
Ejemplo n.º 5
0
        public void NotifyDisplayChange(ScreenSetupReason reason)
        {
            CairoLogger.Instance.Debug($"WindowManager: Received {reason} notification");

            if (reason == ScreenSetupReason.DwmChange)
            {
                lock (displaySetupLock)
                {
                    DwmChanged?.Invoke(this, new WindowManagerEventArgs());
                }
            }
            else
            {
                pendingDisplayEvents++;

                if (!IsSettingDisplays)
                {
                    ProcessDisplayChanges(reason);
                }
            }
        }
Ejemplo n.º 6
0
        protected override void SetScreenProperties(ScreenSetupReason reason)
        {
            if (reason == ScreenSetupReason.DpiChange)
            {
                // DPI change is per-monitor, update ourselves
                SetScreenPosition();
                SetLayoutRounding();
                return;
            }

            if (Settings.Instance.ShowMultiMon)
            {
                // Re-create RetroBar windows based on new screen setup
                _windowManager.NotifyDisplayChange(reason);
            }
            else
            {
                // Update window as necessary
                base.SetScreenProperties(reason);
            }
        }
Ejemplo n.º 7
0
        public void NotifyDisplayChange(ScreenSetupReason reason)
        {
            ShellLogger.Debug($"WindowManager: Display change notification received ({reason})");

            if (reason == ScreenSetupReason.DwmChange)
            {
                // RetroBar doesn't care when DWM is toggled
                return;
            }

            _pendingDisplayEvents++;

            if (_isSettingDisplays)
            {
                return;
            }

            _isSettingDisplays = true;

            while (_pendingDisplayEvents > 0)
            {
                // Skip re-opening taskbars if the screens haven't changed
                if (!haveDisplaysChanged())
                {
                    _pendingDisplayEvents--;
                    continue;
                }

                ReopenTaskbars();

                _pendingDisplayEvents--;
            }

            _isSettingDisplays = false;
            ShellLogger.Debug($"WindowManager: Finished processing display events");
        }
Ejemplo n.º 8
0
 protected override void SetScreenProperties(ScreenSetupReason reason)
 {
     _windowManager.NotifyDisplayChange(reason); // update Cairo window list based on new screen setup
 }
Ejemplo n.º 9
0
        /// <summary>
        /// Compares the system screen list to the screens associated with Cairo windows, then creates or destroys windows as necessary.
        /// Runs at startup and when a WM_DEVICECHANGE, WM_DISPLAYCHANGE, or WM_DPICHANGED message is received by the MenuBar window on the primary display.
        /// </summary>
        private void DisplaySetup(ScreenSetupReason reason)
        {
            if (reason != ScreenSetupReason.FirstRun && !hasCompletedInitialDisplaySetup)
            {
                CairoLogger.Instance.Debug("WindowManager: Display setup ran before startup completed, aborting");
                return;
            }

            CairoLogger.Instance.Debug("WindowManager: Beginning display setup");

            List <string> sysScreens     = new List <string>();
            List <string> openScreens    = new List <string>();
            List <string> addedScreens   = new List <string>();
            List <string> removedScreens = new List <string>();

            // update our knowledge of the displays present
            ScreenState = Screen.AllScreens;

            if (reason != ScreenSetupReason.FirstRun)
            {
                // enumerate screens based on currently open windows
                openScreens = GetOpenScreens();

                sysScreens = GetScreenDeviceNames();

                // figure out which screens have been added
                foreach (string name in sysScreens)
                {
                    if (!openScreens.Contains(name))
                    {
                        addedScreens.Add(name);
                    }
                }

                // figure out which screens have been removed
                foreach (string name in openScreens)
                {
                    if (!sysScreens.Contains(name))
                    {
                        removedScreens.Add(name);
                    }
                }

                // abort if we have no screens or if we are removing all screens without adding new ones
                if (sysScreens.Count == 0 || (removedScreens.Count >= openScreens.Count && addedScreens.Count == 0))
                {
                    CairoLogger.Instance.Debug("WindowManager: Aborted due to no displays present");
                    return;
                }

                // close windows associated with removed screens
                ProcessRemovedScreens(removedScreens);

                // refresh existing window screen properties with updated screen information
                RefreshWindows(reason, true);
            }

            // open windows on newly added screens
            ProcessAddedScreens(addedScreens, reason == ScreenSetupReason.FirstRun);

            // update each display's work area if we are shell
            SetDisplayWorkAreas();

            CairoLogger.Instance.Debug("WindowManager: Completed display setup");
        }