|
| 1 | +# End-to-end check of ShowSystemMenu (#66) from Flutter on Windows: a |
| 2 | +# secondary click on flutter_window_title_bar_example's DragToMoveArea strip |
| 3 | +# opens the native system menu at the pointer, with the item states of the |
| 4 | +# window's current state, and a chosen item acts on the window. Owner-guarded |
| 5 | +# clicks on the example's own window and menu only, no keyboard input. |
| 6 | +$ErrorActionPreference = 'Stop' |
| 7 | +. "$PSScriptRoot\env.ps1" |
| 8 | +. "$PSScriptRoot\winput.ps1" |
| 9 | +. "$PSScriptRoot\guiapp.ps1" |
| 10 | +Add-Type @" |
| 11 | +using System; |
| 12 | +using System.Runtime.InteropServices; |
| 13 | +public static class MenuWin { |
| 14 | + [DllImport("user32.dll")] public static extern bool IsZoomed(IntPtr h); |
| 15 | +} |
| 16 | +"@ |
| 17 | + |
| 18 | +Start-Result "$RemoteScratch\flutter_window_title_bar_system_menu_test.result.txt" |
| 19 | +$exe = $env:TITLE_BAR_EXAMPLE_EXE |
| 20 | +if (-not $exe) { |
| 21 | + $exe = Get-FlutterExe "$RemoteWorkspace\examples\flutter_window_title_bar_example" 'window_title_bar_example' |
| 22 | +} |
| 23 | +Assert-Idle |
| 24 | +$app = Start-GuiApp $exe |
| 25 | +# The probe fails (a traceback on stderr) until the VM service is up, and |
| 26 | +# PowerShell 5.1 turns native stderr into a terminating error under Stop. |
| 27 | +function Get-ViewsQuietly { |
| 28 | + $saved = $ErrorActionPreference |
| 29 | + $ErrorActionPreference = 'Continue' |
| 30 | + try { @(Get-Views $app 2>$null) } catch { @() } finally { $ErrorActionPreference = $saved } |
| 31 | +} |
| 32 | +function Get-State { |
| 33 | + $script:win = Get-Win $app 'nativeapi*' |
| 34 | + if (-not $script:win) { throw 'The example window is missing' } |
| 35 | + $script:view = Get-ViewsQuietly | Select-Object -First 1 |
| 36 | + if (-not $script:view) { throw 'The example has no Flutter view to probe' } |
| 37 | +} |
| 38 | +# The system menu's items in their fixed order, whatever the display |
| 39 | +# language: Restore, Move, Size, Minimize, Maximize, Close. |
| 40 | +function Open-SystemMenu([string]$When) { |
| 41 | + Get-State |
| 42 | + $point = ConvertTo-Screen $win (Get-TextCenter $view 'Drag this strip to move the window') |
| 43 | + Invoke-RightClick $app $point |
| 44 | + if (-not (Wait-Menu $app)) { throw "No system menu opened $When" } |
| 45 | + $menu = @(Get-OpenMenus $app)[0] |
| 46 | + Say " menu $When at $($menu.Rect[0]),$($menu.Rect[1]) for a click at $($point[0]),$($point[1]): $(($menu.Items | % { "$($_.Title)=$(if ($_.Enabled) { 'on' } else { 'off' })" }) -join ', ')" |
| 47 | + Check "the system menu opens at the pointer $When" ` |
| 48 | + ([Math]::Abs($menu.Rect[0] - $point[0]) -le 4 -and [Math]::Abs($menu.Rect[1] - $point[1]) -le 4) ` |
| 49 | + "menu $($menu.Rect[0]),$($menu.Rect[1]) vs click $($point[0]),$($point[1])" |
| 50 | + if ($menu.Items.Count -ne 6) { throw "Expected the 6 system menu items, got $($menu.Items.Count)" } |
| 51 | + return $menu |
| 52 | +} |
| 53 | +function Select-SystemMenuItem($Menu, [int]$Index) { |
| 54 | + $pt = Get-RectCenter $Menu.Items[$Index].Rect |
| 55 | + Move-Cursor $pt 400 |
| 56 | + Pause 0.2 |
| 57 | + Assert-Owner $app.Proc.Id $pt[0] $pt[1] |
| 58 | + [WInput]::Click($pt[0], $pt[1]) |
| 59 | + Pause 1.5 |
| 60 | +} |
| 61 | + |
| 62 | +try { |
| 63 | + $deadline = (Get-Date).AddSeconds(40) |
| 64 | + while (@(Get-ViewsQuietly).Count -eq 0 -and (Get-Date) -lt $deadline) { Pause 0.5 } |
| 65 | + Get-State |
| 66 | + Invoke-Activate $app $win |
| 67 | + $width = $win.Right - $win.Left |
| 68 | + |
| 69 | + $menu = Open-SystemMenu 'on a restored window' |
| 70 | + $on = @($menu.Items | % { $_.Enabled }) |
| 71 | + Check 'restored: Restore is off; Move, Size, Minimize, Maximize, Close are on' ` |
| 72 | + (-not $on[0] -and $on[1] -and $on[2] -and $on[3] -and $on[4] -and $on[5]) |
| 73 | + Select-SystemMenuItem $menu 4 |
| 74 | + Get-State |
| 75 | + Check 'choosing Maximize maximizes the window' ([MenuWin]::IsZoomed([IntPtr]$win.Hwnd)) |
| 76 | + |
| 77 | + $menu = Open-SystemMenu 'on a maximized window' |
| 78 | + $on = @($menu.Items | % { $_.Enabled }) |
| 79 | + Check 'maximized: Restore, Minimize, Close are on; Move, Size, Maximize are off' ` |
| 80 | + ($on[0] -and -not $on[1] -and -not $on[2] -and $on[3] -and -not $on[4] -and $on[5]) |
| 81 | + Select-SystemMenuItem $menu 0 |
| 82 | + Get-State |
| 83 | + Check 'choosing Restore restores the window' (-not [MenuWin]::IsZoomed([IntPtr]$win.Hwnd)) |
| 84 | + Check 'at its earlier width' ([Math]::Abs(($win.Right - $win.Left) - $width) -le 2) "$($win.Right - $win.Left) vs $width" |
| 85 | +} catch { |
| 86 | + Check 'the scenario ran to the end' $false "$($_.Exception.Message) at line $($_.InvocationInfo.ScriptLineNumber)" |
| 87 | +} finally { |
| 88 | + Stop-GuiApp $app | Out-Null |
| 89 | +} |
| 90 | +Say "$(if ($script:Failures) { 'FAILED' } else { 'OK' })" |
0 commit comments