From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: msizanoen1 <msizanoen@qtmlabs.xyz>
Date: Tue, 19 Jul 2022 05:11:06 +0200
Subject: Add maximized parameter to LinuxUI::GetWindowFrameProvider

This allows ClientFrameViewLinux to instruct the toolkit to draw the window
decorations in maximized mode where needed, preventing empty space caused
by decoration shadows and rounded titlebars around the window while maximized.

diff --git a/ui/gtk/gtk_ui.cc b/ui/gtk/gtk_ui.cc
index 99d3dc38ca60dbdc68bcb679067e8fd64e43b06a..7f5c3b103da21d213aa19fe8a4320bec0b7ebeb5 100644
--- a/ui/gtk/gtk_ui.cc
+++ b/ui/gtk/gtk_ui.cc
@@ -480,12 +480,13 @@ std::unique_ptr<ui::NavButtonProvider> GtkUi::CreateNavButtonProvider() {
   return std::make_unique<gtk::NavButtonProviderGtk>();
 }
 
-ui::WindowFrameProvider* GtkUi::GetWindowFrameProvider(bool solid_frame) {
+ui::WindowFrameProvider* GtkUi::GetWindowFrameProvider(bool solid_frame, bool maximized) {
   auto& provider =
-      solid_frame ? solid_frame_provider_ : transparent_frame_provider_;
-  if (!provider) {
-    provider = std::make_unique<gtk::WindowFrameProviderGtk>(solid_frame);
-  }
+      maximized
+        ? (solid_frame ? solid_maximized_frame_provider_ : transparent_maximized_frame_provider_)
+        : (solid_frame ? solid_frame_provider_ : transparent_frame_provider_);
+  if (!provider)
+    provider = std::make_unique<gtk::WindowFrameProviderGtk>(solid_frame, maximized);
   return provider.get();
 }
 
diff --git a/ui/gtk/gtk_ui.h b/ui/gtk/gtk_ui.h
index adf91ed69c33c5da4ba8cf55d7cbfc482d0762ba..404fccbbe6957ba9309955ef5e7498cdcd0411f0 100644
--- a/ui/gtk/gtk_ui.h
+++ b/ui/gtk/gtk_ui.h
@@ -106,7 +106,7 @@ class GtkUi : public ui::LinuxUiAndTheme {
   void GetInactiveSelectionFgColor(SkColor* color) const override;
   bool PreferDarkTheme() const override;
   std::unique_ptr<ui::NavButtonProvider> CreateNavButtonProvider() override;
-  ui::WindowFrameProvider* GetWindowFrameProvider(bool solid_frame) override;
+  ui::WindowFrameProvider* GetWindowFrameProvider(bool solid_frame, bool maximized) override;
 
  private:
   using TintMap = std::map<int, color_utils::HSL>;
@@ -195,6 +195,8 @@ class GtkUi : public ui::LinuxUiAndTheme {
   // while Chrome is running.
   std::unique_ptr<ui::WindowFrameProvider> solid_frame_provider_;
   std::unique_ptr<ui::WindowFrameProvider> transparent_frame_provider_;
+  std::unique_ptr<ui::WindowFrameProvider> solid_maximized_frame_provider_;
+  std::unique_ptr<ui::WindowFrameProvider> transparent_maximized_frame_provider_;
 
   // Objects to notify when the window frame button order changes.
   base::ObserverList<ui::WindowButtonOrderObserver>::Unchecked
diff --git a/ui/gtk/window_frame_provider_gtk.cc b/ui/gtk/window_frame_provider_gtk.cc
index 1925c1a2763b8dd720f5d0a630bc98ec5d16b9a0..a4986477b46aef555d526851cf191650d2972238 100644
--- a/ui/gtk/window_frame_provider_gtk.cc
+++ b/ui/gtk/window_frame_provider_gtk.cc
@@ -39,16 +39,18 @@ std::string GetThemeName() {
   return theme_string;
 }
 
-GtkCssContext WindowContext(bool solid_frame, bool focused) {
+GtkCssContext WindowContext(bool solid_frame, bool maximized, bool focused) {
   std::string selector = "window.background.";
   selector += solid_frame ? "solid-csd" : "csd";
+  if (maximized)
+    selector += ".maximized";
   if (!focused)
     selector += ":inactive";
   return AppendCssNodeToStyleContext({}, selector);
 }
 
-GtkCssContext DecorationContext(bool solid_frame, bool focused) {
-  auto context = WindowContext(solid_frame, focused);
+GtkCssContext DecorationContext(bool solid_frame, bool maximized, bool focused) {
+  auto context = WindowContext(solid_frame, maximized, focused);
   // GTK4 renders the decoration directly on the window.
   if (!GtkCheckVersion(4))
     context = AppendCssNodeToStyleContext(context, "decoration");
@@ -65,8 +67,8 @@ GtkCssContext DecorationContext(bool solid_frame, bool focused) {
   return context;
 }
 
-GtkCssContext HeaderContext(bool solid_frame, bool focused) {
-  auto context = WindowContext(solid_frame, focused);
+GtkCssContext HeaderContext(bool solid_frame, bool maximized, bool focused) {
+  auto context = WindowContext(solid_frame, maximized, focused);
   context =
       AppendCssNodeToStyleContext(context, "headerbar.header-bar.titlebar");
   if (!focused)
@@ -121,8 +123,8 @@ int ComputeTopCornerRadius() {
   // need to experimentally determine the corner radius by rendering a sample.
   // Additionally, in GTK4, the headerbar corners get clipped by the window
   // rather than the headerbar having its own rounded corners.
-  auto context = GtkCheckVersion(4) ? DecorationContext(false, false)
-                                    : HeaderContext(false, false);
+  auto context = GtkCheckVersion(4) ? DecorationContext(false, false, false)
+                                    : HeaderContext(false, false, false);
   ApplyCssToContext(context, R"(window, headerbar {
     background-image: none;
     background-color: black;
@@ -155,7 +157,7 @@ int ComputeTopCornerRadius() {
 bool HeaderIsTranslucent() {
   // The arbitrary square size to render a sample header.
   constexpr int kHeaderSize = 32;
-  auto context = HeaderContext(false, false);
+  auto context = HeaderContext(false, false, false);
   double opacity = 1.0f;
   GtkStyleContextGet(context, "opacity", &opacity, nullptr);
   if (opacity < 1.0f)
@@ -211,8 +213,8 @@ void WindowFrameProviderGtk::Asset::CloneFrom(
   unfocused_bitmap = src.unfocused_bitmap;
 }
 
-WindowFrameProviderGtk::WindowFrameProviderGtk(bool solid_frame)
-    : solid_frame_(solid_frame) {}
+WindowFrameProviderGtk::WindowFrameProviderGtk(bool solid_frame, bool maximized)
+    : solid_frame_(solid_frame), maximized_(maximized) {}
 
 WindowFrameProviderGtk::~WindowFrameProviderGtk() = default;
 
@@ -319,7 +321,7 @@ void WindowFrameProviderGtk::PaintWindowFrame(
       top_area_height_dip * scale - effective_frame_thickness_px.top();
 
   auto header = PaintHeaderbar({client_bounds_px.width(), top_area_height_px},
-                               HeaderContext(solid_frame_, focused), scale);
+                               HeaderContext(solid_frame_, maximized_, focused), scale);
   image = gfx::ImageSkia::CreateFrom1xBitmap(header);
   // In GTK4, the headerbar gets clipped by the window.
   if (GtkCheckVersion(4)) {
@@ -351,7 +353,7 @@ void WindowFrameProviderGtk::MaybeUpdateBitmaps(float scale) {
 
   gfx::Rect frame_bounds_dip(kMaxFrameSizeDip, kMaxFrameSizeDip,
                              2 * kMaxFrameSizeDip, 2 * kMaxFrameSizeDip);
-  auto focused_context = DecorationContext(solid_frame_, true);
+  auto focused_context = DecorationContext(solid_frame_, maximized_, true);
   frame_bounds_dip.Inset(-GtkStyleContextGetPadding(focused_context));
   frame_bounds_dip.Inset(-GtkStyleContextGetBorder(focused_context));
   gfx::Size bitmap_size(BitmapSizePx(asset), BitmapSizePx(asset));
@@ -359,7 +361,7 @@ void WindowFrameProviderGtk::MaybeUpdateBitmaps(float scale) {
       PaintBitmap(bitmap_size, frame_bounds_dip, focused_context, scale);
   asset.unfocused_bitmap =
       PaintBitmap(bitmap_size, frame_bounds_dip,
-                  DecorationContext(solid_frame_, false), scale);
+                  DecorationContext(solid_frame_, maximized_, false), scale);
 
   // In GTK4, there's no way to obtain the frame thickness from CSS values
   // directly, so we must determine it experimentally based on the drawn
diff --git a/ui/gtk/window_frame_provider_gtk.h b/ui/gtk/window_frame_provider_gtk.h
index 32c3d63ae4598339965c58443a8c2d12b99fb89a..91496d957b8291cd37948e237a1cc4bf605848b0 100644
--- a/ui/gtk/window_frame_provider_gtk.h
+++ b/ui/gtk/window_frame_provider_gtk.h
@@ -14,7 +14,7 @@ namespace gtk {
 
 class WindowFrameProviderGtk : public ui::WindowFrameProvider {
  public:
-  explicit WindowFrameProviderGtk(bool solid_frame);
+  explicit WindowFrameProviderGtk(bool solid_frame, bool maximized);
 
   WindowFrameProviderGtk(const WindowFrameProviderGtk&) = delete;
   WindowFrameProviderGtk& operator=(const WindowFrameProviderGtk&) = delete;
@@ -72,6 +72,9 @@ class WindowFrameProviderGtk : public ui::WindowFrameProvider {
 
   // Cached bitmaps and metrics.  The scale is rounded to percent.
   base::flat_map<int, Asset> assets_;
+
+  // Whether to draw the window decorations as maximized.
+  bool maximized_;
 };
 
 }  // namespace gtk
diff --git a/ui/linux/fallback_linux_ui.cc b/ui/linux/fallback_linux_ui.cc
index 5f5abeeb78372785d57315056fa61fc65a3848a9..f52f436d674ad54c9973488eec59e26d02866847 100644
--- a/ui/linux/fallback_linux_ui.cc
+++ b/ui/linux/fallback_linux_ui.cc
@@ -136,7 +136,7 @@ FallbackLinuxUi::CreateNavButtonProvider() {
 }
 
 ui::WindowFrameProvider* FallbackLinuxUi::GetWindowFrameProvider(
-    bool solid_frame) {
+    bool solid_frame, bool maximized) {
   return nullptr;
 }
 
diff --git a/ui/linux/fallback_linux_ui.h b/ui/linux/fallback_linux_ui.h
index d5b12df3f4e32aef6d974986ceeb666edecc4e11..e836f661a17f2e9916685d497ee5f487c4000661 100644
--- a/ui/linux/fallback_linux_ui.h
+++ b/ui/linux/fallback_linux_ui.h
@@ -67,7 +67,7 @@ class FallbackLinuxUi : public LinuxUiAndTheme {
   void GetInactiveSelectionFgColor(SkColor* color) const override;
   bool PreferDarkTheme() const override;
   std::unique_ptr<ui::NavButtonProvider> CreateNavButtonProvider() override;
-  ui::WindowFrameProvider* GetWindowFrameProvider(bool solid_frame) override;
+  ui::WindowFrameProvider* GetWindowFrameProvider(bool solid_frame, bool maximized) override;
 
  private:
   std::string default_font_family_;
diff --git a/ui/linux/linux_ui.h b/ui/linux/linux_ui.h
index 82d40cb5fa1b9ad54e43502793a7d1d3e94e2ebb..6f6296c4f8334e59e1522abe291d65bb508f9541 100644
--- a/ui/linux/linux_ui.h
+++ b/ui/linux/linux_ui.h
@@ -273,7 +273,7 @@ class COMPONENT_EXPORT(LINUX_UI) LinuxUiTheme {
   // if transparency is unsupported and the frame should be rendered opaque.
   // The returned object is not owned by the caller and will remain alive until
   // the process ends.
-  virtual WindowFrameProvider* GetWindowFrameProvider(bool solid_frame) = 0;
+  virtual WindowFrameProvider* GetWindowFrameProvider(bool solid_frame, bool maximized) = 0;
 
  protected:
   LinuxUiTheme();
