Skip to content

Add KioskModeManager component - #14736

Open
KlausLoeffelmann wants to merge 11 commits into
dotnet:mainfrom
KlausLoeffelmann:Net11Api_04_KioskManagerComponent
Open

Add KioskModeManager component#14736
KlausLoeffelmann wants to merge 11 commits into
dotnet:mainfrom
KlausLoeffelmann:Net11Api_04_KioskManagerComponent

Conversation

@KlausLoeffelmann

@KlausLoeffelmann KlausLoeffelmann commented Jul 14, 2026

Copy link
Copy Markdown
Member

Closes #14586.
Contributes to #14694.

Bug fixes

  • Introduces the designer-friendly KioskModeManager component.
  • Supports fullscreen restoration, optional taskbar coverage, topmost behavior, cursor auto-hide, and power-saving suppression.
  • Resolves containing forms safely for both Form- and UserControl-hosted components.
  • Adds lifecycle, initialization, keyboard, wakeup, disposal, and data-binding coverage.
Microsoft Reviewers: Open in CodeFlow

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a designer-friendly kiosk-mode component to WinForms and updates ToolStrip dropdown positioning for fullscreen forms.

Changes:

  • Adds fullscreen, topmost, cursor-hiding, keyboard, and power-request behavior.
  • Adjusts dropdown bounds for taskbar-covering forms and adds tests.
  • Relocates existing component sources and adds API/resource/build support.

Reviewed changes

Copilot reviewed 23 out of 45 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
docs/Net11Api_04_KioskManagerComponent.HighRiskReview.md Records unresolved fullscreen state semantics.
src/BuildAssist/BuildAssist.msbuildproj Quotes the vswhere executable path.
src/System.Windows.Forms.Primitives/src/NativeMethods.txt Adds power-request APIs.
src/System.Windows.Forms/PublicAPI.Unshipped.txt Declares the new public API.
src/System.Windows.Forms/Resources/SR.resx Adds kiosk resource strings.
src/System.Windows.Forms/Resources/xlf/SR.cs.xlf Adds Czech resource entries.
src/System.Windows.Forms/Resources/xlf/SR.de.xlf Adds German resource entries.
src/System.Windows.Forms/Resources/xlf/SR.es.xlf Adds Spanish resource entries.
src/System.Windows.Forms/Resources/xlf/SR.fr.xlf Adds French resource entries.
src/System.Windows.Forms/Resources/xlf/SR.it.xlf Adds Italian resource entries.
src/System.Windows.Forms/Resources/xlf/SR.ja.xlf Adds Japanese resource entries.
src/System.Windows.Forms/Resources/xlf/SR.ko.xlf Adds Korean resource entries.
src/System.Windows.Forms/Resources/xlf/SR.pl.xlf Adds Polish resource entries.
src/System.Windows.Forms/Resources/xlf/SR.pt-BR.xlf Adds Brazilian Portuguese entries.
src/System.Windows.Forms/Resources/xlf/SR.ru.xlf Adds Russian resource entries.
src/System.Windows.Forms/Resources/xlf/SR.tr.xlf Adds Turkish resource entries.
src/System.Windows.Forms/Resources/xlf/SR.zh-Hans.xlf Adds Simplified Chinese entries.
src/System.Windows.Forms/Resources/xlf/SR.zh-Hant.xlf Adds Traditional Chinese entries.
src/System.Windows.Forms/System/Windows/Forms/Components/ErrorProvider/ErrorBlinkStyle.cs Relocates the error blink enum.
src/System.Windows.Forms/System/Windows/Forms/Components/ErrorProvider/ErrorIconAlignment.cs Relocates the icon alignment enum.
src/System.Windows.Forms/System/Windows/Forms/Components/ErrorProvider/ErrorProvider.ControlItem.ControlItemAccessibleObject.cs Relocates accessibility implementation.
src/System.Windows.Forms/System/Windows/Forms/Components/ErrorProvider/ErrorProvider.ControlItem.cs Relocates control-item logic.
src/System.Windows.Forms/System/Windows/Forms/Components/ErrorProvider/ErrorProvider.ErrorProviderStates.cs Relocates state flags.
src/System.Windows.Forms/System/Windows/Forms/Components/ErrorProvider/ErrorProvider.ErrorWindow.ErrorWindowAccessibleObject.cs Relocates window accessibility logic.
src/System.Windows.Forms/System/Windows/Forms/Components/ErrorProvider/ErrorProvider.ErrorWindow.cs Relocates error-window logic.
src/System.Windows.Forms/System/Windows/Forms/Components/ErrorProvider/ErrorProvider.IconRegion.cs Relocates icon-region logic.
src/System.Windows.Forms/System/Windows/Forms/Components/ErrorProvider/ErrorProvider.cs Relocates the ErrorProvider component.
src/System.Windows.Forms/System/Windows/Forms/Components/HelpProvider.cs Relocates the HelpProvider component.
src/System.Windows.Forms/System/Windows/Forms/Components/ImageList/ColorDepth.cs Relocates the color-depth enum.
src/System.Windows.Forms/System/Windows/Forms/Components/ImageList/ImageList.ImageCollection.ImageInfo.cs Relocates image metadata.
src/System.Windows.Forms/System/Windows/Forms/Components/ImageList/ImageList.ImageCollection.cs Relocates image collection logic.
src/System.Windows.Forms/System/Windows/Forms/Components/ImageList/ImageList.Indexer.cs Relocates image indexing logic.
src/System.Windows.Forms/System/Windows/Forms/Components/ImageList/ImageList.NativeImageList.cs Relocates native image-list handling.
src/System.Windows.Forms/System/Windows/Forms/Components/ImageList/ImageList.Original.cs Relocates original-image state.
src/System.Windows.Forms/System/Windows/Forms/Components/ImageList/ImageList.OriginalOptions.cs Relocates original-image flags.
src/System.Windows.Forms/System/Windows/Forms/Components/ImageList/ImageList.cs Relocates the ImageList component.
src/System.Windows.Forms/System/Windows/Forms/Components/ImageList/ImageListConverter.cs Relocates the type converter.
src/System.Windows.Forms/System/Windows/Forms/Components/ImageList/ImageListStreamer.cs Relocates serialization support.
src/System.Windows.Forms/System/Windows/Forms/Components/ImageList/RelatedImageListAttribute.cs Relocates the related-list attribute.
src/System.Windows.Forms/System/Windows/Forms/Components/KioskModeManager/KioskModeManager.cs Implements kiosk-mode behavior.
src/System.Windows.Forms/System/Windows/Forms/Components/Timer.cs Relocates the Timer component.
src/System.Windows.Forms/System/Windows/Forms/Controls/ToolStrips/ToolStripDropDown.cs Makes dropdown bounds owner-aware.
src/System.Windows.Forms/System/Windows/Forms/Controls/ToolStrips/ToolStripDropDownItem.cs Passes the owner when constraining dropdowns.
src/System.Windows.Forms/System/Windows/Forms/Internal/WinFormsUtils.cs Adds fullscreen-aware screen bounds.
src/test/unit/System.Windows.Forms/System/Windows/Forms/KioskModeManagerTests.cs Adds kiosk lifecycle and behavior tests.
Suppressed comments (1)

src/System.Windows.Forms/PublicAPI.Unshipped.txt:134

  • The proposed public member is ToggleFullScreenKey, but this baseline exposes ToggleFullScreenKeys. Public API naming must match the approved proposal before the first release to avoid immediately carrying a compatibility alias or breaking change.
System.Windows.Forms.KioskModeManager.ToggleFullScreenKeys.get -> System.Windows.Forms.Keys
System.Windows.Forms.KioskModeManager.ToggleFullScreenKeys.set -> void

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

[DefaultProperty(nameof(ToggleFullScreenKeys))]
[ToolboxItemFilter("System.Windows.Forms")]
[SRDescription(nameof(SR.DescriptionKioskModeManager))]
public class KioskModeManager : Component, ISupportInitialize
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool FullScreen
{
get => _pendingFullScreen || _isFullScreen;
Comment on lines +725 to +727
// Kiosk fullscreen always covers the complete screen, including the
// taskbar, so there is only one window model to reason about.
Rectangle fullScreenBounds = screen.Bounds;
Comment on lines +1048 to +1050
if (m.MsgInternal == PInvokeCore.WM_DISPLAYCHANGE)
{
_owner.RefreshFullScreenBounds();
Comment on lines +113 to +114
System.Windows.Forms.KioskModeManager.AlwaysOn.get -> bool
System.Windows.Forms.KioskModeManager.AlwaysOn.set -> void
Rectangle suggestedScreenBounds = new(screenPoint, suggestedBounds.Size);
dropDownBounds = WorkingAreaConstrained
? WindowsFormsUtils.ConstrainToScreenWorkingAreaBounds(suggestedScreenBounds)
? WindowsFormsUtils.ConstrainToScreenWorkingAreaBounds(suggestedScreenBounds, GetToplevelOwnerToolStrip())
if (WorkingAreaConstrained)
{
dropDownBounds = WindowsFormsUtils.ConstrainToScreenWorkingAreaBounds(dropDownBounds);
dropDownBounds = WindowsFormsUtils.ConstrainToScreenWorkingAreaBounds(dropDownBounds, GetToplevelOwnerToolStrip());
KlausLoeffelmann and others added 10 commits August 14, 2026 10:38
* Refactor KioskModeManager component and introduce WakeUp-Events incl.. new WakeUpEventArgs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 20883488-cf1e-4ad3-a681-0724e9f16777
Size borderless fullscreen forms directly to the selected screen bounds instead of maximizing them. This keeps StatusStrip items and working-area-constrained dropdowns on the same screen edge while preserving restored form state.

Fixes dotnet#14765

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: c352332b-4b81-4492-bcfc-9dec524c27c9
Choose fullscreen bounds from RestoreBounds for minimized and maximized forms so a minimized-window sentinel cannot redirect kiosk mode to the wrong monitor.

Fixes dotnet#14765

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: c352332b-4b81-4492-bcfc-9dec524c27c9
Reapply explicit fullscreen bounds when display geometry or the taskbar working area changes so the normal-state kiosk window tracks the selected screen like the previous maximized window did.

Fixes dotnet#14765

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: c352332b-4b81-4492-bcfc-9dec524c27c9
API review feedback: the "Wakeup" elements are more general than kiosk mode
and should not be part of KioskModeManager. They can reappear later with a
broader scope.

Removes the Wakeup event, OnWakeup, WakeUpCommand, KioskModeWakeupEventArgs,
KioskModeWakeupEventHandler, and KioskModeWakeupSource, along with the power
broadcast and terminal session notification plumbing that only fed them.
Display change tracking, which keeps the fullscreen bounds current, is kept.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8999e9ff-9bcc-4755-b337-7fc5496d431c
API review feedback: HideTaskbar was removed to simplify the window models.

Kiosk fullscreen now always sizes the borderless form to the complete bounds
of the screen that displays it, so there is a single window model and the
kiosk surface always covers the taskbar.

Because the fullscreen form now covers the taskbar, drop-downs owned by that
form can no longer be constrained to the screen working area - doing so
detaches them from the item that opened them (dotnet#14765).
ToolStripDropDown and ToolStripDropDownItem now constrain to the complete
screen bounds when the owning top-level window is borderless and covers the
screen.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8999e9ff-9bcc-4755-b337-7fc5496d431c
- ToggleFullScreenKey => ToggleFullScreenKeys, for consistency with the
  plurality of the Keys type. The property now matches the complete key
  combination, including modifiers, and Keys.None disables key based
  toggling.
- SuppressPowerSaving => AlwaysOn.

Also documents that the fullscreen keys are focus driven: they are evaluated
only for input dispatched to the managed form or one of its child controls,
and no global keyboard hook or system wide hot key is installed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8999e9ff-9bcc-4755-b337-7fc5496d431c
@KlausLoeffelmann
KlausLoeffelmann force-pushed the Net11Api_04_KioskManagerComponent branch from 0250bc0 to 09a1f56 Compare August 14, 2026 17:38
- Clarified MousePointerAutoHideDelay XML docs regarding message queue observation and lack of hooks.
- Updated OnMousePointerAutoHideTimerTick to only hide cursor in fullscreen, with delay > 0, and when not already hidden.
- Added unit tests for timer interval, delay changes, zero-delay behavior, and pointer visibility logic.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 45 changed files in this pull request and generated no new comments.

Suppressed comments (6)

src/System.Windows.Forms/System/Windows/Forms/Components/KioskModeManager/KioskModeManager.cs:59

  • The advertised two-way data binding is unavailable: deriving directly from Component provides neither DataBindings nor BindingContext, and [Bindable(true)] is only metadata. Consequently, the documented _kioskModeManager.DataBindings.Add(...) usage does not compile. Derive from BindableComponent or otherwise implement the WinForms binding surface and cover the documented scenario.
    src/System.Windows.Forms/System/Windows/Forms/Components/KioskModeManager/KioskModeManager.cs:59
  • The PR promises wakeup support, but this type omits the approved WakeUpCommand, Wakeup, wake-source event args/delegate, and all keyboard, mouse, power-resume, and session wake notifications. Add the missing API and observation paths before this can satisfy the stated feature.
    src/System.Windows.Forms/System/Windows/Forms/Components/KioskModeManager/KioskModeManager.cs:415
  • FullScreen is documented as the current fullscreen state, but this getter also returns a pending request. Setting it before a form exists therefore changes the property without FullScreenChanged; later entering fullscreen raises the event while the property stays true. This breaks normal property-change/data-binding semantics. Resolve whether this API represents requested or actual state and make the getter, event, toggle, and pending transitions consistent.
    src/System.Windows.Forms/System/Windows/Forms/Components/KioskModeManager/KioskModeManager.cs:729
  • Fullscreen is hardwired to Screen.Bounds, so it always covers the taskbar. The PR explicitly promises optional taskbar coverage and the accepted API includes HideTaskbar; add that property and use Screen.WorkingArea when it is disabled.
    src/System.Windows.Forms/System/Windows/Forms/Components/KioskModeManager/KioskModeManager.cs:313
  • The accepted API names this property SuppressPowerSaving; publishing it as AlwaysOn is incompatible with the proposal and is also less specific about what is being kept on. Rename the property and its associated resources/tests/PublicAPI entry before the API ships.
    src/System.Windows.Forms/System/Windows/Forms/Components/KioskModeManager/KioskModeManager.cs:244
  • The accepted API exposes ToggleFullScreenKey (singular), while this introduces ToggleFullScreenKeys. Align the public name with the approved API before it becomes a compatibility commitment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants