Chromium源碼編譯和初步的代碼閱讀


起源

筆者有使用快捷鍵的習慣,相信不少人也都有在不同軟件上定制 HotKey 的需求。然而 Chrome 自帶的快捷鍵有些是不能改的,當使用 Chrome 連接遠程桌面開發調試軟件時,F1 ~ F12 功能鍵中有相當多是無法正常使用的。

  • 有些能通過 Chrome 腳本插件(如 tampermonkey)截斷按鍵的捕獲來解決沖突,有些則處理不了————例如 F11 這種瀏覽器標准中所要求的快捷鍵,優先級是很高的,無法從 js 的層面進行處理。
  • 當然了,第三方改鍵軟件也不失為一種簡單方便的 Workaround,但會影響到其他軟件,終究不是那么的優雅。

因此打算把 Chromium 源碼下載下來,直接修改快捷鍵的處理邏輯,將不需要的快捷鍵屏蔽掉。

代碼下載與編譯

Chromium 的下載最重要的就是 官方文檔。由於國內特殊的網絡環境,一些額外工作也是必不可少,貼一些我在解決問題的過程中搜到的感覺很有用的文檔:

另外,設置 --no-history 也是很重要的。一開始沒有設置,下載了 10G+ 的文件都才 60%,實在太慢。設置以后直接不到 1G 搞定。
此處記錄一個小坑,在 fetch chromium --no-history 的執行上報錯,提示 --no-history 參數錯誤,以為是命令行環境錯誤,一查官方文檔提醒使用 cmd,我使用的就是 cmd,沒辦法只能去改腳本了,修改 depot_tools/fetch.py

def handle_args(argv):
  """Gets the config name from the command line arguments."""
  if len(argv) <= 1:
    usage('Must specify a config.')
  if argv[1] in ('-h', '--help', 'help'):
    usage()

  dry_run = False
  nohooks = False
  no_history = True        // 修改此處
  force = False
  while len(argv) >= 2:
    arg = argv[1]
    if not arg.startswith('-'):
      break
    argv.pop(1)
    if arg in ('-n', '--dry-run'):
      dry_run = True
    elif arg == '--nohooks':
      nohooks = True
    elif arg == '--no-history':
      no_history = True
    elif arg == '--force':
      force = True
    else:
      usage('Invalid option %s.' % arg)

代碼下載完成后就是漫長的編譯了: autoninja -C out\Default chrome
i5 7500的 CPU,16g 內存,默認開啟 6 個進程,總耗時約 6 個小時。

修改代碼

首先還是官方文檔,大概掃了一遍,對主要的幾個工程有一定的了解,其他的先暫時不管,畢竟好幾千個工程,估計代碼能看好幾年... 全看是不現實了,直指目標,搜索關鍵詞 "F11" 看一下,直接出來幾百個搜索結果,而且文件太多了,搜索一直停不下來。將搜索停掉,忽略 ".html", ".js", ".xtb", ".inc", "*unittest.cc" 等可能與主程序邏輯不相關的搜索結果,從文件名開始掃視,fullscreen_control_host.cc 進入眼簾,打開該文件及其頭文件,原來是全屏狀態下顯示退出的 "X" 圖標。

繼續找,搜索了若干相似的關鍵詞,都沒有想要的結果,好吧看來找捷徑失敗,滾回去乖乖看文檔。
Life of a "mouse click" message: 演示了鼠標事件從 browser 到 renderer 的流程。emm,貌似 mouse 事件跟 keyboard 事件處理流程是類似的,這個沒准可行!

  • 找到關鍵類 RenderWidgetHostViewWin,去代碼中搜一搜,竟然沒有,難道這個文件沒有被 VS 收錄?先去 Google 一下 RenderWidgetHostViewWin site:chromium.googlesource.com,得到結果 render_widget_host_view_win.h,這個文件貌似在最新版本沒有了。
  • 既然官方文檔沒有及時更新,那就換個思路,從功能的名稱來搜索。"F11" 對應的是全屏開關,果然,通過 "fullscreen" 關鍵詞找到了 fullscreen_control.cc,其中有兩個相關的方法:
void FullscreenController::ExitFullscreenModeInternal();
void FullscreenController::ExitFullscreenModeForTab(WebContents* web_contents);

根據之前文檔中的描述,Tab-initiated 是由 Flash 或 Api 調用產生的全屏,那剩下的只有 ExitFullscreenModeInternal,進去加斷點,在按 "F11" 退出全屏狀態時成功觸發斷點。

找到切入點后,閱讀上下文的代碼就不會如無頭蒼蠅一般了。

修改代碼,編譯,運行,測試快捷鍵,如預期被修改成功!(此處還是要吐槽一下 chromium 的編譯,哪怕只改了一個模塊,增量編譯也要接近 10 分鍾,吃掉 5g 的內存)

暫告段落

一番折騰,周末也快過去了...但是在 Chromium 源碼的閱讀過程中,還是能發現不少設計模式的影子。作為一款大型桌面軟件,它對軟件模塊的分層也值得學習,特別是插件的設計,還有 web 頁面的渲染機制是什么樣的(例如之前做 WPF 表格控件的時候,無法做到靈活的樣式,而 HTML 中 <table> 能輕松做出合並單元格的樣式),以后有時間再進一步研究。


update: 找到個文檔:Chromium中文文檔,對入門還是有些幫助的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM