public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/chromium] epel9-next: - add qt6 linuxui backend
@ 2026-08-07 16:05 Than Ngo
  0 siblings, 0 replies; only message in thread
From: Than Ngo @ 2026-08-07 16:05 UTC (permalink / raw)
  To: git-commits

            A new commit has been pushed.

            Repo   : rpms/chromium
            Branch : epel9-next
            Commit : 802b55bba2b87f236e24c2ef0dbc6a8143eaac29
            Author : Than Ngo <than@redhat.com>
            Date   : 2023-05-28T10:09:21+02:00
            Stats  : +1153/-2 in 4 file(s)
            URL    : https://src.fedoraproject.org/rpms/chromium/c/802b55bba2b87f236e24c2ef0dbc6a8143eaac29?branch=epel9-next

            Log:
            - add qt6 linuxui backend
- backport: handle scale factor changes
- backport: fix font double_scaling

---
diff --git a/chromium-114-add_qt6_linuxui_backend.patch b/chromium-114-add_qt6_linuxui_backend.patch
new file mode 100644
index 0000000..fef2714
--- /dev/null
+++ b/chromium-114-add_qt6_linuxui_backend.patch
@@ -0,0 +1,545 @@
+commit 75f4b48eb71d4872ba3ac6c9fc3662a60eb4175d
+Author: Tom Anderson <thomasanderson@chromium.org>
+Date:   Thu Apr 27 02:21:34 2023 +0000
+
+    Add QT6 LinuxUi backend
+    
+    - Enable QT6 by default on KDE6
+    - If QT6 load fails, fallback to QT5 (and vice versa)
+    - Add use_qt6 build flag for packager control
+    - Add --qt-version runtime flag for user control
+    
+    R=thestig
+    
+    Change-Id: Ib1d9f6183663ecf7b9ddfe9d7f3e3442e534ccda
+    Fixed: 1434754
+    Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4475369
+    Commit-Queue: Thomas Anderson <thomasanderson@chromium.org>
+    Reviewed-by: Lei Zhang <thestig@chromium.org>
+    Cr-Commit-Position: refs/heads/main@{#1136295}
+
+diff --git a/chrome/installer/linux/BUILD.gn b/chrome/installer/linux/BUILD.gn
+index 5639b9ffc996e..3bacd3398d4a2 100644
+--- a/chrome/installer/linux/BUILD.gn
++++ b/chrome/installer/linux/BUILD.gn
+@@ -109,6 +109,9 @@ if (use_qt) {
+   # to prevent a hard dependency on QT for the package.
+   packaging_files += [ "$root_out_dir/libqt5_shim.so" ]
+ }
++if (use_qt6) {
++  packaging_files += [ "$root_out_dir/libqt6_shim.so" ]
++}
+ 
+ action_foreach("calculate_deb_dependencies") {
+   deps = [ ":installer_deps" ]
+@@ -249,6 +252,12 @@ if (use_qt) {
+     deps = [ "//ui/qt:qt5_shim" ]
+   }
+ }
++if (use_qt6) {
++  strip_binary("strip_qt6_shim") {
++    binary_input = "$root_out_dir/libqt6_shim.so"
++    deps = [ "//ui/qt:qt6_shim" ]
++  }
++}
+ 
+ # This target builds all "normal" Linux installers.  You must set
+ # is_component_build=false before building this target.
+@@ -447,6 +456,12 @@ group("installer_deps") {
+       "//ui/qt:qt5_shim",
+     ]
+   }
++  if (use_qt6) {
++    public_deps += [
++      ":strip_qt6_shim",
++      "//ui/qt:qt6_shim",
++    ]
++  }
+ }
+ 
+ # Creates .deb and .rpm (RPM for non-ChromeOS only) installer packages.
+diff --git a/chrome/installer/linux/common/installer.include b/chrome/installer/linux/common/installer.include
+index 8d76f1f280b01..439ef5ccb0f52 100644
+--- a/chrome/installer/linux/common/installer.include
++++ b/chrome/installer/linux/common/installer.include
+@@ -254,6 +254,11 @@ stage_install_common() {
+     strippedfile="${OUTPUTDIR}/${file}.stripped"
+     install -m ${SHLIB_PERMS} "${strippedfile}" "${STAGEDIR}/${INSTALLDIR}/${file}"
+   fi
++  if [ -f "${OUTPUTDIR}/libqt6_shim.so" ]; then
++    file="libqt6_shim.so"
++    strippedfile="${OUTPUTDIR}/${file}.stripped"
++    install -m ${SHLIB_PERMS} "${strippedfile}" "${STAGEDIR}/${INSTALLDIR}/${file}"
++  fi
+ 
+   # libc++
+   if [ -f "${OUTPUTDIR}/lib/libc++.so" ]; then
+diff --git a/ui/qt/BUILD.gn b/ui/qt/BUILD.gn
+index bbede00daa4d0..6a67961edc2f7 100644
+--- a/ui/qt/BUILD.gn
++++ b/ui/qt/BUILD.gn
+@@ -11,13 +11,6 @@ assert(use_qt)
+ assert(is_linux)
+ assert(!is_castos)
+ 
+-pkg_config("qt5_config") {
+-  packages = [
+-    "Qt5Core",
+-    "Qt5Widgets",
+-  ]
+-}
+-
+ config("qt_internal_config") {
+   if (is_clang) {
+     # libstdc++ headers are incompatible with -fcomplete-member-pointers.
+@@ -56,40 +49,57 @@ if (!use_sysroot) {
+   }
+ }
+ 
+-shared_library("qt5_shim") {
+-  visibility = [
+-    ":qt",
+-    "//chrome/installer/linux:*",
+-  ]
+-
+-  # Since qt_shim is a shared library even in non-component builds, it shouldn't
+-  # depend on any other targets since that would duplicate code between binaries
+-  # leading to increased size and potential issues from duplicated global state.
+-  no_default_deps = true
+-  assert_no_deps = [
+-    "//base",
+-    "//buildtools/third_party/libc++",
+-  ]
+-  deps = [ ":qt_interface" ]
+-
+-  configs -= [ "//build/config/compiler:runtime_library" ]
+-  configs += [
+-    ":qt_internal_config",
+-    ":qt5_config",
+-  ]
++template("qt_shim") {
++  pkg_config("qt" + invoker.qt_version + "_config") {
++    packages = [
++      "Qt" + invoker.qt_version + "Core",
++      "Qt" + invoker.qt_version + "Widgets",
++    ]
++  }
+ 
+-  public = []
+-  sources = [
+-    "qt_shim.cc",
+-    "qt_shim.h",
+-  ]
+-  if (use_sysroot) {
+-    # This file is generated with gen_qt_shim_moc.sh on an amd64 system to
+-    # avoid a build-time dependency on `moc` when using the sysroot.
+-    sources += [ "qt_shim_moc.cc" ]
+-  } else {
+-    sources += get_target_outputs(":generate_moc")
+-    deps += [ ":generate_moc" ]
++  shared_library(target_name) {
++    visibility = [
++      ":qt",
++      "//chrome/installer/linux:*",
++    ]
++
++    # Since qt_shim is a shared library even in non-component builds, it shouldn't
++    # depend on any other targets since that would duplicate code between binaries
++    # leading to increased size and potential issues from duplicated global state.
++    no_default_deps = true
++    assert_no_deps = [
++      "//base",
++      "//buildtools/third_party/libc++",
++    ]
++    deps = [ ":qt_interface" ]
++
++    configs -= [ "//build/config/compiler:runtime_library" ]
++    configs += [
++      ":qt_internal_config",
++      ":qt" + invoker.qt_version + "_config",
++    ]
++
++    public = []
++    sources = [
++      "qt_shim.cc",
++      "qt_shim.h",
++    ]
++    if (use_sysroot) {
++      # This file is generated with gen_qt_shim_moc.sh on an amd64 system to
++      # avoid a build-time dependency on `moc` when using the sysroot.
++      sources += [ "qt" + invoker.qt_version + "_shim_moc.cc" ]
++    } else {
++      sources += get_target_outputs(":generate_moc")
++      deps += [ ":generate_moc" ]
++    }
++  }
++}
++qt_shim("qt5_shim") {
++  qt_version = "5"
++}
++if (use_qt6) {
++  qt_shim("qt6_shim") {
++    qt_version = "6"
+   }
+ }
+ 
+@@ -100,6 +110,9 @@ component("qt") {
+ 
+   # qt_shim is in data_deps since we want to load it manually.
+   data_deps = [ ":qt5_shim" ]
++  if (use_qt6) {
++    data_deps += [ ":qt6_shim" ]
++  }
+   deps = [
+     ":qt_interface",
+     "//base",
+diff --git a/ui/qt/gen_qt_shim_moc.sh b/ui/qt/gen_qt_shim_moc.sh
+index 74272d5611dab..9d02c2dfcb12f 100755
+--- a/ui/qt/gen_qt_shim_moc.sh
++++ b/ui/qt/gen_qt_shim_moc.sh
+@@ -6,11 +6,15 @@
+ set -o nounset
+ set -o errexit
+ 
+-URL="http://archive.debian.org/debian/pool/main/q/qtbase-opensource-src"
+-PACKAGE="qtbase5-dev-tools_5.3.2+dfsg-4+deb8u2_amd64.deb"
+-SHA256="7703754f2c230ce6b8b6030b6c1e7e030899aa9f45a415498df04bd5ec061a76"
+-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
++URL5="http://archive.debian.org/debian/pool/main/q/qtbase-opensource-src"
++PACKAGE5="qtbase5-dev-tools_5.3.2+dfsg-4+deb8u2_amd64.deb"
++SHA256_5="7703754f2c230ce6b8b6030b6c1e7e030899aa9f45a415498df04bd5ec061a76"
++
++URL6="http://archive.ubuntu.com/ubuntu/pool/universe/q/qt6-base"
++PACKAGE6="qt6-base-dev-tools_6.2.4+dfsg-2ubuntu1_amd64.deb"
++SHA256_6="8dddfc79e7743185b07c478ca0f96a4ccc13d48ecccc42f44d2578c33c7d9b8b"
+ 
++SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+ TMP_DIR=$(mktemp -d -p "$SCRIPT_DIR")
+ function cleanup {
+     rm -rf "$TMP_DIR"
+@@ -18,16 +22,22 @@ function cleanup {
+ trap cleanup EXIT
+ 
+ cd "$TMP_DIR"
+-wget "$URL/$PACKAGE"
+-echo "$SHA256  $PACKAGE" | shasum -a 256 -c
+-dpkg -x "$PACKAGE" .
+-cat > ../qt_shim_moc.cc <<EOF
+-// Copyright 2022 The Chromium Authors
++wget "$URL5/$PACKAGE5"
++echo "$SHA256_5  $PACKAGE5" | shasum -a 256 -c
++dpkg -x "$PACKAGE5" .
++wget "$URL6/$PACKAGE6"
++echo "$SHA256_6  $PACKAGE6" | shasum -a 256 -c
++dpkg -x "$PACKAGE6" .
++cat > ../qt5_shim_moc.cc <<EOF
++// Copyright 2023 The Chromium Authors
+ // Use of this source code is governed by a BSD-style license that can be
+ // found in the LICENSE file.
+ 
+ EOF
+ cd "$SCRIPT_DIR/../.."
++cp ui/qt/qt5_shim_moc.cc ui/qt/qt6_shim_moc.cc
+ "$TMP_DIR/usr/lib/x86_64-linux-gnu/qt5/bin/moc" ui/qt/qt_shim.h \
+-    >> ui/qt/qt_shim_moc.cc
+-git cl format ui/qt/qt_shim_moc.cc
++    >> ui/qt/qt5_shim_moc.cc
++"$TMP_DIR//usr/lib/qt6/libexec/moc" ui/qt/qt_shim.h \
++    >> ui/qt/qt6_shim_moc.cc
++git cl format ui/qt/qt5_shim_moc.cc ui/qt/qt6_shim_moc.cc
+diff --git a/ui/qt/qt.gni b/ui/qt/qt.gni
+index 27bb6375880b7..f45823270cb91 100644
+--- a/ui/qt/qt.gni
++++ b/ui/qt/qt.gni
+@@ -4,9 +4,17 @@
+ 
+ import("//build/config/chromecast_build.gni")
+ import("//build/config/sanitizers/sanitizers.gni")
++import("//build/config/sysroot.gni")
+ 
+ declare_args() {
+   # TODO(https://crbug.com/1424435): Allow QT in MSAN builds once QT is
+   # added to the instrumented libraries.
+   use_qt = is_linux && !is_castos && !is_msan
+ }
++
++declare_args() {
++  use_qt6 = use_qt && use_sysroot
++}
++
++# use_qt6 => use_qt
++assert(!use_qt6 || use_qt)
+diff --git a/ui/qt/qt_shim_moc.cc b/ui/qt/qt5_shim_moc.cc
+similarity index 95%
+rename from ui/qt/qt_shim_moc.cc
+rename to ui/qt/qt5_shim_moc.cc
+index dafbfadce56ba..8f8b6b57784a8 100644
+--- a/ui/qt/qt_shim_moc.cc
++++ b/ui/qt/qt5_shim_moc.cc
+@@ -1,4 +1,4 @@
+-// Copyright 2022 The Chromium Authors
++// Copyright 2023 The Chromium Authors
+ // Use of this source code is governed by a BSD-style license that can be
+ // found in the LICENSE file.
+ 
+@@ -89,26 +89,32 @@ const QMetaObject* qt::QtShim::metaObject() const {
+ }
+ 
+ void* qt::QtShim::qt_metacast(const char* _clname) {
+-  if (!_clname)
++  if (!_clname) {
+     return 0;
+-  if (!strcmp(_clname, qt_meta_stringdata_qt__QtShim.stringdata))
++  }
++  if (!strcmp(_clname, qt_meta_stringdata_qt__QtShim.stringdata)) {
+     return static_cast<void*>(const_cast<QtShim*>(this));
+-  if (!strcmp(_clname, "QtInterface"))
++  }
++  if (!strcmp(_clname, "QtInterface")) {
+     return static_cast<QtInterface*>(const_cast<QtShim*>(this));
++  }
+   return QObject::qt_metacast(_clname);
+ }
+ 
+ int qt::QtShim::qt_metacall(QMetaObject::Call _c, int _id, void** _a) {
+   _id = QObject::qt_metacall(_c, _id, _a);
+-  if (_id < 0)
++  if (_id < 0) {
+     return _id;
++  }
+   if (_c == QMetaObject::InvokeMetaMethod) {
+-    if (_id < 2)
++    if (_id < 2) {
+       qt_static_metacall(this, _c, _id, _a);
++    }
+     _id -= 2;
+   } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
+-    if (_id < 2)
++    if (_id < 2) {
+       *reinterpret_cast<int*>(_a[0]) = -1;
++    }
+     _id -= 2;
+   }
+   return _id;
+diff --git a/ui/qt/qt6_shim_moc.cc b/ui/qt/qt6_shim_moc.cc
+new file mode 100644
+index 0000000000000..6d02ca317b65d
+--- /dev/null
++++ b/ui/qt/qt6_shim_moc.cc
+@@ -0,0 +1,143 @@
++// Copyright 2023 The Chromium Authors
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++/****************************************************************************
++** Meta object code from reading C++ file 'qt_shim.h'
++**
++** Created by: The Qt Meta Object Compiler version 68 (Qt 6.2.4)
++**
++** WARNING! All changes made in this file will be lost!
++*****************************************************************************/
++
++#include <QtCore/qbytearray.h>
++#include <QtCore/qmetatype.h>
++#include <memory>
++#include "ui/qt/qt_shim.h"
++#if !defined(Q_MOC_OUTPUT_REVISION)
++#error "The header file 'qt_shim.h' doesn't include <QObject>."
++#elif Q_MOC_OUTPUT_REVISION != 68
++#error "This file was generated using the moc from 6.2.4. It"
++#error "cannot be used with the include files from this version of Qt."
++#error "(The moc has changed too much.)"
++#endif
++
++QT_BEGIN_MOC_NAMESPACE
++QT_WARNING_PUSH
++QT_WARNING_DISABLE_DEPRECATED
++struct qt_meta_stringdata_qt__QtShim_t {
++  const uint offsetsAndSize[12];
++  char stringdata0[52];
++};
++#define QT_MOC_LITERAL(ofs, len) \
++  uint(offsetof(qt_meta_stringdata_qt__QtShim_t, stringdata0) + ofs), len
++static const qt_meta_stringdata_qt__QtShim_t qt_meta_stringdata_qt__QtShim = {
++    {
++        QT_MOC_LITERAL(0, 10),   // "qt::QtShim"
++        QT_MOC_LITERAL(11, 11),  // "FontChanged"
++        QT_MOC_LITERAL(23, 0),   // ""
++        QT_MOC_LITERAL(24, 4),   // "font"
++        QT_MOC_LITERAL(29, 14),  // "PaletteChanged"
++        QT_MOC_LITERAL(44, 7)    // "palette"
++
++    },
++    "qt::QtShim\0FontChanged\0\0font\0"
++    "PaletteChanged\0palette"};
++#undef QT_MOC_LITERAL
++
++static const uint qt_meta_data_qt__QtShim[] = {
++
++    // content:
++    10,     // revision
++    0,      // classname
++    0, 0,   // classinfo
++    2, 14,  // methods
++    0, 0,   // properties
++    0, 0,   // enums/sets
++    0, 0,   // constructors
++    0,      // flags
++    0,      // signalCount
++
++    // slots: name, argc, parameters, tag, flags, initial metatype offsets
++    1, 1, 26, 2, 0x08, 1 /* Private */, 4, 1, 29, 2, 0x08, 3 /* Private */,
++
++    // slots: parameters
++    QMetaType::Void, QMetaType::QFont, 3, QMetaType::Void, QMetaType::QPalette,
++    5,
++
++    0  // eod
++};
++
++void qt::QtShim::qt_static_metacall(QObject* _o,
++                                    QMetaObject::Call _c,
++                                    int _id,
++                                    void** _a) {
++  if (_c == QMetaObject::InvokeMetaMethod) {
++    auto* _t = static_cast<QtShim*>(_o);
++    (void)_t;
++    switch (_id) {
++      case 0:
++        _t->FontChanged((*reinterpret_cast<std::add_pointer_t<QFont>>(_a[1])));
++        break;
++      case 1:
++        _t->PaletteChanged(
++            (*reinterpret_cast<std::add_pointer_t<QPalette>>(_a[1])));
++        break;
++      default:;
++    }
++  }
++}
++
++const QMetaObject qt::QtShim::staticMetaObject = {
++    {QMetaObject::SuperData::link<QObject::staticMetaObject>(),
++     qt_meta_stringdata_qt__QtShim.offsetsAndSize, qt_meta_data_qt__QtShim,
++     qt_static_metacall, nullptr,
++     qt_incomplete_metaTypeArray<
++         qt_meta_stringdata_qt__QtShim_t,
++         QtPrivate::TypeAndForceComplete<QtShim, std::true_type>,
++         QtPrivate::TypeAndForceComplete<void, std::false_type>,
++         QtPrivate::TypeAndForceComplete<const QFont&, std::false_type>,
++         QtPrivate::TypeAndForceComplete<void, std::false_type>,
++         QtPrivate::TypeAndForceComplete<const QPalette&, std::false_type>
++
++         >,
++     nullptr}};
++
++const QMetaObject* qt::QtShim::metaObject() const {
++  return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject()
++                                    : &staticMetaObject;
++}
++
++void* qt::QtShim::qt_metacast(const char* _clname) {
++  if (!_clname) {
++    return nullptr;
++  }
++  if (!strcmp(_clname, qt_meta_stringdata_qt__QtShim.stringdata0)) {
++    return static_cast<void*>(this);
++  }
++  if (!strcmp(_clname, "QtInterface")) {
++    return static_cast<QtInterface*>(this);
++  }
++  return QObject::qt_metacast(_clname);
++}
++
++int qt::QtShim::qt_metacall(QMetaObject::Call _c, int _id, void** _a) {
++  _id = QObject::qt_metacall(_c, _id, _a);
++  if (_id < 0) {
++    return _id;
++  }
++  if (_c == QMetaObject::InvokeMetaMethod) {
++    if (_id < 2) {
++      qt_static_metacall(this, _c, _id, _a);
++    }
++    _id -= 2;
++  } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
++    if (_id < 2) {
++      *reinterpret_cast<QMetaType*>(_a[0]) = QMetaType();
++    }
++    _id -= 2;
++  }
++  return _id;
++}
++QT_WARNING_POP
++QT_END_MOC_NAMESPACE
+diff --git a/ui/qt/qt_ui.cc b/ui/qt/qt_ui.cc
+index d4052b7e8bc3d..6a3b58e9f930b 100644
+--- a/ui/qt/qt_ui.cc
++++ b/ui/qt/qt_ui.cc
+@@ -14,7 +14,9 @@
+ #include "base/check.h"
+ #include "base/command_line.h"
+ #include "base/compiler_specific.h"
++#include "base/environment.h"
+ #include "base/memory/raw_ptr.h"
++#include "base/nix/xdg_util.h"
+ #include "base/notreached.h"
+ #include "base/path_service.h"
+ #include "base/time/time.h"
+@@ -47,6 +49,45 @@ namespace qt {
+ 
+ namespace {
+ 
++const char kQtVersionFlag[] = "qt-version";
++
++void* LoadLibrary(const base::FilePath& path) {
++  return dlopen(path.value().c_str(), RTLD_NOW | RTLD_GLOBAL);
++}
++
++void* LoadLibraryOrFallback(const base::FilePath& path,
++                            const char* preferred,
++                            const char* fallback) {
++  if (void* library = LoadLibrary(path.Append(preferred))) {
++    return library;
++  }
++  return LoadLibrary(path.Append(fallback));
++}
++
++bool PreferQt6() {
++  auto* cmd = base::CommandLine::ForCurrentProcess();
++  if (cmd->HasSwitch(kQtVersionFlag)) {
++    std::string qt_version_string = cmd->GetSwitchValueASCII(kQtVersionFlag);
++    unsigned int qt_version = 0;
++    if (base::StringToUint(qt_version_string, &qt_version)) {
++      switch (qt_version) {
++        case 5:
++          return false;
++        case 6:
++          return true;
++        default:
++          LOG(ERROR) << "Unsupported QT version " << qt_version;
++      }
++    } else {
++      LOG(ERROR) << "Unable to parse QT version " << qt_version_string;
++    }
++  }
++
++  auto env = base::Environment::Create();
++  auto desktop = base::nix::GetDesktopEnvironment(env.get());
++  return desktop == base::nix::DESKTOP_ENVIRONMENT_KDE6;
++}
++
+ int QtWeightToCssWeight(int weight) {
+   struct {
+     int qt_weight;
+@@ -179,8 +220,10 @@ bool QtUi::Initialize() {
+   base::FilePath path;
+   if (!base::PathService::Get(base::DIR_MODULE, &path))
+     return false;
+-  path = path.Append("libqt5_shim.so");
+-  void* libqt_shim = dlopen(path.value().c_str(), RTLD_NOW | RTLD_GLOBAL);
++  void* libqt_shim =
++      PreferQt6()
++          ? LoadLibraryOrFallback(path, "libqt6_shim.so", "libqt5_shim.so")
++          : LoadLibraryOrFallback(path, "libqt5_shim.so", "libqt6_shim.so");
+   if (!libqt_shim)
+     return false;
+   void* create_qt_interface = dlsym(libqt_shim, "CreateQtInterface");

diff --git a/chromium-114-qt-fix_font_double_scaling.patch b/chromium-114-qt-fix_font_double_scaling.patch
new file mode 100644
index 0000000..9713ef6
--- /dev/null
+++ b/chromium-114-qt-fix_font_double_scaling.patch
@@ -0,0 +1,21 @@
+diff --git a/ui/qt/qt_ui.cc b/ui/qt/qt_ui.cc
+index bac5245a..a97fa8b 100644
+--- a/ui/qt/qt_ui.cc
++++ b/ui/qt/qt_ui.cc
+@@ -422,12 +422,14 @@
+   auto desc = shim_->GetFontDescription();
+ 
+   font_family_ = desc.family.c_str();
++  // Points are defined at 72 DPI and pixels are 96 DPI by default.
++  constexpr double kPointToPixelRatio = 96.0 / 72.0;
+   if (desc.size_pixels > 0) {
+     font_size_pixels_ = desc.size_pixels;
+-    font_size_points_ = font_size_pixels_ / GetDeviceScaleFactor();
++    font_size_points_ = std::round(font_size_pixels_ / kPointToPixelRatio);
+   } else {
+     font_size_points_ = desc.size_points;
+-    font_size_pixels_ = font_size_points_ * GetDeviceScaleFactor();
++    font_size_pixels_ = std::round(font_size_points_ * kPointToPixelRatio);
+   }
+   font_style_ = desc.is_italic ? gfx::Font::ITALIC : gfx::Font::NORMAL;
+   font_weight_ = QtWeightToCssWeight(desc.weight);

diff --git a/chromium-114-qt-handle_scale_factor_changes.patch b/chromium-114-qt-handle_scale_factor_changes.patch
new file mode 100644
index 0000000..d8fc72f
--- /dev/null
+++ b/chromium-114-qt-handle_scale_factor_changes.patch
@@ -0,0 +1,574 @@
+commit c51d6447fd0d124903d16bf5952efccbf9e1ca92
+Author: Tom Anderson <thomasanderson@chromium.org>
+Date:   Wed May 24 22:53:20 2023 +0000
+
+    [Qt] Handle scale factor changes
+    
+    This is a speculative fix for https://crbug.com/1439149.  I suspect
+    the scale factor is not set immediately on QT initialization, but
+    is set asynchronously shortly after.  This CL adds a listener for
+    QT scale changes.
+    
+    R=thestig
+    
+    Low-Coverage-Reason: No QT tests currently
+    Change-Id: I7dea23e16a6bb26237564af2dc4e43480f6aea9f
+    Bug: 1439149
+    Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4559732
+    Reviewed-by: Lei Zhang <thestig@chromium.org>
+    Commit-Queue: Thomas Anderson <thomasanderson@chromium.org>
+    Auto-Submit: Thomas Anderson <thomasanderson@chromium.org>
+    Cr-Commit-Position: refs/heads/main@{#1148805}
+
+diff --git a/ui/qt/qt5_shim_moc.cc b/ui/qt/qt5_shim_moc.cc
+index 8f8b6b57784a8..6e504f23c603a 100644
+--- a/ui/qt/qt5_shim_moc.cc
++++ b/ui/qt/qt5_shim_moc.cc
+@@ -23,8 +23,8 @@
+ 
+ QT_BEGIN_MOC_NAMESPACE
+ struct qt_meta_stringdata_qt__QtShim_t {
+-  QByteArrayData data[6];
+-  char stringdata[52];
++  QByteArrayData data[13];
++  char stringdata[151];
+ };
+ #define QT_MOC_LITERAL(idx, ofs, len)                                       \
+   Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(                  \
+@@ -33,9 +33,16 @@ struct qt_meta_stringdata_qt__QtShim_t {
+ static const qt_meta_stringdata_qt__QtShim_t qt_meta_stringdata_qt__QtShim = {
+     {QT_MOC_LITERAL(0, 0, 10), QT_MOC_LITERAL(1, 11, 11),
+      QT_MOC_LITERAL(2, 23, 0), QT_MOC_LITERAL(3, 24, 4),
+-     QT_MOC_LITERAL(4, 29, 14), QT_MOC_LITERAL(5, 44, 7)},
++     QT_MOC_LITERAL(4, 29, 14), QT_MOC_LITERAL(5, 44, 7),
++     QT_MOC_LITERAL(6, 52, 11), QT_MOC_LITERAL(7, 64, 8),
++     QT_MOC_LITERAL(8, 73, 6), QT_MOC_LITERAL(9, 80, 13),
++     QT_MOC_LITERAL(10, 94, 25), QT_MOC_LITERAL(11, 120, 3),
++     QT_MOC_LITERAL(12, 124, 26)},
+     "qt::QtShim\0FontChanged\0\0font\0"
+-    "PaletteChanged\0palette"};
++    "PaletteChanged\0palette\0ScreenAdded\0"
++    "QScreen*\0screen\0ScreenRemoved\0"
++    "LogicalDotsPerInchChanged\0dpi\0"
++    "PhysicalDotsPerInchChanged"};
+ #undef QT_MOC_LITERAL
+ 
+ static const uint qt_meta_data_qt__QtShim[] = {
+@@ -44,7 +51,7 @@ static const uint qt_meta_data_qt__QtShim[] = {
+     7,      // revision
+     0,      // classname
+     0, 0,   // classinfo
+-    2, 14,  // methods
++    6, 14,  // methods
+     0, 0,   // properties
+     0, 0,   // enums/sets
+     0, 0,   // constructors
+@@ -52,11 +59,15 @@ static const uint qt_meta_data_qt__QtShim[] = {
+     0,      // signalCount
+ 
+     // slots: name, argc, parameters, tag, flags
+-    1, 1, 24, 2, 0x08 /* Private */, 4, 1, 27, 2, 0x08 /* Private */,
++    1, 1, 44, 2, 0x08 /* Private */, 4, 1, 47, 2, 0x08 /* Private */, 6, 1, 50,
++    2, 0x08 /* Private */, 9, 1, 53, 2, 0x08 /* Private */, 10, 1, 56, 2,
++    0x08 /* Private */, 12, 1, 59, 2, 0x08 /* Private */,
+ 
+     // slots: parameters
+     QMetaType::Void, QMetaType::QFont, 3, QMetaType::Void, QMetaType::QPalette,
+-    5,
++    5, QMetaType::Void, 0x80000000 | 7, 8, QMetaType::Void, 0x80000000 | 7, 8,
++    QMetaType::Void, QMetaType::QReal, 11, QMetaType::Void, QMetaType::QReal,
++    11,
+ 
+     0  // eod
+ };
+@@ -74,6 +85,18 @@ void qt::QtShim::qt_static_metacall(QObject* _o,
+       case 1:
+         _t->PaletteChanged((*reinterpret_cast<const QPalette(*)>(_a[1])));
+         break;
++      case 2:
++        _t->ScreenAdded((*reinterpret_cast<QScreen*(*)>(_a[1])));
++        break;
++      case 3:
++        _t->ScreenRemoved((*reinterpret_cast<QScreen*(*)>(_a[1])));
++        break;
++      case 4:
++        _t->LogicalDotsPerInchChanged((*reinterpret_cast<qreal(*)>(_a[1])));
++        break;
++      case 5:
++        _t->PhysicalDotsPerInchChanged((*reinterpret_cast<qreal(*)>(_a[1])));
++        break;
+       default:;
+     }
+   }
+@@ -107,15 +130,15 @@ int qt::QtShim::qt_metacall(QMetaObject::Call _c, int _id, void** _a) {
+     return _id;
+   }
+   if (_c == QMetaObject::InvokeMetaMethod) {
+-    if (_id < 2) {
++    if (_id < 6) {
+       qt_static_metacall(this, _c, _id, _a);
+     }
+-    _id -= 2;
++    _id -= 6;
+   } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
+-    if (_id < 2) {
++    if (_id < 6) {
+       *reinterpret_cast<int*>(_a[0]) = -1;
+     }
+-    _id -= 2;
++    _id -= 6;
+   }
+   return _id;
+ }
+diff --git a/ui/qt/qt6_shim_moc.cc b/ui/qt/qt6_shim_moc.cc
+index 6d02ca317b65d..a16515008d892 100644
+--- a/ui/qt/qt6_shim_moc.cc
++++ b/ui/qt/qt6_shim_moc.cc
+@@ -26,8 +26,8 @@ QT_BEGIN_MOC_NAMESPACE
+ QT_WARNING_PUSH
+ QT_WARNING_DISABLE_DEPRECATED
+ struct qt_meta_stringdata_qt__QtShim_t {
+-  const uint offsetsAndSize[12];
+-  char stringdata0[52];
++  const uint offsetsAndSize[26];
++  char stringdata0[151];
+ };
+ #define QT_MOC_LITERAL(ofs, len) \
+   uint(offsetof(qt_meta_stringdata_qt__QtShim_t, stringdata0) + ofs), len
+@@ -38,11 +38,21 @@ static const qt_meta_stringdata_qt__QtShim_t qt_meta_stringdata_qt__QtShim = {
+         QT_MOC_LITERAL(23, 0),   // ""
+         QT_MOC_LITERAL(24, 4),   // "font"
+         QT_MOC_LITERAL(29, 14),  // "PaletteChanged"
+-        QT_MOC_LITERAL(44, 7)    // "palette"
++        QT_MOC_LITERAL(44, 7),   // "palette"
++        QT_MOC_LITERAL(52, 11),  // "ScreenAdded"
++        QT_MOC_LITERAL(64, 8),   // "QScreen*"
++        QT_MOC_LITERAL(73, 6),   // "screen"
++        QT_MOC_LITERAL(80, 13),  // "ScreenRemoved"
++        QT_MOC_LITERAL(94, 25),  // "LogicalDotsPerInchChanged"
++        QT_MOC_LITERAL(120, 3),  // "dpi"
++        QT_MOC_LITERAL(124, 26)  // "PhysicalDotsPerInchChanged"
+ 
+     },
+     "qt::QtShim\0FontChanged\0\0font\0"
+-    "PaletteChanged\0palette"};
++    "PaletteChanged\0palette\0ScreenAdded\0"
++    "QScreen*\0screen\0ScreenRemoved\0"
++    "LogicalDotsPerInchChanged\0dpi\0"
++    "PhysicalDotsPerInchChanged"};
+ #undef QT_MOC_LITERAL
+ 
+ static const uint qt_meta_data_qt__QtShim[] = {
+@@ -51,7 +61,7 @@ static const uint qt_meta_data_qt__QtShim[] = {
+     10,     // revision
+     0,      // classname
+     0, 0,   // classinfo
+-    2, 14,  // methods
++    6, 14,  // methods
+     0, 0,   // properties
+     0, 0,   // enums/sets
+     0, 0,   // constructors
+@@ -59,11 +69,15 @@ static const uint qt_meta_data_qt__QtShim[] = {
+     0,      // signalCount
+ 
+     // slots: name, argc, parameters, tag, flags, initial metatype offsets
+-    1, 1, 26, 2, 0x08, 1 /* Private */, 4, 1, 29, 2, 0x08, 3 /* Private */,
++    1, 1, 50, 2, 0x08, 1 /* Private */, 4, 1, 53, 2, 0x08, 3 /* Private */, 6,
++    1, 56, 2, 0x08, 5 /* Private */, 9, 1, 59, 2, 0x08, 7 /* Private */, 10, 1,
++    62, 2, 0x08, 9 /* Private */, 12, 1, 65, 2, 0x08, 11 /* Private */,
+ 
+     // slots: parameters
+     QMetaType::Void, QMetaType::QFont, 3, QMetaType::Void, QMetaType::QPalette,
+-    5,
++    5, QMetaType::Void, 0x80000000 | 7, 8, QMetaType::Void, 0x80000000 | 7, 8,
++    QMetaType::Void, QMetaType::QReal, 11, QMetaType::Void, QMetaType::QReal,
++    11,
+ 
+     0  // eod
+ };
+@@ -83,6 +97,22 @@ void qt::QtShim::qt_static_metacall(QObject* _o,
+         _t->PaletteChanged(
+             (*reinterpret_cast<std::add_pointer_t<QPalette>>(_a[1])));
+         break;
++      case 2:
++        _t->ScreenAdded(
++            (*reinterpret_cast<std::add_pointer_t<QScreen*>>(_a[1])));
++        break;
++      case 3:
++        _t->ScreenRemoved(
++            (*reinterpret_cast<std::add_pointer_t<QScreen*>>(_a[1])));
++        break;
++      case 4:
++        _t->LogicalDotsPerInchChanged(
++            (*reinterpret_cast<std::add_pointer_t<qreal>>(_a[1])));
++        break;
++      case 5:
++        _t->PhysicalDotsPerInchChanged(
++            (*reinterpret_cast<std::add_pointer_t<qreal>>(_a[1])));
++        break;
+       default:;
+     }
+   }
+@@ -98,7 +128,15 @@ const QMetaObject qt::QtShim::staticMetaObject = {
+          QtPrivate::TypeAndForceComplete<void, std::false_type>,
+          QtPrivate::TypeAndForceComplete<const QFont&, std::false_type>,
+          QtPrivate::TypeAndForceComplete<void, std::false_type>,
+-         QtPrivate::TypeAndForceComplete<const QPalette&, std::false_type>
++         QtPrivate::TypeAndForceComplete<const QPalette&, std::false_type>,
++         QtPrivate::TypeAndForceComplete<void, std::false_type>,
++         QtPrivate::TypeAndForceComplete<QScreen*, std::false_type>,
++         QtPrivate::TypeAndForceComplete<void, std::false_type>,
++         QtPrivate::TypeAndForceComplete<QScreen*, std::false_type>,
++         QtPrivate::TypeAndForceComplete<void, std::false_type>,
++         QtPrivate::TypeAndForceComplete<qreal, std::false_type>,
++         QtPrivate::TypeAndForceComplete<void, std::false_type>,
++         QtPrivate::TypeAndForceComplete<qreal, std::false_type>
+ 
+          >,
+      nullptr}};
+@@ -127,15 +165,15 @@ int qt::QtShim::qt_metacall(QMetaObject::Call _c, int _id, void** _a) {
+     return _id;
+   }
+   if (_c == QMetaObject::InvokeMetaMethod) {
+-    if (_id < 2) {
++    if (_id < 6) {
+       qt_static_metacall(this, _c, _id, _a);
+     }
+-    _id -= 2;
++    _id -= 6;
+   } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
+-    if (_id < 2) {
++    if (_id < 6) {
+       *reinterpret_cast<QMetaType*>(_a[0]) = QMetaType();
+     }
+-    _id -= 2;
++    _id -= 6;
+   }
+   return _id;
+ }
+diff --git a/ui/qt/qt_interface.h b/ui/qt/qt_interface.h
+index 6a362bc66c0e3..28dfc6603544f 100644
+--- a/ui/qt/qt_interface.h
++++ b/ui/qt/qt_interface.h
+@@ -118,6 +118,7 @@ class QtInterface {
+ 
+     virtual void FontChanged() = 0;
+     virtual void ThemeChanged() = 0;
++    virtual void ScaleFactorMaybeChanged() = 0;
+   };
+ 
+   QtInterface() = default;
+diff --git a/ui/qt/qt_shim.cc b/ui/qt/qt_shim.cc
+index 74d34ad196f18..0aec9c3aed4ad 100644
+--- a/ui/qt/qt_shim.cc
++++ b/ui/qt/qt_shim.cc
+@@ -16,6 +16,7 @@
+ #include <QMimeType>
+ #include <QPainter>
+ #include <QPalette>
++#include <QScreen>
+ #include <QStyle>
+ #include <QStyleOptionTitleBar>
+ 
+@@ -52,8 +53,9 @@ FontHinting QtHintingToFontHinting(QFont::HintingPreference hinting) {
+ // Obtain the average color of a gradient.
+ SkColor GradientColor(const QGradient& gradient) {
+   QGradientStops stops = gradient.stops();
+-  if (stops.empty())
++  if (stops.empty()) {
+     return qRgba(0, 0, 0, 0);
++  }
+ 
+   float a = 0;
+   float r = 0;
+@@ -86,11 +88,13 @@ SkColor GradientColor(const QGradient& gradient) {
+ // Obtain the average color of a texture.
+ SkColor TextureColor(QImage image) {
+   size_t size = image.width() * image.height();
+-  if (!size)
++  if (!size) {
+     return qRgba(0, 0, 0, 0);
++  }
+ 
+-  if (image.format() != QImage::Format_ARGB32_Premultiplied)
++  if (image.format() != QImage::Format_ARGB32_Premultiplied) {
+     image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
++  }
+ 
+   size_t a = 0;
+   size_t r = 0;
+@@ -203,6 +207,13 @@ QtShim::QtShim(QtInterface::Delegate* delegate, int* argc, char** argv)
+           SLOT(FontChanged(const QFont&)));
+   connect(&app_, SIGNAL(paletteChanged(const QPalette&)), this,
+           SLOT(PaletteChanged(const QPalette&)));
++  connect(&app_, SIGNAL(screenAdded(QScreen*)), this,
++          SLOT(ScreenAdded(QScreen*)));
++  connect(&app_, SIGNAL(screenRemoved(QScreen*)), this,
++          SLOT(ScreenRemoved(QScreen*)));
++  for (QScreen* screen : app_.screens()) {
++    ScreenAdded(screen);
++  }
+ }
+ 
+ QtShim::~QtShim() = default;
+@@ -241,8 +252,9 @@ Image QtShim::GetIconForContentType(const String& content_type,
+       auto icon = QIcon::fromTheme(name);
+       auto pixmap = icon.pixmap(size);
+       auto image = pixmap.toImage();
+-      if (image.format() != QImage::Format_ARGB32_Premultiplied)
++      if (image.format() != QImage::Format_ARGB32_Premultiplied) {
+         image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
++      }
+       if (auto bytes = image.sizeInBytes()) {
+         return {image.width(), image.height(),
+                 static_cast<float>(image.devicePixelRatio()),
+@@ -283,6 +295,30 @@ void QtShim::PaletteChanged(const QPalette& palette) {
+   delegate_->ThemeChanged();
+ }
+ 
++DISABLE_CFI_VCALL
++void QtShim::ScreenAdded(QScreen* screen) {
++  connect(screen, SIGNAL(logicalDotsPerInchChanged(qreal)), this,
++          SLOT(LogicalDotsPerInchChanged(qreal)));
++  connect(screen, SIGNAL(physicalDotsPerInchChanged(qreal)), this,
++          SLOT(PhysicalDotsPerInchChanged(qreal)));
++  delegate_->ScaleFactorMaybeChanged();
++}
++
++DISABLE_CFI_VCALL
++void QtShim::ScreenRemoved(QScreen* screen) {
++  delegate_->ScaleFactorMaybeChanged();
++}
++
++DISABLE_CFI_VCALL
++void QtShim::LogicalDotsPerInchChanged(qreal dpi) {
++  delegate_->ScaleFactorMaybeChanged();
++}
++
++DISABLE_CFI_VCALL
++void QtShim::PhysicalDotsPerInchChanged(qreal dpi) {
++  delegate_->ScaleFactorMaybeChanged();
++}
++
+ Image QtShim::DrawHeader(int width,
+                          int height,
+                          SkColor default_color,
+@@ -309,8 +345,9 @@ QImage QtShim::DrawHeaderImpl(int width,
+     QStyleOptionTitleBar opt;
+     opt.rect = QRect(-kBorderWidth, -kBorderWidth, width + 2 * kBorderWidth,
+                      height + 2 * kBorderWidth);
+-    if (state == ColorState::kNormal)
++    if (state == ColorState::kNormal) {
+       opt.titleBarState = QStyle::State_Active;
++    }
+     app_.style()->drawComplexControl(QStyle::CC_TitleBar, &opt, &painter,
+                                      nullptr);
+   } else {
+diff --git a/ui/qt/qt_shim.h b/ui/qt/qt_shim.h
+index 607e6fe22dfc0..d979c47d589d4 100644
+--- a/ui/qt/qt_shim.h
++++ b/ui/qt/qt_shim.h
+@@ -42,6 +42,10 @@ class QtShim : public QObject, public QtInterface {
+  private slots:
+   void FontChanged(const QFont& font);
+   void PaletteChanged(const QPalette& palette);
++  void ScreenAdded(QScreen* screen);
++  void ScreenRemoved(QScreen* screen);
++  void LogicalDotsPerInchChanged(qreal dpi);
++  void PhysicalDotsPerInchChanged(qreal dpi);
+ 
+  private:
+   QImage DrawHeaderImpl(int width,
+diff --git a/ui/qt/qt_ui.cc b/ui/qt/qt_ui.cc
+index 6a3b58e9f930b..bac5245a069f9 100644
+--- a/ui/qt/qt_ui.cc
++++ b/ui/qt/qt_ui.cc
+@@ -19,6 +19,7 @@
+ #include "base/nix/xdg_util.h"
+ #include "base/notreached.h"
+ #include "base/path_service.h"
++#include "base/task/single_thread_task_runner.h"
+ #include "base/time/time.h"
+ #include "cc/paint/paint_canvas.h"
+ #include "chrome/browser/themes/theme_properties.h"  // nogncheck
+@@ -36,6 +37,7 @@
+ #include "ui/gfx/image/image.h"
+ #include "ui/gfx/image/image_skia_rep.h"
+ #include "ui/gfx/image/image_skia_source.h"
++#include "ui/linux/device_scale_factor_observer.h"
+ #include "ui/linux/linux_ui.h"
+ #include "ui/linux/nav_button_provider.h"
+ #include "ui/native_theme/native_theme_aura.h"
+@@ -194,16 +196,21 @@ void QtUi::GetDefaultFontDescription(std::string* family_out,
+                                      int* style_out,
+                                      int* weight_out,
+                                      gfx::FontRenderParams* params_out) const {
+-  if (family_out)
++  if (family_out) {
+     *family_out = font_family_;
+-  if (size_pixels_out)
++  }
++  if (size_pixels_out) {
+     *size_pixels_out = font_size_pixels_;
+-  if (style_out)
++  }
++  if (style_out) {
+     *style_out = font_style_;
+-  if (weight_out)
++  }
++  if (weight_out) {
+     *weight_out = font_weight_;
+-  if (params_out)
++  }
++  if (params_out) {
+     *params_out = font_params_;
++  }
+ }
+ 
+ ui::SelectFileDialog* QtUi::CreateSelectFileDialog(
+@@ -236,6 +245,7 @@ bool QtUi::Initialize() {
+   ui::ColorProviderManager::Get().AppendColorProviderInitializer(
+       base::BindRepeating(&QtUi::AddNativeColorMixer, base::Unretained(this)));
+   FontChanged();
++  scale_factor_ = shim_->GetScaleFactor();
+ 
+   return true;
+ }
+@@ -246,8 +256,9 @@ ui::NativeTheme* QtUi::GetNativeTheme() const {
+ 
+ bool QtUi::GetColor(int id, SkColor* color, bool use_custom_frame) const {
+   auto value = GetColor(id, use_custom_frame);
+-  if (value)
++  if (value) {
+     *color = *value;
++  }
+   return value.has_value();
+ }
+ 
+@@ -297,8 +308,9 @@ gfx::Image QtUi::GetIconForContentType(const std::string& content_type,
+                                        float scale) const {
+   Image image =
+       shim_->GetIconForContentType(String(content_type.c_str()), size * scale);
+-  if (!image.data_argb.size())
++  if (!image.data_argb.size()) {
+     return {};
++  }
+ 
+   SkImageInfo image_info = SkImageInfo::Make(
+       image.width, image.height, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
+@@ -345,14 +357,16 @@ bool QtUi::AnimationsEnabled() const {
+ 
+ void QtUi::AddWindowButtonOrderObserver(
+     ui::WindowButtonOrderObserver* observer) {
+-  if (fallback_linux_ui_)
++  if (fallback_linux_ui_) {
+     fallback_linux_ui_->AddWindowButtonOrderObserver(observer);
++  }
+ }
+ 
+ void QtUi::RemoveWindowButtonOrderObserver(
+     ui::WindowButtonOrderObserver* observer) {
+-  if (fallback_linux_ui_)
++  if (fallback_linux_ui_) {
+     fallback_linux_ui_->RemoveWindowButtonOrderObserver(observer);
++  }
+ }
+ 
+ std::unique_ptr<ui::NavButtonProvider> QtUi::CreateNavButtonProvider() {
+@@ -441,11 +455,24 @@ void QtUi::ThemeChanged() {
+   native_theme_->ThemeChanged(PreferDarkTheme());
+ }
+ 
++void QtUi::ScaleFactorMaybeChanged() {
++  // This gets called whenever the monitor configuration changes.  Handle the
++  // scale change asynchronously to allow the change to propagate to QT's scale
++  // factor. This also coalesces scale change events together.
++  if (!scale_factor_task_active_) {
++    scale_factor_task_active_ = true;
++    base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
++        FROM_HERE, base::BindOnce(&QtUi::ScaleFactorMaybeChangedImpl,
++                                  weak_factory_.GetWeakPtr()));
++  }
++}
++
+ DISABLE_CFI_VCALL
+ void QtUi::AddNativeColorMixer(ui::ColorProvider* provider,
+                                const ui::ColorProviderManager::Key& key) {
+-  if (key.system_theme != ui::SystemTheme::kQt)
++  if (key.system_theme != ui::SystemTheme::kQt) {
+     return;
++  }
+ 
+   ui::ColorMixer& mixer = provider->AddMixer();
+   // These color constants are required by native_chrome_color_mixer_linux.cc
+@@ -494,8 +521,9 @@ void QtUi::AddNativeColorMixer(ui::ColorProvider* provider,
+        ColorState::kInactive},
+       {ui::kColorNativeToolbarBackground, ColorType::kButtonBg},
+   };
+-  for (const auto& map : kMaps)
++  for (const auto& map : kMaps) {
+     mixer[map.id] = {shim_->GetColor(map.role, map.state)};
++  }
+ 
+   const bool use_custom_frame =
+       key.frame_type == ui::ColorProviderManager::FrameType::kChromium;
+@@ -578,6 +606,20 @@ absl::optional<SkColor> QtUi::GetColor(int id, bool use_custom_frame) const {
+   }
+ }
+ 
++DISABLE_CFI_VCALL
++void QtUi::ScaleFactorMaybeChangedImpl() {
++  scale_factor_task_active_ = false;
++  double scale = shim_->GetScaleFactor();
++  if (scale == scale_factor_) {
++    return;
++  }
++  scale_factor_ = scale;
++  for (ui::DeviceScaleFactorObserver& observer :
++       device_scale_factor_observer_list()) {
++    observer.OnDeviceScaleFactorChanged();
++  }
++}
++
+ std::unique_ptr<ui::LinuxUiAndTheme> CreateQtUi(
+     ui::LinuxUi* fallback_linux_ui) {
+   return std::make_unique<QtUi>(fallback_linux_ui);
+diff --git a/ui/qt/qt_ui.h b/ui/qt/qt_ui.h
+index b53ed93240708..3319edf1ea9bc 100644
+--- a/ui/qt/qt_ui.h
++++ b/ui/qt/qt_ui.h
+@@ -8,6 +8,7 @@
+ #include <memory>
+ 
+ #include "base/component_export.h"
++#include "base/memory/weak_ptr.h"
+ #include "printing/buildflags/buildflags.h"
+ #include "third_party/abseil-cpp/absl/types/optional.h"
+ #include "ui/color/color_provider.h"
+@@ -88,11 +89,14 @@ class QtUi : public ui::LinuxUiAndTheme, QtInterface::Delegate {
+   // QtInterface::Delegate:
+   void FontChanged() override;
+   void ThemeChanged() override;
++  void ScaleFactorMaybeChanged() override;
+ 
+  private:
+   void AddNativeColorMixer(ui::ColorProvider* provider,
+                            const ui::ColorProviderManager::Key& key);
+ 
++  void ScaleFactorMaybeChangedImpl();
++
+   absl::optional<SkColor> GetColor(int id, bool use_custom_frame) const;
+ 
+   // TODO(https://crbug.com/1317782): This is a fallback for any unimplemented
+@@ -114,6 +118,11 @@ class QtUi : public ui::LinuxUiAndTheme, QtInterface::Delegate {
+   std::unique_ptr<QtInterface> shim_;
+ 
+   std::unique_ptr<QtNativeTheme> native_theme_;
++
++  bool scale_factor_task_active_ = false;
++  double scale_factor_ = 1.0;
++
++  base::WeakPtrFactory<QtUi> weak_factory_{this};
+ };
+ 
+ // This should be the only symbol exported from this component.

diff --git a/chromium.spec b/chromium.spec
index c876a9b..3db1e96 100644
--- a/chromium.spec
+++ b/chromium.spec
@@ -21,7 +21,7 @@
 
 # This flag is so I can build things very fast on a giant system.
 # Enabling this in koji causes aarch64 builds to timeout indefinitely.
-%global use_all_cpus 1
+%global use_all_cpus 0
 
 %if %{use_all_cpus}
 %global numjobs %{_smp_build_ncpus}
@@ -360,6 +360,10 @@ Patch300: chromium-113-rhel8-force-disable-use_gnome_keyring.patch
 Patch302: chromium-114-workaround_clang_bug-structured_binding.patch
 # missing typename
 Patch303: chromium-114-typename.patch
+# Qt issue
+Patch320: chromium-114-add_qt6_linuxui_backend.patch
+Patch321: chromium-114-qt-handle_scale_factor_changes.patch
+Patch322: chromium-114-qt-fix_font_double_scaling.patch
 
 # Use chromium-latest.py to generate clean tarball from released build tarballs, found here:
 # http://build.chromium.org/buildbot/official/
@@ -958,6 +962,10 @@ udev.
 
 %patch -P303 -p1 -b .typename
 
+%patch -P320 -p1 -b .add_qt6_linuxui_backend
+%patch -P321 -p1 -b .handle_scale_factor_changes
+%patch -P322 -p1 -b .fix_font_double_scaling
+
 # Change shebang in all relevant files in this directory and all subdirectories
 # See `man find` for how the `-exec command {} +` syntax works
 find -type f \( -iname "*.py" \) -exec sed -i '1s=^#! */usr/bin/\(python\|env python\)[23]\?=#!%{__python3}=' {} +
@@ -1633,8 +1641,11 @@ getent group chrome-remote-desktop >/dev/null || groupadd -r chrome-remote-deskt
 %{chromium_path}/chromedriver
 
 %changelog
-* Fri May 26 2023 Than Ngo <than@redhat.com> - 114.0.5735.45-1
+* Sun May 28 2023 Than Ngo <than@redhat.com> - 114.0.5735.45-1
 - update to 114.0.5735.45
+- add qt6 linuxui backend
+- backport: handle scale factor changes
+- backport: fix font double_scaling
 
 * Wed May 17 2023 Than Ngo <than@redhat.com> - 113.0.5672.126-1
 - drop clang workaround for el8

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-08-07 16:05 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-07 16:05 [rpms/chromium] epel9-next: - add qt6 linuxui backend Than Ngo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox