creating enum for menu item action

This commit is contained in:
Leon Liang 2021-06-16 10:30:23 -07:00
parent 07467bc221
commit 57c2117c0b
6 changed files with 61 additions and 31 deletions

View file

@ -10,6 +10,9 @@
#include "resource.h"
#include "VirtualDesktopUtils.h"
#include "icon.h"
#include "TrayIconData.h"
#include <LibraryResources.h>
using namespace winrt::Windows::UI;
using namespace winrt::Windows::UI::Composition;
@ -63,6 +66,8 @@ AppHost::AppHost() noexcept :
// Update our own internal state tracking if we're in quake mode or not.
_IsQuakeWindowChanged(nullptr, nullptr);
_window->SetMinimizeToTrayBehavior(_logic.GetMinimizeToTray());
// Tell the window to callback to us when it's about to handle a WM_CREATE
auto pfn = std::bind(&AppHost::_HandleCreateWindow,
this,
@ -991,7 +996,7 @@ void AppHost::_UpdateTrayIcon()
nid.uCallbackMessage = CM_NOTIFY_FROM_TRAY;
nid.hIcon = static_cast<HICON>(GetActiveAppIconHandle(ICON_SMALL));
nid.hIcon = static_cast<HICON>(GetActiveAppIconHandle(true));
StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), L"Windows Terminal");
nid.uFlags = NIF_MESSAGE | NIF_SHOWTIP | NIF_TIP | NIF_ICON;
Shell_NotifyIcon(NIM_ADD, &nid);
@ -1047,37 +1052,61 @@ HMENU AppHost::_CreateTrayContextMenu()
mi.dwStyle = MNS_NOTIFYBYPOS;
SetMenuInfo(hmenu, &mi);
// TODO: Other useful options may include:
// - Summon All
// - Summon MRU or Monarch
// - Though that's technically already available with a left click
// but may be a reasonable request to also put it explicitly in the
// context menu
// - Quit All
// It also might be nice to add options to changing the left click
// behavior (e.g. mru window or all windows or quake window)
// Focus Current Terminal Window
AppendMenu(hmenu, MF_STRING, (UINT_PTR)TrayMenuItemAction::FocusTerminal, L"Focus Terminal");
AppendMenu(hmenu, MF_SEPARATOR, 0, L"");
// Get all peasants' window names
for (const auto [id, name] : _windowManager.GetPeasantNames())
// Submenu for Windows
if (auto windowSubmenu = _CreateWindowSubmenu())
{
// Technically, the id doesn't matter here since we'll
// be referring to this menu item through its position
// in the context menu.
AppendMenu(hmenu, MF_STRING, (UINT_PTR)id, name.c_str());
AppendMenu(hmenu, MF_POPUP, (UINT_PTR)windowSubmenu, L"Windows");
AppendMenu(hmenu, MF_SEPARATOR, 0, L"");
}
AppendMenu(hmenu, MF_STRING, (UINT_PTR)TrayMenuItemAction::QuitAll, L"Close All Windows");
}
return hmenu;
}
HMENU AppHost::_CreateWindowSubmenu()
{
if (auto hmenu = CreatePopupMenu())
{
for (const auto [id, name] : _windowManager.GetPeasantNames())
{
AppendMenu(hmenu, MF_STRING, (UINT_PTR)TrayMenuItemAction::SummonWindow, name.c_str());
}
return hmenu;
}
return nullptr;
}
void AppHost::_TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex)
{
// Grab the window name associated to the given context menu item position.
WCHAR name[255];
GetMenuString(menu, menuItemIndex, name, 255, MF_BYPOSITION);
auto action = (TrayMenuItemAction)GetMenuItemID(menu, menuItemIndex);
switch (action)
{
case TrayMenuItemAction::FocusTerminal:
{
_windowManager.SummonWindow({});
break;
}
case TrayMenuItemAction::SummonWindow:
{
WCHAR name[255];
GetMenuString(menu, menuItemIndex, name, 255, MF_BYPOSITION);
Remoting::SummonWindowSelectionArgs args{ name };
args.SummonBehavior().ToggleVisibility(false);
_windowManager.SummonWindow(args);
Remoting::SummonWindowSelectionArgs args{ name };
args.SummonBehavior().ToggleVisibility(false);
_windowManager.SummonWindow(args);
break;
}
case TrayMenuItemAction::QuitAll:
{
break;
}
}
}
void AppHost::_DestroyTrayIcon()

View file

@ -93,6 +93,7 @@ private:
void _HandleTrayIconPressed();
void _ShowTrayContextMenu(const til::point coord);
HMENU _CreateTrayContextMenu();
HMENU _CreateWindowSubmenu();
void _TrayMenuItemSelected(const HMENU menu, const UINT menuItemIndex);
void _DestroyTrayIcon();

View file

@ -8,9 +8,6 @@
#include <wil/resource.h>
#include <LibraryResources.h>
UTILS_DEFINE_LIBRARY_RESOURCE_SCOPE(L"TerminalApp/Resources")
template<typename T>
class BaseWindow
{

View file

@ -46,6 +46,7 @@
<ClInclude Include="BaseWindow.h" />
<ClInclude Include="IslandWindow.h" />
<ClInclude Include="NonClientIslandWindow.h" />
<ClInclude Include="TrayIconData.h" />
<ClInclude Include="VirtualDesktopUtils.h" />
</ItemGroup>
<ItemGroup>

View file

@ -27,12 +27,14 @@ static int _GetActiveAppIconResource()
return iconResource;
}
HANDLE GetActiveAppIconHandle(int size)
// There's only two possible sizes - ICON_SMALL and ICON_BIG.
// So, use true for smallIcon if you want small and false for big.
HANDLE GetActiveAppIconHandle(bool smallIcon)
{
auto iconResource{ MAKEINTRESOURCEW(_GetActiveAppIconResource()) };
const auto smXIcon = size == ICON_SMALL ? SM_CXSMICON : SM_CXICON;
const auto smYIcon = size == ICON_SMALL ? SM_CYSMICON : SM_CYICON;
const auto smXIcon = smallIcon ? SM_CXSMICON : SM_CXICON;
const auto smYIcon = smallIcon ? SM_CYSMICON : SM_CYICON;
// These handles are loaded with LR_SHARED, so they are safe to "leak".
HANDLE hIcon{ LoadImageW(wil::GetModuleInstanceHandle(), iconResource, IMAGE_ICON, GetSystemMetrics(smXIcon), GetSystemMetrics(smYIcon), LR_SHARED) };
@ -43,11 +45,11 @@ HANDLE GetActiveAppIconHandle(int size)
void UpdateWindowIconForActiveMetrics(HWND window)
{
if (auto smallIcon = GetActiveAppIconHandle(ICON_SMALL))
if (auto smallIcon = GetActiveAppIconHandle(true))
{
SendMessageW(window, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(smallIcon));
}
if (auto largeIcon = GetActiveAppIconHandle(ICON_BIG))
if (auto largeIcon = GetActiveAppIconHandle(false))
{
SendMessageW(window, WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(largeIcon));
}

View file

@ -3,5 +3,5 @@
#pragma once
HANDLE GetActiveAppIconHandle(const int size);
HANDLE GetActiveAppIconHandle(bool smallIcon);
void UpdateWindowIconForActiveMetrics(HWND window);