Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add property to control dropdown speed of global summon #9977

Merged
merged 112 commits into from
May 17, 2021
Merged
Show file tree
Hide file tree
Changes from 110 commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
3bef7bb
Get all the projects created and hooked up to the sln
zadjii-msft Dec 16, 2020
1f52d35
Yank all the M/P files, this builds?!
zadjii-msft Dec 16, 2020
5a9cdc8
Shockingly, this works, it works elevated, and it works unpackaged
zadjii-msft Dec 16, 2020
36539cf
This won't work, but I'm committing this becaus I finally got it to c…
zadjii-msft Dec 16, 2020
27ace16
whoop, we pass the commandline from the peasant, to the monarch, and …
zadjii-msft Dec 16, 2020
9a41647
HOLY SHIT I GOT THE COMANDLINE TO EXECUTE IN THE CURRENT WINDOW!!!!!!…
zadjii-msft Dec 17, 2020
5cabcfb
add a note to future me
zadjii-msft Dec 17, 2020
03bfc6e
This works as a unittest, but not a local test. That's batty
zadjii-msft Dec 17, 2020
590b9ff
this macro makes me feel dirty
zadjii-msft Dec 17, 2020
0579b24
LocalTests_Remoting -> UnitTests_Remoting
zadjii-msft Dec 17, 2020
a3faed6
finish renaming this test
zadjii-msft Dec 17, 2020
9c6eac4
Clean up a lot for review
zadjii-msft Dec 17, 2020
0103331
cleanup Peasant for review
zadjii-msft Dec 17, 2020
b4fe1bf
Final cleanup for review
zadjii-msft Dec 17, 2020
d08e65c
_final_ final cleanup for review
zadjii-msft Dec 17, 2020
e101efd
pr nits
zadjii-msft Dec 18, 2020
e1402d8
This seems to work to create a thread listening for the monarch, and …
zadjii-msft Dec 18, 2020
f978a9c
it's hard to believe he's gone / were it so easy
zadjii-msft Dec 18, 2020
5939636
Oh yea actually remove the thing
zadjii-msft Dec 18, 2020
c088895
last commit before the holidays
zadjii-msft Dec 18, 2020
fa2df47
Merge remote-tracking branch 'origin/main' into dev/migrie/f/remoting…
zadjii-msft Jan 5, 2021
0f5c24f
Enable audit mode
zadjii-msft Jan 5, 2021
921d915
nits
zadjii-msft Jan 5, 2021
00184e7
Merge branch 'dev/migrie/f/remoting.dll' into dev/migrie/f/the-first-…
zadjii-msft Jan 5, 2021
658db6b
Ask the TerminalApp to parse the commandline, and tell us what the wi…
zadjii-msft Jan 6, 2021
977db46
Holy bajesus, this works like a charm
zadjii-msft Jan 6, 2021
bcbef34
Add a note about commiting suicide
zadjii-msft Jan 6, 2021
813dbc6
notes, comments, cleanup
zadjii-msft Jan 6, 2021
0f0df5e
activate windows
zadjii-msft Jan 6, 2021
9fc2f0e
add some tracelogging
zadjii-msft Jan 6, 2021
6537686
The peasant will now correctly inform the monarch when it re-connects
zadjii-msft Jan 7, 2021
a75da0a
mostly just notes
zadjii-msft Jan 7, 2021
c02f25a
peasants now switch to the cwd that was requested
zadjii-msft Jan 7, 2021
3e39ab9
more comments
zadjii-msft Jan 7, 2021
52b2cb6
Allow the user to provide ids on the commandline
zadjii-msft Jan 7, 2021
bc492f1
Code cleanup
zadjii-msft Jan 7, 2021
88ffc6f
Merge remote-tracking branch 'origin/main' into dev/migrie/f/remoting…
zadjii-msft Jan 7, 2021
be74b2e
putting var in headers is bad, mkay?
zadjii-msft Jan 7, 2021
2a7bc94
branding
zadjii-msft Jan 7, 2021
81c09d9
Merge branch 'dev/migrie/f/remoting.dll' into dev/migrie/f/the-first-…
zadjii-msft Jan 8, 2021
c34e4ce
Merge remote-tracking branch 'origin/main' into dev/migrie/f/the-firs…
zadjii-msft Jan 8, 2021
5b8ace2
A bunch of tests for Monarch::ProposeCommandline
zadjii-msft Jan 8, 2021
689c385
sure yea that's a doc comment
zadjii-msft Jan 8, 2021
59deca1
Merge branch 'main' into dev/migrie/f/the-first-galactic-empire
zadjii-msft Jan 26, 2021
f02969b
More tests, more redundancy
zadjii-msft Jan 26, 2021
b2db317
man I can't spel
zadjii-msft Jan 26, 2021
d2a3438
Add try/catch's throughout Monarch.cpp
zadjii-msft Jan 27, 2021
a65f341
trycatch the window manager. A lot more going on there.
zadjii-msft Jan 27, 2021
1c2f8e5
This will always summon the monarch window
zadjii-msft Jan 28, 2021
71f6b58
RegisterHotKey will be more robust
zadjii-msft Jan 28, 2021
18d1a20
Add support for the `win` key in keybindings
zadjii-msft Jan 28, 2021
a41bee6
!!! THIS NEEDS TO BE MOVED TO THE PARENT BRANCH !!!
zadjii-msft Jan 28, 2021
6e7ea61
!!! THIS NEEDS TO BE MOVED TO THE PARENT BRANCH !!!
zadjii-msft Jan 28, 2021
18099d2
Summon the most recent window
zadjii-msft Jan 28, 2021
3e5d927
Cleanup, now that this isn't needed
zadjii-msft Jan 28, 2021
91b52d4
!!! THIS NEEDS TO BE MOVED TO THE PARENT BRANCH !!!
zadjii-msft Jan 28, 2021
848682a
Oh hey SetForegroundWindow might be the thing
zadjii-msft Jan 28, 2021
1dcb4cb
man this is crisp
zadjii-msft Jan 28, 2021
fee6473
Still trying to figure this out exactly. For linking: #653
zadjii-msft Jan 28, 2021
342d3f2
This works if the window _isn't_ minimized
zadjii-msft Jan 29, 2021
5052d31
deal with minimized windows too
zadjii-msft Jan 29, 2021
eff18d1
more cleanup
zadjii-msft Jan 29, 2021
5c039ea
Merge remote-tracking branch 'origin/main' into dev/migrie/f/653-QUAK…
zadjii-msft Apr 12, 2021
10779ca
We caan now summon based on window name or just use the MRU one. Note…
zadjii-msft Apr 12, 2021
25b31ff
Allow the user to set multiple globalSummon keys, and quakeMode for s…
zadjii-msft Apr 12, 2021
7c2a514
if there is no window with the name, then make a new window with the …
zadjii-msft Apr 12, 2021
ac8fef0
THATS RIGHT, IT HOT-RELOADS
zadjii-msft Apr 12, 2021
1fdb6b1
Tests and doc comments
zadjii-msft Apr 14, 2021
784ec73
Merge remote-tracking branch 'origin/main' into dev/migrie/f/653-QUAK…
zadjii-msft Apr 14, 2021
b20222f
More comments
zadjii-msft Apr 14, 2021
9d76c62
Some dead code cleanup
zadjii-msft Apr 14, 2021
2a2f5cb
pre emptive spellbot
zadjii-msft Apr 14, 2021
71577fc
Merge remote-tracking branch 'origin/main' into dev/migrie/f/653-QUAK…
zadjii-msft Apr 16, 2021
f892752
Add some tracelogging to find a heisenbug that might not have ever be…
zadjii-msft Apr 16, 2021
4166afa
Okay that was bad pre-emptive spelling
zadjii-msft Apr 16, 2021
717db81
Again, nobody's got disk space to build x86. This is a guess
zadjii-msft Apr 19, 2021
1b2e7a7
Merge remote-tracking branch 'origin/main' into dev/migrie/f/653-QUAK…
zadjii-msft Apr 19, 2021
305e627
oh man, this will magic summon the window to the current desktop. I'm…
zadjii-msft Apr 19, 2021
9f9eacb
!! THIS NEEDS TO GO TO THE PARENT BRANCH !!
zadjii-msft Apr 19, 2021
f71c948
Add support for summoning to the current virtual desktop
zadjii-msft Apr 19, 2021
51617cf
cache these results
zadjii-msft Apr 20, 2021
2eec961
All of carlos's feedback
zadjii-msft Apr 21, 2021
15a8a9c
!! THIS NEEDS TO GO TO THE PARENT BRANCH !!
zadjii-msft Apr 19, 2021
8370789
replace todo with comment
zadjii-msft Apr 21, 2021
4eb1d3a
Merge remote-tracking branch 'origin/main' into dev/migrie/f/653-QUAK…
zadjii-msft Apr 23, 2021
c215a97
Merge branch 'dev/migrie/f/653-QUAKE-MODE' into dev/migrie/f/quake-to…
zadjii-msft Apr 23, 2021
26d5194
this test is _fantastic_
zadjii-msft Apr 23, 2021
91372ea
more tests, because I like being thorough
zadjii-msft Apr 23, 2021
045a8db
fix a build break
zadjii-msft Apr 23, 2021
c95a429
Give Clint the credit they deserce
zadjii-msft Apr 26, 2021
b5e0f2d
When the window is summoned and is already active, minimize it.
zadjii-msft Apr 26, 2021
6c4238b
Toggle the visibility with an optional argument
zadjii-msft Apr 26, 2021
0abd963
update the comment
zadjii-msft Apr 26, 2021
643b860
Merge remote-tracking branch 'origin/main' into dev/migrie/f/653-QUAK…
zadjii-msft Apr 27, 2021
84c1bd9
Merge remote-tracking branch 'origin/main' into dev/migrie/f/quake-to…
zadjii-msft Apr 28, 2021
24bfbe6
BODGY fix for newer builds
zadjii-msft Apr 28, 2021
4c2e6d2
Merge remote-tracking branch 'origin/main' into dev/migrie/f/quake-to…
zadjii-msft Apr 28, 2021
aec2561
Merge remote-tracking branch 'origin/main' into dev/migrie/f/653-QUAK…
zadjii-msft Apr 28, 2021
22036c2
Merge branch 'dev/migrie/f/653-QUAKE-MODE' into dev/migrie/f/quake-to…
zadjii-msft Apr 28, 2021
173720f
Add property to control dropdown speed of global summon
zadjii-msft Apr 28, 2021
b607a55
The OS has first dibs on animation settings
zadjii-msft Apr 28, 2021
63b3658
spel
zadjii-msft Apr 28, 2021
5940f05
Merge remote-tracking branch 'origin/main' into dev/migrie/f/653-QUAK…
zadjii-msft Apr 28, 2021
06cb41b
Address Dustin's PR comments
zadjii-msft Apr 28, 2021
783be75
Merge branch 'dev/migrie/f/653-QUAKE-MODE' into dev/migrie/f/quake-to…
zadjii-msft Apr 28, 2021
6c424f7
pr nits
zadjii-msft Apr 28, 2021
387d675
Merge branch 'dev/migrie/f/quake-toCurrent-desktop' into dev/migrie/f…
zadjii-msft Apr 28, 2021
f190576
Merge branch 'dev/migrie/f/quake-toggleVisibility' into dev/migrie/f/…
zadjii-msft Apr 28, 2021
960e1fa
Merge remote-tracking branch 'origin/main' into dev/migrie/f/quake-dr…
zadjii-msft Apr 29, 2021
caeb17f
Merge remote-tracking branch 'origin/main' into dev/migrie/f/quake-dr…
zadjii-msft May 13, 2021
2d7ed8d
Merge remote-tracking branch 'origin/main' into dev/migrie/f/quake-dr…
zadjii-msft May 17, 2021
f4c9993
Do the windowplacement thing
zadjii-msft May 17, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/actions/spelling/dictionary/apis.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ HIGHCONTRASTON
HIGHCONTRASTW
hotkeys
href
hrgn
IActivation
IApp
IAppearance
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/Remoting/Peasant.idl
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ namespace Microsoft.Terminal.Remoting
SummonWindowBehavior();
Boolean MoveToCurrentDesktop;
Boolean ToggleVisibility;
UInt32 DropdownDuration;
// Other options:
// * CurrentMonitor
}
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/Remoting/SummonWindowBehavior.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
SummonWindowBehavior() = default;
WINRT_PROPERTY(bool, MoveToCurrentDesktop, true);
WINRT_PROPERTY(bool, ToggleVisibility, true);
WINRT_PROPERTY(uint32_t, DropdownDuration, 0);

public:
SummonWindowBehavior(const Remoting::SummonWindowBehavior& other) :
_MoveToCurrentDesktop{ other.MoveToCurrentDesktop() },
_DropdownDuration{ other.DropdownDuration() },
_ToggleVisibility{ other.ToggleVisibility() } {};
};
}
Expand Down
8 changes: 8 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1159,10 +1159,12 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
WINRT_PROPERTY(winrt::hstring, Name, L"");
WINRT_PROPERTY(Model::DesktopBehavior, Desktop, Model::DesktopBehavior::ToCurrent);
WINRT_PROPERTY(bool, ToggleVisibility, true);
WINRT_PROPERTY(uint32_t, DropdownDuration, 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make the default value something nice to make it look relatively modern? I assume '0' means that it'll just pop up immediately and not animate.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea so now we're getting into the subjective realm - IMO the normal min/maximize behavior looks better than the dropdown. The animation seems more gimmicky - good for literally "quake mode", but seems more annoying for the others.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm gonna tap in @DHowett and @cinnamon-msft, since:

  • this is the most contentious part of this PR
  • someone wants this by next week
  • whenever there's a discussion about a setting, it's always you three

I'd feel more comfortable making dropdown the default if the whole window could animate. But since it can't then this almost feels more experimental. That's why I'm thinking we should leave the default 0. It'll still play the normal Windows "minimize" and "restore" animations that a window would usually get with "dropdownDuration": 0.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think since the animation is requested, we can put it in for now. Then we can test it/play with it and if we don't like it we can just set it back to 0 in a follow up before 1.9?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's always you three

lol


static constexpr std::string_view NameKey{ "name" };
static constexpr std::string_view DesktopKey{ "desktop" };
static constexpr std::string_view ToggleVisibilityKey{ "toggleVisibility" };
static constexpr std::string_view DropdownDurationKey{ "dropdownDuration" };

public:
hstring GenerateName() const;
Expand All @@ -1173,6 +1175,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
return otherAsUs->_Name == _Name &&
otherAsUs->_Desktop == _Desktop &&
otherAsUs->_DropdownDuration == _DropdownDuration &&
otherAsUs->_ToggleVisibility == _ToggleVisibility;
}
return false;
Expand All @@ -1183,6 +1186,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
auto args = winrt::make_self<GlobalSummonArgs>();
JsonUtils::GetValueForKey(json, NameKey, args->_Name);
JsonUtils::GetValueForKey(json, DesktopKey, args->_Desktop);
JsonUtils::GetValueForKey(json, DropdownDurationKey, args->_DropdownDuration);
JsonUtils::GetValueForKey(json, ToggleVisibilityKey, args->_ToggleVisibility);
return { *args, {} };
}
Expand All @@ -1191,6 +1195,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
auto copy{ winrt::make_self<GlobalSummonArgs>() };
copy->_Name = _Name;
copy->_Desktop = _Desktop;
copy->_DropdownDuration = _DropdownDuration;
copy->_ToggleVisibility = _ToggleVisibility;
return *copy;
}
Expand All @@ -1200,7 +1205,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<GlobalSummonArgs>();
// We want to summon the window with the name "_quake" specifically.
args->_Name = QuakeWindowName;
// We want the window to dropdown, with a 200ms duration.
args->_DropdownDuration = 200;
return { *args, {} };
}
size_t Hash() const
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/ActionArgs.idl
Original file line number Diff line number Diff line change
Expand Up @@ -267,5 +267,6 @@ namespace Microsoft.Terminal.Settings.Model
String Name { get; };
DesktopBehavior Desktop { get; };
Boolean ToggleVisibility { get; };
UInt32 DropdownDuration { get; };
};
}
5 changes: 3 additions & 2 deletions src/cascadia/WindowsTerminal/AppHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ void AppHost::_DispatchCommandline(winrt::Windows::Foundation::IInspectable /*se
{
// Summon the window whenever we dispatch a commandline to it. This will
// make it obvious when a new tab/pane is created in a window.
_window->SummonWindow(false);
_window->SummonWindow(false, 0);
_logic.ExecuteCommandline(args.Commandline(), args.CurrentDirectory());
}

Expand Down Expand Up @@ -693,6 +693,7 @@ void AppHost::_GlobalHotkeyPressed(const long hotkeyIndex)
args.OnCurrentDesktop(summonArgs.Desktop() == Settings::Model::DesktopBehavior::OnCurrent);
args.SummonBehavior().MoveToCurrentDesktop(summonArgs.Desktop() == Settings::Model::DesktopBehavior::ToCurrent);
args.SummonBehavior().ToggleVisibility(summonArgs.ToggleVisibility());
args.SummonBehavior().DropdownDuration(summonArgs.DropdownDuration());

_windowManager.SummonWindow(args);
if (args.FoundMatch())
Expand Down Expand Up @@ -775,7 +776,7 @@ bool AppHost::_LazyLoadDesktopManager()
void AppHost::_HandleSummon(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const Remoting::SummonWindowBehavior& args)
{
_window->SummonWindow(args.ToggleVisibility());
_window->SummonWindow(args.ToggleVisibility(), args.DropdownDuration());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to just pass down the whole args at this point?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose not really

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not make IslandWindow more specific to Terminal. I'd prefer it to be less specific to Terminal IMO 😄


if (args != nullptr && args.MoveToCurrentDesktop())
{
Expand Down
175 changes: 152 additions & 23 deletions src/cascadia/WindowsTerminal/IslandWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1007,34 +1007,143 @@ void IslandWindow::SetGlobalHotkeys(const std::vector<winrt::Microsoft::Terminal
// - toggleVisibility: controls how we should behave when already in the foreground.
// Return Value:
// - <none>
winrt::fire_and_forget IslandWindow::SummonWindow(const bool toggleVisibility)
winrt::fire_and_forget IslandWindow::SummonWindow(const bool toggleVisibility, const uint32_t dropdownDuration)
{
// On the foreground thread:
co_await winrt::resume_foreground(_rootGrid.Dispatcher());

uint32_t actualDropdownDuration = dropdownDuration;
// If the user requested an animation, let's check if animations are enabled in the OS.
if (dropdownDuration > 0)
{
BOOL animationsEnabled = TRUE;
SystemParametersInfoW(SPI_GETCLIENTAREAANIMATION, 0, &animationsEnabled, 0);
if (!animationsEnabled)
{
// The OS has animations disabled - we should respect that and
// disable the animation here.
//
// We're doing this here, rather than in _doSlideAnimation, to
// preempt any other specific behavior that
// _globalActivateWindow/_globalDismissWindow might do if they think
// there should be an animation (like making the window appear with
// SetWindowPlacement rather than ShowWindow)
actualDropdownDuration = 0;
}
}

// * If the user doesn't want to toggleVisibility, then just always try to
// activate.
// * If the user does want to toggleVisibility, then dismiss the window if
// we're the current foreground window.
if (toggleVisibility && GetForegroundWindow() == _window.get())
{
_globalDismissWindow();
_globalDismissWindow(actualDropdownDuration);
}
else
{
_globalActivateWindow();
_globalActivateWindow(actualDropdownDuration);
}
}

// Method Description:
// - Helper for performing a sliding animation. This will animate our _Xaml
// Island_, either growing down or shrinking up, using SetWindowRgn.
// - This function does the entire animation on the main thread (the UI thread),
// and **DOES NOT YIELD IT**. The window will be animating for the entire
// duration of dropdownDuration.
// - At the end of the animation, we'll reset the window region, so that it's as
// if nothing occurred.
// Arguments:
// - dropdownDuration: The duration to play the animation, in milliseconds. If
// 0, we won't perform a dropdown animation.
// - down: if true, increase the height from top to bottom. otherwise, decrease
// the height, from bottom to top.
// Return Value:
// - <none>
void IslandWindow::_doSlideAnimation(const uint32_t dropdownDuration, const bool down)
{
til::rectangle fullWindowSize{ GetWindowRect() };
const double fullHeight = fullWindowSize.height<double>();

const double animationDuration = dropdownDuration; // use floating-point math throughout
const auto start = std::chrono::system_clock::now();

// Do at most dropdownDuration frames. After that, just bail straight to the
// final state.
for (uint32_t i = 0; i < dropdownDuration; i++)
{
const auto end = std::chrono::system_clock::now();
const auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
const double dt = ::base::saturated_cast<double>(millis.count());

if (dt > animationDuration)
{
break;
}

// If going down, increase the height over time. If going up, decrease the height.
const double currentHeight = ::base::saturated_cast<double>(
down ? ((dt / animationDuration) * fullHeight) :
((1.0 - (dt / animationDuration)) * fullHeight));

wil::unique_hrgn rgn{ CreateRectRgn(0,
0,
fullWindowSize.width<int>(),
::base::saturated_cast<int>(currentHeight)) };

SetWindowRgn(_interopWindowHandle, rgn.get(), true);

// Go immediately into another frame. This prevents the window from
// doing anything else (tearing our state). A Sleep() here will cause a
// weird stutter, and causes the animation to not be as smooth.
}

// Reset the window.
SetWindowRgn(_interopWindowHandle, nullptr, true);
}

void IslandWindow::_dropdownWindow(const uint32_t dropdownDuration)
{
// First, restore the window. SetWindowPlacement has a fun undocumented
// piece of functionality where it will restore the window position
// _without_ the animation, so use that instead of ShowWindow(SW_RESTORE).
WINDOWPLACEMENT wpc;
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
wpc.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(_window.get(), &wpc);
wpc.showCmd = SW_RESTORE;
SetWindowPlacement(_window.get(), &wpc);

// Now that we're visible, animate the dropdown.
_doSlideAnimation(dropdownDuration, true);
}

void IslandWindow::_slideUpWindow(const uint32_t dropdownDuration)
{
// First, animate the window sliding up.
_doSlideAnimation(dropdownDuration, false);

// Then, use SetWindowPlacement to minimize without the animation.
WINDOWPLACEMENT wpc;
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
wpc.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(_window.get(), &wpc);
wpc.showCmd = SW_MINIMIZE;
SetWindowPlacement(_window.get(), &wpc);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two seem very similar. If you add a second param const bool down (like in _doSlideAnimation), you can cut down on this repeated code.


// Method Description:
// - Force activate this window. This method will bring us to the foreground and
// activate us. If the window is minimized, it will restore the window. If the
// window is on another desktop, the OS will switch to that desktop.
// - If the window is minimized, and dropdownDuration is greater than 0, we'll
// perform a "slide in" animation. We won't do this if the window is already
// on the screen (since that seems silly).
// Arguments:
// - <none>
// - dropdownDuration: The duration to play the dropdown animation, in
// milliseconds. If 0, we won't perform a dropdown animation.
// Return Value:
// - <none>
void IslandWindow::_globalActivateWindow()
void IslandWindow::_globalActivateWindow(const uint32_t dropdownDuration)
{
// From: https://stackoverflow.com/a/59659421
// > The trick is to make windows ‘think’ that our process and the target
Expand All @@ -1045,34 +1154,54 @@ void IslandWindow::_globalActivateWindow()
// restore-down the window.
if (IsIconic(_window.get()))
{
LOG_IF_WIN32_BOOL_FALSE(ShowWindow(_window.get(), SW_RESTORE));
if (dropdownDuration > 0)
{
_dropdownWindow(dropdownDuration);
}
else
{
LOG_IF_WIN32_BOOL_FALSE(ShowWindow(_window.get(), SW_RESTORE));
}
}
else
{
const DWORD windowThreadProcessId = GetWindowThreadProcessId(GetForegroundWindow(), nullptr);
const DWORD currentThreadId = GetCurrentThreadId();

LOG_IF_WIN32_BOOL_FALSE(AttachThreadInput(windowThreadProcessId, currentThreadId, true));
// Just in case, add the thread detach as a scope_exit, to make _sure_ we do it.
auto detachThread = wil::scope_exit([windowThreadProcessId, currentThreadId]() {
LOG_IF_WIN32_BOOL_FALSE(AttachThreadInput(windowThreadProcessId, currentThreadId, false));
});
LOG_IF_WIN32_BOOL_FALSE(BringWindowToTop(_window.get()));
LOG_IF_WIN32_BOOL_FALSE(ShowWindow(_window.get(), SW_SHOW));

// Activate the window too. This will force us to the virtual desktop this
// window is on, if it's on another virtual desktop.
LOG_LAST_ERROR_IF_NULL(SetActiveWindow(_window.get()));
}
const DWORD windowThreadProcessId = GetWindowThreadProcessId(GetForegroundWindow(), nullptr);
const DWORD currentThreadId = GetCurrentThreadId();

LOG_IF_WIN32_BOOL_FALSE(AttachThreadInput(windowThreadProcessId, currentThreadId, true));
// Just in case, add the thread detach as a scope_exit, to make _sure_ we do it.
auto detachThread = wil::scope_exit([windowThreadProcessId, currentThreadId]() {
LOG_IF_WIN32_BOOL_FALSE(AttachThreadInput(windowThreadProcessId, currentThreadId, false));
});
LOG_IF_WIN32_BOOL_FALSE(BringWindowToTop(_window.get()));
LOG_IF_WIN32_BOOL_FALSE(ShowWindow(_window.get(), SW_SHOW));

// Activate the window too. This will force us to the virtual desktop this
// window is on, if it's on another virtual desktop.
LOG_LAST_ERROR_IF_NULL(SetActiveWindow(_window.get()));
}

// Method Description:
// - Minimize the window. This is called when the window is summoned, but is
// already active
// - If dropdownDuration is greater than 0, we'll perform a "slide in"
// animation, before minimizing the window.
// Arguments:
// - <none>
// - dropdownDuration: The duration to play the slide-up animation, in
// milliseconds. If 0, we won't perform a slide-up animation.
// Return Value:
// - <none>
void IslandWindow::_globalDismissWindow()
void IslandWindow::_globalDismissWindow(const uint32_t dropdownDuration)
{
LOG_IF_WIN32_BOOL_FALSE(ShowWindow(_window.get(), SW_MINIMIZE));
if (dropdownDuration > 0)
{
_slideUpWindow(dropdownDuration);
}
else
{
LOG_IF_WIN32_BOOL_FALSE(ShowWindow(_window.get(), SW_MINIMIZE));
}
}

bool IslandWindow::IsQuakeWindow() const noexcept
Expand Down
9 changes: 6 additions & 3 deletions src/cascadia/WindowsTerminal/IslandWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class IslandWindow :
void UnsetHotkeys(const std::vector<winrt::Microsoft::Terminal::Control::KeyChord>& hotkeyList);
void SetGlobalHotkeys(const std::vector<winrt::Microsoft::Terminal::Control::KeyChord>& hotkeyList);

winrt::fire_and_forget SummonWindow(const bool toggleVisibility);
winrt::fire_and_forget SummonWindow(const bool toggleVisibility, const uint32_t dropdownDuration);

bool IsQuakeWindow() const noexcept;
void IsQuakeWindow(bool isQuakeWindow) noexcept;
Expand Down Expand Up @@ -93,8 +93,11 @@ class IslandWindow :
void _OnGetMinMaxInfo(const WPARAM wParam, const LPARAM lParam);
long _calculateTotalSize(const bool isWidth, const long clientSize, const long nonClientSize);

void _globalActivateWindow();
void _globalDismissWindow();
void _globalActivateWindow(const uint32_t dropdownDuration);
void _dropdownWindow(const uint32_t dropdownDuration);
void _slideUpWindow(const uint32_t dropdownDuration);
void _doSlideAnimation(const uint32_t dropdownDuration, const bool down);
void _globalDismissWindow(const uint32_t dropdownDuration);

bool _isQuakeWindow{ false };
void _enterQuakeMode();
Expand Down