This could be another useful pattern, especially when using MF_DISABLED.

I prefer to to disable toolbar buttons when they can’t be used due to the selection not supporting them, e.g. like Make Component in the Lareg Toolset being disabled for empty selections. However this causes issues on Mac as the command often gets stuck in the disabled state.

# Set command state if supported.
#
# Only use when the command state isn't crucial for the functionality of the
# extension as it isn't supported by on Mac prior to SketchUp 2018.
#
# @param command [UI::Command]
#
# @yield_returns [Integer] `MF_ENABLED`, `MF_DISABLED`, `MF_CHECKED`,
# `MF_UNCHECKED`, or `MF_GRAYED`.
#
# @return [UI::Command]
def set_validation_proc(command, &block)
if Sketchup.platform == :platform_win || Sketchup.version.to_i >= 18
command.set_validation_proc(&block)
end
command
end

This example adds the commands Edge Selected and Face Selected to the Extensions menu and a floating toolbar. The commands should be checked when an edge or a face respectively is selected, and otherwise be unchecked.

ok, restarted SketchUp, the toolbar pops up, but does not respond on the selected items (edge, face or both)
However, when reinstated via View>toolbar and with something in the selection, it displays the icon bounded.

Actually upon further thought, … you want a method like this to be as fast as possible.
So, you need to eliminate the conditionals and anything that will slow it down.
This means you conditionally define the correct method for the platform and version …

if OS_IS_WIN
def refresh_toolbars
true # Return if Windows
end
else # Mac
# Use new method if available; older versions
# will use the push/pop tool workaround.
if ::UI.respond_to?(:refresh_toolbars)
def refresh_toolbars
::UI.refresh_toolbars
end
else
def refresh_toolbars
if (model = ::Sketchup.active_model)
model.tools.push_tool(nil)
model.tools.pop_tool
end
end
end
end

Perhaps adding a selection observer to a model and calling refersh_toolbars every time a bulk selection is made could be the way to go on OS X. But of course, that could be performance consuming unless we use an efficient function as Dan described.

Perhaps adding a selection observer to a model and calling refersh_toolbars every time a bulk selection is made could be the way to go on OS X. But of course, that could be performance consuming unless we use an efficient function as Dan described.

Yea, that would be a bit of a overkill. Especially if multiple extensions start doing that.
We looked at it, but toolbar works very differently under OSX than Windows in terms of implementation. It’s not trivial to address.

What I ended up doing for my own extensions is to not rely on the button state on Mac - making sure to have logic that will make the buttons noop if they should have been disabled. Then just have the button state as a bonus on Windows (which is the major platform.)

def set_validation_proc(command, &block)
# If the Mac bug is fixed, change this condition to include the supported versions.
if Sketchup.platform == :platform_win
command.set_validation_proc(&block)
end
command
end