FWIW, this is what I’m using to fake an enabled/disable state:
local function changeButton(btn, new\_options) local options = mui.getWidgetProperty(btn, "layer\_1").muiOptions if (new\_options ~= nil) then options = tableMerge(options, new\_options) end -- faking a "disabled" state local fillColor = options.fillColor local textColor = options.textColor -- "enabled" is a custom property I set on newRectButton() if (options.enabled ~= nil and options.enabled == false) then fillColor[4] = 0.2 textColor[4] = 0.2 else fillColor[4] = 1 textColor[4] = 1 end options.useShadow = options.enabled == nil or options.enabled options.fillColor = fillColor options.textColor = textColor mui.removeWidgetByName(btn) mui.newRectButton(options) end local function isButtonEnabled(btn) local btn = mui.getWidgetProperty(btn, "layer\_1") return btn.muiOptions.enabled ~= nil and btn.muiOptions.enabled end local function onHistoryEmpty() changeButton("btnUndo", {enabled = false}) end local function onNewHistoryItem() if isButtonEnabled("btnUndo") then return end changeButton("btnUndo", {enabled = true}) end local function onActionUndo() if not isButtonEnabled("btnUndo") then return end engine.call(engine.ACTIONS.undo) end