Browse Source

Expand and clarify popover XML documentation

Significantly improve and expand XML documentation for IPopover, PopoverBaseImpl, and PopoverMenu. Add detailed remarks on popover lifecycle, registration requirements, focus, input, and mouse handling. Provide usage examples, parameter and exception documentation, and clarify method/property summaries. Warn about the need to register popovers before showing. No functional code changes except for minor summary tweaks for clarity.
Tig 1 day ago
parent
commit
4dc193b6a3

+ 2 - 0
Examples/UICatalog/Scenarios/Menus.cs

@@ -347,6 +347,8 @@ public class Menus : Scenario
             };
 
             ContextMenu.EnableForDesign (ref host);
+            Application.Popover.Register (ContextMenu);
+
             ContextMenu.Visible = false;
 
             // Demo of PopoverMenu as a context menu

+ 38 - 28
Terminal.Gui/App/IPopover.cs

@@ -8,54 +8,64 @@ namespace Terminal.Gui.App;
 ///     <para>
 ///         A popover is a transient UI element that appears above other content to display contextual information or UI,
 ///         such as menus, tooltips, or dialogs.
-///         Popovers are managed by <see cref="ApplicationPopover"/> and are typically shown using
-///         <see cref="ApplicationPopover.Show"/>.
 ///     </para>
 ///     <para>
-///         Popovers are not modal; they do not block input to the rest of the application, but they do receive focus and
-///         input events while visible.
-///         When a popover is shown, it is responsible for handling its own layout and content.
+///         <b>IMPORTANT:</b> Popovers must be registered with <see cref="Application.Popover"/> using
+///         <see cref="ApplicationPopover.Register"/> before they can be shown with <see cref="ApplicationPopover.Show"/>.
 ///     </para>
 ///     <para>
+///         <b>Lifecycle:</b><br/>
+///         When registered, the popover's lifetime is managed by the application. Registered popovers are
+///         automatically disposed when <see cref="Application.Shutdown"/> is called. Call
+///         <see cref="ApplicationPopover.DeRegister"/> to manage the lifetime directly.
+///     </para>
+///     <para>
+///         <b>Visibility and Hiding:</b><br/>
 ///         Popovers are automatically hidden when:
-///         <list type="bullet">
-///             <item>The user clicks outside the popover (unless occluded by a subview of the popover).</item>
-///             <item>The user presses <see cref="Application.QuitKey"/> (typically <c>Esc</c>).</item>
-///             <item>Another popover is shown.</item>
-///         </list>
 ///     </para>
+///     <list type="bullet">
+///         <item>The user clicks outside the popover (unless clicking on a subview).</item>
+///         <item>The user presses <see cref="Application.QuitKey"/> (typically <c>Esc</c>).</item>
+///         <item>Another popover is shown.</item>
+///         <item><see cref="View.Visible"/> is set to <see langword="false"/>.</item>
+///     </list>
 ///     <para>
 ///         <b>Focus and Input:</b><br/>
-///         When visible, a popover receives focus and input events. If the user clicks outside the popover (and not on a
-///         subview),
-///         presses <see cref="Application.QuitKey"/>, or another popover is shown, the popover will be hidden
-///         automatically.
+///         Popovers are not modal but do receive focus and input events while visible.
+///         Registered popovers receive keyboard events even when not visible, enabling global hotkey support.
 ///     </para>
 ///     <para>
 ///         <b>Layout:</b><br/>
-///         When the popover becomes visible, it is automatically laid out to fill the screen by default. You can override
-///         this behavior
-///         by setting <see cref="View.Width"/> and <see cref="View.Height"/> in your derived class.
+///         When becoming visible, popovers are automatically laid out to fill the screen by default.
+///         Override <see cref="View.Width"/> and <see cref="View.Height"/> to customize size.
 ///     </para>
 ///     <para>
-///         <b>Mouse:</b><br/>
-///         Popovers are transparent to mouse events (see <see cref="ViewportSettingsFlags.TransparentMouse"/>),
-///         meaning mouse events in a popover that are not also within a subview of the popover will not be captured.
+///         <b>Mouse Events:</b><br/>
+///         Popovers use <see cref="ViewportSettingsFlags.TransparentMouse"/>, meaning mouse events
+///         outside subviews are not captured.
 ///     </para>
 ///     <para>
-///         <b>Custom Popovers:</b><br/>
-///         To create a custom popover, inherit from <see cref="PopoverBaseImpl"/> and add your own content and logic.
+///         <b>Creating Custom Popovers:</b><br/>
+///         Inherit from <see cref="PopoverBaseImpl"/> and add your own content and logic.
 ///     </para>
 /// </remarks>
 public interface IPopover
 {
     /// <summary>
-    ///     Gets or sets the <see cref="Current"/> that this Popover is associated with. If null, it is not associated with
-    ///     any Runnable and will receive all keyboard
-    ///     events from the <see cref="IApplication"/>. If set, it will only receive keyboard events the Runnable would normally
-    ///     receive.
-    ///     When <see cref="ApplicationPopover.Register"/> is called, the <see cref="Current"/> is set to the current
-    ///     <see cref="IApplication.TopRunnableView"/> if not already set.
+    ///     Gets or sets the <see cref="IRunnable"/> that this popover is associated with.
     /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         If <see langword="null"/>, the popover is not associated with any runnable and will receive all keyboard
+    ///         events from the application.
+    ///     </para>
+    ///     <para>
+    ///         If set, the popover will only receive keyboard events when the associated runnable is active.
+    ///     </para>
+    ///     <para>
+    ///         When <see cref="ApplicationPopover.Register"/> is called, this property is automatically set to
+    ///         <see cref="IApplication.TopRunnableView"/> if not already set.
+    ///     </para>
+    /// </remarks>
     IRunnable? Current { get; set; }
 }

+ 39 - 27
Terminal.Gui/App/PopoverBaseImpl.cs

@@ -2,36 +2,36 @@
 namespace Terminal.Gui.App;
 
 /// <summary>
-///     Abstract base class for popover views in Terminal.Gui.
+///     Abstract base class for popover views in Terminal.Gui. Implements <see cref="IPopover"/>.
 /// </summary>
 /// <remarks>
 ///     <para>
-///         <b>Popover Lifecycle:</b><br/>
-///         To display a popover, use <see cref="ApplicationPopover.Show"/>. To hide a popover, either call
-///         <see cref="ApplicationPopover.Hide"/>,
-///         set <see cref="View.Visible"/> to <see langword="false"/>, or show another popover.
+///         <b>IMPORTANT:</b> Popovers must be registered with <see cref="Application.Popover"/> using
+///         <see cref="ApplicationPopover.Register"/> before they can be shown.
 ///     </para>
 ///     <para>
-///         <b>Focus and Input:</b><br/>
-///         When visible, a popover receives focus and input events. If the user clicks outside the popover (and not on a
-///         subview),
-///         presses <see cref="Application.QuitKey"/>, or another popover is shown, the popover will be hidden
-///         automatically.
+///         <b>Requirements:</b><br/>
+///         Derived classes must:
 ///     </para>
+///     <list type="bullet">
+///         <item>Set <see cref="View.ViewportSettings"/> to include <see cref="ViewportSettingsFlags.Transparent"/> and <see cref="ViewportSettingsFlags.TransparentMouse"/>.</item>
+///         <item>Add a key binding for <see cref="Command.Quit"/> (typically bound to <see cref="Application.QuitKey"/>).</item>
+///     </list>
 ///     <para>
-///         <b>Layout:</b><br/>
-///         When the popover becomes visible, it is automatically laid out to fill the screen by default. You can override
-///         this behavior
-///         by setting <see cref="View.Width"/> and <see cref="View.Height"/> in your derived class.
+///         <b>Default Behavior:</b><br/>
+///         This base class provides:
 ///     </para>
+///     <list type="bullet">
+///         <item>Fills the screen by default (<see cref="View.Width"/> = <see cref="Dim.Fill"/>, <see cref="View.Height"/> = <see cref="Dim.Fill"/>).</item>
+///         <item>Transparent viewport settings for proper mouse event handling.</item>
+///         <item>Automatic layout when becoming visible.</item>
+///         <item>Focus restoration when hidden.</item>
+///         <item>Default <see cref="Command.Quit"/> implementation that hides the popover.</item>
+///     </list>
 ///     <para>
-///         <b>Mouse:</b><br/>
-///         Popovers are transparent to mouse events (see <see cref="ViewportSettingsFlags.TransparentMouse"/>),
-///         meaning mouse events in a popover that are not also within a subview of the popover will not be captured.
-///     </para>
-///     <para>
-///         <b>Custom Popovers:</b><br/>
-///         To create a custom popover, inherit from <see cref="PopoverBaseImpl"/> and add your own content and logic.
+///         <b>Lifecycle:</b><br/>
+///         Use <see cref="ApplicationPopover.Show"/> to display and <see cref="ApplicationPopover.Hide"/> or
+///         set <see cref="View.Visible"/> to <see langword="false"/> to hide.
 ///     </para>
 /// </remarks>
 public abstract class PopoverBaseImpl : View, IPopover
@@ -40,7 +40,15 @@ public abstract class PopoverBaseImpl : View, IPopover
     ///     Initializes a new instance of the <see cref="PopoverBaseImpl"/> class.
     /// </summary>
     /// <remarks>
-    ///     By default, the popover fills the available screen area and is focusable.
+    ///     <para>
+    ///         Sets up default popover behavior:
+    ///     </para>
+    ///     <list type="bullet">
+    ///         <item>Fills the screen (<see cref="View.Width"/> = <see cref="Dim.Fill"/>, <see cref="View.Height"/> = <see cref="Dim.Fill"/>).</item>
+    ///         <item>Sets <see cref="View.CanFocus"/> to <see langword="true"/>.</item>
+    ///         <item>Configures <see cref="View.ViewportSettings"/> with <see cref="ViewportSettingsFlags.Transparent"/> and <see cref="ViewportSettingsFlags.TransparentMouse"/>.</item>
+    ///         <item>Adds <see cref="Command.Quit"/> bound to <see cref="Application.QuitKey"/> which hides the popover when invoked.</item>
+    ///     </list>
     /// </remarks>
     protected PopoverBaseImpl ()
     {
@@ -87,15 +95,19 @@ public abstract class PopoverBaseImpl : View, IPopover
     }
 
     /// <summary>
-    ///     Called when the <see cref="View.Visible"/> property is changing.
+    ///     Called when the <see cref="View.Visible"/> property is changing. Handles layout and focus management.
     /// </summary>
-    /// <remarks>
-    ///     When becoming visible, the popover is laid out to fit the screen.
-    ///     When becoming hidden, focus is restored to the previous view.
-    /// </remarks>
     /// <returns>
     ///     <see langword="true"/> to cancel the visibility change; otherwise, <see langword="false"/>.
     /// </returns>
+    /// <remarks>
+    ///     <para>
+    ///         <b>When becoming visible:</b> Lays out the popover to fit the screen.
+    ///     </para>
+    ///     <para>
+    ///         <b>When becoming hidden:</b> Restores focus to the previously focused view in the view hierarchy.
+    ///     </para>
+    /// </remarks>
     protected override bool OnVisibleChanging ()
     {
         bool ret = base.OnVisibleChanging ();

+ 160 - 41
Terminal.Gui/Views/Menu/PopoverMenu.cs

@@ -1,16 +1,29 @@
-
-
 namespace Terminal.Gui.Views;
 
 /// <summary>
-///     Provides a cascading menu that pops over all other content. Can be used as a context menu or a drop-down
-///     all other content. Can be used as a context menu or a drop-down
-///     menu as part of <see cref="MenuBar"/> as part of <see cref="MenuBar"/>.
+///     A <see cref="PopoverBaseImpl"/>-derived view that provides a cascading menu.
+///     Can be used as a context menu or a drop-down menu as part of <see cref="MenuBar"/>.
 /// </summary>
 /// <remarks>
 ///     <para>
-///         To use as a context menu, register the popover menu with <see cref="IApplication.Popover"/> and call
-///         <see cref="MakeVisible"/>.
+///         <b>IMPORTANT:</b> Must be registered with <see cref="Application.Popover"/> via
+///         <see cref="ApplicationPopover.Register"/> before calling <see cref="MakeVisible"/> or
+///         <see cref="ApplicationPopover.Show"/>.
+///     </para>
+///     <para>
+///         <b>Usage Example:</b>
+///     </para>
+///     <code>
+///         var menu = new PopoverMenu ([
+///             new MenuItem ("Cut", Command.Cut),
+///             new MenuItem ("Copy", Command.Copy),
+///             new MenuItem ("Paste", Command.Paste)
+///         ]);
+///         Application.Popover?.Register (menu);
+///         menu.MakeVisible (); // or Application.Popover?.Show (menu);
+///     </code>
+///     <para>
+///         See <see cref="PopoverBaseImpl"/> and <see cref="IPopover"/> for lifecycle, focus, and keyboard handling details.
 ///     </para>
 /// </remarks>
 public class PopoverMenu : PopoverBaseImpl, IDesignable
@@ -22,9 +35,12 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
 
     /// <summary>
     ///     Initializes a new instance of the <see cref="PopoverMenu"/> class. If any of the elements of
-    ///     <paramref name="menuItems"/> is <see langword="null"/>,
-    ///     a see <see cref="Line"/> will be created instead.
+    ///     <paramref name="menuItems"/> is <see langword="null"/>, a <see cref="Line"/> will be created instead.
     /// </summary>
+    /// <param name="menuItems">The views to use as menu items. Null elements become separator lines.</param>
+    /// <remarks>
+    ///     Remember to call <see cref="ApplicationPopover.Register"/> before calling <see cref="MakeVisible"/>.
+    /// </remarks>
     public PopoverMenu (IEnumerable<View>? menuItems) : this (
                                                               new Menu (menuItems?.Select (item => item ?? new Line ()))
                                                               {
@@ -32,17 +48,27 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
                                                               })
     { }
 
-    /// <inheritdoc/>
+    /// <summary>
+    ///     Initializes a new instance of the <see cref="PopoverMenu"/> class with the specified menu items.
+    /// </summary>
+    /// <param name="menuItems">The menu items to display in the popover.</param>
+    /// <remarks>
+    ///     Remember to call <see cref="ApplicationPopover.Register"/> before calling <see cref="MakeVisible"/>.
+    /// </remarks>
     public PopoverMenu (IEnumerable<MenuItem>? menuItems) : this (
-                                                                    new Menu (menuItems)
-                                                                    {
-                                                                        Title = "Popover Root"
-                                                                    })
+                                                                  new Menu (menuItems)
+                                                                  {
+                                                                      Title = "Popover Root"
+                                                                  })
     { }
 
     /// <summary>
     ///     Initializes a new instance of the <see cref="PopoverMenu"/> class with the specified root <see cref="Menu"/>.
     /// </summary>
+    /// <param name="root">The root menu that contains the top-level menu items.</param>
+    /// <remarks>
+    ///     Remember to call <see cref="ApplicationPopover.Register"/> before calling <see cref="MakeVisible"/>.
+    /// </remarks>
     public PopoverMenu (Menu? root)
     {
         // Do this to support debugging traces where Title gets set
@@ -132,7 +158,14 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
 
     private Key _key = DefaultKey;
 
-    /// <summary>Specifies the key that will activate the context menu.</summary>
+    /// <summary>
+    ///     Gets or sets the key that will activate the popover menu when it is registered but not visible.
+    /// </summary>
+    /// <remarks>
+    ///     This key binding works as a global hotkey when the popover is registered with
+    ///     <see cref="Application.Popover"/>. The default value is <see cref="DefaultKey"/> (<see cref="Key.F10"/> with
+    ///     Shift).
+    /// </remarks>
     public Key Key
     {
         get => _key;
@@ -144,10 +177,17 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
         }
     }
 
-    /// <summary>Raised when <see cref="Key"/> is changed.</summary>
+    /// <summary>
+    ///     Raised when the <see cref="Key"/> property is changed.
+    /// </summary>
     public event EventHandler<KeyChangedEventArgs>? KeyChanged;
 
-    /// <summary>The default key for activating popover menus.</summary>
+    /// <summary>
+    ///     Gets or sets the default key for activating popover menus. The default value is <see cref="Key.F10"/> with Shift.
+    /// </summary>
+    /// <remarks>
+    ///     This is a configuration property that affects all new <see cref="PopoverMenu"/> instances.
+    /// </remarks>
     [ConfigurationProperty (Scope = typeof (SettingsScope))]
     public static Key DefaultKey { get; set; } = Key.F10.WithShift;
 
@@ -159,12 +199,25 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
 
     /// <summary>
     ///     Makes the popover menu visible and locates it at <paramref name="idealScreenPosition"/>. The actual position of the
-    ///     menu
-    ///     will be adjusted to
-    ///     ensure the menu fully fits on the screen, and the mouse cursor is over the first cell of the
-    ///     first MenuItem.
+    ///     menu will be adjusted to ensure the menu fully fits on the screen, with the mouse cursor positioned over
+    ///     the first cell of the first <see cref="MenuItem"/>.
     /// </summary>
-    /// <param name="idealScreenPosition">If <see langword="null"/>, the current mouse position will be used.</param>
+    /// <param name="idealScreenPosition">
+    ///     The ideal screen-relative position for the menu. If <see langword="null"/>, the current mouse position will be
+    ///     used.
+    /// </param>
+    /// <remarks>
+    ///     <para>
+    ///         IMPORTANT: The popover must be registered with <see cref="Application.Popover"/> before calling this
+    ///         method.
+    ///         Call <see cref="ApplicationPopover.Register"/> first.
+    ///     </para>
+    ///     <para>
+    ///         This method internally calls <see cref="ApplicationPopover.Show"/>, which will throw
+    ///         <see cref="InvalidOperationException"/> if the popover is not registered.
+    ///     </para>
+    /// </remarks>
+    /// <exception cref="InvalidOperationException">Thrown if the popover has not been registered.</exception>
     public void MakeVisible (Point? idealScreenPosition = null)
     {
         if (Visible)
@@ -180,12 +233,18 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
     }
 
     /// <summary>
-    ///     Locates the popover menu at <paramref name="idealScreenPosition"/>. The actual position of the menu will be
-    ///     adjusted to
-    ///     ensure the menu fully fits on the screen, and the mouse cursor is over the first cell of the
-    ///     first MenuItem (if possible).
+    ///     Sets the position of the popover menu at <paramref name="idealScreenPosition"/>. The actual position will be
+    ///     adjusted to ensure the menu fully fits on the screen, with the mouse cursor positioned over the first cell of
+    ///     the first <see cref="MenuItem"/> (if possible).
     /// </summary>
-    /// <param name="idealScreenPosition">If <see langword="null"/>, the current mouse position will be used.</param>
+    /// <param name="idealScreenPosition">
+    ///     The ideal screen-relative position for the menu. If <see langword="null"/>, the current mouse position will be
+    ///     used.
+    /// </param>
+    /// <remarks>
+    ///     This method only sets the position; it does not make the popover visible. Use <see cref="MakeVisible"/> to
+    ///     both position and show the popover.
+    /// </remarks>
     public void SetPosition (Point? idealScreenPosition = null)
     {
         idealScreenPosition ??= App?.Mouse.LastMousePosition;
@@ -212,6 +271,10 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
     }
 
     /// <inheritdoc/>
+    /// <remarks>
+    ///     When becoming visible, the root menu is added and shown. When becoming hidden, the root menu is removed
+    ///     and the popover is hidden via <see cref="ApplicationPopover.Hide"/>.
+    /// </remarks>
     protected override void OnVisibleChanged ()
     {
         // Logging.Debug ($"{Title} - Visible: {Visible}");
@@ -231,8 +294,17 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
     private Menu? _root;
 
     /// <summary>
-    ///     Gets or sets the <see cref="Menu"/> that is the root of the Popover Menu.
+    ///     Gets or sets the <see cref="Menu"/> that is the root of the popover menu hierarchy.
     /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         The root menu contains the top-level menu items. Setting this property updates key bindings and
+    ///         event subscriptions for all menus in the hierarchy.
+    ///     </para>
+    ///     <para>
+    ///         When set, all submenus are configured with appropriate event handlers for selection and acceptance.
+    ///     </para>
+    /// </remarks>
     public Menu? Root
     {
         get => _root;
@@ -306,6 +378,10 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
     }
 
     /// <inheritdoc/>
+    /// <remarks>
+    ///     This method checks all menu items in the hierarchy for a matching key binding and invokes the
+    ///     appropriate menu item if found.
+    /// </remarks>
     protected override bool OnKeyDownNotHandled (Key key)
     {
         // See if any of our MenuItems have this key as Key
@@ -325,9 +401,12 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
     }
 
     /// <summary>
-    ///     Gets all the submenus in the PopoverMenu.
+    ///     Gets all the submenus in the popover menu hierarchy, including the root menu.
     /// </summary>
-    /// <returns></returns>
+    /// <returns>An enumerable collection of all <see cref="Menu"/> instances in the hierarchy.</returns>
+    /// <remarks>
+    ///     This method performs a depth-first traversal of the menu tree, starting from <see cref="Root"/>.
+    /// </remarks>
     public IEnumerable<Menu> GetAllSubMenus ()
     {
         List<Menu> result = [];
@@ -358,9 +437,12 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
     }
 
     /// <summary>
-    ///     Gets all the MenuItems in the PopoverMenu.
+    ///     Gets all the menu items in the popover menu hierarchy.
     /// </summary>
-    /// <returns></returns>
+    /// <returns>An enumerable collection of all <see cref="MenuItem"/> instances across all menus in the hierarchy.</returns>
+    /// <remarks>
+    ///     This method traverses all menus returned by <see cref="GetAllSubMenus"/> and collects their menu items.
+    /// </remarks>
     internal IEnumerable<MenuItem> GetMenuItemsOfAllSubMenus ()
     {
         List<MenuItem> result = [];
@@ -380,9 +462,17 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
     }
 
     /// <summary>
-    ///     Pops up the submenu of the specified MenuItem, if there is one.
+    ///     Shows the submenu of the specified <see cref="MenuItem"/>, if it has one.
     /// </summary>
-    /// <param name="menuItem"></param>
+    /// <param name="menuItem">The menu item whose submenu should be shown.</param>
+    /// <remarks>
+    ///     <para>
+    ///         If another submenu is currently visible at the same level, it will be hidden before showing the new one.
+    ///     </para>
+    ///     <para>
+    ///         The submenu is positioned to the right of the menu item, adjusted to ensure full visibility on screen.
+    ///     </para>
+    /// </remarks>
     internal void ShowSubMenu (MenuItem? menuItem)
     {
         var menu = menuItem?.SuperView as Menu;
@@ -416,11 +506,14 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
     }
 
     /// <summary>
-    ///     Gets the most visible screen-relative location for <paramref name="menu"/>.
+    ///     Calculates the most visible screen-relative location for the specified <paramref name="menu"/>.
     /// </summary>
-    /// <param name="menu">The menu to locate.</param>
-    /// <param name="idealLocation">Ideal screen-relative location.</param>
-    /// <returns></returns>
+    /// <param name="menu">The menu to position.</param>
+    /// <param name="idealLocation">The ideal screen-relative location.</param>
+    /// <returns>The adjusted screen-relative position that ensures maximum visibility of the menu.</returns>
+    /// <remarks>
+    ///     This method adjusts the position to keep the menu fully visible on screen, considering screen boundaries.
+    /// </remarks>
     internal Point GetMostVisibleLocationForSubMenu (Menu menu, Point idealLocation)
     {
         var pos = Point.Empty;
@@ -489,6 +582,7 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
     private void MenuOnAccepting (object? sender, CommandEventArgs e)
     {
         var senderView = sender as View;
+
         // Logging.Debug ($"{Title} ({e.Context?.Source?.Title}) Command: {e.Context?.Command} - Sender: {senderView?.GetType ().Name}");
 
         if (e.Context?.Command != Command.HotKey)
@@ -524,6 +618,14 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
     }
 
     /// <inheritdoc/>
+    /// <remarks>
+    ///     <para>
+    ///         When the popover is not visible, only hotkey commands are processed.
+    ///     </para>
+    ///     <para>
+    ///         This method raises <see cref="View.Accepted"/> for commands that originate from menu items in the hierarchy.
+    ///     </para>
+    /// </remarks>
     protected override bool OnAccepting (CommandEventArgs args)
     {
         // Logging.Debug ($"{Title} ({args.Context?.Source?.Title}) Command: {args.Context?.Command}");
@@ -560,8 +662,6 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
         return false;
     }
 
-
-
     private void MenuOnSelectedMenuItemChanged (object? sender, MenuItem? e)
     {
         // Logging.Debug ($"{Title} - e.Title: {e?.Title}");
@@ -569,6 +669,13 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
     }
 
     /// <inheritdoc/>
+    /// <exception cref="InvalidOperationException">
+    ///     Thrown if attempting to add a <see cref="Menu"/> or <see cref="MenuItem"/> directly to the popover.
+    /// </exception>
+    /// <remarks>
+    ///     Do not add <see cref="MenuItem"/> or <see cref="Menu"/> views directly to the popover.
+    ///     Use the <see cref="Root"/> property instead.
+    /// </remarks>
     protected override void OnSubViewAdded (View view)
     {
         if (Root is null && (view is Menu || view is MenuItem))
@@ -580,6 +687,9 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
     }
 
     /// <inheritdoc/>
+    /// <remarks>
+    ///     This method unsubscribes from all menu events and disposes the root menu.
+    /// </remarks>
     protected override void Dispose (bool disposing)
     {
         if (disposing)
@@ -600,7 +710,16 @@ public class PopoverMenu : PopoverBaseImpl, IDesignable
         base.Dispose (disposing);
     }
 
-    /// <inheritdoc/>
+    /// <summary>
+    ///     Enables the popover menu for use in design-time scenarios.
+    /// </summary>
+    /// <typeparam name="TContext">The type of the target view context.</typeparam>
+    /// <param name="targetView">The target view to associate with the menu commands.</param>
+    /// <returns><see langword="true"/> if successfully enabled for design; otherwise, <see langword="false"/>.</returns>
+    /// <remarks>
+    ///     This method creates a default set of menu items (Cut, Copy, Paste, Select All, Quit) for design-time use.
+    ///     It is primarily used for demonstration and testing purposes.
+    /// </remarks>
     public bool EnableForDesign<TContext> (ref TContext targetView) where TContext : notnull
     {
         // Note: This menu is used by unit tests. If you modify it, you'll likely have to update