| 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" | |
| 35 #include "ui/views/test/views_test_base.h" | 34 #include "ui/views/test/views_test_base.h" |
| 36 #include "ui/views/test/x11_property_change_waiter.h" | 35 #include "ui/views/test/x11_property_change_waiter.h" |
| 37 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" | 36 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" |
| 38 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" | 37 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" |
| 39 #include "ui/views/widget/widget_delegate.h" | 38 #include "ui/views/widget/widget_delegate.h" |
| 40 #include "ui/views/window/non_client_view.h" | 39 #include "ui/views/window/non_client_view.h" |
| 41 | 40 |
| 42 namespace views { | 41 namespace views { |
| 43 | 42 |
| 44 namespace { | 43 namespace { |
| 45 | 44 |
| 46 const int kPointerDeviceId = 1; | 45 const int kPointerDeviceId = 1; |
| 47 | 46 |
| 48 // Blocks till the window state hint, |hint|, is set or unset. | 47 // Blocks till the window state hint, |hint|, is set or unset. |
| 49 class WMStateWaiter : public X11PropertyChangeWaiter { | 48 class WMStateWaiter : public X11PropertyChangeWaiter { |
| 50 public: | 49 public: |
| 51 WMStateWaiter(XID window, | 50 WMStateWaiter(XID window, const char* hint, bool wait_till_set) |
| 52 const char* hint, | |
| 53 bool wait_till_set) | |
| 54 : X11PropertyChangeWaiter(window, "_NET_WM_STATE"), | 51 : X11PropertyChangeWaiter(window, "_NET_WM_STATE"), |
| 55 hint_(hint), | 52 hint_(hint), |
| 56 wait_till_set_(wait_till_set) { | 53 wait_till_set_(wait_till_set) {} |
| 57 const char* const kAtomsToCache[] = { | |
| 58 hint, | |
| 59 nullptr | |
| 60 }; | |
| 61 atom_cache_.reset(new ui::X11AtomCache(gfx::GetXDisplay(), kAtomsToCache)); | |
| 62 } | |
| 63 | 54 |
| 64 ~WMStateWaiter() override {} | 55 ~WMStateWaiter() override {} |
| 65 | 56 |
| 66 private: | 57 private: |
| 67 // X11PropertyChangeWaiter: | 58 // X11PropertyChangeWaiter: |
| 68 bool ShouldKeepOnWaiting(const ui::PlatformEvent& event) override { | 59 bool ShouldKeepOnWaiting(const ui::PlatformEvent& event) override { |
| 69 std::vector<Atom> hints; | 60 std::vector<Atom> hints; |
| 70 if (ui::GetAtomArrayProperty(xwindow(), "_NET_WM_STATE", &hints)) { | 61 if (ui::GetAtomArrayProperty(xwindow(), "_NET_WM_STATE", &hints)) { |
| 71 auto it = std::find(hints.cbegin(), hints.cend(), | 62 auto it = std::find(hints.cbegin(), hints.cend(), ui::GetAtom(hint_)); |
| 72 atom_cache_->GetAtom(hint_)); | |
| 73 bool hint_set = (it != hints.cend()); | 63 bool hint_set = (it != hints.cend()); |
| 74 return hint_set != wait_till_set_; | 64 return hint_set != wait_till_set_; |
| 75 } | 65 } |
| 76 return true; | 66 return true; |
| 77 } | 67 } |
| 78 | 68 |
| 79 std::unique_ptr<ui::X11AtomCache> atom_cache_; | |
| 80 | |
| 81 // The name of the hint to wait to get set or unset. | 69 // The name of the hint to wait to get set or unset. |
| 82 const char* hint_; | 70 const char* hint_; |
| 83 | 71 |
| 84 // Whether we are waiting for |hint| to be set or unset. | 72 // Whether we are waiting for |hint| to be set or unset. |
| 85 bool wait_till_set_; | 73 bool wait_till_set_; |
| 86 | 74 |
| 87 DISALLOW_COPY_AND_ASSIGN(WMStateWaiter); | 75 DISALLOW_COPY_AND_ASSIGN(WMStateWaiter); |
| 88 }; | 76 }; |
| 89 | 77 |
| 90 // A NonClientFrameView with a window mask with the bottom right corner cut out. | 78 // A NonClientFrameView with a window mask with the bottom right corner cut out. |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 { | 327 { |
| 340 WMStateWaiter waiter(xid, "_NET_WM_STATE_FULLSCREEN", true); | 328 WMStateWaiter waiter(xid, "_NET_WM_STATE_FULLSCREEN", true); |
| 341 widget->SetFullscreen(true); | 329 widget->SetFullscreen(true); |
| 342 waiter.Wait(); | 330 waiter.Wait(); |
| 343 } | 331 } |
| 344 EXPECT_TRUE(widget->IsFullscreen()); | 332 EXPECT_TRUE(widget->IsFullscreen()); |
| 345 | 333 |
| 346 // Emulate the window manager exiting fullscreen via a window manager | 334 // Emulate the window manager exiting fullscreen via a window manager |
| 347 // accelerator key. It should not affect the widget's fullscreen state. | 335 // accelerator key. It should not affect the widget's fullscreen state. |
| 348 { | 336 { |
| 349 const char* const kAtomsToCache[] = { | |
| 350 "_NET_WM_STATE", | |
| 351 "_NET_WM_STATE_FULLSCREEN", | |
| 352 nullptr | |
| 353 }; | |
| 354 Display* display = gfx::GetXDisplay(); | 337 Display* display = gfx::GetXDisplay(); |
| 355 ui::X11AtomCache atom_cache(display, kAtomsToCache); | |
| 356 | 338 |
| 357 XEvent xclient; | 339 XEvent xclient; |
| 358 memset(&xclient, 0, sizeof(xclient)); | 340 memset(&xclient, 0, sizeof(xclient)); |
| 359 xclient.type = ClientMessage; | 341 xclient.type = ClientMessage; |
| 360 xclient.xclient.window = xid; | 342 xclient.xclient.window = xid; |
| 361 xclient.xclient.message_type = atom_cache.GetAtom("_NET_WM_STATE"); | 343 xclient.xclient.message_type = ui::GetAtom("_NET_WM_STATE"); |
| 362 xclient.xclient.format = 32; | 344 xclient.xclient.format = 32; |
| 363 xclient.xclient.data.l[0] = 0; | 345 xclient.xclient.data.l[0] = 0; |
| 364 xclient.xclient.data.l[1] = atom_cache.GetAtom("_NET_WM_STATE_FULLSCREEN"); | 346 xclient.xclient.data.l[1] = ui::GetAtom("_NET_WM_STATE_FULLSCREEN"); |
| 365 xclient.xclient.data.l[2] = 0; | 347 xclient.xclient.data.l[2] = 0; |
| 366 xclient.xclient.data.l[3] = 1; | 348 xclient.xclient.data.l[3] = 1; |
| 367 xclient.xclient.data.l[4] = 0; | 349 xclient.xclient.data.l[4] = 0; |
| 368 XSendEvent(display, DefaultRootWindow(display), False, | 350 XSendEvent(display, DefaultRootWindow(display), False, |
| 369 SubstructureRedirectMask | SubstructureNotifyMask, | 351 SubstructureRedirectMask | SubstructureNotifyMask, |
| 370 &xclient); | 352 &xclient); |
| 371 | 353 |
| 372 WMStateWaiter waiter(xid, "_NET_WM_STATE_FULLSCREEN", false); | 354 WMStateWaiter waiter(xid, "_NET_WM_STATE_FULLSCREEN", false); |
| 373 waiter.Wait(); | 355 waiter.Wait(); |
| 374 } | 356 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 390 params.native_widget = new DesktopNativeWidgetAura(&widget); | 372 params.native_widget = new DesktopNativeWidgetAura(&widget); |
| 391 widget.Init(params); | 373 widget.Init(params); |
| 392 widget.Show(); | 374 widget.Show(); |
| 393 ui::X11EventSource::GetInstance()->DispatchXEvents(); | 375 ui::X11EventSource::GetInstance()->DispatchXEvents(); |
| 394 | 376 |
| 395 XID xid = widget.GetNativeWindow()->GetHost()->GetAcceleratedWidget(); | 377 XID xid = widget.GetNativeWindow()->GetHost()->GetAcceleratedWidget(); |
| 396 Display* display = gfx::GetXDisplay(); | 378 Display* display = gfx::GetXDisplay(); |
| 397 | 379 |
| 398 // Minimize by sending _NET_WM_STATE_HIDDEN | 380 // Minimize by sending _NET_WM_STATE_HIDDEN |
| 399 { | 381 { |
| 400 const char* const kAtomsToCache[] = { | |
| 401 "_NET_WM_STATE", | |
| 402 "_NET_WM_STATE_HIDDEN", | |
| 403 nullptr | |
| 404 }; | |
| 405 | |
| 406 ui::X11AtomCache atom_cache(display, kAtomsToCache); | |
| 407 | |
| 408 std::vector< ::Atom> atom_list; | 382 std::vector< ::Atom> atom_list; |
| 409 atom_list.push_back(atom_cache.GetAtom("_NET_WM_STATE_HIDDEN")); | 383 atom_list.push_back(ui::GetAtom("_NET_WM_STATE_HIDDEN")); |
| 410 ui::SetAtomArrayProperty(xid, "_NET_WM_STATE", "ATOM", atom_list); | 384 ui::SetAtomArrayProperty(xid, "_NET_WM_STATE", "ATOM", atom_list); |
| 411 | 385 |
| 412 XEvent xevent; | 386 XEvent xevent; |
| 413 memset(&xevent, 0, sizeof(xevent)); | 387 memset(&xevent, 0, sizeof(xevent)); |
| 414 xevent.type = PropertyNotify; | 388 xevent.type = PropertyNotify; |
| 415 xevent.xproperty.type = PropertyNotify; | 389 xevent.xproperty.type = PropertyNotify; |
| 416 xevent.xproperty.send_event = 1; | 390 xevent.xproperty.send_event = 1; |
| 417 xevent.xproperty.display = display; | 391 xevent.xproperty.display = display; |
| 418 xevent.xproperty.window = xid; | 392 xevent.xproperty.window = xid; |
| 419 xevent.xproperty.atom = atom_cache.GetAtom("_NET_WM_STATE"); | 393 xevent.xproperty.atom = ui::GetAtom("_NET_WM_STATE"); |
| 420 xevent.xproperty.state = 0; | 394 xevent.xproperty.state = 0; |
| 421 XSendEvent(display, DefaultRootWindow(display), False, | 395 XSendEvent(display, DefaultRootWindow(display), False, |
| 422 SubstructureRedirectMask | SubstructureNotifyMask, | 396 SubstructureRedirectMask | SubstructureNotifyMask, |
| 423 &xevent); | 397 &xevent); |
| 424 | 398 |
| 425 WMStateWaiter waiter(xid, "_NET_WM_STATE_HIDDEN", true); | 399 WMStateWaiter waiter(xid, "_NET_WM_STATE_HIDDEN", true); |
| 426 waiter.Wait(); | 400 waiter.Wait(); |
| 427 } | 401 } |
| 428 EXPECT_FALSE(widget.GetNativeWindow()->IsVisible()); | 402 EXPECT_FALSE(widget.GetNativeWindow()->IsVisible()); |
| 429 | 403 |
| 430 // Show from minimized by sending _NET_WM_STATE_FOCUSED | 404 // Show from minimized by sending _NET_WM_STATE_FOCUSED |
| 431 { | 405 { |
| 432 const char* const kAtomsToCache[] = { | |
| 433 "_NET_WM_STATE", | |
| 434 "_NET_WM_STATE_FOCUSED", | |
| 435 nullptr | |
| 436 }; | |
| 437 | |
| 438 ui::X11AtomCache atom_cache(display, kAtomsToCache); | |
| 439 | |
| 440 std::vector< ::Atom> atom_list; | 406 std::vector< ::Atom> atom_list; |
| 441 atom_list.push_back(atom_cache.GetAtom("_NET_WM_STATE_FOCUSED")); | 407 atom_list.push_back(ui::GetAtom("_NET_WM_STATE_FOCUSED")); |
| 442 ui::SetAtomArrayProperty(xid, "_NET_WM_STATE", "ATOM", atom_list); | 408 ui::SetAtomArrayProperty(xid, "_NET_WM_STATE", "ATOM", atom_list); |
| 443 | 409 |
| 444 XEvent xevent; | 410 XEvent xevent; |
| 445 memset(&xevent, 0, sizeof(xevent)); | 411 memset(&xevent, 0, sizeof(xevent)); |
| 446 xevent.type = PropertyNotify; | 412 xevent.type = PropertyNotify; |
| 447 xevent.xproperty.type = PropertyNotify; | 413 xevent.xproperty.type = PropertyNotify; |
| 448 xevent.xproperty.send_event = 1; | 414 xevent.xproperty.send_event = 1; |
| 449 xevent.xproperty.display = display; | 415 xevent.xproperty.display = display; |
| 450 xevent.xproperty.window = xid; | 416 xevent.xproperty.window = xid; |
| 451 xevent.xproperty.atom = atom_cache.GetAtom("_NET_WM_STATE"); | 417 xevent.xproperty.atom = ui::GetAtom("_NET_WM_STATE"); |
| 452 xevent.xproperty.state = 0; | 418 xevent.xproperty.state = 0; |
| 453 XSendEvent(display, DefaultRootWindow(display), False, | 419 XSendEvent(display, DefaultRootWindow(display), False, |
| 454 SubstructureRedirectMask | SubstructureNotifyMask, | 420 SubstructureRedirectMask | SubstructureNotifyMask, |
| 455 &xevent); | 421 &xevent); |
| 456 | 422 |
| 457 WMStateWaiter waiter(xid, "_NET_WM_STATE_FOCUSED", true); | 423 WMStateWaiter waiter(xid, "_NET_WM_STATE_FOCUSED", true); |
| 458 waiter.Wait(); | 424 waiter.Wait(); |
| 459 } | 425 } |
| 460 EXPECT_TRUE(widget.GetNativeWindow()->IsVisible()); | 426 EXPECT_TRUE(widget.GetNativeWindow()->IsVisible()); |
| 461 } | 427 } |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 EXPECT_EQ(ui::ET_MOUSEWHEEL, second_recorder.mouse_events()[0].type()); | 610 EXPECT_EQ(ui::ET_MOUSEWHEEL, second_recorder.mouse_events()[0].type()); |
| 645 EXPECT_EQ(gfx::Point(-25, -25).ToString(), | 611 EXPECT_EQ(gfx::Point(-25, -25).ToString(), |
| 646 second_recorder.mouse_events()[0].location().ToString()); | 612 second_recorder.mouse_events()[0].location().ToString()); |
| 647 | 613 |
| 648 PretendCapture(nullptr); | 614 PretendCapture(nullptr); |
| 649 first.GetNativeWindow()->RemovePreTargetHandler(&first_recorder); | 615 first.GetNativeWindow()->RemovePreTargetHandler(&first_recorder); |
| 650 second.GetNativeWindow()->RemovePreTargetHandler(&second_recorder); | 616 second.GetNativeWindow()->RemovePreTargetHandler(&second_recorder); |
| 651 } | 617 } |
| 652 | 618 |
| 653 } // namespace views | 619 } // namespace views |
| OLD | NEW |