Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Window Fit = autosize windows to take up holes in desktop


  • Please log in to reply
7 replies to this topic
berban
  • Members
  • 202 posts
  • Last active: Apr 12 2019 01:08 AM
  • Joined: 30 Dec 2009
Posted Image

Press ALT+SHIFT+CLICK on a window to resize it to fit holes in your desktop. This is a deceptively complicated problem, but I felt that I wanted it badly enough to write it.

Posted Image

** Make sure you click on the window control that you want resized. For many windows, there is one particularly relevant part. For example in an internet explorer window, the part where the webpage is displayed is the most important. The script will get the control under your mouse when you click on a window evaluate the size of this part when the window is maximized. It would be kind of useless if the script resized your browser window to be long and thin, thus effectively giving you a large command/favorites bar window. (As happens with the MS Word window in the second example .gif; that was before I added this.) This precaution avoids that.

If this doesn't work - if when you click on the relevant control and the window doesn't think there's enough room, i.e. it maximizes, then you can always click on the title bar to avoid collecting a control.

Goes nicely with this script http://www.autohotke...topic58291.html so that you can make a snapshot of a video and then resize your other windows around it and work at the same time.

(Note: WFT <> WTF) :wink:
SetBatchLines, -1
SetWinDelay, 2
WinGetPos, , , , CommandBarHeight, ahk_class Shell_TrayWnd ;**this is auto-execute**


+!LButton::
MouseGetPos, WFT_MouseX, WFT_MouseY, WFT_WinToMove, WFT_Control, 2
If CheckLegitWindow(WFT_WinToMove, 0)
{
   SoundPlay, %A_WinDir%\Media\Windows Ding.wav
   Return
}
WinRestore, ahk_id %WFT_WinToMove%
WinMaximize, ahk_id %WFT_WinToMove%
WinActivate, ahk_id %WFT_WinToMove%
DetectHiddenWindows, Off
WinGet, WFT_WinList, List
WFT_TooManyWindows := 0, WFT_HDif := 0, WFT_VDif := 0
WinGetPos, WFT_WinX, WFT_WinY, WFT_WinW, WFT_WinH, ahk_id %WFT_WinToMove%
ControlGetPos, WFT_cx, WFT_cy, WFT_cw, WFT_ch, , ahk_id %WFT_Control%
If ((WFT_WinW - WFT_cw > 20) or (WFT_WinH - WFT_ch > 20)) and (WFT_cw * WFT_cw / WFT_WinW / WFT_WinH > .5)
   WFT_HDif := WFT_WinW - WFT_cw, WFT_VDif := WFT_WinH - WFT_ch
Goto WindowFit

;----------------------------------------------------------------------------------------------------

WindowFit:
WFT_i := 1, WFT_l := 0
While WFT_WinList%A_Index%
{
   If (WFT_WinList%A_Index% = WFT_WinToMove) or CheckLegitWindow(WFT_WinList%A_Index%, 1)
      Continue
   WinGetPos, WFT_x%WFT_i%, WFT_y%WFT_i%, WFT_Width%WFT_i%, WFT_Height%WFT_i%, % "ahk_id " WFT_WinList%A_Index%
   If (WFT_x%WFT_i% < 0) and (WFT_x%WFT_i% + WFT_Width%WFT_i% > A_ScreenWidth) and (WFT_y%WFT_i% < 0) and (WFT_y%WFT_i% + WFT_Height%WFT_i% > A_ScreenHeight - CommandBarHeight)
      Break
   If (WFT_x%WFT_i% > 1) and (WFT_x%WFT_i% < A_ScreenWidth - 1)
      AddSort("WFT_xLine", WFT_x%WFT_i%)
   If (WFT_y%WFT_i% > 1) and (WFT_y%WFT_i% < A_ScreenHeight - 1 - CommandBarHeight)
      AddSort("WFT_yLine", WFT_y%WFT_i%)
   If (WFT_x%WFT_i% + WFT_Width%WFT_i% > 1) and (WFT_x%WFT_i% + WFT_Width%WFT_i% < A_ScreenWidth - 1)
      AddSort("WFT_xLine", WFT_x%WFT_i% + WFT_Width%WFT_i%)
   If (WFT_y%WFT_i% + WFT_Height%WFT_i% > 1) and (WFT_y%WFT_i% + WFT_Height%WFT_i% < A_ScreenHeight - 1 - CommandBarHeight)
      AddSort("WFT_yLine", WFT_y%WFT_i% + WFT_Height%WFT_i%)
   WFT_i++
   If (WFT_i = WFT_TooManyWindows)
      Break
}
WFT_i--
If not WFT_i
{
   SoundPlay, %A_WinDir%\Media\Windows Ding.wav
   return
}
AddSort("WFT_xLine", 0)
AddSort("WFT_xLine", A_ScreenWidth + 1)
AddSort("WFT_yLine", 0)
AddSort("WFT_yLine", A_ScreenHeight - CommandBarHeight)
Loop % WFT_xLine - 1
{
   WFT_a := A_Index
   Loop % WFT_yLine - 1
   {
      WFT_b := A_Index
      Loop %WFT_b%
      {
         WFT_h := A_Index
         WFT_g := WFT_xLine - WFT_a
         Loop % WFT_yLine - WFT_b
         {
            WFT_c := WFT_h + A_Index - 1
            WFT_d := WFT_h + A_Index
            Loop %WFT_g%
            {
               WFT_e := WFT_a - 1 + A_Index
               WFT_f := WFT_a + A_Index
               If WFT_CheckOccupied(WFT_xLine%WFT_e% + 2, WFT_yLine%WFT_c% + 2) or WFT_CheckOccupied(WFT_xLine%WFT_f% - 2, WFT_yLine%WFT_c% + 2) or WFT_CheckOccupied(WFT_xLine%WFT_e% + 2, WFT_yLine%WFT_d% - 2) or WFT_CheckOccupied(WFT_xLine%WFT_f% - 2, WFT_yLine%WFT_d% - 2)
               {
                  WFT_g := A_Index - 1
                  Break
               }
            }
         }
         If WFT_g
         {
            WFT_l++
            WFT_Left%WFT_l% := WFT_xLine%WFT_a%
            v := WFT_a + WFT_g
            WFT_Right%WFT_l% := WFT_xLine%v%
            WFT_Top%WFT_l% := WFT_yLine%WFT_h%
            v := WFT_h + WFT_yLine - WFT_b
            WFT_Bottom%WFT_l% := WFT_yLine%v%
            WFT_Area%WFT_l% := (WFT_Right%WFT_l% - WFT_Left%WFT_l% - WFT_HDif) * (WFT_Bottom%WFT_l% - WFT_Top%WFT_l% - WFT_VDif)
         }
      }
   }
}
WFT_max = 0
Loop %WFT_l%
   If (WFT_Area%A_Index% > WFT_max)
   {
      WFT_Max := WFT_Area%A_Index%
      WFT_Largest := A_Index
   }
Clear("WFT_xLine")
Clear("WFT_yLine")
Clear("WFT_WinList")
Clear("WFT_x")
Clear("WFT_y")
Clear("WFT_Width")
Clear("WFT_Height")
If (WFT_Max < 80000)
{
   WFT_TooManyWindows := WFT_i
   Goto WindowFit
}
WinMove, ahk_id %WFT_WinToMove%, , WFT_Left%WFT_Largest%, WFT_Top%WFT_Largest%, WFT_Right%WFT_Largest% - WFT_Left%WFT_Largest%, WFT_Bottom%WFT_Largest% - WFT_Top%WFT_Largest%
return

;==============Pertinent Functions==============================================

AddSort(Name, Value)
{
	global
	If (%Name% = "")
		%Name% := 0
	Array_a := %Name%
	%Name% := %Name% + 1
	Array_b := %Name%
	Loop %Array_a%
	{
		If (Value > %Name%%Array_a%)
		{
			%Name%%Array_b% := Value
			Return
		}
		%Name%%Array_b% := %Name%%Array_a%
		Array_a--
		Array_b--
	}
	%Name%1 := Value
	Return
}

Clear(Name) ;clear an array
{
   global
   Loop %Name%
      %Name%%A_Index% =
   %Name% =
}

WFT_CheckOccupied(Xcor, Ycor)
{
	Global
	Loop %WFT_i%
		If (WFT_x%A_Index% < Xcor) and (WFT_x%A_Index% + WFT_Width%A_Index% > Xcor) and (WFT_y%A_Index% < Ycor) and (WFT_y%A_Index% + WFT_Height%A_Index% > Ycor)
			Return 1
	Return 0
}

CheckLegitWindow(WindowToClose, CheckLegitChildWindow) ;Checks whether a window is "legit" i.e. worthy of getting out of the way for. E.g. the desktop or start menu aren't legit. (a 1 for "checklegitchildwindow" will ALLOW dialog boxes, like a "find" box, to exist)
{
	WinGetClass, Class, ahk_id %WindowToClose%
	If Not Class
		Return "null"
	Else If (Class = "Shell_TrayWnd") or (Class = "DV2ControlHost") or (Class = "WorkerW") or (Class = "tooltips_class32") or (Class = "Progman") or (Class = "ClockFlyoutWindow") or ((Class = "#32770") and not CheckLegitChildWindow) or (Class = "Button") or (Class = "ThunderRT6Main") or (Class = "#32768") or (Class = "#32769") or (Class = "#32771") or (Class = "#32772")
		Return Class
	Else
		Return
}

How it works:
- Gets a list of all visible windows, in z-order
- Gets their sizes and locations, and evaluates if they have window edges somewhere in the visible screen area
- Makes a grid of all valid x- and y- window edges
- Iterates through EVERY possible combination of spaces made up of the squares in this grid (hence the five nested loops) and evaluates whether there is a window in each space.
- Takes the spaces that don't have a window in them and finds which is the largest.
- If the size of the largest space is less than 100000 (~300x300 pixels) then it will start over and exclude the lowest z-ordered window until it gets a valid answer.

:)

Find me on the new AutoHotkey forums and send me a message if you have a question about any of the scrips I've posted to this forum!


Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
where can I find WFT_CheckOccupied()?

Wicked
  • Members
  • 504 posts
  • Last active: Nov 18 2018 02:17 AM
  • Joined: 07 Jun 2008
No time to try it at the moment, but it looks fantastic!

berban
  • Members
  • 202 posts
  • Last active: Apr 12 2019 01:08 AM
  • Joined: 30 Dec 2009
@Laszlo: sorry, knew I probably forgot something.

Find me on the new AutoHotkey forums and send me a message if you have a question about any of the scrips I've posted to this forum!


Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Still no luck with the script. I guessed the missing CheckLegitWindow() and WindowingCheckLegit() would be the same, but copying does not help. Nothing happens at the hotkey click (Win7 x64).

berban
  • Members
  • 202 posts
  • Last active: Apr 12 2019 01:08 AM
  • Joined: 30 Dec 2009
Ok it should work now. I actually tested it myself (bad coding etiquette to not do that first :) ) and it worked, not sure why it didn't work for you, although I did catch a small bug which is fixed now

Find me on the new AutoHotkey forums and send me a message if you have a question about any of the scrips I've posted to this forum!


berban
  • Members
  • 202 posts
  • Last active: Apr 12 2019 01:08 AM
  • Joined: 30 Dec 2009
Something I just realized - this works really great with internet explorer full screen windows. Below is a screenshot. There is much more browsing space and much less menu/address bar space. Just press F11 and then do this script's thing (shift+alt+click) on the window, and it'll resize but retain its full-screen properties.

Posted Image

Find me on the new AutoHotkey forums and send me a message if you have a question about any of the scrips I've posted to this forum!


bqw371
  • Members
  • 32 posts
  • Last active: Nov 16 2010 01:38 AM
  • Joined: 26 Nov 2008
I'll let you know how this script works on my 3 monitor setup at work! It looks so useful!