Quantcast

- Fix for 'hanging' tooltip

urnati [02-26-26 - 01:50]
- Fix for 'hanging' tooltip
- Update Volume with new menu with sliders
- Consolidation of startup code
Filename
Titan/Titan.lua
Titan/TitanConfig.lua
Titan/TitanLDB.lua
Titan/TitanMenu.lua
Titan/TitanMovable.lua
Titan/TitanTemplate.lua
Titan/TitanTemplate.xml
Titan/TitanUtils.lua
Titan/TitanVariables.lua
Titan/_ATitanDoc.lua
TitanGold/TitanGold.lua
TitanVolume/TitanVolume.lua
diff --git a/Titan/Titan.lua b/Titan/Titan.lua
index 0581759..25b264a 100644
--- a/Titan/Titan.lua
+++ b/Titan/Titan.lua
@@ -202,6 +202,7 @@ function TitanPanel_SaveCustomProfile(profile_name)
 	--	StaticPopupDialogs["TITAN_SAVE_CUSTOM_PROFILE"] = {}
 end

+--[[
 ---Titan Set or change the font and font size of text on the Titan bar. This affects ALL plugins.
 --- Each registered plugin will have its font updated. Then all plugins will be refreshed to show the new font.
 ---@param fontname string path to font file
@@ -222,6 +223,7 @@ function TitanSetPanelFont(fontname, fontsize)
 	end
 	TitanPanel_RefreshPanelButtons();
 end
+--]]

 local function RegisterForEvents()
 	-- Need to be careful of regeristering for events that initiate
@@ -314,7 +316,6 @@ local function SetToonInfo(toon)
 	toon_info.race = localizedRaceName
 	toon_info.raceName = englishRaceName
 	toon_info.raceId = raceID
-
 end

 local function SetToonLogout(toon)
@@ -331,111 +332,100 @@ local function SetToonLogout(toon)
 	toon_info.logoutStr = TitanUtils_GetDateText(now, true)
 end

----Titan Do all the setup needed when a user logs in / reload UI / enter or leave an instance.
---- This is called after the 'player entering world' event is fired by Blizz.
---- This is also called when a LDB plugin is created after Titan runs the 'player entering world' code.
---- The common code section will setup this toon's info
---- 1) Register any plugins
---- 2) Load the plugin vars (UseSettings)
---- 3) Update the Titan config
---- 4) Set the Titan vars
---- 5) Load / register any LDB plugins into Titan
----@param reload boolean true if reload; false if character 'first' enter
-function TitanPanel_PlayerEnteringWorld(reload)
-	if Titan__InitializedPEW then
-		-- Currently no additional steps needed
-	else
-		Titan_Debug.Out('titan', 'p_e_w', "Init settings")
-
-		-- Get Saved Vars; sync with defaults
-		TitanVariables_InitTitanSettings()
-
-		if TitanAllGetVar("Silenced") then
-			-- No header output
-		else
-			TitanPrint("", "header")
-		end
-
-		-- Set the two anchors in their default positions
-		-- until the Titan bars are drawn
-		Titan_Debug.Out('titan', 'p_e_w', "Create anchors for other addons")
-		TitanPanelTopAnchor:ClearAllPoints();
-		TitanPanelTopAnchor:SetPoint("TOPLEFT", "UIParent", "TOPLEFT", 0, 0);
-		TitanPanelBottomAnchor:ClearAllPoints();
-		TitanPanelBottomAnchor:SetPoint("BOTTOMLEFT", "UIParent", "BOTTOMLEFT", 0, 0);
-
-		-- Ensure the bars are created before the plugins are registered.
-		Titan_Debug.Out('titan', 'p_e_w', "Create frames for Titan bars")
-		for idx, v in pairs(TitanBarData) do
-			Titan_Debug.Out('titan', 'bars_setup', "... " .. tostring(v.name))
-
-			TitanPanelButton_CreateBar(idx, v.locale_name)
-		end
-		--		Titan_AutoHide_Create_Frames()
-
-		-- Add to Addon Compartment, if feature is present
-		RegisterAddonCompartment()
-
-		-- Should be safe to register for events that could show / hide Bars
-		Titan_Debug.Out('titan', 'p_e_w', "Register for events Titan needs")
-		RegisterForEvents()
-	end
-
-	--====== Common code login versus reload / portal / ...
-
-	local _ = nil
-	TitanSettings.Player, _, _ = TitanUtils_GetPlayer()
-	SetToonInfo(TitanSettings.Player)
-
+local function SetPluginsAndConfig()
 	-- Some addons wait to create their LDB component or a Titan addon could
 	-- create additional buttons as needed.
 	Titan_Debug.Out('titan', 'p_e_w', "Register any plugins found")
 	TitanUtils_RegisterPluginList()
 	Titan_Debug.Out('titan', 'p_e_w', "> Register any plugins done")

+	-- Loop through the LDB objects to sync with their created Titan plugin
+	Titan_Debug.Out('titan', 'p_e_w', "Register any LDB (Titan) plugins")
+	TitanLDBRefreshButton()
+	Titan_Debug.Out('titan', 'p_e_w', "> Register any LDB (Titan) plugins done")
+
 	-- Now sync saved variables to the profile chosen by the user.
 	-- This will set the bar(s) and enabled plugins (via OnShow).
 	Titan_Debug.Out('titan', 'p_e_w', "Synch plugin saved vars")
+end

-	Titan_Debug.Out('titan', 'p_e_w', "Set up player")
-	TitanVariables_UseSettings(nil, TitanUtils_GetPlayer(), TITAN_PROFILE_INIT)
+local function SetupTitan()
+	Titan_Debug.Out('titan', 'p_e_w', "Init settings")

-	Titan_Debug.Out('titan', 'p_e_w', "Init config data (right click menu)")
-	-- all addons are loaded so update the config (options)
-	-- some could have registered late...
-	TitanUpdateConfig("init")
+	-- Get Saved Vars; sync with defaults
+	TitanVariables_InitTitanSettings()

 	-- Init panel font
+	-- In case the user does not load the addon with the font they were using
 	local isfontvalid = media:IsValid("font", TitanPanelGetVar("FontName"))
 	if isfontvalid then
-		TitanSetPanelFont(TitanPanelGetVar("FontName"), TitanPanelGetVar("FontSize"))
+		-- should be good
 	else
 		-- if the selected font is not valid, revert to default (Friz Quadrata TT)
 		TitanPanelSetVar("FontName", TPC.FONT_NAME);
-		TitanSetPanelFont(TPC.FONT_NAME, TitanPanelGetVar("FontSize"))
 	end

-	-- Init panel frame strata
-	TitanVariables_SetPanelStrata(TitanPanelGetVar("FrameStrata"))
+	if TitanAllGetVar("Silenced") then
+		-- No header output
+	else
+		TitanPrint("", "header")
+	end

-	-- Titan Panel has initialized its variables and registered plugins.
-	-- Allow Titan - and others - to adjust the bars
-	Titan__InitializedPEW = true
+	-- Set the two anchors in their default positions
+	-- until the Titan bars are drawn
+	Titan_Debug.Out('titan', 'p_e_w', "Create anchors for other addons")
+	TitanPanelTopAnchor:ClearAllPoints();
+	TitanPanelTopAnchor:SetPoint("TOPLEFT", "UIParent", "TOPLEFT", 0, 0);
+	TitanPanelBottomAnchor:ClearAllPoints();
+	TitanPanelBottomAnchor:SetPoint("BOTTOMLEFT", "UIParent", "BOTTOMLEFT", 0, 0);

-	-- Move frames
-	if Titan_Global.switch.can_edit_ui then
-		-- No need
-	else
-		TitanMovable_SecureFrames()
-		TitanPanel_AdjustFrames(true, "_PlayerEnteringWorld")
+	-- Ensure the bars are created before the plugins are registered.
+	Titan_Debug.Out('titan', 'p_e_w', "Create frames for Titan bars")
+	for idx, v in pairs(TitanBarData) do
+		Titan_Debug.Out('titan', 'bars_setup', "... " .. tostring(v.name))
+
+		TitanPanelButton_CreateBar(idx, v.locale_name)
 	end
+	--		Titan_AutoHide_Create_Frames()

-	-- Loop through the LDB objects to sync with their created Titan plugin
-	Titan_Debug.Out('titan', 'p_e_w', "Register any LDB (Titan) plugins")
-	TitanLDBRefreshButton()
-	Titan_Debug.Out('titan', 'p_e_w', "> Register any LDB (Titan) plugins done")
+	-- Add to Addon Compartment, if feature is present
+	RegisterAddonCompartment()
+
+	-- Should be safe to register for events that could show / hide Bars
+	Titan_Debug.Out('titan', 'p_e_w', "Register for events Titan needs")
+	RegisterForEvents()
+
+	local _ = nil
+	TitanSettings.Player, _, _ = TitanUtils_GetPlayer()
+	SetToonInfo(TitanSettings.Player)
+	Titan_Debug.Out('titan', 'p_e_w', "Init settings done")
+end
+
+local function SetupUser()
+	-- User could have changed the addons loaded, so register plugins and LDB again.
+	SetPluginsAndConfig()
+
+	-- Set the profile per the user choices.
+	Titan_Debug.Out('titan', 'p_e_w', "Set up player")
+	TitanVariables_UseSettings(nil, TitanUtils_GetPlayer(), TITAN_PROFILE_INIT)
+
+	Titan_Debug.Out('titan', 'p_e_w', "Init config data (right click menu)")
+	-- all addons are loaded so update the config (options)
+	-- some could have registered late...
+	TitanUpdateConfig("init")
+	Titan_Debug.Out('titan', 'p_e_w', "Init config data (right click menu) done")
+end

-	Titan_Debug.Out('titan', 'p_e_w', "Titan processing done")
+local function ShowTitan()
+	do -- set the bars per the user choices
+		-- Move frames
+		if Titan_Global.switch.can_edit_ui then
+			-- No need
+		else
+			TitanMovable_SecureFrames()
+			TitanPanel_AdjustFrames(true, "_PlayerEnteringWorld")
+		end
+	end
 end

 --------------------------------------------------------------
@@ -457,56 +447,126 @@ end
 		end
 --]===]

+local function FrameCleanup()
+	-- Without a wait this was happening WAY too early in the PEW
+
+
+	TitanUtils_CloseRightClickMenu() -- cleanup any open menus
+
+	-- Nuke the tooltip, if open
+	-- Titan tooltip - newer (2026 Jan)
+	-- Game tooltip - older or custom
+
+
+	-- Ugly until this is wrapped properly
+	if TitanPanelTooltip and TitanPanelTooltip:IsVisible() then
+		TitanPanelTooltip:Hide()
+	else
+		-- not open
+	end
+	if GameTooltip and GameTooltip:IsVisible() then
+		-- WoW may handle this but just in case...
+		GameTooltip:Hide()
+	else
+		-- not open
+	end
+end
+
+local function StopTitan(err_str, ret_val)
+	-- something really bad occured...
+	TitanPrint(err_str .. "!!!!  Cleaning up...", "error")
+	TitanPrint("--" .. ret_val, "error")
+	-- Hide the bars. At times they are there but at 0% transparency.
+	-- They can be over the Blizz action bars creating havoc.
+	TitanPrint("-- Hiding Titan bars...", "warning")
+	TitanPanelBarButton_HideAllBars()
+
+	-- Remove the options pages, just in case; likely config would not work...
+	TitanUpdateConfig("nuke")
+	-- What else to clean up???
+
+	-- raise the error to WoW for display, if display errors is set.
+	-- This *will be* the last statement of PLAYER_ENTERING_WORLD!
+	error(ret_val, 1)
+end

 ---Titan Handle PLAYER_ENTERING_WORLD Initialize Titan, set and display Titan bars and plugins.
-function TitanPanelBarButton:PLAYER_ENTERING_WORLD(arg1, arg2)
+---@param arg1 boolean isLogin
+---@param arg2 boolean isReload
+function TitanPanelBarButton:PLAYER_ENTERING_WORLD(arg1, arg2, arg3, arg4)
 	local call_success = nil
 	local ret_val = nil

 	Titan_Debug.Out('titan', 'p_e_w', "Titan PLAYER_ENTERING_WORLD pcall setup routine")

-	call_success, -- needed for pcall
-	ret_val =  -- actual return values
-		pcall(TitanPanel_PlayerEnteringWorld, arg2)
-	-- pcall does not allow errors to propagate out. Any error
-	-- is returned as text with the success / fail.
-	-- Think of it as a try - catch block
 	--[[
-print("_PlayerEnteringWorld"
-.." "..tostring(call_success)..""
-)
---]]
-	if call_success then
-		-- Titan initialized properly
+	With profile and API changes over the years, the PEW has evolved into 3 distinct sections:
+	1) Setup : Titan vars; variables; events; and creation of bars
+	2) Load :
+	- Profiles : Determining the actual profile to use; cleanup and adjustments of profile data
+	- Plugins : Built-ins, third party, and LDB
+	3) Draw : Place Titan and plugins on WoW UI per the profile
+
+	1) Needed only on login
+	2) and 3) Needed on reload of UI
+	If the user is just changing map locations then no work is needed
+
+	2026 Feb : redone to improve splash screen timing and make Titan more stable on errors
+	--]]
+
+	if arg1 == true then -- login, only once
+		-- if tooltip gets stuck allow user to tap ESC to clear
+		tinsert(UISpecialFrames, "TitanPanelTooltip")
 	else
-		-- something really bad occured...
-		TitanPrint("Titan could not initialize!!!!  Cleaning up...", "error")
-		TitanPrint("--" .. ret_val, "error")
-		-- Clean up best we can and tell the user to submit a ticket.
-		-- This could be the 1st log in or a reload (reload, instance, boat, ...)
+	end
+
+	if arg1 == true -- login
+		or arg2 == true -- reload
+	then
+		-- StopTitan will force error and end this routine
+
+		call_success, ret_val = pcall(SetupTitan)
+		if call_success then
+			-- Titan initialized properly
+		else
+			StopTitan("Could not initialize", ret_val) -- something really bad occured...
+		end

-		-- Hide the bars. At times they are there but at 0% transparency.
-		-- They can be over the Blizz action bars creating havoc.
-		TitanPrint("-- Hiding Titan bars...", "warning")
-		TitanPanelBarButton_HideAllBars()
+		call_success, ret_val = pcall(SetupUser)
+		if call_success then
+			-- Titan initialized properly
+		else
+			StopTitan("Setup error", ret_val) -- something really bad occured...
+		end

-		-- Remove the options pages
-		TitanUpdateConfig("nuke")
-		-- What else to clean up???
+		call_success, ret_val = pcall(ShowTitan)
+		if call_success then
+			-- Titan initialized properly
+		else
+			StopTitan("Could not show Bars", ret_val) -- something really bad occured...
+		end
+	else
+		-- map change
+	end

-		-- raise the error to WoW for display, if display errors is set.
-		-- This *must be* the last statement of the routine!
-		error(ret_val, 1)
+	do -- a little UI cleanup, just in case
+		C_Timer.After(1.0, function() FrameCleanup() end)
 	end
-end

+	-- Titan Panel has initialized its variables and registered plugins.
+	-- Allow Titan - and others - to adjust the bars
+	Titan__InitializedPEW = true
+
+	Titan_Debug.Out('titan', 'p_e_w', "Titan init processing done")
+end
 ---Titan Handle CVAR_UPDATE React to user changed WoW options.
 function TitanPanelBarButton:CVAR_UPDATE(cvarname, cvarvalue)
 	if cvarname == "USE_UISCALE"
 		or cvarname == "WINDOWED_MODE"
 		or cvarname == "uiScale" then
 		if TitanPlayerSettings and TitanPanelGetVar("Scale") then
-			TitanPanel_InitPanelBarButton("CVAR_ " .. tostring(cvarname))
+			--TitanPanel_InitPanelBarButton("CVAR_ " .. tostring(cvarname))
+			TitanPanel_InitPanelButtons("CVAR_ " .. tostring(cvarname))
 			if Titan_Global.switch.can_edit_ui then
 				-- No need
 			else
@@ -719,7 +779,8 @@ local function handle_reset_cmds(cmd_list)
 	elseif p1 == "panelscale" then
 		if not InCombatLockdown() then
 			TitanPanelSetVar("Scale", 1);
-			TitanPanel_InitPanelBarButton("/panelscale reset ")
+			--TitanPanel_InitPanelBarButton("/panelscale reset ")
+			TitanPanel_InitPanelButtons("/panelscale reset ")
 			if Titan_Global.switch.can_edit_ui then
 				-- No need
 			else
@@ -732,7 +793,7 @@ local function handle_reset_cmds(cmd_list)
 		end
 	elseif p1 == "spacing" then
 		TitanPanelSetVar("ButtonSpacing", 20);
-		TitanPanel_InitPanelButtons();
+		TitanPanel_InitPanelButtons("/spacing reset");
 		TitanPrint(L["TITAN_PANEL_SLASH_RESP4"], "info")
 	else
 		handle_slash_help("reset")
@@ -1366,7 +1427,8 @@ local function OnMovingStop(self)
 		-- placement ok
 	else
 		-- Need to 'snap' it to an edge
-		TitanPanel_InitPanelBarButton("OnMovingStop")
+		--TitanPanel_InitPanelBarButton("OnMovingStop")
+		TitanPanel_InitPanelButtons("OnMovingStop")
 	end
 	-- Seems overkill - this will recalc all bars...
 end
@@ -1675,14 +1737,26 @@ end

 ---Titan Show all user selected plugins on the Titan bar(s) then justify per the user selection.
 --- This is done an all bars whether shown or not.
-function TitanPanel_InitPanelButtons()
+---@param reason string For debug
+function TitanPanel_InitPanelButtons(reason)
 	local button
 	local r_prior = {}
 	local l_prior = {}
+
+	-- 2026 Feb : Added setting scale and font on bars and plugins here to consolidate
+	-- processing and reduce routines and hopefully be clearer for future changes
 	local scale = TitanPanelGetVar("Scale");
+	local font_name = TitanPanelGetVar("FontName")
+	local font_size = TitanPanelGetVar("FontSize")
+
 	local button_spacing = TitanPanelGetVar("ButtonSpacing") * scale
 	local icon_spacing = TitanPanelGetVar("IconSpacing") * scale

+	-- build debug output
+	local str = "_InitPanelButtons"
+		.. " " .. tostring(reason) .. ""
+	Titan_Debug.Out('titan', 'bars_setup', str)
+
 	local prior = {}
 	-- set prior to the starting offsets
 	-- The right side plugins are set here.
@@ -1706,6 +1780,7 @@ function TitanPanel_InitPanelButtons()
 				y = y_off,
 			},
 		}
+		_G[idx]:SetScale(scale)
 	end
 	--
 	TitanPanelBarButton_DisplayBarsWanted("TitanPanel_InitPanelButtons");
@@ -1718,6 +1793,12 @@ function TitanPanel_InitPanelButtons()
 			button = TitanUtils_GetButton(id);

 			if button then
+				button:SetScale(scale)
+				local buttonText = _G[button:GetName() .. TITAN_PANEL_TEXT];
+				if buttonText then
+					buttonText:SetFont(font_name, font_size);
+				end
+
 				-- If the plugin has asked to be on the right
 				if TitanUtils_ToRight(id) then
 					-- =========================
@@ -1814,7 +1895,7 @@ function TitanPanel_RemoveButton(id, hide_plugin)
 		currentButton:Hide();
 	end
 	-- Show the existing buttons
-	TitanPanel_InitPanelButtons();
+	TitanPanel_InitPanelButtons("_RemoveButton");
 end

 --- Titan Get the index of the given plugin from the Titan plugin displayed list.
@@ -1835,6 +1916,7 @@ function TitanPanel_GetButtonNumber(id)
 	end
 end

+--[[
 ---Titan Update / refresh each plugin from the Titan plugin list. Used when a Titan option is changed that effects all plugins.
 function TitanPanel_RefreshPanelButtons()
 	if (TitanPanelSettings) then
@@ -1843,6 +1925,7 @@ function TitanPanel_RefreshPanelButtons()
 		end
 	end
 end
+--]]

 ---Titan Justify the plugins on each Titan bar.
 --- Used when :
@@ -1875,11 +1958,11 @@ function TitanPanelButton_Justify()
 	-- Look at each bar for plugins.
 	for idx, v in pairs(TitanBarData) do
 		bar = TitanBarData[idx].name
---print("Bar Y"
---	.. " " .. tostring(idx) .. ""
---	.. " " .. tostring(TitanBarData[idx].plugin_y_offset) .. ""
---	.. " " .. tostring(TitanBarDataVars[idx].plugin_off_y) .. ""
---)
+		--print("Bar Y"
+		--	.. " " .. tostring(idx) .. ""
+		--	.. " " .. tostring(TitanBarData[idx].plugin_y_offset) .. ""
+		--	.. " " .. tostring(TitanBarDataVars[idx].plugin_off_y) .. ""
+		--)
 		y_offset = TitanBarData[idx].plugin_y_offset -- + TitanBarDataVars[idx].plugin_off_y -- user may offset
 		x_offset = TitanBarData[idx].plugin_x_offset
 		firstLeftButton = TitanUtils_GetButton(TitanPanelSettings.Buttons
@@ -1955,19 +2038,20 @@ function TitanPanel_GetPluginSide(id)
 	end
 end

+--[[
 ---Titan Set the scale, texture (graphic), and transparancy of all the Titan bars based on the user selection.
 ---@param reason string Debug note on where the call initiated
 function TitanPanel_InitPanelBarButton(reason)
 	-- Set initial Panel Scale
-	TitanPanel_SetScale();
+--	TitanPanel_SetScale();

 	-- build debug output
 	local str = "_InitPanelBarButton"
 		.. " " .. tostring(reason) .. ""
 	Titan_Debug.Out('titan', 'bars_setup', str)
-	TitanPanelBarButton_DisplayBarsWanted("InitPanelBarButton")
+--	TitanPanelBarButton_DisplayBarsWanted("InitPanelBarButton")
 end
-
+--]]
 ---Titan Handle ADDON_LOADED Minimal setup in prep for player login.
 function TitanPanelBarButton:ADDON_LOADED(addon)
 	if addon == TITAN_ID then
@@ -1988,7 +2072,7 @@ local function AddPlugin(owner, bar, category)
 		plugin = TitanUtils_GetPlugin(id)
 		if plugin then
 			plugin.category = plugin and plugin.category or "General";
-			if (plugin.category == category) then  -- add the plugin to the menu
+			if (plugin.category == category) then -- add the plugin to the menu
 				local internal_bar, which_bar, which_frame_str = TitanUtils_GetWhichBar(id)
 				if not TitanGetVar(id, "ForceBar")
 					or (TitanGetVar(id, "ForceBar") == TitanBarData[bar:GetName()].name) then
@@ -2048,7 +2132,7 @@ local function GeneratorFunction(owner, rootDescription)
 	do
 		---@diagnostic disable-next-line: assign-type-mismatch, param-type-mismatch
 		for index, id in pairs(L["TITAN_PANEL_MENU_CATEGORIES"]) do
-			local cat = TITAN_PANEL_BUTTONS_PLUGIN_CATEGORY[index]
+			local cat = TITAN_PANEL_BUTTONS_PLUGIN_CATEGORY[index]
 			local cat_locale = L["TITAN_PANEL_MENU_CATEGORIES"][index]
 			local opts_plugins = Titan_Menu.AddButton(root, cat_locale)
 			AddPlugin(opts_plugins, bar, cat) -- if same category
@@ -2081,7 +2165,7 @@ local function GeneratorFunction(owner, rootDescription)
 				function(data)
 					TitanBarDataVars[data.f_str].show = not TitanBarDataVars[data.f_str].show
 					TitanPanelBarButton_DisplayBarsWanted(data.f_str ..
-					" right click menu " .. tostring(TitanBarDataVars[data.f_str].show))
+						" right click menu " .. tostring(TitanBarDataVars[data.f_str].show))
 				end,
 				{ f_str = v.frame_name }
 			)
@@ -2089,8 +2173,8 @@ local function GeneratorFunction(owner, rootDescription)
 	end
 	Titan_Menu.AddDivider(root)

--- Hold off for a rewrite using Blizz API over Ace
---[[
+	-- Hold off for a rewrite using Blizz API over Ace
+	--[[
 	if Titan_Global.switch.midnight then
 		-- disable until we figure this out
 	else
diff --git a/Titan/TitanConfig.lua b/Titan/TitanConfig.lua
index 81e41a8..91a03d2 100644
--- a/Titan/TitanConfig.lua
+++ b/Titan/TitanConfig.lua
@@ -2322,7 +2322,8 @@ local optionsUIScale = {
 			get = function() return TitanPanelGetVar("Scale") end,
 			set = function(_, a)
 				TitanPanelSetVar("Scale", a)
-				TitanPanel_InitPanelBarButton("Config scale change " .. a)
+				--TitanPanel_InitPanelBarButton("Config scale change " .. a)
+				TitanPanel_InitPanelButtons("Config scale change " .. a)
 			end,
 			disabled = function()
 				if InCombatLockdown() then
@@ -2344,7 +2345,7 @@ local optionsUIScale = {
 			get = function() return TitanPanelGetVar("ButtonSpacing") end,
 			set = function(_, a)
 				TitanPanelSetVar("ButtonSpacing", a);
-				TitanPanel_InitPanelButtons();
+				TitanPanel_InitPanelButtons("Config: Button spacing");
 			end,
 		},
 		iconspacing = {
@@ -2359,7 +2360,7 @@ local optionsUIScale = {
 			get = function() return TitanPanelGetVar("IconSpacing") end,
 			set = function(_, a)
 				TitanPanelSetVar("IconSpacing", a);
-				TitanPanel_InitPanelButtons();
+				TitanPanel_InitPanelButtons("Config: Icon spacing");
 			end,
 		},
 		spacer01 = {
@@ -2419,8 +2420,8 @@ local optionsUIScale = {
 			end,
 			set = function(_, v)
 				TitanPanelSetVar("FontName", v)
--- "Friz Quadrata TT"
-				TitanSetPanelFont(v, TitanPanelGetVar("FontSize"))
+				--TitanSetPanelFont(v, TitanPanelGetVar("FontSize"))
+				TitanPanel_InitPanelButtons("FontName")
 			end,
 			values = font_list,
 --			values = media:List("font"), --AceGUIWidgetLSMlists.font,
@@ -2438,7 +2439,8 @@ local optionsUIScale = {
 			get = function() return TitanPanelGetVar("FontSize") end,
 			set = function(_, v)
 				TitanPanelSetVar("FontSize", v);
-				TitanSetPanelFont(TitanPanelGetVar("FontName"), v)
+				--TitanSetPanelFont(TitanPanelGetVar("FontName"), v)
+				TitanPanel_InitPanelButtons("FontSize")
 			end,
 		},
 		fontspacer = {
@@ -3139,7 +3141,7 @@ local optionsAdvanced = {
 					order = 501,
 					type = "execute",
 					width = "full",
-					func = function() TitanPanel_InitPanelButtons() end,
+					func = function() TitanPanel_InitPanelButtons("Config: Refresh plugins") end,
 				},
 				space_600_1 = {
 					order = 600,
diff --git a/Titan/TitanLDB.lua b/Titan/TitanLDB.lua
index 10e8603..0e2a64c 100644
--- a/Titan/TitanLDB.lua
+++ b/Titan/TitanLDB.lua
@@ -829,7 +829,7 @@ function TitanLDBCreateObject(self, name_str, obj)
 		-- This works because the .registry is now set
 		TitanUtils_RegisterPluginList()
 		TitanVariables_SyncSinglePluginSettings(registry.id)
-		TitanPanel_InitPanelButtons() -- Show it...
+		TitanPanel_InitPanelButtons("LDB post create : "..registry.id) -- Show it...
 	end
 	Titan_Debug.Out('titan', 'ldb_setup', "LDB create"
 		.. " " .. tostring(pew) .. ""
diff --git a/Titan/TitanMenu.lua b/Titan/TitanMenu.lua
index 9de6d8c..e11dc90 100644
--- a/Titan/TitanMenu.lua
+++ b/Titan/TitanMenu.lua
@@ -1,32 +1,58 @@
 --[===[ File
-Contains various utility routines used by
-- Titan and Plugins for thehier menus (right click) 'drop down'
+Contains various utility routines used by Titan and Plugins for menus (right click)
 --]===]

 --[===[
-This large file contains various utility routines used by
-The Drop Down Menu routines for the Right Click menu are in this file.
+Titan controls menus for its builtin plugins.
+Third party Titan plugins may have Titan control its menu.
+LDB plugins are assumed to control their own menus.

 The Titan routines abstract the menu creation built into WoW.
-
-Whenever there is a change to the menu routines, the abstractions :
+The abstractions :
 : Insulate 3rd party Titan plugin authors from Blizz or lib changes.
-: Allow better maintainance by updating Utils rather than updating Titan using search & replace.
+: Allow better maintainance if implementation changes.
+
+Currently Titan 'supports' three menu schemes
+1- Abstract of an old drop down lib - L_UIDropDownMenu_*
+2- Abstract of Blizzard UIDropDownMenu routines
+3- Abstract of Blizzard_Menu which was introduced in 11.0.0
+
+Having 3 methods evolved over the history of WoW and Titan, not to be dug up :).
+1- This method is really for very old third party Titan plugins in Classic Era so they can run unchanged.
+Many of these addons run but may not be actively maintained.
+This wraps UIDropDownMenu routines to look like the lib routines.
+
+2- This method wraps UIDropDownMenu routines with Titan oriented routines.
+
+3- This method wraps the new Blizzard_Menu general routines to be oriented toward Titan features.
+This method is very different from UIDropDownMenu. The two are distinct and do not overlap.
+Titan uses the general routines to allow Blizzard_Menu to handle menu show / hide, and placement.
+There is less flexability with the tradeoff being a consistent style and behavior.
+
+When a menu is requested, Titan will use the .registry to find the routine to call.
+This routine is expected to fill in the menu using one of the methods listed above.
+In Jan 2026 Titan added a .registry on each bar for the new menu scheme to start combining plugin and bar routines,
+
+Titan will use, in order :
+1) registry.menuContextFunction  : NEW Jan 2026
+2) registry.menuTextFunction  : Feb 2024
+3) "TitanPanelRightClickMenu_Prepare" .. id .. "Menu" : Old as Titan :)

-Late 2023 during DragonFlight, WoW expanded the retail version of drop down menu to more Classic versions.
-Currently (May 2025) Classic Era is the only one using an explicit timer, and a distinct file version, to close menus.
-So, Titan uses a routine only in CE (UIDropDownMenu_StartCounting) to determine which version to use.

-Code notes:
-The expected frame name for the Right Click menu of the plugin is:
-"TitanPanelRightClickMenu_Prepare"..<registry.id>.."Menu"
+Jan 2026 :
+- Created this file by moving menu routines from TitanUtils.
+- The UIDropDownMenu was deprecated as of 11.0.0 (Dragonflight) and could be removed from the game code.
+- Thankfully the new method, Blizzard_Menu, is present in all versions of WoW.
+Titan uses this scheme for its built-in plugins across all WoW versions.

-local drop_down_1 = "" -- changes drop down menu version. Blizzard hard-codes the value...
+Notes:
+- A Titan plugin being updated after 2026 Jan should switch to the Blizzard_Menu method.

-The L_* routines wrap the drop down menu API for Titan Classic plugins.
+- As of May 2025 Classic Era is the only version using an explicit timer to close menus.
+Titan uses a routine only in CE (UIDropDownMenu_StartCounting) to determine which version to use.

+- local drop_down_1 = "" -- changes depending on the drop down menu version. Blizzard hard-codes the value...

-Jan 2026 : New file moving menu routines from TitanUtils
 --]===]

 local _G = getfenv(0);
@@ -37,12 +63,8 @@ local drop_down_1 = "" -- changes if using Blizz drop down (retail) or lib (Clas
 --====== Set the default drop down menu routines per retail or Classic
 drop_down_1 = "DropDownList1" -- Boo!! Per hard-coded Blizz UIDropDownMenu.lua

---[===[ Var API Dropdown Menu wrappers
-Right click menu routines for 3rd party plugins (mainly Classic WoW versions)
-
---]===]

---[[ UI dropdown lib wrappers - Classic plugins mainly
+--[[ UI dropdown lib wrappers - Classic Era plugins mainly
 Local helper(s) from the Ace lib.
 --]]
 -- L_UIDropDownMenuTemplate
@@ -667,11 +689,33 @@ end

 --====== Right click menu routines for Titan Panel bars and plugins

+local function CloseAnyMenu()
+	-- UIDropDownMenu from Blizzard
+	if (_G["DropDownList1"] and _G["DropDownList1"]:IsVisible()) then
+		_G["DropDownList1"]:Hide()
+	else
+		-- not open
+	end
+
+	-- Titan wrapped UIDropDownMenu
+	if _G[drop_down_1] and _G[drop_down_1]:IsVisible() then
+		_G[drop_down_1]:Hide()
+	else
+		-- not open
+	end
+
+	-- Newer Blizzard menu scheme
+	local menu_mgr = Menu.GetManager()
+	if (menu_mgr and menu_mgr:IsAnyMenuOpen()) then -- Blizzard_Menu
+		menu_mgr:CloseMenus();
+	else
+		-- not open
+	end
+end
+
 ---Titan Close the right click menu of any plugin, if it was open. Only one can be open at a time.
 function TitanUtils_CloseRightClickMenu()
-	if (_G["DropDownList1"]:IsVisible()) then
-		_G["DropDownList1"]:Hide();
-	end
+	CloseAnyMenu()
 end

 local function PlaceMenu(self, menu)
@@ -753,18 +797,6 @@ end
 ---@param menu table Frame to use as the menu
 --- Set Titan_Debug.titan.menu to output the error to Chat.
 local function TitanRightClickMenu_OnLoad(self, menu)
-	--[[
-: If menu is for a Titan bar then use TitanPanelRightClickMenu_PrepareBarMenu for ALL Titan bars.
-
-- If Function is a function then the routine can be local or in the global namespace
-- If Function is a string then the routine MUST be in the global namespace.
-
-- The function to create the menu is determined in this order:
-1. Use registry.menuContextFunction - New in 2026 Jan to use Blizzard_Menu scheme intro in 11.0.0
-2. Use registry.menuTextFunction - New in 2024 Feb to allow a explicit menu routine name
-3. Assumed to be "TitanPanelRightClickMenu_Prepare"..plugin_id.."Menu"
-: Titan was written in the beginning to look for this routine so we leave it to not break older plugins.
---]]
 	local id = ""
 	local err = ""
 	local context_menu = false
@@ -856,65 +888,66 @@ end

 ---Titan Close the right click menu if shown. There can only be one.
 function TitanPanelRightClickMenu_Close()
-	if _G[drop_down_1] and _G[drop_down_1]:IsVisible() then
-		_G[drop_down_1]:Hide()
-	end
+	CloseAnyMenu()
 end

+--[=====[ Implementation notes
+--]=====]
+
 --[=====[ NEW menu scheme Jan 2026
 Blizzard introduced a new menu scheme in 11.0.0 (July 2024) coded in Blizzard_Menu.
-The menu scheme is so different new routines are needed so use a new namespace
+The menu scheme is so different we use a new namespace for the new wrapper routines.

 First: Blizzard_Menu works quite different than UIDropDownMenu.
 UIDropDownMenu iterated over the code to create and show the menu.
-Blizzard_Menu changed that scheme it iterates over the objects - not code.
+Blizzard_Menu changed that scheme to iterate over the objects - not code.
 It now expects a set of nested objects (sort of the old info) to be created.
 One impact is - level and info.value disappear!
 The dev no longer needs to check level and info.value to determine which portion of the menu to display.

-Now a 'root description' / menu is created to act as the new 'level 1' / main menu.
+Now a 'root description' / menu is created to act as the new 'level 1' or main menu.
 The routine to create the new menu widgets is passed to the menu create.
+The output is expected to be a nested set of tables describing the menu.
+
 Nesting of submenus are created by attaching a new widget to a menu or button.
 Much as child frames are created with a parent. This acts as the old info.hasArrow.

 Second: The scheme using UIDropDownMenu was deprecated and could be removed in the future.
-This scheme *may* be introduced to Classic in the future.
-Titan needs to keep new and old schemes working side by side.
+Titan needs to keep new and old schemes working side by side for now.
 Thankfully, the two menu schemes work side by side BUT look different.

-Fourth: Blizzard_Menu is intended for full frame options with full blown menu widgets
+Third: Blizzard_Menu is intended for options using a frame with full blown menu widgets
 such as dropdowns, toggles, sliders, and more. It is used for Blizzard options, character creation, and more.

 We decided to KISS (Keep It Simple, Stupid) when using Blizzard_Menu.
 We use a small number of routines designed to use menu default settings. There are very few options to tweak.
-This should protect Titan when Blizzard changes the internal menu implementation.
-Those routines are:
+The routines used as base for Titan menus are:
 - MenuUtil.CreateContextMenu -- root of the menu; old UIDropDownMenu_Initialize
 - MenuUtil.CreateButton -- old info.text; info.func
 - MenuUtil.CreateCheckbox -- old info.text; info.checked; info.func
 - MenuUtil.CreateRadio -- old info.text; info.checked; info.func
-These handle over 90% of Titan and plugin needs.
-Additionally we need to handle :
 - owner:SetEnabled -- old info.disabled
+These handle over 90% of Titan and plugin needs.

 Fourth: Titan wraps the parts of Blizzard_Menu used in a new Titan_Menu table / class.
-See Titan_Menu.lua for available wrappers - feel free to suggest more :).
 Titan_Menu should protect Titan plugin devs when Blizzard changes the internal menu implementation.

 === Implementation notes
-A new Titan registry attribute, .menuContextFunction, was added to the .registry.
-It was created to do explicitly state the plugin routine needed to create the menu widgets.
-Titan will use, in order :
+A new Titan registry attribute, .menuContextFunction, was added to the .registry for plugins to use.
+It was created to explicitly state the plugin routine used to create the menu widgets.
+
+When asked to create a menu, Titan will use the first method found.
+In order these are :
 1) registry.menuContextFunction  : NEW Jan 2026
 2) registry.menuTextFunction  : Feb 2024
 3) "TitanPanelRightClickMenu_Prepare" .. id .. "Menu" : Old as Titan :)

 On right click, Titan will, in order :
-1) create the context menu
-2) add a menu title at top using .registry.id
-3) call the plugin to fill it as before - using pcall, placing error in the menu
-4) add the control vars + right side + Hide on bottom of menu
-The top and bottom of the menu are common so Titan adds them for consistent style.
+1) Create the context menu
+2) Add a menu title at top using .registry.id
+3) Call the plugin to fill it as before - using pcall, placing error in the menu
+4) Add the plugin designated control vars + right side + Hide on bottom of menu
+The top and bottom of the menu are common so Titan adds them for consistent style and relieve the dev a bit.

 The context menu holds all widgets - no nesting of context menus.
 Titan provides routines in Titan_Menu to relieve the dev from some grunt work.
@@ -931,7 +964,7 @@ The old create menu is left in TitanBag for comparison. As a quick example:
 	TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());
 == NEW
 	Titan_Menu.AddSelector(root, TITAN_BAG_ID, L["TITAN_BAG_MENU_OPEN_BAGS"], "OpenBags")
-Where root is the context menu; teh locale string (L) will be placed inline at the main menu.
+Where root is the context menu; the locale string (L) will be placed inline at the main menu.
 ===

 Only atomic elements / widgets can easily be added to the context menu.
diff --git a/Titan/TitanMovable.lua b/Titan/TitanMovable.lua
index 4af8929..4fc313f 100755
--- a/Titan/TitanMovable.lua
+++ b/Titan/TitanMovable.lua
@@ -876,7 +876,7 @@ end
 function Titan_AdjustScale()
 	-- Only adjust if Titan is fully initialized
 	if Titan__InitializedPEW then
-		TitanPanel_SetScale();
+--		TitanPanel_SetScale();

 --		TitanPanel_ClearAllBarTextures()
 --		TitanPanel_CreateBarTextures()
@@ -886,9 +886,10 @@ function Titan_AdjustScale()
 				, TITAN_PANEL_PLACE_TOP);
 		end
 --]]
+		TitanPanel_InitPanelButtons("Movable")
 		TitanMovableFrame_MoveFrames()
 --		TitanPanelBarButton_DisplayBarsWanted()
-		TitanPanel_RefreshPanelButtons();
+--		TitanPanel_RefreshPanelButtons();
 	end
 end

diff --git a/Titan/TitanTemplate.lua b/Titan/TitanTemplate.lua
index 4ed1c13..dad81ea 100644
--- a/Titan/TitanTemplate.lua
+++ b/Titan/TitanTemplate.lua
@@ -78,6 +78,7 @@ local _G = getfenv(0);
 local InCombatLockdown = _G.InCombatLockdown
 local media = LibStub("LibSharedMedia-3.0")

+--- Set Titan_Debug.titan.tool_tips to output debug
 --==========================

 --[[ local
@@ -86,6 +87,7 @@ DESC: Set the scale of each plugin and each Titan bar.
 VAR:  None
 OUT:  None
 --]]
+--[[
 function TitanPanel_SetScale()
 	local scale = TitanPanelGetVar("Scale");

@@ -100,6 +102,7 @@ function TitanPanel_SetScale()
 		end
 	end
 end
+--]]

 ---local Helper to add a line of tooltip text to the tooltip.
 ---@param text string To add
@@ -138,7 +141,6 @@ end
 ---@param xOffset number X offset
 ---@param yOffset number Y offset
 ---@param frame table Tooltip frame
---- Set Titan_Debug.titan.tool_tips to output debug
 local function TitanTooltip_SetOwnerPosition(parent, anchorPoint, relativeToFrame, relativePoint, xOffset, yOffset, frame)
 	-- Changes for 9.1.5 Removed the background template from the Tooltip
 	-- Making changes to it difficult and possibly changing the tooltip globally.
@@ -157,7 +159,7 @@ local function TitanTooltip_SetOwnerPosition(parent, anchorPoint, relativeToFram
 		frame:SetScale(TitanPanelGetVar("TooltipFont"));
 	end

-	local dbg_msg = "_pos"
+	local dbg_msg = "_SetOwner _pos"
 		.. " '" .. tostring(frame:GetName()) .. "'"
 		.. " " .. tostring(frame:IsShown()) .. ""
 		.. " @ '" .. tostring(relativeToFrame) .. "'"
@@ -272,14 +274,14 @@ end

 ---local Set the tooltip of the given Titan plugin.
 ---@param self table Plugin frame
---- Set Titan_Debug.titan.tool_tips to output debug of this routine
 local function TitanPanelButton_SetTooltip(self)
-	local dbg_msg = "TT:"
+	local dbg_msg = "_SetTooltip"
 	local ok = false
 	local frame = TitanPanelTooltip --GameTooltip
 	local id = self.registry.id

 	frame.registry_id = id -- for use in other routines
+	frame.plugin_frame = self
 	frame.plugin_frame_str = self:GetName()

 	ok = AllowTooltip(frame)
@@ -694,6 +696,11 @@ function TitanPanelButton_OnEnter(self)
 	if (id) then
 		TitanPanelButton_SetTooltip(self)
 	end
+
+	-- If tooltip was requested and successful, the tooltip OnUpdate
+	-- will be active.
+	-- NOTE: !!! The tooltip scripts will check if the mouseis over this
+	-- plugin, if so then the tooltip will be kept visible !!!
 end

 ---API Handle the OnLeave event of the requested Titan plugin.
@@ -706,10 +713,17 @@ function TitanPanelButton_OnLeave(self)
 	end

 	-- The cursor has moved away from the plugin.
-	-- Let the tooltip SetScripts handle timer to Hide.
-	--if (id) then
-	--	TitanPanelTooltip:Hide();
-	--end
+	-- NOTE: !!! It is possible, especially with Short bars that the
+	-- user never mouses over the tooltip so start the Hide timer !!!
+	--
+	-- Let the tooltip SetScripts handle OnEnter and OnLeave if
+	-- the user mouses over.
+	if TitanPanelTooltip:IsShown() then
+		local time_out = TitanPanelGetVar("TooltipTimeout")
+		TitanUtils_StartFrameCounting(TitanPanelTooltip, time_out)
+	else
+		-- nothing to do
+	end

 	if TitanPanelGetVar("DisableTooltipFont") then
 		-- use game font & scale
@@ -1237,16 +1251,94 @@ function TitanOptionsSliderTemplate_OnLoad(self)
 end

 -- Set tool tip scripts
+-- OnUpdate starts as soon as OnShow is done...
 local tt_frame = TitanPanelTooltip
+local tt_init_timeout = .5

 tt_frame:SetScript("OnShow", function(self)
+	local time_out = TitanPanelGetVar("TooltipTimeout")
+	local dbg_msg = "OnShow"
+		.. " timeout: " .. tostring(time_out) .. ""
+		.. " USING:  " .. tostring(tt_init_timeout) .. ""
+		.. " isCounting: " .. tostring(self.isCounting) .. ""
+		.. " timer: " .. tostring(self.frameTimer) .. ""
+		.. " plugin: " .. tostring(self.registry_id) .. ""
+		.. " plugin_frame: " .. tostring(self.plugin_frame_str) .. ""
+	Titan_Debug.Out('titan', 'tool_tips', dbg_msg)
+
+	-- OnShow will start the OnUpdate.
+	-- If user enters plugin, the tooltip will show
+	-- BUT if the user never enters the tooltip, it will keep showing because
+	-- the OnLeave did not kick the timer.
+	TitanUtils_StartFrameCounting(self, tt_init_timeout)
 end)
 tt_frame:SetScript("OnEnter", function(self)
+	local time_out = TitanPanelGetVar("TooltipTimeout")
+
+	local dbg_msg = "OnEnter"
+		.. " timeout: " .. tostring(time_out) .. ""
+		.. " isCounting: " .. tostring(self.isCounting) .. ""
+		.. " timer: " .. tostring(self.frameTimer) .. ""
+	Titan_Debug.Out('titan', 'tool_tips', dbg_msg)
+
 	TitanUtils_StopFrameCounting(self)
 end)
 tt_frame:SetScript("OnLeave", function(self)
-	TitanUtils_StartFrameCounting(self, TitanPanelGetVar("TooltipTimeout"))
+	local time_out = TitanPanelGetVar("TooltipTimeout")
+
+	local dbg_msg = "OnLeave"
+		.. " timeout: " .. tostring(time_out) .. ""
+		.. " isCounting: " .. tostring(self.isCounting) .. ""
+		.. " timer: " .. tostring(self.frameTimer) .. ""
+	Titan_Debug.Out('titan', 'tool_tips', dbg_msg)
+
+	if time_out < 0.1 then
+		tt_frame:Hide() -- hide right away
+	else
+		TitanUtils_StartFrameCounting(self, time_out)
+	end
 end)
+
+local debug_over = false
+local debug_over_new = false
 tt_frame:SetScript("OnUpdate", function(self, elapsed)
-	TitanUtils_CheckFrameCounting(self, elapsed);
+	local time_out = TitanPanelGetVar("TooltipTimeout")
+
+	--[[ -- Be VERY careful enabling this debug :)
+	local dbg_msg = "TT OnUpdate"
+		.. " timeout: " .. tostring(time_out) .. ""
+		.. " isCounting: " .. tostring(self.isCounting) .. ""
+		.. " timer: " .. tostring(self.frameTimer) .. ""
+	--Titan_Debug.Out('titan', 'tool_tips', dbg_msg)
+	if self.isCounting == nil then
+		Titan_Debug.Out('titan', 'tool_tips', dbg_msg)
+	elseif self.frameTimer <= 0.01 then
+		Titan_Debug.Out('titan', 'tool_tips', dbg_msg)
+	else
+	end
+	--]]
+
+	-- Compromise to keep tooltip open if the user stays over plugin
+	-- and does not mouse over tooltip frame (OnEnter)
+	local is_over = self.plugin_frame:IsMouseOver()
+	if is_over then
+		TitanUtils_StopFrameCounting(self)
+		debug_over_new = true
+	else
+		TitanUtils_CheckFrameCounting(self, elapsed);
+		debug_over = false
+	end
+
+	--[[
+	if debug_over ~= debug_over_new then
+		debug_over = debug_over_new
+		local dbg_msg = "OnUpdate"
+			.. " over: " .. tostring(is_over) .. ""
+			.. " timeout: " .. tostring(time_out) .. ""
+			.. " isCounting: " .. tostring(self.isCounting) .. ""
+			.. " timer: " .. tostring(self.frameTimer) .. ""
+		Titan_Debug.Out('titan', 'tool_tips', dbg_msg)
+	else
+	end
+	--]]
 end)
diff --git a/Titan/TitanTemplate.xml b/Titan/TitanTemplate.xml
index ef030d6..c0d8ba9 100644
--- a/Titan/TitanTemplate.xml
+++ b/Titan/TitanTemplate.xml
@@ -75,6 +75,9 @@
 		</PushedTextOffset>
 	</Button>

+	<!--
+	2026 Feb : Title was added to simplify Volume and give develpers more choice.
+	-->
 	<Slider name="TitanOptionsSliderTemplate" orientation="VERTICAL" inherits="BackdropTemplate" virtual="true" enableMouse="true" >
 		<Size>
 			<AbsDimension x="10" y="100"/>
@@ -84,6 +87,15 @@
 		</HitRectInsets>
 		<Layers>
 			<Layer level="ARTWORK">
+				<FontString name="$parentTitle" inherits="GameFontGreenSmall">
+					<Anchors>
+						<Anchor point="TOP" relativePoint="TOP">
+							<Offset>
+								<AbsDimension x="0" y="24" />
+							</Offset>
+						</Anchor>
+					</Anchors>
+				</FontString>
 				<FontString name="$parentText" inherits="GameFontGreenSmall">
 					<Anchors>
 						<Anchor point="LEFT" relativePoint="RIGHT">
diff --git a/Titan/TitanUtils.lua b/Titan/TitanUtils.lua
index 5a8487c..8099fe1 100644
--- a/Titan/TitanUtils.lua
+++ b/Titan/TitanUtils.lua
@@ -1006,7 +1006,7 @@ local function TitanUtils_SwapButtonOnBar(from_id, to_id)
 	TitanPanelSettings.Location[from_id] = TitanPanelSettings.Location[to_id]
 	TitanPanelSettings.Buttons[to_id] = button
 	TitanPanelSettings.Location[to_id] = locale
-	TitanPanel_InitPanelButtons();
+	TitanPanel_InitPanelButtons("_SwapButtonOnBar");
 end

 ---local Find the next button index that is on the same bar and is on the same side.
@@ -1074,7 +1074,7 @@ function TitanUtils_AddButtonOnBar(bar, id)
 	-- update / add to the Location
 	TitanPanelSettings.Buttons[i] = (id or "?")
 	TitanPanelSettings.Location[i] = (bar or "Bar")
-	TitanPanel_InitPanelButtons();
+	TitanPanel_InitPanelButtons("_AddpButtonOnBar");
 end

 ---Titan Find the first button that is on the given bar and is on the given side.
diff --git a/Titan/TitanVariables.lua b/Titan/TitanVariables.lua
index bf49791..daded03 100644
--- a/Titan/TitanVariables.lua
+++ b/Titan/TitanVariables.lua
@@ -608,7 +608,7 @@ TITAN_PANEL_SAVED_VARIABLES = {
 	IconSpacing = 0,
 	TooltipTrans = 1,
 	TooltipFont = 1,
-	TooltipTimeout = .5,
+	TooltipTimeout = 0.0, -- New 2026 Jan
 	DisableTooltipFont = 1,
 	FontName = TPC.FONT_NAME,
 	FrameStrata = "LOW",
@@ -1822,16 +1822,18 @@ function TitanVariables_UseSettings(from, profile, action)
 	TitanVariables_SetPanelStrata(TitanPanelGetVar("FrameStrata"))

 	-- show the new profile
+--[[
 	-- build debug output
 	str = "...init bars"
 		.. " " .. tostring(action) .. ""
 	Titan_Debug.Out('titan', 'profile', str)
 	TitanPanel_InitPanelBarButton("UseSettings");
+--]]
 	-- build debug output
 	str = "...init plugins on bars"
 		.. " " .. tostring(action) .. ""
 	Titan_Debug.Out('titan', 'profile', str)
-	TitanPanel_InitPanelButtons();
+	TitanPanel_InitPanelButtons("_UseSettings");
 end

 -- decrecated routines
diff --git a/Titan/_ATitanDoc.lua b/Titan/_ATitanDoc.lua
index d684ca4..7220510 100644
--- a/Titan/_ATitanDoc.lua
+++ b/Titan/_ATitanDoc.lua
@@ -1,57 +1,74 @@
---[===[ File
+--[======[ File
 Starts the Titan developer documention.
---]===]
+--]======]

---[===[ Titan Documentation Beginning
+--[======[ Titan Documentation Beginning

 This document will introduce Titan essentials for a Titan developer.
 The intent is simplify what may appear to be a daunting experience.

 We suggest you grab your favorite beverage, read this doc, and relax!
-Many of Titan mysteries will be explained. 🙂
+Many Titan mysteries will be explained. 🙂

 The Titan team and its users are available to answer questions.
 The two most used ways are :
 - The Titan Discord community
 - Curse comments under Titan Panel addon

-=== IDE Tools used:
+====== IDE Tools used:
 For small changes to Titan, an editor with syntax highlighting and code folding features such as NotepadPlusPlus can be used.

+For larger changes or ongoing maintenance an IDE is suggested.
+
+This is the one used at the moment:
 Visual Studio Code - https://code.visualstudio.com/
-Other IDEs accept Lua Language Server, see if your prefered IDE will accept LLS.
+
+Additional IDE plugins are used for Lua and WoW API.

 Lua Language Server (LLS) - https://marketplace.visualstudio.com/items?itemName=sumneko.lua
 	https://github.com/LuaLS/lua-language-server
 WoW API - LLS extension - https://marketplace.visualstudio.com/items?itemName=ketho.wow-api
 	https://github.com/Ketho/vscode-wow-api

-And a tiny Python parser to pull these comments.
+Other IDEs accept Lua Language Server, see if your prefered IDE will accept LLS.

 Note:
     - The WoW API plugin is geared to Retail.
     There was no option to automatically include 'Classic' deprecated routines.
-    - There are diagnostic annotations used to ignore some warnings.
+    - Diagnostic annotations are used to ignore some warnings.
     Ignore warning annotations were limited as much as practical to 'this line' to point out usage of Classic routines.
     - Files or folders for the IDE such as .vscode; Titan.code-workspace; and others are included in the TItan release.

-The file _TitanIDE.lua contains Titan specific IDE Intellisense definitions. It is NOT included in the TOC file.
+The file _TitanIDE.lua contains Titan specific IDE Intellisense definitions.
+These defintions tell the IDE that we know what we are doing, often providing coding assistance.
+It is NOT included in the TOC file.

-=== Documentation blocks
+====== Documentation blocks
 These are created from annotations in the Lua files.

-API :
+--[===[ File
+Contains ...
+--]===]
+Each file has a terse description of its contents.
+
+---API
 These are routines Titan will keep stable.
-Changes to these varaibles and routines will be broadcast to developers via Discord at a minimum.
+Changes to these varibles and routines will be broadcast to developers via Discord at a minimum.

-Dev :
+---Titan
 These are global routines Titan uses. These may change at any time per Titan needs and design.

-File :
-Each file has a terse description of its contents.
+--[===[ Var
+...
 --]===]
+These are critical tables and info used within Titan.
+Unless specifically marked otherwise, treat these as "---Titan".
+
+---local
+These are local routines that may change at any time.
+--]======]

---[===[ Titan Start editing
+--[======[ Titan Start editing

 Before you start changing any code, it is HIGHLY recommended to install the following WoW addons:
 - BugGrabber : Grabs errors and stores them
@@ -65,7 +82,7 @@ Reload is /reload in game chat.

 Regardless of tools used, please update any annotations and comments as changes are made!!!

-=== Additional Help For You
+====== Additional Help For You
 A good Lua resource is https://www.lua.org/docs.html
 NOTE: WoW uses Lua version 5.1 as its base.
 NOTE: WoW does restrict, add, or even remove some Lua features. For example the file routines and many OS routines are not available to an addon.
@@ -76,7 +93,7 @@ There are sites that have deeper explanations about addon development, such as
 Please use these or other sites for more detailed addon and API information.
 The API information changes as Blizzard adds features, changes API methods, or any other reason.

-=== Folder Structure
+====== Folder Structure
 Inside the Titan folder you will notice :
 - Artwork folder : Contains skins used by Titan
 - libs : Library routines Titan uses
@@ -86,22 +103,21 @@ Inside the Titan folder you will notice :
 - This file


-=== .toc
+====== .toc
 The site https://warcraft.wiki.gg/wiki/TOC_format contains more info than you will ever need on TOC format.

 The folder and the .toc files MUST have the same name!
 Sort of... the name prior to the underscore(_) must be the same as the folder name.
-The part after (postfix) has meaning to the WoW addon loader.
-This list changes : https://warcraft.wiki.gg/wiki/TOC_format
+The part after (postfix) has meaning to the WoW addon loader tells the loader the expansions the addon should be loaded for.
+
+Titan uses at least one postfix value - _Vanilla - for Classic Era version to load Ammo and Regen for CE only.

-Titan uses at least one postfix value - _Vanilla - for Classic Era version
-Notice Ammo and Regen use _Vanilla.toc files.
-This allows Titan to load plugins (built-in or 3rd party) intended for Classic only without change.
+====== .toc internals
+Each .toc file begins with 'directives' which start with "##".

-=== .toc internals
-NOTE: The ## Interface value should match the current interface value of the corresponding WoW version.
+The ## Interface value should match the current interface value of the corresponding WoW version.
 In BattleNet this is typically shown below the 'Play' button.
-DragonFlight 10.02.05 is represented without dots - 100207 - in the .toc.
+For example, DragonFlight 10.02.05 is represented without dots - 100207 - in the .toc.

 If the interface value is higher or lower, WoW will complain that you are running 'out of date' addons.

@@ -119,19 +135,20 @@ Then all the localization files.

 Then the Titan code files.

-=== Artwork
+====== Artwork

 WoW tends to use .tga image files.
 Lookup TextureBase:SetTexture for current accepted image types.
 NOTE: All versions of WoW may not accept all image types.

-Most graphic art software can save to these formats. We don’t recommend using an online source to convert one image format to another.
-They have a tendency to add additional code or info to the artwork.
---]===]
+Most graphic art software can save to these formats.
+We don’t recommend using an online source to convert one image format to another.
+They have a tendency to add additional code or info to the image.
+--]======]

---[===[ Titan Addon code flow
+--[======[ Titan Addon code flow

-First step: ==== Starting WoW
+First step: ======= Starting WoW
 Wow will load Titan along with other addons installed. The order addons are installed is not guaranteed!

 The files listed in the TOC will will be loaded and run in the order listed.
@@ -142,28 +159,30 @@ Examples:
 - Creation of functions
 - TitanLDB.lua creates LDBToTitan frame to handle LDB objects

-ADDON_LOADED event is fired after every addon WoW is loaded.
-When ADDON_LOADED event for Titan is received:
+ADDON_LOADED event is fired after every addon WoW loads.
+When the ADDON_LOADED event for Titan is received:
 - Titan registers for event PLAYER_ENTERING_WORLD
-- Titan ensures its saved variables are whole and known player profiles are read
+- Titan ensures its saved variables are whole and known player profiles are read.

 NOTE: On ADDON_LOADED is the first time addon saved variables should be considered loaded and safe!!
 Using addon saved variables before ADDON_LOADED is likely to result in nil(s).

-NOTE: The addon saved vars are NOT the Titan plugin saved vars via the registry (.savedVariables)! The registry is processed later!
+NOTE: The addon saved vars are NOT the Titan plugin saved vars via the registry (.savedVariables)!
+The registry is processed later!

-Next: ==== Waiting for WoW
+Next: ======= Waiting for WoW
 WoW fires a bunch of events as this and other addons are loaded.
 Eventually the game and all addons are loaded and PLAYER_ENTERING_WORLD event is sent

-Next: ==== Entering world - PLAYER_ENTERING_WORLD (PEW) event
-NOTE: This event (with parameter) is sent on both login and reload.
+Next: ======= Entering world - PLAYER_ENTERING_WORLD (PEW) event
+NOTE: This event is sent on both login and reload with a parameter to tell the difference.

 When PLAYER_ENTERING_WORLD event is received via OnEvent, the real work begins.
-The PEW events do NOT guarantee order across addons, even if a dependency is listed! Titan plugins (addons) could receive a PEW before Titan - See NOTE below.
+There is NO guarantee PEW events are sent in any order across addons!
+See 'Titan Relationship' section below.

 The local routine - TitanPanel_PlayerEnteringWorld - is called using pcall.
-This ensures Titan reacts to errors rather than forcing an error to the user and leaving Titan (and possibly the user) in a bad state.
+This ensures Titan reacts to errors rather than leaving Titan, and possibly WoW, in a bad state.
 TitanPanel_PlayerEnteringWorld does all the variable and profile setup for the character entering the world.

 On login PLAYER_ENTERING_WORLD - not reload - Titan
@@ -174,75 +193,110 @@ On login PLAYER_ENTERING_WORLD - not reload - Titan

 On login and reload Titan
 - Set THIS character profile () - TitanVariables_UseSettings -
-   See TitanVariables (File) for more details on saved variables; this is a simple concept but touchy to implement.
-   The user chosen profile sets the user chosen plugin saved vars for both Titan and any plugins - see NOTE below.
+   See TitanVariables file for more details on saved variables; this is a simple concept but touchy to implement.
+   The user chosen profile sets the user chosen plugin saved vars for both Titan and any plugins.
    TitanVariables_UseSettings uses
    - TitanPanel_InitPanelBarButton to set the bars the user wants.
-   - TitanPanel_InitPanelButtons to set the plugins the user wants on the user selected bars via OnShow.
+   - TitanPanel_InitPanelButtons to set the plugins the user wants on the user selected bars.
 - Update the Titan config tables for the config screens - TitanUpdateConfig
 - Set Titan font and strata
-- Sync any LDB plugins with the cooresponding Titan plugin- TitanLDBRefreshButton
+- Register and set up any Titan plugins.
+- Wrap any LDB plugins with a generated Titan plugin- TitanLDBRefreshButton

 If the above was successful then all is good
-If the above failed with an error then
+If the above failed then
 - tell user something bad happened along with the error they can pass to the dev team
 - attempt to hide all bars as cleanup
 - nuke the Titan config tables as cleanup

-NOTE: The PEW event is an important but subtle distinction for Titan plugins!
-Titan plugins should be very careful if they use the PEW event to run code. The PEW events do NOT guarantee order!
-Meaning the plugin PEW could be processed BEFORE Titan has set saved vars for itself or plugins.
-Titan plugins should not assume ANY saved vars are available until their OnShow.
-Only at the OnShow is the profile known and the plugin saved vars guaranteed to be set.
-We have seen bugs occur on some user systems due to the order addons get and process the PEW event.
---]===]
+--]======]
+
+--[======[ Titan Panel relationship to Titan plugins and LDB
+Titan plugins list Titan as a dependency.
+This ensures Titan is loaded before the plugin and the plugin has access to Titan routines and libs.
+Because Titan registers plugins during PEW, this means Titan calls the plugin OnShow BEFORE the plugin gets its PEW.
+
+A best practice we use in Titan plugins is wait until OnShow to set up resources and processing.
+Then nicely shut down those resources and processing in OnHide.
+This keeps Titan from using resources when the user is not using a plugin.
+
+A side effect of PEW order and best practice is a Titan plugin gets OnShow before PEW.
+In practice this is not harmful but it can be confusing if the plugin relies on PEW to initialize itself.
+
+LDB objects are another source of Titan plugins.
+LDB objects are created by other addons using the LibDataBroker library.
+These objects can be created at any point before or after Titan is up and ready.
+Titan will wrap each LDB object in a generated Titan plugin so it can be displayed by Titan.
+TitanLDB.lua contains more information.
+--]======]

---[[ Frames and Frame Scripts
-Here we detour into XML. TitanTemplate.xml contains the frame definitions used by Titan.
-- TitanPanelBarButton : This "is" Titan in the sense that it has all events attached to it and all the code.
+--[======[ Frames and Frame Scripts
+Here we detour into XML. Titan uses XML only to declare virtual frames used throughout Titan.
+Virtual frames can only be declared in XML.
+They are frame templates used in the 'inherits' parameter of CreateFrame.
+We find creating needed frames in Lua cleaner and less confusing.
+
+TitanTemplate.xml contains the frame definitions used by Titan.
+- TitanPanelBarButton : This "is" Titan in the sense that all events are attached to this frame.
 - Titan_Bar__Display_Template : The template (Button) for a Titan bar.
-- TitanPanelBarButtonHiderTemplate : The template (Button) paired a full width Titan bar to allow hiding and unhiding the paired Titan Bar.
-- TitanPanelTooltip : This or GameTooltip is used for tool tips.
-Currently, the only way to define a 'virtual' template is in XML.
+- TitanPanelBarButtonHiderTemplate : The template (Button) paired to each full width Titan bar;
+	Allows hiding and unhiding the paired Titan Bar.
+- TitanPanelTooltip : This is used for plugin tool tips.

 TitanBarData in TitanVariables.lua holds creation data for each bar.
 TitanPanelButton_CreateBar in Titan.lua creates the full width bars and short bars by looping through TitanBarData.
-TitanBarDataVars holds the Titan and user settings for each bar. An initial setup (fresh / another install) uses TitanBarVarsDefaults.
-
-The frame scripts (OnShow, etc) are how WoW and Titan interact with this addon.
+TitanBarDataVars holds the Titan and user settings for each bar.
+An initial setup / install uses TitanBarVarsDefaults.

-==== OnEnter and OnLeave frame scripts :
-Titan sets these scripts on a Bar for future use. Currently Titan does no work.
+The frame scripts (OnShow, etc) are how WoW and Titan interact with the plugin.

-For Titan Hider Bars these are used to show / hide the Titan Bar.
-Note: Hider Bars are only for the full width bars - NOT Short Bars.
+======= OnClick frame scripts - TitanPanelButton_OnClick default behavior :
+-- Right click is to open the Titan menu.

-==== OnClick frame scripts :
-Right click is to open the Titan menu.
-Left click closes any tooltip and any menu.
+-- Left click closes any tooltip and any menu.
+Then looks for a control frame - frame with name of "TitanPanel" .. plugin_id .. "ControlFrame".
+If a control frame exists, show it.
+This is used by Volume and Clock to show sliders which are not possible in a menu.

-On Short Bars Titan registers for
+======= OnDragStart and OnDragStop frame script :
+On Short Bars Titan registers only to allow moving them (left mouse button).
 - OnDragStart and OnDragStop (left mouse button) for moving Short Bars
-- OnMouseWheel to size a Short Bar

-==== OnShow frame script :
+======= OnMouseWheel frame script :
+On Short Bars Titan registers to size a Short Bar
+
+======= OnShow frame script :
 Not used by Titan bars.

-==== OnHide frame script :
+======= OnHide frame script :
 Not used by Titan bars.

-==== OnEvent frame script :
+======= OnEvent frame script :
 Titan.lua sets the OnEvent stript for TitanPanelBarButton to redirect events to TitanPanelBarButton:<registered event>
 See local function RegisterForEvents for the list of eventsand their usage.
---]]

---[[ Plugin .registry
+======= OnEnter frame script :
+Used to show the plugin tooltip.
+With the addition of 'secret' values in 12.0.0 (Midnight) Titan does not use the Blizzard GameTooltip.
+Titan was blamed for 'secret' value access errors within and shortly after instances.
+
+Also used by Titan Hider Bars to show the hidden Titan Bar.
+
+======= OnHide frame script :
+Used to hide the plugin tooltip.

-=== Titan plugins
-Plugins are the heart of Titan. They provide the information and features users want to see
+Also used by Titan Hider Bars these are used to hide the Titan Bar.
+--]======]
+
+--[======[ Plugin .registry
+
+====== Titan plugins
+Plugins are the heart of Titan. They provide the information and features users want to see.
 The routine - TitanUtils_RegisterPluginList - starts the plugin registry process.

-=== LDB objects : See LDBTitan.lua for many more details.
+See TitanBag.lua for a LOT more detail.
+
+====== LDB objects : See LDBTitan.lua for many more details.
 The OnEvent script of LDBToTitan frame processes the PLAYER_LOGIN event.
 This starts the process to convert all known LDB objects into Titan plugins.

@@ -252,40 +306,45 @@ This event was chosen by the orignal developer.
 Each object found calls TitanLDBCreateObject using pcall to protect Titan.

 Before Titan is initialized (first PLAYER_ENTERING_WORLD) the LDB object will be added to the plugin list.
-As part of the PEW event processing, TitanUtils_RegisterPluginList will be used iteratively to register each found LDB object.
+As part of the PEW event processing, TitanUtils_RegisterPluginList will be used iteratively on each found LDB object.
 Most LDB objects are created on loading by addons. There may be an issue for addons that create many LDB objects on demand.
+--]======]

-The Titan plugin example has a lot more detail from the plugin view that would be helpful to a Titan dev.
---]]
+--[======[ Saved Variables
+WoW allows saved variables to be 'by account' or 'by character'.
+'by account' is a little misleading - it is 'by account' per WoW version.
+Retail and Classic Era are distinct and can not reference each other!

---[[ Saved Variables

-See TitanVariables.lua (File) for additional detail.
-
-Much of the info below is included in the Titan plugin example.
+See TitanVariables.lua for additional detail.

 NOTE: Titan routines have used 1 as true since inception so be careful on 'true checks'.
 As an example
 if ShowUsedSlots then
 *should* work fine if ShowUsedSlots is true or 1

-=== Where are these saved variables?????
+====== Where are these saved variables?????
+The saved variables can be found here: .../World of Warcraft/_retail_/WTF/Account/<account name>/SavedVariables/Titan.lua
+There is a Titan.lua.bak which is the prior save (logout / exit / reload).
+
+NOTE : _retail_ is for Retail WoW.
+Classic and other WoW versions will have different folder names, such as _classic_era_, _beta_, _*ptr_, etc.
+
 The saved variables are specified in the Titan toc :
 ## SavedVariables: TitanAll, TitanSettings, TitanSkins

+This will cause WoW to create a file - Titan.lua - with a table for each saved variable entry.
+Where "Titan" is the addon folder and .toc name.
+
+
 TitanSettings contains all the plugin saved variables.
-Titan uses the single table structure to store the saved variables across a user account.
+Titan uses the single table structure to store the saved variables across characters.
 This makes the setup code rather cumbersome and not straight forward - just warning...

-The saved variables can be found here: .../World of Warcraft/_retail_/WTF/Account/<account name>/SavedVariables/Titan.lua
-There is a Titan.lua.bak which is the prior save (logout / exit / reload).
+It is HIGHLY recommended opening the saved variables file in an
+editor that can handle large files and with code folding features!

-NOTE : _retail_ is for Retail WoW. Classic and other WoW versions will have different folder names, such as _classic_era_, _beta_, _*ptr_, etc.
-
-It is HIGHLY recommended opening the saved variables file in an editor with code folding features!
-This file could be quite large with many lines.
-I have 20+ characters on one server. Even though I do not use many addons, I do test with addons on some characters.
-My file is nearly 90,000 lines long!
+I have 20+ characters on one server. Even though I do not use many addons, my file is nearly 90,000 lines long!
 A plugin such as Titan Panel [Reputation] can create 100+ plugins.

 Say we want to find a character named Embic on Staghelm which you are using for testing.
@@ -348,5 +407,34 @@ TitanSettings = {
 				-- There may be helpful debug data here under your plugin name if the plugin is not shown as expected.
 				-- Titan > Configuration > Attempts shows some of this data, including errors.
 				}
-
---]]
+...
+TitanAll = {
+["OrderHall"] = true,
+["TimerAdjust"] = 1,
+["GlobalProfileUse"] = false,
+["TimerPEW"] = 4,
+["TooltipModiferAlt"] = false,
+["TimerLDB"] = 2,
+["TimerVehicle"] = 1,
+["UseTooltipModifer"] = false,
+["GlobalProfileName"] = "<>",
+["Silenced"] = false,
+["TooltipModiferCtrl"] = false,
+["TooltipModiferShift"] = false,
+["TimerDualSpec"] = 2,
+["Registered"] = false,
+}
+TitanSkins = {
+{
+["titan"] = true,
+["path"] = "Interface\\AddOns\\Titan\\Artwork\\",
+["name"] = "Titan Default",
+},
+{
+["titan"] = true,
+["path"] = "Interface\\AddOns\\Titan\\Artwork\\Custom\\AllBlack Skin\\",
+["name"] = "AllBlack",
+},
+...
+}
+--]======]
diff --git a/TitanGold/TitanGold.lua b/TitanGold/TitanGold.lua
index 60858fa..645f314 100644
--- a/TitanGold/TitanGold.lua
+++ b/TitanGold/TitanGold.lua
@@ -715,7 +715,7 @@ local function Initialize_Array()
 			local char = EvalIndexInfo(index)
 			if char.valid then
 				-- Added 2026 Feb
-			if TitanSettings.Players[index].Info[TITAN_GOLD_ID].show == nil then
+				if TitanSettings.Players[index].Info[TITAN_GOLD_ID].show == nil then
 					TitanSettings.Players[index].Info[TITAN_GOLD_ID].show = true -- default
 				else
 					-- exists, use as is
@@ -724,7 +724,6 @@ local function Initialize_Array()
 				-- ignore custom profiles or toons not logged into yet
 			end
 		end
-
 	end

 	local msg = ">Init done : "
diff --git a/TitanVolume/TitanVolume.lua b/TitanVolume/TitanVolume.lua
index fae9f6e..6aae983 100644
--- a/TitanVolume/TitanVolume.lua
+++ b/TitanVolume/TitanVolume.lua
@@ -20,41 +20,47 @@ local L = LibStub("AceLocale-3.0"):GetLocale(TITAN_ID, true)
 local ALL_SOUND = "Sound_EnableAllSound"

 -- The slider controls are nearly identical so set the data for them using the slider frame name
+local slider_y = -40
 local sliders = {
 	["TitanPanelMasterVolumeControlSlider"] = {
 		short = "master",
 		cvar = "Sound_MasterVolume",
 		gtext = OPTION_TOOLTIP_MASTER_VOLUME,
+		ltext = L["TITAN_VOLUME_MASTER_CONTROL_TITLE"],
 		titan_var = "VolumeMaster",
-		off_x = -160, off_y = -60,
+		off_x = -160, off_y = slider_y,
 	},
 	["TitanPanelSoundVolumeControlSlider"] = {
 		short = "sound",
 		cvar = "Sound_SFXVolume",
 		gtext = OPTION_TOOLTIP_FX_VOLUME,
+		ltext = L["TITAN_VOLUME_SOUND_CONTROL_TITLE"],
 		titan_var = "VolumeSFX",
-		off_x = -90, off_y = -60,
+		off_x = -90, off_y = slider_y,
 	},
 	["TitanPanelMusicVolumeControlSlider"] = {
 		short = "music",
 		cvar = "Sound_MusicVolume",
 		gtext = OPTION_TOOLTIP_MUSIC_VOLUME,
+		ltext = L["TITAN_VOLUME_MUSIC_CONTROL_TITLE"],
 		titan_var = "VolumeMusic",
-		off_x = -20, off_y = -60,
+		off_x = -20, off_y = slider_y,
 	},
 	["TitanPanelAmbienceVolumeControlSlider"] = {
 		short = "ambience",
 		cvar = "Sound_AmbienceVolume",
 		gtext = OPTION_TOOLTIP_AMBIENCE_VOLUME,
+		ltext = L["TITAN_VOLUME_AMBIENCE_CONTROL_TITLE"],
 		titan_var = "VolumeAmbience",
-		off_x = 50, off_y = -60,
+		off_x = 50, off_y = slider_y,
 	},
 	["TitanPanelDialogVolumeControlSlider"] = {
 		short = "dialog",
 		cvar = "Sound_DialogVolume",
 		gtext = OPTION_TOOLTIP_DIALOG_VOLUME,
+		ltext = L["TITAN_VOLUME_DIALOG_CONTROL_TITLE"],
 		titan_var = "VolumeDialog",
-		off_x = 130, off_y = -60,
+		off_x = 120, off_y = slider_y,
 	},
 }
 --C_CVar.GetCVar("Sound_MusicVolume")
@@ -123,7 +129,7 @@ local function OnEvent(self, event, a1, ...)
 end

 ---local Set plugin icon and update plugin.
-local function OnShow()
+local function OnShow(self)
 	if TitanGetVar(TITAN_VOLUME_ID, "OverrideBlizzSettings") then
 		-- Override Blizzard's volume CVar settings
 		if TitanGetVar(TITAN_VOLUME_ID, "VolumeMaster") then
@@ -188,8 +194,8 @@ local function Slider_OnShow(self)
 	local slider = sliders[self:GetName()]

 	_G[self:GetName() .. "Text"]:SetText(GetVolumeText(GetCVolume(slider.cvar)));
-	_G[self:GetName() .. "High"]:SetText(Titan_Global.literals.low);
-	_G[self:GetName() .. "Low"]:SetText(Titan_Global.literals.high);
+--	_G[self:GetName() .. "High"]:SetText(Titan_Global.literals.low);
+--	_G[self:GetName() .. "Low"]:SetText(Titan_Global.literals.high);
 	self:SetMinMaxValues(0, 1);
 	self:SetValueStep(0.01);
 	self:SetObeyStepOnDrag(true) -- since 5.4.2 (Mists of Pandaria)
@@ -231,20 +237,6 @@ local function OnMouseWheel(self, a1)
 	end
 end

----local Inititalize custom left click menu
----@param self Frame
-local function ControlFrame_OnLoad(self)
-	_G[self:GetName() .. "Title"]:SetText(L["TITAN_VOLUME_CONTROL_TITLE"]);         -- VOLUME
-	_G[self:GetName() .. "MasterTitle"]:SetText(L["TITAN_VOLUME_MASTER_CONTROL_TITLE"]); --MASTER_VOLUME
-	_G[self:GetName() .. "MusicTitle"]:SetText(L["TITAN_VOLUME_MUSIC_CONTROL_TITLE"]);
-	_G[self:GetName() .. "SoundTitle"]:SetText(L["TITAN_VOLUME_SOUND_CONTROL_TITLE"]); -- FX_VOLUME
-	_G[self:GetName() .. "AmbienceTitle"]:SetText(L["TITAN_VOLUME_AMBIENCE_CONTROL_TITLE"]);
-	_G[self:GetName() .. "DialogTitle"]:SetText(L["TITAN_VOLUME_DIALOG_CONTROL_TITLE"]);
-	--	_G[self:GetName().."MicrophoneTitle"]:SetText(L["TITAN_VOLUME_MICROPHONE_CONTROL_TITLE"]);
-	--	_G[self:GetName().."SpeakerTitle"]:SetText(L["TITAN_VOLUME_SPEAKER_CONTROL_TITLE"]);
-	TitanPanelRightClickMenu_SetCustomBackdrop(self)
-end
-
 ---local Generate tooltip text
 ---@return string
 local function GetTooltipText()
@@ -304,11 +296,7 @@ local function CreateMenu()
 	TitanPanelRightClickMenu_AddControlVars(TITAN_VOLUME_ID)
 end

----local On double click toggle the all sound mute; will flash the slider frame...
----@param self Button
----@param button string
-local function OnDoubleClick(self, button)
-	if button == "LeftButton" then
+local function ToggleMute()
 		-- Toggle mute value
 		if IsMuted() then
 			SetCVar(ALL_SOUND,"1")
@@ -316,13 +304,35 @@ local function OnDoubleClick(self, button)
 			SetCVar(ALL_SOUND,"0")
 		end
 		SetVolumeIcon()
-		_G[cname]:Hide()
-		TitanPanelButton_UpdateButton(TITAN_VOLUME_ID);
+--		_G[cname]:Hide()
+		TitanPanelButton_UpdateButton(TITAN_VOLUME_ID)
+end
+
+---local On double click toggle the all sound mute; will flash the slider frame...
+---@param self Button
+---@param button string
+local function OnDoubleClick(self, button)
+	if button == "LeftButton" then
+		ToggleMute()
 	else
 		-- No action
 	end
 end

+---Generate and display right click menu options for user.
+---@param owner table Plugin frame
+---@param rootDescription table Menu context root
+local function GeneratorFunction(owner, rootDescription)
+	local id = TITAN_VOLUME_ID
+	local root = rootDescription -- menu widget to start with
+
+-- This does not seem to work in any WoW version...
+	--	Titan_Menu.AddCommand(root, id, L["TITAN_VOLUME_MENU_AUDIO_OPTIONS_LABEL"], ShowUIPanel, VideoOptionsFrame)
+
+	-- Moved to the control frame (left click)
+	--Titan_Menu.AddSelector(root, id, L["TITAN_VOLUME_MENU_OVERRIDE_BLIZZ_SETTINGS"], "OverrideBlizzSettings")
+end
+
 ---local Create plugin .registry and and register for first events
 ---@param self Button
 local function OnLoad(self)
@@ -337,7 +347,7 @@ local function OnLoad(self)
 		category = "Built-ins",
 		version = TITAN_VERSION,
 		menuText = L["TITAN_VOLUME_MENU_TEXT"],
-		menuTextFunction = CreateMenu,
+		menuContextFunction = GeneratorFunction, -- NEW scheme
 		tooltipTitle = VOLUME, --L["TITAN_VOLUME_TOOLTIP"],
 		tooltipTextFunction = GetTooltipText,
 		iconWidth = 32,
@@ -378,7 +388,7 @@ local function Create_Frames()
 	window:SetFrameStrata("FULLSCREEN")
 	-- Using SetScript("OnLoad",   does not work
 	OnLoad(window);
-	--	TitanPanelButton_OnLoad(window); -- Titan XML template calls this...w
+	--	TitanPanelButton_OnLoad(window); -- Titan XML template calls this...

 	window:SetScript("OnShow", function(self)
 		OnShow()
@@ -391,9 +401,16 @@ local function Create_Frames()
 	window:SetScript("OnEvent", function(self, event, ...)
 		OnEvent(self, event, ...)
 	end)
+	window:SetScript("OnDoubleClick", function(self, button)
+		OnDoubleClick(self, button)
+		TitanPanelButton_OnClick(self, button)
+	end)

+	window:SetPropagateMouseMotion(true)

 	---[===[
+	local mname = cname.."Mute"
+	local bname = cname.."Blizz"
 	-- Config screen
 	local config = CreateFrame("Frame", cname, f, BackdropTemplateMixin and "BackdropTemplate")
 	config:SetFrameStrata("FULLSCREEN") --
@@ -401,6 +418,10 @@ local function Create_Frames()
 	config:SetWidth(400)
 	config:SetHeight(200)

+	config:SetScript("OnShow", function(self)
+		_G[mname]:SetChecked(IsMuted())
+		_G[bname]:SetChecked(TitanGetVar(TITAN_VOLUME_ID, "OverrideBlizzSettings"))
+	end)
 	config:SetScript("OnEnter", function(self)
 		TitanUtils_StopFrameCounting(self)
 	end)
@@ -410,37 +431,39 @@ local function Create_Frames()
 	config:SetScript("OnUpdate", function(self, elapsed)
 		TitanUtils_CheckFrameCounting(self, elapsed)
 	end)
-	window:SetScript("OnDoubleClick", function(self, button)
-		OnDoubleClick(self, button)
---		TitanPanelButton_OnClick(self, button)
-	end)
-
-	-- Config font sections
-	local str = nil
-	local style = "GameFontNormalSmall"
-	str = config:CreateFontString(cname .. "Title", "ARTWORK", style)
-	str:SetPoint("TOP", config, 0, -10)
-
-	str = config:CreateFontString(cname .. "MasterTitle", "ARTWORK", style)
-	str:SetPoint("TOP", config, -160, -30)

-	str = config:CreateFontString(cname .. "SoundTitle", "ARTWORK", style)
-	str:SetPoint("TOP", config, -90, -30)
+	local mute_button = CreateFrame("CheckButton", mname, config, "UICheckButtonTemplate")
+	mute_button:SetPoint("BOTTOMLEFT", config, "BOTTOMLEFT", 5, 5)
+	mute_button.text = _G[mname .. "Text"]
+	mute_button.text:SetText(MUTE)

-	str = config:CreateFontString(cname .. "MusicTitle", "ARTWORK", style)
-	str:SetPoint("TOP", config, -20, -30)
+	mute_button:SetChecked(IsMuted())
+	mute_button:SetScript("OnClick", function(self, event, arg1)
+--		if self:GetChecked() then
+		ToggleMute()
+	end)
+	mute_button:SetPropagateMouseMotion(true)

-	str = config:CreateFontString(cname .. "AmbienceTitle", "ARTWORK", style)
-	str:SetPoint("TOP", config, 50, -30)
+	local checkButton = CreateFrame("CheckButton", bname, config, "UICheckButtonTemplate")
+	checkButton:SetPoint("BOTTOM", config, "BOTTOM", -10, 5)
+	checkButton.text = _G[bname .. "Text"]
+	checkButton.text:SetText(L["TITAN_VOLUME_MENU_OVERRIDE_BLIZZ_SETTINGS"])

-	str = config:CreateFontString(cname .. "DialogTitle", "ARTWORK", style)
-	str:SetPoint("TOP", config, 130, -30)
+	checkButton:SetChecked(TitanGetVar(TITAN_VOLUME_ID, "OverrideBlizzSettings"))
+	checkButton:SetScript("OnClick", function(self, event, arg1)
+		TitanToggleVar(TITAN_VOLUME_ID, "OverrideBlizzSettings")
+	end)
+	checkButton:SetPropagateMouseMotion(true)

-	-- ====== Config slider sections
+-- ====== Config slider sections

 	local inherit = "TitanOptionsSliderTemplate"
 	for idx, slider in pairs (sliders) do
 		local s = CreateFrame("Slider", idx, config, inherit)
+		local s_name = s:GetName()
+		_G[s_name .. "Title"]:SetText(slider.ltext)
+		_G[s_name .. "Low"]:SetText("100%")
+		_G[s_name .. "High"]:SetText("0%")
 		s:SetPoint("TOP", config, slider.off_x, slider.off_y)
 		s:SetScript("OnShow", function(self)
 			Slider_OnShow(self)
@@ -460,7 +483,8 @@ local function Create_Frames()
 	end

 	-- Now that the parts exist, initialize
-	ControlFrame_OnLoad(config)
+		TitanPanelRightClickMenu_SetCustomBackdrop(config)
+

 	--]===]
 end