1 // Copyright 2014 Samsung Electronics. 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.
9 #include <ewk_console_message.h>
10 #include <ewk_policy_decision.h>
11 #include <ewk_user_media.h>
12 #include <Elementary.h>
16 #include "window_ui.h"
18 Window::Window(Browser& browser, int width, int height, bool incognito)
20 , is_fullscreen_(false) {
21 window_ = elm_win_util_standard_add("ubrowser", "uBrowser");
22 evas_object_resize(window_, width, height);
23 elm_win_autodel_set(window_, EINA_TRUE);
25 Evas_Object* conform = elm_conformant_add(window_);
26 evas_object_size_hint_weight_set(conform,
29 elm_win_resize_object_add(window_, conform);
30 evas_object_show(conform);
32 Evas_Object *box = elm_box_add(window_);
33 elm_object_content_set(conform, box);
34 evas_object_show(box);
36 ui_ = new WindowUI(*this, browser_);
38 elm_box_pack_end(box, ui_->GetURLBar());
39 evas_object_show(ui_->GetURLBar());
41 Evas* evas = evas_object_evas_get(window_);
43 web_view_ = ewk_view_add_in_incognito_mode(evas);
45 web_view_ = ewk_view_add(evas);
46 evas_object_resize(web_view_, width, height);
47 evas_object_size_hint_align_set(web_view_, EVAS_HINT_FILL, EVAS_HINT_FILL);
48 evas_object_size_hint_weight_set(web_view_, EVAS_HINT_EXPAND,
50 elm_box_pack_end(box, web_view_);
51 evas_object_show(web_view_);
53 elm_box_pack_end(box, ui_->GetNavBar());
54 evas_object_show(ui_->GetNavBar());
56 evas_object_smart_callback_add(web_view_, "title,changed",
57 &Window::OnTitleChanged, this);
58 evas_object_smart_callback_add(web_view_, "url,changed",
59 &Window::OnURLChanged, this);
60 evas_object_smart_callback_add(web_view_, "load,progress,started",
61 &Window::OnLoadStarted, this);
62 evas_object_smart_callback_add(web_view_, "load,progress,finished",
63 &Window::OnLoadFinished, this);
64 evas_object_smart_callback_add(web_view_, "create,window",
65 &Window::OnNewWindowRequest, this);
66 evas_object_smart_callback_add(web_view_, "console,message",
67 &Window::OnConsoleMessage, NULL);
68 evas_object_smart_callback_add(web_view_, "policy,newwindow,decide",
69 &Window::OnNewWindowPolicyDecide, NULL);
70 evas_object_smart_callback_add(web_view_, "back,forward,list,changed",
71 &Window::OnBackForwardListChanged, this);
72 evas_object_smart_callback_add(window_, "delete,request",
73 &Window::OnWindowDelRequest, this);
74 evas_object_smart_callback_add(web_view_, "usermedia,permission,request",
75 &Window::OnUserMediaPermissionRequest, this);
76 evas_object_smart_callback_add(web_view_, "fullscreen,enterfullscreen",
77 &Window::OnEnterFullScreenRequest, this);
78 evas_object_smart_callback_add(web_view_, "fullscreen,exitfullscreen",
79 &Window::OnExitFullScreenRequest, this);
81 ewk_view_quota_permission_request_callback_set(
82 web_view_, &Window::OnQuotaPermissionRequest, this);
84 ewk_settings_form_profile_data_enabled_set(GetEwkSettings(), true);
85 ewk_settings_form_candidate_data_enabled_set(GetEwkSettings(), true);
87 // Auto fit is already turned on for mobile, enable it for "ubrowser --mobile" as well.
88 ewk_settings_auto_fitting_set(GetEwkSettings(), !browser_.IsDesktop());
90 if (elm_win_wm_rotation_supported_get(window_)) {
91 static const int rots[] = {0, 90, 270};
92 elm_win_wm_rotation_available_rotations_set(
93 window_, rots, (sizeof(rots) / sizeof(int)));
94 evas_object_smart_callback_add(window_, "wm,rotation,changed",
95 &Window::OnOrientationChanged, this);
98 EnableMouseEvents(browser_.IsDesktop());
99 EnableTouchEvents(!browser_.IsDesktop());
101 evas_object_show(window_);
106 // deleting view will release context
107 evas_object_del(web_view_);
111 Ewk_Settings* Window::GetEwkSettings() const {
112 return ewk_view_settings_get(web_view_);
115 void Window::LoadURL(std::string url) {
116 const static std::string http = "http://";
117 const static std::string https = "https://";
118 const static std::string file = "file://";
119 const static std::string about = "about:";
120 if (url.compare(0, 1, "/") == 0) {
121 url = "file://" + url;
122 } else if (url.compare(0, http.length(), http) != 0 &&
123 url.compare(0, https.length(), https) != 0 &&
124 url.compare(0, file.length(), file) != 0 &&
125 url.compare(0, about.length(), about) != 0) {
126 url = "http://" + url;
128 log_info("Loading URL: %s", url.c_str());
129 ewk_view_url_set(web_view_, url.c_str());
130 ui_->OnURLChanged(url.c_str());
133 const char* Window::GetURL() const {
134 return ewk_view_url_get(web_view_);
137 void Window::Activate() {
138 log_trace("%s", __PRETTY_FUNCTION__);
139 elm_win_activate(window_);
142 void Window::Close() {
143 log_trace("%s", __PRETTY_FUNCTION__);
144 evas_object_del(window_);
145 browser_.OnWindowDestroyed(Id());
149 void Window::Show() {
150 log_trace("%s", __PRETTY_FUNCTION__);
151 evas_object_show(window_);
154 void Window::Hide() {
155 log_trace("%s", __PRETTY_FUNCTION__);
156 evas_object_hide(window_);
159 void Window::Back() {
160 log_trace("%s", __PRETTY_FUNCTION__);
161 if (is_fullscreen_) {
162 is_fullscreen_ = false;
163 ewk_view_fullscreen_exit(web_view_);
166 ewk_view_back(web_view_);
169 void Window::Forward() {
170 log_trace("%s", __PRETTY_FUNCTION__);
171 ewk_view_forward(web_view_);
174 void Window::Reload() {
175 log_trace("%s", __PRETTY_FUNCTION__);
176 ewk_view_reload(web_view_);
179 void Window::Stop() {
180 log_trace("%s", __PRETTY_FUNCTION__);
181 ewk_view_stop(web_view_);
184 void Window::SetUserAgent(const char* new_ua) {
185 log_trace("%s: %s", __PRETTY_FUNCTION__, new_ua);
186 ewk_view_user_agent_set(web_view_, new_ua);
189 const char* Window::GetUserAgent() const {
190 return ewk_view_user_agent_get(web_view_);
193 void Window::FakeRotate() {
194 log_trace("%s", __PRETTY_FUNCTION__);
195 int x, y, width, height;
196 evas_object_geometry_get(window_, &x, &y, &width, &height);
197 evas_object_move(window_, x, y);
198 evas_object_resize(window_, height, width);
200 ewk_view_orientation_send(web_view_, 0);
202 ewk_view_orientation_send(web_view_, 90);
205 void Window::Resize(int width, int height) {
207 log_trace("%s: %dx%d", __PRETTY_FUNCTION__, width, height);
208 evas_object_geometry_get(window_, &x, &y, 0, 0);
209 evas_object_move(window_, x, y);
210 evas_object_resize(window_, width, height);
211 ewk_view_orientation_send(web_view_, 0);
214 void Window::EnableTouchEvents(bool enable) {
215 log_trace("%s: %d", __PRETTY_FUNCTION__, enable);
216 ewk_view_touch_events_enabled_set(web_view_, enable);
219 void Window::EnableMouseEvents(bool enable) {
220 log_trace("%s: %d", __PRETTY_FUNCTION__, enable);
221 ewk_view_mouse_events_enabled_set(web_view_, enable);
224 bool Window::AreTouchEventsEnabled() const {
225 log_trace("%s", __PRETTY_FUNCTION__);
226 return ewk_view_touch_events_enabled_get(web_view_);
229 bool Window::IsRememberFormDataEnabled() const {
230 log_trace("%s", __PRETTY_FUNCTION__);
231 Ewk_Settings* settings = GetEwkSettings();
232 return ewk_settings_form_candidate_data_enabled_get(settings);
235 bool Window::IsRememberPasswordEnabled() const {
236 log_trace("%s", __PRETTY_FUNCTION__);
237 Ewk_Settings* settings = GetEwkSettings();
238 return ewk_settings_autofill_password_form_enabled_get(settings);
241 bool Window::IsFormProfileEnabled() const {
242 log_trace("%s", __PRETTY_FUNCTION__);
243 Ewk_Settings* settings = GetEwkSettings();
244 return ewk_settings_form_profile_data_enabled_get(settings);
247 double Window::GetScale() const {
248 log_trace("%s", __PRETTY_FUNCTION__);
249 return ewk_view_scale_get(web_view_);
252 void Window::GetScaleRange(double* minScale, double* maxScale) const {
253 log_trace("%s", __PRETTY_FUNCTION__);
254 ewk_view_scale_range_get(web_view_, minScale, maxScale);
257 void Window::SetScale(double scale) {
258 log_trace("%s", __PRETTY_FUNCTION__);
259 ewk_view_scale_set(web_view_, scale, 0, 0);
262 Window::IdType Window::Id() const {
266 void Window::OnEnterFullScreenRequest(void* data, Evas_Object*,
268 log_trace("%s", __PRETTY_FUNCTION__);
269 Window* thiz = static_cast<Window*>(data);
270 thiz->is_fullscreen_ = true;
273 void Window::OnExitFullScreenRequest(void* data, Evas_Object*,
275 log_trace("%s", __PRETTY_FUNCTION__);
276 Window* thiz = static_cast<Window*>(data);
277 thiz->is_fullscreen_ = false;
280 #if defined(OS_TIZEN_TV_PRODUCT)
281 void Window::CreateMouseCursor() {
282 log_trace("%s", __PRETTY_FUNCTION__);
283 #if TIZEN_VERSION_AT_LEAST(5, 0, 0)
284 Ecore_Wl2_Display* wl2_display = ecore_wl2_connected_display_get(NULL);
285 struct wl_display* display = ecore_wl2_display_get(wl2_display);
286 Eina_Iterator* globals = ecore_wl2_display_globals_get(wl2_display);
287 struct wl_registry* registry = ecore_wl2_display_registry_get(wl2_display);
288 struct wl_seat* seat =
289 ecore_wl2_input_seat_get(ecore_wl2_input_default_input_get(wl2_display));
291 Ecore_Wl2_Global* global;
292 EINA_ITERATOR_FOREACH(globals, global) {
293 if (!strcmp(global->interface, "tizen_cursor"))
294 if (!CursorModule_Initialize(display, registry, seat, global->id))
295 log_error("CursorModule_Initialize() Failed!\n");
297 eina_iterator_free(globals);
299 struct wl_surface* const surface =
300 ecore_wl2_window_surface_get(ecore_evas_wayland2_window_get(
301 ecore_evas_ecore_evas_get(evas_object_evas_get(window_))));
304 if (!Cursor_Set_Config(surface, TIZEN_CURSOR_CONFIG_CURSOR_AVAILABLE, NULL))
305 log_error("Cursor_Set_Config() Failed!\n");
306 CursorModule_Finalize();
308 Ecore_Wl_Global* global_data = NULL;
309 unsigned int cursormgr_id = 0;
311 EINA_INLIST_FOREACH(ecore_wl_globals_get(), global_data) {
312 if (0 == strcmp(global_data->interface, "tizen_cursor")) {
313 cursormgr_id = global_data->id; // to get the id of cursormgr object
318 wl_surface* surface =
319 ecore_wl_window_surface_get(elm_win_wl_window_get(window_));
322 int ret_cursormod = CursorModule_Initialize(
323 ecore_wl_display_get(), ecore_wl_registry_get(),
324 ecore_wl_input_seat_get(ecore_wl_input_get()), cursormgr_id);
326 Cursor_Set_Config(surface, TIZEN_CURSOR_CONFIG_CURSOR_AVAILABLE, NULL);
328 CursorModule_Finalize();
329 #endif // TIZEN_VERSION_AT_LEAST(5, 0, 0)
333 void Window::OnUserMediaPermissionRequest(void* data, Evas_Object*,
335 log_trace("%s", __PRETTY_FUNCTION__);
336 Window* thiz = static_cast<Window*>(data);
338 Ewk_User_Media_Permission_Request* permissionRequest =
339 (Ewk_User_Media_Permission_Request*)event_info;
341 ewk_user_media_permission_request_suspend(permissionRequest);
343 thiz->ui_->ShowPermissionPopup(
344 "Media permission request",
345 "Do you want to allow this page to access Media Resources?",
346 OnUserMediaPermissionDecisionTaken,
350 void Window::OnUserMediaPermissionDecisionTaken(bool decision,
352 log_trace("%s", __PRETTY_FUNCTION__);
354 Ewk_User_Media_Permission_Request* permissionRequest =
355 (Ewk_User_Media_Permission_Request*)data;
357 ewk_user_media_permission_request_set(permissionRequest, decision);
360 void Window::OnWindowDelRequest(void* data, Evas_Object*, void*) {
361 Window* thiz = static_cast<Window*>(data);
362 thiz->browser_.OnWindowDestroyed(thiz->Id());
365 void Window::OnNewWindowRequest(void *data, Evas_Object*, void* out_view) {
366 log_trace("%s", __PRETTY_FUNCTION__);
367 Window* thiz = static_cast<Window*>(data);
368 Window& new_window = thiz->browser_.CreateWindow();
369 *static_cast<Evas_Object**>(out_view) = new_window.web_view_;
372 void Window::OnTitleChanged(void *data, Evas_Object *obj, void *arg) {
373 Window* thiz = static_cast<Window*>(data);
374 elm_win_title_set(thiz->window_, static_cast<char*>(arg));
375 log_trace("%s: %s", __PRETTY_FUNCTION__, static_cast<char*>(arg));
376 thiz->browser_.OnWindowTitleChanged(thiz->Id(), static_cast<char *>(arg));
379 void Window::OnURLChanged(void *data, Evas_Object *obj, void *arg) {
380 Window* thiz = static_cast<Window*>(data);
381 log_trace("%s: %s", __PRETTY_FUNCTION__, static_cast<char*>(arg));
382 elm_win_title_set(thiz->window_, static_cast<char*>(arg));
383 thiz->ui_->OnURLChanged(static_cast<char*>(arg));
386 void Window::OnLoadStarted(void* data, Evas_Object*, void*) {
387 Window* thiz = static_cast<Window*>(data);
388 log_trace("%s", __PRETTY_FUNCTION__);
389 thiz->browser_.OnWindowLoadStarted(thiz->Id());
390 thiz->ui_->OnLoadingStarted();
393 void Window::OnLoadFinished(void* data, Evas_Object*, void*) {
394 Window* thiz = static_cast<Window*>(data);
395 log_trace("%s", __PRETTY_FUNCTION__);
396 thiz->browser_.OnWindowLoadFinished(thiz->Id());
397 thiz->ui_->OnLoadingFinished();
400 void Window::OnConsoleMessage(void*, Evas_Object*, void* event_info) {
401 Ewk_Console_Message* msg = static_cast<Ewk_Console_Message*>(event_info);
404 switch (ewk_console_message_level_get(msg)) {
405 case EWK_CONSOLE_MESSAGE_LEVEL_ERROR:
408 case EWK_CONSOLE_MESSAGE_LEVEL_WARNING:
411 case EWK_CONSOLE_MESSAGE_LEVEL_DEBUG:
418 log_message(type, true, "[JS Console] [%s:%d] %s",
419 ewk_console_message_source_get(msg),
420 ewk_console_message_line_get(msg),
421 ewk_console_message_text_get(msg));
424 void Window::OnOrientationChanged(void* data, Evas_Object *obj, void* event) {
425 Window* thiz = static_cast<Window*>(data);
426 log_trace("%s", __PRETTY_FUNCTION__);
428 int rotation = elm_win_rotation_get(thiz->window_);
429 // ewk_view_orientation_send expects angles: 0, 90, -90, 180.
432 ewk_view_orientation_send(thiz->web_view_, rotation);
435 void Window::OnNewWindowPolicyDecide(void*, Evas_Object*, void* policy) {
436 log_trace("%s", __PRETTY_FUNCTION__);
437 Ewk_Policy_Decision *policy_decision = static_cast<Ewk_Policy_Decision*>(policy);
438 const char* url = ewk_policy_decision_url_get(policy_decision);
439 log_info("Allowing new window for: %s", url);
440 ewk_policy_decision_use(policy_decision);
443 void Window::OnBackForwardListChanged(void* data, Evas_Object*, void* policy) {
444 log_trace("%s", __PRETTY_FUNCTION__);
445 Window* thiz = static_cast<Window*>(data);
446 thiz->ui_->EnableBackButton(ewk_view_back_possible(thiz->web_view_));
447 thiz->ui_->EnableForwardButton(ewk_view_forward_possible(thiz->web_view_));
450 void Window::OnQuotaPermissionRequest(Evas_Object*, const Ewk_Quota_Permission_Request* request, void*) {
451 log_trace("%s", __PRETTY_FUNCTION__);
452 ewk_view_quota_permission_request_reply(request, true);
455 void Window::Exit() const {