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/impl/window_tree_host_delegate_wayland.h"
7 #include "ozone/impl/desktop_window_tree_host_wayland.h"
8 #include "ozone/impl/ozone_display.h"
9 #include "ozone/ui/events/event_converter_ozone_wayland.h"
10 #include "ui/events/event_utils.h"
12 using namespace ozonewayland;
16 WindowTreeHostDelegateWayland::WindowTreeHostDelegateWayland()
17 : current_focus_window_(0),
19 stop_propogation_(false),
20 current_dispatcher_(NULL),
21 current_capture_(NULL),
22 current_active_window_(NULL),
25 DCHECK(base::MessagePumpOzone::Current());
26 base::MessagePumpOzone::Current()->AddDispatcherForRootWindow(this);
27 EventConverterOzoneWayland::GetInstance()->SetWindowChangeObserver(this);
30 WindowTreeHostDelegateWayland::~WindowTreeHostDelegateWayland() {
33 void WindowTreeHostDelegateWayland::OnRootWindowCreated(unsigned handle) {
34 open_windows().push_back(handle);
37 aura_windows_->clear();
43 void WindowTreeHostDelegateWayland::OnRootWindowClosed(unsigned handle) {
44 open_windows().remove(handle);
45 if (open_windows().empty()) {
48 SetActiveWindow(NULL);
50 DCHECK(base::MessagePumpOzone::Current());
51 base::MessagePumpOzone::Current()->RemoveDispatcherForRootWindow(this);
52 EventConverterOzoneWayland::GetInstance()->SetWindowChangeObserver(NULL);
56 aura_windows_->clear();
61 if (!current_active_window_ ||
62 GetWindowHandle(current_active_window_->window_) != handle ||
67 DCHECK(!current_active_window_->window_parent_);
68 // Set first top level window in the list of open windows as dispatcher.
69 // This is just a guess of the window which would eventually be focussed.
70 // We should set the correct root window as dispatcher in OnWindowFocused.
71 const std::list<unsigned>& windows = open_windows();
72 DesktopWindowTreeHostWayland* rootWindow =
73 DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(
75 SetActiveWindow(rootWindow);
76 rootWindow->HandleNativeWidgetActivationChanged(true);
79 void WindowTreeHostDelegateWayland::SetActiveWindow(
80 DesktopWindowTreeHostWayland* dispatcher) {
81 current_active_window_ = dispatcher;
82 current_dispatcher_ = current_active_window_;
83 if (!current_active_window_)
86 // Make sure the stacking order is correct. The activated window should be
87 // first one in list of open windows.
88 std::list<unsigned>& windows = open_windows();
89 DCHECK(windows.size());
90 unsigned window_handle = current_active_window_->window_;
91 if (windows.front() != window_handle) {
92 windows.remove(window_handle);
93 windows.insert(windows.begin(), window_handle);
96 current_active_window_->Activate();
99 DesktopWindowTreeHostWayland*
100 WindowTreeHostDelegateWayland::GetActiveWindow() const {
101 return current_active_window_;
104 void WindowTreeHostDelegateWayland::SetCapture(
105 DesktopWindowTreeHostWayland* dispatcher) {
106 if (current_capture_)
107 current_capture_->OnCaptureReleased();
109 current_capture_ = dispatcher;
110 stop_propogation_ = current_capture_ ? true : false;
111 current_dispatcher_ = current_capture_;
112 if (!current_dispatcher_)
113 current_dispatcher_ = current_active_window_;
116 DesktopWindowTreeHostWayland*
117 WindowTreeHostDelegateWayland::GetCurrentCapture() const {
118 return current_capture_;
121 const std::vector<aura::Window*>&
122 WindowTreeHostDelegateWayland::GetAllOpenWindows() {
123 if (!aura_windows_) {
124 const std::list<unsigned>& windows = open_windows();
125 DCHECK(windows.size());
126 aura_windows_ = new std::vector<aura::Window*>(windows.size());
128 windows.begin(), windows.end(), aura_windows_->begin(),
129 DesktopWindowTreeHostWayland::GetContentWindowForAcceleratedWidget);
132 return *aura_windows_;
135 ////////////////////////////////////////////////////////////////////////////////
136 // WindowTreeHostDelegateWayland, Private implementation:
137 void WindowTreeHostDelegateWayland::DispatchMouseEvent(
138 ui::MouseEvent* event) {
140 SendEventToProcessor(event);
141 else if (event->type() == ui::ET_MOUSE_PRESSED)
144 // Stop event propogation as this window is acting as event grabber. All
145 // event's we create are "cancelable". If in future we use events that are not
146 // cancelable, then a check for cancelable events needs to be added here.
147 if (stop_propogation_)
148 event->StopPropagation();
152 WindowTreeHostDelegateWayland::open_windows() {
154 open_windows_ = new std::list<unsigned>();
156 return *open_windows_;
160 WindowTreeHostDelegateWayland::GetWindowHandle(gfx::AcceleratedWidget widget) {
161 return static_cast<unsigned>(widget);
164 ui::EventProcessor* WindowTreeHostDelegateWayland::GetEventProcessor() {
165 return current_dispatcher_->delegate_->GetEventProcessor();
168 ////////////////////////////////////////////////////////////////////////////////
169 // WindowTreeHostDelegateWayland, MessagePumpDispatcher implementation:
170 uint32_t WindowTreeHostDelegateWayland::Dispatch(const base::NativeEvent& ne) {
171 ui::EventType type = ui::EventTypeFromNative(ne);
172 DCHECK(current_dispatcher_);
175 case ui::ET_TOUCH_MOVED:
176 case ui::ET_TOUCH_PRESSED:
177 case ui::ET_TOUCH_CANCELLED:
178 case ui::ET_TOUCH_RELEASED: {
179 ui::TouchEvent* touchev = static_cast<ui::TouchEvent*>(ne);
180 SendEventToProcessor(touchev);
183 case ui::ET_KEY_PRESSED: {
184 ui::KeyEvent* keydown_event = static_cast<ui::KeyEvent*>(ne);
185 SendEventToProcessor(keydown_event);
188 case ui::ET_KEY_RELEASED: {
189 ui::KeyEvent* keyup_event = static_cast<ui::KeyEvent*>(ne);
190 SendEventToProcessor(keyup_event);
193 case ui::ET_MOUSEWHEEL: {
194 ui::MouseWheelEvent* wheelev = static_cast<ui::MouseWheelEvent*>(ne);
195 DispatchMouseEvent(wheelev);
198 case ui::ET_MOUSE_MOVED:
199 case ui::ET_MOUSE_DRAGGED:
200 case ui::ET_MOUSE_PRESSED:
201 case ui::ET_MOUSE_RELEASED:
202 case ui::ET_MOUSE_ENTERED:
203 case ui::ET_MOUSE_EXITED: {
204 ui::MouseEvent* mouseev = static_cast<ui::MouseEvent*>(ne);
205 DispatchMouseEvent(mouseev);
208 case ui::ET_SCROLL_FLING_START:
209 case ui::ET_SCROLL_FLING_CANCEL:
210 case ui::ET_SCROLL: {
211 ui::ScrollEvent* scrollev = static_cast<ui::ScrollEvent*>(ne);
212 SendEventToProcessor(scrollev);
215 case ui::ET_UMA_DATA:
220 NOTIMPLEMENTED() << "WindowTreeHostDelegateWayland: unknown event type.";
222 return POST_DISPATCH_NONE;
225 ////////////////////////////////////////////////////////////////////////////////
226 // DesktopWindowTreeHostWayland, WindowChangeObserver implementation:
227 void WindowTreeHostDelegateWayland::OnWindowFocused(unsigned handle) {
228 current_focus_window_ = handle;
229 // Don't dispatch events in case a window has installed itself as capture
230 // window but doesn't have the focus.
231 handle_event_ = current_capture_ ? current_focus_window_ ==
232 GetWindowHandle(current_capture_->GetAcceleratedWidget()) : true;
233 if (GetWindowHandle(current_active_window_->window_) == handle)
236 // A new window should not steal focus in case the current window has a open
238 if (current_capture_ && current_capture_ != current_active_window_)
241 DesktopWindowTreeHostWayland* window = NULL;
243 window = DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
245 if (!window || window->window_parent_)
248 current_active_window_->HandleNativeWidgetActivationChanged(false);
250 SetActiveWindow(window);
251 window->HandleNativeWidgetActivationChanged(true);
254 void WindowTreeHostDelegateWayland::OnWindowEnter(unsigned handle) {
255 OnWindowFocused(handle);
258 void WindowTreeHostDelegateWayland::OnWindowLeave(unsigned handle) {
261 void WindowTreeHostDelegateWayland::OnWindowClose(unsigned handle) {
262 // we specially treat grabbed windows in this function, thus the need for
263 // current_capture_ always be a valid pointer.
264 if (!handle || !current_capture_)
266 if (GetWindowHandle(current_capture_->window_) != handle)
268 DesktopWindowTreeHostWayland* window = NULL;
269 window = DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
270 window->OnCaptureReleased();
274 void WindowTreeHostDelegateWayland::OnWindowResized(unsigned handle,
277 DesktopWindowTreeHostWayland* window =
278 DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
280 window->HandleWindowResize(width, height);