Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(962)

Side by Side Diff: views/window/window_win.cc

Issue 6386009: Remove app/win/win_util.h,cc etc. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge with NSApp changes in r73581 Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « views/window/window_win.h ('k') | views/window/window_win_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "views/window/window_win.h" 5 #include "views/window/window_win.h"
6 6
7 #include <dwmapi.h> 7 #include <dwmapi.h>
8 #include <shellapi.h> 8 #include <shellapi.h>
9 9
10 #include "app/win/win_util.h"
11 #include "base/i18n/rtl.h" 10 #include "base/i18n/rtl.h"
11 #include "base/win/scoped_gdi_object.h"
12 #include "base/win/win_util.h"
12 #include "base/win/windows_version.h" 13 #include "base/win/windows_version.h"
13 #include "gfx/canvas_skia_paint.h" 14 #include "gfx/canvas_skia_paint.h"
14 #include "gfx/font.h" 15 #include "gfx/font.h"
15 #include "gfx/icon_util.h" 16 #include "gfx/icon_util.h"
16 #include "gfx/path.h" 17 #include "gfx/path.h"
17 #include "ui/base/keycodes/keyboard_code_conversion_win.h" 18 #include "ui/base/keycodes/keyboard_code_conversion_win.h"
19 #include "ui/base/l10n/l10n_util_win.h"
18 #include "ui/base/theme_provider.h" 20 #include "ui/base/theme_provider.h"
19 #include "ui/base/win/hwnd_util.h" 21 #include "ui/base/win/hwnd_util.h"
20 #include "views/accessibility/view_accessibility.h" 22 #include "views/accessibility/view_accessibility.h"
21 #include "views/widget/root_view.h" 23 #include "views/widget/root_view.h"
22 #include "views/window/client_view.h" 24 #include "views/window/client_view.h"
23 #include "views/window/custom_frame_view.h" 25 #include "views/window/custom_frame_view.h"
24 #include "views/window/native_frame_view.h" 26 #include "views/window/native_frame_view.h"
25 #include "views/window/non_client_view.h" 27 #include "views/window/non_client_view.h"
26 #include "views/window/window_delegate.h" 28 #include "views/window/window_delegate.h"
27 29
28 namespace { 30 namespace {
29 31
30 static const int kDragFrameWindowAlpha = 200; 32 static const int kDragFrameWindowAlpha = 200;
31 33
34 // The thickness of an auto-hide taskbar in pixels.
35 static const int kAutoHideTaskbarThicknessPx = 2;
36
32 bool GetMonitorAndRects(const RECT& rect, 37 bool GetMonitorAndRects(const RECT& rect,
33 HMONITOR* monitor, 38 HMONITOR* monitor,
34 gfx::Rect* monitor_rect, 39 gfx::Rect* monitor_rect,
35 gfx::Rect* work_area) { 40 gfx::Rect* work_area) {
36 DCHECK(monitor); 41 DCHECK(monitor);
37 DCHECK(monitor_rect); 42 DCHECK(monitor_rect);
38 DCHECK(work_area); 43 DCHECK(work_area);
39 *monitor = MonitorFromRect(&rect, MONITOR_DEFAULTTONULL); 44 *monitor = MonitorFromRect(&rect, MONITOR_DEFAULTTONULL);
40 if (!*monitor) 45 if (!*monitor)
41 return false; 46 return false;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 MONITORINFO mi = {0}; 86 MONITORINFO mi = {0};
82 mi.cbSize = sizeof(mi); 87 mi.cbSize = sizeof(mi);
83 GetMonitorInfo(monitor, &mi); 88 GetMonitorInfo(monitor, &mi);
84 parent_rect = mi.rcWork; 89 parent_rect = mi.rcWork;
85 } else { 90 } else {
86 NOTREACHED() << "Unable to get default monitor"; 91 NOTREACHED() << "Unable to get default monitor";
87 } 92 }
88 } 93 }
89 94
90 gfx::Rect actual_bounds = bounds; 95 gfx::Rect actual_bounds = bounds;
91 app::win::EnsureRectIsVisibleInRect(gfx::Rect(parent_rect), &actual_bounds, 96 views::internal::EnsureRectIsVisibleInRect(gfx::Rect(parent_rect),
92 padding); 97 &actual_bounds, padding);
93 98
94 SetWindowPos(child_window, insert_after_window, actual_bounds.x(), 99 SetWindowPos(child_window, insert_after_window, actual_bounds.x(),
95 actual_bounds.y(), actual_bounds.width(), 100 actual_bounds.y(), actual_bounds.width(),
96 actual_bounds.height(), flags); 101 actual_bounds.height(), flags);
97 } 102 }
98 103
104 // Returns true if edge |edge| (one of ABE_LEFT, TOP, RIGHT, or BOTTOM) of
105 // monitor |monitor| has an auto-hiding taskbar that's always-on-top.
106 bool EdgeHasTopmostAutoHideTaskbar(UINT edge, HMONITOR monitor) {
107 APPBARDATA taskbar_data = { 0 };
108 taskbar_data.cbSize = sizeof APPBARDATA;
109 taskbar_data.uEdge = edge;
110 HWND taskbar = reinterpret_cast<HWND>(SHAppBarMessage(ABM_GETAUTOHIDEBAR,
111 &taskbar_data));
112 return ::IsWindow(taskbar) && (monitor != NULL) &&
113 (MonitorFromWindow(taskbar, MONITOR_DEFAULTTONULL) == monitor) &&
114 (GetWindowLong(taskbar, GWL_EXSTYLE) & WS_EX_TOPMOST);
115 }
116
99 } // namespace 117 } // namespace
100 118
101 namespace views { 119 namespace views {
102 120
121 namespace internal {
122
123 void EnsureRectIsVisibleInRect(const gfx::Rect& parent_rect,
124 gfx::Rect* child_rect,
125 int padding) {
126 DCHECK(child_rect);
127
128 // We use padding here because it allows some of the original web page to
129 // bleed through around the edges.
130 int twice_padding = padding * 2;
131
132 // FIRST, clamp width and height so we don't open child windows larger than
133 // the containing parent.
134 if (child_rect->width() > (parent_rect.width() + twice_padding))
135 child_rect->set_width(std::max(0, parent_rect.width() - twice_padding));
136 if (child_rect->height() > parent_rect.height() + twice_padding)
137 child_rect->set_height(std::max(0, parent_rect.height() - twice_padding));
138
139 // SECOND, clamp x,y position to padding,padding so we don't position child
140 // windows in hyperspace.
141 // TODO(mpcomplete): I don't see what the second check in each 'if' does that
142 // isn't handled by the LAST set of 'ifs'. Maybe we can remove it.
143 if (child_rect->x() < parent_rect.x() ||
144 child_rect->x() > parent_rect.right()) {
145 child_rect->set_x(parent_rect.x() + padding);
146 }
147 if (child_rect->y() < parent_rect.y() ||
148 child_rect->y() > parent_rect.bottom()) {
149 child_rect->set_y(parent_rect.y() + padding);
150 }
151
152 // LAST, nudge the window back up into the client area if its x,y position is
153 // within the parent bounds but its width/height place it off-screen.
154 if (child_rect->bottom() > parent_rect.bottom())
155 child_rect->set_y(parent_rect.bottom() - child_rect->height() - padding);
156 if (child_rect->right() > parent_rect.right())
157 child_rect->set_x(parent_rect.right() - child_rect->width() - padding);
158 }
159
160 } // namespace internal
161
103 // A scoping class that prevents a window from being able to redraw in response 162 // A scoping class that prevents a window from being able to redraw in response
104 // to invalidations that may occur within it for the lifetime of the object. 163 // to invalidations that may occur within it for the lifetime of the object.
105 // 164 //
106 // Why would we want such a thing? Well, it turns out Windows has some 165 // Why would we want such a thing? Well, it turns out Windows has some
107 // "unorthodox" behavior when it comes to painting its non-client areas. 166 // "unorthodox" behavior when it comes to painting its non-client areas.
108 // Occasionally, Windows will paint portions of the default non-client area 167 // Occasionally, Windows will paint portions of the default non-client area
109 // right over the top of the custom frame. This is not simply fixed by handling 168 // right over the top of the custom frame. This is not simply fixed by handling
110 // WM_NCPAINT/WM_PAINT, with some investigation it turns out that this 169 // WM_NCPAINT/WM_PAINT, with some investigation it turns out that this
111 // rendering is being done *inside* the default implementation of some message 170 // rendering is being done *inside* the default implementation of some message
112 // handlers and functions: 171 // handlers and functions:
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 SendMessage(GetNativeView(), WM_SYSCOMMAND, command, 0); 294 SendMessage(GetNativeView(), WM_SYSCOMMAND, command, 0);
236 } 295 }
237 296
238 namespace { 297 namespace {
239 static BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) { 298 static BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) {
240 SendMessage(window, WM_DWMCOMPOSITIONCHANGED, 0, 0); 299 SendMessage(window, WM_DWMCOMPOSITIONCHANGED, 0, 0);
241 return TRUE; 300 return TRUE;
242 } 301 }
243 } // namespace 302 } // namespace
244 303
245 void WindowWin::FrameTypeChanged() {
246 if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
247 // We need to toggle the rendering policy of the DWM/glass frame as we
248 // change from opaque to glass. "Non client rendering enabled" means that
249 // the DWM's glass non-client rendering is enabled, which is why
250 // DWMNCRP_ENABLED is used for the native frame case. _DISABLED means the
251 // DWM doesn't render glass, and so is used in the custom frame case.
252 DWMNCRENDERINGPOLICY policy =
253 non_client_view_->UseNativeFrame() ? DWMNCRP_ENABLED
254 : DWMNCRP_DISABLED;
255 DwmSetWindowAttribute(GetNativeView(), DWMWA_NCRENDERING_POLICY,
256 &policy, sizeof(DWMNCRENDERINGPOLICY));
257 }
258
259 // Send a frame change notification, since the non-client metrics have
260 // changed.
261 SetWindowPos(NULL, 0, 0, 0, 0,
262 SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
263 SWP_NOOWNERZORDER | SWP_NOACTIVATE);
264
265 // The frame type change results in the client rect changing size, but this
266 // does not explicitly send a WM_SIZE, so we need to force the root view to
267 // be resized now.
268 LayoutRootView();
269
270 // Update the non-client view with the correct frame view for the active frame
271 // type.
272 non_client_view_->UpdateFrame();
273
274 // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want
275 // to notify our children too, since we can have MDI child windows who need to
276 // update their appearance.
277 EnumChildWindows(GetNativeView(), &SendDwmCompositionChanged, NULL);
278 }
279
280 //////////////////////////////////////////////////////////////////////////////// 304 ////////////////////////////////////////////////////////////////////////////////
281 // WindowWin, Window implementation: 305 // WindowWin, Window implementation:
282 306
283 void WindowWin::Show() { 307 void WindowWin::Show() {
284 int show_state = GetShowState(); 308 int show_state = GetShowState();
285 if (saved_maximized_state_) 309 if (saved_maximized_state_)
286 show_state = SW_SHOWMAXIMIZED; 310 show_state = SW_SHOWMAXIMIZED;
287 Show(show_state); 311 Show(show_state);
288 } 312 }
289 313
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 return GetNativeView(); 561 return GetNativeView();
538 } 562 }
539 563
540 bool WindowWin::ShouldUseNativeFrame() const { 564 bool WindowWin::ShouldUseNativeFrame() const {
541 ui::ThemeProvider* tp = GetThemeProvider(); 565 ui::ThemeProvider* tp = GetThemeProvider();
542 if (!tp) 566 if (!tp)
543 return WidgetWin::IsAeroGlassEnabled(); 567 return WidgetWin::IsAeroGlassEnabled();
544 return tp->ShouldUseNativeFrame(); 568 return tp->ShouldUseNativeFrame();
545 } 569 }
546 570
571 void WindowWin::FrameTypeChanged() {
572 // Called when the frame type could possibly be changing (theme change or
573 // DWM composition change).
574 if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
575 // We need to toggle the rendering policy of the DWM/glass frame as we
576 // change from opaque to glass. "Non client rendering enabled" means that
577 // the DWM's glass non-client rendering is enabled, which is why
578 // DWMNCRP_ENABLED is used for the native frame case. _DISABLED means the
579 // DWM doesn't render glass, and so is used in the custom frame case.
580 DWMNCRENDERINGPOLICY policy =
581 non_client_view_->UseNativeFrame() ? DWMNCRP_ENABLED
582 : DWMNCRP_DISABLED;
583 DwmSetWindowAttribute(GetNativeView(), DWMWA_NCRENDERING_POLICY,
584 &policy, sizeof(DWMNCRENDERINGPOLICY));
585 }
586
587 // Send a frame change notification, since the non-client metrics have
588 // changed.
589 SetWindowPos(NULL, 0, 0, 0, 0,
590 SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
591 SWP_NOOWNERZORDER | SWP_NOACTIVATE);
592
593 // The frame type change results in the client rect changing size, but this
594 // does not explicitly send a WM_SIZE, so we need to force the root view to
595 // be resized now.
596 LayoutRootView();
597
598 // Update the non-client view with the correct frame view for the active frame
599 // type.
600 non_client_view_->UpdateFrame();
601
602 // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want
603 // to notify our children too, since we can have MDI child windows who need to
604 // update their appearance.
605 EnumChildWindows(GetNativeView(), &SendDwmCompositionChanged, NULL);
606 }
607
608
609 // static
610 gfx::Font WindowWin::GetWindowTitleFont() {
611 NONCLIENTMETRICS ncm;
612 base::win::GetNonClientMetrics(&ncm);
613 l10n_util::AdjustUIFont(&(ncm.lfCaptionFont));
614 base::win::ScopedHFONT caption_font(CreateFontIndirect(&(ncm.lfCaptionFont)));
615 return gfx::Font(caption_font);
616 }
617
547 /////////////////////////////////////////////////////////////////////////////// 618 ///////////////////////////////////////////////////////////////////////////////
548 // WindowWin, protected: 619 // WindowWin, protected:
549 620
550 WindowWin::WindowWin(WindowDelegate* window_delegate) 621 WindowWin::WindowWin(WindowDelegate* window_delegate)
551 : WidgetWin(), 622 : WidgetWin(),
552 focus_on_creation_(true), 623 focus_on_creation_(true),
553 window_delegate_(window_delegate), 624 window_delegate_(window_delegate),
554 non_client_view_(new NonClientView(this)), 625 non_client_view_(new NonClientView(this)),
555 owning_hwnd_(NULL), 626 owning_hwnd_(NULL),
556 minimum_size_(100, 100), 627 minimum_size_(100, 100),
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 // the window rect given with WM_NCCALCSIZE (which is our previous 907 // the window rect given with WM_NCCALCSIZE (which is our previous
837 // restored window position) we will get the correct monitor handle. 908 // restored window position) we will get the correct monitor handle.
838 monitor = MonitorFromRect(client_rect, MONITOR_DEFAULTTONULL); 909 monitor = MonitorFromRect(client_rect, MONITOR_DEFAULTTONULL);
839 if (!monitor) { 910 if (!monitor) {
840 // This is probably an extreme case that we won't hit, but if we don't 911 // This is probably an extreme case that we won't hit, but if we don't
841 // intersect any monitor, let us not adjust the client rect since our 912 // intersect any monitor, let us not adjust the client rect since our
842 // window will not be visible anyway. 913 // window will not be visible anyway.
843 return 0; 914 return 0;
844 } 915 }
845 } 916 }
846 if (app::win::EdgeHasTopmostAutoHideTaskbar(ABE_LEFT, monitor)) 917 if (EdgeHasTopmostAutoHideTaskbar(ABE_LEFT, monitor))
847 client_rect->left += app::win::kAutoHideTaskbarThicknessPx; 918 client_rect->left += kAutoHideTaskbarThicknessPx;
848 if (app::win::EdgeHasTopmostAutoHideTaskbar(ABE_TOP, monitor)) { 919 if (EdgeHasTopmostAutoHideTaskbar(ABE_TOP, monitor)) {
849 if (GetNonClientView()->UseNativeFrame()) { 920 if (GetNonClientView()->UseNativeFrame()) {
850 // Tricky bit. Due to a bug in DwmDefWindowProc()'s handling of 921 // Tricky bit. Due to a bug in DwmDefWindowProc()'s handling of
851 // WM_NCHITTEST, having any nonclient area atop the window causes the 922 // WM_NCHITTEST, having any nonclient area atop the window causes the
852 // caption buttons to draw onscreen but not respond to mouse 923 // caption buttons to draw onscreen but not respond to mouse
853 // hover/clicks. 924 // hover/clicks.
854 // So for a taskbar at the screen top, we can't push the 925 // So for a taskbar at the screen top, we can't push the
855 // client_rect->top down; instead, we move the bottom up by one pixel, 926 // client_rect->top down; instead, we move the bottom up by one pixel,
856 // which is the smallest change we can make and still get a client area 927 // which is the smallest change we can make and still get a client area
857 // less than the screen size. This is visibly ugly, but there seems to 928 // less than the screen size. This is visibly ugly, but there seems to
858 // be no better solution. 929 // be no better solution.
859 --client_rect->bottom; 930 --client_rect->bottom;
860 } else { 931 } else {
861 client_rect->top += app::win::kAutoHideTaskbarThicknessPx; 932 client_rect->top += kAutoHideTaskbarThicknessPx;
862 } 933 }
863 } 934 }
864 if (app::win::EdgeHasTopmostAutoHideTaskbar(ABE_RIGHT, monitor)) 935 if (EdgeHasTopmostAutoHideTaskbar(ABE_RIGHT, monitor))
865 client_rect->right -= app::win::kAutoHideTaskbarThicknessPx; 936 client_rect->right -= kAutoHideTaskbarThicknessPx;
866 if (app::win::EdgeHasTopmostAutoHideTaskbar(ABE_BOTTOM, monitor)) 937 if (EdgeHasTopmostAutoHideTaskbar(ABE_BOTTOM, monitor))
867 client_rect->bottom -= app::win::kAutoHideTaskbarThicknessPx; 938 client_rect->bottom -= kAutoHideTaskbarThicknessPx;
868 939
869 // We cannot return WVR_REDRAW when there is nonclient area, or Windows 940 // We cannot return WVR_REDRAW when there is nonclient area, or Windows
870 // exhibits bugs where client pixels and child HWNDs are mispositioned by 941 // exhibits bugs where client pixels and child HWNDs are mispositioned by
871 // the width/height of the upper-left nonclient area. 942 // the width/height of the upper-left nonclient area.
872 return 0; 943 return 0;
873 } 944 }
874 945
875 // If the window bounds change, we're going to relayout and repaint anyway. 946 // If the window bounds change, we're going to relayout and repaint anyway.
876 // Returning WVR_REDRAW avoids an extra paint before that of the old client 947 // Returning WVR_REDRAW avoids an extra paint before that of the old client
877 // pixels in the (now wrong) location, and thus makes actions like resizing a 948 // pixels in the (now wrong) location, and thus makes actions like resizing a
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after
1575 Window::CloseSecondaryWidget(root_view->GetWidget()); 1646 Window::CloseSecondaryWidget(root_view->GetWidget());
1576 return TRUE; 1647 return TRUE;
1577 } 1648 }
1578 } // namespace 1649 } // namespace
1579 1650
1580 void Window::CloseAllSecondaryWindows() { 1651 void Window::CloseAllSecondaryWindows() {
1581 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0); 1652 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0);
1582 } 1653 }
1583 1654
1584 } // namespace views 1655 } // namespace views
OLDNEW
« no previous file with comments | « views/window/window_win.h ('k') | views/window/window_win_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698