New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Final Cut Pro Font actions broken #3212
Comments
Hmm, axutil.children looks pretty solid to me. A lot of other things would break if that was buggy. A guess off the top of my head is that the order/structure of the missing fields has changed at some point? Sometimes PopupButtons get switched to MenuButtons by Apple between versions, or they add an extra UI element, or there is something that is only visible sometimes and not others. |
@randomeizer - The interesting thing is that font What's failing is
> cp.ui.PopUpButton.matches(cp.apple.finalcutpro.inspector.text:basic():font():children()[2])
true ...so it's something wrong with
...it just uses --- cp.ui.axutils.childAtIndex(element, index, compareFn[, matcherFn]) -> axuielement
--- Function
--- Searches for the child element which is at number `index` when sorted using the `compareFn`.
---
--- Parameters:
--- * element - the axuielement or array of axuielements
--- * index - the index number of the child to find.
--- * compareFn - a function to compare the elements.
--- * matcherFn - an optional function which is passed each child and returns `true` if the child should be processed.
---
--- Returns:
--- * The child, or `nil` if the index is larger than the number of children.
function axutils.childAtIndex(element, index, compareFn, matcherFn)
if element and index > 0 then
local children = axutils.children(element)
if children then
if matcherFn then
children = axutils.childrenMatching(children, matcherFn)
end
if #children >= index then
sort(children, compareFn)
return children[index]
end
end
end
return nil
end So I think the problem is in Maybe related to #3200 - i.e. Maybe some kind of change upstream in Hammerspoon? |
It could be some leftover old code from before we switched the |
Basically, the problem is that every --- cp.ui.Element:attributeValue(id) -> anything, true | nil, false
--- Method
--- Attempts to retrieve the specified `AX` attribute value, if the `UI` is available.
---
--- Parameters:
--- * id - The `AX` attribute to retrieve.
---
--- Returns:
--- * The current value for the attribute, or `nil` if the `UI` is not available, followed by `true` if the `UI` is present and was called.
function Element:attributeValue(id)
local ui = self:UI()
if ui then
return ui:attributeValue(id), true
end
return nil, false
end This means that when we pass in our
The tricky part is knowing at which point we broke things, as |
Hmm. Interesting... A possible fix could be to flip the order of the check - check for |
So, this implementation seems to work for me: --- cp.ui.axutils.children(element[, compareFn]) -> table
--- Function
--- Finds the children for the element. If it is an `hs.axuielement`, it will
--- attempt to get the `AXChildren` attribute. If it is a table with a `children` function,
--- that will get called. If no children exist, an empty table will be returned.
---
--- Parameters:
--- * element - The element to retrieve the children of.
--- * compareFn - Optional function to use to sort the order of the returned children.
---
--- Returns:
--- * a table of children
function axutils.children(element, compareFn)
local children = element
if element and is.callable(element.children) then
--------------------------------------------------------------------------------
-- There is a `children` function, priorise that.
--------------------------------------------------------------------------------
children = element:children()
elseif element and element.attributeValue then
--------------------------------------------------------------------------------
-- It's an AXUIElement:
--------------------------------------------------------------------------------
children = element:attributeValue("AXChildren") or element
end
if type(children) == "table" then
if type(compareFn) == "function" then
sort(children, compareFn)
end
return children
end
return {}
end Searching through the codebase, very few elements implement a |
In practical terms, it would have only broken for |
@randomeizer - Would it be better for performance if we left For example, we could just add: --- cp.ui.PropertyRow:attributeValue(id) -> anything, true | nil, false
--- Method
--- Attempts to retrieve the specified `AX` attribute value, if the `UI` is available.
---
--- Parameters:
--- * id - The `AX` attribute to retrieve.
---
--- Returns:
--- * The current value for the attribute, or `nil` if the `UI` is not available, followed by `true` if the `UI` is present and was called.
---
--- Notes:
--- * If the `id` is `AXChildren`, then we'll return a table of children for the Property Row.
function PropertyRow:attributeValue(id, ...)
if id == "AXChildren" then
return self:children()
end
local ui = self:UI()
if ui then
return ui:attributeValue(id), true
end
return nil, false
end |
Reported by Daniel Malferrari on Facebook.
Error Message Displayed: Failed to get Font Family UI: nil
The label and reset button seem to work fine - it's just the
family
andtypeface
that are failing:Interestingly, the
row
does contain the right UI items, so it looks like it's failing onchildFromRight(row, 2, PopUpButton.matches)
.The text was updated successfully, but these errors were encountered: