[WRTjs] Refactor popup
[platform/framework/web/chromium-efl.git] / wrt / src / browser / wrt_native_window_on_screen.cc
1 // Copyright 2023 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.
4
5 #include "wrt/src/browser/wrt_native_window_on_screen.h"
6
7 #include <Ecore_Evas.h>
8 #include <Ecore_Wl2.h>
9
10 #include "base/task/single_thread_task_runner.h"
11 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
12 #include "ui/views/view.h"
13 #include "ui/views/widget/native_widget_private.h"
14 #include "ui/views/widget/widget.h"
15 #include "ui/wm/core/focus_controller.h"
16 #include "wrt/src/browser/wrt_native_widget.h"
17 #include "wrt/src/browser/wrt_window_tree_host.h"
18
19 namespace wrt {
20
21 WRTNativeWindowOnScreen::WRTNativeWindowOnScreen() {
22   auto* evas_object = GetWindowTreeHost(nullptr)->GetEvasObject();
23   auto* ee = ecore_evas_ecore_evas_get(evas_object_evas_get(evas_object));
24   auto* wl2_window = ecore_evas_wayland2_window_get(ee);
25   ecore_wl2_window_conformant_set(wl2_window, EINA_TRUE);
26
27   auto* conformant_handler = ecore_event_handler_add(
28       ECORE_WL2_EVENT_CONFORMANT_CHANGE,
29       [](void* data, int, void*) -> Eina_Bool {
30         auto* window = static_cast<WRTNativeWindowOnScreen*>(data);
31         window->OnConformantChange();
32         return ECORE_CALLBACK_PASS_ON;
33       },
34       this);
35   if (conformant_handler)
36     handlers_.push_back(conformant_handler);
37
38   auto* focus_in_handler = ecore_event_handler_add(
39       ECORE_WL2_EVENT_FOCUS_IN,
40       [](void* data, int, void*) -> Eina_Bool {
41         auto* onscreen_window = static_cast<WRTNativeWindowOnScreen*>(data);
42         onscreen_window->ActiveAuraWindow(true);
43         return ECORE_CALLBACK_PASS_ON;
44       },
45       this);
46   if (focus_in_handler)
47     handlers_.push_back(focus_in_handler);
48
49   auto* focus_out_handler = ecore_event_handler_add(
50       ECORE_WL2_EVENT_FOCUS_OUT,
51       [](void* data, int, void*) -> Eina_Bool {
52         auto* onscreen_window = static_cast<WRTNativeWindowOnScreen*>(data);
53         onscreen_window->ActiveAuraWindow(false);
54         return ECORE_CALLBACK_PASS_ON;
55       },
56       this);
57   if (focus_out_handler)
58     handlers_.push_back(focus_out_handler);
59 }
60
61 Evas_Object* WRTNativeWindowOnScreen::GetWindowEvasObject() {
62   return host_->GetEvasObject();
63 }
64
65 Evas_Object* WRTNativeWindowOnScreen::GetTopWindow() {
66   return host_->GetEvasObject();
67 }
68
69 WRTWindowTreeHost* WRTNativeWindowOnScreen::GetWindowTreeHost(
70     WRTNativeWindow* native_window) {
71   if (!host_)
72     host_.reset(WRTWindowTreeHost::Create());
73   return host_.get();
74 }
75
76 void WRTNativeWindowOnScreen::ClearHandlers() {
77   for (auto* handler : handlers_)
78     ecore_event_handler_del(handler);
79   handlers_.clear();
80 }
81
82 void WRTNativeWindowOnScreen::OnNativeWindowDestroyed(
83     WRTNativeWindow* native_window) {
84   if (!native_window->is_main_native_window())
85     return;
86
87   auto* host = host_.release();
88   base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
89       FROM_HERE,
90       base::BindOnce([](WRTWindowTreeHost* host) { delete host; }, host));
91 }
92
93 void WRTNativeWindowOnScreen::InitRotation() {
94   auto* handler = ecore_event_handler_add(
95       ECORE_WL2_EVENT_WINDOW_ROTATE,
96       [](void*, int, void*) -> Eina_Bool {
97         WRTNativeWindow::RotationCallback();
98         return ECORE_CALLBACK_PASS_ON;
99       },
100       nullptr);
101   if (handler)
102     handlers_.push_back(handler);
103 }
104
105 int WRTNativeWindowOnScreen::SetRotationState(bool is_auto, int degree) {
106   auto* ee = WRTNativeWindow::GetPlatformCanvas();
107   int rotation_degree = 0;
108   if (is_auto) {
109     LOG(INFO) << "Rotation : Auto";
110     ecore_evas_wm_rotation_preferred_rotation_set(ee, -1);
111     if (ecore_evas_wm_rotation_supported_get(ee)) {
112       const int rotations[4] = {0, 90, 180, 270};
113       ecore_evas_wm_rotation_available_rotations_set(ee, rotations, 4);
114     }
115     ecore_evas_wm_rotation_manual_rotation_done_set(ee, EINA_TRUE);
116     rotation_degree = ecore_evas_rotation_get(ee);
117   } else {
118     if (degree != -1)
119       rotation_degree = degree % 360;
120     LOG(INFO) << "Rotation : Lock to " << rotation_degree;
121     ecore_evas_wm_rotation_preferred_rotation_set(ee, rotation_degree);
122   }
123
124   return rotation_degree;
125 }
126
127 void WRTNativeWindowOnScreen::SetContentView(WRTNativeWindow* native_window,
128                                              views::View* view) {
129   auto* client_view = native_window->widget()->client_view();
130   if (!client_view)
131     return;
132   if (native_window->content_view())
133     client_view->RemoveChildView(native_window->content_view());
134   client_view->AddChildView(view);
135   view->SetSize(client_view->size());
136 }
137
138 void WRTNativeWindowOnScreen::Show(WRTNativeWindow* native_window) {
139   auto widget = native_window->widget();
140   widget->native_widget_private()->Show(ui::SHOW_STATE_NORMAL, gfx::Rect());
141   // explicitly focus the window
142   widget->Activate();
143 }
144
145 void WRTNativeWindowOnScreen::Hide() {
146   host_->Hide();
147 }
148
149 bool WRTNativeWindowOnScreen::IsFocused(WRTNativeWindow* native_window) {
150   return native_window->widget()->IsActive();
151 }
152
153 void WRTNativeWindowOnScreen::Focus(WRTNativeWindow* native_window,
154                                     bool focus) {
155   auto widget = native_window->widget();
156   if (focus)
157     widget->Activate();
158   else
159     widget->Deactivate();
160 }
161
162 void WRTNativeWindowOnScreen::OnConformantChange() {
163   auto* native_window = WRTNativeWindow::GetActiveNativeWindow();
164   if (!native_window)
165     return;
166
167   if (!native_window->ShouldHandleConformantChange()) {
168     LOG(INFO) << "use.conformant is floating, not handle conformant change!";
169     return;
170   }
171
172   auto* wl2_window =
173       ecore_evas_wayland2_window_get(WRTNativeWindow::GetPlatformCanvas());
174   if (!wl2_window)
175     return;
176
177   int x, y, width, height;
178   ecore_wl2_window_geometry_get(wl2_window, &x, &y, &width, &height);
179   gfx::Rect rect(x, y, width, height);
180
181   if (native_window->WillHandleConformantChange()) {
182     if (ecore_wl2_window_indicator_state_get(wl2_window) ==
183         ECORE_WL2_INDICATOR_STATE_ON) {
184       ecore_wl2_window_indicator_geometry_get(
185           wl2_window, &x, &y, &width, &height);
186       rect.Subtract(gfx::Rect(x, y, width, height));
187     }
188     if (ecore_wl2_window_keyboard_state_get(wl2_window) ==
189         ECORE_WL2_VIRTUAL_KEYBOARD_STATE_ON) {
190       ecore_wl2_window_keyboard_geometry_get(
191           wl2_window, &x, &y, &width, &height);
192       rect.Subtract(gfx::Rect(x, y, width, height));
193     }
194     if (ecore_wl2_window_clipboard_state_get(wl2_window) ==
195         ECORE_WL2_CLIPBOARD_STATE_ON) {
196       ecore_wl2_window_clipboard_geometry_get(
197           wl2_window, &x, &y, &width, &height);
198       rect.Subtract(gfx::Rect(x, y, width, height));
199     }
200   }
201
202   auto rotation = ecore_wl2_window_rotation_get(wl2_window);
203   if (rotation == 90 || rotation == 270)
204     rect.Transpose();
205
206   auto current_rect = native_window->GetBounds();
207   if (rect != current_rect) {
208     LOG(INFO) << "Set bounds : (" << current_rect.ToString() << ") -> ("
209               << rect.ToString() << ")";
210     native_window->SetBounds(rect);
211   }
212 }
213
214 void WRTNativeWindowOnScreen::ActiveAuraWindow(bool active) {
215   auto* native_window = WRTNativeWindow::GetActiveNativeWindow();
216   if (!native_window)
217     return;
218
219   auto* rwhva = native_window->GetRenderWidgetHostView();
220   WRTNativeWidget* widget =
221       (WRTNativeWidget*)native_window->widget()->native_widget();
222   if (rwhva && widget)
223     widget->ActiveAuraWindow(active, rwhva->GetNativeView());
224 }
225
226 void WRTNativeWindowOnScreen::CheckAndResetWidgetClient(
227     WRTNativeWindow* native_window) {
228   if (!native_window)
229     return;
230
231   auto* rwhva = native_window->GetRenderWidgetHostView();
232   WRTNativeWidget* widget =
233       (WRTNativeWidget*)native_window->widget()->native_widget();
234   if (rwhva && widget)
235     widget->CheckAndResetWidgetClient();
236 }
237
238 void WRTNativeWindowOnScreen::RemoveWidgetClient(
239     WRTNativeWindow* native_window) {
240   if (!native_window)
241     return;
242
243   auto* rwhva = native_window->GetRenderWidgetHostView();
244   WRTNativeWidget* widget =
245       (WRTNativeWidget*)native_window->widget()->native_widget();
246   if (rwhva && widget)
247     widget->RemoveWidgetClient();
248 }
249
250 }  // namespace wrt