1 // Copyright 2015 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.
5 #include "wrt/src/browser/wrt_native_window.h"
8 #include <Elementary.h>
10 #include <efl_extension.h>
13 #include "base/base_switches.h"
14 #include "base/command_line.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
17 #include "content/browser/web_contents/web_contents_impl.h"
18 #include "content/browser/web_contents/web_contents_view_aura.h"
19 #include "content/public/browser/navigation_controller.h"
20 #include "content/public/browser/render_frame_host.h"
21 #include "content/public/browser/render_view_host.h"
22 #include "electron/shell/browser/window_list.h"
23 #include "electron/shell/common/gin_helper/dictionary.h"
24 #include "electron/shell/common/options_switches.h"
25 #include "tizen_src/chromium_impl/efl/window_factory.h"
26 #include "tizen_src/chromium_impl/tizen/system_info.h"
27 #include "ui/compositor/compositor_observer_efl.h"
28 #include "ui/display/screen.h"
29 #include "ui/gfx/geometry/rect.h"
30 #include "ui/gfx/geometry/size.h"
31 #include "ui/gfx/image/image.h"
32 #include "wrt/src/browser/splash_screen.h"
33 #include "wrt/src/browser/wrt_frame_view.h"
34 #include "wrt/src/browser/wrt_native_widget.h"
35 #include "wrt/src/browser/wrt_native_window_off_screen.h"
36 #include "wrt/src/browser/wrt_native_window_on_screen.h"
37 #include "wrt/src/browser/wrt_web_contents.h"
38 #include "wrt/src/browser/wrt_window_tree_host.h"
39 #include "wrt/src/common/application_data.h"
40 #include "wrt/src/common/wrt_profile_delegate.h"
42 #if defined(TIZEN_ATK_SUPPORT)
43 #include "tizen_src/ewk/efl_integration/eweb_accessibility.h"
44 #include "tizen_src/ewk/efl_integration/eweb_accessibility_util.h"
47 #if BUILDFLAG(IS_TIZEN_TV)
48 #include "wrt/src/browser/tv/wrt_native_window_tv.h"
50 using WRTNativeWindowType = wrt::WRTNativeWindowTV;
52 using WRTNativeWindowType = wrt::WRTNativeWindow;
59 const char* kBackKeyEventScript =
61 "var __event = document.createEvent(\"CustomEvent\");\n"
62 "__event.initCustomEvent(\"tizenhwkey\", true, true, null);\n"
63 "__event.keyName = \"back\";\n"
64 "document.dispatchEvent(__event);\n"
66 "for (var i=0; i < window.frames.length; i++)\n"
67 "{ window.frames[i].document.dispatchEvent(__event); }"
69 const char* kMenuKeyEventScript =
71 "var __event = document.createEvent(\"CustomEvent\");\n"
72 "__event.initCustomEvent(\"tizenhwkey\", true, true, null);\n"
73 "__event.keyName = \"menu\";\n"
74 "document.dispatchEvent(__event);\n"
76 "for (var i=0; i < window.frames.length; i++)\n"
77 "{ window.frames[i].document.dispatchEvent(__event); }"
80 const int kPortraitNaturalAngle[] = {
81 0, // PORTRAIT_PRIMARY
82 180, // PORTRAIT_SECONDARY
83 270, // LANDSCAPE_PRIMARY
84 90, // LANDSCAPE_SECONDARY
89 const int kLandscapeNaturalAngle[] = {
90 90, // PORTRAIT_PRIMARY
91 270, // PORTRAIT_SECONDARY
92 0, // LANDSCAPE_PRIMARY
93 180, // LANDSCAPE_SECONDARY
98 #if !BUILDFLAG(IS_TIZEN_TV)
99 const char* kFileScheme = "file";
100 const std::string kViewmodeTypeWindowed = "windowed";
103 std::unique_ptr<WRTNativeWindowDelegate> native_window_delegate;
104 bool use_onscreen_rendering = true;
105 Ecore_Evas* platform_canvas = nullptr;
107 Ecore_Event_Handler* visibility_handler_ = nullptr;
110 int rotation_degree = 0;
112 void AddVisibilityEventListener() {
113 LOG(INFO) << "Add event listener for visibility change";
114 #if TIZEN_VERSION_AT_LEAST(7, 0, 0)
115 // From Tizen 7.0, EFL supports 'ecore_wl2_window_visibility_callback_set'
116 // to notify visibility change status early than ecore event.
117 // This callback is invoked at '_tizen_visibility_cb_notify' when wayland IPC
119 auto visibility_callback = [](void* user_data, Ecore_Wl2_Window* win,
120 Eina_Bool visibility) {
121 /* It's fundamental to send visibility events to the latest created
122 page, to retain compatibility and for passing "Page Visibility Test"
123 in tct-behavior tests */
124 auto* native_window = WRTNativeWindow::GetActiveNativeWindow();
126 native_window->IsSameWindowId(ecore_wl2_window_id_get(win))) {
127 native_window->SetPageVisibility(visibility == EINA_TRUE);
129 LOG(ERROR) << "Window " << ecore_wl2_window_id_get(win)
130 << " visibility is changed, but it's not app window("
131 << WRTNativeWindow::GetTopWindow() << "), so skip";
135 Ecore_Wl2_Window* wl_window = ecore_evas_wayland2_window_get(platform_canvas);
136 ecore_wl2_window_visibility_callback_set(wl_window, visibility_callback,
139 auto visibility_callback = [](void* user_data,
141 void* event) -> Eina_Bool {
142 if (!event || electron::WindowList::IsEmpty())
143 return ECORE_CALLBACK_PASS_ON;
145 auto* ev = static_cast<Ecore_Wl2_Event_Window_Visibility_Change*>(event);
146 /* It's fundamental to send visibility events to the latest created
147 page, to retain compatibility and for passing "Page Visibility Test"
148 in tct-behavior tests */
149 auto* native_window = WRTNativeWindow::GetActiveNativeWindow();
150 if (native_window && native_window->IsSameWindowId(ev->win)) {
151 native_window->SetPageVisibility(!ev->fully_obscured);
153 LOG(ERROR) << "Window " << ev->win
154 << " visibility is changed, but it's not app window("
155 << WRTNativeWindow::GetTopWindow() << "), so skip";
158 return ECORE_CALLBACK_PASS_ON;
160 // 'prepend' will add to beginning of handler list
161 visibility_handler_ = ecore_event_handler_prepend(
162 ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, visibility_callback, nullptr);
166 int GetRotationDegree(WRTNativeWindow::ScreenOrientation orientation) {
167 auto display_size = display::Screen::GetScreen()->GetPrimaryDisplay().size();
168 WRTNativeWindow::ScreenOrientation natural_orientation;
169 if (display_size.width() > display_size.height())
170 natural_orientation = WRTNativeWindow::ScreenOrientation::LANDSCAPE_PRIMARY;
172 natural_orientation = WRTNativeWindow::ScreenOrientation::PORTRAIT_PRIMARY;
174 if (natural_orientation ==
175 WRTNativeWindow::ScreenOrientation::PORTRAIT_PRIMARY)
176 return kPortraitNaturalAngle[static_cast<int>(orientation)];
178 return kLandscapeNaturalAngle[static_cast<int>(orientation)];
181 void EnableManualRotation(bool enable) {
182 ecore_evas_wm_rotation_manual_rotation_done_set(
183 platform_canvas, enable ? EINA_TRUE : EINA_FALSE);
186 content::WebContents::Getter GetWebContentsGetter(
187 content::WebContents* web_contents) {
188 // Use the FrameTreeNode ID to get the WebContents
189 int frame_tree_node_id =
190 web_contents->GetPrimaryMainFrame()->GetFrameTreeNodeId();
191 if (frame_tree_node_id != content::RenderFrameHost::kNoFrameTreeNodeId) {
192 return base::BindRepeating(content::WebContents::FromFrameTreeNodeId,
196 // Use the RenderProcessHostID and RenderFrameHost ID to get the WebContents
197 content::RenderFrameHost* render_frame_host =
198 content::RenderFrameHost::FromID(
199 web_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
200 web_contents->GetPrimaryMainFrame()->GetRoutingID());
201 if (render_frame_host) {
202 return base::BindRepeating(content::WebContents::FromRenderFrameHost,
206 return base::BindRepeating([]() -> content::WebContents* { return nullptr; });
212 WRTNativeWindow* WRTNativeWindow::GetMainNativeWindow() {
213 return electron::WindowList::IsEmpty()
215 : static_cast<WRTNativeWindow*>(
216 electron::WindowList::GetWindows().front());
220 WRTNativeWindow* WRTNativeWindow::GetActiveNativeWindow() {
221 return electron::WindowList::IsEmpty()
223 : static_cast<WRTNativeWindow*>(
224 electron::WindowList::GetWindows().back());
228 void WRTNativeWindow::EnsurePlatformWindow() {
229 if (!native_window_delegate) {
230 use_onscreen_rendering =
231 !base::CommandLine::ForCurrentProcess()->HasSwitch(
232 switches::kEnableOffscreenRendering);
233 LOG(INFO) << "Use " << (use_onscreen_rendering ? "onscreen" : "offscreen")
234 << " rendering mode";
235 if (use_onscreen_rendering) {
236 native_window_delegate = std::make_unique<WRTNativeWindowOnScreen>();
238 native_window_delegate = std::make_unique<WRTNativeWindowOffScreen>();
241 auto* window = native_window_delegate->GetWindowEvasObject();
242 platform_canvas = ecore_evas_ecore_evas_get(evas_object_evas_get(window));
246 Evas_Object* WRTNativeWindow::GetHostWindowDelegate(
247 const content::WebContents* web_contents) {
248 if (native_window_delegate)
249 return native_window_delegate->GetWindowEvasObject();
255 Evas_Object* WRTNativeWindow::GetTopWindow() {
256 if (native_window_delegate)
257 return native_window_delegate->GetTopWindow();
263 Evas_Object* WRTNativeWindow::GetConformant() {
264 if (native_window_delegate)
265 return native_window_delegate->GetConformant();
271 Ecore_Evas* WRTNativeWindow::GetPlatformCanvas() {
272 return platform_canvas;
276 WRTNativeWindow* WRTNativeWindow::FromWebContents(
277 const content::WebContents* web_contents) {
278 for (const auto& it : electron::WindowList::GetWindows()) {
279 auto window = static_cast<WRTNativeWindow*>(it);
280 if (window->web_contents_ == web_contents)
287 void WRTNativeWindow::HidePlatformWindow() {
288 native_window_delegate->Hide();
292 bool WRTNativeWindow::UseOnscreenRendering() {
293 return use_onscreen_rendering;
297 WRTNativeWindowDelegate* WRTNativeWindow::GetNativeWindowDelegate() {
298 return native_window_delegate.get();
302 void WRTNativeWindow::InitializePlatformEventListeners() {
303 AddVisibilityEventListener();
305 #if !BUILDFLAG(IS_TIZEN_TV)
306 AddEditorClientEventListeners();
309 auto window = native_window_delegate->GetTopWindow();
310 eext_object_event_callback_add(window, EEXT_CALLBACK_BACK, &OnHWBackKey,
312 // Custom event 'tizenhwkey' for 'menu' key is sent
313 // only when hwkey is enabled in config.xml as per specs
314 if (ApplicationData::GetInstance().setting_info().hwkey_enabled()) {
315 eext_object_event_callback_add(window, EEXT_CALLBACK_MORE, &OnHWMoreKey,
319 if (IsWearableProfile())
320 AddRotaryEventListener();
326 void WRTNativeWindow::CleanupPlatformEventListeners() {
327 auto window = native_window_delegate->GetTopWindow();
328 eext_object_event_callback_del(window, EEXT_CALLBACK_BACK, &OnHWBackKey);
329 if (ApplicationData::GetInstance().setting_info().hwkey_enabled())
330 eext_object_event_callback_del(window, EEXT_CALLBACK_MORE, &OnHWMoreKey);
332 if (visibility_handler_)
333 ecore_event_handler_del(visibility_handler_);
334 visibility_handler_ = nullptr;
338 void WRTNativeWindow::AddEditorClientEventListeners() {
339 auto window = native_window_delegate->GetTopWindow();
340 auto ime_changed_callback = [](void*, Evas_Object*, void* event_info) {
341 Eina_Rectangle* rect = static_cast<Eina_Rectangle*>(event_info);
343 ime_height = rect->h;
345 evas_object_smart_callback_add(window, "inputmethod,changed",
346 ime_changed_callback, nullptr);
348 auto ime_opened_callback = [](void*, Evas_Object*, void* event_info) {
349 WRTNativeWindow* native_window = GetActiveNativeWindow();
351 native_window->OnSoftKeyboardChangeEvent(true);
353 evas_object_smart_callback_add(window, "editorclient,ime,opened",
354 ime_opened_callback, nullptr);
356 auto ime_closed_callback = [](void*, Evas_Object*, void* event_info) {
357 WRTNativeWindow* native_window = GetActiveNativeWindow();
359 native_window->OnSoftKeyboardChangeEvent(false);
361 evas_object_smart_callback_add(window, "editorclient,ime,closed",
362 ime_closed_callback, nullptr);
366 void WRTNativeWindow::AddRotaryEventListener() {
367 auto rotary_callback = [](void*, Evas_Object*,
368 Eext_Rotary_Event_Info* event_info) -> Eina_Bool {
369 for (const auto& it : electron::WindowList::GetWindows()) {
370 auto window = static_cast<WRTNativeWindow*>(it);
371 Eext_Rotary_Event_Info* rotary = event_info;
372 RotaryEventType type;
373 if (rotary->direction == EEXT_ROTARY_DIRECTION_CLOCKWISE)
374 type = RotaryEventType::CLOCKWISE;
376 type = RotaryEventType::COUNTER_CLOCKWISE;
377 window->OnRotaryEvent(type);
382 auto window = native_window_delegate->GetTopWindow();
383 eext_rotary_object_event_callback_add(window, rotary_callback, nullptr);
384 eext_rotary_object_event_activated_set(window, EINA_TRUE);
388 void WRTNativeWindow::RotationCallback() {
389 auto rotation = ecore_evas_rotation_get(platform_canvas);
390 if (rotation_degree != rotation) {
391 rotation_degree = rotation;
392 for (const auto& it : electron::WindowList::GetWindows()) {
393 auto window = static_cast<WRTNativeWindow*>(it);
394 window->OnRotation(rotation_degree);
400 void WRTNativeWindow::InitRotation() {
401 native_window_delegate->InitRotation();
403 if (!WRTNativeWindowType::SetRotation()) {
404 auto& setting_info = ApplicationData::GetInstance().setting_info();
405 if (setting_info.screen_orientation() ==
406 wgt::parse::SettingInfo::ScreenOrientation::AUTO) {
407 LOG(INFO) << "ScreenOrientation is AUTO";
408 SetRotationState(true);
409 } else if (setting_info.screen_orientation() ==
410 wgt::parse::SettingInfo::ScreenOrientation::PORTRAIT) {
411 LOG(INFO) << "ScreenOrientation is PORTRAIT_PRIMARY";
413 false, GetRotationDegree(ScreenOrientation::PORTRAIT_PRIMARY));
414 } else if (setting_info.screen_orientation() ==
415 wgt::parse::SettingInfo::ScreenOrientation::LANDSCAPE) {
416 LOG(INFO) << "ScreenOrientation is LANDSCAPE_PRIMARY";
418 false, GetRotationDegree(ScreenOrientation::LANDSCAPE_PRIMARY));
422 if (IsMobileProfile())
423 EnableManualRotation(true);
427 void WRTNativeWindow::SetRotationState(bool is_auto, int degree) {
428 rotation_degree = native_window_delegate->SetRotationState(is_auto, degree);
432 void WRTNativeWindow::OnHWBackKey(void*, Evas_Object*, void*) {
433 if (electron::WindowList::IsEmpty()) {
434 LOG(INFO) << "no window, so not handle back key";
438 // TODO: We need to consider to clear selection or exit fullscreen
439 // before send JS custom event.
440 auto* native_window = GetActiveNativeWindow();
444 auto* web_contents = native_window->GetWebContents();
448 auto& app_data = ApplicationData::GetInstance();
449 bool hwkey_enabled = app_data.setting_info().hwkey_enabled();
451 content::RenderFrameHost* rfh = web_contents->GetPrimaryMainFrame();
453 rfh->ExecuteJavaScriptWithUserGestureForTests(
454 base::UTF8ToUTF16(kBackKeyEventScript), base::NullCallback());
457 if (IsWearableProfile() && native_window->IsFullscreen()) {
458 native_window->web_contents_->ExitFullscreen(false);
463 #if !BUILDFLAG(IS_TIZEN_TV)
464 // NOTE: This code is added
465 // 1. to enable back-key on remote URL
466 // 2. for backward compatibility. If the 'backbutton_presence' is true,
467 // WebContents should be navigated back.
468 std::string scheme = web_contents->GetURL().scheme();
469 bool backward_support =
470 app_data.setting_info().backbutton_presence() ||
471 app_data.widget_info().view_modes() == kViewmodeTypeWindowed;
472 if (scheme != kFileScheme || (hwkey_enabled && backward_support)) {
473 if (web_contents->GetController().CanGoBack())
474 web_contents->GetController().GoBack();
476 native_window->Close();
482 void WRTNativeWindow::OnHWMoreKey(void*, Evas_Object*, void*) {
483 if (electron::WindowList::IsEmpty()) {
484 LOG(INFO) << "no window, so not handle more key";
488 if (!GetActiveNativeWindow() ||
489 !GetActiveNativeWindow()->GetRenderFrameHost()) {
493 auto* rfh = GetActiveNativeWindow()->GetRenderFrameHost();
494 rfh->ExecuteJavaScriptWithUserGestureForTests(
495 base::UTF8ToUTF16(kMenuKeyEventScript), base::NullCallback());
498 WRTNativeWindow::WRTNativeWindow(const gin_helper::Dictionary& options,
499 electron::NativeWindow* parent)
500 : electron::NativeWindow(options, parent),
501 is_main_native_window_(electron::WindowList::GetWindows().size() == 1),
502 web_contents_(nullptr),
503 fullscreenable_(true),
504 visibility_status_(false) {
505 LOG(INFO) << "WRTNativeWindow[" << this << "] create";
506 if (is_main_native_window_) {
507 EnsurePlatformWindow();
508 InitializePlatformEventListeners();
509 // TODO: Find a way to avoid using elementary
510 elm_app_name_set(ApplicationData::GetInstance().app_id().c_str());
512 options.Get(electron::options::kTitle, &title_);
514 auto* host = GetWindowTreeHost();
515 gfx::Rect bounds = host->window()->bounds();
516 views::Widget::InitParams params;
517 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
518 params.bounds = bounds;
519 params.delegate = this;
520 params.type = views::Widget::InitParams::TYPE_WINDOW;
521 params.remove_standard_frame = !has_frame();
522 params.native_widget = new WRTNativeWidget(widget(), host);
523 params.parent = host->window();
526 params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent;
528 widget()->Init(std::move(params));
531 WRTNativeWindow::~WRTNativeWindow() {
532 LOG(INFO) << "WRTNativeWindow[" << this << "] start to destroy";
534 if (is_main_native_window_) {
535 HidePlatformWindow();
536 CleanupPlatformEventListeners();
537 native_window_delegate->OnNativeWindowDestroyed(this);
538 native_window_delegate.reset();
540 native_window_delegate->OnNativeWindowDestroyed(this);
542 #if defined(TIZEN_ATK_SUPPORT)
543 EWebAccessibilityUtil::GetInstance()->SetEWebAccessibility(nullptr);
547 void WRTNativeWindow::SetWebContents(content::WebContents* web_contents) {
549 LOG(ERROR) << "Try to initialize multiple times";
553 web_contents_ = web_contents;
554 OnRotation(rotation_degree);
556 auto window = native_window_delegate->GetTopWindow();
557 static_cast<content::WebContentsImpl*>(web_contents_)->set_ewk_view(window);
559 #if defined(TIZEN_ATK_SUPPORT)
560 wrt_accessibility_.reset(
561 new EWebAccessibility(window, web_contents_, nullptr));
563 EWebAccessibilityUtil::GetInstance()->SetEWebAccessibility(
564 wrt_accessibility_.get());
568 content::WebContents* WRTNativeWindow::GetWebContents() {
569 CHECK(web_contents_) << "Fail to get web contents";
570 return web_contents_;
573 WRTWindowTreeHost* WRTNativeWindow::GetWindowTreeHost() {
574 return native_window_delegate->GetWindowTreeHost(this);
577 content::RenderFrameHost* WRTNativeWindow::GetRenderFrameHost() {
578 if (GetWebContents())
579 return GetWebContents()->GetPrimaryMainFrame();
583 content::WebContentsViewAura* WRTNativeWindow::GetWebContentsViewAura() {
584 auto* wc = static_cast<content::WebContentsImpl*>(GetWebContents());
585 return static_cast<content::WebContentsViewAura*>(wc->GetView());
588 content::RenderWidgetHostViewAura* WRTNativeWindow::GetRenderWidgetHostView() {
589 if (GetWebContents())
590 return static_cast<content::RenderWidgetHostViewAura*>(
591 GetWebContents()->GetRenderWidgetHostView());
595 void WRTNativeWindow::SetContentView(views::View* view) {
596 auto* wrt_web_contents = WRTWebContents::FromNativeWindow(this);
597 SetWebContents(wrt_web_contents->web_contents());
599 native_window_delegate->SetContentView(this, view);
600 set_content_view(view);
602 compositor_observer_ = std::make_unique<ui::CompositorObserverEfl>(
603 GetWindowTreeHost()->compositor(),
604 GetWebContentsGetter(GetWebContents()));
607 WRTJavaScriptDialogManager* WRTNativeWindow::GetJavaScriptDialogManager() {
608 auto delegate = web_contents_->GetDelegate();
612 return static_cast<WRTJavaScriptDialogManager*>(
613 delegate->GetJavaScriptDialogManager(nullptr));
616 void WRTNativeWindow::OnRotation(int degree) {
617 content::WebContentsViewAura* aura = GetWebContentsViewAura();
618 if (aura->GetOrientation() == degree)
621 if (degree % 90 != 0) {
622 LOG(ERROR) << "Received an invalid degree: " << degree;
626 aura->SetOrientation(degree);
628 auto* dialog_manager = GetJavaScriptDialogManager();
629 if (dialog_manager) {
631 ecore_evas_screen_geometry_get(
632 platform_canvas, nullptr, nullptr, &width, &height);
633 if (degree == 90 || degree == 270)
634 std::swap(width, height);
635 dialog_manager->SetPopupSize(width, height);
639 void WRTNativeWindow::Close() {
640 NotifyWindowCloseButtonClicked();
643 void WRTNativeWindow::CloseImmediately() {
644 if (is_main_native_window_)
645 native_window_delegate->ClearHandlers();
647 native_window_delegate->RemoveWidgetClient(this);
648 NotifyWindowClosed();
651 void WRTNativeWindow::Focus(bool focus) {
652 native_window_delegate->Focus(this, focus);
655 bool WRTNativeWindow::IsFocused() {
656 return native_window_delegate->IsFocused(this);
659 void WRTNativeWindow::SetPageVisibility(bool visibility) {
660 LOG(INFO) << "Page visibility changed to " << visibility;
661 auto* rwhv = GetRenderWidgetHostView();
662 auto* aura_efl_helper = rwhv ? rwhv->aura_efl_helper() : nullptr;
664 aura_efl_helper->SetPageVisibility(visibility);
674 void WRTNativeWindow::Show() {
675 if (visibility_status_ || IsRunningAsBackground() ||
676 SplashScreen::IsShowing())
679 if (!GetWebContents()) {
680 LOG(ERROR) << "There's no available window or webview.";
684 native_window_delegate->Show(this);
685 visibility_status_ = true;
688 void WRTNativeWindow::ShowInactive() {
692 void WRTNativeWindow::Hide() {
693 visibility_status_ = false;
696 void WRTNativeWindow::LowerWindow() {
697 ecore_evas_lower(platform_canvas);
700 bool WRTNativeWindow::IsVisible() {
701 return visibility_status_;
704 bool WRTNativeWindow::IsEnabled() {
708 void WRTNativeWindow::SetScheduledTasks(bool enable) {
709 auto* wrt_web_contents = WRTWebContents::FromNativeWindow(this);
710 if (!wrt_web_contents) {
711 LOG(WARNING) << "WebContents is not created";
714 auto* render_interface = wrt_web_contents->GetRendererInterface();
715 if (!render_interface) {
716 LOG(WARNING) << "Frame is not created";
721 render_interface->ResumeScheduledTasks();
723 render_interface->SuspendScheduledTasks();
726 void WRTNativeWindow::SetEnabled(bool enable) {
727 if (is_enabled_ == enable)
730 is_enabled_ = enable;
732 SetScheduledTasks(enable);
735 void WRTNativeWindow::Maximize() {
736 if (!platform_canvas) {
737 LOG(ERROR) << "There's no available window.";
740 ecore_evas_maximized_set(platform_canvas, EINA_TRUE);
743 void WRTNativeWindow::Unmaximize() {
744 if (!platform_canvas) {
745 LOG(ERROR) << "There's no available window.";
748 ecore_evas_maximized_set(platform_canvas, EINA_FALSE);
751 bool WRTNativeWindow::IsMaximized() {
752 if (!platform_canvas) {
753 LOG(ERROR) << "There's no available window.";
756 return ecore_evas_maximized_get(platform_canvas);
759 void WRTNativeWindow::Minimize() {
763 void WRTNativeWindow::Restore() {
767 bool WRTNativeWindow::IsMinimized() {
768 if (!platform_canvas) {
769 LOG(ERROR) << "There's no available window.";
772 return !ecore_evas_maximized_get(platform_canvas);
775 void WRTNativeWindow::SetFullScreen(bool fullscreen) {
776 if (!platform_canvas) {
777 LOG(ERROR) << "There's no available window.";
780 ecore_evas_fullscreen_set(platform_canvas, fullscreen);
783 bool WRTNativeWindow::IsFullscreen() const {
784 if (!platform_canvas) {
785 LOG(ERROR) << "There's no available window.";
788 return ecore_evas_fullscreen_get(platform_canvas);
791 void WRTNativeWindow::SetBounds(const gfx::Rect& bounds, bool animate) {
792 widget()->SetBounds(bounds);
795 gfx::Rect WRTNativeWindow::GetBounds() {
796 return widget()->GetWindowBoundsInScreen();
799 gfx::Rect WRTNativeWindow::GetNormalBounds() {
804 void WRTNativeWindow::SetResizable(bool resizable) {
808 bool WRTNativeWindow::MoveAbove(const std::string& sourceId) {
813 void WRTNativeWindow::MoveTop() {
814 visibility_status_ = false;
818 bool WRTNativeWindow::IsResizable() {
823 void WRTNativeWindow::SetMovable(bool movable) {
827 bool WRTNativeWindow::IsMovable() {
832 void WRTNativeWindow::SetMinimizable(bool minimizable) {
836 bool WRTNativeWindow::IsMinimizable() {
841 void WRTNativeWindow::SetMaximizable(bool maximizable) {
845 bool WRTNativeWindow::IsMaximizable() {
850 void WRTNativeWindow::SetFullScreenable(bool fullscreenable) {
851 fullscreenable_ = fullscreenable;
854 bool WRTNativeWindow::IsFullScreenable() {
855 return fullscreenable_;
858 void WRTNativeWindow::SetClosable(bool closable) {
862 bool WRTNativeWindow::IsClosable() {
867 void WRTNativeWindow::SetAlwaysOnTop(ui::ZOrderLevel z_order,
868 const std::string& level,
873 ui::ZOrderLevel WRTNativeWindow::GetZOrderLevel() {
875 return ui::ZOrderLevel::kNormal;
878 void WRTNativeWindow::Center() {
882 void WRTNativeWindow::Invalidate() {
886 void WRTNativeWindow::SetTitle(const std::string& title) {
888 ecore_evas_title_set(platform_canvas, title_.c_str());
891 std::string WRTNativeWindow::GetTitle() {
895 void WRTNativeWindow::FlashFrame(bool flash) {
899 void WRTNativeWindow::SetSkipTaskbar(bool skip) {
903 void WRTNativeWindow::SetExcludedFromShownWindowsMenu(bool excluded) {
907 bool WRTNativeWindow::IsExcludedFromShownWindowsMenu() {
912 void WRTNativeWindow::SetSimpleFullScreen(bool simple_fullscreen) {
916 bool WRTNativeWindow::IsSimpleFullScreen() {
921 void WRTNativeWindow::SetKiosk(bool kiosk) {
925 bool WRTNativeWindow::IsKiosk() {
930 void WRTNativeWindow::SetBackgroundColor(SkColor color) {
931 GetWebContentsViewAura()->SetBackgroundColor(color);
934 SkColor WRTNativeWindow::GetBackgroundColor() {
935 return GetWebContentsViewAura()->GetBackgroundColor();
938 void WRTNativeWindow::SetHasShadow(bool has_shadow) {
942 bool WRTNativeWindow::HasShadow() {
947 void WRTNativeWindow::SetOpacity(const double opacity) {
951 double WRTNativeWindow::GetOpacity() {
956 void WRTNativeWindow::SetIgnoreMouseEvents(bool ignore, bool forward) {
960 void WRTNativeWindow::SetContentProtection(bool enable) {
964 void WRTNativeWindow::AddBrowserView(electron::NativeBrowserView* view) {
968 void WRTNativeWindow::RemoveBrowserView(electron::NativeBrowserView* view) {
972 void WRTNativeWindow::SetTopBrowserView(electron::NativeBrowserView* view) {
976 content::DesktopMediaID WRTNativeWindow::GetDesktopMediaID() const {
977 auto id = static_cast<content::DesktopMediaID::Id>(GetAcceleratedWidget());
978 return content::DesktopMediaID(content::DesktopMediaID::TYPE_WINDOW, id);
981 gfx::NativeView WRTNativeWindow::GetNativeView() const {
982 return web_contents_->GetNativeView();
985 gfx::NativeWindow WRTNativeWindow::GetNativeWindow() const {
986 return web_contents_->GetTopLevelNativeWindow();
989 gfx::AcceleratedWidget WRTNativeWindow::GetAcceleratedWidget() const {
991 return gfx::AcceleratedWidget();
994 electron::NativeWindowHandle WRTNativeWindow::GetNativeWindowHandle() const {
995 return GetAcceleratedWidget();
998 void WRTNativeWindow::SetProgressBar(
999 double progress, const ProgressState state) {
1003 void WRTNativeWindow::SetOverlayIcon(
1004 const gfx::Image& overlay, const std::string& description) {
1009 void WRTNativeWindow::SetVisibleOnAllWorkspaces(
1010 bool visible, bool visibleOnFullScreen, bool skipTransformProcessType) {
1014 bool WRTNativeWindow::IsVisibleOnAllWorkspaces() {
1019 // Converts between content bounds and window bounds.
1020 gfx::Rect WRTNativeWindow::ContentBoundsToWindowBounds(
1021 const gfx::Rect& bounds) const {
1026 gfx::Rect WRTNativeWindow::WindowBoundsToContentBounds(
1027 const gfx::Rect& bounds) const {
1032 void WRTNativeWindow::OnSoftKeyboardChangeEvent(bool value) {
1033 content::RenderFrameHost* rfh = GetRenderFrameHost();
1037 std::stringstream script;
1040 << "var __event = document.createEvent(\"CustomEvent\");\n"
1041 << "var __detail = {};\n"
1042 << "__event.initCustomEvent(\"softkeyboardchange\",true,true,__detail);\n"
1043 << "__event.state = \"" << (value == true ? "on" : "off") << "\";\n"
1044 << "__event.width = " << (value == true ? ime_width : 0) << ";\n"
1045 << "__event.height = " << (value == true ? ime_height : 0) << ";\n"
1046 << "document.dispatchEvent(__event);\n"
1048 << "for (var i=0; i < window.frames.length; i++)\n"
1049 << "{ window.frames[i].document.dispatchEvent(__event); }"
1051 std::string kSoftKeyboardScript = script.str();
1052 std::u16string js_script;
1053 base::UTF8ToUTF16(kSoftKeyboardScript.c_str(), kSoftKeyboardScript.size(),
1055 rfh->ExecuteJavaScriptWithUserGestureForTests(
1056 js_script, base::NullCallback());
1059 void WRTNativeWindow::OnRotaryEvent(RotaryEventType type) {
1060 content::RenderFrameHost* rfh = GetRenderFrameHost();
1064 std::stringstream script;
1067 << "var __event = document.createEvent(\"CustomEvent\");\n"
1068 << "var __detail = {};\n"
1069 << "__event.initCustomEvent(\"rotarydetent\", true, true, __detail);\n"
1070 << "__event.detail.direction = \""
1071 << (type == RotaryEventType::CLOCKWISE ? "CW" : "CCW") << "\";\n"
1072 << "document.dispatchEvent(__event);\n"
1074 << "for (var i=0; i < window.frames.length; i++)\n"
1075 << "{ window.frames[i].document.dispatchEvent(__event); }"
1077 std::string kRotaryEventScript = script.str();
1078 std::u16string js_script;
1079 base::UTF8ToUTF16(kRotaryEventScript.c_str(), kRotaryEventScript.size(),
1081 rfh->ExecuteJavaScriptWithUserGestureForTests(
1082 js_script, base::NullCallback());
1085 std::unique_ptr<views::NonClientFrameView>
1086 WRTNativeWindow::CreateNonClientFrameView(views::Widget* widget) {
1087 return std::make_unique<WRTFrameView>();
1092 namespace electron {
1095 NativeWindow* NativeWindow::Create(const gin_helper::Dictionary& options,
1096 NativeWindow* parent) {
1097 return new WRTNativeWindowType(options, parent);
1100 } // namespace electron