name: focus description: This skill should be used when the user asks questions about OpenHarmony ArkUI focus system, including focus navigation (direction keys, Tab key), focus events (onFocus, onBlur, onKey), focus properties (focusOnTouch, defaultFocus, tabIndex, groupDefaultFocus), focus styles (FocusBox, FocusPattern), FocusManager, FocusView, FocusHub, FocusEventHandler, FocusModifier, keyboard navigation, remote control navigation, accessibility focus support, focus chain management, and focus rendering. Covers both ArkTS application layer and C++ implementation layer. version: 1.0.0
OpenHarmony ArkUI Focus System Skill
This skill provides comprehensive support for analyzing and understanding OpenHarmony ArkUI focus system, including focus navigation, event handling, style rendering, and accessibility support.
Focus System Overview
OpenHarmony ArkUI implements a comprehensive focus management system that handles user interface focus interactions for keyboard, remote control, touch, and other input methods.
Core Architecture
The focus system consists of three main layers:
Application Layer (ArkTS/JS):
- Focus properties:
focusOnTouch,defaultFocus,tabIndex - Focus events:
onFocus,onBlur,onKey
Bridge Layer:
- JSFocusFunction
- ArkTS Native Interface (ANI)
C++ Implementation Layer:
- FocusManager: Global focus management
- FocusView: View container management
- FocusHub: Core focus hub
- FocusEventHandler: Event processing
- FocusModifier: Focus box rendering
Key Components
- FocusManager: Global focus state manager, manages FocusView stack
- FocusView: Focusable view container (Window, Dialog, Overlay)
- FocusHub: Core focus hub, manages node focus state
- FocusEventHandler: Handles keyboard and direction key events
- FocusBox: Defines focus box visual style
- FocusPattern: Defines node focus behavior pattern
- FocusModifier: Renders focus box in RenderService layer
Code Locations
Core Focus Code
Located at: /home/z00576141/workspace/lxc_rom_0202/code/foundation/arkui/ace_engine/frameworks/core/components_ng/
components_ng/
├── event/ # Focus event layer
│ ├── focus_hub.h # Core focus hub (line 45)
│ ├── focus_event_handler.h # Focus event handler (line 106)
│ ├── focus_box.h # Focus box style (line 29)
│ ├── focus_state.h # Focus state definitions
│ └── focus_type.h # Focus type definitions (line 23)
├── manager/focus/ # Focus management layer
│ ├── focus_manager.h # FocusManager class (line 171)
│ └── focus_view.h # FocusView class (line 30)
└── render/adapter/ # Focus render layer
├── focus_modifier.h # Focus rendering modifier
├── focus_state_modifier.h # Focus state modifier
└── focus_animation_modifier.h # Focus animation modifier
Accessibility Support
Located at: /home/z00576141/workspace/lxc_rom_0202/code/foundation/arkui/ace_engine/adapter/ohos/osal/accessibility/focus_move/
Key files:
accessibility_focus_strategy.cpp/h- Focus movement strategyaccessibility_focus_move_osal.cpp/h- Focus movement OSALaccessibility_focus_frame_node_utils.cpp/h- FrameNode utilitiesaccessibility_third_node_utils.cpp/h- Third-party node utilities
Bridge Layer
Located at: /home/z00576141/workspace/lxc_rom_0202/code/foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/functions/
Key files:
js_focus_function.cpp/h- JS focus function interface
Located at: /home/z00576141/workspace/lxc_rom_0202/code/foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/
Key files:
arkts_native_common_bridge.cpp- ANI bridge implementations
Focus Type System
FocusType Enum
File: focus_type.h:23
enum class FocusType : int32_t {
DISABLE = 0, // Focus disabled
NODE = 1, // Focusable leaf node (Button, TextInput)
SCOPE = 2, // Focusable container (Row, Column, Grid)
};
Usage:
- DISABLE: Node does not participate in focus system
- NODE: Focusable terminal node
- SCOPE: Focus container that manages child node focus
FocusStyleType Enum
File: focus_type.h:29
enum class FocusStyleType : int32_t {
NONE = -1, // No style
INNER_BORDER = 0, // Inner border
OUTER_BORDER = 1, // Outer border
CUSTOM_BORDER = 2, // Custom border
CUSTOM_REGION = 3, // Custom region
FORCE_BORDER = 4, // Force border
FORCE_NONE = 5, // Force no border
};
FocusStep Enum
File: focus_type.h:48
enum class FocusStep : int32_t {
NONE = 0x0,
LEFT = 0x1, // Move left
UP = 0x2, // Move up
RIGHT = 0x11, // Move right
DOWN = 0x12, // Move down
LEFT_END = 0x3, // Move left to edge
UP_END = 0x4, // Move up to edge
RIGHT_END = 0x13, // Move right to edge
DOWN_END = 0x14, // Move down to edge
SHIFT_TAB = 0x5, // Previous (Shift+Tab)
TAB = 0x15, // Next (Tab)
};
FocusIntension Enum
File: focus_event_handler.h:45
enum class FocusIntension : int32_t {
NONE = 0,
LEFT, UP, RIGHT, DOWN, // Direction keys
TAB, SHIFT_TAB, // Tab navigation
HOME, END, // Home/End keys
SELECT, SPACE, ESC, // Other keys
};
Focus Navigation Flow
Direction Key Navigation
User presses direction key
↓
KeyEvent dispatched to FocusHub
↓
FocusEventHandler.OnKeyEvent()
↓
Parse FocusIntension (LEFT/UP/RIGHT/DOWN)
↓
HandleFocusTravel() [focus_event_handler.h:127]
↓
Find next focusable node based on FocusStep
↓
FocusManager.RequestFocus(newFocusHub) [focus_manager.h:171]
↓
Focus switch successful
Algorithm Key Points:
- Current node check: Check current focus node type (NODE/SCOPE)
- Child traversal: SCOPE type traverses children to find candidate
- Parent delegation: Delegate to parent SCOPE if unable to handle
- Candidate evaluation: Evaluate candidates based on geometry, Tab order
Tab Key Navigation
User presses Tab/Shift+Tab
↓
KeyEvent dispatched to FocusHub
↓
Parse as FocusStep::TAB or SHIFT_TAB
↓
Find next node by tabIndex order
↓
Request focus to target node
↓
Update focus state
Tab Order Rules:
- Priority by
tabIndexascending - Same
tabIndexby document order tabIndex < 0not in Tab navigation
Default Focus
FocusView shows
↓
RequestDefaultFocus() [focus_view.h:67]
↓
Find defaultFocus=true node
↓
Find tabIndex minimum node
↓
Request focus to default node
↓
Focus set successfully
Default Focus Priority:
defaultFocus=trueandisGroupDefault=truenodesdefaultFocus=truenodes- Smallest
tabIndexfocusable node
Common Development Scenarios
Scenario 1: Custom Focus Style
Requirement: Custom component focus box style
Solution (ArkTS):
@Component
struct CustomFocusButton {
@State isFocused: boolean = false
build() {
Button('Click Me')
.border({
width: this.isFocused ? 2 : 0,
color: this.isFocused ? Color.Blue : Color.Transparent,
radius: 8
})
.onFocus(() => {
this.isFocused = true
})
.onBlur(() => {
this.isFocused = false
})
}
}
C++ Layer Implementation:
focus_modifier.h:30- FocusModifier sets focus boxfocus_box.h:29- FocusBox style definition
Scenario 2: Focus Navigation Control
Requirement: Custom direction key navigation logic
Solution (ArkTS):
@Component
struct CustomFocusNavigation {
@State currentIndex: number = 0
private items: string[] = ['Item 1', 'Item 2', 'Item 3', 'Item 4']
build() {
Column() {
ForEach(this.items, (item: string, index: number) => {
Text(item)
.tabIndex(index + 1)
.borderWidth(this.currentIndex === index ? 2 : 1)
.onFocus(() => {
this.currentIndex = index
})
})
}
}
}
C++ Layer:
focus_event_handler.h:127-HandleFocusTravel()virtual functionfocus_type.h:48-FocusStepenum definition
Scenario 3: Focus Group Management
Requirement: Manage focus between multiple areas
Solution (ArkTS):
@Component
struct FocusGroupExample {
@State activeGroup: number = 1
build() {
Column() {
// Group 1
Row() {
Button('A1').tabIndex(1)
Button('A2').tabIndex(2)
}
.groupDefaultFocus(this.activeGroup === 1)
.onFocus(() => {
this.activeGroup = 1
})
// Group 2
Row() {
Button('B1').tabIndex(3)
Button('B2').tabIndex(4)
}
.groupDefaultFocus(this.activeGroup === 2)
.onFocus(() => {
this.activeGroup = 2
})
}
}
}
C++ Layer:
focus_hub.h:97-isDefaultGroupFocus_group default focusfocus_manager.h:171- FocusType::SCOPE management
Scenario 4: Default Focus Setting
Requirement: Auto-focus on specified element when page loads
Solution (ArkTS):
@Entry
@Component
struct DefaultFocusPage {
build() {
Column() {
TextInput({ placeholder: 'Username' })
.defaultFocus(true) // Auto-focus on page load
.tabIndex(1)
TextInput({ placeholder: 'Password' })
.tabIndex(2)
Button('Login')
.tabIndex(3)
}
}
}
Scenario 5: Focus Event Handling
Requirement: Monitor and handle various focus events
Solution (ArkTS):
@Component
struct FocusEventExample {
build() {
Column() {
Button('Focus Event Demo')
.onFocus(() => {
console.log('Gained focus')
})
.onBlur(() => {
console.log('Lost focus')
})
.onKey((event: KeyEvent) => {
// Handle key events
switch (event.type) {
case KeyType.Down:
console.log('Key down: ' + event.keyCode)
break
case KeyType.Up:
console.log('Key up: ' + event.keyCode)
break
}
})
}
}
}
C++ Layer Event Dispatch:
focus_event_handler.h:130- Event callback macro definitionsfocus_event_handler.h:106- FocusIntention enum
API Mapping
ArkTS to C++ Layer Mapping
| ArkTS Property | C++ Property | Setter Method |
|---|---|---|
focusOnTouch |
FocusPattern::focusOnTouch | SetFocusOnTouch() |
defaultFocus |
FocusPattern::defaultFocus | SetDefaultFocus() |
tabIndex |
FocusPattern::tabIndex | SetTabIndex() |
groupDefaultFocus |
FocusPattern::isGroupDefault | SetIsGroupDefault() |
onFocus |
FocusCallbackEvents::onFocusCallback_ | SetOnFocusCallback() |
onBlur |
FocusCallbackEvents::onBlurCallback_ | SetOnBlurCallback() |
onKey |
FocusCallbackEvents::onKeyEventCallback_ | SetOnKeyCallback() |
Bridge Code Example
File: frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.cpp
// Set focusOnTouch
ArkUINativeModuleValue SetFocusOnTouch(ArkUIRuntimeCallInfo* runtimeCallInfo)
{
EcmaVM* vm = runtimeCallInfo->GetVM();
Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0); // Node
Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1); // Value
auto node = nodePtr(firstArg->ToNativePointer(vm)->Value());
bool focusOnTouch = secondArg->ToBoolean(vm)->Value();
auto frameNode = GetFrameNodeByNode(node);
CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
auto focusHub = frameNode->GetFocusHub();
CHECK_NULL_RETURN(focusHub, panda::JSValueRef::Undefined(vm));
focusHub->SetFocusOnTouch(focusOnTouch);
return panda::JSValueRef::Undefined(vm);
}
Debugging Tips
1. Focus State Checking
// Print focus state in component
.onFocus(() => {
console.log(`Element focused: ${this.id}`)
console.log(`Is focused: ${this.isFocused}`)
})
2. Focus Tree Viewing
# View focus tree using hdc tool
hdc shell aa dump --focus
3. Log Tracing (C++ Layer)
// Add logs at key locations
LOGI("FocusHub::RequestFocusImmediately nodeId=%{public}d", id_);
LOGI("FocusManager::RequestFocus result=%{public}d", result);
Common Issues
Issue 1: Focus Box Not Visible
Checklist:
- Component
focusableproperty is true -
FocusStyleTypeconfiguration is correct -
FocusBoxstyle is set -
FocusModifieris correctly applied - Node actually has focus (
IsFocused()returns true)
Issue 2: Focus Cannot Move
Possible causes:
- Focus chain configuration error
- Parent node not set as SCOPE type
- Node disabled or hidden
- Focus priority conflict
Issue 3: Tab Key Order Incorrect
Check points:
tabIndexvalues set as expected- No negative
tabIndex(not in Tab navigation) - Document order for same
tabIndexnodes
Correct configuration:
Column() {
Button('First').tabIndex(1) // First focus
Button('Second').tabIndex(2) // Second
Button('Third').tabIndex(3) // Third
Button('Skip').tabIndex(-1) // Not in Tab nav
}
Best Practices
1. Focus Design Principles
- Predictability: Focus movement should be intuitive (left→right, top→bottom)
- Visibility: Focus box should be clearly visible
- Consistency: Same component types should have same focus behavior
- Efficiency: Minimize focus movement steps
2. Performance Optimization
- Avoid deep focus tree nesting (< 5 layers recommended)
- Use SCOPE type appropriately to reduce traversal range
- Lazy load complex interface focus trees
- Reuse FocusHub instances
3. Accessibility Support
- Set appropriate
tabIndexfor all interactive elements - Provide meaningful
onFocus/onBlurcallbacks - Support keyboard navigation
- Implement focus movement logic for custom components
Search Patterns
# Find focus-related files
find ace_engine -name "*focus*"
# Find FocusHub usage
grep -r "GetFocusHub()" frameworks/core/components_ng
# Find focus event handling
grep -r "OnKeyEvent\|OnFocus\|OnBlur" frameworks/core/components_ng
# Find focus styles
grep -r "FocusBox\|FocusPattern" frameworks/core/components_ng
Reference Files
| File | Description |
|---|---|
focus_hub.h:45 |
FocusHub class definition |
focus_manager.h:171 |
FocusManager class definition |
focus_view.h:30 |
FocusView class definition |
focus_type.h:23 |
FocusType enum |
focus_event_handler.h:125 |
HandleFocusTravel method |
focus_modifier.h:30 |
FocusModifier rendering |
Skill version: 1.0.0 Last updated: 2025-02-04 Applicable version: OpenHarmony API 12+