前言

Chrome 浏览器经过多年的发展已经越来越好,也变成了我默认的浏览器,每次更新我都会紧跟其后,但在发布 71 版本时界面固定使用 Material Design 且无法改回原来的样子,社区对此有很大的异议,我对新的界面也是很不喜欢,圆弧的 Tab 实在太丑了,实在不符合我的审美。一直掌控 Chrome(Chromium) 的 Google 并没有回应,只看到 Chromium 的开发人员说已经不会改回原来的界面,为了安全建议更新到最新版本。

受不了 Chrome 新界面的我又用回了 Firefox,用了一段时间的 Firefox 发现在 MacOS 上 Firefox 耗电严重,我的 Macbook 电脑看两个小时视频就没电了,CPU 占用率也很高。搜了下发现这是个 BUG,Firefox 官方也知道,但是还没还没修复(据说现在 nightly 已经修复了)。

然后我就寻找其他方案,找了半天在 V2 上看到有人修改 Chromium 界面代码自己编译,那我也来试试,中间遇到不少问题,但是也最终编译成功有了下面的 Chromium(不要问我为什么跟 Chromium 心的 Edge 很像,Edge 没发布测试版我就已经改了,不过 Edge 正式发布又多了一个选择):

我对 Chromium 的标签、地址栏、 工具栏、书签栏这几个地方主要做了修改,并添加了 Google API Keys,使 Chromium 能使用 Google 云同步功能,除了因为没有签名无法使用 1password 之外功能上和 Chrome 无异。下面就讲讲怎么修改 Chromium 编译的。

获取 Chromium 源码

我这里是 MacOS 系统,不同系统方式不一样,具体操作查看 Chromium docs

Chromium 源码在https://chromium.googlesource.com/chromium/src.git,需要科学上网才能访问。

安装depot_tools

因为 Google 使用depot_tools管理 Chromium 代码依赖,所以需要先下载depot_tools

$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git

然后把depot_tools工具添加到$PATH环境变量中,执行命令:

$ export PATH="$PATH:/path/to/depot_tools"

或者添加到你的~/.bash_profile or ~/.zshrc

获取代码

创建chromium目录:

$ mkdir chromium && cd chromium

运行depot_tools中的fetch命令(已经添加到$PATH中):

$ fetch chromium

或者网络不好时不下载历史:

$ fetch chromium --no-history

因为 chromium 代码仓库很大,获取代码时一定要在一个非常好的网络环境里,并且科学上网工具也不能差,不然下载到一半断开功亏一篑。对 Git 比较熟的可以下载部分 History 再逐步下载全部代码。

同步代码

同步代码有两个作用,一个是同步当前 Chromium 代码到最新,一个是同步当前 Chromium 分支依赖的第三方库到指定的版本。 同步代码使用:

$ gclient sync

同步分支和 Tag 使用:

$ gclient sync --with_branch_heads --with_tags

每次切换分支后都需要使用同步代码命令来同步第三方依赖库。

从 release tag 构建

下载完代码不建议直接使用master进行构建,因为master分支是开发分支,bug 比较多,建议使用最新Chrome发布版本的分支。

# 同步所有 tag 信息
$ git fetch --tags
# 从 tag 创建新的构建 branch(查看所有 tag: git show-ref --tags)
$ git checkout -b build.78.0.3904.80 78.0.3904.80
# 切换分支后同步代码
$ gclient sync --with_branch_heads --with_tags

配置并编译

配置构建

Chromium 使用Ninja做构建工具,用gn命令生成构建的配置文件和目录:

$ gn gen out/Default

添加编译配置文件:out/Default/args.gn,主要加入了Release参数和多媒体支持。

# Set build arguments here. See `gn buildargs`.
is_official_build = true
blink_symbol_level = 0
chrome_pgo_phase = 0
current_cpu = "x64"
enable_google_now = false
enable_hotwording = false
enable_iterator_debugging = false
enable_nacl = true
ffmpeg_branding = "Chrome"
is_component_build = false
is_debug = false
proprietary_codecs = true
symbol_level = 0
target_cpu = "x64"
exclude_unwind_tables = true
remove_webcore_debug_symbols = true
enable_webrtc = true
rtc_use_h264 = true
rtc_use_lto = true
use_openh264 = true
enable_hangout_services_extension = true
enable_widevine = true
#icu_use_data_file = true
enable_hevc_demuxing = true
enable_ac3_eac3_audio_demuxing = true
enable_mse_mpeg2ts_stream_parser = true

编译

使用autoninja开始编译,如果使用的是配置较高的台式机几个小时或许可以编译完,如果是笔记本就要做好睡一觉才能编译完的准备,最重要的是要做好电脑散热

$ autoninja -C out/Default chrome

编译完成后运行 Chromium:

$ out/Default/Chromium.app/Contents/MacOS/Chromium

添加 Google API Keys

没有添加Google API Keys的浏览器是不能使用 Google 同步服务的,将下面的配置添加到out/Default/args.gn,重新编译后 Chromium 就能使用 Google 同步服务了。(下面的 API Keys 提取自 Chrome,也可以用 Google 帐号申请)

google_api_key = "AIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgw"
google_default_client_id = "77185425430.apps.googleusercontent.com"
google_default_client_secret = "OTJgUOQcT7lO7GsGZq2G4IlT"

修改代码重新编译

Tab

  • 去除 Tab 顶部 8px 的空白

    --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm
    +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm
    @@ -141,7 +141,7 @@ FullscreenToolbarStyle GetUserPreferredToolbarStyle(bool always_show) {
    
    // Mac seems to reserve 1 DIP of the top inset as a resize handle.
    constexpr int kResizeHandleHeight = 1;
    -  constexpr int kTabstripTopInset = 8;
    +  constexpr int kTabstripTopInset = 0;
    int top_inset = kTabstripTopInset;
    
  • Tab 圆角改直角

    --- a/chrome/browser/ui/views/tabs/tab_style_views.cc
    +++ b/chrome/browser/ui/views/tabs/tab_style_views.cc
    @@ -191,7 +191,7 @@ SkPath GM2TabStyle::GetPath(PathType path_type,
    
    // Calculate the corner radii. Note that corner radius is based on original
    // tab width (in DIP), not our new, scaled-and-aligned bounds.
    -  const float radius = GetTopCornerRadiusForWidth(tab_->width()) * scale;
    +  const float radius = GetTopCornerRadiusForWidth(tab_->width()) * scale / 4;
    float top_radius = radius;
    float bottom_radius = radius;
    
  • NewTabButton 改直角

    --- a/chrome/browser/ui/views/tabs/new_tab_button.cc
    +++ b/chrome/browser/ui/views/tabs/new_tab_button.cc
    @@ -186,9 +186,17 @@ void NewTabButton::PaintButtonContents(gfx::Canvas* canvas) {
    
    void NewTabButton::OnBoundsChanged(const gfx::Rect& previous_bounds) {
    ImageButton::OnBoundsChanged(previous_bounds);
    +
    +  SkPath path;
    +  const float radius = GetCornerRadius() / 4;
    +  path.addRoundRect(gfx::RectToSkRect(GetContentsBounds()), radius,
    +                     radius);
    SetProperty(
       views::kHighlightPathKey,
    -      new SkPath(GetBorderPath(GetContentsBounds().origin(), 1.0f, false)));
    +      new SkPath(path));
    +  // SetProperty(
    +  //     views::kHighlightPathKey,
    +  //     new SkPath(GetBorderPath(GetContentsBounds().origin(), 1.0f, false)));
    }
    

地址栏 / 工具栏

  • 地址栏框圆角改直角

    --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
    +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
    @@ -339,7 +339,7 @@ std::unique_ptr<views::Background> LocationBarView::CreateRoundRectBackground(
     SkColor stroke_color,
     SkBlendMode blend_mode,
     bool antialias) const {
    -  const int radius = GetBorderRadius();
    +  const int radius = GetBorderRadius() / 4;
    auto painter =
       stroke_color == SK_ColorTRANSPARENT
           ? views::Painter::CreateSolidRoundRectPainter(
    @@ -936,7 +936,7 @@ void LocationBarView::RefreshFocusRing() {
    
    // We may not have a usable path during initialization before first layout.
    // This will be called again once there is a usable path, so early exit.
    -  const int radius = GetBorderRadius();
    +  const int radius = GetBorderRadius() / 4;
    SkPath path;
    path.addRRect(
       SkRRect::MakeRectXY(RectToSkRect(GetLocalBounds()), radius, radius));
    
  • 地址栏内按钮改直角

    --- a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc
    +++ b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc
    @@ -505,7 +505,7 @@ void IconLabelBubbleView::UpdateHighlightPath() {
     highlight_bounds.Inset(0, 0, GetEndPaddingWithSeparator(), 0);
    highlight_bounds = GetMirroredRect(highlight_bounds);
    
    -  const float corner_radius = highlight_bounds.height() / 2.f;
    +  const float corner_radius = highlight_bounds.height() / 2.f / 4;
    const SkRect rect = RectToSkRect(highlight_bounds);
    
  • suggestions 切换 tab 按钮

    --- a/chrome/browser/ui/views/omnibox/omnibox_tab_switch_button.cc
    +++ b/chrome/browser/ui/views/omnibox/omnibox_tab_switch_button.cc
    @@ -55,7 +55,7 @@ OmniboxTabSwitchButton::OmniboxTabSwitchButton(
     SetText(hint_);
    }
    SetTooltipText(hint_);
    -  SetCornerRadius(kButtonHeight / 2.f);
    +  SetCornerRadius(kButtonHeight / 2.f / 4);
    animation_->SetSlideDuration(500);
    SetElideBehavior(gfx::FADE_TAIL);
    

书签栏

  • 书签栏按钮改成直角

    --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
    +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
    @@ -148,7 +148,7 @@ gfx::ImageSkia* GetImageSkiaNamed(int id) {
    void SetBookmarkHighlightPath(views::View* host_view) {
    auto path = std::make_unique<SkPath>();
    const int radius = ChromeLayoutProvider::Get()->GetCornerRadiusMetric(
    -      views::EMPHASIS_MAXIMUM, host_view->size());
    +      views::EMPHASIS_MAXIMUM, host_view->size()) / 4;
    path->addRoundRect(gfx::RectToSkRect(gfx::Rect(host_view->size())), radius,
                      radius);
    host_view->SetProperty(views::kHighlightPathKey, path.release());
    
  • 书签弹出框宽度调小

    --- a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc
    +++ b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc
    @@ -48,7 +48,7 @@ namespace {
    // Max width of a menu. There does not appear to be an OS value for this, yet
    // both IE and FF restrict the max width of a menu.
    -const int kMaxMenuWidth = 400;
    +const int kMaxMenuWidth = 240;
    
    SkColor TextColorForMenu(MenuItemView* menu, views::Widget* widget) {
    #if !defined(OS_MACOSX)
    

修改完上面的代码后重新编译,然后你就得到一个自己编译的定制界面的 Chromium!

Reference

  1. Chromium docs https://chromium.googlesource.com/chromium/src.git/+/HEAD/docs/README.md
  2. Working with Release Branches https://www.chromium.org/developers/how-tos/get-the-code/working-with-release-branches
  3. chromium src https://chromium.googlesource.com/chromium/src.git