summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/gfx/insets.h3
-rw-r--r--chrome/browser/views/frame/browser_frame_win.cc89
-rw-r--r--chrome/browser/views/frame/browser_frame_win.h5
-rw-r--r--views/widget/widget_win.cc29
-rw-r--r--views/widget/widget_win.h10
-rw-r--r--views/window/window_win.cc80
-rw-r--r--views/window/window_win.h8
7 files changed, 114 insertions, 110 deletions
diff --git a/app/gfx/insets.h b/app/gfx/insets.h
index 6a4ac05..6b8e9b1 100644
--- a/app/gfx/insets.h
+++ b/app/gfx/insets.h
@@ -33,6 +33,9 @@ class Insets {
// top and bottom insets.
int height() const { return top_ + bottom_; }
+ // Returns true if the insets are empty.
+ bool empty() const { return width() == 0 && height() == 0; }
+
void Set(int top, int left, int bottom, int right) {
top_ = top;
left_ = left;
diff --git a/chrome/browser/views/frame/browser_frame_win.cc b/chrome/browser/views/frame/browser_frame_win.cc
index 2616dfb..f9c1bbb 100644
--- a/chrome/browser/views/frame/browser_frame_win.cc
+++ b/chrome/browser/views/frame/browser_frame_win.cc
@@ -119,7 +119,18 @@ bool BrowserFrameWin::AlwaysUseNativeFrame() const {
}
///////////////////////////////////////////////////////////////////////////////
-// BrowserFrame, views::WidgetWin overrides:
+// BrowserFrame, views::WindowWin overrides:
+
+gfx::Insets BrowserFrameWin::GetClientAreaInsets() const {
+ if (!GetNonClientView()->UseNativeFrame())
+ return WindowWin::GetClientAreaInsets();
+
+ int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
+ // We draw our own client edge over part of the default frame.
+ if (!IsMaximized())
+ border_thickness -= kClientEdgeThickness;
+ return gfx::Insets(0, border_thickness, border_thickness, border_thickness);
+}
bool BrowserFrameWin::GetAccelerator(int cmd_id,
views::Accelerator* accelerator) {
@@ -181,78 +192,6 @@ LRESULT BrowserFrameWin::OnNCActivate(BOOL active) {
return WindowWin::OnNCActivate(active);
}
-LRESULT BrowserFrameWin::OnNCCalcSize(BOOL mode, LPARAM l_param) {
- // This class' client rect calculations are specific to the tabbed browser
- // window. When the glass frame is active, the client area is reported to be
- // a rectangle that touches the top of the window and is inset from the left,
- // right and bottom edges. The client rect touches the top because the
- // tabstrip is painted over the caption at a custom offset.
- // When the glass frame is not active, the client area is reported to be the
- // entire window rect, except for the cases noted below.
- // For non-tabbed browser windows, we use the default handling from the
- // views system.
- if (!browser_view_->IsBrowserTypeNormal())
- return WindowWin::OnNCCalcSize(mode, l_param);
-
- RECT* client_rect = mode ?
- &reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param)->rgrc[0] :
- reinterpret_cast<RECT*>(l_param);
- int border_thickness = 0;
- if (browser_view_->IsMaximized()) {
- // Make the maximized mode client rect fit the screen exactly, by
- // subtracting the border Windows automatically adds for maximized mode.
- border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
- // Find all auto-hide taskbars along the screen edges and adjust in by the
- // thickness of the auto-hide taskbar on each such edge, so the window isn't
- // treated as a "fullscreen app", which would cause the taskbars to
- // disappear.
- HMONITOR monitor = MonitorFromWindow(GetNativeView(),
- MONITOR_DEFAULTTONULL);
- if (win_util::EdgeHasTopmostAutoHideTaskbar(ABE_LEFT, monitor))
- client_rect->left += win_util::kAutoHideTaskbarThicknessPx;
- if (win_util::EdgeHasTopmostAutoHideTaskbar(ABE_RIGHT, monitor))
- client_rect->right -= win_util::kAutoHideTaskbarThicknessPx;
- if (win_util::EdgeHasTopmostAutoHideTaskbar(ABE_BOTTOM, monitor)) {
- client_rect->bottom -= win_util::kAutoHideTaskbarThicknessPx;
- } else if (win_util::EdgeHasTopmostAutoHideTaskbar(ABE_TOP, monitor)) {
- // Tricky bit. Due to a bug in DwmDefWindowProc()'s handling of
- // WM_NCHITTEST, having any nonclient area atop the window causes the
- // caption buttons to draw onscreen but not respond to mouse hover/clicks.
- // So for a taskbar at the screen top, we can't push the client_rect->top
- // down; instead, we move the bottom up by one pixel, which is the
- // smallest change we can make and still get a client area less than the
- // screen size. This is visibly ugly, but there seems to be no better
- // solution.
- --client_rect->bottom;
- }
- } else if (!browser_view_->IsFullscreen()) {
- if (GetNonClientView()->UseNativeFrame()) {
- // We draw our own client edge over part of the default frame.
- border_thickness =
- GetSystemMetrics(SM_CXSIZEFRAME) - kClientEdgeThickness;
- } else {
- // This is weird, but highly essential. If we don't offset the bottom edge
- // of the client rect, the window client area and window area will match,
- // and when returning to glass rendering mode from non-glass, the client
- // area will not paint black as transparent. This is because (and I don't
- // know why) the client area goes from matching the window rect to being
- // something else. If the client area is not the window rect in both
- // modes, the blackness doesn't occur. Because of this, we need to tell
- // the RootView to lay out to fit the window rect, rather than the client
- // rect when using the opaque frame. See SizeRootViewToWindowRect.
- --client_rect->bottom;
- }
- }
- client_rect->left += border_thickness;
- client_rect->right -= border_thickness;
- client_rect->bottom -= border_thickness;
-
- // We'd like to return WVR_REDRAW in some cases here, but because we almost
- // always have nonclient area (except in fullscreen mode, where it doesn't
- // matter), we can't. See comments in window.cc:OnNCCalcSize() for more info.
- return 0;
-}
-
LRESULT BrowserFrameWin::OnNCHitTest(const CPoint& pt) {
// Only do DWM hit-testing when we are using the native frame.
if (GetNonClientView()->UseNativeFrame()) {
@@ -320,10 +259,6 @@ ThemeProvider* BrowserFrameWin::GetDefaultThemeProvider() const {
return profile_->GetThemeProvider();
}
-bool BrowserFrameWin::SizeRootViewToWindowRect() const {
- return !GetNonClientView()->UseNativeFrame();
-}
-
///////////////////////////////////////////////////////////////////////////////
// BrowserFrame, views::CustomFrameWindow overrides:
diff --git a/chrome/browser/views/frame/browser_frame_win.h b/chrome/browser/views/frame/browser_frame_win.h
index df59f36..789795b 100644
--- a/chrome/browser/views/frame/browser_frame_win.h
+++ b/chrome/browser/views/frame/browser_frame_win.h
@@ -47,7 +47,8 @@ class BrowserFrameWin : public BrowserFrame, public views::WindowWin {
virtual bool AlwaysUseNativeFrame() const;
protected:
- // Overridden from views::WidgetWin:
+ // Overridden from views::WindowWin:
+ virtual gfx::Insets GetClientAreaInsets() const;
virtual bool GetAccelerator(int cmd_id, views::Accelerator* accelerator);
virtual void OnEndSession(BOOL ending, UINT logoff);
virtual void OnEnterSizeMove();
@@ -59,12 +60,10 @@ class BrowserFrameWin : public BrowserFrame, public views::WindowWin {
virtual void OnMove(const CPoint& point);
virtual void OnMoving(UINT param, LPRECT new_bounds);
virtual LRESULT OnNCActivate(BOOL active);
- virtual LRESULT OnNCCalcSize(BOOL mode, LPARAM l_param);
virtual LRESULT OnNCHitTest(const CPoint& pt);
virtual void OnWindowPosChanged(WINDOWPOS* window_pos);
virtual ThemeProvider* GetThemeProvider() const;
virtual ThemeProvider* GetDefaultThemeProvider() const;
- virtual bool SizeRootViewToWindowRect() const;
// Overridden from views::Window:
virtual int GetShowState() const;
diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc
index 485f1ae..15a10f2 100644
--- a/views/widget/widget_win.cc
+++ b/views/widget/widget_win.cc
@@ -834,6 +834,16 @@ void WidgetWin::OnWindowPosChanged(WINDOWPOS* window_pos) {
SetMsgHandled(FALSE);
}
+gfx::Size WidgetWin::GetRootViewSize() const {
+ CRect rect;
+ if (use_layered_buffer_)
+ GetWindowRect(&rect);
+ else
+ GetClientRect(&rect);
+
+ return gfx::Size(rect.Width(), rect.Height());
+}
+
///////////////////////////////////////////////////////////////////////////////
// WidgetWin, protected:
@@ -950,23 +960,18 @@ void WidgetWin::ProcessMouseExited() {
}
void WidgetWin::LayoutRootView() {
- CRect rect;
- if (SizeRootViewToWindowRect() || use_layered_buffer_) {
- GetWindowRect(&rect);
- } else {
- GetClientRect(&rect);
- }
+ gfx::Size size(GetRootViewSize());
if (use_layered_buffer_)
- SizeContents(rect);
+ SizeContents(size);
// Resizing changes the size of the view hierarchy and thus forces a
// complete relayout.
- root_view_->SetBounds(0, 0, rect.Width(), rect.Height());
+ root_view_->SetBounds(0, 0, size.width(), size.height());
root_view_->SchedulePaint();
if (use_layered_buffer_)
- PaintNow(gfx::Rect(rect));
+ PaintNow(gfx::Rect(0, 0, size.width(), size.height()));
}
bool WidgetWin::ReleaseCaptureOnMouseReleased() {
@@ -995,9 +1000,9 @@ Window* WidgetWin::GetWindowImpl(HWND hwnd) {
return NULL;
}
-void WidgetWin::SizeContents(const CRect& window_rect) {
- contents_.reset(new gfx::Canvas(window_rect.Width(),
- window_rect.Height(),
+void WidgetWin::SizeContents(const gfx::Size& window_size) {
+ contents_.reset(new gfx::Canvas(window_size.width(),
+ window_size.height(),
false));
}
diff --git a/views/widget/widget_win.h b/views/widget/widget_win.h
index f8ba2a5..4f79a76 100644
--- a/views/widget/widget_win.h
+++ b/views/widget/widget_win.h
@@ -387,12 +387,8 @@ class WidgetWin : public app::WindowImpl,
// behavior.
virtual void OnFinalMessage(HWND window);
- // Returns true if the RootView should be sized to the window rect instead of
- // the client rect when the widget is resized. This is true if the widget's
- // WM_NCCALCSIZE handler returns a client rect that differs from the window
- // rect but the painted content of the window should still fill the entire
- // visible window.
- virtual bool SizeRootViewToWindowRect() const { return false; }
+ // Returns the size that the RootView should be set to in LayoutRootView().
+ virtual gfx::Size GetRootViewSize() const;
// Start tracking all mouse events so that this window gets sent mouse leave
// messages too.
@@ -459,7 +455,7 @@ class WidgetWin : public app::WindowImpl,
// Resize the bitmap used to contain the contents of the layered window. This
// recreates the entire bitmap.
- void SizeContents(const CRect& window_rect);
+ void SizeContents(const gfx::Size& window_size);
// Paint into a DIB and then update the layered window with its contents.
void PaintLayeredWindow();
diff --git a/views/window/window_win.cc b/views/window/window_win.cc
index 98c4aa7..f77b806 100644
--- a/views/window/window_win.cc
+++ b/views/window/window_win.cc
@@ -528,6 +528,33 @@ void WindowWin::SizeWindowToDefault() {
false);
}
+gfx::Insets WindowWin::GetClientAreaInsets() const {
+ // Returning an empty Insets object causes the default handling in
+ // WidgetWin::OnNCCalcSize() to be invoked.
+ if (GetNonClientView()->UseNativeFrame())
+ return gfx::Insets();
+
+ if (IsMaximized()) {
+ // Windows automatically adds a standard width border to all sides when a
+ // window is maximized.
+ int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
+ return gfx::Insets(border_thickness, border_thickness, border_thickness,
+ border_thickness);
+ }
+ // This is weird, but highly essential. If we don't offset the bottom edge
+ // of the client rect, the window client area and window area will match,
+ // and when returning to glass rendering mode from non-glass, the client
+ // area will not paint black as transparent. This is because (and I don't
+ // know why) the client area goes from matching the window rect to being
+ // something else. If the client area is not the window rect in both
+ // modes, the blackness doesn't occur. Because of this, we need to tell
+ // the RootView to lay out to fit the window rect, rather than the client
+ // rect when using the opaque frame. See GetRootViewSize.
+ // Note: this is only required for non-fullscreen windows. Note that
+ // fullscreen windows are in restored state, not maximized.
+ return gfx::Insets(0, 0, IsFullscreen() ? 0 : 1, 0);
+}
+
void WindowWin::RunSystemMenu(const gfx::Point& point) {
// We need to reset and clean up any currently created system menu objects.
// We need to call this otherwise there's a small chance that we aren't going
@@ -702,20 +729,20 @@ LRESULT WindowWin::OnNCActivate(BOOL active) {
}
LRESULT WindowWin::OnNCCalcSize(BOOL mode, LPARAM l_param) {
- // We only need to adjust the client size/paint handling when we're not using
- // the native frame.
- if (non_client_view_->UseNativeFrame())
+ // We only override WM_NCCALCSIZE if we want non-standard non-client edge
+ // width.
+ gfx::Insets insets = GetClientAreaInsets();
+ if (insets.empty())
return WidgetWin::OnNCCalcSize(mode, l_param);
RECT* client_rect = mode ?
&reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param)->rgrc[0] :
reinterpret_cast<RECT*>(l_param);
+ client_rect->left += insets.left();
+ client_rect->top += insets.top();
+ client_rect->bottom -= insets.bottom();
+ client_rect->right -= insets.right();
if (IsMaximized()) {
- // Make the maximized mode client rect fit the screen exactly, by
- // subtracting the border Windows automatically adds for maximized mode.
- int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
- InflateRect(client_rect, -border_thickness, -border_thickness);
-
// Find all auto-hide taskbars along the screen edges and adjust in by the
// thickness of the auto-hide taskbar on each such edge, so the window isn't
// treated as a "fullscreen app", which would cause the taskbars to
@@ -724,8 +751,22 @@ LRESULT WindowWin::OnNCCalcSize(BOOL mode, LPARAM l_param) {
MONITOR_DEFAULTTONULL);
if (win_util::EdgeHasTopmostAutoHideTaskbar(ABE_LEFT, monitor))
client_rect->left += win_util::kAutoHideTaskbarThicknessPx;
- if (win_util::EdgeHasTopmostAutoHideTaskbar(ABE_TOP, monitor))
- client_rect->top += win_util::kAutoHideTaskbarThicknessPx;
+ if (win_util::EdgeHasTopmostAutoHideTaskbar(ABE_TOP, monitor)) {
+ if (GetNonClientView()->UseNativeFrame()) {
+ // Tricky bit. Due to a bug in DwmDefWindowProc()'s handling of
+ // WM_NCHITTEST, having any nonclient area atop the window causes the
+ // caption buttons to draw onscreen but not respond to mouse
+ // hover/clicks.
+ // So for a taskbar at the screen top, we can't push the
+ // client_rect->top down; instead, we move the bottom up by one pixel,
+ // which is the smallest change we can make and still get a client area
+ // less than the screen size. This is visibly ugly, but there seems to
+ // be no better solution.
+ --client_rect->bottom;
+ } else {
+ client_rect->top += win_util::kAutoHideTaskbarThicknessPx;
+ }
+ }
if (win_util::EdgeHasTopmostAutoHideTaskbar(ABE_RIGHT, monitor))
client_rect->right -= win_util::kAutoHideTaskbarThicknessPx;
if (win_util::EdgeHasTopmostAutoHideTaskbar(ABE_BOTTOM, monitor))
@@ -741,6 +782,11 @@ LRESULT WindowWin::OnNCCalcSize(BOOL mode, LPARAM l_param) {
// Returning WVR_REDRAW avoids an extra paint before that of the old client
// pixels in the (now wrong) location, and thus makes actions like resizing a
// window from the left edge look slightly less broken.
+ // We special case when left or top insets are 0, since these conditions
+ // actually require another repaint to correct the layout after glass gets
+ // turned on and off.
+ if (insets.left() == 0 || insets.top() == 0)
+ return 0;
return mode ? WVR_REDRAW : 0;
}
@@ -1125,6 +1171,20 @@ void WindowWin::OnWindowPosChanging(WINDOWPOS* window_pos) {
WidgetWin::OnWindowPosChanging(window_pos);
}
+gfx::Size WindowWin::GetRootViewSize() const {
+ // The native frame and maximized modes need to supply the client rect as
+ // determined by the relevant WM_NCCALCSIZE handling, so we just use the
+ // default handling which does this.
+ if (GetNonClientView()->UseNativeFrame() || IsMaximized())
+ return WidgetWin::GetRootViewSize();
+
+ // When using an opaque frame, we consider the entire window rect to be client
+ // area visually.
+ CRect rect;
+ GetWindowRect(&rect);
+ return gfx::Size(rect.Width(), rect.Height());
+}
+
////////////////////////////////////////////////////////////////////////////////
// WindowWin, private:
diff --git a/views/window/window_win.h b/views/window/window_win.h
index 96bed16..19a92d4 100644
--- a/views/window/window_win.h
+++ b/views/window/window_win.h
@@ -102,6 +102,11 @@ class WindowWin : public WidgetWin,
// Sizes the window to the default size specified by its ClientView.
virtual void SizeWindowToDefault();
+ // Returns the insets of the client area relative to the non-client area of
+ // the window. Override this function instead of OnNCCalcSize, which is
+ // crazily complicated.
+ virtual gfx::Insets GetClientAreaInsets() const;
+
// Shows the system menu at the specified screen point.
void RunSystemMenu(const gfx::Point& point);
@@ -119,7 +124,7 @@ class WindowWin : public WidgetWin,
virtual void OnInitMenu(HMENU menu);
virtual void OnMouseLeave();
virtual LRESULT OnNCActivate(BOOL active);
- virtual LRESULT OnNCCalcSize(BOOL mode, LPARAM l_param);
+ LRESULT OnNCCalcSize(BOOL mode, LPARAM l_param); // Don't override.
virtual LRESULT OnNCHitTest(const CPoint& point);
virtual void OnNCPaint(HRGN rgn);
virtual void OnNCLButtonDown(UINT ht_component, const CPoint& point);
@@ -136,6 +141,7 @@ class WindowWin : public WidgetWin,
virtual void OnWindowPosChanging(WINDOWPOS* window_pos);
virtual Window* GetWindow() { return this; }
virtual const Window* GetWindow() const { return this; }
+ virtual gfx::Size GetRootViewSize() const;
// Accessor for disable_inactive_rendering_.
bool disable_inactive_rendering() const {