Ask the TerminalApp to parse the commandline, and tell us what the window should be. It just always says 0 for now, but in the future it could actually give us useful info.
This commit is contained in:
parent
00184e7ef6
commit
658db6b568
5
src/cascadia/Remoting/FindTargetWindowArgs.cpp
Normal file
5
src/cascadia/Remoting/FindTargetWindowArgs.cpp
Normal file
|
@ -0,0 +1,5 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
#include "pch.h"
|
||||
#include "FindTargetWindowArgs.h"
|
||||
#include "FindTargetWindowArgs.g.cpp"
|
17
src/cascadia/Remoting/FindTargetWindowArgs.h
Normal file
17
src/cascadia/Remoting/FindTargetWindowArgs.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "FindTargetWindowArgs.g.h"
|
||||
#include "../cascadia/inc/cppwinrt_utils.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
{
|
||||
struct FindTargetWindowArgs : public FindTargetWindowArgsT<FindTargetWindowArgs>
|
||||
{
|
||||
public:
|
||||
GETSET_PROPERTY(winrt::Microsoft::Terminal::Remoting::CommandlineArgs, Args, nullptr);
|
||||
GETSET_PROPERTY(int, ResultTargetWindow, -1);
|
||||
};
|
||||
}
|
|
@ -19,6 +19,9 @@
|
|||
<ClInclude Include="Monarch.h">
|
||||
<DependentUpon>Monarch.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FindTargetWindowArgs.h">
|
||||
<DependentUpon>Monarch.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="MonarchFactory.h" />
|
||||
<ClInclude Include="Peasant.h">
|
||||
|
@ -36,6 +39,9 @@
|
|||
<ClCompile Include="Monarch.cpp">
|
||||
<DependentUpon>Monarch.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FindTargetWindowArgs.cpp">
|
||||
<DependentUpon>Monarch.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "pch.h"
|
||||
#include "Monarch.h"
|
||||
#include "CommandlineArgs.h"
|
||||
#include "FindTargetWindowArgs.h"
|
||||
|
||||
#include "Monarch.g.cpp"
|
||||
#include "../../types/inc/utils.hpp"
|
||||
|
@ -117,6 +118,13 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|||
}
|
||||
}
|
||||
|
||||
// TODO:MG This probably shouldn't be a public function. I'm making it
|
||||
// public so the WindowManager can use it to manually tell the monarch it's
|
||||
// own ID to use as the MRU, when the monarch is first instantiated. THat's
|
||||
// dumb, but it's a hack to get something working.
|
||||
//
|
||||
// That was stupid. I knew it would be but yea it didn't work.
|
||||
// THe Window manager doesn't have a peasant yet when it first creates the monarch.
|
||||
void Monarch::_setMostRecentPeasant(const uint64_t peasantID)
|
||||
{
|
||||
// TODO:projects/5 Use a heap/priority queue per-desktop to track which
|
||||
|
@ -126,6 +134,24 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|||
_mostRecentPeasant = peasantID;
|
||||
}
|
||||
|
||||
uint64_t Monarch::_getMostRecentPeasantID()
|
||||
{
|
||||
if (_mostRecentPeasant == 0)
|
||||
{
|
||||
// We haven't yet been told the MRU peasant. Just use the first one.
|
||||
// TODO: GOD this is just gonna be a random one. Hacks on hacks on hacks
|
||||
if (_peasants.size() > 0)
|
||||
{
|
||||
return _peasants.begin()->second.GetID();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _mostRecentPeasant;
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Try to handle a commandline from a new WT invocation. We might need to
|
||||
// hand the commandline to an existing window, or we might need to tell
|
||||
|
@ -133,8 +159,10 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
bool Monarch::ProposeCommandline(const Remoting::CommandlineArgs& /*args*/)
|
||||
// - true if the caller should create a new window for this commandline.
|
||||
// False otherwise - the monarch should have dispatched this commandline
|
||||
// to another window in this case.
|
||||
bool Monarch::ProposeCommandline(const Remoting::CommandlineArgs& args)
|
||||
{
|
||||
// TODO:projects/5
|
||||
// The branch dev/migrie/f/remote-commandlines has a more complete
|
||||
|
@ -142,6 +170,30 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|||
// always want to create a new window, so we'll just return true. This
|
||||
// will tell the caller that we didn't handle the commandline, and they
|
||||
// should open a new window to deal with it themselves.
|
||||
auto findWindowArgs = winrt::make_self<Remoting::implementation::FindTargetWindowArgs>();
|
||||
findWindowArgs->Args(args);
|
||||
_FindTargetWindowRequestedHandlers(*this, *findWindowArgs);
|
||||
const auto targetWindow = findWindowArgs->ResultTargetWindow();
|
||||
|
||||
// TODO:projects/5 targetWindow==0 -> use the currently active window
|
||||
if (targetWindow >= 0)
|
||||
{
|
||||
uint64_t windowID = ::base::saturated_cast<uint64_t>(targetWindow);
|
||||
|
||||
if (windowID == 0)
|
||||
{
|
||||
windowID = _getMostRecentPeasantID();
|
||||
}
|
||||
|
||||
if (auto targetPeasant{ _getPeasant(windowID) })
|
||||
{
|
||||
targetPeasant.ExecuteCommandline(args);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// TEMPORARY: if the target window is -1, then we want a new window. All
|
||||
// other cases, just do it in this window (for now).
|
||||
// return targetWindow == -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|||
|
||||
bool ProposeCommandline(const winrt::Microsoft::Terminal::Remoting::CommandlineArgs& args);
|
||||
|
||||
TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs);
|
||||
|
||||
private:
|
||||
Monarch(const uint64_t testPID);
|
||||
uint64_t _ourPID;
|
||||
|
@ -51,6 +53,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|||
|
||||
winrt::Microsoft::Terminal::Remoting::IPeasant _getPeasant(uint64_t peasantID);
|
||||
void _setMostRecentPeasant(const uint64_t peasantID);
|
||||
uint64_t _getMostRecentPeasantID();
|
||||
|
||||
void _peasantWindowActivated(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::Foundation::IInspectable& args);
|
||||
|
|
|
@ -5,11 +5,19 @@ import "Peasant.idl";
|
|||
|
||||
namespace Microsoft.Terminal.Remoting
|
||||
{
|
||||
|
||||
[default_interface] runtimeclass FindTargetWindowArgs {
|
||||
CommandlineArgs Args;
|
||||
Int32 ResultTargetWindow;
|
||||
}
|
||||
|
||||
[default_interface] runtimeclass Monarch {
|
||||
Monarch();
|
||||
|
||||
UInt64 GetPID();
|
||||
UInt64 AddPeasant(IPeasant peasant);
|
||||
Boolean ProposeCommandline(CommandlineArgs args);
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, FindTargetWindowArgs> FindTargetWindowRequested;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -106,10 +106,23 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|||
return;
|
||||
}
|
||||
// Here, we're the king!
|
||||
//
|
||||
// This is where you should do any aditional setup that might need to be
|
||||
// done when we become the king. THis will be called both for the first
|
||||
// window, and when the current monarch diesd.
|
||||
|
||||
// Wait, don't. Let's just have the monarch try/catch any accesses to
|
||||
// peasants. If the peasant dies, then it can't get the peasant's
|
||||
// anything. In that case, _remove it_.
|
||||
|
||||
_monarch.FindTargetWindowRequested({ this, &WindowManager::_raiseFindTargetWindowRequested });
|
||||
|
||||
// winrt::com_ptr<Remoting::implementation::Monarch> monarchImpl;
|
||||
// monarchImpl.copy_from(winrt::get_self<Remoting::implementation::Monarch>(_monarch));
|
||||
// if (monarchImpl)
|
||||
// {
|
||||
// monarchImpl->SetMostRecentPeasant(_peasant.GetID());
|
||||
// }
|
||||
}
|
||||
|
||||
bool WindowManager::_areWeTheKing()
|
||||
|
@ -137,6 +150,9 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|||
|
||||
if (_areWeTheKing())
|
||||
{
|
||||
// This is only called when a _new_ monarch is elected. We need to
|
||||
// do this _always_, even on the first instance, which won't have an
|
||||
// election
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -213,4 +229,9 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|||
return _peasant;
|
||||
}
|
||||
|
||||
void WindowManager::_raiseFindTargetWindowRequested(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs& args)
|
||||
{
|
||||
_FindTargetWindowRequestedHandlers(sender, args);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,10 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|||
|
||||
winrt::Microsoft::Terminal::Remoting::Peasant CurrentWindow();
|
||||
|
||||
// Don't do this, the monarch can and will change over time
|
||||
// FORWARDED_TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs, _monarch, FindTargetWindowRequested);
|
||||
TYPED_EVENT(FindTargetWindowRequested, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs);
|
||||
|
||||
private:
|
||||
bool _shouldCreateWindow{ false };
|
||||
DWORD _registrationHostClass{ 0 };
|
||||
|
@ -39,6 +43,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|||
bool _electionNight2020();
|
||||
void _createPeasantThread();
|
||||
void _waitOnMonarchThread();
|
||||
void _raiseFindTargetWindowRequested(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs& args);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import "Peasant.idl";
|
||||
import "Monarch.idl";
|
||||
|
||||
|
||||
namespace Microsoft.Terminal.Remoting
|
||||
|
@ -9,5 +10,6 @@ namespace Microsoft.Terminal.Remoting
|
|||
void ProposeCommandline(CommandlineArgs args);
|
||||
Boolean ShouldCreateWindow { get; };
|
||||
IPeasant CurrentWindow();
|
||||
event Windows.Foundation.TypedEventHandler<Object, FindTargetWindowArgs> FindTargetWindowRequested;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1125,6 +1125,26 @@ namespace winrt::TerminalApp::implementation
|
|||
return result; // TODO:MG does a return value make sense
|
||||
}
|
||||
|
||||
int32_t AppLogic::FindTargetWindow(array_view<const winrt::hstring> args)
|
||||
{
|
||||
::TerminalApp::AppCommandlineArgs appArgs;
|
||||
auto result = appArgs.ParseArgs(args);
|
||||
if (result == 0)
|
||||
{
|
||||
// TODO:MG Right now, any successful parse will end up in the same window
|
||||
return 0;
|
||||
// TODO:projects/5 We'll want to use the windowingBehavior setting to determine
|
||||
// well
|
||||
// Maybe that'd be a special return value out of here, to tell the monarch to do something special
|
||||
// -1 -> create a new window
|
||||
// -2 -> find the mru, this desktop
|
||||
// -3 -> MRU, any desktop
|
||||
}
|
||||
|
||||
// Any unsuccessful parse will be a new window.
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - If there were any errors parsing the commandline that was used to
|
||||
// initialize the terminal, this will return a string containing that
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace winrt::TerminalApp::implementation
|
|||
|
||||
int32_t SetStartupCommandline(array_view<const winrt::hstring> actions);
|
||||
int32_t ExecuteCommandline(array_view<const winrt::hstring> actions);
|
||||
int32_t FindTargetWindow(array_view<const winrt::hstring> actions);
|
||||
winrt::hstring ParseCommandlineMessage();
|
||||
bool ShouldExitEarly();
|
||||
|
||||
|
|
|
@ -56,6 +56,8 @@ namespace TerminalApp
|
|||
UInt64 GetLastActiveControlTaskbarState();
|
||||
UInt64 GetLastActiveControlTaskbarProgress();
|
||||
|
||||
Int32 FindTargetWindow(String[] args);
|
||||
|
||||
// See IDialogPresenter and TerminalPage's DialogPresenter for more
|
||||
// information.
|
||||
Windows.Foundation.IAsyncOperation<Windows.UI.Xaml.Controls.ContentDialogResult> ShowDialog(Windows.UI.Xaml.Controls.ContentDialog dialog);
|
||||
|
|
|
@ -30,6 +30,12 @@ AppHost::AppHost() noexcept :
|
|||
{
|
||||
_logic = _app.Logic(); // get a ref to app's logic
|
||||
|
||||
// Inform the WindowManager that it can use us to find the target window for
|
||||
// a set of commandline args. This needs to be done before
|
||||
// _HandleCommandlineArgs, because WE might end up being the monarch. That
|
||||
// would mean we'd need to be responsible for looking that up.
|
||||
_windowManager.FindTargetWindowRequested({ this, &AppHost::_FindTargetWindow });
|
||||
|
||||
// If there were commandline args to our process, try and process them here.
|
||||
// Do this before AppLogic::Create, otherwise this will have no effect.
|
||||
//
|
||||
|
@ -521,3 +527,10 @@ void AppHost::_DispatchCommandline(winrt::Windows::Foundation::IInspectable /*se
|
|||
{
|
||||
_logic.ExecuteCommandline(args.Args());
|
||||
}
|
||||
|
||||
void AppHost::_FindTargetWindow(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs& args)
|
||||
{
|
||||
const auto targetWindow = _logic.FindTargetWindow(args.Args().Args());
|
||||
args.ResultTargetWindow(targetWindow);
|
||||
}
|
||||
|
|
|
@ -47,4 +47,7 @@ private:
|
|||
|
||||
void _DispatchCommandline(winrt::Windows::Foundation::IInspectable sender,
|
||||
winrt::Microsoft::Terminal::Remoting::CommandlineArgs args);
|
||||
|
||||
void _FindTargetWindow(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Microsoft::Terminal::Remoting::FindTargetWindowArgs& args);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue