Skip to content

Commit

Permalink
Merge pull request #6804 from Youssef1313/skia-textbox
Browse files Browse the repository at this point in the history
Correctly check if the TextBox is PasswordBox before obscuring text
  • Loading branch information
davidjohnoliver authored Aug 20, 2021
2 parents bd0f948 + 4e02fba commit 7e5f868
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ public void StartEntry()
}

_contentElement = textBox.ContentElement;

EnsureWidgetForAcceptsReturn(textBox.AcceptsReturn, isPassword: textBox is PasswordBox);
EnsureWidget(textBox);
var textInputLayer = GetWindowTextInputLayer();
textInputLayer.Put(_currentInputWidget!, 0, 0);

Expand Down Expand Up @@ -108,7 +107,7 @@ public void UpdateNativeView()
return;
}

EnsureWidgetForAcceptsReturn(textBox.AcceptsReturn, isPassword: textBox is PasswordBox);
EnsureWidget(textBox);

var fontDescription = new FontDescription
{
Expand Down Expand Up @@ -173,25 +172,33 @@ private void UpdateEntryProperties(Entry entry, TextBox textBox)
entry.MaxLength = textBox.MaxLength;
}

private void EnsureWidgetForAcceptsReturn(bool acceptsReturn, bool isPassword)
private void EnsureWidget(TextBox textBox)
{
var isPassword = false;
var isPasswordVisible = true;
if (textBox is PasswordBox passwordBox)
{
isPassword = true;
isPasswordVisible = passwordBox.PasswordRevealMode == PasswordRevealMode.Visible;
}

// On UWP, A PasswordBox doesn't have AcceptsReturn property.
// The property exists on Uno because PasswordBox incorrectly inherits TextBox.
// If we have PasswordBox, ignore AcceptsReturnValue and always use Gtk.Entry
acceptsReturn = acceptsReturn && !isPassword;
var acceptsReturn = textBox.AcceptsReturn && !isPassword;

var isIncompatibleInputType =
(acceptsReturn && !(_currentInputWidget is TextView)) ||
(!acceptsReturn && !(_currentInputWidget is Entry));
if (isIncompatibleInputType)
{
var inputText = GetInputText();
_currentInputWidget = CreateInputWidget(acceptsReturn, isPassword);
_currentInputWidget = CreateInputWidget(acceptsReturn, isPassword, isPasswordVisible);
SetWidgetText(inputText ?? string.Empty);
}
}

private Widget CreateInputWidget(bool acceptsReturn, bool isPassword)
private Widget CreateInputWidget(bool acceptsReturn, bool isPassword, bool isPasswordVisible)
{
Debug.Assert(!acceptsReturn || !isPassword);
Widget widget;
Expand All @@ -208,7 +215,7 @@ private Widget CreateInputWidget(bool acceptsReturn, bool isPassword)
if (isPassword)
{
entry.InputPurpose = InputPurpose.Password;
entry.Visibility = false;
entry.Visibility = isPasswordVisible;
}

entry.Changed += WidgetTextChanged;
Expand Down
22 changes: 20 additions & 2 deletions src/Uno.UI/UI/Xaml/Controls/TextBox/TextBoxView.skia.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ internal class TextBoxView
private readonly ITextBoxViewExtension _textBoxExtension;

private readonly WeakReference<TextBox> _textBox;
private readonly bool _isPasswordBox;
private bool _isPasswordRevealed;

public TextBoxView(TextBox textBox)
{
_textBox = new WeakReference<TextBox>(textBox);
_isPasswordBox = textBox is PasswordBox;
if (!ApiExtensibility.CreateInstance(this, out _textBoxExtension))
{
if (this.Log().IsEnabled(LogLevel.Warning))
Expand Down Expand Up @@ -45,7 +48,18 @@ public TextBox? TextBox

internal void SetTextNative(string text)
{
DisplayBlock.Text = new string('•', text.Length);
// TODO: Inheritance hierarchy is wrong in Uno. PasswordBox shouldn't inherit TextBox.
// This needs to be moved to PasswordBox when it's separated from TextBox (likely in Uno 4).
if (_isPasswordBox && !_isPasswordRevealed)
{
// TODO: PasswordChar isn't currently implemented. It should be used here when implemented.
DisplayBlock.Text = new string('•', text.Length);
}
else
{
DisplayBlock.Text = text;
}

_textBoxExtension?.SetTextNative(text);
}

Expand All @@ -65,7 +79,11 @@ internal void OnFocusStateChanged(FocusState focusState)
}
}

internal void SetIsPassword(bool isPassword) => _textBoxExtension?.SetIsPassword(isPassword);
internal void SetIsPassword(bool isPassword)
{
_isPasswordRevealed = !isPassword;
_textBoxExtension?.SetIsPassword(isPassword);
}

internal void UpdateTextFromNative(string newText)
{
Expand Down

0 comments on commit 7e5f868

Please sign in to comment.