Functions/GenXdev.Windows/Set-WindowPosition.ps1

<##############################################################################
Part of PowerShell module : GenXdev.Windows
Original cmdlet filename : Set-WindowPosition.ps1
Original author : René Vaessen / GenXdev
Version : 2.2.2025
################################################################################
Copyright (c) René Vaessen / GenXdev
 
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
 
    http://www.apache.org/licenses/LICENSE-2.0
 
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
################################################################################>

<#
.SYNOPSIS
Positions and resizes windows when explicit positioning parameters are provided.
 
.DESCRIPTION
Provides precise control over window positioning and sizing when positioning
parameters are specified. Supports multiple monitors, border removal, and
various preset positions like left/right split, top/bottom split, and center
placement. Windows can be positioned by coordinates or using predefined layouts.
Without positioning parameters, the function performs no action on the window.
 
.PARAMETER ProcessName
The process name of the window to position
 
.PARAMETER Process
Process or processes whose windows need positioning
 
.PARAMETER WindowHelper
Window helper object for direct window manipulation
 
.PARAMETER Monitor
Monitor selection: 0=primary, 1+=specific monitor, -1=current, -2=secondary
 
.PARAMETER NoBorders
Removes window borders and title bar for a cleaner appearance
 
.PARAMETER Width
Window width in pixels
 
.PARAMETER Height
Window height in pixels
 
.PARAMETER X
Window horizontal position in pixels
 
.PARAMETER Y
Window vertical position in pixels
 
.PARAMETER Left
Places window on left half of screen
 
.PARAMETER Right
Places window on right half of screen
 
.PARAMETER Top
Places window on top half of screen
 
.PARAMETER Bottom
Places window on bottom half of screen
 
.PARAMETER Centered
Centers window on screen
 
.PARAMETER Fullscreen
Maximizes window to fill entire screen
 
.PARAMETER RestoreFocus
Returns focus to PowerShell window after positioning
 
.PARAMETER PassThru
Returns window helper object for further manipulation
 
.PARAMETER SideBySide
Will either set the window fullscreen on a different monitor than Powershell, or
side by side with Powershell on the same monitor
 
.PARAMETER FocusWindow
Focus the window after positioning
 
.PARAMETER SetForeground
Set the window to foreground after positioning
 
.PARAMETER Minimize
Minimizes the window after positioning
 
.PARAMETER Maximize
Maximize the window after positioning
 
.PARAMETER SetRestored
Restore the window to normal state after positioning
 
.PARAMETER KeysToSend
Keystrokes to send to the window after positioning
 
.PARAMETER SendKeyEscape
Escape control characters and modifiers when sending keys
 
.PARAMETER SendKeyHoldKeyboardFocus
Hold keyboard focus on target window when sending keys
 
.PARAMETER SendKeyUseShiftEnter
Use Shift+Enter instead of Enter when sending keys
 
.PARAMETER SendKeyDelayMilliSeconds
Delay between different input strings in milliseconds when sending keys
 
.PARAMETER SessionOnly
Switch to use alternative settings stored in session for AI preferences
 
.PARAMETER ClearSession
Switch to clear alternative settings stored in session for AI preferences
 
.PARAMETER SkipSession
Switch to store settings only in persistent preferences without affecting
session
 
.PARAMETER OnlyOutputCoords
Only output the calculated coordinates and size without actually positioning
the window. Returns a hashtable with Left, Top, Width, and Height properties
representing global (multi-monitor) coordinates
 
.EXAMPLE
Set-WindowPosition -Centered -Monitor 0 -NoBorders
Position PowerShell window centered on primary monitor with no borders
 
.EXAMPLE
Get-Process notepad,calc | wp -m 1 -l,-r
Split notepad and calc side by side on second monitor using aliases
 
.EXAMPLE
Set-WindowPosition -ProcessName notepad
Does nothing - no positioning parameters specified
 
.EXAMPLE
Set-WindowPosition -ProcessName notepad -KeysToSend "Hello World"
Sends keystrokes to notepad window without repositioning it
 
.EXAMPLE
Set-WindowPosition -ProcessName notepad -Left -Monitor 1 -OnlyOutputCoords
Returns the calculated coordinates where notepad would be placed on the left
side of monitor 1 without actually moving the window
#>

################################################################################
function Set-WindowPosition {

    [CmdletBinding(DefaultParameterSetName = 'Default', SupportsShouldProcess = $true)]
    [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidGlobalVars', '')]
    [Alias('wp')]
    param(
        ########################################################################
        [parameter(
            ParameterSetName = 'ProcessName',
            Mandatory = $false,
            Position = 0,
            HelpMessage = 'The process name of the window to position',
            ValueFromPipeline,
            ValueFromPipelineByPropertyName,
            ValueFromRemainingArguments = $false
        )]
        [SupportsWildcards()]
        [Alias('Name')]
        [string] $ProcessName,
        ########################################################################
        [parameter(
            ParameterSetName = 'Process',
            Mandatory = $false,
            HelpMessage = 'The process of the window to position',
            ValueFromPipeline,
            ValueFromPipelineByPropertyName,
            ValueFromRemainingArguments = $false
        )]
        [ValidateNotNull()]
        [System.Diagnostics.Process] $Process,
        ########################################################################
        [parameter(
            ParameterSetName = 'WindowHelper',
            Mandatory = $false,
            HelpMessage = 'Get-Window helper object for direct window manipulation',
            ValueFromPipeline,
            ValueFromPipelineByPropertyName,
            ValueFromRemainingArguments = $false
        )]
        [ValidateNotNull()]
        [GenXdev.Helpers.WindowObj[]] $WindowHelper,
        ########################################################################
        [parameter(
            Mandatory = $false,
            HelpMessage = 'Monitor selection: 0=primary, 1+=specific monitor, -1=current, -2=secondary'
        )]
        [Alias('m', 'mon')]
        [int] $Monitor = -1,
        ########################################################################
        [Alias('nb')]
        [parameter(
            Mandatory = $false,
            HelpMessage = 'Removes the borders of the window'
        )]
        [switch] $NoBorders,
        ########################################################################
        [parameter(
            Mandatory = $false,
            HelpMessage = 'Window width in pixels'
        )]
        [int] $Width = -1,
        ########################################################################
        [parameter(
            Mandatory = $false,
            HelpMessage = 'Window height in pixels'
        )]
        [int] $Height = -999999,
        ########################################################################
        [parameter(
            Mandatory = $false,
            HelpMessage = 'Window horizontal position in pixels'
        )]
        [int] $X = -999999,
        ########################################################################
        [parameter(
            Mandatory = $false,
            HelpMessage = 'Window vertical position in pixels'
        )]
        [int] $Y = -999999,
        ########################################################################
        [parameter(
            Mandatory = $false,
            HelpMessage = 'Place window on the left side of the screen'
        )]
        [switch] $Left,
        ########################################################################
        [parameter(
            Mandatory = $false,
            HelpMessage = 'Place window on the right side of the screen'
        )]
        [switch] $Right,
        ########################################################################
        [parameter(
            Mandatory = $false,
            HelpMessage = 'Place window on the top side of the screen'
        )]
        [switch] $Top,
        ########################################################################
        [parameter(
            Mandatory = $false,
            HelpMessage = 'Place window on the bottom side of the screen'
        )]
        [switch] $Bottom,
        ########################################################################
        [parameter(
            Mandatory = $false,
            HelpMessage = 'Place window in the center of the screen'
        )]
        [switch] $Centered,
        ########################################################################
        [parameter(
            Mandatory = $false,
            HelpMessage = 'Maximize the window'
        )]
        [Alias('fs')]
        [switch] $Fullscreen,
        ########################################################################

        [parameter(
            Mandatory = $false,
            HelpMessage = 'Restore PowerShell window focus'
        )]
        [Alias('rf', 'bg')]
        [switch]$RestoreFocus,
        ########################################################################
        [parameter(
            Mandatory = $false,
            HelpMessage = 'Returns the window helper for each process'
        )]
        [Alias('pt')]
        [switch]$PassThru,
        ########################################################################
        [parameter(
            Mandatory = $false,
            HelpMessage = ('Will either set the window fullscreen on a different ' +
                'monitor than Powershell, or side by side with Powershell on the ' +
                'same monitor')
        )]
        [Alias('sbs')]
        [switch]$SideBySide,
        ########################################################################
        [Parameter(
            Mandatory = $false,
            HelpMessage = 'Focus the window after opening'
        )]
        [Alias('fw','focus')]
        [switch] $FocusWindow,
        ########################################################################
        [Parameter(
            Mandatory = $false,
            HelpMessage = 'Set the window to foreground after opening'
        )]
        [Alias('fg')]
        [switch] $SetForeground,
        ########################################################################
        [Parameter(
            Mandatory = $false,
            HelpMessage = 'Minimizes the window after positioning'
        )]
        [switch] $Minimize,
        ########################################################################
        [Parameter(
            Mandatory = $false,
            HelpMessage = 'Maximize the window after positioning'
        )]
        [switch] $Maximize,
        ########################################################################
        [Parameter(
            Mandatory = $false,
            HelpMessage = 'Restore the window to normal state after positioning'
        )]
        [switch] $SetRestored,
        ########################################################################
        [Parameter(
            Mandatory = $false,
            HelpMessage = ('Keystrokes to send to the Window, ' +
                'see documentation for cmdlet GenXdev.Windows\Send-Key')
        )]
        [string[]] $KeysToSend,
        ########################################################################
        [Parameter(
            Mandatory = $false,
            HelpMessage = 'Escape control characters and modifiers when sending keys'
        )]
        [Alias('Escape')]
        [switch] $SendKeyEscape,
        ########################################################################
        [Parameter(
            Mandatory = $false,
            HelpMessage = 'Hold keyboard focus on target window when sending keys'
        )]
        [Alias('HoldKeyboardFocus')]
        [switch] $SendKeyHoldKeyboardFocus,
        ########################################################################
        [Parameter(
            Mandatory = $false,
            HelpMessage = 'Use Shift+Enter instead of Enter when sending keys'
        )]
        [Alias('UseShiftEnter')]
        [switch] $SendKeyUseShiftEnter,
        ########################################################################
        [Parameter(
            Mandatory = $false,
            HelpMessage = ('Delay between different input strings in ' +
                'milliseconds when sending keys')
        )]
        [Alias('DelayMilliSeconds')]
        [int] $SendKeyDelayMilliSeconds,
        ########################################################################
        [Parameter(
            Mandatory = $false,
            HelpMessage = ('Use alternative settings stored in session for AI ' +
                'preferences')
        )]
        [switch] $SessionOnly,
        ########################################################################
        [Parameter(
            Mandatory = $false,
            HelpMessage = ('Clear alternative settings stored in session for AI ' +
                'preferences')
        )]
        [switch] $ClearSession,
        ########################################################################
        [Parameter(
            Mandatory = $false,
            HelpMessage = ('Store settings only in persistent preferences without ' +
                'affecting session')
        )]
        [Alias('FromPreferences')]
        [switch] $SkipSession,
        ########################################################################
        [Parameter(
            Mandatory = $false,
            HelpMessage = ('Only output the calculated coordinates and size ' +
                'without actually positioning the window')
        )]
        [switch] $OnlyOutputCoords
        ########################################################################
    )

    begin {

        # initialize screen selection variable for monitor targeting
        $screen = $null
        [int] $setDefaultMonitor = $Global:DefaultSecondaryMonitor -is [int] ?
            (
                $Global:DefaultSecondaryMonitor
            ):
            2;

        # retrieve all available monitors from the system
        $allScreens = @([WpfScreenHelper.Screen]::AllScreens |
                Microsoft.PowerShell.Core\ForEach-Object { $PSItem })

        # log the total number of detected monitors for debugging
        Microsoft.PowerShell.Utility\Write-Verbose ("Found $($allScreens.Count) " +
            "monitors available for window positioning")

        # enumerate and log details of each available monitor
        for ($i = 0; $i -lt $allScreens.Count; $i++) {

            # get current monitor information for logging
            $screenInfo = $allScreens[$i]

            # log monitor specifications including size, position and device name
            Microsoft.PowerShell.Utility\Write-Verbose ("Monitor ${i}: " +
                "$($screenInfo.WorkingArea.Width)x$($screenInfo.WorkingArea.Height) " +
                "at ($($screenInfo.WorkingArea.X),$($screenInfo.WorkingArea.Y)) " +
                "Device: $($screenInfo.DeviceName)")
        }


        # obtain reference to powershell main window for focus restoration
        $powerShellWindow = GenXdev.Windows\Get-PowershellMainWindow

        # log powershell window information if successfully detected
        if ($null -ne $powerShellWindow) {

            Microsoft.PowerShell.Utility\Write-Verbose ("PowerShell window " +
                "found - Handle: $($powerShellWindow.Handle), " +
                "Position: $($powerShellWindow.Position().X)," +
                "$($powerShellWindow.Position().Y), " +
                "Size: $($powerShellWindow.Size().Width)x" +
                "$($powerShellWindow.Size().Height)")
        }
        else {

            # log warning when powershell window cannot be detected
            Microsoft.PowerShell.Utility\Write-Verbose ("PowerShell window " +
                "not found or not available")
        }

        # copy window positioning parameters for validation and logging
        $wpparams = GenXdev.FileSystem\Copy-IdenticalParamValues `
                    -BoundParameters $PSBoundParameters `
                    -FunctionName 'GenXdev.Windows\Set-WindowPosition'

        # log which positioning parameters were provided by the user
        Microsoft.PowerShell.Utility\Write-Verbose ("Window positioning " +
            "parameters available: $($wpparams.Keys -join ', ')")

        # determine if side-by-side mode should be forced due to monitor limitations
        $ForcedSideBySide = ($Monitor -eq -2) -and (
               ($allScreens.Count -lt 2)  -or
               (-not ($setDefaultMonitor -is [int] -and ($setDefaultMonitor -gt 0)))
        )

        if ($ForcedSideBySide) {

            Microsoft.PowerShell.Utility\Write-Verbose ("Forcing side-by-side " +
                "positioning: insufficient monitors ($($allScreens.Count)) or " +
                "invalid DefaultSecondaryMonitor " +
                "($setDefaultMonitor)")
        }

        # Store side-by-side request for processing in the process block
        # where we can handle both coordinate-only and actual window modes
        $SideBySideRequested = $SideBySide -or $ForcedSideBySide

        if ($SideBySideRequested -and (-not $OnlyOutputCoords)) {
            # Only configure side-by-side settings when actually positioning windows
            if ($null -ne $powerShellWindow) {
                Microsoft.PowerShell.Utility\Write-Verbose ("Configuring " +
                    "side-by-side positioning - PowerShell monitor: " +
                    "$($powerShellWindow.GetCurrentMonitor()), " +
                    "Target monitor: $($powerShellWindow.GetCurrentMonitor() + 1)")

                $SideBySide = $true
                $Monitor = $powerShellWindow.GetCurrentMonitor() + 1
                $SetForeground = $true
                $RestoreFocus = $true
                $SetRestored = $true
                $Maximize = $false
                $FullScreen = $false
                if ($null -ne $KeysToSend -and $KeysToSend.Count -eq 1 -and $KeysToSend[0] -in @('f', '{F11}')) {
                    $KeysToSend = $null
                }

                Microsoft.PowerShell.Utility\Write-Verbose ("Side-by-side final " +
                    "settings: Monitor=$Monitor, SetForeground=$SetForeground, " +
                    "RestoreFocus=$RestoreFocus, Maximize=$Maximize")
            } else {
                Microsoft.PowerShell.Utility\Write-Verbose ("Side-by-side requested but PowerShell window not available - deferring to process block")
            }
        }

        # preserve bound parameters for use in subsequent function calls
        $myPSBoundParameters = $PSBoundParameters

        # determine if process lookup should be skipped for coordinate-only calculations
        # coordinate calculation mode only requires positioning math without window interaction
        $skipProcessLookup = $OnlyOutputCoords

        # resolve target process based on the parameter set specified by the user
        switch ($PSCmdlet.ParameterSetName) {
            'ProcessName' {
                # handle process lookup by name when not in coordinate-only mode
                if (-not $skipProcessLookup) {
                    Microsoft.PowerShell.Utility\Write-Verbose ('ParameterSetName: ProcessName')

                    # search for processes matching the specified name with active windows
                    $foundProcess = Microsoft.PowerShell.Management\Get-Process `
                        -Name $ProcessName `
                        -ErrorAction SilentlyContinue |
                        Microsoft.PowerShell.Core\Where-Object `
                            -Property 'MainWindowHandle' `
                            -NE 0 |
                        Microsoft.PowerShell.Utility\Sort-Object `
                            -Property 'StartTime' `
                            -Descending |
                        Microsoft.PowerShell.Utility\Select-Object `
                            -First 1

                    # validate that a matching process with a window was found
                    if ($null -eq $foundProcess) {
                        Microsoft.PowerShell.Utility\Write-Verbose ("No process found with name '$ProcessName' (ProcessName set)")
                        Microsoft.PowerShell.Utility\Write-Error ('No process found with ' + "name '$ProcessName'")
                    }
                    else {
                        Microsoft.PowerShell.Utility\Write-Verbose ("Process found: $($foundProcess.ProcessName) with ID $($foundProcess.Id) (ProcessName set)")
                        $Process = $foundProcess
                        Microsoft.PowerShell.Utility\Write-Verbose ('Found process: ' + "$($Process.ProcessName) with ID $($Process.Id)")
                    }
                } else {
                    Microsoft.PowerShell.Utility\Write-Verbose ('OnlyOutputCoords set - skipping process lookup for ProcessName')
                }
                break;
            }
            'Process' {
                if (-not $skipProcessLookup) {
                    Microsoft.PowerShell.Utility\Write-Verbose ('ParameterSetName: Process')

                # get process by id first
                $foundProcess = Microsoft.PowerShell.Management\Get-Process `
                    -Id ($Process.Id) `
                    -ErrorAction SilentlyContinue |
                    Microsoft.PowerShell.Core\Where-Object `
                        -Property 'MainWindowHandle' `
                        -NE 0

                if ($null -eq $foundProcess) {

                    Microsoft.PowerShell.Utility\Write-Verbose ("No process found by Id $($Process.Id), trying by Name $($Process.Name) (Process set)")

                    # fallback to process by name
                    $foundProcess = Microsoft.PowerShell.Management\Get-Process `
                        -Name ($Process.Name) `
                        -ErrorAction SilentlyContinue |
                        Microsoft.PowerShell.Core\Where-Object `
                            -Property 'MainWindowHandle' `
                            -NE 0

                    if ($null -eq $foundProcess) {

                        Microsoft.PowerShell.Utility\Write-Verbose ("No process found with name '$($Process.Name)' (Process set)")
                        Microsoft.PowerShell.Utility\Write-Error ('No process found with ' + "name '$($Process.Name)'")
                        $Process = $null

                    } else {

                        Microsoft.PowerShell.Utility\Write-Verbose ("Process found by Name: $($foundProcess.ProcessName) with ID $($foundProcess.Id) (Process set)")
                    }
                }
                else {

                    Microsoft.PowerShell.Utility\Write-Verbose ("Process found by Id: $($foundProcess.ProcessName) with ID $($foundProcess.Id) (Process set)")
                    $Process = $foundProcess
                    Microsoft.PowerShell.Utility\Write-Verbose ('Found process: ' + "$($Process.ProcessName) with ID $($Process.Id)")
                }
                } else {
                    Microsoft.PowerShell.Utility\Write-Verbose ('OnlyOutputCoords set - skipping process lookup for Process')
                }
                break;
            }
            'WindowHelper' {
                if (-not $skipProcessLookup) {
                    Microsoft.PowerShell.Utility\Write-Verbose ('ParameterSetName: WindowHelper')

                # get processes from window helper handles
                $foundProcess = Microsoft.PowerShell.Management\Get-Process `
                    -ErrorAction SilentlyContinue |
                    Microsoft.PowerShell.Core\Where-Object `
                        -Property MainWindowHandle `
                        -EQ $WindowHelper.Handle

                if ($null -eq $foundProcess) {

                    Microsoft.PowerShell.Utility\Write-Verbose ("No process found with window handle '$($WindowHelper.Handle)' (WindowHelper set)")
                    Microsoft.PowerShell.Utility\Write-Error ('No process found with ' + "window handle '$($WindowHelper.Handle)'")
                }
                else {

                    Microsoft.PowerShell.Utility\Write-Verbose ("Process found by WindowHelper: $($foundProcess.ProcessName) with ID $($foundProcess.Id) (WindowHelper set)")
                    $Process = $foundProcess
                    Microsoft.PowerShell.Utility\Write-Verbose ('Found process: ' + "$($Process.ProcessName) with ID $($Process.Id)")
                }
                } else {
                    Microsoft.PowerShell.Utility\Write-Verbose ('OnlyOutputCoords set - skipping process lookup for WindowHelper')
                }
                break;
            }
            default {
                if (-not $skipProcessLookup) {
                    Microsoft.PowerShell.Utility\Write-Verbose ('ParameterSetName: default (using PowerShell main window process)')
                    # default to powershell main window process
                    $Process = (GenXdev.Windows\Get-PowershellMainWindowProcess)
                } else {
                    Microsoft.PowerShell.Utility\Write-Verbose ('OnlyOutputCoords set - skipping default process lookup')
                }
                break;
            }
        }
    }

    process {


        ########################################################################

        # handle coordinate-only calculation mode without process interaction
        # this mode calculates positioning coordinates without actually moving any window
        if ($OnlyOutputCoords) {

            Microsoft.PowerShell.Utility\Write-Verbose ('OnlyOutputCoords mode - calculating coordinates without process')

            # Handle side-by-side logic for coordinate calculation
            if ($SideBySideRequested) {
                Microsoft.PowerShell.Utility\Write-Verbose ('Side-by-side requested in coordinate-only mode')

                # For coordinate calculation, assume PowerShell is on primary monitor (index 0)
                # and use sensible defaults for side-by-side positioning
                $powerShellMonitorIndex = 0
                if ($allScreens.Count -gt 1) {
                    # Use next monitor for side-by-side if available
                    $Monitor = 1
                } else {
                    # Single monitor - use half-screen positioning
                    $Monitor = 0
                }

                $SideBySide = $true
                $SetForeground = $true
                $RestoreFocus = $true
                $SetRestored = $true
                $Maximize = $false
                $FullScreen = $false

                # Determine split direction based on primary monitor dimensions
                $primaryScreen = $allScreens[0]
                if ($primaryScreen.WorkingArea.Width -gt $primaryScreen.WorkingArea.Height) {
                    # Wide screen - split horizontally (right side)
                    $Right = $true
                    Microsoft.PowerShell.Utility\Write-Verbose ('Coordinate-only side-by-side: using right half of screen')
                } else {
                    # Tall screen - split vertically (top half)
                    $Top = $true
                    Microsoft.PowerShell.Utility\Write-Verbose ('Coordinate-only side-by-side: using top half of screen')
                }

                Microsoft.PowerShell.Utility\Write-Verbose ("Side-by-side coordinate calculation: Monitor=$Monitor, Right=$Right, Top=$Top")
            }

            # evaluate if any positioning parameters were provided for calculation
            $havePositioningParams = ($X -gt -999999) -or ($Y -gt -999999) `
                -or ($Width -gt 0) -or ($Height -gt 0) `
                -or $Left -or $Right -or $Top -or $Bottom `
                -or $Centered -or $Fullscreen -or $SideBySide `
                -or $Maximize -or $Minimize -or $NoBorders

            # return null if no positioning parameters were provided for calculation
            if (-not $havePositioningParams) {
                Microsoft.PowerShell.Utility\Write-Verbose ('No positioning parameters provided for coordinate calculation')
                return $null
            }
        }

        # begin processing windows that require positioning or focus changes
        if (($null -ne $Process) -or $OnlyOutputCoords) {

            # log which type of processing is being performed
            if ($null -ne $Process) {
                Microsoft.PowerShell.Utility\Write-Verbose ("Processing window for process: $($Process.ProcessName) (Id: $($Process.Id))")
            } else {
                Microsoft.PowerShell.Utility\Write-Verbose ("Processing coordinate calculation (no process)")
            }

            # analyze all provided parameters to determine required operations
            $havePositioningParams = ($X -gt -999999) -or ($Y -gt -999999) `
                -or ($Width -gt 0) -or ($Height -gt 0) `
                -or $Left -or $Right -or $Top -or $Bottom `
                -or $Centered -or $Fullscreen -or $SideBySide `
                -or $Maximize -or $Minimize -or $NoBorders

            # check for focus and foreground control parameters
            $haveFocusParams = $SetForeground -or $FocusWindow -or $RestoreFocus -or ($KeysToSend -and ($KeysToSend.Count -gt 0))

            # determine overall processing requirements based on parameter analysis
            $shouldProcessWindow = $havePositioningParams -or $haveFocusParams -or ($null -ne $KeysToSend -and ($KeysToSend.Count -gt 0))

            # log comprehensive parameter analysis for troubleshooting and debugging
            Microsoft.PowerShell.Utility\Write-Verbose ("Positioning parameters " +
                "detected: $havePositioningParams (X=$X, Y=$Y, Width=$Width, " +
                "Height=$Height, Left=$Left, Right=$Right, Top=$Top, " +
                "Bottom=$Bottom, Centered=$Centered, Fullscreen=$Fullscreen, " +
                "SideBySide=$SideBySide, Maximize=$Maximize, Minimize=$Minimize, " +
                "NoBorders=$NoBorders)")

            # log focus and foreground parameter analysis for debugging
            Microsoft.PowerShell.Utility\Write-Verbose ("Focus parameters " +
                "detected: $haveFocusParams (SetForeground=$SetForeground, " +
                "FocusWindow=$FocusWindow, RestoreFocus=$RestoreFocus)")

            # log overall window processing decision based on parameter analysis
            Microsoft.PowerShell.Utility\Write-Verbose ("Should process window: " +
                "$shouldProcessWindow (positioning=$havePositioningParams, " +
                "focus=$haveFocusParams, keys=$($null -ne $KeysToSend -and ($KeysToSend.Count -gt 0)))")

            # obtain window handle for positioning operations (skip if coordinate-only mode)
            $window = $null
            $originalWindowState = $null
            if (-not $OnlyOutputCoords) {
                # get window object using either provided helper or process main window
                $window = $WindowHelper ? $WindowHelper : (GenXdev.Windows\Get-Window -ProcessId ($Process.Id))

                # capture current window state for potential restoration after positioning
                if ($null -ne $window) {
                    $originalWindowState = $window.CaptureState()
                    Microsoft.PowerShell.Utility\Write-Verbose ("Original window state captured: Maximized=$($originalWindowState.IsMaximized), Minimized=$($originalWindowState.IsMinimized)")
                }
            }

            # validate window object detection and log detailed window information
            if ($null -ne $window) {

                # log comprehensive window details for debugging and troubleshooting
                Microsoft.PowerShell.Utility\Write-Verbose ("`r`n-----------`r`nWindow object found:`r`n" +
                    "Title: $($window.Title)`r`n" +
                    "Handle: $($window.Handle)`r`n" +
                    "Position: $($window.Position().X),$($window.Position().Y)`r`n" +
                    "Size: $($window.Size().Width)x$($window.Size().Height)`r`n-----------")
            }
            else {

                # log appropriate message based on operation mode when window not found
                if (-not $OnlyOutputCoords) {
                    Microsoft.PowerShell.Utility\Write-Verbose ("No window object " +
                        "available for process $($Process.ProcessName)")
                } else {
                    Microsoft.PowerShell.Utility\Write-Verbose ("OnlyOutputCoords mode - no window object needed")
                }
            }

            # determine current monitor for window position comparison (skip in coordinate-only mode)
            $currentWindowScreen = $null
            if (($null -ne $window) -and (-not $OnlyOutputCoords)) {
                # detect which monitor currently contains the window based on position
                $currentWindowScreen = [WpfScreenHelper.Screen]::FromPoint(@{X = $window.Position().X; Y = $window.Position().Y })

                # log current monitor information for positioning reference
                Microsoft.PowerShell.Utility\Write-Verbose ("Window's current " +
                    "monitor detected: $($currentWindowScreen.DeviceName) - " +
                    "$($currentWindowScreen.WorkingArea.Width)x" +
                    "$($currentWindowScreen.WorkingArea.Height)")
            }
            # handle explicit primary monitor selection when monitor parameter is zero
            if ($Monitor -eq 0) {
                Microsoft.PowerShell.Utility\Write-Verbose ('Choosing primary ' +
                    'monitor, because default monitor requested using -Monitor 0')

                # select the system's primary monitor for window positioning
                $Screen = [WpfScreenHelper.Screen]::PrimaryScreen;

                # log primary monitor specifications for reference
                Microsoft.PowerShell.Utility\Write-Verbose ("Primary monitor " +
                    "selected: $($Screen.DeviceName) - " +
                    "$($Screen.WorkingArea.Width)x$($Screen.WorkingArea.Height) " +
                    "at ($($Screen.WorkingArea.X),$($Screen.WorkingArea.Y))")
            }
            elseif ((-not $SideBySide) -and ((GenXdev.Windows\Get-MonitorCount) -gt 1) -and $Monitor -eq -2 -and $setDefaultMonitor -is [int] -and $setDefaultMonitor -ge 0) {

                # use global default secondary monitor when available and valid
                $userMonitorNum = $setDefaultMonitor
                # For monitor selection, convert 1-based monitor number to 0-based array index
                # Monitor 1 = index 0, Monitor 2 = index 1, etc.
                $screenIndex = ($setDefaultMonitor - 1) % $AllScreens.Length
                Microsoft.PowerShell.Utility\Write-Verbose ('Picking monitor ' +
                    "#$userMonitorNum as secondary (requested with -monitor -2) " +
                    "set by `$Global:DefaultSecondaryMonitor")

                # select the user-configured secondary monitor from available screens
                $Screen = $AllScreens[$screenIndex];
                $Monitor = $setDefaultMonitor;

                # log secondary monitor selection details for verification
                Microsoft.PowerShell.Utility\Write-Verbose ("Secondary monitor " +
                    "selected: $($Screen.DeviceName) - " +
                    "$($Screen.WorkingArea.Width)x$($Screen.WorkingArea.Height) " +
                    "at ($($Screen.WorkingArea.X),$($Screen.WorkingArea.Y))")

            } elseif ($Monitor -eq -2 -and ((GenXdev.Windows\Get-MonitorCount) -gt 1) -and -not $SideBySide) {

                # fallback to first secondary monitor when global default not configured
                Microsoft.PowerShell.Utility\Write-Verbose ('Picking monitor #1 ' +
                    'as default secondary (requested with -monitor -2), because ' +
                    '`$Global:DefaultSecondaryMonitor not set')

                # select monitor index 1 as default secondary from available screens
                $Screen = $AllScreens[1 % $AllScreens.Length];

                # log fallback secondary monitor selection for reference
                Microsoft.PowerShell.Utility\Write-Verbose ("Default secondary " +
                    "monitor selected: $($Screen.DeviceName) - " +
                    "$($Screen.WorkingArea.Width)x$($Screen.WorkingArea.Height) " +
                    "at ($($Screen.WorkingArea.X),$($Screen.WorkingArea.Y))")
            }
            elseif ($Monitor -eq -2 -and -not $SideBySide) {
                # fallback to primary monitor when secondary monitor requested but unavailable
                Microsoft.PowerShell.Utility\Write-Verbose ('Monitor -2 requested ' + 'but no secondary monitor found, defaulting to primary.')
                $Monitor = 0
                $Screen = [WpfScreenHelper.Screen]::PrimaryScreen;

                # log fallback to primary monitor when secondary not available
                Microsoft.PowerShell.Utility\Write-Verbose ("Fallback to primary " +
                    "monitor: $($Screen.DeviceName) - " +
                    "$($Screen.WorkingArea.Width)x$($Screen.WorkingArea.Height) " +
                    "at ($($Screen.WorkingArea.X),$($Screen.WorkingArea.Y))")
            }
            elseif ((-not $SideBySide) -and $Monitor -ge 1) {

                # select specific monitor by user-provided number (1-based indexing)
                # Convert 1-based monitor number to 0-based array index
                $selectedIndex = ($Monitor - 1) % $AllScreens.Length

                Microsoft.PowerShell.Utility\Write-Verbose ('Picking monitor ' +
                    "#$Monitor (array index $selectedIndex) as requested by the -Monitor parameter")

                # select the specific monitor from available screens array
                $Screen = $AllScreens[$selectedIndex]

                # log requested monitor selection details for verification
                Microsoft.PowerShell.Utility\Write-Verbose ("Requested monitor " +
                    "selected: $($Screen.DeviceName) - " +
                    "$($Screen.WorkingArea.Width)x$($Screen.WorkingArea.Height) " +
                    "at ($($Screen.WorkingArea.X),$($Screen.WorkingArea.Y))")
            }
            else {
                # handle default monitor selection based on current context
                if (-not $SideBySide) {
                    Microsoft.PowerShell.Utility\Write-Verbose ('Picking monitor ' + '#1 (FromPoint)')
                    # use window's current monitor as default for positioning operations
                    $Screen = $currentWindowScreen

                    # fallback to primary monitor if no current window screen in coordinate-only mode
                    if ($null -eq $Screen) {
                        Microsoft.PowerShell.Utility\Write-Verbose ('No current window screen available, using primary monitor')
                        $Screen = $allScreens[0]
                    }

                    # log current monitor selection when successfully detected
                    if ($null -ne $Screen) {

                        Microsoft.PowerShell.Utility\Write-Verbose ("Monitor used: $($Screen.DeviceName) - " +
                            "$($Screen.WorkingArea.Width)x$($Screen.WorkingArea.Height) " +
                            "at ($($Screen.WorkingArea.X),$($Screen.WorkingArea.Y))")
                    }
                }
                else {
                    # use powershell's monitor for side-by-side positioning reference
                    if (($null -ne $powerShellWindow) -and (-not $OnlyOutputCoords)) {
                        $Screen = $allScreens[$powerShellWindow.GetCurrentMonitor()]
                        Microsoft.PowerShell.Utility\Write-Verbose ("PowerShell's " +
                            "current monitor used for side-by-side: " +
                            "$($Screen.DeviceName) - " +
                            "$($Screen.WorkingArea.Width)x$($Screen.WorkingArea.Height) " +
                            "at ($($Screen.WorkingArea.X),$($Screen.WorkingArea.Y))")
                    } else {
                        # In coordinate-only mode or when PowerShell window not available, use primary monitor
                        $Screen = $allScreens[0]
                        Microsoft.PowerShell.Utility\Write-Verbose ("Side-by-side coordinate calculation using primary monitor: " +
                            "$($Screen.DeviceName) - " +
                            "$($Screen.WorkingArea.Width)x$($Screen.WorkingArea.Height) " +
                            "at ($($Screen.WorkingArea.X),$($Screen.WorkingArea.Y))")
                    }
                }
            }

            # handle side-by-side positioning
            if ($SideBySide -and (($null -eq $powerShellWindow) -or ($null -eq $window) -or ($powerShellWindow.Handle -ne $window.Handle) -or $OnlyOutputCoords)) {

                Microsoft.PowerShell.Utility\Write-Verbose ('SideBySide requested')

                if ($OnlyOutputCoords) {
                    Microsoft.PowerShell.Utility\Write-Verbose ('Side-by-side coordinate calculation mode')
                    # In coordinate-only mode, position logic is already set above
                    # Just ensure the positioning flags are properly set
                    $FullScreen = $false
                    $Centered = $false
                    $RestoreFocus = $true
                } else {
                    # Normal side-by-side window positioning
                    $PowershellScreen = $Screen  # Use the same screen as determined above
                    $powershellMonitorIndex = $AllScreens.IndexOf($PowershellScreen) + 1
                    Microsoft.PowerShell.Utility\Write-Verbose ('Window and PowerShell are ' + 'on the same screen.')
                    Microsoft.PowerShell.Utility\Write-Verbose ("PowerShell screen index: " +
                        "$powershellMonitorIndex for side-by-side positioning")

                    $Left = $false; $Top = $false; $Right = $false; $FullScreen = $false; $Centered = $false
                    if ($null -ne $KeysToSend -and $KeysToSend.Count -eq 1 -and $KeysToSend[0] -in @('f', '{F11}')) {
                        $KeysToSend = @()
                    }
                    $RestoreFocus = $true

                    # split horizontally or vertically based on screen orientation
                    if ($PowershellScreen.WorkingArea.Width -gt $PowershellScreen.WorkingArea.Height) {
                        Microsoft.PowerShell.Utility\Write-Verbose ('Screen is wider than ' +
                            'tall, splitting horizontally (Left). Screen dimensions: ' +
                            "$($PowershellScreen.WorkingArea.Width)x" +
                            "$($PowershellScreen.WorkingArea.Height)")
                        GenXdev.Windows\Set-WindowPosition -Left -Monitor $powershellMonitorIndex
                        $FullScreen = $false
                        $Right = $true
                        Microsoft.PowerShell.Utility\Write-Verbose ('PowerShell moved to ' + 'left, target window will be positioned on right')
                    }
                    else {
                        Microsoft.PowerShell.Utility\Write-Verbose ('Screen is taller than ' +
                            'wide, splitting vertically (Bottom). Screen dimensions: ' +
                            "$($PowershellScreen.WorkingArea.Width)x" +
                            "$($PowershellScreen.WorkingArea.Height)")
                        GenXdev.Windows\Set-WindowPosition -Bottom -Monitor $powershellMonitorIndex
                        $FullScreen = $false
                        $Top = $true
                        Microsoft.PowerShell.Utility\Write-Verbose ('PowerShell moved to ' + 'bottom, target window will be positioned at top')
                    }
                }
            }

            if ($null -eq $screen) {
                Microsoft.PowerShell.Utility\Write-Verbose ("No screen object set, using window's current monitor as fallback.")
                $screen = $currentWindowScreen ? $currentWindowScreen : $allScreens[0]
            }

            # detect if monitor change is being requested (skip in coordinate-only mode)
            $isMonitorChangeRequest = $false
            if (($Monitor -ge 0) -and ($null -ne $currentWindowScreen) -and ($null -ne $Screen) -and (-not $OnlyOutputCoords)) {

                $isMonitorChangeRequest = ($currentWindowScreen.DeviceName -ne $Screen.DeviceName)

                if ($isMonitorChangeRequest) {

                    Microsoft.PowerShell.Utility\Write-Verbose ("Monitor change " +
                        "detected: Moving window from " +
                        "'$($currentWindowScreen.DeviceName)' to " +
                        "'$($Screen.DeviceName)'")
                    Microsoft.PowerShell.Utility\Write-Verbose ("Source monitor " +
                        "working area: $($currentWindowScreen.WorkingArea.Width)x" +
                        "$($currentWindowScreen.WorkingArea.Height) at " +
                        "($($currentWindowScreen.WorkingArea.X)," +
                        "$($currentWindowScreen.WorkingArea.Y))")
                    Microsoft.PowerShell.Utility\Write-Verbose ("Target monitor " +
                        "working area: $($Screen.WorkingArea.Width)x" +
                        "$($Screen.WorkingArea.Height) at " +
                        "($($Screen.WorkingArea.X),$($Screen.WorkingArea.Y))")

                    # Monitor change implies positioning is needed
                    if (-not $havePositioningParams) {

                        Microsoft.PowerShell.Utility\Write-Verbose ('No explicit ' + 'positioning parameters, but monitor change requested ' +
                            '- enabling positioning for monitor change')
                        $havePositioningParams = $true

                        Microsoft.PowerShell.Utility\Write-Verbose ('Detecting ' +
                            'current window position to preserve when moving to ' +
                            'new monitor')

                        # Get current window position and size
                        $currentPos = $window.Position()
                        $currentSize = $window.Size()
                        $currentWorkArea = $currentWindowScreen.WorkingArea

                        # Calculate relative position within current monitor's work area
                        $relativeX = ($currentPos.X - $currentWorkArea.X) / $currentWorkArea.Width
                        $relativeY = ($currentPos.Y - $currentWorkArea.Y) / $currentWorkArea.Height
                        $relativeWidth = $currentSize.Width / $currentWorkArea.Width
                        $relativeHeight = $currentSize.Height / $currentWorkArea.Height

                        Microsoft.PowerShell.Utility\Write-Verbose ("Current relative position: X=$([Math]::Round($relativeX, 2)), Y=$([Math]::Round($relativeY, 2)), W=$([Math]::Round($relativeWidth, 2)), H=$([Math]::Round($relativeHeight, 2))")

                        # Detect positioning style based on relative position and size
                        $tolerance = 0.1  # 10% tolerance for position detection
                        $sizeTolerance = 0.4  # 40% minimum size to consider positioned (allows for half-screen at 50%)

                        # Determine primary positioning based on which dimension is more constrained
                        # If width is more constrained (< 90% of screen), check left/right first
                        # If height is more constrained (< 90% of screen), check top/bottom first

                        $widthConstrained = $relativeWidth -lt 0.9
                        $heightConstrained = $relativeHeight -lt 0.9

                        # Priority 1: Check the more constrained dimension first
                        if ($widthConstrained -and (-not $heightConstrained)) {
                            # Width is constrained, height spans most/all screen - check left/right
                            if ($relativeWidth -ge $sizeTolerance) {
                                if ($relativeX -le $tolerance) {
                                    $Left = $true
                                    Microsoft.PowerShell.Utility\Write-Verbose ('Detected LEFT positioning (full height) - preserving on new monitor')
                                } elseif (($relativeX + $relativeWidth) -ge (1.0 - $tolerance)) {
                                    $Right = $true
                                    Microsoft.PowerShell.Utility\Write-Verbose ('Detected RIGHT positioning (full height) - preserving on new monitor')
                                }
                            }
                        } elseif ($heightConstrained -and (-not $widthConstrained)) {
                            # Height is constrained, width spans most/all screen - check top/bottom
                            if ($relativeHeight -ge $sizeTolerance) {
                                if ($relativeY -le $tolerance) {
                                    $Top = $true
                                    Microsoft.PowerShell.Utility\Write-Verbose ('Detected TOP positioning (full width) - preserving on new monitor')
                                } elseif (($relativeY + $relativeHeight) -ge (1.0 - $tolerance)) {
                                    $Bottom = $true
                                    Microsoft.PowerShell.Utility\Write-Verbose ('Detected BOTTOM positioning (full width) - preserving on new monitor')
                                }
                            }
                        } elseif ($widthConstrained -and $heightConstrained) {
                            # Both dimensions constrained - check for corner positioning or centered
                            $centerX = $relativeX + ($relativeWidth / 2)
                            $centerY = $relativeY + ($relativeHeight / 2)

                            # Window with 10% margins (like X=0.1, W=0.8) should be considered centered
                            $leftMargin = $relativeX
                            $rightMargin = 1.0 - ($relativeX + $relativeWidth)
                            $topMargin = $relativeY
                            $bottomMargin = 1.0 - ($relativeY + $relativeHeight)

                            # Consider centered if ALL margins are small (≤ 10% for more reasonable detection)
                            $hasSmallMargins = ($leftMargin -le 0.1) -and ($rightMargin -le 0.1) -and ($topMargin -le 0.1) -and ($bottomMargin -le 0.1)

                            Microsoft.PowerShell.Utility\Write-Verbose ("Positioning check: centerX=$([Math]::Round($centerX, 2)), centerY=$([Math]::Round($centerY, 2))")
                            Microsoft.PowerShell.Utility\Write-Verbose ("Window bounds: X=$([Math]::Round($relativeX, 2)), Y=$([Math]::Round($relativeY, 2)), W=$([Math]::Round($relativeWidth, 2)), H=$([Math]::Round($relativeHeight, 2))")
                            Microsoft.PowerShell.Utility\Write-Verbose ("Actual margins: Left=$([Math]::Round($leftMargin, 3)), Right=$([Math]::Round($rightMargin, 3)), Top=$([Math]::Round($topMargin, 3)), Bottom=$([Math]::Round($bottomMargin, 3))")
                            Microsoft.PowerShell.Utility\Write-Verbose ("Has small margins (all ≤ 10%): $hasSmallMargins")

                            # If window has small margins on all sides, consider it centered
                            if ($hasSmallMargins) {
                                $Centered = $true
                                Microsoft.PowerShell.Utility\Write-Verbose ('Detected CENTERED positioning (small margins on all sides) - preserving on new monitor')
                            } else {
                                # Check for specific edge positioning
                                # Check left/right first
                                if ($relativeWidth -ge $sizeTolerance) {
                                    if ($relativeX -le $tolerance) {
                                        $Left = $true
                                        Microsoft.PowerShell.Utility\Write-Verbose ('Detected LEFT positioning - preserving on new monitor')
                                    } elseif (($relativeX + $relativeWidth) -ge (1.0 - $tolerance)) {
                                        $Right = $true
                                        Microsoft.PowerShell.Utility\Write-Verbose ('Detected RIGHT positioning - preserving on new monitor')
                                    }
                                }
                                # Then check top/bottom
                                if ($relativeHeight -ge $sizeTolerance) {
                                    if ($relativeY -le $tolerance) {
                                        $Top = $true
                                        Microsoft.PowerShell.Utility\Write-Verbose ('Detected TOP positioning - preserving on new monitor')
                                    } elseif (($relativeY + $relativeHeight) -ge (1.0 - $tolerance)) {
                                        $Bottom = $true
                                        Microsoft.PowerShell.Utility\Write-Verbose ('Detected BOTTOM positioning - preserving on new monitor')
                                    }
                                }

                                # If no specific positioning detected, just enable positioning for auto-sizing
                                if ((-not $Left) -and (-not $Right) -and (-not $Top) -and (-not $Bottom)) {
                                    Microsoft.PowerShell.Utility\Write-Verbose ('No specific positioning detected - enabling auto-sizing to maximum')
                                }
                            }
                        } else {
                            # Neither dimension particularly constrained - likely fullscreen or very large window
                            # Check margins for large window centered detection
                            $leftMargin = $relativeX
                            $rightMargin = 1.0 - ($relativeX + $relativeWidth)
                            $topMargin = $relativeY
                            $bottomMargin = 1.0 - ($relativeY + $relativeHeight)

                            # For large windows, be even more generous (≤ 15% margins)
                            $hasSmallMargins = ($leftMargin -le 0.15) -and ($rightMargin -le 0.15) -and ($topMargin -le 0.15) -and ($bottomMargin -le 0.15)

                            if (-not $hasSmallMargins) {
                                $Centered = $true
                                Microsoft.PowerShell.Utility\Write-Verbose ('Detected CENTERED positioning (large window with small margins) - preserving on new monitor')
                            } else {
                                Microsoft.PowerShell.Utility\Write-Verbose ('Large window not centered - enabling auto-sizing to maximum')
                            }
                        }
                    }
                }
            }

            # calculate final window coordinates and dimensions
            if (($X -le -999999) -or ($X -isnot [int])) {
                Microsoft.PowerShell.Utility\Write-Verbose ('X not provided or invalid, using screen.WorkingArea.X')
                $X = $Screen.WorkingArea.X;
            }
            else {
                # adjust x position for monitor offset
                if ($Monitor -ge 0) {
                    Microsoft.PowerShell.Utility\Write-Verbose ('Adjusting X for monitor offset.')
                    $X = $Screen.WorkingArea.X + $X;
                }
            }
            Microsoft.PowerShell.Utility\Write-Verbose ("X determined to be $X")
            # calculate y position
            if (($Y -le -999999) -or ($Y -isnot [int])) {
                Microsoft.PowerShell.Utility\Write-Verbose ('Y not provided or invalid, using screen.WorkingArea.Y')
                $Y = $Screen.WorkingArea.Y;
            }
            else {
                # adjust y position for monitor offset
                if ($Monitor -ge 0) {
                    Microsoft.PowerShell.Utility\Write-Verbose ('Adjusting Y for monitor offset.')
                    $Y = $Screen.WorkingArea.Y + $Y;
                }
            }
            Microsoft.PowerShell.Utility\Write-Verbose ("Y determined to be $Y")
            # set fullscreen dimensions if requested
            if ($Fullscreen -eq $true) {
                Microsoft.PowerShell.Utility\Write-Verbose ('Fullscreen requested, setting Width/Height to screen.WorkingArea.')
                $Width = $Screen.WorkingArea.Width;
                $Height = $Screen.WorkingArea.Height;
            }
            Microsoft.PowerShell.Utility\Write-Verbose ('Have positioning parameters set')

            # Reset width/height for smart positioning if detected during monitor change
            if ($isMonitorChangeRequest -and ($Left -or $Right -or $Top -or $Bottom -or $Centered)) {
                $Width = -999999
                $Height = -999999
                Microsoft.PowerShell.Utility\Write-Verbose ('Reset Width/Height to allow smart positioning to control sizing')
            }

            # check if width and height were explicitly provided
            $widthProvided = ($Width -gt 0) -and ($Width -is [int]);
            $heightProvided = ($Height -gt 0) -and ($Height -is [int]);
            # use screen width if width not provided
            if ($widthProvided -eq $false) {
                Microsoft.PowerShell.Utility\Write-Verbose ('Width not provided, using screen.WorkingArea.Width')
                $Width = $Screen.WorkingArea.Width;
                Microsoft.PowerShell.Utility\Write-Verbose ('Width not provided ' + "resetted to $Width")
            }
            # use screen height if height not provided
            if ($heightProvided -eq $false) {
                Microsoft.PowerShell.Utility\Write-Verbose ('Height not provided, using screen.WorkingArea.Height')
                $Height = $Screen.WorkingArea.Height;
                Microsoft.PowerShell.Utility\Write-Verbose ('Height not provided ' + "resetted to $Height")
            }
            # apply layout positioning (left/right/top/bottom/centered)
            if ($Left -eq $true) {
                Microsoft.PowerShell.Utility\Write-Verbose ('Left positioning requested.')
                $X = $Screen.WorkingArea.X;
                Microsoft.PowerShell.Utility\Write-Verbose ("Left positioning: " +
                    "X coordinate set to screen working area left edge: $X")
                # use half width if not explicitly provided
                if ($widthProvided -eq $false) {
                    Microsoft.PowerShell.Utility\Write-Verbose ('Width not provided ' + 'for Left, using half screen width.')
                    $Width = [Math]::Min($Screen.WorkingArea.Width / 2, $Width);
                    Microsoft.PowerShell.Utility\Write-Verbose ("Auto-calculated " +
                        "width for left positioning: $Width (half of " +
                        "$($Screen.WorkingArea.Width))")
                }
                Microsoft.PowerShell.Utility\Write-Verbose ("Left chosen, " +
                    "X = $X, Width = $Width")
            }
            else {
                # position on right side
                if ($Right -eq $true) {
                    Microsoft.PowerShell.Utility\Write-Verbose ('Right positioning requested.')
                    # use half width if not explicitly provided
                    if ($widthProvided -eq $false) {
                        Microsoft.PowerShell.Utility\Write-Verbose ('Width not ' + 'provided for Right, using half screen width.')
                        $Width = [Math]::Min($Screen.WorkingArea.Width / 2, $Width);
                        Microsoft.PowerShell.Utility\Write-Verbose ("Auto-calculated " +
                            "width for right positioning: $Width (half of " +
                            "$($Screen.WorkingArea.Width))")
                    }
                    $X = $Screen.WorkingArea.X + $Screen.WorkingArea.Width - $Width;
                    Microsoft.PowerShell.Utility\Write-Verbose ("Right positioning: " +
                        "X coordinate calculated as " +
                        "$($Screen.WorkingArea.X) + $($Screen.WorkingArea.Width) " +
                        "- $Width = $X")
                    Microsoft.PowerShell.Utility\Write-Verbose ("Right chosen, " +
                        "X = $X, Width = $Width")
                }
            }
            # position on top
            if ($Top -eq $true) {
                Microsoft.PowerShell.Utility\Write-Verbose ('Top positioning requested.')
                $Y = $Screen.WorkingArea.Y;
                Microsoft.PowerShell.Utility\Write-Verbose ("Top positioning: " +
                    "Y coordinate set to screen working area top edge: $Y")
                # use half height if not explicitly provided
                if ($heightProvided -eq $false) {
                    Microsoft.PowerShell.Utility\Write-Verbose ('Height not provided ' + 'for Top, using half screen height.')
                    $Height = [Math]::Min($Screen.WorkingArea.Height / 2, $Height);
                    Microsoft.PowerShell.Utility\Write-Verbose ("Auto-calculated " +
                        "height for top positioning: $Height (half of " +
                        "$($Screen.WorkingArea.Height))")
                }
                Microsoft.PowerShell.Utility\Write-Verbose ("Top chosen, " +
                    "Y = $Y, Height = $Height")
            }
            else {
                # position on bottom
                if ($Bottom -eq $true) {
                    Microsoft.PowerShell.Utility\Write-Verbose ('Bottom positioning requested.')
                    # use half height if not explicitly provided
                    if ($heightProvided -eq $false) {
                        Microsoft.PowerShell.Utility\Write-Verbose ('Height not ' + 'provided for Bottom, using half screen height.')
                        $Height = [Math]::Min($Screen.WorkingArea.Height / 2, $Height);
                        Microsoft.PowerShell.Utility\Write-Verbose ("Auto-calculated " +
                            "height for bottom positioning: $Height (half of " +
                            "$($Screen.WorkingArea.Height))")
                    }
                    $Y = $Screen.WorkingArea.Y + $Screen.WorkingArea.Height - $Height;
                    Microsoft.PowerShell.Utility\Write-Verbose ("Bottom positioning: " +
                        "Y coordinate calculated as " +
                        "$($Screen.WorkingArea.Y) + $($Screen.WorkingArea.Height) " +
                        "- $Height = $Y")
                    Microsoft.PowerShell.Utility\Write-Verbose ("Bottom chosen, " +
                        "Y = $Y, Height = $Height")
                }
            }
            # center window on screen
            if ($Centered -eq $true) {

                Microsoft.PowerShell.Utility\Write-Verbose ('Centered positioning requested.')

                # use 80% of screen dimensions if not explicitly provided
                if ($heightProvided -eq $false) {

                    Microsoft.PowerShell.Utility\Write-Verbose ('Height not provided ' + 'for Centered, using 80% of screen height.')
                    $Height = [Math]::Round([Math]::Min($Screen.WorkingArea.Height * 0.8, $Height), 0);

                    Microsoft.PowerShell.Utility\Write-Verbose ("Auto-calculated " +
                        "height for centered positioning: $Height (80% of " +
                        "$($Screen.WorkingArea.Height))")
                }

                if ($widthProvided -eq $false) {

                    Microsoft.PowerShell.Utility\Write-Verbose ('Width not provided ' + 'for Centered, using 80% of screen width.')

                    $Width = [Math]::Round([Math]::Min($Screen.WorkingArea.Width * 0.8, $Width), 0);

                    Microsoft.PowerShell.Utility\Write-Verbose ("Auto-calculated " +
                        "width for centered positioning: $Width (80% of " +
                        "$($Screen.WorkingArea.Width))")
                }

                # calculate center position
                $X = $Screen.WorkingArea.X + [Math]::Round(($screen.WorkingArea.Width - $Width) / 2, 0);
                $Y = $Screen.WorkingArea.Y + [Math]::Round(($screen.WorkingArea.Height - $Height) / 2, 0);

                Microsoft.PowerShell.Utility\Write-Verbose ("Centered position " +
                    "calculation: X = $($Screen.WorkingArea.X) + " +
                    "(($($screen.WorkingArea.Width) - $Width) / 2) = $X")
                Microsoft.PowerShell.Utility\Write-Verbose ("Centered position " +
                    "calculation: Y = $($Screen.WorkingArea.Y) + " +
                    "(($($screen.WorkingArea.Height) - $Height) / 2) = $Y")
                Microsoft.PowerShell.Utility\Write-Verbose ("Centered chosen, " +
                    "X = $X, Width = $Width, Y = $Y, Height = $Height")
            }

            # recalculate shouldProcessWindow after all positioning logic is complete
            # (monitor change detection may have updated havePositioningParams)
            $shouldProcessWindow = $havePositioningParams -or $haveFocusParams -or ($null -ne $KeysToSend -and ($KeysToSend.Count -gt 0))

            Microsoft.PowerShell.Utility\Write-Verbose ("Final shouldProcessWindow check: $shouldProcessWindow (positioning=$havePositioningParams, focus=$haveFocusParams, keys=$($null -ne $KeysToSend -and ($KeysToSend.Count -gt 0)))")

            # if OnlyOutputCoords is set, return the calculated coordinates without positioning
            if ($OnlyOutputCoords) {
                Microsoft.PowerShell.Utility\Write-Verbose ('OnlyOutputCoords specified - returning calculated coordinates without positioning window')

                $coordsOutput = @{
                    Left   = $X
                    Top    = $Y
                    Width  = $Width
                    Height = $Height
                }

                Microsoft.PowerShell.Utility\Write-Verbose ("Calculated coordinates: Left=$($coordsOutput.Left), Top=$($coordsOutput.Top), Width=$($coordsOutput.Width), Height=$($coordsOutput.Height)")

                return $coordsOutput
            }

            if (-not $shouldProcessWindow) {
                Microsoft.PowerShell.Utility\Write-Verbose ('No positioning, focus, or key parameters provided - exiting early')
                return;
            }

            # confirm with user if whatif support is enabled
            $whatIfMessage = if ($havePositioningParams) {
                "Set position/size to: X=$X Y=$Y W=$Width H=$Height"
            } elseif ($haveFocusParams) {
                "Apply focus/foreground changes"
            } elseif ($null -ne $KeysToSend -and ($KeysToSend.Count -gt 0)) {
                "Send keystrokes: $($KeysToSend -join ', ')"
            }
            else {
                "No additional information available"
            }

            if ($PSCmdlet.ShouldProcess(
                    "Window of process '$($Process.ProcessName)'",
                    $whatIfMessage)) {

                Microsoft.PowerShell.Utility\Write-Verbose ('ShouldProcess returned ' + 'true, proceeding with window operations.')

                if ($havePositioningParams) {
                    Microsoft.PowerShell.Utility\Write-Verbose ("Final window positioning: " +
                        "Process='$($Process.ProcessName))', Handle=$($window.Handle), " +
                        "Target coordinates: X=$X, Y=$Y, Width=$Width, Height=$Height")

                    Microsoft.PowerShell.Utility\Write-Verbose ("Target monitor: " +
                        "$($Screen.DeviceName) - Working area: " +
                        "$($Screen.WorkingArea.Width)x$($Screen.WorkingArea.Height) " +
                        "at ($($Screen.WorkingArea.X),$($Screen.WorkingArea.Y))")
                } else {
                    Microsoft.PowerShell.Utility\Write-Verbose ("Processing window for focus/foreground or keystroke operations only - no positioning")
                }

                # have a handle to the mainwindow of the browser?
                if ($null -ne $window) {

                    if ($havePositioningParams) {
                        Microsoft.PowerShell.Utility\Write-Verbose ('Restoring and ' +
                            'positioning window')

                        # restore window from maximized/minimized state first
                        Microsoft.PowerShell.Utility\Write-Verbose ('Restoring window from maximized/minimized state')
                        $null = $window.Restore()

                        # focus and position window
                        Microsoft.PowerShell.Utility\Write-Verbose ('Showing window ' + '(first call to ensure window is visible)')
                        $null = $window.Focus()
                        Microsoft.PowerShell.Utility\Write-Verbose ("[Set-WindowPosition] " +
                            "About to move window. Handle: $($window.Handle) " +
                            "Target: X=$X, Y=$Y, Width=$Width, Height=$Height")
                        Microsoft.PowerShell.Utility\Write-Verbose ('Executing first ' + 'Move operation to set window position and size')
                        $null = $window.Move($X, $Y, $Width, $Height)
                        Microsoft.PowerShell.Utility\Write-Verbose ('Executing second ' + 'Move operation for stability (some windows need this)')
                        $null = $window.Move($X, $Y, $Width, $Height)
                        Microsoft.PowerShell.Utility\Write-Verbose ('Window positioning ' + 'operations completed successfully')
                    } else {
                        Microsoft.PowerShell.Utility\Write-Verbose ('No positioning parameters - skipping window positioning operations')
                    }
                    # maximize window if fullscreen requested
                    if ($Fullscreen) {

                        Microsoft.PowerShell.Utility\Write-Verbose ('Fullscreen ' + 'requested, sending F11 keystroke.')
                        $KeysToSend = ($KeysToSend ? $KeysToSend : @()) + @('{F11}')
                    }
                    # needs to be set noborders manually?
                    if ($NoBorders -eq $true) {

                        Microsoft.PowerShell.Utility\Write-Verbose ('Setting NoBorders ' + '- removing window chrome and decorations')
                        $null = $window.RemoveBorder();
                        Microsoft.PowerShell.Utility\Write-Verbose ('Window border ' + 'removal completed')
                    }

                    if ($Maximize) {

                        if ($PSBoundParameters.Count -gt 1) {
                            Microsoft.PowerShell.Utility\Start-Sleep 1
                        }

                        Microsoft.PowerShell.Utility\Write-Verbose ('Maximize requested, maximizing window.')
                        $null = $window.Maximize()
                        Microsoft.PowerShell.Utility\Write-Verbose ('Window maximization completed')
                    }
                    elseif ($Minimize) {

                        Microsoft.PowerShell.Utility\Write-Verbose ('Minimize requested, minimizing window.')
                        $null = $window.Minimize()
                        Microsoft.PowerShell.Utility\Write-Verbose ('Window minimization completed')
                    }
                    elseif ($SetRestored) {

                        Microsoft.PowerShell.Utility\Write-Verbose ('SetRestored requested, ensuring window is in normal state.')
                        $null = $window.Restore()
                        Microsoft.PowerShell.Utility\Write-Verbose ('Window restored to normal state')
                    }
                    elseif ($havePositioningParams -and ($null -ne $originalWindowState)) {

                        # No explicit state requested, but we moved the window
                        # Restore original state, but never restore to minimized
                        # (if you call Set-WindowPosition, you want to see the window)
                        if ($originalWindowState.IsMaximized) {
                            Microsoft.PowerShell.Utility\Write-Verbose ('Restoring original maximized state after positioning')
                            $null = $window.Maximize()
                        }
                        elseif ($originalWindowState.IsMinimized) {
                            Microsoft.PowerShell.Utility\Write-Verbose ('Window was minimized, but restoring to normal state (not minimized) since Set-WindowPosition was called')
                            $null = $window.Restore()
                        }
                        else {
                            Microsoft.PowerShell.Utility\Write-Verbose ('Preserving original normal window state')
                            # Already in normal state from the Restore() call before Move()
                        }
                    }
                    # handle focus and foreground - if both requested, SetForeground handles both
                    if ($SetForeground -eq $true) {
                        Microsoft.PowerShell.Utility\Write-Verbose ('Setting window to ' +
                            'foreground (bringing to front and giving focus)')
                        $null = $window.SetForeground()
                        Microsoft.PowerShell.Utility\Write-Verbose ('Window foreground ' + 'operation completed')
                    }
                    elseif ($FocusWindow -eq $true) {
                        Microsoft.PowerShell.Utility\Write-Verbose ('Focusing window')
                        $null = $window.Focus()
                    }
                    # send keys if specified, after a delay to ensure window is ready
                    if ($null -ne $KeysToSend -and ($KeysToSend.Count -gt 0)) {

                        $KeysToSend = @($KeysToSend | Microsoft.PowerShell.Core\Where-Object { -not [string]::IsNullOrEmpty($_) })

                        if ($null -ne $KeysToSend -and ($KeysToSend.Count -gt 0)) {

                            Microsoft.PowerShell.Utility\Write-Verbose ('Sending keystrokes ' +
                                'to window after 500ms delay. Keys to send: ' +
                                "$($KeysToSend -join ', ')")

                            Microsoft.PowerShell.Utility\Start-Sleep -Milliseconds 500

                            # copy identical parameters between functions
                            $params = GenXdev.FileSystem\Copy-IdenticalParamValues `
                                -FunctionName 'GenXdev.Windows\Send-Key' `
                                -BoundParameters $myPSBoundParameters `
                                -DefaultValues (Microsoft.PowerShell.Utility\Get-Variable `
                                    -Scope Local -ErrorAction SilentlyContinue)

                            # set the window handle for the send-key function
                            $params.WindowHandle = $window.Handle
                            $params.KeysToSend = $KeysToSend
                            $null = $params.Remove('Process')
                            $null = $params.Remove('ProcessName')

                            # send keys to the window
                            Microsoft.PowerShell.Utility\Write-Verbose ("Calling Send-Key " +
                                "with window handle $($window.Handle) and parameters: " +
                                "$($params | Microsoft.PowerShell.Utility\Out-String)")

                            $null = GenXdev.Windows\Send-Key @params -SendKeyHoldKeyboardFocus
                            Microsoft.PowerShell.Utility\Write-Verbose ('Keystroke sending ' + 'operation completed')
                        }
                    }
                } else {

                    Microsoft.PowerShell.Utility\Write-Verbose ('No window object ' +
                        'available to position.')
                }

                # return window helper if passthru specified
                if ($PassThru -eq $true) {

                    Microsoft.PowerShell.Utility\Write-Verbose ('PassThru specified, returning window object.')
                    $window
                }
            } else {
                Microsoft.PowerShell.Utility\Write-Verbose ('ShouldProcess returned false, skipping window positioning.')
            }
        } else {
            Microsoft.PowerShell.Utility\Write-Verbose ('No process object available, skipping window positioning.')
        }
    }

    end {

        # only proceed if restore focus was requested
        if ($RestoreFocus) {

            $powerShellWindow = GenXdev.Windows\Get-PowershellMainWindow
            if (-not $powerShellWindow) {
                Microsoft.PowerShell.Utility\Write-Verbose 'Failed to retrieve PowerShell main window for focus restoration.'
                return
            }
            Microsoft.PowerShell.Utility\Write-Verbose ('RestoreFocus requested ' + 'and target window differs from PowerShell window')
            Microsoft.PowerShell.Utility\Write-Verbose ("Target window handle: " +
                "$($process.MainWindowHandle)), PowerShell handle: " +
                "$($powerShellWindow.handle)")

            Microsoft.PowerShell.Utility\Write-Verbose ('Restoring focus to ' + 'PowerShell window using Set-WindowPosition with ' +
                '-SetForeground')

            $null = $powerShellWindow.SetForeground();

            Microsoft.PowerShell.Utility\Write-Verbose ('PowerShell window ' + 'focus restoration completed')
        }
    }
}
################################################################################