Page 1 of 1

A fix for Windows 10 invisible borders (and Aero Snap)

Posted: 05 Jan 2017, 09:32
by jimhoyle
I got tired of the Windows 10 problem where the OS has invisible borders around windows. Which results in a problem where windows snapped to screen edge (or to the taskbar at bottom) will be detached from the edge after quitting and reloading the window. So I made a fix for that. I only played around with for a few minutes so it may have bugs etc., but so far it has worked for me! If there is a better way to do this, please let me know. This is just a chewing gum workaround.

Code: Select all

; ShellMessage code to be put to the auto-exec part
Gui +LastFound
hWnd := WinExist()
DllCall( "RegisterShellHookWindow", UInt,hWnd )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )

; Interface sizes (change that margin to whatever your invisible margin is!)
WinGetPos,,,, aeroTaskBarHeight, ahk_class Shell_TrayWnd
global aeroWin10margin := 10 ; In Windows 7 and 8 put here 0! In Win10 there is an invisible border margin (and margin's size depends on settings, a typical value is 10 or maybe more seldomly 15)!
global aeroTaskBarHeight := aeroTaskBarHeight-aeroWin10margin ; Taskbar also has the same invisible margin in Win10

ShellMessage( wParam,lParam )
{
	If ( wParam = 1 ) ;  wParam 1: HSHELL_WINDOWCREATED
	{
		WinWait, ahk_id %lParam%, , 2 ; wait for 2 secs for the window to get ready ; (otherwise it may not be ready for WinGetPos or WinGetTitle)
		WinGetPos, aeroX, aeroY, aeroWidth, aeroHeight, A ; get active window x,y,W,H
		If ( aeroHeight == A_ScreenHeight - aeroTaskBarHeight - aeroWin10margin || aeroHeight == A_ScreenHeight - aeroTaskBarHeight - aeroWin10margin + 1 || aeroY + aeroHeight = A_ScreenHeight - aeroTaskBarHeight - aeroWin10margin ) ; height has 1 x margin missing
		{
			aeroHeight := aeroHeight + aeroWin10margin
			If ( aeroX == 0 ) ; left edge = a margin away from screen left
			{
				aeroX := -aeroWin10margin
				aeroWidth := aeroWidth + aeroWin10margin
			}
			If ( aeroX + aeroWidth == A_ScreenWidth ) ; right edge = a margin away from screen right
			{
				aeroWidth := aeroWidth + aeroWin10margin
			}
			WinMove, A,, aeroX, aeroY, aeroWidth, aeroHeight ; apply changes
		}
		; the previous worked for IntelNUC but the following was needed for Samsung Book9
		Else If ( aeroX == 0 ) ; width has 1 x margin missing at left edge
		{
			aeroX := -aeroWin10margin
			WinMove, A,, aeroX, aeroY, aeroWidth, aeroHeight ; apply changes
		}
	}
}

Re: A fix for Windows 10 invisible borders (and Aero Snap)

Posted: 05 Jan 2017, 09:42
by jimhoyle
Also, to go with that, I can post the newest version of my Aero Snap Window Management where you can use #Left, #Right, #End etc. to snap your windows into neat positions (supports rotating between positions).

Code: Select all

; AERO SNAP WINDOW MANAGEMENT (2017-01-05)
; -----------------------------------------------------------------------------------------------------

; --- Aero window management auto-execute part starts ----------------- ;
WinGetPos,,,, aeroTaskBarHeight, ahk_class Shell_TrayWnd
global aeroWin10margin := 10 ; In Windows 7 and 8 put here 0! In Win10 there is an invisible border margin (and margin's size probably depends on settings, a typical value is 10)!
global aeroTaskBarHeight := aeroTaskBarHeight-aeroWin10margin ; Taskbar also has the same invisible margin in Win10
; --- Aero window management auto-execute part ends ----------------- ;

#End::
<^>!End::GoSub, AeroEndMaxHeight ; <^>! = AltGr, or more precisely left^ right! (which is same as AltGr)

^#End::
^<^>!End::GoSub, AeroEnd800 ; Change width to 800px

+#End::
+<^>!End::GoSub, AeroEnd ; Just center horizontally

#Left::
<^>!Left::GoSub, AeroLeft

#Right::
<^>!Right::GoSub, AeroRight

#Up::
<^>!Up::GoSub, AeroUpHeight ; for some reason AltGr+Up is interpreted as !AltGr+Up???

#Down::
<^>!Down::GoSub, AeroDownHeight

#+Left::
<^>!+Left::GoSub, AeroLeftNoResize

#+Right::
<^>!+Right::GoSub, AeroRightNoResize

<^>!+Down:: ; AltGr+RShift+Down
!#Left::GoSub, AeroLeftWidth ; AltGr+^ is not possible (that's why it's not here)

<^>!+Up:: ; AltGr+RShift+Up
!#Right::GoSub, AeroRightWidth ; AltGr+^ is not possible (that's why it's not here)

!#Up::GoSub, AeroUp

!#Down::GoSub, AeroDown

AeroLeft:
	WinGetTitle, currentWindow, A ; get the active window title
	WinGetPos, aeroX, aeroY, aeroWidth, aeroHeight, A ; get active window x,y,W,H
	WinGet, active_id, ID, A ; get active window ID (like 0xc00dc)
	; / if window is already exactly at left
	if (aeroX=0-aeroWin10margin && aeroY=0 && aeroWidth=(A_ScreenWidth/2)+aeroWin10margin*2 && aeroHeight=(A_ScreenHeight-aeroTaskBarHeight))
		WinMove, %currentWindow%,, (A_ScreenWidth/2)-aeroWin10margin, 0, (A_ScreenWidth/2)+aeroWin10margin*2, (A_ScreenHeight-aeroTaskBarHeight)
	; / if window is exactly at right
	else if (aeroX=(A_ScreenWidth/2)-aeroWin10margin && aeroY=0 && aeroWidth=(A_ScreenWidth/2)+aeroWin10margin*2 && aeroHeight=(A_ScreenHeight-aeroTaskBarHeight))
	{
		; / let's check if we have the center position memorized..
		aeroAlreadyMemorizedAt := 0 ; reset (not found memorized anywhere yet)
		loop
			if aeroAllMemorized%A_Index% ; we have to check if active ID already has a memory slot
			{ ; FYI: aeroAllMemorized[1..n] = "ID x y W H"
				stringsplit, tempArray, aeroAllMemorized%A_Index%, %A_Space%
				if (tempArray1=active_id)
				{
					aeroAlreadyMemorizedAt := %A_Index%
					break
				}
			} else break
		if (aeroAlreadyMemorizedAt=0) ; we didn't find center memorized, so let's just move the window to x-center
		{
			WinMove, %currentWindow%,, A_ScreenWidth/2 - aeroWidth/2, 0
		}
		else ; we found the center, so let's put the window at memorized center
		{
			stringsplit, tempArray, aeroAllMemorized%aeroAlreadyMemorizedAt%, %A_Space%
			WinMove, %currentWindow%,, tempArray2, tempArray3, tempArray4, tempArray5
		}
	}
	else ; we have to memorize this "center" position
	{
		aeroAlreadyMemorizedAt := 0 ; reset (not found memorized anywhere yet)
		memoryBankSize = 0 ; reset
		loop
			if aeroAllMemorized%A_Index% ; we have to check if active ID already has a memory slot
			{
				memoryBankSize++
				stringsplit, tempArray, aeroAllMemorized%A_Index%, %A_Space%
				if (tempArray1=active_id)
				{
					aeroAlreadyMemorizedAt := %A_Index%
					aeroAllMemorized%A_Index% := active_id . " " . aeroX . " " . aeroY . " " . aeroWidth . " " . aeroHeight
					break
				}
			} else break
		if (aeroAlreadyMemorizedAt=0) ; if we didn't find an old memory slot for this ID
		{
			memoryBankSize++ ; let's create a new memory slot
			aeroAllMemorized%memoryBankSize% := active_id . " " . aeroX . " " . aeroY . " " . aeroWidth . " " . aeroHeight
		}
	WinMove, %currentWindow%,, 0-aeroWin10margin, 0, (A_ScreenWidth/2)+aeroWin10margin*2, (A_ScreenHeight-aeroTaskBarHeight)
	}
Return

AeroRight:
	WinGetTitle, currentWindow, A ; get the active window title
	WinGetPos, aeroX, aeroY, aeroWidth, aeroHeight, A ; get active window x,y,W,H
	WinGet, active_id, ID, A ; get active window ID (like 0xc00dc)
	; / if window is already exactly at left
	if (aeroX=0-aeroWin10margin && aeroY=0 && aeroWidth=(A_ScreenWidth/2)+aeroWin10margin*2 && aeroHeight=(A_ScreenHeight-aeroTaskBarHeight))
	{
		; / let's check if we have the center position memorized..
		aeroAlreadyMemorizedAt := 0 ; reset (not found memorized anywhere yet)
		loop
			if aeroAllMemorized%A_Index% ; we have to check if active ID already has a memory slot
			{ ; FYI: aeroAllMemorized[1..n] = "ID x y W H"
				stringsplit, tempArray, aeroAllMemorized%A_Index%, %A_Space%
				if (tempArray1=active_id)
				{
					aeroAlreadyMemorizedAt := %A_Index%
					break
				}
			} else break
		if (aeroAlreadyMemorizedAt=0) ; we didn't find center memorized, so let's just move the window to x-center
			WinMove, %currentWindow%,, aeroWidth/2, 0
		else ; we found the center, so let's put the window at memorized center
		{
			stringsplit, tempArray, aeroAllMemorized%aeroAlreadyMemorizedAt%, %A_Space%
			WinMove, %currentWindow%,, tempArray2, tempArray3, tempArray4, tempArray5
		}
	}
	; / if window is exactly at right
	else if (aeroX=(A_ScreenWidth/2)-aeroWin10margin && aeroY=0 && aeroWidth=(A_ScreenWidth/2)+aeroWin10margin*2 && aeroHeight=(A_ScreenHeight-aeroTaskBarHeight))
		WinMove, %currentWindow%,, 0-aeroWin10margin, 0, (A_ScreenWidth/2)+aeroWin10margin*2, (A_ScreenHeight-aeroTaskBarHeight)
	else ; we have to memorize this "center" position
	{
		aeroAlreadyMemorizedAt := 0 ; reset (not found memorized anywhere yet)
		memoryBankSize = 0 ; reset
		loop
			if aeroAllMemorized%A_Index% ; we have to check if active ID already has a memory slot
			{
				memoryBankSize++
				stringsplit, tempArray, aeroAllMemorized%A_Index%, %A_Space%
				if (tempArray1=active_id)
				{
					aeroAlreadyMemorizedAt := %A_Index%
					aeroAllMemorized%A_Index% := active_id . " " . aeroX . " " . aeroY . " " . aeroWidth . " " . aeroHeight
					break
				}
			} else break
		if (aeroAlreadyMemorizedAt=0) ; if we didn't find an old memory slot for this ID
		{
			memoryBankSize++ ; let's create a new memory slot
			aeroAllMemorized%memoryBankSize% := active_id . " " . aeroX . " " . aeroY . " " . aeroWidth . " " . aeroHeight
		}
	WinMove, %currentWindow%,, (A_ScreenWidth/2)-aeroWin10margin, 0, (A_ScreenWidth/2)+aeroWin10margin*2, (A_ScreenHeight-aeroTaskBarHeight)
	}
Return

AeroUpHeight:
 ; just maximize (current window) vertically
	WinGetTitle, currentWindow, A ; get the active window title
	WinGetPos, aeroX, aeroY, aeroWidth, aeroHeight, A ; get active window x,y,W,H
	WinMove, %currentWindow%,, aeroX, 0, aeroWidth, A_ScreenHeight-aeroTaskBarHeight
Return

AeroDownHeight:
 ; vertically reduce (current window) size by 200px if its current height is more than 300px
	WinGetTitle, currentWindow, A ; get the active window title
	WinGetPos, aeroX, aeroY, aeroWidth, aeroHeight, A ; get active window x,y,W,H
	if aeroHeight >299
	WinMove, %currentWindow%,, aeroX, aeroY+100, aeroWidth, aeroHeight-200
Return

AeroEnd:
; #End CURRENT WINDOW LOCATION TO CENTER
	WinGetTitle, WinTitleHere, A
	WinGetPos,,, Width, Height, %WinTitleHere%
	WinMove, %WinTitleHere%,, (A_ScreenWidth/2)-(Width/2), ((A_ScreenHeight-%aeroTaskBarHeight%)/2)-(Height/2)
Return

AeroEnd800:
; #End CURRENT WINDOW LOCATION TO CENTER AND WIDTH 800
	WinGetTitle, WinTitleHere, A
	WinGetPos,,, Width, Height, %WinTitleHere%
	WinMove, %WinTitleHere%,, (A_ScreenWidth/2)-(800/2), ((A_ScreenHeight-%aeroTaskBarHeight%)/2)-(Height/2), 800
Return

AeroEndMaxHeight:
; #End CURRENT WINDOW LOCATION TO CENTER AND FIT VERTICALLY
	WinGetTitle, WinTitleHere, A
	WinGetPos,,, Width, Height, %WinTitleHere%
	WinMove, %WinTitleHere%,, (A_ScreenWidth/2)-(Width/2), 0,, A_ScreenHeight-aeroTaskBarHeight
Return

AeroLeftNoResize:
	WinGetTitle, currentWindow, A ; get the active window title
	WinGetPos, aeroX, aeroY, aeroWidth, aeroHeight, A ; get active window x,y,W,H
	WinGet, active_id, ID, A ; get active window ID (like 0xc00dc)
	; / if window is horizontally already at left
	if (aeroX=0-aeroWin10margin)
		WinMove, %currentWindow%,, (A_ScreenWidth-aeroWidth)+aeroWin10margin
	; / if window is horizontally already at right
	else if (aeroX=(A_ScreenWidth-aeroWidth)+aeroWin10margin)
	{
		; / let's check if we have the center position memorized..
		aeroAlreadyMemorizedAt := 0 ; reset (not found memorized anywhere yet)
		loop
			if aeroAllMemorized%A_Index% ; we have to check if active ID already has a memory slot
			{ ; FYI: aeroAllMemorized[1..n] = "ID x y W H"
				stringsplit, tempArray, aeroAllMemorized%A_Index%, %A_Space%
				if (tempArray1=active_id)
				{
					aeroAlreadyMemorizedAt := %A_Index%
					break
				}
			} else break
		stringsplit, tempArray, aeroAllMemorized%aeroAlreadyMemorizedAt%, %A_Space%
		if ((aeroAlreadyMemorizedAt=0) || (tempArray2=0 && tempArray3=aeroY && tempArray4=aeroWidth && tempArray5=aeroHeight) || (tempArray2=A_ScreenWidth-aeroWidth+aeroWin10margin && tempArray3=aeroY && tempArray4=aeroWidth && tempArray5=aeroHeight))
				; we didn't find center memorized, so let's just move the window to X-center
				; ..also if the memorized center position happens to be identical to left/right position
			WinMove, %currentWindow%,, A_ScreenWidth/2 - aeroWidth/2, 0 ; move to X-center
		else ; we found the center, so let's put the window at memorized center X (but current Y)
		{
			stringsplit, tempArray, aeroAllMemorized%aeroAlreadyMemorizedAt%, %A_Space%
			WinMove, %currentWindow%,, tempArray2, aeroY, aeroWidth, aeroHeight
		}
	}
	else ; we have to memorize this "center" position
	{
		aeroAlreadyMemorizedAt := 0 ; reset (not found memorized anywhere yet)
		memoryBankSize = 0 ; reset
		loop
			if aeroAllMemorized%A_Index% ; we have to check if active ID already has a memory slot
			{
				memoryBankSize++
				stringsplit, tempArray, aeroAllMemorized%A_Index%, %A_Space%
				if (tempArray1=active_id)
				{
					aeroAlreadyMemorizedAt := %A_Index%
					aeroAllMemorized%A_Index% := active_id . " " . aeroX . " " . aeroY . " " . aeroWidth . " " . aeroHeight
					break
				}
			} else break
		if (aeroAlreadyMemorizedAt=0) ; if we didn't find an old memory slot for this ID
		{
			memoryBankSize++ ; let's create a new memory slot
			aeroAllMemorized%memoryBankSize% := active_id . " " . aeroX . " " . aeroY . " " . aeroWidth . " " . aeroHeight
		}
	WinMove, %currentWindow%,, 0-aeroWin10margin
	}
Return

AeroRightNoResize:
	WinGetTitle, currentWindow, A ; get the active window title
	WinGetPos, aeroX, aeroY, aeroWidth, aeroHeight, A ; get active window x,y,W,H
	WinGet, active_id, ID, A ; get active window ID (like 0xc00dc)
	; / if window is horizontally already at left
	if (aeroX=0-aeroWin10margin)
	{
		; / let's check if we have the center position memorized..
		aeroAlreadyMemorizedAt := 0 ; reset (not found memorized anywhere yet)
		loop
			if aeroAllMemorized%A_Index% ; we have to check if active ID already has a memory slot
			{ ; FYI: aeroAllMemorized[1..n] = "ID x y W H"
				stringsplit, tempArray, aeroAllMemorized%A_Index%, %A_Space%
				if (tempArray1=active_id)
				{
					aeroAlreadyMemorizedAt := %A_Index%
					break
				}
			} else break
		if ((aeroAlreadyMemorizedAt=0) || (tempArray2=0 && tempArray3=aeroY && tempArray4=aeroWidth && tempArray5=aeroHeight) || (tempArray2=A_ScreenWidth-aeroWidth+aeroWin10margin && tempArray3=aeroY && tempArray4=aeroWidth && tempArray5=aeroHeight))
				; we didn't find center memorized, so let's just move the window to X-center
				; ..also if the memorized center position happens to be identical to left/right position
			WinMove, %currentWindow%,, A_ScreenWidth/2-aeroWidth/2, 0 ; move to X-center
		else ; we found the center, so let's put the window at memorized center X (but current Y)
		{
			stringsplit, tempArray, aeroAllMemorized%aeroAlreadyMemorizedAt%, %A_Space%
			WinMove, %currentWindow%,, tempArray2, aeroY, aeroWidth, aeroHeight
		}
	}
	; / if window is horizontally already at right
	else if (aeroX=(A_ScreenWidth-aeroWidth)+aeroWin10margin)
		WinMove, %currentWindow%,, 0-aeroWin10margin
	else ; we have to memorize this "center" position
	{
		aeroAlreadyMemorizedAt := 0 ; reset (not found memorized anywhere yet)
		memoryBankSize = 0 ; reset
		loop
			if aeroAllMemorized%A_Index% ; we have to check if active ID already has a memory slot
			{
				memoryBankSize++
				stringsplit, tempArray, aeroAllMemorized%A_Index%, %A_Space%
				if (tempArray1=active_id)
				{
					aeroAlreadyMemorizedAt := %A_Index%
					aeroAllMemorized%A_Index% := active_id . " " . aeroX . " " . aeroY . " " . aeroWidth . " " . aeroHeight
					break
				}
			} else break
		if (aeroAlreadyMemorizedAt=0) ; if we didn't find an old memory slot for this ID
		{
			memoryBankSize++ ; let's create a new memory slot
			aeroAllMemorized%memoryBankSize% := active_id . " " . aeroX . " " . aeroY . " " . aeroWidth . " " . aeroHeight
		}
	WinMove, %currentWindow%,, (A_ScreenWidth-aeroWidth)+aeroWin10margin
	}
Return

AeroLeftWidth:
	WinGetTitle, currentWindow, A ; get the active window title
	WinGetPos, aeroX, aeroY, aeroWidth, aeroHeight, A ; get active window x,y,W,H
	if (aeroX=0-aeroWin10margin) 
	; if window is at the left edge (0% space at the left) then narrow down to the left until 20%
	{ 
		if (aeroWidth+aeroWin10margin*2 > (Floor(A_ScreenWidth*0.20)+200))
		{
			WinMove, %currentWindow%,, aeroX, aeroY, (aeroWidth-200)+aeroWin10margin*2, aeroHeight
		}
	}
	else 
	if (aeroX < Floor((A_ScreenWidth-aeroWidth)/2)) ; if empty space at the left is less than at the right
	{ 
		WinMove, %currentWindow%,, 0-aeroWin10margin, aeroY, aeroWidth, aeroHeight
	}
	else ; space at the right was less, so let's max to 80% and leave 0% at the right
	{ 
		WinMove, %currentWindow%,, Floor(A_ScreenWidth*0.20)+aeroWin10margin, aeroY, Floor(A_ScreenWidth*0.80), aeroHeight
	}
Return

AeroRightWidth:
	WinGetTitle, currentWindow, A ; get the active window title
	WinGetPos, aeroX, aeroY, aeroWidth, aeroHeight, A ; get active window x,y,W,H
	if (aeroX=A_ScreenWidth+aeroWin10margin-aeroWidth) 
	; if window is at the right edge (0% space at the right) then narrow down to the right until 20%
	{ 
		if (aeroWidth+aeroWin10margin*2 > (Floor(A_ScreenWidth*0.20)+200))
			WinMove, %currentWindow%,, A_ScreenWidth-aeroWidth+200-aeroWin10margin, aeroY, aeroWidth-200+aeroWin10margin*2, aeroHeight
	}
	else 
	if (aeroX > Floor((A_ScreenWidth-aeroWidth)/2)) ; if empty space at the left is more than at the right
	{
		WinMove, %currentWindow%,, A_ScreenWidth-aeroWidth+aeroWin10margin, aeroY, aeroWidth, aeroHeight
	}
	else
	; ..or else horizontally 80%-maximize window so that there is 0% space at the left and 20% space at the right
	{
		WinMove, %currentWindow%,, 0-aeroWin10margin, aeroY, Floor(A_ScreenWidth*0.80), aeroHeight
	}
Return

AeroUp:
	WinGetTitle, currentWindow, A ; get the active window title
	WinGetPos, aeroX, aeroY, aeroWidth, aeroHeight, A ; get active window x,y,W,H
	WinMove, %currentWindow%,, aeroX, 0, aeroWidth, aeroHeight
Return

AeroDown:
	WinGetTitle, currentWindow, A ; get the active window title
	WinGetPos, aeroX, aeroY, aeroWidth, aeroHeight, A ; get active window x,y,W,H
	WinMove, %currentWindow%,, aeroX, A_ScreenHeight-aeroHeight-aeroTaskBarHeight, aeroWidth, aeroHeight
Return


Re: A fix for Windows 10 invisible borders (and Aero Snap)

Posted: 22 Jun 2017, 23:35
by APNBUSTER
Hi. I'm new on this forum, just because of this.

I've downloaded the text file, and it's converted in a .xml file (just in case). But, how can I apply these commands?

I suffer the same little problem on the windows.

Re: A fix for Windows 10 invisible borders (and Aero Snap)

Posted: 23 Jun 2017, 01:07
by RUNIE
APNBUSTER wrote:Hi. I'm new on this forum, just because of this.

I've downloaded the text file, and it's converted in a .xml file (just in case). But, how can I apply these commands?

I suffer the same little problem on the windows.
It's an AutoHotkey script (.ahk)

Re: A fix for Windows 10 invisible borders (and Aero Snap)

Posted: 23 Jun 2017, 18:33
by evilC
Ooh, hadn't noticed this, handy that someone bumped it.
Thanks for sharing, will give it a try.
FYI I have been tinkering with similar aero snap replacement scripts, and I think I may have just worked out a really cunning solution for how to describe your desired window size and position using hotkeys.

Re: A fix for Windows 10 invisible borders (and Aero Snap)

Posted: 24 Oct 2017, 12:07
by mankvl
This is why I love AHK :) Rly thanks for the code, this win 10 feature was driving me nuts, now I can work like before :)

Re: A fix for Windows 10 invisible borders (and Aero Snap)

Posted: 19 Feb 2018, 16:32
by jimhoyle
evilC, that code ("Window Tiling system") is very cool! However, what do you do to remove the invisible border problem on newly created windows? Such as when opening Chrome windows when starting Chrome (when the new windows have annoying margins against screen edges and taskbar)?

I updated my code quickly. It's still buggy and a chewing gum solution, but much better than nothing. The purpose of this code is to remove all annoying 10 pixel (configurable) margins from left/top/right of screen and at bottom on top of the taskbar. The window is checked everytime it's created or activated.

Code: Select all

; ShellMessage code to be put to the auto-exec part
Gui +LastFound
hWnd := WinExist()
DllCall( "RegisterShellHookWindow", UInt,hWnd )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )

; Interface sizes (change that margin to whatever your invisible margin is!)
WinGetPos,,,, aeroTaskBarHeight, ahk_class Shell_TrayWnd
global aeroWin10margin := 10 ; In Windows 7 and 8 put here 0! In Win10 there is an invisible border margin (and margin's size depends on settings, a typical value is 10 or maybe more seldomly 15)!
global aeroTaskBarHeight := aeroTaskBarHeight-aeroWin10margin ; Taskbar also has the same invisible margin in Win10

ShellMessage( wParam,lParam )
{
	If ( (wParam = 32772) || (wParam = 16) || (wParam = 1) ) 
	;  Win10 wParam 32772: window activated??
	;  Win10 wParam 16: window created??
	;  Win7?? wParam 1: HSHELL_WINDOWCREATED
	;  Win7?? wParam 4: window activated
	;  wParam 6: title of a window in the task bar has been redrawn??
	{
	  WinWait, ahk_id %lParam%, , 2 ; wait for 2 secs for the window to get ready	; (otherwise it may not be ready for WinGetPos or WinGetTitle)
	  WinGetPos, aeroX, aeroY, aeroWidth, aeroHeight, A ; get active window x,y,W,H
	  ;MsgBox aeroHeight=%aeroHeight%, A_ScreenHeight=%A_ScreenHeight%, aeroTaskBarHeight=%aeroTaskBarHeight%, 
	  aeroWin10margin=%aeroWin10margin%
	  If ( (aeroHeight == A_ScreenHeight - aeroTaskBarHeight - aeroWin10margin) || (aeroHeight == A_ScreenHeight - aeroTaskBarHeight - aeroWin10margin + 1) || (aeroHeight = A_ScreenHeight - aeroTaskBarHeight) || (aeroHeight = A_ScreenHeight - aeroTaskBarHeight + aeroWin10margin) )
	  {
	    If ( aeroHeight <= A_ScreenHeight - aeroTaskBarHeight - aeroWin10margin)
	      aeroHeight := aeroHeight + aeroWin10margin ; was necessary..
	    If ( aeroHeight == A_ScreenHeight - aeroTaskBarHeight - aeroWin10margin + 1)
	      aeroHeight := A_ScreenHeight - aeroTaskBarHeight ; was necessary..
	    If ( aeroX == 0 ) ; left edge = a margin away from screen left
	    {
	      aeroX := -aeroWin10margin
	      aeroWidth := aeroWidth + aeroWin10margin
	    }
	    If ( aeroX + aeroWidth == A_ScreenWidth ) ; right edge = a margin away from screen right
	    {
	      aeroWidth := aeroWidth + aeroWin10margin
	    }
	    WinMove, A,, aeroX, aeroY, aeroWidth, aeroHeight ; apply changes
	  }
	  Else If ( aeroX == 0 ) ; width has 1 x margin missing at left edge
	  {
	    aeroX := -aeroWin10margin
	    WinMove, A,, aeroX, aeroY, aeroWidth, aeroHeight ; apply changes
	  }
	}
}

Re: A fix for Windows 10 invisible borders (and Aero Snap)

Posted: 23 Feb 2018, 04:13
by mankvl
jimhoyle wrote:evilC, that code ("Window Tiling system") is very cool! However, what do you do to remove the invisible border problem on newly created windows? Such as when opening Chrome windows when starting Chrome (when the new windows have annoying margins against screen edges and taskbar)?

I updated my code quickly. It's still buggy and a chewing gum solution, but much better than nothing. The purpose of this code is to remove all annoying 10 pixel (configurable) margins from left/top/right of screen and at bottom on top of the taskbar. The window is checked everytime it's created or activated.

Code: Select all

; ShellMessage code to be put to the auto-exec part
Gui +LastFound
hWnd := WinExist()
DllCall( "RegisterShellHookWindow", UInt,hWnd )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )

; Interface sizes (change that margin to whatever your invisible margin is!)
WinGetPos,,,, aeroTaskBarHeight, ahk_class Shell_TrayWnd
global aeroWin10margin := 10 ; In Windows 7 and 8 put here 0! In Win10 there is an invisible border margin (and margin's size depends on settings, a typical value is 10 or maybe more seldomly 15)!
global aeroTaskBarHeight := aeroTaskBarHeight-aeroWin10margin ; Taskbar also has the same invisible margin in Win10

ShellMessage( wParam,lParam )
{
	If ( (wParam = 32772) || (wParam = 16) || (wParam = 1) ) 
	;  Win10 wParam 32772: window activated??
	;  Win10 wParam 16: window created??
	;  Win7?? wParam 1: HSHELL_WINDOWCREATED
	;  Win7?? wParam 4: window activated
	;  wParam 6: title of a window in the task bar has been redrawn??
	{
	  WinWait, ahk_id %lParam%, , 2 ; wait for 2 secs for the window to get ready	; (otherwise it may not be ready for WinGetPos or WinGetTitle)
	  WinGetPos, aeroX, aeroY, aeroWidth, aeroHeight, A ; get active window x,y,W,H
	  ;MsgBox aeroHeight=%aeroHeight%, A_ScreenHeight=%A_ScreenHeight%, aeroTaskBarHeight=%aeroTaskBarHeight%, 
	  aeroWin10margin=%aeroWin10margin%
	  If ( (aeroHeight == A_ScreenHeight - aeroTaskBarHeight - aeroWin10margin) || (aeroHeight == A_ScreenHeight - aeroTaskBarHeight - aeroWin10margin + 1) || (aeroHeight = A_ScreenHeight - aeroTaskBarHeight) || (aeroHeight = A_ScreenHeight - aeroTaskBarHeight + aeroWin10margin) )
	  {
	    If ( aeroHeight <= A_ScreenHeight - aeroTaskBarHeight - aeroWin10margin)
	      aeroHeight := aeroHeight + aeroWin10margin ; was necessary..
	    If ( aeroHeight == A_ScreenHeight - aeroTaskBarHeight - aeroWin10margin + 1)
	      aeroHeight := A_ScreenHeight - aeroTaskBarHeight ; was necessary..
	    If ( aeroX == 0 ) ; left edge = a margin away from screen left
	    {
	      aeroX := -aeroWin10margin
	      aeroWidth := aeroWidth + aeroWin10margin
	    }
	    If ( aeroX + aeroWidth == A_ScreenWidth ) ; right edge = a margin away from screen right
	    {
	      aeroWidth := aeroWidth + aeroWin10margin
	    }
	    WinMove, A,, aeroX, aeroY, aeroWidth, aeroHeight ; apply changes
	  }
	  Else If ( aeroX == 0 ) ; width has 1 x margin missing at left edge
	  {
	    aeroX := -aeroWin10margin
	    WinMove, A,, aeroX, aeroY, aeroWidth, aeroHeight ; apply changes
	  }
	}
}
Nice, but this only works for 1 monitor. Any way to update the code not to move the windows to next monitors? Now it moves to the Right/Left site too much.

Re: A fix for Windows 10 invisible borders (and Aero Snap)

Posted: 09 Nov 2018, 13:59
by dmnmsc
jimhoyle wrote:
05 Jan 2017, 09:32

Code: Select all

; ShellMessage code to be put to the auto-exec part
Gui +LastFound
hWnd := WinExist()
DllCall( "RegisterShellHookWindow", UInt,hWnd )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )

; Interface sizes (change that margin to whatever your invisible margin is!)
WinGetPos,,,, aeroTaskBarHeight, ahk_class Shell_TrayWnd
global aeroWin10margin := 10 ; In Windows 7 and 8 put here 0! In Win10 there is an invisible border margin (and margin's size depends on settings, a typical value is 10 or maybe more seldomly 15)!
global aeroTaskBarHeight := aeroTaskBarHeight-aeroWin10margin ; Taskbar also has the same invisible margin in Win10

ShellMessage( wParam,lParam )
{
	If ( wParam = 1 ) ;  wParam 1: HSHELL_WINDOWCREATED
	{
		WinWait, ahk_id %lParam%, , 2 ; wait for 2 secs for the window to get ready ; (otherwise it may not be ready for WinGetPos or WinGetTitle)
		WinGetPos, aeroX, aeroY, aeroWidth, aeroHeight, A ; get active window x,y,W,H
		If ( aeroHeight == A_ScreenHeight - aeroTaskBarHeight - aeroWin10margin || aeroHeight == A_ScreenHeight - aeroTaskBarHeight - aeroWin10margin + 1 || aeroY + aeroHeight = A_ScreenHeight - aeroTaskBarHeight - aeroWin10margin ) ; height has 1 x margin missing
		{
			aeroHeight := aeroHeight + aeroWin10margin
			If ( aeroX == 0 ) ; left edge = a margin away from screen left
			{
				aeroX := -aeroWin10margin
				aeroWidth := aeroWidth + aeroWin10margin
			}
			If ( aeroX + aeroWidth == A_ScreenWidth ) ; right edge = a margin away from screen right
			{
				aeroWidth := aeroWidth + aeroWin10margin
			}
			WinMove, A,, aeroX, aeroY, aeroWidth, aeroHeight ; apply changes
		}
		; the previous worked for IntelNUC but the following was needed for Samsung Book9
		Else If ( aeroX == 0 ) ; width has 1 x margin missing at left edge
		{
			aeroX := -aeroWin10margin
			WinMove, A,, aeroX, aeroY, aeroWidth, aeroHeight ; apply changes
		}
	}
}
So I really love this script, Thanks! But I found a little problem. Desktop icons move to the left when you have this script enabled and you will see icon's name cut and icons missplaced. Is there a way to exlude "desktop" from it? Or maybe a different workaround like make this script work just for desired apps. Dunno... newbie user here.

Re: A fix for Windows 10 invisible borders (and Aero Snap)

Posted: 10 Jun 2020, 16:29
by jimhoyle
A bit late reply, but here goes. This is a new version, where some of those problems should be better/fixed:

Code: Select all

; ShellMessage code to be put to the auto-exec part
Gui +LastFound
hWnd := WinExist()
DllCall( "RegisterShellHookWindow", UInt,hWnd )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )

; Interface sizes (change that margin to whatever your invisible margin is!)
WinGetPos,,,, aeroTaskBarHeight, ahk_class Shell_TrayWnd
global aeroWin10margin := 10 ; In Windows 7 and 8 put here 0! In Win10 there is an invisible border margin (and margin's size depends on settings, a typical value is 10 or maybe more seldomly 15)!
global aeroTaskBarHeight := aeroTaskBarHeight-aeroWin10margin ; Taskbar also has the same invisible margin in Win10

ShellMessage( wParam,lParam )
{
	If ( (wParam = 32772) || (wParam = 16) || (wParam = 1) || (wParam = 6) ) 
	;  according to testing on 4.3.2020, creating and activating windows in a basic setting where many apps are open (Chrome, Spotify, Photoshop etc.)
	;  * Win10 wParam 16: something typical, related to new window creation (possibly) - might always trigger when new window is created?
	;  * Win10 wParam 6: something typical, related to old/new window activating/appearing - might always trigger when new window is created?
	;  * Win10 wParam 1: relatively rare, seems to relate to new program launching and creating a window, however in some cases, randomly "1" does NOT trigger when creating a new window
	;  * Win10 wParam 32772: already existing program, then window activated (either maximized or activated)
	;  * Win10 wParan 32774: rarely occurs, something
	;  * ..typically when a new program is launched, the opening window triggers many wParams, e.g.: 6, 16, 6, 1, 32772, 6, 16, 16 (but varies a lot!)

	{
		Sleep 1 ; just a workaround
	  Title=
	  SavedClass=
		WinGetTitle, Title, A
		WinGetClass, SavedClass, A

	  If ( !Title )
	  {
	  	Sleep 30 ; give time for the active window to draw and form a title and class (who knows what number would be enough!)
	  	WinGetTitle, Title, A
		  WinGetClass, SavedClass, A
	  }
		
		If ( SavedClass != "ClassicShell.CMenuContainer" && SavedClass != "DV2ControlHost" && SavedClass != "MultitaskingViewFrame" && SavedClass != "Windows.UI.Core.CoreWindow" && SavedClass != "#32770" && SavedClass != "CtrlNotifySink" && !RegExMatch(Title, "Open.*") && !RegExMatch(Title, "Save.*") && !RegExMatch(Title, "Export.*") && !RegExMatch(Title, "Place.*") )
		{
		  WinGetPos, aeroX, aeroY, aeroWidth, aeroHeight, A ; get active window x,y,W,H
	    If ( (aeroHeight == A_ScreenHeight - aeroTaskBarHeight - aeroWin10margin) || (aeroHeight == A_ScreenHeight - aeroTaskBarHeight - aeroWin10margin + 1) || (aeroHeight = A_ScreenHeight - aeroTaskBarHeight) || (aeroHeight = A_ScreenHeight - aeroTaskBarHeight + aeroWin10margin) )
	    {
	    	If ( aeroHeight <= A_ScreenHeight - aeroTaskBarHeight - aeroWin10margin)
	    	  aeroHeight := aeroHeight + aeroWin10margin ; was necessary..
	    	If ( aeroHeight == A_ScreenHeight - aeroTaskBarHeight - aeroWin10margin + 1)
	    	  aeroHeight := A_ScreenHeight - aeroTaskBarHeight ; was necessary..
		    If ( aeroX == 0 ) ; left edge = a margin away from screen left
		    {
		    	aeroX := -aeroWin10margin
		      aeroWidth := aeroWidth + aeroWin10margin
		    }
		    If ( aeroX + aeroWidth == A_ScreenWidth ) ; right edge = a margin away from screen right
		    {
		    	aeroWidth := aeroWidth + aeroWin10margin
		    }
		    ; [MICROSOFT APP FIX HERE]
	      If !( aeroHeight == A_ScreenHeight - aeroTaskBarHeight && ( RegExMatch(Title, "Outlook$") || RegExMatch(Title, "Word$") || RegExMatch(Title, "Excel$") ) )
	        WinMove, A,, aeroX, aeroY, aeroWidth, aeroHeight ; apply changes ONLY if it's not a Microsoft program listed above (because those seem to be fixed already)
	    }
	    Else If ( aeroWidth == A_ScreenWidth && aeroHeight == A_ScreenHeight )
	    {
	      Return ; do NOT continue to the following cases if fullscreen mode detected (otherwise in a faultless fullscreen window unwanted things would happen)
	    }
	    Else If ( aeroX == 0  ) ; width has 1 x margin missing at left edge
	    {
	      aeroX := -aeroWin10margin
	      WinMove, A,, aeroX, aeroY, aeroWidth, aeroHeight ; apply changes
	    }
	    Else If ( aeroWidth == A_ScreenWidth - aeroX ) ; thought it should be "aeroWidth == A_ScreenWidth - aeroWin10margin - aeroX" but no
	    { ; this fixes Task Manager having right and bottom margins off the screen right edge and taskbar
	    	aeroX := aeroX + aeroWin10margin
	    	If ( aeroHeight == A_ScreenHeight - aeroY - aeroTaskBarHeight - aeroWin10margin )
	    	  aeroY := aeroY + aeroWin10margin
	    	WinMove, A,, aeroX, aeroY, aeroWidth, aeroHeight ; apply changes
	    }
	  }
	}
  }