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 ab8f0d6b545b24c28eb427e6d2ef33ef35d22e91..ed3213e73959079e5bc119987da7c31cc07f2f27 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 794efdb773422ddc12ccbe013a13aadeb980b487..a60bbd76141f06202343c68e78688a95179b0083 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;
@@ -206,8 +209,8 @@ void WindowFrameProviderGtk::Asset::CloneFrom(
   unfocused_bitmap = src.unfocused_bitmap;
 }
 
-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,
@@ -325,7 +328,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)) {
@@ -352,7 +355,7 @@ void WindowFrameProviderGtk::MaybeUpdateBitmaps(float scale) {
 
   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));
@@ -360,7 +363,7 @@ void WindowFrameProviderGtk::MaybeUpdateBitmaps(float scale) {
                                      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);
 
   // 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 bed28192daffe032fde3a74ca70f1298fb12b1b7..268acade8bd1075f3ce756cdf29bf50905ccb433 100644
--- a/ui/gtk/window_frame_provider_gtk.h
+++ b/ui/gtk/window_frame_provider_gtk.h
@@ -18,7 +18,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;
@@ -70,6 +70,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.
   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();
