)]}'
{
  "commit": "dae999ed5e446ba3907ca792030cd5a5de2e9a8b",
  "tree": "8ddcc65e810fe99a77a87833709d26986ab8fe89",
  "parents": [
    "70665773233a20cee6b93700cd4d52168fbeabfc"
  ],
  "author": {
    "name": "alxgibsn",
    "email": "hello@rive.app",
    "time": "Wed Jul 08 22:31:10 2026 +0000"
  },
  "committer": {
    "name": "alxgibsn",
    "email": "hello@rive.app",
    "time": "Wed Jul 08 22:31:10 2026 +0000"
  },
  "message": "feat(focus): ui pass 1 (#13029) 72963a4d12\n* core updates\n\n* wip\n\n* icons\n\n* rebased\n\n* rive remote and initial value fix\n\n* forgot the riv...\n\n* feat(editor): stage focus overlay indicating focus during playback\n\nAdd a corner-bracket overlay on the design stage that shows where focus\nis while a state machine plays, without needing to wire focus state\nthrough view model properties.\n\n- Blue brackets around a directly focused element in the active artboard\n- Grey brackets around a nested artboard/component when focus is\n  contained within it (matched via shared focus-node identity)\n- d-pad next/previous now wakes the stage so the bracket updates\n  immediately instead of only on hover\n\n* feat(focus): unify focus listener actions, add Clear focus, and focus transition conditions\n\nEditor + core changes for focus authoring in state machines:\n\nListener actions\n- Merge the separate \"Focus Target\" and \"Focus Traversal\" listener behaviours\n  into a single \"Focus\" action with a leading mode combo (target / traverse /\n  clear). Combos size to their widest option.\n- Add a new FocusActionClear core type (Dart + C++ runtime + rml) that clears\n  the artboard focus at runtime.\n\nViewport\n- Move the \"Focus Indicator\" option above \"Show Final Playback\" via a decoupled\n  ViewportOption.displayOrder (enum declaration order stays fixed for the\n  persisted bitmask).\n\nTransition conditions\n- Add a \"Focus\" left-hand condition option (in the artboard section, behind the\n  focusManagement flag): `focus \u003d\u003d / !\u003d \u003cfocusable component\u003e`, with a\n  right-hand dropdown listing components that have a FocusData child.\n- New TransitionFocusCondition core type (extends TransitionViewModelCondition),\n  reusing a component comparator to store the target. Self-contained evaluation\n  in Dart and C++ (queries FocusManager::hasPrimaryFocus); added a const\n  focusManager() accessor on StateMachineInstance. Registered in rive_core,\n  runtime, and rml core registries.\n\nNote: focus_overlay.dart carries a small pre-existing change (gating the overlay\non the focusBrackets viewport option) included with this branch\u0027s focus work.\n\n* review: address Copilot feedback on focus condition\n\n- TransitionFocusCondition (Dart): resolve the target component comparator\n  from either the right OR left slot, matching the C++ runtime. A .riv\n  re-imported into the editor assigns the single exported comparator to the\n  left slot, which previously made target/validateCondition/evaluate/uniqueId\n  treat the condition as invalid and always evaluate false.\n- state_machine_manager: focus condition create/select helpers now use the\n  slot-agnostic targetComparator so editing an imported focus condition works.\n- StageViewport: assert ViewportOption.displayOrder contains every option so a\n  future enum addition can\u0027t silently drop a toggle from the menus.\n\n* fix(editor): remove unused imports failing flutter analyze\n\nCI runs `flutter analyze --no-fatal-infos --fatal-warnings`, which promoted two\nunused_import warnings in focus_data_inspector_builder.dart (component.dart and\ncore_text_field.dart) to fatal errors. Neither symbol is referenced; removed\nthem so the editor analyze step passes.\n\n* test(editor): allowlist condition_row.dart in theme rename audit\n\nThe new `_FocusConditionFlow` paints `colors.warning` (0xFFF6C566) on its node\nconnectors in the invalid state, mirroring `_DataPropertyFlow` — a legitimate\n+1 warning-hex site vs mainline, not a rename miswire. Add condition_row.dart\nto the audit allowlist with a justification (baseline regeneration only applies\nto changes already on mainline).\n\n* test(editor): allowlist backboard_inspector_builder.dart in theme rename audit\n\nThe focus feature removed the legacy _FocusButton / _DPad / _DPadButton widgets\nfrom the backboard inspector (superseded by per-component focus authoring).\nThose widgets held all of the file\u0027s RiveColors sites (border, trackEmphasis,\ntextSecondary x2 each), so the branch paints 0 vs mainline\u0027s 6 — an intentional\nremoval, not a rename. Add it to the audit allowlist with a justification.\n\n* chore(rive_core): regenerate core from defs (focus types)\n\n* fix(core): reassign focus type keys to avoid collision with master\n\nMaster\u0027s data-bind font PR (#13031) added ViewModelPropertyAssetFont (1034)\nand ViewModelInstanceAssetFont (1035), which now collide with the focus types\nintroduced here. Reassign FocusActionClear -\u003e 1037 and TransitionFocusCondition\n-\u003e 1038 (next free keys after master\u0027s 1036) in the defs and generated base\nfiles (Dart + runtime + rml). Registrations reference the typeKey constants, so\nno other changes are needed.\n\n* style(runtime,rml): clang-format focus C++ files\n\n* test(runtime): add C++ tests for FocusActionClear and TransitionFocusCondition\n\n* test(runtime): avoid ODR-use of TransitionFocusCondition typeKey static\n\n* runtime test\n\n* feedback\n\nCo-authored-by: Alex Gibson \u003cagibson.uk@gmail.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "786a329482ae648dd1f70ee6519e30c3f9ee6bc4",
      "old_mode": 33188,
      "old_path": ".rive_head",
      "new_id": "69cffd2952bbff0ff2451d31312831b68fb0a4da",
      "new_mode": 33188,
      "new_path": ".rive_head"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "10ea749d9a1755c9923c5d607e7511ab2d17bd2c",
      "new_mode": 33188,
      "new_path": "dev/defs/animation/focus_action_clear.json"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "c3e751989f8c9d7ad62dcdd509b24676848b12e1",
      "new_mode": 33188,
      "new_path": "dev/defs/animation/transition_focus_condition.json"
    },
    {
      "type": "modify",
      "old_id": "817271f64385bec817aeba54f73d75fbe6c7e78b",
      "old_mode": 33188,
      "old_path": "dev/defs/focus_data.json",
      "new_id": "d0b84e9eb8757f75ae29eb3d6a6da309aafd6a8e",
      "new_mode": 33188,
      "new_path": "dev/defs/focus_data.json"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "a17d954006b30015c90307799acec29f522a5f04",
      "new_mode": 33188,
      "new_path": "include/rive/animation/focus_action_clear.hpp"
    },
    {
      "type": "modify",
      "old_id": "a45b5565e94892aceb2550b44b1b2ce295e72e99",
      "old_mode": 33188,
      "old_path": "include/rive/animation/state_machine_instance.hpp",
      "new_id": "24774a890a45be76b994f1d3637857d25d1dee38",
      "new_mode": 33188,
      "new_path": "include/rive/animation/state_machine_instance.hpp"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "7e7eaa5d2917737daf7578d806c31df49690c249",
      "new_mode": 33188,
      "new_path": "include/rive/animation/transition_focus_condition.hpp"
    },
    {
      "type": "modify",
      "old_id": "10b21f1cd692a8501ab2283d2d248bdd9928178b",
      "old_mode": 33188,
      "old_path": "include/rive/focus_data.hpp",
      "new_id": "87dfbf18fd65d812a3b5b1fdb028934a03fa16ff",
      "new_mode": 33188,
      "new_path": "include/rive/focus_data.hpp"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "1b67298eb61f593243145e31ca13d70377a2d4e3",
      "new_mode": 33188,
      "new_path": "include/rive/generated/animation/focus_action_clear_base.hpp"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "a9759a08730357a8f6d5479fb7f29c475f3496bd",
      "new_mode": 33188,
      "new_path": "include/rive/generated/animation/transition_focus_condition_base.hpp"
    },
    {
      "type": "modify",
      "old_id": "36e1fc93abae75369fc1786a8e3eb971729b323b",
      "old_mode": 33188,
      "old_path": "include/rive/generated/core_registry.hpp",
      "new_id": "adf504c007dbd90e19eb2303666bb1ee34296f3b",
      "new_mode": 33188,
      "new_path": "include/rive/generated/core_registry.hpp"
    },
    {
      "type": "modify",
      "old_id": "e680398b6f71a0b575acadeb2075b916cca8d86c",
      "old_mode": 33188,
      "old_path": "include/rive/generated/focus_data_base.hpp",
      "new_id": "25ea1665164f20d78c24fb8f0a88a080cc8f17b9",
      "new_mode": 33188,
      "new_path": "include/rive/generated/focus_data_base.hpp"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "c5d2ebbc8c541d56a63a95a246ef4fe07f590d0f",
      "new_mode": 33188,
      "new_path": "src/animation/focus_action_clear.cpp"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "7e19f3edefe0dd4732415c35649c54043b38ca35",
      "new_mode": 33188,
      "new_path": "src/animation/transition_focus_condition.cpp"
    },
    {
      "type": "modify",
      "old_id": "3d66d88fc3c22e78b08b0e21759b462ee19eb85f",
      "old_mode": 33188,
      "old_path": "src/file.cpp",
      "new_id": "9bb11509e0bd658504a30e8f8b6c7d7b3cc33fd5",
      "new_mode": 33188,
      "new_path": "src/file.cpp"
    },
    {
      "type": "modify",
      "old_id": "631e61937200f8eafdf94f0d0e690337f5af8ebb",
      "old_mode": 33188,
      "old_path": "src/focus_data.cpp",
      "new_id": "d4a3387c27a67e510a2c2c5a73bee83367b360d4",
      "new_mode": 33188,
      "new_path": "src/focus_data.cpp"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "adec5affb6465884871035a7467b1f1d5faff605",
      "new_mode": 33188,
      "new_path": "src/generated/animation/focus_action_clear_base.cpp"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "6ff444aa038d375f90956f8a1664c8ef7fd9bc38",
      "new_mode": 33188,
      "new_path": "src/generated/animation/transition_focus_condition_base.cpp"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "a328f3911370aa39282427a059ca7aee01205a66",
      "new_mode": 33188,
      "new_path": "tests/unit_tests/assets/focus_test.riv"
    },
    {
      "type": "modify",
      "old_id": "e6887585f1993d1c01ba492450042e8fc3d7db2e",
      "old_mode": 33188,
      "old_path": "tests/unit_tests/runtime/focus_test.cpp",
      "new_id": "0e856b69ed07082b2e4a83f412242314a969e4c5",
      "new_mode": 33188,
      "new_path": "tests/unit_tests/runtime/focus_test.cpp"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "79cc14ba0434ad90be8ef47b0a8a5ae42425ae20",
      "new_mode": 33188,
      "new_path": "tests/unit_tests/silvers/focus_test.sriv"
    }
  ]
}
