summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-06 17:33:14 +0000
committerpkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-06 17:33:14 +0000
commit08090a8f2588b1e03c3766fd676b5a19824d5b62 (patch)
treef239d61a904d90c2fb29c94d5eab950e5d759b70
parent76b5257c62a4b7e0d70e734f0d29071323ed137c (diff)
downloadchromium_src-08090a8f2588b1e03c3766fd676b5a19824d5b62.zip
chromium_src-08090a8f2588b1e03c3766fd676b5a19824d5b62.tar.gz
chromium_src-08090a8f2588b1e03c3766fd676b5a19824d5b62.tar.bz2
Support custom border widths. Allow user to resize the window (instead of doing nothing) when over our client edge graphics. Make resize corner behavior on XP more native. More cleanup.
BUG=5054 Review URL: http://codereview.chromium.org/21116 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9315 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/views/frame/aero_glass_frame.cc87
-rw-r--r--chrome/browser/views/frame/aero_glass_non_client_view.cc102
-rw-r--r--chrome/views/non_client_view.cc53
3 files changed, 109 insertions, 133 deletions
diff --git a/chrome/browser/views/frame/aero_glass_frame.cc b/chrome/browser/views/frame/aero_glass_frame.cc
index d78f12c..288678e 100644
--- a/chrome/browser/views/frame/aero_glass_frame.cc
+++ b/chrome/browser/views/frame/aero_glass_frame.cc
@@ -15,14 +15,10 @@
// static
-// The width of the sizing borders.
-static const int kResizeBorder = 8;
// The width of the client edge to the left and right of the window.
-static const int kWindowHorizontalClientEdgeWidth = 3;
+static const int kClientEdgeWidth = 3;
// The height of the client edge to the bottom of the window.
-static const int kWindowBottomClientEdgeHeight = 2;
-// By how much the toolbar overlaps with the tab strip.
-static const int kToolbarOverlapVertOffset = 5;
+static const int kClientEdgeHeight = 2;
HICON AeroGlassFrame::throbber_icons_[AeroGlassFrame::kThrobberIconCount];
@@ -130,9 +126,11 @@ LRESULT AeroGlassFrame::OnNCActivate(BOOL active) {
return TRUE;
if (!frame_initialized_) {
- ::SetWindowPos(GetHWND(), NULL, 0, 0, 0, 0,
- SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
- UpdateDWMFrame();
+ if (browser_view_->IsTabStripVisible()) {
+ ::SetWindowPos(GetHWND(), NULL, 0, 0, 0, 0,
+ SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
+ UpdateDWMFrame();
+ }
frame_initialized_ = true;
}
browser_view_->ActivationChanged(!!active);
@@ -141,34 +139,20 @@ LRESULT AeroGlassFrame::OnNCActivate(BOOL active) {
}
LRESULT AeroGlassFrame::OnNCCalcSize(BOOL mode, LPARAM l_param) {
- // By default the client side is set to the window size which is what
- // we want.
- if (browser_view_->IsTabStripVisible() && mode == TRUE) {
- // Calculate new NCCALCSIZE_PARAMS based on custom NCA inset.
- NCCALCSIZE_PARAMS* params = reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param);
-
- // Hack necessary to stop black background flicker, we cut out
- // resizeborder here to save us from having to do too much
- // addition and subtraction in Layout(). We don't cut off the
- // top + titlebar as that prevents the window controls from
- // highlighting.
- params->rgrc[0].left +=
- (kResizeBorder - kWindowHorizontalClientEdgeWidth);
- params->rgrc[0].right -=
- (kResizeBorder - kWindowHorizontalClientEdgeWidth);
- params->rgrc[0].bottom -=
- (kResizeBorder - kWindowBottomClientEdgeHeight);
-
- SetMsgHandled(TRUE);
-
- // We need to reset the frame, as Vista resets it whenever it changes
- // composition modes (and NCCALCSIZE is the closest thing we get to
- // a reliable message about the change).
- UpdateDWMFrame();
-
+ if (!browser_view_->IsTabStripVisible() || !mode) {
+ SetMsgHandled(FALSE);
return 0;
}
- SetMsgHandled(FALSE);
+
+ NCCALCSIZE_PARAMS* params = reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param);
+ int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
+ params->rgrc[0].left += (border_thickness - kClientEdgeWidth);
+ params->rgrc[0].right -= (border_thickness - kClientEdgeWidth);
+ params->rgrc[0].bottom -= (border_thickness - kClientEdgeHeight);
+
+ UpdateDWMFrame();
+
+ SetMsgHandled(TRUE);
return 0;
}
@@ -196,31 +180,14 @@ void AeroGlassFrame::UpdateDWMFrame() {
if (!client_view())
return;
- // We only adjust the DWM's glass rendering when we're a browser window.
- // Popups and app windows get the standard client edge.
- if (browser_view_->IsTabStripVisible()) {
- // By default, we just want to adjust the glass by the width of the inner
- // bevel that aero renders to demarcate the client area. We supply our own
- // client edge for the browser window and detached popups, so we don't want
- // to show the default one.
- int client_edge_left_width = kWindowHorizontalClientEdgeWidth + 1;
- int client_edge_right_width = kWindowHorizontalClientEdgeWidth + 1;
- int client_edge_bottom_height = kWindowBottomClientEdgeHeight + 1;
- int client_edge_top_height = kWindowBottomClientEdgeHeight;
- if (browser_view_->IsTabStripVisible()) {
- gfx::Rect tabstrip_bounds =
- GetBoundsForTabStrip(browser_view_->tabstrip());
- client_edge_top_height = tabstrip_bounds.bottom();
- }
-
- // Now poke the DWM.
- MARGINS margins = { client_edge_left_width, client_edge_right_width,
- client_edge_top_height, client_edge_bottom_height };
- // Note: we don't use DwmEnableBlurBehindWindow because any region not
- // included in the glass region is composited source over. This means
- // that anything drawn directly with GDI appears fully transparent.
- DwmExtendFrameIntoClientArea(GetHWND(), &margins);
- }
+ MARGINS margins = { kClientEdgeWidth + 1,
+ kClientEdgeWidth + 1,
+ GetBoundsForTabStrip(browser_view_->tabstrip()).bottom(),
+ kClientEdgeHeight + 1 };
+ // Note: we don't use DwmEnableBlurBehindWindow because any region not
+ // included in the glass region is composited source over. This means
+ // that anything drawn directly with GDI appears fully transparent.
+ DwmExtendFrameIntoClientArea(GetHWND(), &margins);
}
AeroGlassNonClientView* AeroGlassFrame::GetAeroGlassNonClientView() const {
diff --git a/chrome/browser/views/frame/aero_glass_non_client_view.cc b/chrome/browser/views/frame/aero_glass_non_client_view.cc
index 6f1098b..d897b91 100644
--- a/chrome/browser/views/frame/aero_glass_non_client_view.cc
+++ b/chrome/browser/views/frame/aero_glass_non_client_view.cc
@@ -89,13 +89,13 @@ SkBitmap AeroGlassWindowResources::app_top_right_;
AeroGlassWindowResources* AeroGlassNonClientView::resources_ = NULL;
SkBitmap AeroGlassNonClientView::distributor_logo_;
-// The distance between the top of the TabStrip and the top of the non-client
-// area of the window.
-static const int kNoTitleTopSpacing = 8;
// The width of the client edge to the left and right of the window.
-static const int kWindowHorizontalClientEdgeWidth = 3;
+static const int kClientEdgeWidth = 3;
// The height of the client edge to the bottom of the window.
-static const int kWindowBottomClientEdgeHeight = 2;
+static const int kClientEdgeHeight = 2;
+// In the window corners, the resize areas don't actually expand bigger, but the
+// 16 px at the end of the top and bottom edges triggers diagonal resizing.
+const int kResizeEdgeWidth = 16;
// The horizontal distance between the left of the minimize button and the
// right edge of the distributor logo.
static const int kDistributorLogoHorizontalOffset = 7;
@@ -109,8 +109,6 @@ static const int kTabStripY = 19;
static const int kTabStripRightHorizOffset = 30;
// A single pixel.
static const int kPixel = 1;
-// The height of the sizing border.
-static const int kWindowSizingBorderSize = 8;
// The size (width/height) of the window icon.
static const int kWindowIconSize = 16;
// In maximized mode, the OTR avatar starts 2 px below the top of the screen, so
@@ -139,8 +137,7 @@ AeroGlassNonClientView::~AeroGlassNonClientView() {
gfx::Rect AeroGlassNonClientView::GetBoundsForTabStrip(TabStrip* tabstrip) {
int tabstrip_x = browser_view_->ShouldShowOffTheRecordAvatar() ?
- (otr_avatar_bounds_.right() + kOTRSideSpacing) :
- kWindowHorizontalClientEdgeWidth;
+ (otr_avatar_bounds_.right() + kOTRSideSpacing) : kClientEdgeWidth;
int tabstrip_width = width() - tabstrip_x - kTabStripRightHorizOffset -
(frame_->IsMaximized() ? frame_->GetMinimizeButtonOffset() : 0);
int tabstrip_y =
@@ -158,17 +155,17 @@ gfx::Rect AeroGlassNonClientView::CalculateClientAreaBounds(int win_width,
return gfx::Rect(0, 0, width(), height());
int top_margin = CalculateNonClientTopHeight();
- return gfx::Rect(kWindowHorizontalClientEdgeWidth, top_margin,
- std::max(0, win_width - (2 * kWindowHorizontalClientEdgeWidth)),
- std::max(0, win_height - top_margin - kWindowBottomClientEdgeHeight));
+ return gfx::Rect(kClientEdgeWidth, top_margin,
+ std::max(0, win_width - (2 * kClientEdgeWidth)),
+ std::max(0, win_height - top_margin - kClientEdgeHeight));
}
gfx::Size AeroGlassNonClientView::CalculateWindowSizeForClientSize(
int width,
int height) const {
int top_margin = CalculateNonClientTopHeight();
- return gfx::Size(width + (2 * kWindowHorizontalClientEdgeWidth),
- height + top_margin + kWindowBottomClientEdgeHeight);
+ return gfx::Size(width + (2 * kClientEdgeWidth),
+ height + top_margin + kClientEdgeHeight);
}
CPoint AeroGlassNonClientView::GetSystemMenuPoint() const {
@@ -178,35 +175,49 @@ CPoint AeroGlassNonClientView::GetSystemMenuPoint() const {
}
int AeroGlassNonClientView::NonClientHitTest(const gfx::Point& point) {
- CRect bounds;
- CPoint test_point = point.ToPOINT();
+ // If we don't have a tabstrip, we haven't customized the frame, so Windows
+ // can figure this out. If the point isn't within our bounds, then it's in
+ // the native portion of the frame, so again Windows can figure it out.
+ if (!browser_view_->IsTabStripVisible() || !bounds().Contains(point))
+ return HTNOWHERE;
// See if the client view intersects the non-client area (e.g. blank areas
// of the TabStrip).
- int component = frame_->client_view()->NonClientHitTest(point);
- if (component != HTNOWHERE)
- return component;
-
- // This check is only done when we have a tabstrip, which is the only time
- // that we have a non-standard non-client area.
- if (browser_view_->IsTabStripVisible()) {
- // Because we tell Windows that our client area extends all the way to the
- // top of the browser window, but our BrowserView doesn't actually go up that
- // high, we need to make sure the right hit-test codes are returned for the
- // caption area above the tabs and the top sizing border.
- int client_view_right =
- frame_->client_view()->x() + frame_->client_view()->width();
- if (point.x() >= frame_->client_view()->x() &&
- point.x() < client_view_right) {
- if (point.y() < kWindowSizingBorderSize)
- return HTTOP;
- if (point.y() < (y() + height()))
- return HTCAPTION;
- }
+ int frame_component = frame_->client_view()->NonClientHitTest(point);
+ if (frame_component != HTNOWHERE)
+ return frame_component;
+
+ int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
+ int resize_width = kResizeEdgeWidth - border_thickness;
+ if (point.x() < kClientEdgeWidth) {
+ if (point.y() < border_thickness)
+ return HTTOPLEFT;
+ if (point.y() >= (height() - kClientEdgeHeight))
+ return HTBOTTOMLEFT;
+ return HTLEFT;
}
-
- // Let Windows figure it out.
- return HTNOWHERE;
+ if (point.x() >= (width() - kClientEdgeWidth)) {
+ if (point.y() < border_thickness)
+ return HTTOPRIGHT;
+ if (point.y() >= (height() - kClientEdgeHeight))
+ return HTBOTTOMRIGHT;
+ return HTRIGHT;
+ }
+ if (point.y() < border_thickness) {
+ if (point.x() < resize_width)
+ return HTTOPLEFT;
+ if (point.x() >= (width() - resize_width))
+ return HTTOPRIGHT;
+ return HTTOP;
+ }
+ if (point.y() >= (height() - kClientEdgeHeight)) {
+ if (point.x() < resize_width)
+ return HTBOTTOMLEFT;
+ if (point.x() >= (width() - resize_width))
+ return HTBOTTOMRIGHT;
+ return HTBOTTOM;
+ }
+ return HTCAPTION;
}
void AeroGlassNonClientView::GetWindowMask(const gfx::Size& size,
@@ -242,9 +253,8 @@ void AeroGlassNonClientView::Layout() {
gfx::Size AeroGlassNonClientView::GetPreferredSize() {
gfx::Size prefsize = frame_->client_view()->GetPreferredSize();
- prefsize.Enlarge(2 * kWindowHorizontalClientEdgeWidth,
- CalculateNonClientTopHeight() +
- kWindowBottomClientEdgeHeight);
+ prefsize.Enlarge(2 * kClientEdgeWidth,
+ CalculateNonClientTopHeight() + kClientEdgeHeight);
return prefsize;
}
@@ -262,9 +272,8 @@ void AeroGlassNonClientView::ViewHierarchyChanged(bool is_add,
// AeroGlassNonClientView, private:
int AeroGlassNonClientView::CalculateNonClientTopHeight() const {
- if (frame_->window_delegate()->ShouldShowWindowTitle())
- return browser_view_->IsToolbarVisible() ? -1 : 0;
- return kNoTitleTopSpacing;
+ return browser_view_->IsTabStripVisible() ?
+ GetSystemMetrics(SM_CYSIZEFRAME) : 0;
}
void AeroGlassNonClientView::PaintOTRAvatar(ChromeCanvas* canvas) {
@@ -373,8 +382,7 @@ void AeroGlassNonClientView::LayoutOTRAvatar() {
int otr_height = frame_->IsMaximized() ?
(tabstrip_height - kOTRMaximizedTopSpacing) :
otr_avatar_icon.height();
- otr_avatar_bounds_.SetRect(
- kWindowHorizontalClientEdgeWidth + kOTRSideSpacing,
+ otr_avatar_bounds_.SetRect(kClientEdgeWidth + kOTRSideSpacing,
top_height + tabstrip_height - otr_height, otr_avatar_icon.width(),
otr_height);
}
diff --git a/chrome/views/non_client_view.cc b/chrome/views/non_client_view.cc
index cbf5636..91dd070 100644
--- a/chrome/views/non_client_view.cc
+++ b/chrome/views/non_client_view.cc
@@ -13,46 +13,47 @@ int NonClientView::GetHTComponentForFrame(const gfx::Point& point,
int resize_border_thickness,
int resize_corner_size,
bool can_resize) {
- int component = HTNOWHERE;
+ // Tricky: In XP, native behavior is to return HTTOPLEFT and HTTOPRIGHT for
+ // a |resize_corner_size|-length strip of both the side and top borders, but
+ // only to return HTBOTTOMLEFT/HTBOTTOMRIGHT along the bottom border + corner
+ // (not the side border). Vista goes further and doesn't return these on any
+ // of the side borders. Here we copy the XP behavior.
+ int component;
if (point.x() < resize_border_thickness) {
- if (point.y() < resize_corner_size) {
+ if (point.y() < resize_corner_size)
component = HTTOPLEFT;
- } else if (point.y() >= (height() - resize_corner_size)) {
+ else if (point.y() >= (height() - resize_border_thickness))
component = HTBOTTOMLEFT;
- } else {
+ else
component = HTLEFT;
- }
- } else if (point.x() < resize_corner_size) {
- if (point.y() < top_resize_border_height) {
- component = HTTOPLEFT;
- } else if (point.y() >= (height() - resize_border_thickness)) {
- component = HTBOTTOMLEFT;
- }
} else if (point.x() >= (width() - resize_border_thickness)) {
- if (point.y() < resize_corner_size) {
+ if (point.y() < resize_corner_size)
component = HTTOPRIGHT;
- } else if (point.y() >= (height() - resize_corner_size)) {
+ else if (point.y() >= (height() - resize_border_thickness))
component = HTBOTTOMRIGHT;
- } else {
+ else
component = HTRIGHT;
- }
- } else if (point.x() >= (width() - resize_corner_size)) {
- if (point.y() < top_resize_border_height) {
- component = HTTOPRIGHT;
- } else if (point.y() >= (height() - resize_border_thickness)) {
- component = HTBOTTOMRIGHT;
- }
} else if (point.y() < top_resize_border_height) {
- component = HTTOP;
+ if (point.x() < resize_corner_size)
+ component = HTTOPLEFT;
+ else if (point.x() >= (width() - resize_corner_size))
+ component = HTTOPRIGHT;
+ else
+ component = HTTOP;
} else if (point.y() >= (height() - resize_border_thickness)) {
- component = HTBOTTOM;
+ if (point.x() < resize_corner_size)
+ component = HTBOTTOMLEFT;
+ else if (point.x() >= (width() - resize_corner_size))
+ component = HTBOTTOMRIGHT;
+ else
+ component = HTBOTTOM;
+ } else {
+ return HTNOWHERE;
}
// If the window can't be resized, there are no resize boundaries, just
// window borders.
- if (component != HTNOWHERE)
- return can_resize ? component : HTBORDER;
- return HTNOWHERE;
+ return can_resize ? component : HTBORDER;
}
} // namespace views