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 7b81a752ffad229a7bf1917f000b7a45f0828c36..1f08396713155eafc78a1fa9fc8fec22df350a91 100644
--- a/ui/gtk/gtk_ui.cc
+++ b/ui/gtk/gtk_ui.cc
@@ -562,11 +562,12 @@ std::unique_ptr<ui::NavButtonProvider> GtkUi::CreateNavButtonProvider() {
 }
 
 ui::WindowFrameProvider* GtkUi::GetWindowFrameProvider(bool solid_frame,
-                                                       bool tiled) {
-  auto& provider = frame_providers_[solid_frame][tiled];
+                                                       bool tiled,
+                                                       bool maximized) {
+  auto& provider = frame_providers_[solid_frame][tiled][maximized];
   if (!provider) {
     provider =
-        std::make_unique<gtk::WindowFrameProviderGtk>(solid_frame, tiled);
+        std::make_unique<gtk::WindowFrameProviderGtk>(solid_frame, tiled, maximized);
   }
   return provider.get();
 }
diff --git a/ui/gtk/gtk_ui.h b/ui/gtk/gtk_ui.h
index 0432ea4f5906502a4f6def46ab064292a6628218..e3cbfa3a1ac8c169c429e29c1262d0dd2a05a4b6 100644
--- a/ui/gtk/gtk_ui.h
+++ b/ui/gtk/gtk_ui.h
@@ -107,7 +107,8 @@ class GtkUi : public ui::LinuxUiAndTheme {
   void SetDarkTheme(bool dark) override;
   std::unique_ptr<ui::NavButtonProvider> CreateNavButtonProvider() override;
   ui::WindowFrameProvider* GetWindowFrameProvider(bool solid_frame,
-                                                  bool tiled) override;
+                                                  bool tiled,
+                                                  bool maximized) override;
 
  private:
   using TintMap = std::map<int, color_utils::HSL>;
@@ -191,7 +192,7 @@ class GtkUi : public ui::LinuxUiAndTheme {
   // while Chrome is running.  This 2D array is indexed first by whether the
   // frame is translucent (0) or solid(1), then by whether the frame is normal
   // (0) or tiled (1).
-  std::unique_ptr<ui::WindowFrameProvider> frame_providers_[2][2];
+  std::unique_ptr<ui::WindowFrameProvider> frame_providers_[2][2][2];
 
   // 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 0b8fa0ec76098e0319b2e853719166d405cd3828..52615c5c119c58f17850454e98d1240b141e8a09 100644
--- a/ui/gtk/window_frame_provider_gtk.cc
+++ b/ui/gtk/window_frame_provider_gtk.cc
@@ -30,20 +30,23 @@ constexpr int kMaxFrameSizeDip = 64;
 // will get an incorrect hint as to which pixels are fully opaque.
 constexpr int kMaxCornerRadiusDip = 32;
 
-GtkCssContext WindowContext(bool solid_frame, bool tiled, bool focused) {
+GtkCssContext WindowContext(bool solid_frame, bool tiled, bool maximized, bool focused) {
   std::string selector = "window.background.";
   selector += solid_frame ? "solid-csd" : "csd";
   if (tiled) {
     selector += ".tiled";
   }
+  if (maximized) {
+    selector += ".maximized";
+  }
   if (!focused) {
     selector += ":inactive";
   }
   return AppendCssNodeToStyleContext({}, selector);
 }
 
-GtkCssContext DecorationContext(bool solid_frame, bool tiled, bool focused) {
-  auto context = WindowContext(solid_frame, tiled, focused);
+GtkCssContext DecorationContext(bool solid_frame, bool tiled, bool maximized, bool focused) {
+  auto context = WindowContext(solid_frame, tiled, maximized, focused);
   // GTK4 renders the decoration directly on the window.
   if (!GtkCheckVersion(4)) {
     context = AppendCssNodeToStyleContext(context, "decoration");
@@ -62,8 +65,8 @@ GtkCssContext DecorationContext(bool solid_frame, bool tiled, bool focused) {
   return context;
 }
 
-GtkCssContext HeaderContext(bool solid_frame, bool tiled, bool focused) {
-  auto context = WindowContext(solid_frame, tiled, focused);
+GtkCssContext HeaderContext(bool solid_frame, bool tiled, bool maximized, bool focused) {
+  auto context = WindowContext(solid_frame, tiled, maximized, focused);
   context =
       AppendCssNodeToStyleContext(context, "headerbar.header-bar.titlebar");
   if (!focused) {
@@ -120,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, false)
-                                    : HeaderContext(false, false, false);
+  auto context = GtkCheckVersion(4) ? DecorationContext(false, false, false, false)
+                                    : HeaderContext(false, false, false, false);
   ApplyCssToContext(context, R"(window, headerbar {
     background-image: none;
     background-color: black;
@@ -155,7 +158,7 @@ int ComputeTopCornerRadius() {
 bool HeaderIsTranslucent() {
   // The arbitrary square size to render a sample header.
   constexpr int kHeaderSize = 32;
-  auto context = HeaderContext(false, false, false);
+  auto context = HeaderContext(false, false, false, false);
   double opacity = GetOpacityFromContext(context);
   if (opacity < 1.0) {
     return true;
@@ -189,8 +192,8 @@ WindowFrameProviderGtk::Asset& WindowFrameProviderGtk::Asset::operator=(
 
 WindowFrameProviderGtk::Asset::~Asset() = default;
 
-WindowFrameProviderGtk::WindowFrameProviderGtk(bool solid_frame, bool tiled)
-    : solid_frame_(solid_frame), tiled_(tiled) {
+WindowFrameProviderGtk::WindowFrameProviderGtk(bool solid_frame, bool tiled, bool maximized)
+    : solid_frame_(solid_frame), tiled_(tiled), maximized_(maximized) {
   GtkSettings* settings = gtk_settings_get_default();
   // Unretained() is safe since WindowFrameProviderGtk will own the signals.
   auto callback = base::BindRepeating(&WindowFrameProviderGtk::OnThemeChanged,
@@ -340,7 +343,7 @@ void WindowFrameProviderGtk::PaintWindowFrame(gfx::Canvas* canvas,
 
   auto header =
       PaintHeaderbar({client_bounds_px.width(), top_area_height_px},
-                     HeaderContext(solid_frame_, tiled_, focused), scale);
+                     HeaderContext(solid_frame_, tiled_, maximized_, focused), scale);
   image = gfx::ImageSkia::CreateFrom1xBitmap(header);
   // In GTK4, the headerbar gets clipped by the window.
   if (GtkCheckVersion(4)) {
@@ -369,7 +372,7 @@ WindowFrameProviderGtk::Asset& WindowFrameProviderGtk::GetOrCreateAsset(
 
   gfx::Rect frame_bounds_dip(kMaxFrameSizeDip, kMaxFrameSizeDip,
                              2 * kMaxFrameSizeDip, 2 * kMaxFrameSizeDip);
-  auto focused_context = DecorationContext(solid_frame_, tiled_, true);
+  auto focused_context = DecorationContext(solid_frame_, tiled_, maximized_, true);
   frame_bounds_dip.Inset(-GtkStyleContextGetPadding(focused_context));
   frame_bounds_dip.Inset(-GtkStyleContextGetBorder(focused_context));
   gfx::Size bitmap_size(BitmapSizePx(asset), BitmapSizePx(asset));
@@ -377,7 +380,7 @@ WindowFrameProviderGtk::Asset& WindowFrameProviderGtk::GetOrCreateAsset(
                                      focused_context, scale);
   asset.unfocused_bitmap =
       PaintBitmap(bitmap_size, gfx::RectF(frame_bounds_dip),
-                  DecorationContext(solid_frame_, tiled_, false), scale);
+                  DecorationContext(solid_frame_, tiled_, maximized_, false), scale);
 
   return asset;
 }
diff --git a/ui/gtk/window_frame_provider_gtk.h b/ui/gtk/window_frame_provider_gtk.h
index 4faaae32a203bfa57f3e61c391dc6917c4a0bf59..94050a0136b78730f607f42991742e0434948d0e 100644
--- a/ui/gtk/window_frame_provider_gtk.h
+++ b/ui/gtk/window_frame_provider_gtk.h
@@ -20,7 +20,7 @@ namespace gtk {
 
 class WindowFrameProviderGtk : public ui::WindowFrameProvider {
  public:
-  WindowFrameProviderGtk(bool solid_frame, bool tiled);
+  WindowFrameProviderGtk(bool solid_frame, bool tiled, bool maximized);
 
   WindowFrameProviderGtk(const WindowFrameProviderGtk&) = delete;
   WindowFrameProviderGtk& operator=(const WindowFrameProviderGtk&) = delete;
@@ -65,6 +65,8 @@ class WindowFrameProviderGtk : public ui::WindowFrameProvider {
   // Input parameters used for drawing.
   const bool solid_frame_;
   const bool tiled_;
+  // Whether to draw the window decorations as maximized.
+  const bool maximized_;
 
   // Scale-independent metric calculated based on the bitmaps.
   std::optional<gfx::Insets> frame_thickness_dip_;
diff --git a/ui/linux/fallback_linux_ui.cc b/ui/linux/fallback_linux_ui.cc
index 8903f9ba950e7878fbd1bfa0cf2a42e0cc9daa21..7d13381eb1d16193bad0be1318e8ed199c6fb845 100644
--- a/ui/linux/fallback_linux_ui.cc
+++ b/ui/linux/fallback_linux_ui.cc
@@ -141,7 +141,8 @@ FallbackLinuxUi::CreateNavButtonProvider() {
 
 ui::WindowFrameProvider* FallbackLinuxUi::GetWindowFrameProvider(
     bool solid_frame,
-    bool tiled) {
+    bool tiled,
+    bool maximized) {
   return nullptr;
 }
 
diff --git a/ui/linux/fallback_linux_ui.h b/ui/linux/fallback_linux_ui.h
index 2612cb68984a8435c84f0b0592eda8a5df6dd91e..282b48038f83d4a6dafe734f639d994c245c67ac 100644
--- a/ui/linux/fallback_linux_ui.h
+++ b/ui/linux/fallback_linux_ui.h
@@ -66,7 +66,8 @@ class FallbackLinuxUi : public LinuxUiAndTheme {
   void SetDarkTheme(bool dark) override;
   std::unique_ptr<ui::NavButtonProvider> CreateNavButtonProvider() override;
   ui::WindowFrameProvider* GetWindowFrameProvider(bool solid_frame,
-                                                  bool tiled) override;
+                                                  bool tiled,
+                                                  bool maximized) override;
 
  private:
   std::optional<gfx::FontRenderParams> default_font_render_params_;
diff --git a/ui/linux/linux_ui.h b/ui/linux/linux_ui.h
index b940382678ba70debaf7f33698c0b8bd02c42c4e..4477a1012fef5ad6dd365d70d28eadd3db136ceb 100644
--- a/ui/linux/linux_ui.h
+++ b/ui/linux/linux_ui.h
@@ -304,7 +304,8 @@ class COMPONENT_EXPORT(LINUX_UI) LinuxUiTheme {
   // The returned object is not owned by the caller and will remain alive until
   // the process ends.
   virtual WindowFrameProvider* GetWindowFrameProvider(bool solid_frame,
-                                                      bool tiled) = 0;
+                                                      bool tiled,
+                                                      bool maximized) = 0;
 
  protected:
   LinuxUiTheme();
