Upstream version 6.34.113.0
[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_ ||
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_->delegate_->GetEventProcessor();
166 }
167
168 ////////////////////////////////////////////////////////////////////////////////
169 // WindowTreeHostDelegateWayland, MessagePumpDispatcher implementation:
170 uint32_t WindowTreeHostDelegateWayland::Dispatch(const base::NativeEvent& ne) {
171   ui::EventType type = ui::EventTypeFromNative(ne);
172   DCHECK(current_dispatcher_);
173
174   switch (type) {
175     case ui::ET_TOUCH_MOVED:
176     case ui::ET_TOUCH_PRESSED:
177     case ui::ET_TOUCH_CANCELLED:
178     case ui::ET_TOUCH_RELEASED: {
179       ui::TouchEvent* touchev = static_cast<ui::TouchEvent*>(ne);
180       SendEventToProcessor(touchev);
181       break;
182     }
183     case ui::ET_KEY_PRESSED: {
184       ui::KeyEvent* keydown_event = static_cast<ui::KeyEvent*>(ne);
185       SendEventToProcessor(keydown_event);
186       break;
187     }
188     case ui::ET_KEY_RELEASED: {
189       ui::KeyEvent* keyup_event = static_cast<ui::KeyEvent*>(ne);
190       SendEventToProcessor(keyup_event);
191       break;
192     }
193     case ui::ET_MOUSEWHEEL: {
194       ui::MouseWheelEvent* wheelev = static_cast<ui::MouseWheelEvent*>(ne);
195       DispatchMouseEvent(wheelev);
196       break;
197     }
198     case ui::ET_MOUSE_MOVED:
199     case ui::ET_MOUSE_DRAGGED:
200     case ui::ET_MOUSE_PRESSED:
201     case ui::ET_MOUSE_RELEASED:
202     case ui::ET_MOUSE_ENTERED:
203     case ui::ET_MOUSE_EXITED: {
204       ui::MouseEvent* mouseev = static_cast<ui::MouseEvent*>(ne);
205       DispatchMouseEvent(mouseev);
206       break;
207     }
208     case ui::ET_SCROLL_FLING_START:
209     case ui::ET_SCROLL_FLING_CANCEL:
210     case ui::ET_SCROLL: {
211       ui::ScrollEvent* scrollev = static_cast<ui::ScrollEvent*>(ne);
212       SendEventToProcessor(scrollev);
213       break;
214     }
215     case ui::ET_UMA_DATA:
216       break;
217     case ui::ET_UNKNOWN:
218       break;
219     default:
220       NOTIMPLEMENTED() << "WindowTreeHostDelegateWayland: unknown event type.";
221   }
222   return POST_DISPATCH_NONE;
223 }
224
225 ////////////////////////////////////////////////////////////////////////////////
226 // DesktopWindowTreeHostWayland, WindowChangeObserver implementation:
227 void WindowTreeHostDelegateWayland::OnWindowFocused(unsigned handle) {
228   current_focus_window_ = handle;
229   // Don't dispatch events in case a window has installed itself as capture
230   // window but doesn't have the focus.
231   handle_event_ = current_capture_ ? current_focus_window_ ==
232           GetWindowHandle(current_capture_->GetAcceleratedWidget()) : true;
233   if (GetWindowHandle(current_active_window_->window_) == handle)
234     return;
235
236   // A new window should not steal focus in case the current window has a open
237   // popup.
238   if (current_capture_ && current_capture_ != current_active_window_)
239     return;
240
241   DesktopWindowTreeHostWayland* window = NULL;
242   if (handle)
243     window = DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
244
245   if (!window || window->window_parent_)
246     return;
247
248   current_active_window_->HandleNativeWidgetActivationChanged(false);
249
250   SetActiveWindow(window);
251   window->HandleNativeWidgetActivationChanged(true);
252 }
253
254 void WindowTreeHostDelegateWayland::OnWindowEnter(unsigned handle) {
255   OnWindowFocused(handle);
256 }
257
258 void WindowTreeHostDelegateWayland::OnWindowLeave(unsigned handle) {
259 }
260
261 void WindowTreeHostDelegateWayland::OnWindowClose(unsigned handle) {
262   // we specially treat grabbed windows in this function, thus the need for
263   // current_capture_ always be a valid pointer.
264   if (!handle || !current_capture_)
265     return;
266   if (GetWindowHandle(current_capture_->window_) != handle)
267     return;
268   DesktopWindowTreeHostWayland* window = NULL;
269   window = DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
270   window->OnCaptureReleased();
271   window->Close();
272 }
273
274 void WindowTreeHostDelegateWayland::OnWindowResized(unsigned handle,
275                                                     unsigned width,
276                                                     unsigned height) {
277   DesktopWindowTreeHostWayland* window =
278       DesktopWindowTreeHostWayland::GetHostForAcceleratedWidget(handle);
279   DCHECK(window);
280   window->HandleWindowResize(width, height);
281 }
282
283 }  // namespace views