| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 <stddef.h> | 5 #include <stddef.h> |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/macros.h" | 9 #include "base/macros.h" |
| 10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
| (...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 | 798 |
| 799 gfx::Rect fullscreen_bounds_after_activate = | 799 gfx::Rect fullscreen_bounds_after_activate = |
| 800 widget1.GetWindowBoundsInScreen(); | 800 widget1.GetWindowBoundsInScreen(); |
| 801 | 801 |
| 802 // After activation the bounds of the fullscreen widget should be restored. | 802 // After activation the bounds of the fullscreen widget should be restored. |
| 803 EXPECT_EQ(fullscreen_bounds, fullscreen_bounds_after_activate); | 803 EXPECT_EQ(fullscreen_bounds, fullscreen_bounds_after_activate); |
| 804 | 804 |
| 805 widget1.CloseNow(); | 805 widget1.CloseNow(); |
| 806 widget2.CloseNow(); | 806 widget2.CloseNow(); |
| 807 } | 807 } |
| 808 | |
| 809 // Provides functionality to subclass a window and keep track of messages | |
| 810 // received. | |
| 811 class SubclassWindowHelper { | |
| 812 public: | |
| 813 explicit SubclassWindowHelper(HWND window) | |
| 814 : window_(window), | |
| 815 message_to_destroy_on_(0) { | |
| 816 EXPECT_EQ(instance_, nullptr); | |
| 817 instance_ = this; | |
| 818 EXPECT_TRUE(Subclass()); | |
| 819 } | |
| 820 | |
| 821 ~SubclassWindowHelper() { | |
| 822 Unsubclass(); | |
| 823 instance_ = nullptr; | |
| 824 } | |
| 825 | |
| 826 // Returns true if the |message| passed in was received. | |
| 827 bool received_message(unsigned int message) { | |
| 828 return (messages_.find(message) != messages_.end()); | |
| 829 } | |
| 830 | |
| 831 void Clear() { | |
| 832 messages_.clear(); | |
| 833 } | |
| 834 | |
| 835 void set_message_to_destroy_on(unsigned int message) { | |
| 836 message_to_destroy_on_ = message; | |
| 837 } | |
| 838 | |
| 839 private: | |
| 840 bool Subclass() { | |
| 841 old_proc_ = reinterpret_cast<WNDPROC>( | |
| 842 ::SetWindowLongPtr(window_, | |
| 843 GWLP_WNDPROC, | |
| 844 reinterpret_cast<LONG_PTR>(WndProc))); | |
| 845 return old_proc_ != nullptr; | |
| 846 } | |
| 847 | |
| 848 void Unsubclass() { | |
| 849 ::SetWindowLongPtr(window_, | |
| 850 GWLP_WNDPROC, | |
| 851 reinterpret_cast<LONG_PTR>(old_proc_)); | |
| 852 } | |
| 853 | |
| 854 static LRESULT CALLBACK WndProc(HWND window, | |
| 855 unsigned int message, | |
| 856 WPARAM w_param, | |
| 857 LPARAM l_param) { | |
| 858 EXPECT_NE(instance_, nullptr); | |
| 859 EXPECT_EQ(window, instance_->window_); | |
| 860 | |
| 861 // Keep track of messags received for this window. | |
| 862 instance_->messages_.insert(message); | |
| 863 | |
| 864 LRESULT ret = ::CallWindowProc(instance_->old_proc_, window, message, | |
| 865 w_param, l_param); | |
| 866 if (message == instance_->message_to_destroy_on_) { | |
| 867 instance_->Unsubclass(); | |
| 868 ::DestroyWindow(window); | |
| 869 } | |
| 870 return ret; | |
| 871 } | |
| 872 | |
| 873 WNDPROC old_proc_; | |
| 874 HWND window_; | |
| 875 static SubclassWindowHelper* instance_; | |
| 876 std::set<unsigned int> messages_; | |
| 877 unsigned int message_to_destroy_on_; | |
| 878 | |
| 879 DISALLOW_COPY_AND_ASSIGN(SubclassWindowHelper); | |
| 880 }; | |
| 881 | |
| 882 SubclassWindowHelper* SubclassWindowHelper::instance_ = nullptr; | |
| 883 | |
| 884 // This test validates whether the WM_SYSCOMMAND message for SC_MOVE is | |
| 885 // received when we post a WM_NCLBUTTONDOWN message for the caption in the | |
| 886 // following scenarios:- | |
| 887 // 1. Posting a WM_NCMOUSEMOVE message for a different location. | |
| 888 // 2. Posting a WM_NCMOUSEMOVE message with a different hittest code. | |
| 889 // 3. Posting a WM_MOUSEMOVE message. | |
| 890 TEST_F(WidgetTestInteractive, | |
| 891 SysCommandMoveOnNCLButtonDownOnCaptionAndMoveTest) { | |
| 892 Widget widget; | |
| 893 Widget::InitParams params = | |
| 894 CreateParams(Widget::InitParams::TYPE_WINDOW); | |
| 895 params.native_widget = new DesktopNativeWidgetAura(&widget); | |
| 896 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 897 widget.Init(params); | |
| 898 widget.SetBounds(gfx::Rect(0, 0, 200, 200)); | |
| 899 widget.Show(); | |
| 900 ::SetCursorPos(500, 500); | |
| 901 | |
| 902 HWND window = widget.GetNativeWindow()->GetHost()->GetAcceleratedWidget(); | |
| 903 | |
| 904 SubclassWindowHelper subclass_helper(window); | |
| 905 | |
| 906 // Posting just a WM_NCLBUTTONDOWN message should not result in a | |
| 907 // WM_SYSCOMMAND | |
| 908 ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100)); | |
| 909 RunPendingMessages(); | |
| 910 EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN)); | |
| 911 EXPECT_FALSE(subclass_helper.received_message(WM_SYSCOMMAND)); | |
| 912 | |
| 913 subclass_helper.Clear(); | |
| 914 // Posting a WM_NCLBUTTONDOWN message followed by a WM_NCMOUSEMOVE at the | |
| 915 // same location should not result in a WM_SYSCOMMAND message. | |
| 916 ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100)); | |
| 917 ::PostMessage(window, WM_NCMOUSEMOVE, HTCAPTION, MAKELPARAM(100, 100)); | |
| 918 RunPendingMessages(); | |
| 919 | |
| 920 EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN)); | |
| 921 EXPECT_TRUE(subclass_helper.received_message(WM_NCMOUSEMOVE)); | |
| 922 EXPECT_FALSE(subclass_helper.received_message(WM_SYSCOMMAND)); | |
| 923 | |
| 924 subclass_helper.Clear(); | |
| 925 // Posting a WM_NCLBUTTONDOWN message followed by a WM_NCMOUSEMOVE at a | |
| 926 // different location should result in a WM_SYSCOMMAND message. | |
| 927 ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100)); | |
| 928 ::PostMessage(window, WM_NCMOUSEMOVE, HTCAPTION, MAKELPARAM(110, 110)); | |
| 929 RunPendingMessages(); | |
| 930 | |
| 931 EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN)); | |
| 932 EXPECT_TRUE(subclass_helper.received_message(WM_NCMOUSEMOVE)); | |
| 933 EXPECT_TRUE(subclass_helper.received_message(WM_SYSCOMMAND)); | |
| 934 | |
| 935 subclass_helper.Clear(); | |
| 936 // Posting a WM_NCLBUTTONDOWN message followed by a WM_NCMOUSEMOVE at a | |
| 937 // different location with a different hittest code should result in a | |
| 938 // WM_SYSCOMMAND message. | |
| 939 ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100)); | |
| 940 ::PostMessage(window, WM_NCMOUSEMOVE, HTTOP, MAKELPARAM(110, 102)); | |
| 941 RunPendingMessages(); | |
| 942 | |
| 943 EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN)); | |
| 944 EXPECT_TRUE(subclass_helper.received_message(WM_NCMOUSEMOVE)); | |
| 945 EXPECT_TRUE(subclass_helper.received_message(WM_SYSCOMMAND)); | |
| 946 | |
| 947 subclass_helper.Clear(); | |
| 948 // Posting a WM_NCLBUTTONDOWN message followed by a WM_MOUSEMOVE should | |
| 949 // result in a WM_SYSCOMMAND message. | |
| 950 ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100)); | |
| 951 ::PostMessage(window, WM_MOUSEMOVE, HTCLIENT, MAKELPARAM(110, 110)); | |
| 952 RunPendingMessages(); | |
| 953 | |
| 954 EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN)); | |
| 955 EXPECT_TRUE(subclass_helper.received_message(WM_MOUSEMOVE)); | |
| 956 EXPECT_TRUE(subclass_helper.received_message(WM_SYSCOMMAND)); | |
| 957 | |
| 958 widget.CloseNow(); | |
| 959 } | |
| 960 | |
| 961 // This test validates that destroying the window in the context of the | |
| 962 // WM_SYSCOMMAND message with SC_MOVE does not crash. | |
| 963 TEST_F(WidgetTestInteractive, DestroyInSysCommandNCLButtonDownOnCaption) { | |
| 964 Widget widget; | |
| 965 Widget::InitParams params = | |
| 966 CreateParams(Widget::InitParams::TYPE_WINDOW); | |
| 967 params.native_widget = new DesktopNativeWidgetAura(&widget); | |
| 968 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 969 widget.Init(params); | |
| 970 widget.SetBounds(gfx::Rect(0, 0, 200, 200)); | |
| 971 widget.Show(); | |
| 972 ::SetCursorPos(500, 500); | |
| 973 | |
| 974 HWND window = widget.GetNativeWindow()->GetHost()->GetAcceleratedWidget(); | |
| 975 | |
| 976 SubclassWindowHelper subclass_helper(window); | |
| 977 | |
| 978 // Destroying the window in the context of the WM_SYSCOMMAND message | |
| 979 // should not crash. | |
| 980 subclass_helper.set_message_to_destroy_on(WM_SYSCOMMAND); | |
| 981 | |
| 982 ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100)); | |
| 983 ::PostMessage(window, WM_NCMOUSEMOVE, HTCAPTION, MAKELPARAM(110, 110)); | |
| 984 RunPendingMessages(); | |
| 985 | |
| 986 EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN)); | |
| 987 EXPECT_TRUE(subclass_helper.received_message(WM_SYSCOMMAND)); | |
| 988 | |
| 989 widget.CloseNow(); | |
| 990 } | |
| 991 #endif // defined(OS_WIN) | 808 #endif // defined(OS_WIN) |
| 992 | 809 |
| 993 #if !defined(OS_CHROMEOS) | 810 #if !defined(OS_CHROMEOS) |
| 994 // Provides functionality to create a window modal dialog. | 811 // Provides functionality to create a window modal dialog. |
| 995 class ModalDialogDelegate : public DialogDelegateView { | 812 class ModalDialogDelegate : public DialogDelegateView { |
| 996 public: | 813 public: |
| 997 explicit ModalDialogDelegate(ui::ModalType type) : type_(type) {} | 814 explicit ModalDialogDelegate(ui::ModalType type) : type_(type) {} |
| 998 ~ModalDialogDelegate() override {} | 815 ~ModalDialogDelegate() override {} |
| 999 | 816 |
| 1000 // WidgetDelegate overrides. | 817 // WidgetDelegate overrides. |
| (...skipping 914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1915 | 1732 |
| 1916 ui::KeyEvent key_event2(key_event); | 1733 ui::KeyEvent key_event2(key_event); |
| 1917 widget->OnKeyEvent(&key_event2); | 1734 widget->OnKeyEvent(&key_event2); |
| 1918 EXPECT_FALSE(key_event2.stopped_propagation()); | 1735 EXPECT_FALSE(key_event2.stopped_propagation()); |
| 1919 | 1736 |
| 1920 widget->CloseNow(); | 1737 widget->CloseNow(); |
| 1921 } | 1738 } |
| 1922 | 1739 |
| 1923 } // namespace test | 1740 } // namespace test |
| 1924 } // namespace views | 1741 } // namespace views |
| OLD | NEW |