[PR #9977] Add property to control dropdown speed of global summon #27847

Closed
opened 2026-01-31 09:24:37 +00:00 by claunia · 0 comments
Owner

Original Pull Request: https://github.com/microsoft/terminal/pull/9977

State: closed
Merged: Yes


Summary of the Pull Request

Adds the dropdownDuration property to globalSummon. This controls how fast the window appears on the screen when summoned from minimized. It similarly controls the speed for sliding out of view when the window is dismissed with "toggleVisibility": true.

dropdownDuration specifies the duration in milliseconds. This defaults to 0 for globalSummon, and defaults to 200 for quakeMode. 200 was picked because, according to AnimateWindow:

Typically, an animation takes 200 milliseconds to play.

Do note that you won't be able to interact with the window during the animation! Input sent during the dropdown will arrive at the end of the animation, but input sent during the slide-up won't. Avoid setting this to large values!

The gifs are in Teams.

References

PR Checklist

Detailed Description of the Pull Request / Additional comments

I had the following previously in the doc comments, but it feels better in the PR body:

  • This was chosen because it was easier to implement and generally nicer than:
    • AnimateWindow, which would show the window borders for the duration of
      the animation, and occasionally just plain not work. Additionally, for
      AnimateWindow to work, the window much not be visible, so we'd need to
      first restore the window, then hide it, then animate it. That would flash
      the taskbar.
    • SetWindowRgn on the root HWND, which caused the xaml content to shift to
      the left, and caused a black bar to be drawn on the right of the window.
      Presumably, SetWindowRgn and DwmExtendFrameIntoClientArea did not play
      well with each other.
    • SetWindowPos(..., SWP_NOSENDCHANGING), which worked the absolute best for
      longer animations, and is the closest to the actual implementation of
      AnimateWindow. This would resize the ROOT window, without sending resizes
      to the XAML island, allowing the content to not reflow. but for a
      duration of 200ms, would only ever display ~2 frames. That's basically
      not even animation anymore, it's now just an "appear". Since that's how
      long the default animation is, if felt silly to have it basically not
      work by default.
  • If a future reader would like to implement this better, they should feel
    free to
    , and not mistake my notes here as expertise. These are research
    notes into the dark and terrible land that is Win32 programming. I'm no expert.

Validation Steps Performed

This is the blob of json I'm testing with these days:

        { "keys": "ctrl+`", "command": { "action": "quakeMode" } },
        { "keys": "ctrl+1", "command": { "action": "globalSummon" } },
        // { "keys": "ctrl+2", "command": { "action": "globalSummon", "desktop": "toCurrent" } },
        // { "keys": "ctrl+2", "command": { "action": "globalSummon", "toggleVisibility": false } },
        { "keys": "ctrl+2", "command": { "action": "globalSummon", "dropdownDuration": 2000 } },
        { "keys": "ctrl+3", "command": { "action": "globalSummon", "desktop": "onCurrent" } },
        { "keys": "ctrl+4", "command": { "action": "globalSummon", "desktop": "any" } },
  • ctrl+` will summon the quake window with a quick animation
  • ctrl+2 will summon the window with a s l o w animation
**Original Pull Request:** https://github.com/microsoft/terminal/pull/9977 **State:** closed **Merged:** Yes --- ## Summary of the Pull Request Adds the `dropdownDuration` property to `globalSummon`. This controls how fast the window appears on the screen when summoned from minimized. It similarly controls the speed for sliding out of view when the window is dismissed with `"toggleVisibility": true`. `dropdownDuration` specifies the duration in **milliseconds**. This defaults to `0` for `globalSummon`, and defaults to `200` for `quakeMode`. 200 was picked because, according to [`AnimateWindow`](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-animatewindow): > Typically, an animation takes 200 milliseconds to play. Do note that you won't be able to interact with the window during the animation! Input sent during the dropdown will arrive at the end of the animation, but input sent during the slide-up _won't_. Avoid setting this to large values! The gifs are in Teams. ## References * Original thread: #653 * Spec: #9274 * megathread: #8888 ## PR Checklist * [x] Closes https://github.com/microsoft/terminal/projects/5#card-59030824 * [x] I work here * [x] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments I had the following previously in the doc comments, but it feels better in the PR body: - This was chosen because it was easier to implement and generally nicer than: * `AnimateWindow`, which would show the window borders for the duration of the animation, and occasionally just plain not work. Additionally, for `AnimateWindow` to work, the window much not be visible, so we'd need to first restore the window, then hide it, then animate it. That would flash the taskbar. * `SetWindowRgn` on the root HWND, which caused the xaml content to shift to the left, and caused a black bar to be drawn on the right of the window. Presumably, `SetWindowRgn` and `DwmExtendFrameIntoClientArea` did not play well with each other. * `SetWindowPos(..., SWP_NOSENDCHANGING)`, which worked the absolute best for longer animations, and is the closest to the actual implementation of `AnimateWindow`. This would resize the ROOT window, without sending resizes to the XAML island, allowing the content to _not_ reflow. but for a duration of 200ms, would only ever display ~2 frames. That's basically not even animation anymore, it's now just an "appear". Since that's how long the default animation is, if felt silly to have it basically not work by default. - If a future reader would like to implement this better, **they should feel free to**, and not mistake my notes here as expertise. These are research notes into the dark and terrible land that is Win32 programming. I'm no expert. ## Validation Steps Performed This is the blob of json I'm testing with these days: ```jsonc { "keys": "ctrl+`", "command": { "action": "quakeMode" } }, { "keys": "ctrl+1", "command": { "action": "globalSummon" } }, // { "keys": "ctrl+2", "command": { "action": "globalSummon", "desktop": "toCurrent" } }, // { "keys": "ctrl+2", "command": { "action": "globalSummon", "toggleVisibility": false } }, { "keys": "ctrl+2", "command": { "action": "globalSummon", "dropdownDuration": 2000 } }, { "keys": "ctrl+3", "command": { "action": "globalSummon", "desktop": "onCurrent" } }, { "keys": "ctrl+4", "command": { "action": "globalSummon", "desktop": "any" } }, ``` * <kbd>ctrl+\`</kbd> will summon the quake window with a _quick_ animation * <kbd>ctrl+2</kbd> will summon the window with a s l o w animation
claunia added the pull-request label 2026-01-31 09:24:37 +00:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#27847