Skip to content

Commit

Permalink
prevent scrollviewer from stealing keyboard focus
Browse files Browse the repository at this point in the history
  • Loading branch information
doubleyewdee committed Nov 27, 2018
1 parent 4a5bf59 commit 72c04ae
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 39 deletions.
27 changes: 11 additions & 16 deletions src/ConsoleBuffer/Buffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -401,34 +401,29 @@ private void HandleSGR(Commands.SetGraphicsRendition sgr)

if (sgr.HaveBasicForeground)
{
newTemplate.Options &= ~Character.ForegroundExtendedFlag;
newTemplate.Options |= Character.ForegroundBasicColorFlag;
newTemplate.Options &= ~Character.ForegroundColorMask;
newTemplate.Options |= Character.GetColorFlags(sgr.BasicForegroundColor, false);
newTemplate.Options &= ~(Character.ForegroundExtendedFlag | Character.ForegroundColorMask);
newTemplate.Options |= (short)(Character.ForegroundBasicColorFlag | Character.GetColorFlags(sgr.BasicForegroundColor, false));
}
else if (sgr.HaveForeground)
else if (sgr.HaveForeground || sgr.HaveXtermForeground)
{
newTemplate.Options &= ~Character.ForegroundBasicColorFlag;
newTemplate.Options &= ~Character.ForegroundColorMask;
newTemplate.Options &= ~(Character.ForegroundBasicColorFlag | Character.ForegroundColorMask);
newTemplate.Options |= Character.ForegroundExtendedFlag;
newTemplate.Foreground = sgr.ForegroundColor;
newTemplate.Foreground = (sgr.HaveXtermForeground ? this.Palette[sgr.XtermForegroundColor] : sgr.ForegroundColor);
}

if (sgr.HaveBasicBackground)
{
newTemplate.Options &= ~Character.BackgroundExtendedFlag;
newTemplate.Options |= Character.BackgroundBasicColorFlag;
newTemplate.Options &= ~Character.BackgroundColorMask;
newTemplate.Options |= Character.GetColorFlags(sgr.BasicBackgroundColor, true);
newTemplate.Options &= ~(Character.BackgroundExtendedFlag | Character.BackgroundColorMask);
newTemplate.Options |= (short)(Character.BackgroundBasicColorFlag | Character.GetColorFlags(sgr.BasicBackgroundColor, true));
}
else if (sgr.HaveBackground)
else if (sgr.HaveBackground || sgr.HaveXtermBackground)
{
newTemplate.Options &= ~Character.BackgroundBasicColorFlag;
newTemplate.Options &= ~Character.BackgroundColorMask;
newTemplate.Options &= ~(Character.BackgroundBasicColorFlag | Character.BackgroundColorMask);
newTemplate.Options |= Character.BackgroundExtendedFlag;
newTemplate.Background = sgr.BackgroundColor;
newTemplate.Background = (sgr.HaveXtermBackground ? this.Palette[sgr.XtermBackgroundColor] : sgr.BackgroundColor);
}

// we need to set these down here because they are impacted by the 'bright' bit.
if (newTemplate.HasBasicForegroundColor) newTemplate.Foreground = this.GetColorInfoFromBasicColor(newTemplate.BasicForegroundColor, newTemplate.ForegroundBright);
if (newTemplate.HasBasicBackgroundColor) newTemplate.Background = this.GetColorInfoFromBasicColor(newTemplate.BasicBackgroundColor, newTemplate.BackgroundBright);

Expand Down
65 changes: 47 additions & 18 deletions src/ConsoleBuffer/Commands/SetGraphicsRendition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,6 @@ public enum Colors : short

public SetGraphicsRendition(string bufferData) : base(bufferData)
{
#if DEBUG
// XXX: remove later.
Trace.WriteLine($"SGR: ^[[{bufferData}m");
#endif

this.ForegroundBright = FlagValue.None;
this.BackgroundBright = FlagValue.None;
this.Underline = FlagValue.None;
Expand Down Expand Up @@ -104,12 +99,22 @@ public SetGraphicsRendition(string bufferData) : base(bufferData)
break;
case 38:
{
if (this.ReadXtermColorIndex(p, out var idx))
if (this.ReadXtermColorInfo(ref p, out var idx, out var color))
{
this.HaveXtermForeground = true;
this.XtermForegroundColor = idx;
if (idx > -1)
{
this.HaveXtermForeground = true;
this.XtermForegroundColor = idx;
}
else
{
this.HaveForeground = true;
this.ForegroundColor = color;
}
break;
}
break;
this.Reset();
return;
}
case 39:
this.HaveBasicForeground = true;
Expand All @@ -128,12 +133,22 @@ public SetGraphicsRendition(string bufferData) : base(bufferData)
break;
case 48:
{
if (this.ReadXtermColorIndex(p, out var idx))
if (this.ReadXtermColorInfo(ref p, out var idx, out var color))
{
this.HaveXtermBackground = true;
this.XtermBackgroundColor = idx;
if (idx > -1)
{
this.HaveXtermBackground = true;
this.XtermBackgroundColor = idx;
}
else
{
this.HaveBackground = true;
this.BackgroundColor = color;
}
break;
}
break;
this.Reset();
return;
}
case 49:
this.HaveBasicBackground = true;
Expand Down Expand Up @@ -169,19 +184,33 @@ public SetGraphicsRendition(string bufferData) : base(bufferData)
}
}

private bool ReadXtermColorIndex(int p, out int value)
private bool ReadXtermColorInfo(ref int p, out int value, out Character.ColorInfo color)
{
value = -1;
color = new Character.ColorInfo();
if (++p < this.Parameters.Count)
{
var subCommand = this.ParameterToNumber(p, defaultValue: -1);
if (subCommand == 5)
if (subCommand == 2)
{
if (++p < this.Parameters.Count)
var colorValues = new int[3];
for (var i = 0; i < colorValues.Length; ++i) // prime candidate for funrolling of loops
{
value = this.ParameterToNumber(p, defaultValue: -1, maxValue: int.MaxValue);
return value > -1 && value < 256;
++p;
colorValues[i] = this.ParameterToNumber(p, defaultValue: -1, maxValue: int.MaxValue);
if (colorValues[i] < 0 || colorValues[i] > 255)
{
return false;
}
}
color = new Character.ColorInfo { R = (byte)colorValues[0], G = (byte)colorValues[1], B = (byte)colorValues[2] };
return true;
}
else if (subCommand == 5)
{
++p;
value = this.ParameterToNumber(p, defaultValue: -1, maxValue: int.MaxValue);
return value > -1 && value < 256;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/condo/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
mc:Ignorable="d"
Title="MainWindow" SizeToContent="WidthAndHeight">
<Grid Background="Black">
<ScrollViewer Name="scrollViewer" CanContentScroll="true" IsDeferredScrollingEnabled="true">
<ScrollViewer Name="scrollViewer" CanContentScroll="true" IsDeferredScrollingEnabled="true" Focusable="False">
<local:Screen x:Name="screen" />
</ScrollViewer>
</Grid>
Expand Down
30 changes: 28 additions & 2 deletions test/ConsoleBufferTests/BufferTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ public void BrightForegroundText()
}

[TestMethod]
public void BasicColorTest()
public void BasicColor()
{
var surface = new RenderTest();

var buffer = new ConsoleBuffer.Buffer(DefaultColumns, DefaultRows);

for (var fg = 0; fg < 16; ++fg)
{
for (var bg = 0; bg < 16; ++bg)
Expand All @@ -108,5 +108,31 @@ public void BasicColorTest()
}
}
}

[TestMethod]
public void XtermColorIndex()
{
var surface = new RenderTest();
var buffer = new ConsoleBuffer.Buffer(DefaultColumns, DefaultRows);

for (var i = 0;i < 256; ++i)
{
buffer.AppendString($"\x1b[2J\x1b[H\x1b[38;5;{i}mc");
surface.OnChar = (c, x, y) =>
{
if (c.Glyph != 'c') return;
Assert.AreEqual(buffer.Palette[i], c.Foreground);
};
buffer.Render(surface);

buffer.AppendString($"\x1b[2J\x1b[H\x1b[48;5;{i}mc");
surface.OnChar = (c, x, y) =>
{
if (c.Glyph != 'c') return;
Assert.AreEqual(buffer.Palette[i], c.Background);
};
buffer.Render(surface);
}
}
}
}
58 changes: 56 additions & 2 deletions test/ConsoleBufferTests/SequenceParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -319,14 +319,17 @@ public void SGRBasicBackgroundColors(string data, ConsoleBuffer.Commands.SetGrap
[DataRow("38;5;0", true, 0)]
[DataRow("38;5;255", true, 255)]
[DataRow("38;5;256", false, 0)]
public void SGRXtermForeground(string data, bool haveXtermColor, int expectedValue)
public void SGRXtermForegroundIndex(string data, bool haveXtermColor, int expectedValue)
{
var parser = this.EnsureCommandParses($"\x1b[{data}m");
var cmd = parser.Command as ConsoleBuffer.Commands.SetGraphicsRendition;
Assert.IsNotNull(cmd);
Assert.AreEqual(haveXtermColor, cmd.HaveXtermForeground);
if (haveXtermColor)
{
Assert.IsFalse(cmd.HaveBasicForeground);
Assert.IsFalse(cmd.HaveForeground);
Assert.IsTrue(cmd.HaveXtermForeground);
Assert.AreEqual(expectedValue, cmd.XtermForegroundColor);
}
}
Expand All @@ -338,18 +341,69 @@ public void SGRXtermForeground(string data, bool haveXtermColor, int expectedVal
[DataRow("48;5;0", true, 0)]
[DataRow("48;5;255", true, 255)]
[DataRow("48;5;256", false, 0)]
public void SGRXtermBackground(string data, bool haveXtermColor, int expectedValue)
public void SGRXtermBackgroundIndex(string data, bool haveXtermColor, int expectedValue)
{
var parser = this.EnsureCommandParses($"\x1b[{data}m");
var cmd = parser.Command as ConsoleBuffer.Commands.SetGraphicsRendition;
Assert.IsNotNull(cmd);
Assert.AreEqual(haveXtermColor, cmd.HaveXtermBackground);
if (haveXtermColor)
{
Assert.IsFalse(cmd.HaveBasicBackground);
Assert.IsFalse(cmd.HaveBackground);
Assert.IsTrue(cmd.HaveXtermBackground);
Assert.AreEqual(expectedValue, cmd.XtermBackgroundColor);
}
}

[TestMethod]
[DataRow("38;2", false, 0, 0, 0)]
[DataRow("38;2;", false, 0, 0, 0)]
[DataRow("38;2;1", false, 0, 0, 0)]
[DataRow("38;2;1;2", false, 0, 0, 0)]
[DataRow("38;2;1;2;", false, 0, 0, 0)]
[DataRow("38;2;1;2;3", true, 1, 2, 3)]
[DataRow("38;2;0;0;0", true, 0, 0, 0)]
[DataRow("38;2;255;255;255", true, 255, 255, 255)]
public void SGRXtermForegroundRGB(string data, bool haveColor, int r, int g, int b)
{
var parser = this.EnsureCommandParses($"\x1b[{data}m");
var cmd = parser.Command as ConsoleBuffer.Commands.SetGraphicsRendition;
Assert.IsNotNull(cmd);
Assert.AreEqual(haveColor, cmd.HaveForeground);
if (haveColor)
{
Assert.IsFalse(cmd.HaveBasicForeground);
Assert.IsFalse(cmd.HaveXtermForeground);
Assert.IsTrue(cmd.HaveForeground);
Assert.AreEqual(new Character.ColorInfo { R = (byte)r, G = (byte)g, B = (byte)b }, cmd.ForegroundColor);
}
}

[TestMethod]
[DataRow("48;2", false, 0, 0, 0)]
[DataRow("48;2;", false, 0, 0, 0)]
[DataRow("48;2;1", false, 0, 0, 0)]
[DataRow("48;2;1;2", false, 0, 0, 0)]
[DataRow("48;2;1;2;", false, 0, 0, 0)]
[DataRow("48;2;1;2;3", true, 1, 2, 3)]
[DataRow("48;2;0;0;0", true, 0, 0, 0)]
[DataRow("48;2;255;255;255", true, 255, 255, 255)]
public void SGRXtermBackgroundRGB(string data, bool haveColor, int r, int g, int b)
{
var parser = this.EnsureCommandParses($"\x1b[{data}m");
var cmd = parser.Command as ConsoleBuffer.Commands.SetGraphicsRendition;
Assert.IsNotNull(cmd);
Assert.AreEqual(haveColor, cmd.HaveBackground);
if (haveColor)
{
Assert.IsFalse(cmd.HaveBasicBackground);
Assert.IsFalse(cmd.HaveXtermBackground);
Assert.IsTrue(cmd.HaveBackground);
Assert.AreEqual(new Character.ColorInfo { R = (byte)r, G = (byte)g, B = (byte)b }, cmd.BackgroundColor);
}
}

private SequenceParser EnsureCommandParses(string command)
{
var parser = new SequenceParser();
Expand Down

0 comments on commit 72c04ae

Please sign in to comment.