From WowAce Wiki
Jump to: navigation, search

WindowLib is a small library that takes care of standard "windowy" behavior used in the main frames of many addons, and attempt to do so in a smarter way than the average addon author would find time to do.

  • Save and restore positions: WindowLib will pick the attach point based on which quadrant of the screen the frame is in: top-left? bottom-right? center?
  • Handle window dragging
  • Mouse wheel zooming
  • Only mouse-enabling the window while Alt is held
  • .. more will surely come


win = LibStub("LibWindow-1.1")

myframe = CreateFrame("Frame") 
win.RegisterConfig(myframe, self.db.profile)
win.RestorePosition(myframe)  -- restores scale also

API Documentation

.RegisterConfig(frame, storage[, names])

local win = LibStub("LibWindow-1.1")

win.RegisterConfig(myframe, self.db.profile)

This call initializes a frame for use with LibWindow, and tells it where configuration data lives. Optionally, you can specify the exact names of the variables that will be saved.

Note that if your addon supports profiles (i.e. changing config data live), you'll need to do a new .RegisterConfig() followed by .RestorePosition() when the profile is changed over.


the frame to enable positioning support for
a table to store configuration in
(optional) a table specifying which names to store in the configuration - see below

Manual variable naming

The optional last argument to the function is a table containing name mappings and/or a prefix for all variable names.

Example use - manually specify all variable names:

names = {
  x = "posx",
  y = "posy",
  scale = "size",
  point = "whereToAttach",

Example use - just prefix most names, but hardcode one

names = {
  prefix = "myframe",  -- names become e.g. "myframex", "myframey"
  point = "gluemyframe",


Computes which quadrant the frame lives in, and saves its position relative to the right corner.

myframe:SetScript("OnDragStop", win.SavePosition)
  function(...) return win.SavePosition(...) end


Restores position and scale from configuration data.


.SetScale(frame, scale)

Sets the scale of the frame (without causing it to move, of course)

win.SetScale(myframe, myscale)


Adds drag handlers to the frame and makes it movable. Positioning information is automatically stored according to :RegisterConfig().

  • You can of course also handle dragging yourself, in which case you instead call .SavePosition(frame) when dragging is done.
  • There are also .OnDragStart(frame) and .OnDragStop(frame) handlers which do the necessary API calls for you along with calling .SavePosition(frame).


Only mouse-enables the window while [Alt] is held, i.e. you normally click through the window.



Adds mousewheel handlers to the frame, automatically increasing/decreasing scale by 10% per wheel tick and calling .SetScale(myframe) for you.


You can also manually call win.OnMouseWheel(frame,dir). This would be of interest if e.g. your addon already uses the mousewheel for something. I recommend using ctrl as the modifier key for scaling - it is already in use by other addons.


On positioning logic

WindowLib will pick the attach point based on which quadrant of the screen the frame is in: top-left? bottom-right? center?

  • This means that frames do NOT necessarily stay exactly in place when the UI is resized
  • This is a GOOD THING! Much better than static positioning (i.e. :GetLeft()*:GetEffectiveScale)
  • Two frames sitting next to eachother when the UI is resized, will keep sitting next to eachother with this relative positioning. (For example: Think of how your Bags sit next to eachother, regardless of UI scale!)

Adding LibWindow to an existing addon

You will likely have window positioning data saved in your database since before. This data will likely need to be converted before LibWindow will handle it well.

LibWindow remembers position in the parent's scale. BUT: most addons translate to global scale and save that. This is not compatible unless your UIParent is scale 1.0.

Example old code:

function MyAddon:SavePosition(frame)
  local p = self.db.profile
  p.x = frame:GetLeft() / frame:GetEffectiveScale()
  p.y = frame:GetTop() / frame:GetEffectiveScale()

Example code to patch the scale for LibWindow use:

function MyAddon:OnProfileEnable()
  local p = self.db.profile
  if not p.libwindowed then
    p.x = p.x / UIParent:GetScale()
    p.y = p.y / UIParent:GetScale()
    p.libwindowed = true
  -- now it's safe to call .RestorePosition()