## Summary of the Pull Request This is a follow up to #9300. Now that we have names on our windows, it would be nice to see who is named what. So this adds two actions: * `identifyWindow`: This action will pop up a little toast (#8592) displaying the name and ID of the window, and is bound by default. ![identify-window-toast-000](https://user-images.githubusercontent.com/18356694/111529085-bf710580-872f-11eb-8880-b0b617596cfc.gif) * `identifyWindows`: This action will request that ALL windows pop up that toast. This is meant to feel like the "Identify" button on the Windows display settings. However, sometimes, it's wonky. ![teaching-tip-dismiss-001](https://user-images.githubusercontent.com/18356694/111529292-fe06c000-872f-11eb-8d4a-5688e4ce1175.gif) That's being tracked upstream on https://github.com/microsoft/microsoft-ui-xaml/issues/4382 Because it's so wonky, we won't bind that by default. Maybe if we get that fixed, then we'll change the default binding from `identifyWindow` to `identifyWindows` ## References ## PR Checklist * [x] Closes https://github.com/microsoft/terminal/projects/5#card-51431492 * [x] I work here * [x] Tests added/passed * [ ] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments You may note that there are some macros to make interacting with lots and lots of actions easier. There's a lot of boilerplate whenever you need to make a new action, so I thought: "Can we make that easier?" Turns out you can make it a _LOT_ easier, but that work is still behind another PR after this one. Get excited
168 lines
5.9 KiB
C++
168 lines
5.9 KiB
C++
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT license.
|
|
|
|
#include "pch.h"
|
|
#include "Peasant.h"
|
|
#include "CommandlineArgs.h"
|
|
#include "Peasant.g.cpp"
|
|
#include "../../types/inc/utils.hpp"
|
|
|
|
using namespace winrt;
|
|
using namespace winrt::Microsoft::Terminal;
|
|
using namespace winrt::Windows::Foundation;
|
|
using namespace ::Microsoft::Console;
|
|
|
|
namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|
{
|
|
Peasant::Peasant() :
|
|
_ourPID{ GetCurrentProcessId() }
|
|
{
|
|
}
|
|
|
|
// This is a private constructor to be used in unit tests, where we don't
|
|
// want each Peasant to necessarily use the current PID.
|
|
Peasant::Peasant(const uint64_t testPID) :
|
|
_ourPID{ testPID }
|
|
{
|
|
}
|
|
|
|
void Peasant::AssignID(uint64_t id)
|
|
{
|
|
_id = id;
|
|
}
|
|
uint64_t Peasant::GetID()
|
|
{
|
|
return _id;
|
|
}
|
|
|
|
uint64_t Peasant::GetPID()
|
|
{
|
|
return _ourPID;
|
|
}
|
|
|
|
bool Peasant::ExecuteCommandline(const Remoting::CommandlineArgs& args)
|
|
{
|
|
// If this is the first set of args we were ever told about, stash them
|
|
// away. We'll need to get at them later, when we setup the startup
|
|
// actions for the window.
|
|
if (_initialArgs == nullptr)
|
|
{
|
|
_initialArgs = args;
|
|
}
|
|
|
|
TraceLoggingWrite(g_hRemotingProvider,
|
|
"Peasant_ExecuteCommandline",
|
|
TraceLoggingUInt64(GetID(), "peasantID", "Our ID"),
|
|
TraceLoggingWideString(args.CurrentDirectory().c_str(), "directory", "the provided cwd"),
|
|
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE));
|
|
|
|
// Raise an event with these args. The AppHost will listen for this
|
|
// event to know when to take these args and dispatch them to a
|
|
// currently-running window.
|
|
_ExecuteCommandlineRequestedHandlers(*this, args);
|
|
|
|
return true;
|
|
}
|
|
|
|
Remoting::CommandlineArgs Peasant::InitialArgs()
|
|
{
|
|
return _initialArgs;
|
|
}
|
|
|
|
void Peasant::ActivateWindow(const Remoting::WindowActivatedArgs& args)
|
|
{
|
|
// TODO: projects/5 - somehow, pass an identifier for the current
|
|
// desktop into this method. The Peasant shouldn't need to be able to
|
|
// figure it out, but it will need to report it to the monarch.
|
|
|
|
// Store these new args as our last activated state. If a new monarch
|
|
// comes looking, we can use this info to tell them when we were last
|
|
// activated.
|
|
_lastActivatedArgs = args;
|
|
|
|
bool successfullyNotified = false;
|
|
// Raise our WindowActivated event, to let the monarch know we've been
|
|
// activated.
|
|
try
|
|
{
|
|
// Try/catch this, because the other side of this event is handled
|
|
// by the monarch. The monarch might have died. If they have, this
|
|
// will throw an exception. Just eat it, the election thread will
|
|
// handle hooking up the new one.
|
|
_WindowActivatedHandlers(*this, args);
|
|
successfullyNotified = true;
|
|
}
|
|
catch (...)
|
|
{
|
|
LOG_CAUGHT_EXCEPTION();
|
|
}
|
|
|
|
TraceLoggingWrite(g_hRemotingProvider,
|
|
"Peasant_ActivateWindow",
|
|
TraceLoggingUInt64(GetID(), "peasantID", "Our ID"),
|
|
TraceLoggingBoolean(successfullyNotified, "successfullyNotified", "true if we successfully notified the monarch"),
|
|
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE));
|
|
}
|
|
|
|
// Method Description:
|
|
// - Retrieve the WindowActivatedArgs describing the last activation of this
|
|
// peasant. New monarchs can use this state to determine when we were last
|
|
// activated.
|
|
// Arguments:
|
|
// - <none>
|
|
// Return Value:
|
|
// - a WindowActivatedArgs with info about when and where we were last activated.
|
|
Remoting::WindowActivatedArgs Peasant::GetLastActivatedArgs()
|
|
{
|
|
return _lastActivatedArgs;
|
|
}
|
|
|
|
// Method Description:
|
|
// - Tell this window to display it's window ID. We'll raise a
|
|
// DisplayWindowIdRequested event, which will get handled in the AppHost,
|
|
// and used to tell the app to display the ID toast.
|
|
// Arguments:
|
|
// - <none>
|
|
// Return Value:
|
|
// - <none>
|
|
void Peasant::DisplayWindowId()
|
|
{
|
|
// Not worried about try/catching this. The handler is in AppHost, which
|
|
// is in-proc for us.
|
|
_DisplayWindowIdRequestedHandlers(*this, nullptr);
|
|
}
|
|
|
|
// Method Description:
|
|
// - Raises an event to ask that all windows be identified. This will come
|
|
// back to us when the Monarch handles the event and calls our
|
|
// DisplayWindowId method.
|
|
// Arguments:
|
|
// - <none>
|
|
// Return Value:
|
|
// - <none>
|
|
void Peasant::RequestIdentifyWindows()
|
|
{
|
|
bool successfullyNotified = false;
|
|
|
|
try
|
|
{
|
|
// Try/catch this, because the other side of this event is handled
|
|
// by the monarch. The monarch might have died. If they have, this
|
|
// will throw an exception. Just eat it, the election thread will
|
|
// handle hooking up the new one.
|
|
_IdentifyWindowsRequestedHandlers(*this, nullptr);
|
|
successfullyNotified = true;
|
|
}
|
|
catch (...)
|
|
{
|
|
LOG_CAUGHT_EXCEPTION();
|
|
}
|
|
TraceLoggingWrite(g_hRemotingProvider,
|
|
"Peasant_RequestIdentifyWindows",
|
|
TraceLoggingUInt64(GetID(), "peasantID", "Our ID"),
|
|
TraceLoggingBoolean(successfullyNotified, "successfullyNotified", "true if we successfully notified the monarch"),
|
|
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE));
|
|
}
|
|
|
|
}
|