PROBLEM SOLVED
Issue:
When you move a window, the game saves its location as a relationship between whichever edge of the window is closest to an edge of the screen or letterbox, and that edge. When you exit and re-enter the game, it loads that relationship based on the window's size
as defined in the xml file, unless the window is resizable, in which case it loads the window's size as saved in the character's ini file.
Because the bag window is not flagged as resizable, but
gets resized, its location can become borked if the bottom of the window (at its full size) is closer to a screen edge than the top.
SOLUTION:
Step 1: Add these properties to the bag window's main page (Inventory.Bag):
UserResizable="true" OnHoverIn="UserResizable=false"
This causes the bag window to save its size in the character's ini file so it won't get borked, and make it so it's not actually user resizable.
Step 2: It's also necessary to set the first bag slot in each row to
Visible="false" and
OnShow="Parent.Size=(X,Y) Parent.MinimumSize=(X,Y)", where (X,Y) is the size that the bag should be when that slot's row is shown. If you don't do this, then the window will do it's resize-down-from-default size from that bag's saved size and you won't see your bag windows.
Step 3: (Nevermind, this problem can't actually affect the bags if they are set up properly.)
STEP 4:
If you're using somebody else's bag mod, they may have left code in there that hinders the proper saving of a bag's size. Such as, for example, Fetish Nightfall v3.3 bags containing a MaximumSize value in the XML that's smaller than the bag is going to be.
Remove any Minimumsize and Maximumsize parameters from the main bag page. This will be on the second line if opened in Notepad. Example, FetishNightfall v3.3 bag:
<Page Activated="true" eq2usescomwndcontrols="true" Location="3,58" MaximumSize="134,23" MinimumSize="134,23" Name="Bag"...
Replace with:
<Page Activated="true" eq2usescomwndcontrols="true" Location="3,58" Name="Bag"...