| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #include <X11/extensions/shape.h> | 6 #include <X11/extensions/shape.h> |
| 7 #include <X11/Xlib.h> | 7 #include <X11/Xlib.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 #include "ui/aura/window_tree_host.h" | 24 #include "ui/aura/window_tree_host.h" |
| 25 #include "ui/base/hit_test.h" | 25 #include "ui/base/hit_test.h" |
| 26 #include "ui/base/x/x11_util.h" | 26 #include "ui/base/x/x11_util.h" |
| 27 #include "ui/display/display_switches.h" | 27 #include "ui/display/display_switches.h" |
| 28 #include "ui/events/devices/x11/touch_factory_x11.h" | 28 #include "ui/events/devices/x11/touch_factory_x11.h" |
| 29 #include "ui/events/platform/x11/x11_event_source_glib.h" | 29 #include "ui/events/platform/x11/x11_event_source_glib.h" |
| 30 #include "ui/events/test/platform_event_source_test_api.h" | 30 #include "ui/events/test/platform_event_source_test_api.h" |
| 31 #include "ui/gfx/geometry/point.h" | 31 #include "ui/gfx/geometry/point.h" |
| 32 #include "ui/gfx/geometry/rect.h" | 32 #include "ui/gfx/geometry/rect.h" |
| 33 #include "ui/gfx/path.h" | 33 #include "ui/gfx/path.h" |
| 34 #include "ui/gfx/x/x11_atom_cache.h" |
| 34 #include "ui/views/test/views_test_base.h" | 35 #include "ui/views/test/views_test_base.h" |
| 35 #include "ui/views/test/x11_property_change_waiter.h" | 36 #include "ui/views/test/x11_property_change_waiter.h" |
| 36 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" | 37 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" |
| 37 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" | 38 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" |
| 38 #include "ui/views/widget/widget_delegate.h" | 39 #include "ui/views/widget/widget_delegate.h" |
| 39 #include "ui/views/window/non_client_view.h" | 40 #include "ui/views/window/non_client_view.h" |
| 40 | 41 |
| 41 namespace views { | 42 namespace views { |
| 42 | 43 |
| 43 namespace { | 44 namespace { |
| 44 | 45 |
| 45 const int kPointerDeviceId = 1; | 46 const int kPointerDeviceId = 1; |
| 46 | 47 |
| 47 // Blocks till the window state hint, |hint|, is set or unset. | 48 // Blocks till the window state hint, |hint|, is set or unset. |
| 48 class WMStateWaiter : public X11PropertyChangeWaiter { | 49 class WMStateWaiter : public X11PropertyChangeWaiter { |
| 49 public: | 50 public: |
| 50 WMStateWaiter(XID window, const char* hint, bool wait_till_set) | 51 WMStateWaiter(XID window, const char* hint, bool wait_till_set) |
| 51 : X11PropertyChangeWaiter(window, "_NET_WM_STATE"), | 52 : X11PropertyChangeWaiter(window, "_NET_WM_STATE"), |
| 52 hint_(hint), | 53 hint_(hint), |
| 53 wait_till_set_(wait_till_set) {} | 54 wait_till_set_(wait_till_set) {} |
| 54 | 55 |
| 55 ~WMStateWaiter() override {} | 56 ~WMStateWaiter() override {} |
| 56 | 57 |
| 57 private: | 58 private: |
| 58 // X11PropertyChangeWaiter: | 59 // X11PropertyChangeWaiter: |
| 59 bool ShouldKeepOnWaiting(const ui::PlatformEvent& event) override { | 60 bool ShouldKeepOnWaiting(const ui::PlatformEvent& event) override { |
| 60 std::vector<Atom> hints; | 61 std::vector<Atom> hints; |
| 61 if (ui::GetAtomArrayProperty(xwindow(), "_NET_WM_STATE", &hints)) { | 62 if (ui::GetAtomArrayProperty(xwindow(), "_NET_WM_STATE", &hints)) { |
| 62 auto it = std::find(hints.cbegin(), hints.cend(), ui::GetAtom(hint_)); | 63 auto it = std::find(hints.cbegin(), hints.cend(), gfx::GetAtom(hint_)); |
| 63 bool hint_set = (it != hints.cend()); | 64 bool hint_set = (it != hints.cend()); |
| 64 return hint_set != wait_till_set_; | 65 return hint_set != wait_till_set_; |
| 65 } | 66 } |
| 66 return true; | 67 return true; |
| 67 } | 68 } |
| 68 | 69 |
| 69 // The name of the hint to wait to get set or unset. | 70 // The name of the hint to wait to get set or unset. |
| 70 const char* hint_; | 71 const char* hint_; |
| 71 | 72 |
| 72 // Whether we are waiting for |hint| to be set or unset. | 73 // Whether we are waiting for |hint| to be set or unset. |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 shape_rects = GetShapeRects(xid1); | 232 shape_rects = GetShapeRects(xid1); |
| 232 ASSERT_FALSE(shape_rects.empty()); | 233 ASSERT_FALSE(shape_rects.empty()); |
| 233 EXPECT_TRUE(ShapeRectContainsPoint(shape_rects, 85, 5)); | 234 EXPECT_TRUE(ShapeRectContainsPoint(shape_rects, 85, 5)); |
| 234 EXPECT_TRUE(ShapeRectContainsPoint(shape_rects, 95, 5)); | 235 EXPECT_TRUE(ShapeRectContainsPoint(shape_rects, 95, 5)); |
| 235 EXPECT_TRUE(ShapeRectContainsPoint(shape_rects, 185, 5)); | 236 EXPECT_TRUE(ShapeRectContainsPoint(shape_rects, 185, 5)); |
| 236 EXPECT_FALSE(ShapeRectContainsPoint(shape_rects, 195, 5)); | 237 EXPECT_FALSE(ShapeRectContainsPoint(shape_rects, 195, 5)); |
| 237 EXPECT_TRUE(ShapeRectContainsPoint(shape_rects, 195, 15)); | 238 EXPECT_TRUE(ShapeRectContainsPoint(shape_rects, 195, 15)); |
| 238 EXPECT_FALSE(ShapeRectContainsPoint(shape_rects, 205, 15)); | 239 EXPECT_FALSE(ShapeRectContainsPoint(shape_rects, 205, 15)); |
| 239 } | 240 } |
| 240 | 241 |
| 241 if (ui::WmSupportsHint(ui::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"))) { | 242 if (ui::WmSupportsHint(gfx::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"))) { |
| 242 // The shape should be changed to a rectangle which fills the entire screen | 243 // The shape should be changed to a rectangle which fills the entire screen |
| 243 // when |widget1| is maximized. | 244 // when |widget1| is maximized. |
| 244 { | 245 { |
| 245 WMStateWaiter waiter(xid1, "_NET_WM_STATE_MAXIMIZED_VERT", true); | 246 WMStateWaiter waiter(xid1, "_NET_WM_STATE_MAXIMIZED_VERT", true); |
| 246 widget1->Maximize(); | 247 widget1->Maximize(); |
| 247 waiter.Wait(); | 248 waiter.Wait(); |
| 248 } | 249 } |
| 249 | 250 |
| 250 // Ensure that the task which is posted when a window is resized is run. | 251 // Ensure that the task which is posted when a window is resized is run. |
| 251 RunAllPendingInMessageLoop(); | 252 RunAllPendingInMessageLoop(); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 EXPECT_TRUE(ShapeRectContainsPoint(shape_rects, 5, 5)); | 309 EXPECT_TRUE(ShapeRectContainsPoint(shape_rects, 5, 5)); |
| 309 EXPECT_TRUE(ShapeRectContainsPoint(shape_rects, 15, 5)); | 310 EXPECT_TRUE(ShapeRectContainsPoint(shape_rects, 15, 5)); |
| 310 EXPECT_TRUE(ShapeRectContainsPoint(shape_rects, 95, 15)); | 311 EXPECT_TRUE(ShapeRectContainsPoint(shape_rects, 95, 15)); |
| 311 EXPECT_TRUE(ShapeRectContainsPoint(shape_rects, 105, 15)); | 312 EXPECT_TRUE(ShapeRectContainsPoint(shape_rects, 105, 15)); |
| 312 EXPECT_FALSE(ShapeRectContainsPoint(shape_rects, 500, 500)); | 313 EXPECT_FALSE(ShapeRectContainsPoint(shape_rects, 500, 500)); |
| 313 } | 314 } |
| 314 | 315 |
| 315 // Test that the widget ignores changes in fullscreen state initiated by the | 316 // Test that the widget ignores changes in fullscreen state initiated by the |
| 316 // window manager (e.g. via a window manager accelerator key). | 317 // window manager (e.g. via a window manager accelerator key). |
| 317 TEST_F(DesktopWindowTreeHostX11Test, WindowManagerTogglesFullscreen) { | 318 TEST_F(DesktopWindowTreeHostX11Test, WindowManagerTogglesFullscreen) { |
| 318 if (!ui::WmSupportsHint(ui::GetAtom("_NET_WM_STATE_FULLSCREEN"))) | 319 if (!ui::WmSupportsHint(gfx::GetAtom("_NET_WM_STATE_FULLSCREEN"))) |
| 319 return; | 320 return; |
| 320 | 321 |
| 321 std::unique_ptr<Widget> widget = CreateWidget(new ShapedWidgetDelegate()); | 322 std::unique_ptr<Widget> widget = CreateWidget(new ShapedWidgetDelegate()); |
| 322 XID xid = widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget(); | 323 XID xid = widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget(); |
| 323 widget->Show(); | 324 widget->Show(); |
| 324 ui::X11EventSource::GetInstance()->DispatchXEvents(); | 325 ui::X11EventSource::GetInstance()->DispatchXEvents(); |
| 325 | 326 |
| 326 gfx::Rect initial_bounds = widget->GetWindowBoundsInScreen(); | 327 gfx::Rect initial_bounds = widget->GetWindowBoundsInScreen(); |
| 327 { | 328 { |
| 328 WMStateWaiter waiter(xid, "_NET_WM_STATE_FULLSCREEN", true); | 329 WMStateWaiter waiter(xid, "_NET_WM_STATE_FULLSCREEN", true); |
| 329 widget->SetFullscreen(true); | 330 widget->SetFullscreen(true); |
| 330 waiter.Wait(); | 331 waiter.Wait(); |
| 331 } | 332 } |
| 332 EXPECT_TRUE(widget->IsFullscreen()); | 333 EXPECT_TRUE(widget->IsFullscreen()); |
| 333 | 334 |
| 334 // Emulate the window manager exiting fullscreen via a window manager | 335 // Emulate the window manager exiting fullscreen via a window manager |
| 335 // accelerator key. It should not affect the widget's fullscreen state. | 336 // accelerator key. It should not affect the widget's fullscreen state. |
| 336 { | 337 { |
| 337 Display* display = gfx::GetXDisplay(); | 338 Display* display = gfx::GetXDisplay(); |
| 338 | 339 |
| 339 XEvent xclient; | 340 XEvent xclient; |
| 340 memset(&xclient, 0, sizeof(xclient)); | 341 memset(&xclient, 0, sizeof(xclient)); |
| 341 xclient.type = ClientMessage; | 342 xclient.type = ClientMessage; |
| 342 xclient.xclient.window = xid; | 343 xclient.xclient.window = xid; |
| 343 xclient.xclient.message_type = ui::GetAtom("_NET_WM_STATE"); | 344 xclient.xclient.message_type = gfx::GetAtom("_NET_WM_STATE"); |
| 344 xclient.xclient.format = 32; | 345 xclient.xclient.format = 32; |
| 345 xclient.xclient.data.l[0] = 0; | 346 xclient.xclient.data.l[0] = 0; |
| 346 xclient.xclient.data.l[1] = ui::GetAtom("_NET_WM_STATE_FULLSCREEN"); | 347 xclient.xclient.data.l[1] = gfx::GetAtom("_NET_WM_STATE_FULLSCREEN"); |
| 347 xclient.xclient.data.l[2] = 0; | 348 xclient.xclient.data.l[2] = 0; |
| 348 xclient.xclient.data.l[3] = 1; | 349 xclient.xclient.data.l[3] = 1; |
| 349 xclient.xclient.data.l[4] = 0; | 350 xclient.xclient.data.l[4] = 0; |
| 350 XSendEvent(display, DefaultRootWindow(display), False, | 351 XSendEvent(display, DefaultRootWindow(display), False, |
| 351 SubstructureRedirectMask | SubstructureNotifyMask, | 352 SubstructureRedirectMask | SubstructureNotifyMask, |
| 352 &xclient); | 353 &xclient); |
| 353 | 354 |
| 354 WMStateWaiter waiter(xid, "_NET_WM_STATE_FULLSCREEN", false); | 355 WMStateWaiter waiter(xid, "_NET_WM_STATE_FULLSCREEN", false); |
| 355 waiter.Wait(); | 356 waiter.Wait(); |
| 356 } | 357 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 373 widget.Init(params); | 374 widget.Init(params); |
| 374 widget.Show(); | 375 widget.Show(); |
| 375 ui::X11EventSource::GetInstance()->DispatchXEvents(); | 376 ui::X11EventSource::GetInstance()->DispatchXEvents(); |
| 376 | 377 |
| 377 XID xid = widget.GetNativeWindow()->GetHost()->GetAcceleratedWidget(); | 378 XID xid = widget.GetNativeWindow()->GetHost()->GetAcceleratedWidget(); |
| 378 Display* display = gfx::GetXDisplay(); | 379 Display* display = gfx::GetXDisplay(); |
| 379 | 380 |
| 380 // Minimize by sending _NET_WM_STATE_HIDDEN | 381 // Minimize by sending _NET_WM_STATE_HIDDEN |
| 381 { | 382 { |
| 382 std::vector< ::Atom> atom_list; | 383 std::vector< ::Atom> atom_list; |
| 383 atom_list.push_back(ui::GetAtom("_NET_WM_STATE_HIDDEN")); | 384 atom_list.push_back(gfx::GetAtom("_NET_WM_STATE_HIDDEN")); |
| 384 ui::SetAtomArrayProperty(xid, "_NET_WM_STATE", "ATOM", atom_list); | 385 ui::SetAtomArrayProperty(xid, "_NET_WM_STATE", "ATOM", atom_list); |
| 385 | 386 |
| 386 XEvent xevent; | 387 XEvent xevent; |
| 387 memset(&xevent, 0, sizeof(xevent)); | 388 memset(&xevent, 0, sizeof(xevent)); |
| 388 xevent.type = PropertyNotify; | 389 xevent.type = PropertyNotify; |
| 389 xevent.xproperty.type = PropertyNotify; | 390 xevent.xproperty.type = PropertyNotify; |
| 390 xevent.xproperty.send_event = 1; | 391 xevent.xproperty.send_event = 1; |
| 391 xevent.xproperty.display = display; | 392 xevent.xproperty.display = display; |
| 392 xevent.xproperty.window = xid; | 393 xevent.xproperty.window = xid; |
| 393 xevent.xproperty.atom = ui::GetAtom("_NET_WM_STATE"); | 394 xevent.xproperty.atom = gfx::GetAtom("_NET_WM_STATE"); |
| 394 xevent.xproperty.state = 0; | 395 xevent.xproperty.state = 0; |
| 395 XSendEvent(display, DefaultRootWindow(display), False, | 396 XSendEvent(display, DefaultRootWindow(display), False, |
| 396 SubstructureRedirectMask | SubstructureNotifyMask, | 397 SubstructureRedirectMask | SubstructureNotifyMask, |
| 397 &xevent); | 398 &xevent); |
| 398 | 399 |
| 399 WMStateWaiter waiter(xid, "_NET_WM_STATE_HIDDEN", true); | 400 WMStateWaiter waiter(xid, "_NET_WM_STATE_HIDDEN", true); |
| 400 waiter.Wait(); | 401 waiter.Wait(); |
| 401 } | 402 } |
| 402 EXPECT_FALSE(widget.GetNativeWindow()->IsVisible()); | 403 EXPECT_FALSE(widget.GetNativeWindow()->IsVisible()); |
| 403 | 404 |
| 404 // Show from minimized by sending _NET_WM_STATE_FOCUSED | 405 // Show from minimized by sending _NET_WM_STATE_FOCUSED |
| 405 { | 406 { |
| 406 std::vector< ::Atom> atom_list; | 407 std::vector< ::Atom> atom_list; |
| 407 atom_list.push_back(ui::GetAtom("_NET_WM_STATE_FOCUSED")); | 408 atom_list.push_back(gfx::GetAtom("_NET_WM_STATE_FOCUSED")); |
| 408 ui::SetAtomArrayProperty(xid, "_NET_WM_STATE", "ATOM", atom_list); | 409 ui::SetAtomArrayProperty(xid, "_NET_WM_STATE", "ATOM", atom_list); |
| 409 | 410 |
| 410 XEvent xevent; | 411 XEvent xevent; |
| 411 memset(&xevent, 0, sizeof(xevent)); | 412 memset(&xevent, 0, sizeof(xevent)); |
| 412 xevent.type = PropertyNotify; | 413 xevent.type = PropertyNotify; |
| 413 xevent.xproperty.type = PropertyNotify; | 414 xevent.xproperty.type = PropertyNotify; |
| 414 xevent.xproperty.send_event = 1; | 415 xevent.xproperty.send_event = 1; |
| 415 xevent.xproperty.display = display; | 416 xevent.xproperty.display = display; |
| 416 xevent.xproperty.window = xid; | 417 xevent.xproperty.window = xid; |
| 417 xevent.xproperty.atom = ui::GetAtom("_NET_WM_STATE"); | 418 xevent.xproperty.atom = gfx::GetAtom("_NET_WM_STATE"); |
| 418 xevent.xproperty.state = 0; | 419 xevent.xproperty.state = 0; |
| 419 XSendEvent(display, DefaultRootWindow(display), False, | 420 XSendEvent(display, DefaultRootWindow(display), False, |
| 420 SubstructureRedirectMask | SubstructureNotifyMask, | 421 SubstructureRedirectMask | SubstructureNotifyMask, |
| 421 &xevent); | 422 &xevent); |
| 422 | 423 |
| 423 WMStateWaiter waiter(xid, "_NET_WM_STATE_FOCUSED", true); | 424 WMStateWaiter waiter(xid, "_NET_WM_STATE_FOCUSED", true); |
| 424 waiter.Wait(); | 425 waiter.Wait(); |
| 425 } | 426 } |
| 426 EXPECT_TRUE(widget.GetNativeWindow()->IsVisible()); | 427 EXPECT_TRUE(widget.GetNativeWindow()->IsVisible()); |
| 427 } | 428 } |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 EXPECT_EQ(ui::ET_MOUSEWHEEL, second_recorder.mouse_events()[0].type()); | 611 EXPECT_EQ(ui::ET_MOUSEWHEEL, second_recorder.mouse_events()[0].type()); |
| 611 EXPECT_EQ(gfx::Point(-25, -25).ToString(), | 612 EXPECT_EQ(gfx::Point(-25, -25).ToString(), |
| 612 second_recorder.mouse_events()[0].location().ToString()); | 613 second_recorder.mouse_events()[0].location().ToString()); |
| 613 | 614 |
| 614 PretendCapture(nullptr); | 615 PretendCapture(nullptr); |
| 615 first.GetNativeWindow()->RemovePreTargetHandler(&first_recorder); | 616 first.GetNativeWindow()->RemovePreTargetHandler(&first_recorder); |
| 616 second.GetNativeWindow()->RemovePreTargetHandler(&second_recorder); | 617 second.GetNativeWindow()->RemovePreTargetHandler(&second_recorder); |
| 617 } | 618 } |
| 618 | 619 |
| 619 } // namespace views | 620 } // namespace views |
| OLD | NEW |