1 // Copyright 2014 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ozone/ui/desktop_aura/window_tree_host_delegate_wayland.h"
7 #include "ozone/ui/desktop_aura/desktop_window_tree_host_wayland.h"
8 #include "ozone/ui/events/event_factory_ozone_wayland.h"
9 #include "ui/events/event_utils.h"
13 WindowTreeHostDelegateWayland::WindowTreeHostDelegateWayland()
14 : current_focus_window_(0),
16 stop_propogation_(false),
17 current_dispatcher_(NULL),
18 current_capture_(NULL),
19 current_active_window_(NULL),
22 DCHECK(base::MessagePumpOzone::Current());
23 base::MessagePumpOzone::Current()->AddDispatcherForRootWindow(this);
24 ui::EventFactoryOzoneWayland::GetInstance()->SetWindowChangeObserver(this);
27 WindowTreeHostDelegateWayland::~WindowTreeHostDelegateWayland() {
30 void WindowTreeHostDelegateWayland::OnRootWindowCreated(unsigned handle) {
31 open_windows().push_back(handle);
34 aura_windows_->clear();
40 void WindowTreeHostDelegateWayland::OnRootWindowClosed(unsigned handle) {
41 open_windows().remove(handle);
42 if (open_windows().empty()) {
45 SetActiveWindow(NULL);
47 DCHECK(base::MessagePumpOzone::Current());
48 base::MessagePumpOzone::Current()->RemoveDispatcherForRootWindow(this);
49 ui::EventFactoryOzoneWayland::GetInstance()->SetWindowChangeObserver(NULL);
53 aura_windows_->clear();
58 if (!current_active_window_ ||
59 GetWindowHandle(current_active_window_->window_) != handle ||
64 DCHECK(!current_active_window_->window_parent_);
65 // Set first top level window in the list of open windows as dispatcher.
66 // This is just a guess of the window which would eventually be focussed.
67 // We should set the correct root window as dispatcher in OnWindowFocused.
68 const std::list<unsigned>& windows = open_windows();
69 DesktopWindowTreeHostWayland* rootWindow =
70 DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(
72 SetActiveWindow(rootWindow);
73 rootWindow->HandleNativeWidgetActivationChanged(true);
76 void WindowTreeHostDelegateWayland::SetActiveWindow(
77 DesktopWindowTreeHostWayland* dispatcher) {
78 current_active_window_ = dispatcher;
79 current_dispatcher_ = current_active_window_;
80 if (!current_active_window_)
83 // Make sure the stacking order is correct. The activated window should be
84 // first one in list of open windows.
85 std::list<unsigned>& windows = open_windows();
86 DCHECK(windows.size());
87 unsigned window_handle = current_active_window_->window_;
88 if (windows.front() != window_handle) {
89 windows.remove(window_handle);
90 windows.insert(windows.begin(), window_handle);
93 current_active_window_->Activate();
96 DesktopWindowTreeHostWayland*
97 WindowTreeHostDelegateWayland::GetActiveWindow() const {
98 return current_active_window_;
101 void WindowTreeHostDelegateWayland::SetCapture(
102 DesktopWindowTreeHostWayland* dispatcher) {
103 if (current_capture_)
104 current_capture_->OnCaptureReleased();
106 current_capture_ = dispatcher;
107 stop_propogation_ = current_capture_ ? true : false;
108 current_dispatcher_ = current_capture_;
109 if (!current_dispatcher_)
110 current_dispatcher_ = current_active_window_;
113 DesktopWindowTreeHostWayland*
114 WindowTreeHostDelegateWayland::GetCurrentCapture() const {
115 return current_capture_;
118 const std::vector<aura::Window*>&
119 WindowTreeHostDelegateWayland::GetAllOpenWindows() {
120 if (!aura_windows_) {
121 const std::list<unsigned>& windows = open_windows();
122 DCHECK(windows.size());
123 aura_windows_ = new std::vector<aura::Window*>(windows.size());
125 windows.begin(), windows.end(), aura_windows_->begin(),
126 DesktopWindowTreeHostWayland::GetContentWindowForAcceleratedWidget);
129 return *aura_windows_;
132 ////////////////////////////////////////////////////////////////////////////////
133 // WindowTreeHostDelegateWayland, Private implementation:
134 void WindowTreeHostDelegateWayland::DispatchMouseEvent(
135 ui::MouseEvent* event) {
137 SendEventToProcessor(event);
138 else if (event->type() == ui::ET_MOUSE_PRESSED)
141 // Stop event propogation as this window is acting as event grabber. All
142 // event's we create are "cancelable". If in future we use events that are not
143 // cancelable, then a check for cancelable events needs to be added here.
144 if (stop_propogation_)
145 event->StopPropagation();
149 WindowTreeHostDelegateWayland::open_windows() {
151 open_windows_ = new std::list<unsigned>();
153 return *open_windows_;
157 WindowTreeHostDelegateWayland::GetWindowHandle(gfx::AcceleratedWidget widget) {
158 return static_cast<unsigned>(widget);
161 ui::EventProcessor* WindowTreeHostDelegateWayland::GetEventProcessor() {
162 return current_dispatcher_->dispatcher();
165 ////////////////////////////////////////////////////////////////////////////////
166 // WindowTreeHostDelegateWayland, MessagePumpDispatcher implementation:
167 uint32_t WindowTreeHostDelegateWayland::Dispatch(const base::NativeEvent& ne) {
168 ui::EventType type = ui::EventTypeFromNative(ne);
169 DCHECK(current_dispatcher_);
172 case ui::ET_TOUCH_MOVED:
173 case ui::ET_TOUCH_PRESSED:
174 case ui::ET_TOUCH_CANCELLED:
175 case ui::ET_TOUCH_RELEASED: {
176 ui::TouchEvent* touchev = static_cast<ui::TouchEvent*>(ne);
177 SendEventToProcessor(touchev);
180 case ui::ET_KEY_PRESSED: {
181 ui::KeyEvent* keydown_event = static_cast<ui::KeyEvent*>(ne);
182 SendEventToProcessor(keydown_event);
185 case ui::ET_KEY_RELEASED: {
186 ui::KeyEvent* keyup_event = static_cast<ui::KeyEvent*>(ne);
187 SendEventToProcessor(keyup_event);
190 case ui::ET_MOUSEWHEEL: {
191 ui::MouseWheelEvent* wheelev = static_cast<ui::MouseWheelEvent*>(ne);
192 DispatchMouseEvent(wheelev);
195 case ui::ET_MOUSE_MOVED:
196 case ui::ET_MOUSE_DRAGGED:
197 case ui::ET_MOUSE_PRESSED:
198 case ui::ET_MOUSE_RELEASED:
199 case ui::ET_MOUSE_ENTERED:
200 case ui::ET_MOUSE_EXITED: {
201 ui::MouseEvent* mouseev = static_cast<ui::MouseEvent*>(ne);
202 DispatchMouseEvent(mouseev);
205 case ui::ET_SCROLL_FLING_START:
206 case ui::ET_SCROLL_FLING_CANCEL:
207 case ui::ET_SCROLL: {
208 ui::ScrollEvent* scrollev = static_cast<ui::ScrollEvent*>(ne);
209 SendEventToProcessor(scrollev);
212 case ui::ET_UMA_DATA:
217 NOTIMPLEMENTED() << "WindowTreeHostDelegateWayland: unknown event type.";
219 return POST_DISPATCH_NONE;
222 ////////////////////////////////////////////////////////////////////////////////
223 // DesktopWindowTreeHostWayland, WindowChangeObserver implementation:
224 void WindowTreeHostDelegateWayland::OnWindowFocused(unsigned handle) {
225 current_focus_window_ = handle;
226 // Don't dispatch events in case a window has installed itself as capture
227 // window but doesn't have the focus.
228 handle_event_ = current_capture_ ? current_focus_window_ ==
229 GetWindowHandle(current_capture_->GetAcceleratedWidget()) : true;
230 if (GetWindowHandle(current_active_window_->window_) == handle)
233 // A new window should not steal focus in case the current window has a open
235 if (current_capture_ && current_capture_ != current_active_window_)
238 DesktopWindowTreeHostWayland* window = NULL;
240 window = DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
242 if (!window || window->window_parent_)
245 current_active_window_->HandleNativeWidgetActivationChanged(false);
247 SetActiveWindow(window);
248 window->HandleNativeWidgetActivationChanged(true);
251 void WindowTreeHostDelegateWayland::OnWindowEnter(unsigned handle) {
252 OnWindowFocused(handle);
255 void WindowTreeHostDelegateWayland::OnWindowLeave(unsigned handle) {
258 void WindowTreeHostDelegateWayland::OnWindowClose(unsigned handle) {
259 // we specially treat grabbed windows in this function, thus the need for
260 // current_capture_ always be a valid pointer.
261 if (!handle || !current_capture_)
263 if (GetWindowHandle(current_capture_->window_) != handle)
265 DesktopWindowTreeHostWayland* window = NULL;
266 window = DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
267 window->OnCaptureReleased();
271 void WindowTreeHostDelegateWayland::OnWindowResized(unsigned handle,
274 DesktopWindowTreeHostWayland* window =
275 DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
277 window->HandleWindowResize(width, height);