diff options
author | kylechar <kylechar@chromium.org> | 2016-03-21 08:53:22 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-03-21 15:54:43 +0000 |
commit | 9707ed3240dc11fa1296ad28389142d5ac2fcf95 (patch) | |
tree | f831436d9d543683ee77c5341b53d03eb459422c /ui | |
parent | e1f453c8038dd60f17847dc37603c64835f9d865 (diff) | |
download | chromium_src-9707ed3240dc11fa1296ad28389142d5ac2fcf95.zip chromium_src-9707ed3240dc11fa1296ad28389142d5ac2fcf95.tar.gz chromium_src-9707ed3240dc11fa1296ad28389142d5ac2fcf95.tar.bz2 |
Fix multiple displays with Ozone X11.
When simulating multiple displays using the --ash-host-window-bounds
flag, event targetting was broken and all events routed to the first
display. Fix broken event targetting with multiple displays by checking
event locations. Also implement PlatformWindow::MoveCursorTo() for
X11WindowOzone so that cursor moves between windows (aka displays)
correctly.
BUG=361137
Review URL: https://codereview.chromium.org/1801343003
Cr-Commit-Position: refs/heads/master@{#382297}
Diffstat (limited to 'ui')
-rw-r--r-- | ui/events/platform/x11/x11_event_source_libevent.cc | 8 | ||||
-rw-r--r-- | ui/ozone/platform/x11/ozone_platform_x11.cc | 7 | ||||
-rw-r--r-- | ui/platform_window/x11/BUILD.gn | 2 | ||||
-rw-r--r-- | ui/platform_window/x11/x11_window_base.cc | 6 | ||||
-rw-r--r-- | ui/platform_window/x11/x11_window_manager_ozone.cc | 27 | ||||
-rw-r--r-- | ui/platform_window/x11/x11_window_manager_ozone.h | 37 | ||||
-rw-r--r-- | ui/platform_window/x11/x11_window_ozone.cc | 37 | ||||
-rw-r--r-- | ui/platform_window/x11/x11_window_ozone.h | 7 |
8 files changed, 116 insertions, 15 deletions
diff --git a/ui/events/platform/x11/x11_event_source_libevent.cc b/ui/events/platform/x11/x11_event_source_libevent.cc index b1a7ad9..cf0e3d6 100644 --- a/ui/events/platform/x11/x11_event_source_libevent.cc +++ b/ui/events/platform/x11/x11_event_source_libevent.cc @@ -148,13 +148,7 @@ void X11EventSourceLibevent::RemoveXEventDispatcher( void X11EventSourceLibevent::ProcessXEvent(XEvent* xevent) { scoped_ptr<ui::Event> translated_event = TranslateXEventToEvent(*xevent); if (translated_event) { - // The ui::Events produced by TranslateXEventToEvent() don't use - // base::NativeEvent constructors. To trigger any additional checks that - // occur in the base::NativeEvent constructor (eg. check for double click) - // we create a copy here. - scoped_ptr<ui::Event> event_copy = - ui::EventFromNative(translated_event.get()); - DispatchEvent(event_copy.get()); + DispatchEvent(translated_event.get()); } else { // Only if we can't translate XEvent into ui::Event, try to dispatch XEvent // directly to XEventDispatchers. diff --git a/ui/ozone/platform/x11/ozone_platform_x11.cc b/ui/ozone/platform/x11/ozone_platform_x11.cc index bd1bea2..cfaf098 100644 --- a/ui/ozone/platform/x11/ozone_platform_x11.cc +++ b/ui/ozone/platform/x11/ozone_platform_x11.cc @@ -18,6 +18,7 @@ #include "ui/ozone/public/ozone_platform.h" #include "ui/ozone/public/system_input_injector.h" #include "ui/platform_window/platform_window.h" +#include "ui/platform_window/x11/x11_window_manager_ozone.h" #include "ui/platform_window/x11/x11_window_ozone.h" namespace ui { @@ -62,8 +63,8 @@ class OzonePlatformX11 : public OzonePlatform { scoped_ptr<PlatformWindow> CreatePlatformWindow( PlatformWindowDelegate* delegate, const gfx::Rect& bounds) override { - scoped_ptr<X11WindowOzone> window = - make_scoped_ptr(new X11WindowOzone(event_source_.get(), delegate)); + scoped_ptr<X11WindowOzone> window = make_scoped_ptr(new X11WindowOzone( + event_source_.get(), window_manager_.get(), delegate)); window->SetBounds(bounds); window->Create(); return std::move(window); @@ -78,6 +79,7 @@ class OzonePlatformX11 : public OzonePlatform { } void InitializeUI() override { + window_manager_.reset(new X11WindowManagerOzone); event_source_.reset(new X11EventSourceLibevent(gfx::GetXDisplay())); surface_factory_ozone_.reset(new X11SurfaceFactory()); overlay_manager_.reset(new StubOverlayManager()); @@ -93,6 +95,7 @@ class OzonePlatformX11 : public OzonePlatform { private: // Objects in the Browser process. + scoped_ptr<X11WindowManagerOzone> window_manager_; scoped_ptr<X11EventSourceLibevent> event_source_; scoped_ptr<OverlayManagerOzone> overlay_manager_; scoped_ptr<InputController> input_controller_; diff --git a/ui/platform_window/x11/BUILD.gn b/ui/platform_window/x11/BUILD.gn index 5f841b3..bac1aaa 100644 --- a/ui/platform_window/x11/BUILD.gn +++ b/ui/platform_window/x11/BUILD.gn @@ -35,6 +35,8 @@ component("x11") { sources += [ "x11_cursor_ozone.cc", "x11_cursor_ozone.h", + "x11_window_manager_ozone.cc", + "x11_window_manager_ozone.h", "x11_window_ozone.cc", "x11_window_ozone.h", ] diff --git a/ui/platform_window/x11/x11_window_base.cc b/ui/platform_window/x11/x11_window_base.cc index 4c24d7e..51b19ac 100644 --- a/ui/platform_window/x11/x11_window_base.cc +++ b/ui/platform_window/x11/x11_window_base.cc @@ -218,7 +218,11 @@ void X11WindowBase::Minimize() {} void X11WindowBase::Restore() {} -void X11WindowBase::MoveCursorTo(const gfx::Point& location) {} +void X11WindowBase::MoveCursorTo(const gfx::Point& location) { + XWarpPointer(xdisplay_, None, xroot_window_, 0, 0, 0, 0, + confirmed_bounds_.x() + location.x(), + confirmed_bounds_.y() + location.y()); +} void X11WindowBase::ConfineCursorToBounds(const gfx::Rect& bounds) {} diff --git a/ui/platform_window/x11/x11_window_manager_ozone.cc b/ui/platform_window/x11/x11_window_manager_ozone.cc new file mode 100644 index 0000000..f29cf9e --- /dev/null +++ b/ui/platform_window/x11/x11_window_manager_ozone.cc @@ -0,0 +1,27 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/platform_window/x11/x11_window_manager_ozone.h" + +#include <X11/Xlib.h> + +namespace ui { + +X11WindowManagerOzone::X11WindowManagerOzone() : event_grabber_(None) {} + +X11WindowManagerOzone::~X11WindowManagerOzone() {} + +void X11WindowManagerOzone::GrabEvents(XID xwindow) { + if (event_grabber_ != None) + return; + event_grabber_ = xwindow; +} + +void X11WindowManagerOzone::UngrabEvents(XID xwindow) { + if (event_grabber_ != xwindow) + return; + event_grabber_ = None; +} + +} // namespace ui diff --git a/ui/platform_window/x11/x11_window_manager_ozone.h b/ui/platform_window/x11/x11_window_manager_ozone.h new file mode 100644 index 0000000..1cb6bd1 --- /dev/null +++ b/ui/platform_window/x11/x11_window_manager_ozone.h @@ -0,0 +1,37 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_PLATFORM_WINDOW_X11_X11_WINDOW_MANAGER_OZONE_H_ +#define UI_PLATFORM_WINDOW_X11_X11_WINDOW_MANAGER_OZONE_H_ + +#include "base/macros.h" +#include "ui/platform_window/x11/x11_window_export.h" +#include "ui/platform_window/x11/x11_window_ozone.h" + +namespace ui { + +class X11_WINDOW_EXPORT X11WindowManagerOzone { + public: + X11WindowManagerOzone(); + ~X11WindowManagerOzone(); + + // Tries to set a given XWindow as the recipient for events. It will fail if + // there is already another XWindow as recipient. + void GrabEvents(XID xwindow); + + // Unsets a given XWindow as the recipient for events. + void UngrabEvents(XID xwindow); + + // Gets the current XWindow recipient of mouse events. + XID event_grabber() const { return event_grabber_; } + + private: + XID event_grabber_; + + DISALLOW_COPY_AND_ASSIGN(X11WindowManagerOzone); +}; + +} // namespace ui + +#endif // UI_PLATFORM_WINDOW_X11_X11_WINDOW_MANAGER_OZONE_H_ diff --git a/ui/platform_window/x11/x11_window_ozone.cc b/ui/platform_window/x11/x11_window_ozone.cc index 3a370dc..5a83070 100644 --- a/ui/platform_window/x11/x11_window_ozone.cc +++ b/ui/platform_window/x11/x11_window_ozone.cc @@ -11,13 +11,18 @@ #include "ui/events/platform/x11/x11_event_source.h" #include "ui/gfx/geometry/point.h" #include "ui/platform_window/x11/x11_cursor_ozone.h" +#include "ui/platform_window/x11/x11_window_manager_ozone.h" namespace ui { X11WindowOzone::X11WindowOzone(X11EventSourceLibevent* event_source, + X11WindowManagerOzone* window_manager, PlatformWindowDelegate* delegate) - : X11WindowBase(delegate), event_source_(event_source) { + : X11WindowBase(delegate), + event_source_(event_source), + window_manager_(window_manager) { DCHECK(event_source_); + DCHECK(window_manager); event_source_->AddPlatformEventDispatcher(this); event_source_->AddXEventDispatcher(this); } @@ -27,6 +32,14 @@ X11WindowOzone::~X11WindowOzone() { event_source_->RemoveXEventDispatcher(this); } +void X11WindowOzone::SetCapture() { + window_manager_->GrabEvents(xwindow()); +} + +void X11WindowOzone::ReleaseCapture() { + window_manager_->UngrabEvents(xwindow()); +} + void X11WindowOzone::SetCursor(PlatformCursor cursor) { X11CursorOzone* cursor_ozone = static_cast<X11CursorOzone*>(cursor); XDefineCursor(xdisplay(), xwindow(), cursor_ozone->xcursor()); @@ -40,10 +53,24 @@ bool X11WindowOzone::DispatchXEvent(XEvent* xev) { return true; } -bool X11WindowOzone::CanDispatchEvent(const PlatformEvent& event) { - // TODO(kylechar): This is broken, there is no way to include XID of XWindow - // in ui::Event. Fix or use similar hack to DrmWindowHost. - return xwindow() != None; +bool X11WindowOzone::CanDispatchEvent(const PlatformEvent& platform_event) { + if (xwindow() == None) + return false; + + // If there is a grab, capture events here. + XID grabber = window_manager_->event_grabber(); + if (grabber != None) + return grabber == xwindow(); + + // TODO(kylechar): We may need to do something special for TouchEvents similar + // to how DrmWindowHost handles them. + if (static_cast<Event*>(platform_event)->IsLocatedEvent()) { + const LocatedEvent* event = + static_cast<const LocatedEvent*>(platform_event); + return GetBounds().Contains(event->root_location()); + } + + return true; } uint32_t X11WindowOzone::DispatchEvent(const PlatformEvent& platform_event) { diff --git a/ui/platform_window/x11/x11_window_ozone.h b/ui/platform_window/x11/x11_window_ozone.h index b6c4573..da847ecc 100644 --- a/ui/platform_window/x11/x11_window_ozone.h +++ b/ui/platform_window/x11/x11_window_ozone.h @@ -9,19 +9,25 @@ #include "ui/events/platform/platform_event_dispatcher.h" #include "ui/events/platform/x11/x11_event_source_libevent.h" #include "ui/platform_window/x11/x11_window_base.h" +#include "ui/platform_window/x11/x11_window_export.h" namespace ui { +class X11WindowManagerOzone; + // PlatformWindow implementation for X11 Ozone. PlatformEvents are ui::Events. class X11_WINDOW_EXPORT X11WindowOzone : public X11WindowBase, public PlatformEventDispatcher, public XEventDispatcher { public: X11WindowOzone(X11EventSourceLibevent* event_source, + X11WindowManagerOzone* window_manager, PlatformWindowDelegate* delegate); ~X11WindowOzone() override; // PlatformWindow: + void SetCapture() override; + void ReleaseCapture() override; void SetCursor(PlatformCursor cursor) override; // XEventDispatcher: @@ -33,6 +39,7 @@ class X11_WINDOW_EXPORT X11WindowOzone : public X11WindowBase, uint32_t DispatchEvent(const PlatformEvent& event) override; X11EventSourceLibevent* event_source_; + X11WindowManagerOzone* window_manager_; DISALLOW_COPY_AND_ASSIGN(X11WindowOzone); }; |