"'앱이 떠 있나' 를 묻지 마. '내가 붙잡은 그게 아직 거기 있나' 를 물어. 아주 다른 질문이야."
믿지 말고 다시 읽어
네이티브 접근성 자리라면, 사진이 맞는지 확인한다는 건 세상을 다시 읽어서 붙잡아둔 것과 하나씩 맞춰본다는 뜻이야. 시스템 전역 요소로 돌아가 포커스된 요소를 다시 읽고, 거기 긁힌 글이랑 범위를 다시 읽고. Track 3 에서 걸었던 그 사슬을 넣는 시점에 한 번 더 도는 거지. 자리를 새로 구하려는 게 아니라, 이미 갖고 있는 자리가 아직 현실이랑 맞는지 확인하려는 거야. 옛 사진을 그냥 믿는 건 나를 안전하게 지켜주는 바로 그 단계를 건너뛰는 거고.
뭐가 맞아야 하나
네이티브 확인은 여러 개를 맞춰보고 전부 통과해야 해. 앞에 있는 앱이랑 프로세스 번호가 같아야 같은 앱이고. 포커스된 요소의 역할이랑 정체가 같아야 같은 칸이고. 그리고 제일 중요한 게 긁혀 있는 글이랑 그 범위야. 내가 대신하려던 바로 그 글자들이 아직 긁혀 있어야 하니까. 이 마지막 확인이 Flint 의 확인을 어설픈 확인이랑 갈라놔. 같은 앱만으론 부족해. 같은 칸도 부족하고. 같은 글이 긁혀 있는 것 이 기준이야. 그게 지금 덮어써질 거니까.
붙잡아둔 것 (t0) 다시 읽은 것 (t1) 판정
--------------------- --------------------- -------
앱 이름 + pid 앱 이름 + pid 같아야 함
포커스된 요소 역할 포커스된 요소 역할 같아야 함
긁힌 글 긁힌 글 같아야 함
긁힌 범위 긁힌 범위 같아야 함
다 맞으면 -> 대신한다
하나라도 다르면 -> 거부
긁힌 자리만 정확히 대신하기
확인이 통과하면 네이티브 교체는 아주 정밀해. 포커스된 요소의 '긁힌 글' 속성에 바뀐 글을 넣으면 지금 긁혀 있는 범위만 정확히 덮어써져. 그 범위가 아직 붙잡아뒀던 그거라고 방금 확인했으니까, 덮어쓰기가 사용자가 뜻한 바로 그 자리에 떨어지고. 이게 있을 수 있는 제일 깨끗한 삽입이야. 클립보드도 안 건드리고, 가짜 키 입력도 없고, 확인된 범위만 딱 바꾸는 것. 그리고 네이티브 자리가 범위를 먼저 다시 확인하게 해줬기 때문에 가능한 거고.
AXUIElement 참조는 시간을 건너 비교하기엔 못 미더워. 같은 칸이 다른 참조를 돌려줄 수도 있고, 낡은 참조가 허공을 가리킬 수도 있거든. 그러니 '이게 같은 객체 포인터인가' 를 확인하지 마. '지금 포커스된 요소가 같은 앱, 같은 역할, 같은 글, 같은 범위를 말하고 있나' 를 확인해. 믿을 수 있는 정체는 다시 읽어서 확인되는 정체지, 캐시해둔 손잡이가 아니야.