From c19ea6ace38f79386f1c4727851dcbcdf23b036f Mon Sep 17 00:00:00 2001
From: Soreepeong <3614868+Soreepeong@users.noreply.github.com>
Date: Tue, 1 Jul 2025 19:02:32 +0900
Subject: [PATCH 01/50] Add ITextureProvider.CreateTextureFromSeString
---
.../Internal/SeStringColorStackSet.cs | 32 ++--
.../Internal/SeStringRenderer.cs | 176 +++++++++---------
.../Internal/TextFragment.cs | 39 ++++
.../SeStringDrawState.cs | 99 +++++++---
.../Interface/Internal/DalamudInterface.cs | 7 +
.../Internal/Windows/Data/DataWindow.cs | 31 ++-
.../Data/Widgets/FontAwesomeTestWidget.cs | 26 ++-
.../Widgets/SeStringRendererTestWidget.cs | 46 +++--
.../Windows/Data/Widgets/TexWidget.cs | 12 +-
.../Interface/ManagedFontAtlas/IFontHandle.cs | 24 ++-
.../ManagedFontAtlas/Internals/FontHandle.cs | 7 +-
.../Internal/TextureManager.FromSeString.cs | 35 ++++
.../Textures/Internal/TextureManager.cs | 3 +-
.../Internal/TextureManagerPluginScoped.cs | 13 ++
Dalamud/Interface/UiBuilder.cs | 33 +++-
.../Utility/BufferBackedImDrawData.cs | 112 +++++++++++
Dalamud/Interface/Utility/ImGuiHelpers.cs | 9 +
.../Utility/Internal/DevTextureSaveMenu.cs | 126 ++++++++-----
Dalamud/Plugin/Services/ITextureProvider.cs | 14 +-
19 files changed, 629 insertions(+), 215 deletions(-)
create mode 100644 Dalamud/Interface/ImGuiSeStringRenderer/Internal/TextFragment.cs
create mode 100644 Dalamud/Interface/Textures/Internal/TextureManager.FromSeString.cs
create mode 100644 Dalamud/Interface/Utility/BufferBackedImDrawData.cs
diff --git a/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringColorStackSet.cs b/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringColorStackSet.cs
index ad60d405e..85ab2e441 100644
--- a/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringColorStackSet.cs
+++ b/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringColorStackSet.cs
@@ -15,10 +15,6 @@ namespace Dalamud.Interface.ImGuiSeStringRenderer.Internal;
/// Color stacks to use while evaluating a SeString.
internal sealed class SeStringColorStackSet
{
- /// Parsed , containing colors to use with and
- /// .
- private readonly uint[,] colorTypes;
-
/// Foreground color stack while evaluating a SeString for rendering.
/// Touched only from the main thread.
private readonly List colorStack = [];
@@ -39,30 +35,38 @@ internal sealed class SeStringColorStackSet
foreach (var row in uiColor)
maxId = (int)Math.Max(row.RowId, maxId);
- this.colorTypes = new uint[maxId + 1, 4];
+ this.ColorTypes = new uint[maxId + 1, 4];
foreach (var row in uiColor)
{
// Contains ABGR.
- this.colorTypes[row.RowId, 0] = row.Dark;
- this.colorTypes[row.RowId, 1] = row.Light;
- this.colorTypes[row.RowId, 2] = row.ClassicFF;
- this.colorTypes[row.RowId, 3] = row.ClearBlue;
+ this.ColorTypes[row.RowId, 0] = row.Dark;
+ this.ColorTypes[row.RowId, 1] = row.Light;
+ this.ColorTypes[row.RowId, 2] = row.ClassicFF;
+ this.ColorTypes[row.RowId, 3] = row.ClearBlue;
}
if (BitConverter.IsLittleEndian)
{
// ImGui wants RGBA in LE.
- fixed (uint* p = this.colorTypes)
+ fixed (uint* p = this.ColorTypes)
{
- foreach (ref var r in new Span(p, this.colorTypes.GetLength(0) * this.colorTypes.GetLength(1)))
+ foreach (ref var r in new Span(p, this.ColorTypes.GetLength(0) * this.ColorTypes.GetLength(1)))
r = BinaryPrimitives.ReverseEndianness(r);
}
}
}
+ /// Initializes a new instance of the class.
+ /// Color types.
+ public SeStringColorStackSet(uint[,] colorTypes) => this.ColorTypes = colorTypes;
+
/// Gets a value indicating whether at least one color has been pushed to the edge color stack.
public bool HasAdditionalEdgeColor { get; private set; }
+ /// Gets the parsed containing colors to use with
+ /// and .
+ public uint[,] ColorTypes { get; }
+
/// Resets the colors in the stack.
/// Draw state.
internal void Initialize(scoped ref SeStringDrawState drawState)
@@ -191,9 +195,9 @@ internal sealed class SeStringColorStackSet
}
// Opacity component is ignored.
- var color = themeIndex >= 0 && themeIndex < this.colorTypes.GetLength(1) &&
- colorTypeIndex < this.colorTypes.GetLength(0)
- ? this.colorTypes[colorTypeIndex, themeIndex]
+ var color = themeIndex >= 0 && themeIndex < this.ColorTypes.GetLength(1) &&
+ colorTypeIndex < this.ColorTypes.GetLength(0)
+ ? this.ColorTypes[colorTypeIndex, themeIndex]
: 0u;
rgbaStack.Add(color | 0xFF000000u);
diff --git a/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringRenderer.cs b/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringRenderer.cs
index d0c40cd9f..0099e6e5d 100644
--- a/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringRenderer.cs
+++ b/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringRenderer.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Numerics;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
@@ -25,7 +26,7 @@ namespace Dalamud.Interface.ImGuiSeStringRenderer.Internal;
/// Draws SeString.
[ServiceManager.EarlyLoadedService]
-internal unsafe class SeStringRenderer : IInternalDisposableService
+internal class SeStringRenderer : IServiceType
{
private const int ImGuiContextCurrentWindowOffset = 0x3FF0;
private const int ImGuiWindowDcOffset = 0x118;
@@ -47,28 +48,19 @@ internal unsafe class SeStringRenderer : IInternalDisposableService
/// Parsed text fragments from a SeString.
/// Touched only from the main thread.
- private readonly List fragments = [];
+ private readonly List fragmentsMainThread = [];
/// Color stacks to use while evaluating a SeString for rendering.
/// Touched only from the main thread.
- private readonly SeStringColorStackSet colorStackSet;
-
- /// Splits a draw list so that different layers of a single glyph can be drawn out of order.
- private ImDrawListSplitter* splitter = ImGui.ImDrawListSplitter();
+ private readonly SeStringColorStackSet colorStackSetMainThread;
[ServiceManager.ServiceConstructor]
private SeStringRenderer(DataManager dm, TargetSigScanner sigScanner)
{
- this.colorStackSet = new(dm.Excel.GetSheet());
+ this.colorStackSetMainThread = new(dm.Excel.GetSheet());
this.gfd = dm.GetFile("common/font/gfdata.gfd")!;
}
- /// Finalizes an instance of the class.
- ~SeStringRenderer() => this.ReleaseUnmanagedResources();
-
- ///
- void IInternalDisposableService.DisposeService() => this.ReleaseUnmanagedResources();
-
/// Compiles and caches a SeString from a text macro representation.
/// SeString text macro representation.
/// Newline characters will be normalized to newline payloads.
@@ -80,6 +72,44 @@ internal unsafe class SeStringRenderer : IInternalDisposableService
text.ReplaceLineEndings("
"),
new() { ExceptionMode = MacroStringParseExceptionMode.EmbedError }));
+ /// Creates a draw data that will draw the given SeString onto it.
+ /// SeString to render.
+ /// Parameters for drawing.
+ /// A new self-contained draw data.
+ public unsafe BufferBackedImDrawData CreateDrawData(
+ ReadOnlySeStringSpan sss,
+ scoped in SeStringDrawParams drawParams = default)
+ {
+ if (drawParams.TargetDrawList is not null)
+ {
+ throw new ArgumentException(
+ $"{nameof(SeStringDrawParams.TargetDrawList)} may not be specified.",
+ nameof(drawParams));
+ }
+
+ var dd = BufferBackedImDrawData.Create();
+
+ try
+ {
+ var size = this.Draw(sss, drawParams with { TargetDrawList = dd.ListPtr }).Size;
+
+ var offset = drawParams.ScreenOffset ?? Vector2.Zero;
+ foreach (var vtx in new Span(dd.ListPtr.VtxBuffer.Data, dd.ListPtr.VtxBuffer.Size))
+ offset = Vector2.Min(offset, vtx.Pos);
+
+ dd.Data.DisplayPos = offset;
+ dd.Data.DisplaySize = size - offset;
+ dd.Data.Valid = 1;
+ dd.UpdateDrawDataStatistics();
+ return dd;
+ }
+ catch
+ {
+ dd.Dispose();
+ throw;
+ }
+ }
+
/// Compiles and caches a SeString from a text macro representation, and then draws it.
/// SeString text macro representation.
/// Newline characters will be normalized to newline payloads.
@@ -113,28 +143,42 @@ internal unsafe class SeStringRenderer : IInternalDisposableService
/// ImGui ID, if link functionality is desired.
/// Button flags to use on link interaction.
/// Interaction result of the rendered text.
- public SeStringDrawResult Draw(
+ public unsafe SeStringDrawResult Draw(
ReadOnlySeStringSpan sss,
scoped in SeStringDrawParams drawParams = default,
ImGuiId imGuiId = default,
ImGuiButtonFlags buttonFlags = ImGuiButtonFlags.MouseButtonDefault)
{
- // Drawing is only valid if done from the main thread anyway, especially with interactivity.
- ThreadSafety.AssertMainThread();
+ // Interactivity is supported only from the main thread.
+ if (!imGuiId.IsEmpty())
+ ThreadSafety.AssertMainThread();
if (drawParams.TargetDrawList is not null && imGuiId)
throw new ArgumentException("ImGuiId cannot be set if TargetDrawList is manually set.", nameof(imGuiId));
- // This also does argument validation for drawParams. Do it here.
- var state = new SeStringDrawState(sss, drawParams, this.colorStackSet, this.splitter);
+ using var cleanup = new DisposeSafety.ScopedFinalizer();
- // Reset and initialize the state.
- this.fragments.Clear();
- this.colorStackSet.Initialize(ref state);
+ ImFont* font = null;
+ if (drawParams.Font.HasValue)
+ font = drawParams.Font.Value;
+ if (ThreadSafety.IsMainThread && drawParams.TargetDrawList is null && font is null)
+ font = ImGui.GetFont();
+ if (font is null)
+ throw new ArgumentException("Specified font is empty.");
+
+ // This also does argument validation for drawParams. Do it here.
+ // `using var` makes a struct read-only, but we do want to modify it.
+ using var stateStorage = new SeStringDrawState(
+ sss,
+ drawParams,
+ ThreadSafety.IsMainThread ? this.colorStackSetMainThread : new(this.colorStackSetMainThread.ColorTypes),
+ ThreadSafety.IsMainThread ? this.fragmentsMainThread : [],
+ font);
+ ref var state = ref Unsafe.AsRef(in stateStorage);
// Analyze the provided SeString and break it up to text fragments.
this.CreateTextFragments(ref state);
- var fragmentSpan = CollectionsMarshal.AsSpan(this.fragments);
+ var fragmentSpan = CollectionsMarshal.AsSpan(state.Fragments);
// Calculate size.
var size = Vector2.Zero;
@@ -147,24 +191,17 @@ internal unsafe class SeStringRenderer : IInternalDisposableService
state.SplitDrawList();
- // Handle cases where ImGui.AlignTextToFramePadding has been called.
- var context = ImGui.GetCurrentContext();
- var currLineTextBaseOffset = 0f;
- if (!context.IsNull)
- {
- var currentWindow = context.CurrentWindow;
- if (!currentWindow.IsNull)
- {
- currLineTextBaseOffset = currentWindow.DC.CurrLineTextBaseOffset;
- }
- }
-
var itemSize = size;
- if (currLineTextBaseOffset != 0f)
+ if (drawParams.TargetDrawList is null)
{
- itemSize.Y += 2 * currLineTextBaseOffset;
- foreach (ref var f in fragmentSpan)
- f.Offset += new Vector2(0, currLineTextBaseOffset);
+ // Handle cases where ImGui.AlignTextToFramePadding has been called.
+ var currLineTextBaseOffset = ImGui.GetCurrentContext().CurrentWindow.DC.CurrLineTextBaseOffset;
+ if (currLineTextBaseOffset != 0f)
+ {
+ itemSize.Y += 2 * currLineTextBaseOffset;
+ foreach (ref var f in fragmentSpan)
+ f.Offset += new Vector2(0, currLineTextBaseOffset);
+ }
}
// Draw all text fragments.
@@ -280,15 +317,6 @@ internal unsafe class SeStringRenderer : IInternalDisposableService
return displayRune.Value != 0;
}
- private void ReleaseUnmanagedResources()
- {
- if (this.splitter is not null)
- {
- this.splitter->Destroy();
- this.splitter = null;
- }
- }
-
/// Creates text fragment, taking line and word breaking into account.
/// Draw state.
private void CreateTextFragments(ref SeStringDrawState state)
@@ -391,7 +419,7 @@ internal unsafe class SeStringRenderer : IInternalDisposableService
var overflows = Math.Max(w, xy.X + fragment.VisibleWidth) > state.WrapWidth;
// Test if the fragment does not fit into the current line and the current line is not empty.
- if (xy.X != 0 && this.fragments.Count > 0 && !this.fragments[^1].BreakAfter && overflows)
+ if (xy.X != 0 && state.Fragments.Count > 0 && !state.Fragments[^1].BreakAfter && overflows)
{
// Introduce break if this is the first time testing the current break unit or the current fragment
// is an entity.
@@ -401,7 +429,7 @@ internal unsafe class SeStringRenderer : IInternalDisposableService
xy.X = 0;
xy.Y += state.LineHeight;
w = 0;
- CollectionsMarshal.AsSpan(this.fragments)[^1].BreakAfter = true;
+ CollectionsMarshal.AsSpan(state.Fragments)[^1].BreakAfter = true;
fragment.Offset = xy;
// Now that the fragment is given its own line, test if it overflows again.
@@ -419,16 +447,16 @@ internal unsafe class SeStringRenderer : IInternalDisposableService
fragment = this.CreateFragment(state, prev, curr, true, xy, link, entity, remainingWidth);
}
}
- else if (this.fragments.Count > 0 && xy.X != 0)
+ else if (state.Fragments.Count > 0 && xy.X != 0)
{
// New fragment fits into the current line, and it has a previous fragment in the same line.
// If the previous fragment ends with a soft hyphen, adjust its width so that the width of its
// trailing soft hyphens are not considered.
- if (this.fragments[^1].EndsWithSoftHyphen)
- xy.X += this.fragments[^1].AdvanceWidthWithoutSoftHyphen - this.fragments[^1].AdvanceWidth;
+ if (state.Fragments[^1].EndsWithSoftHyphen)
+ xy.X += state.Fragments[^1].AdvanceWidthWithoutSoftHyphen - state.Fragments[^1].AdvanceWidth;
// Adjust this fragment's offset from kerning distance.
- xy.X += state.CalculateScaledDistance(this.fragments[^1].LastRune, fragment.FirstRune);
+ xy.X += state.CalculateScaledDistance(state.Fragments[^1].LastRune, fragment.FirstRune);
fragment.Offset = xy;
}
@@ -439,7 +467,7 @@ internal unsafe class SeStringRenderer : IInternalDisposableService
w = Math.Max(w, xy.X + fragment.VisibleWidth);
xy.X += fragment.AdvanceWidth;
prev = fragment.To;
- this.fragments.Add(fragment);
+ state.Fragments.Add(fragment);
if (fragment.BreakAfter)
{
@@ -491,7 +519,7 @@ internal unsafe class SeStringRenderer : IInternalDisposableService
if (gfdTextureSrv != 0)
{
state.Draw(
- new ImTextureID(gfdTextureSrv),
+ new(gfdTextureSrv),
offset + new Vector2(x, MathF.Round((state.LineHeight - size.Y) / 2)),
size,
useHq ? gfdEntry.HqUv0 : gfdEntry.Uv0,
@@ -528,7 +556,7 @@ internal unsafe class SeStringRenderer : IInternalDisposableService
return;
- static nint GetGfdTextureSrv()
+ static unsafe nint GetGfdTextureSrv()
{
var uim = UIModule.Instance();
if (uim is null)
@@ -553,7 +581,7 @@ internal unsafe class SeStringRenderer : IInternalDisposableService
/// Determines a bitmap icon to display for the given SeString payload.
/// Byte span that should include a SeString payload.
/// Icon to display, or if it should not be displayed as an icon.
- private BitmapFontIcon GetBitmapFontIconFor(ReadOnlySpan sss)
+ private unsafe BitmapFontIcon GetBitmapFontIconFor(ReadOnlySpan sss)
{
var e = new ReadOnlySeStringSpan(sss).GetEnumerator();
if (!e.MoveNext() || e.Current.MacroCode is not MacroCode.Icon and not MacroCode.Icon2)
@@ -710,38 +738,4 @@ internal unsafe class SeStringRenderer : IInternalDisposableService
firstDisplayRune ?? default,
lastNonSoftHyphenRune);
}
-
- /// Represents a text fragment in a SeString span.
- /// Starting byte offset (inclusive) in a SeString.
- /// Ending byte offset (exclusive) in a SeString.
- /// Byte offset of the link that decorates this text fragment, or -1 if none.
- /// Offset in pixels w.r.t. .
- /// Replacement entity, if any.
- /// Visible width of this text fragment. This is the width required to draw everything
- /// without clipping.
- /// Advance width of this text fragment. This is the width required to add to the cursor
- /// to position the next fragment correctly.
- /// Same with , but trimming all the
- /// trailing soft hyphens.
- /// Whether to insert a line break after this text fragment.
- /// Whether this text fragment ends with one or more soft hyphens.
- /// First rune in this text fragment.
- /// Last rune in this text fragment, for the purpose of calculating kerning distance with
- /// the following text fragment in the same line, if any.
- private record struct TextFragment(
- int From,
- int To,
- int Link,
- Vector2 Offset,
- SeStringReplacementEntity Entity,
- float VisibleWidth,
- float AdvanceWidth,
- float AdvanceWidthWithoutSoftHyphen,
- bool BreakAfter,
- bool EndsWithSoftHyphen,
- Rune FirstRune,
- Rune LastRune)
- {
- public bool IsSoftHyphenVisible => this.EndsWithSoftHyphen && this.BreakAfter;
- }
}
diff --git a/Dalamud/Interface/ImGuiSeStringRenderer/Internal/TextFragment.cs b/Dalamud/Interface/ImGuiSeStringRenderer/Internal/TextFragment.cs
new file mode 100644
index 000000000..a64c32109
--- /dev/null
+++ b/Dalamud/Interface/ImGuiSeStringRenderer/Internal/TextFragment.cs
@@ -0,0 +1,39 @@
+using System.Numerics;
+using System.Text;
+
+namespace Dalamud.Interface.ImGuiSeStringRenderer.Internal;
+
+/// Represents a text fragment in a SeString span.
+/// Starting byte offset (inclusive) in a SeString.
+/// Ending byte offset (exclusive) in a SeString.
+/// Byte offset of the link that decorates this text fragment, or -1 if none.
+/// Offset in pixels w.r.t. .
+/// Replacement entity, if any.
+/// Visible width of this text fragment. This is the width required to draw everything
+/// without clipping.
+/// Advance width of this text fragment. This is the width required to add to the cursor
+/// to position the next fragment correctly.
+/// Same with , but trimming all the
+/// trailing soft hyphens.
+/// Whether to insert a line break after this text fragment.
+/// Whether this text fragment ends with one or more soft hyphens.
+/// First rune in this text fragment.
+/// Last rune in this text fragment, for the purpose of calculating kerning distance with
+/// the following text fragment in the same line, if any.
+internal record struct TextFragment(
+ int From,
+ int To,
+ int Link,
+ Vector2 Offset,
+ SeStringReplacementEntity Entity,
+ float VisibleWidth,
+ float AdvanceWidth,
+ float AdvanceWidthWithoutSoftHyphen,
+ bool BreakAfter,
+ bool EndsWithSoftHyphen,
+ Rune FirstRune,
+ Rune LastRune)
+{
+ /// Gets a value indicating whether the fragment ends with a visible soft hyphen.
+ public bool IsSoftHyphenVisible => this.EndsWithSoftHyphen && this.BreakAfter;
+}
diff --git a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs
index 64a7f3db3..722de1fda 100644
--- a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs
+++ b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs
@@ -1,3 +1,4 @@
+using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -6,6 +7,8 @@ using System.Text;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface.ImGuiSeStringRenderer.Internal;
using Dalamud.Interface.Utility;
+using Dalamud.Utility;
+
using FFXIVClientStructs.FFXIV.Component.GUI;
using Lumina.Text.Payloads;
using Lumina.Text.ReadOnly;
@@ -14,51 +17,80 @@ namespace Dalamud.Interface.ImGuiSeStringRenderer;
/// Calculated values from using ImGui styles.
[StructLayout(LayoutKind.Sequential)]
-public unsafe ref struct SeStringDrawState
+public unsafe ref struct SeStringDrawState : IDisposable
{
private static readonly int ChannelCount = Enum.GetValues().Length;
private readonly ImDrawList* drawList;
- private readonly SeStringColorStackSet colorStackSet;
- private readonly ImDrawListSplitter* splitter;
+
+ private ImDrawListSplitter splitter;
/// Initializes a new instance of the struct.
/// Raw SeString byte span.
/// Instance of to initialize from.
/// Instance of to use.
- /// Instance of ImGui Splitter to use.
+ /// Fragments.
+ /// Font to use.
internal SeStringDrawState(
ReadOnlySpan span,
scoped in SeStringDrawParams ssdp,
SeStringColorStackSet colorStackSet,
- ImDrawListSplitter* splitter)
+ List fragments,
+ ImFont* font)
{
- this.colorStackSet = colorStackSet;
- this.splitter = splitter;
- this.drawList = ssdp.TargetDrawList ?? ImGui.GetWindowDrawList();
this.Span = span;
+ this.ColorStackSet = colorStackSet;
+ this.Fragments = fragments;
+ this.Font = font;
+
+ if (ssdp.TargetDrawList is null)
+ {
+ if (!ThreadSafety.IsMainThread)
+ {
+ throw new ArgumentException(
+ $"{nameof(ssdp.TargetDrawList)} must be set to render outside the main thread.");
+ }
+
+ this.drawList = ssdp.TargetDrawList ?? ImGui.GetWindowDrawList();
+ this.ScreenOffset = ssdp.ScreenOffset ?? ImGui.GetCursorScreenPos();
+ this.FontSize = ssdp.FontSize ?? ImGui.GetFontSize();
+ this.WrapWidth = ssdp.WrapWidth ?? ImGui.GetContentRegionAvail().X;
+ this.Color = ssdp.Color ?? ImGui.GetColorU32(ImGuiCol.Text);
+ this.LinkHoverBackColor = ssdp.LinkHoverBackColor ?? ImGui.GetColorU32(ImGuiCol.ButtonHovered);
+ this.LinkActiveBackColor = ssdp.LinkActiveBackColor ?? ImGui.GetColorU32(ImGuiCol.ButtonActive);
+ this.ThemeIndex = ssdp.ThemeIndex ?? AtkStage.Instance()->AtkUIColorHolder->ActiveColorThemeType;
+ }
+ else
+ {
+ this.drawList = ssdp.TargetDrawList.Value;
+ this.ScreenOffset = Vector2.Zero;
+ this.FontSize = ssdp.FontSize ?? throw new ArgumentException(
+ $"{nameof(ssdp.FontSize)} must be set to render outside the main thread.");
+ this.WrapWidth = ssdp.WrapWidth ?? float.MaxValue;
+ this.Color = ssdp.Color ?? uint.MaxValue;
+ this.LinkHoverBackColor = 0; // Interactivity is unused outside the main thread.
+ this.LinkActiveBackColor = 0; // Interactivity is unused outside the main thread.
+ this.ThemeIndex = ssdp.ThemeIndex ?? 0;
+ }
+
+ this.splitter = default;
this.GetEntity = ssdp.GetEntity;
- this.ScreenOffset = ssdp.ScreenOffset ?? ImGui.GetCursorScreenPos();
this.ScreenOffset = new(MathF.Round(this.ScreenOffset.X), MathF.Round(this.ScreenOffset.Y));
- this.Font = ssdp.EffectiveFont;
- this.FontSize = ssdp.FontSize ?? ImGui.GetFontSize();
this.FontSizeScale = this.FontSize / this.Font->FontSize;
this.LineHeight = MathF.Round(ssdp.EffectiveLineHeight);
- this.WrapWidth = ssdp.WrapWidth ?? ImGui.GetContentRegionAvail().X;
this.LinkUnderlineThickness = ssdp.LinkUnderlineThickness ?? 0f;
this.Opacity = ssdp.EffectiveOpacity;
this.EdgeOpacity = (ssdp.EdgeStrength ?? 0.25f) * ssdp.EffectiveOpacity;
- this.Color = ssdp.Color ?? ImGui.GetColorU32(ImGuiCol.Text);
this.EdgeColor = ssdp.EdgeColor ?? 0xFF000000;
this.ShadowColor = ssdp.ShadowColor ?? 0xFF000000;
- this.LinkHoverBackColor = ssdp.LinkHoverBackColor ?? ImGui.GetColorU32(ImGuiCol.ButtonHovered);
- this.LinkActiveBackColor = ssdp.LinkActiveBackColor ?? ImGui.GetColorU32(ImGuiCol.ButtonActive);
this.ForceEdgeColor = ssdp.ForceEdgeColor;
- this.ThemeIndex = ssdp.ThemeIndex ?? AtkStage.Instance()->AtkUIColorHolder->ActiveColorThemeType;
this.Bold = ssdp.Bold;
this.Italic = ssdp.Italic;
this.Edge = ssdp.Edge;
this.Shadow = ssdp.Shadow;
+
+ this.ColorStackSet.Initialize(ref this);
+ fragments.Clear();
}
///
@@ -135,7 +167,7 @@ public unsafe ref struct SeStringDrawState
/// Gets a value indicating whether the edge should be drawn.
public readonly bool ShouldDrawEdge =>
- (this.Edge || this.colorStackSet.HasAdditionalEdgeColor) && this.EdgeColor >= 0x1000000;
+ (this.Edge || this.ColorStackSet.HasAdditionalEdgeColor) && this.EdgeColor >= 0x1000000;
/// Gets a value indicating whether the edge should be drawn.
public readonly bool ShouldDrawShadow => this is { Shadow: true, ShadowColor: >= 0x1000000 };
@@ -143,11 +175,21 @@ public unsafe ref struct SeStringDrawState
/// Gets a value indicating whether the edge should be drawn.
public readonly bool ShouldDrawForeground => this is { Color: >= 0x1000000 };
+ /// Gets the color stacks.
+ internal SeStringColorStackSet ColorStackSet { get; }
+
+ /// Gets the text fragments.
+ internal List Fragments { get; }
+
+ ///
+ public void Dispose() =>
+ ImGuiNative.Destroy((ImDrawListSplitter*)Unsafe.AsPointer(ref this.splitter));
+
/// Sets the current channel in the ImGui draw list splitter.
/// Channel to switch to.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public readonly void SetCurrentChannel(SeStringDrawChannel channelIndex) =>
- this.splitter->SetCurrentChannel(this.drawList, (int)channelIndex);
+ public void SetCurrentChannel(SeStringDrawChannel channelIndex) =>
+ this.splitter.SetCurrentChannel(this.drawList, (int)channelIndex);
/// Draws a single texture.
/// ImGui texture ID to draw from.
@@ -216,7 +258,7 @@ public unsafe ref struct SeStringDrawState
/// Draws a single glyph using current styling configurations.
/// Glyph to draw.
/// Offset of the glyph in pixels w.r.t. .
- internal readonly void DrawGlyph(scoped in ImGuiHelpers.ImFontGlyphReal g, Vector2 offset)
+ internal void DrawGlyph(scoped in ImGuiHelpers.ImFontGlyphReal g, Vector2 offset)
{
var texId = this.Font->ContainerAtlas->Textures.Ref(g.TextureIndex).TexID;
var xy0 = new Vector2(
@@ -268,7 +310,7 @@ public unsafe ref struct SeStringDrawState
/// Offset of the glyph in pixels w.r.t.
/// .
/// Advance width of the glyph.
- internal readonly void DrawLinkUnderline(Vector2 offset, float advanceWidth)
+ internal void DrawLinkUnderline(Vector2 offset, float advanceWidth)
{
if (this.LinkUnderlineThickness < 1f)
return;
@@ -350,15 +392,15 @@ public unsafe ref struct SeStringDrawState
switch (payload.MacroCode)
{
case MacroCode.Color:
- this.colorStackSet.HandleColorPayload(ref this, payload);
+ this.ColorStackSet.HandleColorPayload(ref this, payload);
return true;
case MacroCode.EdgeColor:
- this.colorStackSet.HandleEdgeColorPayload(ref this, payload);
+ this.ColorStackSet.HandleEdgeColorPayload(ref this, payload);
return true;
case MacroCode.ShadowColor:
- this.colorStackSet.HandleShadowColorPayload(ref this, payload);
+ this.ColorStackSet.HandleShadowColorPayload(ref this, payload);
return true;
case MacroCode.Bold when payload.TryGetExpression(out var e) && e.TryGetUInt(out var u):
@@ -379,11 +421,11 @@ public unsafe ref struct SeStringDrawState
return true;
case MacroCode.ColorType:
- this.colorStackSet.HandleColorTypePayload(ref this, payload);
+ this.ColorStackSet.HandleColorTypePayload(ref this, payload);
return true;
case MacroCode.EdgeColorType:
- this.colorStackSet.HandleEdgeColorTypePayload(ref this, payload);
+ this.ColorStackSet.HandleEdgeColorTypePayload(ref this, payload);
return true;
default:
@@ -393,10 +435,9 @@ public unsafe ref struct SeStringDrawState
/// Splits the draw list.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal readonly void SplitDrawList() =>
- this.splitter->Split(this.drawList, ChannelCount);
+ internal void SplitDrawList() => this.splitter.Split(this.drawList, ChannelCount);
/// Merges the draw list.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal readonly void MergeDrawList() => this.splitter->Merge(this.drawList);
+ internal void MergeDrawList() => this.splitter.Merge(this.drawList);
}
diff --git a/Dalamud/Interface/Internal/DalamudInterface.cs b/Dalamud/Interface/Internal/DalamudInterface.cs
index d475d36bc..7afe7e709 100644
--- a/Dalamud/Interface/Internal/DalamudInterface.cs
+++ b/Dalamud/Interface/Internal/DalamudInterface.cs
@@ -531,6 +531,13 @@ internal class DalamudInterface : IInternalDisposableService
this.creditsDarkeningAnimation.Restart();
}
+ ///
+ public T GetDataWindowWidget() where T : IDataWindowWidget => this.dataWindow.GetWidget();
+
+ /// Sets the data window current widget.
+ /// Widget to set current.
+ public void SetDataWindowWidget(IDataWindowWidget widget) => this.dataWindow.CurrentWidget = widget;
+
private void OnDraw()
{
this.FrameCount++;
diff --git a/Dalamud/Interface/Internal/Windows/Data/DataWindow.cs b/Dalamud/Interface/Internal/Windows/Data/DataWindow.cs
index ae86958dd..eb0589d59 100644
--- a/Dalamud/Interface/Internal/Windows/Data/DataWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/Data/DataWindow.cs
@@ -68,7 +68,7 @@ internal class DataWindow : Window, IDisposable
private bool isExcept;
private bool selectionCollapsed;
- private IDataWindowWidget currentWidget;
+
private bool isLoaded;
///
@@ -82,9 +82,12 @@ internal class DataWindow : Window, IDisposable
this.RespectCloseHotkey = false;
this.orderedModules = this.modules.OrderBy(module => module.DisplayName);
- this.currentWidget = this.orderedModules.First();
+ this.CurrentWidget = this.orderedModules.First();
}
+ /// Gets or sets the current widget.
+ public IDataWindowWidget CurrentWidget { get; set; }
+
///
public void Dispose() => this.modules.OfType().AggregateToDisposable().Dispose();
@@ -99,6 +102,20 @@ internal class DataWindow : Window, IDisposable
{
}
+ /// Gets the data window widget of the specified type.
+ /// Type of the data window widget to find.
+ /// Found widget.
+ public T GetWidget() where T : IDataWindowWidget
+ {
+ foreach (var m in this.modules)
+ {
+ if (m is T w)
+ return w;
+ }
+
+ throw new ArgumentException($"No widget of type {typeof(T).FullName} found.");
+ }
+
///
/// Set the DataKind dropdown menu.
///
@@ -110,7 +127,7 @@ internal class DataWindow : Window, IDisposable
if (this.modules.FirstOrDefault(module => module.IsWidgetCommand(dataKind)) is { } targetModule)
{
- this.currentWidget = targetModule;
+ this.CurrentWidget = targetModule;
}
else
{
@@ -153,9 +170,9 @@ internal class DataWindow : Window, IDisposable
{
foreach (var widget in this.orderedModules)
{
- if (ImGui.Selectable(widget.DisplayName, this.currentWidget == widget))
+ if (ImGui.Selectable(widget.DisplayName, this.CurrentWidget == widget))
{
- this.currentWidget = widget;
+ this.CurrentWidget = widget;
}
}
@@ -206,9 +223,9 @@ internal class DataWindow : Window, IDisposable
try
{
- if (this.currentWidget is { Ready: true })
+ if (this.CurrentWidget is { Ready: true })
{
- this.currentWidget.Draw();
+ this.CurrentWidget.Draw();
}
else
{
diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/FontAwesomeTestWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/FontAwesomeTestWidget.cs
index 91f1af98e..4f5540daf 100644
--- a/Dalamud/Interface/Internal/Windows/Data/Widgets/FontAwesomeTestWidget.cs
+++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/FontAwesomeTestWidget.cs
@@ -1,9 +1,15 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
using System.Numerics;
+using System.Threading.Tasks;
using Dalamud.Bindings.ImGui;
+using Dalamud.Interface.Components;
+using Dalamud.Interface.Textures.Internal;
using Dalamud.Interface.Utility;
+using Dalamud.Interface.Utility.Internal;
+
+using Lumina.Text.ReadOnly;
namespace Dalamud.Interface.Internal.Windows.Data.Widgets;
@@ -87,12 +93,30 @@ internal class FontAwesomeTestWidget : IDataWindowWidget
ImGuiHelpers.ScaledDummy(10f);
for (var i = 0; i < this.icons?.Count; i++)
{
+ if (this.icons[i] == FontAwesomeIcon.None)
+ continue;
+
+ ImGui.AlignTextToFramePadding();
ImGui.Text($"0x{(int)this.icons[i].ToIconChar():X}");
ImGuiHelpers.ScaledRelativeSameLine(50f);
ImGui.Text($"{this.iconNames?[i]}");
ImGuiHelpers.ScaledRelativeSameLine(280f);
ImGui.PushFont(this.useFixedWidth ? InterfaceManager.IconFontFixedWidth : InterfaceManager.IconFont);
ImGui.Text(this.icons[i].ToIconString());
+ ImGuiHelpers.ScaledRelativeSameLine(320f);
+ if (this.useFixedWidth
+ ? ImGui.Button($"{(char)this.icons[i]}##FontAwesomeIconButton{i}")
+ : ImGuiComponents.IconButton($"##FontAwesomeIconButton{i}", this.icons[i]))
+ {
+ _ = Service.Get().ShowTextureSaveMenuAsync(
+ this.DisplayName,
+ this.icons[i].ToString(),
+ Task.FromResult(
+ Service.Get().CreateTextureFromSeString(
+ ReadOnlySeString.FromText(this.icons[i].ToIconString()),
+ new() { Font = ImGui.GetFont(), FontSize = ImGui.GetFontSize() })));
+ }
+
ImGui.PopFont();
ImGuiHelpers.ScaledDummy(2f);
}
diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/SeStringRendererTestWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/SeStringRendererTestWidget.cs
index 7ff5a63be..0f51e0322 100644
--- a/Dalamud/Interface/Internal/Windows/Data/Widgets/SeStringRendererTestWidget.cs
+++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/SeStringRendererTestWidget.cs
@@ -1,5 +1,6 @@
using System.Numerics;
using System.Text;
+using System.Threading.Tasks;
using Dalamud.Bindings.ImGui;
using Dalamud.Data;
@@ -9,11 +10,13 @@ using Dalamud.Interface.ImGuiSeStringRenderer;
using Dalamud.Interface.ImGuiSeStringRenderer.Internal;
using Dalamud.Interface.Textures.Internal;
using Dalamud.Interface.Utility;
+using Dalamud.Interface.Utility.Internal;
using Dalamud.Storage.Assets;
using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Component.GUI;
using Lumina.Excel.Sheets;
using Lumina.Text;
+using Lumina.Text.Parse;
using Lumina.Text.Payloads;
using Lumina.Text.ReadOnly;
@@ -56,11 +59,11 @@ internal unsafe class SeStringRendererTestWidget : IDataWindowWidget
///
public void Draw()
{
- var t2 = ImGui.ColorConvertU32ToFloat4(this.style.Color ?? ImGui.GetColorU32(ImGuiCol.Text));
+ var t2 = ImGui.ColorConvertU32ToFloat4(this.style.Color ??= ImGui.GetColorU32(ImGuiCol.Text));
if (ImGui.ColorEdit4("Color", ref t2))
this.style.Color = ImGui.ColorConvertFloat4ToU32(t2);
- t2 = ImGui.ColorConvertU32ToFloat4(this.style.EdgeColor ?? 0xFF000000u);
+ t2 = ImGui.ColorConvertU32ToFloat4(this.style.EdgeColor ??= 0xFF000000u);
if (ImGui.ColorEdit4("Edge Color", ref t2))
this.style.EdgeColor = ImGui.ColorConvertFloat4ToU32(t2);
@@ -69,27 +72,27 @@ internal unsafe class SeStringRendererTestWidget : IDataWindowWidget
if (ImGui.Checkbox("Forced"u8, ref t))
this.style.ForceEdgeColor = t;
- t2 = ImGui.ColorConvertU32ToFloat4(this.style.ShadowColor ?? 0xFF000000u);
- if (ImGui.ColorEdit4("Shadow Color", ref t2))
+ t2 = ImGui.ColorConvertU32ToFloat4(this.style.ShadowColor ??= 0xFF000000u);
+ if (ImGui.ColorEdit4("Shadow Color"u8, ref t2))
this.style.ShadowColor = ImGui.ColorConvertFloat4ToU32(t2);
- t2 = ImGui.ColorConvertU32ToFloat4(this.style.LinkHoverBackColor ?? ImGui.GetColorU32(ImGuiCol.ButtonHovered));
- if (ImGui.ColorEdit4("Link Hover Color", ref t2))
+ t2 = ImGui.ColorConvertU32ToFloat4(this.style.LinkHoverBackColor ??= ImGui.GetColorU32(ImGuiCol.ButtonHovered));
+ if (ImGui.ColorEdit4("Link Hover Color"u8, ref t2))
this.style.LinkHoverBackColor = ImGui.ColorConvertFloat4ToU32(t2);
- t2 = ImGui.ColorConvertU32ToFloat4(this.style.LinkActiveBackColor ?? ImGui.GetColorU32(ImGuiCol.ButtonActive));
- if (ImGui.ColorEdit4("Link Active Color", ref t2))
+ t2 = ImGui.ColorConvertU32ToFloat4(this.style.LinkActiveBackColor ??= ImGui.GetColorU32(ImGuiCol.ButtonActive));
+ if (ImGui.ColorEdit4("Link Active Color"u8, ref t2))
this.style.LinkActiveBackColor = ImGui.ColorConvertFloat4ToU32(t2);
- var t3 = this.style.LineHeight ?? 1f;
+ var t3 = this.style.LineHeight ??= 1f;
if (ImGui.DragFloat("Line Height"u8, ref t3, 0.01f, 0.4f, 3f, "%.02f"))
this.style.LineHeight = t3;
- t3 = this.style.Opacity ?? ImGui.GetStyle().Alpha;
+ t3 = this.style.Opacity ??= 1f;
if (ImGui.DragFloat("Opacity"u8, ref t3, 0.005f, 0f, 1f, "%.02f"))
this.style.Opacity = t3;
- t3 = this.style.EdgeStrength ?? 0.25f;
+ t3 = this.style.EdgeStrength ??= 0.25f;
if (ImGui.DragFloat("Edge Strength"u8, ref t3, 0.005f, 0f, 1f, "%.02f"))
this.style.EdgeStrength = t3;
@@ -240,6 +243,27 @@ internal unsafe class SeStringRendererTestWidget : IDataWindowWidget
Service.Get().CompileAndCache(this.testString).Data.Span));
}
+ ImGui.SameLine();
+
+ if (ImGui.Button("Copy as Image"))
+ {
+ _ = Service.Get().ShowTextureSaveMenuAsync(
+ this.DisplayName,
+ $"From {nameof(SeStringRendererTestWidget)}",
+ Task.FromResult(
+ Service.Get().CreateTextureFromSeString(
+ ReadOnlySeString.FromMacroString(
+ this.testString,
+ new(ExceptionMode: MacroStringParseExceptionMode.EmbedError)),
+ this.style with
+ {
+ Font = ImGui.GetFont(),
+ FontSize = ImGui.GetFontSize(),
+ WrapWidth = ImGui.GetContentRegionAvail().X,
+ ThemeIndex = AtkStage.Instance()->AtkUIColorHolder->ActiveColorThemeType,
+ })));
+ }
+
ImGuiHelpers.ScaledDummy(3);
ImGuiHelpers.CompileSeStringWrapped(
"Optional features implemented for the following test input:
" +
diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs
index 52fa0e822..3416a2506 100644
--- a/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs
+++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
@@ -306,12 +306,12 @@ internal class TexWidget : IDataWindowWidget
pres->Release();
ImGui.Text($"RC: Resource({rcres})/View({rcsrv})");
- ImGui.Text(source.ToString());
+ ImGui.Text($"{source.Width} x {source.Height} | {source}");
}
else
{
- ImGui.Text("RC: -"u8);
- ImGui.Text(" "u8);
+ ImGui.Text("RC: -");
+ ImGui.Text(string.Empty);
}
}
@@ -342,6 +342,10 @@ internal class TexWidget : IDataWindowWidget
runLater?.Invoke();
}
+ /// Adds a texture wrap for debug display purposes.
+ /// Task returning a texture.
+ public void AddTexture(Task textureTask) => this.addedTextures.Add(new(Api10: textureTask));
+
private unsafe void DrawBlame(List allBlames)
{
var im = Service.Get();
diff --git a/Dalamud/Interface/ManagedFontAtlas/IFontHandle.cs b/Dalamud/Interface/ManagedFontAtlas/IFontHandle.cs
index 2853aa4d2..be2f5a742 100644
--- a/Dalamud/Interface/ManagedFontAtlas/IFontHandle.cs
+++ b/Dalamud/Interface/ManagedFontAtlas/IFontHandle.cs
@@ -1,4 +1,5 @@
-using System.Threading.Tasks;
+using System.Threading;
+using System.Threading.Tasks;
using Dalamud.Bindings.ImGui;
@@ -33,10 +34,22 @@ public interface IFontHandle : IDisposable
///
///
/// Use directly if you want to keep the current ImGui font if the font is not ready.
- /// Alternatively, use to wait for this property to become true.
+ /// Alternatively, use to wait for this property to become true.
///
bool Available { get; }
+ ///
+ /// Attempts to lock the fully constructed instance of corresponding to the this
+ /// , for use in any thread.
+ /// Modification of the font will exhibit undefined behavior if some other thread also uses the font.
+ ///
+ /// The error message, if any.
+ ///
+ /// An instance of that must be disposed after use on success;
+ /// null with populated on failure.
+ ///
+ ILockedImFont? TryLock(out string? errorMessage);
+
///
/// Locks the fully constructed instance of corresponding to the this
/// , for use in any thread.
@@ -92,4 +105,11 @@ public interface IFontHandle : IDisposable
///
/// A task containing this .
Task WaitAsync();
+
+ ///
+ /// Waits for to become true.
+ ///
+ /// The cancellation token.
+ /// A task containing this .
+ Task WaitAsync(CancellationToken cancellationToken);
}
diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/FontHandle.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/FontHandle.cs
index 1fdaf4596..98a823deb 100644
--- a/Dalamud/Interface/ManagedFontAtlas/Internals/FontHandle.cs
+++ b/Dalamud/Interface/ManagedFontAtlas/Internals/FontHandle.cs
@@ -238,12 +238,17 @@ internal abstract class FontHandle : IFontHandle
}
///
- public Task WaitAsync()
+ public Task WaitAsync() => this.WaitAsync(CancellationToken.None);
+
+ ///
+ public Task WaitAsync(CancellationToken cancellationToken)
{
if (this.Available)
return Task.FromResult(this);
var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
+ cancellationToken.Register(() => tcs.TrySetCanceled());
+
this.ImFontChanged += OnImFontChanged;
this.Disposed += OnDisposed;
if (this.Available)
diff --git a/Dalamud/Interface/Textures/Internal/TextureManager.FromSeString.cs b/Dalamud/Interface/Textures/Internal/TextureManager.FromSeString.cs
new file mode 100644
index 000000000..3e90ae3ea
--- /dev/null
+++ b/Dalamud/Interface/Textures/Internal/TextureManager.FromSeString.cs
@@ -0,0 +1,35 @@
+using Dalamud.Interface.ImGuiSeStringRenderer;
+using Dalamud.Interface.ImGuiSeStringRenderer.Internal;
+using Dalamud.Interface.Textures.TextureWraps;
+using Dalamud.Utility;
+
+namespace Dalamud.Interface.Textures.Internal;
+
+/// Service responsible for loading and disposing ImGui texture wraps.
+internal sealed partial class TextureManager
+{
+ [ServiceManager.ServiceDependency]
+ private readonly SeStringRenderer seStringRenderer = Service.Get();
+
+ ///
+ public IDalamudTextureWrap CreateTextureFromSeString(
+ ReadOnlySpan text,
+ scoped in SeStringDrawParams drawParams = default,
+ string? debugName = null)
+ {
+ ThreadSafety.AssertMainThread();
+ using var dd = this.seStringRenderer.CreateDrawData(text, drawParams);
+ var texture = this.CreateDrawListTexture(debugName ?? nameof(this.CreateTextureFromSeString));
+ try
+ {
+ texture.Size = dd.Data.DisplaySize;
+ texture.Draw(dd.DataPtr);
+ return texture;
+ }
+ catch
+ {
+ texture.Dispose();
+ throw;
+ }
+ }
+}
diff --git a/Dalamud/Interface/Textures/Internal/TextureManager.cs b/Dalamud/Interface/Textures/Internal/TextureManager.cs
index 059c716ce..d0f0d8c07 100644
--- a/Dalamud/Interface/Textures/Internal/TextureManager.cs
+++ b/Dalamud/Interface/Textures/Internal/TextureManager.cs
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
using Dalamud.Configuration.Internal;
using Dalamud.Data;
using Dalamud.Game;
+using Dalamud.Interface.ImGuiSeStringRenderer.Internal;
using Dalamud.Interface.Internal;
using Dalamud.Interface.Textures.Internal.SharedImmediateTextures;
using Dalamud.Interface.Textures.TextureWraps;
@@ -248,7 +249,7 @@ internal sealed partial class TextureManager
usage = D3D11_USAGE.D3D11_USAGE_DYNAMIC;
else
usage = D3D11_USAGE.D3D11_USAGE_DEFAULT;
-
+
using var texture = this.device.CreateTexture2D(
new()
{
diff --git a/Dalamud/Interface/Textures/Internal/TextureManagerPluginScoped.cs b/Dalamud/Interface/Textures/Internal/TextureManagerPluginScoped.cs
index 9b0fa0943..ac6de7dd7 100644
--- a/Dalamud/Interface/Textures/Internal/TextureManagerPluginScoped.cs
+++ b/Dalamud/Interface/Textures/Internal/TextureManagerPluginScoped.cs
@@ -6,6 +6,7 @@ using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
+using Dalamud.Interface.ImGuiSeStringRenderer;
using Dalamud.Interface.Internal;
using Dalamud.Interface.Textures.TextureWraps;
using Dalamud.IoC;
@@ -283,6 +284,18 @@ internal sealed class TextureManagerPluginScoped
return textureWrap;
}
+ ///
+ public IDalamudTextureWrap CreateTextureFromSeString(
+ ReadOnlySpan text,
+ scoped in SeStringDrawParams drawParams = default,
+ string? debugName = null)
+ {
+ var manager = this.ManagerOrThrow;
+ var textureWrap = manager.CreateTextureFromSeString(text, drawParams, debugName);
+ manager.Blame(textureWrap, this.plugin);
+ return textureWrap;
+ }
+
///
public IEnumerable GetSupportedImageDecoderInfos() =>
this.ManagerOrThrow.Wic.GetSupportedDecoderInfos();
diff --git a/Dalamud/Interface/UiBuilder.cs b/Dalamud/Interface/UiBuilder.cs
index b870e7a94..355b5d571 100644
--- a/Dalamud/Interface/UiBuilder.cs
+++ b/Dalamud/Interface/UiBuilder.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Diagnostics;
+using System.Threading;
using System.Threading.Tasks;
using Dalamud.Bindings.ImGui;
@@ -657,13 +658,14 @@ public sealed class UiBuilder : IDisposable, IUiBuilder
FontAtlasAutoRebuildMode autoRebuildMode,
bool isGlobalScaled = true,
string? debugName = null) =>
- this.scopedFinalizer.Add(Service
- .Get()
- .CreateFontAtlas(
- this.namespaceName + ":" + (debugName ?? "custom"),
- autoRebuildMode,
- isGlobalScaled,
- this.plugin));
+ this.scopedFinalizer.Add(
+ Service
+ .Get()
+ .CreateFontAtlas(
+ this.namespaceName + ":" + (debugName ?? "custom"),
+ autoRebuildMode,
+ isGlobalScaled,
+ this.plugin));
///
/// Unregister the UiBuilder. Do not call this in plugin code.
@@ -825,6 +827,15 @@ public sealed class UiBuilder : IDisposable, IUiBuilder
// Note: do not dispose w; we do not own it
}
+ public ILockedImFont? TryLock(out string? errorMessage)
+ {
+ if (this.wrapped is { } w)
+ return w.TryLock(out errorMessage);
+
+ errorMessage = nameof(ObjectDisposedException);
+ return null;
+ }
+
public ILockedImFont Lock() =>
this.wrapped?.Lock() ?? throw new ObjectDisposedException(nameof(FontHandleWrapper));
@@ -833,7 +844,13 @@ public sealed class UiBuilder : IDisposable, IUiBuilder
public void Pop() => this.WrappedNotDisposed.Pop();
public Task WaitAsync() =>
- this.WrappedNotDisposed.WaitAsync().ContinueWith(_ => (IFontHandle)this);
+ this.wrapped?.WaitAsync().ContinueWith(_ => (IFontHandle)this)
+ ?? Task.FromException(new ObjectDisposedException(nameof(FontHandleWrapper)));
+
+ public Task WaitAsync(CancellationToken cancellationToken) =>
+ this.wrapped?.WaitAsync(cancellationToken)
+ .ContinueWith(_ => (IFontHandle)this, cancellationToken)
+ ?? Task.FromException(new ObjectDisposedException(nameof(FontHandleWrapper)));
public override string ToString() =>
$"{nameof(FontHandleWrapper)}({this.wrapped?.ToString() ?? "disposed"})";
diff --git a/Dalamud/Interface/Utility/BufferBackedImDrawData.cs b/Dalamud/Interface/Utility/BufferBackedImDrawData.cs
new file mode 100644
index 000000000..112fda8a8
--- /dev/null
+++ b/Dalamud/Interface/Utility/BufferBackedImDrawData.cs
@@ -0,0 +1,112 @@
+using System.Numerics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+using Dalamud.Bindings.ImGui;
+
+namespace Dalamud.Interface.Utility;
+
+/// Wrapper aroundx containing one .
+public unsafe struct BufferBackedImDrawData : IDisposable
+{
+ private nint buffer;
+
+ /// Initializes a new instance of the struct.
+ /// Address of buffer to use.
+ private BufferBackedImDrawData(nint buffer) => this.buffer = buffer;
+
+ /// Gets the stored in this buffer.
+ public readonly ref ImDrawData Data => ref ((DataStruct*)this.buffer)->Data;
+
+ /// Gets the stored in this buffer.
+ public readonly ImDrawDataPtr DataPtr => new((ImDrawData*)Unsafe.AsPointer(ref this.Data));
+
+ /// Gets the stored in this buffer.
+ public readonly ref ImDrawList List => ref ((DataStruct*)this.buffer)->List;
+
+ /// Gets the stored in this buffer.
+ public readonly ImDrawListPtr ListPtr => new((ImDrawList*)Unsafe.AsPointer(ref this.List));
+
+ /// Creates a new instance of .
+ /// A new instance of .
+ public static BufferBackedImDrawData Create()
+ {
+ if (ImGui.GetCurrentContext().IsNull || ImGui.GetIO().FontDefault.Handle is null)
+ throw new("ImGui is not ready");
+
+ var res = new BufferBackedImDrawData(Marshal.AllocHGlobal(sizeof(DataStruct)));
+ var ds = (DataStruct*)res.buffer;
+ *ds = default;
+
+ var atlas = ImGui.GetIO().Fonts;
+ ref var atlasTail = ref ImFontAtlasTailReal.From(atlas);
+ ds->SharedData = *ImGui.GetDrawListSharedData().Handle;
+ ds->SharedData.TexIdCommon = atlas.Textures[atlasTail.TextureIndexCommon].TexID;
+ ds->SharedData.TexUvWhitePixel = atlas.TexUvWhitePixel;
+ ds->SharedData.TexUvLines = (Vector4*)Unsafe.AsPointer(ref atlas.TexUvLines[0]);
+ ds->SharedData.Font = ImGui.GetIO().FontDefault;
+ ds->SharedData.FontSize = ds->SharedData.Font->FontSize;
+ ds->SharedData.ClipRectFullscreen = new(
+ float.NegativeInfinity,
+ float.NegativeInfinity,
+ float.PositiveInfinity,
+ float.PositiveInfinity);
+
+ ds->List.Data = &ds->SharedData;
+ ds->ListPtr = &ds->List;
+ ds->Data.CmdLists = &ds->ListPtr;
+ ds->Data.CmdListsCount = 1;
+ ds->Data.FramebufferScale = Vector2.One;
+
+ res.ListPtr._ResetForNewFrame();
+ res.ListPtr.PushClipRectFullScreen();
+ res.ListPtr.PushTextureID(new(atlasTail.TextureIndexCommon));
+ return res;
+ }
+
+ /// Updates the statistics information stored in from .
+ public readonly void UpdateDrawDataStatistics()
+ {
+ this.Data.TotalIdxCount = this.List.IdxBuffer.Size;
+ this.Data.TotalVtxCount = this.List.VtxBuffer.Size;
+ }
+
+ ///
+ public void Dispose()
+ {
+ if (this.buffer != 0)
+ {
+ this.ListPtr._ClearFreeMemory();
+ Marshal.FreeHGlobal(this.buffer);
+ this.buffer = 0;
+ }
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ private struct DataStruct
+ {
+ public ImDrawData Data;
+ public ImDrawList* ListPtr;
+ public ImDrawList List;
+ public ImDrawListSharedData SharedData;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ private struct ImFontAtlasTailReal
+ {
+ /// Index of texture containing the below.
+ public int TextureIndexCommon;
+
+ /// Custom texture rectangle ID for both of the below.
+ public int PackIdCommon;
+
+ /// Custom texture rectangle for white pixel and mouse cursors.
+ public ImFontAtlasCustomRect RectMouseCursors;
+
+ /// Custom texture rectangle for baked anti-aliased lines.
+ public ImFontAtlasCustomRect RectLines;
+
+ public static ref ImFontAtlasTailReal From(ImFontAtlasPtr fontAtlasPtr) =>
+ ref *(ImFontAtlasTailReal*)(&fontAtlasPtr.Handle->FontBuilderFlags + sizeof(uint));
+ }
+}
diff --git a/Dalamud/Interface/Utility/ImGuiHelpers.cs b/Dalamud/Interface/Utility/ImGuiHelpers.cs
index 27cb3596c..98159c1bc 100644
--- a/Dalamud/Interface/Utility/ImGuiHelpers.cs
+++ b/Dalamud/Interface/Utility/ImGuiHelpers.cs
@@ -234,6 +234,15 @@ public static partial class ImGuiHelpers
ImGuiButtonFlags buttonFlags = ImGuiButtonFlags.MouseButtonDefault) =>
Service.Get().CompileAndDrawWrapped(text, style, imGuiId, buttonFlags);
+ /// Creates a draw data that will draw the given SeString onto it.
+ /// SeString to render.
+ /// Initial rendering style.
+ /// A new self-contained draw data.
+ public static BufferBackedImDrawData CreateDrawData(
+ ReadOnlySpan sss,
+ scoped in SeStringDrawParams style = default) =>
+ Service.Get().CreateDrawData(sss, style);
+
///
/// Write unformatted text wrapped.
///
diff --git a/Dalamud/Interface/Utility/Internal/DevTextureSaveMenu.cs b/Dalamud/Interface/Utility/Internal/DevTextureSaveMenu.cs
index 86435e8c1..4a0137c88 100644
--- a/Dalamud/Interface/Utility/Internal/DevTextureSaveMenu.cs
+++ b/Dalamud/Interface/Utility/Internal/DevTextureSaveMenu.cs
@@ -6,10 +6,12 @@ using System.Text;
using System.Threading.Tasks;
using Dalamud.Bindings.ImGui;
+using Dalamud.Game;
using Dalamud.Interface.ImGuiFileDialog;
using Dalamud.Interface.ImGuiNotification;
using Dalamud.Interface.ImGuiNotification.Internal;
using Dalamud.Interface.Internal;
+using Dalamud.Interface.Internal.Windows.Data.Widgets;
using Dalamud.Interface.Textures.Internal;
using Dalamud.Interface.Textures.TextureWraps;
using Serilog;
@@ -33,6 +35,14 @@ internal sealed class DevTextureSaveMenu : IInternalDisposableService
this.interfaceManager.Draw += this.InterfaceManagerOnDraw;
}
+ private enum ContextMenuActionType
+ {
+ None,
+ SaveAsFile,
+ CopyToClipboard,
+ SendToTexWidget,
+ }
+
///
void IInternalDisposableService.DisposeService() => this.interfaceManager.Draw -= this.InterfaceManagerOnDraw;
@@ -66,15 +76,16 @@ internal sealed class DevTextureSaveMenu : IInternalDisposableService
var textureManager = await Service.GetAsync();
var popupName = $"{nameof(this.ShowTextureSaveMenuAsync)}_{textureWrap.Handle.Handle:X}";
+ ContextMenuActionType action;
BitmapCodecInfo? encoder;
{
var first = true;
var encoders = textureManager.Wic.GetSupportedEncoderInfos().ToList();
- var tcs = new TaskCompletionSource(
+ var tcs = new TaskCompletionSource<(ContextMenuActionType Action, BitmapCodecInfo? Codec)>(
TaskCreationOptions.RunContinuationsAsynchronously);
Service.Get().Draw += DrawChoices;
- encoder = await tcs.Task;
+ (action, encoder) = await tcs.Task;
[SuppressMessage("ReSharper", "AccessToDisposedClosure", Justification = "This shall not escape")]
void DrawChoices()
@@ -98,13 +109,20 @@ internal sealed class DevTextureSaveMenu : IInternalDisposableService
}
if (ImGui.Selectable("Copy"u8))
- tcs.TrySetResult(null);
+ tcs.TrySetResult((ContextMenuActionType.CopyToClipboard, null));
+ if (ImGui.Selectable("Send to TexWidget"u8))
+ tcs.TrySetResult((ContextMenuActionType.SendToTexWidget, null));
+
+ ImGui.Separator();
+
foreach (var encoder2 in encoders)
{
if (ImGui.Selectable(encoder2.Name))
- tcs.TrySetResult(encoder2);
+ tcs.TrySetResult((ContextMenuActionType.SaveAsFile, encoder2));
}
+ ImGui.Separator();
+
const float previewImageWidth = 320;
var size = textureWrap.Size;
if (size.X > previewImageWidth)
@@ -120,50 +138,68 @@ internal sealed class DevTextureSaveMenu : IInternalDisposableService
}
}
- if (encoder is null)
+ switch (action)
{
- isCopy = true;
- await textureManager.CopyToClipboardAsync(textureWrap, name, true);
- }
- else
- {
- var props = new Dictionary();
- if (encoder.ContainerGuid == GUID.GUID_ContainerFormatTiff)
- props["CompressionQuality"] = 1.0f;
- else if (encoder.ContainerGuid == GUID.GUID_ContainerFormatJpeg ||
- encoder.ContainerGuid == GUID.GUID_ContainerFormatHeif ||
- encoder.ContainerGuid == GUID.GUID_ContainerFormatWmp)
- props["ImageQuality"] = 1.0f;
+ case ContextMenuActionType.CopyToClipboard:
+ isCopy = true;
+ await textureManager.CopyToClipboardAsync(textureWrap, name, true);
+ break;
- var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
- this.fileDialogManager.SaveFileDialog(
- "Save texture...",
- $"{encoder.Name.Replace(',', '.')}{{{string.Join(',', encoder.Extensions)}}}",
- name + encoder.Extensions.First(),
- encoder.Extensions.First(),
- (ok, path2) =>
- {
- if (!ok)
- tcs.SetCanceled();
- else
- tcs.SetResult(path2);
- });
- var path = await tcs.Task.ConfigureAwait(false);
-
- await textureManager.SaveToFileAsync(textureWrap, encoder.ContainerGuid, path, props: props);
-
- var notif = Service.Get().AddNotification(
- new()
- {
- Content = $"File saved to: {path}",
- Title = initiatorName,
- Type = NotificationType.Success,
- });
- notif.Click += n =>
+ case ContextMenuActionType.SendToTexWidget:
{
- Process.Start(new ProcessStartInfo(path) { UseShellExecute = true });
- n.Notification.DismissNow();
- };
+ var framework = await Service.GetAsync();
+ var dalamudInterface = await Service.GetAsync();
+ await framework.RunOnFrameworkThread(
+ () =>
+ {
+ var texWidget = dalamudInterface.GetDataWindowWidget();
+ dalamudInterface.SetDataWindowWidget(texWidget);
+ texWidget.AddTexture(Task.FromResult(textureWrap.CreateWrapSharingLowLevelResource()));
+ });
+ break;
+ }
+
+ case ContextMenuActionType.SaveAsFile when encoder is not null:
+ {
+ var props = new Dictionary();
+ if (encoder.ContainerGuid == GUID.GUID_ContainerFormatTiff)
+ props["CompressionQuality"] = 1.0f;
+ else if (encoder.ContainerGuid == GUID.GUID_ContainerFormatJpeg ||
+ encoder.ContainerGuid == GUID.GUID_ContainerFormatHeif ||
+ encoder.ContainerGuid == GUID.GUID_ContainerFormatWmp)
+ props["ImageQuality"] = 1.0f;
+
+ var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
+ this.fileDialogManager.SaveFileDialog(
+ "Save texture...",
+ $"{encoder.Name.Replace(',', '.')}{{{string.Join(',', encoder.Extensions)}}}",
+ name + encoder.Extensions.First(),
+ encoder.Extensions.First(),
+ (ok, path2) =>
+ {
+ if (!ok)
+ tcs.SetCanceled();
+ else
+ tcs.SetResult(path2);
+ });
+ var path = await tcs.Task.ConfigureAwait(false);
+
+ await textureManager.SaveToFileAsync(textureWrap, encoder.ContainerGuid, path, props: props);
+
+ var notif = Service.Get().AddNotification(
+ new()
+ {
+ Content = $"File saved to: {path}",
+ Title = initiatorName,
+ Type = NotificationType.Success,
+ });
+ notif.Click += n =>
+ {
+ Process.Start(new ProcessStartInfo(path) { UseShellExecute = true });
+ n.Notification.DismissNow();
+ };
+ break;
+ }
}
}
catch (Exception e)
diff --git a/Dalamud/Plugin/Services/ITextureProvider.cs b/Dalamud/Plugin/Services/ITextureProvider.cs
index a8ad76995..9c499d3f5 100644
--- a/Dalamud/Plugin/Services/ITextureProvider.cs
+++ b/Dalamud/Plugin/Services/ITextureProvider.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
@@ -6,6 +6,7 @@ using System.Threading;
using System.Threading.Tasks;
using Dalamud.Bindings.ImGui;
+using Dalamud.Interface.ImGuiSeStringRenderer;
using Dalamud.Interface.Internal.Windows.Data.Widgets;
using Dalamud.Interface.Textures;
using Dalamud.Interface.Textures.TextureWraps;
@@ -186,6 +187,17 @@ public interface ITextureProvider
string? debugName = null,
CancellationToken cancellationToken = default);
+ /// Creates a texture by drawing a SeString onto it.
+ /// SeString to render.
+ /// Parameters for drawing.
+ /// Name for debug display purposes.
+ /// The new texture.
+ /// Can be only be used from the main thread.
+ public IDalamudTextureWrap CreateTextureFromSeString(
+ ReadOnlySpan text,
+ scoped in SeStringDrawParams drawParams = default,
+ string? debugName = null);
+
/// Gets the supported bitmap decoders.
/// The supported bitmap decoders.
///
From 40e63f2d9a7e015f1c7659f714d6aff1c3397918 Mon Sep 17 00:00:00 2001
From: Soreepeong <3614868+Soreepeong@users.noreply.github.com>
Date: Mon, 11 Aug 2025 00:44:02 +0900
Subject: [PATCH 02/50] Enable viewport alpha
---
Dalamud/Interface/Windowing/Window.cs | 21 +++++++++------------
lib/cimgui | 2 +-
2 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/Dalamud/Interface/Windowing/Window.cs b/Dalamud/Interface/Windowing/Window.cs
index d302552f5..a6b5e0801 100644
--- a/Dalamud/Interface/Windowing/Window.cs
+++ b/Dalamud/Interface/Windowing/Window.cs
@@ -449,11 +449,8 @@ public abstract class Window
}
// Not supported yet on non-main viewports
- if ((this.internalIsPinned || this.internalIsClickthrough || this.internalAlpha.HasValue) &&
- ImGui.GetWindowViewport().ID != ImGui.GetMainViewport().ID)
+ if (this.internalIsClickthrough && ImGui.GetWindowViewport().ID != ImGui.GetMainViewport().ID)
{
- this.internalAlpha = null;
- this.internalIsPinned = false;
this.internalIsClickthrough = false;
this.presetDirty = true;
}
@@ -482,11 +479,6 @@ public abstract class Window
if (ImGui.BeginPopup(additionsPopupName, ImGuiWindowFlags.NoMove))
{
- var isAvailable = ImGuiHelpers.CheckIsWindowOnMainViewport();
-
- if (!isAvailable)
- ImGui.BeginDisabled();
-
if (this.internalIsClickthrough)
ImGui.BeginDisabled();
@@ -506,6 +498,11 @@ public abstract class Window
if (this.internalIsClickthrough)
ImGui.EndDisabled();
+ var isAvailable = ImGuiHelpers.CheckIsWindowOnMainViewport();
+
+ if (!isAvailable)
+ ImGui.BeginDisabled();
+
if (this.AllowClickthrough)
{
if (ImGui.Checkbox(
@@ -519,6 +516,9 @@ public abstract class Window
Loc.Localize("WindowSystemContextActionClickthroughHint", "Clickthrough windows will not receive mouse input, move or resize. They are completely inert."));
}
+ if (!isAvailable)
+ ImGui.EndDisabled();
+
var alpha = (this.internalAlpha ?? ImGui.GetStyle().Alpha) * 100f;
if (ImGui.SliderFloat(Loc.Localize("WindowSystemContextActionAlpha", "Opacity"), ref alpha, 20f,
100f))
@@ -547,9 +547,6 @@ public abstract class Window
"These features are only available if this window is inside the game window."));
}
- if (!isAvailable)
- ImGui.EndDisabled();
-
if (ImGui.Button(Loc.Localize("WindowSystemContextActionPrintWindow", "Print window")))
printWindow = true;
diff --git a/lib/cimgui b/lib/cimgui
index 27c8565f6..68cce5e21 160000
--- a/lib/cimgui
+++ b/lib/cimgui
@@ -1 +1 @@
-Subproject commit 27c8565f631b004c3266373890e41ecc627f775b
+Subproject commit 68cce5e2185948612eb80d981d4001b9737c32cf
From e5451c37af8dc2f9b24c6bee35c2416e6a65b3a0 Mon Sep 17 00:00:00 2001
From: Soreepeong <3614868+Soreepeong@users.noreply.github.com>
Date: Tue, 12 Aug 2025 16:18:49 +0900
Subject: [PATCH 03/50] Update InputHandler to match changes in
imgui_impl_win32.cpp
---
.../InputHandler/Win32InputHandler.cs | 255 ++++++++++--------
.../Internal/Windows/TitleScreenMenuWindow.cs | 3 +-
imgui/Dalamud.Bindings.ImGui/ImVector.cs | 237 ++++++++++------
3 files changed, 308 insertions(+), 187 deletions(-)
diff --git a/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.cs b/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.cs
index 596df4c67..62e254a1a 100644
--- a/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.cs
+++ b/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.cs
@@ -34,11 +34,12 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
private readonly HCURSOR[] cursors;
private readonly WndProcDelegate wndProcDelegate;
- private readonly bool[] imguiMouseIsDown;
private readonly nint platformNamePtr;
private ViewportHandler viewportHandler;
+ private int mouseButtonsDown;
+ private bool mouseTracked;
private long lastTime;
private nint iniPathPtr;
@@ -64,7 +65,8 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
io.BackendFlags |= ImGuiBackendFlags.HasMouseCursors |
ImGuiBackendFlags.HasSetMousePos |
ImGuiBackendFlags.RendererHasViewports |
- ImGuiBackendFlags.PlatformHasViewports;
+ ImGuiBackendFlags.PlatformHasViewports |
+ ImGuiBackendFlags.HasMouseHoveredViewport;
this.platformNamePtr = Marshal.StringToHGlobalAnsi("imgui_impl_win32_c#");
io.Handle->BackendPlatformName = (byte*)this.platformNamePtr;
@@ -74,8 +76,6 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
if (io.ConfigFlags.HasFlag(ImGuiConfigFlags.ViewportsEnable))
this.viewportHandler = new(this);
- this.imguiMouseIsDown = new bool[5];
-
this.cursors = new HCURSOR[9];
this.cursors[(int)ImGuiMouseCursor.Arrow] = LoadCursorW(default, IDC.IDC_ARROW);
this.cursors[(int)ImGuiMouseCursor.TextInput] = LoadCursorW(default, IDC.IDC_IBEAM);
@@ -95,8 +95,6 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
private delegate LRESULT WndProcDelegate(HWND hWnd, uint uMsg, WPARAM wparam, LPARAM lparam);
- private delegate BOOL MonitorEnumProcDelegate(HMONITOR monitor, HDC hdc, RECT* rect, LPARAM lparam);
-
///
public bool UpdateCursor { get; set; } = true;
@@ -155,6 +153,7 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
public void NewFrame(int targetWidth, int targetHeight)
{
var io = ImGui.GetIO();
+ var focusedWindow = GetForegroundWindow();
io.DisplaySize.X = targetWidth;
io.DisplaySize.Y = targetHeight;
@@ -168,9 +167,9 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
this.viewportHandler.UpdateMonitors();
- this.UpdateMousePos();
+ this.UpdateMouseData(focusedWindow);
- this.ProcessKeyEventsWorkarounds();
+ this.ProcessKeyEventsWorkarounds(focusedWindow);
// TODO: need to figure out some way to unify all this
// The bottom case works(?) if the caller hooks SetCursor, but otherwise causes fps issues
@@ -224,6 +223,40 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
switch (msg)
{
+ case WM.WM_MOUSEMOVE:
+ {
+ if (!this.mouseTracked)
+ {
+ var tme = new TRACKMOUSEEVENT
+ {
+ cbSize = (uint)sizeof(TRACKMOUSEEVENT),
+ dwFlags = TME.TME_LEAVE,
+ hwndTrack = hWndCurrent,
+ };
+ this.mouseTracked = TrackMouseEvent(&tme);
+ }
+
+ var mousePos = new POINT(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ if ((io.ConfigFlags & ImGuiConfigFlags.ViewportsEnable) != 0)
+ ClientToScreen(hWndCurrent, &mousePos);
+ io.AddMousePosEvent(mousePos.x, mousePos.y);
+ break;
+ }
+
+ case WM.WM_MOUSELEAVE:
+ {
+ this.mouseTracked = false;
+ var mouseScreenPos = new POINT(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ ClientToScreen(hWndCurrent, &mouseScreenPos);
+ if (this.ViewportFromPoint(mouseScreenPos).IsNull)
+ {
+ var fltMax = ImGuiNative.GETFLTMAX();
+ io.AddMousePosEvent(-fltMax, -fltMax);
+ }
+
+ break;
+ }
+
case WM.WM_LBUTTONDOWN:
case WM.WM_LBUTTONDBLCLK:
case WM.WM_RBUTTONDOWN:
@@ -236,11 +269,10 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
var button = GetButton(msg, wParam);
if (io.WantCaptureMouse)
{
- if (!ImGui.IsAnyMouseDown() && GetCapture() == nint.Zero)
+ if (this.mouseButtonsDown == 0 && GetCapture() == nint.Zero)
SetCapture(hWndCurrent);
-
- io.MouseDown[button] = true;
- this.imguiMouseIsDown[button] = true;
+ this.mouseButtonsDown |= 1 << button;
+ io.AddMouseButtonEvent(button, true);
return default(LRESULT);
}
@@ -256,13 +288,12 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
case WM.WM_XBUTTONUP:
{
var button = GetButton(msg, wParam);
- if (io.WantCaptureMouse && this.imguiMouseIsDown[button])
+ if (io.WantCaptureMouse)
{
- if (!ImGui.IsAnyMouseDown() && GetCapture() == hWndCurrent)
+ this.mouseButtonsDown &= ~(1 << button);
+ if (this.mouseButtonsDown == 0 && GetCapture() == hWndCurrent)
ReleaseCapture();
-
- io.MouseDown[button] = false;
- this.imguiMouseIsDown[button] = false;
+ io.AddMouseButtonEvent(button, false);
return default(LRESULT);
}
@@ -272,7 +303,7 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
case WM.WM_MOUSEWHEEL:
if (io.WantCaptureMouse)
{
- io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
+ io.AddMouseWheelEvent(0, GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA);
return default(LRESULT);
}
@@ -280,7 +311,7 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
case WM.WM_MOUSEHWHEEL:
if (io.WantCaptureMouse)
{
- io.MouseWheelH += GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
+ io.AddMouseWheelEvent(GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA, 0);
return default(LRESULT);
}
@@ -374,68 +405,86 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
this.viewportHandler.UpdateMonitors();
break;
- case WM.WM_KILLFOCUS when hWndCurrent == this.hWnd:
- if (!ImGui.IsAnyMouseDown() && GetCapture() == hWndCurrent)
- ReleaseCapture();
+ case WM.WM_SETFOCUS when hWndCurrent == this.hWnd:
+ io.AddFocusEvent(true);
+ break;
- ImGui.GetIO().WantCaptureMouse = false;
- ImGui.ClearWindowFocus();
+ case WM.WM_KILLFOCUS when hWndCurrent == this.hWnd:
+ io.AddFocusEvent(false);
+ // if (!ImGui.IsAnyMouseDown() && GetCapture() == hWndCurrent)
+ // ReleaseCapture();
+ //
+ // ImGui.GetIO().WantCaptureMouse = false;
+ // ImGui.ClearWindowFocus();
break;
}
return null;
}
- private void UpdateMousePos()
+ private void UpdateMouseData(HWND focusedWindow)
{
var io = ImGui.GetIO();
- var pt = default(POINT);
- // Depending on if Viewports are enabled, we have to change how we process
- // the cursor position. If viewports are enabled, we pass the absolute cursor
- // position to ImGui. Otherwise, we use the old method of passing client-local
- // mouse position to ImGui.
- if (io.ConfigFlags.HasFlag(ImGuiConfigFlags.ViewportsEnable))
+ var mouseScreenPos = default(POINT);
+ var hasMouseScreenPos = GetCursorPos(&mouseScreenPos) != 0;
+
+ var isAppFocused =
+ focusedWindow != default
+ && (focusedWindow == this.hWnd
+ || IsChild(focusedWindow, this.hWnd)
+ || !ImGui.FindViewportByPlatformHandle(focusedWindow).IsNull);
+
+ if (isAppFocused)
{
+ // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
+ // When multi-viewports are enabled, all Dear ImGui positions are same as OS positions.
if (io.WantSetMousePos)
{
- SetCursorPos((int)io.MousePos.X, (int)io.MousePos.Y);
+ var pos = new POINT((int)io.MousePos.X, (int)io.MousePos.Y);
+ if ((io.ConfigFlags & ImGuiConfigFlags.ViewportsEnable) != 0)
+ ClientToScreen(this.hWnd, &pos);
+ SetCursorPos(pos.x, pos.y);
}
- if (GetCursorPos(&pt))
+ // (Optional) Fallback to provide mouse position when focused (WM_MOUSEMOVE already provides this when hovered or captured)
+ if (!io.WantSetMousePos && !this.mouseTracked && hasMouseScreenPos)
{
- io.MousePos.X = pt.x;
- io.MousePos.Y = pt.y;
- }
- else
- {
- io.MousePos.X = float.MinValue;
- io.MousePos.Y = float.MinValue;
+ // Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
+ // (This is the position you can get with ::GetCursorPos() + ::ScreenToClient() or WM_MOUSEMOVE.)
+ // Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
+ // (This is the position you can get with ::GetCursorPos() or WM_MOUSEMOVE + ::ClientToScreen(). In theory adding viewport->Pos to a client position would also be the same.)
+ var mousePos = mouseScreenPos;
+ if ((io.ConfigFlags & ImGuiConfigFlags.ViewportsEnable) == 0)
+ ClientToScreen(focusedWindow, &mousePos);
+ io.AddMousePosEvent(mousePos.x, mousePos.y);
}
}
+
+ // (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering.
+ // If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic.
+ // - [X] Win32 backend correctly ignore viewports with the _NoInputs flag (here using ::WindowFromPoint with WM_NCHITTEST + HTTRANSPARENT in WndProc does that)
+ // Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window
+ // for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported
+ // by the backend, and use its flawed heuristic to guess the viewport behind.
+ // - [X] Win32 backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target).
+ if (hasMouseScreenPos)
+ {
+ var viewport = this.ViewportFromPoint(mouseScreenPos);
+ io.AddMouseViewportEvent(!viewport.IsNull ? viewport.ID : 0u);
+ }
else
{
- if (io.WantSetMousePos)
- {
- pt.x = (int)io.MousePos.X;
- pt.y = (int)io.MousePos.Y;
- ClientToScreen(this.hWnd, &pt);
- SetCursorPos(pt.x, pt.y);
- }
-
- if (GetCursorPos(&pt) && ScreenToClient(this.hWnd, &pt))
- {
- io.MousePos.X = pt.x;
- io.MousePos.Y = pt.y;
- }
- else
- {
- io.MousePos.X = float.MinValue;
- io.MousePos.Y = float.MinValue;
- }
+ io.AddMouseViewportEvent(0);
}
}
+ private ImGuiViewportPtr ViewportFromPoint(POINT mouseScreenPos)
+ {
+ var hoveredHwnd = WindowFromPoint(mouseScreenPos);
+ return hoveredHwnd != default ? ImGui.FindViewportByPlatformHandle(hoveredHwnd) : default;
+ }
+
private bool UpdateMouseCursor()
{
var io = ImGui.GetIO();
@@ -451,7 +500,7 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
return true;
}
- private void ProcessKeyEventsWorkarounds()
+ private void ProcessKeyEventsWorkarounds(HWND focusedWindow)
{
// Left & right Shift keys: when both are pressed together, Windows tend to not generate the WM_KEYUP event for the first released one.
if (ImGui.IsKeyDown(ImGuiKey.LeftShift) && !IsVkDown(VK.VK_LSHIFT))
@@ -480,7 +529,7 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
{
// See: https://github.com/goatcorp/ImGuiScene/pull/13
// > GetForegroundWindow from winuser.h is a surprisingly expensive function.
- var isForeground = GetForegroundWindow() == this.hWnd;
+ var isForeground = focusedWindow == this.hWnd;
for (var i = (int)ImGuiKey.NamedKeyBegin; i < (int)ImGuiKey.NamedKeyEnd; i++)
{
// Skip raising modifier keys if the game is focused.
@@ -646,14 +695,7 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
return;
var pio = ImGui.GetPlatformIO();
-
- if (ImGui.GetPlatformIO().Handle->Monitors.Data != null)
- {
- // We allocated the platform monitor data in OnUpdateMonitors ourselves,
- // so we have to free it ourselves to ImGui doesn't try to, or else it will crash
- Marshal.FreeHGlobal(new IntPtr(ImGui.GetPlatformIO().Handle->Monitors.Data));
- ImGui.GetPlatformIO().Handle->Monitors = default;
- }
+ ImGui.GetPlatformIO().Handle->Monitors.Free();
fixed (char* windowClassNamePtr = WindowClassName)
{
@@ -693,59 +735,50 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
// Here we use a manual ImVector overload, free the existing monitor data,
// and allocate our own, as we are responsible for telling ImGui about monitors
var pio = ImGui.GetPlatformIO();
- var numMonitors = GetSystemMetrics(SM.SM_CMONITORS);
- var data = Marshal.AllocHGlobal(Marshal.SizeOf() * numMonitors);
- if (pio.Handle->Monitors.Data != null)
- Marshal.FreeHGlobal(new IntPtr(pio.Handle->Monitors.Data));
- pio.Handle->Monitors = new(numMonitors, numMonitors, (ImGuiPlatformMonitor*)data.ToPointer());
+ pio.Handle->Monitors.Resize(0);
- // ImGuiPlatformIOPtr platformIO = ImGui.GetPlatformIO();
- // Marshal.FreeHGlobal(platformIO.Handle->Monitors.Data);
- // int numMonitors = GetSystemMetrics(SystemMetric.SM_CMONITORS);
- // nint data = Marshal.AllocHGlobal(Marshal.SizeOf() * numMonitors);
- // platformIO.Handle->Monitors = new ImVector(numMonitors, numMonitors, data);
-
- var monitorIndex = -1;
- var enumfn = new MonitorEnumProcDelegate(
- (hMonitor, _, _, _) =>
- {
- monitorIndex++;
- var info = new MONITORINFO { cbSize = (uint)sizeof(MONITORINFO) };
- if (!GetMonitorInfoW(hMonitor, &info))
- return true;
-
- var monitorLt = new Vector2(info.rcMonitor.left, info.rcMonitor.top);
- var monitorRb = new Vector2(info.rcMonitor.right, info.rcMonitor.bottom);
- var workLt = new Vector2(info.rcWork.left, info.rcWork.top);
- var workRb = new Vector2(info.rcWork.right, info.rcWork.bottom);
- // Give ImGui the info for this display
-
- ref var imMonitor = ref ImGui.GetPlatformIO().Monitors.Ref(monitorIndex);
- imMonitor.MainPos = monitorLt;
- imMonitor.MainSize = monitorRb - monitorLt;
- imMonitor.WorkPos = workLt;
- imMonitor.WorkSize = workRb - workLt;
- imMonitor.DpiScale = 1f;
- return true;
- });
- EnumDisplayMonitors(
- default,
- null,
- (delegate* unmanaged)Marshal.GetFunctionPointerForDelegate(enumfn),
- default);
+ EnumDisplayMonitors(default, null, &EnumDisplayMonitorsCallback, default);
Log.Information("Monitors set up!");
- for (var i = 0; i < numMonitors; i++)
+ foreach (ref var monitor in pio.Handle->Monitors)
{
- var monitor = pio.Handle->Monitors[i];
Log.Information(
- "Monitor {Index}: {MainPos} {MainSize} {WorkPos} {WorkSize}",
- i,
+ "Monitor: {MainPos} {MainSize} {WorkPos} {WorkSize}",
monitor.MainPos,
monitor.MainSize,
monitor.WorkPos,
monitor.WorkSize);
}
+
+ return;
+
+ [UnmanagedCallersOnly]
+ static BOOL EnumDisplayMonitorsCallback(HMONITOR hMonitor, HDC hdc, RECT* rect, LPARAM lParam)
+ {
+ var info = new MONITORINFO { cbSize = (uint)sizeof(MONITORINFO) };
+ if (!GetMonitorInfoW(hMonitor, &info))
+ return true;
+
+ var monitorLt = new Vector2(info.rcMonitor.left, info.rcMonitor.top);
+ var monitorRb = new Vector2(info.rcMonitor.right, info.rcMonitor.bottom);
+ var workLt = new Vector2(info.rcWork.left, info.rcWork.top);
+ var workRb = new Vector2(info.rcWork.right, info.rcWork.bottom);
+
+ // Give ImGui the info for this display
+ var imMonitor = new ImGuiPlatformMonitor
+ {
+ MainPos = monitorLt,
+ MainSize = monitorRb - monitorLt,
+ WorkPos = workLt,
+ WorkSize = workRb - workLt,
+ DpiScale = 1f,
+ };
+ if ((info.dwFlags & MONITORINFOF_PRIMARY) != 0)
+ ImGui.GetPlatformIO().Monitors.PushFront(imMonitor);
+ else
+ ImGui.GetPlatformIO().Monitors.PushBack(imMonitor);
+ return true;
+ }
}
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])]
diff --git a/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs b/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs
index e3eb22a04..69cdc4d28 100644
--- a/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs
@@ -86,7 +86,8 @@ internal class TitleScreenMenuWindow : Window, IDisposable
: base(
"TitleScreenMenuOverlay",
ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoScrollbar |
- ImGuiWindowFlags.NoBackground | ImGuiWindowFlags.NoFocusOnAppearing | ImGuiWindowFlags.NoNavFocus)
+ ImGuiWindowFlags.NoBackground | ImGuiWindowFlags.NoFocusOnAppearing | ImGuiWindowFlags.NoNavFocus |
+ ImGuiWindowFlags.NoDocking)
{
this.showTsm = consoleManager.AddVariable("dalamud.show_tsm", "Show the Title Screen Menu", true);
diff --git a/imgui/Dalamud.Bindings.ImGui/ImVector.cs b/imgui/Dalamud.Bindings.ImGui/ImVector.cs
index 9a10c1d6b..67e450193 100644
--- a/imgui/Dalamud.Bindings.ImGui/ImVector.cs
+++ b/imgui/Dalamud.Bindings.ImGui/ImVector.cs
@@ -1,7 +1,12 @@
-using System.Runtime.CompilerServices;
+using System.Collections;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
namespace Dalamud.Bindings.ImGui;
+///
+/// A structure representing a dynamic array for unmanaged types.
+///
public unsafe struct ImVector
{
public readonly int Size;
@@ -15,23 +20,23 @@ public unsafe struct ImVector
Data = data;
}
- public ref T Ref(int index)
- {
- return ref Unsafe.AsRef((byte*)Data + index * Unsafe.SizeOf());
- }
+ public readonly ref T Ref(int index) => ref Unsafe.AsRef((byte*)this.Data + (index * Unsafe.SizeOf()));
- public IntPtr Address(int index)
- {
- return (IntPtr)((byte*)Data + index * Unsafe.SizeOf());
- }
+ public readonly nint Address(int index) => (nint)((byte*)this.Data + (index * Unsafe.SizeOf()));
}
///
/// A structure representing a dynamic array for unmanaged types.
///
/// The type of elements in the vector, must be unmanaged.
-public unsafe struct ImVector where T : unmanaged
+[StructLayout(LayoutKind.Sequential)]
+public unsafe struct ImVector : IEnumerable
+ where T : unmanaged
{
+ private int size;
+ private int capacity;
+ private T* data;
+
///
/// Initializes a new instance of the struct with the specified size, capacity, and data pointer.
///
@@ -45,11 +50,6 @@ public unsafe struct ImVector where T : unmanaged
this.data = data;
}
- private int size;
- private int capacity;
- private unsafe T* data;
-
-
///
/// Gets or sets the element at the specified index.
///
@@ -58,80 +58,72 @@ public unsafe struct ImVector where T : unmanaged
/// Thrown when the index is out of range.
public T this[int index]
{
- get
+ readonly get
{
- if (index < 0 || index >= size)
- {
+ if (index < 0 || index >= this.size)
throw new IndexOutOfRangeException();
- }
- return data[index];
+ return this.data[index];
}
set
{
- if (index < 0 || index >= size)
- {
+ if (index < 0 || index >= this.size)
throw new IndexOutOfRangeException();
- }
- data[index] = value;
+ this.data[index] = value;
}
}
///
/// Gets a pointer to the first element of the vector.
///
- public readonly T* Data => data;
+ public readonly T* Data => this.data;
///
/// Gets a pointer to the first element of the vector.
///
- public readonly T* Front => data;
+ public readonly T* Front => this.data;
///
/// Gets a pointer to the last element of the vector.
///
- public readonly T* Back => size > 0 ? data + size - 1 : null;
+ public readonly T* Back => this.size > 0 ? this.data + this.size - 1 : null;
///
/// Gets or sets the capacity of the vector.
///
public int Capacity
{
- readonly get => capacity;
+ readonly get => this.capacity;
set
{
- if (capacity == value)
- {
+ ArgumentOutOfRangeException.ThrowIfLessThan(value, this.size, nameof(Capacity));
+ if (this.capacity == value)
return;
- }
- if (data == null)
+ if (this.data == null)
{
- data = (T*)ImGui.MemAlloc((nuint)(value * sizeof(T)));
+ this.data = (T*)ImGui.MemAlloc((nuint)(value * sizeof(T)));
}
else
{
- int newSize = Math.Min(size, value);
- T* newData = (T*)ImGui.MemAlloc((nuint)(value * sizeof(T)));
- Buffer.MemoryCopy(data, newData, (nuint)(value * sizeof(T)), (nuint)(newSize * sizeof(T)));
- ImGui.MemFree(data);
- data = newData;
- size = newSize;
+ var newSize = Math.Min(this.size, value);
+ var newData = (T*)ImGui.MemAlloc((nuint)(value * sizeof(T)));
+ Buffer.MemoryCopy(this.data, newData, (nuint)(value * sizeof(T)), (nuint)(newSize * sizeof(T)));
+ ImGui.MemFree(this.data);
+ this.data = newData;
+ this.size = newSize;
}
- capacity = value;
+ this.capacity = value;
// Clear the rest of the data
- for (int i = size; i < capacity; i++)
- {
- data[i] = default;
- }
+ new Span(this.data + this.size, this.capacity - this.size).Clear();
}
}
///
/// Gets the number of elements in the vector.
///
- public readonly int Size => size;
+ public readonly int Size => this.size;
///
/// Grows the capacity of the vector to at least the specified value.
@@ -139,10 +131,8 @@ public unsafe struct ImVector where T : unmanaged
/// The new capacity.
public void Grow(int newCapacity)
{
- if (newCapacity > capacity)
- {
- Capacity = newCapacity * 2;
- }
+ var newCapacity2 = this.capacity > 0 ? this.capacity + (this.capacity / 2) : 8;
+ this.Capacity = newCapacity2 > newCapacity ? newCapacity2 : newCapacity;
}
///
@@ -151,10 +141,8 @@ public unsafe struct ImVector where T : unmanaged
/// The minimum capacity required.
public void EnsureCapacity(int size)
{
- if (size > capacity)
- {
+ if (size > this.capacity)
Grow(size);
- }
}
///
@@ -164,25 +152,46 @@ public unsafe struct ImVector where T : unmanaged
public void Resize(int newSize)
{
EnsureCapacity(newSize);
- size = newSize;
+ this.size = newSize;
}
///
/// Clears all elements from the vector.
///
- public void Clear()
+ public void Clear() => this.size = 0;
+
+ ///
+ /// Adds an element to the end of the vector.
+ ///
+ /// The value to add.
+ [OverloadResolutionPriority(1)]
+ public void PushBack(T value)
{
- size = 0;
+ this.EnsureCapacity(this.size + 1);
+ this.data[this.size++] = value;
}
///
/// Adds an element to the end of the vector.
///
/// The value to add.
- public void PushBack(T value)
+ [OverloadResolutionPriority(2)]
+ public void PushBack(in T value)
{
- EnsureCapacity(size + 1);
- data[size++] = value;
+ EnsureCapacity(this.size + 1);
+ this.data[this.size++] = value;
+ }
+
+ ///
+ /// Adds an element to the front of the vector.
+ ///
+ /// The value to add.
+ public void PushFront(in T value)
+ {
+ if (this.size == 0)
+ this.PushBack(value);
+ else
+ this.Insert(0, value);
}
///
@@ -190,48 +199,126 @@ public unsafe struct ImVector where T : unmanaged
///
public void PopBack()
{
- if (size > 0)
+ if (this.size > 0)
{
- size--;
+ this.size--;
}
}
+ public ref T Insert(int index, in T v) {
+ ArgumentOutOfRangeException.ThrowIfNegative(index, nameof(index));
+ ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(index, this.size, nameof(index));
+ this.EnsureCapacity(this.size + 1);
+ if (index < this.size)
+ {
+ Buffer.MemoryCopy(
+ this.data + index,
+ this.data + index + 1,
+ (this.size - index) * sizeof(T),
+ (this.size - index) * sizeof(T));
+ }
+
+ this.data[index] = v;
+ this.size++;
+ return ref this.data[index];
+ }
+
+ public Span InsertRange(int index, ReadOnlySpan v)
+ {
+ ArgumentOutOfRangeException.ThrowIfNegative(index, nameof(index));
+ ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(index, this.size, nameof(index));
+ this.EnsureCapacity(this.size + v.Length);
+ if (index < this.size)
+ {
+ Buffer.MemoryCopy(
+ this.data + index,
+ this.data + index + v.Length,
+ (this.size - index) * sizeof(T),
+ (this.size - index) * sizeof(T));
+ }
+
+ var dstSpan = new Span(this.data + index, v.Length);
+ v.CopyTo(new(this.data + index, v.Length));
+ this.size += v.Length;
+ return dstSpan;
+ }
+
///
/// Frees the memory allocated for the vector.
///
public void Free()
{
- if (data != null)
+ if (this.data != null)
{
- ImGui.MemFree(data);
- data = null;
- size = 0;
- capacity = 0;
+ ImGui.MemFree(this.data);
+ this.data = null;
+ this.size = 0;
+ this.capacity = 0;
}
}
- public ref T Ref(int index)
+ public readonly ref T Ref(int index)
{
- return ref Unsafe.AsRef((byte*)Data + index * Unsafe.SizeOf());
+ return ref Unsafe.AsRef((byte*)Data + (index * Unsafe.SizeOf()));
}
- public ref TCast Ref(int index)
+ public readonly ref TCast Ref(int index)
{
- return ref Unsafe.AsRef((byte*)Data + index * Unsafe.SizeOf());
+ return ref Unsafe.AsRef((byte*)Data + (index * Unsafe.SizeOf()));
}
- public void* Address(int index)
+ public readonly void* Address(int index)
{
- return (byte*)Data + index * Unsafe.SizeOf();
+ return (byte*)Data + (index * Unsafe.SizeOf());
}
- public void* Address(int index)
+ public readonly void* Address(int index)
{
- return (byte*)Data + index * Unsafe.SizeOf();
+ return (byte*)Data + (index * Unsafe.SizeOf());
}
- public ImVector* ToUntyped()
+ public readonly ImVector* ToUntyped()
{
- return (ImVector*)Unsafe.AsPointer(ref this);
+ return (ImVector*)Unsafe.AsPointer(ref Unsafe.AsRef(in this));
+ }
+
+ public readonly Span AsSpan() => new(this.data, this.size);
+
+ public readonly Enumerator GetEnumerator() => new(this.data, this.data + this.size);
+
+ readonly IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
+
+ readonly IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
+
+ public struct Enumerator(T* begin, T* end) : IEnumerator, IEnumerable
+ {
+ private T* current = null;
+
+ public readonly ref T Current => ref *this.current;
+
+ readonly T IEnumerator.Current => this.Current;
+
+ readonly object IEnumerator.Current => this.Current;
+
+ public bool MoveNext()
+ {
+ var next = this.current == null ? begin : this.current + 1;
+ if (next == end)
+ return false;
+ this.current = next;
+ return true;
+ }
+
+ public void Reset() => this.current = null;
+
+ public readonly Enumerator GetEnumerator() => new(begin, end);
+
+ readonly void IDisposable.Dispose()
+ {
+ }
+
+ readonly IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
+
+ readonly IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
}
}
From 544f8b28bfc115968ea53fbfb08207c6d7d010ea Mon Sep 17 00:00:00 2001
From: Soreepeong <3614868+Soreepeong@users.noreply.github.com>
Date: Sat, 16 Aug 2025 16:42:30 +0900
Subject: [PATCH 04/50] Support make clickthrough
---
...Win32InputHandler.StaticLookupFunctions.cs | 9 +-
.../InputHandler/Win32InputHandler.cs | 28 ++--
Dalamud/Interface/Windowing/Window.cs | 133 ++++++++----------
3 files changed, 79 insertions(+), 91 deletions(-)
diff --git a/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.StaticLookupFunctions.cs b/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.StaticLookupFunctions.cs
index 5710a5991..a7b70ce35 100644
--- a/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.StaticLookupFunctions.cs
+++ b/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.StaticLookupFunctions.cs
@@ -299,11 +299,12 @@ internal sealed partial class Win32InputHandler
private static void ViewportFlagsToWin32Styles(ImGuiViewportFlags flags, out int style, out int exStyle)
{
- style = (int)(flags.HasFlag(ImGuiViewportFlags.NoDecoration) ? WS.WS_POPUP : WS.WS_OVERLAPPEDWINDOW);
- exStyle =
- (int)(flags.HasFlag(ImGuiViewportFlags.NoTaskBarIcon) ? WS.WS_EX_TOOLWINDOW : (uint)WS.WS_EX_APPWINDOW);
+ style = (flags & ImGuiViewportFlags.NoDecoration) != 0 ? unchecked((int)WS.WS_POPUP) : WS.WS_OVERLAPPEDWINDOW;
+ exStyle = (flags & ImGuiViewportFlags.NoTaskBarIcon) != 0 ? WS.WS_EX_TOOLWINDOW : WS.WS_EX_APPWINDOW;
exStyle |= WS.WS_EX_NOREDIRECTIONBITMAP;
- if (flags.HasFlag(ImGuiViewportFlags.TopMost))
+ if ((flags & ImGuiViewportFlags.TopMost) != 0)
exStyle |= WS.WS_EX_TOPMOST;
+ if ((flags & ImGuiViewportFlags.NoInputs) != 0)
+ exStyle |= WS.WS_EX_TRANSPARENT | WS.WS_EX_LAYERED;
}
}
diff --git a/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.cs b/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.cs
index 62e254a1a..0b2e27b57 100644
--- a/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.cs
+++ b/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.cs
@@ -8,6 +8,7 @@ using System.Text;
using Dalamud.Bindings.ImGui;
using Dalamud.Memory;
+using Dalamud.Utility;
using Serilog;
@@ -446,19 +447,19 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
ClientToScreen(this.hWnd, &pos);
SetCursorPos(pos.x, pos.y);
}
+ }
- // (Optional) Fallback to provide mouse position when focused (WM_MOUSEMOVE already provides this when hovered or captured)
- if (!io.WantSetMousePos && !this.mouseTracked && hasMouseScreenPos)
- {
- // Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
- // (This is the position you can get with ::GetCursorPos() + ::ScreenToClient() or WM_MOUSEMOVE.)
- // Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
- // (This is the position you can get with ::GetCursorPos() or WM_MOUSEMOVE + ::ClientToScreen(). In theory adding viewport->Pos to a client position would also be the same.)
- var mousePos = mouseScreenPos;
- if ((io.ConfigFlags & ImGuiConfigFlags.ViewportsEnable) == 0)
- ClientToScreen(focusedWindow, &mousePos);
- io.AddMousePosEvent(mousePos.x, mousePos.y);
- }
+ // (Optional) Fallback to provide mouse position when focused (WM_MOUSEMOVE already provides this when hovered or captured)
+ if (!io.WantSetMousePos && !this.mouseTracked && hasMouseScreenPos)
+ {
+ // Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
+ // (This is the position you can get with ::GetCursorPos() + ::ScreenToClient() or WM_MOUSEMOVE.)
+ // Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
+ // (This is the position you can get with ::GetCursorPos() or WM_MOUSEMOVE + ::ClientToScreen(). In theory adding viewport->Pos to a client position would also be the same.)
+ var mousePos = mouseScreenPos;
+ if ((io.ConfigFlags & ImGuiConfigFlags.ViewportsEnable) == 0)
+ ClientToScreen(focusedWindow, &mousePos);
+ io.AddMousePosEvent(mousePos.x, mousePos.y);
}
// (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering.
@@ -827,6 +828,9 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
null);
}
+ if (data->Hwnd == 0)
+ Util.Fatal($"CreateWindowExW failed: {GetLastError()}", "ImGui Viewport error");
+
data->HwndOwned = true;
viewport.PlatformRequestResize = false;
viewport.PlatformHandle = viewport.PlatformHandleRaw = data->Hwnd;
diff --git a/Dalamud/Interface/Windowing/Window.cs b/Dalamud/Interface/Windowing/Window.cs
index a6b5e0801..e24f96ff8 100644
--- a/Dalamud/Interface/Windowing/Window.cs
+++ b/Dalamud/Interface/Windowing/Window.cs
@@ -1,9 +1,6 @@
using System.Collections.Generic;
using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Linq;
using System.Numerics;
-using System.Runtime.InteropServices;
using System.Threading.Tasks;
using CheapLoc;
@@ -19,10 +16,13 @@ using Dalamud.Interface.Utility.Internal;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Interface.Windowing.Persistence;
using Dalamud.Logging.Internal;
-using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.UI;
+using TerraFX.Interop.Windows;
+
+using static TerraFX.Interop.Windows.Windows;
+
namespace Dalamud.Interface.Windowing;
///
@@ -31,11 +31,15 @@ namespace Dalamud.Interface.Windowing;
public abstract class Window
{
private const float FadeInOutTime = 0.072f;
+ private const string AdditionsPopupName = "WindowSystemContextActions";
private static readonly ModuleLog Log = new("WindowSystem");
private static bool wasEscPressedLastFrame = false;
+ private readonly TitleBarButton additionsButton;
+ private readonly List allButtons = [];
+
private bool internalLastIsOpen = false;
private bool internalIsOpen = false;
private bool internalIsPinned = false;
@@ -69,6 +73,20 @@ public abstract class Window
this.WindowName = name;
this.Flags = flags;
this.ForceMainWindow = forceMainWindow;
+
+ this.additionsButton = new()
+ {
+ Icon = FontAwesomeIcon.Bars,
+ IconOffset = new Vector2(2.5f, 1),
+ Click = _ =>
+ {
+ this.internalIsClickthrough = false;
+ this.presetDirty = false;
+ ImGui.OpenPopup(AdditionsPopupName);
+ },
+ Priority = int.MinValue,
+ AvailableClickthrough = true,
+ };
}
///
@@ -448,11 +466,12 @@ public abstract class Window
ImGuiP.GetCurrentWindow().InheritNoInputs = this.internalIsClickthrough;
}
- // Not supported yet on non-main viewports
- if (this.internalIsClickthrough && ImGui.GetWindowViewport().ID != ImGui.GetMainViewport().ID)
+ if (ImGui.GetWindowViewport().ID != ImGui.GetMainViewport().ID)
{
- this.internalIsClickthrough = false;
- this.presetDirty = true;
+ if ((flags & ImGuiWindowFlags.NoInputs) == ImGuiWindowFlags.NoInputs)
+ ImGui.GetWindowViewport().Flags |= ImGuiViewportFlags.NoInputs;
+ else
+ ImGui.GetWindowViewport().Flags &= ~ImGuiViewportFlags.NoInputs;
}
// Draw the actual window contents
@@ -466,7 +485,6 @@ public abstract class Window
}
}
- const string additionsPopupName = "WindowSystemContextActions";
var flagsApplicableForTitleBarIcons = !flags.HasFlag(ImGuiWindowFlags.NoDecoration) &&
!flags.HasFlag(ImGuiWindowFlags.NoTitleBar);
var showAdditions = (this.AllowPinning || this.AllowClickthrough) &&
@@ -477,7 +495,7 @@ public abstract class Window
{
ImGui.PushStyleVar(ImGuiStyleVar.Alpha, 1f);
- if (ImGui.BeginPopup(additionsPopupName, ImGuiWindowFlags.NoMove))
+ if (ImGui.BeginPopup(AdditionsPopupName, ImGuiWindowFlags.NoMove))
{
if (this.internalIsClickthrough)
ImGui.BeginDisabled();
@@ -498,11 +516,6 @@ public abstract class Window
if (this.internalIsClickthrough)
ImGui.EndDisabled();
- var isAvailable = ImGuiHelpers.CheckIsWindowOnMainViewport();
-
- if (!isAvailable)
- ImGui.BeginDisabled();
-
if (this.AllowClickthrough)
{
if (ImGui.Checkbox(
@@ -516,9 +529,6 @@ public abstract class Window
Loc.Localize("WindowSystemContextActionClickthroughHint", "Clickthrough windows will not receive mouse input, move or resize. They are completely inert."));
}
- if (!isAvailable)
- ImGui.EndDisabled();
-
var alpha = (this.internalAlpha ?? ImGui.GetStyle().Alpha) * 100f;
if (ImGui.SliderFloat(Loc.Localize("WindowSystemContextActionAlpha", "Opacity"), ref alpha, 20f,
100f))
@@ -534,18 +544,11 @@ public abstract class Window
this.presetDirty = true;
}
- if (isAvailable)
- {
- ImGui.TextColored(ImGuiColors.DalamudGrey,
- Loc.Localize("WindowSystemContextActionClickthroughDisclaimer",
- "Open this menu again by clicking the three dashes to disable clickthrough."));
- }
- else
- {
- ImGui.TextColored(ImGuiColors.DalamudGrey,
- Loc.Localize("WindowSystemContextActionViewportDisclaimer",
- "These features are only available if this window is inside the game window."));
- }
+ ImGui.TextColored(
+ ImGuiColors.DalamudGrey,
+ Loc.Localize(
+ "WindowSystemContextActionClickthroughDisclaimer",
+ "Open this menu again by clicking the three dashes to disable clickthrough."));
if (ImGui.Button(Loc.Localize("WindowSystemContextActionPrintWindow", "Print window")))
printWindow = true;
@@ -556,34 +559,15 @@ public abstract class Window
ImGui.PopStyleVar();
}
- unsafe
+ if (flagsApplicableForTitleBarIcons)
{
- var window = ImGuiP.GetCurrentWindow();
-
- ImRect outRect;
- ImGuiP.TitleBarRect(&outRect, window);
-
- var additionsButton = new TitleBarButton
- {
- Icon = FontAwesomeIcon.Bars,
- IconOffset = new Vector2(2.5f, 1),
- Click = _ =>
- {
- this.internalIsClickthrough = false;
- this.presetDirty = false;
- ImGui.OpenPopup(additionsPopupName);
- },
- Priority = int.MinValue,
- AvailableClickthrough = true,
- };
-
- if (flagsApplicableForTitleBarIcons)
- {
- this.DrawTitleBarButtons(window, flags, outRect,
- showAdditions
- ? this.TitleBarButtons.Append(additionsButton)
- : this.TitleBarButtons);
- }
+ this.allButtons.Clear();
+ this.allButtons.EnsureCapacity(this.TitleBarButtons.Count + 1);
+ this.allButtons.AddRange(this.TitleBarButtons);
+ if (showAdditions)
+ this.allButtons.Add(this.additionsButton);
+ this.allButtons.Sort(static (a, b) => b.Priority - a.Priority);
+ this.DrawTitleBarButtons();
}
if (wasFocused)
@@ -740,8 +724,11 @@ public abstract class Window
}
}
- private unsafe void DrawTitleBarButtons(ImGuiWindowPtr window, ImGuiWindowFlags flags, ImRect titleBarRect, IEnumerable buttons)
+ private unsafe void DrawTitleBarButtons()
{
+ var window = ImGuiP.GetCurrentWindow();
+ var flags = window.Flags;
+ var titleBarRect = window.TitleBarRect();
ImGui.PushClipRect(ImGui.GetWindowPos(), ImGui.GetWindowPos() + ImGui.GetWindowSize(), false);
var style = ImGui.GetStyle();
@@ -776,26 +763,22 @@ public abstract class Window
var max = pos + new Vector2(fontSize, fontSize);
ImRect bb = new(pos, max);
var isClipped = !ImGuiP.ItemAdd(bb, id, null, 0);
- bool hovered, held;
- var pressed = false;
+ bool hovered, held, pressed;
if (this.internalIsClickthrough)
{
- hovered = false;
- held = false;
-
// ButtonBehavior does not function if the window is clickthrough, so we have to do it ourselves
- if (ImGui.IsMouseHoveringRect(pos, max))
- {
- hovered = true;
+ var pad = ImGui.GetStyle().TouchExtraPadding;
+ var rect = new ImRect(pos - pad, max + pad);
+ hovered = rect.Contains(ImGui.GetMousePos());
- // We can't use ImGui native functions here, because they don't work with clickthrough
- if ((global::Windows.Win32.PInvoke.GetKeyState((int)VirtualKey.LBUTTON) & 0x8000) != 0)
- {
- held = true;
- pressed = true;
- }
- }
+ // Temporarily enable inputs
+ // This will be reset on next frame, and then enabled again if it is still being hovered
+ if (hovered && ImGui.GetWindowViewport().ID != ImGui.GetMainViewport().ID)
+ ImGui.GetWindowViewport().Flags &= ~ImGuiViewportFlags.NoInputs;
+
+ // We can't use ImGui native functions here, because they don't work with clickthrough
+ pressed = held = hovered && (GetKeyState(VK.VK_LBUTTON) & 0x8000) != 0;
}
else
{
@@ -824,7 +807,7 @@ public abstract class Window
return pressed;
}
- foreach (var button in buttons.OrderBy(x => x.Priority))
+ foreach (var button in this.allButtons)
{
if (this.internalIsClickthrough && !button.AvailableClickthrough)
return;
@@ -932,7 +915,7 @@ public abstract class Window
///
/// Gets or sets an action that is called when the button is clicked.
///
- public Action Click { get; set; }
+ public Action? Click { get; set; }
///
/// Gets or sets the priority the button shall be shown in.
From 2a60bc61a7713172bf60ff1b2b78076b44473ac4 Mon Sep 17 00:00:00 2001
From: MidoriKami
Date: Thu, 27 Nov 2025 15:52:18 -0800
Subject: [PATCH 05/50] Force style vars so erroring window renders at least
partially sanely
---
Dalamud/Interface/Windowing/Window.cs | 47 ++++++++++++++++++++++++---
1 file changed, 42 insertions(+), 5 deletions(-)
diff --git a/Dalamud/Interface/Windowing/Window.cs b/Dalamud/Interface/Windowing/Window.cs
index f12e87099..5169b9746 100644
--- a/Dalamud/Interface/Windowing/Window.cs
+++ b/Dalamud/Interface/Windowing/Window.cs
@@ -57,6 +57,7 @@ public abstract class Window
private bool hasError = false;
private Exception? lastError;
+ private bool isErrorStylePushed;
///
/// Initializes a new instance of the class.
@@ -425,8 +426,16 @@ public abstract class Window
UIGlobals.PlaySoundEffect(this.OnOpenSfxId);
}
- this.PreDraw();
- this.ApplyConditionals();
+ if (!this.hasError)
+ {
+ this.PreDraw();
+ this.ApplyConditionals();
+ }
+ else
+ {
+ Style.StyleModelV1.DalamudStandard.Push();
+ this.isErrorStylePushed = true;
+ }
if (this.ForceMainWindow)
ImGuiHelpers.ForceNextWindowMainViewport();
@@ -448,10 +457,28 @@ public abstract class Window
var flags = this.Flags;
if (this.internalIsPinned || this.internalIsClickthrough)
- flags |= ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoResize;
+ {
+ if (!this.hasError)
+ {
+ flags |= ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoResize;
+ }
+ else
+ {
+ flags &= ~(ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoResize);
+ }
+ }
if (this.internalIsClickthrough)
- flags |= ImGuiWindowFlags.NoInputs | ImGuiWindowFlags.NoNav | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoScrollWithMouse | ImGuiWindowFlags.NoMouseInputs;
+ {
+ if (!this.hasError)
+ {
+ flags |= ImGuiWindowFlags.NoInputs | ImGuiWindowFlags.NoNav | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoScrollWithMouse | ImGuiWindowFlags.NoMouseInputs;
+ }
+ else
+ {
+ flags &= ~(ImGuiWindowFlags.NoInputs | ImGuiWindowFlags.NoNav | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoScrollWithMouse | ImGuiWindowFlags.NoMouseInputs);
+ }
+ }
if (this.CanShowCloseButton ? ImGui.Begin(this.WindowName, ref this.internalIsOpen, flags) : ImGui.Begin(this.WindowName, flags))
{
@@ -670,7 +697,17 @@ public abstract class Window
Task.FromResult(tex));
}
- this.PostDraw();
+ if (!this.hasError)
+ {
+ this.PostDraw();
+ }
+ else
+ {
+ if (this.isErrorStylePushed)
+ {
+ Style.StyleModelV1.DalamudStandard.Pop();
+ }
+ }
this.PostHandlePreset(persistence);
From fadf941fa47f5d8775f157a64a5414bfcb00faab Mon Sep 17 00:00:00 2001
From: goaaats
Date: Sun, 30 Nov 2025 02:01:01 +0100
Subject: [PATCH 06/50] Re-add config properties for XLCore/XoM backwards
compatibility
---
Dalamud/Configuration/Internal/DalamudConfiguration.cs | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Dalamud/Configuration/Internal/DalamudConfiguration.cs b/Dalamud/Configuration/Internal/DalamudConfiguration.cs
index 9404b5b10..d546dc517 100644
--- a/Dalamud/Configuration/Internal/DalamudConfiguration.cs
+++ b/Dalamud/Configuration/Internal/DalamudConfiguration.cs
@@ -487,6 +487,14 @@ internal sealed class DalamudConfiguration : IInternalDisposableService
///
public Vector2 NotificationAnchorPosition { get; set; } = new(1f, 1f);
+#pragma warning disable SA1600
+#pragma warning disable SA1516
+ // XLCore/XoM compatibility until they move it out
+ public string? DalamudBetaKey { get; set; } = null;
+ public string? DalamudBetaKind { get; set; }
+#pragma warning restore SA1516
+#pragma warning restore SA1600
+
///
/// Load a configuration from the provided path.
///
From ac2d522415b9a5ccec7a8c5cead997413412a699 Mon Sep 17 00:00:00 2001
From: goaaats
Date: Sun, 30 Nov 2025 02:47:07 +0100
Subject: [PATCH 07/50] build: 13.0.0.12
---
Dalamud/Dalamud.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj
index ce140b8c9..d1f730d5e 100644
--- a/Dalamud/Dalamud.csproj
+++ b/Dalamud/Dalamud.csproj
@@ -6,7 +6,7 @@
XIV Launcher addon framework
- 13.0.0.11
+ 13.0.0.12
$(DalamudVersion)
$(DalamudVersion)
$(DalamudVersion)
From 2e246967317427d2d5749d69b24a3e8ebc77d328 Mon Sep 17 00:00:00 2001
From: MidoriKami
Date: Sun, 30 Nov 2025 14:47:24 -0800
Subject: [PATCH 08/50] Set flags, and unlock size
---
Dalamud/Interface/Windowing/Window.cs | 26 ++++++++++----------------
1 file changed, 10 insertions(+), 16 deletions(-)
diff --git a/Dalamud/Interface/Windowing/Window.cs b/Dalamud/Interface/Windowing/Window.cs
index 5169b9746..700481ce5 100644
--- a/Dalamud/Interface/Windowing/Window.cs
+++ b/Dalamud/Interface/Windowing/Window.cs
@@ -458,26 +458,20 @@ public abstract class Window
if (this.internalIsPinned || this.internalIsClickthrough)
{
- if (!this.hasError)
- {
- flags |= ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoResize;
- }
- else
- {
- flags &= ~(ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoResize);
- }
+ flags |= ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoResize;
}
if (this.internalIsClickthrough)
{
- if (!this.hasError)
- {
- flags |= ImGuiWindowFlags.NoInputs | ImGuiWindowFlags.NoNav | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoScrollWithMouse | ImGuiWindowFlags.NoMouseInputs;
- }
- else
- {
- flags &= ~(ImGuiWindowFlags.NoInputs | ImGuiWindowFlags.NoNav | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoScrollWithMouse | ImGuiWindowFlags.NoMouseInputs);
- }
+ flags |= ImGuiWindowFlags.NoInputs | ImGuiWindowFlags.NoNav | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoScrollWithMouse | ImGuiWindowFlags.NoMouseInputs;
+ }
+
+ // If we have an error, reset all flags to default, and unlock window size.
+ if (this.hasError)
+ {
+ flags = ImGuiWindowFlags.None;
+ ImGui.SetNextWindowCollapsed(false, ImGuiCond.Once);
+ ImGui.SetNextWindowSizeConstraints(Vector2.Zero, Vector2.PositiveInfinity);
}
if (this.CanShowCloseButton ? ImGui.Begin(this.WindowName, ref this.internalIsOpen, flags) : ImGui.Begin(this.WindowName, flags))
From fb229a0a128dd36b3e531be7bd00d260649ce379 Mon Sep 17 00:00:00 2001
From: Haselnussbomber
Date: Mon, 1 Dec 2025 12:07:34 +0100
Subject: [PATCH 09/50] Fix PlayerState.Level being synced
---
Dalamud/Game/Player/PlayerState.cs | 2 +-
Dalamud/Plugin/Services/IPlayerState.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Dalamud/Game/Player/PlayerState.cs b/Dalamud/Game/Player/PlayerState.cs
index 917c946db..bd19b5bfb 100644
--- a/Dalamud/Game/Player/PlayerState.cs
+++ b/Dalamud/Game/Player/PlayerState.cs
@@ -77,7 +77,7 @@ internal unsafe class PlayerState : IServiceType, IPlayerState
public RowRef ClassJob => this.IsLoaded ? LuminaUtils.CreateRef(CSPlayerState.Instance()->CurrentClassJobId) : default;
///
- public short Level => this.IsLoaded ? CSPlayerState.Instance()->CurrentLevel : default;
+ public short Level => this.IsLoaded && this.ClassJob.IsValid ? this.GetClassJobLevel(this.ClassJob.Value) : this.EffectiveLevel;
///
public bool IsLevelSynced => this.IsLoaded && CSPlayerState.Instance()->IsLevelSynced;
diff --git a/Dalamud/Plugin/Services/IPlayerState.cs b/Dalamud/Plugin/Services/IPlayerState.cs
index 1416dfb77..21d88010b 100644
--- a/Dalamud/Plugin/Services/IPlayerState.cs
+++ b/Dalamud/Plugin/Services/IPlayerState.cs
@@ -79,7 +79,7 @@ public interface IPlayerState : IDalamudService
bool IsLevelSynced { get; }
///
- /// Gets the effective level of the local character.
+ /// Gets the effective level of the local character, taking level sync into account.
///
short EffectiveLevel { get; }
From 14e97a1a374b7968f28dc856203e9ba990c31ccd Mon Sep 17 00:00:00 2001
From: MidoriKami
Date: Mon, 1 Dec 2025 14:19:12 -0800
Subject: [PATCH 10/50] Use local variable to track pushed style state
---
Dalamud/Interface/Windowing/Window.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Dalamud/Interface/Windowing/Window.cs b/Dalamud/Interface/Windowing/Window.cs
index 700481ce5..e90e38119 100644
--- a/Dalamud/Interface/Windowing/Window.cs
+++ b/Dalamud/Interface/Windowing/Window.cs
@@ -57,7 +57,6 @@ public abstract class Window
private bool hasError = false;
private Exception? lastError;
- private bool isErrorStylePushed;
///
/// Initializes a new instance of the class.
@@ -426,6 +425,7 @@ public abstract class Window
UIGlobals.PlaySoundEffect(this.OnOpenSfxId);
}
+ var isErrorStylePushed = false;
if (!this.hasError)
{
this.PreDraw();
@@ -434,7 +434,7 @@ public abstract class Window
else
{
Style.StyleModelV1.DalamudStandard.Push();
- this.isErrorStylePushed = true;
+ isErrorStylePushed = true;
}
if (this.ForceMainWindow)
@@ -697,7 +697,7 @@ public abstract class Window
}
else
{
- if (this.isErrorStylePushed)
+ if (isErrorStylePushed)
{
Style.StyleModelV1.DalamudStandard.Pop();
}
From 518b3a4fb351eb1a826d3712f1c7fc4b712d658f Mon Sep 17 00:00:00 2001
From: Haselnussbomber
Date: Wed, 3 Dec 2025 16:43:12 +0100
Subject: [PATCH 11/50] Fix NounProcessor BeastTribe column offset
---
Dalamud/Game/Text/Noun/NounParams.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Dalamud/Game/Text/Noun/NounParams.cs b/Dalamud/Game/Text/Noun/NounParams.cs
index 3d5c424be..ab7a732d2 100644
--- a/Dalamud/Game/Text/Noun/NounParams.cs
+++ b/Dalamud/Game/Text/Noun/NounParams.cs
@@ -60,8 +60,8 @@ internal record struct NounParams()
///
public readonly int ColumnOffset => this.SheetName switch
{
- // See "E8 ?? ?? ?? ?? 44 8B 6B 08"
- nameof(LSheets.BeastTribe) => 10,
+ // See "E8 ?? ?? ?? ?? 44 8B 66 ?? 8B E8"
+ nameof(LSheets.BeastTribe) => 11,
nameof(LSheets.DeepDungeonItem) => 1,
nameof(LSheets.DeepDungeonEquipment) => 1,
nameof(LSheets.DeepDungeonMagicStone) => 1,
From f198ce46dc1d2100d95d4c090e446077e2af5729 Mon Sep 17 00:00:00 2001
From: Haselnussbomber
Date: Wed, 3 Dec 2025 16:47:13 +0100
Subject: [PATCH 12/50] Add self tests for ColumnOffset
---
.../Steps/NounProcessorSelfTestStep.cs | 23 +++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/Dalamud/Interface/Internal/Windows/SelfTest/Steps/NounProcessorSelfTestStep.cs b/Dalamud/Interface/Internal/Windows/SelfTest/Steps/NounProcessorSelfTestStep.cs
index ccb23d395..ccccc691c 100644
--- a/Dalamud/Interface/Internal/Windows/SelfTest/Steps/NounProcessorSelfTestStep.cs
+++ b/Dalamud/Interface/Internal/Windows/SelfTest/Steps/NounProcessorSelfTestStep.cs
@@ -191,6 +191,29 @@ internal class NounProcessorSelfTestStep : ISelfTestStep
new(nameof(LSheets.Item), 44348, ClientLanguage.French, 2, (int)FrenchArticleType.PossessiveFirstPerson, 1, "mes mémoquartz inhabituels fantasmagoriques"),
new(nameof(LSheets.Item), 44348, ClientLanguage.French, 2, (int)FrenchArticleType.PossessiveSecondPerson, 1, "tes mémoquartz inhabituels fantasmagoriques"),
new(nameof(LSheets.Item), 44348, ClientLanguage.French, 2, (int)FrenchArticleType.PossessiveThirdPerson, 1, "ses mémoquartz inhabituels fantasmagoriques"),
+
+ // ColumnOffset tests
+
+ new(nameof(LSheets.BeastTribe), 1, ClientLanguage.English, 1, (int)EnglishArticleType.Indefinite, 1, "a Amalj'aa"),
+ new(nameof(LSheets.BeastTribe), 1, ClientLanguage.English, 1, (int)EnglishArticleType.Definite, 1, "the Amalj'aa"),
+
+ new(nameof(LSheets.DeepDungeonEquipment), 1, ClientLanguage.English, 1, (int)EnglishArticleType.Indefinite, 1, "an aetherpool arm"),
+ new(nameof(LSheets.DeepDungeonEquipment), 1, ClientLanguage.English, 1, (int)EnglishArticleType.Definite, 1, "the aetherpool arm"),
+
+ new(nameof(LSheets.DeepDungeonItem), 1, ClientLanguage.English, 1, (int)EnglishArticleType.Indefinite, 1, "a pomander of safety"),
+ new(nameof(LSheets.DeepDungeonItem), 1, ClientLanguage.English, 1, (int)EnglishArticleType.Definite, 1, "the pomander of safety"),
+
+ new(nameof(LSheets.DeepDungeonMagicStone), 1, ClientLanguage.English, 1, (int)EnglishArticleType.Indefinite, 1, "a splinter of Inferno magicite"),
+ new(nameof(LSheets.DeepDungeonMagicStone), 1, ClientLanguage.English, 1, (int)EnglishArticleType.Definite, 1, "the splinter of Inferno magicite"),
+
+ new(nameof(LSheets.DeepDungeonDemiclone), 1, ClientLanguage.English, 1, (int)EnglishArticleType.Indefinite, 1, "an Unei demiclone"),
+ new(nameof(LSheets.DeepDungeonDemiclone), 1, ClientLanguage.English, 1, (int)EnglishArticleType.Definite, 1, "the Unei demiclone"),
+
+ new(nameof(LSheets.Glasses), 1, ClientLanguage.English, 1, (int)EnglishArticleType.Indefinite, 1, "a pair of oval spectacles"),
+ new(nameof(LSheets.Glasses), 1, ClientLanguage.English, 1, (int)EnglishArticleType.Definite, 1, "the pair of oval spectacles"),
+
+ new(nameof(LSheets.GlassesStyle), 1, ClientLanguage.English, 1, (int)EnglishArticleType.Indefinite, 1, "a shaded spectacles"),
+ new(nameof(LSheets.GlassesStyle), 1, ClientLanguage.English, 1, (int)EnglishArticleType.Definite, 1, "the shaded spectacles"),
];
private enum GermanCases
From 0e6dae9f6476050eaca0e01d2560bbbb136b123d Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Wed, 3 Dec 2025 18:39:04 +0000
Subject: [PATCH 13/50] Update ClientStructs
---
lib/FFXIVClientStructs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/FFXIVClientStructs b/lib/FFXIVClientStructs
index e5f586630..e5dedba42 160000
--- a/lib/FFXIVClientStructs
+++ b/lib/FFXIVClientStructs
@@ -1 +1 @@
-Subproject commit e5f586630ef06fa48d5dc0d8c0fa679323093c77
+Subproject commit e5dedba42a3fea8f050ea54ac583a5874bf51c6f
From df0bfc18c3877c027000b5400e78359e8b21b9f0 Mon Sep 17 00:00:00 2001
From: goat <16760685+goaaats@users.noreply.github.com>
Date: Thu, 4 Dec 2025 01:10:51 +0100
Subject: [PATCH 14/50] Make ImGuiHelpers.CreateDrawData() internal for now
---
Dalamud/Interface/Utility/ImGuiHelpers.cs | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/Dalamud/Interface/Utility/ImGuiHelpers.cs b/Dalamud/Interface/Utility/ImGuiHelpers.cs
index b8e7d5fe3..ee2840d3d 100644
--- a/Dalamud/Interface/Utility/ImGuiHelpers.cs
+++ b/Dalamud/Interface/Utility/ImGuiHelpers.cs
@@ -234,15 +234,6 @@ public static partial class ImGuiHelpers
ImGuiButtonFlags buttonFlags = ImGuiButtonFlags.MouseButtonDefault) =>
Service.Get().CompileAndDrawWrapped(text, style, imGuiId, buttonFlags);
- /// Creates a draw data that will draw the given SeString onto it.
- /// SeString to render.
- /// Initial rendering style.
- /// A new self-contained draw data.
- public static BufferBackedImDrawData CreateDrawData(
- ReadOnlySpan sss,
- scoped in SeStringDrawParams style = default) =>
- Service.Get().CreateDrawData(sss, style);
-
///
/// Write unformatted text wrapped.
///
@@ -584,6 +575,15 @@ public static partial class ImGuiHelpers
public static unsafe ImFontPtr OrElse(this ImFontPtr self, ImFontPtr other) =>
self.IsNull ? other : self;
+ /// Creates a draw data that will draw the given SeString onto it.
+ /// SeString to render.
+ /// Initial rendering style.
+ /// A new self-contained draw data.
+ internal static BufferBackedImDrawData CreateDrawData(
+ ReadOnlySpan sss,
+ scoped in SeStringDrawParams style = default) =>
+ Service.Get().CreateDrawData(sss, style);
+
///
/// Mark 4K page as used, after adding a codepoint to a font.
///
From 1fe2d5412839378a446fdf2aea867eb66d731c78 Mon Sep 17 00:00:00 2001
From: goaaats
Date: Thu, 4 Dec 2025 01:29:04 +0100
Subject: [PATCH 15/50] Upgrade cimgui, prep for viewport alpha
---
lib/cimgui | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/cimgui b/lib/cimgui
index 27c8565f6..bc3272967 160000
--- a/lib/cimgui
+++ b/lib/cimgui
@@ -1 +1 @@
-Subproject commit 27c8565f631b004c3266373890e41ecc627f775b
+Subproject commit bc327296758d57d3bdc963cb6ce71dd5b0c7e54c
From 9bce0d33a6deb5b1c8ca22cd53389a97c459dfdf Mon Sep 17 00:00:00 2001
From: goaaats
Date: Thu, 4 Dec 2025 02:04:27 +0100
Subject: [PATCH 16/50] Don't try to free CLR memory
---
.../ImGuiSeStringRenderer/Internal/SeStringRenderer.cs | 2 +-
.../Interface/ImGuiSeStringRenderer/SeStringDrawState.cs | 6 +-----
2 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringRenderer.cs b/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringRenderer.cs
index 0099e6e5d..87df2da2c 100644
--- a/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringRenderer.cs
+++ b/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringRenderer.cs
@@ -168,7 +168,7 @@ internal class SeStringRenderer : IServiceType
// This also does argument validation for drawParams. Do it here.
// `using var` makes a struct read-only, but we do want to modify it.
- using var stateStorage = new SeStringDrawState(
+ var stateStorage = new SeStringDrawState(
sss,
drawParams,
ThreadSafety.IsMainThread ? this.colorStackSetMainThread : new(this.colorStackSetMainThread.ColorTypes),
diff --git a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs
index 722de1fda..11c1120b4 100644
--- a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs
+++ b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs
@@ -17,7 +17,7 @@ namespace Dalamud.Interface.ImGuiSeStringRenderer;
/// Calculated values from using ImGui styles.
[StructLayout(LayoutKind.Sequential)]
-public unsafe ref struct SeStringDrawState : IDisposable
+public unsafe ref struct SeStringDrawState
{
private static readonly int ChannelCount = Enum.GetValues().Length;
@@ -181,10 +181,6 @@ public unsafe ref struct SeStringDrawState : IDisposable
/// Gets the text fragments.
internal List Fragments { get; }
- ///
- public void Dispose() =>
- ImGuiNative.Destroy((ImDrawListSplitter*)Unsafe.AsPointer(ref this.splitter));
-
/// Sets the current channel in the ImGui draw list splitter.
/// Channel to switch to.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
From 1b5fbaa82ed43343f73dfcf72a5941ba0ca16d60 Mon Sep 17 00:00:00 2001
From: goaaats
Date: Thu, 4 Dec 2025 02:04:45 +0100
Subject: [PATCH 17/50] Access custom font atlas fields directly through
bindings
---
.../Utility/BufferBackedImDrawData.cs | 24 ++-----------------
1 file changed, 2 insertions(+), 22 deletions(-)
diff --git a/Dalamud/Interface/Utility/BufferBackedImDrawData.cs b/Dalamud/Interface/Utility/BufferBackedImDrawData.cs
index 112fda8a8..e6128992a 100644
--- a/Dalamud/Interface/Utility/BufferBackedImDrawData.cs
+++ b/Dalamud/Interface/Utility/BufferBackedImDrawData.cs
@@ -39,9 +39,8 @@ public unsafe struct BufferBackedImDrawData : IDisposable
*ds = default;
var atlas = ImGui.GetIO().Fonts;
- ref var atlasTail = ref ImFontAtlasTailReal.From(atlas);
ds->SharedData = *ImGui.GetDrawListSharedData().Handle;
- ds->SharedData.TexIdCommon = atlas.Textures[atlasTail.TextureIndexCommon].TexID;
+ ds->SharedData.TexIdCommon = atlas.Textures[atlas.TextureIndexCommon].TexID;
ds->SharedData.TexUvWhitePixel = atlas.TexUvWhitePixel;
ds->SharedData.TexUvLines = (Vector4*)Unsafe.AsPointer(ref atlas.TexUvLines[0]);
ds->SharedData.Font = ImGui.GetIO().FontDefault;
@@ -60,7 +59,7 @@ public unsafe struct BufferBackedImDrawData : IDisposable
res.ListPtr._ResetForNewFrame();
res.ListPtr.PushClipRectFullScreen();
- res.ListPtr.PushTextureID(new(atlasTail.TextureIndexCommon));
+ res.ListPtr.PushTextureID(new(atlas.TextureIndexCommon));
return res;
}
@@ -90,23 +89,4 @@ public unsafe struct BufferBackedImDrawData : IDisposable
public ImDrawList List;
public ImDrawListSharedData SharedData;
}
-
- [StructLayout(LayoutKind.Sequential)]
- private struct ImFontAtlasTailReal
- {
- /// Index of texture containing the below.
- public int TextureIndexCommon;
-
- /// Custom texture rectangle ID for both of the below.
- public int PackIdCommon;
-
- /// Custom texture rectangle for white pixel and mouse cursors.
- public ImFontAtlasCustomRect RectMouseCursors;
-
- /// Custom texture rectangle for baked anti-aliased lines.
- public ImFontAtlasCustomRect RectLines;
-
- public static ref ImFontAtlasTailReal From(ImFontAtlasPtr fontAtlasPtr) =>
- ref *(ImFontAtlasTailReal*)(&fontAtlasPtr.Handle->FontBuilderFlags + sizeof(uint));
- }
}
From ddc743aae1337f968223ce791a3720d48b0e71b8 Mon Sep 17 00:00:00 2001
From: goaaats
Date: Thu, 4 Dec 2025 23:00:36 +0100
Subject: [PATCH 18/50] Note that font ptr must be supplied when setting
TargetDrawList
---
.../Interface/ImGuiSeStringRenderer/SeStringDrawParams.cs | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawParams.cs b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawParams.cs
index f3d4c44e9..1d8126f3b 100644
--- a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawParams.cs
+++ b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawParams.cs
@@ -12,7 +12,10 @@ public record struct SeStringDrawParams
/// Gets or sets the target draw list.
/// Target draw list, default(ImDrawListPtr) to not draw, or null to use
/// (the default).
- /// If this value is set, will not be called, and ImGui ID will be ignored.
+ ///
+ /// If this value is set, will not be called, and ImGui ID will be ignored.
+ /// You must specify a valid draw list and a valid font via if you set this value,
+ /// since the renderer will not be able to retrieve them from ImGui context.
///
public ImDrawListPtr? TargetDrawList { get; set; }
From 0112e17fdb052d0e3ebd6dc87b9b8bfaeaf9e1e0 Mon Sep 17 00:00:00 2001
From: Haselnussbomber
Date: Thu, 4 Dec 2025 23:27:06 +0100
Subject: [PATCH 19/50] Replace internal SharpDX usage with TerraFX
---
.../Internals/FontAtlasFactory.BuildToolkit.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.BuildToolkit.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.BuildToolkit.cs
index 2a93cf093..41c87fd39 100644
--- a/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.BuildToolkit.cs
+++ b/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.BuildToolkit.cs
@@ -15,7 +15,6 @@ using Dalamud.Interface.Textures.TextureWraps;
using Dalamud.Interface.Utility;
using Dalamud.Storage.Assets;
using Dalamud.Utility;
-using SharpDX.DXGI;
using TerraFX.Interop.DirectX;
namespace Dalamud.Interface.ManagedFontAtlas.Internals;
@@ -749,7 +748,7 @@ internal sealed partial class FontAtlasFactory
new(
width,
height,
- (int)(use4 ? Format.B4G4R4A4_UNorm : Format.B8G8R8A8_UNorm),
+ (int)(use4 ? DXGI_FORMAT.DXGI_FORMAT_B4G4R4A4_UNORM : DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM),
width * bpp),
buf,
name);
From da7be64fdf3bfd69cd69d77b98d1a7eaf2f3a73a Mon Sep 17 00:00:00 2001
From: Haselnussbomber
Date: Thu, 4 Dec 2025 23:31:31 +0100
Subject: [PATCH 20/50] Remove SharpDX
---
Dalamud/Dalamud.csproj | 2 -
Dalamud/Interface/UiBuilder.cs | 16 ------
Dalamud/Storage/Assets/DalamudAssetPurpose.cs | 6 +--
Dalamud/Utility/VectorExtensions.cs | 51 -------------------
Directory.Packages.props | 2 -
5 files changed, 3 insertions(+), 74 deletions(-)
delete mode 100644 Dalamud/Utility/VectorExtensions.cs
diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj
index b9b453f89..e8c2516af 100644
--- a/Dalamud/Dalamud.csproj
+++ b/Dalamud/Dalamud.csproj
@@ -73,8 +73,6 @@
all
-
-
diff --git a/Dalamud/Interface/UiBuilder.cs b/Dalamud/Interface/UiBuilder.cs
index e38537018..6e4740b22 100644
--- a/Dalamud/Interface/UiBuilder.cs
+++ b/Dalamud/Interface/UiBuilder.cs
@@ -12,7 +12,6 @@ using Dalamud.Interface.FontIdentifier;
using Dalamud.Interface.Internal;
using Dalamud.Interface.ManagedFontAtlas;
using Dalamud.Interface.ManagedFontAtlas.Internals;
-using Dalamud.Plugin;
using Dalamud.Plugin.Internal.Types;
using Dalamud.Utility;
using Serilog;
@@ -150,13 +149,6 @@ public interface IUiBuilder
///
public ImFontPtr FontMono { get; }
- ///
- /// Gets the game's active Direct3D device.
- ///
- // TODO: Remove it on API11/APIXI, and remove SharpDX/PInvoke/etc. dependency from Dalamud.
- [Obsolete($"Use {nameof(DeviceHandle)} and wrap it using DirectX wrapper library of your choice.")]
- SharpDX.Direct3D11.Device Device { get; }
-
/// Gets the game's active Direct3D device.
/// Pointer to the instance of IUnknown that the game is using and should be containing an ID3D11Device,
/// or 0 if it is not available yet.
@@ -302,8 +294,6 @@ public sealed class UiBuilder : IDisposable, IUiBuilder
private IFontHandle? monoFontHandle;
private IFontHandle? iconFontFixedWidthHandle;
- private SharpDX.Direct3D11.Device? sdxDevice;
-
///
/// Initializes a new instance of the class and registers it.
/// You do not have to call this manually.
@@ -493,12 +483,6 @@ public sealed class UiBuilder : IDisposable, IUiBuilder
this.InterfaceManagerWithScene?.MonoFontHandle
?? throw new InvalidOperationException("Scene is not yet ready.")));
- ///
- // TODO: Remove it on API11/APIXI, and remove SharpDX/PInvoke/etc. dependency from Dalamud.
- [Obsolete($"Use {nameof(DeviceHandle)} and wrap it using DirectX wrapper library of your choice.")]
- public SharpDX.Direct3D11.Device Device =>
- this.sdxDevice ??= new(this.InterfaceManagerWithScene!.Backend!.DeviceHandle);
-
///
public nint DeviceHandle => this.InterfaceManagerWithScene?.Backend?.DeviceHandle ?? 0;
diff --git a/Dalamud/Storage/Assets/DalamudAssetPurpose.cs b/Dalamud/Storage/Assets/DalamudAssetPurpose.cs
index e6c7bd920..69de1f871 100644
--- a/Dalamud/Storage/Assets/DalamudAssetPurpose.cs
+++ b/Dalamud/Storage/Assets/DalamudAssetPurpose.cs
@@ -11,12 +11,12 @@ public enum DalamudAssetPurpose
Empty = 0,
///
- /// The asset is a .png file, and can be purposed as a .
+ /// The asset is a .png file, and can be purposed as a .
///
TextureFromPng = 10,
-
+
///
- /// The asset is a raw texture, and can be purposed as a .
+ /// The asset is a raw texture, and can be purposed as a .
///
TextureFromRaw = 1001,
diff --git a/Dalamud/Utility/VectorExtensions.cs b/Dalamud/Utility/VectorExtensions.cs
deleted file mode 100644
index f617c8420..000000000
--- a/Dalamud/Utility/VectorExtensions.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using System.Numerics;
-
-namespace Dalamud.Utility;
-
-///
-/// Extension methods for System.Numerics.VectorN and SharpDX.VectorN.
-///
-public static class VectorExtensions
-{
- ///
- /// Converts a SharpDX vector to System.Numerics.
- ///
- /// Vector to convert.
- /// A converted vector.
- public static Vector2 ToSystem(this SharpDX.Vector2 vec) => new(x: vec.X, y: vec.Y);
-
- ///
- /// Converts a SharpDX vector to System.Numerics.
- ///
- /// Vector to convert.
- /// A converted vector.
- public static Vector3 ToSystem(this SharpDX.Vector3 vec) => new(x: vec.X, y: vec.Y, z: vec.Z);
-
- ///
- /// Converts a SharpDX vector to System.Numerics.
- ///
- /// Vector to convert.
- /// A converted vector.
- public static Vector4 ToSystem(this SharpDX.Vector4 vec) => new(x: vec.X, y: vec.Y, z: vec.Z, w: vec.W);
-
- ///
- /// Converts a System.Numerics vector to SharpDX.
- ///
- /// Vector to convert.
- /// A converted vector.
- public static SharpDX.Vector2 ToSharpDX(this Vector2 vec) => new(x: vec.X, y: vec.Y);
-
- ///
- /// Converts a System.Numerics vector to SharpDX.
- ///
- /// Vector to convert.
- /// A converted vector.
- public static SharpDX.Vector3 ToSharpDX(this Vector3 vec) => new(x: vec.X, y: vec.Y, z: vec.Z);
-
- ///
- /// Converts a System.Numerics vector to SharpDX.
- ///
- /// Vector to convert.
- /// A converted vector.
- public static SharpDX.Vector4 ToSharpDX(this Vector4 vec) => new(x: vec.X, y: vec.Y, z: vec.Z, w: vec.W);
-}
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 903a8ee88..481e7591d 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -27,8 +27,6 @@
-
-
From ddc31132444f350a8bb1f794a8d5e91bec00c9a3 Mon Sep 17 00:00:00 2001
From: Haselnussbomber
Date: Fri, 5 Dec 2025 00:37:25 +0100
Subject: [PATCH 21/50] Update TerraFX.Interop.Windows
---
.../IObjectWithLocalizableName.cs | 4 +--
.../FontIdentifier/SystemFontFamilyId.cs | 4 +--
.../Interface/FontIdentifier/SystemFontId.cs | 6 ++--
.../ImGuiBackend/Helpers/ReShadePeeler.cs | 14 ++++----
.../InputHandler/Win32InputHandler.cs | 10 +++---
.../Interface/Internal/InterfaceManager.cs | 2 +-
.../ReShadeAddonInterface.Exports.cs | 6 ++--
.../ReShadeHandling/ReShadeUnwrapper.cs | 2 +-
.../Interface/Internal/StaThreadService.cs | 8 ++---
.../Textures/Internal/BitmapCodecInfo.cs | 4 +--
.../Internal/TextureManager.BlameTracker.cs | 6 ++--
.../Internal/TextureManager.Clipboard.cs | 6 ++--
Dalamud/Service/LoadingDialog.cs | 32 +++++++++----------
Dalamud/Utility/ClipboardFormats.cs | 4 +--
Dalamud/Utility/TerraFxCom/ManagedIStream.cs | 28 ++++++++--------
.../TerraFxComInterfaceExtensions.cs | 8 ++---
Directory.Packages.props | 2 +-
17 files changed, 73 insertions(+), 73 deletions(-)
diff --git a/Dalamud/Interface/FontIdentifier/IObjectWithLocalizableName.cs b/Dalamud/Interface/FontIdentifier/IObjectWithLocalizableName.cs
index 2b970a5fd..4b3860431 100644
--- a/Dalamud/Interface/FontIdentifier/IObjectWithLocalizableName.cs
+++ b/Dalamud/Interface/FontIdentifier/IObjectWithLocalizableName.cs
@@ -64,9 +64,9 @@ public interface IObjectWithLocalizableName
var result = new Dictionary((int)count);
for (var i = 0u; i < count; i++)
{
- fn->GetLocaleName(i, (ushort*)buf, maxStrLen).ThrowOnError();
+ fn->GetLocaleName(i, buf, maxStrLen).ThrowOnError();
var key = new string(buf);
- fn->GetString(i, (ushort*)buf, maxStrLen).ThrowOnError();
+ fn->GetString(i, buf, maxStrLen).ThrowOnError();
var value = new string(buf);
result[key.ToLowerInvariant()] = value;
}
diff --git a/Dalamud/Interface/FontIdentifier/SystemFontFamilyId.cs b/Dalamud/Interface/FontIdentifier/SystemFontFamilyId.cs
index 420ee77a4..83a5e810d 100644
--- a/Dalamud/Interface/FontIdentifier/SystemFontFamilyId.cs
+++ b/Dalamud/Interface/FontIdentifier/SystemFontFamilyId.cs
@@ -133,8 +133,8 @@ public sealed class SystemFontFamilyId : IFontFamilyId
var familyIndex = 0u;
BOOL exists = false;
- fixed (void* pName = this.EnglishName)
- sfc.Get()->FindFamilyName((ushort*)pName, &familyIndex, &exists).ThrowOnError();
+ fixed (char* pName = this.EnglishName)
+ sfc.Get()->FindFamilyName(pName, &familyIndex, &exists).ThrowOnError();
if (!exists)
throw new FileNotFoundException($"Font \"{this.EnglishName}\" not found.");
diff --git a/Dalamud/Interface/FontIdentifier/SystemFontId.cs b/Dalamud/Interface/FontIdentifier/SystemFontId.cs
index e11759a88..8401f4c79 100644
--- a/Dalamud/Interface/FontIdentifier/SystemFontId.cs
+++ b/Dalamud/Interface/FontIdentifier/SystemFontId.cs
@@ -113,8 +113,8 @@ public sealed class SystemFontId : IFontId
var familyIndex = 0u;
BOOL exists = false;
- fixed (void* name = this.Family.EnglishName)
- sfc.Get()->FindFamilyName((ushort*)name, &familyIndex, &exists).ThrowOnError();
+ fixed (char* name = this.Family.EnglishName)
+ sfc.Get()->FindFamilyName(name, &familyIndex, &exists).ThrowOnError();
if (!exists)
throw new FileNotFoundException($"Font \"{this.Family.EnglishName}\" not found.");
@@ -151,7 +151,7 @@ public sealed class SystemFontId : IFontId
flocal.Get()->GetFilePathLengthFromKey(refKey, refKeySize, &pathSize).ThrowOnError();
var path = stackalloc char[(int)pathSize + 1];
- flocal.Get()->GetFilePathFromKey(refKey, refKeySize, (ushort*)path, pathSize + 1).ThrowOnError();
+ flocal.Get()->GetFilePathFromKey(refKey, refKeySize, path, pathSize + 1).ThrowOnError();
return (new(path, 0, (int)pathSize), (int)fface.Get()->GetIndex());
}
diff --git a/Dalamud/Interface/ImGuiBackend/Helpers/ReShadePeeler.cs b/Dalamud/Interface/ImGuiBackend/Helpers/ReShadePeeler.cs
index 824ba382a..3f3c98c26 100644
--- a/Dalamud/Interface/ImGuiBackend/Helpers/ReShadePeeler.cs
+++ b/Dalamud/Interface/ImGuiBackend/Helpers/ReShadePeeler.cs
@@ -104,19 +104,19 @@ internal static unsafe class ReShadePeeler
fixed (byte* pfn5 = "glBegin"u8)
fixed (byte* pfn6 = "vkCreateDevice"u8)
{
- if (GetProcAddress((HMODULE)dosh, (sbyte*)pfn0) == 0)
+ if (GetProcAddress((HMODULE)dosh, (sbyte*)pfn0) == null)
continue;
- if (GetProcAddress((HMODULE)dosh, (sbyte*)pfn1) == 0)
+ if (GetProcAddress((HMODULE)dosh, (sbyte*)pfn1) == null)
continue;
- if (GetProcAddress((HMODULE)dosh, (sbyte*)pfn2) == 0)
+ if (GetProcAddress((HMODULE)dosh, (sbyte*)pfn2) == null)
continue;
- if (GetProcAddress((HMODULE)dosh, (sbyte*)pfn3) == 0)
+ if (GetProcAddress((HMODULE)dosh, (sbyte*)pfn3) == null)
continue;
- if (GetProcAddress((HMODULE)dosh, (sbyte*)pfn4) == 0)
+ if (GetProcAddress((HMODULE)dosh, (sbyte*)pfn4) == null)
continue;
- if (GetProcAddress((HMODULE)dosh, (sbyte*)pfn5) == 0)
+ if (GetProcAddress((HMODULE)dosh, (sbyte*)pfn5) == null)
continue;
- if (GetProcAddress((HMODULE)dosh, (sbyte*)pfn6) == 0)
+ if (GetProcAddress((HMODULE)dosh, (sbyte*)pfn6) == null)
continue;
}
diff --git a/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.cs b/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.cs
index 596df4c67..18330d3a2 100644
--- a/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.cs
+++ b/Dalamud/Interface/ImGuiBackend/InputHandler/Win32InputHandler.cs
@@ -622,7 +622,7 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
hbrBackground = (HBRUSH)(1 + COLOR.COLOR_BACKGROUND),
lpfnWndProc = (delegate* unmanaged)Marshal
.GetFunctionPointerForDelegate(this.input.wndProcDelegate),
- lpszClassName = (ushort*)windowClassNamePtr,
+ lpszClassName = windowClassNamePtr,
};
if (RegisterClassExW(&wcex) == 0)
@@ -658,7 +658,7 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
fixed (char* windowClassNamePtr = WindowClassName)
{
UnregisterClassW(
- (ushort*)windowClassNamePtr,
+ windowClassNamePtr,
(HINSTANCE)Marshal.GetHINSTANCE(typeof(ViewportHandler).Module));
}
@@ -781,8 +781,8 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
{
data->Hwnd = CreateWindowExW(
(uint)data->DwExStyle,
- (ushort*)windowClassNamePtr,
- (ushort*)windowClassNamePtr,
+ windowClassNamePtr,
+ windowClassNamePtr,
(uint)data->DwStyle,
rect.left,
rect.top,
@@ -993,7 +993,7 @@ internal sealed unsafe partial class Win32InputHandler : IImGuiInputHandler
{
var data = (ImGuiViewportDataWin32*)viewport.PlatformUserData;
fixed (char* pwszTitle = MemoryHelper.ReadStringNullTerminated((nint)title))
- SetWindowTextW(data->Hwnd, (ushort*)pwszTitle);
+ SetWindowTextW(data->Hwnd, pwszTitle);
}
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])]
diff --git a/Dalamud/Interface/Internal/InterfaceManager.cs b/Dalamud/Interface/Internal/InterfaceManager.cs
index 76a1b5172..96fcb7dfd 100644
--- a/Dalamud/Interface/Internal/InterfaceManager.cs
+++ b/Dalamud/Interface/Internal/InterfaceManager.cs
@@ -256,7 +256,7 @@ internal partial class InterfaceManager : IInternalDisposableService
var gwh = default(HWND);
fixed (char* pClass = "FFXIVGAME")
{
- while ((gwh = FindWindowExW(default, gwh, (ushort*)pClass, default)) != default)
+ while ((gwh = FindWindowExW(default, gwh, pClass, default)) != default)
{
uint pid;
_ = GetWindowThreadProcessId(gwh, &pid);
diff --git a/Dalamud/Interface/Internal/ReShadeHandling/ReShadeAddonInterface.Exports.cs b/Dalamud/Interface/Internal/ReShadeHandling/ReShadeAddonInterface.Exports.cs
index d8d210076..d7d3b56c3 100644
--- a/Dalamud/Interface/Internal/ReShadeHandling/ReShadeAddonInterface.Exports.cs
+++ b/Dalamud/Interface/Internal/ReShadeHandling/ReShadeAddonInterface.Exports.cs
@@ -63,11 +63,11 @@ internal sealed unsafe partial class ReShadeAddonInterface
return;
- bool GetProcAddressInto(ProcessModule m, ReadOnlySpan name, void* res)
+ static bool GetProcAddressInto(ProcessModule m, ReadOnlySpan name, void* res)
{
Span name8 = stackalloc byte[Encoding.UTF8.GetByteCount(name) + 1];
name8[Encoding.UTF8.GetBytes(name, name8)] = 0;
- *(nint*)res = GetProcAddress((HMODULE)m.BaseAddress, (sbyte*)Unsafe.AsPointer(ref name8[0]));
+ *(nint*)res = (nint)GetProcAddress((HMODULE)m.BaseAddress, (sbyte*)Unsafe.AsPointer(ref name8[0]));
return *(nint*)res != 0;
}
}
@@ -174,7 +174,7 @@ internal sealed unsafe partial class ReShadeAddonInterface
CERT.CERT_NAME_SIMPLE_DISPLAY_TYPE,
CERT.CERT_NAME_ISSUER_FLAG,
null,
- (ushort*)Unsafe.AsPointer(ref issuerName[0]),
+ (char*)Unsafe.AsPointer(ref issuerName[0]),
pcb);
if (pcb == 0)
throw new Win32Exception("CertGetNameStringW(2)");
diff --git a/Dalamud/Interface/Internal/ReShadeHandling/ReShadeUnwrapper.cs b/Dalamud/Interface/Internal/ReShadeHandling/ReShadeUnwrapper.cs
index f1210425d..711de6eb2 100644
--- a/Dalamud/Interface/Internal/ReShadeHandling/ReShadeUnwrapper.cs
+++ b/Dalamud/Interface/Internal/ReShadeHandling/ReShadeUnwrapper.cs
@@ -94,7 +94,7 @@ internal static unsafe class ReShadeUnwrapper
static bool HasProcExported(ProcessModule m, ReadOnlySpan name)
{
fixed (byte* p = name)
- return GetProcAddress((HMODULE)m.BaseAddress, (sbyte*)p) != 0;
+ return GetProcAddress((HMODULE)m.BaseAddress, (sbyte*)p) != null;
}
}
diff --git a/Dalamud/Interface/Internal/StaThreadService.cs b/Dalamud/Interface/Internal/StaThreadService.cs
index 87e003288..bb5caa281 100644
--- a/Dalamud/Interface/Internal/StaThreadService.cs
+++ b/Dalamud/Interface/Internal/StaThreadService.cs
@@ -216,7 +216,7 @@ internal partial class StaThreadService : IInternalDisposableService
lpfnWndProc = &MessageReceiverWndProcStatic,
hInstance = hInstance,
hbrBackground = (HBRUSH)(COLOR.COLOR_BACKGROUND + 1),
- lpszClassName = (ushort*)name,
+ lpszClassName = name,
};
wndClassAtom = RegisterClassExW(&wndClass);
@@ -226,8 +226,8 @@ internal partial class StaThreadService : IInternalDisposableService
this.messageReceiverHwndTask.SetResult(
CreateWindowExW(
0,
- (ushort*)wndClassAtom,
- (ushort*)name,
+ (char*)wndClassAtom,
+ name,
0,
CW_USEDEFAULT,
CW_USEDEFAULT,
@@ -275,7 +275,7 @@ internal partial class StaThreadService : IInternalDisposableService
_ = OleFlushClipboard();
OleUninitialize();
if (wndClassAtom != 0)
- UnregisterClassW((ushort*)wndClassAtom, hInstance);
+ UnregisterClassW((char*)wndClassAtom, hInstance);
this.messageReceiverHwndTask.TrySetException(e);
}
}
diff --git a/Dalamud/Interface/Textures/Internal/BitmapCodecInfo.cs b/Dalamud/Interface/Textures/Internal/BitmapCodecInfo.cs
index 3d5456500..ec56caadd 100644
--- a/Dalamud/Interface/Textures/Internal/BitmapCodecInfo.cs
+++ b/Dalamud/Interface/Textures/Internal/BitmapCodecInfo.cs
@@ -44,12 +44,12 @@ internal sealed class BitmapCodecInfo : IBitmapCodecInfo
private static unsafe string ReadStringUsing(
IWICBitmapCodecInfo* codecInfo,
- delegate* unmanaged readFuncPtr)
+ delegate* unmanaged[MemberFunction] readFuncPtr)
{
var cch = 0u;
_ = readFuncPtr(codecInfo, 0, null, &cch);
var buf = stackalloc char[(int)cch + 1];
- Marshal.ThrowExceptionForHR(readFuncPtr(codecInfo, cch + 1, (ushort*)buf, &cch));
+ Marshal.ThrowExceptionForHR(readFuncPtr(codecInfo, cch + 1, buf, &cch));
return new(buf, 0, (int)cch);
}
}
diff --git a/Dalamud/Interface/Textures/Internal/TextureManager.BlameTracker.cs b/Dalamud/Interface/Textures/Internal/TextureManager.BlameTracker.cs
index 837b41271..fde40d462 100644
--- a/Dalamud/Interface/Textures/Internal/TextureManager.BlameTracker.cs
+++ b/Dalamud/Interface/Textures/Internal/TextureManager.BlameTracker.cs
@@ -219,14 +219,14 @@ internal sealed partial class TextureManager
return;
- [UnmanagedCallersOnly]
+ [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
static int QueryInterfaceStatic(IUnknown* pThis, Guid* riid, void** ppvObject) =>
ToManagedObject(pThis)?.QueryInterface(riid, ppvObject) ?? E.E_UNEXPECTED;
- [UnmanagedCallersOnly]
+ [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
static uint AddRefStatic(IUnknown* pThis) => (uint)(ToManagedObject(pThis)?.AddRef() ?? 0);
- [UnmanagedCallersOnly]
+ [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
static uint ReleaseStatic(IUnknown* pThis) => (uint)(ToManagedObject(pThis)?.Release() ?? 0);
}
diff --git a/Dalamud/Interface/Textures/Internal/TextureManager.Clipboard.cs b/Dalamud/Interface/Textures/Internal/TextureManager.Clipboard.cs
index 8a510e967..75f7ab975 100644
--- a/Dalamud/Interface/Textures/Internal/TextureManager.Clipboard.cs
+++ b/Dalamud/Interface/Textures/Internal/TextureManager.Clipboard.cs
@@ -133,7 +133,7 @@ internal sealed partial class TextureManager
},
},
};
- namea.AsSpan().CopyTo(new(fgda.fgd.e0.cFileName, 260));
+ namea.AsSpan().CopyTo(new(Unsafe.AsPointer(ref fgda.fgd.e0.cFileName[0]), 260));
AddToDataObject(
pdo,
@@ -157,7 +157,7 @@ internal sealed partial class TextureManager
},
},
};
- preferredFileNameWithoutExtension.AsSpan().CopyTo(new(fgdw.fgd.e0.cFileName, 260));
+ preferredFileNameWithoutExtension.AsSpan().CopyTo(new(Unsafe.AsPointer(ref fgdw.fgd.e0.cFileName[0]), 260));
AddToDataObject(
pdo,
@@ -450,7 +450,7 @@ internal sealed partial class TextureManager
try
{
IStream* pfs;
- SHCreateStreamOnFileW((ushort*)pPath, sharedRead, &pfs).ThrowOnError();
+ SHCreateStreamOnFileW((char*)pPath, sharedRead, &pfs).ThrowOnError();
var stgm2 = new STGMEDIUM
{
diff --git a/Dalamud/Service/LoadingDialog.cs b/Dalamud/Service/LoadingDialog.cs
index 424087743..ea45d3bb2 100644
--- a/Dalamud/Service/LoadingDialog.cs
+++ b/Dalamud/Service/LoadingDialog.cs
@@ -1,4 +1,4 @@
-using System.Collections.Concurrent;
+using System.Collections.Concurrent;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
@@ -294,18 +294,18 @@ internal sealed class LoadingDialog
? null
: Icon.ExtractAssociatedIcon(Path.Combine(workingDirectory, "Dalamud.Injector.exe"));
- fixed (void* pszEmpty = "-")
- fixed (void* pszWindowTitle = "Dalamud")
- fixed (void* pszDalamudBoot = "Dalamud.Boot.dll")
- fixed (void* pszThemesManifestResourceName = "RT_MANIFEST_THEMES")
- fixed (void* pszHide = Loc.Localize("LoadingDialogHide", "Hide"))
- fixed (void* pszShowLatestLogs = Loc.Localize("LoadingDialogShowLatestLogs", "Show Latest Logs"))
- fixed (void* pszHideLatestLogs = Loc.Localize("LoadingDialogHideLatestLogs", "Hide Latest Logs"))
+ fixed (char* pszEmpty = "-")
+ fixed (char* pszWindowTitle = "Dalamud")
+ fixed (char* pszDalamudBoot = "Dalamud.Boot.dll")
+ fixed (char* pszThemesManifestResourceName = "RT_MANIFEST_THEMES")
+ fixed (char* pszHide = Loc.Localize("LoadingDialogHide", "Hide"))
+ fixed (char* pszShowLatestLogs = Loc.Localize("LoadingDialogShowLatestLogs", "Show Latest Logs"))
+ fixed (char* pszHideLatestLogs = Loc.Localize("LoadingDialogHideLatestLogs", "Hide Latest Logs"))
{
var taskDialogButton = new TASKDIALOG_BUTTON
{
nButtonID = IDOK,
- pszButtonText = (ushort*)pszHide,
+ pszButtonText = pszHide,
};
var taskDialogConfig = new TASKDIALOGCONFIG
{
@@ -318,8 +318,8 @@ internal sealed class LoadingDialog
(int)TDF_CALLBACK_TIMER |
(extractedIcon is null ? 0 : (int)TDF_USE_HICON_MAIN),
dwCommonButtons = 0,
- pszWindowTitle = (ushort*)pszWindowTitle,
- pszMainIcon = extractedIcon is null ? TD.TD_INFORMATION_ICON : (ushort*)extractedIcon.Handle,
+ pszWindowTitle = pszWindowTitle,
+ pszMainIcon = extractedIcon is null ? TD.TD_INFORMATION_ICON : (char*)extractedIcon.Handle,
pszMainInstruction = null,
pszContent = null,
cButtons = 1,
@@ -329,9 +329,9 @@ internal sealed class LoadingDialog
pRadioButtons = null,
nDefaultRadioButton = 0,
pszVerificationText = null,
- pszExpandedInformation = (ushort*)pszEmpty,
- pszExpandedControlText = (ushort*)pszShowLatestLogs,
- pszCollapsedControlText = (ushort*)pszHideLatestLogs,
+ pszExpandedInformation = pszEmpty,
+ pszExpandedControlText = pszShowLatestLogs,
+ pszCollapsedControlText = pszHideLatestLogs,
pszFooterIcon = null,
pszFooter = null,
pfCallback = &HResultFuncBinder,
@@ -348,8 +348,8 @@ internal sealed class LoadingDialog
{
cbSize = (uint)sizeof(ACTCTXW),
dwFlags = ACTCTX_FLAG_HMODULE_VALID | ACTCTX_FLAG_RESOURCE_NAME_VALID,
- lpResourceName = (ushort*)pszThemesManifestResourceName,
- hModule = GetModuleHandleW((ushort*)pszDalamudBoot),
+ lpResourceName = pszThemesManifestResourceName,
+ hModule = GetModuleHandleW(pszDalamudBoot),
};
hActCtx = CreateActCtxW(&actctx);
if (hActCtx == default)
diff --git a/Dalamud/Utility/ClipboardFormats.cs b/Dalamud/Utility/ClipboardFormats.cs
index 07b6c00d6..b80e05dd3 100644
--- a/Dalamud/Utility/ClipboardFormats.cs
+++ b/Dalamud/Utility/ClipboardFormats.cs
@@ -30,8 +30,8 @@ internal static class ClipboardFormats
private static unsafe uint ClipboardFormatFromName(ReadOnlySpan name)
{
uint cf;
- fixed (void* p = name)
- cf = RegisterClipboardFormatW((ushort*)p);
+ fixed (char* p = name)
+ cf = RegisterClipboardFormatW(p);
if (cf != 0)
return cf;
throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()) ??
diff --git a/Dalamud/Utility/TerraFxCom/ManagedIStream.cs b/Dalamud/Utility/TerraFxCom/ManagedIStream.cs
index caec65da2..eb1997daf 100644
--- a/Dalamud/Utility/TerraFxCom/ManagedIStream.cs
+++ b/Dalamud/Utility/TerraFxCom/ManagedIStream.cs
@@ -57,60 +57,60 @@ internal sealed unsafe class ManagedIStream : IStream.Interface, IRefCountable
static ManagedIStream? ToManagedObject(void* pThis) =>
GCHandle.FromIntPtr(((nint*)pThis)[1]).Target as ManagedIStream;
- [UnmanagedCallersOnly]
+ [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
static int QueryInterfaceStatic(IStream* pThis, Guid* riid, void** ppvObject) =>
ToManagedObject(pThis)?.QueryInterface(riid, ppvObject) ?? E.E_UNEXPECTED;
- [UnmanagedCallersOnly]
+ [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
static uint AddRefStatic(IStream* pThis) => (uint)(ToManagedObject(pThis)?.AddRef() ?? 0);
- [UnmanagedCallersOnly]
+ [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
static uint ReleaseStatic(IStream* pThis) => (uint)(ToManagedObject(pThis)?.Release() ?? 0);
- [UnmanagedCallersOnly]
+ [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
static int ReadStatic(IStream* pThis, void* pv, uint cb, uint* pcbRead) =>
ToManagedObject(pThis)?.Read(pv, cb, pcbRead) ?? E.E_UNEXPECTED;
- [UnmanagedCallersOnly]
+ [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
static int WriteStatic(IStream* pThis, void* pv, uint cb, uint* pcbWritten) =>
ToManagedObject(pThis)?.Write(pv, cb, pcbWritten) ?? E.E_UNEXPECTED;
- [UnmanagedCallersOnly]
+ [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
static int SeekStatic(
IStream* pThis, LARGE_INTEGER dlibMove, uint dwOrigin, ULARGE_INTEGER* plibNewPosition) =>
ToManagedObject(pThis)?.Seek(dlibMove, dwOrigin, plibNewPosition) ?? E.E_UNEXPECTED;
- [UnmanagedCallersOnly]
+ [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
static int SetSizeStatic(IStream* pThis, ULARGE_INTEGER libNewSize) =>
ToManagedObject(pThis)?.SetSize(libNewSize) ?? E.E_UNEXPECTED;
- [UnmanagedCallersOnly]
+ [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
static int CopyToStatic(
IStream* pThis, IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead,
ULARGE_INTEGER* pcbWritten) =>
ToManagedObject(pThis)?.CopyTo(pstm, cb, pcbRead, pcbWritten) ?? E.E_UNEXPECTED;
- [UnmanagedCallersOnly]
+ [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
static int CommitStatic(IStream* pThis, uint grfCommitFlags) =>
ToManagedObject(pThis)?.Commit(grfCommitFlags) ?? E.E_UNEXPECTED;
- [UnmanagedCallersOnly]
+ [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
static int RevertStatic(IStream* pThis) => ToManagedObject(pThis)?.Revert() ?? E.E_UNEXPECTED;
- [UnmanagedCallersOnly]
+ [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
static int LockRegionStatic(IStream* pThis, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, uint dwLockType) =>
ToManagedObject(pThis)?.LockRegion(libOffset, cb, dwLockType) ?? E.E_UNEXPECTED;
- [UnmanagedCallersOnly]
+ [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
static int UnlockRegionStatic(
IStream* pThis, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, uint dwLockType) =>
ToManagedObject(pThis)?.UnlockRegion(libOffset, cb, dwLockType) ?? E.E_UNEXPECTED;
- [UnmanagedCallersOnly]
+ [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
static int StatStatic(IStream* pThis, STATSTG* pstatstg, uint grfStatFlag) =>
ToManagedObject(pThis)?.Stat(pstatstg, grfStatFlag) ?? E.E_UNEXPECTED;
- [UnmanagedCallersOnly]
+ [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
static int CloneStatic(IStream* pThis, IStream** ppstm) => ToManagedObject(pThis)?.Clone(ppstm) ?? E.E_UNEXPECTED;
}
diff --git a/Dalamud/Utility/TerraFxCom/TerraFxComInterfaceExtensions.cs b/Dalamud/Utility/TerraFxCom/TerraFxComInterfaceExtensions.cs
index f9252839f..ec108403e 100644
--- a/Dalamud/Utility/TerraFxCom/TerraFxComInterfaceExtensions.cs
+++ b/Dalamud/Utility/TerraFxCom/TerraFxComInterfaceExtensions.cs
@@ -88,7 +88,7 @@ internal static unsafe partial class TerraFxComInterfaceExtensions
fixed (char* pPath = path)
{
SHCreateStreamOnFileEx(
- (ushort*)pPath,
+ pPath,
grfMode,
(uint)attributes,
fCreate,
@@ -115,7 +115,7 @@ internal static unsafe partial class TerraFxComInterfaceExtensions
{
fixed (char* pName = name)
{
- var option = new PROPBAG2 { pstrName = (ushort*)pName };
+ var option = new PROPBAG2 { pstrName = pName };
return obj.Write(1, &option, &varValue);
}
}
@@ -145,7 +145,7 @@ internal static unsafe partial class TerraFxComInterfaceExtensions
try
{
fixed (char* pName = name)
- return obj.SetMetadataByName((ushort*)pName, &propVarValue);
+ return obj.SetMetadataByName(pName, &propVarValue);
}
finally
{
@@ -165,7 +165,7 @@ internal static unsafe partial class TerraFxComInterfaceExtensions
public static HRESULT RemoveMetadataByName(ref this IWICMetadataQueryWriter obj, string name)
{
fixed (char* pName = name)
- return obj.RemoveMetadataByName((ushort*)pName);
+ return obj.RemoveMetadataByName(pName);
}
[LibraryImport("propsys.dll")]
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 903a8ee88..d62d247c3 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -26,7 +26,7 @@
-
+
From fc983458fa16c698977b386fdefac4d385256f01 Mon Sep 17 00:00:00 2001
From: Haselnussbomber
Date: Fri, 5 Dec 2025 01:44:18 +0100
Subject: [PATCH 22/50] Update Nuke
---
build/DalamudBuild.cs | 6 ++----
build/build.csproj | 2 +-
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/build/DalamudBuild.cs b/build/DalamudBuild.cs
index ba2b09a4d..1a189f2c7 100644
--- a/build/DalamudBuild.cs
+++ b/build/DalamudBuild.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.IO;
using Nuke.Common;
using Nuke.Common.Execution;
using Nuke.Common.Git;
@@ -128,7 +127,7 @@ public class DalamudBuild : NukeBuild
if (IsCIBuild)
{
s = s
- .SetProcessArgumentConfigurator(a => a.Add("/clp:NoSummary")); // Disable MSBuild summary on CI builds
+ .SetProcessAdditionalArguments("/clp:NoSummary"); // Disable MSBuild summary on CI builds
}
// We need to emit compiler generated files for the docs build, since docfx can't run generators directly
// TODO: This fails every build after this because of redefinitions...
@@ -238,7 +237,6 @@ public class DalamudBuild : NukeBuild
.SetProject(InjectorProjectFile)
.SetConfiguration(Configuration));
- FileSystemTasks.DeleteDirectory(ArtifactsDirectory);
- Directory.CreateDirectory(ArtifactsDirectory);
+ ArtifactsDirectory.CreateOrCleanDirectory();
});
}
diff --git a/build/build.csproj b/build/build.csproj
index 1e1416d92..7096c7f8a 100644
--- a/build/build.csproj
+++ b/build/build.csproj
@@ -11,7 +11,7 @@
false
-
+
From e7d4786a1fec6411908ed9e319f1a06b67738389 Mon Sep 17 00:00:00 2001
From: goat <16760685+goaaats@users.noreply.github.com>
Date: Fri, 5 Dec 2025 18:18:57 +0100
Subject: [PATCH 23/50] Oops, wrong version
---
Directory.Packages.props | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 481e7591d..6c5070d35 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -26,7 +26,7 @@
-
+
From 7cf20fe102bf14bea99dead9ec0d4e5ad3c23c92 Mon Sep 17 00:00:00 2001
From: Haselnussbomber
Date: Fri, 5 Dec 2025 00:35:52 +0100
Subject: [PATCH 24/50] Update Microsoft.Windows.CsWin32
---
Dalamud/SafeMemory.cs | 15 +++++++++++++--
Dalamud/Utility/FilesystemUtil.cs | 10 +++++++---
Directory.Packages.props | 2 +-
3 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/Dalamud/SafeMemory.cs b/Dalamud/SafeMemory.cs
index a8ac40a5d..9a1af0625 100644
--- a/Dalamud/SafeMemory.cs
+++ b/Dalamud/SafeMemory.cs
@@ -1,6 +1,8 @@
using System.Runtime.InteropServices;
using System.Text;
+using Windows.Win32.Foundation;
+
namespace Dalamud;
///
@@ -28,12 +30,18 @@ public static class SafeMemory
/// Whether the read succeeded.
public static unsafe bool ReadBytes(IntPtr address, int count, out byte[] buffer)
{
+ if (Handle.IsClosed || Handle.IsInvalid)
+ {
+ buffer = [];
+ return false;
+ }
+
buffer = new byte[count <= 0 ? 0 : count];
fixed (byte* p = buffer)
{
UIntPtr bytesRead;
if (!Windows.Win32.PInvoke.ReadProcessMemory(
- Handle,
+ (HANDLE)Handle.DangerousGetHandle(),
address.ToPointer(),
p,
new UIntPtr((uint)count),
@@ -54,6 +62,9 @@ public static class SafeMemory
/// Whether the write succeeded.
public static unsafe bool WriteBytes(IntPtr address, byte[] buffer)
{
+ if (Handle.IsClosed || Handle.IsInvalid)
+ return false;
+
if (buffer.Length == 0)
return true;
@@ -61,7 +72,7 @@ public static class SafeMemory
fixed (byte* p = buffer)
{
if (!Windows.Win32.PInvoke.WriteProcessMemory(
- Handle,
+ (HANDLE)Handle.DangerousGetHandle(),
address.ToPointer(),
p,
new UIntPtr((uint)buffer.Length),
diff --git a/Dalamud/Utility/FilesystemUtil.cs b/Dalamud/Utility/FilesystemUtil.cs
index 3b4298b37..560e06da3 100644
--- a/Dalamud/Utility/FilesystemUtil.cs
+++ b/Dalamud/Utility/FilesystemUtil.cs
@@ -1,7 +1,8 @@
-using System.ComponentModel;
+using System.ComponentModel;
using System.IO;
using System.Text;
+using Windows.Win32.Foundation;
using Windows.Win32.Storage.FileSystem;
namespace Dalamud.Utility;
@@ -61,8 +62,11 @@ public static class FilesystemUtil
// Write the data
uint bytesWritten = 0;
- if (!Windows.Win32.PInvoke.WriteFile(tempFile, new ReadOnlySpan(bytes), &bytesWritten, null))
- throw new Win32Exception();
+ fixed (byte* ptr = bytes)
+ {
+ if (!Windows.Win32.PInvoke.WriteFile((HANDLE)tempFile.DangerousGetHandle(), ptr, (uint)bytes.Length, &bytesWritten, null))
+ throw new Win32Exception();
+ }
if (bytesWritten != bytes.Length)
throw new Exception($"Could not write all bytes to temp file ({bytesWritten} of {bytes.Length})");
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 6c5070d35..58e355400 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -27,7 +27,7 @@
-
+
From d94cacaac3bec7e2b64d3d13bde9d1dbd61d0714 Mon Sep 17 00:00:00 2001
From: Haselnussbomber
Date: Fri, 5 Dec 2025 19:10:31 +0100
Subject: [PATCH 25/50] Disable SafeHandles
---
Dalamud/EntryPoint.cs | 2 +-
Dalamud/Hooking/Hook.cs | 14 +++++++-------
Dalamud/NativeMethods.json | 1 +
Dalamud/SafeMemory.cs | 12 ++++++------
Dalamud/Utility/FilesystemUtil.cs | 16 +++++++++++-----
Dalamud/Utility/Util.cs | 5 ++---
6 files changed, 28 insertions(+), 22 deletions(-)
diff --git a/Dalamud/EntryPoint.cs b/Dalamud/EntryPoint.cs
index 15077f3d8..b5504b046 100644
--- a/Dalamud/EntryPoint.cs
+++ b/Dalamud/EntryPoint.cs
@@ -263,7 +263,7 @@ public sealed class EntryPoint
var symbolPath = Path.Combine(info.AssetDirectory, "UIRes", "pdb");
var searchPath = $".;{symbolPath}";
- var currentProcess = Windows.Win32.PInvoke.GetCurrentProcess_SafeHandle();
+ var currentProcess = Windows.Win32.PInvoke.GetCurrentProcess();
// Remove any existing Symbol Handler and Init a new one with our search path added
Windows.Win32.PInvoke.SymCleanup(currentProcess);
diff --git a/Dalamud/Hooking/Hook.cs b/Dalamud/Hooking/Hook.cs
index faf4658a5..1cd3ef91d 100644
--- a/Dalamud/Hooking/Hook.cs
+++ b/Dalamud/Hooking/Hook.cs
@@ -201,19 +201,19 @@ public abstract class Hook : IDalamudHook where T : Delegate
if (EnvironmentConfiguration.DalamudForceMinHook)
useMinHook = true;
- using var moduleHandle = Windows.Win32.PInvoke.GetModuleHandle(moduleName);
- if (moduleHandle.IsInvalid)
+ var moduleHandle = Windows.Win32.PInvoke.GetModuleHandle(moduleName);
+ if (moduleHandle.IsNull)
throw new Exception($"Could not get a handle to module {moduleName}");
- var procAddress = (nint)Windows.Win32.PInvoke.GetProcAddress(moduleHandle, exportName);
- if (procAddress == IntPtr.Zero)
+ var procAddress = Windows.Win32.PInvoke.GetProcAddress(moduleHandle, exportName);
+ if (procAddress.IsNull)
throw new Exception($"Could not get the address of {moduleName}::{exportName}");
- procAddress = HookManager.FollowJmp(procAddress);
+ var address = HookManager.FollowJmp(procAddress.Value);
if (useMinHook)
- return new MinHookHook(procAddress, detour, Assembly.GetCallingAssembly());
+ return new MinHookHook(address, detour, Assembly.GetCallingAssembly());
else
- return new ReloadedHook(procAddress, detour, Assembly.GetCallingAssembly());
+ return new ReloadedHook(address, detour, Assembly.GetCallingAssembly());
}
///
diff --git a/Dalamud/NativeMethods.json b/Dalamud/NativeMethods.json
index ffb313dfc..46fd3504f 100644
--- a/Dalamud/NativeMethods.json
+++ b/Dalamud/NativeMethods.json
@@ -1,4 +1,5 @@
{
"$schema": "https://aka.ms/CsWin32.schema.json",
+ "useSafeHandles": false,
"allowMarshaling": false
}
diff --git a/Dalamud/SafeMemory.cs b/Dalamud/SafeMemory.cs
index 9a1af0625..ca0c8ff92 100644
--- a/Dalamud/SafeMemory.cs
+++ b/Dalamud/SafeMemory.cs
@@ -14,11 +14,11 @@ namespace Dalamud;
///
public static class SafeMemory
{
- private static readonly SafeHandle Handle;
+ private static readonly HANDLE Handle;
static SafeMemory()
{
- Handle = Windows.Win32.PInvoke.GetCurrentProcess_SafeHandle();
+ Handle = Windows.Win32.PInvoke.GetCurrentProcess();
}
///
@@ -30,7 +30,7 @@ public static class SafeMemory
/// Whether the read succeeded.
public static unsafe bool ReadBytes(IntPtr address, int count, out byte[] buffer)
{
- if (Handle.IsClosed || Handle.IsInvalid)
+ if (Handle.IsNull)
{
buffer = [];
return false;
@@ -41,7 +41,7 @@ public static class SafeMemory
{
UIntPtr bytesRead;
if (!Windows.Win32.PInvoke.ReadProcessMemory(
- (HANDLE)Handle.DangerousGetHandle(),
+ Handle,
address.ToPointer(),
p,
new UIntPtr((uint)count),
@@ -62,7 +62,7 @@ public static class SafeMemory
/// Whether the write succeeded.
public static unsafe bool WriteBytes(IntPtr address, byte[] buffer)
{
- if (Handle.IsClosed || Handle.IsInvalid)
+ if (Handle.IsNull)
return false;
if (buffer.Length == 0)
@@ -72,7 +72,7 @@ public static class SafeMemory
fixed (byte* p = buffer)
{
if (!Windows.Win32.PInvoke.WriteProcessMemory(
- (HANDLE)Handle.DangerousGetHandle(),
+ Handle,
address.ToPointer(),
p,
new UIntPtr((uint)buffer.Length),
diff --git a/Dalamud/Utility/FilesystemUtil.cs b/Dalamud/Utility/FilesystemUtil.cs
index 560e06da3..f1b62ee21 100644
--- a/Dalamud/Utility/FilesystemUtil.cs
+++ b/Dalamud/Utility/FilesystemUtil.cs
@@ -48,33 +48,39 @@ public static class FilesystemUtil
// Open the temp file
var tempPath = path + ".tmp";
- using var tempFile = Windows.Win32.PInvoke.CreateFile(
+ var tempFile = Windows.Win32.PInvoke.CreateFile(
tempPath,
(uint)(FILE_ACCESS_RIGHTS.FILE_GENERIC_READ | FILE_ACCESS_RIGHTS.FILE_GENERIC_WRITE),
FILE_SHARE_MODE.FILE_SHARE_NONE,
null,
FILE_CREATION_DISPOSITION.CREATE_ALWAYS,
FILE_FLAGS_AND_ATTRIBUTES.FILE_ATTRIBUTE_NORMAL,
- null);
+ HANDLE.Null);
- if (tempFile.IsInvalid)
+ if (tempFile.IsNull)
throw new Win32Exception();
// Write the data
uint bytesWritten = 0;
fixed (byte* ptr = bytes)
{
- if (!Windows.Win32.PInvoke.WriteFile((HANDLE)tempFile.DangerousGetHandle(), ptr, (uint)bytes.Length, &bytesWritten, null))
+ if (!Windows.Win32.PInvoke.WriteFile(tempFile, ptr, (uint)bytes.Length, &bytesWritten, null))
throw new Win32Exception();
}
if (bytesWritten != bytes.Length)
+ {
+ Windows.Win32.PInvoke.CloseHandle(tempFile);
throw new Exception($"Could not write all bytes to temp file ({bytesWritten} of {bytes.Length})");
+ }
if (!Windows.Win32.PInvoke.FlushFileBuffers(tempFile))
+ {
+ Windows.Win32.PInvoke.CloseHandle(tempFile);
throw new Win32Exception();
+ }
- tempFile.Close();
+ Windows.Win32.PInvoke.CloseHandle(tempFile);
if (!Windows.Win32.PInvoke.MoveFileEx(tempPath, path, MOVE_FILE_FLAGS.MOVEFILE_REPLACE_EXISTING | MOVE_FILE_FLAGS.MOVEFILE_WRITE_THROUGH))
throw new Win32Exception();
diff --git a/Dalamud/Utility/Util.cs b/Dalamud/Utility/Util.cs
index 19610ef64..f50efcf0d 100644
--- a/Dalamud/Utility/Util.cs
+++ b/Dalamud/Utility/Util.cs
@@ -858,7 +858,7 @@ public static partial class Util
var sizeWithTerminators = pathBytesSize + (pathBytes.Length * 2);
var dropFilesSize = sizeof(DROPFILES);
- var hGlobal = Win32_PInvoke.GlobalAlloc_SafeHandle(
+ var hGlobal = Win32_PInvoke.GlobalAlloc(
GLOBAL_ALLOC_FLAGS.GHND,
// struct size + size of encoded strings + null terminator for each
// string + two null terminators for end of list
@@ -896,12 +896,11 @@ public static partial class Util
{
Win32_PInvoke.SetClipboardData(
(uint)CLIPBOARD_FORMAT.CF_HDROP,
- hGlobal);
+ (Windows.Win32.Foundation.HANDLE)hGlobal.Value);
Win32_PInvoke.CloseClipboard();
return true;
}
- hGlobal.Dispose();
return false;
}
From a36e11574b14ea6887cb0f7d2513920ebdd820bf Mon Sep 17 00:00:00 2001
From: goat <16760685+goaaats@users.noreply.github.com>
Date: Sat, 6 Dec 2025 01:10:00 +0100
Subject: [PATCH 26/50] Add git status checks to workflow to see what's dirty
---
.github/workflows/main.yml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 299d71e95..f552e446b 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -33,8 +33,12 @@ jobs:
($env:REPO_NAME) >> VERSION
($env:BRANCH) >> VERSION
($env:COMMIT) >> VERSION
+ - name: git status
+ run: git status
- name: Build and Test Dalamud
run: .\build.ps1 ci
+ - name: git status
+ run: git status
- name: Sign Dalamud
if: ${{ github.repository_owner == 'goatcorp' && github.event_name == 'push' }}
env:
From 3c7dbf9f81e147e45f7b3541844e95cebcc3a5df Mon Sep 17 00:00:00 2001
From: MidoriKami
Date: Fri, 5 Dec 2025 16:59:17 -0800
Subject: [PATCH 27/50] Remove AddonEventManagerAddressResolver.cs
---
.../Game/Addon/Events/AddonEventManager.cs | 30 ++++++++-----------
.../AddonEventManagerAddressResolver.cs | 21 -------------
2 files changed, 12 insertions(+), 39 deletions(-)
delete mode 100644 Dalamud/Game/Addon/Events/AddonEventManagerAddressResolver.cs
diff --git a/Dalamud/Game/Addon/Events/AddonEventManager.cs b/Dalamud/Game/Addon/Events/AddonEventManager.cs
index 945197e2b..980404940 100644
--- a/Dalamud/Game/Addon/Events/AddonEventManager.cs
+++ b/Dalamud/Game/Addon/Events/AddonEventManager.cs
@@ -9,7 +9,6 @@ using Dalamud.Logging.Internal;
using Dalamud.Plugin.Internal.Types;
using Dalamud.Plugin.Services;
-using FFXIVClientStructs.FFXIV.Client.UI;
using FFXIVClientStructs.FFXIV.Component.GUI;
namespace Dalamud.Game.Addon.Events;
@@ -32,25 +31,21 @@ internal unsafe class AddonEventManager : IInternalDisposableService
private readonly AddonLifecycleEventListener finalizeEventListener;
- private readonly AddonEventManagerAddressResolver address;
- private readonly Hook onUpdateCursor;
+ private readonly Hook onUpdateCursor;
private readonly ConcurrentDictionary pluginEventControllers;
- private AddonCursorType? cursorOverride;
+ private AtkCursor.CursorType? cursorOverride;
[ServiceManager.ServiceConstructor]
- private AddonEventManager(TargetSigScanner sigScanner)
+ private AddonEventManager()
{
- this.address = new AddonEventManagerAddressResolver();
- this.address.Setup(sigScanner);
-
this.pluginEventControllers = new ConcurrentDictionary();
this.pluginEventControllers.TryAdd(DalamudInternalKey, new PluginEventController());
this.cursorOverride = null;
- this.onUpdateCursor = Hook.FromAddress(this.address.UpdateCursor, this.UpdateCursorDetour);
+ this.onUpdateCursor = Hook.FromAddress(AtkUnitManager.Addresses.UpdateCursor.Value, this.UpdateCursorDetour);
this.finalizeEventListener = new AddonLifecycleEventListener(AddonEvent.PreFinalize, string.Empty, this.OnAddonFinalize);
this.addonLifecycle.RegisterListener(this.finalizeEventListener);
@@ -58,8 +53,6 @@ internal unsafe class AddonEventManager : IInternalDisposableService
this.onUpdateCursor.Enable();
}
- private delegate nint UpdateCursorDelegate(RaptureAtkModule* module);
-
///
void IInternalDisposableService.DisposeService()
{
@@ -117,7 +110,7 @@ internal unsafe class AddonEventManager : IInternalDisposableService
/// Force the game cursor to be the specified cursor.
///
/// Which cursor to use.
- internal void SetCursor(AddonCursorType cursor) => this.cursorOverride = cursor;
+ internal void SetCursor(AddonCursorType cursor) => this.cursorOverride = (AtkCursor.CursorType)cursor;
///
/// Un-forces the game cursor.
@@ -168,7 +161,7 @@ internal unsafe class AddonEventManager : IInternalDisposableService
}
}
- private nint UpdateCursorDetour(RaptureAtkModule* module)
+ private void UpdateCursorDetour(AtkUnitManager* thisPtr)
{
try
{
@@ -176,13 +169,14 @@ internal unsafe class AddonEventManager : IInternalDisposableService
if (this.cursorOverride is not null && atkStage is not null)
{
- var cursor = (AddonCursorType)atkStage->AtkCursor.Type;
- if (cursor != this.cursorOverride)
+ ref var atkCursor = ref atkStage->AtkCursor;
+
+ if (atkCursor.Type != this.cursorOverride)
{
- AtkStage.Instance()->AtkCursor.SetCursorType((AtkCursor.CursorType)this.cursorOverride, 1);
+ atkCursor.SetCursorType((AtkCursor.CursorType)this.cursorOverride, 1);
}
- return nint.Zero;
+ return;
}
}
catch (Exception e)
@@ -190,7 +184,7 @@ internal unsafe class AddonEventManager : IInternalDisposableService
Log.Error(e, "Exception in UpdateCursorDetour.");
}
- return this.onUpdateCursor!.Original(module);
+ this.onUpdateCursor!.Original(thisPtr);
}
}
diff --git a/Dalamud/Game/Addon/Events/AddonEventManagerAddressResolver.cs b/Dalamud/Game/Addon/Events/AddonEventManagerAddressResolver.cs
deleted file mode 100644
index 415e1b169..000000000
--- a/Dalamud/Game/Addon/Events/AddonEventManagerAddressResolver.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-namespace Dalamud.Game.Addon.Events;
-
-///
-/// AddonEventManager memory address resolver.
-///
-internal class AddonEventManagerAddressResolver : BaseAddressResolver
-{
- ///
- /// Gets the address of the AtkModule UpdateCursor method.
- ///
- public nint UpdateCursor { get; private set; }
-
- ///
- /// Scan for and setup any configured address pointers.
- ///
- /// The signature scanner to facilitate setup.
- protected override void Setup64Bit(ISigScanner scanner)
- {
- this.UpdateCursor = scanner.ScanText("48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 20 4C 8B F1 E8 ?? ?? ?? ?? 49 8B CE"); // unnamed in CS
- }
-}
From 2e5c560ed729b7e88e6f036aa9987bca5e6f7be0 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Sat, 6 Dec 2025 12:48:34 +0000
Subject: [PATCH 28/50] Update ClientStructs
---
lib/FFXIVClientStructs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/FFXIVClientStructs b/lib/FFXIVClientStructs
index e5dedba42..6f339d8f7 160000
--- a/lib/FFXIVClientStructs
+++ b/lib/FFXIVClientStructs
@@ -1 +1 @@
-Subproject commit e5dedba42a3fea8f050ea54ac583a5874bf51c6f
+Subproject commit 6f339d8f725fa6922449f7e5c584ca6b8fa2fb19
From 9c2d2b7c1dbe192599748e7320fce3c1cc972072 Mon Sep 17 00:00:00 2001
From: goaaats
Date: Sat, 6 Dec 2025 15:07:09 +0100
Subject: [PATCH 29/50] Report CLR errors through DalamudCrashHandler/VEH by
hooking ReportEventW
---
Dalamud.Boot/dllmain.cpp | 41 ++++++++++++++++++++++++++++++++++++++++
Dalamud.Boot/veh.cpp | 37 ++++++++++++++++++++++++++++--------
Dalamud.Boot/veh.h | 1 +
3 files changed, 71 insertions(+), 8 deletions(-)
diff --git a/Dalamud.Boot/dllmain.cpp b/Dalamud.Boot/dllmain.cpp
index 80a16f89a..2af78092d 100644
--- a/Dalamud.Boot/dllmain.cpp
+++ b/Dalamud.Boot/dllmain.cpp
@@ -331,6 +331,47 @@ HRESULT WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) {
logging::I("VEH was disabled manually");
}
+ // ============================== CLR Reporting =================================== //
+
+ // This is pretty horrible - CLR just doesn't provide a way for us to handle these events, and the API for it
+ // was pushed back to .NET 11, so we have to hook ReportEventW and catch them ourselves for now.
+ // Ideally all of this will go away once they get to it.
+ static std::shared_ptr> s_hook;
+ s_hook = std::make_shared>("advapi32.dll!ReportEventW (global import, hook_clr_report_event)", L"advapi32.dll", "ReportEventW");
+ s_hook->set_detour([hook = s_hook.get()]( HANDLE hEventLog,
+ WORD wType,
+ WORD wCategory,
+ DWORD dwEventID,
+ PSID lpUserSid,
+ WORD wNumStrings,
+ DWORD dwDataSize,
+ LPCWSTR* lpStrings,
+ LPVOID lpRawData)->BOOL {
+
+ // Check for CLR Error Event IDs
+ if (dwEventID != 1026 && // ERT_UnhandledException: The process was terminated due to an unhandled exception
+ dwEventID != 1025 && // ERT_ManagedFailFast: The application requested process termination through System.Environment.FailFast
+ dwEventID != 1023 && // ERT_UnmanagedFailFast: The process was terminated due to an internal error in the .NET Runtime
+ dwEventID != 1027 && // ERT_StackOverflow: The process was terminated due to a stack overflow
+ dwEventID != 1028) // ERT_CodeContractFailed: The application encountered a bug. A managed code contract (precondition, postcondition, object invariant, or assert) failed
+ {
+ return hook->call_original(hEventLog, wType, wCategory, dwEventID, lpUserSid, wNumStrings, dwDataSize, lpStrings, lpRawData);
+ }
+
+ if (wNumStrings == 0 || lpStrings == nullptr) {
+ logging::W("ReportEventW called with no strings.");
+ return hook->call_original(hEventLog, wType, wCategory, dwEventID, lpUserSid, wNumStrings, dwDataSize, lpStrings, lpRawData);
+ }
+
+ // In most cases, DalamudCrashHandler will kill us now, so call original here to make sure we still write to the event log.
+ const BOOL original_ret = hook->call_original(hEventLog, wType, wCategory, dwEventID, lpUserSid, wNumStrings, dwDataSize, lpStrings, lpRawData);
+
+ const std::wstring error_details(lpStrings[0]);
+ veh::raise_external_event(error_details);
+
+ return original_ret;
+ });
+
// ============================== Dalamud ==================================== //
if (static_cast(g_startInfo.BootWaitMessageBox) & static_cast(DalamudStartInfo::WaitMessageboxFlags::BeforeDalamudEntrypoint))
diff --git a/Dalamud.Boot/veh.cpp b/Dalamud.Boot/veh.cpp
index b0ec1cefa..24a846e66 100644
--- a/Dalamud.Boot/veh.cpp
+++ b/Dalamud.Boot/veh.cpp
@@ -11,6 +11,8 @@
#include "crashhandler_shared.h"
#include "DalamudStartInfo.h"
+#define CUSTOM_EXCEPTION_EXTERNAL_EVENT 0x12345679
+
#pragma comment(lib, "comctl32.lib")
#if defined _M_IX86
@@ -31,6 +33,8 @@ HANDLE g_crashhandler_process = nullptr;
HANDLE g_crashhandler_event = nullptr;
HANDLE g_crashhandler_pipe_write = nullptr;
+wchar_t g_external_event_info[16384] = L"";
+
std::recursive_mutex g_exception_handler_mutex;
std::chrono::time_point g_time_start;
@@ -190,7 +194,11 @@ LONG exception_handler(EXCEPTION_POINTERS* ex)
DuplicateHandle(GetCurrentProcess(), g_crashhandler_event, g_crashhandler_process, &exinfo.hEventHandle, 0, TRUE, DUPLICATE_SAME_ACCESS);
std::wstring stackTrace;
- if (!g_clr)
+ if (ex->ExceptionRecord->ExceptionCode == CUSTOM_EXCEPTION_EXTERNAL_EVENT)
+ {
+ stackTrace = std::wstring(g_external_event_info);
+ }
+ else if (!g_clr)
{
stackTrace = L"(no CLR stack trace available)";
}
@@ -251,6 +259,12 @@ LONG WINAPI structured_exception_handler(EXCEPTION_POINTERS* ex)
LONG WINAPI vectored_exception_handler(EXCEPTION_POINTERS* ex)
{
+ // special case for CLR exceptions, always trigger crash handler
+ if (ex->ExceptionRecord->ExceptionCode == CUSTOM_EXCEPTION_EXTERNAL_EVENT)
+ {
+ return exception_handler(ex);
+ }
+
if (ex->ExceptionRecord->ExceptionCode == 0x12345678)
{
// pass
@@ -268,7 +282,7 @@ LONG WINAPI vectored_exception_handler(EXCEPTION_POINTERS* ex)
if (!is_ffxiv_address(L"ffxiv_dx11.exe", ex->ContextRecord->Rip) &&
!is_ffxiv_address(L"cimgui.dll", ex->ContextRecord->Rip))
- return EXCEPTION_CONTINUE_SEARCH;
+ return EXCEPTION_CONTINUE_SEARCH;
}
return exception_handler(ex);
@@ -297,7 +311,7 @@ bool veh::add_handler(bool doFullDump, const std::string& workingDirectory)
if (HANDLE hReadPipeRaw, hWritePipeRaw; CreatePipe(&hReadPipeRaw, &hWritePipeRaw, nullptr, 65536))
{
hWritePipe.emplace(hWritePipeRaw, &CloseHandle);
-
+
if (HANDLE hReadPipeInheritableRaw; DuplicateHandle(GetCurrentProcess(), hReadPipeRaw, GetCurrentProcess(), &hReadPipeInheritableRaw, 0, TRUE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
{
hReadPipeInheritable.emplace(hReadPipeInheritableRaw, &CloseHandle);
@@ -315,9 +329,9 @@ bool veh::add_handler(bool doFullDump, const std::string& workingDirectory)
}
// additional information
- STARTUPINFOEXW siex{};
+ STARTUPINFOEXW siex{};
PROCESS_INFORMATION pi{};
-
+
siex.StartupInfo.cb = sizeof siex;
siex.StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
siex.StartupInfo.wShowWindow = g_startInfo.CrashHandlerShow ? SW_SHOW : SW_HIDE;
@@ -385,7 +399,7 @@ bool veh::add_handler(bool doFullDump, const std::string& workingDirectory)
argstr.push_back(L' ');
}
argstr.pop_back();
-
+
if (!handles.empty() && !UpdateProcThreadAttribute(siex.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, &handles[0], std::span(handles).size_bytes(), nullptr, nullptr))
{
logging::W("Failed to launch DalamudCrashHandler.exe: UpdateProcThreadAttribute error 0x{:x}", GetLastError());
@@ -400,7 +414,7 @@ bool veh::add_handler(bool doFullDump, const std::string& workingDirectory)
TRUE, // Set handle inheritance to FALSE
EXTENDED_STARTUPINFO_PRESENT, // lpStartupInfo actually points to a STARTUPINFOEX(W)
nullptr, // Use parent's environment block
- nullptr, // Use parent's starting directory
+ nullptr, // Use parent's starting directory
&siex.StartupInfo, // Pointer to STARTUPINFO structure
&pi // Pointer to PROCESS_INFORMATION structure (removed extra parentheses)
))
@@ -416,7 +430,7 @@ bool veh::add_handler(bool doFullDump, const std::string& workingDirectory)
}
CloseHandle(pi.hThread);
-
+
g_crashhandler_process = pi.hProcess;
g_crashhandler_pipe_write = hWritePipe->release();
logging::I("Launched DalamudCrashHandler.exe: PID {}", pi.dwProcessId);
@@ -434,3 +448,10 @@ bool veh::remove_handler()
}
return false;
}
+
+void veh::raise_external_event(const std::wstring& errorMessage)
+{
+ const auto info_size = std::min(errorMessage.size(), std::size(g_external_event_info) - 1);
+ wcsncpy_s(g_external_event_info, errorMessage.c_str(), info_size);
+ RaiseException(CUSTOM_EXCEPTION_EXTERNAL_EVENT, 0, 0, nullptr);
+}
diff --git a/Dalamud.Boot/veh.h b/Dalamud.Boot/veh.h
index 1905272ea..2a02c374e 100644
--- a/Dalamud.Boot/veh.h
+++ b/Dalamud.Boot/veh.h
@@ -4,4 +4,5 @@ namespace veh
{
bool add_handler(bool doFullDump, const std::string& workingDirectory);
bool remove_handler();
+ void raise_external_event(const std::wstring& info);
}
From e09c43b8decc55fcbc38cd61102256db0bdc4e29 Mon Sep 17 00:00:00 2001
From: goaaats
Date: Sat, 6 Dec 2025 15:07:46 +0100
Subject: [PATCH 30/50] Fix bad exit condition when looping exception records
---
DalamudCrashHandler/DalamudCrashHandler.cpp | 78 ++++++++++++---------
1 file changed, 43 insertions(+), 35 deletions(-)
diff --git a/DalamudCrashHandler/DalamudCrashHandler.cpp b/DalamudCrashHandler/DalamudCrashHandler.cpp
index ec7115ffd..107261541 100644
--- a/DalamudCrashHandler/DalamudCrashHandler.cpp
+++ b/DalamudCrashHandler/DalamudCrashHandler.cpp
@@ -119,7 +119,7 @@ std::wstring describe_module(const std::filesystem::path& path) {
return std::format(L"", GetLastError());
UINT size = 0;
-
+
std::wstring version = L"v?.?.?.?";
if (LPVOID lpBuffer; VerQueryValueW(block.data(), L"\\", &lpBuffer, &size)) {
const auto& v = *static_cast(lpBuffer);
@@ -176,7 +176,7 @@ const std::map& get_remote_modules() {
std::vector buf(8192);
for (size_t i = 0; i < 64; i++) {
if (DWORD needed; !EnumProcessModules(g_hProcess, &buf[0], static_cast(std::span(buf).size_bytes()), &needed)) {
- std::cerr << std::format("EnumProcessModules error: 0x{:x}", GetLastError()) << std::endl;
+ std::cerr << std::format("EnumProcessModules error: 0x{:x}", GetLastError()) << std::endl;
break;
} else if (needed > std::span(buf).size_bytes()) {
buf.resize(needed / sizeof(HMODULE) + 16);
@@ -201,7 +201,7 @@ const std::map& get_remote_modules() {
data[hModule] = nth64.OptionalHeader.SizeOfImage;
}
-
+
return data;
}();
@@ -292,35 +292,43 @@ std::wstring to_address_string(const DWORD64 address, const bool try_ptrderef =
void print_exception_info(HANDLE hThread, const EXCEPTION_POINTERS& ex, const CONTEXT& ctx, std::wostringstream& log) {
std::vector exRecs;
- if (ex.ExceptionRecord) {
+ if (ex.ExceptionRecord)
+ {
size_t rec_index = 0;
size_t read;
- exRecs.emplace_back();
+
for (auto pRemoteExRec = ex.ExceptionRecord;
- pRemoteExRec
- && rec_index < 64
- && ReadProcessMemory(g_hProcess, pRemoteExRec, &exRecs.back(), sizeof exRecs.back(), &read)
- && read >= offsetof(EXCEPTION_RECORD, ExceptionInformation)
- && read >= static_cast(reinterpret_cast(&exRecs.back().ExceptionInformation[exRecs.back().NumberParameters]) - reinterpret_cast(&exRecs.back()));
- rec_index++) {
+ pRemoteExRec && rec_index < 64;
+ rec_index++)
+ {
+ exRecs.emplace_back();
+
+ if (!ReadProcessMemory(g_hProcess, pRemoteExRec, &exRecs.back(), sizeof exRecs.back(), &read)
+ || read < offsetof(EXCEPTION_RECORD, ExceptionInformation)
+ || read < static_cast(reinterpret_cast(&exRecs.back().ExceptionInformation[exRecs.
+ back().NumberParameters]) - reinterpret_cast(&exRecs.back())))
+ {
+ exRecs.pop_back();
+ break;
+ }
log << std::format(L"\nException Info #{}\n", rec_index);
log << std::format(L"Address: {:X}\n", exRecs.back().ExceptionCode);
log << std::format(L"Flags: {:X}\n", exRecs.back().ExceptionFlags);
log << std::format(L"Address: {:X}\n", reinterpret_cast(exRecs.back().ExceptionAddress));
- if (!exRecs.back().NumberParameters)
- continue;
- log << L"Parameters: ";
- for (DWORD i = 0; i < exRecs.back().NumberParameters; ++i) {
- if (i != 0)
- log << L", ";
- log << std::format(L"{:X}", exRecs.back().ExceptionInformation[i]);
+ if (exRecs.back().NumberParameters)
+ {
+ log << L"Parameters: ";
+ for (DWORD i = 0; i < exRecs.back().NumberParameters; ++i)
+ {
+ if (i != 0)
+ log << L", ";
+ log << std::format(L"{:X}", exRecs.back().ExceptionInformation[i]);
+ }
}
pRemoteExRec = exRecs.back().ExceptionRecord;
- exRecs.emplace_back();
}
- exRecs.pop_back();
}
log << L"\nCall Stack\n{";
@@ -410,7 +418,7 @@ void print_exception_info_extended(const EXCEPTION_POINTERS& ex, const CONTEXT&
std::wstring escape_shell_arg(const std::wstring& arg) {
// https://docs.microsoft.com/en-us/archive/blogs/twistylittlepassagesallalike/everyone-quotes-command-line-arguments-the-wrong-way
-
+
std::wstring res;
if (!arg.empty() && arg.find_first_of(L" \t\n\v\"") == std::wstring::npos) {
res.append(arg);
@@ -504,7 +512,7 @@ void export_tspack(HWND hWndParent, const std::filesystem::path& logDir, const s
filePath.emplace(pFilePath);
std::fstream fileStream(*filePath, std::ios::binary | std::ios::in | std::ios::out | std::ios::trunc);
-
+
mz_zip_archive zipa{};
zipa.m_pIO_opaque = &fileStream;
zipa.m_pRead = [](void* pOpaque, mz_uint64 file_ofs, void* pBuf, size_t n) -> size_t {
@@ -566,7 +574,7 @@ void export_tspack(HWND hWndParent, const std::filesystem::path& logDir, const s
const auto hLogFile = CreateFileW(logFilePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, nullptr);
if (hLogFile == INVALID_HANDLE_VALUE)
throw_last_error(std::format("indiv. log file: CreateFileW({})", ws_to_u8(logFilePath.wstring())));
-
+
std::unique_ptr hLogFileClose(hLogFile, &CloseHandle);
LARGE_INTEGER size, baseOffset{};
@@ -695,7 +703,7 @@ int main() {
// IFileSaveDialog only works on STA
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
-
+
std::vector args;
if (int argc = 0; const auto argv = CommandLineToArgvW(GetCommandLineW(), &argc)) {
for (auto i = 0; i < argc; i++)
@@ -823,14 +831,14 @@ int main() {
hr = pOleWindow->GetWindow(&hwndProgressDialog);
if (SUCCEEDED(hr))
{
- SetWindowPos(hwndProgressDialog, HWND_TOPMOST, 0, 0, 0, 0,
+ SetWindowPos(hwndProgressDialog, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
SetForegroundWindow(hwndProgressDialog);
}
-
+
pOleWindow->Release();
}
-
+
}
else {
std::cerr << "Failed to create progress window" << std::endl;
@@ -852,14 +860,14 @@ int main() {
https://github.com/sumatrapdfreader/sumatrapdf/blob/master/src/utils/DbgHelpDyn.cpp
*/
-
+
if (g_bSymbolsAvailable) {
SymRefreshModuleList(g_hProcess);
}
else if(!assetDir.empty())
{
auto symbol_search_path = std::format(L".;{}", (assetDir / "UIRes" / "pdb").wstring());
-
+
g_bSymbolsAvailable = SymInitializeW(g_hProcess, symbol_search_path.c_str(), true);
std::wcout << std::format(L"Init symbols with PDB at {}", symbol_search_path) << std::endl;
@@ -870,12 +878,12 @@ int main() {
g_bSymbolsAvailable = SymInitializeW(g_hProcess, nullptr, true);
std::cout << "Init symbols without PDB" << std::endl;
}
-
+
if (!g_bSymbolsAvailable) {
std::wcerr << std::format(L"SymInitialize error: 0x{:x}", GetLastError()) << std::endl;
}
- if (pProgressDialog)
+ if (pProgressDialog)
pProgressDialog->SetLine(3, L"Reading troubleshooting data", FALSE, NULL);
std::wstring stackTrace(exinfo.dwStackTraceLength, L'\0');
@@ -936,7 +944,7 @@ int main() {
if (shutup)
log << L"======= Crash handler was globally muted(shutdown?) =======" << std::endl;
-
+
if (dumpPath.empty())
log << L"Dump skipped" << std::endl;
else if (dumpError.empty())
@@ -1003,7 +1011,7 @@ int main() {
R"aa(Help | Open log directory | Open log file)aa"
);
#endif
-
+
// Can't do this, xiv stops pumping messages here
//config.hwndParent = FindWindowA("FFXIVGAME", NULL);
@@ -1056,13 +1064,13 @@ int main() {
return (*reinterpret_cast(dwRefData))(hwnd, uNotification, wParam, lParam);
};
config.lpCallbackData = reinterpret_cast(&callback);
-
+
if (pProgressDialog) {
pProgressDialog->StopProgressDialog();
pProgressDialog->Release();
pProgressDialog = NULL;
}
-
+
const auto kill_game = [&] { TerminateProcess(g_hProcess, exinfo.ExceptionRecord.ExceptionCode); };
if (shutup) {
From 446c7e38771a943ac7b2dd9d5b48478f95d66250 Mon Sep 17 00:00:00 2001
From: goaaats
Date: Sat, 6 Dec 2025 15:14:13 +0100
Subject: [PATCH 31/50] Some logging, cleanup
---
Dalamud.Boot/dllmain.cpp | 26 +++++++++++++++-----------
Dalamud.Boot/veh.cpp | 6 +++---
2 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/Dalamud.Boot/dllmain.cpp b/Dalamud.Boot/dllmain.cpp
index 2af78092d..687089f82 100644
--- a/Dalamud.Boot/dllmain.cpp
+++ b/Dalamud.Boot/dllmain.cpp
@@ -336,19 +336,22 @@ HRESULT WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) {
// This is pretty horrible - CLR just doesn't provide a way for us to handle these events, and the API for it
// was pushed back to .NET 11, so we have to hook ReportEventW and catch them ourselves for now.
// Ideally all of this will go away once they get to it.
- static std::shared_ptr> s_hook;
- s_hook = std::make_shared>("advapi32.dll!ReportEventW (global import, hook_clr_report_event)", L"advapi32.dll", "ReportEventW");
- s_hook->set_detour([hook = s_hook.get()]( HANDLE hEventLog,
- WORD wType,
- WORD wCategory,
- DWORD dwEventID,
- PSID lpUserSid,
- WORD wNumStrings,
- DWORD dwDataSize,
- LPCWSTR* lpStrings,
- LPVOID lpRawData)->BOOL {
+ static std::shared_ptr> s_report_event_hook;
+ s_report_event_hook = std::make_shared>(
+ "advapi32.dll!ReportEventW (global import, hook_clr_report_event)", L"advapi32.dll", "ReportEventW");
+ s_report_event_hook->set_detour([hook = s_report_event_hook.get()](
+ HANDLE hEventLog,
+ WORD wType,
+ WORD wCategory,
+ DWORD dwEventID,
+ PSID lpUserSid,
+ WORD wNumStrings,
+ DWORD dwDataSize,
+ LPCWSTR* lpStrings,
+ LPVOID lpRawData)-> BOOL {
// Check for CLR Error Event IDs
+ // https://github.com/dotnet/runtime/blob/v10.0.0/src/coreclr/vm/eventreporter.cpp#L370
if (dwEventID != 1026 && // ERT_UnhandledException: The process was terminated due to an unhandled exception
dwEventID != 1025 && // ERT_ManagedFailFast: The application requested process termination through System.Environment.FailFast
dwEventID != 1023 && // ERT_UnmanagedFailFast: The process was terminated due to an internal error in the .NET Runtime
@@ -371,6 +374,7 @@ HRESULT WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) {
return original_ret;
});
+ logging::I("ReportEventW hook installed.");
// ============================== Dalamud ==================================== //
diff --git a/Dalamud.Boot/veh.cpp b/Dalamud.Boot/veh.cpp
index 24a846e66..25c9b5045 100644
--- a/Dalamud.Boot/veh.cpp
+++ b/Dalamud.Boot/veh.cpp
@@ -449,9 +449,9 @@ bool veh::remove_handler()
return false;
}
-void veh::raise_external_event(const std::wstring& errorMessage)
+void veh::raise_external_event(const std::wstring& info)
{
- const auto info_size = std::min(errorMessage.size(), std::size(g_external_event_info) - 1);
- wcsncpy_s(g_external_event_info, errorMessage.c_str(), info_size);
+ const auto info_size = std::min(info.size(), std::size(g_external_event_info) - 1);
+ wcsncpy_s(g_external_event_info, info.c_str(), info_size);
RaiseException(CUSTOM_EXCEPTION_EXTERNAL_EVENT, 0, 0, nullptr);
}
From 1d1db04f04f98a353995f836c53a4e3918b683a6 Mon Sep 17 00:00:00 2001
From: Haselnussbomber
Date: Sat, 6 Dec 2025 16:09:42 +0100
Subject: [PATCH 32/50] Use ImFontPtr in SeStringDrawState
---
.../ImGuiSeStringRenderer/SeStringDrawState.cs | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs
index 11c1120b4..3a21e0db9 100644
--- a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs
+++ b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs
@@ -76,7 +76,7 @@ public unsafe ref struct SeStringDrawState
this.splitter = default;
this.GetEntity = ssdp.GetEntity;
this.ScreenOffset = new(MathF.Round(this.ScreenOffset.X), MathF.Round(this.ScreenOffset.Y));
- this.FontSizeScale = this.FontSize / this.Font->FontSize;
+ this.FontSizeScale = this.FontSize / this.Font.FontSize;
this.LineHeight = MathF.Round(ssdp.EffectiveLineHeight);
this.LinkUnderlineThickness = ssdp.LinkUnderlineThickness ?? 0f;
this.Opacity = ssdp.EffectiveOpacity;
@@ -106,7 +106,7 @@ public unsafe ref struct SeStringDrawState
public Vector2 ScreenOffset { get; }
///
- public ImFont* Font { get; }
+ public ImFontPtr Font { get; }
///
public float FontSize { get; }
@@ -256,7 +256,7 @@ public unsafe ref struct SeStringDrawState
/// Offset of the glyph in pixels w.r.t. .
internal void DrawGlyph(scoped in ImGuiHelpers.ImFontGlyphReal g, Vector2 offset)
{
- var texId = this.Font->ContainerAtlas->Textures.Ref(g.TextureIndex).TexID;
+ var texId = this.Font.ContainerAtlas.Textures.Ref(g.TextureIndex).TexID;
var xy0 = new Vector2(
MathF.Round(g.X0 * this.FontSizeScale),
MathF.Round(g.Y0 * this.FontSizeScale));
@@ -313,7 +313,7 @@ public unsafe ref struct SeStringDrawState
offset += this.ScreenOffset;
offset.Y += (this.LinkUnderlineThickness - 1) / 2f;
- offset.Y += MathF.Round(((this.LineHeight - this.FontSize) / 2) + (this.Font->Ascent * this.FontSizeScale));
+ offset.Y += MathF.Round(((this.LineHeight - this.FontSize) / 2) + (this.Font.Ascent * this.FontSizeScale));
this.SetCurrentChannel(SeStringDrawChannel.Foreground);
this.DrawList.AddLine(
@@ -340,9 +340,9 @@ public unsafe ref struct SeStringDrawState
internal readonly ref ImGuiHelpers.ImFontGlyphReal FindGlyph(Rune rune)
{
var p = rune.Value is >= ushort.MinValue and < ushort.MaxValue
- ? this.Font->FindGlyph((ushort)rune.Value)
- : this.Font->FallbackGlyph;
- return ref *(ImGuiHelpers.ImFontGlyphReal*)p;
+ ? (ImFontGlyphPtr)this.Font.FindGlyph((ushort)rune.Value)
+ : this.Font.FallbackGlyph;
+ return ref *(ImGuiHelpers.ImFontGlyphReal*)p.Handle;
}
/// Gets the glyph corresponding to the given codepoint.
@@ -375,7 +375,7 @@ public unsafe ref struct SeStringDrawState
return 0;
return MathF.Round(
- this.Font->GetDistanceAdjustmentForPair(
+ this.Font.GetDistanceAdjustmentForPair(
(ushort)left.Value,
(ushort)right.Value) * this.FontSizeScale);
}
From e032840ac8e7ac13cd0493a30cac4398bcd86d94 Mon Sep 17 00:00:00 2001
From: goaaats
Date: Sat, 6 Dec 2025 18:32:03 +0100
Subject: [PATCH 33/50] Clean up crash handler window log for external events
---
Dalamud.Boot/crashhandler_shared.h | 2 ++
Dalamud.Boot/veh.cpp | 2 --
DalamudCrashHandler/DalamudCrashHandler.cpp | 26 ++++++++++++++++++---
3 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/Dalamud.Boot/crashhandler_shared.h b/Dalamud.Boot/crashhandler_shared.h
index 8d93e4460..0308306ce 100644
--- a/Dalamud.Boot/crashhandler_shared.h
+++ b/Dalamud.Boot/crashhandler_shared.h
@@ -6,6 +6,8 @@
#define WIN32_LEAN_AND_MEAN
#include
+#define CUSTOM_EXCEPTION_EXTERNAL_EVENT 0x12345679
+
struct exception_info
{
LPEXCEPTION_POINTERS pExceptionPointers;
diff --git a/Dalamud.Boot/veh.cpp b/Dalamud.Boot/veh.cpp
index 25c9b5045..50ac9b34c 100644
--- a/Dalamud.Boot/veh.cpp
+++ b/Dalamud.Boot/veh.cpp
@@ -11,8 +11,6 @@
#include "crashhandler_shared.h"
#include "DalamudStartInfo.h"
-#define CUSTOM_EXCEPTION_EXTERNAL_EVENT 0x12345679
-
#pragma comment(lib, "comctl32.lib")
#if defined _M_IX86
diff --git a/DalamudCrashHandler/DalamudCrashHandler.cpp b/DalamudCrashHandler/DalamudCrashHandler.cpp
index 107261541..1feec4b2f 100644
--- a/DalamudCrashHandler/DalamudCrashHandler.cpp
+++ b/DalamudCrashHandler/DalamudCrashHandler.cpp
@@ -938,9 +938,19 @@ int main() {
} while (false);
}
+ const bool is_external_event = exinfo.ExceptionRecord.ExceptionCode == CUSTOM_EXCEPTION_EXTERNAL_EVENT;
+
std::wostringstream log;
- log << std::format(L"Unhandled native exception occurred at {}", to_address_string(exinfo.ContextRecord.Rip, false)) << std::endl;
- log << std::format(L"Code: {:X}", exinfo.ExceptionRecord.ExceptionCode) << std::endl;
+
+ if (!is_external_event)
+ {
+ log << std::format(L"Unhandled native exception occurred at {}", to_address_string(exinfo.ContextRecord.Rip, false)) << std::endl;
+ log << std::format(L"Code: {:X}", exinfo.ExceptionRecord.ExceptionCode) << std::endl;
+ }
+ else
+ {
+ log << L"CLR error occurred" << std::endl;
+ }
if (shutup)
log << L"======= Crash handler was globally muted(shutdown?) =======" << std::endl;
@@ -957,9 +967,19 @@ int main() {
if (pProgressDialog)
pProgressDialog->SetLine(3, L"Refreshing Module List", FALSE, NULL);
+ std::wstring window_log_str;
+
+ // Cut the log here for external events, the rest is unreadable and doesn't matter since we can't get
+ // symbols for mixed-mode stacks yet.
+ if (is_external_event)
+ window_log_str = log.str();
+
SymRefreshModuleList(GetCurrentProcess());
print_exception_info(exinfo.hThreadHandle, exinfo.ExceptionPointers, exinfo.ContextRecord, log);
- const auto window_log_str = log.str();
+
+ if (!is_external_event)
+ window_log_str = log.str();
+
print_exception_info_extended(exinfo.ExceptionPointers, exinfo.ContextRecord, log);
std::wofstream(logPath) << log.str();
From b2d9480f9f83cb64e476d77f25068817beee6790 Mon Sep 17 00:00:00 2001
From: goaaats
Date: Sat, 6 Dec 2025 18:38:13 +0100
Subject: [PATCH 34/50] Submit nuke schema
---
.nuke/build.schema.json | 162 ++++++++++++++++++++--------------------
1 file changed, 81 insertions(+), 81 deletions(-)
diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json
index 03211ce8f..6ffb3bb01 100644
--- a/.nuke/build.schema.json
+++ b/.nuke/build.schema.json
@@ -1,19 +1,57 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
- "title": "Build Schema",
- "$ref": "#/definitions/build",
"definitions": {
- "build": {
- "type": "object",
+ "Host": {
+ "type": "string",
+ "enum": [
+ "AppVeyor",
+ "AzurePipelines",
+ "Bamboo",
+ "Bitbucket",
+ "Bitrise",
+ "GitHubActions",
+ "GitLab",
+ "Jenkins",
+ "Rider",
+ "SpaceAutomation",
+ "TeamCity",
+ "Terminal",
+ "TravisCI",
+ "VisualStudio",
+ "VSCode"
+ ]
+ },
+ "ExecutableTarget": {
+ "type": "string",
+ "enum": [
+ "CI",
+ "Clean",
+ "Compile",
+ "CompileCImGui",
+ "CompileCImGuizmo",
+ "CompileCImPlot",
+ "CompileDalamud",
+ "CompileDalamudBoot",
+ "CompileDalamudCrashHandler",
+ "CompileImGuiNatives",
+ "CompileInjector",
+ "Restore",
+ "SetCILogging",
+ "Test"
+ ]
+ },
+ "Verbosity": {
+ "type": "string",
+ "description": "",
+ "enum": [
+ "Verbose",
+ "Normal",
+ "Minimal",
+ "Quiet"
+ ]
+ },
+ "NukeBuild": {
"properties": {
- "Configuration": {
- "type": "string",
- "description": "Configuration to build - Default is 'Debug' (local) or 'Release' (server)",
- "enum": [
- "Debug",
- "Release"
- ]
- },
"Continue": {
"type": "boolean",
"description": "Indicates to continue a previously failed build attempt"
@@ -23,29 +61,8 @@
"description": "Shows the help text for this build assembly"
},
"Host": {
- "type": "string",
"description": "Host for execution. Default is 'automatic'",
- "enum": [
- "AppVeyor",
- "AzurePipelines",
- "Bamboo",
- "Bitbucket",
- "Bitrise",
- "GitHubActions",
- "GitLab",
- "Jenkins",
- "Rider",
- "SpaceAutomation",
- "TeamCity",
- "Terminal",
- "TravisCI",
- "VisualStudio",
- "VSCode"
- ]
- },
- "IsDocsBuild": {
- "type": "boolean",
- "description": "Whether we are building for documentation - emits generated files"
+ "$ref": "#/definitions/Host"
},
"NoLogo": {
"type": "boolean",
@@ -74,63 +91,46 @@
"type": "array",
"description": "List of targets to be skipped. Empty list skips all dependencies",
"items": {
- "type": "string",
- "enum": [
- "CI",
- "Clean",
- "Compile",
- "CompileCImGui",
- "CompileCImGuizmo",
- "CompileCImPlot",
- "CompileDalamud",
- "CompileDalamudBoot",
- "CompileDalamudCrashHandler",
- "CompileImGuiNatives",
- "CompileInjector",
- "Restore",
- "SetCILogging",
- "Test"
- ]
+ "$ref": "#/definitions/ExecutableTarget"
}
},
- "Solution": {
- "type": "string",
- "description": "Path to a solution file that is automatically loaded"
- },
"Target": {
"type": "array",
"description": "List of targets to be invoked. Default is '{default_target}'",
"items": {
- "type": "string",
- "enum": [
- "CI",
- "Clean",
- "Compile",
- "CompileCImGui",
- "CompileCImGuizmo",
- "CompileCImPlot",
- "CompileDalamud",
- "CompileDalamudBoot",
- "CompileDalamudCrashHandler",
- "CompileImGuiNatives",
- "CompileInjector",
- "Restore",
- "SetCILogging",
- "Test"
- ]
+ "$ref": "#/definitions/ExecutableTarget"
}
},
"Verbosity": {
- "type": "string",
"description": "Logging verbosity during build execution. Default is 'Normal'",
- "enum": [
- "Minimal",
- "Normal",
- "Quiet",
- "Verbose"
- ]
+ "$ref": "#/definitions/Verbosity"
}
}
}
- }
-}
\ No newline at end of file
+ },
+ "allOf": [
+ {
+ "properties": {
+ "Configuration": {
+ "type": "string",
+ "description": "Configuration to build - Default is 'Debug' (local) or 'Release' (server)",
+ "enum": [
+ "Debug",
+ "Release"
+ ]
+ },
+ "IsDocsBuild": {
+ "type": "boolean",
+ "description": "Whether we are building for documentation - emits generated files"
+ },
+ "Solution": {
+ "type": "string",
+ "description": "Path to a solution file that is automatically loaded"
+ }
+ }
+ },
+ {
+ "$ref": "#/definitions/NukeBuild"
+ }
+ ]
+}
From 3d29157391da8bc50a60c2aed640510647f257ba Mon Sep 17 00:00:00 2001
From: goaaats
Date: Sat, 6 Dec 2025 18:38:23 +0100
Subject: [PATCH 35/50] Revert "Add git status checks to workflow to see what's
dirty"
This reverts commit a36e11574b14ea6887cb0f7d2513920ebdd820bf.
---
.github/workflows/main.yml | 4 ----
1 file changed, 4 deletions(-)
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index f552e446b..299d71e95 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -33,12 +33,8 @@ jobs:
($env:REPO_NAME) >> VERSION
($env:BRANCH) >> VERSION
($env:COMMIT) >> VERSION
- - name: git status
- run: git status
- name: Build and Test Dalamud
run: .\build.ps1 ci
- - name: git status
- run: git status
- name: Sign Dalamud
if: ${{ github.repository_owner == 'goatcorp' && github.event_name == 'push' }}
env:
From ab5ea34e686e7ead9673f0fb8492ca0a00aa5a09 Mon Sep 17 00:00:00 2001
From: goat <16760685+goaaats@users.noreply.github.com>
Date: Sat, 6 Dec 2025 18:46:06 +0100
Subject: [PATCH 36/50] ci: make deploying builds globally blocking, don't
cancel in-progress
---
.github/workflows/main.yml | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index be44afacc..ea1afcac5 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -1,9 +1,10 @@
name: Build Dalamud
on: [push, pull_request, workflow_dispatch]
+# Globally blocking because of git pushes in deploy step
concurrency:
- group: build_dalamud_${{ github.ref_name }}
- cancel-in-progress: true
+ group: build_dalamud_${{ github.repository_owner }}
+ cancel-in-progress: false
jobs:
build:
From caa869d3ace57609680782b5862bb1d0820e86b5 Mon Sep 17 00:00:00 2001
From: goaaats
Date: Sun, 7 Dec 2025 12:54:13 +0100
Subject: [PATCH 37/50] Clarify exception and docs regarding off-thread drawing
with SeStrings, again
---
.../Interface/ImGuiSeStringRenderer/SeStringDrawParams.cs | 5 ++++-
Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs | 2 +-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawParams.cs b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawParams.cs
index 1d8126f3b..972013328 100644
--- a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawParams.cs
+++ b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawParams.cs
@@ -14,8 +14,9 @@ public record struct SeStringDrawParams
/// (the default).
///
/// If this value is set, will not be called, and ImGui ID will be ignored.
- /// You must specify a valid draw list and a valid font via if you set this value,
+ /// You must specify a valid draw list, a valid font via and if you set this value,
/// since the renderer will not be able to retrieve them from ImGui context.
+ /// Must be set when drawing off the main thread.
///
public ImDrawListPtr? TargetDrawList { get; set; }
@@ -29,11 +30,13 @@ public record struct SeStringDrawParams
/// Gets or sets the font to use.
/// Font to use, or null to use (the default).
+ /// Must be set when specifying a target draw-list or drawing off the main thread.
public ImFontPtr? Font { get; set; }
/// Gets or sets the font size.
/// Font size in pixels, or 0 to use the current ImGui font size .
///
+ /// Must be set when specifying a target draw-list or drawing off the main thread.
public float? FontSize { get; set; }
/// Gets or sets the line height ratio.
diff --git a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs
index 11c1120b4..04d0501b1 100644
--- a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs
+++ b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs
@@ -65,7 +65,7 @@ public unsafe ref struct SeStringDrawState
this.drawList = ssdp.TargetDrawList.Value;
this.ScreenOffset = Vector2.Zero;
this.FontSize = ssdp.FontSize ?? throw new ArgumentException(
- $"{nameof(ssdp.FontSize)} must be set to render outside the main thread.");
+ $"{nameof(ssdp.FontSize)} must be set when specifying a target draw list, as it cannot be fetched from the ImGui state.");
this.WrapWidth = ssdp.WrapWidth ?? float.MaxValue;
this.Color = ssdp.Color ?? uint.MaxValue;
this.LinkHoverBackColor = 0; // Interactivity is unused outside the main thread.
From b35faf13b53ce25e0f3f92977a75c4cb154a050b Mon Sep 17 00:00:00 2001
From: goaaats
Date: Sun, 7 Dec 2025 13:04:11 +0100
Subject: [PATCH 38/50] Show unhandled exceptions through VEH
---
Dalamud.Boot/veh.cpp | 6 +++++
Dalamud/EntryPoint.cs | 25 +++----------------
.../Interface/Internal/DalamudInterface.cs | 7 ++++++
Dalamud/Utility/ErrorHandling.cs | 21 ++++++++++++++++
DalamudCrashHandler/DalamudCrashHandler.cpp | 4 +--
5 files changed, 40 insertions(+), 23 deletions(-)
create mode 100644 Dalamud/Utility/ErrorHandling.cs
diff --git a/Dalamud.Boot/veh.cpp b/Dalamud.Boot/veh.cpp
index 50ac9b34c..194840e52 100644
--- a/Dalamud.Boot/veh.cpp
+++ b/Dalamud.Boot/veh.cpp
@@ -453,3 +453,9 @@ void veh::raise_external_event(const std::wstring& info)
wcsncpy_s(g_external_event_info, info.c_str(), info_size);
RaiseException(CUSTOM_EXCEPTION_EXTERNAL_EVENT, 0, 0, nullptr);
}
+
+extern "C" __declspec(dllexport) void BootVehRaiseExternalEventW(LPCWSTR info)
+{
+ const std::wstring info_wstr(info);
+ veh::raise_external_event(info_wstr);
+}
diff --git a/Dalamud/EntryPoint.cs b/Dalamud/EntryPoint.cs
index 15077f3d8..0f8cb0480 100644
--- a/Dalamud/EntryPoint.cs
+++ b/Dalamud/EntryPoint.cs
@@ -292,7 +292,6 @@ public sealed class EntryPoint
}
var pluginInfo = string.Empty;
- var supportText = ", please visit us on Discord for more help";
try
{
var pm = Service.GetNullable();
@@ -300,9 +299,6 @@ public sealed class EntryPoint
if (plugin != null)
{
pluginInfo = $"Plugin that caused this:\n{plugin.Name}\n\nClick \"Yes\" and remove it.\n\n";
-
- if (plugin.IsThirdParty)
- supportText = string.Empty;
}
}
catch
@@ -310,31 +306,18 @@ public sealed class EntryPoint
// ignored
}
- const MESSAGEBOX_STYLE flags = MESSAGEBOX_STYLE.MB_YESNO | MESSAGEBOX_STYLE.MB_ICONERROR | MESSAGEBOX_STYLE.MB_SYSTEMMODAL;
- var result = Windows.Win32.PInvoke.MessageBox(
- new HWND(Process.GetCurrentProcess().MainWindowHandle),
- $"An internal error in a Dalamud plugin occurred.\nThe game must close.\n\n{ex.GetType().Name}\n{info}\n\n{pluginInfo}More information has been recorded separately{supportText}.\n\nDo you want to disable all plugins the next time you start the game?",
- "Dalamud",
- flags);
-
- if (result == MESSAGEBOX_RESULT.IDYES)
- {
- Log.Information("User chose to disable plugins on next launch...");
- var config = Service.Get();
- config.PluginSafeMode = true;
- config.ForceSave();
- }
-
Log.CloseAndFlush();
- Environment.Exit(-1);
+
+ ErrorHandling.CrashWithContext($"{ex}\n\n{info}\n\n{pluginInfo}");
break;
default:
Log.Fatal("Unhandled SEH object on AppDomain: {Object}", args.ExceptionObject);
Log.CloseAndFlush();
- Environment.Exit(-1);
break;
}
+
+ Environment.Exit(-1);
}
private static void OnUnhandledExceptionStallDebug(object sender, UnhandledExceptionEventArgs args)
diff --git a/Dalamud/Interface/Internal/DalamudInterface.cs b/Dalamud/Interface/Internal/DalamudInterface.cs
index af78c5b0c..bf55a5486 100644
--- a/Dalamud/Interface/Internal/DalamudInterface.cs
+++ b/Dalamud/Interface/Internal/DalamudInterface.cs
@@ -667,6 +667,8 @@ internal class DalamudInterface : IInternalDisposableService
{
if (this.isImGuiDrawDevMenu)
{
+ using var barColor = ImRaii.PushColor(ImGuiCol.WindowBg, new Vector4(0.060f, 0.060f, 0.060f, 0.773f));
+ barColor.Push(ImGuiCol.MenuBarBg, Vector4.Zero);
if (ImGui.BeginMainMenuBar())
{
var pluginManager = Service.Get();
@@ -839,6 +841,11 @@ internal class DalamudInterface : IInternalDisposableService
ImGui.PopStyleVar();
}
+ if (ImGui.MenuItem("Raise external event through boot"))
+ {
+ ErrorHandling.CrashWithContext("Tést");
+ }
+
ImGui.EndMenu();
}
diff --git a/Dalamud/Utility/ErrorHandling.cs b/Dalamud/Utility/ErrorHandling.cs
new file mode 100644
index 000000000..3c025a12e
--- /dev/null
+++ b/Dalamud/Utility/ErrorHandling.cs
@@ -0,0 +1,21 @@
+using System.Runtime.InteropServices;
+
+namespace Dalamud.Utility;
+
+///
+/// Utilities for handling errors inside Dalamud.
+///
+internal static partial class ErrorHandling
+{
+ ///
+ /// Crash the game at this point, and show the crash handler with the supplied context.
+ ///
+ /// The context to show in the crash handler.
+ public static void CrashWithContext(string context)
+ {
+ BootVehRaiseExternalEvent(context);
+ }
+
+ [LibraryImport("Dalamud.Boot.dll", EntryPoint = "BootVehRaiseExternalEventW", StringMarshalling = StringMarshalling.Utf16)]
+ private static partial void BootVehRaiseExternalEvent(string info);
+}
diff --git a/DalamudCrashHandler/DalamudCrashHandler.cpp b/DalamudCrashHandler/DalamudCrashHandler.cpp
index 1feec4b2f..3955bd983 100644
--- a/DalamudCrashHandler/DalamudCrashHandler.cpp
+++ b/DalamudCrashHandler/DalamudCrashHandler.cpp
@@ -1014,8 +1014,8 @@ int main() {
config.pButtons = buttons;
config.cButtons = ARRAYSIZE(buttons);
config.nDefaultButton = IdButtonRestart;
- config.pszExpandedControlText = L"Hide stack trace";
- config.pszCollapsedControlText = L"Stack trace for plugin developers";
+ config.pszExpandedControlText = L"Hide further information";
+ config.pszCollapsedControlText = L"Further information for developers";
config.pszExpandedInformation = window_log_str.c_str();
config.pszWindowTitle = L"Dalamud Crash Handler";
config.pRadioButtons = radios;
From 9e5723359a2ab36915488edb5612776e7da93c00 Mon Sep 17 00:00:00 2001
From: Haselnussbomber
Date: Sun, 7 Dec 2025 15:35:38 +0100
Subject: [PATCH 39/50] Remove obsolete casts from Lumina.Text.SeString
---
Dalamud/Game/Text/Evaluator/SeStringParameter.cs | 4 ----
Dalamud/Game/Text/SeStringHandling/SeString.cs | 8 --------
2 files changed, 12 deletions(-)
diff --git a/Dalamud/Game/Text/Evaluator/SeStringParameter.cs b/Dalamud/Game/Text/Evaluator/SeStringParameter.cs
index 1c6dd96cb..036d1c921 100644
--- a/Dalamud/Game/Text/Evaluator/SeStringParameter.cs
+++ b/Dalamud/Game/Text/Evaluator/SeStringParameter.cs
@@ -3,7 +3,6 @@ using System.Globalization;
using Lumina.Text.ReadOnly;
using DSeString = Dalamud.Game.Text.SeStringHandling.SeString;
-using LSeString = Lumina.Text.SeString;
namespace Dalamud.Game.Text.Evaluator;
@@ -71,9 +70,6 @@ public readonly struct SeStringParameter
public static implicit operator SeStringParameter(ReadOnlySeStringSpan value) => new(new ReadOnlySeString(value));
- [Obsolete("Switch to using ReadOnlySeString instead of Lumina's SeString.", true)]
- public static implicit operator SeStringParameter(LSeString value) => new(new ReadOnlySeString(value.RawData));
-
public static implicit operator SeStringParameter(DSeString value) => new(new ReadOnlySeString(value.Encode()));
public static implicit operator SeStringParameter(string value) => new(value);
diff --git a/Dalamud/Game/Text/SeStringHandling/SeString.cs b/Dalamud/Game/Text/SeStringHandling/SeString.cs
index 8805c2177..a1ef5e936 100644
--- a/Dalamud/Game/Text/SeStringHandling/SeString.cs
+++ b/Dalamud/Game/Text/SeStringHandling/SeString.cs
@@ -113,14 +113,6 @@ public class SeString
/// Equivalent SeString.
public static implicit operator SeString(string str) => new(new TextPayload(str));
- ///
- /// Implicitly convert a string into a SeString containing a .
- ///
- /// string to convert.
- /// Equivalent SeString.
- [Obsolete("Switch to using ReadOnlySeString instead of Lumina's SeString.", true)]
- public static explicit operator SeString(Lumina.Text.SeString str) => str.ToDalamudString();
-
///
/// Parse a binary game message into an SeString.
///
From d4fe523d73925944d5151d7d6ee7428034ef4cf0 Mon Sep 17 00:00:00 2001
From: Haselnussbomber
Date: Sun, 7 Dec 2025 15:38:10 +0100
Subject: [PATCH 40/50] Clean up some warnings
---
Dalamud/Interface/Windowing/Window.cs | 2 +-
Dalamud/Utility/Util.cs | 20 ++++++++++----------
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/Dalamud/Interface/Windowing/Window.cs b/Dalamud/Interface/Windowing/Window.cs
index b0786fbb5..48352daa2 100644
--- a/Dalamud/Interface/Windowing/Window.cs
+++ b/Dalamud/Interface/Windowing/Window.cs
@@ -908,7 +908,7 @@ public abstract class Window
private void DrawErrorMessage()
{
// TODO: Once window systems are services, offer to reload the plugin
- ImGui.TextColoredWrapped(ImGuiColors.DalamudRed,Loc.Localize("WindowSystemErrorOccurred", "An error occurred while rendering this window. Please contact the developer for details."));
+ ImGui.TextColoredWrapped(ImGuiColors.DalamudRed, Loc.Localize("WindowSystemErrorOccurred", "An error occurred while rendering this window. Please contact the developer for details."));
ImGuiHelpers.ScaledDummy(5);
diff --git a/Dalamud/Utility/Util.cs b/Dalamud/Utility/Util.cs
index f50efcf0d..bde113904 100644
--- a/Dalamud/Utility/Util.cs
+++ b/Dalamud/Utility/Util.cs
@@ -158,16 +158,6 @@ public static partial class Util
return branchInternal = gitBranch;
}
- ///
- /// Gets the active Dalamud track, if this instance was launched through XIVLauncher and used a version
- /// downloaded from webservices.
- ///
- /// The name of the track, or null.
- internal static string? GetActiveTrack()
- {
- return Environment.GetEnvironmentVariable("DALAMUD_BRANCH");
- }
-
///
public static unsafe string DescribeAddress(void* p) => DescribeAddress((nint)p);
@@ -703,6 +693,16 @@ public static partial class Util
}
}
+ ///
+ /// Gets the active Dalamud track, if this instance was launched through XIVLauncher and used a version
+ /// downloaded from webservices.
+ ///
+ /// The name of the track, or null.
+ internal static string? GetActiveTrack()
+ {
+ return Environment.GetEnvironmentVariable("DALAMUD_BRANCH");
+ }
+
///
/// Gets a random, inoffensive, human-friendly string.
///
From c50237cf6604f32de59c070667abab6813534b84 Mon Sep 17 00:00:00 2001
From: goaaats
Date: Sun, 7 Dec 2025 15:46:01 +0100
Subject: [PATCH 41/50] Add compatibility changes for SeString API breakage
---
.../Internal/SeStringRenderer.cs | 4 +++-
.../ImGuiSeStringRenderer/SeStringDrawState.cs | 16 ++++++++++++++--
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringRenderer.cs b/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringRenderer.cs
index 87df2da2c..397502b30 100644
--- a/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringRenderer.cs
+++ b/Dalamud/Interface/ImGuiSeStringRenderer/Internal/SeStringRenderer.cs
@@ -161,7 +161,9 @@ internal class SeStringRenderer : IServiceType
ImFont* font = null;
if (drawParams.Font.HasValue)
font = drawParams.Font.Value;
- if (ThreadSafety.IsMainThread && drawParams.TargetDrawList is null && font is null)
+
+ // API14: Remove commented out code
+ if (ThreadSafety.IsMainThread /* && drawParams.TargetDrawList is null */ && font is null)
font = ImGui.GetFont();
if (font is null)
throw new ArgumentException("Specified font is empty.");
diff --git a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs
index 04d0501b1..5e63ef160 100644
--- a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs
+++ b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs
@@ -64,8 +64,20 @@ public unsafe ref struct SeStringDrawState
{
this.drawList = ssdp.TargetDrawList.Value;
this.ScreenOffset = Vector2.Zero;
- this.FontSize = ssdp.FontSize ?? throw new ArgumentException(
- $"{nameof(ssdp.FontSize)} must be set when specifying a target draw list, as it cannot be fetched from the ImGui state.");
+
+ // API14: Remove, always throw
+ if (ThreadSafety.IsMainThread)
+ {
+ this.FontSize = ssdp.FontSize ?? ImGui.GetFontSize();
+ }
+ else
+ {
+ throw new ArgumentException(
+ $"{nameof(ssdp.FontSize)} must be set when specifying a target draw list, as it cannot be fetched from the ImGui state.");
+ }
+
+ // this.FontSize = ssdp.FontSize ?? throw new ArgumentException(
+ // $"{nameof(ssdp.FontSize)} must be set when specifying a target draw list, as it cannot be fetched from the ImGui state.");
this.WrapWidth = ssdp.WrapWidth ?? float.MaxValue;
this.Color = ssdp.Color ?? uint.MaxValue;
this.LinkHoverBackColor = 0; // Interactivity is unused outside the main thread.
From 094483e5a08315b218f1e20277db44df360cbc2f Mon Sep 17 00:00:00 2001
From: goaaats
Date: Sun, 7 Dec 2025 15:52:13 +0100
Subject: [PATCH 42/50] List PRs in changelog generator
---
.github/generate_changelog.py | 209 +++++++++++++++++------
.github/workflows/generate-changelog.yml | 24 +--
2 files changed, 166 insertions(+), 67 deletions(-)
diff --git a/.github/generate_changelog.py b/.github/generate_changelog.py
index 5e921fd6e..b07100115 100644
--- a/.github/generate_changelog.py
+++ b/.github/generate_changelog.py
@@ -8,7 +8,8 @@ import re
import sys
import json
import argparse
-from typing import List, Tuple, Optional
+import os
+from typing import List, Tuple, Optional, Dict, Any
def run_git_command(args: List[str]) -> str:
@@ -30,14 +31,14 @@ def get_last_two_tags() -> Tuple[str, str]:
"""Get the latest two git tags."""
tags = run_git_command(["tag", "--sort=-version:refname"])
tag_list = [t for t in tags.split("\n") if t]
-
+
# Filter out old tags that start with 'v' (old versioning scheme)
tag_list = [t for t in tag_list if not t.startswith('v')]
if len(tag_list) < 2:
print("Error: Need at least 2 tags in the repository", file=sys.stderr)
sys.exit(1)
-
+
return tag_list[0], tag_list[1]
@@ -55,58 +56,144 @@ def get_submodule_commit(submodule_path: str, tag: str) -> Optional[str]:
return None
-def get_commits_between_tags(tag1: str, tag2: str) -> List[Tuple[str, str]]:
- """Get commits between two tags. Returns list of (message, author) tuples."""
+def get_repo_info() -> Tuple[str, str]:
+ """Get repository owner and name from git remote."""
+ try:
+ remote_url = run_git_command(["config", "--get", "remote.origin.url"])
+
+ # Handle both HTTPS and SSH URLs
+ # SSH: git@github.com:owner/repo.git
+ # HTTPS: https://github.com/owner/repo.git
+ match = re.search(r'github\.com[:/](.+?)/(.+?)(?:\.git)?$', remote_url)
+ if match:
+ owner = match.group(1)
+ repo = match.group(2)
+ return owner, repo
+ else:
+ print("Error: Could not parse GitHub repository from remote URL", file=sys.stderr)
+ sys.exit(1)
+ except:
+ print("Error: Could not get git remote URL", file=sys.stderr)
+ sys.exit(1)
+
+
+def get_commits_between_tags(tag1: str, tag2: str) -> List[str]:
+ """Get commit SHAs between two tags."""
log_output = run_git_command([
"log",
f"{tag2}..{tag1}",
- "--format=%s|%an|%h"
+ "--format=%H"
])
-
- commits = []
- for line in log_output.split("\n"):
- if "|" in line:
- message, author, sha = line.split("|", 2)
- commits.append((message.strip(), author.strip(), sha.strip()))
-
+
+ commits = [sha.strip() for sha in log_output.split("\n") if sha.strip()]
return commits
-def filter_commits(commits: List[Tuple[str, str]], ignore_patterns: List[str]) -> List[Tuple[str, str]]:
- """Filter out commits matching any of the ignore patterns."""
+def get_pr_for_commit(commit_sha: str, owner: str, repo: str, token: str) -> Optional[Dict[str, Any]]:
+ """Get PR information for a commit using GitHub API."""
+ try:
+ import requests
+ except ImportError:
+ print("Error: requests library is required. Install it with: pip install requests", file=sys.stderr)
+ sys.exit(1)
+
+ headers = {
+ "Accept": "application/vnd.github+json",
+ "X-GitHub-Api-Version": "2022-11-28"
+ }
+
+ if token:
+ headers["Authorization"] = f"Bearer {token}"
+
+ url = f"https://api.github.com/repos/{owner}/{repo}/commits/{commit_sha}/pulls"
+
+ try:
+ response = requests.get(url, headers=headers)
+ response.raise_for_status()
+ prs = response.json()
+
+ if prs and len(prs) > 0:
+ # Return the first PR (most relevant one)
+ pr = prs[0]
+ return {
+ "number": pr["number"],
+ "title": pr["title"],
+ "author": pr["user"]["login"],
+ "url": pr["html_url"]
+ }
+ except requests.exceptions.HTTPError as e:
+ if e.response.status_code == 404:
+ # Commit might not be associated with a PR
+ return None
+ elif e.response.status_code == 403:
+ print("Warning: GitHub API rate limit exceeded. Consider providing a token.", file=sys.stderr)
+ return None
+ else:
+ print(f"Warning: Failed to fetch PR for commit {commit_sha[:7]}: {e}", file=sys.stderr)
+ return None
+ except Exception as e:
+ print(f"Warning: Error fetching PR for commit {commit_sha[:7]}: {e}", file=sys.stderr)
+ return None
+
+ return None
+
+
+def get_prs_between_tags(tag1: str, tag2: str, owner: str, repo: str, token: str) -> List[Dict[str, Any]]:
+ """Get PRs between two tags using GitHub API."""
+ commits = get_commits_between_tags(tag1, tag2)
+ print(f"Found {len(commits)} commits, fetching PR information...")
+
+ prs = []
+ seen_pr_numbers = set()
+
+ for i, commit_sha in enumerate(commits, 1):
+ if i % 10 == 0:
+ print(f"Progress: {i}/{len(commits)} commits processed...")
+
+ pr_info = get_pr_for_commit(commit_sha, owner, repo, token)
+ if pr_info and pr_info["number"] not in seen_pr_numbers:
+ seen_pr_numbers.add(pr_info["number"])
+ prs.append(pr_info)
+
+ return prs
+
+
+def filter_prs(prs: List[Dict[str, Any]], ignore_patterns: List[str]) -> List[Dict[str, Any]]:
+ """Filter out PRs matching any of the ignore patterns."""
compiled_patterns = [re.compile(pattern) for pattern in ignore_patterns]
-
+
filtered = []
- for message, author, sha in commits:
- if not any(pattern.search(message) for pattern in compiled_patterns):
- filtered.append((message, author, sha))
-
+ for pr in prs:
+ if not any(pattern.search(pr["title"]) for pattern in compiled_patterns):
+ filtered.append(pr)
+
return filtered
-def generate_changelog(version: str, prev_version: str, commits: List[Tuple[str, str]],
- cs_commit_new: Optional[str], cs_commit_old: Optional[str]) -> str:
+def generate_changelog(version: str, prev_version: str, prs: List[Dict[str, Any]],
+ cs_commit_new: Optional[str], cs_commit_old: Optional[str],
+ owner: str, repo: str) -> str:
"""Generate markdown changelog."""
# Calculate statistics
- commit_count = len(commits)
- unique_authors = len(set(author for _, author, _ in commits))
-
+ pr_count = len(prs)
+ unique_authors = len(set(pr["author"] for pr in prs))
+
changelog = f"# Dalamud Release v{version}\n\n"
changelog += f"We just released Dalamud v{version}, which should be available to users within a few minutes. "
- changelog += f"This release includes **{commit_count} commit{'s' if commit_count != 1 else ''} from {unique_authors} contributor{'s' if unique_authors != 1 else ''}**.\n"
- changelog += f"[Click here]() to see all Dalamud changes.\n\n"
-
+ changelog += f"This release includes **{pr_count} PR{'s' if pr_count != 1 else ''} from {unique_authors} contributor{'s' if unique_authors != 1 else ''}**.\n"
+ changelog += f"[Click here]() to see all Dalamud changes.\n\n"
+
if cs_commit_new and cs_commit_old and cs_commit_new != cs_commit_old:
changelog += f"It ships with an updated **FFXIVClientStructs [`{cs_commit_new[:7]}`]()**.\n"
changelog += f"[Click here]() to see all CS changes.\n"
elif cs_commit_new:
changelog += f"It ships with **FFXIVClientStructs [`{cs_commit_new[:7]}`]()**.\n"
-
+
changelog += "## Dalamud Changes\n\n"
-
- for message, author, sha in commits:
- changelog += f"* {message} (by **{author}** as [`{sha}`]())\n"
-
+
+ for pr in prs:
+ changelog += f"* {pr['title']} ([#**{pr['number']}**](<{pr['url']}>) by **{pr['author']}**)\n"
+
return changelog
@@ -117,9 +204,9 @@ def post_to_discord(webhook_url: str, content: str, version: str) -> None:
except ImportError:
print("Error: requests library is required. Install it with: pip install requests", file=sys.stderr)
sys.exit(1)
-
+
filename = f"changelog-v{version}.md"
-
+
# Prepare the payload
data = {
"content": f"Dalamud v{version} has been released!",
@@ -130,13 +217,13 @@ def post_to_discord(webhook_url: str, content: str, version: str) -> None:
}
]
}
-
+
# Prepare the files
files = {
"payload_json": (None, json.dumps(data)),
"files[0]": (filename, content.encode('utf-8'), 'text/markdown')
}
-
+
try:
result = requests.post(webhook_url, files=files)
result.raise_for_status()
@@ -158,54 +245,64 @@ def main():
required=True,
help="Discord webhook URL"
)
+ parser.add_argument(
+ "--github-token",
+ default=os.environ.get("GITHUB_TOKEN"),
+ help="GitHub API token (or set GITHUB_TOKEN env var). Increases rate limit."
+ )
parser.add_argument(
"--ignore",
action="append",
default=[],
- help="Regex patterns to ignore commits (can be specified multiple times)"
+ help="Regex patterns to ignore PRs (can be specified multiple times)"
)
parser.add_argument(
"--submodule-path",
default="lib/FFXIVClientStructs",
help="Path to the FFXIVClientStructs submodule (default: lib/FFXIVClientStructs)"
)
-
+
args = parser.parse_args()
-
+
+ # Get repository info
+ owner, repo = get_repo_info()
+ print(f"Repository: {owner}/{repo}")
+
# Get the last two tags
latest_tag, previous_tag = get_last_two_tags()
print(f"Generating changelog between {previous_tag} and {latest_tag}")
-
+
# Get submodule commits at both tags
cs_commit_new = get_submodule_commit(args.submodule_path, latest_tag)
cs_commit_old = get_submodule_commit(args.submodule_path, previous_tag)
-
+
if cs_commit_new:
print(f"FFXIVClientStructs commit (new): {cs_commit_new[:7]}")
if cs_commit_old:
print(f"FFXIVClientStructs commit (old): {cs_commit_old[:7]}")
-
- # Get commits between tags
- commits = get_commits_between_tags(latest_tag, previous_tag)
- print(f"Found {len(commits)} commits")
-
- # Filter commits
- filtered_commits = filter_commits(commits, args.ignore)
- print(f"After filtering: {len(filtered_commits)} commits")
-
+
+ # Get PRs between tags
+ prs = get_prs_between_tags(latest_tag, previous_tag, owner, repo, args.github_token)
+ prs.reverse()
+ print(f"Found {len(prs)} PRs")
+
+ # Filter PRs
+ filtered_prs = filter_prs(prs, args.ignore)
+ print(f"After filtering: {len(filtered_prs)} PRs")
+
# Generate changelog
- changelog = generate_changelog(latest_tag, previous_tag, filtered_commits,
- cs_commit_new, cs_commit_old)
-
+ changelog = generate_changelog(latest_tag, previous_tag, filtered_prs,
+ cs_commit_new, cs_commit_old, owner, repo)
+
print("\n" + "="*50)
print("Generated Changelog:")
print("="*50)
print(changelog)
print("="*50 + "\n")
-
+
# Post to Discord
post_to_discord(args.webhook_url, changelog, latest_tag)
if __name__ == "__main__":
- main()
\ No newline at end of file
+ main()
diff --git a/.github/workflows/generate-changelog.yml b/.github/workflows/generate-changelog.yml
index 5fed3b1eb..e62d5f37c 100644
--- a/.github/workflows/generate-changelog.yml
+++ b/.github/workflows/generate-changelog.yml
@@ -6,41 +6,43 @@ on:
tags:
- '*'
+permissions: read-all
+
jobs:
generate-changelog:
runs-on: ubuntu-latest
-
+
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history and tags
submodules: true # Fetch submodules
-
+
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.14'
-
+
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install requests
-
+
- name: Generate and post changelog
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GIT_TERMINAL_PROMPT: 0
run: |
python .github/generate_changelog.py \
--webhook-url "${{ secrets.DISCORD_CHANGELOG_WEBHOOK_URL }}" \
- --ignore "^Merge" \
- --ignore "^build:" \
- --ignore "^docs:"
- env:
- GIT_TERMINAL_PROMPT: 0
-
+ --ignore "Update ClientStructs" \
+ --ignore "^build:"
+
- name: Upload changelog as artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: changelog
path: changelog-*.md
- if-no-files-found: ignore
\ No newline at end of file
+ if-no-files-found: ignore
From 652ff59672efa8abf1a7cba81898431be4b61c81 Mon Sep 17 00:00:00 2001
From: goaaats
Date: Sun, 7 Dec 2025 15:52:26 +0100
Subject: [PATCH 43/50] build: 13.0.0.13
---
Dalamud/Dalamud.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj
index d1f730d5e..a50f12d79 100644
--- a/Dalamud/Dalamud.csproj
+++ b/Dalamud/Dalamud.csproj
@@ -6,7 +6,7 @@
XIV Launcher addon framework
- 13.0.0.12
+ 13.0.0.13
$(DalamudVersion)
$(DalamudVersion)
$(DalamudVersion)
From 8a5f1fd96d7192c76602b90bdbad1e95d8c03f26 Mon Sep 17 00:00:00 2001
From: Haselnussbomber
Date: Sun, 7 Dec 2025 15:55:43 +0100
Subject: [PATCH 44/50] Add PluginUISoundEffectsEnabled to UiBuilder
---
Dalamud/Interface/UiBuilder.cs | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/Dalamud/Interface/UiBuilder.cs b/Dalamud/Interface/UiBuilder.cs
index 9f60aba6a..ea0e21e97 100644
--- a/Dalamud/Interface/UiBuilder.cs
+++ b/Dalamud/Interface/UiBuilder.cs
@@ -219,6 +219,12 @@ public interface IUiBuilder
///
bool ShouldUseReducedMotion { get; }
+ ///
+ /// Gets a value indicating whether the user has enabled the "Enable sound effects for plugin windows" setting.
+ /// This setting is effected by the in-game "System Sounds" option and volume.
+ ///
+ bool PluginUISoundEffectsEnabled { get; }
+
///
/// Loads an ULD file that can load textures containing multiple icons in a single texture.
///
@@ -560,6 +566,9 @@ public sealed class UiBuilder : IDisposable, IUiBuilder
///
public bool ShouldUseReducedMotion => Service.Get().ReduceMotions ?? false;
+ ///
+ public bool PluginUISoundEffectsEnabled => Service.Get().EnablePluginUISoundEffects;
+
///
/// Gets or sets a value indicating whether statistics about UI draw time should be collected.
///
From 7199bfb0a90f886cd0c831c0eeed6303fbde4fcb Mon Sep 17 00:00:00 2001
From: Haselnussbomber
Date: Sun, 7 Dec 2025 16:20:55 +0100
Subject: [PATCH 45/50] Remove targets
---
targets/Dalamud.Plugin.Bootstrap.targets | 11 --------
targets/Dalamud.Plugin.targets | 35 ------------------------
2 files changed, 46 deletions(-)
delete mode 100644 targets/Dalamud.Plugin.Bootstrap.targets
delete mode 100644 targets/Dalamud.Plugin.targets
diff --git a/targets/Dalamud.Plugin.Bootstrap.targets b/targets/Dalamud.Plugin.Bootstrap.targets
deleted file mode 100644
index db4bf6cd7..000000000
--- a/targets/Dalamud.Plugin.Bootstrap.targets
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
- $(appdata)\XIVLauncher\addon\Hooks\dev\
- $(HOME)/.xlcore/dalamud/Hooks/dev/
- $(HOME)/Library/Application Support/XIV on Mac/dalamud/Hooks/dev/
- $(DALAMUD_HOME)/
-
-
-
-
diff --git a/targets/Dalamud.Plugin.targets b/targets/Dalamud.Plugin.targets
deleted file mode 100644
index 08d19735e..000000000
--- a/targets/Dalamud.Plugin.targets
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
- net8.0-windows
- x64
- enable
- latest
- true
- false
- false
- true
- true
- $(AssemblySearchPaths);$(DalamudLibPath)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
From 2f5f52b572850342ef09ec9fab81f6d564e651fe Mon Sep 17 00:00:00 2001
From: Haselnussbomber
Date: Sun, 7 Dec 2025 16:23:13 +0100
Subject: [PATCH 46/50] Forgot to remove this too
---
Dalamud/Dalamud.csproj | 5 -----
1 file changed, 5 deletions(-)
diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj
index 1c16891b7..d1b77b1fc 100644
--- a/Dalamud/Dalamud.csproj
+++ b/Dalamud/Dalamud.csproj
@@ -227,9 +227,4 @@
-
-
-
-
-
From c254c8600e19f134ed4d526a7886e2620677f14f Mon Sep 17 00:00:00 2001
From: Haselnussbomber
Date: Sun, 7 Dec 2025 16:31:03 +0100
Subject: [PATCH 47/50] Update Font Awesome to 7.1.0
---
.../Interface/FontAwesome/FontAwesomeIcon.cs | 1171 ++++++++++-------
1 file changed, 671 insertions(+), 500 deletions(-)
diff --git a/Dalamud/Interface/FontAwesome/FontAwesomeIcon.cs b/Dalamud/Interface/FontAwesome/FontAwesomeIcon.cs
index f88d7f8f0..35df9cfbc 100644
--- a/Dalamud/Interface/FontAwesome/FontAwesomeIcon.cs
+++ b/Dalamud/Interface/FontAwesome/FontAwesomeIcon.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
//
// Generated by Dalamud.FASharpGen - don't modify this file directly.
-// Font-Awesome Version: 6.4.2
+// Font-Awesome Version: 7.1.0
//
//------------------------------------------------------------------------------
@@ -29,14 +29,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "address-book" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "address book", "contact", "directory", "index", "little black book", "rolodex" })]
+ [FontAwesomeSearchTerms(new[] { "address book", "contact", "directory", "employee", "index", "little black book", "portfolio", "rolodex", "uer", "username" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Communication", "Users + People" })]
AddressBook = 0xF2B9,
///
/// The Font Awesome "address-card" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "address card", "about", "contact", "id", "identification", "postcard", "profile", "registration" })]
+ [FontAwesomeSearchTerms(new[] { "address card", "about", "contact", "employee", "id", "identification", "portfolio", "postcard", "profile", "registration", "uer", "username" })]
[FontAwesomeCategoriesAttribute(new[] { "Accessibility", "Alphabet", "Business", "Communication", "Users + People" })]
AddressCard = 0xF2BB,
@@ -54,6 +54,13 @@ public enum FontAwesomeIcon
[FontAwesomeCategoriesAttribute(new[] { "Automotive" })]
AirFreshener = 0xF5D0,
+ ///
+ /// The Font Awesome "alarm-clock" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "alarm clock", "alarm", "alarm clock", "clock", "date", "late", "pending", "reminder", "sleep", "snooze", "timer", "timestamp", "watch" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Alert", "Time", "Travel + Hotel" })]
+ AlarmClock = 0xF34E,
+
///
/// The Font Awesome "align-center" icon unicode character.
///
@@ -113,28 +120,28 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "anchor-circle-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "anchor circle check", "marina", "not affected", "ok", "okay", "port" })]
+ [FontAwesomeSearchTerms(new[] { "anchor circle check", "enable", "marina", "not affected", "ok", "okay", "port", "validate", "working" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Logistics", "Maritime" })]
AnchorCircleCheck = 0xE4AA,
///
/// The Font Awesome "anchor-circle-exclamation" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "anchor circle exclamation", "affected", "marina", "port" })]
+ [FontAwesomeSearchTerms(new[] { "anchor circle exclamation", "affected", "failed", "marina", "port" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Logistics", "Maritime" })]
AnchorCircleExclamation = 0xE4AB,
///
/// The Font Awesome "anchor-circle-xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "anchor circle xmark", "destroy", "marina", "port" })]
+ [FontAwesomeSearchTerms(new[] { "anchor circle xmark", "destroy", "marina", "port", "uncheck" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Logistics", "Maritime" })]
AnchorCircleXmark = 0xE4AC,
///
/// The Font Awesome "anchor-lock" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "anchor lock", "closed", "lockdown", "marina", "port", "quarantine" })]
+ [FontAwesomeSearchTerms(new[] { "anchor lock", "closed", "lockdown", "marina", "padlock", "port", "privacy", "quarantine" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Logistics", "Maritime" })]
AnchorLock = 0xE4AD,
@@ -169,7 +176,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "angle-down" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "angle down", "down arrowhead", "arrow", "caret", "download", "expand" })]
+ [FontAwesomeSearchTerms(new[] { "angle down", "down arrowhead", "arrow", "caret", "download", "expand", "insert" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
AngleDown = 0xF107,
@@ -190,7 +197,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "angle-up" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "angle up", "up arrowhead", "arrow", "caret", "collapse", "upload" })]
+ [FontAwesomeSearchTerms(new[] { "angle up", "up arrowhead", "arrow", "caret", "collapse", "upgrade", "upload" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
AngleUp = 0xF106,
@@ -253,7 +260,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "circle-up" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "circle up", "arrow-circle-o-up" })]
+ [FontAwesomeSearchTerms(new[] { "circle up", "arrow-circle-o-up", "upgrade" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
ArrowAltCircleUp = 0xF35B,
@@ -281,7 +288,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "circle-arrow-up" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "circle arrow up", "upload" })]
+ [FontAwesomeSearchTerms(new[] { "circle arrow up", "upgrade", "upload" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
ArrowCircleUp = 0xF0AA,
@@ -309,7 +316,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "arrow-down-up-lock" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrow down up lock", "border", "closed", "crossing", "lockdown", "quarantine", "transfer" })]
+ [FontAwesomeSearchTerms(new[] { "arrow down up lock", "border", "closed", "crossing", "lockdown", "padlock", "privacy", "quarantine", "transfer" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows", "Humanitarian" })]
ArrowDownUpLock = 0xE4B0,
@@ -337,7 +344,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "arrow-right-arrow-left" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrow right arrow left", "rightwards arrow over leftwards arrow", "arrow", "arrows", "reciprocate", "return", "swap", "transfer" })]
+ [FontAwesomeSearchTerms(new[] { "arrow right arrow left", "arrow", "arrows", "reciprocate", "return", "swap", "transfer" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
ArrowRightArrowLeft = 0xF0EC,
@@ -358,14 +365,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "arrow-right-to-bracket" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrow right to bracket", "arrow", "enter", "join", "log in", "login", "sign in", "sign up", "sign-in", "signin", "signup" })]
+ [FontAwesomeSearchTerms(new[] { "arrow right to bracket", "arrow", "enter", "insert", "join", "log in", "login", "sign in", "sign up", "sign-in", "signin", "signup" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
ArrowRightToBracket = 0xF090,
///
/// The Font Awesome "arrow-right-to-city" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrow right to city", "building", "city", "exodus", "rural", "urban" })]
+ [FontAwesomeSearchTerms(new[] { "arrow right to city", "building", "city", "exodus", "insert", "rural", "urban" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Humanitarian" })]
ArrowRightToCity = 0xE4B3,
@@ -393,14 +400,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "arrows-down-to-line" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrows down to line", "scale down", "sink" })]
+ [FontAwesomeSearchTerms(new[] { "arrows down to line", "insert", "scale down", "sink" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows", "Humanitarian" })]
ArrowsDownToLine = 0xE4B8,
///
/// The Font Awesome "arrows-down-to-people" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrows down to people", "affected", "focus", "targeted" })]
+ [FontAwesomeSearchTerms(new[] { "arrows down to people", "affected", "focus", "insert", "targeted", "together", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
ArrowsDownToPeople = 0xE4B9,
@@ -435,14 +442,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "arrows-to-circle" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrows to circle", "center", "concentrate", "coordinate", "coordination", "focal point", "focus" })]
+ [FontAwesomeSearchTerms(new[] { "arrows to circle", "center", "concentrate", "coordinate", "coordination", "focal point", "focus", "insert" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows", "Humanitarian" })]
ArrowsToCircle = 0xE4BD,
///
/// The Font Awesome "arrows-to-dot" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrows to dot", "assembly point", "center", "condense", "focus", "minimize" })]
+ [FontAwesomeSearchTerms(new[] { "arrows to dot", "assembly point", "center", "condense", "focus", "insert", "minimize" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows", "Business", "Humanitarian", "Marketing" })]
ArrowsToDot = 0xE4BE,
@@ -463,7 +470,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "arrows-turn-to-dots" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrows turn to dots", "destination", "nexus" })]
+ [FontAwesomeSearchTerms(new[] { "arrows turn to dots", "destination", "insert", "nexus" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows", "Humanitarian" })]
ArrowsTurnToDots = 0xE4C1,
@@ -484,7 +491,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "arrows-up-to-line" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrows up to line", "rise", "scale up" })]
+ [FontAwesomeSearchTerms(new[] { "arrows up to line", "rise", "scale up", "upgrade" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows", "Humanitarian" })]
ArrowsUpToLine = 0xE4C2,
@@ -519,28 +526,28 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "arrow-up" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrow up", "upwards arrow", "forward", "upload" })]
+ [FontAwesomeSearchTerms(new[] { "arrow up", "upwards arrow", "forward", "upgrade", "upload" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
ArrowUp = 0xF062,
///
/// The Font Awesome "arrow-up-from-bracket" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrow up from bracket", "share", "transfer", "upload" })]
+ [FontAwesomeSearchTerms(new[] { "arrow up from bracket", "share", "transfer", "upgrade", "upload" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
ArrowUpFromBracket = 0xE09A,
///
/// The Font Awesome "arrow-up-from-ground-water" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrow up from ground water", "groundwater", "spring", "water supply", "water table" })]
+ [FontAwesomeSearchTerms(new[] { "arrow up from ground water", "groundwater", "spring", "upgrade", "water supply", "water table" })]
[FontAwesomeCategoriesAttribute(new[] { "Construction", "Energy", "Humanitarian" })]
ArrowUpFromGroundWater = 0xE4B5,
///
/// The Font Awesome "arrow-up-from-water-pump" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrow up from water pump", "flood", "groundwater", "pump", "submersible", "sump pump" })]
+ [FontAwesomeSearchTerms(new[] { "arrow up from water pump", "flood", "groundwater", "pump", "submersible", "sump pump", "upgrade" })]
[FontAwesomeCategoriesAttribute(new[] { "Household", "Humanitarian" })]
ArrowUpFromWaterPump = 0xE4B6,
@@ -554,14 +561,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "arrow-up-right-dots" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrow up right dots", "growth", "increase", "population" })]
+ [FontAwesomeSearchTerms(new[] { "arrow up right dots", "growth", "increase", "population", "upgrade" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows", "Humanitarian" })]
ArrowUpRightDots = 0xE4B7,
///
/// The Font Awesome "arrow-up-right-from-square" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrow up right from square", "new", "open", "send", "share" })]
+ [FontAwesomeSearchTerms(new[] { "arrow up right from square", "new", "open", "send", "share", "upgrade" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows", "Humanitarian" })]
ArrowUpRightFromSquare = 0xF08E,
@@ -576,7 +583,7 @@ public enum FontAwesomeIcon
/// The Font Awesome "asterisk" icon unicode character.
/// Uses a legacy unicode value for backwards compatability. The current unicode value is 0x2A.
///
- [FontAwesomeSearchTerms(new[] { "asterisk", "asterisk", "heavy asterisk", "annotation", "details", "reference", "star" })]
+ [FontAwesomeSearchTerms(new[] { "asterisk", "asterisk", "heavy asterisk", "annotation", "details", "reference", "required", "star" })]
[FontAwesomeCategoriesAttribute(new[] { "Punctuation + Symbols", "Spinners" })]
Asterisk = 0xF069,
@@ -591,14 +598,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "book-atlas" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "book atlas", "book", "directions", "geography", "globe", "library", "map", "research", "travel", "wayfinding" })]
+ [FontAwesomeSearchTerms(new[] { "book atlas", "book", "directions", "geography", "globe", "knowledge", "library", "map", "research", "travel", "wayfinding" })]
[FontAwesomeCategoriesAttribute(new[] { "Maps", "Travel + Hotel" })]
Atlas = 0xF558,
///
/// The Font Awesome "atom" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "atheism", "atheist", "atom", "atom symbol", "chemistry", "electron", "ion", "isotope", "neutron", "nuclear", "proton", "science" })]
+ [FontAwesomeSearchTerms(new[] { "atheism", "atheist", "atom", "atom symbol", "chemistry", "electron", "ion", "isotope", "knowledge", "neutron", "nuclear", "proton", "science" })]
[FontAwesomeCategoriesAttribute(new[] { "Education", "Energy", "Religion", "Science", "Science Fiction", "Spinners" })]
Atom = 0xF5D2,
@@ -619,14 +626,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "award" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "award", "honor", "praise", "prize", "recognition", "ribbon", "trophy" })]
+ [FontAwesomeSearchTerms(new[] { "award", "guarantee", "honor", "praise", "prize", "recognition", "ribbon", "trophy", "warranty" })]
[FontAwesomeCategoriesAttribute(new[] { "Education", "Political" })]
Award = 0xF559,
///
/// The Font Awesome "baby" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "baby", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "baby", "uer", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Childhood", "Humanitarian", "Users + People" })]
Baby = 0xF77C,
@@ -668,7 +675,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "bacterium" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "bacterium", "antibiotic", "antibody", "covid-19", "health", "organism", "sick" })]
+ [FontAwesomeSearchTerms(new[] { "bacterium", "antibiotic", "antibody", "covid-19", "germ", "health", "organism", "sick" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Medical + Health" })]
Bacterium = 0xE05A,
@@ -710,14 +717,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "ban" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "abort", "ban", "block", "cancel", "delete", "entry", "forbidden", "hide", "no", "not", "prohibit", "prohibited", "remove", "stop", "trash" })]
+ [FontAwesomeSearchTerms(new[] { "404", "abort", "ban", "block", "cancel", "circle", "delete", "deny", "disabled", "entry", "failed", "forbidden", "hide", "no", "not", "not found", "prohibit", "prohibited", "remove", "slash", "stop", "trash" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Security" })]
Ban = 0xF05E,
///
/// The Font Awesome "bandage" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "adhesive bandage", "bandage", "boo boo", "first aid", "ouch" })]
+ [FontAwesomeSearchTerms(new[] { "adhesive bandage", "bandage", "boo boo", "first aid", "modify", "ouch" })]
[FontAwesomeCategoriesAttribute(new[] { "Editing", "Medical + Health" })]
BandAid = 0xF462,
@@ -815,7 +822,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "bed" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "bed", "hospital", "hotel", "lodging", "mattress", "patient", "person in bed", "rest", "sleep", "travel" })]
+ [FontAwesomeSearchTerms(new[] { "bed", "hospital", "hotel", "lodging", "mattress", "patient", "person in bed", "rest", "sleep", "travel", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Household", "Humanitarian", "Maps", "Travel + Hotel", "Users + People" })]
Bed = 0xF236,
@@ -829,7 +836,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "bell" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "alarm", "alert", "bel", "bell", "chime", "notification", "reminder" })]
+ [FontAwesomeSearchTerms(new[] { "alarm", "alert", "bel", "bell", "chime", "notification", "reminder", "request" })]
[FontAwesomeCategoriesAttribute(new[] { "Alert", "Education", "Household", "Maps", "Shopping", "Social", "Time" })]
Bell = 0xF0F3,
@@ -864,14 +871,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "person-biking" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person biking", "bicycle", "bike", "biking", "cyclist", "pedal", "person biking", "summer", "wheel" })]
+ [FontAwesomeSearchTerms(new[] { "person biking", "bicycle", "bike", "biking", "cyclist", "pedal", "person biking", "summer", "uer", "wheel" })]
[FontAwesomeCategoriesAttribute(new[] { "Childhood", "Sports + Fitness", "Users + People" })]
Biking = 0xF84A,
///
/// The Font Awesome "binoculars" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "binoculars", "glasses", "magnify", "scenic", "spyglass", "view" })]
+ [FontAwesomeSearchTerms(new[] { "binoculars", "glasses", "inspection", "magnifier", "magnify", "scenic", "spyglass", "view" })]
[FontAwesomeCategoriesAttribute(new[] { "Astronomy", "Camping", "Maps", "Nature" })]
Binoculars = 0xF1E5,
@@ -913,7 +920,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "person-walking-with-cane" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person walking with cane", "blind", "cane" })]
+ [FontAwesomeSearchTerms(new[] { "person walking with cane", "blind", "cane", "follow", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Accessibility", "Maps", "Users + People" })]
Blind = 0xF29D,
@@ -969,14 +976,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "book" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "book", "cover", "decorated", "diary", "documentation", "journal", "library", "notebook", "notebook with decorative cover", "read", "research" })]
+ [FontAwesomeSearchTerms(new[] { "book", "cover", "decorated", "diary", "documentation", "journal", "knowledge", "library", "notebook", "notebook with decorative cover", "read", "research", "scholar" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Maps", "Writing" })]
Book = 0xF02D,
///
/// The Font Awesome "book-bookmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "book bookmark", "library", "research" })]
+ [FontAwesomeSearchTerms(new[] { "book bookmark", "knowledge", "library", "research" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Writing" })]
BookBookmark = 0xE0BB,
@@ -1004,7 +1011,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "book-open" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "book open", "book", "book", "flyer", "library", "notebook", "open", "open book", "pamphlet", "reading", "research" })]
+ [FontAwesomeSearchTerms(new[] { "book open", "book", "book", "flyer", "knowledge", "library", "notebook", "open", "open book", "pamphlet", "reading", "research" })]
[FontAwesomeCategoriesAttribute(new[] { "Education" })]
BookOpen = 0xF518,
@@ -1130,7 +1137,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "brain" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "brain", "cerebellum", "gray matter", "intellect", "intelligent", "medulla oblongata", "mind", "noodle", "wit" })]
+ [FontAwesomeSearchTerms(new[] { "brain", "cerebellum", "gray matter", "intellect", "intelligent", "knowledge", "medulla oblongata", "mind", "noodle", "scholar", "wit" })]
[FontAwesomeCategoriesAttribute(new[] { "Medical + Health", "Science" })]
Brain = 0xF5DC,
@@ -1158,28 +1165,28 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "bridge-circle-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "bridge circle check", "bridge", "not affected", "ok", "okay", "road" })]
+ [FontAwesomeSearchTerms(new[] { "bridge circle check", "bridge", "enable", "not affected", "ok", "okay", "road", "validate", "working" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Logistics" })]
BridgeCircleCheck = 0xE4C9,
///
/// The Font Awesome "bridge-circle-exclamation" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "bridge circle exclamation", "affected", "bridge", "road" })]
+ [FontAwesomeSearchTerms(new[] { "bridge circle exclamation", "affected", "bridge", "failed", "road" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Logistics" })]
BridgeCircleExclamation = 0xE4CA,
///
/// The Font Awesome "bridge-circle-xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "bridge circle xmark", "bridge", "destroy", "road" })]
+ [FontAwesomeSearchTerms(new[] { "bridge circle xmark", "bridge", "destroy", "road", "uncheck" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Logistics" })]
BridgeCircleXmark = 0xE4CB,
///
/// The Font Awesome "bridge-lock" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "bridge lock", "bridge", "closed", "lockdown", "quarantine", "road" })]
+ [FontAwesomeSearchTerms(new[] { "bridge lock", "bridge", "closed", "lockdown", "padlock", "privacy", "quarantine", "road" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Logistics" })]
BridgeLock = 0xE4CC,
@@ -1193,7 +1200,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "briefcase" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "bag", "briefcas", "briefcase", "business", "luggage", "office", "work" })]
+ [FontAwesomeSearchTerms(new[] { "bag", "briefcas", "briefcase", "business", "luggage", "offer", "office", "portfolio", "work" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Maps", "Travel + Hotel" })]
Briefcase = 0xF0B1,
@@ -1207,7 +1214,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "tower-broadcast" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "tower broadcast", "airwaves", "antenna", "communication", "emergency", "radio", "reception", "waves" })]
+ [FontAwesomeSearchTerms(new[] { "tower broadcast", "airwaves", "antenna", "communication", "emergency", "radio", "reception", "signal", "waves" })]
[FontAwesomeCategoriesAttribute(new[] { "Connectivity", "Energy", "Film + Video", "Humanitarian" })]
BroadcastTower = 0xF519,
@@ -1221,7 +1228,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "brush" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "brush", "art", "bristles", "color", "handle", "paint" })]
+ [FontAwesomeSearchTerms(new[] { "brush", "art", "bristles", "color", "handle", "maintenance", "modify", "paint" })]
[FontAwesomeCategoriesAttribute(new[] { "Construction", "Design", "Editing" })]
Brush = 0xF55D,
@@ -1249,7 +1256,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "bug-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "bug slash", "beetle", "fix", "glitch", "insect", "optimize", "repair", "report", "warning" })]
+ [FontAwesomeSearchTerms(new[] { "bug slash", "beetle", "disabled", "fix", "glitch", "insect", "optimize", "repair", "report", "warning" })]
[FontAwesomeCategoriesAttribute(new[] { "Coding", "Security" })]
BugSlash = 0xE490,
@@ -1270,42 +1277,42 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "building-circle-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "building circle check", "building", "city", "not affected", "office", "ok", "okay" })]
+ [FontAwesomeSearchTerms(new[] { "building circle check", "building", "city", "enable", "not affected", "office", "ok", "okay", "validate", "working" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Humanitarian" })]
BuildingCircleCheck = 0xE4D2,
///
/// The Font Awesome "building-circle-exclamation" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "building circle exclamation", "affected", "building", "city", "office" })]
+ [FontAwesomeSearchTerms(new[] { "building circle exclamation", "affected", "building", "city", "failed", "office" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Humanitarian" })]
BuildingCircleExclamation = 0xE4D3,
///
/// The Font Awesome "building-circle-xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "building circle xmark", "building", "city", "destroy", "office" })]
+ [FontAwesomeSearchTerms(new[] { "building circle xmark", "building", "city", "destroy", "office", "uncheck" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Humanitarian" })]
BuildingCircleXmark = 0xE4D4,
///
/// The Font Awesome "building-flag" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "building flag", " city", "building", "diplomat", "embassy", "flag", "headquarters", "united nations" })]
+ [FontAwesomeSearchTerms(new[] { "building flag", "building", "city", "diplomat", "embassy", "flag", "headquarters", "united nations" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Humanitarian", "Political" })]
BuildingFlag = 0xE4D5,
///
/// The Font Awesome "building-lock" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "building lock", "building", "city", "closed", "lock", "lockdown", "quarantine", "secure" })]
+ [FontAwesomeSearchTerms(new[] { "building lock", "building", "city", "closed", "lock", "lockdown", "padlock", "privacy", "quarantine", "secure" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Humanitarian", "Security" })]
BuildingLock = 0xE4D6,
///
/// The Font Awesome "building-ngo" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "building ngo", " city", "building", "non governmental organization", "office" })]
+ [FontAwesomeSearchTerms(new[] { "building ngo", "building", "city", "non governmental organization", "office" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Humanitarian" })]
BuildingNgo = 0xE4D7,
@@ -1326,7 +1333,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "building-user" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "building user", "apartment", "building", "city" })]
+ [FontAwesomeSearchTerms(new[] { "building user", "apartment", "building", "city", "employee", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Humanitarian" })]
BuildingUser = 0xE4DA,
@@ -1340,7 +1347,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "bullhorn" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "bullhorn", "bullhorn", "announcement", "broadcast", "loud", "louder", "loudspeaker", "megaphone", "public address", "share" })]
+ [FontAwesomeSearchTerms(new[] { "bullhorn", "bullhorn", "announcement", "broadcast", "loud", "louder", "loudspeaker", "megaphone", "public address", "request", "share" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Communication", "Marketing", "Political", "Shopping" })]
Bullhorn = 0xF0A1,
@@ -1382,10 +1389,17 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "business-time" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "business time", "alarm", "briefcase", "business socks", "clock", "flight of the conchords", "reminder", "wednesday" })]
+ [FontAwesomeSearchTerms(new[] { "business time", "alarm", "briefcase", "business socks", "clock", "flight of the conchords", "portfolio", "reminder", "wednesday" })]
[FontAwesomeCategoriesAttribute(new[] { "Business" })]
BusinessTime = 0xF64A,
+ ///
+ /// The Font Awesome "bus-side" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "bus side", "bus", "public transportation", "transportation", "travel", "vehicle" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Automotive", "Humanitarian", "Logistics", "Transportation", "Travel + Hotel" })]
+ BusSide = 0xE81D,
+
///
/// The Font Awesome "calculator" icon unicode character.
///
@@ -1410,7 +1424,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "calendar-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "calendar check", "accept", "agree", "appointment", "confirm", "correct", "date", "day", "done", "event", "month", "ok", "schedule", "select", "success", "tick", "time", "todo", "when", "year" })]
+ [FontAwesomeSearchTerms(new[] { "calendar check", "accept", "agree", "appointment", "confirm", "correct", "date", "day", "done", "enable", "event", "month", "ok", "schedule", "select", "success", "tick", "time", "todo", "validate", "warranty", "when", "working", "year" })]
[FontAwesomeCategoriesAttribute(new[] { "Time" })]
CalendarCheck = 0xF274,
@@ -1438,7 +1452,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "calendar-xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "calendar xmark", "archive", "calendar", "date", "day", "delete", "event", "month", "remove", "schedule", "time", "when", "x", "year" })]
+ [FontAwesomeSearchTerms(new[] { "calendar xmark", "archive", "calendar", "date", "day", "delete", "event", "month", "remove", "schedule", "time", "uncheck", "when", "x", "year" })]
[FontAwesomeCategoriesAttribute(new[] { "Time" })]
CalendarTimes = 0xF273,
@@ -1452,21 +1466,21 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "camera" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "camera", "image", "lens", "photo", "picture", "record", "shutter", "video" })]
+ [FontAwesomeSearchTerms(new[] { "camera", "image", "img", "lens", "photo", "picture", "record", "shutter", "video" })]
[FontAwesomeCategoriesAttribute(new[] { "Devices + Hardware", "Photos + Images", "Shopping", "Social" })]
Camera = 0xF030,
///
/// The Font Awesome "camera-retro" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "camera retro", "camera", "image", "lens", "photo", "picture", "record", "shutter", "video" })]
+ [FontAwesomeSearchTerms(new[] { "camera retro", "camera", "image", "img", "lens", "photo", "picture", "record", "shutter", "video" })]
[FontAwesomeCategoriesAttribute(new[] { "Devices + Hardware", "Photos + Images", "Shopping" })]
CameraRetro = 0xF083,
///
/// The Font Awesome "camera-rotate" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "camera rotate", "flip", "front-facing", "photo", "selfie" })]
+ [FontAwesomeSearchTerms(new[] { "camera rotate", "flip", "front-facing", "img", "photo", "selfie" })]
[FontAwesomeCategoriesAttribute(new[] { "Photos + Images" })]
CameraRotate = 0xE0D8,
@@ -1557,7 +1571,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "square-caret-down" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "square caret down", "arrow", "caret-square-o-down", "dropdown", "expand", "menu", "more", "triangle" })]
+ [FontAwesomeSearchTerms(new[] { "square caret down", "arrow", "caret-square-o-down", "dropdown", "expand", "insert", "menu", "more", "triangle" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
CaretSquareDown = 0xF150,
@@ -1578,14 +1592,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "square-caret-up" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "square caret up", "arrow", "caret-square-o-up", "collapse", "triangle", "upload" })]
+ [FontAwesomeSearchTerms(new[] { "square caret up", "arrow", "caret-square-o-up", "collapse", "triangle", "upgrade", "upload" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
CaretSquareUp = 0xF151,
///
/// The Font Awesome "caret-up" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "caret up", "arrow", "collapse", "triangle" })]
+ [FontAwesomeSearchTerms(new[] { "caret up", "arrow", "collapse", "triangle", "upgrade" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
CaretUp = 0xF0D8,
@@ -1613,7 +1627,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "cart-arrow-down" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "cart arrow down", "download", "save", "shopping" })]
+ [FontAwesomeSearchTerms(new[] { "cart arrow down", "download", "insert", "save", "shopping" })]
[FontAwesomeCategoriesAttribute(new[] { "Shopping" })]
CartArrowDown = 0xF218,
@@ -1662,7 +1676,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "certificate" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "certificate", "badge", "star", "verified" })]
+ [FontAwesomeSearchTerms(new[] { "certificate", "badge", "guarantee", "star", "verified" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Shapes", "Shopping", "Spinners" })]
Certificate = 0xF0A3,
@@ -1683,91 +1697,98 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "chalkboard-user" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "chalkboard user", "blackboard", "instructor", "learning", "professor", "school", "whiteboard", "writing" })]
+ [FontAwesomeSearchTerms(new[] { "chalkboard user", "blackboard", "instructor", "learning", "professor", "school", "uer", "whiteboard", "writing" })]
[FontAwesomeCategoriesAttribute(new[] { "Education", "Users + People" })]
ChalkboardTeacher = 0xF51C,
///
/// The Font Awesome "charging-station" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "charging station", "electric", "ev", "tesla", "vehicle" })]
+ [FontAwesomeSearchTerms(new[] { "charging station", "car charger", "charge", "charging", "electric", "ev", "tesla", "vehicle" })]
[FontAwesomeCategoriesAttribute(new[] { "Automotive", "Energy" })]
ChargingStation = 0xF5E7,
///
/// The Font Awesome "chart-area" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "chart area", "analytics", "area", "chart", "graph" })]
+ [FontAwesomeSearchTerms(new[] { "chart area", "analytics", "area", "chart", "graph", "performance", "revenue", "statistics" })]
[FontAwesomeCategoriesAttribute(new[] { "Charts + Diagrams" })]
ChartArea = 0xF1FE,
///
/// The Font Awesome "chart-bar" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "chart bar", "analytics", "bar", "chart", "graph" })]
+ [FontAwesomeSearchTerms(new[] { "chart bar", "analytics", "bar", "chart", "graph", "performance", "statistics" })]
[FontAwesomeCategoriesAttribute(new[] { "Charts + Diagrams" })]
ChartBar = 0xF080,
///
/// The Font Awesome "chart-column" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "chart column", "bar", "bar chart", "chart", "graph", "track", "trend" })]
+ [FontAwesomeSearchTerms(new[] { "chart column", "bar", "bar chart", "chart", "graph", "performance", "revenue", "statistics", "track", "trend" })]
[FontAwesomeCategoriesAttribute(new[] { "Charts + Diagrams" })]
ChartColumn = 0xE0E3,
+ ///
+ /// The Font Awesome "chart-diagram" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "chart diagram", "algorithm", "analytics", "flow", "graph" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Charts + Diagrams", "Coding" })]
+ ChartDiagram = 0xE695,
+
///
/// The Font Awesome "chart-gantt" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "chart gantt", "chart", "graph", "track", "trend" })]
+ [FontAwesomeSearchTerms(new[] { "chart gantt", "chart", "graph", "performance", "statistics", "track", "trend" })]
[FontAwesomeCategoriesAttribute(new[] { "Charts + Diagrams" })]
ChartGantt = 0xE0E4,
///
/// The Font Awesome "chart-line" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "chart line", "activity", "analytics", "chart", "dashboard", "gain", "graph", "increase", "line" })]
+ [FontAwesomeSearchTerms(new[] { "chart line", "activity", "analytics", "chart", "dashboard", "gain", "graph", "increase", "line", "performance", "revenue", "statistics" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Charts + Diagrams", "Money" })]
ChartLine = 0xF201,
///
/// The Font Awesome "chart-pie" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "chart pie", "analytics", "chart", "diagram", "graph", "pie" })]
+ [FontAwesomeSearchTerms(new[] { "chart pie", "analytics", "chart", "diagram", "graph", "performance", "pie", "revenue", "statistics" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Charts + Diagrams", "Money" })]
ChartPie = 0xF200,
///
/// The Font Awesome "chart-simple" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "chart simple", "analytics", "bar", "chart", "column", "graph", "row", "trend" })]
+ [FontAwesomeSearchTerms(new[] { "chart simple", "analytics", "bar", "chart", "column", "graph", "performance", "revenue", "row", "statistics", "trend" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Charts + Diagrams", "Editing", "Logistics", "Marketing" })]
ChartSimple = 0xE473,
///
/// The Font Awesome "check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "check mark", "accept", "agree", "check", "check mark", "checkmark", "confirm", "correct", "done", "mark", "notice", "notification", "notify", "ok", "select", "success", "tick", "todo", "yes", "✓" })]
+ [FontAwesomeSearchTerms(new[] { "check mark", "accept", "agree", "check", "check mark", "checkmark", "confirm", "correct", "coupon", "done", "enable", "mark", "notice", "notification", "notify", "ok", "select", "success", "tick", "todo", "true", "validate", "working", "yes", "✓" })]
[FontAwesomeCategoriesAttribute(new[] { "Editing", "Punctuation + Symbols", "Text Formatting" })]
Check = 0xF00C,
///
/// The Font Awesome "circle-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "circle check", "accept", "affected", "agree", "clear", "confirm", "correct", "done", "ok", "select", "success", "tick", "todo", "yes" })]
+ [FontAwesomeSearchTerms(new[] { "circle check", "accept", "affected", "agree", "clear", "confirm", "correct", "coupon", "done", "enable", "ok", "select", "success", "tick", "todo", "validate", "working", "yes" })]
[FontAwesomeCategoriesAttribute(new[] { "Editing", "Text Formatting", "Toggle" })]
CheckCircle = 0xF058,
///
/// The Font Awesome "check-double" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "check double", "accept", "agree", "checkmark", "confirm", "correct", "done", "notice", "notification", "notify", "ok", "select", "success", "tick", "todo" })]
+ [FontAwesomeSearchTerms(new[] { "check double", "accept", "agree", "checkmark", "confirm", "correct", "coupon", "done", "enable", "notice", "notification", "notify", "ok", "select", "select all", "success", "tick", "todo", "validate", "working" })]
[FontAwesomeCategoriesAttribute(new[] { "Editing", "Political", "Punctuation + Symbols", "Text Formatting" })]
CheckDouble = 0xF560,
///
/// The Font Awesome "square-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "square check", "accept", "agree", "box", "button", "check", "check box with check", "check mark button", "checkmark", "confirm", "correct", "done", "mark", "ok", "select", "success", "tick", "todo", "yes", "✓" })]
+ [FontAwesomeSearchTerms(new[] { "square check", "accept", "agree", "box", "button", "check", "check box with check", "check mark button", "checkmark", "confirm", "correct", "coupon", "done", "enable", "mark", "ok", "select", "success", "tick", "todo", "validate", "working", "yes", "✓" })]
[FontAwesomeCategoriesAttribute(new[] { "Editing", "Text Formatting" })]
CheckSquare = 0xF14A,
@@ -1858,14 +1879,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "circle-chevron-up" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "circle chevron up", "arrow", "collapse", "upload" })]
+ [FontAwesomeSearchTerms(new[] { "circle chevron up", "arrow", "collapse", "upgrade", "upload" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
ChevronCircleUp = 0xF139,
///
/// The Font Awesome "chevron-down" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "chevron down", "arrow", "download", "expand" })]
+ [FontAwesomeSearchTerms(new[] { "chevron down", "arrow", "download", "expand", "insert" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
ChevronDown = 0xF078,
@@ -1886,14 +1907,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "chevron-up" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "chevron up", "arrow", "collapse", "upload" })]
+ [FontAwesomeSearchTerms(new[] { "chevron up", "arrow", "collapse", "upgrade", "upload" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
ChevronUp = 0xF077,
///
/// The Font Awesome "child" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "child", "boy", "girl", "kid", "toddler", "young", "youth" })]
+ [FontAwesomeSearchTerms(new[] { "child", "boy", "girl", "kid", "toddler", "uer", "young", "youth" })]
[FontAwesomeCategoriesAttribute(new[] { "Childhood", "Users + People" })]
Child = 0xF1AE,
@@ -1907,21 +1928,21 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "child-dress" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "child dress", "boy", "girl", "kid", "toddler", "young", "youth" })]
+ [FontAwesomeSearchTerms(new[] { "child dress", "boy", "girl", "kid", "toddler", "uer", "young", "youth" })]
[FontAwesomeCategoriesAttribute(new[] { "Childhood", "Users + People" })]
ChildDress = 0xE59C,
///
/// The Font Awesome "child-reaching" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "child reaching", "boy", "girl", "kid", "toddler", "young", "youth" })]
+ [FontAwesomeSearchTerms(new[] { "child reaching", "boy", "girl", "kid", "toddler", "uer", "young", "youth" })]
[FontAwesomeCategoriesAttribute(new[] { "Childhood", "Users + People" })]
ChildReaching = 0xE59D,
///
/// The Font Awesome "children" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "children", "boy", "child", "girl", "kid", "kids", "young", "youth" })]
+ [FontAwesomeSearchTerms(new[] { "children", "boy", "child", "girl", "kid", "kids", "together", "uer", "young", "youth" })]
[FontAwesomeCategoriesAttribute(new[] { "Childhood", "Humanitarian", "Users + People" })]
Children = 0xE4E1,
@@ -1977,49 +1998,49 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "clipboard" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "clipboar", "clipboard", "copy", "notes", "paste", "record" })]
+ [FontAwesomeSearchTerms(new[] { "clipboard", "copy", "notepad", "notes", "paste", "record" })]
[FontAwesomeCategoriesAttribute(new[] { "Business" })]
Clipboard = 0xF328,
///
/// The Font Awesome "clipboard-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "clipboard check", "accept", "agree", "confirm", "done", "ok", "select", "success", "tick", "todo", "yes" })]
- [FontAwesomeCategoriesAttribute(new[] { "Logistics", "Science" })]
+ [FontAwesomeSearchTerms(new[] { "clipboard check", "accept", "agree", "confirm", "coupon", "done", "enable", "ok", "select", "success", "tick", "todo", "validate", "working", "yes" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Business", "Logistics", "Science" })]
ClipboardCheck = 0xF46C,
///
/// The Font Awesome "clipboard-list" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "clipboard list", "checklist", "completed", "done", "finished", "intinerary", "ol", "schedule", "tick", "todo", "ul" })]
+ [FontAwesomeSearchTerms(new[] { "clipboard list", "cheatsheet", "checklist", "completed", "done", "finished", "intinerary", "ol", "schedule", "summary", "survey", "tick", "todo", "ul", "wishlist" })]
[FontAwesomeCategoriesAttribute(new[] { "Logistics" })]
ClipboardList = 0xF46D,
///
/// The Font Awesome "clipboard-question" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "clipboard question", "assistance", "interview", "query", "question" })]
+ [FontAwesomeSearchTerms(new[] { "clipboard question", "assistance", "faq", "interview", "query", "question" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Humanitarian", "Logistics" })]
ClipboardQuestion = 0xE4E3,
///
/// The Font Awesome "clipboard-user" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "clipboard user", "attendance", "record", "roster", "staff" })]
- [FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Medical + Health", "Users + People" })]
+ [FontAwesomeSearchTerms(new[] { "clipboard user", "attendance", "employee", "record", "roster", "staff", "uer" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Logistics", "Medical + Health", "Users + People" })]
ClipboardUser = 0xF7F3,
///
/// The Font Awesome "clock" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "00", "4", "4:00", "clock", "date", "four", "four o’clock", "hour", "late", "minute", "o'clock", "o’clock", "schedule", "ticking", "time", "timer", "timestamp", "watch" })]
+ [FontAwesomeSearchTerms(new[] { "00", "4", "4:00", "clock", "date", "four", "four o’clock", "hour", "late", "minute", "o'clock", "o’clock", "pending", "schedule", "ticking", "time", "timer", "timestamp", "watch" })]
[FontAwesomeCategoriesAttribute(new[] { "Time" })]
Clock = 0xF017,
///
/// The Font Awesome "clone" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "clone", "arrange", "copy", "duplicate", "paste" })]
+ [FontAwesomeSearchTerms(new[] { "clone", "add", "arrange", "copy", "duplicate", "new", "paste" })]
[FontAwesomeCategoriesAttribute(new[] { "Design", "Files", "Photos + Images" })]
Clone = 0xF24D,
@@ -2112,7 +2133,7 @@ public enum FontAwesomeIcon
/// The Font Awesome "cloud-arrow-up" icon unicode character.
/// Uses a legacy unicode value for backwards compatability. The current unicode value is 0xF0EE.
///
- [FontAwesomeSearchTerms(new[] { "cloud arrow up", "import", "save", "upload" })]
+ [FontAwesomeSearchTerms(new[] { "cloud arrow up", "import", "save", "upgrade", "upload" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows", "Connectivity" })]
CloudUploadAlt = 0xF382,
@@ -2133,14 +2154,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "code" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "brackets", "code", "development", "html" })]
+ [FontAwesomeSearchTerms(new[] { "brackets", "code", "development", "html", "mysql", "sql" })]
[FontAwesomeCategoriesAttribute(new[] { "Coding" })]
Code = 0xF121,
///
/// The Font Awesome "code-branch" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "code branch", "branch", "git", "github", "rebase", "svn", "vcs", "version" })]
+ [FontAwesomeSearchTerms(new[] { "code branch", "branch", "git", "github", "mysql", "rebase", "sql", "svn", "vcs", "version" })]
[FontAwesomeCategoriesAttribute(new[] { "Coding" })]
CodeBranch = 0xF126,
@@ -2189,21 +2210,21 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "gear" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "cog", "cogwheel", "gear", "mechanical", "settings", "sprocket", "tool", "wheel" })]
+ [FontAwesomeSearchTerms(new[] { "cog", "cogwheel", "configuration", "gear", "mechanical", "modify", "settings", "sprocket", "tool", "wheel" })]
[FontAwesomeCategoriesAttribute(new[] { "Coding", "Editing", "Spinners" })]
Cog = 0xF013,
///
/// The Font Awesome "gears" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "gears", "mechanical", "settings", "sprocket", "wheel" })]
+ [FontAwesomeSearchTerms(new[] { "configuration", "gears", "mechanical", "modify", "settings", "sprocket", "wheel" })]
[FontAwesomeCategoriesAttribute(new[] { "Coding", "Logistics" })]
Cogs = 0xF085,
///
/// The Font Awesome "coins" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "coins", "currency", "dime", "financial", "gold", "money", "penny" })]
+ [FontAwesomeSearchTerms(new[] { "coins", "currency", "dime", "financial", "gold", "money", "penny", "premium" })]
[FontAwesomeCategoriesAttribute(new[] { "Money" })]
Coins = 0xF51E,
@@ -2217,63 +2238,70 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "table-columns" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "table columns", "browser", "dashboard", "organize", "panes", "split" })]
+ [FontAwesomeSearchTerms(new[] { "table columns", "browser", "category", "dashboard", "organize", "panes", "split" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Text Formatting" })]
Columns = 0xF0DB,
///
/// The Font Awesome "comment" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "comment", "right speech bubble", "bubble", "chat", "commenting", "conversation", "feedback", "message", "note", "notification", "sms", "speech", "texting" })]
+ [FontAwesomeSearchTerms(new[] { "comment", "right speech bubble", "answer", "bubble", "chat", "commenting", "conversation", "conversation", "discussion", "feedback", "message", "note", "notification", "sms", "speech", "talk", "talking", "texting" })]
[FontAwesomeCategoriesAttribute(new[] { "Communication", "Shapes", "Social" })]
Comment = 0xF075,
///
/// The Font Awesome "message" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "bubble", "chat", "commenting", "conversation", "feedback", "message", "note", "notification", "sms", "speech", "texting" })]
+ [FontAwesomeSearchTerms(new[] { "answer", "bubble", "chat", "commenting", "conversation", "conversation", "discussion", "feedback", "message", "note", "notification", "sms", "speech", "talk", "talking", "texting" })]
[FontAwesomeCategoriesAttribute(new[] { "Communication", "Social" })]
CommentAlt = 0xF27A,
///
/// The Font Awesome "comment-dollar" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "comment dollar", "bubble", "chat", "commenting", "conversation", "feedback", "message", "money", "note", "notification", "pay", "sms", "speech", "spend", "texting", "transfer" })]
+ [FontAwesomeSearchTerms(new[] { "comment dollar", "answer", "bubble", "chat", "commenting", "conversation", "feedback", "message", "money", "note", "notification", "pay", "salary", "sms", "speech", "spend", "texting", "transfer" })]
[FontAwesomeCategoriesAttribute(new[] { "Marketing", "Money" })]
CommentDollar = 0xF651,
///
/// The Font Awesome "comment-dots" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "comment dots", "balloon", "bubble", "chat", "comic", "commenting", "conversation", "dialog", "feedback", "message", "more", "note", "notification", "reply", "sms", "speech", "speech balloon", "texting" })]
+ [FontAwesomeSearchTerms(new[] { "comment dots", "answer", "balloon", "bubble", "chat", "comic", "commenting", "conversation", "dialog", "feedback", "message", "more", "note", "notification", "reply", "request", "sms", "speech", "speech balloon", "texting" })]
[FontAwesomeCategoriesAttribute(new[] { "Communication" })]
CommentDots = 0xF4AD,
///
/// The Font Awesome "comment-medical" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "comment medical", "advice", "bubble", "chat", "commenting", "conversation", "diagnose", "feedback", "message", "note", "notification", "prescription", "sms", "speech", "texting" })]
+ [FontAwesomeSearchTerms(new[] { "comment medical", "advice", "answer", "bubble", "chat", "commenting", "conversation", "diagnose", "feedback", "message", "note", "notification", "prescription", "sms", "speech", "texting" })]
[FontAwesomeCategoriesAttribute(new[] { "Communication", "Medical + Health" })]
CommentMedical = 0xF7F5,
+ ///
+ /// The Font Awesome "comment-nodes" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "comment nodes", "ai", "artificial intelligence", "cluster", "language", "model", "network", "neuronal" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Coding", "Communication" })]
+ CommentNodes = 0xE696,
+
///
/// The Font Awesome "comments" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "comments", "two speech bubbles", "bubble", "chat", "commenting", "conversation", "feedback", "message", "note", "notification", "sms", "speech", "texting" })]
+ [FontAwesomeSearchTerms(new[] { "comments", "two speech bubbles", "answer", "bubble", "chat", "commenting", "conversation", "conversation", "discussion", "feedback", "message", "note", "notification", "sms", "speech", "talk", "talking", "texting" })]
[FontAwesomeCategoriesAttribute(new[] { "Communication" })]
Comments = 0xF086,
///
/// The Font Awesome "comments-dollar" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "comments dollar", "bubble", "chat", "commenting", "conversation", "feedback", "message", "money", "note", "notification", "pay", "sms", "speech", "spend", "texting", "transfer" })]
+ [FontAwesomeSearchTerms(new[] { "comments dollar", "answer", "bubble", "chat", "commenting", "conversation", "feedback", "message", "money", "note", "notification", "pay", "salary", "sms", "speech", "spend", "texting", "transfer" })]
[FontAwesomeCategoriesAttribute(new[] { "Marketing", "Money" })]
CommentsDollar = 0xF653,
///
/// The Font Awesome "comment-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "comment slash", "bubble", "cancel", "chat", "commenting", "conversation", "feedback", "message", "mute", "note", "notification", "quiet", "sms", "speech", "texting" })]
+ [FontAwesomeSearchTerms(new[] { "comment slash", "answer", "bubble", "cancel", "chat", "commenting", "conversation", "disabled", "feedback", "message", "mute", "note", "notification", "quiet", "sms", "speech", "texting" })]
[FontAwesomeCategoriesAttribute(new[] { "Communication" })]
CommentSlash = 0xF4B3,
@@ -2301,7 +2329,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "down-left-and-up-right-to-center" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "down left and up right to center", "collapse", "fullscreen", "minimize", "move", "resize", "shrink", "smaller" })]
+ [FontAwesomeSearchTerms(new[] { "down left and up right to center", "collapse", "fullscreen", "minimize", "move", "resize", "scale", "shrink", "size", "smaller" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows", "Media Playback" })]
CompressAlt = 0xF422,
@@ -2322,7 +2350,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "bell-concierge" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "bell concierge", "attention", "bell", "bellhop", "bellhop bell", "hotel", "receptionist", "service", "support" })]
+ [FontAwesomeSearchTerms(new[] { "bell concierge", "attention", "bell", "bellhop", "bellhop bell", "hotel", "receptionist", "request", "service", "support" })]
[FontAwesomeCategoriesAttribute(new[] { "Travel + Hotel" })]
ConciergeBell = 0xF562,
@@ -2378,14 +2406,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "crop" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "crop", "design", "frame", "mask", "resize", "shrink" })]
+ [FontAwesomeSearchTerms(new[] { "crop", "design", "frame", "mask", "modify", "resize", "shrink" })]
[FontAwesomeCategoriesAttribute(new[] { "Design", "Editing" })]
Crop = 0xF125,
///
/// The Font Awesome "crop-simple" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "crop simple", "design", "frame", "mask", "resize", "shrink" })]
+ [FontAwesomeSearchTerms(new[] { "crop simple", "design", "frame", "mask", "modify", "resize", "shrink" })]
[FontAwesomeCategoriesAttribute(new[] { "Design", "Editing" })]
CropAlt = 0xF565,
@@ -2413,7 +2441,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "crown" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "award", "clothing", "crown", "favorite", "king", "queen", "royal", "tiara" })]
+ [FontAwesomeSearchTerms(new[] { "award", "clothing", "crown", "favorite", "king", "queen", "royal", "tiara", "vip" })]
[FontAwesomeCategoriesAttribute(new[] { "Shapes" })]
Crown = 0xF521,
@@ -2455,14 +2483,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "scissors" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "black safety scissors", "white scissors", "clip", "cutting", "scissors", "snip", "tool" })]
+ [FontAwesomeSearchTerms(new[] { "black safety scissors", "white scissors", "clip", "cutting", "equipment", "modify", "scissors", "snip", "tool" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Design", "Editing", "Files" })]
Cut = 0xF0C4,
///
/// The Font Awesome "database" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "database", "computer", "development", "directory", "memory", "storage" })]
+ [FontAwesomeSearchTerms(new[] { "database", "computer", "development", "directory", "memory", "mysql", "sql", "storage" })]
[FontAwesomeCategoriesAttribute(new[] { "Devices + Hardware" })]
Database = 0xF1C0,
@@ -2470,7 +2498,7 @@ public enum FontAwesomeIcon
/// The Font Awesome "ear-deaf" icon unicode character.
///
[FontAwesomeSearchTerms(new[] { "ear deaf", "ear", "hearing", "sign language" })]
- [FontAwesomeCategoriesAttribute(new[] { "Accessibility" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Accessibility", "Communication" })]
Deaf = 0xF2A4,
///
@@ -2498,7 +2526,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "person-dots-from-line" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person dots from line", "allergy", "diagnosis" })]
+ [FontAwesomeSearchTerms(new[] { "person dots from line", "allergy", "diagnosis", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Medical + Health", "Users + People" })]
Diagnoses = 0xF470,
@@ -2526,7 +2554,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "diamond" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "diamond", "card", "cards", "diamond suit", "game", "gem", "gemstone", "poker", "suit" })]
+ [FontAwesomeSearchTerms(new[] { "diamond", "ace", "card", "cards", "diamond suit", "game", "gem", "gemstone", "poker", "suit" })]
[FontAwesomeCategoriesAttribute(new[] { "Gaming", "Shapes" })]
Diamond = 0xF219,
@@ -2653,7 +2681,7 @@ public enum FontAwesomeIcon
/// The Font Awesome "dollar-sign" icon unicode character.
/// Uses a legacy unicode value for backwards compatability. The current unicode value is 0x24.
///
- [FontAwesomeSearchTerms(new[] { "dollar sign", "dollar sign", "currency", "dollar", "heavy dollar sign", "money" })]
+ [FontAwesomeSearchTerms(new[] { "dollar sign", "dollar sign", "coupon", "currency", "dollar", "heavy dollar sign", "investment", "money", "premium", "revenue", "salary" })]
[FontAwesomeCategoriesAttribute(new[] { "Charity", "Maps", "Money" })]
DollarSign = 0xF155,
@@ -2674,7 +2702,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "circle-dollar-to-slot" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "circle dollar to slot", "contribute", "generosity", "gift", "give" })]
+ [FontAwesomeSearchTerms(new[] { "circle dollar to slot", "contribute", "generosity", "gift", "give", "premium" })]
[FontAwesomeCategoriesAttribute(new[] { "Charity", "Money", "Political" })]
Donate = 0xF4B9,
@@ -2688,7 +2716,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "door-closed" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "door closed", "doo", "door", "enter", "exit", "locked" })]
+ [FontAwesomeSearchTerms(new[] { "door closed", "doo", "door", "enter", "exit", "locked", "privacy" })]
[FontAwesomeCategoriesAttribute(new[] { "Household", "Security", "Travel + Hotel" })]
DoorClosed = 0xF52A,
@@ -2716,7 +2744,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "download" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "download", "export", "hard drive", "save", "transfer" })]
+ [FontAwesomeSearchTerms(new[] { "download", "export", "hard drive", "insert", "save", "transfer" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows", "Devices + Hardware" })]
Download = 0xF019,
@@ -2765,7 +2793,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "dumbbell" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "dumbbell", "exercise", "gym", "strength", "weight", "weight-lifting" })]
+ [FontAwesomeSearchTerms(new[] { "dumbbell", "exercise", "gym", "strength", "weight", "weight-lifting", "workout" })]
[FontAwesomeCategoriesAttribute(new[] { "Sports + Fitness", "Travel + Hotel" })]
Dumbbell = 0xF44B,
@@ -2800,7 +2828,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "pen-to-square" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "pen to square", "edit", "pen", "pencil", "update", "write" })]
+ [FontAwesomeSearchTerms(new[] { "pen to square", "edit", "modify", "pen", "pencil", "update", "write" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Design", "Editing", "Writing" })]
Edit = 0xF044,
@@ -2821,56 +2849,56 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "elevator" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "accessibility", "elevator", "hoist", "lift", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "accessibility", "elevator", "hoist", "lift", "uer", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Travel + Hotel", "Users + People" })]
Elevator = 0xE16D,
///
/// The Font Awesome "ellipsis" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "ellipsis", "dots", "drag", "kebab", "list", "menu", "nav", "navigation", "ol", "pacman", "reorder", "settings", "ul" })]
+ [FontAwesomeSearchTerms(new[] { "ellipsis", "dots", "drag", "kebab", "list", "menu", "nav", "navigation", "ol", "pacman", "reorder", "settings", "three dots", "ul" })]
[FontAwesomeCategoriesAttribute(new[] { "Editing" })]
EllipsisH = 0xF141,
///
/// The Font Awesome "ellipsis-vertical" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "ellipsis vertical", "dots", "drag", "kebab", "list", "menu", "nav", "navigation", "ol", "reorder", "settings", "ul" })]
+ [FontAwesomeSearchTerms(new[] { "ellipsis vertical", "bullet", "dots", "drag", "kebab", "list", "menu", "nav", "navigation", "ol", "reorder", "settings", "three dots", "ul" })]
[FontAwesomeCategoriesAttribute(new[] { "Editing" })]
EllipsisV = 0xF142,
///
/// The Font Awesome "envelope" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "back of envelope", "e-mail", "email", "envelope", "letter", "mail", "message", "notification", "support" })]
+ [FontAwesomeSearchTerms(new[] { "back of envelope", "e-mail", "email", "envelope", "letter", "mail", "message", "newsletter", "notification", "offer", "support" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Communication", "Humanitarian", "Social", "Writing" })]
Envelope = 0xF0E0,
///
/// The Font Awesome "envelope-circle-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "envelope circle check", "check", "email", "envelope", "mail", "not affected", "ok", "okay", "read", "sent" })]
+ [FontAwesomeSearchTerms(new[] { "envelope circle check", "check", "email", "enable", "envelope", "mail", "not affected", "ok", "okay", "read", "sent", "validate", "working" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Communication", "Humanitarian" })]
EnvelopeCircleCheck = 0xE4E8,
///
/// The Font Awesome "envelope-open" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "envelope open", "e-mail", "email", "letter", "mail", "message", "notification", "support" })]
+ [FontAwesomeSearchTerms(new[] { "envelope open", "e-mail", "email", "letter", "mail", "message", "newsletter", "notification", "offer", "support" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Communication", "Writing" })]
EnvelopeOpen = 0xF2B6,
///
/// The Font Awesome "envelope-open-text" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "envelope open text", "e-mail", "email", "letter", "mail", "message", "notification", "support" })]
+ [FontAwesomeSearchTerms(new[] { "envelope open text", "e-mail", "email", "letter", "mail", "message", "newsletter", "notification", "offer", "support" })]
[FontAwesomeCategoriesAttribute(new[] { "Marketing" })]
EnvelopeOpenText = 0xF658,
///
/// The Font Awesome "square-envelope" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "square envelope", "e-mail", "email", "letter", "mail", "message", "notification", "support" })]
+ [FontAwesomeSearchTerms(new[] { "square envelope", "e-mail", "email", "letter", "mail", "message", "notification", "offer", "support" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Communication" })]
EnvelopeSquare = 0xF199,
@@ -2914,42 +2942,42 @@ public enum FontAwesomeIcon
/// The Font Awesome "exclamation" icon unicode character.
/// Uses a legacy unicode value for backwards compatability. The current unicode value is 0x21.
///
- [FontAwesomeSearchTerms(new[] { "!", "exclamation mark", "alert", "danger", "error", "exclamation", "important", "mark", "notice", "notification", "notify", "outlined", "problem", "punctuation", "red exclamation mark", "warning", "white exclamation mark" })]
+ [FontAwesomeSearchTerms(new[] { "!", "exclamation mark", "alert", "attention", "danger", "error", "exclamation", "failed", "important", "mark", "notice", "notification", "notify", "outlined", "problem", "punctuation", "red exclamation mark", "required", "warning", "white exclamation mark" })]
[FontAwesomeCategoriesAttribute(new[] { "Alert", "Punctuation + Symbols" })]
Exclamation = 0xF12A,
///
/// The Font Awesome "circle-exclamation" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "circle exclamation", "affect", "alert", "damage", "danger", "error", "important", "notice", "notification", "notify", "problem", "warning" })]
+ [FontAwesomeSearchTerms(new[] { "circle exclamation", "affect", "alert", "attention", "damage", "danger", "error", "failed", "important", "notice", "notification", "notify", "problem", "required", "warning" })]
[FontAwesomeCategoriesAttribute(new[] { "Alert", "Punctuation + Symbols" })]
ExclamationCircle = 0xF06A,
///
/// The Font Awesome "triangle-exclamation" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "triangle exclamation", "alert", "danger", "error", "important", "notice", "notification", "notify", "problem", "warnin", "warning" })]
+ [FontAwesomeSearchTerms(new[] { "triangle exclamation", "alert", "attention", "danger", "error", "failed", "important", "notice", "notification", "notify", "problem", "required", "warnin", "warning" })]
[FontAwesomeCategoriesAttribute(new[] { "Alert" })]
ExclamationTriangle = 0xF071,
///
/// The Font Awesome "expand" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "expand", "bigger", "crop", "enlarge", "focus", "fullscreen", "resize", "viewfinder" })]
+ [FontAwesomeSearchTerms(new[] { "arrows", "bigger", "enlarge", "expand", "fullscreen", "maximize", "resize", "resize", "scale", "size", "viewfinder" })]
[FontAwesomeCategoriesAttribute(new[] { "Media Playback" })]
Expand = 0xF065,
///
/// The Font Awesome "up-right-and-down-left-from-center" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "up right and down left from center", "arrows", "bigger", "enlarge", "fullscreen", "resize" })]
+ [FontAwesomeSearchTerms(new[] { "up right and down left from center", "arrows", "bigger", "enlarge", "expand", "fullscreen", "maximize", "resize", "resize", "scale", "size" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows", "Media Playback" })]
ExpandAlt = 0xF424,
///
/// The Font Awesome "maximize" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "maximize", "bigger", "enlarge", "fullscreen", "move", "resize" })]
+ [FontAwesomeSearchTerms(new[] { "arrows", "bigger", "enlarge", "expand", "fullscreen", "maximize", "resize", "resize", "scale", "size" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows", "Media Playback" })]
ExpandArrowsAlt = 0xF31E,
@@ -2963,7 +2991,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "up-right-from-square" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "up right from square", "external-link", "new", "open", "share" })]
+ [FontAwesomeSearchTerms(new[] { "up right from square", "external-link", "new", "open", "share", "upgrade" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
ExternalLinkAlt = 0xF35D,
@@ -2991,7 +3019,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "eye-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "eye slash", "blind", "hide", "show", "toggle", "unseen", "views", "visible", "visiblity" })]
+ [FontAwesomeSearchTerms(new[] { "eye slash", "blind", "disabled", "hide", "show", "toggle", "unseen", "views", "visible", "visiblity" })]
[FontAwesomeCategoriesAttribute(new[] { "Design", "Editing", "Maps", "Photos + Images", "Security" })]
EyeSlash = 0xF070,
@@ -3005,14 +3033,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "backward-fast" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "backward fast", "arrow", "beginning", "first", "last track button", "previous", "previous scene", "previous track", "rewind", "start", "triangle" })]
+ [FontAwesomeSearchTerms(new[] { "backward fast", "arrow", "beginning", "first", "last track button", "previous", "previous scene", "previous track", "quick", "rewind", "start", "triangle" })]
[FontAwesomeCategoriesAttribute(new[] { "Media Playback" })]
FastBackward = 0xF049,
///
/// The Font Awesome "forward-fast" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "forward fast", "arrow", "end", "last", "next", "next scene", "next track", "next track button", "triangle" })]
+ [FontAwesomeSearchTerms(new[] { "forward fast", "arrow", "end", "last", "next", "next scene", "next track", "next track button", "quick", "triangle" })]
[FontAwesomeCategoriesAttribute(new[] { "Media Playback" })]
FastForward = 0xF050,
@@ -3054,7 +3082,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "person-dress" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person dress", "man", "skirt", "woman" })]
+ [FontAwesomeSearchTerms(new[] { "person dress", "man", "skirt", "uer", "woman" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
Female = 0xF182,
@@ -3075,7 +3103,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "file" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "file", "empty document", "document", "new", "page", "page facing up", "pdf", "resume" })]
+ [FontAwesomeSearchTerms(new[] { "file", "empty document", "cv", "document", "new", "page", "page facing up", "pdf", "resume" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Coding", "Files", "Humanitarian", "Shapes", "Writing" })]
File = 0xF15B,
@@ -3103,14 +3131,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "file-circle-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "file circle check", "document", "file", "not affected", "ok", "okay", "paper" })]
+ [FontAwesomeSearchTerms(new[] { "file circle check", "document", "enable", "file", "not affected", "ok", "okay", "paper", "validate", "working" })]
[FontAwesomeCategoriesAttribute(new[] { "Files", "Humanitarian" })]
FileCircleCheck = 0xE5A0,
///
/// The Font Awesome "file-circle-exclamation" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "file circle exclamation", "document", "file", "paper" })]
+ [FontAwesomeSearchTerms(new[] { "file circle exclamation", "document", "failed", "file", "paper" })]
[FontAwesomeCategoriesAttribute(new[] { "Files", "Humanitarian" })]
FileCircleExclamation = 0xE4EB,
@@ -3138,21 +3166,21 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "file-circle-xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "file circle xmark", "document", "file", "paper" })]
+ [FontAwesomeSearchTerms(new[] { "file circle xmark", "document", "file", "paper", "uncheck" })]
[FontAwesomeCategoriesAttribute(new[] { "Files", "Humanitarian" })]
FileCircleXmark = 0xE5A1,
///
/// The Font Awesome "file-code" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "file code", "css", "development", "document", "html" })]
+ [FontAwesomeSearchTerms(new[] { "file code", "css", "development", "document", "html", "mysql", "sql" })]
[FontAwesomeCategoriesAttribute(new[] { "Coding", "Files" })]
FileCode = 0xF1C9,
///
/// The Font Awesome "file-contract" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "file contract", "agreement", "binding", "document", "legal", "signature" })]
+ [FontAwesomeSearchTerms(new[] { "file contract", "agreement", "binding", "document", "legal", "signature", "username" })]
[FontAwesomeCategoriesAttribute(new[] { "Security" })]
FileContract = 0xF56C,
@@ -3166,7 +3194,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "file-arrow-down" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "file arrow down", "document", "export", "save" })]
+ [FontAwesomeSearchTerms(new[] { "file arrow down", "archive", "document", "export", "insert", "save" })]
[FontAwesomeCategoriesAttribute(new[] { "Files" })]
FileDownload = 0xF56D,
@@ -3184,17 +3212,31 @@ public enum FontAwesomeIcon
[FontAwesomeCategoriesAttribute(new[] { "Files" })]
FileExport = 0xF56E,
+ ///
+ /// The Font Awesome "file-fragment" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "file fragment", "block", "data", "partial", "piece" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Files" })]
+ FileFragment = 0xE697,
+
+ ///
+ /// The Font Awesome "file-half-dashed" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "file half dashed", "data", "fragment", "partial", "piece" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Files" })]
+ FileHalfDashed = 0xE698,
+
///
/// The Font Awesome "file-image" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "file image", "document with picture", "document", "image", "jpg", "photo", "png" })]
+ [FontAwesomeSearchTerms(new[] { "file image", "document with picture", "document", "image", "img", "jpg", "photo", "png" })]
[FontAwesomeCategoriesAttribute(new[] { "Files", "Photos + Images" })]
FileImage = 0xF1C5,
///
/// The Font Awesome "file-import" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "file import", "copy", "document", "send", "upload" })]
+ [FontAwesomeSearchTerms(new[] { "file import", "copy", "document", "insert", "send", "upload" })]
[FontAwesomeCategoriesAttribute(new[] { "Files" })]
FileImport = 0xF56F,
@@ -3208,7 +3250,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "file-invoice-dollar" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "file invoice dollar", "$", "account", "bill", "charge", "document", "dollar-sign", "money", "payment", "receipt", "usd" })]
+ [FontAwesomeSearchTerms(new[] { "file invoice dollar", "$", "account", "bill", "charge", "document", "dollar-sign", "money", "payment", "receipt", "revenue", "salary", "usd" })]
[FontAwesomeCategoriesAttribute(new[] { "Money" })]
FileInvoiceDollar = 0xF571,
@@ -3236,7 +3278,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "file-pen" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "file pen", "edit", "memo", "pen", "pencil", "update", "write" })]
+ [FontAwesomeSearchTerms(new[] { "file pen", "edit", "memo", "modify", "pen", "pencil", "update", "write" })]
[FontAwesomeCategoriesAttribute(new[] { "Files", "Humanitarian" })]
FilePen = 0xF31C,
@@ -3264,14 +3306,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "file-signature" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "file signature", "john hancock", "contract", "document", "name" })]
+ [FontAwesomeSearchTerms(new[] { "file signature", "john hancock", "contract", "document", "name", "username" })]
[FontAwesomeCategoriesAttribute(new[] { "Security" })]
FileSignature = 0xF573,
///
/// The Font Awesome "file-arrow-up" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "file arrow up", "document", "import", "page", "save" })]
+ [FontAwesomeSearchTerms(new[] { "file arrow up", "document", "import", "page", "save", "upgrade" })]
[FontAwesomeCategoriesAttribute(new[] { "Files" })]
FileUpload = 0xF574,
@@ -3320,14 +3362,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "filter-circle-xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "filter circle xmark", "cancel", "funnel", "options", "remove", "separate", "sort" })]
+ [FontAwesomeSearchTerms(new[] { "filter circle xmark", "cancel", "funnel", "options", "remove", "separate", "sort", "uncheck" })]
[FontAwesomeCategoriesAttribute(new[] { "Text Formatting" })]
FilterCircleXmark = 0xE17B,
///
/// The Font Awesome "fingerprint" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "fingerprint", "human", "id", "identification", "lock", "smudge", "touch", "unique", "unlock" })]
+ [FontAwesomeSearchTerms(new[] { "fingerprint", "human", "id", "identification", "lock", "privacy", "smudge", "touch", "unique", "unlock" })]
[FontAwesomeCategoriesAttribute(new[] { "Accessibility", "Security" })]
Fingerprint = 0xF577,
@@ -3411,14 +3453,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "flask" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "flask", "beaker", "chemicals", "experiment", "experimental", "labs", "liquid", "potion", "science", "vial" })]
+ [FontAwesomeSearchTerms(new[] { "flask", "beaker", "chemicals", "experiment", "experimental", "knowledge", "labs", "liquid", "potion", "science", "vial" })]
[FontAwesomeCategoriesAttribute(new[] { "Food + Beverage", "Maps", "Medical + Health", "Science" })]
Flask = 0xF0C3,
///
/// The Font Awesome "flask-vial" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "flask vial", " beaker", " chemicals", " experiment", " experimental", " labs", " liquid", " science", " vial", "ampule", "chemistry", "lab", "laboratory", "potion", "test", "test tube" })]
+ [FontAwesomeSearchTerms(new[] { "flask vial", "ampule", "beaker", "chemicals", "chemistry", "experiment", "experimental", "lab", "laboratory", "labs", "liquid", "potion", "science", "test", "test tube", "vial" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Medical + Health", "Science" })]
FlaskVial = 0xE4F3,
@@ -3539,7 +3581,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "face-frown" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "face frown", "disapprove", "emoticon", "face", "frown", "frowning face", "rating", "sad" })]
+ [FontAwesomeSearchTerms(new[] { "face frown", "disapprove", "emoticon", "face", "frown", "frowning face", "rating", "sad", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Communication", "Emoji", "Users + People" })]
Frown = 0xF119,
@@ -3553,7 +3595,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "filter-circle-dollar" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "filter circle dollar", "filter", "money", "options", "separate", "sort" })]
+ [FontAwesomeSearchTerms(new[] { "filter circle dollar", "filter", "money", "options", "premium", "separate", "sort" })]
[FontAwesomeCategoriesAttribute(new[] { "Marketing" })]
FunnelDollar = 0xF662,
@@ -3567,7 +3609,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "gamepad" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "gamepad", "arcade", "controller", "d-pad", "joystick", "video", "video game" })]
+ [FontAwesomeSearchTerms(new[] { "gamepad", "arcade", "controller", "d-pad", "joystick", "playstore", "video", "video game" })]
[FontAwesomeCategoriesAttribute(new[] { "Childhood", "Devices + Hardware", "Gaming", "Maps" })]
Gamepad = 0xF11B,
@@ -3595,7 +3637,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "gauge-simple-high" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "gauge simple high", "dashboard", "fast", "odometer", "speed", "speedometer" })]
+ [FontAwesomeSearchTerms(new[] { "gauge simple high", "dashboard", "fast", "odometer", "quick", "speed", "speedometer" })]
[FontAwesomeCategoriesAttribute(new[] { "Automotive" })]
GaugeSimpleHigh = 0xF62A,
@@ -3693,7 +3735,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "globe" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "all", "coordinates", "country", "earth", "global", "globe", "globe with meridians", "gps", "internet", "language", "localize", "location", "map", "meridians", "network", "online", "place", "planet", "translate", "travel", "world" })]
+ [FontAwesomeSearchTerms(new[] { "all", "coordinates", "country", "earth", "global", "globe", "globe with meridians", "gps", "internet", "language", "localize", "location", "map", "meridians", "network", "online", "place", "planet", "translate", "travel", "world", "www" })]
[FontAwesomeCategoriesAttribute(new[] { "Astronomy", "Business", "Charity", "Connectivity", "Maps" })]
Globe = 0xF0AC,
@@ -3820,7 +3862,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "face-grin-stars" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "face grin stars", "emoticon", "eyes", "face", "grinning", "star", "star-struck", "starry-eyed" })]
+ [FontAwesomeSearchTerms(new[] { "face grin stars", "emoticon", "eyes", "face", "grinning", "quality", "star", "star-struck", "starry-eyed", "vip" })]
[FontAwesomeCategoriesAttribute(new[] { "Emoji" })]
GrinStars = 0xF587,
@@ -3862,7 +3904,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "grip" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "grip", "affordance", "drag", "drop", "grab", "handle" })]
+ [FontAwesomeSearchTerms(new[] { "grip", "affordance", "app", "collection", "dashboard", "drag", "drop", "grab", "grid", "handle", "launcher", "square" })]
[FontAwesomeCategoriesAttribute(new[] { "Editing" })]
GripHorizontal = 0xF58D,
@@ -3925,7 +3967,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "hammer" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "admin", "fix", "hammer", "recovery", "repair", "settings", "tool" })]
+ [FontAwesomeSearchTerms(new[] { "admin", "configuration", "equipment", "fix", "hammer", "maintenance", "modify", "recovery", "repair", "settings", "tool" })]
[FontAwesomeCategoriesAttribute(new[] { "Construction", "Humanitarian" })]
Hammer = 0xF6E3,
@@ -3953,8 +3995,8 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "hand-holding-droplet" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "hand holding droplet", "carry", "covid-19", "drought", "grow", "lift", "sanitation" })]
- [FontAwesomeCategoriesAttribute(new[] { "Charity", "Hands" })]
+ [FontAwesomeSearchTerms(new[] { "hand holding droplet", "blood", "carry", "covid-19", "drought", "grow", "lift", "sanitation" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Charity", "Hands", "Medical + Health" })]
HandHoldingDroplet = 0xF4C1,
///
@@ -3967,7 +4009,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "hand-holding-heart" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "hand holding heart", "carry", "charity", "gift", "lift", "package" })]
+ [FontAwesomeSearchTerms(new[] { "hand holding heart", "carry", "charity", "gift", "lift", "package", "wishlist" })]
[FontAwesomeCategoriesAttribute(new[] { "Charity", "Hands" })]
HandHoldingHeart = 0xF4BE,
@@ -3981,7 +4023,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "hand-holding-dollar" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "hand holding dollar", "$", "carry", "dollar sign", "donation", "giving", "lift", "money", "price" })]
+ [FontAwesomeSearchTerms(new[] { "hand holding dollar", "$", "carry", "coupon", "dollar sign", "donate", "donation", "giving", "investment", "lift", "money", "premium", "price", "revenue", "salary" })]
[FontAwesomeCategoriesAttribute(new[] { "Charity", "Hands", "Money" })]
HandHoldingUsd = 0xF4C0,
@@ -4002,7 +4044,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "hand" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "hand", "raised hand", "backhand", "game", "halt", "palm", "raised", "raised back of hand", "roshambo", "stop" })]
+ [FontAwesomeSearchTerms(new[] { "hand", "raised hand", "backhand", "game", "halt", "palm", "raised", "raised back of hand", "request", "roshambo", "stop" })]
[FontAwesomeCategoriesAttribute(new[] { "Hands", "Media Playback" })]
HandPaper = 0xF256,
@@ -4044,7 +4086,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "hand-point-up" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "hand point up", "finger", "hand", "hand-o-up", "index", "index pointing up", "point", "up" })]
+ [FontAwesomeSearchTerms(new[] { "hand point up", "finger", "hand", "hand-o-up", "index", "index pointing up", "point", "request", "up", "upgrade" })]
[FontAwesomeCategoriesAttribute(new[] { "Hands" })]
HandPointUp = 0xF0A6,
@@ -4094,27 +4136,29 @@ public enum FontAwesomeIcon
/// The Font Awesome "handshake" icon unicode character.
///
[FontAwesomeSearchTerms(new[] { "handshake", "agreement", "greeting", "meeting", "partnership" })]
- [FontAwesomeCategoriesAttribute(new[] { "Charity", "Hands", "Political", "Shopping" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Charity", "Hands", "Humanitarian", "Political", "Shopping" })]
Handshake = 0xF2B5,
///
- /// The Font Awesome "handshake-simple" icon unicode character.
+ /// The Font Awesome "handshake" icon unicode character.
+ /// Uses a legacy unicode value for backwards compatability. The current unicode value is 0xF2B5.
///
- [FontAwesomeSearchTerms(new[] { "handshake simple", "agreement", "greeting", "hand", "handshake", "meeting", "partnership", "shake" })]
- [FontAwesomeCategoriesAttribute(new[] { "Charity", "Hands", "Humanitarian" })]
+ [FontAwesomeSearchTerms(new[] { "handshake", "agreement", "greeting", "meeting", "partnership" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Charity", "Hands", "Humanitarian", "Political", "Shopping" })]
HandshakeSimple = 0xF4C6,
///
- /// The Font Awesome "handshake-simple-slash" icon unicode character.
+ /// The Font Awesome "handshake-slash" icon unicode character.
+ /// Uses a legacy unicode value for backwards compatability. The current unicode value is 0xE060.
///
- [FontAwesomeSearchTerms(new[] { "handshake simple slash", "broken", "covid-19", "social distance" })]
+ [FontAwesomeSearchTerms(new[] { "handshake slash", "broken", "covid-19", "disabled", "social distance" })]
[FontAwesomeCategoriesAttribute(new[] { "Hands" })]
HandshakeSimpleSlash = 0xE05F,
///
/// The Font Awesome "handshake-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "handshake slash", "broken", "covid-19", "social distance" })]
+ [FontAwesomeSearchTerms(new[] { "handshake slash", "broken", "covid-19", "disabled", "social distance" })]
[FontAwesomeCategoriesAttribute(new[] { "Hands" })]
HandshakeSlash = 0xE060,
@@ -4128,7 +4172,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "hands-holding-child" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "hands holding child", "care", "give", "help", "hold", "protect" })]
+ [FontAwesomeSearchTerms(new[] { "hands holding child", "care", "give", "help", "hold", "parent", "protect" })]
[FontAwesomeCategoriesAttribute(new[] { "Charity", "Childhood", "Hands", "Humanitarian", "Security" })]
HandsHoldingChild = 0xE4FA,
@@ -4163,7 +4207,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "helmet-safety" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "helmet safety", "construction", "hardhat", "helmet", "safety" })]
+ [FontAwesomeSearchTerms(new[] { "helmet safety", "construction", "hardhat", "helmet", "maintenance", "safety" })]
[FontAwesomeCategoriesAttribute(new[] { "Construction", "Logistics" })]
HardHat = 0xF807,
@@ -4218,10 +4262,11 @@ public enum FontAwesomeIcon
Headphones = 0xF025,
///
- /// The Font Awesome "headphones-simple" icon unicode character.
+ /// The Font Awesome "headphones" icon unicode character.
+ /// Uses a legacy unicode value for backwards compatability. The current unicode value is 0xF025.
///
- [FontAwesomeSearchTerms(new[] { "headphones simple", "audio", "listen", "music", "sound", "speaker" })]
- [FontAwesomeCategoriesAttribute(new[] { "Music + Audio" })]
+ [FontAwesomeSearchTerms(new[] { "headphones", "audio", "earbud", "headphone", "listen", "music", "sound", "speaker" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Devices + Hardware", "Film + Video", "Music + Audio" })]
HeadphonesAlt = 0xF58F,
///
@@ -4234,35 +4279,35 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "head-side-cough" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "head side cough", "cough", "covid-19", "germs", "lungs", "respiratory", "sick" })]
+ [FontAwesomeSearchTerms(new[] { "head side cough", "cough", "covid-19", "germs", "lungs", "respiratory", "sick", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Medical + Health", "Users + People" })]
HeadSideCough = 0xE061,
///
/// The Font Awesome "head-side-cough-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "head side cough slash", "cough", "covid-19", "germs", "lungs", "respiratory", "sick" })]
+ [FontAwesomeSearchTerms(new[] { "head side cough slash", "cough", "covid-19", "disabled", "germs", "lungs", "respiratory", "sick", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Medical + Health", "Users + People" })]
HeadSideCoughSlash = 0xE062,
///
/// The Font Awesome "head-side-mask" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "head side mask", "breath", "coronavirus", "covid-19", "filter", "flu", "infection", "pandemic", "respirator", "virus" })]
+ [FontAwesomeSearchTerms(new[] { "head side mask", "breath", "coronavirus", "covid-19", "filter", "flu", "infection", "pandemic", "respirator", "uer", "virus" })]
[FontAwesomeCategoriesAttribute(new[] { "Medical + Health", "Users + People" })]
HeadSideMask = 0xE063,
///
/// The Font Awesome "head-side-virus" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "head side virus", "cold", "coronavirus", "covid-19", "flu", "infection", "pandemic", "sick" })]
+ [FontAwesomeSearchTerms(new[] { "head side virus", "cold", "coronavirus", "covid-19", "flu", "infection", "pandemic", "sick", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Medical + Health", "Users + People" })]
HeadSideVirus = 0xE064,
///
/// The Font Awesome "heart" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "black", "black heart", "blue", "blue heart", "brown", "brown heart", "card", "evil", "favorite", "game", "green", "green heart", "heart", "heart suit", "like", "love", "orange", "orange heart", "purple", "purple heart", "red heart", "relationship", "valentine", "white", "white heart", "wicked", "yellow", "yellow heart" })]
+ [FontAwesomeSearchTerms(new[] { "ace", "card", "favorite", "game", "heart", "heart suit", "like", "love", "relationship", "valentine", "wishlist" })]
[FontAwesomeCategoriesAttribute(new[] { "Charity", "Gaming", "Holidays", "Maps", "Medical + Health", "Shapes", "Shopping", "Social", "Sports + Fitness" })]
Heart = 0xF004,
@@ -4290,14 +4335,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "heart-circle-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "heart circle check", "favorite", "heart", "love", "not affected", "ok", "okay" })]
+ [FontAwesomeSearchTerms(new[] { "heart circle check", "enable", "favorite", "heart", "love", "not affected", "ok", "okay", "validate", "working" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Medical + Health" })]
HeartCircleCheck = 0xE4FD,
///
/// The Font Awesome "heart-circle-exclamation" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "heart circle exclamation", "favorite", "heart", "love" })]
+ [FontAwesomeSearchTerms(new[] { "heart circle exclamation", "failed", "favorite", "heart", "love" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Medical + Health" })]
HeartCircleExclamation = 0xE4FE,
@@ -4318,7 +4363,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "heart-circle-xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "heart circle xmark", "favorite", "heart", "love" })]
+ [FontAwesomeSearchTerms(new[] { "heart circle xmark", "favorite", "heart", "love", "uncheck" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Medical + Health" })]
HeartCircleXmark = 0xE501,
@@ -4343,17 +4388,38 @@ public enum FontAwesomeIcon
[FontAwesomeCategoriesAttribute(new[] { "Disaster + Crisis", "Humanitarian" })]
HelmetUn = 0xE503,
+ ///
+ /// The Font Awesome "hexagon" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "hexagon", "horizontal black hexagon", "geometry", "honeycomb", "polygon", "shape" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Shapes" })]
+ Hexagon = 0xF312,
+
+ ///
+ /// The Font Awesome "hexagon-nodes" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "hexagon nodes", "action", "ai", "artificial intelligence", "cluster", "graph", "language", "llm", "model", "network", "neuronal" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Charts + Diagrams", "Coding" })]
+ HexagonNodes = 0xE699,
+
+ ///
+ /// The Font Awesome "hexagon-nodes-bolt" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "hexagon nodes bolt", "llm", "action", "ai", "artificial intelligence", "cluster", "graph", "language", "llm", "model", "network", "neuronal" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Charts + Diagrams", "Coding" })]
+ HexagonNodesBolt = 0xE69A,
+
///
/// The Font Awesome "highlighter" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "highlighter", "edit", "marker", "sharpie", "update", "write" })]
+ [FontAwesomeSearchTerms(new[] { "highlighter", "edit", "marker", "modify", "sharpie", "update", "write" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Design", "Text Formatting" })]
Highlighter = 0xF591,
///
/// The Font Awesome "person-hiking" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person hiking", "autumn", "fall", "hike", "mountain", "outdoors", "summer", "walk" })]
+ [FontAwesomeSearchTerms(new[] { "person hiking", "autumn", "fall", "follow", "hike", "mountain", "outdoors", "summer", "uer", "walk" })]
[FontAwesomeCategoriesAttribute(new[] { "Camping", "Nature", "Sports + Fitness", "Users + People" })]
Hiking = 0xF6EC,
@@ -4381,7 +4447,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "clock-rotate-left" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "clock rotate left", "rewind", "clock", "reverse", "time", "time machine", "time travel" })]
+ [FontAwesomeSearchTerms(new[] { "clock rotate left", "rewind", "clock", "pending", "reverse", "time", "time machine", "time travel", "waiting" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows", "Medical + Health" })]
History = 0xF1DA,
@@ -4445,7 +4511,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "hospital-user" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "hospital user", "covid-19", "doctor", "network", "patient", "primary care" })]
+ [FontAwesomeSearchTerms(new[] { "hospital user", "covid-19", "doctor", "network", "patient", "primary care", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Medical + Health", "Users + People" })]
HospitalUser = 0xF80D,
@@ -4466,7 +4532,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "hot-tub-person" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "hot tub person", "jacuzzi", "spa" })]
+ [FontAwesomeSearchTerms(new[] { "hot tub person", "jacuzzi", "spa", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Travel + Hotel", "Users + People" })]
HotTub = 0xF593,
@@ -4480,21 +4546,21 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "hourglass-end" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "hourglass end", "hour", "hourglass done", "minute", "sand", "stopwatch", "time", "timer" })]
+ [FontAwesomeSearchTerms(new[] { "hourglass end", "hour", "hourglass done", "minute", "pending", "sand", "stopwatch", "time", "timer", "waiting" })]
[FontAwesomeCategoriesAttribute(new[] { "Time" })]
HourglassEnd = 0xF253,
///
/// The Font Awesome "hourglass-half" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "hourglass half", "hour", "minute", "sand", "stopwatch", "time" })]
+ [FontAwesomeSearchTerms(new[] { "hourglass half", "hour", "minute", "pending", "sand", "stopwatch", "time", "waiting" })]
[FontAwesomeCategoriesAttribute(new[] { "Time" })]
HourglassHalf = 0xF252,
///
/// The Font Awesome "hourglass-start" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "hourglass start", "hour", "minute", "sand", "stopwatch", "time" })]
+ [FontAwesomeSearchTerms(new[] { "hourglass start", "hour", "minute", "sand", "stopwatch", "time", "waiting" })]
[FontAwesomeCategoriesAttribute(new[] { "Time" })]
HourglassStart = 0xF251,
@@ -4508,7 +4574,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "house-chimney-user" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "house chimney user", "covid-19", "home", "isolation", "quarantine" })]
+ [FontAwesomeSearchTerms(new[] { "house chimney user", "covid-19", "home", "isolation", "quarantine", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Household", "Users + People" })]
HouseChimneyUser = 0xE065,
@@ -4522,21 +4588,21 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "house-circle-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "house circle check", "abode", "home", "house", "not affected", "ok", "okay" })]
+ [FontAwesomeSearchTerms(new[] { "house circle check", "abode", "enable", "home", "house", "not affected", "ok", "okay", "validate", "working" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Humanitarian" })]
HouseCircleCheck = 0xE509,
///
/// The Font Awesome "house-circle-exclamation" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "house circle exclamation", "abode", "affected", "home", "house" })]
+ [FontAwesomeSearchTerms(new[] { "house circle exclamation", "abode", "affected", "failed", "home", "house" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Humanitarian" })]
HouseCircleExclamation = 0xE50A,
///
/// The Font Awesome "house-circle-xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "house circle xmark", "abode", "destroy", "home", "house" })]
+ [FontAwesomeSearchTerms(new[] { "house circle xmark", "abode", "destroy", "home", "house", "uncheck" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Humanitarian" })]
HouseCircleXmark = 0xE50B,
@@ -4592,7 +4658,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "house-lock" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "house lock", "closed", "home", "house", "lockdown", "quarantine" })]
+ [FontAwesomeSearchTerms(new[] { "house lock", "closed", "home", "house", "lockdown", "padlock", "privacy", "quarantine" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Household", "Humanitarian", "Security" })]
HouseLock = 0xE510,
@@ -4606,21 +4672,21 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "house-medical-circle-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "house medical circle check", "clinic", "hospital", "not affected", "ok", "okay" })]
+ [FontAwesomeSearchTerms(new[] { "house medical circle check", "clinic", "enable", "hospital", "not affected", "ok", "okay", "validate", "working" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Humanitarian", "Medical + Health" })]
HouseMedicalCircleCheck = 0xE511,
///
/// The Font Awesome "house-medical-circle-exclamation" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "house medical circle exclamation", "affected", "clinic", "hospital" })]
+ [FontAwesomeSearchTerms(new[] { "house medical circle exclamation", "affected", "clinic", "failed", "hospital" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Humanitarian", "Medical + Health" })]
HouseMedicalCircleExclamation = 0xE512,
///
/// The Font Awesome "house-medical-circle-xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "house medical circle xmark", "clinic", "destroy", "hospital" })]
+ [FontAwesomeSearchTerms(new[] { "house medical circle xmark", "clinic", "destroy", "hospital", "uncheck" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Humanitarian", "Medical + Health" })]
HouseMedicalCircleXmark = 0xE513,
@@ -4634,7 +4700,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "house-signal" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "house signal", "abode", "building", "connect", "family", "home", "residence", "smart home", "wifi" })]
+ [FontAwesomeSearchTerms(new[] { "house signal", "abode", "building", "connect", "family", "home", "residence", "smart home", "wifi", "www" })]
[FontAwesomeCategoriesAttribute(new[] { "Connectivity", "Household", "Humanitarian" })]
HouseSignal = 0xE012,
@@ -4648,7 +4714,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "house-user" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "house user", "house" })]
+ [FontAwesomeSearchTerms(new[] { "house user", "house", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Household", "Users + People" })]
HouseUser = 0xE1B0,
@@ -4690,7 +4756,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "icons" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "icons", "bolt", "emoji", "heart", "image", "music", "photo", "symbols" })]
+ [FontAwesomeSearchTerms(new[] { "icons", "bolt", "category", "emoji", "heart", "image", "music", "photo", "symbols" })]
[FontAwesomeCategoriesAttribute(new[] { "Communication", "Design", "Social", "Text Formatting" })]
Icons = 0xF86D,
@@ -4704,21 +4770,21 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "id-badge" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "id badge", "address", "contact", "identification", "license", "profile" })]
+ [FontAwesomeSearchTerms(new[] { "id badge", "address", "contact", "identification", "license", "profile", "uer", "username" })]
[FontAwesomeCategoriesAttribute(new[] { "Photos + Images", "Security", "Users + People" })]
IdBadge = 0xF2C1,
///
/// The Font Awesome "id-card" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "id card", "contact", "demographics", "document", "identification", "issued", "profile", "registration" })]
+ [FontAwesomeSearchTerms(new[] { "id card", "contact", "demographics", "document", "identification", "issued", "profile", "registration", "uer", "username" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Photos + Images", "Security", "Users + People" })]
IdCard = 0xF2C2,
///
/// The Font Awesome "id-card-clip" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "id card clip", "contact", "demographics", "document", "identification", "issued", "profile" })]
+ [FontAwesomeSearchTerms(new[] { "id card clip", "contact", "demographics", "document", "identification", "issued", "profile", "uer", "username" })]
[FontAwesomeCategoriesAttribute(new[] { "Medical + Health", "Security", "Users + People" })]
IdCardAlt = 0xF47F,
@@ -4732,14 +4798,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "image" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "image", "album", "landscape", "photo", "picture" })]
+ [FontAwesomeSearchTerms(new[] { "image", "album", "img", "landscape", "photo", "picture" })]
[FontAwesomeCategoriesAttribute(new[] { "Maps", "Photos + Images", "Social" })]
Image = 0xF03E,
///
/// The Font Awesome "images" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "images", "album", "landscape", "photo", "picture" })]
+ [FontAwesomeSearchTerms(new[] { "images", "album", "img", "landscape", "photo", "picture" })]
[FontAwesomeCategoriesAttribute(new[] { "Maps", "Photos + Images", "Social" })]
Images = 0xF302,
@@ -4792,6 +4858,12 @@ public enum FontAwesomeIcon
[FontAwesomeCategoriesAttribute(new[] { "Accessibility", "Maps" })]
InfoCircle = 0xF05A,
+ ///
+ /// The Font Awesome "instagramsquare" icon unicode character.
+ ///
+ [Obsolete]
+ InstagramSquare = 0xF955,
+
///
/// The Font Awesome "italic" icon unicode character.
///
@@ -4921,7 +4993,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "landmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "landmark", "building", "classical", "historic", "memorable", "monument", "museum", "politics" })]
+ [FontAwesomeSearchTerms(new[] { "landmark", "building", "classical", "historic", "memorable", "monument", "museum", "politics", "society" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Business", "Humanitarian", "Maps", "Money" })]
Landmark = 0xF66F,
@@ -4956,14 +5028,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "laptop" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "computer", "cpu", "dell", "demo", "device", "laptop", "mac", "macbook", "machine", "pc", "personal" })]
+ [FontAwesomeSearchTerms(new[] { "computer", "cpu", "dell", "demo", "device", "fabook", "fb", "laptop", "mac", "macbook", "machine", "pc", "personal" })]
[FontAwesomeCategoriesAttribute(new[] { "Devices + Hardware", "Humanitarian" })]
Laptop = 0xF109,
///
/// The Font Awesome "laptop-code" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "laptop code", "computer", "cpu", "dell", "demo", "develop", "device", "mac", "macbook", "machine", "pc" })]
+ [FontAwesomeSearchTerms(new[] { "laptop code", "computer", "cpu", "dell", "demo", "develop", "device", "fabook", "fb", "mac", "macbook", "machine", "mysql", "pc", "sql" })]
[FontAwesomeCategoriesAttribute(new[] { "Coding", "Education" })]
LaptopCode = 0xF5FC,
@@ -5019,7 +5091,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "layer-group" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "layer group", "arrange", "develop", "layers", "map", "stack" })]
+ [FontAwesomeSearchTerms(new[] { "layer group", "arrange", "category", "develop", "layers", "map", "platform", "stack" })]
[FontAwesomeCategoriesAttribute(new[] { "Design", "Maps" })]
LayerGroup = 0xF5FD,
@@ -5076,7 +5148,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "lightbulb" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "lightbulb", " comic", " electric", " idea", " innovation", " inspiration", " light", " light bulb", " bulb", "bulb", "comic", "electric", "energy", "idea", "inspiration", "mechanical" })]
+ [FontAwesomeSearchTerms(new[] { "lightbulb", "bulb", "bulb", "comic", "comic", "electric", "electric", "energy", "idea", "idea", "innovation", "inspiration", "inspiration", "light", "light bulb", "mechanical" })]
[FontAwesomeCategoriesAttribute(new[] { "Energy", "Household", "Maps", "Marketing" })]
Lightbulb = 0xF0EB,
@@ -5104,28 +5176,28 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "list" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "list", "checklist", "completed", "done", "finished", "ol", "todo", "ul" })]
+ [FontAwesomeSearchTerms(new[] { "list", "bullet", "category", "cheatsheet", "checklist", "completed", "done", "finished", "ol", "summary", "todo", "ul" })]
[FontAwesomeCategoriesAttribute(new[] { "Text Formatting" })]
List = 0xF03A,
///
/// The Font Awesome "rectangle-list" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "rectangle list", "checklist", "completed", "done", "finished", "ol", "todo", "ul" })]
+ [FontAwesomeSearchTerms(new[] { "rectangle list", "cheatsheet", "checklist", "completed", "done", "finished", "ol", "summary", "todo", "ul" })]
[FontAwesomeCategoriesAttribute(new[] { "Text Formatting" })]
ListAlt = 0xF022,
///
/// The Font Awesome "list-ol" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "list ol", "checklist", "completed", "done", "finished", "numbers", "ol", "todo", "ul" })]
+ [FontAwesomeSearchTerms(new[] { "list ol", "cheatsheet", "checklist", "completed", "done", "finished", "numbers", "ol", "summary", "todo", "ul" })]
[FontAwesomeCategoriesAttribute(new[] { "Text Formatting" })]
ListOl = 0xF0CB,
///
/// The Font Awesome "list-ul" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "list ul", "checklist", "completed", "done", "finished", "ol", "todo", "ul" })]
+ [FontAwesomeSearchTerms(new[] { "list ul", "bullet", "cheatsheet", "checklist", "completed", "done", "finished", "ol", "summary", "survey", "todo", "ul" })]
[FontAwesomeCategoriesAttribute(new[] { "Text Formatting" })]
ListUl = 0xF0CA,
@@ -5153,21 +5225,21 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "location-pin-lock" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "location pin lock", "closed", "lockdown", "map", "quarantine" })]
+ [FontAwesomeSearchTerms(new[] { "location pin lock", "closed", "lockdown", "map", "padlock", "privacy", "quarantine" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Maps" })]
LocationPinLock = 0xE51F,
///
/// The Font Awesome "lock" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "admin", "closed", "lock", "locked", "open", "password", "private", "protect", "security" })]
+ [FontAwesomeSearchTerms(new[] { "admin", "closed", "lock", "locked", "open", "padlock", "password", "privacy", "private", "protect", "security" })]
[FontAwesomeCategoriesAttribute(new[] { "Security" })]
Lock = 0xF023,
///
/// The Font Awesome "lock-open" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "lock open", "admin", "lock", "open", "password", "private", "protect", "security", "unlock" })]
+ [FontAwesomeSearchTerms(new[] { "lock open", "admin", "lock", "open", "padlock", "password", "privacy", "private", "protect", "security", "unlock" })]
[FontAwesomeCategoriesAttribute(new[] { "Security" })]
LockOpen = 0xF3C1,
@@ -5202,7 +5274,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "up-long" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "up long", "long-arrow-up", "upload" })]
+ [FontAwesomeSearchTerms(new[] { "up long", "long-arrow-up", "upgrade", "upload" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
LongArrowAltUp = 0xF30C,
@@ -5251,28 +5323,28 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "magnifying-glass-arrow-right" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "magnifying glass arrow right", "find", "next", "search" })]
+ [FontAwesomeSearchTerms(new[] { "magnifying glass arrow right", "find", "magnifier", "next", "search" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Humanitarian", "Marketing" })]
MagnifyingGlassArrowRight = 0xE521,
///
/// The Font Awesome "magnifying-glass-chart" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "magnifying glass chart", " data", " graph", " intelligence", "analysis", "chart", "market" })]
+ [FontAwesomeSearchTerms(new[] { "magnifying glass chart", "analysis", "chart", "data", "graph", "intelligence", "magnifier", "market", "revenue" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Humanitarian", "Marketing" })]
MagnifyingGlassChart = 0xE522,
///
/// The Font Awesome "envelopes-bulk" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "envelopes bulk", "archive", "envelope", "letter", "post office", "postal", "postcard", "send", "stamp", "usps" })]
+ [FontAwesomeSearchTerms(new[] { "envelopes bulk", "archive", "envelope", "letter", "newsletter", "offer", "post office", "postal", "postcard", "send", "stamp", "usps" })]
[FontAwesomeCategoriesAttribute(new[] { "Marketing" })]
MailBulk = 0xF674,
///
/// The Font Awesome "person" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person", "man", "person standing", "stand", "standing", "woman" })]
+ [FontAwesomeSearchTerms(new[] { "person", "default", "man", "person standing", "stand", "standing", "uer", "woman" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Maps", "Users + People" })]
Male = 0xF183,
@@ -5335,7 +5407,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "marker" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "marker", "design", "edit", "sharpie", "update", "write" })]
+ [FontAwesomeSearchTerms(new[] { "marker", "design", "edit", "modify", "sharpie", "update", "write" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Design" })]
Marker = 0xF5A1,
@@ -5349,7 +5421,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "mars-and-venus-burst" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "mars and venus burst", "gender", "violence" })]
+ [FontAwesomeSearchTerms(new[] { "mars and venus burst", "gender", "uer", "violence" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Security", "Users + People" })]
MarsAndVenusBurst = 0xE523,
@@ -5412,7 +5484,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "medal" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "award", "medal", "ribbon", "sports medal", "star", "trophy" })]
+ [FontAwesomeSearchTerms(new[] { "award", "guarantee", "medal", "quality", "ribbon", "sports medal", "star", "trophy", "warranty" })]
[FontAwesomeCategoriesAttribute(new[] { "Sports + Fitness" })]
Medal = 0xF5A2,
@@ -5426,7 +5498,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "face-meh" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "face meh", "deadpan", "emoticon", "face", "meh", "neutral", "neutral face", "rating" })]
+ [FontAwesomeSearchTerms(new[] { "face meh", "deadpan", "default", "emoticon", "face", "meh", "neutral", "neutral face", "rating", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Communication", "Emoji", "Users + People" })]
Meh = 0xF11A,
@@ -5482,35 +5554,35 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "microphone" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "microphone", "address", "audio", "information", "podcast", "public", "record", "sing", "sound", "voice" })]
+ [FontAwesomeSearchTerms(new[] { "microphone", "address", "audio", "information", "podcast", "public", "record", "sing", "sound", "talking", "voice" })]
[FontAwesomeCategoriesAttribute(new[] { "Communication", "Film + Video", "Music + Audio", "Toggle" })]
Microphone = 0xF130,
///
/// The Font Awesome "microphone-lines" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "microphone lines", "audio", "mic", "microphone", "music", "podcast", "record", "sing", "sound", "studio", "studio microphone", "voice" })]
+ [FontAwesomeSearchTerms(new[] { "microphone lines", "audio", "mic", "microphone", "music", "podcast", "record", "sing", "sound", "studio", "studio microphone", "talking", "voice" })]
[FontAwesomeCategoriesAttribute(new[] { "Communication", "Film + Video", "Music + Audio" })]
MicrophoneAlt = 0xF3C9,
///
/// The Font Awesome "microphone-lines-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "microphone lines slash", "audio", "disable", "mute", "podcast", "record", "sing", "sound", "voice" })]
+ [FontAwesomeSearchTerms(new[] { "microphone lines slash", "audio", "disable", "disabled", "disconnect", "disconnect", "mute", "podcast", "record", "sing", "sound", "voice" })]
[FontAwesomeCategoriesAttribute(new[] { "Communication", "Film + Video", "Music + Audio" })]
MicrophoneAltSlash = 0xF539,
///
/// The Font Awesome "microphone-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "microphone slash", "audio", "disable", "mute", "podcast", "record", "sing", "sound", "voice" })]
+ [FontAwesomeSearchTerms(new[] { "microphone slash", "audio", "disable", "disabled", "mute", "podcast", "record", "sing", "sound", "voice" })]
[FontAwesomeCategoriesAttribute(new[] { "Communication", "Film + Video", "Music + Audio", "Toggle" })]
MicrophoneSlash = 0xF131,
///
/// The Font Awesome "microscope" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "covid-19", "electron", "lens", "microscope", "optics", "science", "shrink", "testing", "tool" })]
+ [FontAwesomeSearchTerms(new[] { "covid-19", "electron", "knowledge", "lens", "microscope", "optics", "science", "shrink", "testing", "tool" })]
[FontAwesomeCategoriesAttribute(new[] { "Education", "Humanitarian", "Medical + Health", "Science" })]
Microscope = 0xF610,
@@ -5584,73 +5656,80 @@ public enum FontAwesomeIcon
[FontAwesomeCategoriesAttribute(new[] { "Communication", "Devices + Hardware", "Humanitarian" })]
MobileScreen = 0xF3CF,
+ ///
+ /// The Font Awesome "mobile-vibrate" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "mobile vibrate", "android", "call", "cell", "cell phone", "device", "haptic", "mobile", "mobile phone", "notification", "number", "phone", "screen", "telephone", "text" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Communication", "Devices + Hardware" })]
+ MobileVibrate = 0xE816,
+
///
/// The Font Awesome "money-bill" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "money bill", "buy", "cash", "checkout", "money", "payment", "price", "purchase" })]
+ [FontAwesomeSearchTerms(new[] { "money bill", "buy", "cash", "checkout", "coupon", "investment", "money", "payment", "premium", "price", "purchase", "revenue", "salary" })]
[FontAwesomeCategoriesAttribute(new[] { "Maps", "Money" })]
MoneyBill = 0xF0D6,
///
/// The Font Awesome "money-bill-1" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "money bill 1", "buy", "cash", "checkout", "money", "payment", "price", "purchase" })]
+ [FontAwesomeSearchTerms(new[] { "money bill 1", "buy", "cash", "checkout", "money", "payment", "premium", "price", "purchase", "salary" })]
[FontAwesomeCategoriesAttribute(new[] { "Maps", "Money" })]
MoneyBillAlt = 0xF3D1,
///
/// The Font Awesome "money-bills" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "money bills", "atm", "cash", "money", "moolah" })]
+ [FontAwesomeSearchTerms(new[] { "money bills", "atm", "cash", "investment", "money", "moolah", "premium", "revenue", "salary" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Money" })]
MoneyBills = 0xE1F3,
///
/// The Font Awesome "money-bill-transfer" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "money bill transfer", "bank", "conversion", "deposit", "money", "transfer", "withdrawal" })]
+ [FontAwesomeSearchTerms(new[] { "money bill transfer", "bank", "conversion", "deposit", "investment", "money", "salary", "transfer", "withdrawal" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Money" })]
MoneyBillTransfer = 0xE528,
///
/// The Font Awesome "money-bill-trend-up" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "money bill trend up", "bank", "bonds", "inflation", "market", "stocks", "trade" })]
+ [FontAwesomeSearchTerms(new[] { "money bill trend up", "bank", "bonds", "inflation", "investment", "market", "revenue", "salary", "stocks", "trade" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Money" })]
MoneyBillTrendUp = 0xE529,
///
/// The Font Awesome "money-bill-wave" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "money bill wave", "buy", "cash", "checkout", "money", "payment", "price", "purchase" })]
+ [FontAwesomeSearchTerms(new[] { "money bill wave", "buy", "cash", "checkout", "money", "payment", "premium", "price", "purchase", "salary" })]
[FontAwesomeCategoriesAttribute(new[] { "Money" })]
MoneyBillWave = 0xF53A,
///
/// The Font Awesome "money-bill-1-wave" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "money bill 1 wave", "buy", "cash", "checkout", "money", "payment", "price", "purchase" })]
+ [FontAwesomeSearchTerms(new[] { "money bill 1 wave", "buy", "cash", "checkout", "money", "payment", "premium", "price", "purchase", "salary" })]
[FontAwesomeCategoriesAttribute(new[] { "Money" })]
MoneyBillWaveAlt = 0xF53B,
///
/// The Font Awesome "money-bill-wheat" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "money bill wheat", "agribusiness", "agriculture", "farming", "food", "livelihood", "subsidy" })]
+ [FontAwesomeSearchTerms(new[] { "money bill wheat", "agribusiness", "agriculture", "farming", "food", "investment", "livelihood", "subsidy" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Money" })]
MoneyBillWheat = 0xE52A,
///
/// The Font Awesome "money-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "money check", "bank check", "buy", "checkout", "cheque", "money", "payment", "price", "purchase" })]
+ [FontAwesomeSearchTerms(new[] { "money check", "bank check", "buy", "checkout", "cheque", "money", "payment", "price", "purchase", "salary" })]
[FontAwesomeCategoriesAttribute(new[] { "Money", "Shopping" })]
MoneyCheck = 0xF53C,
///
/// The Font Awesome "money-check-dollar" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "money check dollar", "bank check", "buy", "checkout", "cheque", "money", "payment", "price", "purchase" })]
+ [FontAwesomeSearchTerms(new[] { "money check dollar", "bank check", "buy", "checkout", "cheque", "money", "payment", "price", "purchase", "salary" })]
[FontAwesomeCategoriesAttribute(new[] { "Money", "Shopping" })]
MoneyCheckAlt = 0xF53D,
@@ -5783,14 +5862,21 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "newspaper" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "article", "editorial", "headline", "journal", "journalism", "news", "newspaper", "paper", "press" })]
+ [FontAwesomeSearchTerms(new[] { "article", "editorial", "headline", "journal", "journalism", "news", "newsletter", "newspaper", "paper", "press" })]
[FontAwesomeCategoriesAttribute(new[] { "Maps", "Writing" })]
Newspaper = 0xF1EA,
+ ///
+ /// The Font Awesome "non-binary" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "non binary", "female", "gender", "male", "nb", "queer" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Genders" })]
+ NonBinary = 0xE807,
+
///
/// The Font Awesome "notdef" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "notdef", "close", "missing" })]
+ [FontAwesomeSearchTerms(new[] { "notdef", "404", "close", "missing", "not found" })]
[FontAwesomeCategoriesAttribute(new[] { "Coding", "Writing" })]
Notdef = 0xE1FE,
@@ -5822,6 +5908,13 @@ public enum FontAwesomeIcon
[FontAwesomeCategoriesAttribute(new[] { "Design" })]
ObjectUngroup = 0xF248,
+ ///
+ /// The Font Awesome "octagon" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "octagon", "octagonal", "shape", "sign", "stop", "stop sign" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Shapes" })]
+ Octagon = 0xF306,
+
///
/// The Font Awesome "oil-can" icon unicode character.
///
@@ -5867,14 +5960,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "paintbrush" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "acrylic", "art", "brush", "color", "fill", "paint", "paintbrush", "painting", "pigment", "watercolor" })]
+ [FontAwesomeSearchTerms(new[] { "acrylic", "art", "brush", "color", "fill", "modify", "paint", "paintbrush", "painting", "pigment", "watercolor" })]
[FontAwesomeCategoriesAttribute(new[] { "Design", "Editing" })]
PaintBrush = 0xF1FC,
///
/// The Font Awesome "paint-roller" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "paint roller", "acrylic", "art", "brush", "color", "fill", "paint", "pigment", "watercolor" })]
+ [FontAwesomeSearchTerms(new[] { "paint roller", "acrylic", "art", "brush", "color", "fill", "maintenance", "paint", "pigment", "watercolor" })]
[FontAwesomeCategoriesAttribute(new[] { "Construction", "Design" })]
PaintRoller = 0xF5AA,
@@ -5895,7 +5988,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "panorama" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "panorama", "image", "landscape", "photo", "wide" })]
+ [FontAwesomeSearchTerms(new[] { "panorama", "image", "img", "landscape", "photo", "wide" })]
[FontAwesomeCategoriesAttribute(new[] { "Photos + Images" })]
Panorama = 0xE209,
@@ -5986,98 +6079,105 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "pen" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "ballpoint", "design", "edit", "pen", "update", "write" })]
+ [FontAwesomeSearchTerms(new[] { "ballpoint", "design", "edit", "modify", "pen", "update", "write" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Design", "Editing", "Writing" })]
Pen = 0xF304,
///
/// The Font Awesome "pen-clip" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "pen clip", "design", "edit", "update", "write" })]
+ [FontAwesomeSearchTerms(new[] { "pen clip", "design", "edit", "modify", "update", "write" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Design", "Editing", "Writing" })]
PenAlt = 0xF305,
///
/// The Font Awesome "pencil" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "lower left pencil", "design", "draw", "edit", "lead", "pencil", "update", "write" })]
+ [FontAwesomeSearchTerms(new[] { "lower left pencil", "design", "draw", "edit", "lead", "maintenance", "modify", "pencil", "update", "write" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Construction", "Design", "Editing", "Writing" })]
PencilAlt = 0xF303,
///
/// The Font Awesome "pen-ruler" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "pen ruler", "design", "draft", "draw", "pencil" })]
+ [FontAwesomeSearchTerms(new[] { "pen ruler", "design", "draft", "draw", "maintenance", "modify", "pencil" })]
[FontAwesomeCategoriesAttribute(new[] { "Construction", "Design", "Editing" })]
PencilRuler = 0xF5AE,
///
/// The Font Awesome "pen-fancy" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "pen fancy", "black nib", "design", "edit", "fountain", "fountain pen", "nib", "pen", "update", "write" })]
+ [FontAwesomeSearchTerms(new[] { "pen fancy", "black nib", "design", "edit", "fountain", "fountain pen", "modify", "nib", "pen", "update", "write" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Design", "Editing" })]
PenFancy = 0xF5AC,
///
/// The Font Awesome "pen-nib" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "pen nib", "design", "edit", "fountain pen", "update", "write" })]
+ [FontAwesomeSearchTerms(new[] { "pen nib", "design", "edit", "fountain pen", "modify", "update", "write" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Design", "Editing" })]
PenNib = 0xF5AD,
///
/// The Font Awesome "square-pen" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "square pen", "edit", "pencil-square", "update", "write" })]
+ [FontAwesomeSearchTerms(new[] { "square pen", "edit", "modify", "pencil-square", "update", "write" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Editing", "Writing" })]
PenSquare = 0xF14B,
+ ///
+ /// The Font Awesome "pentagon" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "5", "five", "pentagon", "shape" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Shapes" })]
+ Pentagon = 0xE790,
+
///
/// The Font Awesome "people-arrows" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "people arrows", "distance", "isolation", "separate", "social distancing", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "people arrows", "conversation", "discussion", "distance", "insert", "isolation", "separate", "social distancing", "talk", "talking", "together", "uer", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
PeopleArrows = 0xE068,
///
/// The Font Awesome "people-carry-box" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "people carry box", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "people carry box", "together", "uer", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Moving", "Users + People" })]
PeopleCarry = 0xF4CE,
///
/// The Font Awesome "people-group" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "people group", "family", "group", "team" })]
+ [FontAwesomeSearchTerms(new[] { "people group", "crowd", "family", "group", "team", "together", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Marketing", "Users + People" })]
PeopleGroup = 0xE533,
///
/// The Font Awesome "people-line" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "people line", "group", "need" })]
+ [FontAwesomeSearchTerms(new[] { "people line", "crowd", "group", "need", "together", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
PeopleLine = 0xE534,
///
/// The Font Awesome "people-pulling" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "people pulling", "forced return", "yanking" })]
+ [FontAwesomeSearchTerms(new[] { "people pulling", "forced return", "together", "uer", "yanking" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Security", "Users + People" })]
PeoplePulling = 0xE535,
///
/// The Font Awesome "people-robbery" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "people robbery", "criminal", "hands up", "looting", "robbery", "steal" })]
+ [FontAwesomeSearchTerms(new[] { "people robbery", "criminal", "hands up", "looting", "robbery", "steal", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Security", "Users + People" })]
PeopleRobbery = 0xE536,
///
/// The Font Awesome "people-roof" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "people roof", "family", "group", "manage", "people", "safe", "shelter" })]
+ [FontAwesomeSearchTerms(new[] { "people roof", "crowd", "family", "group", "manage", "people", "safe", "shelter", "together", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Camping", "Household", "Humanitarian", "Users + People" })]
PeopleRoof = 0xE537,
@@ -6107,105 +6207,105 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "person-arrow-down-to-line" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person arrow down to line", "ground", "indigenous", "native" })]
+ [FontAwesomeSearchTerms(new[] { "person arrow down to line", "ground", "indigenous", "insert", "native", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
PersonArrowDownToLine = 0xE538,
///
/// The Font Awesome "person-arrow-up-from-line" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person arrow up from line", "population", "rise" })]
+ [FontAwesomeSearchTerms(new[] { "person arrow up from line", "population", "rise", "uer", "upgrade" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
PersonArrowUpFromLine = 0xE539,
///
/// The Font Awesome "person-booth" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person booth", "changing room", "curtain", "vote", "voting" })]
+ [FontAwesomeSearchTerms(new[] { "person booth", "changing room", "curtain", "uer", "vote", "voting" })]
[FontAwesomeCategoriesAttribute(new[] { "Political", "Shopping", "Users + People" })]
PersonBooth = 0xF756,
///
/// The Font Awesome "person-breastfeeding" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person breastfeeding", "baby", "child", "infant", "mother", "nutrition", "sustenance" })]
+ [FontAwesomeSearchTerms(new[] { "person breastfeeding", "baby", "child", "infant", "mother", "nutrition", "parent", "sustenance", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Childhood", "Humanitarian", "Medical + Health", "Users + People" })]
PersonBreastfeeding = 0xE53A,
///
/// The Font Awesome "person-burst" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person burst", "abuse", "accident", "crash", "explode", "violence" })]
+ [FontAwesomeSearchTerms(new[] { "person burst", "abuse", "accident", "crash", "explode", "uer", "violence" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Security", "Users + People" })]
PersonBurst = 0xE53B,
///
/// The Font Awesome "person-cane" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person cane", "aging", "cane", "elderly", "old", "staff" })]
+ [FontAwesomeSearchTerms(new[] { "person cane", "aging", "cane", "elderly", "old", "staff", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Accessibility", "Humanitarian", "Medical + Health", "Users + People" })]
PersonCane = 0xE53C,
///
/// The Font Awesome "person-chalkboard" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person chalkboard", "blackboard", "instructor", "keynote", "lesson", "presentation", "teacher" })]
+ [FontAwesomeSearchTerms(new[] { "person chalkboard", "blackboard", "instructor", "keynote", "lesson", "presentation", "teacher", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Education", "Humanitarian", "Users + People" })]
PersonChalkboard = 0xE53D,
///
/// The Font Awesome "person-circle-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person circle check", "approved", "not affected", "ok", "okay" })]
+ [FontAwesomeSearchTerms(new[] { "person circle check", "approved", "enable", "not affected", "ok", "okay", "uer", "validate", "working" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
PersonCircleCheck = 0xE53E,
///
/// The Font Awesome "person-circle-exclamation" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person circle exclamation", "affected", "alert", "lost", "missing" })]
+ [FontAwesomeSearchTerms(new[] { "person circle exclamation", "affected", "alert", "failed", "lost", "missing", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
PersonCircleExclamation = 0xE53F,
///
/// The Font Awesome "person-circle-minus" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person circle minus", "delete", "remove" })]
+ [FontAwesomeSearchTerms(new[] { "person circle minus", "delete", "remove", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
PersonCircleMinus = 0xE540,
///
/// The Font Awesome "person-circle-plus" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person circle plus", "add", "found" })]
+ [FontAwesomeSearchTerms(new[] { "person circle plus", "add", "follow", "found", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
PersonCirclePlus = 0xE541,
///
/// The Font Awesome "person-circle-question" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person circle question", "lost", "missing" })]
+ [FontAwesomeSearchTerms(new[] { "person circle question", "faq", "lost", "missing", "request", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
PersonCircleQuestion = 0xE542,
///
/// The Font Awesome "person-circle-xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person circle xmark", "dead", "removed" })]
+ [FontAwesomeSearchTerms(new[] { "person circle xmark", "dead", "removed", "uer", "uncheck" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
PersonCircleXmark = 0xE543,
///
/// The Font Awesome "person-digging" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person digging", "bury", "construction", "debris", "dig", "men at work" })]
+ [FontAwesomeSearchTerms(new[] { "person digging", "bury", "construction", "debris", "dig", "maintenance", "men at work", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Construction", "Humanitarian", "Users + People" })]
PersonDigging = 0xF85E,
///
/// The Font Awesome "person-dress-burst" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person dress burst", "abuse", "accident", "crash", "explode", "violence" })]
+ [FontAwesomeSearchTerms(new[] { "person dress burst", "abuse", "accident", "crash", "explode", "uer", "violence" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Security", "Users + People" })]
PersonDressBurst = 0xE544,
@@ -6219,112 +6319,112 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "person-falling" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person falling", "accident", "fall", "trip" })]
+ [FontAwesomeSearchTerms(new[] { "person falling", "accident", "fall", "trip", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
PersonFalling = 0xE546,
///
/// The Font Awesome "person-falling-burst" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person falling burst", "accident", "crash", "death", "fall", "homicide", "murder" })]
+ [FontAwesomeSearchTerms(new[] { "person falling burst", "accident", "crash", "death", "fall", "homicide", "murder", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Security", "Users + People" })]
PersonFallingBurst = 0xE547,
///
/// The Font Awesome "person-half-dress" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person half dress", "gender", "man", "restroom", "transgender", "woman" })]
+ [FontAwesomeSearchTerms(new[] { "person half dress", "gender", "man", "restroom", "transgender", "uer", "woman" })]
[FontAwesomeCategoriesAttribute(new[] { "Genders", "Humanitarian", "Medical + Health", "Users + People" })]
PersonHalfDress = 0xE548,
///
/// The Font Awesome "person-harassing" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person harassing", "abuse", "scream", "shame", "shout", "yell" })]
+ [FontAwesomeSearchTerms(new[] { "person harassing", "abuse", "scream", "shame", "shout", "uer", "yell" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Security", "Users + People" })]
PersonHarassing = 0xE549,
///
/// The Font Awesome "person-military-pointing" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person military pointing", "army", "customs", "guard" })]
+ [FontAwesomeSearchTerms(new[] { "person military pointing", "army", "customs", "guard", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Security", "Users + People" })]
PersonMilitaryPointing = 0xE54A,
///
/// The Font Awesome "person-military-rifle" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person military rifle", "armed forces", "army", "military", "rifle", "war" })]
+ [FontAwesomeSearchTerms(new[] { "person military rifle", "armed forces", "army", "military", "rifle", "uer", "war" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Security", "Users + People" })]
PersonMilitaryRifle = 0xE54B,
///
/// The Font Awesome "person-military-to-person" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person military to person", "civilian", "coordination", "military" })]
+ [FontAwesomeSearchTerms(new[] { "person military to person", "civilian", "coordination", "military", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Security", "Users + People" })]
PersonMilitaryToPerson = 0xE54C,
///
/// The Font Awesome "person-pregnant" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person pregnant", "baby", "birth", "child", "pregnant", "pregnant woman", "woman" })]
+ [FontAwesomeSearchTerms(new[] { "person pregnant", "baby", "birth", "child", "parent", "pregnant", "pregnant woman", "uer", "woman" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
PersonPregnant = 0xE31E,
///
/// The Font Awesome "person-rays" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person rays", "affected", "focus", "shine" })]
+ [FontAwesomeSearchTerms(new[] { "person rays", "affected", "focus", "shine", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Marketing", "Users + People" })]
PersonRays = 0xE54D,
///
/// The Font Awesome "person-rifle" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person rifle", "army", "combatant", "gun", "military", "rifle", "war" })]
+ [FontAwesomeSearchTerms(new[] { "person rifle", "army", "combatant", "gun", "military", "rifle", "uer", "war" })]
[FontAwesomeCategoriesAttribute(new[] { "Disaster + Crisis", "Humanitarian", "Security", "Users + People" })]
PersonRifle = 0xE54E,
///
/// The Font Awesome "person-shelter" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person shelter", "house", "inside", "roof", "safe", "safety", "shelter" })]
+ [FontAwesomeSearchTerms(new[] { "person shelter", "house", "inside", "roof", "safe", "safety", "shelter", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Camping", "Humanitarian", "Security", "Users + People" })]
PersonShelter = 0xE54F,
///
/// The Font Awesome "person-through-window" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person through window", "door", "exit", "forced entry", "leave", "robbery", "steal", "window" })]
+ [FontAwesomeSearchTerms(new[] { "person through window", "door", "exit", "forced entry", "leave", "robbery", "steal", "uer", "window" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Security", "Users + People" })]
PersonThroughWindow = 0xE5A9,
///
/// The Font Awesome "person-walking-arrow-loop-left" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person walking arrow loop left", "population return", "return" })]
+ [FontAwesomeSearchTerms(new[] { "person walking arrow loop left", "follow", "population return", "return", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Disaster + Crisis", "Humanitarian", "Users + People" })]
PersonWalkingArrowLoopLeft = 0xE551,
///
/// The Font Awesome "person-walking-arrow-right" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person walking arrow right", "exit", "internally displaced", "leave", "refugee" })]
+ [FontAwesomeSearchTerms(new[] { "person walking arrow right", "exit", "follow", "internally displaced", "leave", "refugee", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Disaster + Crisis", "Humanitarian", "Users + People" })]
PersonWalkingArrowRight = 0xE552,
///
/// The Font Awesome "person-walking-dashed-line-arrow-right" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person walking dashed line arrow right", "exit", "refugee" })]
+ [FontAwesomeSearchTerms(new[] { "person walking dashed line arrow right", "exit", "follow", "refugee", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Disaster + Crisis", "Humanitarian", "Users + People" })]
PersonWalkingDashedLineArrowRight = 0xE553,
///
/// The Font Awesome "person-walking-luggage" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person walking luggage", "bag", "baggage", "briefcase", "carry-on", "deployment", "rolling" })]
+ [FontAwesomeSearchTerms(new[] { "person walking luggage", "bag", "baggage", "briefcase", "carry-on", "deployment", "follow", "rolling", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Travel + Hotel", "Users + People" })]
PersonWalkingLuggage = 0xE554,
@@ -6345,7 +6445,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "phone" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "left hand telephone receiver", "call", "earphone", "number", "phone", "receiver", "support", "telephone", "telephone receiver", "voice" })]
+ [FontAwesomeSearchTerms(new[] { "left hand telephone receiver", "call", "earphone", "number", "phone", "receiver", "support", "talking", "telephone", "telephone receiver", "voice" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Communication", "Maps" })]
Phone = 0xF095,
@@ -6359,7 +6459,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "phone-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "phone slash", "call", "cancel", "earphone", "mute", "number", "support", "telephone", "voice" })]
+ [FontAwesomeSearchTerms(new[] { "phone slash", "call", "cancel", "disabled", "disconnect", "earphone", "mute", "number", "support", "telephone", "voice" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Communication" })]
PhoneSlash = 0xF3DD,
@@ -6380,7 +6480,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "phone-volume" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "phone volume", "call", "earphone", "number", "sound", "support", "telephone", "voice", "volume-control-phone" })]
+ [FontAwesomeSearchTerms(new[] { "phone volume", "call", "earphone", "number", "ring", "ringing", "sound", "support", "talking", "telephone", "voice", "volume-control-phone" })]
[FontAwesomeCategoriesAttribute(new[] { "Accessibility", "Business", "Communication", "Maps", "Media Playback" })]
PhoneVolume = 0xF2A0,
@@ -6394,7 +6494,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "piggy-bank" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "piggy bank", "bank", "save", "savings" })]
+ [FontAwesomeSearchTerms(new[] { "piggy bank", "bank", "salary", "save", "savings" })]
[FontAwesomeCategoriesAttribute(new[] { "Charity", "Money", "Political" })]
PiggyBank = 0xF4D3,
@@ -6430,27 +6530,27 @@ public enum FontAwesomeIcon
/// The Font Awesome "plane-arrival" icon unicode character.
///
[FontAwesomeSearchTerms(new[] { "plane arrival", "aeroplane", "airplane", "airplane arrival", "airport", "arrivals", "arriving", "destination", "fly", "land", "landing", "location", "mode", "travel", "trip" })]
- [FontAwesomeCategoriesAttribute(new[] { "Travel + Hotel" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Transportation", "Travel + Hotel" })]
PlaneArrival = 0xF5AF,
///
/// The Font Awesome "plane-circle-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "plane circle check", "airplane", "airport", "flight", "fly", "not affected", "ok", "okay", "travel" })]
+ [FontAwesomeSearchTerms(new[] { "plane circle check", "airplane", "airport", "enable", "flight", "fly", "not affected", "ok", "okay", "travel", "validate", "working" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Logistics", "Travel + Hotel" })]
PlaneCircleCheck = 0xE555,
///
/// The Font Awesome "plane-circle-exclamation" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "plane circle exclamation", "affected", "airplane", "airport", "flight", "fly", "travel" })]
+ [FontAwesomeSearchTerms(new[] { "plane circle exclamation", "affected", "airplane", "airport", "failed", "flight", "fly", "travel" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Logistics", "Travel + Hotel" })]
PlaneCircleExclamation = 0xE556,
///
/// The Font Awesome "plane-circle-xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "plane circle xmark", "airplane", "airport", "destroy", "flight", "fly", "travel" })]
+ [FontAwesomeSearchTerms(new[] { "plane circle xmark", "airplane", "airport", "destroy", "flight", "fly", "travel", "uncheck" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Logistics", "Travel + Hotel" })]
PlaneCircleXmark = 0xE557,
@@ -6464,14 +6564,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "plane-lock" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "plane lock", "airplane", "airport", "closed", "flight", "fly", "lockdown", "quarantine", "travel" })]
+ [FontAwesomeSearchTerms(new[] { "plane lock", "airplane", "airport", "closed", "flight", "fly", "lockdown", "padlock", "privacy", "quarantine", "travel" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Logistics", "Travel + Hotel" })]
PlaneLock = 0xE558,
///
/// The Font Awesome "plane-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "plane slash", "airplane mode", "airport", "canceled", "covid-19", "delayed", "grounded", "travel" })]
+ [FontAwesomeSearchTerms(new[] { "plane slash", "airplane mode", "airport", "canceled", "covid-19", "delayed", "disabled", "grounded", "travel" })]
[FontAwesomeCategoriesAttribute(new[] { "Transportation", "Travel + Hotel" })]
PlaneSlash = 0xE069,
@@ -6527,21 +6627,21 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "plug-circle-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "plug circle check", "electric", "electricity", "not affected", "ok", "okay", "plug", "power" })]
+ [FontAwesomeSearchTerms(new[] { "plug circle check", "electric", "electricity", "enable", "not affected", "ok", "okay", "plug", "power", "validate", "working" })]
[FontAwesomeCategoriesAttribute(new[] { "Energy", "Humanitarian" })]
PlugCircleCheck = 0xE55C,
///
/// The Font Awesome "plug-circle-exclamation" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "plug circle exclamation", "affected", "electric", "electricity", "plug", "power" })]
+ [FontAwesomeSearchTerms(new[] { "plug circle exclamation", "affected", "electric", "electricity", "failed", "plug", "power" })]
[FontAwesomeCategoriesAttribute(new[] { "Energy", "Humanitarian" })]
PlugCircleExclamation = 0xE55D,
///
/// The Font Awesome "plug-circle-minus" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "plug circle minus", "electric", "electricity", "plug", "power" })]
+ [FontAwesomeSearchTerms(new[] { "plug circle minus", "disconnect", "electric", "electricity", "plug", "power" })]
[FontAwesomeCategoriesAttribute(new[] { "Energy", "Humanitarian" })]
PlugCircleMinus = 0xE55E,
@@ -6555,7 +6655,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "plug-circle-xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "plug circle xmark", "destroy", "electric", "electricity", "outage", "plug", "power" })]
+ [FontAwesomeSearchTerms(new[] { "plug circle xmark", "destroy", "disconnect", "electric", "electricity", "outage", "plug", "power", "uncheck" })]
[FontAwesomeCategoriesAttribute(new[] { "Energy", "Humanitarian" })]
PlugCircleXmark = 0xE560,
@@ -6563,7 +6663,7 @@ public enum FontAwesomeIcon
/// The Font Awesome "plus" icon unicode character.
/// Uses a legacy unicode value for backwards compatability. The current unicode value is 0x2B.
///
- [FontAwesomeSearchTerms(new[] { "+", "plus sign", "add", "create", "expand", "math", "new", "plus", "positive", "shape", "sign" })]
+ [FontAwesomeSearchTerms(new[] { "+", "plus sign", "add", "create", "expand", "follow", "math", "modify", "new", "plus", "positive", "shape", "sign" })]
[FontAwesomeCategoriesAttribute(new[] { "Editing", "Maps", "Mathematics", "Medical + Health", "Punctuation + Symbols" })]
Plus = 0xF067,
@@ -6598,21 +6698,21 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "square-poll-vertical" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "square poll vertical", "chart", "graph", "results", "survey", "trend", "vote", "voting" })]
+ [FontAwesomeSearchTerms(new[] { "square poll vertical", "chart", "graph", "results", "revenue", "statistics", "survey", "trend", "vote", "voting" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Charts + Diagrams", "Marketing", "Social" })]
Poll = 0xF681,
///
/// The Font Awesome "square-poll-horizontal" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "square poll horizontal", "chart", "graph", "results", "survey", "trend", "vote", "voting" })]
+ [FontAwesomeSearchTerms(new[] { "square poll horizontal", "chart", "graph", "results", "statistics", "survey", "trend", "vote", "voting" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Charts + Diagrams", "Marketing", "Social" })]
PollH = 0xF682,
///
/// The Font Awesome "poo" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "crap", "dung", "face", "monster", "pile of poo", "poo", "poop", "shit", "smile", "turd" })]
+ [FontAwesomeSearchTerms(new[] { "crap", "dung", "face", "monster", "pile of poo", "poo", "poop", "shit", "smile", "turd", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Communication", "Users + People" })]
Poo = 0xF2FE,
@@ -6633,7 +6733,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "image-portrait" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "image portrait", "id", "image", "photo", "picture", "selfie" })]
+ [FontAwesomeSearchTerms(new[] { "image portrait", "id", "image", "img", "photo", "picture", "selfie", "uer", "username" })]
[FontAwesomeCategoriesAttribute(new[] { "Photos + Images", "Users + People" })]
Portrait = 0xF3E0,
@@ -6654,7 +6754,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "person-praying" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person praying", "kneel", "place of worship", "religion", "thank", "worship" })]
+ [FontAwesomeSearchTerms(new[] { "person praying", "kneel", "place of worship", "religion", "thank", "uer", "worship" })]
[FontAwesomeCategoriesAttribute(new[] { "Religion", "Users + People" })]
Pray = 0xF683,
@@ -6703,7 +6803,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "diagram-project" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "diagram project", "chart", "graph", "network", "pert" })]
+ [FontAwesomeSearchTerms(new[] { "diagram project", "chart", "graph", "network", "pert", "statistics" })]
[FontAwesomeCategoriesAttribute(new[] { "Charts + Diagrams", "Coding" })]
ProjectDiagram = 0xF542,
@@ -6731,22 +6831,22 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "qrcode" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "qrcode", "barcode", "info", "information", "scan" })]
- [FontAwesomeCategoriesAttribute(new[] { "Coding" })]
+ [FontAwesomeSearchTerms(new[] { "qrcode", "barcode", "info", "information", "qr", "qr-code", "scan" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Coding", "Shopping" })]
Qrcode = 0xF029,
///
/// The Font Awesome "question" icon unicode character.
/// Uses a legacy unicode value for backwards compatability. The current unicode value is 0x3F.
///
- [FontAwesomeSearchTerms(new[] { "?", "question mark", "help", "information", "mark", "outlined", "punctuation", "question", "red question mark", "support", "unknown", "white question mark" })]
+ [FontAwesomeSearchTerms(new[] { "?", "question mark", "faq", "help", "information", "mark", "outlined", "punctuation", "question", "red question mark", "request", "support", "unknown", "white question mark" })]
[FontAwesomeCategoriesAttribute(new[] { "Accessibility", "Alert", "Punctuation + Symbols" })]
Question = 0xF128,
///
/// The Font Awesome "circle-question" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "circle question", "help", "information", "support", "unknown" })]
+ [FontAwesomeSearchTerms(new[] { "circle question", "faq", "help", "information", "support", "unknown" })]
[FontAwesomeCategoriesAttribute(new[] { "Accessibility", "Punctuation + Symbols" })]
QuestionCircle = 0xF059,
@@ -6816,14 +6916,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "ranking-star" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "ranking star", "chart", "first place", "podium", "rank", "win" })]
+ [FontAwesomeSearchTerms(new[] { "ranking star", "chart", "first place", "podium", "quality", "rank", "revenue", "win" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Marketing", "Sports + Fitness" })]
RankingStar = 0xE561,
///
/// The Font Awesome "receipt" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "accounting", "bookkeeping", "check", "evidence", "invoice", "money", "pay", "proof", "receipt", "table" })]
+ [FontAwesomeSearchTerms(new[] { "accounting", "bookkeeping", "check", "coupon", "evidence", "invoice", "money", "pay", "proof", "receipt", "table" })]
[FontAwesomeCategoriesAttribute(new[] { "Medical + Health", "Money", "Shopping" })]
Receipt = 0xF543,
@@ -6844,15 +6944,15 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "arrow-rotate-right" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrow rotate right", "clockwise open circle arrow", "forward", "refresh", "reload", "repeat" })]
- [FontAwesomeCategoriesAttribute(new[] { "Arrows", "Media Playback" })]
+ [FontAwesomeSearchTerms(new[] { "arrow rotate right", "clockwise open circle arrow", "forward", "refresh", "reload", "renew", "repeat", "retry" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Arrows", "Media Playback", "Spinners" })]
Redo = 0xF01E,
///
/// The Font Awesome "rotate-right" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "rotate right", "forward", "refresh", "reload", "repeat" })]
- [FontAwesomeCategoriesAttribute(new[] { "Arrows", "Media Playback" })]
+ [FontAwesomeSearchTerms(new[] { "rotate right", "forward", "refresh", "reload", "renew", "repeat", "retry" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Arrows", "Media Playback", "Spinners" })]
RedoAlt = 0xF2F9,
///
@@ -6865,14 +6965,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "text-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "text slash", "cancel", "font", "format", "remove", "style", "text" })]
+ [FontAwesomeSearchTerms(new[] { "text slash", "cancel", "disabled", "font", "format", "remove", "style", "text" })]
[FontAwesomeCategoriesAttribute(new[] { "Text Formatting" })]
RemoveFormat = 0xF87D,
///
/// The Font Awesome "repeat" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrow", "clockwise", "flip", "reload", "repeat", "repeat button", "rewind", "switch" })]
+ [FontAwesomeSearchTerms(new[] { "arrow", "clockwise", "flip", "reload", "renew", "repeat", "repeat button", "retry", "rewind", "switch" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows", "Media Playback" })]
Repeat = 0xF363,
@@ -6900,14 +7000,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "restroom" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "restroom", "bathroom", "toilet", "water closet", "wc" })]
+ [FontAwesomeSearchTerms(new[] { "restroom", "bathroom", "toilet", "uer", "water closet", "wc" })]
[FontAwesomeCategoriesAttribute(new[] { "Maps", "Users + People" })]
Restroom = 0xF7BD,
///
/// The Font Awesome "retweet" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "retweet", "refresh", "reload", "share", "swap" })]
+ [FontAwesomeSearchTerms(new[] { "retweet", "refresh", "reload", "renew", "retry", "share", "swap" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows", "Social" })]
Retweet = 0xF079,
@@ -6921,7 +7021,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "ring" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "ring", "dungeons & dragons", "gollum", "band", "binding", "d&d", "dnd", "engagement", "fantasy", "gold", "jewelry", "marriage", "precious" })]
+ [FontAwesomeSearchTerms(new[] { "ring", "dungeons & dragons", "gollum", "band", "binding", "d&d", "dnd", "engagement", "fantasy", "gold", "jewelry", "marriage", "precious", "premium" })]
[FontAwesomeCategoriesAttribute(new[] { "Gaming", "Spinners" })]
Ring = 0xF70B,
@@ -6949,28 +7049,28 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "road-circle-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "road circle check", "freeway", "highway", "not affected", "ok", "okay", "pavement", "road" })]
+ [FontAwesomeSearchTerms(new[] { "road circle check", "enable", "freeway", "highway", "not affected", "ok", "okay", "pavement", "road", "validate", "working" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Logistics" })]
RoadCircleCheck = 0xE564,
///
/// The Font Awesome "road-circle-exclamation" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "road circle exclamation", "affected", "freeway", "highway", "pavement", "road" })]
+ [FontAwesomeSearchTerms(new[] { "road circle exclamation", "affected", "failed", "freeway", "highway", "pavement", "road" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Logistics" })]
RoadCircleExclamation = 0xE565,
///
/// The Font Awesome "road-circle-xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "road circle xmark", "destroy", "freeway", "highway", "pavement", "road" })]
+ [FontAwesomeSearchTerms(new[] { "road circle xmark", "destroy", "freeway", "highway", "pavement", "road", "uncheck" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Logistics" })]
RoadCircleXmark = 0xE566,
///
/// The Font Awesome "road-lock" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "road lock", "closed", "freeway", "highway", "lockdown", "pavement", "quarantine", "road" })]
+ [FontAwesomeSearchTerms(new[] { "road lock", "closed", "freeway", "highway", "lockdown", "padlock", "pavement", "privacy", "quarantine", "road" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Logistics" })]
RoadLock = 0xE567,
@@ -7061,7 +7161,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "person-running" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person running", "exit", "flee", "marathon", "person running", "race", "running" })]
+ [FontAwesomeSearchTerms(new[] { "person running", "exit", "flee", "follow", "marathon", "person running", "race", "running", "uer", "workout" })]
[FontAwesomeCategoriesAttribute(new[] { "Sports + Fitness", "Users + People" })]
Running = 0xF70C,
@@ -7082,14 +7182,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "sack-dollar" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "sack dollar", "bag", "burlap", "cash", "dollar", "money", "money bag", "moneybag", "robber", "santa", "usd" })]
+ [FontAwesomeSearchTerms(new[] { "sack dollar", "bag", "burlap", "cash", "dollar", "investment", "money", "money bag", "moneybag", "premium", "robber", "salary", "santa", "usd" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Money" })]
SackDollar = 0xF81D,
///
/// The Font Awesome "sack-xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "sack xmark", "bag", "burlap", "rations" })]
+ [FontAwesomeSearchTerms(new[] { "sack xmark", "bag", "burlap", "coupon", "rations", "salary", "uncheck" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Money" })]
SackXmark = 0xE56A,
@@ -7145,21 +7245,21 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "school-circle-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "school circle check", "not affected", "ok", "okay", "schoolhouse" })]
+ [FontAwesomeSearchTerms(new[] { "school circle check", "enable", "not affected", "ok", "okay", "schoolhouse", "validate", "working" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Education", "Humanitarian" })]
SchoolCircleCheck = 0xE56B,
///
/// The Font Awesome "school-circle-exclamation" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "school circle exclamation", "affected", "schoolhouse" })]
+ [FontAwesomeSearchTerms(new[] { "school circle exclamation", "affected", "failed", "schoolhouse" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Education", "Humanitarian" })]
SchoolCircleExclamation = 0xE56C,
///
/// The Font Awesome "school-circle-xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "school circle xmark", "destroy", "schoolhouse" })]
+ [FontAwesomeSearchTerms(new[] { "school circle xmark", "destroy", "schoolhouse", "uncheck" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Education", "Humanitarian" })]
SchoolCircleXmark = 0xE56D,
@@ -7173,63 +7273,63 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "school-lock" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "school lock", "closed", "lockdown", "quarantine", "schoolhouse" })]
+ [FontAwesomeSearchTerms(new[] { "school lock", "closed", "lockdown", "padlock", "privacy", "quarantine", "schoolhouse" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Education", "Humanitarian" })]
SchoolLock = 0xE56F,
///
/// The Font Awesome "screwdriver" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "admin", "fix", "mechanic", "repair", "screw", "screwdriver", "settings", "tool" })]
+ [FontAwesomeSearchTerms(new[] { "admin", "configuration", "equipment", "fix", "maintenance", "mechanic", "modify", "repair", "screw", "screwdriver", "settings", "tool" })]
[FontAwesomeCategoriesAttribute(new[] { "Construction" })]
Screwdriver = 0xF54A,
///
/// The Font Awesome "scroll" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "dungeons & dragons", "announcement", "d&d", "dnd", "fantasy", "paper", "script", "scroll" })]
+ [FontAwesomeSearchTerms(new[] { "dungeons & dragons", "announcement", "d&d", "dnd", "fantasy", "paper", "scholar", "script", "scroll" })]
[FontAwesomeCategoriesAttribute(new[] { "Gaming" })]
Scroll = 0xF70E,
///
/// The Font Awesome "sd-card" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "sd card", "image", "memory", "photo", "save" })]
+ [FontAwesomeSearchTerms(new[] { "sd card", "image", "img", "memory", "photo", "save" })]
[FontAwesomeCategoriesAttribute(new[] { "Devices + Hardware" })]
SdCard = 0xF7C2,
///
/// The Font Awesome "magnifying-glass" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "magnifying glass", "bigger", "enlarge", "find", "glass", "magnify", "magnifying", "magnifying glass tilted left", "preview", "search", "tool", "zoom" })]
+ [FontAwesomeSearchTerms(new[] { "magnifying glass", "bigger", "enlarge", "equipment", "find", "glass", "inspection", "magnifier", "magnify", "magnifying", "magnifying glass tilted left", "preview", "search", "tool", "zoom" })]
[FontAwesomeCategoriesAttribute(new[] { "Maps" })]
Search = 0xF002,
///
/// The Font Awesome "magnifying-glass-dollar" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "magnifying glass dollar", "bigger", "enlarge", "find", "magnify", "money", "preview", "zoom" })]
+ [FontAwesomeSearchTerms(new[] { "magnifying glass dollar", "bigger", "enlarge", "find", "magnifier", "magnify", "money", "preview", "zoom" })]
[FontAwesomeCategoriesAttribute(new[] { "Marketing" })]
SearchDollar = 0xF688,
///
/// The Font Awesome "magnifying-glass-location" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "magnifying glass location", "bigger", "enlarge", "find", "magnify", "preview", "zoom" })]
- [FontAwesomeCategoriesAttribute(new[] { "Marketing" })]
+ [FontAwesomeSearchTerms(new[] { "magnifying glass location", "bigger", "enlarge", "find", "magnifier", "magnify", "preview", "zoom" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Maps", "Marketing" })]
SearchLocation = 0xF689,
///
/// The Font Awesome "magnifying-glass-minus" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "magnifying glass minus", "minify", "negative", "smaller", "zoom", "zoom out" })]
+ [FontAwesomeSearchTerms(new[] { "magnifying glass minus", "magnifier", "minify", "negative", "smaller", "zoom", "zoom out" })]
[FontAwesomeCategoriesAttribute(new[] { "Maps" })]
SearchMinus = 0xF010,
///
/// The Font Awesome "magnifying-glass-plus" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "magnifying glass plus", "bigger", "enlarge", "magnify", "positive", "zoom", "zoom in" })]
+ [FontAwesomeSearchTerms(new[] { "magnifying glass plus", "bigger", "enlarge", "magnifier", "magnify", "positive", "zoom", "zoom in" })]
[FontAwesomeCategoriesAttribute(new[] { "Maps" })]
SearchPlus = 0xF00E,
@@ -7243,14 +7343,21 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "seedling" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "environment", "flora", "grow", "plant", "sapling", "seedling", "vegan", "young" })]
+ [FontAwesomeSearchTerms(new[] { "environment", "flora", "grow", "investment", "plant", "sapling", "seedling", "vegan", "young" })]
[FontAwesomeCategoriesAttribute(new[] { "Charity", "Energy", "Food + Beverage", "Fruits + Vegetables", "Humanitarian", "Nature", "Science" })]
Seedling = 0xF4D8,
+ ///
+ /// The Font Awesome "septagon" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "septagon", "7", "heptagon", "seven", "shape" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Shapes" })]
+ Septagon = 0xE820,
+
///
/// The Font Awesome "server" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "server", "computer", "cpu", "database", "hardware", "network" })]
+ [FontAwesomeSearchTerms(new[] { "server", "computer", "cpu", "database", "hardware", "mysql", "network", "sql" })]
[FontAwesomeCategoriesAttribute(new[] { "Devices + Hardware" })]
Server = 0xF233,
@@ -7313,7 +7420,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "shield-halved" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "shield halved", "achievement", "armor", "award", "block", "cleric", "defend", "defense", "holy", "paladin", "security", "shield", "weapon", "winner" })]
+ [FontAwesomeSearchTerms(new[] { "shield halved", "achievement", "armor", "award", "block", "cleric", "defend", "defense", "holy", "paladin", "privacy", "security", "shield", "weapon", "winner" })]
[FontAwesomeCategoriesAttribute(new[] { "Coding", "Gaming", "Security" })]
ShieldAlt = 0xF3ED,
@@ -7334,7 +7441,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "shield-heart" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "shield heart", "love", "protect", "safe", "safety", "shield" })]
+ [FontAwesomeSearchTerms(new[] { "shield heart", "love", "protect", "safe", "safety", "shield", "wishlist" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Security" })]
ShieldHeart = 0xE574,
@@ -7355,7 +7462,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "truck-fast" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "truck fast", "express", "fedex", "mail", "overnight", "package", "ups" })]
+ [FontAwesomeSearchTerms(new[] { "truck fast", "express", "fedex", "mail", "overnight", "package", "quick", "ups" })]
[FontAwesomeCategoriesAttribute(new[] { "Logistics", "Shopping" })]
ShippingFast = 0xF48B,
@@ -7369,7 +7476,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "shop-lock" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "shop lock", "bodega", "building", "buy", "closed", "lock", "lockdown", "market", "purchase", "quarantine", "shop", "shopping", "store" })]
+ [FontAwesomeSearchTerms(new[] { "shop lock", "bodega", "building", "buy", "closed", "lock", "lockdown", "market", "padlock", "privacy", "purchase", "quarantine", "shop", "shopping", "store" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Humanitarian", "Shopping" })]
ShopLock = 0xE4A5,
@@ -7397,7 +7504,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "shop-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "shop slash", "building", "buy", "closed", "covid-19", "purchase", "shopping" })]
+ [FontAwesomeSearchTerms(new[] { "shop slash", "building", "buy", "closed", "disabled", "purchase", "shopping" })]
[FontAwesomeCategoriesAttribute(new[] { "Shopping" })]
ShopSlash = 0xE070,
@@ -7418,7 +7525,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "van-shuttle" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "van shuttle", "airport", "bus", "machine", "minibus", "public-transportation", "transportation", "travel", "vehicle" })]
+ [FontAwesomeSearchTerms(new[] { "van shuttle", "airport", "bus", "minibus", "public-transportation", "transportation", "travel", "vehicle" })]
[FontAwesomeCategoriesAttribute(new[] { "Automotive", "Transportation", "Travel + Hotel" })]
ShuttleVan = 0xF5B6,
@@ -7439,7 +7546,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "signature" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "signature", "john hancock", "cursive", "name", "writing" })]
+ [FontAwesomeSearchTerms(new[] { "signature", "john hancock", "cursive", "name", "username", "writing" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Editing", "Writing" })]
Signature = 0xF5B7,
@@ -7471,6 +7578,20 @@ public enum FontAwesomeIcon
[FontAwesomeCategoriesAttribute(new[] { "Devices + Hardware" })]
SimCard = 0xF7C4,
+ ///
+ /// The Font Awesome "single-quote-left" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "single quote left", "left single quotation mark", "mention", "note", "phrase", "text", "type" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Communication", "Punctuation + Symbols", "Writing" })]
+ SingleQuoteLeft = 0xE81B,
+
+ ///
+ /// The Font Awesome "single-quote-right" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "single quote right", "mention", "note", "phrase", "right single quotation mark", "text", "type" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Communication", "Punctuation + Symbols", "Writing" })]
+ SingleQuoteRight = 0xE81C,
+
///
/// The Font Awesome "sink" icon unicode character.
///
@@ -7488,28 +7609,28 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "person-skating" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person skating", "figure skating", "ice", "olympics", "rink", "skate", "winter" })]
+ [FontAwesomeSearchTerms(new[] { "person skating", "figure skating", "ice", "olympics", "rink", "skate", "uer", "winter" })]
[FontAwesomeCategoriesAttribute(new[] { "Sports + Fitness", "Users + People" })]
Skating = 0xF7C5,
///
/// The Font Awesome "person-skiing" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person skiing", "downhill", "olympics", "ski", "skier", "snow", "winter" })]
+ [FontAwesomeSearchTerms(new[] { "person skiing", "downhill", "olympics", "ski", "skier", "snow", "uer", "winter" })]
[FontAwesomeCategoriesAttribute(new[] { "Sports + Fitness", "Users + People" })]
Skiing = 0xF7C9,
///
/// The Font Awesome "person-skiing-nordic" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person skiing nordic", "cross country", "olympics", "winter" })]
+ [FontAwesomeSearchTerms(new[] { "person skiing nordic", "cross country", "olympics", "uer", "winter" })]
[FontAwesomeCategoriesAttribute(new[] { "Sports + Fitness", "Users + People" })]
SkiingNordic = 0xF7CA,
///
/// The Font Awesome "skull" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "bones", "death", "face", "fairy tale", "monster", "skeleton", "skull", "x-ray", "yorick" })]
+ [FontAwesomeSearchTerms(new[] { "bones", "death", "face", "fairy tale", "monster", "skeleton", "skull", "uer", "x-ray", "yorick" })]
[FontAwesomeCategoriesAttribute(new[] { "Halloween", "Medical + Health", "Users + People" })]
Skull = 0xF54C,
@@ -7537,14 +7658,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "sliders" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "adjust", "settings", "sliders", "toggle" })]
- [FontAwesomeCategoriesAttribute(new[] { "Editing", "Media Playback", "Music + Audio", "Photos + Images" })]
+ [FontAwesomeSearchTerms(new[] { "adjust", "configuration", "modify", "settings", "sliders", "toggle" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Editing", "Media Playback", "Music + Audio", "Photos + Images", "Toggle" })]
SlidersH = 0xF1DE,
///
/// The Font Awesome "face-smile" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "face smile", "approve", "emoticon", "face", "happy", "rating", "satisfied", "slightly smiling face", "smile" })]
+ [FontAwesomeSearchTerms(new[] { "face smile", "approve", "default", "emoticon", "face", "happy", "rating", "satisfied", "slightly smiling face", "smile", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Communication", "Emoji", "Users + People" })]
Smile = 0xF118,
@@ -7579,21 +7700,21 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "ban-smoking" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "ban smoking", "ban", "cancel", "forbidden", "no", "no smoking", "non-smoking", "not", "prohibited", "smoking" })]
+ [FontAwesomeSearchTerms(new[] { "ban smoking", "ban", "cancel", "circle", "deny", "disabled", "forbidden", "no", "no smoking", "non-smoking", "not", "prohibited", "slash", "smoking" })]
[FontAwesomeCategoriesAttribute(new[] { "Medical + Health", "Travel + Hotel" })]
SmokingBan = 0xF54D,
///
/// The Font Awesome "comment-sms" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "comment sms", "chat", "conversation", "message", "mobile", "notification", "phone", "sms", "texting" })]
+ [FontAwesomeSearchTerms(new[] { "comment sms", "answer", "chat", "conversation", "message", "mobile", "notification", "phone", "sms", "texting" })]
[FontAwesomeCategoriesAttribute(new[] { "Communication" })]
Sms = 0xF7CD,
///
/// The Font Awesome "person-snowboarding" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person snowboarding", "olympics", "ski", "snow", "snowboard", "snowboarder", "winter" })]
+ [FontAwesomeSearchTerms(new[] { "person snowboarding", "olympics", "ski", "snow", "snowboard", "snowboarder", "uer", "winter" })]
[FontAwesomeCategoriesAttribute(new[] { "Sports + Fitness", "Users + People" })]
Snowboarding = 0xF7CE,
@@ -7691,7 +7812,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "arrow-up-wide-short" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrow up wide short", "arrange", "filter", "order", "sort-amount-desc" })]
+ [FontAwesomeSearchTerms(new[] { "arrow up wide short", "arrange", "filter", "order", "sort-amount-desc", "upgrade" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
SortAmountUp = 0xF161,
@@ -7705,7 +7826,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "sort-down" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "sort down", "arrow", "descending", "filter", "order", "sort-desc" })]
+ [FontAwesomeSearchTerms(new[] { "sort down", "arrow", "descending", "filter", "insert", "order", "sort-desc" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
SortDown = 0xF0DD,
@@ -7740,7 +7861,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "sort-up" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "sort up", "arrow", "ascending", "filter", "order", "sort-asc" })]
+ [FontAwesomeSearchTerms(new[] { "sort up", "arrow", "ascending", "filter", "order", "sort-asc", "upgrade" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
SortUp = 0xF0DE,
@@ -7761,7 +7882,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "spell-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "spell check", "dictionary", "edit", "editor", "grammar", "text" })]
+ [FontAwesomeSearchTerms(new[] { "spell check", "dictionary", "edit", "editor", "enable", "grammar", "text", "validate", "working" })]
[FontAwesomeCategoriesAttribute(new[] { "Text Formatting" })]
SpellCheck = 0xF891,
@@ -7775,10 +7896,17 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "spinner" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "spinner", "circle", "loading", "progress" })]
+ [FontAwesomeSearchTerms(new[] { "spinner", "circle", "loading", "pending", "progress" })]
[FontAwesomeCategoriesAttribute(new[] { "Spinners" })]
Spinner = 0xF110,
+ ///
+ /// The Font Awesome "spiral" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "spiral", "design", "dizzy", "rotate", "spin", "swirl", "twist" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Design", "Shapes" })]
+ Spiral = 0xE80A,
+
///
/// The Font Awesome "splotch" icon unicode character.
///
@@ -7807,6 +7935,13 @@ public enum FontAwesomeIcon
[FontAwesomeCategoriesAttribute(new[] { "Arrows" })]
SquareArrowUpRight = 0xF14C,
+ ///
+ /// The Font Awesome "square-binary" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "square binary", "ai", "data", "language", "llm", "model", "programming", "token" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Coding", "Shapes" })]
+ SquareBinary = 0xE69B,
+
///
/// The Font Awesome "square-full" icon unicode character.
///
@@ -7824,7 +7959,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "square-person-confined" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "square person confined", "captivity", "confined" })]
+ [FontAwesomeSearchTerms(new[] { "square person confined", "captivity", "confined", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Security", "Users + People" })]
SquarePersonConfined = 0xE577,
@@ -7845,7 +7980,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "square-xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "square xmark", "close", "cross", "cross mark button", "incorrect", "mark", "notice", "notification", "notify", "problem", "square", "window", "wrong", "x", "×" })]
+ [FontAwesomeSearchTerms(new[] { "square xmark", "close", "cross", "cross mark button", "incorrect", "mark", "notice", "notification", "notify", "problem", "square", "uncheck", "window", "wrong", "x", "×" })]
[FontAwesomeCategoriesAttribute(new[] { "Mathematics" })]
SquareXmark = 0xF2D3,
@@ -7880,7 +8015,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "star" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "achievement", "award", "favorite", "important", "night", "rating", "score", "star" })]
+ [FontAwesomeSearchTerms(new[] { "achievement", "award", "favorite", "important", "night", "quality", "rating", "score", "star", "vip" })]
[FontAwesomeCategoriesAttribute(new[] { "Shapes", "Shopping", "Social", "Toggle" })]
Star = 0xF005,
@@ -7964,7 +8099,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "stopwatch" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "clock", "reminder", "stopwatch", "time" })]
+ [FontAwesomeSearchTerms(new[] { "clock", "reminder", "stopwatch", "time", "waiting" })]
[FontAwesomeCategoriesAttribute(new[] { "Time" })]
Stopwatch = 0xF2F2,
@@ -7992,7 +8127,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "store-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "store slash", "building", "buy", "closed", "covid-19", "purchase", "shopping" })]
+ [FontAwesomeSearchTerms(new[] { "store slash", "building", "buy", "closed", "disabled", "purchase", "shopping" })]
[FontAwesomeCategoriesAttribute(new[] { "Shopping" })]
StoreSlash = 0xE071,
@@ -8006,14 +8141,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "street-view" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "street view", "directions", "location", "map", "navigation" })]
+ [FontAwesomeSearchTerms(new[] { "street view", "directions", "location", "map", "navigation", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Maps", "Users + People" })]
StreetView = 0xF21D,
///
/// The Font Awesome "strikethrough" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "strikethrough", "cancel", "edit", "font", "format", "text", "type" })]
+ [FontAwesomeSearchTerms(new[] { "strikethrough", "cancel", "edit", "font", "format", "modify", "text", "type" })]
[FontAwesomeCategoriesAttribute(new[] { "Text Formatting" })]
Strikethrough = 0xF0CC,
@@ -8090,7 +8225,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "person-swimming" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person swimming", "ocean", "person swimming", "pool", "sea", "swim", "water" })]
+ [FontAwesomeSearchTerms(new[] { "person swimming", "ocean", "person swimming", "pool", "sea", "swim", "uer", "water" })]
[FontAwesomeCategoriesAttribute(new[] { "Maritime", "Sports + Fitness", "Travel + Hotel", "Users + People" })]
Swimmer = 0xF5C4,
@@ -8111,14 +8246,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "arrows-rotate" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "arrows rotate", "clockwise right and left semicircle arrows", "exchange", "refresh", "reload", "rotate", "swap" })]
- [FontAwesomeCategoriesAttribute(new[] { "Arrows", "Editing", "Media Playback" })]
+ [FontAwesomeSearchTerms(new[] { "arrows rotate", "clockwise right and left semicircle arrows", "clockwise", "exchange", "modify", "refresh", "reload", "renew", "retry", "rotate", "swap" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Arrows", "Editing", "Media Playback", "Spinners" })]
Sync = 0xF021,
///
/// The Font Awesome "rotate" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "anticlockwise", "arrow", "counterclockwise", "counterclockwise arrows button", "exchange", "refresh", "reload", "rotate", "swap", "withershins" })]
+ [FontAwesomeSearchTerms(new[] { "arrow", "clockwise", "exchange", "modify", "refresh", "reload", "renew", "retry", "rotate", "swap", "withershins" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows", "Editing", "Media Playback", "Spinners" })]
SyncAlt = 0xF2F1,
@@ -8132,10 +8267,31 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "table" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "table", "data", "excel", "spreadsheet" })]
+ [FontAwesomeSearchTerms(new[] { "table", "category", "data", "excel", "spreadsheet" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Text Formatting" })]
Table = 0xF0CE,
+ ///
+ /// The Font Awesome "table-cells-column-lock" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "table cells column lock", "blocks", "boxes", "category", "column", "excel", "grid", "lock", "spreadsheet", "squares" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Text Formatting" })]
+ TableCellsColumnLock = 0xE678,
+
+ ///
+ /// The Font Awesome "table-cells-row-lock" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "table cells row lock", "blocks", "boxes", "category", "column", "column", "excel", "grid", "lock", "lock", "spreadsheet", "squares" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Text Formatting" })]
+ TableCellsRowLock = 0xE67A,
+
+ ///
+ /// The Font Awesome "table-cells-row-unlock" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "table cells row unlock", "blocks", "boxes", "category", "column", "column", "excel", "grid", "lock", "lock", "spreadsheet", "squares", "unlock" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Text Formatting" })]
+ TableCellsRowUnlock = 0xE691,
+
///
/// The Font Awesome "tablet" icon unicode character.
///
@@ -8175,7 +8331,7 @@ public enum FontAwesomeIcon
/// The Font Awesome "gauge-high" icon unicode character.
/// Uses a legacy unicode value for backwards compatability. The current unicode value is 0xF625.
///
- [FontAwesomeSearchTerms(new[] { "gauge high", "dashboard", "fast", "odometer", "speed", "speedometer" })]
+ [FontAwesomeSearchTerms(new[] { "gauge high", "dashboard", "fast", "odometer", "quick", "speed", "speedometer" })]
[FontAwesomeCategoriesAttribute(new[] { "Automotive" })]
TachometerAlt = 0xF3FD,
@@ -8217,7 +8373,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "list-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "list check", "checklist", "downloading", "downloads", "loading", "progress", "project management", "settings", "to do" })]
+ [FontAwesomeSearchTerms(new[] { "list check", "bullet", "cheatsheet", "checklist", "downloading", "downloads", "enable", "loading", "progress", "project management", "settings", "summary", "to do", "validate", "working" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Text Formatting" })]
Tasks = 0xF0AE,
@@ -8280,42 +8436,42 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "tent" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "bivouac", "campground", "refugee", "shelter", "tent" })]
+ [FontAwesomeSearchTerms(new[] { "bivouac", "campground", "campsite", "refugee", "shelter", "tent" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Camping", "Humanitarian" })]
Tent = 0xE57D,
///
/// The Font Awesome "tent-arrow-down-to-line" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "tent arrow down to line", "permanent", "refugee", "shelter" })]
+ [FontAwesomeSearchTerms(new[] { "tent arrow down to line", "bivouac", "campground", "campsite", "permanent", "refugee", "refugee", "shelter", "shelter", "tent" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Camping", "Humanitarian" })]
TentArrowDownToLine = 0xE57E,
///
/// The Font Awesome "tent-arrow-left-right" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "tent arrow left right", "refugee", "shelter", "transition" })]
+ [FontAwesomeSearchTerms(new[] { "tent arrow left right", "bivouac", "campground", "campsite", "refugee", "refugee", "shelter", "shelter", "tent", "transition" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Camping", "Humanitarian" })]
TentArrowLeftRight = 0xE57F,
///
/// The Font Awesome "tent-arrows-down" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "tent arrows down", "refugee", "shelter", "spontaneous" })]
+ [FontAwesomeSearchTerms(new[] { "tent arrows down", "bivouac", "campground", "campsite", "insert", "refugee", "refugee", "shelter", "shelter", "spontaneous", "tent" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Camping", "Humanitarian" })]
TentArrowsDown = 0xE581,
///
/// The Font Awesome "tent-arrow-turn-left" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "tent arrow turn left", "refugee", "shelter", "temporary" })]
+ [FontAwesomeSearchTerms(new[] { "tent arrow turn left", "bivouac", "campground", "campsite", "refugee", "refugee", "shelter", "shelter", "temporary", "tent" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Camping", "Humanitarian" })]
TentArrowTurnLeft = 0xE580,
///
/// The Font Awesome "tents" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "tents", "bivouac", "campground", "refugee", "shelter", "tent" })]
+ [FontAwesomeSearchTerms(new[] { "tents", "bivouac", "bivouac", "campground", "campground", "campsite", "refugee", "refugee", "shelter", "shelter", "tent", "tent" })]
[FontAwesomeCategoriesAttribute(new[] { "Buildings", "Camping", "Humanitarian" })]
Tents = 0xE582,
@@ -8329,21 +8485,21 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "text-height" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "text height", "edit", "font", "format", "text", "type" })]
+ [FontAwesomeSearchTerms(new[] { "text height", "edit", "font", "format", "modify", "text", "type" })]
[FontAwesomeCategoriesAttribute(new[] { "Text Formatting" })]
TextHeight = 0xF034,
///
/// The Font Awesome "text-width" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "text width", "edit", "font", "format", "text", "type" })]
+ [FontAwesomeSearchTerms(new[] { "text width", "edit", "font", "format", "modify", "text", "type" })]
[FontAwesomeCategoriesAttribute(new[] { "Text Formatting" })]
TextWidth = 0xF035,
///
/// The Font Awesome "table-cells" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "table cells", "blocks", "boxes", "grid", "squares" })]
+ [FontAwesomeSearchTerms(new[] { "table cells", "blocks", "boxes", "category", "excel", "grid", "spreadsheet", "squares" })]
[FontAwesomeCategoriesAttribute(new[] { "Text Formatting" })]
Th = 0xF00A,
@@ -8399,14 +8555,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "table-cells-large" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "table cells large", "blocks", "boxes", "grid", "squares" })]
+ [FontAwesomeSearchTerms(new[] { "table cells large", "blocks", "boxes", "category", "excel", "grid", "spreadsheet", "squares" })]
[FontAwesomeCategoriesAttribute(new[] { "Text Formatting" })]
ThLarge = 0xF009,
///
/// The Font Awesome "table-list" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "table list", "checklist", "completed", "done", "finished", "ol", "todo", "ul" })]
+ [FontAwesomeSearchTerms(new[] { "table list", "category", "cheatsheet", "checklist", "completed", "done", "finished", "ol", "summary", "todo", "ul" })]
[FontAwesomeCategoriesAttribute(new[] { "Text Formatting" })]
ThList = 0xF00B,
@@ -8431,17 +8587,24 @@ public enum FontAwesomeIcon
[FontAwesomeCategoriesAttribute(new[] { "Business", "Maps", "Social", "Writing" })]
Thumbtack = 0xF08D,
+ ///
+ /// The Font Awesome "thumbtack-slash" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "thumbtack slash", "black pushpin", "coordinates", "location", "marker", "pin", "pushpin", "thumb-tack", "unpin" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Business", "Maps", "Social", "Writing" })]
+ ThumbtackSlash = 0xE68F,
+
///
/// The Font Awesome "ticket" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "admission", "admission tickets", "movie", "pass", "support", "ticket" })]
+ [FontAwesomeSearchTerms(new[] { "admission", "admission tickets", "coupon", "movie", "pass", "support", "ticket", "voucher" })]
[FontAwesomeCategoriesAttribute(new[] { "Film + Video", "Maps" })]
Ticket = 0xF145,
///
/// The Font Awesome "ticket-simple" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "ticket simple", "movie", "pass", "support", "ticket" })]
+ [FontAwesomeSearchTerms(new[] { "ticket simple", "admission", "coupon", "movie", "pass", "support", "ticket", "voucher" })]
[FontAwesomeCategoriesAttribute(new[] { "Maps", "Shapes" })]
TicketAlt = 0xF3FF,
@@ -8455,29 +8618,29 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "xmark", "cancellation x", "multiplication sign", "multiplication x", "cancel", "close", "cross", "cross mark", "error", "exit", "incorrect", "mark", "multiplication", "multiply", "notice", "notification", "notify", "problem", "sign", "wrong", "x", "×" })]
+ [FontAwesomeSearchTerms(new[] { "xmark", "cancellation x", "multiplication sign", "multiplication x", "cancel", "close", "cross", "cross mark", "error", "exit", "incorrect", "mark", "multiplication", "multiply", "notice", "notification", "notify", "problem", "sign", "uncheck", "wrong", "x", "×" })]
[FontAwesomeCategoriesAttribute(new[] { "Editing", "Mathematics" })]
Times = 0xF00D,
///
/// The Font Awesome "circle-xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "circle xmark", "close", "cross", "destroy", "exit", "incorrect", "notice", "notification", "notify", "problem", "wrong", "x" })]
+ [FontAwesomeSearchTerms(new[] { "circle xmark", "close", "cross", "destroy", "exit", "incorrect", "notice", "notification", "notify", "problem", "uncheck", "wrong", "x" })]
[FontAwesomeCategoriesAttribute(new[] { "Mathematics" })]
TimesCircle = 0xF057,
///
/// The Font Awesome "droplet" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "cold", "color", "comic", "drop", "droplet", "raindrop", "sweat", "waterdrop" })]
- [FontAwesomeCategoriesAttribute(new[] { "Design", "Humanitarian", "Maps", "Photos + Images" })]
+ [FontAwesomeSearchTerms(new[] { "blood", "cold", "color", "comic", "drop", "droplet", "raindrop", "sweat", "waterdrop" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Design", "Humanitarian", "Maps", "Medical + Health", "Photos + Images" })]
Tint = 0xF043,
///
/// The Font Awesome "droplet-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "droplet slash", "color", "drop", "droplet", "raindrop", "waterdrop" })]
- [FontAwesomeCategoriesAttribute(new[] { "Design" })]
+ [FontAwesomeSearchTerms(new[] { "droplet slash", "blood", "color", "disabled", "drop", "droplet", "raindrop", "waterdrop" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Design", "Medical + Health" })]
TintSlash = 0xF5C7,
///
@@ -8518,7 +8681,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "toilet-paper-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "toilet paper slash", "bathroom", "covid-19", "halloween", "holiday", "lavatory", "leaves", "prank", "privy", "restroom", "roll", "toilet", "trouble", "ut oh", "wipe" })]
+ [FontAwesomeSearchTerms(new[] { "toilet paper slash", "bathroom", "covid-19", "disabled", "halloween", "holiday", "lavatory", "leaves", "prank", "privy", "restroom", "roll", "toilet", "trouble", "ut oh", "wipe" })]
[FontAwesomeCategoriesAttribute(new[] { "Household" })]
ToiletPaperSlash = 0xE072,
@@ -8539,14 +8702,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "toolbox" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "admin", "chest", "container", "fix", "mechanic", "repair", "settings", "tool", "toolbox", "tools" })]
+ [FontAwesomeSearchTerms(new[] { "admin", "chest", "configuration", "container", "equipment", "fix", "maintenance", "mechanic", "modify", "repair", "settings", "tool", "toolbox", "tools" })]
[FontAwesomeCategoriesAttribute(new[] { "Construction" })]
Toolbox = 0xF552,
///
/// The Font Awesome "screwdriver-wrench" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "screwdriver wrench", "admin", "fix", "repair", "screwdriver", "settings", "tools", "wrench" })]
+ [FontAwesomeSearchTerms(new[] { "screwdriver wrench", "admin", "configuration", "equipment", "fix", "maintenance", "modify", "repair", "screwdriver", "settings", "tools", "wrench" })]
[FontAwesomeCategoriesAttribute(new[] { "Construction" })]
Tools = 0xF7D9,
@@ -8581,7 +8744,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "tower-cell" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "tower cell", "airwaves", "antenna", "communication", "radio", "reception", "waves" })]
+ [FontAwesomeSearchTerms(new[] { "tower cell", "airwaves", "antenna", "communication", "radio", "reception", "signal", "waves" })]
[FontAwesomeCategoriesAttribute(new[] { "Communication", "Connectivity", "Film + Video", "Humanitarian" })]
TowerCell = 0xE585,
@@ -8609,7 +8772,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "traffic-light" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "traffic light", "direction", "light", "road", "signal", "traffic", "travel", "vertical traffic light" })]
+ [FontAwesomeSearchTerms(new[] { "traffic light", "direction", "go", "light", "road", "signal", "slow", "stop", "traffic", "travel", "vertical traffic light" })]
[FontAwesomeCategoriesAttribute(new[] { "Maps" })]
TrafficLight = 0xF637,
@@ -8665,21 +8828,21 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "trash-arrow-up" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "trash arrow up", "back", "control z", "delete", "garbage", "hide", "oops", "remove", "undo" })]
+ [FontAwesomeSearchTerms(new[] { "trash arrow up", "back", "control z", "delete", "garbage", "hide", "oops", "remove", "undo", "upgrade" })]
[FontAwesomeCategoriesAttribute(new[] { "Editing" })]
TrashRestore = 0xF829,
///
/// The Font Awesome "trash-can-arrow-up" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "trash can arrow up", "back", "control z", "delete", "garbage", "hide", "oops", "remove", "undo" })]
+ [FontAwesomeSearchTerms(new[] { "trash can arrow up", "back", "control z", "delete", "garbage", "hide", "oops", "remove", "undo", "upgrade" })]
[FontAwesomeCategoriesAttribute(new[] { "Editing" })]
TrashRestoreAlt = 0xF82A,
///
/// The Font Awesome "tree" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "bark", "evergreen tree", "fall", "flora", "forest", "nature", "plant", "seasonal", "tree" })]
+ [FontAwesomeSearchTerms(new[] { "bark", "evergreen tree", "fall", "flora", "forest", "investment", "nature", "plant", "seasonal", "tree" })]
[FontAwesomeCategoriesAttribute(new[] { "Camping", "Maps", "Nature" })]
Tree = 0xF1BB,
@@ -8700,14 +8863,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "trowel" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "trowel", "build", "construction", "tool" })]
+ [FontAwesomeSearchTerms(new[] { "trowel", "build", "construction", "equipment", "maintenance", "tool" })]
[FontAwesomeCategoriesAttribute(new[] { "Construction", "Humanitarian" })]
Trowel = 0xE589,
///
/// The Font Awesome "trowel-bricks" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "trowel bricks", "build", "construction", "reconstruction", "tool" })]
+ [FontAwesomeSearchTerms(new[] { "trowel bricks", "build", "construction", "maintenance", "reconstruction", "tool" })]
[FontAwesomeCategoriesAttribute(new[] { "Construction", "Humanitarian" })]
TrowelBricks = 0xE58A,
@@ -8728,8 +8891,8 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "truck-droplet" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "truck droplet", "thirst", "truck", "water", "water supply" })]
- [FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Transportation" })]
+ [FontAwesomeSearchTerms(new[] { "truck droplet", "blood", "thirst", "truck", "water", "water supply" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Medical + Health", "Transportation" })]
TruckDroplet = 0xE58C,
///
@@ -8777,7 +8940,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "truck-pickup" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "truck pickup", "cargo", "pick-up", "pickup", "pickup truck", "truck", "vehicle" })]
+ [FontAwesomeSearchTerms(new[] { "truck pickup", "cargo", "maintenance", "pick-up", "pickup", "pickup truck", "truck", "vehicle" })]
[FontAwesomeCategoriesAttribute(new[] { "Automotive", "Construction", "Transportation" })]
TruckPickup = 0xF63C,
@@ -8833,7 +8996,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "underline" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "underline", "edit", "emphasis", "format", "text", "writing" })]
+ [FontAwesomeSearchTerms(new[] { "underline", "edit", "emphasis", "format", "modify", "text", "writing" })]
[FontAwesomeCategoriesAttribute(new[] { "Text Formatting" })]
Underline = 0xF0CD,
@@ -8841,20 +9004,20 @@ public enum FontAwesomeIcon
/// The Font Awesome "arrow-rotate-left" icon unicode character.
///
[FontAwesomeSearchTerms(new[] { "arrow rotate left", "anticlockwise open circle arrow", "back", "control z", "exchange", "oops", "return", "rotate", "swap" })]
- [FontAwesomeCategoriesAttribute(new[] { "Arrows", "Media Playback" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Arrows", "Media Playback", "Spinners" })]
Undo = 0xF0E2,
///
/// The Font Awesome "rotate-left" icon unicode character.
///
[FontAwesomeSearchTerms(new[] { "rotate left", "back", "control z", "exchange", "oops", "return", "swap" })]
- [FontAwesomeCategoriesAttribute(new[] { "Arrows", "Media Playback" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Arrows", "Media Playback", "Spinners" })]
UndoAlt = 0xF2EA,
///
/// The Font Awesome "universal-access" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "universal access", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "universal access", "uer", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Accessibility" })]
UniversalAccess = 0xF29A,
@@ -8868,252 +9031,254 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "link-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "link slash", "attachment", "chain", "chain-broken", "remove" })]
+ [FontAwesomeSearchTerms(new[] { "link slash", "attachment", "chain", "chain-broken", "disabled", "disconnect", "remove" })]
[FontAwesomeCategoriesAttribute(new[] { "Editing" })]
Unlink = 0xF127,
///
/// The Font Awesome "unlock" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "admin", "lock", "open", "password", "private", "protect", "unlock", "unlocked" })]
+ [FontAwesomeSearchTerms(new[] { "admin", "lock", "open", "padlock", "password", "privacy", "private", "protect", "unlock", "unlocked" })]
[FontAwesomeCategoriesAttribute(new[] { "Security" })]
Unlock = 0xF09C,
///
/// The Font Awesome "unlock-keyhole" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "unlock keyhole", "admin", "lock", "password", "private", "protect" })]
+ [FontAwesomeSearchTerms(new[] { "unlock keyhole", "admin", "lock", "padlock", "password", "privacy", "private", "protect" })]
[FontAwesomeCategoriesAttribute(new[] { "Security" })]
UnlockAlt = 0xF13E,
///
/// The Font Awesome "upload" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "upload", "hard drive", "import", "publish" })]
+ [FontAwesomeSearchTerms(new[] { "upload", "hard drive", "import", "publish", "upgrade" })]
[FontAwesomeCategoriesAttribute(new[] { "Arrows", "Devices + Hardware" })]
Upload = 0xF093,
///
/// The Font Awesome "user" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user", "adult", "bust", "bust in silhouette", "gender-neutral", "person", "profile", "silhouette", "unspecified gender", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "user", "adult", "bust", "bust in silhouette", "default", "employee", "gender-neutral", "person", "profile", "silhouette", "uer", "unspecified gender", "username", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Social", "Users + People" })]
User = 0xF007,
///
- /// The Font Awesome "user-large" icon unicode character.
+ /// The Font Awesome "user" icon unicode character.
+ /// Uses a legacy unicode value for backwards compatability. The current unicode value is 0xF007.
///
- [FontAwesomeSearchTerms(new[] { "user large", "users-people" })]
- [FontAwesomeCategoriesAttribute(new[] { "Users + People" })]
+ [FontAwesomeSearchTerms(new[] { "user", "adult", "bust", "bust in silhouette", "default", "employee", "gender-neutral", "person", "profile", "silhouette", "uer", "unspecified gender", "username", "users-people" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Social", "Users + People" })]
UserAlt = 0xF406,
///
- /// The Font Awesome "user-large-slash" icon unicode character.
+ /// The Font Awesome "user-slash" icon unicode character.
+ /// Uses a legacy unicode value for backwards compatability. The current unicode value is 0xF506.
///
- [FontAwesomeSearchTerms(new[] { "user large slash", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "user slash", "ban", "delete", "deny", "disabled", "disconnect", "employee", "remove", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Users + People" })]
UserAltSlash = 0xF4FA,
///
/// The Font Awesome "user-astronaut" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user astronaut", "avatar", "clothing", "cosmonaut", "nasa", "space", "suit" })]
+ [FontAwesomeSearchTerms(new[] { "user astronaut", "avatar", "clothing", "cosmonaut", "nasa", "space", "suit", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Astronomy", "Science Fiction", "Users + People" })]
UserAstronaut = 0xF4FB,
///
/// The Font Awesome "user-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user check", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "user check", "employee", "enable", "uer", "users-people", "validate", "working" })]
[FontAwesomeCategoriesAttribute(new[] { "Users + People" })]
UserCheck = 0xF4FC,
///
/// The Font Awesome "circle-user" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "circle user", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "circle user", "employee", "uer", "username", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Social", "Users + People" })]
UserCircle = 0xF2BD,
///
/// The Font Awesome "user-clock" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user clock", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "user clock", "employee", "uer", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Users + People" })]
UserClock = 0xF4FD,
///
/// The Font Awesome "user-gear" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user gear", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "user gear", "employee", "together", "uer", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Users + People" })]
UserCog = 0xF4FE,
///
/// The Font Awesome "user-pen" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user pen", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "user pen", "employee", "modify", "uer", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Users + People" })]
UserEdit = 0xF4FF,
///
/// The Font Awesome "user-group" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user group", "bust", "busts in silhouette", "silhouette", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "user group", "bust", "busts in silhouette", "crowd", "employee", "silhouette", "together", "uer", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Social", "Users + People" })]
UserFriends = 0xF500,
///
/// The Font Awesome "user-graduate" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user graduate", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "user graduate", "uer", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Education", "Users + People" })]
UserGraduate = 0xF501,
///
/// The Font Awesome "user-injured" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user injured", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "user injured", "employee", "uer", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
UserInjured = 0xF728,
///
/// The Font Awesome "user-lock" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user lock", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "user lock", "employee", "padlock", "privacy", "uer", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Security", "Users + People" })]
UserLock = 0xF502,
///
/// The Font Awesome "user-doctor" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user doctor", "covid-19", "health", "job", "medical", "nurse", "occupation", "physician", "profile", "surgeon", "worker" })]
+ [FontAwesomeSearchTerms(new[] { "user doctor", "covid-19", "health", "job", "medical", "nurse", "occupation", "physician", "profile", "surgeon", "uer", "worker" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Medical + Health", "Users + People" })]
UserMd = 0xF0F0,
///
/// The Font Awesome "user-minus" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user minus", "delete", "negative", "remove" })]
+ [FontAwesomeSearchTerms(new[] { "user minus", "delete", "employee", "negative", "remove", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Users + People" })]
UserMinus = 0xF503,
///
/// The Font Awesome "user-ninja" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user ninja", "assassin", "avatar", "dangerous", "deadly", "fighter", "hidden", "ninja", "sneaky", "stealth" })]
+ [FontAwesomeSearchTerms(new[] { "user ninja", "assassin", "avatar", "dangerous", "deadly", "fighter", "hidden", "ninja", "sneaky", "stealth", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Users + People" })]
UserNinja = 0xF504,
///
/// The Font Awesome "user-nurse" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user nurse", "covid-19", "doctor", "health", "md", "medical", "midwife", "physician", "practitioner", "surgeon", "worker" })]
+ [FontAwesomeSearchTerms(new[] { "user nurse", "covid-19", "doctor", "health", "md", "medical", "midwife", "physician", "practitioner", "surgeon", "uer", "worker" })]
[FontAwesomeCategoriesAttribute(new[] { "Medical + Health", "Users + People" })]
UserNurse = 0xF82F,
///
/// The Font Awesome "user-plus" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user plus", "add", "avatar", "positive", "sign up", "signup", "team" })]
+ [FontAwesomeSearchTerms(new[] { "user plus", "add", "avatar", "employee", "follow", "positive", "sign up", "signup", "team", "user" })]
[FontAwesomeCategoriesAttribute(new[] { "Social", "Users + People" })]
UserPlus = 0xF234,
///
/// The Font Awesome "users" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "users", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "users", "employee", "together", "uer", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Social", "Users + People" })]
Users = 0xF0C0,
///
/// The Font Awesome "users-between-lines" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "users between lines", "covered", "group", "people" })]
+ [FontAwesomeSearchTerms(new[] { "users between lines", "covered", "crowd", "employee", "group", "people", "together", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
UsersBetweenLines = 0xE591,
///
/// The Font Awesome "users-gear" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "users gear", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "users gear", "employee", "uer", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Users + People" })]
UsersCog = 0xF509,
///
/// The Font Awesome "user-secret" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user secret", "detective", "sleuth", "spy", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "user secret", "detective", "sleuth", "spy", "uer", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Coding", "Security", "Users + People" })]
UserSecret = 0xF21B,
///
/// The Font Awesome "user-shield" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user shield", "protect", "safety" })]
+ [FontAwesomeSearchTerms(new[] { "user shield", "employee", "protect", "safety", "security", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Security", "Users + People" })]
UserShield = 0xF505,
///
/// The Font Awesome "user-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user slash", "ban", "delete", "remove" })]
+ [FontAwesomeSearchTerms(new[] { "user slash", "ban", "delete", "deny", "disabled", "disconnect", "employee", "remove", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Users + People" })]
UserSlash = 0xF506,
///
/// The Font Awesome "users-line" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "users line", "group", "need", "people" })]
+ [FontAwesomeSearchTerms(new[] { "users line", "crowd", "employee", "group", "need", "people", "together", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
UsersLine = 0xE592,
///
/// The Font Awesome "users-rays" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "users rays", "affected", "focused", "group", "people" })]
+ [FontAwesomeSearchTerms(new[] { "users rays", "affected", "crowd", "employee", "focused", "group", "people", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
UsersRays = 0xE593,
///
/// The Font Awesome "users-rectangle" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "users rectangle", "focus", "group", "people", "reached" })]
+ [FontAwesomeSearchTerms(new[] { "users rectangle", "crowd", "employee", "focus", "group", "people", "reached", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
UsersRectangle = 0xE594,
///
/// The Font Awesome "users-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "users slash", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "users slash", "disabled", "disconnect", "employee", "together", "uer", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Users + People" })]
UsersSlash = 0xE073,
///
/// The Font Awesome "users-viewfinder" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "users viewfinder", "focus", "group", "people", "targeted" })]
+ [FontAwesomeSearchTerms(new[] { "users viewfinder", "crowd", "focus", "group", "people", "targeted", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Users + People" })]
UsersViewfinder = 0xE595,
///
/// The Font Awesome "user-tag" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user tag", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "user tag", "employee", "uer", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Users + People" })]
UserTag = 0xF507,
///
/// The Font Awesome "user-tie" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user tie", "avatar", "business", "clothing", "formal", "professional", "suit" })]
+ [FontAwesomeSearchTerms(new[] { "user tie", "administrator", "avatar", "business", "clothing", "employee", "formal", "offer", "portfolio", "professional", "suit", "uer" })]
[FontAwesomeCategoriesAttribute(new[] { "Clothing + Fashion", "Users + People" })]
UserTie = 0xF508,
///
/// The Font Awesome "user-xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "user xmark", "archive", "delete", "remove", "x" })]
+ [FontAwesomeSearchTerms(new[] { "user xmark", "archive", "delete", "employee", "remove", "uer", "uncheck", "x" })]
[FontAwesomeCategoriesAttribute(new[] { "Users + People" })]
UserTimes = 0xF235,
@@ -9134,15 +9299,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "vault" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "vault", "bank", "important", "lock", "money", "safe" })]
+ [FontAwesomeSearchTerms(new[] { "vault", "bank", "important", "investment", "lock", "money", "premium", "privacy", "safe", "salary" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Money", "Security" })]
Vault = 0xE2C5,
///
- /// The Font Awesome "vector-square" icon unicode character.
+ /// The Font Awesome "vectorsquare" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "vector square", "anchors", "lines", "object", "render", "shape" })]
- [FontAwesomeCategoriesAttribute(new[] { "Design" })]
+ [Obsolete]
VectorSquare = 0xF5CB,
///
@@ -9183,21 +9347,21 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "vial" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "vial", "ampule", "chemist", "chemistry", "experiment", "lab", "sample", "science", "test", "test tube" })]
+ [FontAwesomeSearchTerms(new[] { "vial", "ampule", "chemist", "chemistry", "experiment", "knowledge", "lab", "sample", "science", "test", "test tube" })]
[FontAwesomeCategoriesAttribute(new[] { "Medical + Health", "Science" })]
Vial = 0xF492,
///
/// The Font Awesome "vial-circle-check" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "vial circle check", "ampule", "chemist", "chemistry", "not affected", "ok", "okay", "success", "test tube", "tube", "vaccine" })]
+ [FontAwesomeSearchTerms(new[] { "vial circle check", "ampule", "chemist", "chemistry", "enable", "not affected", "ok", "okay", "success", "test tube", "tube", "vaccine", "validate", "working" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Medical + Health", "Science" })]
VialCircleCheck = 0xE596,
///
/// The Font Awesome "vials" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "vials", "ampule", "experiment", "lab", "sample", "science", "test", "test tube" })]
+ [FontAwesomeSearchTerms(new[] { "vials", "ampule", "experiment", "knowledge", "lab", "sample", "science", "test", "test tube" })]
[FontAwesomeCategoriesAttribute(new[] { "Medical + Health", "Science" })]
Vials = 0xF493,
@@ -9218,7 +9382,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "video-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "video slash", "add", "create", "film", "new", "positive", "record", "video" })]
+ [FontAwesomeSearchTerms(new[] { "video slash", "add", "create", "disabled", "disconnect", "film", "new", "positive", "record", "video" })]
[FontAwesomeCategoriesAttribute(new[] { "Communication", "Film + Video" })]
VideoSlash = 0xF4E2,
@@ -9246,7 +9410,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "virus-covid-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "virus covid slash", "bug", "covid-19", "flu", "health", "infection", "pandemic", "vaccine", "viral", "virus" })]
+ [FontAwesomeSearchTerms(new[] { "virus covid slash", "bug", "covid-19", "disabled", "flu", "health", "infection", "pandemic", "vaccine", "viral", "virus" })]
[FontAwesomeCategoriesAttribute(new[] { "Medical + Health" })]
VirusCovidSlash = 0xE4A9,
@@ -9260,7 +9424,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "virus-slash" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "virus slash", "bug", "coronavirus", "covid-19", "cure", "eliminate", "flu", "health", "infection", "pandemic", "sick", "vaccine", "viral" })]
+ [FontAwesomeSearchTerms(new[] { "virus slash", "bug", "coronavirus", "covid-19", "cure", "disabled", "eliminate", "flu", "health", "infection", "pandemic", "sick", "vaccine", "viral" })]
[FontAwesomeCategoriesAttribute(new[] { "Medical + Health" })]
VirusSlash = 0xE075,
@@ -9316,7 +9480,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "check-to-slot" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "check to slot", "accept", "cast", "election", "politics", "positive", "voting", "yes" })]
+ [FontAwesomeSearchTerms(new[] { "check to slot", "accept", "cast", "election", "enable", "politics", "positive", "validate", "voting", "working", "yes" })]
[FontAwesomeCategoriesAttribute(new[] { "Political" })]
VoteYea = 0xF772,
@@ -9337,14 +9501,14 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "person-walking" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "person walking", "crosswalk", "exercise", "hike", "move", "person walking", "walk", "walking" })]
+ [FontAwesomeSearchTerms(new[] { "person walking", "crosswalk", "exercise", "follow", "hike", "move", "person walking", "uer", "walk", "walking", "workout" })]
[FontAwesomeCategoriesAttribute(new[] { "Humanitarian", "Sports + Fitness", "Users + People" })]
Walking = 0xF554,
///
/// The Font Awesome "wallet" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "wallet", "billfold", "cash", "currency", "money" })]
+ [FontAwesomeSearchTerms(new[] { "wallet", "billfold", "cash", "currency", "money", "salary" })]
[FontAwesomeCategoriesAttribute(new[] { "Business", "Money" })]
Wallet = 0xF555,
@@ -9380,9 +9544,16 @@ public enum FontAwesomeIcon
/// The Font Awesome "wave-square" icon unicode character.
///
[FontAwesomeSearchTerms(new[] { "wave square", "frequency", "pulse", "signal" })]
- [FontAwesomeCategoriesAttribute(new[] { "Mathematics" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Mathematics", "Music + Audio" })]
WaveSquare = 0xF83E,
+ ///
+ /// The Font Awesome "web-awesome" icon unicode character.
+ ///
+ [FontAwesomeSearchTerms(new[] { "web awesome", "awesome", "coding", "components", "crown", "web" })]
+ [FontAwesomeCategoriesAttribute(new[] { "Coding", "Design" })]
+ WebAwesome = 0xE682,
+
///
/// The Font Awesome "weight-scale" icon unicode character.
///
@@ -9407,28 +9578,28 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "wheat-awn-circle-exclamation" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "wheat awn circle exclamation", "affected", "famine", "food", "gluten", "hunger", "starve", "straw" })]
+ [FontAwesomeSearchTerms(new[] { "wheat awn circle exclamation", "affected", "failed", "famine", "food", "gluten", "hunger", "starve", "straw" })]
[FontAwesomeCategoriesAttribute(new[] { "Disaster + Crisis", "Food + Beverage", "Humanitarian" })]
WheatAwnCircleExclamation = 0xE598,
///
/// The Font Awesome "wheelchair" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "wheelchair", "users-people" })]
+ [FontAwesomeSearchTerms(new[] { "wheelchair", "disabled", "uer", "users-people" })]
[FontAwesomeCategoriesAttribute(new[] { "Accessibility", "Maps", "Medical + Health", "Transportation", "Travel + Hotel", "Users + People" })]
Wheelchair = 0xF193,
///
/// The Font Awesome "wheelchair-move" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "wheelchair move", "access", "handicap", "impairment", "physical", "wheelchair symbol" })]
+ [FontAwesomeSearchTerms(new[] { "wheelchair move", "access", "disabled", "handicap", "impairment", "physical", "uer", "wheelchair symbol" })]
[FontAwesomeCategoriesAttribute(new[] { "Accessibility", "Humanitarian", "Maps", "Medical + Health", "Transportation", "Travel + Hotel", "Users + People" })]
WheelchairMove = 0xE2CE,
///
/// The Font Awesome "wifi" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "wifi", "connection", "hotspot", "internet", "network", "wireless" })]
+ [FontAwesomeSearchTerms(new[] { "wifi", "connection", "hotspot", "internet", "network", "signal", "wireless", "www" })]
[FontAwesomeCategoriesAttribute(new[] { "Connectivity", "Humanitarian", "Maps", "Toggle", "Travel + Hotel" })]
Wifi = 0xF1EB,
@@ -9442,7 +9613,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "rectangle-xmark" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "rectangle xmark", "browser", "cancel", "computer", "development" })]
+ [FontAwesomeSearchTerms(new[] { "rectangle xmark", "browser", "cancel", "computer", "development", "uncheck" })]
[FontAwesomeCategoriesAttribute(new[] { "Coding" })]
WindowClose = 0xF410,
@@ -9505,7 +9676,7 @@ public enum FontAwesomeIcon
///
/// The Font Awesome "wrench" icon unicode character.
///
- [FontAwesomeSearchTerms(new[] { "construction", "fix", "mechanic", "plumbing", "settings", "spanner", "tool", "update", "wrench" })]
+ [FontAwesomeSearchTerms(new[] { "configuration", "construction", "equipment", "fix", "mechanic", "modify", "plumbing", "settings", "spanner", "tool", "update", "wrench" })]
[FontAwesomeCategoriesAttribute(new[] { "Construction", "Maps" })]
Wrench = 0xF0AD,
From 624191d1e03a052e5eafe56bd921f1f0623e3969 Mon Sep 17 00:00:00 2001
From: Haselnussbomber
Date: Sun, 7 Dec 2025 16:45:40 +0100
Subject: [PATCH 48/50] Update DalamudAssetPath to FontAwesome710FreeSolid.otf
---
Dalamud/DalamudAsset.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Dalamud/DalamudAsset.cs b/Dalamud/DalamudAsset.cs
index 27771116e..e234fbb4c 100644
--- a/Dalamud/DalamudAsset.cs
+++ b/Dalamud/DalamudAsset.cs
@@ -151,7 +151,7 @@ public enum DalamudAsset
/// : FontAwesome Free Solid.
///
[DalamudAsset(DalamudAssetPurpose.Font)]
- [DalamudAssetPath("UIRes", "FontAwesomeFreeSolid.otf")]
+ [DalamudAssetPath("UIRes", "FontAwesome710FreeSolid.otf")]
FontAwesomeFreeSolid = 2003,
///
From 2029a0f8a69e0d10b32b8795ce180ebf3c6eb8e5 Mon Sep 17 00:00:00 2001
From: goaaats
Date: Sun, 7 Dec 2025 21:31:25 +0100
Subject: [PATCH 49/50] Also add fallback for SeStringDrawState.ScreenOffset
for now, make sure that it is populated
---
.../SeStringDrawParams.cs | 4 +++-
.../ImGuiSeStringRenderer/SeStringDrawState.cs | 3 ++-
.../Data/Widgets/SeStringRendererTestWidget.cs | 18 ++++++++++++++++++
3 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawParams.cs b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawParams.cs
index 972013328..09c3e9ed9 100644
--- a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawParams.cs
+++ b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawParams.cs
@@ -25,7 +25,9 @@ public record struct SeStringDrawParams
public SeStringReplacementEntity.GetEntityDelegate? GetEntity { get; set; }
/// Gets or sets the screen offset of the left top corner.
- /// Screen offset to draw at, or null to use .
+ /// Screen offset to draw at, or null to use , if no
+ /// is specified. Otherwise, you must specify it (for example, by passing when passing the window
+ /// draw list.
public Vector2? ScreenOffset { get; set; }
/// Gets or sets the font to use.
diff --git a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs
index 5e63ef160..5601100e9 100644
--- a/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs
+++ b/Dalamud/Interface/ImGuiSeStringRenderer/SeStringDrawState.cs
@@ -63,11 +63,12 @@ public unsafe ref struct SeStringDrawState
else
{
this.drawList = ssdp.TargetDrawList.Value;
- this.ScreenOffset = Vector2.Zero;
+ this.ScreenOffset = ssdp.ScreenOffset ?? Vector2.Zero;
// API14: Remove, always throw
if (ThreadSafety.IsMainThread)
{
+ this.ScreenOffset = ssdp.ScreenOffset ?? ImGui.GetCursorScreenPos();
this.FontSize = ssdp.FontSize ?? ImGui.GetFontSize();
}
else
diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/SeStringRendererTestWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/SeStringRendererTestWidget.cs
index 0f51e0322..6a07152e5 100644
--- a/Dalamud/Interface/Internal/Windows/Data/Widgets/SeStringRendererTestWidget.cs
+++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/SeStringRendererTestWidget.cs
@@ -177,6 +177,24 @@ internal unsafe class SeStringRendererTestWidget : IDataWindowWidget
ImGuiHelpers.SeStringWrapped(this.logkind.Value.Data.Span, this.style);
}
+ if (ImGui.CollapsingHeader("Draw into drawlist"))
+ {
+ ImGuiHelpers.ScaledDummy(100);
+ ImGui.SetCursorScreenPos(ImGui.GetItemRectMin() + ImGui.GetStyle().FramePadding);
+ var clipMin = ImGui.GetItemRectMin() + ImGui.GetStyle().FramePadding;
+ var clipMax = ImGui.GetItemRectMax() - ImGui.GetStyle().FramePadding;
+ clipMin.Y = MathF.Max(clipMin.Y, ImGui.GetWindowPos().Y);
+ clipMax.Y = MathF.Min(clipMax.Y, ImGui.GetWindowPos().Y + ImGui.GetWindowHeight());
+
+ var dl = ImGui.GetWindowDrawList();
+ dl.PushClipRect(clipMin, clipMax);
+ ImGuiHelpers.CompileSeStringWrapped(
+ "Test test",
+ new SeStringDrawParams
+ { Color = 0xFFFFFFFF, WrapWidth = float.MaxValue, TargetDrawList = dl });
+ dl.PopClipRect();
+ }
+
if (ImGui.CollapsingHeader("Addon Table"u8))
{
if (ImGui.BeginTable("Addon Sheet"u8, 3))
From c45c6aafe1a8a8561826155aae0efc46b478a2d8 Mon Sep 17 00:00:00 2001
From: goaaats
Date: Sun, 7 Dec 2025 21:57:54 +0100
Subject: [PATCH 50/50] Don't consider failed index integrity checks as having
"modified game data files"
---
Dalamud/Data/DataManager.cs | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Dalamud/Data/DataManager.cs b/Dalamud/Data/DataManager.cs
index ed0aa6c4d..559bd84dc 100644
--- a/Dalamud/Data/DataManager.cs
+++ b/Dalamud/Data/DataManager.cs
@@ -82,8 +82,10 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager
var tsInfo =
JsonConvert.DeserializeObject(
dalamud.StartInfo.TroubleshootingPackData);
+
+ // Don't fail for IndexIntegrityResult.Exception, since the check during launch has a very small timeout
this.HasModifiedGameDataFiles =
- tsInfo?.IndexIntegrity is LauncherTroubleshootingInfo.IndexIntegrityResult.Failed or LauncherTroubleshootingInfo.IndexIntegrityResult.Exception;
+ tsInfo?.IndexIntegrity is LauncherTroubleshootingInfo.IndexIntegrityResult.Failed;
if (this.HasModifiedGameDataFiles)
Log.Verbose("Game data integrity check failed!\n{TsData}", dalamud.StartInfo.TroubleshootingPackData);