microsoft / microsoft/PowerToys
[FancyZones] add toggle to open new non saved windows at the center of the screen / active window or near the mouse cursor
- Dominant language
- C
- Stars
- 139k
- Forks
- 8.6k
- PR merge metrics
- PR metrics pending
Description
### Description of the new feature / enhancement
Windows already saves apps screen positions if not fixated by FancyZones, even so, system and some (most) non resizable windows simply open anywhere. Would make sense to expect (any) new non saved window to always open at the center of the screen, over the active window if a child one or near the mouse.
Constantly updating iterations (thread edits), I'm vibe coding (no programing experience) an AutoHotKey v2 script that hooks and reposition non maximizable Windows **only** to the center of the screen or parent window, depending from where you open it, not to conflict with my PowerToys FancyZones, for reference. (This turned out into something completely new..)
Below a mouse centered hook, also.
Thank you! FancyZones is amazing! : )
```
#Requires AutoHotkey v2.0
#SingleInstance Force
; CENTRALIZA NA MÃE (Versão 5.6 - Proteção contra Access Denied & Overlays)
if !A_IsAdmin {
try Run('*RunAs "' A_AhkPath '" "' A_ScriptFullPath '"')
ExitApp()
}
global ID_JanelaMaeRecente := 0
global janelasProcessadas := Map()
; --- LIMPEZA DE MEMÓRIA ---
LimparMapa(*) {
global janelasProcessadas
deletar := []
for hwnd in janelasProcessadas {
if !WinExist(hwnd)
deletar.Push(hwnd)
}
for hwnd in deletar
janelasProcessadas.Delete(hwnd)
}
SetTimer(LimparMapa, 30000)
; --- HOOK DE EVENTOS ---
global CallbackAddr := CallbackCreate(OnWindowFocus, "C")
global Hook := DllCall("SetWinEventHook", "UInt", 0x0003, "UInt", 0x0003, "Ptr", 0, "Ptr", CallbackAddr, "UInt", 0, "UInt", 0, "UInt", 0)
OnExit((*) => (IsSet(Hook) && DllCall("UnhookWinEvent", "Ptr", Hook), IsSet(CallbackAddr) && CallbackFree(CallbackAddr)))
EstaVisivel(id) => DllCall("user32\IsWindowVisible", "Ptr", id)
; --- ATUALIZAÇÃO DA MÃE ---
~LButton Up::
~RButton Up:: {
SetTimer(() => DefinirComoMae(WinExist("A")), -50)
}
~LAlt Up::
~RAlt Up:: {
SetTimer(() => DefinirComoMae(WinExist("A")), -150)
}
DefinirComoMae(hwnd) {
global ID_JanelaMaeRecente
if (!hwnd || !WinExist(hwnd) || !EstaVisivel(hwnd))
return
estilo := WinGetStyle(hwnd)
exEstilo := WinGetExStyle(hwnd)
classe := WinGetClass(hwnd)
if (exEstilo & 0x00080000 || exEstilo & 0x00000080)
return
if (classe ~= "i)Shell_TrayWnd|TrayNotifyWnd|Taskbar|Progman|WorkerW|SearchHost|Windows.UI.Core.CoreWindow") {
ID_JanelaMaeRecente := 0
return
}
if (estilo & 0x00C00000)
ID_JanelaMaeRecente := hwnd
}
OnWindowFocus(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime) {
global ID_JanelaMaeRecente, janelasProcessadas
try {
if (idObject != 0 || !WinExist(hwnd) || janelasProcessadas.Has(hwnd))
return
classe := WinGetClass(hwnd)
titulo := WinGetTitle(hwnd)
estilo := WinGetStyle(hwnd)
exEstilo := WinGetExStyle(hwnd)
WinGetPos(,, &nW, &nH, hwnd)
if (exEstilo & 0x00080000 || exEstilo & 0x00000080) {
janelasProcessadas[hwnd] := true
return
}
if (classe ~= "i)Shell_TrayWnd|TrayNotifyWnd|Taskbar|Progman|WorkerW|SearchHost") {
ID_JanelaMaeRecente := 0
return
}
if (titulo == "" || classe ~= "i)Splash|Loading|MsoSplash|Ghost|NetUI|#32768|Menu|Shadow|Tooltip|Dimmer|Overlay")
return
; PREPARAÇÃO VISUAL
try WinSetTransparent(0, hwnd)
Loop 10 {
if EstaVisivel(hwnd)
break
Sleep(30)
}
if !EstaVisivel(hwnd) {
try WinSetTransparent("Off", hwnd)
return
}
area := nW * nH
deveMover := (classe == "#32770") || ((estilo & 0x00C00000) && area < 350000)
if (WinGetMinMax(hwnd) != 0 || !deveMover) {
try WinSetTransparent("Off", hwnd)
janelasProcessadas[hwnd] := true
DefinirComoMae(hwnd)
return
}
; --- EXECUÇÃO ---
ProcessarPosicionamento(hwnd)
; Timer com proteção contra Access Denied (Excel/MacType)
RevelarJanela(*) {
try {
if WinExist(hwnd)
WinSetTransparent("Off", hwnd)
}
}
SetTimer(RevelarJanela, -100)
janelasProcessadas[hwnd] := true
}
}
ProcessarPosicionamento(hwnd) {
global ID_JanelaMaeRecente
try {
if !WinExist(hwnd)
return
WinGetPos(,, &nW, &nH, hwnd)
idMaeFinal := 0
if (hOwner := DllCall("GetWindow", "Ptr", hwnd, "Uint", 4, "Ptr")) {
if (WinExist(hOwner) && EstaVisivel(hOwner))
idMaeFinal := hOwner
}
if (idMaeFinal == 0 && ID_JanelaMaeRecente != 0 && WinExist(ID_JanelaMaeRecente)) {
if (WinGetPID(hwnd) == WinGetPID(ID_JanelaMaeRecente) && EstaVisivel(ID_JanelaMaeRecente))
idMaeFinal := ID_JanelaMaeRecente
}
if (idMaeFinal == 0 && ID_JanelaMaeRecente != 0 && WinExist(ID_JanelaMaeRecente) && EstaVisivel(ID_JanelaMaeRecente)) {
idMaeFinal := ID_JanelaMaeRecente
}
if (idMaeFinal != 0 && idMaeFinal != hwnd) {
WinGetPos(&pX, &pY, &pW, &pH, idMaeFinal)
novoX := pX + (pW / 2) - (nW / 2)
novoY := pY + (pH / 2) - (nH / 2)
monitorNum := MonitorGetFromPoint(pX + (pW / 2), pY + (pH / 2))
} else {
CoordMode "Mouse", "Screen"
MouseGetPos(&mX, &mY)
monitorNum := MonitorGetFromPoint(mX, mY)
MonitorGetWorkArea(monitorNum, &mL, &mT, &mR, &mB)
novoX := mL + (mR - mL - nW) / 2
novoY := mT + (mB - mT - nH) / 2
}
MonitorGetWorkArea(monitorNum, &mL, &mT, &mR, &mB)
novoX := Max(mL, Min(novoX, mR - nW))
novoY := Max(mT, Min(novoY, mB - nH))
DllCall("user32\MoveWindow", "Ptr", hwnd, "Int", Integer(novoX), "Int", Integer(novoY), "Int", Integer(nW), "Int", Integer(nH), "Int", 1)
; Snap final com proteção try
FinalizarPosicao(*) {
try {
if WinExist(hwnd)
WinMove(novoX, novoY,,, hwnd)
}
}
SetTimer(FinalizarPosicao, -200)
}
}
MonitorGetFromPoint(x, y) {
Loop MonitorGetCount() {
MonitorGet(A_Index, &L, &T, &R, &B)
if (x >= L && x <= R && y >= T && y <= B)
return A_Index
}
return MonitorGetPrimary()
}
```
Contributor guide
Research direction
The issue concerns FancyZones window placement and includes an AutoHotkey v2 reference script, but it does not identify a PowerToys source file, test, or implementation entry point. First locate the FancyZones logic that handles newly opened non-resizable windows; done should include a user-selectable placement mode for screen center, active or parent window, and mouse position.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- desktop
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100