Upstream version 9.38.204.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 <string>
8
9 #include "ozone/ui/desktop_aura/desktop_window_tree_host_wayland.h"
10 #include "ozone/ui/events/event_factory_ozone_wayland.h"
11 #include "ui/events/event_utils.h"
12 #include "ui/events/platform/platform_event_source.h"
13
14 namespace views {
15
16 WindowTreeHostDelegateWayland::WindowTreeHostDelegateWayland()
17     : current_focus_window_(0),
18       handle_event_(true),
19       stop_propogation_(false),
20       current_dispatcher_(NULL),
21       current_capture_(NULL),
22       current_active_window_(NULL),
23       open_windows_(NULL),
24       aura_windows_(NULL) {
25   if (ui::PlatformEventSource::GetInstance())
26     ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
27   ui::EventFactoryOzoneWayland::GetInstance()->SetWindowChangeObserver(this);
28 }
29
30 WindowTreeHostDelegateWayland::~WindowTreeHostDelegateWayland() {
31 }
32
33 void WindowTreeHostDelegateWayland::OnRootWindowCreated(unsigned handle) {
34   open_windows().push_back(handle);
35
36   if (aura_windows_) {
37     aura_windows_->clear();
38     delete aura_windows_;
39     aura_windows_ = NULL;
40   }
41 }
42
43 void WindowTreeHostDelegateWayland::OnRootWindowClosed(unsigned handle) {
44   open_windows().remove(handle);
45   if (open_windows().empty()) {
46     delete open_windows_;
47     open_windows_ = NULL;
48     SetActiveWindow(NULL);
49
50     ui::PlatformEventSource* event_source =
51         ui::PlatformEventSource::GetInstance();
52     if (event_source)
53       event_source->RemovePlatformEventDispatcher(this);
54     ui::EventFactoryOzoneWayland::GetInstance()->SetWindowChangeObserver(NULL);
55   }
56
57   if (aura_windows_) {
58     aura_windows_->clear();
59     delete aura_windows_;
60     aura_windows_ = NULL;
61   }
62
63   if (!current_active_window_ ||
64       GetWindowHandle(current_active_window_->window_) != handle ||
65       !open_windows_) {
66      return;
67   }
68
69   DCHECK(!current_active_window_->window_parent_);
70   // Set first top level window in the list of open windows as dispatcher.
71   // This is just a guess of the window which would eventually be focussed.
72   // We should set the correct root window as dispatcher in OnWindowFocused.
73   const std::list<unsigned>& windows = open_windows();
74   DesktopWindowTreeHostWayland* rootWindow =
75       DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(
76           windows.front());
77   SetActiveWindow(rootWindow);
78   rootWindow->HandleNativeWidgetActivationChanged(true);
79 }
80
81 void WindowTreeHostDelegateWayland::SetActiveWindow(
82     DesktopWindowTreeHostWayland* dispatcher) {
83   current_active_window_ = dispatcher;
84   current_dispatcher_ = current_active_window_;
85   if (!current_active_window_)
86     return;
87
88   // Make sure the stacking order is correct. The activated window should be
89   // first one in list of open windows.
90   std::list<unsigned>& windows = open_windows();
91   DCHECK(windows.size());
92   unsigned window_handle = current_active_window_->window_;
93   if (windows.front() != window_handle) {
94     windows.remove(window_handle);
95     windows.insert(windows.begin(), window_handle);
96   }
97
98   current_active_window_->Activate();
99 }
100
101 DesktopWindowTreeHostWayland*
102 WindowTreeHostDelegateWayland::GetActiveWindow() const {
103   return current_active_window_;
104 }
105
106 void WindowTreeHostDelegateWayland::SetCapture(
107     DesktopWindowTreeHostWayland* dispatcher) {
108   if (current_capture_)
109     current_capture_->OnCaptureReleased();
110
111   current_capture_ = dispatcher;
112   stop_propogation_ = current_capture_ ? true : false;
113   current_dispatcher_ = current_capture_;
114   if (!current_dispatcher_)
115     current_dispatcher_ = current_active_window_;
116 }
117
118 DesktopWindowTreeHostWayland*
119 WindowTreeHostDelegateWayland::GetCurrentCapture() const {
120   return current_capture_;
121 }
122
123 const std::vector<aura::Window*>&
124 WindowTreeHostDelegateWayland::GetAllOpenWindows() {
125   if (!aura_windows_) {
126     const std::list<unsigned>& windows = open_windows();
127     DCHECK(windows.size());
128     aura_windows_ = new std::vector<aura::Window*>(windows.size());
129     std::transform(
130         windows.begin(), windows.end(), aura_windows_->begin(),
131             DesktopWindowTreeHostWayland::GetContentWindowForAcceleratedWidget);
132   }
133
134   return *aura_windows_;
135 }
136
137 ////////////////////////////////////////////////////////////////////////////////
138 // WindowTreeHostDelegateWayland, Private implementation:
139 void WindowTreeHostDelegateWayland::DispatchMouseEvent(
140          ui::MouseEvent* event) {
141   if (handle_event_)
142     SendEventToProcessor(event);
143   else if (event->type() == ui::ET_MOUSE_PRESSED)
144     SetCapture(NULL);
145
146   // Stop event propogation as this window is acting as event grabber. All
147   // event's we create are "cancelable". If in future we use events that are not
148   // cancelable, then a check for cancelable events needs to be added here.
149   if (stop_propogation_)
150     event->StopPropagation();
151 }
152
153 std::list<unsigned>&
154 WindowTreeHostDelegateWayland::open_windows() {
155   if (!open_windows_)
156     open_windows_ = new std::list<unsigned>();
157
158   return *open_windows_;
159 }
160
161 unsigned
162 WindowTreeHostDelegateWayland::GetWindowHandle(gfx::AcceleratedWidget widget) {
163   return static_cast<unsigned>(widget);
164 }
165
166 ui::EventProcessor* WindowTreeHostDelegateWayland::GetEventProcessor() {
167   return current_dispatcher_->dispatcher();
168 }
169
170 ////////////////////////////////////////////////////////////////////////////////
171 // WindowTreeHostDelegateWayland, ui::PlatformEventDispatcher implementation:
172 bool WindowTreeHostDelegateWayland::CanDispatchEvent(
173     const ui::PlatformEvent& ne) {
174   DCHECK(ne);
175   return true;
176 }
177
178 uint32_t WindowTreeHostDelegateWayland::DispatchEvent(
179     const ui::PlatformEvent& ne) {
180   ui::EventType type = ui::EventTypeFromNative(ne);
181   DCHECK(current_dispatcher_);
182
183   switch (type) {
184     case ui::ET_TOUCH_MOVED:
185     case ui::ET_TOUCH_PRESSED:
186     case ui::ET_TOUCH_CANCELLED:
187     case ui::ET_TOUCH_RELEASED: {
188       ui::TouchEvent* touchev = static_cast<ui::TouchEvent*>(ne);
189       SendEventToProcessor(touchev);
190       break;
191     }
192     case ui::ET_KEY_PRESSED: {
193       ui::KeyEvent* keydown_event = static_cast<ui::KeyEvent*>(ne);
194       SendEventToProcessor(keydown_event);
195       break;
196     }
197     case ui::ET_KEY_RELEASED: {
198       ui::KeyEvent* keyup_event = static_cast<ui::KeyEvent*>(ne);
199       SendEventToProcessor(keyup_event);
200       break;
201     }
202     case ui::ET_MOUSEWHEEL: {
203       ui::MouseWheelEvent* wheelev = static_cast<ui::MouseWheelEvent*>(ne);
204       DispatchMouseEvent(wheelev);
205       break;
206     }
207     case ui::ET_MOUSE_MOVED:
208     case ui::ET_MOUSE_DRAGGED:
209     case ui::ET_MOUSE_PRESSED:
210     case ui::ET_MOUSE_RELEASED:
211     case ui::ET_MOUSE_ENTERED:
212     case ui::ET_MOUSE_EXITED: {
213       ui::MouseEvent* mouseev = static_cast<ui::MouseEvent*>(ne);
214       DispatchMouseEvent(mouseev);
215       break;
216     }
217     case ui::ET_SCROLL_FLING_START:
218     case ui::ET_SCROLL_FLING_CANCEL:
219     case ui::ET_SCROLL: {
220       ui::ScrollEvent* scrollev = static_cast<ui::ScrollEvent*>(ne);
221       SendEventToProcessor(scrollev);
222       break;
223     }
224     case ui::ET_UMA_DATA:
225       break;
226     case ui::ET_UNKNOWN:
227       break;
228     default:
229       NOTIMPLEMENTED() << "WindowTreeHostDelegateWayland: unknown event type.";
230   }
231   return ui::POST_DISPATCH_STOP_PROPAGATION;
232 }
233
234 ////////////////////////////////////////////////////////////////////////////////
235 // DesktopWindowTreeHostWayland, WindowChangeObserver implementation:
236 void WindowTreeHostDelegateWayland::OnWindowFocused(unsigned handle) {
237   current_focus_window_ = handle;
238   // Don't dispatch events in case a window has installed itself as capture
239   // window but doesn't have the focus.
240   handle_event_ = current_capture_ ? current_focus_window_ ==
241           GetWindowHandle(current_capture_->GetAcceleratedWidget()) : true;
242   if (GetWindowHandle(current_active_window_->window_) == handle)
243     return;
244
245   // A new window should not steal focus in case the current window has a open
246   // popup.
247   if (current_capture_ && current_capture_ != current_active_window_)
248     return;
249
250   DesktopWindowTreeHostWayland* window = NULL;
251   if (handle)
252     window = DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
253
254   if (!window || window->window_parent_)
255     return;
256
257   current_active_window_->HandleNativeWidgetActivationChanged(false);
258
259   SetActiveWindow(window);
260   window->HandleNativeWidgetActivationChanged(true);
261 }
262
263 void WindowTreeHostDelegateWayland::OnWindowEnter(unsigned handle) {
264   OnWindowFocused(handle);
265 }
266
267 void WindowTreeHostDelegateWayland::OnWindowLeave(unsigned handle) {
268 }
269
270 void WindowTreeHostDelegateWayland::OnWindowClose(unsigned handle) {
271   // we specially treat grabbed windows in this function, thus the need for
272   // current_capture_ always be a valid pointer.
273   if (!handle || !current_capture_)
274     return;
275   if (GetWindowHandle(current_capture_->window_) != handle)
276     return;
277   DesktopWindowTreeHostWayland* window = NULL;
278   window = DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
279   window->OnCaptureReleased();
280   window->Close();
281 }
282
283 void WindowTreeHostDelegateWayland::OnWindowResized(unsigned handle,
284                                                     unsigned width,
285                                                     unsigned height) {
286   DesktopWindowTreeHostWayland* window =
287       DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
288   DCHECK(window);
289   window->HandleWindowResize(width, height);
290 }
291
292 void WindowTreeHostDelegateWayland::OnWindowUnminimized(unsigned handle) {
293   DesktopWindowTreeHostWayland* window =
294       DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
295   DCHECK(window);
296   window->HandleWindowUnminimized();
297 }
298
299 void WindowTreeHostDelegateWayland::OnCommit(unsigned handle,
300                                              const std::string& text) {
301   DesktopWindowTreeHostWayland* window =
302       DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
303   DCHECK(window);
304   window->HandleCommit(text);
305 }
306
307 void WindowTreeHostDelegateWayland::OnPreeditChanged(unsigned handle,
308                                                    const std::string& text,
309                                                    const std::string& commit) {
310   DesktopWindowTreeHostWayland* window =
311       DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
312   DCHECK(window);
313   window->HandlePreeditChanged(text, commit);
314 }
315
316 }  // namespace views