diff --git a/shell/browser/ui/views/win_frame_view.cc b/shell/browser/ui/views/win_frame_view.cc index 61f72e4aad8e0..93c56f192a4fd 100644 --- a/shell/browser/ui/views/win_frame_view.cc +++ b/shell/browser/ui/views/win_frame_view.cc @@ -4,12 +4,31 @@ #include "shell/browser/ui/views/win_frame_view.h" +#include "base/win/windows_version.h" #include "shell/browser/native_window_views.h" +#include "ui/display/win/screen_win.h" #include "ui/views/widget/widget.h" #include "ui/views/win/hwnd_util.h" namespace electron { +namespace { + +gfx::Insets GetGlassInsets() { + int frame_height = + display::win::ScreenWin::GetSystemMetricsInDIP(SM_CYSIZEFRAME) + + display::win::ScreenWin::GetSystemMetricsInDIP(SM_CXPADDEDBORDER); + + int frame_size = + base::win::GetVersion() < base::win::Version::WIN8 + ? display::win::ScreenWin::GetSystemMetricsInDIP(SM_CXSIZEFRAME) + : 0; + + return gfx::Insets(frame_height, frame_size, frame_size, frame_size); +} + +} // namespace + const char WinFrameView::kViewClassName[] = "WinFrameView"; WinFrameView::WinFrameView() {} @@ -23,6 +42,17 @@ gfx::Rect WinFrameView::GetWindowBoundsForClientBounds( client_bounds); } +gfx::Rect WinFrameView::GetBoundsForClientView() const { + if (window_->IsMaximized() && !window_->has_frame()) { + gfx::Insets insets = GetGlassInsets(); + gfx::Rect result(width(), height()); + result.Inset(insets); + return result; + } else { + return bounds(); + } +} + int WinFrameView::NonClientHitTest(const gfx::Point& point) { if (window_->has_frame()) return frame_->client_view()->NonClientHitTest(point); diff --git a/shell/browser/ui/views/win_frame_view.h b/shell/browser/ui/views/win_frame_view.h index 884a13e506c3e..a77dfa95bf7b3 100644 --- a/shell/browser/ui/views/win_frame_view.h +++ b/shell/browser/ui/views/win_frame_view.h @@ -16,6 +16,7 @@ class WinFrameView : public FramelessView { ~WinFrameView() override; // views::NonClientFrameView: + gfx::Rect GetBoundsForClientView() const override; gfx::Rect GetWindowBoundsForClientBounds( const gfx::Rect& client_bounds) const override; int NonClientHitTest(const gfx::Point& point) 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..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 @@ -4,7 +4,12 @@ #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" +#include "ui/display/win/screen_win.h" +#include "ui/views/win/hwnd_util.h" namespace electron { @@ -36,18 +41,49 @@ 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()) { + 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::WIN8 + ? display::win::ScreenWin::GetSystemMetricsForMonitor( + monitor, SM_CXSIZEFRAME) + : 0; + insets->Set(frame_height, frame_size, frame_size, frame_size); + 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); + 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|. + // 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; 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;