4k window manager

Post your working scripts, libraries and tools for AHK v1.1 and older
Roel
Posts: 12
Joined: 27 Oct 2014, 16:40
Contact:

4k window manager

27 Oct 2014, 17:16

This is a butt-simple window manager designed specifically for 4k monitors. It's not really a full-blown window manager, just a window *sizer*, I use it in conjunction with iSwitchw for a complete window management solution more appropriate than Microsoft "Windows" for the large real estate available in 4k.

Numeric keypad (NumLock off) does the following to the active window:
0 tiny (cycle through three positions)
1 full-screen
2 half-screen (cycle through two positions)
3 third-screen (cycle through three positions)
4 quarter-screen (cycle through four portrait + four landscape positions)
6 sixth-screen (cycle through six positions)
8 eighth-screen (cycle through eight positions)

Before using, set values for marginLeft, marginTop, etc. to reflect your own Windows Taskbar location & size.

Code: Select all

/*
wm4k -- simple window management for 4k monitors
by Roel Hammerschlag, September 2014

Before using, set values for marginLeft etc. below to reflect
your own location & size of Windows Taskbar.

Hotkeys are designed for NumLock OFF.
*/

SetBatchLines, -1
SetTitleMatchMode, 2
SetTitleMatchMode, fast
SetWinDelay, 10
#NoEnv
#SingleInstance force
#WinActivateForce

xGross := 3840
yGross := 2160
marginLeft := 0
marginRight := 0
marginTop := 30
marginBottom := 0

xAvailable := xGross - marginLeft - marginRight
yAvailable := yGross - marginTop - marginBottom

xStep := xAvailable // 12
yStep := yAvailable // 2

xPos00 := marginLeft
xPos01 := marginLeft + xStep
xPos02 := marginLeft + xStep*2
xPos03 := marginLeft + xStep*3
xPos04 := marginLeft + xStep*4
xPos05 := marginLeft + xStep*5
xPos06 := marginLeft + xStep*6
xPos07 := marginLeft + xStep*7
xPos08 := marginLeft + xStep*8
xPos09 := marginLeft + xStep*9
xPos10 := marginLeft + xStep*10
xPos11 := marginLeft + xStep*11

yPos00 := marginTop
yPos01 := marginTop + yStep

tinyWidth := xAvailable // 8
tinyHeight := yAvailable // 4

xPosTiny0 := xPos03 - tinyWidth // 2
xPosTiny1 := xPos06 - tinyWidth // 2
xPosTiny2 := xPos09 - tinyWidth // 2

yPosTiny := yPos01 - tinyHeight // 2


NumpadEnd::                                      ;"1" on num pad invokes full-screen window
   WinMove, A, , xPos00, yPos00, xStep*12, yStep*2
   return


NumpadDown::                                     ;"2" on num pad handles 1/2-screen windows
   WinGetPos, x, y, width, height, A
   if (width = xStep*6 and height = yStep*2)
   {
      if (y = yPos00)
      {
         if (x = xPos00)
            WinMove, A, , xPos06, yPos00
         else
            WinMove, A, , xPos00, yPos00
      }
      else                                       ;1/2-screen window is off grid
         WinMove, A, , xPos00, yPos00
   }
   else                                          ;any other size window
      WinMove, A, , xPos00, yPos00, xStep*6, yStep*2
   return


NumpadPgDn::                                     ;"3" on num pad handles 1/3-screen windows
   WinGetPos, x, y, width, height, A
   if (width = xStep*4 and height = yStep*2)
   {
      if (y = yPos00)
      {
         if (x = xPos00)
            WinMove, A, , xPos04, yPos00
         else if (x = xPos04)
            WinMove, A, , xPos08, yPos00
         else
            WinMove, A, , xPos00, yPos00
      }
      else                                       ;1/3-screen window is off grid
         WinMove, A, , xPos00, yPos00
   }
   else                                          ;any other size window
      WinMove, A, , xPos00, yPos00, xStep*4, yStep*2
   return


NumpadLeft::                                     ;"4" on num pad handles 1/4-screen windows
   WinGetPos, x, y, width, height, A
   if (width = xStep*3 and height = yStep*2)     ;portrait format 1/4-screen window
   {
      if (y = yPos00)
      {
         if (x = xPos00)
            WinMove, A, , xPos03, yPos00
         else if (x = xPos03)
            WinMove, A, , xPos06, yPos00
         else if (x = xPos06)
            WinMove, A, , xPos09, yPos00
         else if (x = xPos09)                    ;if in last position convert to landscape
            WinMove, A, , xPos00, yPos00, xStep*6, yStep
         else                                    ;off x grid only
            WinMove, A, , xPos00, yPos00         ;go home
      }
      else                                       ;completely off grid
         WinMove, A, , xPos00, yPos00
   }
   else if (width = xStep*6 and height = yStep)  ;landscape format 1/4-screen window
   {
      if (y = yPos00)
      {
         if (x = xPos00)
            WinMove, A, , xPos06, yPos00
         else if (x = xPos06)
            WinMove, A, , xPos00, yPos01
         else                                    ;off x grid only
            WinMove, A, , xPos00, yPos00         ;return to beginning of row
      }
      else if (y = yPos01)
      {
         if (x = xPos00)
            WinMove, A, , xPos06, yPos01
         else if (x = xPos06)                    ;if in last posisiton convert to portrait
            WinMove, A, , xPos00, yPos00, xStep*3, yStep*2
         else                                    ;off x grid only
            WinMove, A, , xPos00, yPos01         ;return to beginning of row
      }
      else                                       ;completely off grid
         WinMove, A, , xPos00, yPos00
   }
   else                                          ;any other size window
      WinMove, A, , xPos00, yPos00, xStep*3, yStep*2
   return


NumpadRight::                                     ;"6" on num pad handles 1/6-screen windows
   WinGetPos, x, y, width, height, A
   if (width = xStep*4 and height = yStep)
   {
      if (y = yPos00)
      {
         if (x = xPos00)
            WinMove, A, , xPos04, yPos00
         else if (x = xPos04)
            WinMove, A, , xPos08, yPos00
         else if (x = xPos08)
            WinMove, A, , xPos00, yPos01
         else                                    ;off x grid only
            WinMove, A, , xPos00, yPos00         ;go home
      }
      else if (y = yPos01)
      {
         if (x = xPos00)
            WinMove, A, , xPos04, yPos01
         else if (x = xPos04)
            WinMove, A, , xPos08, yPos01
         else                                    ;off x grid only, or in last position
            WinMove, A, , xPos00, yPos00         ;go home
      }
      else                                       ;completely off grid
         WinMove, A, , xPos00, yPos00            ;go home
   }
   else                                          ;any non-1/8 window
      WinMove, A, , xPos00, yPos00, xStep*4, yStep
   return


NumpadUp::                                       ;"8" on num pad handles 1/8-screen windows
   WinGetPos, x, y, width, height, A
   if (width = xStep*3 and height = yStep)
   {
      if (y = yPos00)
      {
         if (x = xPos00)
            WinMove, A, , xPos03, yPos00
         else if (x = xPos03)
            WinMove, A, , xPos06, yPos00
         else if (x = xPos06)
            WinMove, A, , xPos09, yPos00
         else if (x = xPos09)
            WinMove, A, , xPos00, yPos01
         else                                    ;off x grid only
            WinMove, A, , xPos00, yPos00         ;go home
      }
      else if (y = yPos01)
      {
         if (x = xPos00)
            WinMove, A, , xPos03, yPos01
         else if (x = xPos03)
            WinMove, A, , xPos06, yPos01
         else if (x = xPos06)
            WinMove, A, , xPos09, yPos01
         else                                    ;off x grid only, or in last position
            WinMove, A, , xPos00, yPos00         ;go home
      }
      else                                       ;completely off grid
         WinMove, A, , xPos00, yPos00            ;go home
   }
   else                                          ;any non-1/8 window
      WinMove, A, , xPos00, yPos00, xStep*3, yStep
   return


NumpadIns::                                      ;"0" on num pad makes a Tiny window
   WinGetPos, x, y, width, height, A
   if (width = tinyWidth and height = tinyHeight)
   {
      if (y = yPosTiny)
      {
         if (x = xPosTiny0)
            WinMove, A, , xPosTiny1, yPosTiny
         else if (x = xPosTiny1)
            WinMove, A, , xPosTiny2, yPosTiny
         else                                    ;Tiny window is in row but not snapped to grid
            WinMove, A, , xPosTiny0, yPosTiny    ;   or it's in last available grid position
      }
      else                                       ;Tiny window is off the grid
         WinMove, A, , xPosTiny0, yPosTiny
   }
   else                                          ;any non-Tiny window
      WinMove, A, , xPosTiny0, yPosTiny, tinyWidth, tinyHeight
   return
Roel
Posts: 12
Joined: 27 Oct 2014, 16:40
Contact:

Re: 4k window manager

05 May 2016, 13:15

Some Windows Aero themes include transparent window borders that make the window sizer appear to produce undersize windows. The following new release solves this. While I was at it I also streamlined the coding and changed the numeric keypad assignments slightly, so now they are (Numlock OFF):

1 full-screen
2 half-screen (cycle through two positions)
3 third-screen (cycle through three positions)
4 quarter-screen (cycle through four portrait-format positions)
^4 quarter-screen (cycle through four landscape-format positions)
6 sixth-screen (cycle through six portrait-format positions)
^6 sixth-screen (cycle through six landscape-format positions)
8 eighth-screen (cycle through eight positions)
* twelfth-screen (cycle through twelve positions)

You must have include file WinGetPosEx.ahk available for the new version to work! Here it is:

Code: Select all

/*
wm4k: butt-simple window management for 4k monitors
by Roel Hammerschlag
Version 1.0: September 2014
Version 2.0: April 2016

Before using, set values for marginLeft etc. below to reflect
your own Windows Taskbar size & location.

Hotkeys are designed for NumLock OFF.
*/

SetBatchLines, -1
SetTitleMatchMode, 2
SetTitleMatchMode, fast
SetWinDelay, 10
#NoEnv
#SingleInstance force
#WinActivateForce

xGross := 3840
yGross := 2160
marginLeft := 0
marginRight := 0
marginTop := 30
marginBottom := 0

xStep := (xGross - marginLeft - marginRight) // 12
yStep := (yGross - marginTop - marginBottom) // 2
yTopRow := marginTop
yBottomRow := marginTop + yStep

topRowTest := marginTop + yStep/2


NumpadEnd::                                      ;"1" on num pad invokes full-screen window
   WinMaximize, A
   return


NumpadDown::                                     ;"2" on num pad handles 1/2-screen windows

   width := xStep*6
   height := yStep*2
   Gosub, spyActiveWindow

   x := marginLeft + width * mod(((xInner - marginLeft) // width + 1),2)
   y := yTopRow
   WinMove, A, , x - xOffset, y - yOffset, width + wDiff, height + hDiff
   
   return


NumpadPgDn::                                     ;"3" on num pad handles 1/3-screen windows

   width := xStep*4
   height := yStep*2
   Gosub, spyActiveWindow

   x := marginLeft + width * mod(((xInner - marginLeft) // width + 1),3)
   y := yTopRow
   WinMove, A, , x - xOffset, y - yOffset, width + wDiff, height + hDiff
   
   return


NumpadLeft::                                     ;"4" on num pad handles 1/4-screen windoows
                                                 ;  (portrait format)
   width := xStep*3
   height := yStep*2
   Gosub, spyActiveWindow

   x := marginLeft + width * mod(((xInner - marginLeft) // width + 1),4)
   y := yTopRow
   WinMove, A, , x - xOffset, y - yOffset, width + wDiff, height + hDiff
   
   return


^NumpadLeft::                                    ;"4" on num pad handles 1/4-screen windoows
                                                 ;  (landscape format)
   width := xStep*6
   height := yStep
   Gosub, spyActiveWindow

   x := marginLeft + width * mod(((xInner - marginLeft) // width + 1),2)
   Gosub, chooseRow
   WinMove, A, , x - xOffset, y - yOffset, width + wDiff, height + hDiff
   
   return


NumpadRight::                                     ;"6" on num pad handles 1/6-screen windows
                                                 ;  (portrait format)
   width := xStep*2
   height := yStep*2
   Gosub, spyActiveWindow

   x := marginLeft + width * mod(((xInner - marginLeft) // width + 1),6)
   y := yTopRow
   WinMove, A, , x - xOffset, y - yOffset, width + wDiff, height + hDiff
   
   return


^NumpadRight::                                   ;"6" on num pad handles 1/6-screen windoows
                                                 ;  (landscape format)
   width := xStep*4
   height := yStep
   Gosub, spyActiveWindow

   x := marginLeft + width * mod(((xInner - marginLeft) // width + 1),3)
   Gosub, chooseRow
   WinMove, A, , x - xOffset, y - yOffset, width + wDiff, height + hDiff
   
   return


NumpadUp::                                       ;"8" on num pad handles 1/8-screen windows

   width := xStep*3
   height := yStep
   Gosub, spyActiveWindow

   x := marginLeft + width * mod(((xInner - marginLeft) // width + 1),4)
   Gosub, chooseRow
   WinMove, A, , x - xOffset, y - yOffset, width + wDiff, height + hDiff
   
   return


NumpadMult::                                      ;where the "12" would be, if there was one. :-)

   width := xStep*2
   height := yStep
   Gosub, spyActiveWindow

   x := marginLeft + width * mod(((xInner - marginLeft) // width + 1),6)
   Gosub, chooseRow
   WinMove, A, , x - xOffset, y - yOffset, width + wDiff, height + hDiff
   
   return


NumpadDel::
   WinSet, AlwaysOnTop, toggle, A


chooseRow:
   if (x = marginLeft) {
      if (yOuter < topRowTest)                   ;if the x position just cycled to the left
         y := yBottomRow                         ; edge of the screen then switch rows...
      else
         y := yTopRow
   }
   else {
      if (yOuter < topRowTest)                   ;...otherwise, keep it in the same row.
         y := yTopRow
      else
         y := yBottomRow
   }
   return
   

spyActiveWindow:
   WinRestore, A
   WinGet, hA, ID, A
   WinGetPos, xOuter, yOuter, wOuter, hOuter, A
   WinGetPosEx(hA, xInner, yInner, wInner, hInner)
   xOffset := xInner - xOuter
   yOffset := yInner - yOuter
   wDiff := wOuter - wInner
   hDiff := hOuter - hInner
   return
   

#include WinGetPosEx.ahk
Peter2
Posts: 325
Joined: 21 Sep 2014, 14:38
Location: CH

Re: 4k window manager

11 Feb 2021, 05:51

HI @Roel

two questions
a) should this also work with non-4k monitors?
b) I have a laptop with deactivated monitor and 2 external, active monitors. It seem that is includes also the inactive monitor in its calculation - right?
Peter (AHK Beginner) / Win 10 x64, AHK Version v1.1.33
A_NewUser
Posts: 11
Joined: 03 Feb 2019, 07:35

Re: 4k window manager

01 Mar 2021, 11:28

Hey, @Roel
Nice script!
But, where I can download WinGetPosEx.ahk??
User avatar
DataLife
Posts: 460
Joined: 29 Sep 2013, 19:52

Re: 4k window manager

01 Mar 2021, 18:14

A_NewUser wrote:
01 Mar 2021, 11:28
Hey, @Roel
Nice script!
But, where I can download WinGetPosEx.ahk??
https://www.autohotkey.com/boards/viewtopic.php?t=3392
Check out my scripts. (MyIpChanger) (ClipBoard Manager) (SavePictureAs)
All my scripts are tested on Windows 10, AutoHotkey 32 bit Ansi unless otherwise stated.
A_NewUser
Posts: 11
Joined: 03 Feb 2019, 07:35

Re: 4k window manager

02 Mar 2021, 05:03

@DataLife thx

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 294 guests