summaryrefslogtreecommitdiffstats
path: root/views
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-23 07:12:26 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-23 07:12:26 +0000
commitc38ba0250a72f17c2b5caed4dc96dcca8db927b2 (patch)
tree2b96576c37cb39ef75d2d4f30d69c4cc049527a4 /views
parent1c12ae7b1d3af2578e0fa8411bf70e5e627eebfe (diff)
downloadchromium_src-c38ba0250a72f17c2b5caed4dc96dcca8db927b2.zip
chromium_src-c38ba0250a72f17c2b5caed4dc96dcca8db927b2.tar.gz
chromium_src-c38ba0250a72f17c2b5caed4dc96dcca8db927b2.tar.bz2
Make sure the RootView is sized to the correct bounds when the opaque frame is maximized.It seems that now, when an opaque frame is maximized we also need to add the SM_CXSIZEFRAME to the top of the client rect. I don't know why, it's just is.I reworked the way Widget allows subclasses to handle sizing of the RootView... I delegate responsibility for determining the RootView's bounds to a helper virtual function which BrowserFrameWin overrides. This seems cleaner to me. I make sure this handling only occurs when the window is not maximized.http://crbug.com/25227TEST=use to a theme or switch off glass on vista or use Xp. Maximize the browser window. The tabs should be entirely visible.
Review URL: http://codereview.chromium.org/304007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29882 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-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
4 files changed, 97 insertions, 30 deletions
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 {