Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/widget/widget_win.h" | 5 #include "views/widget/widget_win.h" |
| 6 | 6 |
| 7 #include <dwmapi.h> | 7 #include <dwmapi.h> |
| 8 | 8 |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "base/win/windows_version.h" | 10 #include "base/win/windows_version.h" |
| 11 #include "ui/base/dragdrop/drag_drop_types.h" | 11 #include "ui/base/dragdrop/drag_drop_types.h" |
| 12 #include "ui/base/dragdrop/drag_source.h" | 12 #include "ui/base/dragdrop/drag_source.h" |
| 13 #include "ui/base/dragdrop/os_exchange_data.h" | 13 #include "ui/base/dragdrop/os_exchange_data.h" |
| 14 #include "ui/base/dragdrop/os_exchange_data_provider_win.h" | 14 #include "ui/base/dragdrop/os_exchange_data_provider_win.h" |
| 15 #include "ui/base/keycodes/keyboard_code_conversion_win.h" | 15 #include "ui/base/keycodes/keyboard_code_conversion_win.h" |
| 16 #include "ui/base/l10n/l10n_util_win.h" | 16 #include "ui/base/l10n/l10n_util_win.h" |
| 17 #include "ui/base/system_monitor/system_monitor.h" | 17 #include "ui/base/system_monitor/system_monitor.h" |
| 18 #include "ui/base/theme_provider.h" | 18 #include "ui/base/theme_provider.h" |
| 19 #include "ui/base/view_prop.h" | 19 #include "ui/base/view_prop.h" |
| 20 #include "ui/base/win/hwnd_util.h" | 20 #include "ui/base/win/hwnd_util.h" |
| 21 #include "ui/gfx/canvas_skia.h" | 21 #include "ui/gfx/canvas_skia.h" |
| 22 #include "ui/gfx/native_theme_win.h" | 22 #include "ui/gfx/native_theme_win.h" |
| 23 #include "ui/gfx/path.h" | 23 #include "ui/gfx/path.h" |
| 24 #include "views/accessibility/native_view_accessibility_win.h" | 24 #include "views/accessibility/native_view_accessibility_win.h" |
| 25 #include "views/controls/native_control_win.h" | 25 #include "views/controls/native_control_win.h" |
| 26 #include "views/focus/accelerator_handler.h" | 26 #include "views/focus/accelerator_handler.h" |
| 27 #include "views/focus/focus_util_win.h" | 27 #include "views/focus/focus_util_win.h" |
| 28 #include "views/focus/view_storage.h" | 28 #include "views/focus/view_storage.h" |
| 29 #include "views/ime/input_method.h" | |
| 29 #include "views/views_delegate.h" | 30 #include "views/views_delegate.h" |
| 30 #include "views/widget/aero_tooltip_manager.h" | 31 #include "views/widget/aero_tooltip_manager.h" |
| 31 #include "views/widget/child_window_message_processor.h" | 32 #include "views/widget/child_window_message_processor.h" |
| 32 #include "views/widget/drop_target_win.h" | 33 #include "views/widget/drop_target_win.h" |
| 33 #include "views/widget/native_widget_delegate.h" | 34 #include "views/widget/native_widget_delegate.h" |
| 34 #include "views/widget/root_view.h" | 35 #include "views/widget/root_view.h" |
| 35 #include "views/widget/widget_delegate.h" | 36 #include "views/widget/widget_delegate.h" |
| 36 #include "views/window/window_win.h" | 37 #include "views/window/window_win.h" |
| 37 | 38 |
| 38 #pragma comment(lib, "dwmapi.lib") | 39 #pragma comment(lib, "dwmapi.lib") |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 138 layered_alpha_(255), | 139 layered_alpha_(255), |
| 139 ALLOW_THIS_IN_INITIALIZER_LIST(paint_layered_window_factory_(this)), | 140 ALLOW_THIS_IN_INITIALIZER_LIST(paint_layered_window_factory_(this)), |
| 140 delete_on_destroy_(true), | 141 delete_on_destroy_(true), |
| 141 can_update_layered_window_(true), | 142 can_update_layered_window_(true), |
| 142 last_mouse_event_was_move_(false), | 143 last_mouse_event_was_move_(false), |
| 143 is_mouse_down_(false), | 144 is_mouse_down_(false), |
| 144 is_window_(false), | 145 is_window_(false), |
| 145 restore_focus_when_enabled_(false), | 146 restore_focus_when_enabled_(false), |
| 146 accessibility_view_events_index_(-1), | 147 accessibility_view_events_index_(-1), |
| 147 accessibility_view_events_(kMaxAccessibilityViewEvents), | 148 accessibility_view_events_(kMaxAccessibilityViewEvents), |
| 148 previous_cursor_(NULL) { | 149 previous_cursor_(NULL), |
| 150 is_input_method_win_(false) { | |
| 149 set_native_widget(this); | 151 set_native_widget(this); |
| 150 } | 152 } |
| 151 | 153 |
| 152 WidgetWin::~WidgetWin() { | 154 WidgetWin::~WidgetWin() { |
| 153 DestroyRootView(); | 155 DestroyRootView(); |
| 154 } | 156 } |
| 155 | 157 |
| 156 // static | 158 // static |
| 157 WidgetWin* WidgetWin::GetWidget(HWND hwnd) { | 159 WidgetWin* WidgetWin::GetWidget(HWND hwnd) { |
| 158 // TODO(jcivelli): http://crbug.com/44499 We need a way to test that hwnd is | 160 // TODO(jcivelli): http://crbug.com/44499 We need a way to test that hwnd is |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 275 } | 277 } |
| 276 | 278 |
| 277 void WidgetWin::ReleaseNativeCapture() { | 279 void WidgetWin::ReleaseNativeCapture() { |
| 278 ReleaseCapture(); | 280 ReleaseCapture(); |
| 279 } | 281 } |
| 280 | 282 |
| 281 bool WidgetWin::HasNativeCapture() const { | 283 bool WidgetWin::HasNativeCapture() const { |
| 282 return GetCapture() == hwnd(); | 284 return GetCapture() == hwnd(); |
| 283 } | 285 } |
| 284 | 286 |
| 287 InputMethod* WidgetWin::GetInputMethodNative() { | |
| 288 return input_method_.get(); | |
| 289 } | |
| 290 | |
| 291 void WidgetWin::ReplaceInputMethod(InputMethod* input_method) { | |
| 292 input_method_.reset(input_method); | |
| 293 if (input_method) { | |
| 294 input_method->set_delegate(this); | |
| 295 input_method->Init(GetWidget()); | |
| 296 } | |
| 297 is_input_method_win_ = false; | |
| 298 } | |
| 299 | |
| 285 gfx::Rect WidgetWin::GetWindowScreenBounds() const { | 300 gfx::Rect WidgetWin::GetWindowScreenBounds() const { |
| 286 RECT r; | 301 RECT r; |
| 287 GetWindowRect(&r); | 302 GetWindowRect(&r); |
| 288 return gfx::Rect(r); | 303 return gfx::Rect(r); |
| 289 } | 304 } |
| 290 | 305 |
| 291 gfx::Rect WidgetWin::GetClientAreaScreenBounds() const { | 306 gfx::Rect WidgetWin::GetClientAreaScreenBounds() const { |
| 292 RECT r; | 307 RECT r; |
| 293 GetClientRect(&r); | 308 GetClientRect(&r); |
| 294 POINT point = { r.left, r.top }; | 309 POINT point = { r.left, r.top }; |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 325 // we don't destroy the window before the callback returned (as the caller | 340 // we don't destroy the window before the callback returned (as the caller |
| 326 // may delete ourselves on destroy and the ATL callback would still | 341 // may delete ourselves on destroy and the ATL callback would still |
| 327 // dereference us when the callback returns). | 342 // dereference us when the callback returns). |
| 328 MessageLoop::current()->PostTask(FROM_HERE, | 343 MessageLoop::current()->PostTask(FROM_HERE, |
| 329 close_widget_factory_.NewRunnableMethod( | 344 close_widget_factory_.NewRunnableMethod( |
| 330 &WidgetWin::CloseNow)); | 345 &WidgetWin::CloseNow)); |
| 331 } | 346 } |
| 332 } | 347 } |
| 333 | 348 |
| 334 void WidgetWin::CloseNow() { | 349 void WidgetWin::CloseNow() { |
| 350 // Destroys the input method before closing the window so that it can be | |
| 351 // detached from the widget correctly. | |
| 352 input_method_.reset(); | |
| 353 is_input_method_win_ = false; | |
| 354 | |
| 335 // We may already have been destroyed if the selection resulted in a tab | 355 // We may already have been destroyed if the selection resulted in a tab |
| 336 // switch which will have reactivated the browser window and closed us, so | 356 // switch which will have reactivated the browser window and closed us, so |
| 337 // we need to check to see if we're still a window before trying to destroy | 357 // we need to check to see if we're still a window before trying to destroy |
| 338 // ourself. | 358 // ourself. |
| 339 if (IsWindow()) | 359 if (IsWindow()) |
| 340 DestroyWindow(hwnd()); | 360 DestroyWindow(hwnd()); |
| 341 } | 361 } |
| 342 | 362 |
| 343 void WidgetWin::Show() { | 363 void WidgetWin::Show() { |
| 344 if (IsWindow()) | 364 if (IsWindow()) |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 564 // Bug 964884: detach the IME attached to this window. | 584 // Bug 964884: detach the IME attached to this window. |
| 565 // We should attach IMEs only when we need to input CJK strings. | 585 // We should attach IMEs only when we need to input CJK strings. |
| 566 ImmAssociateContextEx(hwnd(), NULL, 0); | 586 ImmAssociateContextEx(hwnd(), NULL, 0); |
| 567 | 587 |
| 568 // We need to allow the delegate to size its contents since the window may not | 588 // We need to allow the delegate to size its contents since the window may not |
| 569 // receive a size notification when its initial bounds are specified at window | 589 // receive a size notification when its initial bounds are specified at window |
| 570 // creation time. | 590 // creation time. |
| 571 ClientAreaSizeChanged(); | 591 ClientAreaSizeChanged(); |
| 572 | 592 |
| 573 delegate_->OnNativeWidgetCreated(); | 593 delegate_->OnNativeWidgetCreated(); |
| 594 | |
| 595 // delegate_->OnNativeWidgetCreated() creates the focus manager for top-level | |
| 596 // widget. Only top-level widget should have an input method. | |
| 597 if (delegate_->HasFocusManager()) { | |
| 598 input_method_.reset(new InputMethodWin(this)); | |
| 599 input_method_->Init(GetWidget()); | |
| 600 is_input_method_win_ = true; | |
| 601 } | |
| 574 return 0; | 602 return 0; |
| 575 } | 603 } |
| 576 | 604 |
| 577 void WidgetWin::OnDestroy() { | 605 void WidgetWin::OnDestroy() { |
| 578 if (drop_target_.get()) { | 606 if (drop_target_.get()) { |
| 579 RevokeDragDrop(hwnd()); | 607 RevokeDragDrop(hwnd()); |
| 580 drop_target_ = NULL; | 608 drop_target_ = NULL; |
| 581 } | 609 } |
| 582 | 610 |
| 583 props_.reset(); | 611 props_.reset(); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 643 } | 671 } |
| 644 | 672 |
| 645 void WidgetWin::OnGetMinMaxInfo(MINMAXINFO* minmax_info) { | 673 void WidgetWin::OnGetMinMaxInfo(MINMAXINFO* minmax_info) { |
| 646 SetMsgHandled(FALSE); | 674 SetMsgHandled(FALSE); |
| 647 } | 675 } |
| 648 | 676 |
| 649 void WidgetWin::OnHScroll(int scroll_type, short position, HWND scrollbar) { | 677 void WidgetWin::OnHScroll(int scroll_type, short position, HWND scrollbar) { |
| 650 SetMsgHandled(FALSE); | 678 SetMsgHandled(FALSE); |
| 651 } | 679 } |
| 652 | 680 |
| 681 LRESULT WidgetWin::OnImeMessages(UINT message, WPARAM w_param, LPARAM l_param) { | |
| 682 if (!is_input_method_win_) { | |
| 683 SetMsgHandled(FALSE); | |
| 684 return 0; | |
| 685 } | |
| 686 | |
| 687 InputMethodWin* ime = static_cast<InputMethodWin*>(input_method_.get()); | |
| 688 BOOL handled = FALSE; | |
| 689 LRESULT result = 0; | |
| 690 switch (message) { | |
| 691 case WM_IME_SETCONTEXT: | |
| 692 result = ime->OnImeSetContext(message, w_param, l_param, &handled); | |
| 693 break; | |
| 694 case WM_IME_STARTCOMPOSITION: | |
| 695 result = ime->OnImeStartComposition(message, w_param, l_param, &handled); | |
| 696 break; | |
| 697 case WM_IME_COMPOSITION: | |
| 698 result = ime->OnImeComposition(message, w_param, l_param, &handled); | |
| 699 break; | |
| 700 case WM_IME_ENDCOMPOSITION: | |
| 701 result = ime->OnImeEndComposition(message, w_param, l_param, &handled); | |
| 702 break; | |
| 703 case WM_CHAR: | |
| 704 case WM_SYSCHAR: | |
| 705 result = ime->OnChar(message, w_param, l_param, &handled); | |
| 706 break; | |
| 707 case WM_DEADCHAR: | |
| 708 case WM_SYSDEADCHAR: | |
| 709 result = ime->OnDeadChar(message, w_param, l_param, &handled); | |
| 710 break; | |
| 711 default: | |
| 712 NOTREACHED() << "Unknown IME message:" << message; | |
| 713 break; | |
| 714 } | |
| 715 | |
| 716 SetMsgHandled(handled); | |
| 717 return result; | |
| 718 } | |
| 719 | |
| 653 void WidgetWin::OnInitMenu(HMENU menu) { | 720 void WidgetWin::OnInitMenu(HMENU menu) { |
| 654 SetMsgHandled(FALSE); | 721 SetMsgHandled(FALSE); |
| 655 } | 722 } |
| 656 | 723 |
| 657 void WidgetWin::OnInitMenuPopup(HMENU menu, | 724 void WidgetWin::OnInitMenuPopup(HMENU menu, |
| 658 UINT position, | 725 UINT position, |
| 659 BOOL is_system_menu) { | 726 BOOL is_system_menu) { |
| 660 SetMsgHandled(FALSE); | 727 SetMsgHandled(FALSE); |
| 661 } | 728 } |
| 662 | 729 |
| 730 void WidgetWin::OnInputLangChange(DWORD character_set, HKL input_language_id) { | |
| 731 if (is_input_method_win_) { | |
| 732 static_cast<InputMethodWin*>(input_method_.get())->OnInputLangChange( | |
| 733 character_set, input_language_id); | |
| 734 } | |
| 735 } | |
| 736 | |
| 663 LRESULT WidgetWin::OnKeyDown(UINT message, WPARAM w_param, LPARAM l_param) { | 737 LRESULT WidgetWin::OnKeyDown(UINT message, WPARAM w_param, LPARAM l_param) { |
| 664 RootView* root_view = GetFocusedViewRootView(); | |
| 665 if (!root_view) | |
| 666 root_view = GetRootView(); | |
| 667 | |
| 668 MSG msg; | 738 MSG msg; |
| 669 MakeMSG(&msg, message, w_param, l_param); | 739 MakeMSG(&msg, message, w_param, l_param); |
| 670 SetMsgHandled(root_view->ProcessKeyEvent(KeyEvent(msg))); | 740 KeyEvent key(msg); |
| 741 if (input_method_.get()) | |
| 742 input_method_->DispatchKeyEvent(key); | |
| 743 else | |
| 744 DispatchKeyEventPostIME(key); | |
|
sadrul
2011/03/21 19:57:45
Instead of DispatchKeyEvent'ing here (and OnKeyUp,
James Su
2011/03/21 21:34:07
It's not possible. The native widget may still nee
| |
| 671 return 0; | 745 return 0; |
| 672 } | 746 } |
| 673 | 747 |
| 674 LRESULT WidgetWin::OnKeyUp(UINT message, WPARAM w_param, LPARAM l_param) { | 748 LRESULT WidgetWin::OnKeyUp(UINT message, WPARAM w_param, LPARAM l_param) { |
| 675 RootView* root_view = GetFocusedViewRootView(); | |
| 676 if (!root_view) | |
| 677 root_view = GetRootView(); | |
| 678 | |
| 679 MSG msg; | 749 MSG msg; |
| 680 MakeMSG(&msg, message, w_param, l_param); | 750 MakeMSG(&msg, message, w_param, l_param); |
| 681 SetMsgHandled(root_view->ProcessKeyEvent(KeyEvent(msg))); | 751 KeyEvent key(msg); |
| 752 if (input_method_.get()) | |
| 753 input_method_->DispatchKeyEvent(key); | |
| 754 else | |
| 755 DispatchKeyEventPostIME(key); | |
| 682 return 0; | 756 return 0; |
| 683 } | 757 } |
| 684 | 758 |
| 685 void WidgetWin::OnKillFocus(HWND focused_window) { | 759 void WidgetWin::OnKillFocus(HWND focused_window) { |
| 686 delegate_->OnNativeBlur(focused_window); | 760 delegate_->OnNativeBlur(focused_window); |
| 761 if (is_input_method_win_) | |
| 762 static_cast<InputMethodWin*>(input_method_.get())->OnKillFocus(); | |
| 687 SetMsgHandled(FALSE); | 763 SetMsgHandled(FALSE); |
| 688 } | 764 } |
| 689 | 765 |
| 690 LRESULT WidgetWin::OnMouseActivate(UINT message, | 766 LRESULT WidgetWin::OnMouseActivate(UINT message, |
| 691 WPARAM w_param, | 767 WPARAM w_param, |
| 692 LPARAM l_param) { | 768 LPARAM l_param) { |
| 693 SetMsgHandled(FALSE); | 769 SetMsgHandled(FALSE); |
| 694 return MA_ACTIVATE; | 770 return MA_ACTIVATE; |
| 695 } | 771 } |
| 696 | 772 |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 854 | 930 |
| 855 LRESULT WidgetWin::OnReflectedMessage(UINT msg, | 931 LRESULT WidgetWin::OnReflectedMessage(UINT msg, |
| 856 WPARAM w_param, | 932 WPARAM w_param, |
| 857 LPARAM l_param) { | 933 LPARAM l_param) { |
| 858 SetMsgHandled(FALSE); | 934 SetMsgHandled(FALSE); |
| 859 return 0; | 935 return 0; |
| 860 } | 936 } |
| 861 | 937 |
| 862 void WidgetWin::OnSetFocus(HWND focused_window) { | 938 void WidgetWin::OnSetFocus(HWND focused_window) { |
| 863 delegate_->OnNativeFocus(focused_window); | 939 delegate_->OnNativeFocus(focused_window); |
| 940 if (is_input_method_win_) | |
| 941 static_cast<InputMethodWin*>(input_method_.get())->OnSetFocus(); | |
| 864 SetMsgHandled(FALSE); | 942 SetMsgHandled(FALSE); |
| 865 } | 943 } |
| 866 | 944 |
| 867 LRESULT WidgetWin::OnSetIcon(UINT size_type, HICON new_icon) { | 945 LRESULT WidgetWin::OnSetIcon(UINT size_type, HICON new_icon) { |
| 868 SetMsgHandled(FALSE); | 946 SetMsgHandled(FALSE); |
| 869 return 0; | 947 return 0; |
| 870 } | 948 } |
| 871 | 949 |
| 872 LRESULT WidgetWin::OnSetText(const wchar_t* text) { | 950 LRESULT WidgetWin::OnSetText(const wchar_t* text) { |
| 873 SetMsgHandled(FALSE); | 951 SetMsgHandled(FALSE); |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1136 layered_window_contents_.reset( | 1214 layered_window_contents_.reset( |
| 1137 new gfx::CanvasSkia(s.width(), s.height(), false)); | 1215 new gfx::CanvasSkia(s.width(), s.height(), false)); |
| 1138 } | 1216 } |
| 1139 } | 1217 } |
| 1140 | 1218 |
| 1141 gfx::AcceleratedWidget WidgetWin::GetAcceleratedWidget() { | 1219 gfx::AcceleratedWidget WidgetWin::GetAcceleratedWidget() { |
| 1142 // TODO(beng): | 1220 // TODO(beng): |
| 1143 return gfx::kNullAcceleratedWidget; | 1221 return gfx::kNullAcceleratedWidget; |
| 1144 } | 1222 } |
| 1145 | 1223 |
| 1224 void WidgetWin::DispatchKeyEventPostIME(const KeyEvent& key) { | |
| 1225 RootView* root_view = GetFocusedViewRootView(); | |
| 1226 if (!root_view) | |
| 1227 root_view = GetRootView(); | |
| 1228 | |
| 1229 SetMsgHandled(root_view->ProcessKeyEvent(key)); | |
| 1230 } | |
| 1231 | |
| 1146 //////////////////////////////////////////////////////////////////////////////// | 1232 //////////////////////////////////////////////////////////////////////////////// |
| 1147 // Widget, public: | 1233 // Widget, public: |
| 1148 | 1234 |
| 1149 // static | 1235 // static |
| 1150 Widget* Widget::CreatePopupWidget(TransparencyParam transparent, | 1236 Widget* Widget::CreatePopupWidget(TransparencyParam transparent, |
| 1151 EventsParam accept_events, | 1237 EventsParam accept_events, |
| 1152 DeleteParam delete_on_destroy, | 1238 DeleteParam delete_on_destroy, |
| 1153 MirroringParam mirror_in_rtl) { | 1239 MirroringParam mirror_in_rtl) { |
| 1154 WidgetWin* popup = new WidgetWin; | 1240 WidgetWin* popup = new WidgetWin; |
| 1155 DWORD ex_style = WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE; | 1241 DWORD ex_style = WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1220 return; | 1306 return; |
| 1221 | 1307 |
| 1222 NativeWidget* native_widget = GetNativeWidgetForNativeView(native_view); | 1308 NativeWidget* native_widget = GetNativeWidgetForNativeView(native_view); |
| 1223 if (native_widget) | 1309 if (native_widget) |
| 1224 children->insert(native_widget); | 1310 children->insert(native_widget); |
| 1225 EnumChildWindows(native_view, EnumerateChildWindowsForNativeWidgets, | 1311 EnumChildWindows(native_view, EnumerateChildWindowsForNativeWidgets, |
| 1226 reinterpret_cast<LPARAM>(children)); | 1312 reinterpret_cast<LPARAM>(children)); |
| 1227 } | 1313 } |
| 1228 | 1314 |
| 1229 } // namespace views | 1315 } // namespace views |
| OLD | NEW |