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 d6b7bf6496c25bd873f5e28ed38d21ef5725fee1..c4bb9b5e509907de06a4fa64370b99992f3ce5c7 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 e24cce85b453ecee9a4854bfdf7b8eeb6814f8c3..d3e3e9b918011c433b4ac6ded245803410ccb5d4 100644
--- a/ui/gtk/window_frame_provider_gtk.cc
+++ b/ui/gtk/window_frame_provider_gtk.cc
@@ -29,20 +29,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");
@@ -61,8 +64,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) {
@@ -117,8 +120,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;
@@ -152,7 +155,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;
@@ -186,8 +189,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,
@@ -337,7 +340,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)) {
@@ -366,7 +369,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));
@@ -374,7 +377,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();
