## 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]]