## Profile Picker window frame issue investigation While investigating [window decoration for profile selection page does not fit \[382645174\] - Chromium](https://issues.chromium.org/issues/382645174) it was found that, when the compositor does not support server-side decorations, some windows, such as the profile picker uses a "default theme" which does not match the system's one, e.g: dark mode, etc. ### Findings - On Views-based Desktop ports, `NonClientFrameView` is created at [Widget initialization](https://source.chromium.org/chromium/chromium/src/+/main:ui/views/widget/widget.cc;l=566;drc=3deaac799dc39f0ba14200463fd31bba49eb72a6); - Chrome's `BrowserFrame` uses a special `NonClientFrameView` specialization, which integrates with browser profile, user preferences, theme service, etc. - It does it by overriding [CreateNonClientFrameView method](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/views/frame/browser_non_client_frame_view_factory_views.cc;l=81;drc=3deaac799dc39f0ba14200463fd31bba49eb72a6), which relies on classes from `//c/b/u/v/frame/`, such as, `BrowserFrame` and `BrowserView`. - It basically constructs and returns an [OpaqueBrowserFrameView](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/views/frame/opaque_browser_frame_view.h;l=41;drc=3deaac799dc39f0ba14200463fd31bba49eb72a6) instance. - In case of Linux Desktop, an specific specialization of that class is used instead, which implements the native theme look & feel integration bits, which is [BrowserFrameViewLinuxNative](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/views/frame/browser_frame_view_linux_native.h;l=18;drc=e6d13737bf4ae3855fd24c9a84b04fee185cb777) - `OpaqueBrowserFrameView` extends [BrowserNonClientFrameView](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/views/frame/browser_non_client_frame_view.h;drc=3deaac799dc39f0ba14200463fd31bba49eb72a6;bpv=0;bpt=1;l=27) and has references, for example, "color provider" when painting itself. **TODO:** Investigate further. - When not overridden, [Widget::CreateNonClientFrameView()](https://source.chromium.org/chromium/chromium/src/+/main:ui/views/widget/widget.cc;l=1472-1489;drc=3deaac799dc39f0ba14200463fd31bba49eb72a6) falls back into a few options. - On Linux/X11, where server-side decorations is usually supported (ie: [X11Window::ShouldUseNativeFrame()](https://source.chromium.org/chromium/chromium/src/+/main:ui/ozone/platform/x11/x11_window.cc;l=845;drc=3deaac799dc39f0ba14200463fd31bba49eb72a6) returns true), a [NativeFrameView](https://source.chromium.org/chromium/chromium/src/+/main:ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc;l=726;drc=3deaac799dc39f0ba14200463fd31bba49eb72a6) instance is returned. - On Linux/Wayland and a compositor which doesn't support server-side decorations, eg: Mutter, [CustomFrameView](https://source.chromium.org/chromium/chromium/src/+/main:ui/views/window/custom_frame_view.h;l=35;drc=3deaac799dc39f0ba14200463fd31bba49eb72a6) is instantiated instead. - It can be seen in the [[#Screenshots]] below. - `ProfilePickerView` already properly [determines](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/views/profiles/profile_picker_view.cc;l=425;drc=c00be413d1aa5a7d661f806978cecc0f6574a705) if dark colors should be used, though it's currently used only for its web contents. ### Widgets where the issue is observed - Profile Picker window - Trigger: first run, chrome toolbar > profile button > manage chrome profiles - Send Feedback dialog - Trigger: main menu > help > report an issue, Ctrl+Shift+i (branded builds only?) - Chrome task manager window - Trigger: main menu > more tools > task manager - First run dialog - Launch chrome with a empty user data dir. eg: `--user-data-dir=$(mktemp -d)` ### Analysis #### Solution: Factor out and reuse `BrowserFrame`'s frame view impl >[!attention] Status: On Hold > Deprioritized for now as it's not a critical issue for the glinux/wayland project. > > crbug: https://issues.chromium.org/396190939 - Logic is spread over a set of classes and interfaces, including `BrowserFrameView[Linux,LinuxNative,LayoutLinux,LayoutLinuxNative]`, `OpaqueBrowserFrameView`, `BrowserNonClientFramView` family of classes in [//chrome/browser/ui/views/frame](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/views/frame/) - Cons: Quite convoluated and tight-coupled impl. #### Initial attempt: New NonClientFrameView impl based on AppFrameView - Prototyped at https://chromium-review.googlesource.com/6260413 - Conclusion: Not enough. I does not integrate with LinuxUi's native theme. Seems obsolete or only used for ChromeOS apps (maybe native apps?) ![[poc-chrome-profile-picker-app-frame-view-dark.png]] ### TODOs - [x] Check [ColorProvider](https://source.chromium.org/chromium/chromium/src/+/main:ui/color/color_provider.cc;l=24;drc=3deaac799dc39f0ba14200463fd31bba49eb72a6) and how its mixers are initialized and then used later on to determine colors for views, such as, in `CustomFrameView`. - [x] Both [Gtk](https://source.chromium.org/chromium/chromium/src/+/main:ui/gtk/gtk_color_mixers.cc;l=26;drc=3deaac799dc39f0ba14200463fd31bba49eb72a6) and [native theme](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/color/linux/native_chrome_color_mixer_linux.cc;l=75;drc=3deaac799dc39f0ba14200463fd31bba49eb72a6) mixers seem to be added. - [x] Study [ColorProviderKey](https://source.chromium.org/chromium/chromium/src/+/main:ui/color/color_provider_key.h;l=27;drc=3deaac799dc39f0ba14200463fd31bba49eb72a6) and [ThemeInitializerSupplier](https://source.chromium.org/chromium/chromium/src/+/main:ui/color/color_provider_key.h;l=101;drc=3deaac799dc39f0ba14200463fd31bba49eb72a6) - Use `BrowserFrame`'s [GetColorProviderKey()](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/views/frame/browser_frame.cc;l=489;drc=3deaac799dc39f0ba14200463fd31bba49eb72a6) and [GetCustomTheme()](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/views/frame/browser_frame.cc;l=346;drc=3deaac799dc39f0ba14200463fd31bba49eb72a6) as reference for tests with `ProfilePickerView`'s widget impl. - [ ] ~~Debug GTK color mixer code and check if it's indeed used after the `ProfilePickerWidget::GetNativeTheme()` was tweaked to return GtkUi's theme.~~ - There are a few util linux-specific functions at [//c/b/u/v/frame/frame/browser_frame_view_paint_utils_linux.cc](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/views/frame/browser_frame_view_paint_utils_linux.cc;l=37;drc=3deaac799dc39f0ba14200463fd31bba49eb72a6) which seem to consider native theme values and are used in chrome's `BrowserFrameLinux` impl. Maybe a starting point to share logic with other windows? ### Screenshots - Taken in a Gnome 48 alpha as of 2025/02/05 - Gathered using chromium's native UI inspect tool #### X11 with server-side decorations ![[Screenshot From 2025-02-04 22-04-46.png]] #### Wayland without server-side decorations ![[Screenshot From 2025-02-04 22-06-35.png]]