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

Side by Side Diff: ui/views/widget/widget_interactive_uitest.cc

Issue 2409423003: Move WidgetActivationWaiter to a common place (Closed)
Patch Set: based on comments Created 4 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
« no previous file with comments | « ui/views/test/widget_test.cc ('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) 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/location.h" 9 #include "base/location.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 base::RunLoop run_loop; 149 base::RunLoop run_loop;
150 run_loop.Run(); 150 run_loop.Run();
151 return true; 151 return true;
152 } 152 }
153 153
154 Widget* widget_; 154 Widget* widget_;
155 155
156 DISALLOW_COPY_AND_ASSIGN(NestedLoopCaptureView); 156 DISALLOW_COPY_AND_ASSIGN(NestedLoopCaptureView);
157 }; 157 };
158 158
159 // Spins a run loop until a Widget's active state matches a desired state.
160 class WidgetActivationWaiter : public WidgetObserver {
161 public:
162 WidgetActivationWaiter(Widget* widget, bool active) : observed_(false) {
163 #if defined(OS_WIN)
164 // On Windows, a HWND can receive a WM_ACTIVATE message without the value
165 // of ::GetActiveWindow() updating to reflect that change. This can cause
166 // the active window reported by IsActive() to get out of sync. Usually this
167 // happens after a call to HWNDMessageHandler::Deactivate() which works by
168 // activating some other window, which might be in another application.
169 // Doing this can trigger the native OS activation-blocker, causing the
170 // taskbar icon to flash instead. But since activation of native widgets on
171 // Windows is synchronous, we never have to wait anyway, so it's safe to
172 // return here.
173 if (active == widget->IsActive()) {
174 observed_ = true;
175 return;
176 }
177 #endif
178 // Always expect a change for tests using this.
179 EXPECT_NE(active, widget->IsActive());
180 widget->AddObserver(this);
181 }
182
183 void Wait() {
184 if (!observed_)
185 run_loop_.Run();
186 }
187
188 void OnWidgetActivationChanged(Widget* widget, bool active) override {
189 observed_ = true;
190 widget->RemoveObserver(this);
191 if (run_loop_.running())
192 run_loop_.Quit();
193 }
194
195 private:
196 base::RunLoop run_loop_;
197 bool observed_;
198
199 DISALLOW_COPY_AND_ASSIGN(WidgetActivationWaiter);
200 };
201
202 ui::WindowShowState GetWidgetShowState(const Widget* widget) { 159 ui::WindowShowState GetWidgetShowState(const Widget* widget) {
203 // Use IsMaximized/IsMinimized/IsFullScreen instead of GetWindowPlacement 160 // Use IsMaximized/IsMinimized/IsFullScreen instead of GetWindowPlacement
204 // because the former is implemented on all platforms but the latter is not. 161 // because the former is implemented on all platforms but the latter is not.
205 return widget->IsFullscreen() ? ui::SHOW_STATE_FULLSCREEN : 162 return widget->IsFullscreen() ? ui::SHOW_STATE_FULLSCREEN :
206 widget->IsMaximized() ? ui::SHOW_STATE_MAXIMIZED : 163 widget->IsMaximized() ? ui::SHOW_STATE_MAXIMIZED :
207 widget->IsMinimized() ? ui::SHOW_STATE_MINIMIZED : 164 widget->IsMinimized() ? ui::SHOW_STATE_MINIMIZED :
208 widget->IsActive() ? ui::SHOW_STATE_NORMAL : 165 widget->IsActive() ? ui::SHOW_STATE_NORMAL :
209 ui::SHOW_STATE_INACTIVE; 166 ui::SHOW_STATE_INACTIVE;
210 } 167 }
211 168
212 // Give the OS an opportunity to process messages for an activation change, when 169 // Give the OS an opportunity to process messages for an activation change, when
213 // there is actually no change expected (e.g. ShowInactive()). 170 // there is actually no change expected (e.g. ShowInactive()).
214 void RunPendingMessagesForActiveStatusChange() { 171 void RunPendingMessagesForActiveStatusChange() {
215 #if defined(OS_MACOSX) 172 #if defined(OS_MACOSX)
216 // On Mac, a single spin is *usually* enough. It isn't when a widget is shown 173 // On Mac, a single spin is *usually* enough. It isn't when a widget is shown
217 // and made active in two steps, so tests should follow up with a ShowSync() 174 // and made active in two steps, so tests should follow up with a ShowSync()
218 // or ActivateSync to ensure a consistent state. 175 // or ActivateSync to ensure a consistent state.
219 base::RunLoop().RunUntilIdle(); 176 base::RunLoop().RunUntilIdle();
220 #endif 177 #endif
221 // TODO(tapted): Check for desktop aura widgets. 178 // TODO(tapted): Check for desktop aura widgets.
222 } 179 }
223 180
224 // Activate a widget, and wait for it to become active. On non-desktop Aura 181 // Activate a widget, and wait for it to become active. On non-desktop Aura
225 // this is just an activation. For other widgets, it means activating and then 182 // this is just an activation. For other widgets, it means activating and then
226 // spinning the run loop until the OS has activated the window. 183 // spinning the run loop until the OS has activated the window.
227 void ActivateSync(Widget* widget) { 184 void ActivateSync(Widget* widget) {
228 WidgetActivationWaiter waiter(widget, true); 185 views::test::WidgetActivationWaiter waiter(widget, true);
229 widget->Activate(); 186 widget->Activate();
230 waiter.Wait(); 187 waiter.Wait();
231 } 188 }
232 189
233 // Like for ActivateSync(), wait for a widget to become active, but Show() the 190 // Like for ActivateSync(), wait for a widget to become active, but Show() the
234 // widget rather than calling Activate(). 191 // widget rather than calling Activate().
235 void ShowSync(Widget* widget) { 192 void ShowSync(Widget* widget) {
236 WidgetActivationWaiter waiter(widget, true); 193 views::test::WidgetActivationWaiter waiter(widget, true);
237 widget->Show(); 194 widget->Show();
238 waiter.Wait(); 195 waiter.Wait();
239 } 196 }
240 197
241 void DeactivateSync(Widget* widget) { 198 void DeactivateSync(Widget* widget) {
242 #if defined(OS_MACOSX) 199 #if defined(OS_MACOSX)
243 // Deactivation of a window isn't a concept on Mac: If an application is 200 // Deactivation of a window isn't a concept on Mac: If an application is
244 // active and it has any activatable windows, then one of them is always 201 // active and it has any activatable windows, then one of them is always
245 // active. But we can simulate deactivation (e.g. as if another application 202 // active. But we can simulate deactivation (e.g. as if another application
246 // became active) by temporarily making |widget| non-activatable, then 203 // became active) by temporarily making |widget| non-activatable, then
247 // activating (and closing) a temporary widget. 204 // activating (and closing) a temporary widget.
248 widget->widget_delegate()->set_can_activate(false); 205 widget->widget_delegate()->set_can_activate(false);
249 Widget* stealer = new Widget; 206 Widget* stealer = new Widget;
250 stealer->Init(Widget::InitParams(Widget::InitParams::TYPE_WINDOW)); 207 stealer->Init(Widget::InitParams(Widget::InitParams::TYPE_WINDOW));
251 ShowSync(stealer); 208 ShowSync(stealer);
252 stealer->CloseNow(); 209 stealer->CloseNow();
253 widget->widget_delegate()->set_can_activate(true); 210 widget->widget_delegate()->set_can_activate(true);
254 #else 211 #else
255 WidgetActivationWaiter waiter(widget, false); 212 views::test::WidgetActivationWaiter waiter(widget, false);
256 widget->Deactivate(); 213 widget->Deactivate();
257 waiter.Wait(); 214 waiter.Wait();
258 #endif 215 #endif
259 } 216 }
260 217
261 #if defined(OS_WIN) 218 #if defined(OS_WIN)
262 void ActivatePlatformWindow(Widget* widget) { 219 void ActivatePlatformWindow(Widget* widget) {
263 ::SetActiveWindow( 220 ::SetActiveWindow(
264 widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget()); 221 widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget());
265 } 222 }
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 modal_dialog_widget->Show(); 876 modal_dialog_widget->Show();
920 877
921 gfx::NativeView modal_native_view = modal_dialog_widget->GetNativeView(); 878 gfx::NativeView modal_native_view = modal_dialog_widget->GetNativeView();
922 ASSERT_EQ(3u, focus_changes.size()); 879 ASSERT_EQ(3u, focus_changes.size());
923 EXPECT_EQ(nullptr, focus_changes[1]); 880 EXPECT_EQ(nullptr, focus_changes[1]);
924 EXPECT_EQ(modal_native_view, focus_changes[2]); 881 EXPECT_EQ(modal_native_view, focus_changes[2]);
925 882
926 #if defined(OS_MACOSX) 883 #if defined(OS_MACOSX)
927 // Window modal dialogs on Mac are "sheets", which animate to close before 884 // Window modal dialogs on Mac are "sheets", which animate to close before
928 // activating their parent widget. 885 // activating their parent widget.
929 WidgetActivationWaiter waiter(&top_level_widget, true); 886 views::test::WidgetActivationWaiter waiter(&top_level_widget, true);
930 modal_dialog_widget->Close(); 887 modal_dialog_widget->Close();
931 waiter.Wait(); 888 waiter.Wait();
932 #else 889 #else
933 modal_dialog_widget->CloseNow(); 890 modal_dialog_widget->CloseNow();
934 #endif 891 #endif
935 892
936 ASSERT_EQ(5u, focus_changes.size()); 893 ASSERT_EQ(5u, focus_changes.size());
937 EXPECT_EQ(nullptr, focus_changes[3]); 894 EXPECT_EQ(nullptr, focus_changes[3]);
938 EXPECT_EQ(top_level_native_view, focus_changes[4]); 895 EXPECT_EQ(top_level_native_view, focus_changes[4]);
939 896
(...skipping 919 matching lines...) Expand 10 before | Expand all | Expand 10 after
1859 1816
1860 ui::KeyEvent key_event2(key_event); 1817 ui::KeyEvent key_event2(key_event);
1861 widget->OnKeyEvent(&key_event2); 1818 widget->OnKeyEvent(&key_event2);
1862 EXPECT_FALSE(key_event2.stopped_propagation()); 1819 EXPECT_FALSE(key_event2.stopped_propagation());
1863 1820
1864 widget->CloseNow(); 1821 widget->CloseNow();
1865 } 1822 }
1866 1823
1867 } // namespace test 1824 } // namespace test
1868 } // namespace views 1825 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/test/widget_test.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698