Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / ozone / ui / desktop_aura / window_tree_host_delegate_wayland.cc
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.
4
5 #include "ozone/ui/desktop_aura/window_tree_host_delegate_wayland.h"
6
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"
10
11 namespace views {
12
13 WindowTreeHostDelegateWayland::WindowTreeHostDelegateWayland()
14     : current_focus_window_(0),
15       handle_event_(true),
16       stop_propogation_(false),
17       current_dispatcher_(NULL),
18       current_capture_(NULL),
19       current_active_window_(NULL),
20       open_windows_(NULL),
21       aura_windows_(NULL) {
22   DCHECK(base::MessagePumpOzone::Current());
23   base::MessagePumpOzone::Current()->AddDispatcherForRootWindow(this);
24   ui::EventFactoryOzoneWayland::GetInstance()->SetWindowChangeObserver(this);
25 }
26
27 WindowTreeHostDelegateWayland::~WindowTreeHostDelegateWayland() {
28 }
29
30 void WindowTreeHostDelegateWayland::OnRootWindowCreated(unsigned handle) {
31   open_windows().push_back(handle);
32
33   if (aura_windows_) {
34     aura_windows_->clear();
35     delete aura_windows_;
36     aura_windows_ = NULL;
37   }
38 }
39
40 void WindowTreeHostDelegateWayland::OnRootWindowClosed(unsigned handle) {
41   open_windows().remove(handle);
42   if (open_windows().empty()) {
43     delete open_windows_;
44     open_windows_ = NULL;
45     SetActiveWindow(NULL);
46
47     DCHECK(base::MessagePumpOzone::Current());
48     base::MessagePumpOzone::Current()->RemoveDispatcherForRootWindow(this);
49     ui::EventFactoryOzoneWayland::GetInstance()->SetWindowChangeObserver(NULL);
50   }
51
52   if (aura_windows_) {
53     aura_windows_->clear();
54     delete aura_windows_;
55     aura_windows_ = NULL;
56   }
57
58   if (!current_active_window_ ||
59       GetWindowHandle(current_active_window_->window_) != handle ||
60       !open_windows_) {
61      return;
62   }
63
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(
71           windows.front());
72   SetActiveWindow(rootWindow);
73   rootWindow->HandleNativeWidgetActivationChanged(true);
74 }
75
76 void WindowTreeHostDelegateWayland::SetActiveWindow(
77     DesktopWindowTreeHostWayland* dispatcher) {
78   current_active_window_ = dispatcher;
79   current_dispatcher_ = current_active_window_;
80   if (!current_active_window_)
81     return;
82
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);
91   }
92
93   current_active_window_->Activate();
94 }
95
96 DesktopWindowTreeHostWayland*
97 WindowTreeHostDelegateWayland::GetActiveWindow() const {
98   return current_active_window_;
99 }
100
101 void WindowTreeHostDelegateWayland::SetCapture(
102     DesktopWindowTreeHostWayland* dispatcher) {
103   if (current_capture_)
104     current_capture_->OnCaptureReleased();
105
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_;
111 }
112
113 DesktopWindowTreeHostWayland*
114 WindowTreeHostDelegateWayland::GetCurrentCapture() const {
115   return current_capture_;
116 }
117
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());
124     std::transform(
125         windows.begin(), windows.end(), aura_windows_->begin(),
126             DesktopWindowTreeHostWayland::GetContentWindowForAcceleratedWidget);
127   }
128
129   return *aura_windows_;
130 }
131
132 ////////////////////////////////////////////////////////////////////////////////
133 // WindowTreeHostDelegateWayland, Private implementation:
134 void WindowTreeHostDelegateWayland::DispatchMouseEvent(
135          ui::MouseEvent* event) {
136   if (handle_event_)
137     SendEventToProcessor(event);
138   else if (event->type() == ui::ET_MOUSE_PRESSED)
139     SetCapture(NULL);
140
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();
146 }
147
148 std::list<unsigned>&
149 WindowTreeHostDelegateWayland::open_windows() {
150   if (!open_windows_)
151     open_windows_ = new std::list<unsigned>();
152
153   return *open_windows_;
154 }
155
156 unsigned
157 WindowTreeHostDelegateWayland::GetWindowHandle(gfx::AcceleratedWidget widget) {
158   return static_cast<unsigned>(widget);
159 }
160
161 ui::EventProcessor* WindowTreeHostDelegateWayland::GetEventProcessor() {
162   return current_dispatcher_->dispatcher();
163 }
164
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_);
170
171   switch (type) {
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);
178       break;
179     }
180     case ui::ET_KEY_PRESSED: {
181       ui::KeyEvent* keydown_event = static_cast<ui::KeyEvent*>(ne);
182       SendEventToProcessor(keydown_event);
183       break;
184     }
185     case ui::ET_KEY_RELEASED: {
186       ui::KeyEvent* keyup_event = static_cast<ui::KeyEvent*>(ne);
187       SendEventToProcessor(keyup_event);
188       break;
189     }
190     case ui::ET_MOUSEWHEEL: {
191       ui::MouseWheelEvent* wheelev = static_cast<ui::MouseWheelEvent*>(ne);
192       DispatchMouseEvent(wheelev);
193       break;
194     }
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);
203       break;
204     }
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);
210       break;
211     }
212     case ui::ET_UMA_DATA:
213       break;
214     case ui::ET_UNKNOWN:
215       break;
216     default:
217       NOTIMPLEMENTED() << "WindowTreeHostDelegateWayland: unknown event type.";
218   }
219   return POST_DISPATCH_NONE;
220 }
221
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)
231     return;
232
233   // A new window should not steal focus in case the current window has a open
234   // popup.
235   if (current_capture_ && current_capture_ != current_active_window_)
236     return;
237
238   DesktopWindowTreeHostWayland* window = NULL;
239   if (handle)
240     window = DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
241
242   if (!window || window->window_parent_)
243     return;
244
245   current_active_window_->HandleNativeWidgetActivationChanged(false);
246
247   SetActiveWindow(window);
248   window->HandleNativeWidgetActivationChanged(true);
249 }
250
251 void WindowTreeHostDelegateWayland::OnWindowEnter(unsigned handle) {
252   OnWindowFocused(handle);
253 }
254
255 void WindowTreeHostDelegateWayland::OnWindowLeave(unsigned handle) {
256 }
257
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_)
262     return;
263   if (GetWindowHandle(current_capture_->window_) != handle)
264     return;
265   DesktopWindowTreeHostWayland* window = NULL;
266   window = DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
267   window->OnCaptureReleased();
268   window->Close();
269 }
270
271 void WindowTreeHostDelegateWayland::OnWindowResized(unsigned handle,
272                                                     unsigned width,
273                                                     unsigned height) {
274   DesktopWindowTreeHostWayland* window =
275       DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
276   DCHECK(window);
277   window->HandleWindowResize(width, height);
278 }
279
280 }  // namespace views