diff options
author | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-03 06:01:16 +0000 |
---|---|---|
committer | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-03 06:01:16 +0000 |
commit | 75b6805083c906bb17192a738b311bd21791e9f8 (patch) | |
tree | bce38efec20d50a7ef55a694f58036ae365d5e0a /views | |
parent | 2aa8b71eb688aa13a4f745027bcd4bb726bf6663 (diff) | |
download | chromium_src-75b6805083c906bb17192a738b311bd21791e9f8.zip chromium_src-75b6805083c906bb17192a738b311bd21791e9f8.tar.gz chromium_src-75b6805083c906bb17192a738b311bd21791e9f8.tar.bz2 |
Cross-platform CL to remove app/win/win_util.h&cc and related work.
See Issue 70141 for the full move details; see my inline review comments.
Changes significantly different from or beyond those prescribed by the bug:
*Consolidated a lot of GrabWindowSnapshot code.
*Moved EnsureRectIsVisibleInRect to views::internal namespace for test access.
*Moved app/win/win_util_unittest.cc to views/window/window_win_unittest.h
*Named ui/base/message_box_win.h instead of ui/base/message_box.h
*Made WindowWin::GetWindowTitleFont static; needed in static contexts.
*Denoted WindowWin::FrameTypeChanged as a Window override, moved code.
*Moved TestGrabWindowSnapshot into new file: chrome/browser/ui/window_snapshot/window_snapshot_mac_unittest.mm
BUG=70141
TEST=none
Review URL: http://codereview.chromium.org/6386009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@73589 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r-- | views/controls/textfield/native_textfield_win.cc | 36 | ||||
-rw-r--r-- | views/controls/textfield/native_textfield_win.h | 12 | ||||
-rw-r--r-- | views/controls/textfield/textfield.cc | 3 | ||||
-rw-r--r-- | views/views.gyp | 3 | ||||
-rwxr-xr-x | views/widget/monitor_win.cc | 27 | ||||
-rwxr-xr-x | views/widget/monitor_win.h | 21 | ||||
-rw-r--r-- | views/widget/tooltip_manager_win.cc | 8 | ||||
-rw-r--r-- | views/widget/widget_win.cc | 14 | ||||
-rw-r--r-- | views/window/custom_frame_view.cc | 6 | ||||
-rw-r--r-- | views/window/window_win.cc | 163 | ||||
-rw-r--r-- | views/window/window_win.h | 20 | ||||
-rw-r--r-- | views/window/window_win_unittest.cc | 58 |
12 files changed, 307 insertions, 64 deletions
diff --git a/views/controls/textfield/native_textfield_win.cc b/views/controls/textfield/native_textfield_win.cc index ecdb38f..14c5317 100644 --- a/views/controls/textfield/native_textfield_win.cc +++ b/views/controls/textfield/native_textfield_win.cc @@ -6,7 +6,6 @@ #include <algorithm> -#include "app/win/win_util.h" #include "base/i18n/rtl.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" @@ -131,6 +130,37 @@ NativeTextfieldWin::~NativeTextfieldWin() { DestroyWindow(); } +// static +bool NativeTextfieldWin::IsDoubleClick(const POINT& origin, + const POINT& current, + DWORD elapsed_time) { + // The CXDOUBLECLK and CYDOUBLECLK system metrics describe the width and + // height of a rectangle around the origin position, inside of which clicks + // within the double click time are considered double clicks. + return (elapsed_time <= GetDoubleClickTime()) && + (abs(current.x - origin.x) <= (GetSystemMetrics(SM_CXDOUBLECLK) / 2)) && + (abs(current.y - origin.y) <= (GetSystemMetrics(SM_CYDOUBLECLK) / 2)); +} + +// static +bool NativeTextfieldWin::IsNumPadDigit(int key_code, bool extended_key) { + if (key_code >= VK_NUMPAD0 && key_code <= VK_NUMPAD9) + return true; + + // Check for num pad keys without NumLock. + // Note: there is no easy way to know if a the key that was pressed comes from + // the num pad or the rest of the keyboard. Investigating how + // TranslateMessage() generates the WM_KEYCHAR from an + // ALT + <NumPad sequences> it appears it looks at the extended key flag + // (which is on if the key pressed comes from one of the 3 clusters to + // the left of the numeric keypad). So we use it as well. + return !extended_key && + ((key_code >= VK_PRIOR && key_code <= VK_DOWN) || // All keys but 5 + // and 0. + (key_code == VK_CLEAR) || // Key 5. + (key_code == VK_INSERT)); // Key 0. +} + void NativeTextfieldWin::AttachHack() { // See the code in textfield.cc that calls this for why this is here. container_view_->set_focus_view(textfield_); @@ -678,8 +708,8 @@ void NativeTextfieldWin::OnLButtonDown(UINT keys, const CPoint& point) { // double_click_time_ from the current message's time even if the timer has // wrapped in between. const bool is_triple_click = tracking_double_click_ && - app::win::IsDoubleClick(double_click_point_, point, - GetCurrentMessage()->time - double_click_time_); + IsDoubleClick(double_click_point_, point, + GetCurrentMessage()->time - double_click_time_); tracking_double_click_ = false; ScopedFreeze freeze(this, GetTextObjectModel()); diff --git a/views/controls/textfield/native_textfield_win.h b/views/controls/textfield/native_textfield_win.h index efc5d57..b0c8902 100644 --- a/views/controls/textfield/native_textfield_win.h +++ b/views/controls/textfield/native_textfield_win.h @@ -43,6 +43,18 @@ class NativeTextfieldWin explicit NativeTextfieldWin(Textfield* parent); ~NativeTextfieldWin(); + // Returns true if the current point is close enough to the origin point in + // space and time that it would be considered a double click. + static bool IsDoubleClick(const POINT& origin, + const POINT& current, + DWORD elapsed_time); + + // Returns true if the virtual key code is a digit coming from the numeric + // keypad (with or without NumLock on). |extended_key| should be set to the + // extended key flag specified in the WM_KEYDOWN/UP where the |key_code| + // originated. + static bool IsNumPadDigit(int key_code, bool extended_key); + // See the code in textfield.cc that calls this for why this is here. void AttachHack(); diff --git a/views/controls/textfield/textfield.cc b/views/controls/textfield/textfield.cc index a228ed9..cbd6f52 100644 --- a/views/controls/textfield/textfield.cc +++ b/views/controls/textfield/textfield.cc @@ -21,7 +21,6 @@ #if defined(OS_LINUX) #include "ui/base/keycodes/keyboard_code_conversion_gtk.h" #elif defined(OS_WIN) -#include "app/win/win_util.h" #include "base/win/win_util.h" // TODO(beng): this should be removed when the OS_WIN hack from // ViewHierarchyChanged is removed. @@ -318,7 +317,7 @@ bool Textfield::SkipDefaultKeyEventProcessing(const KeyEvent& e) { // We don't translate accelerators for ALT + NumPad digit on Windows, they are // used for entering special characters. We do translate alt-home. if (e.IsAltDown() && (key != ui::VKEY_HOME) && - app::win::IsNumPadDigit(key, e.IsExtendedKey())) + NativeTextfieldWin::IsNumPadDigit(key, e.IsExtendedKey())) return true; #endif return false; diff --git a/views/views.gyp b/views/views.gyp index 5a437d9..9be2292 100644 --- a/views/views.gyp +++ b/views/views.gyp @@ -336,6 +336,8 @@ 'widget/tooltip_manager.h', 'widget/tooltip_window_gtk.cc', 'widget/tooltip_window_gtk.h', + 'widget/monitor_win.cc', + 'widget/monitor_win.h', 'widget/widget.h', 'widget/widget_gtk.cc', 'widget/widget_gtk.h', @@ -468,6 +470,7 @@ 'test/test_views_delegate.h', 'view_unittest.cc', 'widget/widget_win_unittest.cc', + 'window/window_win_unittest.cc', '<(SHARED_INTERMEDIATE_DIR)/app/app_resources/app_resources.rc', ], diff --git a/views/widget/monitor_win.cc b/views/widget/monitor_win.cc new file mode 100755 index 0000000..848adfa --- /dev/null +++ b/views/widget/monitor_win.cc @@ -0,0 +1,27 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "views/widget/monitor_win.h" + +#include <windows.h> + +#include "base/logging.h" +#include "gfx/rect.h" + +namespace views { + +gfx::Rect GetMonitorBoundsForRect(const gfx::Rect& rect) { + RECT p_rect = rect.ToRECT(); + HMONITOR monitor = MonitorFromRect(&p_rect, MONITOR_DEFAULTTONEAREST); + if (monitor) { + MONITORINFO mi = {0}; + mi.cbSize = sizeof(mi); + GetMonitorInfo(monitor, &mi); + return gfx::Rect(mi.rcWork); + } + NOTREACHED(); + return gfx::Rect(); +} + +} // namespace views diff --git a/views/widget/monitor_win.h b/views/widget/monitor_win.h new file mode 100755 index 0000000..b1cdf24 --- /dev/null +++ b/views/widget/monitor_win.h @@ -0,0 +1,21 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef VIEWS_WIDGET_MONITOR_WIN_H_ +#define VIEWS_WIDGET_MONITOR_WIN_H_ +#pragma once + +namespace gfx { +class Rect; +} + +namespace views { + +// Returns the bounds for the monitor that contains the largest area of +// intersection with the specified rectangle. +gfx::Rect GetMonitorBoundsForRect(const gfx::Rect& rect); + +} // namespace views + +#endif // VIEWS_WIDGET_MONITOR_WIN_H_ diff --git a/views/widget/tooltip_manager_win.cc b/views/widget/tooltip_manager_win.cc index 0ea8187..854275e 100644 --- a/views/widget/tooltip_manager_win.cc +++ b/views/widget/tooltip_manager_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -7,7 +7,6 @@ #include <windowsx.h> #include <limits> -#include "app/win/win_util.h" #include "base/i18n/rtl.h" #include "base/logging.h" #include "base/message_loop.h" @@ -15,6 +14,7 @@ #include "ui/base/l10n/l10n_util_win.h" #include "views/screen.h" #include "views/view.h" +#include "views/widget/monitor_win.h" #include "views/widget/root_view.h" #include "views/widget/widget.h" @@ -228,7 +228,7 @@ bool TooltipManagerWin::SetTooltipPosition(int text_x, int text_y) { // doesn't, return false so that windows positions the tooltip at the // default location. gfx::Rect monitor_bounds = - app::win::GetMonitorBoundsForRect(gfx::Rect(bounds.left,bounds.right, + views::GetMonitorBoundsForRect(gfx::Rect(bounds.left,bounds.right, 0, 0)); if (!monitor_bounds.Contains(gfx::Rect(bounds))) { return false; @@ -356,7 +356,7 @@ void TooltipManagerWin::ShowKeyboardTooltip(View* focused_view) { screen_point.y() + focused_bounds.height() + line_count * tooltip_height_ }; gfx::Rect monitor_bounds = - app::win::GetMonitorBoundsForRect(gfx::Rect(rect_bounds)); + views::GetMonitorBoundsForRect(gfx::Rect(rect_bounds)); rect_bounds = gfx::Rect(rect_bounds).AdjustToFit(monitor_bounds).ToRECT(); ::SetWindowPos(keyboard_tooltip_hwnd_, NULL, rect_bounds.left, rect_bounds.top, 0, 0, diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc index 2f7603a..a7731e5 100644 --- a/views/widget/widget_win.cc +++ b/views/widget/widget_win.cc @@ -6,7 +6,6 @@ #include <dwmapi.h> -#include "app/win/win_util.h" #include "base/string_util.h" #include "base/win/windows_version.h" #include "gfx/canvas_skia.h" @@ -35,6 +34,17 @@ using ui::ViewProp; +namespace { + +// Returns whether the specified window is the current active window. +bool IsWindowActive(HWND hwnd) { + WINDOWINFO info; + return ::GetWindowInfo(hwnd, &info) && + ((info.dwWindowStatus & WS_ACTIVECAPTION) != 0); +} + +} // namespace + namespace views { // Property used to link the HWND to its RootView. @@ -407,7 +417,7 @@ bool WidgetWin::IsVisible() const { } bool WidgetWin::IsActive() const { - return app::win::IsWindowActive(hwnd()); + return IsWindowActive(hwnd()); } bool WidgetWin::IsAccessibleWidget() const { diff --git a/views/window/custom_frame_view.cc b/views/window/custom_frame_view.cc index fe2fc30..edc9acf 100644 --- a/views/window/custom_frame_view.cc +++ b/views/window/custom_frame_view.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -21,7 +21,7 @@ #endif #if defined(OS_WIN) -#include "app/win/win_util.h" +#include "views/window/window_win.h" #endif namespace views { @@ -571,7 +571,7 @@ void CustomFrameView::InitClass() { static bool initialized = false; if (!initialized) { #if defined(OS_WIN) - title_font_ = new gfx::Font(app::win::GetWindowTitleFont()); + title_font_ = new gfx::Font(WindowWin::GetWindowTitleFont()); #elif defined(OS_LINUX) // TODO(ben): need to resolve what font this is. title_font_ = new gfx::Font(); diff --git a/views/window/window_win.cc b/views/window/window_win.cc index dff4527..64dde6c 100644 --- a/views/window/window_win.cc +++ b/views/window/window_win.cc @@ -7,14 +7,16 @@ #include <dwmapi.h> #include <shellapi.h> -#include "app/win/win_util.h" #include "base/i18n/rtl.h" +#include "base/win/scoped_gdi_object.h" +#include "base/win/win_util.h" #include "base/win/windows_version.h" #include "gfx/canvas_skia_paint.h" #include "gfx/font.h" #include "gfx/icon_util.h" #include "gfx/path.h" #include "ui/base/keycodes/keyboard_code_conversion_win.h" +#include "ui/base/l10n/l10n_util_win.h" #include "ui/base/theme_provider.h" #include "ui/base/win/hwnd_util.h" #include "views/accessibility/view_accessibility.h" @@ -29,6 +31,9 @@ namespace { static const int kDragFrameWindowAlpha = 200; +// The thickness of an auto-hide taskbar in pixels. +static const int kAutoHideTaskbarThicknessPx = 2; + bool GetMonitorAndRects(const RECT& rect, HMONITOR* monitor, gfx::Rect* monitor_rect, @@ -88,18 +93,72 @@ void SetChildBounds(HWND child_window, HWND parent_window, } gfx::Rect actual_bounds = bounds; - app::win::EnsureRectIsVisibleInRect(gfx::Rect(parent_rect), &actual_bounds, - padding); + views::internal::EnsureRectIsVisibleInRect(gfx::Rect(parent_rect), + &actual_bounds, padding); SetWindowPos(child_window, insert_after_window, actual_bounds.x(), actual_bounds.y(), actual_bounds.width(), actual_bounds.height(), flags); } +// Returns true if edge |edge| (one of ABE_LEFT, TOP, RIGHT, or BOTTOM) of +// monitor |monitor| has an auto-hiding taskbar that's always-on-top. +bool EdgeHasTopmostAutoHideTaskbar(UINT edge, HMONITOR monitor) { + APPBARDATA taskbar_data = { 0 }; + taskbar_data.cbSize = sizeof APPBARDATA; + taskbar_data.uEdge = edge; + HWND taskbar = reinterpret_cast<HWND>(SHAppBarMessage(ABM_GETAUTOHIDEBAR, + &taskbar_data)); + return ::IsWindow(taskbar) && (monitor != NULL) && + (MonitorFromWindow(taskbar, MONITOR_DEFAULTTONULL) == monitor) && + (GetWindowLong(taskbar, GWL_EXSTYLE) & WS_EX_TOPMOST); +} + } // namespace namespace views { +namespace internal { + +void EnsureRectIsVisibleInRect(const gfx::Rect& parent_rect, + gfx::Rect* child_rect, + int padding) { + DCHECK(child_rect); + + // We use padding here because it allows some of the original web page to + // bleed through around the edges. + int twice_padding = padding * 2; + + // FIRST, clamp width and height so we don't open child windows larger than + // the containing parent. + if (child_rect->width() > (parent_rect.width() + twice_padding)) + child_rect->set_width(std::max(0, parent_rect.width() - twice_padding)); + if (child_rect->height() > parent_rect.height() + twice_padding) + child_rect->set_height(std::max(0, parent_rect.height() - twice_padding)); + + // SECOND, clamp x,y position to padding,padding so we don't position child + // windows in hyperspace. + // TODO(mpcomplete): I don't see what the second check in each 'if' does that + // isn't handled by the LAST set of 'ifs'. Maybe we can remove it. + if (child_rect->x() < parent_rect.x() || + child_rect->x() > parent_rect.right()) { + child_rect->set_x(parent_rect.x() + padding); + } + if (child_rect->y() < parent_rect.y() || + child_rect->y() > parent_rect.bottom()) { + child_rect->set_y(parent_rect.y() + padding); + } + + // LAST, nudge the window back up into the client area if its x,y position is + // within the parent bounds but its width/height place it off-screen. + if (child_rect->bottom() > parent_rect.bottom()) + child_rect->set_y(parent_rect.bottom() - child_rect->height() - padding); + if (child_rect->right() > parent_rect.right()) + child_rect->set_x(parent_rect.right() - child_rect->width() - padding); +} + +} // namespace internal + // A scoping class that prevents a window from being able to redraw in response // to invalidations that may occur within it for the lifetime of the object. // @@ -242,41 +301,6 @@ static BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) { } } // namespace -void WindowWin::FrameTypeChanged() { - if (base::win::GetVersion() >= base::win::VERSION_VISTA) { - // We need to toggle the rendering policy of the DWM/glass frame as we - // change from opaque to glass. "Non client rendering enabled" means that - // the DWM's glass non-client rendering is enabled, which is why - // DWMNCRP_ENABLED is used for the native frame case. _DISABLED means the - // DWM doesn't render glass, and so is used in the custom frame case. - DWMNCRENDERINGPOLICY policy = - non_client_view_->UseNativeFrame() ? DWMNCRP_ENABLED - : DWMNCRP_DISABLED; - DwmSetWindowAttribute(GetNativeView(), DWMWA_NCRENDERING_POLICY, - &policy, sizeof(DWMNCRENDERINGPOLICY)); - } - - // Send a frame change notification, since the non-client metrics have - // changed. - SetWindowPos(NULL, 0, 0, 0, 0, - SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | - SWP_NOOWNERZORDER | SWP_NOACTIVATE); - - // The frame type change results in the client rect changing size, but this - // does not explicitly send a WM_SIZE, so we need to force the root view to - // be resized now. - LayoutRootView(); - - // Update the non-client view with the correct frame view for the active frame - // type. - non_client_view_->UpdateFrame(); - - // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want - // to notify our children too, since we can have MDI child windows who need to - // update their appearance. - EnumChildWindows(GetNativeView(), &SendDwmCompositionChanged, NULL); -} - //////////////////////////////////////////////////////////////////////////////// // WindowWin, Window implementation: @@ -544,6 +568,53 @@ bool WindowWin::ShouldUseNativeFrame() const { return tp->ShouldUseNativeFrame(); } +void WindowWin::FrameTypeChanged() { + // Called when the frame type could possibly be changing (theme change or + // DWM composition change). + if (base::win::GetVersion() >= base::win::VERSION_VISTA) { + // We need to toggle the rendering policy of the DWM/glass frame as we + // change from opaque to glass. "Non client rendering enabled" means that + // the DWM's glass non-client rendering is enabled, which is why + // DWMNCRP_ENABLED is used for the native frame case. _DISABLED means the + // DWM doesn't render glass, and so is used in the custom frame case. + DWMNCRENDERINGPOLICY policy = + non_client_view_->UseNativeFrame() ? DWMNCRP_ENABLED + : DWMNCRP_DISABLED; + DwmSetWindowAttribute(GetNativeView(), DWMWA_NCRENDERING_POLICY, + &policy, sizeof(DWMNCRENDERINGPOLICY)); + } + + // Send a frame change notification, since the non-client metrics have + // changed. + SetWindowPos(NULL, 0, 0, 0, 0, + SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | + SWP_NOOWNERZORDER | SWP_NOACTIVATE); + + // The frame type change results in the client rect changing size, but this + // does not explicitly send a WM_SIZE, so we need to force the root view to + // be resized now. + LayoutRootView(); + + // Update the non-client view with the correct frame view for the active frame + // type. + non_client_view_->UpdateFrame(); + + // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want + // to notify our children too, since we can have MDI child windows who need to + // update their appearance. + EnumChildWindows(GetNativeView(), &SendDwmCompositionChanged, NULL); +} + + +// static +gfx::Font WindowWin::GetWindowTitleFont() { + NONCLIENTMETRICS ncm; + base::win::GetNonClientMetrics(&ncm); + l10n_util::AdjustUIFont(&(ncm.lfCaptionFont)); + base::win::ScopedHFONT caption_font(CreateFontIndirect(&(ncm.lfCaptionFont))); + return gfx::Font(caption_font); +} + /////////////////////////////////////////////////////////////////////////////// // WindowWin, protected: @@ -843,9 +914,9 @@ LRESULT WindowWin::OnNCCalcSize(BOOL mode, LPARAM l_param) { return 0; } } - if (app::win::EdgeHasTopmostAutoHideTaskbar(ABE_LEFT, monitor)) - client_rect->left += app::win::kAutoHideTaskbarThicknessPx; - if (app::win::EdgeHasTopmostAutoHideTaskbar(ABE_TOP, monitor)) { + if (EdgeHasTopmostAutoHideTaskbar(ABE_LEFT, monitor)) + client_rect->left += kAutoHideTaskbarThicknessPx; + if (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 @@ -858,13 +929,13 @@ LRESULT WindowWin::OnNCCalcSize(BOOL mode, LPARAM l_param) { // be no better solution. --client_rect->bottom; } else { - client_rect->top += app::win::kAutoHideTaskbarThicknessPx; + client_rect->top += kAutoHideTaskbarThicknessPx; } } - if (app::win::EdgeHasTopmostAutoHideTaskbar(ABE_RIGHT, monitor)) - client_rect->right -= app::win::kAutoHideTaskbarThicknessPx; - if (app::win::EdgeHasTopmostAutoHideTaskbar(ABE_BOTTOM, monitor)) - client_rect->bottom -= app::win::kAutoHideTaskbarThicknessPx; + if (EdgeHasTopmostAutoHideTaskbar(ABE_RIGHT, monitor)) + client_rect->right -= kAutoHideTaskbarThicknessPx; + if (EdgeHasTopmostAutoHideTaskbar(ABE_BOTTOM, monitor)) + client_rect->bottom -= kAutoHideTaskbarThicknessPx; // We cannot return WVR_REDRAW when there is nonclient area, or Windows // exhibits bugs where client pixels and child HWNDs are mispositioned by diff --git a/views/window/window_win.h b/views/window/window_win.h index 37d56d1..6b20667a 100644 --- a/views/window/window_win.h +++ b/views/window/window_win.h @@ -10,12 +10,24 @@ #include "views/window/window.h" namespace gfx { +class Font; class Point; class Size; }; namespace views { +namespace internal { +// This is exposed only for testing + +// Adjusts the value of |child_rect| if necessary to ensure that it is +// completely visible within |parent_rect|. +void EnsureRectIsVisibleInRect(const gfx::Rect& parent_rect, + gfx::Rect* child_rect, + int padding); + +} // namespace internal + class Client; class WindowDelegate; @@ -45,10 +57,6 @@ class WindowWin : public WidgetWin, // Executes the specified SC_command. void ExecuteSystemMenuCommand(int command); - // Called when the frame type could possibly be changing (theme change or - // DWM composition change). - void FrameTypeChanged(); - // Accessors and setters for various properties. HWND owning_window() const { return owning_hwnd_; } void set_focus_on_creation(bool focus_on_creation) { @@ -89,6 +97,10 @@ class WindowWin : public WidgetWin, virtual ClientView* GetClientView() const; virtual gfx::NativeWindow GetNativeWindow() const; virtual bool ShouldUseNativeFrame() const; + virtual void FrameTypeChanged(); + + // Returns the system set window title font. + static gfx::Font GetWindowTitleFont(); protected: friend Window; diff --git a/views/window/window_win_unittest.cc b/views/window/window_win_unittest.cc new file mode 100644 index 0000000..0e1f037 --- /dev/null +++ b/views/window/window_win_unittest.cc @@ -0,0 +1,58 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "views/window/window_win.h" + +#include "gfx/rect.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace views { + +TEST(WindowWinTest, EnsureRectIsVisibleInRect) { + gfx::Rect parent_rect(0, 0, 500, 400); + + { + // Child rect x < 0 + gfx::Rect child_rect(-50, 20, 100, 100); + internal::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); + EXPECT_EQ(gfx::Rect(10, 20, 100, 100), child_rect); + } + + { + // Child rect y < 0 + gfx::Rect child_rect(20, -50, 100, 100); + internal::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); + EXPECT_EQ(gfx::Rect(20, 10, 100, 100), child_rect); + } + + { + // Child rect right > parent_rect.right + gfx::Rect child_rect(450, 20, 100, 100); + internal::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); + EXPECT_EQ(gfx::Rect(390, 20, 100, 100), child_rect); + } + + { + // Child rect bottom > parent_rect.bottom + gfx::Rect child_rect(20, 350, 100, 100); + internal::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); + EXPECT_EQ(gfx::Rect(20, 290, 100, 100), child_rect); + } + + { + // Child rect width > parent_rect.width + gfx::Rect child_rect(20, 20, 700, 100); + internal::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); + EXPECT_EQ(gfx::Rect(20, 20, 480, 100), child_rect); + } + + { + // Child rect height > parent_rect.height + gfx::Rect child_rect(20, 20, 100, 700); + internal::EnsureRectIsVisibleInRect(parent_rect, &child_rect, 10); + EXPECT_EQ(gfx::Rect(20, 20, 100, 380), child_rect); + } +} + +} // namespace views |