System menu for Terminal shows up on wrong monitor #19948

Open
opened 2026-01-31 06:58:18 +00:00 by claunia · 7 comments
Owner

Originally created by @zadjii-msft on GitHub (May 24, 2023).

From MSFT:41390752, courtesy of @oldnewthing

Open Terminal maximized on right-hand monitor of dual-monitor system. Press Alt+Space to open the system menu.

Expect: Menu appears at the top left corner of the window.
Actual: Menu appears at the top right corner of the wrong monitor.

Screen shot shows menu opening on the wrong monitor.

Maybe this has to do with monitor layout? I suppose each of my monitors are set up a little higher than the one on the left:
image

Sure enough, this layout repros:
image

My monitors are nowhere near that exotically laid out.

image

When maximized on monitor 3 (the primary monitor), the system menu appears in the upper right of monitor 2.

Originally created by @zadjii-msft on GitHub (May 24, 2023). From MSFT:41390752, courtesy of @oldnewthing > Open Terminal maximized on right-hand monitor of dual-monitor system. Press Alt+Space to open the system menu. > > Expect: Menu appears at the top left corner of the window. > Actual: Menu appears at the top right corner of the wrong monitor. > > Screen shot shows menu opening on the wrong monitor. > Maybe this has to do with monitor layout? I suppose each of my monitors are set up a little higher than the one on the left: > ![image](https://github.com/microsoft/terminal/assets/18356694/a2a7aa0d-7b55-43bb-8e7a-eefc6abfab3e) > > Sure enough, this layout repros: > ![image](https://github.com/microsoft/terminal/assets/18356694/98cfc266-0ce5-4d5a-a64d-41ab960a2f51) > My monitors are nowhere near that exotically laid out. > > ![image](https://github.com/microsoft/terminal/assets/18356694/a70e9319-87e1-4001-8b14-baca8428c706) > > When maximized on monitor 3 (the primary monitor), the system menu appears in the upper right of monitor 2.
claunia added the Help WantedIssue-BugIn-PRProduct-TerminalArea-Windowing labels 2026-01-31 06:58:18 +00:00
Author
Owner

@michalnpl commented on GitHub (May 25, 2023):

I can confirm the monitor display layout is important. The issue does not repro on this layout:

image

but it reproes on both:

image

and

image

@michalnpl commented on GitHub (May 25, 2023): I can confirm the monitor display layout is important. The issue **does not repro on this layout**: ![image](https://github.com/microsoft/terminal/assets/25628581/7b805f0d-51ed-4b61-bc38-80885ddcbe5b) **but it reproes on both:** ![image](https://github.com/microsoft/terminal/assets/25628581/07a5f008-f604-45b6-a123-a76859ecd80e) **and** ![image](https://github.com/microsoft/terminal/assets/25628581/9abf70e1-428d-4a55-8faf-3c8d86b934a3)
Author
Owner

@michalnpl commented on GitHub (May 28, 2023):

Getting closer using Inspect. For this configuration:

image

getting :PowersShell" window (HWND?)

image

Answering only to the desktop being out of bounds... almost like there is padding or a margin.

@michalnpl commented on GitHub (May 28, 2023): Getting closer using Inspect. For this configuration: ![image](https://github.com/microsoft/terminal/assets/25628581/4435b501-0179-49e6-bd10-6f46bf2dd1d0) getting :PowersShell" window (HWND?) ![image](https://github.com/microsoft/terminal/assets/25628581/ebce0c20-f4ba-4f9a-b0fa-3f5f4cb7ae00) Answering only to the desktop being out of bounds... almost like there is padding or a margin.
Author
Owner

@oldnewthing commented on GitHub (May 29, 2023):

Okay, I see what's going on. You are manually showing the system menu at the upper left corner of the GetWindowRect and didn't take into account the fact that maximized windows have borders which extend beyond the monitor. It never occurred to me that you would try to show the system menu yourself instead of just letting DefWindowProc do it. (Why not just let DefWindowProc do it?)

This also explains why the system menu shows too high. Regular apps show the system menu below the caption, but Terminal shows it over the caption. Put the system menu at the upper left client pixel (not the upper left window pixel) and I think you'll be all good again.

@oldnewthing commented on GitHub (May 29, 2023): Okay, I see what's going on. You are [manually showing the system menu at the upper left corner of the GetWindowRect](https://github.com/microsoft/terminal/blob/c9e993a38ec04833e15edac230300948a0fab83b/src/cascadia/WindowsTerminal/IslandWindow.cpp#L1822) and didn't take into account the fact that [maximized windows have borders which extend beyond the monitor](https://devblogs.microsoft.com/oldnewthing/20150304-00/?p=44543). It never occurred to me that you would try to show the system menu yourself instead of just letting DefWindowProc do it. (Why not just let DefWindowProc do it?) This also explains why the system menu shows too high. Regular apps show the system menu below the caption, but Terminal shows it *over* the caption. Put the system menu at the upper left client pixel (not the upper left window pixel) and I think you'll be all good again.
Author
Owner

@michalnpl commented on GitHub (May 31, 2023):

I've developed a fix for this issue. I tweaked the position calculations for the system menu, and now it behaves properly. I also added a bunch of error checking and error logging. Thanks for the pointers @oldnewthing!

I've tested manually all the cases that were working just fine before (and they're still good, no worries there) and also with the situations that were causing trouble. Happy to say it's all working correctly now.

I've run the TAEF tests too, and everything came out clean. I also checked the fullscreen mode (F11), and it's all good.

I lack insight into why DefWindowProc doesn't open system menu, but that is recognized in code:

c9e993a38e/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp (L955)

case WM_NCRBUTTONUP:
        // The `DefWindowProc` function doesn't open the system menu for some
        // reason so we have to do it ourselves.
        if (wParam == HTCAPTION)
        {
            OpenSystemMenu(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
        }

Maybe @zadjii-msft can help here; it may be the same reason why some events have to be routed manually.

I was also wondering if this behavior of "borders which extend beyond the monitor" is caused by backward compatibility from DUI or DWM...

Anyway, I'd like to go ahead and create a PR with the fix if that's OK?

@michalnpl commented on GitHub (May 31, 2023): I've developed a fix for this issue. I tweaked the position calculations for the system menu, and now it behaves properly. I also added a bunch of error checking and error logging. Thanks for the pointers @oldnewthing! I've tested manually all the cases that were working just fine before (and they're still good, no worries there) and also with the situations that were causing trouble. Happy to say it's all working correctly now. I've run the TAEF tests too, and everything came out clean. I also checked the fullscreen mode (F11), and it's all good. I lack insight into why **DefWindowProc** doesn't open system menu, but that is recognized in code: https://github.com/microsoft/terminal/blob/c9e993a38ec04833e15edac230300948a0fab83b/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp#L955 ``` case WM_NCRBUTTONUP: // The `DefWindowProc` function doesn't open the system menu for some // reason so we have to do it ourselves. if (wParam == HTCAPTION) { OpenSystemMenu(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); } ``` Maybe @zadjii-msft can help here; it may be the same reason why some events have to be routed manually. I was also wondering if this behavior of "borders which extend beyond the monitor" is caused by backward compatibility from DUI or DWM... Anyway, I'd like to go ahead and create a PR with the fix if that's OK?
Author
Owner

@michalnpl commented on GitHub (Jun 16, 2023):

Ping.

@michalnpl commented on GitHub (Jun 16, 2023): Ping.
Author
Owner

@DHowett commented on GitHub (Jun 16, 2023):

Oh, sorry @michalnpl! Mike went on paternity leave recently. I'm certain this is a fine fix--it is at least better than what we have--and would be glad to see it in PR. Please do.

Why not just let DefWindowProc do it?

As we always say, "I think there was a reason!" This was probably an early casualty of the weird stuff we had to do to interact with the DirectInput capture site that was making our lives difficult when we moved the tabs into the non-client area1 .

OpenSystemMenu is the handler for the user-rebindable "open system menu" action, which they can unbind from Alt+Space. I'm not certain whether we can have DefWindowProc handle it for us (though I would very much like to!)


  1. which happened long before WinAppSDK/WinUI3 offered support for it, so it's very much homebrew and very much rough-hewn ↩︎

@DHowett commented on GitHub (Jun 16, 2023): Oh, sorry @michalnpl! Mike went on paternity leave recently. I'm certain this is a fine fix--it is at least better than what we have--and would be glad to see it in PR. Please do. > Why not just let DefWindowProc do it? As we always say, "I think there was a reason!" This was probably an early casualty of the weird stuff we had to do to interact with the DirectInput capture site that was making our lives difficult when we moved the tabs into the non-client area[^1]. `OpenSystemMenu` is the handler for the user-rebindable "open system menu" action, which they can unbind from <kbd>Alt+Space</kbd>. I'm not certain whether we can have DefWindowProc handle it for us (though I would very much like to!) [^1]: which happened long before WinAppSDK/WinUI3 offered support for it, so it's very much homebrew and very much rough-hewn
Author
Owner

@michalnpl commented on GitHub (Jul 5, 2023):

Thanks @DHowett , PR created.

@michalnpl commented on GitHub (Jul 5, 2023): Thanks @DHowett , PR created.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#19948