From dc5b21f988239d95abd077d19dc3abe9ff8e9bd2 Mon Sep 17 00:00:00 2001 From: Deepak Mohan Date: Wed, 19 Aug 2020 15:09:14 -0700 Subject: [PATCH 1/6] fix: client area inset calculation when maximized --- shell/browser/ui/views/win_frame_view.cc | 72 ++++++++++++++++++- shell/browser/ui/views/win_frame_view.h | 5 ++ .../electron_desktop_window_tree_host_win.cc | 27 +++++-- .../electron_desktop_window_tree_host_win.h | 1 + 4 files changed, 96 insertions(+), 9 deletions(-) diff --git a/shell/browser/ui/views/win_frame_view.cc b/shell/browser/ui/views/win_frame_view.cc index 61f72e4aad8e0..03705ecf1ae59 100644 --- a/shell/browser/ui/views/win_frame_view.cc +++ b/shell/browser/ui/views/win_frame_view.cc @@ -4,7 +4,12 @@ #include "shell/browser/ui/views/win_frame_view.h" +#include + +#include "base/win/windows_version.h" #include "shell/browser/native_window_views.h" +#include "ui/base/win/hwnd_metrics.h" +#include "ui/display/win/screen_win.h" #include "ui/views/widget/widget.h" #include "ui/views/win/hwnd_util.h" @@ -16,11 +21,72 @@ WinFrameView::WinFrameView() {} WinFrameView::~WinFrameView() {} +gfx::Insets WinFrameView::GetGlassInsets() const { + int frame_height = + display::win::ScreenWin::GetSystemMetricsInDIP(SM_CYSIZEFRAME) + + display::win::ScreenWin::GetSystemMetricsInDIP(SM_CXPADDEDBORDER); + + int frame_size = + base::win::GetVersion() < base::win::Version::WIN10 + ? display::win::ScreenWin::GetSystemMetricsInDIP(SM_CXSIZEFRAME) + : 0; + + return gfx::Insets(frame_height, frame_size, frame_size, frame_size); +} + +gfx::Insets WinFrameView::GetClientAreaInsets(HMONITOR monitor) const { + gfx::Insets insets; + if (base::win::GetVersion() < base::win::Version::WIN10) { + // This tells Windows that most of the window is a client area, meaning + // Chrome will draw it. Windows still fills in the glass bits because of the + // DwmExtendFrameIntoClientArea call in |UpdateDWMFrame|. + // Without this 1 pixel offset on the right and bottom: + // * windows paint in a more standard way, and + // * we get weird black bars at the top when maximized in multiple monitor + // configurations. + int border_thickness = 1; + insets.Set(0, 0, border_thickness, border_thickness); + } else { + const int frame_thickness = ui::GetFrameThickness(monitor); + insets.Set(0, frame_thickness, frame_thickness, frame_thickness); + } + return insets; +} + gfx::Rect WinFrameView::GetWindowBoundsForClientBounds( const gfx::Rect& client_bounds) const { - return views::GetWindowBoundsForClientBounds( - static_cast(const_cast(this)), - client_bounds); + if (window_->IsMaximized() && !window_->has_frame()) { + gfx::Insets insets = GetGlassInsets(); + insets += GetClientAreaInsets( + MonitorFromWindow(HWNDForView(this), MONITOR_DEFAULTTONEAREST)); + return gfx::Rect(client_bounds.x() - insets.left(), + client_bounds.y() - insets.top(), + client_bounds.width() + insets.left() + insets.right(), + client_bounds.height() + insets.top() + insets.bottom()); + } else { + return views::GetWindowBoundsForClientBounds( + static_cast(const_cast(this)), + client_bounds); + } +} + +gfx::Rect WinFrameView::GetBoundsForClientView() const { + if (window_->IsMaximized() && !window_->has_frame()) { + gfx::Insets insets = GetGlassInsets(); + return gfx::Rect(insets.left(), insets.top(), + std::max(0, width() - insets.left() - insets.right()), + std::max(0, height() - insets.top() - insets.bottom())); + } else { + return bounds(); + } +} + +gfx::Size WinFrameView::CalculatePreferredSize() const { + gfx::Size pref = frame_->client_view()->GetPreferredSize(); + gfx::Rect bounds(0, 0, pref.width(), pref.height()); + return frame_->non_client_view() + ->GetWindowBoundsForClientBounds(bounds) + .size(); } int WinFrameView::NonClientHitTest(const gfx::Point& point) { diff --git a/shell/browser/ui/views/win_frame_view.h b/shell/browser/ui/views/win_frame_view.h index 884a13e506c3e..b2b1b7c5634df 100644 --- a/shell/browser/ui/views/win_frame_view.h +++ b/shell/browser/ui/views/win_frame_view.h @@ -15,10 +15,15 @@ class WinFrameView : public FramelessView { WinFrameView(); ~WinFrameView() override; + gfx::Insets GetGlassInsets() const; + gfx::Insets GetClientAreaInsets(HMONITOR monitor) const; + // views::NonClientFrameView: + gfx::Rect GetBoundsForClientView() const override; gfx::Rect GetWindowBoundsForClientBounds( const gfx::Rect& client_bounds) const override; int NonClientHitTest(const gfx::Point& point) override; + gfx::Size CalculatePreferredSize() const override; // views::View: const char* GetClassName() const override; diff --git a/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc b/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc index 8fc9b230e696c..4b87a89cf0839 100644 --- a/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc +++ b/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc @@ -4,7 +4,10 @@ #include "shell/browser/ui/win/electron_desktop_window_tree_host_win.h" +#include "shell/browser/ui/views/win_frame_view.h" #include "ui/base/win/hwnd_metrics.h" +#include "ui/base/win/shell.h" +#include "ui/display/win/dpi.h" namespace electron { @@ -36,18 +39,30 @@ bool ElectronDesktopWindowTreeHostWin::HasNativeFrame() const { // Since we never use chromium's titlebar implementation, we can just say // that we use a native titlebar. This will disable the repaint locking when // DWM composition is disabled. - return true; + return !ui::win::IsAeroGlassEnabled(); +} + +bool ElectronDesktopWindowTreeHostWin::GetDwmFrameInsetsInPixels( + gfx::Insets* insets) const { + if (IsMaximized() && !native_window_view_->has_frame()) { + WinFrameView* frame = static_cast( + native_window_view_->widget()->non_client_view()->frame_view()); + *insets = frame->GetGlassInsets(); + // The DWM API's expect values in pixels. We need to convert from DIP to + // pixels here. + *insets = insets->Scale(display::win::GetDPIScale()); + return true; + } + return false; } bool ElectronDesktopWindowTreeHostWin::GetClientAreaInsets( gfx::Insets* insets, HMONITOR monitor) const { if (IsMaximized() && !native_window_view_->has_frame()) { - // Windows automatically adds a standard width border to all sides when a - // window is maximized. - int frame_thickness = ui::GetFrameThickness(monitor) - 1; - *insets = gfx::Insets(frame_thickness, frame_thickness, frame_thickness, - frame_thickness); + WinFrameView* frame = static_cast( + native_window_view_->widget()->non_client_view()->frame_view()); + *insets = frame->GetClientAreaInsets(monitor); return true; } return false; diff --git a/shell/browser/ui/win/electron_desktop_window_tree_host_win.h b/shell/browser/ui/win/electron_desktop_window_tree_host_win.h index 9aa3b8fb11434..ef96175474e1e 100644 --- a/shell/browser/ui/win/electron_desktop_window_tree_host_win.h +++ b/shell/browser/ui/win/electron_desktop_window_tree_host_win.h @@ -27,6 +27,7 @@ class ElectronDesktopWindowTreeHostWin LRESULT* result) override; bool ShouldPaintAsActive() const override; bool HasNativeFrame() const override; + bool GetDwmFrameInsetsInPixels(gfx::Insets* insets) const override; bool GetClientAreaInsets(gfx::Insets* insets, HMONITOR monitor) const override; From 0c37b7f624c1e7af7e3c1cdae5107a1fc8591ff5 Mon Sep 17 00:00:00 2001 From: Deepak Mohan Date: Thu, 27 Aug 2020 13:48:11 -0700 Subject: [PATCH 2/6] address review feedback --- shell/browser/ui/views/win_frame_view.cc | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/shell/browser/ui/views/win_frame_view.cc b/shell/browser/ui/views/win_frame_view.cc index 03705ecf1ae59..9a938f80edfc0 100644 --- a/shell/browser/ui/views/win_frame_view.cc +++ b/shell/browser/ui/views/win_frame_view.cc @@ -59,10 +59,9 @@ gfx::Rect WinFrameView::GetWindowBoundsForClientBounds( gfx::Insets insets = GetGlassInsets(); insets += GetClientAreaInsets( MonitorFromWindow(HWNDForView(this), MONITOR_DEFAULTTONEAREST)); - return gfx::Rect(client_bounds.x() - insets.left(), - client_bounds.y() - insets.top(), - client_bounds.width() + insets.left() + insets.right(), - client_bounds.height() + insets.top() + insets.bottom()); + gfx::Rect result(client_bounds); + result.Inset(-insets); + return result; } else { return views::GetWindowBoundsForClientBounds( static_cast(const_cast(this)), @@ -73,9 +72,9 @@ gfx::Rect WinFrameView::GetWindowBoundsForClientBounds( gfx::Rect WinFrameView::GetBoundsForClientView() const { if (window_->IsMaximized() && !window_->has_frame()) { gfx::Insets insets = GetGlassInsets(); - return gfx::Rect(insets.left(), insets.top(), - std::max(0, width() - insets.left() - insets.right()), - std::max(0, height() - insets.top() - insets.bottom())); + gfx::Rect result(width(), height()); + result.Inset(insets); + return result; } else { return bounds(); } @@ -83,7 +82,7 @@ gfx::Rect WinFrameView::GetBoundsForClientView() const { gfx::Size WinFrameView::CalculatePreferredSize() const { gfx::Size pref = frame_->client_view()->GetPreferredSize(); - gfx::Rect bounds(0, 0, pref.width(), pref.height()); + gfx::Rect bounds(pref); return frame_->non_client_view() ->GetWindowBoundsForClientBounds(bounds) .size(); From 8a0124e305422b26eb388ee76ac920ebf49f9d7d Mon Sep 17 00:00:00 2001 From: Deepak Mohan Date: Thu, 27 Aug 2020 14:10:21 -0700 Subject: [PATCH 3/6] adopt per monitor scale factor --- .../browser/ui/win/electron_desktop_window_tree_host_win.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc b/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc index 4b87a89cf0839..dd22053cc80ae 100644 --- a/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc +++ b/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc @@ -7,7 +7,8 @@ #include "shell/browser/ui/views/win_frame_view.h" #include "ui/base/win/hwnd_metrics.h" #include "ui/base/win/shell.h" -#include "ui/display/win/dpi.h" +#include "ui/display/win/screen_win.h" +#include "ui/views/win/hwnd_util.h" namespace electron { @@ -50,7 +51,8 @@ bool ElectronDesktopWindowTreeHostWin::GetDwmFrameInsetsInPixels( *insets = frame->GetGlassInsets(); // The DWM API's expect values in pixels. We need to convert from DIP to // pixels here. - *insets = insets->Scale(display::win::GetDPIScale()); + *insets = insets->Scale( + display::win::ScreenWin::GetScaleFactorForHWND(HWNDForView(frame))); return true; } return false; From 2e04c8dfb84197d6b03f3d41d022bcb3818ec847 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 28 Aug 2020 17:05:51 +0900 Subject: [PATCH 4/6] pass correct glass insets to GetDwmFrameInsetsInPixels --- shell/browser/ui/views/win_frame_view.cc | 30 +++++++++++++++---- shell/browser/ui/views/win_frame_view.h | 8 ++++- .../electron_desktop_window_tree_host_win.cc | 8 ++--- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/shell/browser/ui/views/win_frame_view.cc b/shell/browser/ui/views/win_frame_view.cc index 9a938f80edfc0..33162587b49c3 100644 --- a/shell/browser/ui/views/win_frame_view.cc +++ b/shell/browser/ui/views/win_frame_view.cc @@ -21,6 +21,21 @@ WinFrameView::WinFrameView() {} WinFrameView::~WinFrameView() {} +gfx::Insets WinFrameView::GetGlassInsetsInPixels() const { + // Note that we should explicitly get metrics for monitor, instead of scaling + // from the DIP results, otherwise results might be wrong. + HMONITOR monitor = GetMonitor(); + int frame_height = display::win::ScreenWin::GetSystemMetricsForMonitor( + monitor, SM_CYSIZEFRAME) + + display::win::ScreenWin::GetSystemMetricsForMonitor( + monitor, SM_CXPADDEDBORDER); + int frame_size = base::win::GetVersion() < base::win::Version::WIN10 + ? display::win::ScreenWin::GetSystemMetricsForMonitor( + monitor, SM_CXSIZEFRAME) + : 0; + return gfx::Insets(frame_height, frame_size, frame_size, frame_size); +} + gfx::Insets WinFrameView::GetGlassInsets() const { int frame_height = display::win::ScreenWin::GetSystemMetricsInDIP(SM_CYSIZEFRAME) + @@ -34,7 +49,7 @@ gfx::Insets WinFrameView::GetGlassInsets() const { return gfx::Insets(frame_height, frame_size, frame_size, frame_size); } -gfx::Insets WinFrameView::GetClientAreaInsets(HMONITOR monitor) const { +gfx::Insets WinFrameView::GetClientAreaInsets() const { gfx::Insets insets; if (base::win::GetVersion() < base::win::Version::WIN10) { // This tells Windows that most of the window is a client area, meaning @@ -47,7 +62,10 @@ gfx::Insets WinFrameView::GetClientAreaInsets(HMONITOR monitor) const { int border_thickness = 1; insets.Set(0, 0, border_thickness, border_thickness); } else { - const int frame_thickness = ui::GetFrameThickness(monitor); + const int frame_thickness = ui::GetFrameThickness(GetMonitor()); + // Reduce the Windows non-client border size because we extend the border + // into our client area in UpdateDWMFrame(). The top inset must be 0 or + // else Windows will draw a full native titlebar outside the client area. insets.Set(0, frame_thickness, frame_thickness, frame_thickness); } return insets; @@ -56,9 +74,7 @@ gfx::Insets WinFrameView::GetClientAreaInsets(HMONITOR monitor) const { gfx::Rect WinFrameView::GetWindowBoundsForClientBounds( const gfx::Rect& client_bounds) const { if (window_->IsMaximized() && !window_->has_frame()) { - gfx::Insets insets = GetGlassInsets(); - insets += GetClientAreaInsets( - MonitorFromWindow(HWNDForView(this), MONITOR_DEFAULTTONEAREST)); + gfx::Insets insets = GetGlassInsets() + GetClientAreaInsets(); gfx::Rect result(client_bounds); result.Inset(-insets); return result; @@ -99,4 +115,8 @@ const char* WinFrameView::GetClassName() const { return kViewClassName; } +HMONITOR WinFrameView::GetMonitor() const { + return ::MonitorFromWindow(HWNDForView(this), MONITOR_DEFAULTTONEAREST); +} + } // namespace electron diff --git a/shell/browser/ui/views/win_frame_view.h b/shell/browser/ui/views/win_frame_view.h index b2b1b7c5634df..6e89ab0363460 100644 --- a/shell/browser/ui/views/win_frame_view.h +++ b/shell/browser/ui/views/win_frame_view.h @@ -15,8 +15,12 @@ class WinFrameView : public FramelessView { WinFrameView(); ~WinFrameView() override; + // Get frame metrics in pixels. + gfx::Insets GetGlassInsetsInPixels() const; + + // Get frame metrics in DIP. gfx::Insets GetGlassInsets() const; - gfx::Insets GetClientAreaInsets(HMONITOR monitor) const; + gfx::Insets GetClientAreaInsets() const; // views::NonClientFrameView: gfx::Rect GetBoundsForClientView() const override; @@ -29,6 +33,8 @@ class WinFrameView : public FramelessView { const char* GetClassName() const override; private: + HMONITOR GetMonitor() const; + DISALLOW_COPY_AND_ASSIGN(WinFrameView); }; diff --git a/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc b/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc index dd22053cc80ae..bb14505353248 100644 --- a/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc +++ b/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc @@ -48,11 +48,7 @@ bool ElectronDesktopWindowTreeHostWin::GetDwmFrameInsetsInPixels( if (IsMaximized() && !native_window_view_->has_frame()) { WinFrameView* frame = static_cast( native_window_view_->widget()->non_client_view()->frame_view()); - *insets = frame->GetGlassInsets(); - // The DWM API's expect values in pixels. We need to convert from DIP to - // pixels here. - *insets = insets->Scale( - display::win::ScreenWin::GetScaleFactorForHWND(HWNDForView(frame))); + *insets = frame->GetGlassInsetsInPixels(); return true; } return false; @@ -64,7 +60,7 @@ bool ElectronDesktopWindowTreeHostWin::GetClientAreaInsets( if (IsMaximized() && !native_window_view_->has_frame()) { WinFrameView* frame = static_cast( native_window_view_->widget()->non_client_view()->frame_view()); - *insets = frame->GetClientAreaInsets(monitor); + *insets = frame->GetClientAreaInsets(); return true; } return false; From 5c39e2326120f13d113484e9cd05606bd2a5c87a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 28 Aug 2020 17:37:31 +0900 Subject: [PATCH 5/6] remove unused code --- shell/browser/ui/views/win_frame_view.cc | 79 +++---------------- shell/browser/ui/views/win_frame_view.h | 10 --- .../electron_desktop_window_tree_host_win.cc | 35 ++++++-- 3 files changed, 41 insertions(+), 83 deletions(-) diff --git a/shell/browser/ui/views/win_frame_view.cc b/shell/browser/ui/views/win_frame_view.cc index 33162587b49c3..1231608de215f 100644 --- a/shell/browser/ui/views/win_frame_view.cc +++ b/shell/browser/ui/views/win_frame_view.cc @@ -4,39 +4,17 @@ #include "shell/browser/ui/views/win_frame_view.h" -#include - #include "base/win/windows_version.h" #include "shell/browser/native_window_views.h" -#include "ui/base/win/hwnd_metrics.h" #include "ui/display/win/screen_win.h" #include "ui/views/widget/widget.h" #include "ui/views/win/hwnd_util.h" namespace electron { -const char WinFrameView::kViewClassName[] = "WinFrameView"; - -WinFrameView::WinFrameView() {} +namespace { -WinFrameView::~WinFrameView() {} - -gfx::Insets WinFrameView::GetGlassInsetsInPixels() const { - // Note that we should explicitly get metrics for monitor, instead of scaling - // from the DIP results, otherwise results might be wrong. - HMONITOR monitor = GetMonitor(); - int frame_height = display::win::ScreenWin::GetSystemMetricsForMonitor( - monitor, SM_CYSIZEFRAME) + - display::win::ScreenWin::GetSystemMetricsForMonitor( - monitor, SM_CXPADDEDBORDER); - int frame_size = base::win::GetVersion() < base::win::Version::WIN10 - ? display::win::ScreenWin::GetSystemMetricsForMonitor( - monitor, SM_CXSIZEFRAME) - : 0; - return gfx::Insets(frame_height, frame_size, frame_size, frame_size); -} - -gfx::Insets WinFrameView::GetGlassInsets() const { +gfx::Insets GetGlassInsets() { int frame_height = display::win::ScreenWin::GetSystemMetricsInDIP(SM_CYSIZEFRAME) + display::win::ScreenWin::GetSystemMetricsInDIP(SM_CXPADDEDBORDER); @@ -49,40 +27,19 @@ gfx::Insets WinFrameView::GetGlassInsets() const { return gfx::Insets(frame_height, frame_size, frame_size, frame_size); } -gfx::Insets WinFrameView::GetClientAreaInsets() const { - gfx::Insets insets; - if (base::win::GetVersion() < base::win::Version::WIN10) { - // This tells Windows that most of the window is a client area, meaning - // Chrome will draw it. Windows still fills in the glass bits because of the - // DwmExtendFrameIntoClientArea call in |UpdateDWMFrame|. - // Without this 1 pixel offset on the right and bottom: - // * windows paint in a more standard way, and - // * we get weird black bars at the top when maximized in multiple monitor - // configurations. - int border_thickness = 1; - insets.Set(0, 0, border_thickness, border_thickness); - } else { - const int frame_thickness = ui::GetFrameThickness(GetMonitor()); - // Reduce the Windows non-client border size because we extend the border - // into our client area in UpdateDWMFrame(). The top inset must be 0 or - // else Windows will draw a full native titlebar outside the client area. - insets.Set(0, frame_thickness, frame_thickness, frame_thickness); - } - return insets; -} +} // namespace + +const char WinFrameView::kViewClassName[] = "WinFrameView"; + +WinFrameView::WinFrameView() {} + +WinFrameView::~WinFrameView() {} gfx::Rect WinFrameView::GetWindowBoundsForClientBounds( const gfx::Rect& client_bounds) const { - if (window_->IsMaximized() && !window_->has_frame()) { - gfx::Insets insets = GetGlassInsets() + GetClientAreaInsets(); - gfx::Rect result(client_bounds); - result.Inset(-insets); - return result; - } else { - return views::GetWindowBoundsForClientBounds( - static_cast(const_cast(this)), - client_bounds); - } + return views::GetWindowBoundsForClientBounds( + static_cast(const_cast(this)), + client_bounds); } gfx::Rect WinFrameView::GetBoundsForClientView() const { @@ -96,14 +53,6 @@ gfx::Rect WinFrameView::GetBoundsForClientView() const { } } -gfx::Size WinFrameView::CalculatePreferredSize() const { - gfx::Size pref = frame_->client_view()->GetPreferredSize(); - gfx::Rect bounds(pref); - return frame_->non_client_view() - ->GetWindowBoundsForClientBounds(bounds) - .size(); -} - int WinFrameView::NonClientHitTest(const gfx::Point& point) { if (window_->has_frame()) return frame_->client_view()->NonClientHitTest(point); @@ -115,8 +64,4 @@ const char* WinFrameView::GetClassName() const { return kViewClassName; } -HMONITOR WinFrameView::GetMonitor() const { - return ::MonitorFromWindow(HWNDForView(this), MONITOR_DEFAULTTONEAREST); -} - } // namespace electron diff --git a/shell/browser/ui/views/win_frame_view.h b/shell/browser/ui/views/win_frame_view.h index 6e89ab0363460..a77dfa95bf7b3 100644 --- a/shell/browser/ui/views/win_frame_view.h +++ b/shell/browser/ui/views/win_frame_view.h @@ -15,26 +15,16 @@ class WinFrameView : public FramelessView { WinFrameView(); ~WinFrameView() override; - // Get frame metrics in pixels. - gfx::Insets GetGlassInsetsInPixels() const; - - // Get frame metrics in DIP. - gfx::Insets GetGlassInsets() const; - gfx::Insets GetClientAreaInsets() const; - // views::NonClientFrameView: gfx::Rect GetBoundsForClientView() const override; gfx::Rect GetWindowBoundsForClientBounds( const gfx::Rect& client_bounds) const override; int NonClientHitTest(const gfx::Point& point) override; - gfx::Size CalculatePreferredSize() const override; // views::View: const char* GetClassName() const override; private: - HMONITOR GetMonitor() const; - DISALLOW_COPY_AND_ASSIGN(WinFrameView); }; diff --git a/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc b/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc index bb14505353248..b28009c842d6e 100644 --- a/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc +++ b/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc @@ -4,6 +4,7 @@ #include "shell/browser/ui/win/electron_desktop_window_tree_host_win.h" +#include "base/win/windows_version.h" #include "shell/browser/ui/views/win_frame_view.h" #include "ui/base/win/hwnd_metrics.h" #include "ui/base/win/shell.h" @@ -46,9 +47,17 @@ bool ElectronDesktopWindowTreeHostWin::HasNativeFrame() const { bool ElectronDesktopWindowTreeHostWin::GetDwmFrameInsetsInPixels( gfx::Insets* insets) const { if (IsMaximized() && !native_window_view_->has_frame()) { - WinFrameView* frame = static_cast( - native_window_view_->widget()->non_client_view()->frame_view()); - *insets = frame->GetGlassInsetsInPixels(); + HMONITOR monitor = ::MonitorFromWindow( + native_window_view_->GetAcceleratedWidget(), MONITOR_DEFAULTTONEAREST); + int frame_height = display::win::ScreenWin::GetSystemMetricsForMonitor( + monitor, SM_CYSIZEFRAME) + + display::win::ScreenWin::GetSystemMetricsForMonitor( + monitor, SM_CXPADDEDBORDER); + int frame_size = base::win::GetVersion() < base::win::Version::WIN10 + ? display::win::ScreenWin::GetSystemMetricsForMonitor( + monitor, SM_CXSIZEFRAME) + : 0; + insets->Set(frame_height, frame_size, frame_size, frame_size); return true; } return false; @@ -58,9 +67,23 @@ bool ElectronDesktopWindowTreeHostWin::GetClientAreaInsets( gfx::Insets* insets, HMONITOR monitor) const { if (IsMaximized() && !native_window_view_->has_frame()) { - WinFrameView* frame = static_cast( - native_window_view_->widget()->non_client_view()->frame_view()); - *insets = frame->GetClientAreaInsets(); + if (base::win::GetVersion() < base::win::Version::WIN10) { + // This tells Windows that most of the window is a client area, meaning + // Chrome will draw it. Windows still fills in the glass bits because of + // the // DwmExtendFrameIntoClientArea call in |UpdateDWMFrame|. + // Without this 1 pixel offset on the right and bottom: + // * windows paint in a more standard way, and + // * we get weird black bars at the top when maximized in multiple + // monitor configurations. + int border_thickness = 1; + insets->Set(0, 0, border_thickness, border_thickness); + } else { + const int frame_thickness = ui::GetFrameThickness(monitor); + // Reduce the Windows non-client border size because we extend the border + // into our client area in UpdateDWMFrame(). The top inset must be 0 or + // else Windows will draw a full native titlebar outside the client area. + insets->Set(0, frame_thickness, frame_thickness, frame_thickness); + } return true; } return false; From b75aad39f587d13ae4930be1a341abe3a292da75 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 31 Aug 2020 10:52:25 +0900 Subject: [PATCH 6/6] Windows 8 and 10 use the same DWM frame calculation --- shell/browser/ui/views/win_frame_view.cc | 2 +- shell/browser/ui/win/electron_desktop_window_tree_host_win.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/shell/browser/ui/views/win_frame_view.cc b/shell/browser/ui/views/win_frame_view.cc index 1231608de215f..93c56f192a4fd 100644 --- a/shell/browser/ui/views/win_frame_view.cc +++ b/shell/browser/ui/views/win_frame_view.cc @@ -20,7 +20,7 @@ gfx::Insets GetGlassInsets() { display::win::ScreenWin::GetSystemMetricsInDIP(SM_CXPADDEDBORDER); int frame_size = - base::win::GetVersion() < base::win::Version::WIN10 + base::win::GetVersion() < base::win::Version::WIN8 ? display::win::ScreenWin::GetSystemMetricsInDIP(SM_CXSIZEFRAME) : 0; diff --git a/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc b/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc index b28009c842d6e..2cd84295fcdc3 100644 --- a/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc +++ b/shell/browser/ui/win/electron_desktop_window_tree_host_win.cc @@ -53,7 +53,7 @@ bool ElectronDesktopWindowTreeHostWin::GetDwmFrameInsetsInPixels( monitor, SM_CYSIZEFRAME) + display::win::ScreenWin::GetSystemMetricsForMonitor( monitor, SM_CXPADDEDBORDER); - int frame_size = base::win::GetVersion() < base::win::Version::WIN10 + int frame_size = base::win::GetVersion() < base::win::Version::WIN8 ? display::win::ScreenWin::GetSystemMetricsForMonitor( monitor, SM_CXSIZEFRAME) : 0; @@ -67,7 +67,7 @@ bool ElectronDesktopWindowTreeHostWin::GetClientAreaInsets( gfx::Insets* insets, HMONITOR monitor) const { if (IsMaximized() && !native_window_view_->has_frame()) { - if (base::win::GetVersion() < base::win::Version::WIN10) { + if (base::win::GetVersion() < base::win::Version::WIN8) { // This tells Windows that most of the window is a client area, meaning // Chrome will draw it. Windows still fills in the glass bits because of // the // DwmExtendFrameIntoClientArea call in |UpdateDWMFrame|.