Can we detect anytime an any editbox is currently selected?

I’m trying to make my addon know if any editbox is currently selected. Is there a global way to know if currently the player is typing in an edit box?

I’ve tried:

EditBox:SetScript(“OnEditFocusGained”,
function(self)
print(“SELECTED!”)
end
)

But I’m guessing that is not a global solution.

This is a safe way of doing it. (The “unsafe” way if you’re adventurous is with metamethods but it can wreak all kinds of havok with protected stuff in the mix.)

It basically enumerates the children of UIParent looking for EditBoxes and hooks their OnEditFocusGained. Because some EditBoxes are created on demand (and some whole addons load on demand) it has to periodically check for new ones to come into existence.

This may not be the most elegant solution but it should get you started:

local hookedEditBoxes = {} -- accumulated EditBoxes that have been hooked
local waiting = nil -- a timer while waiting for one frame after potentially many CreateFrames happen

-- the function that runs when an EditBox gains focus; self is the EditBox that gains focus
local function onEditFocusGained(self)
  print(self:GetName() or "unnamed", "has focus")
end

local frame = CreateFrame("Frame")
frame:SetScript("OnEvent",function()

  -- goes through all descendants of parent to find any EditBoxes that have not been hooked and hooks them
  local function hookEditBoxes(parent)
for _,frame in pairs({parent:GetChildren()}) do
  if not frame:IsForbidden() then
    if not hookedEditBoxes[frame] and frame:GetObjectType()=="EditBox" then
      frame:HookScript("OnEditFocusGained",onEditFocusGained)
      hookedEditBoxes[frame] = true
    end
    hookEditBoxes(frame)
  end
end
  end

  -- looks for any new EditBoxes and resets waiting timer
  local function findNewEditBoxes()
hookEditBoxes(UIParent)
waiting = nil
  end

  -- to avoid creating a timer to enumerate potentially thousands of frames for potentially hundreds of created frames in an execution path, set up a timer to wait a frame (the end of all execution paths)
  hooksecurefunc("CreateFrame",function() 
if not waiting then
  waiting = C_Timer.NewTimer(0,findNewEditBoxes)
end
  end)

  -- look for new EditBoxes when a LoD addon loads too
  hooksecurefunc("LoadAddOn",findNewEditBoxes)

  -- (optional) if an EditBox created in XML is unparented and becomes parented to a UIParent descendant sometime later, this will eventually catch them
  C_Timer.NewTicker(5, findNewEditBoxes)

  -- do an initial search
  findNewEditBoxes()
end)
frame:RegisterEvent("PLAYER_LOGIN") -- wait until player logs in before looking for EditBoxes