You mean only the first part is being evaluated in
elsif @item_window.index < 2 && Input.repeat?(Input::UP)
Give me a sec and I'll confirm... I'll edit this post.
EDIT:
Nah, the elsif works fine.
QuoteIt seems to me like it changes my menu's index to 0 BEFORE it processes the Input.repeat? command. Is that at all possible?
Not possible from the code in your post. Remember, a window can still be active with its index <0, and inactive with its index >=0. Dunno, it might have to do something with the update method of that key items window. You said you used someone else's code for update_cursor_rect? Now that I think about it, you don't need to mod update_cursor_rect for this to work. At least, so I think.
EDIT2:
Okay, tested it with an other script of mine, which has an item grouping system (items, equipment, key items).
I'll describe what happens when I try to do what you did. When you're on the index 2 or 3, and pressed up (Input.trigger?), the above window becomes active. The reason:
@item_window is being updated, which means as soon as you press up, item window will be updated first,
then our code for window switching will be run, by which time, the index is already 0 or 1 in the item window. To fix this, you somehow need to execute your code before the item window is updated. Here's what you try. Remove the item window updating from the update method, and add it to update_item method, after the window-switching code. I'll try it and tell you the result.
EDIT3:
Yup, works

So that's it, you need to do the window-switching before updating the item window.