mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Fixed Windows input provider, Vulkan and logging
This commit is contained in:
parent
4518691907
commit
02e85af4af
@ -20,7 +20,7 @@ public static class UIContainerExtensions
|
|||||||
public static void RegisterProviders(this IContainer container)
|
public static void RegisterProviders(this IContainer container)
|
||||||
{
|
{
|
||||||
container.Register<ICursorProvider, CursorProvider>(Reuse.Singleton);
|
container.Register<ICursorProvider, CursorProvider>(Reuse.Singleton);
|
||||||
// container.Register<IGraphicsContextProvider, GraphicsContextProvider>(Reuse.Singleton);
|
container.Register<IGraphicsContextProvider, GraphicsContextProvider>(Reuse.Singleton);
|
||||||
container.Register<IAutoRunProvider, AutoRunProvider>();
|
container.Register<IAutoRunProvider, AutoRunProvider>();
|
||||||
container.Register<InputProvider, WindowsInputProvider>(serviceKey: WindowsInputProvider.Id);
|
container.Register<InputProvider, WindowsInputProvider>(serviceKey: WindowsInputProvider.Id);
|
||||||
container.Register<IUpdateNotificationProvider, WindowsUpdateNotificationProvider>();
|
container.Register<IUpdateNotificationProvider, WindowsUpdateNotificationProvider>();
|
||||||
|
|||||||
@ -5,7 +5,7 @@ using System.Timers;
|
|||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
using Artemis.UI.Windows.Utilities;
|
using Artemis.UI.Windows.Utilities;
|
||||||
using Avalonia.Controls.ApplicationLifetimes;
|
using Avalonia.Controls.Platform;
|
||||||
using Avalonia.Platform;
|
using Avalonia.Platform;
|
||||||
using Linearstar.Windows.RawInput;
|
using Linearstar.Windows.RawInput;
|
||||||
using Linearstar.Windows.RawInput.Native;
|
using Linearstar.Windows.RawInput.Native;
|
||||||
@ -15,35 +15,43 @@ namespace Artemis.UI.Windows.Providers.Input;
|
|||||||
|
|
||||||
public class WindowsInputProvider : InputProvider
|
public class WindowsInputProvider : InputProvider
|
||||||
{
|
{
|
||||||
|
private const int GWL_WNDPROC = -4;
|
||||||
private const int WM_INPUT = 0x00FF;
|
private const int WM_INPUT = 0x00FF;
|
||||||
|
|
||||||
|
private readonly IWindowImpl _window;
|
||||||
|
private readonly nint _hWndProcHook;
|
||||||
|
private readonly WndProc? _fnWndProcHook;
|
||||||
private readonly IInputService _inputService;
|
private readonly IInputService _inputService;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly Timer _taskManagerTimer;
|
private readonly Timer _taskManagerTimer;
|
||||||
|
|
||||||
private int _lastProcessId;
|
private int _lastProcessId;
|
||||||
|
delegate nint WndProc(nint hWnd, uint msg, nint wParam, nint lParam);
|
||||||
|
|
||||||
|
private nint CustomWndProc(nint hWnd, uint msg, nint wParam, nint lParam)
|
||||||
|
{
|
||||||
|
OnWndProcCalled(hWnd, msg, wParam, lParam);
|
||||||
|
return CallWindowProc(_hWndProcHook, hWnd, msg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
public WindowsInputProvider(ILogger logger, IInputService inputService)
|
public WindowsInputProvider(ILogger logger, IInputService inputService)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_inputService = inputService;
|
_inputService = inputService;
|
||||||
|
|
||||||
_taskManagerTimer = new Timer(500);
|
_taskManagerTimer = new Timer(500);
|
||||||
_taskManagerTimer.Elapsed += TaskManagerTimerOnElapsed;
|
_taskManagerTimer.Elapsed += TaskManagerTimerOnElapsed;
|
||||||
_taskManagerTimer.Start();
|
_taskManagerTimer.Start();
|
||||||
|
|
||||||
// if (Avalonia.Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
_window = PlatformManager.CreateWindow();
|
||||||
// {
|
|
||||||
// IWindowImpl window = desktop.MainWindow!.PlatformImpl!;
|
_hWndProcHook = GetWindowLongPtr(_window.Handle.Handle, GWL_WNDPROC);
|
||||||
//
|
_fnWndProcHook = CustomWndProc;
|
||||||
// // https://github.com/sanjay900/guitar-configurator/blob/master/Notify/WindowsDeviceNotifierAvalonia.cs
|
nint newLong = Marshal.GetFunctionPointerForDelegate(_fnWndProcHook);
|
||||||
// // _hWndProcHook = GetWindowLongPtr(window.Handle.Handle, GwlWndproc);
|
SetWindowLongPtr(_window.Handle.Handle, GWL_WNDPROC, newLong);
|
||||||
// // _fnWndProcHook = CustomWndProc;
|
|
||||||
// // var newLong = Marshal.GetFunctionPointerForDelegate(_fnWndProcHook);
|
RawInputDevice.RegisterDevice(HidUsageAndPage.Keyboard, RawInputDeviceFlags.InputSink, _window.Handle.Handle);
|
||||||
// // SetWindowLongPtr(window.Handle.Handle, GwlWndproc, newLong);
|
RawInputDevice.RegisterDevice(HidUsageAndPage.Mouse, RawInputDeviceFlags.InputSink, _window.Handle.Handle);
|
||||||
//
|
|
||||||
// RawInputDevice.RegisterDevice(HidUsageAndPage.Keyboard, RawInputDeviceFlags.InputSink, window.Handle.Handle);
|
|
||||||
// RawInputDevice.RegisterDevice(HidUsageAndPage.Mouse, RawInputDeviceFlags.InputSink, window.Handle.Handle);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Guid Id { get; } = new("6737b204-ffb1-4cd9-8776-9fb851db303a");
|
public static Guid Id { get; } = new("6737b204-ffb1-4cd9-8776-9fb851db303a");
|
||||||
@ -256,6 +264,15 @@ public class WindowsInputProvider : InputProvider
|
|||||||
|
|
||||||
#region Native
|
#region Native
|
||||||
|
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||||
|
static extern IntPtr CallWindowProc(nint lpPrevWndFunc, IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr", CharSet = CharSet.Unicode)]
|
||||||
|
private static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Unicode)]
|
||||||
|
private static extern IntPtr SetWindowLongPtr(nint hWnd, int nIndex, IntPtr dwNewLong);
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
private static extern bool GetCursorPos(ref Win32Point pt);
|
private static extern bool GetCursorPos(ref Win32Point pt);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls.Platform;
|
||||||
using Avalonia.Win32;
|
using Avalonia.Platform;
|
||||||
using SharpVk;
|
using SharpVk;
|
||||||
using SharpVk.Khronos;
|
using SharpVk.Khronos;
|
||||||
|
|
||||||
@ -11,10 +11,10 @@ internal sealed class Win32VkContext : VkContext
|
|||||||
{
|
{
|
||||||
public Win32VkContext()
|
public Win32VkContext()
|
||||||
{
|
{
|
||||||
Window = new Window();
|
Window = PlatformManager.CreateWindow();
|
||||||
Instance = Instance.Create(null, new[] {"VK_KHR_surface", "VK_KHR_win32_surface"});
|
Instance = Instance.Create(null, new[] {"VK_KHR_surface", "VK_KHR_win32_surface"});
|
||||||
PhysicalDevice = Instance.EnumeratePhysicalDevices().First();
|
PhysicalDevice = Instance.EnumeratePhysicalDevices().First();
|
||||||
Surface = Instance.CreateWin32Surface(Kernel32.CurrentModuleHandle, Window.PlatformImpl!.Handle.Handle);
|
Surface = Instance.CreateWin32Surface(Kernel32.CurrentModuleHandle, Window.Handle.Handle);
|
||||||
|
|
||||||
(GraphicsFamily, PresentFamily) = FindQueueFamilies();
|
(GraphicsFamily, PresentFamily) = FindQueueFamilies();
|
||||||
|
|
||||||
@ -44,12 +44,12 @@ internal sealed class Win32VkContext : VkContext
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public Window Window { get; }
|
public IWindowImpl Window { get; }
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
base.Dispose();
|
base.Dispose();
|
||||||
Window.Close();
|
Window.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private IntPtr Proc(string name, IntPtr instanceHandle, IntPtr deviceHandle)
|
private IntPtr Proc(string name, IntPtr instanceHandle, IntPtr deviceHandle)
|
||||||
|
|||||||
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Avalonia" Version="11.0.0-preview6" />
|
<PackageReference Include="Avalonia" Version="11.0.0-preview6" />
|
||||||
<PackageReference Include="Avalonia.AvaloniaEdit" Version="11.0.0-preview5" />
|
|
||||||
<PackageReference Include="Avalonia.Controls.PanAndZoom" Version="11.0.0-preview6" />
|
<PackageReference Include="Avalonia.Controls.PanAndZoom" Version="11.0.0-preview6" />
|
||||||
<PackageReference Include="Avalonia.Controls.Skia" Version="11.0.0-preview6" />
|
<PackageReference Include="Avalonia.Controls.Skia" Version="11.0.0-preview6" />
|
||||||
<PackageReference Include="Avalonia.Desktop" Version="11.0.0-preview6" />
|
<PackageReference Include="Avalonia.Desktop" Version="11.0.0-preview6" />
|
||||||
|
|||||||
@ -16,7 +16,6 @@
|
|||||||
Height="800">
|
Height="800">
|
||||||
|
|
||||||
<Window.Styles>
|
<Window.Styles>
|
||||||
<StyleInclude Source="avares://AvaloniaEdit/AvaloniaEdit.xaml" />
|
|
||||||
<Style Selector="StackPanel.sidebar-stackpanel avalonia|MaterialIcon">
|
<Style Selector="StackPanel.sidebar-stackpanel avalonia|MaterialIcon">
|
||||||
<Setter Property="Margin" Value="-7 0 0 0" />
|
<Setter Property="Margin" Value="-7 0 0 0" />
|
||||||
</Style>
|
</Style>
|
||||||
|
|||||||
@ -8,19 +8,7 @@
|
|||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
x:Class="Artemis.UI.Screens.Debugger.Logs.LogsDebugView"
|
x:Class="Artemis.UI.Screens.Debugger.Logs.LogsDebugView"
|
||||||
x:DataType="logs:LogsDebugViewModel">
|
x:DataType="logs:LogsDebugViewModel">
|
||||||
<aedit:TextEditor Name="LogTextEditor"
|
<ScrollViewer Name="LogsScrollViewer" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
|
||||||
Document="{ CompiledBinding Document }"
|
<SelectableTextBlock Inlines="{CompiledBinding Lines}" FontFamily="Consolas" SizeChanged="Control_OnSizeChanged"></SelectableTextBlock>
|
||||||
IsReadOnly="True"
|
</ScrollViewer>
|
||||||
FontFamily="Consolas"
|
|
||||||
FontSize="12"
|
|
||||||
HorizontalScrollBarVisibility="Auto"
|
|
||||||
Padding="0 15 15 15"
|
|
||||||
TextChanged="OnTextChanged" >
|
|
||||||
|
|
||||||
<aedit:TextEditor.Styles>
|
|
||||||
<Style Selector="aedit|TextArea">
|
|
||||||
<Setter Property="SelectionBrush" Value="#44ffffff" />
|
|
||||||
</Style>
|
|
||||||
</aedit:TextEditor.Styles>
|
|
||||||
</aedit:TextEditor>
|
|
||||||
</UserControl>
|
</UserControl>
|
||||||
@ -1,7 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Avalonia.Controls;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
using Avalonia.ReactiveUI;
|
using Avalonia.ReactiveUI;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
using ReactiveUI;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Debugger.Logs;
|
namespace Artemis.UI.Screens.Debugger.Logs;
|
||||||
|
|
||||||
@ -19,36 +22,42 @@ public partial class LogsDebugView : ReactiveUserControl<LogsDebugViewModel>
|
|||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
base.OnInitialized();
|
base.OnInitialized();
|
||||||
Dispatcher.UIThread.Post(() => LogTextEditor.ScrollToEnd(), DispatcherPriority.ApplicationIdle);
|
Dispatcher.UIThread.Post(() => LogsScrollViewer.ScrollToEnd(), DispatcherPriority.ApplicationIdle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnTextChanged(object? sender, EventArgs e)
|
// private void OnTextChanged(object? sender, EventArgs e)
|
||||||
|
// {
|
||||||
|
// if (LogTextEditor.ExtentHeight == 0)
|
||||||
|
// return;
|
||||||
|
//
|
||||||
|
// int linesAdded = LogTextEditor.LineCount - _lineCount;
|
||||||
|
// double lineHeight = LogTextEditor.ExtentHeight / LogTextEditor.LineCount;
|
||||||
|
// double outOfScreenTextHeight = LogTextEditor.ExtentHeight - LogTextEditor.VerticalOffset - LogTextEditor.ViewportHeight;
|
||||||
|
// double outOfScreenLines = outOfScreenTextHeight / lineHeight;
|
||||||
|
//
|
||||||
|
// //we need this help distance because of rounding.
|
||||||
|
// //if we scroll slightly above the end, we still want it
|
||||||
|
// //to scroll down to the new lines.
|
||||||
|
// const double GRACE_DISTANCE = 1d;
|
||||||
|
//
|
||||||
|
// //if we were at the bottom of the log and
|
||||||
|
// //if the last log event was 5 lines long
|
||||||
|
// //we will be 5 lines out sync.
|
||||||
|
// //if this is the case, scroll down.
|
||||||
|
//
|
||||||
|
// //if we are more than that out of sync,
|
||||||
|
// //the user scrolled up and we should not
|
||||||
|
// //mess with anything.
|
||||||
|
// if (_lineCount == 0 || linesAdded + GRACE_DISTANCE > outOfScreenLines)
|
||||||
|
// {
|
||||||
|
// Dispatcher.UIThread.Post(() => LogTextEditor.ScrollToEnd(), DispatcherPriority.ApplicationIdle);
|
||||||
|
// _lineCount = LogTextEditor.LineCount;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
private void Control_OnSizeChanged(object? sender, SizeChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (LogTextEditor.ExtentHeight == 0)
|
if (!(LogsScrollViewer.Extent.Height - LogsScrollViewer.Offset.Y - LogsScrollViewer.Bounds.Bottom <= 60))
|
||||||
return;
|
return;
|
||||||
|
Dispatcher.UIThread.Post(() => LogsScrollViewer.ScrollToEnd(), DispatcherPriority.Normal);
|
||||||
int linesAdded = LogTextEditor.LineCount - _lineCount;
|
|
||||||
double lineHeight = LogTextEditor.ExtentHeight / LogTextEditor.LineCount;
|
|
||||||
double outOfScreenTextHeight = LogTextEditor.ExtentHeight - LogTextEditor.VerticalOffset - LogTextEditor.ViewportHeight;
|
|
||||||
double outOfScreenLines = outOfScreenTextHeight / lineHeight;
|
|
||||||
|
|
||||||
//we need this help distance because of rounding.
|
|
||||||
//if we scroll slightly above the end, we still want it
|
|
||||||
//to scroll down to the new lines.
|
|
||||||
const double GRACE_DISTANCE = 1d;
|
|
||||||
|
|
||||||
//if we were at the bottom of the log and
|
|
||||||
//if the last log event was 5 lines long
|
|
||||||
//we will be 5 lines out sync.
|
|
||||||
//if this is the case, scroll down.
|
|
||||||
|
|
||||||
//if we are more than that out of sync,
|
|
||||||
//the user scrolled up and we should not
|
|
||||||
//mess with anything.
|
|
||||||
if (_lineCount == 0 || linesAdded + GRACE_DISTANCE > outOfScreenLines)
|
|
||||||
{
|
|
||||||
Dispatcher.UIThread.Post(() => LogTextEditor.ScrollToEnd(), DispatcherPriority.ApplicationIdle);
|
|
||||||
_lineCount = LogTextEditor.LineCount;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,12 +1,15 @@
|
|||||||
using Artemis.Core;
|
using System;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using Artemis.Core;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using AvaloniaEdit.Document;
|
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
using Serilog.Formatting.Display;
|
using Serilog.Formatting.Display;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
|
using Avalonia.Controls.Documents;
|
||||||
|
using Avalonia.Media;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Debugger.Logs;
|
namespace Artemis.UI.Screens.Debugger.Logs;
|
||||||
|
|
||||||
@ -14,38 +17,32 @@ public class LogsDebugViewModel : ActivatableViewModelBase
|
|||||||
{
|
{
|
||||||
private readonly MessageTemplateTextFormatter _formatter;
|
private readonly MessageTemplateTextFormatter _formatter;
|
||||||
|
|
||||||
public TextDocument Document { get; }
|
public InlineCollection Lines { get; } = new InlineCollection();
|
||||||
|
|
||||||
private const int MAX_ENTRIES = 1000;
|
private const int MAX_ENTRIES = 1000;
|
||||||
|
|
||||||
public LogsDebugViewModel()
|
public LogsDebugViewModel()
|
||||||
{
|
{
|
||||||
DisplayName = "Logs";
|
DisplayName = "Logs";
|
||||||
Document = new TextDocument();
|
|
||||||
_formatter = new MessageTemplateTextFormatter(
|
_formatter = new MessageTemplateTextFormatter(
|
||||||
"[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] [{Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}"
|
"[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] [{Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}"
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach(LogEvent logEvent in LogStore.Events)
|
foreach (LogEvent logEvent in LogStore.Events)
|
||||||
AddLogEvent(logEvent);
|
AddLogEvent(logEvent);
|
||||||
|
|
||||||
this.WhenActivated(disp =>
|
this.WhenActivated(disp =>
|
||||||
{
|
{
|
||||||
LogStore.EventAdded += OnLogEventAdded;
|
LogStore.EventAdded += OnLogEventAdded;
|
||||||
|
|
||||||
Disposable.Create(() =>
|
Disposable.Create(() => { LogStore.EventAdded -= OnLogEventAdded; }).DisposeWith(disp);
|
||||||
{
|
|
||||||
LogStore.EventAdded -= OnLogEventAdded;
|
|
||||||
}).DisposeWith(disp);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnLogEventAdded(object? sender, LogEventEventArgs e)
|
private void OnLogEventAdded(object? sender, LogEventEventArgs e)
|
||||||
{
|
{
|
||||||
Dispatcher.UIThread.Post(() =>
|
Dispatcher.UIThread.Post(() => { AddLogEvent(e.LogEvent); });
|
||||||
{
|
|
||||||
AddLogEvent(e.LogEvent);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddLogEvent(LogEvent? logEvent)
|
private void AddLogEvent(LogEvent? logEvent)
|
||||||
@ -56,22 +53,27 @@ public class LogsDebugViewModel : ActivatableViewModelBase
|
|||||||
using StringWriter writer = new();
|
using StringWriter writer = new();
|
||||||
_formatter.Format(logEvent, writer);
|
_formatter.Format(logEvent, writer);
|
||||||
string line = writer.ToString();
|
string line = writer.ToString();
|
||||||
Document.Insert(Document.TextLength, '\n' + line.TrimEnd('\r', '\n'));
|
|
||||||
while (Document.LineCount > MAX_ENTRIES)
|
|
||||||
RemoveOldestLine();
|
Lines.Add(new Run(line.TrimEnd('\r', '\n') + '\n')
|
||||||
|
{
|
||||||
|
Foreground = logEvent.Level switch
|
||||||
|
{
|
||||||
|
LogEventLevel.Verbose => new SolidColorBrush(Colors.White),
|
||||||
|
LogEventLevel.Debug => new SolidColorBrush(Color.FromRgb(216, 216, 216)),
|
||||||
|
LogEventLevel.Information => new SolidColorBrush(Color.FromRgb(93, 201, 255)),
|
||||||
|
LogEventLevel.Warning => new SolidColorBrush(Color.FromRgb(255, 177, 53)),
|
||||||
|
LogEventLevel.Error => new SolidColorBrush(Color.FromRgb(255, 63, 63)),
|
||||||
|
LogEventLevel.Fatal => new SolidColorBrush(Colors.Red),
|
||||||
|
_ => throw new ArgumentOutOfRangeException()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
LimitLines();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RemoveOldestLine()
|
private void LimitLines()
|
||||||
{
|
{
|
||||||
int firstNewLine = Document.IndexOf('\n', 0, Document.TextLength);
|
if (Lines.Count > MAX_ENTRIES)
|
||||||
if (firstNewLine == -1)
|
Lines.RemoveRange(0, Lines.Count - MAX_ENTRIES);
|
||||||
{
|
|
||||||
//this should never happen.
|
|
||||||
//just in case let's return
|
|
||||||
//instead of throwing
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Document.Remove(0, firstNewLine + 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user