zcr_remote_shell_v2.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. // Copyright 2021 The Chromium Authors. 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. #include <aura-shell-server-protocol.h>
  5. #include <remote-shell-unstable-v2-server-protocol.h>
  6. #include "ash/wm/desks/desks_util.h"
  7. #include "components/exo/wayland/server_util.h"
  8. #include "components/exo/wayland/zcr_remote_shell_impl.h"
  9. #include "components/exo/wm_helper_chromeos.h"
  10. namespace exo {
  11. namespace wayland {
  12. namespace {
  13. int RemoteSurfaceContainerV2(uint32_t container) {
  14. switch (container) {
  15. case ZCR_REMOTE_SHELL_V2_CONTAINER_DEFAULT:
  16. return ash::desks_util::GetActiveDeskContainerId();
  17. case ZCR_REMOTE_SHELL_V2_CONTAINER_OVERLAY:
  18. return ash::kShellWindowId_SystemModalContainer;
  19. default:
  20. DLOG(WARNING) << "Unsupported container: " << container;
  21. return ash::desks_util::GetActiveDeskContainerId();
  22. }
  23. }
  24. const struct WaylandRemoteOutputEventMapping remote_output_event_mapping_v2 = {
  25. zcr_remote_output_v2_send_identification_data,
  26. // deprecated but not removed due to lack of alternative for stable
  27. // identifier for wl_resource required on the ARC side.
  28. zcr_remote_output_v2_send_display_id,
  29. zcr_remote_output_v2_send_port,
  30. zcr_remote_output_v2_send_insets,
  31. zcr_remote_output_v2_send_stable_insets,
  32. zcr_remote_output_v2_send_systemui_behavior,
  33. ZCR_REMOTE_OUTPUT_V2_SYSTEMUI_BEHAVIOR_SINCE_VERSION,
  34. ZCR_REMOTE_OUTPUT_V2_STABLE_INSETS_SINCE_VERSION,
  35. };
  36. const WaylandRemoteShellEventMapping wayland_remote_shell_event_mapping_v2 = {
  37. zcr_remote_surface_v2_send_window_geometry_changed,
  38. zcr_remote_surface_v2_send_change_zoom_level,
  39. zcr_remote_surface_v2_send_state_type_changed,
  40. zcr_remote_surface_v2_send_bounds_changed_in_output,
  41. zcr_remote_surface_v2_send_bounds_changed,
  42. nullptr, // moved to zaura-shell protocol
  43. zcr_remote_shell_v2_send_desktop_focus_state_changed,
  44. nullptr, // event removed in v2
  45. zcr_remote_surface_v2_send_drag_finished,
  46. zcr_remote_surface_v2_send_drag_started,
  47. zcr_remote_shell_v2_send_layout_mode,
  48. zcr_remote_shell_v2_send_default_device_scale_factor,
  49. nullptr, // event removed in v2
  50. ZCR_REMOTE_SURFACE_V2_BOUNDS_CHANGED_IN_OUTPUT_SINCE_VERSION,
  51. ZCR_REMOTE_SHELL_V2_DESKTOP_FOCUS_STATE_CHANGED_SINCE_VERSION,
  52. ZCR_REMOTE_SHELL_V2_LAYOUT_MODE_SINCE_VERSION,
  53. ZCR_REMOTE_SHELL_V2_DEFAULT_DEVICE_SCALE_FACTOR_SINCE_VERSION,
  54. 1,
  55. 1,
  56. 1,
  57. };
  58. const struct zcr_remote_surface_v2_interface remote_surface_implementation_v2 =
  59. {
  60. +[](wl_client* client, wl_resource* resource) {
  61. wl_resource_destroy(resource);
  62. },
  63. zcr_remote_shell::remote_surface_set_app_id,
  64. zcr_remote_shell::remote_surface_set_title,
  65. zcr_remote_shell::remote_surface_set_top_inset,
  66. zcr_remote_shell::remote_surface_maximize,
  67. zcr_remote_shell::remote_surface_minimize,
  68. zcr_remote_shell::remote_surface_restore,
  69. zcr_remote_shell::remote_surface_fullscreen,
  70. zcr_remote_shell::remote_surface_pin,
  71. zcr_remote_shell::remote_surface_unpin,
  72. zcr_remote_shell::remote_surface_set_system_modal,
  73. zcr_remote_shell::remote_surface_unset_system_modal,
  74. zcr_remote_shell::remote_surface_set_rectangular_surface_shadow,
  75. zcr_remote_shell::remote_surface_set_systemui_visibility,
  76. zcr_remote_shell::remote_surface_set_always_on_top,
  77. zcr_remote_shell::remote_surface_unset_always_on_top,
  78. zcr_remote_shell::remote_surface_set_orientation,
  79. zcr_remote_shell::remote_surface_start_move,
  80. zcr_remote_shell::remote_surface_set_can_maximize,
  81. zcr_remote_shell::remote_surface_unset_can_maximize,
  82. zcr_remote_shell::remote_surface_set_min_size,
  83. zcr_remote_shell::remote_surface_set_max_size,
  84. zcr_remote_shell::remote_surface_set_snapped_to_left,
  85. zcr_remote_shell::remote_surface_set_snapped_to_right,
  86. zcr_remote_shell::remote_surface_start_resize,
  87. zcr_remote_shell::remote_surface_set_frame,
  88. zcr_remote_shell::remote_surface_set_frame_buttons,
  89. zcr_remote_shell::remote_surface_set_extra_title,
  90. zcr_remote_shell::remote_surface_set_orientation_lock,
  91. zcr_remote_shell::remote_surface_pip,
  92. zcr_remote_shell::remote_surface_set_aspect_ratio,
  93. zcr_remote_shell::remote_surface_set_accessibility_id,
  94. zcr_remote_shell::remote_surface_set_pip_original_window,
  95. zcr_remote_shell::remote_surface_unset_pip_original_window,
  96. zcr_remote_shell::remote_surface_set_system_gesture_exclusion,
  97. zcr_remote_shell::remote_surface_set_resize_lock,
  98. zcr_remote_shell::remote_surface_unset_resize_lock,
  99. zcr_remote_shell::remote_surface_set_bounds_in_output,
  100. zcr_remote_shell::remote_surface_set_resize_lock_type,
  101. };
  102. const struct zcr_notification_surface_v2_interface
  103. notification_surface_implementation_v2 = {
  104. +[](wl_client* client, wl_resource* resource) {
  105. wl_resource_destroy(resource);
  106. },
  107. zcr_remote_shell::notification_surface_set_app_id,
  108. };
  109. const struct zcr_input_method_surface_v2_interface
  110. input_method_surface_implementation_v2 = {
  111. +[](wl_client* client, wl_resource* resource) {
  112. wl_resource_destroy(resource);
  113. },
  114. zcr_remote_shell::input_method_surface_set_bounds_in_output,
  115. };
  116. const struct zcr_toast_surface_v2_interface toast_surface_implementation_v2 = {
  117. +[](wl_client* client, wl_resource* resource) {
  118. wl_resource_destroy(resource);
  119. },
  120. zcr_remote_shell::toast_surface_set_bounds_in_output,
  121. };
  122. const struct zcr_remote_output_v2_interface remote_output_implementation_v2 = {
  123. +[](wl_client* client, wl_resource* resource) {
  124. wl_resource_destroy(resource);
  125. },
  126. };
  127. void HandleRemoteSurfaceCloseCallbackV2(wl_resource* resource) {
  128. zcr_remote_surface_v2_send_close(resource);
  129. wl_client_flush(wl_resource_get_client(resource));
  130. }
  131. void remote_shell_get_remote_surface_v2(wl_client* client,
  132. wl_resource* resource,
  133. uint32_t id,
  134. wl_resource* surface,
  135. uint32_t container) {
  136. WaylandRemoteShell* shell = GetUserDataAs<WaylandRemoteShell>(resource);
  137. double default_scale_factor = zcr_remote_shell::GetDefaultDeviceScaleFactor();
  138. std::unique_ptr<ClientControlledShellSurface> shell_surface =
  139. shell->CreateShellSurface(GetUserDataAs<Surface>(surface),
  140. RemoteSurfaceContainerV2(container),
  141. default_scale_factor);
  142. if (!shell_surface) {
  143. wl_resource_post_error(resource, ZCR_REMOTE_SHELL_V2_ERROR_ROLE,
  144. "surface has already been assigned a role");
  145. return;
  146. }
  147. wl_resource* remote_surface_resource =
  148. wl_resource_create(client, &zcr_remote_surface_v2_interface,
  149. wl_resource_get_version(resource), id);
  150. shell_surface->SetSecurityDelegate(GetSecurityDelegate(client));
  151. shell_surface->set_delegate(
  152. shell->CreateShellSurfaceDelegate(remote_surface_resource));
  153. shell_surface->set_close_callback(
  154. base::BindRepeating(&HandleRemoteSurfaceCloseCallbackV2,
  155. base::Unretained(remote_surface_resource)));
  156. shell_surface->set_surface_destroyed_callback(base::BindOnce(
  157. &wl_resource_destroy, base::Unretained(remote_surface_resource)));
  158. SetImplementation(remote_surface_resource, &remote_surface_implementation_v2,
  159. std::move(shell_surface));
  160. }
  161. void remote_shell_get_notification_surface_v2(wl_client* client,
  162. wl_resource* resource,
  163. uint32_t id,
  164. wl_resource* surface,
  165. const char* notification_key) {
  166. if (GetUserDataAs<Surface>(surface)->HasSurfaceDelegate()) {
  167. wl_resource_post_error(resource, ZCR_REMOTE_SHELL_V2_ERROR_ROLE,
  168. "surface has already been assigned a role");
  169. return;
  170. }
  171. std::unique_ptr<NotificationSurface> notification_surface =
  172. GetUserDataAs<WaylandRemoteShell>(resource)->CreateNotificationSurface(
  173. GetUserDataAs<Surface>(surface), std::string(notification_key));
  174. if (!notification_surface) {
  175. wl_resource_post_error(resource,
  176. ZCR_REMOTE_SHELL_V2_ERROR_INVALID_NOTIFICATION_KEY,
  177. "invalid notification key");
  178. return;
  179. }
  180. wl_resource* notification_surface_resource =
  181. wl_resource_create(client, &zcr_notification_surface_v2_interface,
  182. wl_resource_get_version(resource), id);
  183. SetImplementation(notification_surface_resource,
  184. &notification_surface_implementation_v2,
  185. std::move(notification_surface));
  186. }
  187. void remote_shell_get_input_method_surface_v2(wl_client* client,
  188. wl_resource* resource,
  189. uint32_t id,
  190. wl_resource* surface) {
  191. if (GetUserDataAs<Surface>(surface)->HasSurfaceDelegate()) {
  192. wl_resource_post_error(resource, ZCR_REMOTE_SHELL_V2_ERROR_ROLE,
  193. "surface has already been assigned a role");
  194. return;
  195. }
  196. std::unique_ptr<ClientControlledShellSurface> input_method_surface =
  197. GetUserDataAs<WaylandRemoteShell>(resource)->CreateInputMethodSurface(
  198. GetUserDataAs<Surface>(surface),
  199. zcr_remote_shell::GetDefaultDeviceScaleFactor());
  200. if (!input_method_surface) {
  201. wl_resource_post_error(resource, ZCR_REMOTE_SHELL_V2_ERROR_ROLE,
  202. "Cannot create an IME surface");
  203. return;
  204. }
  205. wl_resource* input_method_surface_resource =
  206. wl_resource_create(client, &zcr_input_method_surface_v2_interface,
  207. wl_resource_get_version(resource), id);
  208. SetImplementation(input_method_surface_resource,
  209. &input_method_surface_implementation_v2,
  210. std::move(input_method_surface));
  211. }
  212. void remote_shell_get_toast_surface_v2(wl_client* client,
  213. wl_resource* resource,
  214. uint32_t id,
  215. wl_resource* surface) {
  216. if (GetUserDataAs<Surface>(surface)->HasSurfaceDelegate()) {
  217. wl_resource_post_error(resource, ZCR_REMOTE_SHELL_V2_ERROR_ROLE,
  218. "surface has already been assigned a role");
  219. return;
  220. }
  221. std::unique_ptr<ClientControlledShellSurface> toast_surface =
  222. GetUserDataAs<WaylandRemoteShell>(resource)->CreateToastSurface(
  223. GetUserDataAs<Surface>(surface),
  224. zcr_remote_shell::GetDefaultDeviceScaleFactor());
  225. if (!toast_surface) {
  226. wl_resource_post_error(resource, ZCR_REMOTE_SHELL_V2_ERROR_ROLE,
  227. "Cannot create an toast surface");
  228. return;
  229. }
  230. wl_resource* toast_surface_resource =
  231. wl_resource_create(client, &zcr_toast_surface_v2_interface,
  232. wl_resource_get_version(resource), id);
  233. SetImplementation(toast_surface_resource, &toast_surface_implementation_v2,
  234. std::move(toast_surface));
  235. }
  236. void remote_shell_get_remote_output_v2(wl_client* client,
  237. wl_resource* resource,
  238. uint32_t id,
  239. wl_resource* output_resource) {
  240. WaylandDisplayHandler* display_handler =
  241. GetUserDataAs<WaylandDisplayHandler>(output_resource);
  242. wl_resource* remote_output_resource =
  243. wl_resource_create(client, &zcr_remote_output_v2_interface,
  244. wl_resource_get_version(resource), id);
  245. auto remote_output = std::make_unique<WaylandRemoteOutput>(
  246. remote_output_resource, remote_output_event_mapping_v2, display_handler);
  247. SetImplementation(remote_output_resource, &remote_output_implementation_v2,
  248. std::move(remote_output));
  249. }
  250. const struct zcr_remote_shell_v2_interface remote_shell_implementation_v2 = {
  251. +[](wl_client* client, wl_resource* resource) {
  252. // Nothing to do here.
  253. },
  254. remote_shell_get_remote_surface_v2,
  255. remote_shell_get_notification_surface_v2,
  256. remote_shell_get_input_method_surface_v2,
  257. remote_shell_get_toast_surface_v2,
  258. remote_shell_get_remote_output_v2};
  259. } // namespace
  260. void bind_remote_shell_v2(wl_client* client,
  261. void* data,
  262. uint32_t version,
  263. uint32_t id) {
  264. wl_resource* resource = wl_resource_create(
  265. client, &zcr_remote_shell_v2_interface,
  266. std::min<uint32_t>(version, zcr_remote_shell_v2_interface.version), id);
  267. auto* remote_shell_data = static_cast<WaylandRemoteShellData*>(data);
  268. SetImplementation(
  269. resource, &remote_shell_implementation_v2,
  270. std::make_unique<WaylandRemoteShell>(
  271. remote_shell_data->display, resource,
  272. base::BindRepeating(remote_shell_data->output_provider, client),
  273. wayland_remote_shell_event_mapping_v2,
  274. /*use_default_scale_cancellation_default=*/false));
  275. }
  276. } // namespace wayland
  277. } // namespace exo