a72903dc1fa2a884d4a4873bd46d47b7c21ac5cc
[platform/framework/web/crosswalk.git] / src / ozone / impl / 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/impl/window_tree_host_delegate_wayland.h"
6
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"
11
12 using namespace ozonewayland;
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   DCHECK(base::MessagePumpOzone::Current());
26   base::MessagePumpOzone::Current()->AddDispatcherForRootWindow(this);
27   EventConverterOzoneWayland::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     DCHECK(base::MessagePumpOzone::Current());
51     base::MessagePumpOzone::Current()->RemoveDispatcherForRootWindow(this);
52     EventConverterOzoneWayland::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_ || current_active_window_->window_ != handle ||
62         !open_windows_) {
63      return;
64   }
65
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(
73           windows.front());
74   SetActiveWindow(rootWindow);
75   rootWindow->HandleNativeWidgetActivationChanged(true);
76 }
77
78 void WindowTreeHostDelegateWayland::SetActiveWindow(
79     DesktopWindowTreeHostWayland* dispatcher) {
80   current_active_window_ = dispatcher;
81   current_dispatcher_ = current_active_window_;
82   if (!current_active_window_)
83     return;
84
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);
93   }
94
95   current_active_window_->Activate();
96 }
97
98 DesktopWindowTreeHostWayland*
99 WindowTreeHostDelegateWayland::GetActiveWindow() const {
100   return current_active_window_;
101 }
102
103 void WindowTreeHostDelegateWayland::SetCapture(
104     DesktopWindowTreeHostWayland* dispatcher) {
105   if (current_capture_)
106     current_capture_->OnCaptureReleased();
107
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_;
113 }
114
115 DesktopWindowTreeHostWayland*
116 WindowTreeHostDelegateWayland::GetCurrentCapture() const {
117   return current_capture_;
118 }
119
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());
126     std::transform(
127         windows.begin(), windows.end(), aura_windows_->begin(),
128             DesktopWindowTreeHostWayland::GetContentWindowForAcceleratedWidget);
129   }
130
131   return *aura_windows_;
132 }
133
134 ////////////////////////////////////////////////////////////////////////////////
135 // WindowTreeHostDelegateWayland, Private implementation:
136 void WindowTreeHostDelegateWayland::DispatchMouseEvent(
137          ui::MouseEvent* event) {
138   if (handle_event_)
139     SendEventToProcessor(event);
140   else if (event->type() == ui::ET_MOUSE_PRESSED)
141     SetCapture(NULL);
142
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();
148 }
149
150 std::list<gfx::AcceleratedWidget>&
151 WindowTreeHostDelegateWayland::open_windows() {
152   if (!open_windows_)
153     open_windows_ = new std::list<gfx::AcceleratedWidget>();
154
155   return *open_windows_;
156 }
157
158 ui::EventProcessor* WindowTreeHostDelegateWayland::GetEventProcessor() {
159   return current_dispatcher_->delegate_->GetEventProcessor();
160 }
161
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_);
167
168   switch (type) {
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);
175       break;
176     }
177     case ui::ET_KEY_PRESSED: {
178       ui::KeyEvent* keydown_event = static_cast<ui::KeyEvent*>(ne);
179       SendEventToProcessor(keydown_event);
180       break;
181     }
182     case ui::ET_KEY_RELEASED: {
183       ui::KeyEvent* keyup_event = static_cast<ui::KeyEvent*>(ne);
184       SendEventToProcessor(keyup_event);
185       break;
186     }
187     case ui::ET_MOUSEWHEEL: {
188       ui::MouseWheelEvent* wheelev = static_cast<ui::MouseWheelEvent*>(ne);
189       DispatchMouseEvent(wheelev);
190       break;
191     }
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);
200       break;
201     }
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);
207       break;
208     }
209     case ui::ET_UMA_DATA:
210       break;
211     case ui::ET_UNKNOWN:
212       break;
213     default:
214       NOTIMPLEMENTED() << "WindowTreeHostDelegateWayland: unknown event type.";
215   }
216   return POST_DISPATCH_NONE;
217 }
218
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)
228     return;
229
230   // A new window should not steal focus in case the current window has a open
231   // popup.
232   if (current_capture_ && current_capture_ != current_active_window_)
233     return;
234
235   DesktopWindowTreeHostWayland* window = NULL;
236   if (handle)
237     window = DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
238
239   if (!window || window->window_parent_)
240     return;
241
242   current_active_window_->HandleNativeWidgetActivationChanged(false);
243
244   SetActiveWindow(window);
245   window->HandleNativeWidgetActivationChanged(true);
246 }
247
248 void WindowTreeHostDelegateWayland::OnWindowEnter(unsigned handle) {
249   OnWindowFocused(handle);
250 }
251
252 void WindowTreeHostDelegateWayland::OnWindowLeave(unsigned handle) {
253 }
254
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_)
259     return;
260   if (current_capture_->window_ != handle)
261     return;
262   DesktopWindowTreeHostWayland* window = NULL;
263   window = DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
264   window->OnCaptureReleased();
265   window->Close();
266 }
267
268 void WindowTreeHostDelegateWayland::OnWindowResized(unsigned handle,
269                                                     unsigned width,
270                                                     unsigned height) {
271   DesktopWindowTreeHostWayland* window =
272       DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
273   DCHECK(window);
274   window->HandleWindowResize(width, height);
275 }
276
277 }  // namespace views