fix(closeout): address closure-review findings
- gate keybind pill-sync on IsChannelOrExistingLinkshell so an empty linkshell slot no longer desyncs the pill from the real send channel - close manually-popped pop-out windows on logout via an IsOpen filter instead of the PopOut flag (which manual pops never set) - read the router's tell-tab lookup through a lock-wrapped accessor so the framework thread cannot enumerate Config.Tabs mid worker-thread mutation - add a "switch on every tell" toggle (default on) and make the auto-open mode pick the matching layout, so Sidebar vs Top-tab are distinct - comment corrections (stale/contradictory text, TEST-MIRROR path depth)
This commit is contained in:
@@ -9,7 +9,7 @@ namespace HellionChat.Services;
|
||||
// that service owns tab CREATION + lifecycle; this only REVEALS/pops the tab it
|
||||
// finds. Popout guards on pool.IsOpen so it never double-pops a tab the
|
||||
// AutoTellTabsOpenAsPopout path already opened. Subscribes to the resolved
|
||||
// MessageManager.MessageProcessed stream (partner already extracted), not the raw
|
||||
// MessageManager.MessageProcessed stream (a resolved Message), not the raw
|
||||
// IChatGui event, and defers the reveal one tick so the tab exists regardless of
|
||||
// subscriber order. Wired by TellRouterServiceInitHostedService.
|
||||
internal sealed class TellRouterService : IDisposable
|
||||
@@ -69,7 +69,9 @@ internal sealed class TellRouterService : IDisposable
|
||||
// mutation) is serialized with Draw (reference_dalamud_framework_thread).
|
||||
Plugin.Framework.RunOnFrameworkThread(() =>
|
||||
{
|
||||
var tab = AutoTellTabsService.FindTempTab(name, world);
|
||||
// Lock-safe lookup: AutoTellTabs mutates Config.Tabs under its lock on the
|
||||
// worker thread, so we read through its guarded accessor, not the static.
|
||||
var tab = Plugin.Instance.AutoTellTabsService?.FindTempTabSafe(name, world);
|
||||
if (tab == null)
|
||||
return; // nothing to reveal (auto-tell-tabs off -> no tab created)
|
||||
|
||||
@@ -77,7 +79,26 @@ internal sealed class TellRouterService : IDisposable
|
||||
{
|
||||
case TellAutoOpenMode.Sidebar:
|
||||
case TellAutoOpenMode.TopTab:
|
||||
Plugin.Instance.MainWindow?.ActivateTab(tab);
|
||||
// Switching to the tab on every tell is user-gated
|
||||
// (TellAutoOpenSwitchAlways, default on); when off the tab still
|
||||
// appears with its unread badge but the active tab is left alone.
|
||||
// The mode also picks the layout, so Sidebar vs TopTab are actually
|
||||
// distinct outcomes, not the same ActivateTab.
|
||||
if (Plugin.Config.TellAutoOpenSwitchAlways)
|
||||
{
|
||||
var wantLayout =
|
||||
mode == TellAutoOpenMode.TopTab
|
||||
? MainWindowLayoutMode.TopTabs
|
||||
: MainWindowLayoutMode.Sidebar;
|
||||
if (Plugin.Config.MainWindowLayoutMode != wantLayout)
|
||||
{
|
||||
Plugin.Config.MainWindowLayoutMode = wantLayout;
|
||||
Plugin.Instance.SaveConfig();
|
||||
}
|
||||
|
||||
Plugin.Instance.MainWindow?.ActivateTab(tab);
|
||||
}
|
||||
|
||||
break;
|
||||
case TellAutoOpenMode.Popout:
|
||||
// IsOpen-guard: don't double-pop a tab the AutoTellTabsOpenAsPopout
|
||||
|
||||
Reference in New Issue
Block a user