Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |