Skip to content

Commit

Permalink
SEBWIN-536, #349: Fixed keyboard system component to correctly displa…
Browse files Browse the repository at this point in the history
…y all installed keyboard layouts / input languages.
  • Loading branch information
dbuechel committed Apr 26, 2022
1 parent 05430f6 commit a4d1904
Show file tree
Hide file tree
Showing 15 changed files with 101 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ public interface IKeyboardLayout
/// </summary>
string CultureCode { get; }

/// <summary>
/// The culture name of this keyboard layout.
/// </summary>
string CultureName { get; }

/// <summary>
/// The unique identifier of the keyboard layout.
/// </summary>
Expand All @@ -33,6 +38,6 @@ public interface IKeyboardLayout
/// <summary>
/// The name of this keyboard layout.
/// </summary>
string Name { get; }
string LayoutName { get; }
}
}
61 changes: 33 additions & 28 deletions SafeExamBrowser.SystemComponents/Keyboard/Keyboard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Input;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
Expand All @@ -19,9 +20,10 @@ namespace SafeExamBrowser.SystemComponents.Keyboard
{
public class Keyboard : IKeyboard
{
private IList<KeyboardLayout> layouts;
private ILogger logger;
private CultureInfo originalLanguage;
private readonly IList<KeyboardLayout> layouts;
private readonly ILogger logger;

private InputLanguage originalLanguage;

public event LayoutChangedEventHandler LayoutChanged;

Expand All @@ -33,68 +35,71 @@ public Keyboard(ILogger logger)

public void ActivateLayout(Guid layoutId)
{
var layout = layouts.FirstOrDefault(l => l.Id == layoutId);
var layout = layouts.First(l => l.Id == layoutId);

if (layout != default(KeyboardLayout))
{
logger.Info($"Changing keyboard layout to {ToString(layout.CultureInfo)}.");
InputLanguageManager.Current.CurrentInputLanguage = layout.CultureInfo;
}
else
{
logger.Error($"Could not find keyboard layout with id '{layoutId}'!");
}
logger.Info($"Changing keyboard layout to {layout}...");
InputLanguage.CurrentInputLanguage = layout.InputLanguage;

layout.IsCurrent = true;
LayoutChanged?.Invoke(layout);
}

public void Initialize()
{
originalLanguage = InputLanguageManager.Current.CurrentInputLanguage;
originalLanguage = InputLanguage.CurrentInputLanguage;
logger.Info($"Saved current keyboard layout {ToString(originalLanguage)}.");

foreach (CultureInfo info in InputLanguageManager.Current.AvailableInputLanguages)
foreach (InputLanguage language in InputLanguage.InstalledInputLanguages)
{
var layout = new KeyboardLayout
{
CultureCode = info.ThreeLetterISOLanguageName.ToUpper(),
CultureInfo = info,
IsCurrent = originalLanguage.Equals(info),
Name = info.NativeName
CultureCode = language.Culture.ThreeLetterISOLanguageName.ToUpper(),
CultureName = language.Culture.NativeName,
InputLanguage = language,
IsCurrent = originalLanguage.Equals(language),
LayoutName = language.LayoutName
};

layouts.Add(layout);
logger.Info($"Detected keyboard layout {ToString(info)}.");
logger.Info($"Detected keyboard layout {layout}.");
}

InputLanguageManager.Current.InputLanguageChanged += Current_InputLanguageChanged;
InputLanguageManager.Current.InputLanguageChanged += InputLanguageManager_InputLanguageChanged;
}

public IEnumerable<IKeyboardLayout> GetLayouts()
{
return layouts;
return new List<KeyboardLayout>(layouts.OrderBy(l => l.CultureName));
}

public void Terminate()
{
InputLanguageManager.Current.InputLanguageChanged -= Current_InputLanguageChanged;
InputLanguageManager.Current.InputLanguageChanged -= InputLanguageManager_InputLanguageChanged;

if (originalLanguage != null)
{
InputLanguageManager.Current.CurrentInputLanguage = originalLanguage;
InputLanguage.CurrentInputLanguage = originalLanguage;
logger.Info($"Restored original keyboard layout {ToString(originalLanguage)}.");
}
}

private void Current_InputLanguageChanged(object sender, InputLanguageEventArgs e)
private void InputLanguageManager_InputLanguageChanged(object sender, InputLanguageEventArgs e)
{
var layout = layouts.First(l => l.CultureInfo.Equals(e.NewLanguage));
var layout = layouts.First(l => l.InputLanguage.Culture.Equals(e.NewLanguage));

logger.Info($"Detected keyboard layout change from {ToString(e.PreviousLanguage)} to {ToString(e.NewLanguage)}.");
layout.IsCurrent = true;
LayoutChanged?.Invoke(layout);
}

private string ToString(CultureInfo info)
private string ToString(InputLanguage language)
{
return $"'{language.Culture.NativeName}' [{language.Culture.ThreeLetterISOLanguageName.ToUpper()}, {language.LayoutName}]";
}

private string ToString(CultureInfo culture)
{
return $"'{info.DisplayName}' ({info.ThreeLetterISOLanguageName.ToUpper()})";
return $"'{culture.NativeName}' [{culture.ThreeLetterISOLanguageName.ToUpper()}]";
}
}
}
12 changes: 9 additions & 3 deletions SafeExamBrowser.SystemComponents/Keyboard/KeyboardLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,29 @@
*/

using System;
using System.Globalization;
using System.Windows.Forms;
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;

namespace SafeExamBrowser.SystemComponents.Keyboard
{
internal class KeyboardLayout : IKeyboardLayout
{
internal CultureInfo CultureInfo { get; set; }
internal InputLanguage InputLanguage { get; set; }

public string CultureCode { get; set; }
public string CultureName { get; set; }
public Guid Id { get; }
public bool IsCurrent { get; set; }
public string Name { get; set; }
public string LayoutName { get; set; }

public KeyboardLayout()
{
Id = Guid.NewGuid();
}

public override string ToString()
{
return $"'{CultureName}' [{CultureCode}, {LayoutName}]";
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenter.KeyboardLayoutButton" x:ClassModifier="internal"
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenter.KeyboardLayoutButton" x:ClassModifier="internal"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:fa="http://schemas.fontawesome.io/icons/"
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Desktop.Controls"
mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="250">
<UserControl.Resources>
Expand All @@ -23,7 +24,13 @@
</Grid.ColumnDefinitions>
<TextBlock x:Name="IsCurrentTextBlock" Grid.Column="0" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Hidden">•</TextBlock>
<TextBlock x:Name="CultureCodeTextBlock" Grid.Column="1" FontWeight="Bold" HorizontalAlignment="Left" Margin="10,0,5,0" VerticalAlignment="Center" />
<TextBlock x:Name="LayoutNameTextBlock" Grid.Column="2" Foreground="White" HorizontalAlignment="Left" Margin="5,0,10,0" VerticalAlignment="Center" />
<StackPanel Grid.Column="2" VerticalAlignment="Center">
<TextBlock x:Name="CultureNameTextBlock" Foreground="White" HorizontalAlignment="Left" Margin="5,0,10,0" TextDecorations="Underline" VerticalAlignment="Center" />
<StackPanel Orientation="Horizontal">
<fa:ImageAwesome Foreground="LightGray" Height="10" Icon="KeyboardOutline" Margin="5,0" />
<TextBlock x:Name="LayoutNameTextBlock" Foreground="LightGray" HorizontalAlignment="Left" Margin="0,0,10,0" VerticalAlignment="Center" />
</StackPanel>
</StackPanel>
</Grid>
</Button>
</Grid>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenter
{
internal partial class KeyboardLayoutButton : UserControl
{
private IKeyboardLayout layout;
private readonly IKeyboardLayout layout;

internal bool IsCurrent
{
Expand All @@ -41,7 +41,8 @@ private void InitializeLayoutButton()
{
Button.Click += (o, args) => LayoutSelected?.Invoke(this, EventArgs.Empty);
CultureCodeTextBlock.Text = layout.CultureCode;
LayoutNameTextBlock.Text = layout.Name;
CultureNameTextBlock.Text = layout.CultureName;
LayoutNameTextBlock.Text = layout.LayoutName;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ private void ActivateLayout(IKeyboardLayout layout)

private void SetCurrent(IKeyboardLayout layout)
{
var tooltip = text.Get(TextKey.SystemControl_KeyboardLayoutTooltip).Replace("%%LAYOUT%%", layout.Name);
var tooltip = text.Get(TextKey.SystemControl_KeyboardLayoutTooltip).Replace("%%LAYOUT%%", layout.CultureName);

foreach (var child in LayoutsStackPanel.Children)
{
Expand All @@ -87,7 +87,7 @@ private void SetCurrent(IKeyboardLayout layout)
}
}

Text.Text = layout.Name;
Text.Text = layout.CultureName;
Button.ToolTip = tooltip;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:fa="http://schemas.fontawesome.io/icons/"
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Desktop.Controls"
mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="250">
<UserControl.Resources>
Expand All @@ -23,7 +24,13 @@
</Grid.ColumnDefinitions>
<TextBlock x:Name="IsCurrentTextBlock" Grid.Column="0" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Hidden">•</TextBlock>
<TextBlock x:Name="CultureCodeTextBlock" Grid.Column="1" FontWeight="Bold" HorizontalAlignment="Left" Margin="10,0,5,0" VerticalAlignment="Center" />
<TextBlock x:Name="LayoutNameTextBlock" Grid.Column="2" Foreground="Gray" HorizontalAlignment="Left" Margin="5,0,10,0" VerticalAlignment="Center" />
<StackPanel Grid.Column="2" VerticalAlignment="Center">
<TextBlock x:Name="CultureNameTextBlock" HorizontalAlignment="Left" Margin="5,0,10,0" TextDecorations="Underline" VerticalAlignment="Center" />
<StackPanel Orientation="Horizontal">
<fa:ImageAwesome Foreground="Gray" Height="10" Icon="KeyboardOutline" Margin="5,0" />
<TextBlock x:Name="LayoutNameTextBlock" Foreground="Gray" HorizontalAlignment="Left" Margin="0,0,10,0" VerticalAlignment="Center" />
</StackPanel>
</StackPanel>
</Grid>
</Button>
</Grid>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar
{
internal partial class KeyboardLayoutButton : UserControl
{
private IKeyboardLayout layout;
private readonly IKeyboardLayout layout;

internal bool IsCurrent
{
Expand All @@ -41,7 +41,8 @@ private void InitializeLayoutButton()
{
Button.Click += (o, args) => LayoutSelected?.Invoke(this, EventArgs.Empty);
CultureCodeTextBlock.Text = layout.CultureCode;
LayoutNameTextBlock.Text = layout.Name;
CultureNameTextBlock.Text = layout.CultureName;
LayoutNameTextBlock.Text = layout.LayoutName;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ private void ActivateLayout(IKeyboardLayout layout)

private void SetCurrent(IKeyboardLayout layout)
{
var name = layout.Name?.Length > 3 ? String.Join(string.Empty, layout.Name.Split(' ').Where(s => Char.IsLetter(s.First())).Select(s => s.First())) : layout.Name;
var tooltip = text.Get(TextKey.SystemControl_KeyboardLayoutTooltip).Replace("%%LAYOUT%%", layout.Name);
var name = layout.CultureName?.Length > 3 ? String.Join(string.Empty, layout.CultureName.Split(' ').Where(s => Char.IsLetter(s.First())).Select(s => s.First())) : layout.CultureName;
var tooltip = text.Get(TextKey.SystemControl_KeyboardLayoutTooltip).Replace("%%LAYOUT%%", layout.CultureName);

foreach (var child in LayoutsStackPanel.Children)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:fa="http://schemas.fontawesome.io/icons/"
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Mobile.Controls"
mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="250">
<UserControl.Resources>
Expand All @@ -23,7 +24,13 @@
</Grid.ColumnDefinitions>
<TextBlock x:Name="IsCurrentTextBlock" Grid.Column="0" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Hidden">•</TextBlock>
<TextBlock x:Name="CultureCodeTextBlock" Grid.Column="1" FontWeight="Bold" HorizontalAlignment="Left" Margin="10,0,5,0" VerticalAlignment="Center" />
<TextBlock x:Name="LayoutNameTextBlock" Grid.Column="2" Foreground="White" HorizontalAlignment="Left" Margin="5,0,10,0" VerticalAlignment="Center" />
<StackPanel Grid.Column="2" VerticalAlignment="Center">
<TextBlock x:Name="CultureNameTextBlock" Foreground="White" HorizontalAlignment="Left" Margin="5,0,10,0" TextDecorations="Underline" VerticalAlignment="Center" />
<StackPanel Orientation="Horizontal">
<fa:ImageAwesome Foreground="LightGray" Height="10" Icon="KeyboardOutline" Margin="5,0" />
<TextBlock x:Name="LayoutNameTextBlock" Foreground="LightGray" HorizontalAlignment="Left" Margin="0,0,10,0" VerticalAlignment="Center" />
</StackPanel>
</StackPanel>
</Grid>
</Button>
</Grid>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.ActionCenter
{
internal partial class KeyboardLayoutButton : UserControl
{
private IKeyboardLayout layout;
private readonly IKeyboardLayout layout;

internal bool IsCurrent
{
Expand All @@ -41,7 +41,8 @@ private void InitializeLayoutButton()
{
Button.Click += (o, args) => LayoutSelected?.Invoke(this, EventArgs.Empty);
CultureCodeTextBlock.Text = layout.CultureCode;
LayoutNameTextBlock.Text = layout.Name;
CultureNameTextBlock.Text = layout.CultureName;
LayoutNameTextBlock.Text = layout.LayoutName;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ private void ActivateLayout(IKeyboardLayout layout)

private void SetCurrent(IKeyboardLayout layout)
{
var tooltip = text.Get(TextKey.SystemControl_KeyboardLayoutTooltip).Replace("%%LAYOUT%%", layout.Name);
var tooltip = text.Get(TextKey.SystemControl_KeyboardLayoutTooltip).Replace("%%LAYOUT%%", layout.CultureName);

foreach (var child in LayoutsStackPanel.Children)
{
Expand All @@ -87,7 +87,7 @@ private void SetCurrent(IKeyboardLayout layout)
}
}

Text.Text = layout.Name;
Text.Text = layout.CultureName;
Button.ToolTip = tooltip;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:fa="http://schemas.fontawesome.io/icons/"
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Mobile.Controls"
mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="250">
<UserControl.Resources>
Expand All @@ -23,7 +24,13 @@
</Grid.ColumnDefinitions>
<TextBlock x:Name="IsCurrentTextBlock" Grid.Column="0" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Hidden">•</TextBlock>
<TextBlock x:Name="CultureCodeTextBlock" Grid.Column="1" FontWeight="Bold" HorizontalAlignment="Left" Margin="10,0,5,0" VerticalAlignment="Center" />
<TextBlock x:Name="LayoutNameTextBlock" Grid.Column="2" Foreground="Gray" HorizontalAlignment="Left" Margin="5,0,10,0" VerticalAlignment="Center" />
<StackPanel Grid.Column="2" VerticalAlignment="Center">
<TextBlock x:Name="CultureNameTextBlock" HorizontalAlignment="Left" Margin="5,0,10,0" TextDecorations="Underline" VerticalAlignment="Center" />
<StackPanel Orientation="Horizontal">
<fa:ImageAwesome Foreground="Gray" Height="10" Icon="KeyboardOutline" Margin="5,0" />
<TextBlock x:Name="LayoutNameTextBlock" Foreground="Gray" HorizontalAlignment="Left" Margin="0,0,10,0" VerticalAlignment="Center" />
</StackPanel>
</StackPanel>
</Grid>
</Button>
</Grid>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
{
internal partial class KeyboardLayoutButton : UserControl
{
private IKeyboardLayout layout;
private readonly IKeyboardLayout layout;

internal bool IsCurrent
{
Expand All @@ -41,7 +41,8 @@ private void InitializeLayoutButton()
{
Button.Click += (o, args) => LayoutSelected?.Invoke(this, EventArgs.Empty);
CultureCodeTextBlock.Text = layout.CultureCode;
LayoutNameTextBlock.Text = layout.Name;
CultureNameTextBlock.Text = layout.CultureName;
LayoutNameTextBlock.Text = layout.LayoutName;
}
}
}
Loading

0 comments on commit a4d1904

Please sign in to comment.