Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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" |
| 11 #include "app/gfx/font.h" | 11 #include "app/gfx/font.h" |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 492 window_closed_(false), | 492 window_closed_(false), |
| 493 disable_inactive_rendering_(false), | 493 disable_inactive_rendering_(false), |
| 494 is_active_(false), | 494 is_active_(false), |
| 495 lock_updates_(false), | 495 lock_updates_(false), |
| 496 saved_window_style_(0), | 496 saved_window_style_(0), |
| 497 saved_maximized_state_(0), | 497 saved_maximized_state_(0), |
| 498 ignore_window_pos_changes_(false), | 498 ignore_window_pos_changes_(false), |
| 499 ignore_pos_changes_factory_(this), | 499 ignore_pos_changes_factory_(this), |
| 500 force_hidden_count_(0), | 500 force_hidden_count_(0), |
| 501 is_right_mouse_pressed_on_caption_(false), | 501 is_right_mouse_pressed_on_caption_(false), |
| 502 last_time_system_menu_clicked_(0), | |
| 503 last_monitor_(NULL) { | 502 last_monitor_(NULL) { |
| 504 is_window_ = true; | 503 is_window_ = true; |
| 505 InitClass(); | 504 InitClass(); |
| 506 DCHECK(window_delegate_); | 505 DCHECK(window_delegate_); |
| 507 window_delegate_->window_.reset(this); | 506 window_delegate_->window_.reset(this); |
| 508 // Initialize these values to 0 so that subclasses can override the default | 507 // Initialize these values to 0 so that subclasses can override the default |
| 509 // behavior before calling Init. | 508 // behavior before calling Init. |
| 510 set_window_style(0); | 509 set_window_style(0); |
| 511 set_window_ex_style(0); | 510 set_window_ex_style(0); |
| 512 } | 511 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 569 // know why) the client area goes from matching the window rect to being | 568 // know why) the client area goes from matching the window rect to being |
| 570 // something else. If the client area is not the window rect in both | 569 // something else. If the client area is not the window rect in both |
| 571 // modes, the blackness doesn't occur. Because of this, we need to tell | 570 // modes, the blackness doesn't occur. Because of this, we need to tell |
| 572 // the RootView to lay out to fit the window rect, rather than the client | 571 // the RootView to lay out to fit the window rect, rather than the client |
| 573 // rect when using the opaque frame. See GetRootViewSize. | 572 // rect when using the opaque frame. See GetRootViewSize. |
| 574 // Note: this is only required for non-fullscreen windows. Note that | 573 // Note: this is only required for non-fullscreen windows. Note that |
| 575 // fullscreen windows are in restored state, not maximized. | 574 // fullscreen windows are in restored state, not maximized. |
| 576 return gfx::Insets(0, 0, IsFullscreen() ? 0 : 1, 0); | 575 return gfx::Insets(0, 0, IsFullscreen() ? 0 : 1, 0); |
| 577 } | 576 } |
| 578 | 577 |
| 579 void WindowWin::RunSystemMenu(const gfx::Point& point) { | |
| 580 // We need to reset and clean up any currently created system menu objects. | |
| 581 // We need to call this otherwise there's a small chance that we aren't going | |
| 582 // to get a system menu. We also can't take the return value of this | |
| 583 // function. We need to call it *again* to get a valid HMENU. | |
| 584 //::GetSystemMenu(GetNativeView(), TRUE); | |
| 585 UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD; | |
| 586 if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) | |
| 587 flags |= TPM_RIGHTALIGN; | |
| 588 HMENU system_menu = ::GetSystemMenu(GetNativeView(), FALSE); | |
| 589 int id = ::TrackPopupMenu(system_menu, flags, | |
| 590 point.x(), point.y(), 0, GetNativeView(), NULL); | |
| 591 ExecuteSystemMenuCommand(id); | |
| 592 if (id) // something was selected | |
| 593 last_time_system_menu_clicked_ = 0; | |
| 594 } | |
| 595 | |
| 596 /////////////////////////////////////////////////////////////////////////////// | 578 /////////////////////////////////////////////////////////////////////////////// |
| 597 // WindowWin, WidgetWin overrides: | 579 // WindowWin, WidgetWin overrides: |
| 598 | 580 |
| 599 void WindowWin::OnActivate(UINT action, BOOL minimized, HWND window) { | 581 void WindowWin::OnActivate(UINT action, BOOL minimized, HWND window) { |
| 600 if (action == WA_INACTIVE) | 582 if (action == WA_INACTIVE) |
| 601 SaveWindowPosition(); | 583 SaveWindowPosition(); |
| 602 } | 584 } |
| 603 | 585 |
| 604 void WindowWin::OnActivateApp(BOOL active, DWORD thread_id) { | 586 void WindowWin::OnActivateApp(BOOL active, DWORD thread_id) { |
| 605 if (!active && thread_id != GetCurrentThreadId()) { | 587 if (!active && thread_id != GetCurrentThreadId()) { |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 955 // window control button appearance, in the Windows classic style, over | 937 // window control button appearance, in the Windows classic style, over |
| 956 // our view! Ick! By handling this message we prevent Windows from | 938 // our view! Ick! By handling this message we prevent Windows from |
| 957 // doing this undesirable thing, but that means we need to roll the | 939 // doing this undesirable thing, but that means we need to roll the |
| 958 // sys-command handling ourselves. | 940 // sys-command handling ourselves. |
| 959 ProcessNCMousePress(point, MK_LBUTTON); | 941 ProcessNCMousePress(point, MK_LBUTTON); |
| 960 return; | 942 return; |
| 961 } | 943 } |
| 962 } | 944 } |
| 963 } | 945 } |
| 964 | 946 |
| 965 // TODO(beng): figure out why we need to run the system menu manually | 947 WidgetWin::OnNCLButtonDown(ht_component, point); |
| 966 // ourselves. This is wrong and causes many subtle bugs. | |
| 967 // From my initial research, it looks like DefWindowProc tries | |
| 968 // to run it but fails before sending the initial WM_MENUSELECT | |
| 969 // for the sysmenu. | |
| 970 // TODO(georgey): Remove the fix for double click when we figure out why | |
| 971 // system menu does not open automatically and pass it to | |
| 972 // default processing. | |
| 973 if (ht_component == HTSYSMENU) { | |
| 974 // We use 0 as a special value. If user is "lucky" and double clicks on | |
| 975 // system icon exactly 49.7x days after PC was started we ignore that | |
| 976 // click. | |
| 977 last_time_system_menu_clicked_ = GetTickCount(); | |
| 978 RunSystemMenu(non_client_view_->GetSystemMenuPoint()); | |
| 979 } else { | |
| 980 WidgetWin::OnNCLButtonDown(ht_component, point); | |
| 981 } | |
| 982 | 948 |
| 983 /* TODO(beng): Fix the standard non-client over-painting bug. This code | 949 /* TODO(beng): Fix the standard non-client over-painting bug. This code |
| 984 doesn't work but identifies the problem. | 950 doesn't work but identifies the problem. |
| 985 if (!IsMsgHandled()) { | 951 if (!IsMsgHandled()) { |
| 986 // WindowWin::OnNCLButtonDown set the message as unhandled. This normally | 952 // WindowWin::OnNCLButtonDown set the message as unhandled. This normally |
| 987 // means WidgetWin::ProcessWindowMessage will pass it to | 953 // means WidgetWin::ProcessWindowMessage will pass it to |
| 988 // DefWindowProc. Sadly, DefWindowProc for WM_NCLBUTTONDOWN does weird | 954 // DefWindowProc. Sadly, DefWindowProc for WM_NCLBUTTONDOWN does weird |
| 989 // non-client painting, so we need to call it directly here inside a | 955 // non-client painting, so we need to call it directly here inside a |
| 990 // scoped update lock. | 956 // scoped update lock. |
| 991 ScopedRedrawLock lock(this); | 957 ScopedRedrawLock lock(this); |
| 992 DefWindowProc(GetNativeView(), WM_NCLBUTTONDOWN, ht_component, | 958 DefWindowProc(GetNativeView(), WM_NCLBUTTONDOWN, ht_component, |
| 993 MAKELPARAM(point.x, point.y)); | 959 MAKELPARAM(point.x, point.y)); |
| 994 SetMsgHandled(TRUE); | 960 SetMsgHandled(TRUE); |
| 995 } | 961 } |
| 996 */ | 962 */ |
| 997 } | 963 } |
| 998 | 964 |
| 999 void WindowWin::OnNCLButtonUp(UINT ht_component, const CPoint& point) { | |
| 1000 // georgey : fix for double click on system icon not working | |
| 1001 // As we do track on system menu, the following sequence occurs, when user | |
| 1002 // double clicks: | |
| 1003 // 1. Window gets WM_NCLBUTTONDOWN with ht_component == HTSYSMENU | |
| 1004 // 2. We call TrackPopupMenu, that captures the mouse | |
| 1005 // 3. Menu, not window, gets WM_NCLBUTTONUP | |
| 1006 // 4. Menu gets WM_NCLBUTTONDOWN and closes returning 0 (canceled) from | |
| 1007 // TrackPopupMenu. | |
| 1008 // 5. Window gets WM_NCLBUTTONUP with ht_component == HTSYSMENU | |
| 1009 if (ht_component == HTSYSMENU) { | |
| 1010 if (last_time_system_menu_clicked_) { | |
| 1011 if ((GetTickCount() - last_time_system_menu_clicked_) <= | |
| 1012 GetDoubleClickTime()) { | |
| 1013 // User double clicked left mouse button on system menu - close | |
| 1014 // window | |
| 1015 ExecuteSystemMenuCommand(SC_CLOSE); | |
| 1016 } | |
| 1017 last_time_system_menu_clicked_ = 0; | |
| 1018 } | |
| 1019 } | |
| 1020 | |
| 1021 WidgetWin::OnNCLButtonUp(ht_component, point); | |
| 1022 } | |
| 1023 | |
| 1024 void WindowWin::OnNCRButtonDown(UINT ht_component, const CPoint& point) { | 965 void WindowWin::OnNCRButtonDown(UINT ht_component, const CPoint& point) { |
| 1025 if (ht_component == HTCAPTION || ht_component == HTSYSMENU) { | 966 if (ht_component == HTCAPTION || ht_component == HTSYSMENU) { |
| 1026 is_right_mouse_pressed_on_caption_ = true; | 967 is_right_mouse_pressed_on_caption_ = true; |
| 1027 // Using SetCapture() here matches Windows native behavior for right-clicks | 968 // We SetCapture() to ensure we only show the menu when the button down and |
| 1028 // on the title bar. It's not obvious why Windows does this. | 969 // up are both on the caption. Note: this causes the button up to be |
| 970 // WM_RBUTTONUP instead of WM_NCRBUTTONUP. | |
| 1029 SetCapture(); | 971 SetCapture(); |
| 1030 } | 972 } |
| 1031 | 973 |
| 1032 WidgetWin::OnNCRButtonDown(ht_component, point); | 974 WidgetWin::OnNCRButtonDown(ht_component, point); |
| 1033 } | 975 } |
| 1034 | 976 |
| 1035 void WindowWin::OnNCRButtonUp(UINT ht_component, const CPoint& point) { | |
| 1036 if (is_right_mouse_pressed_on_caption_) | |
| 1037 is_right_mouse_pressed_on_caption_ = false; | |
| 1038 | |
| 1039 WidgetWin::OnNCRButtonUp(ht_component, point); | |
| 1040 } | |
| 1041 | |
| 1042 void WindowWin::OnRButtonUp(UINT ht_component, const CPoint& point) { | 977 void WindowWin::OnRButtonUp(UINT ht_component, const CPoint& point) { |
| 1043 // We handle running the system menu on mouseup here because calling | |
| 1044 // SetCapture() on mousedown makes the mouseup generate WM_RBUTTONUP instead | |
| 1045 // of WM_NCRBUTTONUP. | |
| 1046 if (is_right_mouse_pressed_on_caption_) { | 978 if (is_right_mouse_pressed_on_caption_) { |
| 1047 is_right_mouse_pressed_on_caption_ = false; | 979 is_right_mouse_pressed_on_caption_ = false; |
| 1048 ReleaseCapture(); | 980 ReleaseCapture(); |
| 1049 // |point| is in window coordinates, but WM_NCHITTEST and RunSystemMenu() | 981 // |point| is in window coordinates, but WM_NCHITTEST and TrackPopupMenu() |
| 1050 // expect screen coordinates. | 982 // expect screen coordinates. |
| 1051 CPoint screen_point(point); | 983 CPoint screen_point(point); |
| 1052 MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_point, 1); | 984 MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_point, 1); |
| 1053 ht_component = ::SendMessage(GetNativeView(), WM_NCHITTEST, 0, | 985 ht_component = SendMessage(GetNativeView(), WM_NCHITTEST, 0, |
| 1054 MAKELPARAM(screen_point.x, screen_point.y)); | 986 MAKELPARAM(screen_point.x, screen_point.y)); |
| 1055 if (ht_component == HTCAPTION || ht_component == HTSYSMENU) { | 987 if (ht_component == HTCAPTION || ht_component == HTSYSMENU) { |
| 1056 RunSystemMenu(gfx::Point(screen_point)); | 988 UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD; |
| 989 if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) | |
| 990 flags |= TPM_RIGHTALIGN; | |
| 991 HMENU system_menu = GetSystemMenu(GetNativeView(), FALSE); | |
| 992 int id = TrackPopupMenu(system_menu, flags, screen_point.x, | |
| 993 screen_point.y, 0, GetNativeView(), NULL); | |
| 994 ExecuteSystemMenuCommand(id); | |
|
Ben Goodger (Google)
2010/02/05 03:27:25
This is all because we called SetCapture right? i.
Peter Kasting
2010/02/05 05:01:06
Sadly, no. I tried this, and then I tried making
| |
| 1057 return; | 995 return; |
| 1058 } | 996 } |
| 1059 } | 997 } |
| 1060 | 998 |
| 1061 WidgetWin::OnRButtonUp(ht_component, point); | 999 WidgetWin::OnRButtonUp(ht_component, point); |
| 1062 } | 1000 } |
| 1063 | 1001 |
| 1064 LRESULT WindowWin::OnNCUAHDrawCaption(UINT msg, WPARAM w_param, | 1002 LRESULT WindowWin::OnNCUAHDrawCaption(UINT msg, WPARAM w_param, |
| 1065 LPARAM l_param) { | 1003 LPARAM l_param) { |
| 1066 // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for | 1004 // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1139 // sizing/moving feedback can be continuous. | 1077 // sizing/moving feedback can be continuous. |
| 1140 UnlockUpdates(); | 1078 UnlockUpdates(); |
| 1141 } | 1079 } |
| 1142 } | 1080 } |
| 1143 } | 1081 } |
| 1144 | 1082 |
| 1145 // First see if the delegate can handle it. | 1083 // First see if the delegate can handle it. |
| 1146 if (window_delegate_->ExecuteWindowsCommand(notification_code)) | 1084 if (window_delegate_->ExecuteWindowsCommand(notification_code)) |
| 1147 return; | 1085 return; |
| 1148 | 1086 |
| 1149 if ((notification_code == SC_KEYMENU) && (click.x == VK_SPACE)) { | 1087 // Use the default implementation for any other command. |
| 1150 // Run the system menu at the NonClientView's desired location. | 1088 DefWindowProc(GetNativeView(), WM_SYSCOMMAND, notification_code, |
| 1151 RunSystemMenu(non_client_view_->GetSystemMenuPoint()); | 1089 MAKELPARAM(click.x, click.y)); |
| 1152 } else { | |
| 1153 // Use the default implementation for any other command. | |
| 1154 DefWindowProc(GetNativeView(), WM_SYSCOMMAND, notification_code, | |
| 1155 MAKELPARAM(click.y, click.x)); | |
| 1156 } | |
| 1157 } | 1090 } |
| 1158 | 1091 |
| 1159 void WindowWin::OnWindowPosChanging(WINDOWPOS* window_pos) { | 1092 void WindowWin::OnWindowPosChanging(WINDOWPOS* window_pos) { |
| 1160 if (force_hidden_count_) { | 1093 if (force_hidden_count_) { |
| 1161 // Prevent the window from being made visible if we've been asked to do so. | 1094 // Prevent the window from being made visible if we've been asked to do so. |
| 1162 // See comment in header as to why we might want this. | 1095 // See comment in header as to why we might want this. |
| 1163 window_pos->flags &= ~SWP_SHOWWINDOW; | 1096 window_pos->flags &= ~SWP_SHOWWINDOW; |
| 1164 } | 1097 } |
| 1165 | 1098 |
| 1166 if (ignore_window_pos_changes_) { | 1099 if (ignore_window_pos_changes_) { |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1491 Window::CloseSecondaryWidget(root_view->GetWidget()); | 1424 Window::CloseSecondaryWidget(root_view->GetWidget()); |
| 1492 return TRUE; | 1425 return TRUE; |
| 1493 } | 1426 } |
| 1494 } // namespace | 1427 } // namespace |
| 1495 | 1428 |
| 1496 void Window::CloseAllSecondaryWindows() { | 1429 void Window::CloseAllSecondaryWindows() { |
| 1497 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0); | 1430 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0); |
| 1498 } | 1431 } |
| 1499 | 1432 |
| 1500 } // namespace views | 1433 } // namespace views |
| OLD | NEW |