smooth like butter

This commit is contained in:
Leon Liang 2021-06-07 15:30:15 -07:00
parent b90f0aaec5
commit f82cffa42f
19 changed files with 100 additions and 23 deletions

View file

@ -762,4 +762,14 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
}
}
Windows::Foundation::Collections::IMap<uint64_t, winrt::hstring> Monarch::GetPeasantNames()
{
auto names = winrt::single_threaded_map<uint64_t, winrt::hstring>();
for (auto [key, value] : _peasants)
{
names.Insert(key, value.WindowName());
}
return names;
}
}

View file

@ -51,6 +51,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
void HandleActivatePeasant(const winrt::Microsoft::Terminal::Remoting::WindowActivatedArgs& args);
void SummonWindow(const Remoting::SummonWindowSelectionArgs& args);
Windows::Foundation::Collections::IMap<uint64_t, winrt::hstring> GetPeasantNames();
TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs);
private:

View file

@ -40,6 +40,8 @@ namespace Microsoft.Terminal.Remoting
void HandleActivatePeasant(WindowActivatedArgs args);
void SummonWindow(SummonWindowSelectionArgs args);
Windows.Foundation.Collections.IMap<UInt64, String> GetPeasantNames();
event Windows.Foundation.TypedEventHandler<Object, FindTargetWindowArgs> FindTargetWindowRequested;
};
}

View file

@ -30,6 +30,12 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
void Peasant::AssignID(uint64_t id)
{
_id = id;
// Provide a default name if we're currently unnamed.
if (_WindowName.empty())
{
_WindowName = fmt::format(L"Window {}", _id);
}
}
uint64_t Peasant::GetID()
{

View file

@ -274,7 +274,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
p->AssignID(givenID.value());
}
// If the name wasn't specified, this will be an empty string.
p->WindowName(givenName);
_peasant = *p;
@ -509,4 +508,10 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
_monarch.SummonWindow(args);
}
Windows::Foundation::Collections::IMap<uint64_t, winrt::hstring> WindowManager::GetPeasantNames()
{
assert(_monarch);
return _monarch.GetPeasantNames();
}
}

View file

@ -40,6 +40,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
bool IsMonarch();
void SummonWindow(const Remoting::SummonWindowSelectionArgs& args);
Windows::Foundation::Collections::IMap<uint64_t, winrt::hstring> GetPeasantNames();
TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs);
TYPED_EVENT(BecameMonarch, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);

View file

@ -12,6 +12,7 @@ namespace Microsoft.Terminal.Remoting
IPeasant CurrentWindow();
Boolean IsMonarch { get; };
void SummonWindow(SummonWindowSelectionArgs args);
Windows.Foundation.Collections.IMap<UInt64, String> GetPeasantNames();
event Windows.Foundation.TypedEventHandler<Object, FindTargetWindowArgs> FindTargetWindowRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> BecameMonarch;
};

View file

@ -815,4 +815,11 @@ namespace winrt::TerminalApp::implementation
}
}
}
void TerminalPage::_HandleMinimizeToTray(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
_MinimizeToTrayRequestedHandlers(*this, nullptr);
args.Handled(true);
}
}

View file

@ -166,6 +166,7 @@ namespace winrt::TerminalApp::implementation
FORWARDED_TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs, _root, RenameWindowRequested);
FORWARDED_TYPED_EVENT(IsQuakeWindowChanged, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, IsQuakeWindowChanged);
FORWARDED_TYPED_EVENT(SummonWindowRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, SummonWindowRequested);
FORWARDED_TYPED_EVENT(MinimizeToTrayRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, MinimizeToTrayRequested);
#ifdef UNIT_TESTING
friend class TerminalAppLocalTests::CommandlineTest;

View file

@ -93,5 +93,6 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<Object, Object> SettingsChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> IsQuakeWindowChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> SummonWindowRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> MinimizeToTrayRequested;
}
}

View file

@ -125,6 +125,7 @@ namespace winrt::TerminalApp::implementation
TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs);
TYPED_EVENT(IsQuakeWindowChanged, IInspectable, IInspectable);
TYPED_EVENT(SummonWindowRequested, IInspectable, IInspectable);
TYPED_EVENT(MinimizeToTrayRequested, IInspectable, IInspectable);
private:
friend struct TerminalPageT<TerminalPage>; // for Xaml to bind events

View file

@ -57,5 +57,6 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<Object, RenameWindowRequestedArgs> RenameWindowRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> IsQuakeWindowChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> SummonWindowRequested;
event Windows.Foundation.TypedEventHandler<Object, Object> MinimizeToTrayRequested;
}
}

View file

@ -61,6 +61,7 @@ static constexpr std::string_view OpenWindowRenamerKey{ "openWindowRenamer" };
static constexpr std::string_view GlobalSummonKey{ "globalSummon" };
static constexpr std::string_view QuakeModeKey{ "quakeMode" };
static constexpr std::string_view FocusPaneKey{ "focusPane" };
static constexpr std::string_view MinimizeToTrayKey{ "minimizeToTray" };
static constexpr std::string_view ActionKey{ "action" };
@ -330,6 +331,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{ ShortcutAction::GlobalSummon, L"" }, // Intentionally omitted, must be generated by GenerateName
{ ShortcutAction::QuakeMode, RS_(L"QuakeModeCommandKey") },
{ ShortcutAction::FocusPane, L"" }, // Intentionally omitted, must be generated by GenerateName
{ ShortcutAction::MinimizeToTray, RS_(L"MinimizeToTrayCommandKey") },
};
}();

View file

@ -75,7 +75,8 @@
ON_ALL_ACTIONS(OpenWindowRenamer) \
ON_ALL_ACTIONS(GlobalSummon) \
ON_ALL_ACTIONS(QuakeMode) \
ON_ALL_ACTIONS(FocusPane)
ON_ALL_ACTIONS(FocusPane) \
ON_ALL_ACTIONS(MinimizeToTray)
#define ALL_SHORTCUT_ACTIONS_WITH_ARGS \
ON_ALL_ACTIONS_WITH_ARGS(AdjustFontSize) \

View file

@ -413,4 +413,7 @@
<value>Windows Console Host</value>
<comment>Name describing the usage of the classic windows console as the terminal UI. (`conhost.exe`)</comment>
</data>
<data name="MinimizeToTrayCommandKey" xml:space="preserve">
<value>Minimize window to tray</value>
</data>
</root>

View file

@ -79,15 +79,11 @@ AppHost::AppHost() noexcept :
_window->WindowActivated({ this, &AppHost::_WindowActivated });
_window->HotkeyPressed({ this, &AppHost::_GlobalHotkeyPressed });
_window->NotifyTrayIconPressed({ this, &AppHost::_HandleTrayIconPressed });
_window->NotifyShowTrayContextMenu({this, &AppHost::_CreateTrayContextMenu });
_window->NotifyShowTrayContextMenu({this, &AppHost::_ShowTrayContextMenu });
_window->NotifyTrayMenuItemSelected({this, &AppHost::_TrayMenuItemSelected });
_window->SetAlwaysOnTop(_logic.GetInitialAlwaysOnTop());
_window->MakeWindow();
if (_window->IsQuakeWindow())
{
_UpdateTrayIcon();
}
_windowManager.BecameMonarch({ this, &AppHost::_BecomeMonarch });
if (_windowManager.IsMonarch())
{
@ -275,6 +271,7 @@ void AppHost::Initialize()
_logic.SettingsChanged({ this, &AppHost::_HandleSettingsChanged });
_logic.IsQuakeWindowChanged({ this, &AppHost::_IsQuakeWindowChanged });
_logic.SummonWindowRequested({ this, &AppHost::_SummonWindowRequested });
_logic.MinimizeToTrayRequested({ this, &AppHost::_MinimizeToTrayRequested });
_window->UpdateTitle(_logic.Title());
@ -649,6 +646,7 @@ void AppHost::_BecomeMonarch(const winrt::Windows::Foundation::IInspectable& /*s
const winrt::Windows::Foundation::IInspectable& /*args*/)
{
_UpdateTrayIcon();
_CreateTrayContextMenu();
_setupGlobalHotkeys();
// The monarch is just going to be THE listener for inbound connections.
@ -946,6 +944,12 @@ void AppHost::_SummonWindowRequested(const winrt::Windows::Foundation::IInspecta
_HandleSummon(sender, summonArgs);
}
void AppHost::_MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspectable&,
const winrt::Windows::Foundation::IInspectable&)
{
ShowWindow(_window->GetHandle(), SW_HIDE);
}
void AppHost::_HandleTrayIconPressed()
{
// No name in the args means summon the mru window.
@ -998,20 +1002,11 @@ void AppHost::_UpdateTrayIcon()
}
}
void AppHost::_CreateTrayContextMenu(const til::point coord)
void AppHost::_ShowTrayContextMenu(const til::point coord)
{
auto hmenu = CreatePopupMenu();
if (hmenu)
_trayContextMenu = _CreateTrayContextMenu();
if (_trayContextMenu)
{
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-menuinfo
MENUINFO mi{};
mi.fMask = MIM_APPLYTOSUBMENUS | MIM_STYLE;
mi.dwStyle = MNS_NOCHECK | MNS_NOTIFYBYPOS;
SetMenuInfo(hmenu, &mi);
// Just testing how to insert menu items
InsertMenu(hmenu, 0, MF_STRING, 0, L"Start");
// We'll need to set our window to the foreground before calling
// TrackPopupMenuEx or else the menu won't dismiss when clicking away.
SetForegroundWindow(_window->GetHandle());
@ -1026,7 +1021,36 @@ void AppHost::_CreateTrayContextMenu(const til::point coord)
uFlags |= TPM_LEFTALIGN;
}
TrackPopupMenuEx(hmenu, uFlags, (int)coord.x(), (int)coord.y(), _window->GetHandle(), NULL);
DestroyMenu(hmenu);
TrackPopupMenuEx(_trayContextMenu.value(), uFlags, (int)coord.x(), (int)coord.y(), _window->GetHandle(), NULL);
}
}
HMENU AppHost::_CreateTrayContextMenu()
{
auto hmenu = CreatePopupMenu();
if (hmenu)
{
MENUINFO mi{};
mi.fMask = MIM_STYLE;
mi.dwStyle = MNS_NOCHECK;
assert(SetMenuInfo(hmenu, &mi));
// Get all peasants' window names
for (auto [id, name] : _windowManager.GetPeasantNames())
{
AppendMenu(hmenu, MF_STRING, id, name.c_str());
}
}
return hmenu;
}
void AppHost::_TrayMenuItemSelected(const UINT menuItemID)
{
// Grab the window name associated to the given context menu item ID.
WCHAR name[255];
GetMenuString(_trayContextMenu.value(), menuItemID, name, 255, MF_BYCOMMAND);
Remoting::SummonWindowSelectionArgs args{ name };
args.SummonBehavior().ToggleVisibility(false);
_windowManager.SummonWindow(args);
}

View file

@ -86,9 +86,15 @@ private:
void _SummonWindowRequested(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::Foundation::IInspectable& args);
void _MinimizeToTrayRequested(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::Foundation::IInspectable&);
void _UpdateTrayIcon();
void _HandleTrayIconPressed();
void _CreateTrayContextMenu(const til::point coord);
void _ShowTrayContextMenu(const til::point coord);
HMENU _CreateTrayContextMenu();
void _TrayMenuItemSelected(const UINT menuItemID);
std::optional<NOTIFYICONDATA> _trayIconData;
std::optional<HMENU> _trayContextMenu;
};

View file

@ -527,6 +527,7 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize
}
case WM_COMMAND:
{
_NotifyTrayMenuItemSelectedHandlers(static_cast<UINT>(wparam));
return 0;
}
}

View file

@ -55,6 +55,7 @@ public:
WINRT_CALLBACK(HotkeyPressed, winrt::delegate<void(long)>);
WINRT_CALLBACK(NotifyTrayIconPressed, winrt::delegate<void()>);
WINRT_CALLBACK(NotifyShowTrayContextMenu, winrt::delegate<void(til::point)>);
WINRT_CALLBACK(NotifyTrayMenuItemSelected, winrt::delegate<void(UINT)>);
protected:
void ForceResize()