Skip to content

SettingsProtectionHelper: support always-hidden controls - #1522

Merged
imnasnainaec merged 16 commits into
masterfrom
fix/1134-always-hidden-controls
Aug 6, 2026
Merged

SettingsProtectionHelper: support always-hidden controls#1522
imnasnainaec merged 16 commits into
masterfrom
fix/1134-always-hidden-controls

Conversation

@imnasnainaec

@imnasnainaec imnasnainaec commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add SetSettingsProtection(Control, bool, bool keepHidden) and SetSettingsProtection(ToolStripItem, bool, bool keepHidden) overloads so a control or ToolStripItem can be marked always-hidden, staying hidden even while Ctrl+Shift reveals the other protected components. The original 2-parameter overloads are preserved for WinForms designer extender-property discovery and binary compatibility.
  • Track always-hidden components in a separate _alwaysHiddenComponents set, which UpdateDisplay() hides unconditionally after the normal pass. GetSettingsProtection reports true for them too.
  • Apply always-hidden registration immediately at run time instead of leaving the component visible until the next (~100 ms) timer tick. Design time is deliberately excluded: the extender property setter runs there as well, where the timer is off and the component must stay visible on the design surface.
  • Apply the normal visibility rule immediately when a component leaves always-hidden, so the two directions are symmetric. The !NormallyHidden || Ctrl+Shift rule moved into a property shared with UpdateDisplay(), which had been recomputing it once per component.
  • Rework Dispose(bool) into the standard form used elsewhere in the repo — the missing-Dispose debug warning, an early return that makes it idempotent, managed cleanup only when disposing, and _isDisposed set after base.Dispose(disposing). That ordering matters: Component.Dispose removes itself from its container, which reads the Site property, and this class overrides Site to throw once disposed. The explicit _checkForCtrlKeyTimer.Dispose() is gone, since the timer is owned by the components container that disposes it.
  • Give both new overloads full XML documentation (summary plus a tag for every parameter).
  • Add SettingsProtectionHelperTests — 11 tests covering normal vs. always-hidden visibility, both transition directions and their immediacy, unprotecting, GetSettingsProtection, and disposing while still sited in a container.
  • Add CHANGELOG entries under Added and Fixed.

Scope note on #1134

keepHidden is a "never show this" primitive: an always-hidden component is not revealed by Ctrl+Shift, and it is not revealed by entering the settings password either — nothing records that the password was entered, and UpdateDisplay() re-hides these components on every tick.

#1134 asks for components that remain hidden unless the password is entered. A client can build that on top of this: mark the components keepHidden: true, then re-register them with keepHidden: false after a successful challenge. This PR does not add that behavior to the library itself.

Fixes #1134

Devin review: https://app.devin.ai/review/sillsdev/libpalaso/pull/1522


This change is Reviewable

…ontrols (#1134)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@imnasnainaec imnasnainaec changed the title SettingsProtectionHelper: support always-hidden controls (#1134) SettingsProtectionHelper: support always-hidden controls Jun 30, 2026
@imnasnainaec imnasnainaec self-assigned this Jun 30, 2026
@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Palaso Tests

     4 files  ± 0       4 suites  ±0   10m 27s ⏱️ ±0s
 5 119 tests +11   4 885 ✅ +10  234 💤 +1  0 ❌ ±0 
16 669 runs  +33  15 948 ✅ +32  721 💤 +1  0 ❌ ±0 

Results for commit 4fdbee4. ± Comparison against base commit e65a140.

This pull request skips 1 test.
SIL.Tests.IO.FileLocationUtilitiesTests ‑ LocateInProgramFiles_SendValidProgramDeepSearch_ReturnsProgramPath

♻️ This comment has been updated with latest results.

imnasnainaec and others added 5 commits June 30, 2026 15:47
- Restore CHANGELOG from base commit to fix double-encoded UTF-8
  (Chinese characters and curly apostrophe were corrupted by PowerShell
  Get-Content/Set-Content mishandling UTF-8-without-BOM)
- Re-apply keepHidden entry in the correct ### Added section
- Add XML doc to 3-param SetSettingsProtection overloads clarifying that
  keepHidden has no effect when isProtected is false

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Timer is owned by the components container, so components.Dispose()
already disposes it; the explicit _checkForCtrlKeyTimer.Dispose() call
was a no-op double-dispose.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The keepHidden feature entry didn't cover the separate Dispose(bool)
fix that moves managed-resource cleanup inside the disposing guard
and removes the redundant explicit timer disposal.
@imnasnainaec
imnasnainaec marked this pull request as ready for review July 8, 2026 21:37
@imnasnainaec
imnasnainaec requested a review from tombogle July 8, 2026 21:37
Comment thread SIL.Windows.Forms.Tests/SettingsProtection/SettingsProtectionHelperTests.cs Outdated
Comment thread SIL.Windows.Forms/SettingProtection/SettingsProtectionHelper.Designer.cs Outdated
imnasnainaec and others added 4 commits August 5, 2026 12:53
- Follow the standard Dispose(bool) form used elsewhere in the repo; set
  _isDisposed only after base.Dispose(disposing), since Component's base
  implementation removes itself from its container, which reads the Site
  property that this class overrides to throw once disposed
- Dispose test controls with using
- Initialize the tracking sets in field initializers so they are non-null
  before anything can observe them

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Hide an always-hidden component as soon as it is registered instead of
  leaving it visible until the next timer tick, but only at run time: the
  extender property setter also runs at design time, where the timer is
  off and the component must stay visible on the design surface
- Give the new SetSettingsProtection overloads a summary and tags for
  every parameter, and correct the reveal mechanism in the text (holding
  Ctrl+Shift, not the settings password)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@imnasnainaec
imnasnainaec marked this pull request as draft August 5, 2026 17:35
@imnasnainaec
imnasnainaec removed the request for review from tombogle August 5, 2026 17:35
imnasnainaec and others added 2 commits August 5, 2026 13:39
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Registering a component as always-hidden hides it at once, so the reverse
transition now applies the normal visibility rule at once too, rather than
leaving the component hidden until the next timer tick. Extracted the
visibility rule into a property shared with UpdateDisplay, which was
recomputing it once per component.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@imnasnainaec

This comment was marked as resolved.

imnasnainaec

This comment was marked as resolved.

@papeh papeh 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.

@papeh reviewed 1 file and made 1 comment.
Reviewable status: 1 of 4 files reviewed, 2 unresolved discussions (waiting on imnasnainaec).


SIL.Windows.Forms/SettingProtection/SettingsProtectionHelper.cs line 77 at r1 (raw file):

			foreach (var component in _componentsUnderSettingsProtection)
			{
				bool visible = !SettingsProtectionSingleton.Settings.NormallyHidden || ((Control.ModifierKeys & keys) == keys);

nice improvement!

@imnasnainaec
imnasnainaec marked this pull request as ready for review August 6, 2026 13:20

@imnasnainaec imnasnainaec left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@imnasnainaec reviewed all commit messages and made 1 comment.
Reviewable status: 0 of 4 files reviewed, 2 unresolved discussions (waiting on papeh).


SIL.Windows.Forms/SettingProtection/SettingsProtectionHelper.cs line 77 at r1 (raw file):

Previously, papeh wrote…

nice improvement!

Thanks!

@imnasnainaec
imnasnainaec requested a review from papeh August 6, 2026 13:22
@imnasnainaec
imnasnainaec merged commit a8bc5a7 into master Aug 6, 2026
14 of 16 checks passed
@imnasnainaec
imnasnainaec deleted the fix/1134-always-hidden-controls branch August 6, 2026 14:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

When Settings protections is turned on with password protection, need a way to keep protected controls hidden

2 participants