Upstream version 7.36.149.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 #include "ui/events/platform/platform_event_source.h"
11
12 namespace views {
13
14 WindowTreeHostDelegateWayland::WindowTreeHostDelegateWayland()
15     : current_focus_window_(0),
16       handle_event_(true),
17       stop_propogation_(false),
18       current_dispatcher_(NULL),
19       current_capture_(NULL),
20       current_active_window_(NULL),
21       open_windows_(NULL),
22       aura_windows_(NULL) {
23   if (ui::PlatformEventSource::GetInstance())
24     ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
25   ui::EventFactoryOzoneWayland::GetInstance()->SetWindowChangeObserver(this);
26 }
27
28 WindowTreeHostDelegateWayland::~WindowTreeHostDelegateWayland() {
29 }
30
31 void WindowTreeHostDelegateWayland::OnRootWindowCreated(unsigned handle) {
32   open_windows().push_back(handle);
33
34   if (aura_windows_) {
35     aura_windows_->clear();
36     delete aura_windows_;
37     aura_windows_ = NULL;
38   }
39 }
40
41 void WindowTreeHostDelegateWayland::OnRootWindowClosed(unsigned handle) {
42   open_windows().remove(handle);
43   if (open_windows().empty()) {
44     delete open_windows_;
45     open_windows_ = NULL;
46     SetActiveWindow(NULL);
47
48     ui::PlatformEventSource* event_source =
49         ui::PlatformEventSource::GetInstance();
50     if (event_source)
51       event_source->RemovePlatformEventDispatcher(this);
52     ui::EventFactoryOzoneWayland::GetInstance()->SetWindowChangeObserver(NULL);
53   }
54
55   if (aura_windows_) {
56     aura_windows_->clear();
57     delete aura_windows_;
58     aura_windows_ = NULL;
59   }
60
61   if (!current_active_window_ ||
62       GetWindowHandle(current_active_window_->window_) != handle ||
63       !open_windows_) {
64      return;
65   }
66
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(
74           windows.front());
75   SetActiveWindow(rootWindow);
76   rootWindow->HandleNativeWidgetActivationChanged(true);
77 }
78
79 void WindowTreeHostDelegateWayland::SetActiveWindow(
80     DesktopWindowTreeHostWayland* dispatcher) {
81   current_active_window_ = dispatcher;
82   current_dispatcher_ = current_active_window_;
83   if (!current_active_window_)
84     return;
85
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);
94   }
95
96   current_active_window_->Activate();
97 }
98
99 DesktopWindowTreeHostWayland*
100 WindowTreeHostDelegateWayland::GetActiveWindow() const {
101   return current_active_window_;
102 }
103
104 void WindowTreeHostDelegateWayland::SetCapture(
105     DesktopWindowTreeHostWayland* dispatcher) {
106   if (current_capture_)
107     current_capture_->OnCaptureReleased();
108
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_;
114 }
115
116 DesktopWindowTreeHostWayland*
117 WindowTreeHostDelegateWayland::GetCurrentCapture() const {
118   return current_capture_;
119 }
120
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());
127     std::transform(
128         windows.begin(), windows.end(), aura_windows_->begin(),
129             DesktopWindowTreeHostWayland::GetContentWindowForAcceleratedWidget);
130   }
131
132   return *aura_windows_;
133 }
134
135 ////////////////////////////////////////////////////////////////////////////////
136 // WindowTreeHostDelegateWayland, Private implementation:
137 void WindowTreeHostDelegateWayland::DispatchMouseEvent(
138          ui::MouseEvent* event) {
139   if (handle_event_)
140     SendEventToProcessor(event);
141   else if (event->type() == ui::ET_MOUSE_PRESSED)
142     SetCapture(NULL);
143
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();
149 }
150
151 std::list<unsigned>&
152 WindowTreeHostDelegateWayland::open_windows() {
153   if (!open_windows_)
154     open_windows_ = new std::list<unsigned>();
155
156   return *open_windows_;
157 }
158
159 unsigned
160 WindowTreeHostDelegateWayland::GetWindowHandle(gfx::AcceleratedWidget widget) {
161   return static_cast<unsigned>(widget);
162 }
163
164 ui::EventProcessor* WindowTreeHostDelegateWayland::GetEventProcessor() {
165   return current_dispatcher_->dispatcher();
166 }
167
168 ////////////////////////////////////////////////////////////////////////////////
169 // WindowTreeHostDelegateWayland, ui::PlatformEventDispatcher implementation:
170 bool WindowTreeHostDelegateWayland::CanDispatchEvent(
171     const ui::PlatformEvent& ne) {
172   DCHECK(ne);
173   return true;
174 }
175
176 uint32_t WindowTreeHostDelegateWayland::DispatchEvent(
177     const ui::PlatformEvent& ne) {
178   ui::EventType type = ui::EventTypeFromNative(ne);
179   DCHECK(current_dispatcher_);
180
181   switch (type) {
182     case ui::ET_TOUCH_MOVED:
183     case ui::ET_TOUCH_PRESSED:
184     case ui::ET_TOUCH_CANCELLED:
185     case ui::ET_TOUCH_RELEASED: {
186       ui::TouchEvent* touchev = static_cast<ui::TouchEvent*>(ne);
187       SendEventToProcessor(touchev);
188       break;
189     }
190     case ui::ET_KEY_PRESSED: {
191       ui::KeyEvent* keydown_event = static_cast<ui::KeyEvent*>(ne);
192       SendEventToProcessor(keydown_event);
193       break;
194     }
195     case ui::ET_KEY_RELEASED: {
196       ui::KeyEvent* keyup_event = static_cast<ui::KeyEvent*>(ne);
197       SendEventToProcessor(keyup_event);
198       break;
199     }
200     case ui::ET_MOUSEWHEEL: {
201       ui::MouseWheelEvent* wheelev = static_cast<ui::MouseWheelEvent*>(ne);
202       DispatchMouseEvent(wheelev);
203       break;
204     }
205     case ui::ET_MOUSE_MOVED:
206     case ui::ET_MOUSE_DRAGGED:
207     case ui::ET_MOUSE_PRESSED:
208     case ui::ET_MOUSE_RELEASED:
209     case ui::ET_MOUSE_ENTERED:
210     case ui::ET_MOUSE_EXITED: {
211       ui::MouseEvent* mouseev = static_cast<ui::MouseEvent*>(ne);
212       DispatchMouseEvent(mouseev);
213       break;
214     }
215     case ui::ET_SCROLL_FLING_START:
216     case ui::ET_SCROLL_FLING_CANCEL:
217     case ui::ET_SCROLL: {
218       ui::ScrollEvent* scrollev = static_cast<ui::ScrollEvent*>(ne);
219       SendEventToProcessor(scrollev);
220       break;
221     }
222     case ui::ET_UMA_DATA:
223       break;
224     case ui::ET_UNKNOWN:
225       break;
226     default:
227       NOTIMPLEMENTED() << "WindowTreeHostDelegateWayland: unknown event type.";
228   }
229   return ui::POST_DISPATCH_STOP_PROPAGATION;
230 }
231
232 ////////////////////////////////////////////////////////////////////////////////
233 // DesktopWindowTreeHostWayland, WindowChangeObserver implementation:
234 void WindowTreeHostDelegateWayland::OnWindowFocused(unsigned handle) {
235   current_focus_window_ = handle;
236   // Don't dispatch events in case a window has installed itself as capture
237   // window but doesn't have the focus.
238   handle_event_ = current_capture_ ? current_focus_window_ ==
239           GetWindowHandle(current_capture_->GetAcceleratedWidget()) : true;
240   if (GetWindowHandle(current_active_window_->window_) == handle)
241     return;
242
243   // A new window should not steal focus in case the current window has a open
244   // popup.
245   if (current_capture_ && current_capture_ != current_active_window_)
246     return;
247
248   DesktopWindowTreeHostWayland* window = NULL;
249   if (handle)
250     window = DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
251
252   if (!window || window->window_parent_)
253     return;
254
255   current_active_window_->HandleNativeWidgetActivationChanged(false);
256
257   SetActiveWindow(window);
258   window->HandleNativeWidgetActivationChanged(true);
259 }
260
261 void WindowTreeHostDelegateWayland::OnWindowEnter(unsigned handle) {
262   OnWindowFocused(handle);
263 }
264
265 void WindowTreeHostDelegateWayland::OnWindowLeave(unsigned handle) {
266 }
267
268 void WindowTreeHostDelegateWayland::OnWindowClose(unsigned handle) {
269   // we specially treat grabbed windows in this function, thus the need for
270   // current_capture_ always be a valid pointer.
271   if (!handle || !current_capture_)
272     return;
273   if (GetWindowHandle(current_capture_->window_) != handle)
274     return;
275   DesktopWindowTreeHostWayland* window = NULL;
276   window = DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
277   window->OnCaptureReleased();
278   window->Close();
279 }
280
281 void WindowTreeHostDelegateWayland::OnWindowResized(unsigned handle,
282                                                     unsigned width,
283                                                     unsigned height) {
284   DesktopWindowTreeHostWayland* window =
285       DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
286   DCHECK(window);
287   window->HandleWindowResize(width, height);
288 }
289
290 }  // namespace views