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_ || current_active_window_->window_ != handle ||
66 DCHECK(!current_active_window_->window_parent_);
67 // Set first top level window in the list of open windows as dispatcher.
68 // This is just a guess of the window which would eventually be focussed.
69 // We should set the correct root window as dispatcher in OnWindowFocused.
70 const std::list<gfx::AcceleratedWidget>& windows = open_windows();
71 DesktopWindowTreeHostWayland* rootWindow =
72 DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(
74 SetActiveWindow(rootWindow);
75 rootWindow->HandleNativeWidgetActivationChanged(true);
78 void WindowTreeHostDelegateWayland::SetActiveWindow(
79 DesktopWindowTreeHostWayland* dispatcher) {
80 current_active_window_ = dispatcher;
81 current_dispatcher_ = current_active_window_;
82 if (!current_active_window_)
85 // Make sure the stacking order is correct. The activated window should be
86 // first one in list of open windows.
87 std::list<gfx::AcceleratedWidget>& windows = open_windows();
88 DCHECK(windows.size());
89 unsigned window_handle = current_active_window_->window_;
90 if (windows.front() != window_handle) {
91 windows.remove(window_handle);
92 windows.insert(windows.begin(), window_handle);
95 current_active_window_->Activate();
98 DesktopWindowTreeHostWayland*
99 WindowTreeHostDelegateWayland::GetActiveWindow() const {
100 return current_active_window_;
103 void WindowTreeHostDelegateWayland::SetCapture(
104 DesktopWindowTreeHostWayland* dispatcher) {
105 if (current_capture_)
106 current_capture_->OnCaptureReleased();
108 current_capture_ = dispatcher;
109 stop_propogation_ = current_capture_ ? true : false;
110 current_dispatcher_ = current_capture_;
111 if (!current_dispatcher_)
112 current_dispatcher_ = current_active_window_;
115 DesktopWindowTreeHostWayland*
116 WindowTreeHostDelegateWayland::GetCurrentCapture() const {
117 return current_capture_;
120 const std::vector<aura::Window*>&
121 WindowTreeHostDelegateWayland::GetAllOpenWindows() {
122 if (!aura_windows_) {
123 const std::list<gfx::AcceleratedWidget>& windows = open_windows();
124 DCHECK(windows.size());
125 aura_windows_ = new std::vector<aura::Window*>(windows.size());
127 windows.begin(), windows.end(), aura_windows_->begin(),
128 DesktopWindowTreeHostWayland::GetContentWindowForAcceleratedWidget);
131 return *aura_windows_;
134 ////////////////////////////////////////////////////////////////////////////////
135 // WindowTreeHostDelegateWayland, Private implementation:
136 void WindowTreeHostDelegateWayland::DispatchMouseEvent(
137 ui::MouseEvent* event) {
139 SendEventToProcessor(event);
140 else if (event->type() == ui::ET_MOUSE_PRESSED)
143 // Stop event propogation as this window is acting as event grabber. All
144 // event's we create are "cancelable". If in future we use events that are not
145 // cancelable, then a check for cancelable events needs to be added here.
146 if (stop_propogation_)
147 event->StopPropagation();
150 std::list<gfx::AcceleratedWidget>&
151 WindowTreeHostDelegateWayland::open_windows() {
153 open_windows_ = new std::list<gfx::AcceleratedWidget>();
155 return *open_windows_;
158 ui::EventProcessor* WindowTreeHostDelegateWayland::GetEventProcessor() {
159 return current_dispatcher_->delegate_->GetEventProcessor();
162 ////////////////////////////////////////////////////////////////////////////////
163 // WindowTreeHostDelegateWayland, MessagePumpDispatcher implementation:
164 uint32_t WindowTreeHostDelegateWayland::Dispatch(const base::NativeEvent& ne) {
165 ui::EventType type = ui::EventTypeFromNative(ne);
166 DCHECK(current_dispatcher_);
169 case ui::ET_TOUCH_MOVED:
170 case ui::ET_TOUCH_PRESSED:
171 case ui::ET_TOUCH_CANCELLED:
172 case ui::ET_TOUCH_RELEASED: {
173 ui::TouchEvent* touchev = static_cast<ui::TouchEvent*>(ne);
174 SendEventToProcessor(touchev);
177 case ui::ET_KEY_PRESSED: {
178 ui::KeyEvent* keydown_event = static_cast<ui::KeyEvent*>(ne);
179 SendEventToProcessor(keydown_event);
182 case ui::ET_KEY_RELEASED: {
183 ui::KeyEvent* keyup_event = static_cast<ui::KeyEvent*>(ne);
184 SendEventToProcessor(keyup_event);
187 case ui::ET_MOUSEWHEEL: {
188 ui::MouseWheelEvent* wheelev = static_cast<ui::MouseWheelEvent*>(ne);
189 DispatchMouseEvent(wheelev);
192 case ui::ET_MOUSE_MOVED:
193 case ui::ET_MOUSE_DRAGGED:
194 case ui::ET_MOUSE_PRESSED:
195 case ui::ET_MOUSE_RELEASED:
196 case ui::ET_MOUSE_ENTERED:
197 case ui::ET_MOUSE_EXITED: {
198 ui::MouseEvent* mouseev = static_cast<ui::MouseEvent*>(ne);
199 DispatchMouseEvent(mouseev);
202 case ui::ET_SCROLL_FLING_START:
203 case ui::ET_SCROLL_FLING_CANCEL:
204 case ui::ET_SCROLL: {
205 ui::ScrollEvent* scrollev = static_cast<ui::ScrollEvent*>(ne);
206 SendEventToProcessor(scrollev);
209 case ui::ET_UMA_DATA:
214 NOTIMPLEMENTED() << "WindowTreeHostDelegateWayland: unknown event type.";
216 return POST_DISPATCH_NONE;
219 ////////////////////////////////////////////////////////////////////////////////
220 // DesktopWindowTreeHostWayland, WindowChangeObserver implementation:
221 void WindowTreeHostDelegateWayland::OnWindowFocused(unsigned handle) {
222 current_focus_window_ = handle;
223 // Don't dispatch events in case a window has installed itself as capture
224 // window but doesn't have the focus.
225 handle_event_ = current_capture_ ? current_focus_window_ ==
226 current_capture_->GetAcceleratedWidget() : true;
227 if (current_active_window_->window_ == handle)
230 // A new window should not steal focus in case the current window has a open
232 if (current_capture_ && current_capture_ != current_active_window_)
235 DesktopWindowTreeHostWayland* window = NULL;
237 window = DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
239 if (!window || window->window_parent_)
242 current_active_window_->HandleNativeWidgetActivationChanged(false);
244 SetActiveWindow(window);
245 window->HandleNativeWidgetActivationChanged(true);
248 void WindowTreeHostDelegateWayland::OnWindowEnter(unsigned handle) {
249 OnWindowFocused(handle);
252 void WindowTreeHostDelegateWayland::OnWindowLeave(unsigned handle) {
255 void WindowTreeHostDelegateWayland::OnWindowClose(unsigned handle) {
256 // we specially treat grabbed windows in this function, thus the need for
257 // current_capture_ always be a valid pointer.
258 if (!handle || !current_capture_)
260 if (current_capture_->window_ != handle)
262 DesktopWindowTreeHostWayland* window = NULL;
263 window = DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
264 window->OnCaptureReleased();
268 void WindowTreeHostDelegateWayland::OnWindowResized(unsigned handle,
271 DesktopWindowTreeHostWayland* window =
272 DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
274 window->HandleWindowResize(width, height);