diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 7104d0b3bf2..85852ba57fe 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -56,6 +56,7 @@ "switchToTab", "toggleBorderless", "toggleFullscreen", + "toggleAlwaysOnTop", "find", "setTabColor", "openTabColorPicker", @@ -321,6 +322,11 @@ "additionalProperties": true, "description": "Properties that affect the entire window, regardless of the profile settings.", "properties": { + "alwaysOnTop": { + "default": false, + "description": "When set to true, the window is created on top of all other windows. If multiple windows are all \"always on top\", the most recently focused one will be the topmost", + "type": "boolean" + }, "alwaysShowTabs": { "default": true, "description": "When set to true, tabs are always displayed. When set to false and \"showTabsInTitlebar\" is set to false, tabs only appear after opening a new tab.", diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index f72abe4612d..2868d38d7e4 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1907,6 +1907,9 @@ namespace winrt::TerminalApp::implementation _CreateNewTabFlyout(); } + // Reload the current value of alwaysOnTop from the settings file. This + // will let the user hot-reload this setting, but any runtime changes to + // the alwaysOnTop setting will be lost. _isAlwayOnTop = _settings->GlobalSettings().AlwaysOnTop(); _alwaysOnTopChangedHandlers(*this, nullptr); } @@ -1991,6 +1994,12 @@ namespace winrt::TerminalApp::implementation _UpdateTabView(); } + // Method Description: + // - Toggles always on top mode. Raises our AlwaysOnTopChanged event. + // Arguments: + // - + // Return Value: + // - void TerminalPage::ToggleAlwaysOnTop() { _isAlwayOnTop = !_isAlwayOnTop; @@ -2185,6 +2194,15 @@ namespace winrt::TerminalApp::implementation } } + // Method Description: + // - Returns true if we're currently in "Always on top" mode. When we're in + // always on top mode, the window should be on top of all other windows. + // If multiple windows are all "always on top", they'll maintain their own + // z-order, with all the windows on top of all other non-topmost windows. + // Arguments: + // - + // Return Value: + // - true if we should be in "always on top" mode bool TerminalPage::AlwaysOnTop() const { return _isAlwayOnTop; diff --git a/src/cascadia/TerminalApp/defaults.json b/src/cascadia/TerminalApp/defaults.json index 0be643ad95b..fcb95eafa27 100644 --- a/src/cascadia/TerminalApp/defaults.json +++ b/src/cascadia/TerminalApp/defaults.json @@ -6,6 +6,7 @@ "initialCols": 120, "initialRows": 30, "launchMode": "default", + "alwaysOnTop": false, // Selection "copyOnSelect": false, diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 801acd3aed7..9c579504058 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -464,6 +464,15 @@ void IslandWindow::ToggleFullscreen() _SetIsFullscreen(!_fullscreen); } +// Method Description: +// - Enter or exit the "always on top" state. Before the window is created, this +// value will later be used when we create the window to create the window on +// top of all others. After the window is created, it will either enter the +// group of topmost windows, or exit the group of topmost windows. +// Arguments: +// - alwaysOnTop: whether we should be entering or exiting always on top mode. +// Return Value: +// - void IslandWindow::SetAlwaysOnTop(const bool alwaysOnTop) { _alwaysOnTop = alwaysOnTop; @@ -472,7 +481,7 @@ void IslandWindow::SetAlwaysOnTop(const bool alwaysOnTop) if (hwnd) { const til::rectangle windowPos{ GetWindowRect() }; - SetWindowPos(GetHandle(), + SetWindowPos(hwnd, _alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST, windowPos.left(), windowPos.top(),