microsoft / microsoft/terminal

BringWindowToTop doesn't set active tab

Open
#18,429 0 comments 0 reactions 0 assignees View on GitHub
Area-Windowing Issue-Feature Product-Conpty
Dominant language
C++
Stars
105k
Forks
9.6k
Avg merge
3d 17h
Merged PRs (30d)
29

Description

### Description of the new feature

Currently, BringWindowToTop only brings the terminal window to the foreground; however, it does not activate the correct tab. In certain scenarios, the user's focus is not restored to the intended location if the active tab isn't the one that initiated the BringWindowToTop call.

Using the information from [this StackOverflow post](https://stackoverflow.com/a/59659421/3594197), I created a [functional example](https://github.com/zacuke/start-shim). The example demonstrates BringWindowToTop being used to ensure the user focus returns to the correct command line.

A current workaround for this limitation is to avoid using tabs altogether and stick with individual console windows instead.

As a side note, it would be nice if the built-in windows `start` command also had a `/refocus` option, so the functional example I created wouldn't be necessary. We could alias `start /wait /refocus myapp $*` to achieve this workflow behavior.

### Proposed technical implementation details

If BringWindowToTop() can't be hooked to automatically switch to the active tab, is there an alternative approach to programmatically identify the correct tab using some sort of ID or identifier, and then invoke a function to set that tab as active?

I see a possible way of doing it on line 940 in src/cascadia/TerminalControl/HwndTerminal.cpp
`void __stdcall TerminalSetFocus(void* terminal)` but it doesn't seem to me that is exposed as a public API.

Which leads me to this
```
/// This class is only left public since xaml cannot work with internal classes.
///
public class TerminalContainer : HwndHost
{
...
private IntPtr TerminalContainer_MessageHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (hwnd == this.hwnd)
{
switch ((NativeMethods.WindowMessage)msg)
{
case NativeMethods.WindowMessage.WM_SETFOCUS:
NativeMethods.TerminalSetFocus(this.terminal);
```

I can imagine trying to send the terminal host process some kind of IPC message which would trigger the TerminalSetFocus allowing us to call BringWindowToTop as well as this additional trick to bring the correct tab up too. But ideally, the host process detects BringWindowToTop() and also brings the tab to top.

Contributor guide

Open the contributing guide

Research direction

Start by reading src/cascadia/TerminalControl/HwndTerminal.cpp at TerminalSetFocus and reproduce the behavior with the linked start-shim functional example. Done means defining and implementing a supported way for BringWindowToTop, or an explicit API/IPC path, to activate the initiating tab, with the scenario verified.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
desktop, operating-systems
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.