Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Wayland general CSD fixes (#35206)
* fix: broken wayland window decorations due to botched chromium update The `GetTitlebarBounds().height()` is obviously intended to be placed in the `top` parameter, which used to be the second one before upstream removed multi-parameter `gfx::Rect::Inset`, but it's the first parameter for `gfx::Insets::TLBR`, which was intended to replace the removed `Inset` function. However, whoever updated Chromium kept the parameter unchanged, causing the title bar height to be passed to the `left` parameter, causing the window title bar to be unclickable. * fix: wayland window top bar buttons unclickable Use NonClientFrameView::TargetForRect for the ClientFrameViewLinux implementation because the default inherited from FramelessView blocks any non-HTCLIENT events. * fix: add maximized parameter to LinuxUI::GetWindowFrameProvider * fix: pass frame_->IsMaximized() to GetWindowFrameProvider This ensures that the toolkit renders the window decorations in maximized mode while the window is maximized to ensure that there is no empty space around the window.
- Loading branch information
1 parent
5274c25
commit c84a45f
Showing
4 changed files
with
190 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
176 changes: 176 additions & 0 deletions
176
patches/chromium/add_maximized_parameter_to_linuxui_getwindowframeprovider.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
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 12193ad9090de969b81fa6aa6bed9520aea5bae1..99ea60219b39a6864bdea45ba0917316bff7f2d9 100644 | ||
--- a/ui/gtk/gtk_ui.cc | ||
+++ b/ui/gtk/gtk_ui.cc | ||
@@ -556,13 +556,15 @@ std::unique_ptr<views::NavButtonProvider> GtkUi::CreateNavButtonProvider() { | ||
return nullptr; | ||
} | ||
|
||
-views::WindowFrameProvider* GtkUi::GetWindowFrameProvider(bool solid_frame) { | ||
+views::WindowFrameProvider* GtkUi::GetWindowFrameProvider(bool solid_frame, bool maximized) { | ||
if (!GtkCheckVersion(3, 14)) | ||
return nullptr; | ||
auto& provider = | ||
- solid_frame ? solid_frame_provider_ : transparent_frame_provider_; | ||
+ 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); | ||
+ 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 65f9d6c81804d1b0efb88ced4a9c80c000ba0f5a..35d851a054a2b2f9887c77a9faaf16ce1aa363b9 100644 | ||
--- a/ui/gtk/gtk_ui.h | ||
+++ b/ui/gtk/gtk_ui.h | ||
@@ -89,7 +89,7 @@ class GtkUi : public views::LinuxUI { | ||
bool PreferDarkTheme() const override; | ||
bool AnimationsEnabled() const override; | ||
std::unique_ptr<views::NavButtonProvider> CreateNavButtonProvider() override; | ||
- views::WindowFrameProvider* GetWindowFrameProvider(bool solid_frame) override; | ||
+ views::WindowFrameProvider* GetWindowFrameProvider(bool solid_frame, bool maximized) override; | ||
base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override; | ||
std::string GetCursorThemeName() override; | ||
int GetCursorThemeSize() override; | ||
@@ -188,6 +188,8 @@ class GtkUi : public views::LinuxUI { | ||
// while Chrome is running. | ||
std::unique_ptr<views::WindowFrameProvider> solid_frame_provider_; | ||
std::unique_ptr<views::WindowFrameProvider> transparent_frame_provider_; | ||
+ std::unique_ptr<views::WindowFrameProvider> solid_maximized_frame_provider_; | ||
+ std::unique_ptr<views::WindowFrameProvider> transparent_maximized_frame_provider_; | ||
}; | ||
|
||
} // namespace gtk | ||
diff --git a/ui/gtk/window_frame_provider_gtk.cc b/ui/gtk/window_frame_provider_gtk.cc | ||
index e4dbdad327eb77994ffd7f068c67336a19897915..d3ae0636455489a7c7443df85cb769952c98aca2 100644 | ||
--- a/ui/gtk/window_frame_provider_gtk.cc | ||
+++ b/ui/gtk/window_frame_provider_gtk.cc | ||
@@ -38,16 +38,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"); | ||
@@ -64,8 +66,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) | ||
@@ -110,8 +112,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; | ||
@@ -169,8 +171,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; | ||
|
||
@@ -264,7 +266,7 @@ void WindowFrameProviderGtk::PaintWindowFrame(gfx::Canvas* canvas, | ||
top_area_height_dip * scale - asset.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)) { | ||
@@ -296,7 +298,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)); | ||
@@ -304,7 +306,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 d3039d73161378197557947aece88d2710c1e486..f7d4605938210b0b75517bb7bcab28b588a16520 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 views::WindowFrameProvider { | ||
public: | ||
- explicit WindowFrameProviderGtk(bool solid_frame); | ||
+ explicit WindowFrameProviderGtk(bool solid_frame, bool maximized); | ||
|
||
WindowFrameProviderGtk(const WindowFrameProviderGtk&) = delete; | ||
WindowFrameProviderGtk& operator=(const WindowFrameProviderGtk&) = delete; | ||
@@ -69,6 +69,9 @@ class WindowFrameProviderGtk : public views::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/views/linux_ui/linux_ui.h b/ui/views/linux_ui/linux_ui.h | ||
index 7d59a2c9ff87cf9d8cb3ed0b45e34e2831545d28..a6ae4feec8df8f149a9ebbe1c3d2252db73135db 100644 | ||
--- a/ui/views/linux_ui/linux_ui.h | ||
+++ b/ui/views/linux_ui/linux_ui.h | ||
@@ -170,7 +170,7 @@ class VIEWS_EXPORT LinuxUI : public ui::LinuxInputMethodContextFactory, | ||
// 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; | ||
|
||
// Returns a map of KeyboardEvent code to KeyboardEvent key values. | ||
virtual base::flat_map<std::string, std::string> GetKeyboardLayoutMap() = 0; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters