terminal/src/cascadia/TerminalApp/GlobalAppSettings.h
Kaiyu Wang 35d7d20a07 Enable setting an initial position and maximized launch (#2817)
This PR includes the code changes that enable users to set an initial position
(top left corner) and launch maximized. There are some corner cases:

1. Multiple monitors. The user should be able to set the initial position to
any monitors attached. For the monitors on the left side of the major monitor,
the initial position values are negative.

2. If the initial position is larger than the screen resolution and the window
is off-screen, the current solution is to check if the top left corner of the
window intersect with any monitors. If it is not, we set the initial position
to the top left corner of the nearest monitor.

3. If the user wants to launch maximized and provides an initial position, we
launch the maximized window on the monitor where the position is located.

# Testing

To test:
1. Check-out this branch and build on VS2019
2. Launch Terminal, and open Settings. Then close the terminal.
3. Add the following setting into Json settings file as part of "globals", just
after "initialRows":
  "initialPosition": "1000, 1000",
  "launchMode": "default"

My test data:
I have already tested with the following variables:
  1. showTabsInTitlebar true or false
  2. The initial position of the top left corner of the window
  3. Whether to launch maximized
  4. The DPI of the monitor

Test data combination:

Non-client island window (showTabsInTitlebar true)

1. Three monitors with the same DPI (100%), left, middle and right, with the
middle one as the primary, resolution: 1980 * 1200, 1920 * 1200, 1920 * 1080
    launchMode: default
      In-Screen test: (0, 0), (1000, 500), (2000, 300), (-1000, 400),
        (-100, 200), (-2000, 100), (0, 1119)
      out-of-screen:
        (200, -200): initialize to (0, 0)
        (200, 1500): initialize to (0, 0)
        (2000, -200): initialize to (1920, 0)
        (2500, 2000): initialize to (1920, 0)
        (4000 100): initialize to (1920, 0)
        (-1000, -100): initialize to (-1920, 0)
        (-3000, 100): initialize to (-1920, 0)
        (10000, -10000): initialize to (1920, 0)
        (-10000, 10000): initialize to (-1920, 0)
        (0, -10000): initialize to (0, 0)
        (0, -1):  initialize to (0, 0)
        (0, 1200):  initialize to (0, 0)
    launch mode: maximize
        (100, 100)
        (-1000, 100): On the left monitor
        (0, -2000): On the primary monitor
        (10000, 10000): On the primary monitor


2. Left monitor 200% DPI, primary monitor 100% DPI
    In screen: (-1900, 100), (-3000, 100), (-1000, 100)
    our-of-screen: (-8000, 100): initialize at (-1920, 0)
    launch Maximized:  (-100, 100): launch maximized on the left monitor
      correctly

3. Left monitor 100% DPI, primary monitor 200% DPI
    In-screen: (-1900, 100), (300, 100), (-800, 100), (-200, 100)
    out-of-screen: (-3000, 100): initialize at (-1920, 0)
    launch maximized: (100, 100), (-1000, 100)

For client island window, the test data is the same as above.

Issues:

1. If we set the initial position on the monitor with a different DPI as the
primary monitor, and the window "lays" across two monitors, then the window
still renders as it is on the primary monitor. The size of the window is
correct.

Closes #1043
2019-10-16 21:51:50 -07:00

118 lines
3.9 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- CascadiaSettings.hpp
Abstract:
- This class encapsulates all of the settings that are global to the app, and
not a part of any particular profile.
Author(s):
- Mike Griese - March 2019
--*/
#pragma once
#include "AppKeyBindings.h"
#include "ColorScheme.h"
// fwdecl unittest classes
namespace TerminalAppLocalTests
{
class SettingsTests;
class ColorSchemeTests;
};
namespace TerminalApp
{
class GlobalAppSettings;
};
class TerminalApp::GlobalAppSettings final
{
public:
GlobalAppSettings();
~GlobalAppSettings();
std::unordered_map<std::wstring, ColorScheme>& GetColorSchemes() noexcept;
const std::unordered_map<std::wstring, ColorScheme>& GetColorSchemes() const noexcept;
void AddColorScheme(ColorScheme scheme);
void SetDefaultProfile(const GUID defaultProfile) noexcept;
GUID GetDefaultProfile() const noexcept;
winrt::TerminalApp::AppKeyBindings GetKeybindings() const noexcept;
bool GetAlwaysShowTabs() const noexcept;
void SetAlwaysShowTabs(const bool showTabs) noexcept;
bool GetShowTitleInTitlebar() const noexcept;
void SetShowTitleInTitlebar(const bool showTitleInTitlebar) noexcept;
void SetRequestedTheme(const winrt::Windows::UI::Xaml::ElementTheme requestedTheme) noexcept;
bool GetShowTabsInTitlebar() const noexcept;
void SetShowTabsInTitlebar(const bool showTabsInTitlebar) noexcept;
std::wstring GetWordDelimiters() const noexcept;
void SetWordDelimiters(const std::wstring wordDelimiters) noexcept;
bool GetCopyOnSelect() const noexcept;
void SetCopyOnSelect(const bool copyOnSelect) noexcept;
std::optional<int32_t> GetInitialX() const noexcept;
std::optional<int32_t> GetInitialY() const noexcept;
winrt::TerminalApp::LaunchMode GetLaunchMode() const noexcept;
void SetLaunchMode(const winrt::TerminalApp::LaunchMode launchMode);
winrt::Windows::UI::Xaml::ElementTheme GetRequestedTheme() const noexcept;
Json::Value ToJson() const;
static GlobalAppSettings FromJson(const Json::Value& json);
void LayerJson(const Json::Value& json);
void ApplyToSettings(winrt::Microsoft::Terminal::Settings::TerminalSettings& settings) const noexcept;
private:
GUID _defaultProfile;
winrt::com_ptr<winrt::TerminalApp::implementation::AppKeyBindings> _keybindings;
std::unordered_map<std::wstring, ColorScheme> _colorSchemes;
int32_t _initialRows;
int32_t _initialCols;
std::optional<int32_t> _initialX;
std::optional<int32_t> _initialY;
bool _showStatusline;
bool _alwaysShowTabs;
bool _showTitleInTitlebar;
bool _showTabsInTitlebar;
std::wstring _wordDelimiters;
bool _copyOnSelect;
winrt::Windows::UI::Xaml::ElementTheme _requestedTheme;
winrt::TerminalApp::LaunchMode _launchMode;
static winrt::Windows::UI::Xaml::ElementTheme _ParseTheme(const std::wstring& themeString) noexcept;
static std::wstring_view _SerializeTheme(const winrt::Windows::UI::Xaml::ElementTheme theme) noexcept;
static void _ParseInitialPosition(const std::wstring& initialPosition,
std::optional<int32_t>& initialX,
std::optional<int32_t>& initialY) noexcept;
static std::string _SerializeInitialPosition(const std::optional<int32_t>& initialX,
const std::optional<int32_t>& initialY) noexcept;
static std::wstring_view _SerializeLaunchMode(const winrt::TerminalApp::LaunchMode launchMode) noexcept;
static winrt::TerminalApp::LaunchMode _ParseLaunchMode(const std::wstring& launchModeString) noexcept;
friend class TerminalAppLocalTests::SettingsTests;
friend class TerminalAppLocalTests::ColorSchemeTests;
};