레이블이 Bug-82276인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Bug-82276인 게시물을 표시합니다. 모든 게시물 표시

2012년 5월 8일 화요일

Chromium Bug - 82276 (3)

이제 FindBarController가 마우스 클릭 이벤트를 구독하도록 하고, 이벤트 핸들러를 구현해보자.

이전 포스트에서 언급했듯이 Find Bar의 life cycle은 FindBarController 의 Show()/EndFindSession() 에서 시작되고 종료된다.

Show() 함수에서 다음과 같이 마우스 클릭 이벤트를 등록했다.


registrar_ (content::NotificationRegistrar) 의 Add() 를 이용해서 Noti를 받고싶은 원하는 notification type을 등록한다.
Add()의 첫번째 파라미터로 NotificationObserver를 구현한 객체를 전달하는데,
Notificaiton Service (NotificationServiceImpl) 에게 이 Noti가 발생했을때, 이 객체의 Observe()를 호출하라는 의미이다.
두번째 파라미터는 Noti의 이름이고, 세번째 파라미터는 받고싶은 Noti의 Source를 설정하는 부분이다.
Noti의 Source란 이 Noti를 생성하는 부분인데, 두번째 파라미터의 Noti를 Observer 가 특정 객체로부터 생성된 것만 받거나 모든 객체에서 생성되것을 받을 수 있다.
다음과 깉이 설정하면 WebContents의 객체에서 Noti만 받을 수 있다.
content::Source(tab_contents_->web_contents())
위 그림에서 처럼 AllSources() 로 설정하면, 모든 객체에서 생성되는 INPUT_EVENT_ACK Noti를 받을 수 있다.


다음은 Observe() 함수에 추가한 부분이다.



Observe() 함수의 파라미터를 통해 type, source, details를 받을 수 있다.
details는 이 Noti가 전달해주는 추가 데이터이다. INPUT_EVENT_ACK의 경우 인풋 이벤트의 종류이다.
여기서는 Mouse Up 이벤트만 관심있으므로 datails 를 통해 인풋 이벤트중 원하는 이벤트를 선택할 수 있다.

마지막으로 이벤트 등록을 삭제하는 부분이다.


삭제도 물론 NotificationService 로부터 이루어지므로 registrar_의 Remove() 를 통해 이루어지고, 파라미터는 Add() 와 같다.


이것으로 Find Refresh 에 필요한 이벤트 등록이 완료됐다.
다음 포스트에서는 어떻게 Refresh를 할지 고민해보자.

2012년 5월 4일 금요일

Chromium Bug - 82276 (2)

Chromium - Notification Registration/Handler

이 버그를 어떻게 풀어나갈지 고민 중이다.

우선 Find Bar를 언제 Refresh 해야할까? (여기서 Refresh란 다시 find 동작을 수행하는 것이다.)
웹페이지의 Re-Paint 이벤트는 이 상황에서 적당한 이벤트 일까?
Re-Paint 이벤트는 웹페이지 내 커서만 깜빡여도 발생하므로 Refresh 가 쉴새 없이 진행될 것이다.
따라서 Refresh 이벤트로 사용하기에는 부적절한 것 같다.
이 경우에 쓸만할 적당한 이벤트가 무엇이 있을까?
흠... 이 버그를 보이게 한 시작점은 폴딩된 메일의 클릭이므로, 마우스 클릭 이벤트를 Refresh 이벤트로 사용해보자!

소스코드를 뒤진 결과 다음과 같은 이벤트가 있다.
content::NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK
이 이벤트는 RenderWidgetHostImpl 객체에서 인풋 이벤트 처리가 끝난 후, Notify 하고 있다.
인풋 이벤트 처리 후가 Refresh 시점에 적절한 지는 좀 더 생각을 해봐야하겠지만, 우선은
인풋 관련 해서 현재 Noti 하고있는 이벤트는 이것뿐인 것 같으므로 사용해보자.

그렇다면 이 이벤트는 언제 받아보면 될까?
브라우저가 실행되고 있다고 해서 이 인풋 이벤트를 받아볼 필요는 없다.
Find Bar 가 떠 있는 상태에서만 인풋 이벤트를 받아서 처리하면 될 것이다.
그렇다면 Find Bar의 보이기/사라지기 가 수행되는 시점을 찾아서 보이기 시점에 인풋 이벤트를 구독하고
사라지는 시점에 구독하던 이벤트를 제거하면 될 것 같다.
Find Bar는 FindBarController::Show()에서 FindBar를 보이게 하고, FindBarController::EndFindSession()에서 사라지게 하고 있다.
따라서 인풋 이벤트는 Show() 호출 시 이벤트와 핸들러를 등록하고, EndFindSession() 불릴 때, 제거하면 될 것같다.

그렇다면...
Chromium은 이벤트 등록/핸들러를 어떻게 할까?

원하는 이벤트의 등록을 위해 NotificationRegistrar 클래스를 제공하고 있다.
이 클래스는 content/public/browser/notification_registrar.h 에 정의되어 있다.
이벤트 핸들러구현을 위해서는 NotificationObserver 클래스를 제공하고 있고,
content/public/browser/notification_observer.h 에 정의되어 있다.

원하는 이벤트 등록을 위해서는 NotificationRegistrar 클래스를 사용해야한다.
아래 그림은 content::NotificationRegistrar 클래스 이다.
public 함수들을 보면 Add(), Remove(), RemoveAll() 등등 이벤트 등록에 필요한 함수들이
구현되어 있음을 알 수 있다.



이벤트 핸들러 등록을 처리하는 NotificationObserver 에 대해서 알아보자.
아래 소스를 보면 NotifiationObserver 는 추상클래스 이다.


핸들러 등록을 원하는 클래스에서 이 추상 클래스를 구현하면 등록한 이벤트가 발생했을때,
이 클래스의 Observe() 함수가 호출이 됨으로써 등록한 핸들러가 실행이 된다.

다음 포스트에서는 FindBarController 클래스의 Show()/EndFindSession()에서 이벤트의 등록/핸들러 구현을 해보겠다.

2012년 4월 14일 토요일

Chromium Bug - 82276 (1)

소스분석을 하면서 사소한 패치들을 올려왔다.
지금까지 여러개의 패치를 올렸지만 모두 사소한 것들이라 패치라고 하기에도 민망하긴 하다.

이젠 알려진 버그 해결을 시도해볼 계획이다.
지금까진, Chromium의 구조를 다 이해하지 못해서 망설이고 있었지만,
Chromium committer가 목표를 높게 가져보라는 말을 듣고, 시도를 해볼 계획이다.

http://code.google.com/p/chromium/issues 로 가면 현재 Chromium의 버그 리포팅들을 볼 수 있고, 진행 상태를 알 수 있다.

쭈욱 살펴보니 대부분은 내용을 알수없는 버그들이다...
무엇을 골라야할지 고민하다, 그래도 버그 내용이 이해가 되는 것을 골랐다.


브라우저에서 웹페이지 내의 문자열을 찾을때, Ctrl+F 를 통해 찾게된다.
위 버그는 gmail 에서 발견된 버그인데, gmail의 경우 엮인 메일들이 많을경우,
엮인 메일중 특정 메일의 내용을 접을수가 있다.
접힌상태의 메일에 포함된 문자열을 검색하면, 접힌 상태이므로 검색이 안된다.
그런데, 접힌 메일을 풀게되도 Find Bar에 입력된 문자열이 자동으로 강조(highlight)되지 않는다.

이 버그를 잡아보려한다.

어디서 시작해야할지는 전혀 감이 안오지만, 멘땅에 헤딩해보자!

Thank you Peter & Carlos.