diff --git a/shell/browser/ui/views/win_frame_view.cc b/shell/browser/ui/views/win_frame_view.cc index 93c56f192a4..55119cf1e42 100644 --- a/shell/browser/ui/views/win_frame_view.cc +++ b/shell/browser/ui/views/win_frame_view.cc @@ -6,29 +6,11 @@ #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() {} @@ -42,17 +24,6 @@ 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 a77dfa95bf7..884a13e506c 100644 --- a/shell/browser/ui/views/win_frame_view.h +++ b/shell/browser/ui/views/win_frame_view.h @@ -16,7 +16,6 @@ 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 2cd84295fcd..7718fd03d09 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 @@ -6,10 +6,7 @@ #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 { @@ -41,23 +38,25 @@ 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. + // See also https://github.com/electron/electron/issues/1821. return !ui::win::IsAeroGlassEnabled(); } bool ElectronDesktopWindowTreeHostWin::GetDwmFrameInsetsInPixels( gfx::Insets* insets) const { + // Set DWMFrameInsets to prevent maximized frameless window from bleeding + // into other monitors. 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); + // This would be equivalent to calling: + // DwmExtendFrameIntoClientArea({0, 0, 0, 0}); + // + // which means do not extend window frame into client area. It is almost + // a no-op, but it can tell Windows to not extend the window frame to be + // larger than current workspace. + // + // See also: + // https://devblogs.microsoft.com/oldnewthing/20150304-00/?p=44543 + *insets = gfx::Insets(); return true; } return false; @@ -66,24 +65,20 @@ bool ElectronDesktopWindowTreeHostWin::GetDwmFrameInsetsInPixels( bool ElectronDesktopWindowTreeHostWin::GetClientAreaInsets( gfx::Insets* insets, HMONITOR monitor) const { + // Windows by deafult extends the maximized window slightly larger than + // current workspace, for frameless window since the standard frame has been + // removed, the client area would then be drew outside current workspace. + // + // Indenting the client area can fix this behavior. if (IsMaximized() && !native_window_view_->has_frame()) { - 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); - } + // The insets would be eventually passed to WM_NCCALCSIZE, which takes + // the metrics under the DPI of _main_ monitor instead of current moniotr. + // + // Please make sure you tested maximized frameless window under multiple + // monitors with different DPIs before changing this code. + const int thickness = ::GetSystemMetrics(SM_CXSIZEFRAME) + + ::GetSystemMetrics(SM_CXPADDEDBORDER); + insets->Set(thickness, thickness, thickness, thickness); return true; } return false;