특정 위젯 내에서의 클릭 (위젯 내의 버튼 및 공백 영역 등..) 이벤트가 있을 시

텍스트 입력창(EditableText)에서의 Focus를 유지시켜주거나

위젯 외부에서의 클릭 이벤트가 있을 시엔 위젯을 닫아주는 기능을 개발 했었는데,

 

이 때 어째선지 특정 위젯 내의 Button Pressed Event는 정상적으로 호출 되었지만

Clicked Event가 오지 않는 문제가 발생하여 그 이유를 살펴 보았다.

 


 

1. 작업 한 Focus 관리 방식

 

 

위의 코드는 UUserWidget::NativeOnFocusChanging() 함수를 Override 한 내용인데

Slate에서의 Focus의 점유가 변경될 때 호출되는 함수이다. 

 

주석 하단 부분의 조건을 통과하게 된다면 

최상위 위젯 내부에서의 Focus 변경  => 텍스트 입력창에게 다시 Focus 부여

외부 위젯에서의 Focus 점유  => 위젯 Close 처리

위와 같은 처리가 되게 작업을 하였다.

 

여기서 어떤 부분이 문제였는지, Button Widget들의 Clicked Event가 오지 않아

클릭 시의 처리가 불가능한 문제가 발생 하였다. 

 


 

2. 원인 파악

 

FSlateApplication::SetUserFocus() 함수 내 Line:2952

 

Slate에서 Focus가 변경될 때 이전에 Focus를 지니고 있던 위젯의

OnFocusLost()함수를 호출해주게 된다.

 

 

이 때 SButton에서는 FocusLost() 함수를 Override하여 Release()라는 함수를 호출해주게 되는데,

Release() 함수는 멤버 변수인 bIsPressed를 false로 변경 해주며

버튼의 상태(이미지 등..)를 변경시켜주는 등의 작업을 해주게 된다.

 

이후 FSlateApplication::ProcessMouseButtonUpEvent() 함수에 의해

SButton의 OnMouseButtonUp() 함수가 호출되는데, 여기서 문제가 발생한다.

(Slate Input 처리 Flow 관련 게시글 : https://manduk8412.tistory.com/83)  

 

 

코드를 보면

Line : 355에서 bMustBePressed라는 변수는 버튼의 ClickMethod를 검사하며

Line : 356에서 bMeetsPressedRequirements를 통해 Pressed가 필요한 Method일 경우

bIsPressed 변수의 값을 통해 상태가 결정되는 구조이다.

 

여기서 이미 FocusLost() 호출에 의해 bIsPressed 변수가 false로 변경된 상태이기 때문에

Line : 358에서의 조건이 통과되지 않게되고, Line : 390 에서의 ExecuteOnClick()이 호출되지 않아

버튼의 Clicked Event Callback이 호출되지 않는 문제였다.

+ Recent posts