페이지

2013년 7월 28일 일요일

WebKit, Blink에 Caret Color Patch 적용 완료!

드디어 WebKit에도 그동안 작업했던 Caret Color patch가 적용되었고 Mac port를 위한 gardening도 끝났다. Blink와 WebKit에 적용된 이번 Patch로 인해 이제 적어도 IE를 제외한 모든 Gecko, WebKit, Blink 기반 브라우저는 같은 방식으로 Caret Color를 결정한다. 사실, Caret Color는 웹표준의 영역도 아니고, 대부분 플랫폼이 어떤 특별한 기준을 갖고 있지도 않다. 그렇기 때문에 브라우저 엔진 마다 Caret Color를 결정하는 방식이 달랐다. 어찌보면 사소한 일이지만, 이 부분이 상당히 눈에 거슬렸고, 나중에 접근성 문제까지 있다는 사실을 알게되어 관심을 갖지 않을 수 없었다. 그렇다면 그 동안 무슨 문제가 있었고 어떻게 해결했는지 잠깐 소개해보려고 한다.

Caret Color 문제는 HTML5 ContentEditable 표준과 관계가 깊다. IE에서 먼저 구현한 이 기능을 Firefox가 구현했고 HTML5 표준으로 채택되면서 이제 모든 브라우저에서 사용할 수 있게 되었다. 하지만 Caret Color에 대한 부분은 표준에서 논의되지 않았다. 어찌보면 플랫폼의 영역같이 보이지만, 실제 Windows를 제외하면 명확한 기준도 없다. 그러다 보니, Caret Color를 선택하는 기준이 애플리케이션 마다 다른 경우도 있다.

 위 비디오에서 봐서 알 수 있듯이, Opera, Firefox, Chromium 브라우저에서 Caret Color가 모두 다른 것을 알 수 있다. 특히, 당시 WebKit엔진을 사용했던 Chromium 브라우저의 경우, 검은 배경에서 Caret이 보이지 않는 특수한 상황이 존재했었다. 아직 반영된 patch가 릴리스버전에 포함되기 까지 시간이 걸리기 때문에 비디오에서 보는 Test Case를 열어보면 아직까지 Caret Color가 서로 다른 것을 확인할 수 있다.

각 브라우저 엔진에서 Caret Color를 얻어오는 방식은 다음과 같다.

1. Firefox : 편집 중인 element의 CSS color property에서 Caret Color를 얻어온다. 위 비디오에서 볼 수 있듯이, element의 Color에 따라 Caret Color가 바뀌는 것을 볼 수 있다.

2. IE: IE는 Windows에서 제공하는 API를 이용해서 Caret을 그린다. 그러므로 모든 응용 프로그램에서 같은 Caret Color를 보여준다. Color 선택방식으로 배경색의 XOR하여 즉, 반전효과를 이용해서 어떤 배경에서도 Caret를 구분시켜준다. 이 방식의 큰 장점은 이미지 배경에서도 Caret이 보일 수 있도록 한다. 단점이라면 회색 배경에서는 다소 Caret이 잘 보이지는 않는 점이다. 특히, 색명인 사용자는 회색 배경에서 반전된 Caret은 잘 보이지 않는다고 한다.

3. WebKit: WebKit은 특이하게 현재 편집중인 element의 최상위 ContentEditable element의 CSS color property에서 Caret Color를 얻어왔다. 예를 들어 body tag에서 contentEditable attribute를 추가했다면 body이하 모든 태그가 편집 가능한데, 바로 편집 가능한 최상위 태그인 body tag의 CSS Color property에서 Caret Color를 얻어온다는 것이다. 그러한 이유로, WebKit에서 대부분 Caret Color가 항상 검은색을 갖고 있다.

2010년에 처음 이 작업을 시작할 때는 Firefox 방식으로 patch를 작성했다. 가장 구현하기 쉽고, 검은 배경에서 검색은 글꼴만 아니면, Caret이 항상 구분 가능 방법이다. 하지만 Reviwer는 글꼴 색상에 따라 변경되는 것은 보기 좋지 않다는 의견을 주었고, 나 역시도 빨갛고 노란 Caret Color는 맘에 들지 않았다. 그래서 나온 아이디어가 배경의 lightness를 얻어서 이에 따라 Caret을 흰색 또는 검은색으로 결정하는 것이였다. 배경색을 얻기 힘든 이미지 배경만 빼면 색맹 사용자도 배려한 괜찮은 아이디였다. 물론 Windows용 WebKit port에서만 Caret를 구한 API를  사용하기로 하였다. 그리고는 다른 일로 인해 이 patch를 더 이상 발전시키지 못하고 시간이 2년 넘게 흐르고 말았다.

다시 Blink에 이 patch를 적용하면서 Caret Color를 구하는 방식을 잘못 이해한 부분과 배경의 lightness를 얻는 것이 특정 상황에서는 상당히 복잡도가 높다는 것을 알게 되었다. 예를 들어, CSS position, z-order, text-align 등 사용하면, 편집되고 있는 자식 element가 부모 element 영역을 벗어날 수 있다. 이 경우에는 좌표를 통해 배경색을 얻어야 하는데, caret를 그릴 때 마다 이런 작업을 하기에는 복잡도가 너무 높다.

결과적으로, 편집 중인 text node를 포함하고 있는 element의 CSS color property에서 Caret Color를 얻어오는 것으로 patch가 작성되었고, 이는 WebKit과 Blink에 모두 반영되었다. 참고로, Chromium Canary버전에서 확인할 수 있다.

아직 caret color 논쟁이 끝난 것이 아니다. 색맹인 사용자도 caret을 잘 구분할 수 있고, image배경에서도 잘 구분할 수 있는 방법이 필요하다.

이제 Firefox, WebKit, Blink가 같은 방식으로 caret를 그리게 되었다. 비록 큰 변화는 아니지만, 뭔가 브라우저간의 차이를 조금 줄였다는데 보람이 느껴진다.


2013년 7월 25일 목요일

OSCON 2013

꿈에 그리던 OSCON에서 드디어 갔다왔다. Expo만 갔다오긴 했지만, 그래도 기분은 좋다. Intel부스에서 동료들을 만나고, 나를 위해(?) Tizen IVI 시스템에서 소녀시대 비디오로 동영상 시연하는 센스!  Samsung 부스에서 옛 동료도 만나고.. 여기 저기 부스에서 T-Shirt도 좀 얻어서 올해 옷 걱정은 안해도 될 듯. RMS 전기도 하나 샀는데, 본인이 2판을 직접 update했다고 한다. 전기에서 자서전으로 바뀐건가?

삼성 부스에서 Rust Project에서 활약중인 서상현님과 Mozilla 사람들 만났다. Mozilla 티셔츠 입고 갔더니 더 반가워해주는 듯. Mozilla 사람들은 정말 오랜만에 만나보는 것 같다.  Rust와 Servo를 개발하는 분들인데, 사실 이쪽은 많이 공부하지 않아서 질문은 못했고, 최근 작업중인 Firefox 한글 입력 버그를 설명할 기회를 갖게 되었다. 한글의 조합원리는 영어로 설명하는 것이 그리 쉽지 않다는 것을 새삼 느끼며(우리말로 설명하기도 쉽지 않다고 스스로를 위안하며)... 그리고, 얼마전에 Linux Kernel 3.8에 merge된 Log structured flash memory file system도 전시장에서 소개되고 있었다. 개발자 분도 직접 만나 잠깐 이야기도 나누었다.

MS, Twitter도 부스가 있었는데, Twitter경우 오픈소스 개발자를 뽑으려고 부스를 만들어놓았다. Twitter 솔루션이 오픈소스 기반으로 동작하며 관련한 개발자를 뽑는다고 했다. MS는 자신들의 툴이 Php와 같은 오픈소스를 잘 지원한다는 것을 홍보하고 있었다.

지난 번 GNOME Asia에 keynote를 하신 GNOME Foundation Executive director인, Karen Sandler 님도 잠깐 만났다.

내년에는 반드시 full time으로 참석을 해야겠다.

2013년 7월 5일 금요일

Why upstream?


오픈소스 소프트웨어를 상용 제품에 적용하는 것은 이제 너무나 당연한 일이다. 특히 리눅스를 기반으로 제품을 개발하는 경우에는. 하지만, 많은 회사들이 여전히 실수하는 것 중 하나가 바로 개발 중에 upstream을 하지 않는 것이다. 도대체 upstream이 왜 중요하며, 개발 중에 upstream하면 뭐가 좋을까?

첫번째, maintainer들에게 code review를 받을 수 있다. 상용 제품에 들어가는 code를 maintainer에게 review를 받는다면 그 만큼 좋은 질의 code가 들어간다는 것을 의미한다. 뿐만 아니라 project 방향과 architecture에 잘 들어맞는지 확인도 해준다. 이는 나중에 upstream 불가능한 사태를 미리 피할 수 있도록 해준다. 또한 maintainer와 함께 patch를 review하면서 개발자도 더 많은 것을 배우게 되고 이는 제품의 품질 향상에 기여한다.

두번째, rebase 또는 merge에 따른 비용을 줄일 수 있다. 보통 제품이 나올 때면 작업하는 code의 기반이 upstream으로 최소 1년 최대 2년정도 차이가 생긴다. 이는 엄청난 차이인데, 나중에 upstream에서 code를 다시 가져올 때, 이미 상품화에 적용된 patch가 upstream에 반영되어 있다면 그 만큼 작업이 쉬워질 것이다.

세번째, code가 죽는 것을 방지
사실 개발자에게 상품화 이후 만들어진 patch를 upstream할 시간적 여유는 주어지지 않는 경우가 많다. 바로 다음 프로젝트에 투입되거나 다른 일을 맡기도 한다. 이런 경우, patch는 죽은 code가 되어 버리고 최소한 License 규약을 지키기 위해 tarball로 묶여서 인터넷 어딘가를 떠돌게 된다. 최악의 경우, 다음 상품화 버전에 다른 개발자가 똑같은 patch를 만드는 경우도 발생할 수 있다.

네번째, 특정 feature 또는 module에 관해 ownership확보 가능
작성한 patch의 규모가 큰 경우, ownership을 가지고 지속적으로 maintain도 가능하다. 이런 경우 자사 상품화 최적화도 할 수 있고 개발 방향을 이끌 수 있다.

그렇다면 왜, upstream을 못하는가?

첫번째, 가장 큰 이유는 code 공개에 따른 체질적 두려움이 있다.
회사 입장에서 비용들여 만든 code를 남이 쓴다는 것, 특히, 경쟁사가 쓰면 어떻게 하냐고 걱정 하는 경우가 많다. 설사 경쟁 회사가 쓰더라도 이미 우리는 상품화를 끝낸 후가 될 가능성이 높다. 그들 역시 upstream으로 부터 먼 code를 기반으로 제품을 개발하기 때문에 바로 해당 patch를 반영하기 어려울 수도 있고, 여러가지 기술적 검토를 안할 수 없기 때문에 patch가 공개된 이후 경쟁사가 이를 상품화 반영하기까지는 당연히 시간이 걸린다.

그리고, 우선 알아야할 것이 오픈소스 소프트웨어를 쓴다는 것이 경쟁사와의 차별화 요소가 아니라는 것이다. 소바자가 제품을 선택할 때, 리눅스 커널 버전 살피고 patch 내용을 살필 수 없다.  오픈소스 소프트웨어는 마치 3rd party에서 부품을 구매하듯이 누구나 공유하는 공공재라고 보면 된다. 기업의 오픈소스 참여는 공동 개발을 통해 개발 비용을 줄이는 것이 목적이지 경쟁사와의 차별화를 위한 것이 아니라는 것을 강조하고 싶다.

두번째, 너무 바쁘다.
최소한 개발자에게 upstream할 시간적 여유를 줘야 하는데, 상품화에 치여 그럴 여유를 주지 못하는 경우가 많다.

세번째, upstream process가 없다.
기업에서 code를 upstream할 때는 최소한의 process가 필요하다. 사소한 bug fix는 그냥해도 되지만, feature단위라면 IP 문제가 있는지도 확인할 필요가 있다. 다른 특허를 침해한다면 복잡한 특허 분쟁에 엮일 수 있기 때문이다. 주의할 점은 개발자에 또 하나의 업무가 아닌 upstream을 장려할 수 있는 process를 만들어야 한다.

Linux Kernel과 WebKit project는 여러 회사가 공동으로 개발에 참여하는 좋은 본보기이다. 살펴보면, contribution을 많이 하는 회사 제품이 당연히 시장에서도 잘 팔린다. 그 이유는 해당 소프트웨어를 더 잘 이해하는 개발자가 좋은 제품을 개발하기 때문이다. 예를 들어, 애플과 노키아를 제외한 모든 스마트폰 제조사가 똑같은 구글의 Android를 기반으로 스마트폰을 출시하고 있다. 하지만 삼성 제품이 독보적으로 잘 팔리고 있다. 이유를 살펴보면, 물론, 디자인도 중요하지만, 삼성이 Android 폰을 만드는 제조사 중에 Linux Kernel contribution을 제일 많이 하는 회사라는 사실은 우연이 아니다. 같은 Android에서 차별화가 가능한 부분은 Linux Kernel과 device driver가 가장 큰데, upstream 경험이 많은 Linux Kernel 개발자를 보유한 회사가 빠르고 안정적인 Android 폰을 만들 수 있는 것은 당연한 것이 아닌가 싶다.

이제 upstream은 선택이 아닌 기업의 경쟁력 확보를 위해 반드시 필요한 전략임을 깨달아야 한다.