changeset 74:9824d524a661

- binding slot mixin: - store key binding definitions under their slot's data table - apply action button attributes when a slot is assigned - obtain correct macro body text when a macro is slotted - fix algorithm for resolving renamed macro indices - move spell detail lookup code out of mixin script - event chains: - initialize addon from PLAYER_LOGIN - reload keybinds from PLAYER_SPECIALIZATION_CHANGED, after spec profile is resolved - refresh interface content from SPELLS_CHANGED - hotkey text: - restore communication and detection of key binding updates and reflect them accordingly - properly respond to dynamic bindings that result from talent updates
author Nenue
date Sat, 14 Jan 2017 02:29:33 -0500
parents 68365bda5ab5
children e75a2fd448c0
files ActionTemplates.lua BindingsFrame.lua Events.lua KeyButton.lua SkeletonKey.lua SkeletonKey.xml
diffstat 6 files changed, 195 insertions(+), 149 deletions(-) [+]
line wrap: on
line diff
--- a/ActionTemplates.lua	Sat Jan 07 12:52:05 2017 -0500
+++ b/ActionTemplates.lua	Sat Jan 14 02:29:33 2017 -0500
@@ -106,13 +106,77 @@
 --- Resolves the SecureActionButton attribute names used for the given action
 kb.RegisterAction = function(actionType, id, name)
   assert(atype[actionType], 'Missing actionType handler for `'..tostring(actionType)..'`')
-  local target, attributeName, attributeValue, button  = atype[actionType](id, name)
-  local command = target .. attributeName
-
-  return attributeName, attributeValue, command, target, button
+  local prefix, attributeName, attributeValue, button  = atype[actionType](id, name)
+  local command = prefix .. attributeName
+  return attributeName, attributeValue, command, prefix, button
 end
 
 
+local spells = {}
+local SkeletonKey_GetGenericSpell = function(spellName, spellID, icon)
+  if not spells[spellID] then
+    spells[spellID] = {}
+    spells[spellID].actionType = 'spell'
+    spells[spellID].actionID = spellID
+    spells[spellID].actionName = spellName
+    spells[spellID].iconPath = icon
+    spells[spellID].statusText = '|cFFBBBBBBSpell|r'
+    spells[spellID].dynamicType = nil
+  end
+  return spells[spellID]
+end
+
+-- tries to resolve spells from talent overrides/profession book/etc
+local dynamicTypes = {['profession'] = 'ProfessionCache', ['talent'] = 'TalentCache', ['petaction'] = 'PetInfoCache'}
+kb.ResolveSpellSlot = function(self)
+  local spellName, spellID, command, icon = self.actionName, self.actionID, self.command, self.iconPath
+  --print(' In:', spellName, spellID, command)
+  --print(GetSpellInfo(spellName or spellID))
+  local internalName, _, internalIcon, _, _, _, _ = GetSpellInfo(spellName or spellID)
+  local isAvailable = internalName and true
+
+  if internalName and (internalName ~= spellName) then
+    -- it's a binding for the originating spell, leave it as is
+    print('  |cFFFF4400spell is an override(', internalName, '~=', spellName,') leave the name info alone')
+    self.statusText = '|cFFFFFF00Spell|r'
+    self.isAvailable = true
+    return
+  end
+
+  -- let's us match spells replaced by talents
+  local info = kb.DynamicSpells[internalName or spellName]
+  if not info then
+    local dynamicType, dynamicIndex, dynamicSubIndex = command:match("(%a+)_(%S+)_(%S+)")
+    if kb.DynamicSpells[dynamicType] then
+      print('|cFFFF4400resolving dynamic type index:', internalName, spellName, command)
+      dynamicIndex = tonumber(dynamicIndex)
+      dynamicSubIndex = tonumber(dynamicSubIndex)
+      local cache = kb.DynamicSpells[dynamicType]
+      print('type:', dynamicType)
+      if dynamicIndex and cache[dynamicIndex] then
+        info = kb.DynamicSpells[dynamicType][dynamicIndex]
+        print('index:', dynamicIndex)
+        if dynamicSubIndex and info[dynamicSubIndex] then
+          info = info[dynamicSubIndex]
+          print('sub-index:', dynamicSubIndex)
+        end
+        isAvailable = true
+      end
+    end
+    if not info then
+      info = SkeletonKey_GetGenericSpell(spellName, spellID, internalIcon or icon)
+    end
+  end
+  info.isAvailable = isAvailable
+
+  print('|cFF00FF88Slot Details:|r', info.actionName, info.actionID, info.dynamicType, info.isAvailable)
+  for k,v in pairs(info) do
+    --cprint(' ',k,v)
+    self[k] = v
+  end
+
+  return info
+end
 
 
 kb.ApplyTalentBinding = function(talentInfo, cache)
@@ -312,15 +376,20 @@
         if not configTable.assignedKeys then
           configTable.assignedKeys = {GetBindingKey(configTable.command) }
         end
-        if configTable.dynamicType then
-          kb:print(table.concat(configTable.assignedKeys, ', ') .. ' bound to '.. configTable.actionName)
+        if configTable.dynamicType == 'talent' then
+          --kb:print(table.concat(configTable.assignedKeys, ', ') .. ' bound to '.. configTable.actionName)
         end
+        for _, key in pairs(configTable.assignedKeys) do
+
+          SetBinding(key, configTable.command)
+        end
+
       end
     end
   end
 
   kb.ApplyAllBindings =function ()
-    cprint('|cFF0088FFApplyAllBindings()')
+    print('|cFFFFFF00ApplyAllBindings()')
     wipe(kb.TalentBindings)
     wipe(kb.bindings)
     --kb:print('Loading binding profile', kb.profileName)
@@ -366,7 +435,6 @@
   if kb.talentsPushed then
     return
   end
-  wipe(kb.TalentCache)
   for row =1, MAX_TALENT_TIERS do
     for col = 1, NUM_TALENT_COLUMNS do
       local talentID, talentName, icon, selected, available, spellID = GetTalentInfo(row, col, 1)
@@ -406,7 +474,6 @@
   end
 
   kb.talentsPushed = true
-
   kb.UpdateDynamicButtons('talent')
 end
 
@@ -638,12 +705,9 @@
     if #kb.pendingAttributes == 0 then
       kb:print(kb.L('Key bindings will be applied when you exit combat.'))
     end
-
     tinsert(kb.pendingAttributes, {target, name, value})
     SkeletonKey:RegisterEvent('PLAYER_REGEN_ENABLED')
-
   else
-
     --cprint('|cFFFF4444' .. target:GetName()..'|r.|cFFFFFF00'.. tostring(name)..'|r = "'..tostring(value)..'"')
     target:SetAttribute(name, value)
   end
--- a/BindingsFrame.lua	Sat Jan 07 12:52:05 2017 -0500
+++ b/BindingsFrame.lua	Sat Jan 14 02:29:33 2017 -0500
@@ -17,7 +17,8 @@
 
 SkeletonKeyButtonMixin = {}
 local _, kb = ...
-local print = (DEVIAN_PNAME == 'SkeletonKey') and function(...) _G.print('SK', ...) end or nop
+local print = (DEVIAN_PNAME == 'SkeletonKey') and function(...) _G.print('SKUI', ...) end or nop
+local gprint = (DEVIAN_PNAME == 'SkeletonKey') and function(...) _G.print('SK', ...) end or nop
 local L = kb.L
 local BINDS_PER_ROW = 2
 local BINDING_TYPE_SPECIALIZATION = 3
@@ -249,7 +250,7 @@
 
 --- push current information into living UI
 function SkeletonKeyMixin:Update(force)
-  print('|cFFFF8800'..self:GetName()..':Update()|r', InCombatLockdown() and 'combat', self:IsShown())
+  gprint('|cFFFF8800'..self:GetName()..':Update()|r', InCombatLockdown() and 'combat', self:IsShown())
   for index, frame in ipairs(self.Plugins) do
     if frame.Update then
       frame:Update(force)
@@ -351,6 +352,7 @@
   else
     tabID = BINDING_TYPE_GLOBAL
   end
+  print(selectedProfile)
   scrollOffset = scrollOffset or 0
 
   local leftSlot, upSlot
--- a/Events.lua	Sat Jan 07 12:52:05 2017 -0500
+++ b/Events.lua	Sat Jan 14 02:29:33 2017 -0500
@@ -21,33 +21,28 @@
 end
 
 kb.PLAYER_REGEN_ENABLED = function()
-  SkeletonKey:Update()
-end
-
-kb.PLAYER_SPECIALIZATION_CHANGED =  function(...)
-
-  kb.UpdateSpecInfo()
-  kb.UpdateTalentInfo()
-
-  kb.SelectProfileSet(kb.profileName)
-  kb.ApplyAllBindings()
-  SkeletonKey:Update(true)
-end
-kb.PLAYER_TALENT_UPDATE = function()
-  --kb.UpdateTalentInfo()
-  --kb.SelectProfileSet(kb.profileName)
-  --kb.ApplyAllBindings()
-  --SkeletonKey:Update()
+  SkeletonKey:SetShown(kb.db.showUI)
 end
 kb.ACTIONBAR_SLOT_CHANGED = function(self, event, slot)
   --kb.HotKeyText(slot)
   return true
 end
 
+kb.PLAYER_TALENT_UPDATE = function()
+  kb.TalentsChanged = true
+end
+
 -- only need to respond to this for pet actions
-kb.SPELLS_CHANGED = function(self, event, unit)
-  print('|cFFFF0088'.. event..'|r', unit)
+kb.PLAYER_SPECIALIZATION_CHANGED = function(self, event, unit)
+  kb.UpdateSpecInfo()
+  kb.UpdateTalentInfo()
   kb.UpdatePetInfo()
+  kb.SelectProfileSet(kb.profileName)
+  kb.ApplyAllBindings()
+end
+
+kb.SPELLS_CHANGED = function()
+  SkeletonKey:Update()
 end
 
 kb.UPDATE_MACROS = function()
--- a/KeyButton.lua	Sat Jan 07 12:52:05 2017 -0500
+++ b/KeyButton.lua	Sat Jan 14 02:29:33 2017 -0500
@@ -5,7 +5,7 @@
 -- Deals with display and manipulation of binding slots
 
 local _, kb = ...
-local print = (DEVIAN_PNAME == 'SkeletonKey') and function(...) _G.print('SkeletonKey', ...) end or function() end
+local print = (DEVIAN_PNAME == 'SkeletonKey') and function(...) _G.print('KeyButton', ...) end or function() end
 local cprint = (DEVIAN_PNAME == 'SkeletonKey') and function(...) _G.print('Cfg', ...) end or function() end
 local L = kb.L
 local type, tonumber, tostring, tinsert, tremove, ipairs, pairs = type, tonumber, tostring, tinsert, tremove, ipairs, pairs
@@ -170,7 +170,7 @@
     end
 
 
-    local name, icon, _
+    local name, icon, _, macroName, macroText
     local pickupID, pickupBook
 
     if actionType == 'spell' then
@@ -178,7 +178,8 @@
       name, _, icon = GetSpellInfo(actionID)
 
     elseif actionType == 'macro' then
-      name, icon = GetMacroInfo(actionID)
+      name, icon, macroText = GetMacroInfo(actionID)
+      macroName = name
     elseif actionType == 'petaction' then
       if CURSOR_SPELLSLOT and CURSOR_BOOKTYPE then
 
@@ -217,7 +218,7 @@
       icon = petIcon
 
     end
-    local macroName, macroText, command = kb.RegisterAction(actionType, actionID, name)
+    local _, macroBody, command = kb.RegisterAction(actionType, actionID, name)
     local slotInfo = {
       command = command,
       actionName = name,
@@ -225,7 +226,7 @@
       actionType = actionType,
       actionID = actionID,
       macroName = macroName,
-      macroText = macroText,
+      macroText = macroText or macroBody,
       spellbookSlot = pickupID,
       spellbookType = pickupBook,
       assignedKeys = {GetBindingKey(command)}
@@ -242,6 +243,11 @@
       StaticPopup_Show('SKELETONKEY_CONFIRM_ASSIGN_SLOT')
     else
       kb.currentProfile.buttons[self:GetID()] = slotInfo
+      if #slotInfo.assignedKeys >= 1 then
+        kb:print('Obtained following hotkeys:', table.concat(slotInfo.assignedKeys, ', '))
+
+      end
+      kb.LoadBinding(slotInfo)
       self:SetSlot(slotInfo)
       self:UpdateSlot()
       self.active = nil
@@ -312,8 +318,8 @@
 
   if self.command then
 
-    print('|cFFFF4400', self.actionName, #self.assignedKeys, self.assignedKeys)
-    print(table.concat(self.assignedKeys, ','))
+    print('|cFFFF4400', self.actionName, #self.assignedKeys, table.concat(self.assignedKeys, ','))
+    print(self.isAvailable)
     print(self.actionID)
     self.bindingText= kb.BindingString(unpack(self.assignedKeys))
     if not self.isAvailable then
@@ -336,13 +342,7 @@
     else
       self.macro:Hide()
       if self.actionType == 'spell' then
-        local dummy = GetSpellInfo(self.actionName)
-        if not dummy then
-          self.icon:SetDesaturated(true)
-        else
-          self.icon:SetDesaturated(false)
-        end
-
+        self.isAvailable = GetSpellInfo(self.actionName) and true or false
       end
     end
 
@@ -378,12 +378,14 @@
 
   end
 
-  self.ignoreTexture:SetShown(self.command and not self.isAvailable)
-
   if not self.isAvailable then
-    self.bind:SetTextColor(0.7,0.7,0.7,1)
+    self.bind:SetTextColor(.7,.7,.7,1)
+    self.ignoreTexture:SetShown(self.command and true)
+    self.icon:SetVertexColor(.5,.5,.5)
   else
+    self.ignoreTexture:SetShown(false)
     self.bind:SetTextColor(1,1,1,1)
+    self.icon:SetVertexColor(1,1,1)
   end
 
 
@@ -459,76 +461,10 @@
 
 end
 
-local spells = {}
-local SkeletonKey_GetGenericSpell = function(spellName, spellID, icon)
-  if not spells[spellID] then
-    spells[spellID] = {}
-    spells[spellID].actionType = 'spell'
-    spells[spellID].actionID = spellID
-    spells[spellID].actionName = spellName
-    spells[spellID].iconPath = icon
-    spells[spellID].statusText = '|cFFBBBBBBSpell|r'
-    spells[spellID].dynamicType = nil
-  end
-  return spells[spellID]
+local DoMacroCheck = function(name, macroText, searchID, roughResult)
+
+  return matchID, matchName, matchBody, endOfSearch
 end
-
-local tempInfo = {}
--- tries to resolve spells from talent overrides/profession book/etc
-local dynamicTypes = {['profession'] = 'ProfessionCache', ['talent'] = 'TalentCache', ['petaction'] = 'PetInfoCache'}
-local SkeletonKey_GetSpellDetails = function(self)
-
-  local spellName, spellID, command, icon = self.actionName, self.actionID, self.command, self.iconPath
-
-
-  print(' In:', spellName, spellID, command)
-  print(GetSpellInfo(spellName or spellID))
-  local internalName, _, internalIcon, _, _, _, _ = GetSpellInfo(spellName or spellID)
-  local isAvailable = internalName and true
-
-  if internalName and (internalName ~= spellName) then
-    -- it's a binding for the originating spell, leave it as is
-    print('  |cFFFF4400spell is an override(', internalName, '~=', spellName,') leave the name info alone')
-    self.statusText = '|cFFFFFF00Spell|r'
-    self.isAvailable = true
-    return
-  end
-
-  -- let's us match spells replaced by talents
-  local info = kb.DynamicSpells[internalName or spellName]
-  if not info then
-    local dynamicType, dynamicIndex, dynamicSubIndex = command:match("(%a+)_(%S+)_(%S+)")
-    if kb.DynamicSpells[dynamicType] then
-      print('|cFFFF4400resolving dynamic type index:', internalName, spellName, command)
-      dynamicIndex = tonumber(dynamicIndex)
-      dynamicSubIndex = tonumber(dynamicSubIndex)
-      local cache = kb.DynamicSpells[dynamicType]
-      print('type:', dynamicType)
-      if dynamicIndex and cache[dynamicIndex] then
-        info = kb.DynamicSpells[dynamicType][dynamicIndex]
-        print('index:', dynamicIndex)
-        if dynamicSubIndex and info[dynamicSubIndex] then
-          info = info[dynamicSubIndex]
-          print('sub-index:', dynamicSubIndex)
-        end
-        isAvailable = true
-      end
-    end
-    if not info then
-      info = SkeletonKey_GetGenericSpell(spellName, spellID, internalIcon or icon)
-    end
-  end
-  info.isAvailable = isAvailable
-
-  print('|cFF00FF88SpellDetails:|r', info.actionName, info.actionID, info.dynamicType, info.isAvailable)
-  for k,v in pairs(info) do
-    --cprint(' ',k,v)
-    self[k] = v
-  end
-
-  return info
-end
-
 --- Assigns the slot via table copy; any manipulations from this point are temporary and
 function skb:SetSlot(slotInfo)
   print('slot info', self:GetID())
@@ -549,7 +485,7 @@
 
     isBound = kb.IsCommandBound(self, self.command)
     if actionType == 'spell' then
-      local info = SkeletonKey_GetSpellDetails(self)
+      local info = kb.ResolveSpellSlot(self)
       name, icon, actionType, actionID, macroName, macroText, pickupSlot, pickupBook = self.actionName, self.iconPath, self.actionType, self.actionID, self.macroName, self.macroText, self.spellbookSlot, self.spellbookType
       self.isAvailable = info and info.isAvailable
     elseif actionType == 'petaction' then
@@ -573,35 +509,75 @@
       self.isAvailable = (kb.PetCache.spellslot[name])
     elseif actionType == 'macro' then
       if actionID then
-        -- look for corruption
+
+        -- Update stored information if it mis-matches
         local nameByID, _, bodyByID = GetMacroInfo(actionID)
-        local nameByName, _, bodyByName = GetMacroInfo(name)
+        --print(bodyByID, "\n", macroText)
         if (nameByID ~= name) or (bodyByID ~= macroText) then
-          local prevIndex = actionID
-          actionID = GetMacroIndexByName(name)
-          local firstName, _, firstBody = GetMacroInfo(actionID)
+          --kb:print('mismatches for slot', self:GetID(), actionID, ((nameByID ~= name) and 'name' or ''), ((bodyByID ~= macroText) and 'body' or ''))
+          local matchID, matchName, matchBody, hasMultiple
+          local roughResult = ""
+
+          local newID = GetMacroIndexByName(name)
+          local firstName, _, firstBody = GetMacroInfo(newID)
           if (firstName ~= name) or (firstBody ~= macroText) then
+
+
             -- go even deeper
-            for i = 1, GetNumMacros() do
-              local searchName, _ , searchBody = GetMacroInfo(i)
+            local numAccount, numCharacter = GetNumMacros()
+            local searchID = 1
+            while searchID <= (120+numCharacter) do
+              --kb:print(searchID)
+
+
+              local searchName, _ , searchBody = GetMacroInfo(searchID)
               if (searchName == name) and (searchBody == macroText) then
+                --kb:print('definitely', matchID, searchName, '\n', searchBody)
                 -- complete match
-                actionID = i
-                kb:print('Macro index changed: |cFFFFFF00', actionType, '|r', name, '(was '..tostring(prevIndex)..', now '..tostring(actionID)..')')
+                matchID = searchID
+                matchName = searchName
+                matchBody = searchBody
                 break
               elseif (searchName == name) or (searchBody == macroText) then
                 -- partial match, continue the search
-                actionID = i
-                kb:print('Macro index changed: |cFFFFFF00', actionType, '|r', name, '(was '..tostring(prevIndex)..', now '..tostring(actionID)..')')
+
+                if matchID then
+                  hasMultiple = true
+                  roughResult = roughResult .. "\n" .. tostring(searchID) .. ':'..tostring(searchName)
+                end
+
+                matchID = searchID
+                matchName = searchName
+                matchBody = searchBody
+                --kb:print('possibly', matchID, matchName, '\n', matchBody)
               end
+
+              if searchID == numAccount then
+                searchID = 120
+              end
+              searchID = searchID + 1
             end
+          else
+            matchID = newID
+            matchName = firstName
+            matchBody = firstBody
           end
 
+          --kb:print(matchID, hasMultiple)
+          if hasMultiple then
+            kb:print('Macro assignment in slot #'..tostring(self:GetID())..' has multiple possible indexes:\nSaved Info: '..tostring(actionID)..'/'..tostring(name)..'\n|cFFFFFF00', roughResult)
+          elseif matchID then
+            kb:print('Macro for slot #'..tostring(self:GetID())..' ('..tostring(name)..') has probably changed:', ((actionID ~= newID) and (' |cFFFF4400'..tostring(actionID)..'|r to |cFF00FF88' .. newID .. '|r.') or ''), 'We\'re not sure, so you may want to re-do that assignment.')
+            actionID = matchID
+            name = matchName
+            macroName = matchName
+            macroText = matchBody
+          end
         end
       else
         actionID = GetMacroIndexByName(name)
       end
-      self.statusText = 'Macro'
+      self.statusText = 'Macro ' .. tostring(actionID)
       self.isAvailable = true
     else
       if not actionID then
@@ -692,6 +668,8 @@
   self.iconPath = icon
   self.profile = kb.db.bindMode
   self:RegisterForDrag('LeftButton')
+
+  return slotInfo
 end
 
 kb.GetCommandAction = function(command)
--- a/SkeletonKey.lua	Sat Jan 07 12:52:05 2017 -0500
+++ b/SkeletonKey.lua	Sat Jan 14 02:29:33 2017 -0500
@@ -151,8 +151,8 @@
   for i = 1, select('#', ...) do
     local key = select(i, ...)
     if type(key) == 'string' then
-    stack[i] = key:gsub('SHIFT', 's'):gsub('ALT', 'a'):gsub('CTRL', 'c'):gsub('SPACE', 'Sp'):gsub('BUTTON', 'M '):gsub('NUMPAD', '# ')
-      end
+      stack[i] = key:gsub('SHIFT', 's'):gsub('ALT', 'a'):gsub('CTRL', 'c'):gsub('SPACE', 'Sp'):gsub('BUTTON', 'M '):gsub('NUMPAD', '# ')
+    end
   end
 
   if #stack >= 1 then
@@ -243,8 +243,8 @@
   local defaultMode
   --- General info
   classHeader, className, classID = UnitClass('player')
-  print('|cFF00FF00profile:|r', name)
-  print('|cFF00FF00class:|r', UnitClass('player'))
+  --kb:print('|cFF00FF00profile:|r', name)
+  --kb:print('|cFF00FF00class:|r', UnitClass('player'))
 
   defaultMode = BINDING_TYPE_GLOBAL
   if db[name] then
@@ -287,9 +287,10 @@
   setmetatable(kb.loadedProfiles[BINDING_TYPE_CHARACTER], {__tostring =function() return kb.configHeaders[BINDING_TYPE_CHARACTER] end})
   setmetatable(kb.loadedProfiles[BINDING_TYPE_SPECIALIZATION], {__tostring =function() return kb.configHeaders[BINDING_TYPE_SPECIALIZATION] end})
 
-  print('|cFF00FF00bindMode:|r', db.bindMode)
   kb.currentProfile = kb.loadedProfiles[db.bindMode]
   kb.currentHeader = kb.configHeaders[db.bindMode]
+
+  print('|cFF88FF00SelectProfile()|r', kb.profileName, classHeader, kb.specInfo.name)
 end
 
 
@@ -317,9 +318,10 @@
   print('|cFF0088FF'..self:GetName()..':OnLoad()')
 
   self.CloseButton:SetScript('OnClick', CloseButton_OnClick)
-  self:RegisterEvent('PLAYER_LOGIN')
   self:RegisterEvent('PLAYER_ENTERING_WORLD')
   self:RegisterEvent('ADDON_LOADED')
+  self:RegisterEvent('PLAYER_LOGIN')
+  self:RegisterUnitEvent('PLAYER_SPECIALIZATION_CHANGED', 'player')
   self:EnableKeyboard(false)
 
   self.zoomScale = self:GetScale()
@@ -330,13 +332,15 @@
 end
 
 function SkeletonKeyMixin:OnEvent(event, arg)
-  if event == 'ADDON_LOADED' then
+  print('|cFFFF0088'.. event..'|r', unit)
+  if event == 'PLAYER_LOGIN' then
 
     print('|cFF00FFFF'..event ..'|r', arg or '', IsLoggedIn())
-        if IsLoggedIn() and not self.initialized then
+    if not self.initialized then
       self:Setup()
       self.initialized = true
-      self:Update()
+      kb.ApplyAllBindings()
+      self:Update(true)
     end
 
 
@@ -351,6 +355,11 @@
   end
 end
 
+function SkeletonKeyMixin:RefreshSpells()
+
+  kb.UpdateTalentInfo()
+  kb.UpdatePetInfo()
+end
 
 --- post ADDON_LOADED
 function SkeletonKeyMixin:Setup ()
@@ -365,10 +374,10 @@
   kb.UpdateSpecInfo()
   kb.UpdateTalentInfo()
   kb.SelectProfileSet(kb.profileName)
+  self:SetShown(kb.db.showUI)
   -- todo: redo import checking
 
   kb.UpdateSystemBinds()
-  kb.ApplyAllBindings()
 
   if not InCombatLockdown() then
     kb.CreateHooks()
@@ -380,17 +389,14 @@
   SLASH_SKB2 = "/skeletonkey"
   SlashCmdList.SKB = kb.Command
 
-  self:SetShown(kb.db.showUI)
-  self:Update(true)
 
   self:RegisterEvent('UPDATE_MACROS')
-  self:RegisterEvent('UPDATE_BINDINGS')
+  --self:RegisterEvent('UPDATE_BINDINGS')
   self:RegisterUnitEvent('UNIT_PORTRAIT_UPDATE', 'player', 'pet')
-  self:RegisterUnitEvent('PLAYER_SPECIALIZATION_CHANGED', 'player', 'pet')
-  self:RegisterUnitEvent('SPELLS_CHANGED')
-  self:RegisterUnitEvent('TALENT_UPDATE', 'player', 'pet')
   self:RegisterEvent('PLAYER_REGEN_DISABLED')
   self:RegisterEvent('PLAYER_REGEN_ENABLED')
+  self:RegisterEvent('SPELLS_CHANGED')
+  self:RegisterEvent('PLAYER_TALENT_UPDATE')
 
   self:RegisterForDrag('LeftButton')
   self:SetMovable(true)
--- a/SkeletonKey.xml	Sat Jan 07 12:52:05 2017 -0500
+++ b/SkeletonKey.xml	Sat Jan 14 02:29:33 2017 -0500
@@ -297,9 +297,9 @@
         </FontString>
 
         <Texture parentKey="ignoreTexture" file="Interface\PaperDollInfoFrame\UI-GearManager-LeaveItem-Transparent" hidden="true">
+          <Size x="24" y="24" />
           <Anchors>
-            <Anchor point="TOPLEFT" x="0" y="0" />
-            <Anchor point="BOTTOMRIGHT" x="0" y="0" />
+            <Anchor point="TOPLEFT" x="2" y="-2" />
           </Anchors>
         </Texture>
       </Layer>