by Imkenyo | 19/06/2007 17:26:39

Well, this is a bit of a doozy of an interface issue. It all started back when I first got WoW. I took interest in the interface customization capabilities WoW offers, and so I took the opportunity to write addons that fix what I consider to be bugs in the vanilla WoW UI. One of those bugs is in the world map frame's OnMouseClick handler. I originally tried to bind my mouse4 button to toggle world map, since I have a fancy mouse with extra buttons. I immediately noticed that pressing mouse4 would toggle the world map on, and then subsequent mouse4 clicks would cause the map to zoom out, rather than toggle off. I figured the problem must be some poorly designed logic, such as: if ( button == "MOUSE1" ) ...; else ... So I checked, and sure enough, that was the problem. So, I wrote the following simple addon to work around the problem. It looks something like this:
function FixWoWUI_OnLoad() FixWoWUI_Orig_WorldMapOnClick = WorldMapButton_OnClick; -- Hook WorldMapButton_OnClick() from WorldMapFrame.lua WorldMapButton_OnClick = FixWoWUI_Hook_WorldMapOnClick; end
function FixWoWUI_Hook_WorldMapOnClick(mouseButton, ...) -- Handle the originally intended left-mouse/right-mouse click logic correctly. if ( mouseButton == "LeftButton" or mouseButton == "RightButton" ) then return FixWoWUI_Orig_WorldMapOnClick(mouseButton, ...); end -- For any other mouse buttons, use the intended in-worldmap keypress logic. local KeyConvTable = { ["MiddleButton"] = "BUTTON3", ["Button4"] = "BUTTON4", ["Button5"] = "BUTTON5" }; local temp_arg1 = arg1; arg1 = KeyConvTable[mouseButton]; WorldMapFrame:GetScript("OnKeyDown")(); arg1 = temp_arg1; end
Simple enough, and that fixed the problem. But, after a while with that fix in place, I began to notice that occasionally, my UI would be hidden (as if I pressed alt+Z) after exiting the world map. For a while I never really gave it any thought, but recently it was bugging me, so I decided to track down the problem. This is what I discovered. Naturally, my hook introduces taint into the execution path, so the OnKeyDown handler (which in turn executes the binding) runs with taint. For toggling the world map, that is not normally an issue, since hiding the world map frame and showing UIParent, which is what the binding for toggling the world map does essentially, is not a protected action. Then I noticed that the problem occurs when I'm in combat and I toggle the world map on and off. Aha. So, I check wowwiki.com for in-combat addon restrictions, and sure enough, I find:
Q u o t e:
Some things can't be done on "Protected" frames, their parents, or any frame they are anchored to. These include, but are not restricted to: Hiding the frame using Hide widget method. Showing the frame using Show widget method. ...
Naturally, UIParent falls into the category of being a parent of a protected frame. So there lies the problem. My addon to fix a WoW UI bug causes a tainted binding to fail to UIParent:Show(). I recommend fixing the world map OnClick handler. That will satisfactorily address the issue I have described. Thank you. |