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

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

Issue 304007: Make sure the RootView is sized to the correct bounds when the opaque frame i... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 2 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
« views/widget/widget_win.cc ('K') | « views/window/window_win.h ('k') | no next file » | 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) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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/gfx/canvas_paint.h" 10 #include "app/gfx/canvas_paint.h"
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 &last_work_area_); 521 &last_work_area_);
522 ResetWindowRegion(false); 522 ResetWindowRegion(false);
523 } 523 }
524 524
525 void WindowWin::SizeWindowToDefault() { 525 void WindowWin::SizeWindowToDefault() {
526 win_util::CenterAndSizeWindow(owning_window(), GetNativeView(), 526 win_util::CenterAndSizeWindow(owning_window(), GetNativeView(),
527 non_client_view_->GetPreferredSize().ToSIZE(), 527 non_client_view_->GetPreferredSize().ToSIZE(),
528 false); 528 false);
529 } 529 }
530 530
531 gfx::Insets WindowWin::GetClientAreaInsets() const {
532 // Returning an empty Insets object causes the default handling in
533 // WidgetWin::OnNCCalcSize() to be invoked.
534 if (GetNonClientView()->UseNativeFrame())
535 return gfx::Insets();
536
537 if (IsMaximized()) {
538 // Windows automatically adds a standard width border to all sides when a
539 // window is maximized.
540 int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
541 return gfx::Insets(border_thickness, border_thickness, border_thickness,
542 border_thickness);
543 }
544 // This is weird, but highly essential. If we don't offset the bottom edge
545 // of the client rect, the window client area and window area will match,
546 // and when returning to glass rendering mode from non-glass, the client
547 // area will not paint black as transparent. This is because (and I don't
548 // know why) the client area goes from matching the window rect to being
549 // something else. If the client area is not the window rect in both
550 // modes, the blackness doesn't occur. Because of this, we need to tell
551 // the RootView to lay out to fit the window rect, rather than the client
552 // rect when using the opaque frame. See GetRootViewSize.
553 // Note: this is only required for non-fullscreen windows. Note that
554 // fullscreen windows are in restored state, not maximized.
555 return gfx::Insets(0, 0, !IsFullscreen() ? 1 : 0, 0);
Peter Kasting 2009/10/23 05:09:31 Nit: Could remove the ! and reverse the condition
556 }
557
531 void WindowWin::RunSystemMenu(const gfx::Point& point) { 558 void WindowWin::RunSystemMenu(const gfx::Point& point) {
532 // We need to reset and clean up any currently created system menu objects. 559 // We need to reset and clean up any currently created system menu objects.
533 // We need to call this otherwise there's a small chance that we aren't going 560 // We need to call this otherwise there's a small chance that we aren't going
534 // to get a system menu. We also can't take the return value of this 561 // to get a system menu. We also can't take the return value of this
535 // function. We need to call it *again* to get a valid HMENU. 562 // function. We need to call it *again* to get a valid HMENU.
536 //::GetSystemMenu(GetNativeView(), TRUE); 563 //::GetSystemMenu(GetNativeView(), TRUE);
537 UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD; 564 UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD;
538 if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) 565 if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT)
539 flags |= TPM_RIGHTALIGN; 566 flags |= TPM_RIGHTALIGN;
540 HMENU system_menu = ::GetSystemMenu(GetNativeView(), FALSE); 567 HMENU system_menu = ::GetSystemMenu(GetNativeView(), FALSE);
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 722
696 // Reset the disable inactive rendering state since activation has changed. 723 // Reset the disable inactive rendering state since activation has changed.
697 if (disable_inactive_rendering_) { 724 if (disable_inactive_rendering_) {
698 disable_inactive_rendering_ = false; 725 disable_inactive_rendering_ = false;
699 return CallDefaultNCActivateHandler(TRUE); 726 return CallDefaultNCActivateHandler(TRUE);
700 } 727 }
701 return CallDefaultNCActivateHandler(active); 728 return CallDefaultNCActivateHandler(active);
702 } 729 }
703 730
704 LRESULT WindowWin::OnNCCalcSize(BOOL mode, LPARAM l_param) { 731 LRESULT WindowWin::OnNCCalcSize(BOOL mode, LPARAM l_param) {
705 // We only need to adjust the client size/paint handling when we're not using 732 // We only override WM_NCCALCSIZE if we want non-standard non-client edge
706 // the native frame. 733 // width.
707 if (non_client_view_->UseNativeFrame()) 734 gfx::Insets insets = GetClientAreaInsets();
735 if (insets.width() == 0 && insets.height() == 0)
Peter Kasting 2009/10/23 05:09:31 Nit: I'm not in a position to check, but is there
708 return WidgetWin::OnNCCalcSize(mode, l_param); 736 return WidgetWin::OnNCCalcSize(mode, l_param);
709 737
710 RECT* client_rect = mode ? 738 RECT* client_rect = mode ?
711 &reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param)->rgrc[0] : 739 &reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param)->rgrc[0] :
712 reinterpret_cast<RECT*>(l_param); 740 reinterpret_cast<RECT*>(l_param);
741 client_rect->left += insets.left();
742 client_rect->top += insets.top();
743 client_rect->bottom -= insets.bottom();
744 client_rect->right -= insets.right();
713 if (IsMaximized()) { 745 if (IsMaximized()) {
714 // Make the maximized mode client rect fit the screen exactly, by
715 // subtracting the border Windows automatically adds for maximized mode.
716 int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
717 InflateRect(client_rect, -border_thickness, -border_thickness);
718
719 // Find all auto-hide taskbars along the screen edges and adjust in by the 746 // Find all auto-hide taskbars along the screen edges and adjust in by the
720 // thickness of the auto-hide taskbar on each such edge, so the window isn't 747 // thickness of the auto-hide taskbar on each such edge, so the window isn't
721 // treated as a "fullscreen app", which would cause the taskbars to 748 // treated as a "fullscreen app", which would cause the taskbars to
722 // disappear. 749 // disappear.
723 HMONITOR monitor = MonitorFromWindow(GetNativeView(), 750 HMONITOR monitor = MonitorFromWindow(GetNativeView(),
724 MONITOR_DEFAULTTONULL); 751 MONITOR_DEFAULTTONULL);
725 if (win_util::EdgeHasTopmostAutoHideTaskbar(ABE_LEFT, monitor)) 752 if (win_util::EdgeHasTopmostAutoHideTaskbar(ABE_LEFT, monitor))
726 client_rect->left += win_util::kAutoHideTaskbarThicknessPx; 753 client_rect->left += win_util::kAutoHideTaskbarThicknessPx;
727 if (win_util::EdgeHasTopmostAutoHideTaskbar(ABE_TOP, monitor)) 754 if (win_util::EdgeHasTopmostAutoHideTaskbar(ABE_TOP, monitor)) {
728 client_rect->top += win_util::kAutoHideTaskbarThicknessPx; 755 if (GetNonClientView()->UseNativeFrame()) {
756 // Tricky bit. Due to a bug in DwmDefWindowProc()'s handling of
757 // WM_NCHITTEST, having any nonclient area atop the window causes the
758 // caption buttons to draw onscreen but not respond to mouse
759 // hover/clicks.
760 // So for a taskbar at the screen top, we can't push the
761 // client_rect->top down; instead, we move the bottom up by one pixel,
762 // which is the smallest change we can make and still get a client area
763 // less than the screen size. This is visibly ugly, but there seems to
764 // be no better solution.
765 --client_rect->bottom;
766 } else {
767 client_rect->top += win_util::kAutoHideTaskbarThicknessPx;
768 }
769 }
729 if (win_util::EdgeHasTopmostAutoHideTaskbar(ABE_RIGHT, monitor)) 770 if (win_util::EdgeHasTopmostAutoHideTaskbar(ABE_RIGHT, monitor))
730 client_rect->right -= win_util::kAutoHideTaskbarThicknessPx; 771 client_rect->right -= win_util::kAutoHideTaskbarThicknessPx;
731 if (win_util::EdgeHasTopmostAutoHideTaskbar(ABE_BOTTOM, monitor)) 772 if (win_util::EdgeHasTopmostAutoHideTaskbar(ABE_BOTTOM, monitor))
732 client_rect->bottom -= win_util::kAutoHideTaskbarThicknessPx; 773 client_rect->bottom -= win_util::kAutoHideTaskbarThicknessPx;
733 774
734 // We cannot return WVR_REDRAW when there is nonclient area, or Windows 775 // We cannot return WVR_REDRAW when there is nonclient area, or Windows
735 // exhibits bugs where client pixels and child HWNDs are mispositioned by 776 // exhibits bugs where client pixels and child HWNDs are mispositioned by
736 // the width/height of the upper-left nonclient area. 777 // the width/height of the upper-left nonclient area.
737 return 0; 778 return 0;
738 } 779 }
739 780
740 // If the window bounds change, we're going to relayout and repaint anyway. 781 // If the window bounds change, we're going to relayout and repaint anyway.
741 // Returning WVR_REDRAW avoids an extra paint before that of the old client 782 // Returning WVR_REDRAW avoids an extra paint before that of the old client
742 // pixels in the (now wrong) location, and thus makes actions like resizing a 783 // pixels in the (now wrong) location, and thus makes actions like resizing a
743 // window from the left edge look slightly less broken. 784 // window from the left edge look slightly less broken.
785 // We special case when left and top insets are 0, since these conditions
Peter Kasting 2009/10/23 05:09:31 Nit: and -> or
786 // actually require another repaint to correct the layout after glass gets
787 // turned on and off.
788 if (insets.left() == 0 || insets.top() == 0)
789 return 0;
744 return mode ? WVR_REDRAW : 0; 790 return mode ? WVR_REDRAW : 0;
745 } 791 }
746 792
747 LRESULT WindowWin::OnNCHitTest(const CPoint& point) { 793 LRESULT WindowWin::OnNCHitTest(const CPoint& point) {
748 // First, give the NonClientView a chance to test the point to see if it 794 // First, give the NonClientView a chance to test the point to see if it
749 // provides any of the non-client area. 795 // provides any of the non-client area.
750 CPoint temp = point; 796 CPoint temp = point;
751 MapWindowPoints(HWND_DESKTOP, GetNativeView(), &temp, 1); 797 MapWindowPoints(HWND_DESKTOP, GetNativeView(), &temp, 1);
752 int component = non_client_view_->NonClientHitTest(gfx::Point(temp)); 798 int component = non_client_view_->NonClientHitTest(gfx::Point(temp));
753 if (component != HTNOWHERE) 799 if (component != HTNOWHERE)
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 } 1164 }
1119 last_monitor_ = monitor; 1165 last_monitor_ = monitor;
1120 last_monitor_rect_ = monitor_rect; 1166 last_monitor_rect_ = monitor_rect;
1121 last_work_area_ = work_area; 1167 last_work_area_ = work_area;
1122 } 1168 }
1123 } 1169 }
1124 1170
1125 WidgetWin::OnWindowPosChanging(window_pos); 1171 WidgetWin::OnWindowPosChanging(window_pos);
1126 } 1172 }
1127 1173
1174 gfx::Size WindowWin::GetRootViewSize() const {
1175 // The native frame and maximized modes need to supply the client rect as
1176 // determined by the relevant WM_NCCALCSIZE handling, so we just use the
1177 // default handling which does this.
1178 if (GetNonClientView()->UseNativeFrame() || IsMaximized())
1179 return WidgetWin::GetRootViewSize();
1180
1181 // When using an opaque frame, we consider the entire window rect to be client
1182 // area visually.
1183 CRect rect;
1184 GetWindowRect(&rect);
1185 return gfx::Size(rect.Width(), rect.Height());
1186 }
1187
1128 //////////////////////////////////////////////////////////////////////////////// 1188 ////////////////////////////////////////////////////////////////////////////////
1129 // WindowWin, private: 1189 // WindowWin, private:
1130 1190
1131 void WindowWin::BecomeModal() { 1191 void WindowWin::BecomeModal() {
1132 // We implement modality by crawling up the hierarchy of windows starting 1192 // We implement modality by crawling up the hierarchy of windows starting
1133 // at the owner, disabling all of them so that they don't receive input 1193 // at the owner, disabling all of them so that they don't receive input
1134 // messages. 1194 // messages.
1135 DCHECK(owning_hwnd_) << "Can't create a modal dialog without an owner"; 1195 DCHECK(owning_hwnd_) << "Can't create a modal dialog without an owner";
1136 HWND start = owning_hwnd_; 1196 HWND start = owning_hwnd_;
1137 while (start != NULL) { 1197 while (start != NULL) {
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1375 Window::CloseSecondaryWidget(root_view->GetWidget()); 1435 Window::CloseSecondaryWidget(root_view->GetWidget());
1376 return TRUE; 1436 return TRUE;
1377 } 1437 }
1378 } // namespace 1438 } // namespace
1379 1439
1380 void Window::CloseAllSecondaryWindows() { 1440 void Window::CloseAllSecondaryWindows() {
1381 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0); 1441 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0);
1382 } 1442 }
1383 1443
1384 } // namespace views 1444 } // namespace views
OLDNEW
« views/widget/widget_win.cc ('K') | « views/window/window_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698