A customizable, keyboard-driven command menu addon for Final Fantasy XI Windower 4. It also includes a drop-in library for developer use.
Repository: https://github.com/State-Null/MenuFocus
Note
Project Structure:
- The Demo Addon (
MenuFocus.lua): A working Windower 4 addon that showcases the menu system. You can download and run it immediately! - The Library (
menu_focus.lua): A clean drop-in module designed to be integrated directly into existing mouse-only or HUD-based addons.
- Quick Start: Run the Demo Addon
- How to Customize the Menu Options
- Keyboard Controls
- Bridging to Gamepads
- For Developers: Drop-in Library Integration
- Key Features
- License
MenuFocus works out of the box as a standalone addon. To try it:
- Install: Download the files and place the
MenuFocusfolder in your Windower addons directory:C:\Windower4\addons\MenuFocus\ - Load: Open FFXI and type
//lua load MenuFocusin the chat window. - Open Menu: Type
//mf focusin chat (or create an in-game macro/console mf focus) to display the menu. - Test Navigation:
- Cycle options using
Tabor your keyboardArrow Keys. - Select an option using
EnterorSpace. - Close or go back using
Escape. - Note: The default menu options execute harmless
/echocommands to show you how selections trigger actions in the chat box without needing active gameplay targets.
- Cycle options using
You can customize the menu labels and actions using any standard text editor (like Notepad) to execute your own spells, items, or macros.
Go to C:\Windower4\addons\MenuFocus\ and open the MenuFocus.lua file using Notepad.
Scroll down to line 17. You will see this block of text:
localmenu_items= {
{ name="Travel Options...", submenu= {
{ name="Use Warp Ring", action="/echo Using Warp Ring..." },
{ name="Cast Warp", action="/echo Casting Warp..." },
{ name="Back to Main", action="back" }
}
},
{ name="Buffs & Items...", submenu= {
{ name="Use Echo Drops", action="/item \"Echo Drops\" <me>" },
{ name="Use Remedy (Mock)", action="/echo Using Remedy..." },
{ name="Back to Main", action="back" }
}
},
{ name="Exit Menu", action="close" }
}Simply swap out the text inside the quotation marks with your own labels and FFXI slash commands.
Warning
Editing Rules:
- Preserve quotation marks: Ensure all names and actions are enclosed in double quotes
""or single quotes''. - Preserve commas: Make sure every menu line ends with a comma
,(except the last item in a list block). - Special Actions:
- Use
action = "back"to go back up one level in a submenu. - Use
action = "close"to close the menu.
- Use
To add a direct command to execute a Weaponskill, add a new line like this:
{ name="Savage Blade", action="/ws \"Savage Blade\" <t>" },When focus mode is active, the following default keyboard controls are dynamically registered:
Tab/Down/Right: Cycle highlight cursor to the next item.Shift + Tab/Up/Left: Cycle highlight cursor to the previous item.Space: Confirm and trigger the selected action (fully blockable to prevent chat box leakage).Escape: Cancel selection, go back in submenus, or close the menu.1through9: Instant selection shortcut for the corresponding item.Numpad 0: Cycles highlight cursor to the next item (acts as a convenient secondaryTabkey next to the arrow keys).Numpad Enter: Confirms and triggers the selected action (fully tested and safe from chat box leakage).
MenuFocus is designed with a decoupled architecture. It does not handle controller hardware directly. Instead, it exposes simple Windower console commands (like //mf menu_next or //mf menu_select) that make it easy to bind controller buttons to these commands using any mapping software (such as reWASD, JoyToKey, Xpadder, Steam Input, or AutoHotkey).
Refer to the templates/ directory for details on setting up gamepad bridges.
If you are writing a custom addon and want to add keyboard/controller focus navigation to your HUD or GUI, you can drop menu_focus.lua into your project and use it as a library.
Place menu_focus.lua in your addon's directory.
Load the module and set your callbacks:
localmenu_focus=require('menu_focus')
menu_focus.init({
on_select=function(item, index)
-- Triggers when player selects an itemwindower.send_command('input ' ..item.action)
menu_focus.unfocus()
end,
on_focus_change=function(focused, index)
-- Optional: Redraw your HUD styling and highlight cursorsupdate_my_ui(focused, index)
end
})
menu_focus.set_items(my_menu_list)Forward Windower console commands to the library in your command event handler:
windower.register_event('addon command', function(cmd, ...)
localargs= {...}
localcmd_lower=cmdandcmd:lower()
ifcmd_lower=='focus' thenmenu_focus.focus()
elseifcmd_lower=='unfocus' orcmd_lower=='close' thenmenu_focus.unfocus()
elseifcmd_lower=='menu_next' thenmenu_focus.next()
elseifcmd_lower=='menu_prev' thenmenu_focus.prev()
elseifcmd_lower=='menu_select' thenmenu_focus.select()
elseifcmd_lower=='menu_num_select' thenmenu_focus.num_select(args[1])
elseifcmd_lower=='clear_binds' thenmenu_focus.clear_binds()
endend)For more detailed blueprints and case studies (e.g. Checklist HUD scrolling and Graphical UI grid navigation), see developer_guide.md.
- Chat Box Safety (
%modifier): Keyboard binds automatically suspend whenever the FFXI chat input box is open. Players can type spaces, use numbers, and tab-complete text normally without triggering menu navigation. - Leak-Free Unbinding (0.15s Buffer): Implements delayed unbinding to swallow the key-release (key-up) event. This prevents the FFXI client from receiving trailing inputs that might accidentally open the chat input line (a common issue in Compact Keyboard mode).
- Direct Numeric Shortcuts (1-9): Dynamically binds the number keys matching the active menu count, letting players hit number keys for instant selections.
- Dynamic Submenus: Native support for infinite nested menus using stack-based history navigation (using
EscapeorBackto traverse up). - Conflict Arbitration: A built-in arbitrator automatically releases focus binds from other active addons using this framework if a new one claims focus locally.
- Zero Dependencies: Completely sandboxed and portable. Just drop
menu_focus.luainto your addon folder and require it.
This library is open-source and free to include in any FFXI Windower addon.
