TC windows jump on RDP reconnect

Moderators: Hacker, petermad, Stefan2, white

Post Reply
igor3v
Junior Member
Junior Member
Posts: 10
Joined: 2024-08-13, 14:52 UTC

TC windows jump on RDP reconnect

Post by *igor3v »

TC 11.03 64 bit , on Windows 10 x64, both client and server side.
When I reconnect to my remote session, Total Commander windows on non-primary monitors tend to jump and change size.

To be more specific, here's an experiment:
  1. I have 3 monitors connected to my local system. The monitor2 is in the center, this is the Windows "main monitor", and there's the Windows Taskbar on it.
  2. I connect to a remote system with the standard Windows RDP.
  3. Just in case, I open 1 TC instance, position it in the lower-half of the monitor1 (using the AHK script below)(this could be reproduced manually, but the pixel-perfect positioning is painful). I click "Configuration->Save Position" close TC and then reopen to make sure it remembers the position. Then I close this TC.
  4. I open 6 TC instances, position them like this:
    1. upper-half of the monitor1
    2. lower-half of the monitor1
    3. upper-half of the monitor2
    4. lower-half of the monitor2
    5. upper-half of the monitor3
    6. lower-half of the monitor3
  5. I close my RDP session window
  6. Almost immediately, I reconnect to the same RDP session (nothing changed in the local monitor config)
  7. As a result:
    1. remains almost in place, but shrinks a bit - now there are small gaps in between the window and the monitor edges
    2. jumps to the upper half of the monitor1, exactly the same position as the previous window
    3. everything looks OK - the window is exactly where it was
    4. everything looks OK - the window is exactly where it was
    5. remains almost in place, but shrinks a bit - now there are small gaps in between the window and the monitor edges
    6. jumps to the upper half of the monitor3, exactly the same position as the previous window
  8. I tried few other scenarios.. But the behavior seem to be erratic and not always reproducible. I'm not really sure why. Maybe I'm missing something.
  9. I try to reproduce the same with "notepad.exe" windows, but they keep their positions perfectly.
I found File name column width on RDP reconnect thread and tried to use Spy++ to catch the WM_DISPLAYCHANGE on RDP reconnect. Although there are ~170 lines in that log after the relogin, there's no WM_DISPLAYCHANGE in there.

My monitor config is as follows:

Code: Select all

PS C:\temp> Add-Type -AssemblyName System.Windows.Forms
PS C:\temp> [System.Windows.Forms.Screen]::AllScreens

BitsPerPixel : 32
Bounds       : {X=0,Y=0,Width=3840,Height=2160}
DeviceName   : \\.\DISPLAY5
Primary      : True
WorkingArea  : {X=0,Y=0,Width=3778,Height=2160}

BitsPerPixel : 32
Bounds       : {X=-1200,Y=0,Width=1200,Height=1920}
DeviceName   : \\.\DISPLAY7
Primary      : False
WorkingArea  : {X=-1200,Y=0,Width=1200,Height=1920}

BitsPerPixel : 32
Bounds       : {X=3840,Y=0,Width=1200,Height=1920}
DeviceName   : \\.\DISPLAY6
Primary      : False
WorkingArea  : {X=3840,Y=0,Width=1200,Height=1920}
The AHK script:

Code: Select all

UpDownSnap(Direction)
{
  ; WinMaximize("A")
  WinGetPos(&x, &y, &w, &h, "a", , ,)
  monitorCount := MonitorGetCount()
  refArea := 0
  Loop monitorCount
  {
    MonitorGetWorkArea(A_Index, &mLeft, &mTop, &mRight, &mBottom)
	xo := Max(0, Min(x + w, mRight) - Max(x, mLeft))
	yo := Max(0, Min(y + h, mBottom) - Max(y, mTop))
	
    ; SysGet, m, MonitorWorkArea, %A_Index%
    ;xo := Max(0, Min(x + w, mRight) - Max(x, mLeft))
    ;yo := Max(0, Min(y + h, mBottom) - Max(y, mTop))
    area := xo * yo
    if (area > refArea)
    {
      monTop := mTop
      monBottom := mBottom
      monLeft := mLeft
      monRight := mRight
      refArea := area
    }
  }

  ; If the refArea is still equal to 0, the window does
  ; not overlap with any monitors. Wat?
  if (refArea > 0)
  {
  	; Need some "boder width" to compensate for invisible window boders, for all sides except top
	; https://autohotkey.com/boards/viewtopic.php?p=87378#p87378
	bw := 7  
  
    if (direction = 1)
      newY := monTop
    Else
      newY := (monBottom - monTop) / 2 + monTop
	  
    WinMove(monLeft-bw, newY, (monRight - monLeft)+bw*2, (monBottom - monTop) / 2 + bw, "a")
	
	; Log("Moving to x=" monLeft)
	; Log("Moving to monTop=" monTop)
  }
}
^#Up::UpDownSnap(1)
^#Down::UpDownSnap(0)
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48559
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: TC windows jump on RDP reconnect

Post by *ghisler(Author) »

Total Commander listens to WM_DISPLAYCHANGE and adjusts its window to the changed dimensions. This behaviour is intentional and not a bug. You can save the window position and size for each screen dimensions separately. Just resize the window to the desired dimensions and choose menu Configuration - Save position.
Author of Total Commander
https://www.ghisler.com
User avatar
AntonyD
Power Member
Power Member
Posts: 1313
Joined: 2006-11-04, 15:30 UTC
Location: Russian Federation

Re: TC windows jump on RDP reconnect

Post by *AntonyD »

2ghisler(Author)
I found File name column width on RDP reconnect thread and tried to use Spy++ to catch the WM_DISPLAYCHANGE on RDP reconnect. Although there are ~170 lines in that log after the relogin, there's no WM_DISPLAYCHANGE in there.
Maybe we are reading different posts? But our friend wrote that the expected message simply DIDN’T HAPPEN in principle!
Those - what is being discussed is not the fact that for some reason Total reacts to it, but precisely the opposite - it was expected
that it would REACT, but the wm_message itself never arrived.
Hence the conclusion - since for the same notepad.exe it is possible to achieve correct memorization of the window size/position - this
means that It's not enough to just follow this one wm_message, it looks like something additional needs to be done.

Or even the opposite is true - you are ALREADY monitoring some other incoming wm_message, but you are using it incorrectly/at the wrong time.
Because the final result of current work of the code is the fact that Total's main window still moves somewhere/changes its size on its own.
The man also described this in detail in his post.

He also mentioned that he had already USED the sequence of steps you recommended to remember the size and position.
I click "Configuration->Save Position"
BUT it doesn’t help anyway - and he described exactly: what and how exactly is not working, what and how is(not) changing.
#146217 personal license
browny
Senior Member
Senior Member
Posts: 298
Joined: 2007-09-10, 13:19 UTC

Re: TC windows jump on RDP reconnect

Post by *browny »

WM_DISPLAYCHANGE is most certainly sent on RDP (re)connect, as well as in case of a few other events.
The main application window receives this message and should do adjustments.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48559
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: TC windows jump on RDP reconnect

Post by *ghisler(Author) »

WM_DISPLAYCHANGE is most certainly sent on RDP (re)connect
That's also my experience.
Author of Total Commander
https://www.ghisler.com
igor3v
Junior Member
Junior Member
Posts: 10
Joined: 2024-08-13, 14:52 UTC

Re: TC windows jump on RDP reconnect

Post by *igor3v »

ghisler(Author) wrote: 2024-09-09, 16:31 UTC You can save the window position and size for each screen dimensions separately. Just resize the window to the desired dimensions and choose menu Configuration - Save position.
The thing is, the "saved" position still isn't reproduced either. Here's a simplified experiment:
  1. I connect to the remote PC via RDP (the entire setup is the same as originally described).
  2. I resize a TC window so that it occupies the entire upper half of the monitor3.
  3. I do "Configuration - Save position".
  4. I open a new TC window. It perfectly reproduces the position of the 1st TC window - great. Then I close this new window.
  5. I disconnect from RDP
  6. I reconnect to the RDP session. And... There's now a gap in between the screen edges and the TC window (that is, the position of the Window changed a bit, despite the monitor configuration is the same as before).
  7. I open a new TC window. It perfectly reproduces the position of the old TC window (no gaps).

browny wrote: 2024-09-10, 17:48 UTC WM_DISPLAYCHANGE is most certainly sent on RDP (re)connect
I just carried out the same experiment again, and now I do see WM_DISPLAYCHANGE messages on RDP reconnect.
I'm not sure what was wrong before. Maybe I just wasn't selecting the main TC window... :oops:

Interestingly, the message parameters are related to monitor2 (the main monitor), while actually this TC window is on monitor3

Code: Select all

<000180> 000C2010 S WM_DISPLAYCHANGE cBitsPerPixel:32 cxScreen:3840 cyScreen:2160
<000148> 000117AC R WM_DISPLAYCHANGE
Maybe this is somehow related to that TC windows on the monitor2 are not "jumping" or "resizing" on RDP reconnection.

Moreover, with Spy++ active, the RDP reconnection process slows down to a slideshow like this (simplified):
  1. Monitor2 starts to show something. Both other monitors are just black. Everything on Monitor2 is messed up: taskbar position, the position of all windows and etc. It resembles the attempt to scale down the combined picture from all the 3 monitors to make it fit into just this monitor.
  2. WM_DISPLAYCHANGE happens
  3. After a couple of seconds, monitor 3 starts to show something (not the "final result" yet)
  4. After a couple of seconds, monitor 1 starts to show something (not the "final result" yet)
  5. TC window in question is moved to monitor3. Its size is still correct (no gaps).
  6. TC window is resized (gaps are added to the right and to the left of it).
  7. Some other things happen (e.g. Windows taskbar is finally getting rendered in the appropriate position).
  8. Everything finally looks like normal.
Without Spy++ running, nothing like this is visible. But probably all this still momentarily happens under the hood.

Provided that I see only one pair of messages ("S"+"R") in the Spy++, maybe TC runs "GetMonitorInfo" (or something) before the "final monitor configuration" is actually established.
browny
Senior Member
Senior Member
Posts: 298
Joined: 2007-09-10, 13:19 UTC

Re: TC windows jump on RDP reconnect

Post by *browny »

TC's manifest has this element:
<dpiAware>true</dpiAware>
Such setting should be good enough for single monitor configurations (provided that application code will handle DPI change).

According to MS docs, for muli-monitor configurations, string should be true/pm or per monitor.
Another possibility - element dpiAwareness with permonitor or permonitorv2 values.
Elements gdiScaling and highResolutionScrollingAware might be needed too.
Of course, application code has to be modified.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48559
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: TC windows jump on RDP reconnect

Post by *ghisler(Author) »

If the monitor position or size changes between sessions, the saved window dimensions cannot be restored. You can try saving the position again when the window appears in the wrong location.
Author of Total Commander
https://www.ghisler.com
igor3v
Junior Member
Junior Member
Posts: 10
Joined: 2024-08-13, 14:52 UTC

Re: TC windows jump on RDP reconnect

Post by *igor3v »

2ghisler(Author)
  1. I never changed the monitor positions/sizes in my experiments.
  2. Virtually (due to some implementation details of the Windows RDP client/server for the multi-monitor case), monitor positions/sizes might change back and forth momentarily during the RDP (re)connection process, but the "final configuration" is the same.
  3. The "notepad.exe" (as well as all other apps) demonstrates that it is able to perfectly possible for a windows to restore its position after the RDP re-connection. AFAIU, there's some conflict between what Windows is doing and what TC is doing, that makes it impossible for TC to restore its window position correctly for non-main monitors, yep.
  4. If I save the "wrong location" (the one that I get after TC window jumped on RDP reconnect, e.g. "upper half of the monitor3, with gaps around the window"), and then disconnect that reconnect RDP again, the TC window remains in this position (this is a perfectly correct behavior, but this is not a very practical scenario). If I move this TC window (to the bottom half of this monitor) and reconnect - it jumps to the remembered position. If I open a second TC window (and position both TC windows anyhow), they both end up in the same "remembered position" on RDP reconnect.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48559
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: TC windows jump on RDP reconnect

Post by *ghisler(Author) »

Sorry, I can't find a way to reproduce your problem.
Author of Total Commander
https://www.ghisler.com
Post Reply