ToplevelTests.cs 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690
  1. using System;
  2. using Xunit;
  3. using Xunit.Abstractions;
  4. namespace Terminal.Gui.ViewsTests;
  5. public class ToplevelTests {
  6. readonly ITestOutputHelper _output;
  7. public ToplevelTests (ITestOutputHelper output) => _output = output;
  8. [Fact]
  9. [AutoInitShutdown]
  10. public void Constructor_Default ()
  11. {
  12. var top = new Toplevel ();
  13. Assert.Equal (Colors.TopLevel, top.ColorScheme);
  14. Assert.Equal ("Fill(0)", top.Width.ToString ());
  15. Assert.Equal ("Fill(0)", top.Height.ToString ());
  16. Assert.False (top.Running);
  17. Assert.False (top.Modal);
  18. Assert.Null (top.MenuBar);
  19. Assert.Null (top.StatusBar);
  20. Assert.False (top.IsOverlappedContainer);
  21. Assert.False (top.IsOverlapped);
  22. // Because Toplevel is LayoutStyle.Computed, SetRelativeLayout needs to be called
  23. // to set the Frame.
  24. top.SetRelativeLayout (new Rect (0, 0, Application.Driver.Cols, Application.Driver.Rows));
  25. Assert.Equal (new Rect (0, 0, Application.Driver.Cols, Application.Driver.Rows), top.Frame);
  26. }
  27. [Fact]
  28. [AutoInitShutdown]
  29. public void Create_Toplevel ()
  30. {
  31. var top = new Toplevel ();
  32. Assert.Equal (Colors.TopLevel, top.ColorScheme);
  33. Assert.Equal ("Fill(0)", top.Width.ToString ());
  34. Assert.Equal ("Fill(0)", top.Height.ToString ());
  35. Assert.False (top.Running);
  36. Assert.False (top.Modal);
  37. Assert.Null (top.MenuBar);
  38. Assert.Null (top.StatusBar);
  39. Assert.False (top.IsOverlappedContainer);
  40. Assert.False (top.IsOverlapped);
  41. // Because Toplevel is LayoutStyle.Computed, SetRelativeLayout needs to be called
  42. // to set the Frame.
  43. top.SetRelativeLayout (new Rect (0, 0, Application.Driver.Cols, Application.Driver.Rows));
  44. Assert.Equal (new Rect (0, 0, Application.Driver.Cols, Application.Driver.Rows), top.Frame);
  45. }
  46. #if BROKE_IN_2927
  47. // BUGBUG: The name of this test does not match what it does.
  48. [Fact]
  49. [AutoInitShutdown]
  50. public void Application_Top_GetLocationThatFits_To_Driver_Rows_And_Cols ()
  51. {
  52. var iterations = 0;
  53. Application.Iteration += (s, a) => {
  54. switch (iterations) {
  55. case 0:
  56. Assert.False (Application.Top.AutoSize);
  57. Assert.Equal ("Top1", Application.Top.Text);
  58. Assert.Equal (0, Application.Top.Frame.X);
  59. Assert.Equal (0, Application.Top.Frame.Y);
  60. Assert.Equal (Application.Driver.Cols, Application.Top.Frame.Width);
  61. Assert.Equal (Application.Driver.Rows, Application.Top.Frame.Height);
  62. Application.OnKeyPressed (new (Key.CtrlMask | Key.R));
  63. break;
  64. case 1:
  65. Assert.Equal ("Top2", Application.Top.Text);
  66. Assert.Equal (0, Application.Top.Frame.X);
  67. Assert.Equal (0, Application.Top.Frame.Y);
  68. Assert.Equal (Application.Driver.Cols, Application.Top.Frame.Width);
  69. Assert.Equal (Application.Driver.Rows, Application.Top.Frame.Height);
  70. Application.OnKeyPressed (new (Key.CtrlMask | Key.C));
  71. break;
  72. case 3:
  73. Assert.Equal ("Top1", Application.Top.Text);
  74. Assert.Equal (0, Application.Top.Frame.X);
  75. Assert.Equal (0, Application.Top.Frame.Y);
  76. Assert.Equal (Application.Driver.Cols, Application.Top.Frame.Width);
  77. Assert.Equal (Application.Driver.Rows, Application.Top.Frame.Height);
  78. Application.OnKeyPressed (new (Key.CtrlMask | Key.R));
  79. break;
  80. case 4:
  81. Assert.Equal ("Top2", Application.Top.Text);
  82. Assert.Equal (0, Application.Top.Frame.X);
  83. Assert.Equal (0, Application.Top.Frame.Y);
  84. Assert.Equal (Application.Driver.Cols, Application.Top.Frame.Width);
  85. Assert.Equal (Application.Driver.Rows, Application.Top.Frame.Height);
  86. Application.OnKeyPressed (new (Key.CtrlMask | Key.C));
  87. break;
  88. case 6:
  89. Assert.Equal ("Top1", Application.Top.Text);
  90. Assert.Equal (0, Application.Top.Frame.X);
  91. Assert.Equal (0, Application.Top.Frame.Y);
  92. Assert.Equal (Application.Driver.Cols, Application.Top.Frame.Width);
  93. Assert.Equal (Application.Driver.Rows, Application.Top.Frame.Height);
  94. Application.OnKeyPressed (new (Key.CtrlMask | Key.Q));
  95. break;
  96. }
  97. iterations++;
  98. };
  99. Application.Run (Top1 ());
  100. Toplevel Top1 ()
  101. {
  102. var top = Application.Top;
  103. top.Text = "Top1";
  104. var menu = new MenuBar (new MenuBarItem [] {
  105. new MenuBarItem ("_Options", new MenuItem [] {
  106. new MenuItem ("_Run Top2", "", () => Application.Run (Top2 ()), null, null, Key.CtrlMask | Key.R),
  107. new MenuItem ("_Quit", "", () => Application.RequestStop(), null, null, Key.CtrlMask | Key.Q)
  108. })
  109. });
  110. top.Add (menu);
  111. var statusBar = new StatusBar (new [] {
  112. new StatusItem(Key.CtrlMask | Key.R, "~^R~ Run Top2", () => Application.Run (Top2 ())),
  113. new StatusItem(Application.QuitKey, $"{Application.QuitKey} to Quit", () => Application.RequestStop())
  114. });
  115. top.Add (statusBar);
  116. var t1 = new Toplevel ();
  117. top.Add (t1);
  118. return top;
  119. }
  120. Toplevel Top2 ()
  121. {
  122. var top = new Toplevel (Application.Top.Frame);
  123. top.Text = "Top2";
  124. var win = new Window () { Width = Dim.Fill (), Height = Dim.Fill () };
  125. var menu = new MenuBar (new MenuBarItem [] {
  126. new MenuBarItem ("_Stage", new MenuItem [] {
  127. new MenuItem ("_Close", "", () => Application.RequestStop(), null, null, Key.CtrlMask | Key.C)
  128. })
  129. });
  130. top.Add (menu);
  131. var statusBar = new StatusBar (new [] {
  132. new StatusItem(Key.CtrlMask | Key.C, "~^C~ Close", () => Application.RequestStop()),
  133. });
  134. top.Add (statusBar);
  135. win.Add (new ListView () {
  136. X = 0,
  137. Y = 0,
  138. Width = Dim.Fill (),
  139. Height = Dim.Fill ()
  140. });
  141. top.Add (win);
  142. return top;
  143. }
  144. }
  145. #endif
  146. [Fact]
  147. [AutoInitShutdown]
  148. public void Internal_Tests ()
  149. {
  150. var top = new Toplevel ();
  151. var eventInvoked = "";
  152. top.ChildUnloaded += (s, e) => eventInvoked = "ChildUnloaded";
  153. top.OnChildUnloaded (top);
  154. Assert.Equal ("ChildUnloaded", eventInvoked);
  155. top.ChildLoaded += (s, e) => eventInvoked = "ChildLoaded";
  156. top.OnChildLoaded (top);
  157. Assert.Equal ("ChildLoaded", eventInvoked);
  158. top.Closed += (s, e) => eventInvoked = "Closed";
  159. top.OnClosed (top);
  160. Assert.Equal ("Closed", eventInvoked);
  161. top.Closing += (s, e) => eventInvoked = "Closing";
  162. top.OnClosing (new ToplevelClosingEventArgs (top));
  163. Assert.Equal ("Closing", eventInvoked);
  164. top.AllChildClosed += (s, e) => eventInvoked = "AllChildClosed";
  165. top.OnAllChildClosed ();
  166. Assert.Equal ("AllChildClosed", eventInvoked);
  167. top.ChildClosed += (s, e) => eventInvoked = "ChildClosed";
  168. top.OnChildClosed (top);
  169. Assert.Equal ("ChildClosed", eventInvoked);
  170. top.Deactivate += (s, e) => eventInvoked = "Deactivate";
  171. top.OnDeactivate (top);
  172. Assert.Equal ("Deactivate", eventInvoked);
  173. top.Activate += (s, e) => eventInvoked = "Activate";
  174. top.OnActivate (top);
  175. Assert.Equal ("Activate", eventInvoked);
  176. top.Loaded += (s, e) => eventInvoked = "Loaded";
  177. top.OnLoaded ();
  178. Assert.Equal ("Loaded", eventInvoked);
  179. top.Ready += (s, e) => eventInvoked = "Ready";
  180. top.OnReady ();
  181. Assert.Equal ("Ready", eventInvoked);
  182. top.Unloaded += (s, e) => eventInvoked = "Unloaded";
  183. top.OnUnloaded ();
  184. Assert.Equal ("Unloaded", eventInvoked);
  185. top.AddMenuStatusBar (new MenuBar ());
  186. Assert.NotNull (top.MenuBar);
  187. top.AddMenuStatusBar (new StatusBar ());
  188. Assert.NotNull (top.StatusBar);
  189. top.RemoveMenuStatusBar (top.MenuBar);
  190. Assert.Null (top.MenuBar);
  191. top.RemoveMenuStatusBar (top.StatusBar);
  192. Assert.Null (top.StatusBar);
  193. Application.Begin (top);
  194. Assert.Equal (top, Application.Top);
  195. // Application.Top without menu and status bar.
  196. var supView = top.GetLocationThatFits (top, 2, 2, out var nx, out var ny, out var mb, out var sb);
  197. Assert.Equal (Application.Top, supView);
  198. Assert.Equal (0, nx);
  199. Assert.Equal (0, ny);
  200. Assert.Null (mb);
  201. Assert.Null (sb);
  202. top.AddMenuStatusBar (new MenuBar ());
  203. Assert.NotNull (top.MenuBar);
  204. // Application.Top with a menu and without status bar.
  205. top.GetLocationThatFits (top, 2, 2, out nx, out ny, out mb, out sb);
  206. Assert.Equal (0, nx);
  207. Assert.Equal (1, ny);
  208. Assert.NotNull (mb);
  209. Assert.Null (sb);
  210. top.AddMenuStatusBar (new StatusBar ());
  211. Assert.NotNull (top.StatusBar);
  212. // Application.Top with a menu and status bar.
  213. top.GetLocationThatFits (top, 2, 2, out nx, out ny, out mb, out sb);
  214. Assert.Equal (0, nx);
  215. // The available height is lower than the Application.Top height minus
  216. // the menu bar and status bar, then the top can go beyond the bottom
  217. Assert.Equal (2, ny);
  218. Assert.NotNull (mb);
  219. Assert.NotNull (sb);
  220. top.RemoveMenuStatusBar (top.MenuBar);
  221. Assert.Null (top.MenuBar);
  222. // Application.Top without a menu and with a status bar.
  223. top.GetLocationThatFits (top, 2, 2, out nx, out ny, out mb, out sb);
  224. Assert.Equal (0, nx);
  225. // The available height is lower than the Application.Top height minus
  226. // the status bar, then the top can go beyond the bottom
  227. Assert.Equal (2, ny);
  228. Assert.Null (mb);
  229. Assert.NotNull (sb);
  230. top.RemoveMenuStatusBar (top.StatusBar);
  231. Assert.Null (top.StatusBar);
  232. Assert.Null (top.MenuBar);
  233. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  234. top.Add (win);
  235. top.LayoutSubviews ();
  236. // The SuperView is always the same regardless of the caller.
  237. supView = top.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb);
  238. Assert.Equal (Application.Top, supView);
  239. supView = win.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb);
  240. Assert.Equal (Application.Top, supView);
  241. // Application.Top without menu and status bar.
  242. top.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb);
  243. Assert.Equal (0, nx);
  244. Assert.Equal (0, ny);
  245. Assert.Null (mb);
  246. Assert.Null (sb);
  247. top.AddMenuStatusBar (new MenuBar ());
  248. Assert.NotNull (top.MenuBar);
  249. // Application.Top with a menu and without status bar.
  250. top.GetLocationThatFits (win, 2, 2, out nx, out ny, out mb, out sb);
  251. Assert.Equal (0, nx);
  252. Assert.Equal (1, ny);
  253. Assert.NotNull (mb);
  254. Assert.Null (sb);
  255. top.AddMenuStatusBar (new StatusBar ());
  256. Assert.NotNull (top.StatusBar);
  257. // Application.Top with a menu and status bar.
  258. top.GetLocationThatFits (win, 30, 20, out nx, out ny, out mb, out sb);
  259. Assert.Equal (0, nx);
  260. // The available height is lower than the Application.Top height minus
  261. // the menu bar and status bar, then the top can go beyond the bottom
  262. Assert.Equal (20, ny);
  263. Assert.NotNull (mb);
  264. Assert.NotNull (sb);
  265. top.RemoveMenuStatusBar (top.MenuBar);
  266. top.RemoveMenuStatusBar (top.StatusBar);
  267. Assert.Null (top.StatusBar);
  268. Assert.Null (top.MenuBar);
  269. top.Remove (win);
  270. win = new Window { Width = 60, Height = 15 };
  271. top.Add (win);
  272. // Application.Top without menu and status bar.
  273. top.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb);
  274. Assert.Equal (0, nx);
  275. Assert.Equal (0, ny);
  276. Assert.Null (mb);
  277. Assert.Null (sb);
  278. top.AddMenuStatusBar (new MenuBar ());
  279. Assert.NotNull (top.MenuBar);
  280. // Application.Top with a menu and without status bar.
  281. top.GetLocationThatFits (win, 2, 2, out nx, out ny, out mb, out sb);
  282. Assert.Equal (2, nx);
  283. Assert.Equal (2, ny);
  284. Assert.NotNull (mb);
  285. Assert.Null (sb);
  286. top.AddMenuStatusBar (new StatusBar ());
  287. Assert.NotNull (top.StatusBar);
  288. // Application.Top with a menu and status bar.
  289. top.GetLocationThatFits (win, 30, 20, out nx, out ny, out mb, out sb);
  290. Assert.Equal (20, nx); // 20+60=80
  291. Assert.Equal (9, ny); // 9+15+1(mb)=25
  292. Assert.NotNull (mb);
  293. Assert.NotNull (sb);
  294. top.PositionToplevels ();
  295. Assert.Equal (new Rect (0, 1, 60, 15), win.Frame);
  296. Assert.Null (Toplevel._dragPosition);
  297. win.MouseEvent (new MouseEvent { X = 6, Y = 0, Flags = MouseFlags.Button1Pressed });
  298. Assert.Equal (new Point (6, 0), Toplevel._dragPosition);
  299. win.MouseEvent (new MouseEvent { X = 6, Y = 0, Flags = MouseFlags.Button1Released });
  300. Assert.Null (Toplevel._dragPosition);
  301. win.CanFocus = false;
  302. win.MouseEvent (new MouseEvent { X = 6, Y = 0, Flags = MouseFlags.Button1Pressed });
  303. Assert.Null (Toplevel._dragPosition);
  304. }
  305. [Fact]
  306. [AutoInitShutdown]
  307. public void KeyBindings_Command ()
  308. {
  309. var isRunning = false;
  310. var win1 = new Window { Id = "win1", Width = Dim.Percent (50f), Height = Dim.Fill () };
  311. var lblTf1W1 = new Label ("Enter text in TextField on Win1:") { Id = "lblTf1W1" };
  312. var tf1W1 = new TextField ("Text1 on Win1") { Id = "tf1W1", X = Pos.Right (lblTf1W1) + 1, Width = Dim.Fill () };
  313. var lblTvW1 = new Label ("Enter text in TextView on Win1:") { Id = "lblTvW1", Y = Pos.Bottom (lblTf1W1) + 1 };
  314. var tvW1 = new TextView { Id = "tvW1", X = Pos.Left (tf1W1), Width = Dim.Fill (), Height = 2, Text = "First line Win1\nSecond line Win1" };
  315. var lblTf2W1 = new Label ("Enter text in TextField on Win1:") { Id = "lblTf2W1", Y = Pos.Bottom (lblTvW1) + 1 };
  316. var tf2W1 = new TextField ("Text2 on Win1") { Id = "tf2W1", X = Pos.Left (tf1W1), Width = Dim.Fill () };
  317. win1.Add (lblTf1W1, tf1W1, lblTvW1, tvW1, lblTf2W1, tf2W1);
  318. var win2 = new Window { Id = "win2", X = Pos.Right (win1) + 1, Width = Dim.Percent (50f), Height = Dim.Fill () };
  319. var lblTf1W2 = new Label ("Enter text in TextField on Win2:") { Id = "lblTf1W2" };
  320. var tf1W2 = new TextField ("Text1 on Win2") { Id = "tf1W2", X = Pos.Right (lblTf1W2) + 1, Width = Dim.Fill () };
  321. var lblTvW2 = new Label ("Enter text in TextView on Win2:") { Id = "lblTvW2", Y = Pos.Bottom (lblTf1W2) + 1 };
  322. var tvW2 = new TextView { Id = "tvW2", X = Pos.Left (tf1W2), Width = Dim.Fill (), Height = 2, Text = "First line Win1\nSecond line Win2" };
  323. var lblTf2W2 = new Label ("Enter text in TextField on Win2:") { Id = "lblTf2W2", Y = Pos.Bottom (lblTvW2) + 1 };
  324. var tf2W2 = new TextField ("Text2 on Win2") { Id = "tf2W2", X = Pos.Left (tf1W2), Width = Dim.Fill () };
  325. win2.Add (lblTf1W2, tf1W2, lblTvW2, tvW2, lblTf2W2, tf2W2);
  326. var top = Application.Top;
  327. top.Add (win1, win2);
  328. top.Loaded += (s, e) => isRunning = true;
  329. top.Closing += (s, e) => isRunning = false;
  330. Application.Begin (top);
  331. top.Running = true;
  332. Assert.Equal (new Rect (0, 0, 40, 25), win1.Frame);
  333. Assert.Equal (new Rect (41, 0, 40, 25), win2.Frame);
  334. Assert.Equal (win1, top.Focused);
  335. Assert.Equal (tf1W1, top.MostFocused);
  336. Assert.True (isRunning);
  337. Assert.True (Application.OnKeyDown (Application.QuitKey));
  338. Assert.False (isRunning);
  339. Assert.True (Application.OnKeyDown (new Key (KeyCode.Z | KeyCode.CtrlMask)));
  340. Assert.True (Application.OnKeyDown (new Key (KeyCode.F5))); // refresh
  341. Assert.True (Application.OnKeyDown (new Key (KeyCode.Tab)));
  342. Assert.Equal (win1, top.Focused);
  343. Assert.Equal (tvW1, top.MostFocused);
  344. Assert.True (Application.OnKeyDown (new Key (KeyCode.Tab)));
  345. Assert.Equal ($"\tFirst line Win1{Environment.NewLine}Second line Win1", tvW1.Text);
  346. Assert.True (Application.OnKeyDown (new Key (KeyCode.Tab | KeyCode.ShiftMask)));
  347. Assert.Equal ($"First line Win1{Environment.NewLine}Second line Win1", tvW1.Text);
  348. Assert.True (Application.OnKeyDown (new Key (KeyCode.Tab | KeyCode.CtrlMask)));
  349. Assert.Equal (win1, top.Focused);
  350. Assert.Equal (tf2W1, top.MostFocused);
  351. Assert.True (Application.OnKeyDown (new Key (KeyCode.Tab)));
  352. Assert.Equal (win1, top.Focused);
  353. Assert.Equal (tf1W1, top.MostFocused);
  354. Assert.True (Application.OnKeyDown (new Key (KeyCode.CursorRight)));
  355. Assert.Equal (win1, top.Focused);
  356. Assert.Equal (tf1W1, top.MostFocused);
  357. Assert.True (Application.OnKeyDown (new Key (KeyCode.CursorDown)));
  358. Assert.Equal (win1, top.Focused);
  359. Assert.Equal (tvW1, top.MostFocused);
  360. #if UNIX_KEY_BINDINGS
  361. Assert.True (Application.OnKeyDown (new (Key.I | Key.CtrlMask)));
  362. Assert.Equal (win1, top.Focused);
  363. Assert.Equal (tf2W1, top.MostFocused);
  364. #endif
  365. Assert.True (Application.OnKeyDown (new Key (KeyCode.Tab | KeyCode.ShiftMask)));
  366. Assert.Equal (win1, top.Focused);
  367. Assert.Equal (tvW1, top.MostFocused);
  368. Assert.True (Application.OnKeyDown (new Key (KeyCode.CursorLeft)));
  369. Assert.Equal (win1, top.Focused);
  370. Assert.Equal (tf1W1, top.MostFocused);
  371. Assert.True (Application.OnKeyDown (new Key (KeyCode.CursorUp)));
  372. Assert.Equal (win1, top.Focused);
  373. Assert.Equal (tf2W1, top.MostFocused);
  374. Assert.True (Application.OnKeyDown (new Key (KeyCode.Tab | KeyCode.CtrlMask)));
  375. Assert.Equal (win2, top.Focused);
  376. Assert.Equal (tf1W2, top.MostFocused);
  377. Assert.True (Application.OnKeyDown (new Key (KeyCode.Tab | KeyCode.CtrlMask | KeyCode.ShiftMask)));
  378. Assert.Equal (win1, top.Focused);
  379. Assert.Equal (tf2W1, top.MostFocused);
  380. Assert.True (Application.OnKeyDown (Application.AlternateForwardKey));
  381. Assert.Equal (win2, top.Focused);
  382. Assert.Equal (tf1W2, top.MostFocused);
  383. Assert.True (Application.OnKeyDown (Application.AlternateBackwardKey));
  384. Assert.Equal (win1, top.Focused);
  385. Assert.Equal (tf2W1, top.MostFocused);
  386. Assert.True (Application.OnKeyDown (new Key (KeyCode.CursorUp)));
  387. Assert.Equal (win1, top.Focused);
  388. Assert.Equal (tvW1, top.MostFocused);
  389. #if UNIX_KEY_BINDINGS
  390. Assert.True (Application.OnKeyDown (new (Key.B | Key.CtrlMask)));
  391. #else
  392. Assert.True (Application.OnKeyDown (new Key (KeyCode.CursorLeft)));
  393. #endif
  394. Assert.Equal (win1, top.Focused);
  395. Assert.Equal (tf1W1, top.MostFocused);
  396. Assert.True (Application.OnKeyDown (new Key (KeyCode.CursorDown)));
  397. Assert.Equal (win1, top.Focused);
  398. Assert.Equal (tvW1, top.MostFocused);
  399. Assert.Equal (new Point (0, 0), tvW1.CursorPosition);
  400. Assert.True (Application.OnKeyDown (new Key (KeyCode.End | KeyCode.CtrlMask)));
  401. Assert.Equal (win1, top.Focused);
  402. Assert.Equal (tvW1, top.MostFocused);
  403. Assert.Equal (new Point (16, 1), tvW1.CursorPosition);
  404. #if UNIX_KEY_BINDINGS
  405. Assert.True (Application.OnKeyDown (new (Key.F | Key.CtrlMask)));
  406. #else
  407. Assert.True (Application.OnKeyDown (new Key (KeyCode.CursorRight)));
  408. #endif
  409. Assert.Equal (win1, top.Focused);
  410. Assert.Equal (tf2W1, top.MostFocused);
  411. #if UNIX_KEY_BINDINGS
  412. Assert.True (Application.OnKeyDown (new (Key.L | Key.CtrlMask)));
  413. #else
  414. Assert.True (Application.OnKeyDown (new Key (KeyCode.F5)));
  415. #endif
  416. }
  417. [Fact]
  418. [AutoInitShutdown]
  419. public void KeyBindings_Command_With_OverlappedTop ()
  420. {
  421. var top = Application.Top;
  422. Assert.Null (Application.OverlappedTop);
  423. top.IsOverlappedContainer = true;
  424. Application.Begin (top);
  425. Assert.Equal (Application.Top, Application.OverlappedTop);
  426. var isRunning = true;
  427. var win1 = new Window { Id = "win1", Width = Dim.Percent (50f), Height = Dim.Fill () };
  428. var lblTf1W1 = new Label ("Enter text in TextField on Win1:");
  429. var tf1W1 = new TextField ("Text1 on Win1") { X = Pos.Right (lblTf1W1) + 1, Width = Dim.Fill () };
  430. var lblTvW1 = new Label ("Enter text in TextView on Win1:") { Y = Pos.Bottom (lblTf1W1) + 1 };
  431. var tvW1 = new TextView { X = Pos.Left (tf1W1), Width = Dim.Fill (), Height = 2, Text = "First line Win1\nSecond line Win1" };
  432. var lblTf2W1 = new Label ("Enter text in TextField on Win1:") { Y = Pos.Bottom (lblTvW1) + 1 };
  433. var tf2W1 = new TextField ("Text2 on Win1") { X = Pos.Left (tf1W1), Width = Dim.Fill () };
  434. win1.Add (lblTf1W1, tf1W1, lblTvW1, tvW1, lblTf2W1, tf2W1);
  435. var win2 = new Window { Id = "win2", Width = Dim.Percent (50f), Height = Dim.Fill () };
  436. var lblTf1W2 = new Label ("Enter text in TextField on Win2:");
  437. var tf1W2 = new TextField ("Text1 on Win2") { X = Pos.Right (lblTf1W2) + 1, Width = Dim.Fill () };
  438. var lblTvW2 = new Label ("Enter text in TextView on Win2:") { Y = Pos.Bottom (lblTf1W2) + 1 };
  439. var tvW2 = new TextView { X = Pos.Left (tf1W2), Width = Dim.Fill (), Height = 2, Text = "First line Win1\nSecond line Win2" };
  440. var lblTf2W2 = new Label ("Enter text in TextField on Win2:") { Y = Pos.Bottom (lblTvW2) + 1 };
  441. var tf2W2 = new TextField ("Text2 on Win2") { X = Pos.Left (tf1W2), Width = Dim.Fill () };
  442. win2.Add (lblTf1W2, tf1W2, lblTvW2, tvW2, lblTf2W2, tf2W2);
  443. win1.Closing += (s, e) => isRunning = false;
  444. Assert.Null (top.Focused);
  445. Assert.Equal (top, Application.Current);
  446. Assert.True (top.IsCurrentTop);
  447. Assert.Equal (top, Application.OverlappedTop);
  448. Application.Begin (win1);
  449. Assert.Equal (new Rect (0, 0, 40, 25), win1.Frame);
  450. Assert.NotEqual (top, Application.Current);
  451. Assert.False (top.IsCurrentTop);
  452. Assert.Equal (win1, Application.Current);
  453. Assert.True (win1.IsCurrentTop);
  454. Assert.True (win1.IsOverlapped);
  455. Assert.Null (top.Focused);
  456. Assert.Null (top.MostFocused);
  457. Assert.Equal (tf1W1, win1.MostFocused);
  458. Assert.True (win1.IsOverlapped);
  459. Assert.Single (Application.OverlappedChildren);
  460. Application.Begin (win2);
  461. Assert.Equal (new Rect (0, 0, 40, 25), win2.Frame);
  462. Assert.NotEqual (top, Application.Current);
  463. Assert.False (top.IsCurrentTop);
  464. Assert.Equal (win2, Application.Current);
  465. Assert.True (win2.IsCurrentTop);
  466. Assert.True (win2.IsOverlapped);
  467. Assert.Null (top.Focused);
  468. Assert.Null (top.MostFocused);
  469. Assert.Equal (tf1W2, win2.MostFocused);
  470. Assert.Equal (2, Application.OverlappedChildren.Count);
  471. Application.MoveToOverlappedChild (win1);
  472. Assert.Equal (win1, Application.Current);
  473. Assert.Equal (win1, Application.OverlappedChildren [0]);
  474. win1.Running = true;
  475. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Application.QuitKey));
  476. Assert.False (isRunning);
  477. Assert.False (win1.Running);
  478. Assert.Equal (win1, Application.OverlappedChildren [0]);
  479. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.Z | KeyCode.CtrlMask)));
  480. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.F5))); // refresh
  481. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.Tab)));
  482. Assert.True (win1.IsCurrentTop);
  483. Assert.Equal (tvW1, win1.MostFocused);
  484. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.Tab)));
  485. Assert.Equal ($"\tFirst line Win1{Environment.NewLine}Second line Win1", tvW1.Text);
  486. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.Tab | KeyCode.ShiftMask)));
  487. Assert.Equal ($"First line Win1{Environment.NewLine}Second line Win1", tvW1.Text);
  488. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.Tab | KeyCode.CtrlMask)));
  489. Assert.Equal (win1, Application.OverlappedChildren [0]);
  490. Assert.Equal (tf2W1, win1.MostFocused);
  491. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.Tab)));
  492. Assert.Equal (win1, Application.OverlappedChildren [0]);
  493. Assert.Equal (tf1W1, win1.MostFocused);
  494. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.CursorRight)));
  495. Assert.Equal (win1, Application.OverlappedChildren [0]);
  496. Assert.Equal (tf1W1, win1.MostFocused);
  497. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.CursorDown)));
  498. Assert.Equal (win1, Application.OverlappedChildren [0]);
  499. Assert.Equal (tvW1, win1.MostFocused);
  500. #if UNIX_KEY_BINDINGS
  501. Assert.True (Application.OverlappedChildren [0].ProcessKeyDown (new (Key.I | Key.CtrlMask)));
  502. Assert.Equal (win1, Application.OverlappedChildren [0]);
  503. Assert.Equal (tf2W1, win1.MostFocused);
  504. #endif
  505. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.Tab | KeyCode.ShiftMask)));
  506. Assert.Equal (win1, Application.OverlappedChildren [0]);
  507. Assert.Equal (tvW1, win1.MostFocused);
  508. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.CursorLeft)));
  509. Assert.Equal (win1, Application.OverlappedChildren [0]);
  510. Assert.Equal (tf1W1, win1.MostFocused);
  511. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.CursorUp)));
  512. Assert.Equal (win1, Application.OverlappedChildren [0]);
  513. Assert.Equal (tf2W1, win1.MostFocused);
  514. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.Tab)));
  515. Assert.Equal (win1, Application.OverlappedChildren [0]);
  516. Assert.Equal (tf1W1, win1.MostFocused);
  517. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.Tab | KeyCode.CtrlMask)));
  518. Assert.Equal (win2, Application.OverlappedChildren [0]);
  519. Assert.Equal (tf1W2, win2.MostFocused);
  520. tf2W2.SetFocus ();
  521. Assert.True (tf2W2.HasFocus);
  522. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.Tab | KeyCode.CtrlMask | KeyCode.ShiftMask)));
  523. Assert.Equal (win1, Application.OverlappedChildren [0]);
  524. Assert.Equal (tf1W1, win1.MostFocused);
  525. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Application.AlternateForwardKey));
  526. Assert.Equal (win2, Application.OverlappedChildren [0]);
  527. Assert.Equal (tf2W2, win2.MostFocused);
  528. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Application.AlternateBackwardKey));
  529. Assert.Equal (win1, Application.OverlappedChildren [0]);
  530. Assert.Equal (tf1W1, win1.MostFocused);
  531. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.CursorDown)));
  532. Assert.Equal (win1, Application.OverlappedChildren [0]);
  533. Assert.Equal (tvW1, win1.MostFocused);
  534. #if UNIX_KEY_BINDINGS
  535. Assert.True (Application.OverlappedChildren [0].ProcessKeyDown (new (Key.B | Key.CtrlMask)));
  536. #else
  537. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.CursorLeft)));
  538. #endif
  539. Assert.Equal (win1, Application.OverlappedChildren [0]);
  540. Assert.Equal (tf1W1, win1.MostFocused);
  541. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.CursorDown)));
  542. Assert.Equal (win1, Application.OverlappedChildren [0]);
  543. Assert.Equal (tvW1, win1.MostFocused);
  544. Assert.Equal (new Point (0, 0), tvW1.CursorPosition);
  545. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.End | KeyCode.CtrlMask)));
  546. Assert.Equal (win1, Application.OverlappedChildren [0]);
  547. Assert.Equal (tvW1, win1.MostFocused);
  548. Assert.Equal (new Point (16, 1), tvW1.CursorPosition);
  549. #if UNIX_KEY_BINDINGS
  550. Assert.True (Application.OverlappedChildren [0].ProcessKeyDown (new (Key.F | Key.CtrlMask)));
  551. #else
  552. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (new Key (KeyCode.CursorRight)));
  553. #endif
  554. Assert.Equal (win1, Application.OverlappedChildren [0]);
  555. Assert.Equal (tf2W1, win1.MostFocused);
  556. #if UNIX_KEY_BINDINGS
  557. Assert.True (Application.OverlappedChildren [0].ProcessKeyDown (new (Key.L | Key.CtrlMask)));
  558. #endif
  559. }
  560. [Fact]
  561. public void Added_Event_Should_Not_Be_Used_To_Initialize_Toplevel_Events ()
  562. {
  563. Key alternateForwardKey = default;
  564. Key alternateBackwardKey = default;
  565. Key quitKey = default;
  566. var wasAdded = false;
  567. var view = new View ();
  568. view.Added += View_Added;
  569. void View_Added (object sender, SuperViewChangedEventArgs e)
  570. {
  571. Assert.Throws<NullReferenceException> (() => Application.Top.AlternateForwardKeyChanged += (s, e) => alternateForwardKey = (KeyCode)e.OldKey);
  572. Assert.Throws<NullReferenceException> (() => Application.Top.AlternateBackwardKeyChanged += (s, e) => alternateBackwardKey = (KeyCode)e.OldKey);
  573. Assert.Throws<NullReferenceException> (() => Application.Top.QuitKeyChanged += (s, e) => quitKey = (KeyCode)e.OldKey);
  574. Assert.False (wasAdded);
  575. wasAdded = true;
  576. view.Added -= View_Added;
  577. }
  578. var win = new Window ();
  579. win.Add (view);
  580. Application.Init (new FakeDriver ());
  581. var top = Application.Top;
  582. top.Add (win);
  583. Assert.True (wasAdded);
  584. Application.Shutdown ();
  585. }
  586. [Fact]
  587. [AutoInitShutdown]
  588. public void AlternateForwardKeyChanged_AlternateBackwardKeyChanged_QuitKeyChanged_Events ()
  589. {
  590. Key alternateForwardKey = KeyCode.Null;
  591. Key alternateBackwardKey = KeyCode.Null;
  592. Key quitKey = KeyCode.Null;
  593. var view = new View ();
  594. view.Initialized += View_Initialized;
  595. void View_Initialized (object sender, EventArgs e)
  596. {
  597. Application.Top.AlternateForwardKeyChanged += (s, e) => alternateForwardKey = e.OldKey;
  598. Application.Top.AlternateBackwardKeyChanged += (s, e) => alternateBackwardKey = e.OldKey;
  599. Application.Top.QuitKeyChanged += (s, e) => quitKey = e.OldKey;
  600. }
  601. var win = new Window ();
  602. win.Add (view);
  603. var top = Application.Top;
  604. top.Add (win);
  605. Application.Begin (top);
  606. Assert.Equal (KeyCode.Null, alternateForwardKey);
  607. Assert.Equal (KeyCode.Null, alternateBackwardKey);
  608. Assert.Equal (KeyCode.Null, quitKey);
  609. Assert.Equal (KeyCode.PageDown | KeyCode.CtrlMask, Application.AlternateForwardKey);
  610. Assert.Equal (KeyCode.PageUp | KeyCode.CtrlMask, Application.AlternateBackwardKey);
  611. Assert.Equal (KeyCode.Q | KeyCode.CtrlMask, Application.QuitKey);
  612. Application.AlternateForwardKey = KeyCode.A;
  613. Application.AlternateBackwardKey = KeyCode.B;
  614. Application.QuitKey = KeyCode.C;
  615. Assert.Equal (KeyCode.PageDown | KeyCode.CtrlMask, alternateForwardKey);
  616. Assert.Equal (KeyCode.PageUp | KeyCode.CtrlMask, alternateBackwardKey);
  617. Assert.Equal (KeyCode.Q | KeyCode.CtrlMask, quitKey);
  618. Assert.Equal (KeyCode.A, Application.AlternateForwardKey);
  619. Assert.Equal (KeyCode.B, Application.AlternateBackwardKey);
  620. Assert.Equal (KeyCode.C, Application.QuitKey);
  621. // Replacing the defaults keys to avoid errors on others unit tests that are using it.
  622. Application.AlternateForwardKey = KeyCode.PageDown | KeyCode.CtrlMask;
  623. Application.AlternateBackwardKey = KeyCode.PageUp | KeyCode.CtrlMask;
  624. Application.QuitKey = KeyCode.Q | KeyCode.CtrlMask;
  625. Assert.Equal (KeyCode.PageDown | KeyCode.CtrlMask, Application.AlternateForwardKey);
  626. Assert.Equal (KeyCode.PageUp | KeyCode.CtrlMask, Application.AlternateBackwardKey);
  627. Assert.Equal (KeyCode.Q | KeyCode.CtrlMask, Application.QuitKey);
  628. }
  629. [Fact]
  630. [AutoInitShutdown]
  631. public void Mouse_Drag_On_Top_With_Superview_Null ()
  632. {
  633. var win = new Window ();
  634. var top = Application.Top;
  635. top.Add (win);
  636. var iterations = -1;
  637. Window testWindow;
  638. Application.Iteration += (s, a) => {
  639. iterations++;
  640. if (iterations == 0) {
  641. ((FakeDriver)Application.Driver).SetBufferSize (15, 7);
  642. // Don't use MessageBox here; it's too complicated for this unit test; just use Window
  643. testWindow = new Window {
  644. Text = "Hello",
  645. X = 2,
  646. Y = 2,
  647. Width = 10,
  648. Height = 3
  649. };
  650. Application.Run (testWindow);
  651. } else if (iterations == 1) {
  652. TestHelpers.AssertDriverContentsWithFrameAre (@"
  653. ┌─────────────┐
  654. │ │
  655. │ ┌────────┐ │
  656. │ │Hello │ │
  657. │ └────────┘ │
  658. │ │
  659. └─────────────┘
  660. ", _output);
  661. } else if (iterations == 2) {
  662. Assert.Null (Application.MouseGrabView);
  663. // Grab the mouse
  664. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  665. X = 3,
  666. Y = 2,
  667. Flags = MouseFlags.Button1Pressed
  668. }));
  669. Assert.Equal (Application.Current, Application.MouseGrabView);
  670. Assert.Equal (new Rect (2, 2, 10, 3), Application.MouseGrabView.Frame);
  671. } else if (iterations == 3) {
  672. Assert.Equal (Application.Current, Application.MouseGrabView);
  673. // Drag to left
  674. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  675. X = 2,
  676. Y = 2,
  677. Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  678. }));
  679. Application.Refresh ();
  680. Assert.Equal (Application.Current, Application.MouseGrabView);
  681. Assert.Equal (new Rect (1, 2, 10, 3), Application.MouseGrabView.Frame);
  682. } else if (iterations == 4) {
  683. Assert.Equal (Application.Current, Application.MouseGrabView);
  684. TestHelpers.AssertDriverContentsWithFrameAre (@"
  685. ┌─────────────┐
  686. │ │
  687. │┌────────┐ │
  688. ││Hello │ │
  689. │└────────┘ │
  690. │ │
  691. └─────────────┘", _output);
  692. Assert.Equal (Application.Current, Application.MouseGrabView);
  693. } else if (iterations == 5) {
  694. Assert.Equal (Application.Current, Application.MouseGrabView);
  695. // Drag up
  696. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  697. X = 2,
  698. Y = 1,
  699. Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  700. }));
  701. Application.Refresh ();
  702. Assert.Equal (Application.Current, Application.MouseGrabView);
  703. Assert.Equal (new Rect (1, 1, 10, 3), Application.MouseGrabView.Frame);
  704. } else if (iterations == 6) {
  705. Assert.Equal (Application.Current, Application.MouseGrabView);
  706. TestHelpers.AssertDriverContentsWithFrameAre (@"
  707. ┌─────────────┐
  708. │┌────────┐ │
  709. ││Hello │ │
  710. │└────────┘ │
  711. │ │
  712. │ │
  713. └─────────────┘", _output);
  714. Assert.Equal (Application.Current, Application.MouseGrabView);
  715. Assert.Equal (new Rect (1, 1, 10, 3), Application.MouseGrabView.Frame);
  716. } else if (iterations == 7) {
  717. Assert.Equal (Application.Current, Application.MouseGrabView);
  718. // Ungrab the mouse
  719. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  720. X = 2,
  721. Y = 1,
  722. Flags = MouseFlags.Button1Released
  723. }));
  724. Application.Refresh ();
  725. Assert.Null (Application.MouseGrabView);
  726. } else if (iterations == 8) {
  727. Application.RequestStop ();
  728. } else if (iterations == 9) {
  729. Application.RequestStop ();
  730. }
  731. };
  732. Application.Run ();
  733. }
  734. [Fact]
  735. [AutoInitShutdown]
  736. public void Mouse_Drag_On_Top_With_Superview_Not_Null ()
  737. {
  738. var win = new Window {
  739. X = 3,
  740. Y = 2,
  741. Width = 10,
  742. Height = 5
  743. };
  744. var top = Application.Top;
  745. top.Add (win);
  746. var iterations = -1;
  747. var movex = 0;
  748. var movey = 0;
  749. var location = new Rect (win.Frame.X, win.Frame.Y, 7, 3);
  750. Application.Iteration += (s, a) => {
  751. iterations++;
  752. if (iterations == 0) {
  753. ((FakeDriver)Application.Driver).SetBufferSize (30, 10);
  754. } else if (iterations == 1) {
  755. location = win.Frame;
  756. Assert.Null (Application.MouseGrabView);
  757. // Grab the mouse
  758. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  759. X = win.Frame.X,
  760. Y = win.Frame.Y,
  761. Flags = MouseFlags.Button1Pressed
  762. }));
  763. Assert.Equal (win, Application.MouseGrabView);
  764. Assert.Equal (location, Application.MouseGrabView.Frame);
  765. } else if (iterations == 2) {
  766. Assert.Equal (win, Application.MouseGrabView);
  767. // Drag to left
  768. movex = 1;
  769. movey = 0;
  770. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  771. X = win.Frame.X + movex,
  772. Y = win.Frame.Y + movey,
  773. Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  774. }));
  775. Assert.Equal (win, Application.MouseGrabView);
  776. } else if (iterations == 3) {
  777. // we should have moved +1, +0
  778. Assert.Equal (win, Application.MouseGrabView);
  779. Assert.Equal (win, Application.MouseGrabView);
  780. location.Offset (movex, movey);
  781. Assert.Equal (location, Application.MouseGrabView.Frame);
  782. } else if (iterations == 4) {
  783. Assert.Equal (win, Application.MouseGrabView);
  784. // Drag up
  785. movex = 0;
  786. movey = -1;
  787. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  788. X = win.Frame.X + movex,
  789. Y = win.Frame.Y + movey,
  790. Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  791. }));
  792. Assert.Equal (win, Application.MouseGrabView);
  793. } else if (iterations == 5) {
  794. // we should have moved +0, -1
  795. Assert.Equal (win, Application.MouseGrabView);
  796. location.Offset (movex, movey);
  797. Assert.Equal (location, Application.MouseGrabView.Frame);
  798. } else if (iterations == 6) {
  799. Assert.Equal (win, Application.MouseGrabView);
  800. // Ungrab the mouse
  801. movex = 0;
  802. movey = 0;
  803. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  804. X = win.Frame.X + movex,
  805. Y = win.Frame.Y + movey,
  806. Flags = MouseFlags.Button1Released
  807. }));
  808. Assert.Null (Application.MouseGrabView);
  809. } else if (iterations == 7) {
  810. Application.RequestStop ();
  811. }
  812. };
  813. Application.Run ();
  814. }
  815. [Fact]
  816. [AutoInitShutdown]
  817. public void GetLocationThatFits_With_Border_Null_Not_Throws ()
  818. {
  819. var top = new Toplevel ();
  820. Application.Begin (top);
  821. var exception = Record.Exception (() => ((FakeDriver)Application.Driver).SetBufferSize (0, 10));
  822. Assert.Null (exception);
  823. exception = Record.Exception (() => ((FakeDriver)Application.Driver).SetBufferSize (10, 0));
  824. Assert.Null (exception);
  825. }
  826. [Fact]
  827. [AutoInitShutdown]
  828. public void OnEnter_OnLeave_Triggered_On_Application_Begin_End ()
  829. {
  830. var isEnter = false;
  831. var isLeave = false;
  832. var v = new View ();
  833. v.Enter += (s, _) => isEnter = true;
  834. v.Leave += (s, _) => isLeave = true;
  835. var top = Application.Top;
  836. top.Add (v);
  837. Assert.False (v.CanFocus);
  838. var exception = Record.Exception (() => top.OnEnter (top));
  839. Assert.Null (exception);
  840. exception = Record.Exception (() => top.OnLeave (top));
  841. Assert.Null (exception);
  842. v.CanFocus = true;
  843. Application.Begin (top);
  844. Assert.True (isEnter);
  845. Assert.False (isLeave);
  846. isEnter = false;
  847. var d = new Dialog ();
  848. var rs = Application.Begin (d);
  849. Assert.False (isEnter);
  850. Assert.True (isLeave);
  851. isLeave = false;
  852. Application.End (rs);
  853. Assert.True (isEnter);
  854. Assert.False (isLeave); // Leave event cannot be trigger because it v.Enter was performed and v is focused
  855. Assert.True (v.HasFocus);
  856. }
  857. [Fact]
  858. [AutoInitShutdown]
  859. public void OnEnter_OnLeave_Triggered_On_Application_Begin_End_With_More_Toplevels ()
  860. {
  861. var iterations = 0;
  862. var steps = new int [5];
  863. var isEnterTop = false;
  864. var isLeaveTop = false;
  865. var vt = new View ();
  866. var top = Application.Top;
  867. var diag = new Dialog ();
  868. vt.Enter += (s, e) => {
  869. iterations++;
  870. isEnterTop = true;
  871. if (iterations == 1) {
  872. steps [0] = iterations;
  873. Assert.Null (e.View);
  874. } else {
  875. steps [4] = iterations;
  876. Assert.Equal (diag, e.View);
  877. }
  878. };
  879. vt.Leave += (s, e) => {
  880. iterations++;
  881. steps [1] = iterations;
  882. isLeaveTop = true;
  883. Assert.Equal (diag, e.View);
  884. };
  885. top.Add (vt);
  886. Assert.False (vt.CanFocus);
  887. var exception = Record.Exception (() => top.OnEnter (top));
  888. Assert.Null (exception);
  889. exception = Record.Exception (() => top.OnLeave (top));
  890. Assert.Null (exception);
  891. vt.CanFocus = true;
  892. Application.Begin (top);
  893. Assert.True (isEnterTop);
  894. Assert.False (isLeaveTop);
  895. isEnterTop = false;
  896. var isEnterDiag = false;
  897. var isLeaveDiag = false;
  898. var vd = new View ();
  899. vd.Enter += (s, e) => {
  900. iterations++;
  901. steps [2] = iterations;
  902. isEnterDiag = true;
  903. Assert.Null (e.View);
  904. };
  905. vd.Leave += (s, e) => {
  906. iterations++;
  907. steps [3] = iterations;
  908. isLeaveDiag = true;
  909. Assert.Equal (top, e.View);
  910. };
  911. diag.Add (vd);
  912. Assert.False (vd.CanFocus);
  913. exception = Record.Exception (() => diag.OnEnter (diag));
  914. Assert.Null (exception);
  915. exception = Record.Exception (() => diag.OnLeave (diag));
  916. Assert.Null (exception);
  917. vd.CanFocus = true;
  918. var rs = Application.Begin (diag);
  919. Assert.True (isEnterDiag);
  920. Assert.False (isLeaveDiag);
  921. Assert.False (isEnterTop);
  922. Assert.True (isLeaveTop);
  923. isEnterDiag = false;
  924. isLeaveTop = false;
  925. Application.End (rs);
  926. Assert.False (isEnterDiag);
  927. Assert.True (isLeaveDiag);
  928. Assert.True (isEnterTop);
  929. Assert.False (isLeaveTop); // Leave event cannot be trigger because it v.Enter was performed and v is focused
  930. Assert.True (vt.HasFocus);
  931. Assert.Equal (1, steps [0]);
  932. Assert.Equal (2, steps [1]);
  933. Assert.Equal (3, steps [2]);
  934. Assert.Equal (4, steps [3]);
  935. Assert.Equal (5, steps [^1]);
  936. }
  937. [Fact]
  938. [AutoInitShutdown]
  939. public void PositionCursor_SetCursorVisibility_To_Invisible_If_Focused_Is_Null ()
  940. {
  941. var tf = new TextField ("test") { Width = 5 };
  942. var view = new View { Width = 10, Height = 10 };
  943. view.Add (tf);
  944. Application.Top.Add (view);
  945. Application.Begin (Application.Top);
  946. Assert.True (tf.HasFocus);
  947. Application.Driver.GetCursorVisibility (out var cursor);
  948. Assert.Equal (CursorVisibility.Default, cursor);
  949. view.Enabled = false;
  950. Assert.False (tf.HasFocus);
  951. Application.Refresh ();
  952. Application.Driver.GetCursorVisibility (out cursor);
  953. Assert.Equal (CursorVisibility.Invisible, cursor);
  954. }
  955. [Fact]
  956. [AutoInitShutdown]
  957. public void IsLoaded_Application_Begin ()
  958. {
  959. var top = Application.Top;
  960. Assert.False (top.IsLoaded);
  961. Application.Begin (top);
  962. Assert.True (top.IsLoaded);
  963. }
  964. [Fact]
  965. [AutoInitShutdown]
  966. public void IsLoaded_With_Sub_Toplevel_Application_Begin_NeedDisplay ()
  967. {
  968. var top = Application.Top;
  969. var subTop = new Toplevel ();
  970. var view = new View (new Rect (0, 0, 20, 10));
  971. subTop.Add (view);
  972. top.Add (subTop);
  973. Assert.False (top.IsLoaded);
  974. Assert.False (subTop.IsLoaded);
  975. Assert.Equal (new Rect (0, 0, 20, 10), view.Frame);
  976. view.LayoutStarted += view_LayoutStarted;
  977. void view_LayoutStarted (object sender, LayoutEventArgs e)
  978. {
  979. Assert.Equal (new Rect (0, 0, 20, 10), view._needsDisplayRect);
  980. view.LayoutStarted -= view_LayoutStarted;
  981. }
  982. Application.Begin (top);
  983. Assert.True (top.IsLoaded);
  984. Assert.True (subTop.IsLoaded);
  985. Assert.Equal (new Rect (0, 0, 20, 10), view.Frame);
  986. view.Frame = new Rect (1, 3, 10, 5);
  987. Assert.Equal (new Rect (1, 3, 10, 5), view.Frame);
  988. Assert.Equal (new Rect (0, 0, 10, 5), view._needsDisplayRect);
  989. view.OnDrawContent (view.Bounds);
  990. view.Frame = new Rect (1, 3, 10, 5);
  991. Assert.Equal (new Rect (1, 3, 10, 5), view.Frame);
  992. Assert.Equal (new Rect (0, 0, 10, 5), view._needsDisplayRect);
  993. }
  994. // BUGBUG: Broke this test with #2483 - @bdisp I need your help figuring out why
  995. [Fact]
  996. [AutoInitShutdown]
  997. public void Toplevel_Inside_ScrollView_MouseGrabView ()
  998. {
  999. var scrollView = new ScrollView {
  1000. X = 3,
  1001. Y = 3,
  1002. Width = 40,
  1003. Height = 16,
  1004. ContentSize = new Size (200, 100)
  1005. };
  1006. var win = new Window { X = 3, Y = 3, Width = Dim.Fill (3), Height = Dim.Fill (3) };
  1007. scrollView.Add (win);
  1008. var top = Application.Top;
  1009. top.Add (scrollView);
  1010. Application.Begin (top);
  1011. Assert.Equal (new Rect (0, 0, 80, 25), top.Frame);
  1012. Assert.Equal (new Rect (3, 3, 40, 16), scrollView.Frame);
  1013. Assert.Equal (new Rect (0, 0, 200, 100), scrollView.Subviews [0].Frame);
  1014. Assert.Equal (new Rect (3, 3, 194, 94), win.Frame);
  1015. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1016. ┌───────────────────────────────────┴
  1017. │ ░
  1018. │ ░
  1019. │ ░
  1020. │ ░
  1021. │ ░
  1022. │ ░
  1023. │ ░
  1024. │ ░
  1025. │ ░
  1026. │ ░
  1027. │ ▼
  1028. ◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ", _output);
  1029. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  1030. X = 6,
  1031. Y = 6,
  1032. Flags = MouseFlags.Button1Pressed
  1033. }));
  1034. Assert.Equal (win, Application.MouseGrabView);
  1035. Assert.Equal (new Rect (3, 3, 194, 94), win.Frame);
  1036. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  1037. X = 9,
  1038. Y = 9,
  1039. Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  1040. }));
  1041. Assert.Equal (win, Application.MouseGrabView);
  1042. top.SetNeedsLayout ();
  1043. top.LayoutSubviews ();
  1044. Assert.Equal (new Rect (6, 6, 191, 91), win.Frame);
  1045. Application.Refresh ();
  1046. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1047. ┌────────────────────────────────░
  1048. │ ░
  1049. │ ░
  1050. │ ░
  1051. │ ░
  1052. │ ░
  1053. │ ░
  1054. │ ░
  1055. │ ▼
  1056. ◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ", _output);
  1057. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  1058. X = 5,
  1059. Y = 5,
  1060. Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  1061. }));
  1062. Assert.Equal (win, Application.MouseGrabView);
  1063. top.SetNeedsLayout ();
  1064. top.LayoutSubviews ();
  1065. Assert.Equal (new Rect (2, 2, 195, 95), win.Frame);
  1066. Application.Refresh ();
  1067. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1068. ┌────────────────────────────────────│
  1069. │ ┴
  1070. │ ░
  1071. │ ░
  1072. │ ░
  1073. │ ░
  1074. │ ░
  1075. │ ░
  1076. │ ░
  1077. │ ░
  1078. │ ░
  1079. │ ░
  1080. │ ▼
  1081. ◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ", _output);
  1082. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  1083. X = 5,
  1084. Y = 5,
  1085. Flags = MouseFlags.Button1Released
  1086. }));
  1087. Assert.Null (Application.MouseGrabView);
  1088. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  1089. X = 4,
  1090. Y = 4,
  1091. Flags = MouseFlags.ReportMousePosition
  1092. }));
  1093. Assert.Equal (scrollView, Application.MouseGrabView);
  1094. }
  1095. [Fact]
  1096. [AutoInitShutdown]
  1097. public void Window_Bounds_Bigger_Than_Driver_Cols_And_Rows_Allow_Drag_Beyond_Left_Right_And_Bottom ()
  1098. {
  1099. var top = Application.Top;
  1100. var window = new Window { Width = 20, Height = 3 };
  1101. Application.Begin (top);
  1102. ((FakeDriver)Application.Driver).SetBufferSize (40, 10);
  1103. Application.Begin (window);
  1104. Application.Refresh ();
  1105. Assert.Equal (new Rect (0, 0, 40, 10), top.Frame);
  1106. Assert.Equal (new Rect (0, 0, 20, 3), window.Frame);
  1107. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1108. ┌──────────────────┐
  1109. │ │
  1110. └──────────────────┘
  1111. ", _output);
  1112. Assert.Null (Application.MouseGrabView);
  1113. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  1114. X = 0,
  1115. Y = 0,
  1116. Flags = MouseFlags.Button1Pressed
  1117. }));
  1118. Assert.Equal (window, Application.MouseGrabView);
  1119. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  1120. X = -11,
  1121. Y = -4,
  1122. Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  1123. }));
  1124. Application.Refresh ();
  1125. Assert.Equal (new Rect (0, 0, 40, 10), top.Frame);
  1126. Assert.Equal (new Rect (0, 0, 20, 3), window.Frame);
  1127. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1128. ┌──────────────────┐
  1129. │ │
  1130. └──────────────────┘
  1131. ", _output);
  1132. // Changes Top size to same size as Dialog more menu and scroll bar
  1133. ((FakeDriver)Application.Driver).SetBufferSize (20, 3);
  1134. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  1135. X = -1,
  1136. Y = -1,
  1137. Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  1138. }));
  1139. Application.Refresh ();
  1140. Assert.Equal (new Rect (0, 0, 20, 3), top.Frame);
  1141. Assert.Equal (new Rect (0, 0, 20, 3), window.Frame);
  1142. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1143. ┌──────────────────┐
  1144. │ │
  1145. └──────────────────┘
  1146. ", _output);
  1147. // Changes Top size smaller than Dialog size
  1148. ((FakeDriver)Application.Driver).SetBufferSize (19, 2);
  1149. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  1150. X = -1,
  1151. Y = -1,
  1152. Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  1153. }));
  1154. Application.Refresh ();
  1155. Assert.Equal (new Rect (0, 0, 19, 2), top.Frame);
  1156. Assert.Equal (new Rect (-1, 0, 20, 3), window.Frame);
  1157. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1158. ──────────────────┐
  1159. ", _output);
  1160. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  1161. X = 18,
  1162. Y = 1,
  1163. Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  1164. }));
  1165. Application.Refresh ();
  1166. Assert.Equal (new Rect (0, 0, 19, 2), top.Frame);
  1167. Assert.Equal (new Rect (18, 1, 20, 3), window.Frame);
  1168. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1169. ┌", _output);
  1170. // On a real app we can't go beyond the SuperView bounds
  1171. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  1172. X = 19,
  1173. Y = 2,
  1174. Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  1175. }));
  1176. Application.Refresh ();
  1177. Assert.Equal (new Rect (0, 0, 19, 2), top.Frame);
  1178. Assert.Equal (new Rect (19, 2, 20, 3), window.Frame);
  1179. TestHelpers.AssertDriverContentsWithFrameAre (@"", _output);
  1180. }
  1181. [Fact]
  1182. [AutoInitShutdown]
  1183. public void Modal_As_Top_Will_Drag_Cleanly ()
  1184. {
  1185. // Don't use Dialog as a Top, use a Window instead - dialog has complex layout behavior that is not needed here.
  1186. var window = new Window { Width = 10, Height = 3 };
  1187. window.Add (new Label (
  1188. "Test") {
  1189. X = Pos.Center (),
  1190. Y = Pos.Center (),
  1191. Width = Dim.Fill (),
  1192. Height = Dim.Fill (),
  1193. TextAlignment = TextAlignment.Centered,
  1194. VerticalTextAlignment = VerticalTextAlignment.Middle,
  1195. AutoSize = false
  1196. });
  1197. var rs = Application.Begin (window);
  1198. Assert.Null (Application.MouseGrabView);
  1199. Assert.Equal (new Rect (0, 0, 10, 3), window.Frame);
  1200. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1201. ┌────────┐
  1202. │ Test │
  1203. └────────┘", _output);
  1204. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  1205. X = 0,
  1206. Y = 0,
  1207. Flags = MouseFlags.Button1Pressed
  1208. }));
  1209. var firstIteration = false;
  1210. Application.RunIteration (ref rs, ref firstIteration);
  1211. Assert.Equal (window, Application.MouseGrabView);
  1212. Assert.Equal (new Rect (0, 0, 10, 3), window.Frame);
  1213. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1214. ┌────────┐
  1215. │ Test │
  1216. └────────┘", _output);
  1217. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  1218. X = 1,
  1219. Y = 1,
  1220. Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  1221. }));
  1222. firstIteration = false;
  1223. Application.RunIteration (ref rs, ref firstIteration);
  1224. Assert.Equal (window, Application.MouseGrabView);
  1225. Assert.Equal (new Rect (1, 1, 10, 3), window.Frame);
  1226. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1227. ┌────────┐
  1228. │ Test │
  1229. └────────┘", _output);
  1230. Application.End (rs);
  1231. }
  1232. [Fact]
  1233. [AutoInitShutdown]
  1234. public void Begin_With_Window_Sets_Size_Correctly ()
  1235. {
  1236. var top = Application.Top;
  1237. Application.Begin (top);
  1238. ((FakeDriver)Application.Driver).SetBufferSize (20, 20);
  1239. var testWindow = new Window { X = 2, Y = 1, Width = 15, Height = 10 };
  1240. Assert.Equal (new Rect (2, 1, 15, 10), testWindow.Frame);
  1241. var rs = Application.Begin (testWindow);
  1242. Assert.Equal (new Rect (2, 1, 15, 10), testWindow.Frame);
  1243. }
  1244. // Don't use Dialog as a Top, use a Window instead - dialog has complex layout behavior that is not needed here.
  1245. [Fact]
  1246. [AutoInitShutdown]
  1247. public void Draw_A_Top_Subview_On_A_Window ()
  1248. {
  1249. var top = Application.Top;
  1250. var win = new Window ();
  1251. top.Add (win);
  1252. Application.Begin (top);
  1253. ((FakeDriver)Application.Driver).SetBufferSize (20, 20);
  1254. Assert.Equal (new Rect (0, 0, 20, 20), win.Frame);
  1255. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1256. ┌──────────────────┐
  1257. │ │
  1258. │ │
  1259. │ │
  1260. │ │
  1261. │ │
  1262. │ │
  1263. │ │
  1264. │ │
  1265. │ │
  1266. │ │
  1267. │ │
  1268. │ │
  1269. │ │
  1270. │ │
  1271. │ │
  1272. │ │
  1273. │ │
  1274. │ │
  1275. └──────────────────┘", _output);
  1276. var btnPopup = new Button ("Popup");
  1277. var testWindow = new Window { X = 2, Y = 1, Width = 15, Height = 10 };
  1278. testWindow.Add (btnPopup);
  1279. btnPopup.Clicked += (s, e) => {
  1280. var viewToScreen = btnPopup.BoundsToScreen (top.Frame);
  1281. var viewAddedToTop = new View {
  1282. Text = "viewAddedToTop",
  1283. X = 1,
  1284. Y = viewToScreen.Y + 1,
  1285. Width = 18,
  1286. Height = 16,
  1287. BorderStyle = LineStyle.Single
  1288. };
  1289. Assert.Equal (testWindow, Application.Current);
  1290. Application.Current.DrawContentComplete += testWindow_DrawContentComplete;
  1291. top.Add (viewAddedToTop);
  1292. void testWindow_DrawContentComplete (object sender, DrawEventArgs e)
  1293. {
  1294. Assert.Equal (new Rect (1, 3, 18, 16), viewAddedToTop.Frame);
  1295. var savedClip = Application.Driver.Clip;
  1296. Application.Driver.Clip = top.Frame;
  1297. viewAddedToTop.Draw ();
  1298. top.Move (2, 15);
  1299. View.Driver.AddStr ("One");
  1300. top.Move (2, 16);
  1301. View.Driver.AddStr ("Two");
  1302. top.Move (2, 17);
  1303. View.Driver.AddStr ("Three");
  1304. Application.Driver.Clip = savedClip;
  1305. Application.Current.DrawContentComplete -= testWindow_DrawContentComplete;
  1306. }
  1307. };
  1308. var rs = Application.Begin (testWindow);
  1309. Assert.Equal (new Rect (2, 1, 15, 10), testWindow.Frame);
  1310. TestHelpers.AssertDriverContentsWithFrameAre (@$"
  1311. ┌──────────────────┐
  1312. │ ┌─────────────┐ │
  1313. │ │{CM.Glyphs.LeftBracket} Popup {CM.Glyphs.RightBracket} │ │
  1314. │ │ │ │
  1315. │ │ │ │
  1316. │ │ │ │
  1317. │ │ │ │
  1318. │ │ │ │
  1319. │ │ │ │
  1320. │ │ │ │
  1321. │ └─────────────┘ │
  1322. │ │
  1323. │ │
  1324. │ │
  1325. │ │
  1326. │ │
  1327. │ │
  1328. │ │
  1329. │ │
  1330. └──────────────────┘", _output);
  1331. Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent {
  1332. X = 5,
  1333. Y = 2,
  1334. Flags = MouseFlags.Button1Clicked
  1335. }));
  1336. Application.Top.Draw ();
  1337. var firstIteration = false;
  1338. Application.RunIteration (ref rs, ref firstIteration);
  1339. TestHelpers.AssertDriverContentsWithFrameAre (@$"
  1340. ┌──────────────────┐
  1341. │ ┌─────────────┐ │
  1342. │ │{CM.Glyphs.LeftBracket} Popup {CM.Glyphs.RightBracket} │ │
  1343. │┌────────────────┐│
  1344. ││viewAddedToTop ││
  1345. ││ ││
  1346. ││ ││
  1347. ││ ││
  1348. ││ ││
  1349. ││ ││
  1350. ││ ││
  1351. ││ ││
  1352. ││ ││
  1353. ││ ││
  1354. ││ ││
  1355. ││One ││
  1356. ││Two ││
  1357. ││Three ││
  1358. │└────────────────┘│
  1359. └──────────────────┘", _output);
  1360. Application.End (rs);
  1361. }
  1362. [Fact]
  1363. [AutoInitShutdown]
  1364. public void Activating_MenuBar_By_Alt_Key_Does_Not_Throw ()
  1365. {
  1366. var menu = new MenuBar (new MenuBarItem [] {
  1367. new ("Child", new MenuItem [] {
  1368. new ("_Create Child", "", null)
  1369. })
  1370. });
  1371. var topChild = new Toplevel ();
  1372. topChild.Add (menu);
  1373. Application.Top.Add (topChild);
  1374. Application.Begin (Application.Top);
  1375. var exception = Record.Exception (() => topChild.NewKeyDownEvent (new Key (KeyCode.AltMask)));
  1376. Assert.Null (exception);
  1377. }
  1378. [Fact]
  1379. [TestRespondersDisposed]
  1380. public void Multi_Thread_Toplevels ()
  1381. {
  1382. Application.Init (new FakeDriver ());
  1383. var t = Application.Top;
  1384. var w = new Window ();
  1385. t.Add (w);
  1386. int count = 0, count1 = 0, count2 = 0;
  1387. bool log = false, log1 = false, log2 = false;
  1388. var fromTopStillKnowFirstIsRunning = false;
  1389. var fromTopStillKnowSecondIsRunning = false;
  1390. var fromFirstStillKnowSecondIsRunning = false;
  1391. Application.AddTimeout (TimeSpan.FromMilliseconds (100), () => {
  1392. count++;
  1393. if (count1 == 5) {
  1394. log1 = true;
  1395. }
  1396. if (count1 == 14 && count2 == 10 && count == 15) {
  1397. // count2 is already stopped
  1398. fromTopStillKnowFirstIsRunning = true;
  1399. }
  1400. if (count1 == 7 && count2 == 7 && count == 8) {
  1401. fromTopStillKnowSecondIsRunning = true;
  1402. }
  1403. if (count == 30) {
  1404. Assert.Equal (30, count);
  1405. Assert.Equal (20, count1);
  1406. Assert.Equal (10, count2);
  1407. Assert.True (log);
  1408. Assert.True (log1);
  1409. Assert.True (log2);
  1410. Assert.True (fromTopStillKnowFirstIsRunning);
  1411. Assert.True (fromTopStillKnowSecondIsRunning);
  1412. Assert.True (fromFirstStillKnowSecondIsRunning);
  1413. Application.RequestStop ();
  1414. return false;
  1415. }
  1416. return true;
  1417. });
  1418. t.Ready += FirstWindow;
  1419. void FirstWindow (object sender, EventArgs args)
  1420. {
  1421. var firstWindow = new Window ();
  1422. firstWindow.Ready += SecondWindow;
  1423. Application.AddTimeout (TimeSpan.FromMilliseconds (100), () => {
  1424. count1++;
  1425. if (count2 == 5) {
  1426. log2 = true;
  1427. }
  1428. if (count2 == 4 && count1 == 5 && count == 5) {
  1429. fromFirstStillKnowSecondIsRunning = true;
  1430. }
  1431. if (count1 == 20) {
  1432. Assert.Equal (20, count1);
  1433. Application.RequestStop ();
  1434. return false;
  1435. }
  1436. return true;
  1437. });
  1438. Application.Run (firstWindow);
  1439. }
  1440. void SecondWindow (object sender, EventArgs args)
  1441. {
  1442. var testWindow = new Window ();
  1443. Application.AddTimeout (TimeSpan.FromMilliseconds (100), () => {
  1444. count2++;
  1445. if (count < 30) {
  1446. log = true;
  1447. }
  1448. if (count2 == 10) {
  1449. Assert.Equal (10, count2);
  1450. Application.RequestStop ();
  1451. return false;
  1452. }
  1453. return true;
  1454. });
  1455. Application.Run (testWindow);
  1456. }
  1457. Application.Run ();
  1458. Application.Shutdown ();
  1459. }
  1460. }