Skip to content

Commit

Permalink
oh man, this will magic summon the window to the current desktop. I'm…
Browse files Browse the repository at this point in the history
… shocked that it works, thanks powertoys
  • Loading branch information
zadjii-msft committed Apr 19, 2021
1 parent 1b2e7a7 commit 305e627
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/cascadia/Remoting/Monarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// If no name was provided, then just summon the MRU window.
if (searchedForName.empty())
{
windowId = _getMostRecentPeasantID(true);
// TODO!: let this optionally be true, in the SummonWindowSelectionArgs
windowId = _getMostRecentPeasantID(false);
}
else
{
Expand Down
43 changes: 43 additions & 0 deletions src/cascadia/WindowsTerminal/AppHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "../types/inc/User32Utils.hpp"
#include "../WinRTUtils/inc/WtExeUtils.h"
#include "resource.h"
#include "VirtualDesktopUtils.h"

using namespace winrt::Windows::UI;
using namespace winrt::Windows::UI::Composition;
Expand Down Expand Up @@ -721,10 +722,52 @@ winrt::fire_and_forget AppHost::_createNewTerminalWindow(Settings::Model::Global
co_return;
}

GUID _currentlyActiveDesktop()
{
// // HWND desktop = GetDesktopWindow();

// static const wchar_t* const PSEUDO_WINDOW_CLASS = L"Pseudo1ConsoleWindow";
// WNDCLASS pseudoClass{ 0 };
// pseudoClass.lpszClassName = PSEUDO_WINDOW_CLASS;
// pseudoClass.lpfnWndProc = DefWindowProc;
// RegisterClass(&pseudoClass);
// // Attempt to create window
// wil::unique_hwnd hwnd{ CreateWindowExW(
// 0, PSEUDO_WINDOW_CLASS, nullptr, WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, HWND_DESKTOP, nullptr, nullptr, nullptr) };
// HWND h = hwnd.get();
// GUID currentDesktopGuid{ 0 };
// try
// {
// const auto manager = winrt::create_instance<IVirtualDesktopManager>(__uuidof(VirtualDesktopManager));
// if (manager)
// {
// DebugBreak();
// LOG_IF_FAILED(manager->GetWindowDesktopId(h, &currentDesktopGuid));
// }
// }
// CATCH_LOG();
GUID currentDesktopGuid;
VirtualDesktopUtils::GetCurrentVirtualDesktopId(&currentDesktopGuid);
return currentDesktopGuid;
}

void AppHost::_HandleSummon(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const winrt::Windows::Foundation::IInspectable& /*args*/)
{
_window->SummonWindow();

const auto currentWindowDesktop{ _CurrentDesktopGuid() };
const auto currentlyActiveDesktop{ _currentlyActiveDesktop() };
// DebugBreak();
try
{
const auto manager = winrt::create_instance<IVirtualDesktopManager>(__uuidof(VirtualDesktopManager));
if (manager)
{
LOG_IF_FAILED(manager->MoveWindowToDesktop(_window->GetHandle(), currentlyActiveDesktop));
}
}
CATCH_LOG();
}

GUID AppHost::_CurrentDesktopGuid()
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/WindowsTerminal/IslandWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,7 @@ void IslandWindow::UnsetHotkeys(const std::vector<winrt::Microsoft::Terminal::Co
TraceLoggingInt64(hotkeyList.size(), "numHotkeys", "The number of hotkeys to unset"),
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE));

for (size_t i = 0; i < hotkeyList.size(); i++)
for (int i = 0; i < ::base::saturated_cast<int>(hotkeyList.size()); i++)
{
LOG_IF_WIN32_BOOL_FALSE(UnregisterHotKey(_window.get(), i));
}
Expand Down
141 changes: 141 additions & 0 deletions src/cascadia/WindowsTerminal/VirtualDesktopUtils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// Shamelessly copied from PowerToys

#include "pch.h"

#include "VirtualDesktopUtils.h"

// Non-Localizable strings
namespace NonLocalizable
{
const wchar_t RegCurrentVirtualDesktop[] = L"CurrentVirtualDesktop";
const wchar_t RegVirtualDesktopIds[] = L"VirtualDesktopIDs";
const wchar_t RegKeyVirtualDesktops[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\VirtualDesktops";
const wchar_t RegKeyVirtualDesktopsFromSession[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\SessionInfo\\%d\\VirtualDesktops";
}

namespace VirtualDesktopUtils
{
bool GetDesktopIdFromCurrentSession(GUID* desktopId)
{
DWORD sessionId;
if (!ProcessIdToSessionId(GetCurrentProcessId(), &sessionId))
{
return false;
}

wchar_t sessionKeyPath[256]{};
if (FAILED(StringCchPrintfW(sessionKeyPath, ARRAYSIZE(sessionKeyPath), NonLocalizable::RegKeyVirtualDesktopsFromSession, sessionId)))
{
return false;
}

wil::unique_hkey key{};
if (RegOpenKeyExW(HKEY_CURRENT_USER, sessionKeyPath, 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
{
GUID value{};
DWORD size = sizeof(GUID);
if (RegQueryValueExW(key.get(), NonLocalizable::RegCurrentVirtualDesktop, 0, nullptr, reinterpret_cast<BYTE*>(&value), &size) == ERROR_SUCCESS)
{
*desktopId = value;
return true;
}
}
return false;
}

bool GetVirtualDesktopIds(HKEY hKey, std::vector<GUID>& ids)
{
if (!hKey)
{
return false;
}
DWORD bufferCapacity;
// request regkey binary buffer capacity only
if (RegQueryValueExW(hKey, NonLocalizable::RegVirtualDesktopIds, 0, nullptr, nullptr, &bufferCapacity) != ERROR_SUCCESS)
{
return false;
}
std::unique_ptr<BYTE[]> buffer = std::make_unique<BYTE[]>(bufferCapacity);
// request regkey binary content
if (RegQueryValueExW(hKey, NonLocalizable::RegVirtualDesktopIds, 0, nullptr, buffer.get(), &bufferCapacity) != ERROR_SUCCESS)
{
return false;
}
const size_t guidSize = sizeof(GUID);
std::vector<GUID> temp;
temp.reserve(bufferCapacity / guidSize);
for (size_t i = 0; i < bufferCapacity; i += guidSize)
{
GUID* guid = reinterpret_cast<GUID*>(buffer.get() + i);
temp.push_back(*guid);
}
ids = std::move(temp);
return true;
}

HKEY OpenVirtualDesktopsRegKey()
{
HKEY hKey{ nullptr };
if (RegOpenKeyEx(HKEY_CURRENT_USER, NonLocalizable::RegKeyVirtualDesktops, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{
return hKey;
}
return nullptr;
}

HKEY GetVirtualDesktopsRegKey()
{
static wil::unique_hkey virtualDesktopsKey{ OpenVirtualDesktopsRegKey() };
return virtualDesktopsKey.get();
}
bool GetVirtualDesktopIds(std::vector<GUID>& ids)
{
return GetVirtualDesktopIds(GetVirtualDesktopsRegKey(), ids);
}

bool GetVirtualDesktopIds(std::vector<std::wstring>& ids)
{
std::vector<GUID> guids{};
if (GetVirtualDesktopIds(guids))
{
for (auto& guid : guids)
{
wil::unique_cotaskmem_string guidString;
if (SUCCEEDED(StringFromCLSID(guid, &guidString)))
{
ids.push_back(guidString.get());
}
}
return true;
}
return false;
}

bool GetCurrentVirtualDesktopId(GUID* desktopId)
{
// Explorer persists current virtual desktop identifier to registry on a per session basis, but only
// after first virtual desktop switch happens. If the user hasn't switched virtual desktops in this
// session, value in registry will be empty.
if (GetDesktopIdFromCurrentSession(desktopId))
{
return true;
}
// Fallback scenario is to get array of virtual desktops stored in registry, but not kept per session.
// Note that we are taking first element from virtual desktop array, which is primary desktop.
// If user has more than one virtual desktop, previous function should return correct value, as desktop
// switch occurred in current session.
else
{
std::vector<GUID> ids{};
if (GetVirtualDesktopIds(ids) && ids.size() > 0)
{
*desktopId = ids[0];
return true;
}
}
return false;
}
}
9 changes: 9 additions & 0 deletions src/cascadia/WindowsTerminal/VirtualDesktopUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

#pragma once

namespace VirtualDesktopUtils
{
bool GetCurrentVirtualDesktopId(GUID* desktopId);
}
2 changes: 2 additions & 0 deletions src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
<ClInclude Include="BaseWindow.h" />
<ClInclude Include="IslandWindow.h" />
<ClInclude Include="NonClientIslandWindow.h" />
<ClInclude Include="VirtualDesktopUtils.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
Expand All @@ -57,6 +58,7 @@
<ClCompile Include="AppHost.cpp" />
<ClCompile Include="IslandWindow.cpp" />
<ClCompile Include="NonClientIslandWindow.cpp" />
<ClCompile Include="VirtualDesktopUtils.cpp" />
<ClCompile Include="icon.cpp" />
</ItemGroup>
<ItemGroup>
Expand Down

0 comments on commit 305e627

Please sign in to comment.