zcr_remote_shell_impl.cc 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560
  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 "components/exo/wayland/zcr_remote_shell_impl.h"
  5. #include "ash/public/cpp/arc_resize_lock_type.h"
  6. #include "ash/shelf/shelf_layout_manager.h"
  7. #include "ash/shell.h"
  8. #include "ash/wm/window_resizer.h"
  9. #include "base/command_line.h"
  10. #include "chromeos/ui/base/window_pin_type.h"
  11. #include "components/exo/display.h"
  12. #include "components/exo/wayland/server_util.h"
  13. #include "components/exo/wm_helper_chromeos.h"
  14. #include "ui/display/screen.h"
  15. #include "ui/views/window/caption_button_types.h"
  16. #include "ui/wm/core/window_animations.h"
  17. namespace exo {
  18. namespace wayland {
  19. // Ensure that V1 and V2 constants remain identical.
  20. static_assert(
  21. static_cast<int>(ZCR_REMOTE_SURFACE_V1_SYSTEMUI_VISIBILITY_STATE_VISIBLE) ==
  22. static_cast<int>(
  23. ZCR_REMOTE_SURFACE_V2_SYSTEMUI_VISIBILITY_STATE_VISIBLE),
  24. "ZCR_REMOTE_SURFACE_V1_SYSTEMUI_VISIBILITY_STATE_VISIBLE and "
  25. "ZCR_REMOTE_SURFACE_V2_SYSTEMUI_VISIBILITY_STATE_VISIBLE should be equal");
  26. static_assert(
  27. static_cast<int>(
  28. ZCR_REMOTE_SURFACE_V1_SYSTEMUI_VISIBILITY_STATE_AUTOHIDE_NON_STICKY) ==
  29. static_cast<int>(
  30. ZCR_REMOTE_SURFACE_V2_SYSTEMUI_VISIBILITY_STATE_AUTOHIDE_NON_STICKY),
  31. "ZCR_REMOTE_SURFACE_V1_SYSTEMUI_VISIBILITY_STATE_AUTOHIDE_NON_STICKY and "
  32. "ZCR_REMOTE_SURFACE_V2_SYSTEMUI_VISIBILITY_STATE_AUTOHIDE_NON_STICKY "
  33. "should be equal");
  34. static_assert(
  35. static_cast<int>(ZCR_REMOTE_OUTPUT_V1_SYSTEMUI_BEHAVIOR_VISIBLE) ==
  36. static_cast<int>(ZCR_REMOTE_OUTPUT_V2_SYSTEMUI_BEHAVIOR_VISIBLE),
  37. "ZCR_REMOTE_OUTPUT_V1_SYSTEMUI_BEHAVIOR_VISIBLE and "
  38. "ZCR_REMOTE_OUTPUT_V2_SYSTEMUI_BEHAVIOR_VISIBLE should be equal");
  39. static_assert(
  40. static_cast<int>(ZCR_REMOTE_OUTPUT_V1_SYSTEMUI_BEHAVIOR_HIDDEN) ==
  41. static_cast<int>(ZCR_REMOTE_OUTPUT_V2_SYSTEMUI_BEHAVIOR_HIDDEN),
  42. "ZCR_REMOTE_OUTPUT_V1_SYSTEMUI_BEHAVIOR_HIDDEN and "
  43. "ZCR_REMOTE_OUTPUT_V2_SYSTEMUI_BEHAVIOR_HIDDEN should be equal");
  44. static_assert(static_cast<int>(ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_NONE) ==
  45. static_cast<int>(ZCR_REMOTE_SURFACE_V2_RESIZE_DIRECTION_NONE),
  46. "ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_NONE and "
  47. "ZCR_REMOTE_SURFACE_V2_RESIZE_DIRECTION_NONE should be equal");
  48. static_assert(static_cast<int>(ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_TOP) ==
  49. static_cast<int>(ZCR_REMOTE_SURFACE_V2_RESIZE_DIRECTION_TOP),
  50. "ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_TOP and "
  51. "ZCR_REMOTE_SURFACE_V2_RESIZE_DIRECTION_TOP should be equal");
  52. static_assert(
  53. static_cast<int>(ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_TOPRIGHT) ==
  54. static_cast<int>(ZCR_REMOTE_SURFACE_V2_RESIZE_DIRECTION_TOPRIGHT),
  55. "ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_TOPRIGHT and "
  56. "ZCR_REMOTE_SURFACE_V2_RESIZE_DIRECTION_TOPRIGHT should be equal");
  57. static_assert(
  58. static_cast<int>(ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_RIGHT) ==
  59. static_cast<int>(ZCR_REMOTE_SURFACE_V2_RESIZE_DIRECTION_RIGHT),
  60. "ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_RIGHT and "
  61. "ZCR_REMOTE_SURFACE_V2_RESIZE_DIRECTION_RIGHT should be equal");
  62. static_assert(
  63. static_cast<int>(ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_BOTTOMRIGHT) ==
  64. static_cast<int>(ZCR_REMOTE_SURFACE_V2_RESIZE_DIRECTION_BOTTOMRIGHT),
  65. "ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_BOTTOMRIGHT and "
  66. "ZCR_REMOTE_SURFACE_V2_RESIZE_DIRECTION_BOTTOMRIGHT should be equal");
  67. static_assert(
  68. static_cast<int>(ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_BOTTOM) ==
  69. static_cast<int>(ZCR_REMOTE_SURFACE_V2_RESIZE_DIRECTION_BOTTOM),
  70. "ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_BOTTOM and "
  71. "ZCR_REMOTE_SURFACE_V2_RESIZE_DIRECTION_BOTTOM should be equal");
  72. static_assert(
  73. static_cast<int>(ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_BOTTOMLEFT) ==
  74. static_cast<int>(ZCR_REMOTE_SURFACE_V2_RESIZE_DIRECTION_BOTTOMLEFT),
  75. "ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_BOTTOMLEFT and "
  76. "ZCR_REMOTE_SURFACE_V2_RESIZE_DIRECTION_BOTTOMLEFT should be equal");
  77. static_assert(static_cast<int>(ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_LEFT) ==
  78. static_cast<int>(ZCR_REMOTE_SURFACE_V2_RESIZE_DIRECTION_LEFT),
  79. "ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_LEFT and "
  80. "ZCR_REMOTE_SURFACE_V2_RESIZE_DIRECTION_LEFT should be equal");
  81. static_assert(
  82. static_cast<int>(ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_TOPLEFT) ==
  83. static_cast<int>(ZCR_REMOTE_SURFACE_V2_RESIZE_DIRECTION_TOPLEFT),
  84. "ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_TOPLEFT and "
  85. "ZCR_REMOTE_SURFACE_V2_RESIZE_DIRECTION_TOPLEFT should be equal");
  86. static_assert(static_cast<int>(ZCR_REMOTE_SHELL_V1_LAYOUT_MODE_TABLET) ==
  87. static_cast<int>(ZCR_REMOTE_SHELL_V2_LAYOUT_MODE_TABLET),
  88. "ZCR_REMOTE_SHELL_V1_LAYOUT_MODE_TABLET and "
  89. "ZCR_REMOTE_SHELL_V2_LAYOUT_MODE_TABLET should be equal");
  90. static_assert(static_cast<int>(ZCR_REMOTE_SHELL_V1_LAYOUT_MODE_WINDOWED) ==
  91. static_cast<int>(ZCR_REMOTE_SHELL_V2_LAYOUT_MODE_WINDOWED),
  92. "ZCR_REMOTE_SHELL_V1_LAYOUT_MODE_WINDOWED and "
  93. "ZCR_REMOTE_SHELL_V2_LAYOUT_MODE_WINDOWED should be equal");
  94. static_assert(
  95. static_cast<int>(ZCR_REMOTE_SHELL_V1_DESKTOP_FOCUS_STATE_CLIENT_FOCUSED) ==
  96. static_cast<int>(
  97. ZCR_REMOTE_SHELL_V2_DESKTOP_FOCUS_STATE_CLIENT_FOCUSED),
  98. "ZCR_REMOTE_SHELL_V1_DESKTOP_FOCUS_STATE_CLIENT_FOCUSED and "
  99. "ZCR_REMOTE_SHELL_V2_DESKTOP_FOCUS_STATE_CLIENT_FOCUSED should be equal");
  100. static_assert(
  101. static_cast<int>(
  102. ZCR_REMOTE_SHELL_V1_DESKTOP_FOCUS_STATE_OTHER_CLIENT_FOCUSED) ==
  103. static_cast<int>(
  104. ZCR_REMOTE_SHELL_V2_DESKTOP_FOCUS_STATE_OTHER_CLIENT_FOCUSED),
  105. "ZCR_REMOTE_SHELL_V1_DESKTOP_FOCUS_STATE_OTHER_CLIENT_FOCUSED and "
  106. "ZCR_REMOTE_SHELL_V2_DESKTOP_FOCUS_STATE_OTHER_CLIENT_FOCUSED should be "
  107. "equal");
  108. static_assert(
  109. static_cast<int>(ZCR_REMOTE_SHELL_V1_DESKTOP_FOCUS_STATE_NO_FOCUS) ==
  110. static_cast<int>(ZCR_REMOTE_SHELL_V2_DESKTOP_FOCUS_STATE_NO_FOCUS),
  111. "ZCR_REMOTE_SHELL_V1_DESKTOP_FOCUS_STATE_NO_FOCUS and "
  112. "ZCR_REMOTE_SHELL_V2_DESKTOP_FOCUS_STATE_NO_FOCUS should be equal");
  113. static_assert(
  114. static_cast<int>(ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_RESIZE) ==
  115. static_cast<int>(ZCR_REMOTE_SURFACE_V2_BOUNDS_CHANGE_REASON_RESIZE),
  116. "ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_RESIZE and "
  117. "ZCR_REMOTE_SURFACE_V2_BOUNDS_CHANGE_REASON_RESIZE should be equal");
  118. static_assert(
  119. static_cast<int>(ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_MOVE) ==
  120. static_cast<int>(ZCR_REMOTE_SURFACE_V2_BOUNDS_CHANGE_REASON_MOVE),
  121. "ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_MOVE and "
  122. "ZCR_REMOTE_SURFACE_V2_BOUNDS_CHANGE_REASON_MOVE should be equal");
  123. static_assert(
  124. static_cast<int>(ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_PIP) ==
  125. static_cast<int>(ZCR_REMOTE_SURFACE_V2_BOUNDS_CHANGE_REASON_PIP),
  126. "ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_PIP and "
  127. "ZCR_REMOTE_SURFACE_V2_BOUNDS_CHANGE_REASON_PIP should be equal");
  128. static_assert(
  129. static_cast<int>(ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_DRAG_RESIZE) ==
  130. static_cast<int>(
  131. ZCR_REMOTE_SURFACE_V2_BOUNDS_CHANGE_REASON_DRAG_RESIZE),
  132. "ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_DRAG_RESIZE and "
  133. "ZCR_REMOTE_SURFACE_V2_BOUNDS_CHANGE_REASON_DRAG_RESIZE should be equal");
  134. static_assert(
  135. static_cast<int>(ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_DRAG_MOVE) ==
  136. static_cast<int>(ZCR_REMOTE_SURFACE_V2_BOUNDS_CHANGE_REASON_DRAG_MOVE),
  137. "ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_DRAG_MOVE and "
  138. "ZCR_REMOTE_SURFACE_V2_BOUNDS_CHANGE_REASON_DRAG_MOVE should be equal");
  139. static_assert(
  140. static_cast<int>(ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_SNAP_TO_LEFT) ==
  141. static_cast<int>(
  142. ZCR_REMOTE_SURFACE_V2_BOUNDS_CHANGE_REASON_SNAP_TO_LEFT),
  143. "ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_SNAP_TO_LEFT and "
  144. "ZCR_REMOTE_SURFACE_V2_BOUNDS_CHANGE_REASON_SNAP_TO_LEFT should be equal");
  145. static_assert(
  146. static_cast<int>(
  147. ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_SNAP_TO_RIGHT) ==
  148. static_cast<int>(
  149. ZCR_REMOTE_SURFACE_V2_BOUNDS_CHANGE_REASON_SNAP_TO_RIGHT),
  150. "ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_SNAP_TO_RIGHT and "
  151. "ZCR_REMOTE_SURFACE_V2_BOUNDS_CHANGE_REASON_SNAP_TO_RIGHT should be equal");
  152. static_assert(static_cast<int>(ZCR_REMOTE_SHELL_V1_STATE_TYPE_NORMAL) ==
  153. static_cast<int>(ZCR_REMOTE_SURFACE_V2_STATE_TYPE_NORMAL),
  154. "ZCR_REMOTE_SHELL_V1_STATE_TYPE_NORMAL and "
  155. "ZCR_REMOTE_SURFACE_V2_STATE_TYPE_NORMAL should be equal");
  156. static_assert(static_cast<int>(ZCR_REMOTE_SHELL_V1_STATE_TYPE_MINIMIZED) ==
  157. static_cast<int>(ZCR_REMOTE_SURFACE_V2_STATE_TYPE_MINIMIZED),
  158. "ZCR_REMOTE_SHELL_V1_STATE_TYPE_MINIMIZED and "
  159. "ZCR_REMOTE_SURFACE_V2_STATE_TYPE_MINIMIZED should be equal");
  160. static_assert(static_cast<int>(ZCR_REMOTE_SHELL_V1_STATE_TYPE_MAXIMIZED) ==
  161. static_cast<int>(ZCR_REMOTE_SURFACE_V2_STATE_TYPE_MAXIMIZED),
  162. "ZCR_REMOTE_SHELL_V1_STATE_TYPE_MAXIMIZED and "
  163. "ZCR_REMOTE_SURFACE_V2_STATE_TYPE_MAXIMIZED should be equal");
  164. static_assert(static_cast<int>(ZCR_REMOTE_SHELL_V1_STATE_TYPE_FULLSCREEN) ==
  165. static_cast<int>(ZCR_REMOTE_SURFACE_V2_STATE_TYPE_FULLSCREEN),
  166. "ZCR_REMOTE_SHELL_V1_STATE_TYPE_FULLSCREEN and "
  167. "ZCR_REMOTE_SURFACE_V2_STATE_TYPE_FULLSCREEN should be equal");
  168. static_assert(static_cast<int>(ZCR_REMOTE_SHELL_V1_STATE_TYPE_PINNED) ==
  169. static_cast<int>(ZCR_REMOTE_SURFACE_V2_STATE_TYPE_PINNED),
  170. "ZCR_REMOTE_SHELL_V1_STATE_TYPE_PINNED and "
  171. "ZCR_REMOTE_SURFACE_V2_STATE_TYPE_PINNED should be equal");
  172. static_assert(
  173. static_cast<int>(ZCR_REMOTE_SHELL_V1_STATE_TYPE_TRUSTED_PINNED) ==
  174. static_cast<int>(ZCR_REMOTE_SURFACE_V2_STATE_TYPE_TRUSTED_PINNED),
  175. "ZCR_REMOTE_SHELL_V1_STATE_TYPE_TRUSTED_PINNED and "
  176. "ZCR_REMOTE_SURFACE_V2_STATE_TYPE_TRUSTED_PINNED should be equal");
  177. static_assert(
  178. static_cast<int>(ZCR_REMOTE_SHELL_V1_STATE_TYPE_LEFT_SNAPPED) ==
  179. static_cast<int>(ZCR_REMOTE_SURFACE_V2_STATE_TYPE_LEFT_SNAPPED),
  180. "ZCR_REMOTE_SHELL_V1_STATE_TYPE_LEFT_SNAPPED and "
  181. "ZCR_REMOTE_SURFACE_V2_STATE_TYPE_LEFT_SNAPPED should be equal");
  182. static_assert(
  183. static_cast<int>(ZCR_REMOTE_SHELL_V1_STATE_TYPE_RIGHT_SNAPPED) ==
  184. static_cast<int>(ZCR_REMOTE_SURFACE_V2_STATE_TYPE_RIGHT_SNAPPED),
  185. "ZCR_REMOTE_SHELL_V1_STATE_TYPE_RIGHT_SNAPPED and "
  186. "ZCR_REMOTE_SURFACE_V2_STATE_TYPE_RIGHT_SNAPPED should be equal");
  187. static_assert(static_cast<int>(ZCR_REMOTE_SHELL_V1_STATE_TYPE_PIP) ==
  188. static_cast<int>(ZCR_REMOTE_SURFACE_V2_STATE_TYPE_PIP),
  189. "ZCR_REMOTE_SHELL_V1_STATE_TYPE_PIP and "
  190. "ZCR_REMOTE_SURFACE_V2_STATE_TYPE_PIP should be equal");
  191. static_assert(static_cast<int>(ZCR_REMOTE_SURFACE_V1_ZOOM_CHANGE_IN) ==
  192. static_cast<int>(ZCR_REMOTE_SURFACE_V2_ZOOM_CHANGE_IN),
  193. "ZCR_REMOTE_SURFACE_V1_ZOOM_CHANGE_IN and "
  194. "ZCR_REMOTE_SURFACE_V2_ZOOM_CHANGE_IN should be equal");
  195. static_assert(static_cast<int>(ZCR_REMOTE_SURFACE_V1_ZOOM_CHANGE_OUT) ==
  196. static_cast<int>(ZCR_REMOTE_SURFACE_V2_ZOOM_CHANGE_OUT),
  197. "ZCR_REMOTE_SURFACE_V1_ZOOM_CHANGE_OUT and "
  198. "ZCR_REMOTE_SURFACE_V2_ZOOM_CHANGE_OUT should be equal");
  199. static_assert(static_cast<int>(ZCR_REMOTE_SURFACE_V1_ZOOM_CHANGE_RESET) ==
  200. static_cast<int>(ZCR_REMOTE_SURFACE_V2_ZOOM_CHANGE_RESET),
  201. "ZCR_REMOTE_SURFACE_V1_ZOOM_CHANGE_RESET and "
  202. "ZCR_REMOTE_SURFACE_V2_ZOOM_CHANGE_RESET should be equal");
  203. using chromeos::WindowStateType;
  204. // We don't send configure immediately after tablet mode switch
  205. // because layout can change due to orientation lock state or accelerometer.
  206. constexpr int kConfigureDelayAfterLayoutSwitchMs = 300;
  207. constexpr int kRemoteShellSeatObserverPriority = 0;
  208. static_assert(Seat::IsValidObserverPriority(kRemoteShellSeatObserverPriority),
  209. "kRemoteShellSeatObserverPriority is not in the valid range.");
  210. // Convert to 8.24 fixed format.
  211. int32_t To8_24Fixed(double value) {
  212. constexpr int kDecimalBits = 24;
  213. return static_cast<int32_t>(value * (1 << kDecimalBits));
  214. }
  215. ash::ShelfLayoutManager* GetShelfLayoutManagerForDisplay(
  216. const display::Display& display) {
  217. auto* root = ash::Shell::GetRootWindowForDisplayId(display.id());
  218. return ash::Shelf::ForWindow(root)->shelf_layout_manager();
  219. }
  220. int SystemUiVisibility(const display::Display& display) {
  221. auto* shelf_layout_manager = GetShelfLayoutManagerForDisplay(display);
  222. switch (shelf_layout_manager->visibility_state()) {
  223. case ash::SHELF_VISIBLE:
  224. return ZCR_REMOTE_SURFACE_V1_SYSTEMUI_VISIBILITY_STATE_VISIBLE;
  225. case ash::SHELF_AUTO_HIDE:
  226. case ash::SHELF_HIDDEN:
  227. return ZCR_REMOTE_SURFACE_V1_SYSTEMUI_VISIBILITY_STATE_AUTOHIDE_NON_STICKY;
  228. }
  229. NOTREACHED() << "Got unexpected shelf visibility state "
  230. << shelf_layout_manager->visibility_state();
  231. return 0;
  232. }
  233. int SystemUiBehavior(const display::Display& display) {
  234. auto* shelf_layout_manager = GetShelfLayoutManagerForDisplay(display);
  235. switch (shelf_layout_manager->auto_hide_behavior()) {
  236. case ash::ShelfAutoHideBehavior::kNever:
  237. return ZCR_REMOTE_OUTPUT_V1_SYSTEMUI_BEHAVIOR_VISIBLE;
  238. case ash::ShelfAutoHideBehavior::kAlways:
  239. case ash::ShelfAutoHideBehavior::kAlwaysHidden:
  240. return ZCR_REMOTE_OUTPUT_V1_SYSTEMUI_BEHAVIOR_HIDDEN;
  241. }
  242. NOTREACHED() << "Got unexpected shelf visibility behavior.";
  243. return 0;
  244. }
  245. uint32_t ResizeDirection(int component) {
  246. switch (component) {
  247. case HTCAPTION:
  248. return ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_NONE;
  249. case HTTOP:
  250. return ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_TOP;
  251. case HTTOPRIGHT:
  252. return ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_TOPRIGHT;
  253. case HTRIGHT:
  254. return ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_RIGHT;
  255. case HTBOTTOMRIGHT:
  256. return ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_BOTTOMRIGHT;
  257. case HTBOTTOM:
  258. return ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_BOTTOM;
  259. case HTBOTTOMLEFT:
  260. return ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_BOTTOMLEFT;
  261. case HTLEFT:
  262. return ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_LEFT;
  263. case HTTOPLEFT:
  264. return ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_TOPLEFT;
  265. default:
  266. LOG(ERROR) << "Unknown component:" << component;
  267. break;
  268. }
  269. NOTREACHED();
  270. return ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_NONE;
  271. }
  272. // This is a workaround for b/148977363
  273. void MaybeApplyCTSHack(int layout_mode,
  274. const gfx::Size& size_in_pixel,
  275. gfx::Insets* insets_in_client_pixel,
  276. gfx::Insets* stable_insets_in_client_pixel) {
  277. constexpr int kBadBottomInsets = 90;
  278. if (layout_mode == ZCR_REMOTE_SHELL_V1_LAYOUT_MODE_TABLET &&
  279. size_in_pixel.width() == 3000 && size_in_pixel.height() == 2000 &&
  280. stable_insets_in_client_pixel->bottom() == kBadBottomInsets) {
  281. stable_insets_in_client_pixel->set_bottom(kBadBottomInsets + 1);
  282. if (insets_in_client_pixel->bottom() == kBadBottomInsets)
  283. insets_in_client_pixel->set_bottom(kBadBottomInsets + 1);
  284. }
  285. }
  286. bool WaylandRemoteOutput::SendDisplayMetrics(const display::Display& display,
  287. uint32_t changed_metrics) {
  288. if (wl_resource_get_version(resource_) <
  289. event_mapping_.stable_insets_since_version) {
  290. return false;
  291. }
  292. if (initial_config_sent_ &&
  293. !(changed_metrics & display::DisplayObserver::DISPLAY_METRIC_WORK_AREA)) {
  294. return false;
  295. }
  296. if (!initial_config_sent_) {
  297. initial_config_sent_ = true;
  298. uint32_t display_id_hi = static_cast<uint32_t>(display.id() >> 32);
  299. uint32_t display_id_lo = static_cast<uint32_t>(display.id());
  300. if (event_mapping_.send_display_id)
  301. event_mapping_.send_display_id(resource_, display_id_hi, display_id_lo);
  302. constexpr int64_t DISPLAY_ID_PORT_MASK = 0xff;
  303. uint32_t port = static_cast<uint32_t>(display.id() & DISPLAY_ID_PORT_MASK);
  304. if (event_mapping_.send_port)
  305. event_mapping_.send_port(resource_, port);
  306. wl_array data;
  307. wl_array_init(&data);
  308. const auto& bytes =
  309. WMHelper::GetInstance()->GetDisplayIdentificationData(display.id());
  310. for (uint8_t byte : bytes) {
  311. uint8_t* ptr =
  312. static_cast<uint8_t*>(wl_array_add(&data, sizeof(uint8_t)));
  313. DCHECK(ptr);
  314. *ptr = byte;
  315. }
  316. event_mapping_.send_identification_data(resource_, &data);
  317. wl_array_release(&data);
  318. }
  319. float device_scale_factor = display.device_scale_factor();
  320. gfx::Size size_in_pixel = display.GetSizeInPixel();
  321. gfx::Insets insets_in_pixel = GetWorkAreaInsetsInPixel(
  322. display, device_scale_factor, size_in_pixel, display.work_area());
  323. event_mapping_.send_insets(resource_, insets_in_pixel.left(),
  324. insets_in_pixel.top(), insets_in_pixel.right(),
  325. insets_in_pixel.bottom());
  326. gfx::Insets stable_insets_in_pixel = GetWorkAreaInsetsInPixel(
  327. display, device_scale_factor, size_in_pixel, GetStableWorkArea(display));
  328. event_mapping_.send_stable_insets(
  329. resource_, stable_insets_in_pixel.left(), stable_insets_in_pixel.top(),
  330. stable_insets_in_pixel.right(), stable_insets_in_pixel.bottom());
  331. // Currently no client uses zcr_remote_output_v1 systemui_visibility.
  332. // Only systemui_behavior is sent here.
  333. if (wl_resource_get_version(resource_) >=
  334. event_mapping_.system_ui_behavior_since_version) {
  335. int systemui_behavior = SystemUiBehavior(display);
  336. event_mapping_.send_systemui_behavior(resource_, systemui_behavior);
  337. }
  338. return true;
  339. }
  340. void WaylandRemoteOutput::OnOutputDestroyed() {
  341. display_handler_->RemoveObserver(this);
  342. display_handler_ = nullptr;
  343. }
  344. WaylandRemoteSurfaceDelegate::WaylandRemoteSurfaceDelegate(
  345. base::WeakPtr<WaylandRemoteShell> shell,
  346. wl_resource* resource,
  347. WaylandRemoteShellEventMapping event_mapping)
  348. : shell_(std::move(shell)),
  349. resource_(resource),
  350. event_mapping_(event_mapping) {}
  351. WaylandRemoteSurfaceDelegate::~WaylandRemoteSurfaceDelegate() {
  352. if (shell_)
  353. shell_->OnRemoteSurfaceDestroyed(resource_);
  354. }
  355. // ClientControlledShellSurfaceDelegate:
  356. void WaylandRemoteSurfaceDelegate::OnGeometryChanged(
  357. const gfx::Rect& geometry) {
  358. if (shell_)
  359. shell_->OnRemoteSurfaceGeometryChanged(resource_, geometry);
  360. }
  361. void WaylandRemoteSurfaceDelegate::OnStateChanged(
  362. chromeos::WindowStateType old_state_type,
  363. chromeos::WindowStateType new_state_type) {
  364. shell_->OnRemoteSurfaceStateChanged(resource_, old_state_type,
  365. new_state_type);
  366. }
  367. void WaylandRemoteSurfaceDelegate::OnBoundsChanged(
  368. chromeos::WindowStateType current_state,
  369. chromeos::WindowStateType requested_state,
  370. int64_t display_id,
  371. const gfx::Rect& bounds_in_display,
  372. bool is_resize,
  373. int bounds_change) {
  374. if (shell_) {
  375. shell_->OnRemoteSurfaceBoundsChanged(
  376. resource_, current_state, requested_state, display_id,
  377. bounds_in_display, is_resize, bounds_change);
  378. }
  379. }
  380. void WaylandRemoteSurfaceDelegate::OnDragStarted(int component) {
  381. event_mapping_.send_drag_started(resource_, ResizeDirection(component));
  382. wl_client_flush(wl_resource_get_client(resource_));
  383. }
  384. void WaylandRemoteSurfaceDelegate::OnDragFinished(int x, int y, bool canceled) {
  385. event_mapping_.send_drag_finished(resource_, x, y, canceled ? 1 : 0);
  386. wl_client_flush(wl_resource_get_client(resource_));
  387. }
  388. void WaylandRemoteSurfaceDelegate::OnZoomLevelChanged(ZoomChange zoom_change) {
  389. if (wl_resource_get_version(resource_) >=
  390. event_mapping_.change_zoom_level_since_version &&
  391. shell_) {
  392. shell_->OnRemoteSurfaceChangeZoomLevel(resource_, zoom_change);
  393. }
  394. }
  395. WaylandRemoteOutput::WaylandRemoteOutput(
  396. wl_resource* resource,
  397. WaylandRemoteOutputEventMapping event_mapping,
  398. WaylandDisplayHandler* display_handler)
  399. : resource_(resource),
  400. event_mapping_(event_mapping),
  401. display_handler_(display_handler) {
  402. display_handler_->AddObserver(this);
  403. }
  404. WaylandRemoteOutput::~WaylandRemoteOutput() {
  405. if (display_handler_)
  406. display_handler_->RemoveObserver(this);
  407. }
  408. using OutputResourceProvider = base::RepeatingCallback<wl_resource*(int64_t)>;
  409. WaylandRemoteShell::WaylandRemoteShell(
  410. Display* display,
  411. wl_resource* remote_shell_resource,
  412. OutputResourceProvider output_provider,
  413. WaylandRemoteShellEventMapping event_mapping,
  414. bool use_default_scale_cancellation_default)
  415. : event_mapping_(event_mapping),
  416. display_(display),
  417. remote_shell_resource_(remote_shell_resource),
  418. output_provider_(output_provider),
  419. use_default_scale_cancellation_(use_default_scale_cancellation_default),
  420. seat_(display->seat()) {
  421. WMHelperChromeOS* helper = WMHelperChromeOS::GetInstance();
  422. helper->AddTabletModeObserver(this);
  423. helper->AddFrameThrottlingObserver();
  424. helper->SetDefaultScaleCancellation(use_default_scale_cancellation_);
  425. layout_mode_ = helper->InTabletMode()
  426. ? ZCR_REMOTE_SHELL_V1_LAYOUT_MODE_TABLET
  427. : ZCR_REMOTE_SHELL_V1_LAYOUT_MODE_WINDOWED;
  428. if (wl_resource_get_version(remote_shell_resource_) >=
  429. event_mapping_.layout_mode_since_version) {
  430. event_mapping_.send_layout_mode(remote_shell_resource_, layout_mode_);
  431. }
  432. if (wl_resource_get_version(remote_shell_resource_) >=
  433. event_mapping_.default_device_scale_factor_since_version) {
  434. double scale_factor = GetDefaultDeviceScaleFactor();
  435. int32_t fixed_scale = To8_24Fixed(scale_factor);
  436. event_mapping_.send_default_device_scale_factor(remote_shell_resource_,
  437. fixed_scale);
  438. }
  439. SendDisplayMetrics();
  440. // The activation event has been moved to aura_shell, but the
  441. // desktop_focus_state event is still in remote_shell, which needs to be
  442. // called before the activation event.
  443. display->seat()->AddObserver(this, kRemoteShellSeatObserverPriority);
  444. }
  445. WaylandRemoteShell::~WaylandRemoteShell() {
  446. WMHelperChromeOS* helper = WMHelperChromeOS::GetInstance();
  447. helper->RemoveTabletModeObserver(this);
  448. helper->RemoveFrameThrottlingObserver();
  449. if (seat_)
  450. seat_->RemoveObserver(this);
  451. }
  452. std::unique_ptr<ClientControlledShellSurface>
  453. WaylandRemoteShell::CreateShellSurface(Surface* surface,
  454. int container,
  455. double default_device_scale_factor) {
  456. return display_->CreateOrGetClientControlledShellSurface(
  457. surface, container, default_device_scale_factor,
  458. use_default_scale_cancellation_);
  459. }
  460. std::unique_ptr<ClientControlledShellSurface::Delegate>
  461. WaylandRemoteShell::CreateShellSurfaceDelegate(wl_resource* resource) {
  462. return std::make_unique<WaylandRemoteSurfaceDelegate>(
  463. weak_ptr_factory_.GetWeakPtr(), resource, event_mapping_);
  464. }
  465. std::unique_ptr<NotificationSurface>
  466. WaylandRemoteShell::CreateNotificationSurface(
  467. Surface* surface,
  468. const std::string& notification_key) {
  469. return display_->CreateNotificationSurface(surface, notification_key);
  470. }
  471. std::unique_ptr<InputMethodSurface>
  472. WaylandRemoteShell::CreateInputMethodSurface(
  473. Surface* surface,
  474. double default_device_scale_factor) {
  475. return display_->CreateInputMethodSurface(
  476. surface, default_device_scale_factor, use_default_scale_cancellation_);
  477. }
  478. std::unique_ptr<ToastSurface> WaylandRemoteShell::CreateToastSurface(
  479. Surface* surface,
  480. double default_device_scale_factor) {
  481. return display_->CreateToastSurface(surface, default_device_scale_factor,
  482. use_default_scale_cancellation_);
  483. }
  484. void WaylandRemoteShell::SetUseDefaultScaleCancellation(
  485. bool use_default_scale) {
  486. use_default_scale_cancellation_ = use_default_scale;
  487. WMHelper::GetInstance()->SetDefaultScaleCancellation(use_default_scale);
  488. }
  489. void WaylandRemoteShell::OnRemoteSurfaceDestroyed(wl_resource* resource) {
  490. // Sometimes resource might be destroyed after bounds change is scheduled to
  491. // |pending_bounds_change_| but before that bounds change is emitted. Erase
  492. // it from |pending_bounds_changes_| to prevent crashes. See also
  493. // https://crbug.com/1163271.
  494. pending_bounds_changes_.erase(resource);
  495. }
  496. // Overridden from display::DisplayObserver:
  497. void WaylandRemoteShell::OnWillProcessDisplayChanges() {
  498. in_display_update_ = true;
  499. }
  500. void WaylandRemoteShell::OnDidProcessDisplayChanges() {
  501. in_display_update_ = false;
  502. }
  503. void WaylandRemoteShell::OnDisplayAdded(const display::Display& new_display) {
  504. ScheduleSendDisplayMetrics(0);
  505. }
  506. void WaylandRemoteShell::OnDisplayRemoved(const display::Display& old_display) {
  507. ScheduleSendDisplayMetrics(0);
  508. }
  509. void WaylandRemoteShell::OnDisplayTabletStateChanged(
  510. display::TabletState state) {
  511. const bool layout_change_started =
  512. state == display::TabletState::kEnteringTabletMode ||
  513. state == display::TabletState::kExitingTabletMode;
  514. if (layout_change_started)
  515. ScheduleSendDisplayMetrics(kConfigureDelayAfterLayoutSwitchMs);
  516. }
  517. void WaylandRemoteShell::OnDisplayMetricsChanged(
  518. const display::Display& display,
  519. uint32_t changed_metrics) {
  520. // No need to update when a primary display has changed without bounds
  521. // change. See WaylandDisplayObserver::OnDisplayMetricsChanged
  522. // for more details.
  523. if (changed_metrics &
  524. (DISPLAY_METRIC_BOUNDS | DISPLAY_METRIC_DEVICE_SCALE_FACTOR |
  525. DISPLAY_METRIC_ROTATION | DISPLAY_METRIC_WORK_AREA)) {
  526. ScheduleSendDisplayMetrics(0);
  527. }
  528. }
  529. // Overridden from ash::TabletModeObserver:
  530. void WaylandRemoteShell::OnTabletModeStarted() {
  531. layout_mode_ = ZCR_REMOTE_SHELL_V1_LAYOUT_MODE_TABLET;
  532. if (wl_resource_get_version(remote_shell_resource_) >=
  533. event_mapping_.layout_mode_since_version)
  534. event_mapping_.send_layout_mode(remote_shell_resource_, layout_mode_);
  535. }
  536. void WaylandRemoteShell::OnTabletModeEnding() {
  537. layout_mode_ = ZCR_REMOTE_SHELL_V1_LAYOUT_MODE_WINDOWED;
  538. if (wl_resource_get_version(remote_shell_resource_) >=
  539. event_mapping_.layout_mode_since_version)
  540. event_mapping_.send_layout_mode(remote_shell_resource_, layout_mode_);
  541. }
  542. void WaylandRemoteShell::OnTabletModeEnded() {}
  543. void WaylandRemoteShell::ScheduleSendDisplayMetrics(int delay_ms) {
  544. needs_send_display_metrics_ = true;
  545. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
  546. FROM_HERE,
  547. base::BindOnce(&WaylandRemoteShell::SendDisplayMetrics,
  548. weak_ptr_factory_.GetWeakPtr()),
  549. base::Milliseconds(delay_ms));
  550. }
  551. // Returns the transform that a display's output is currently adjusted for.
  552. wl_output_transform WaylandRemoteShell::DisplayTransform(
  553. display::Display::Rotation rotation) {
  554. switch (rotation) {
  555. case display::Display::ROTATE_0:
  556. return WL_OUTPUT_TRANSFORM_NORMAL;
  557. case display::Display::ROTATE_90:
  558. return WL_OUTPUT_TRANSFORM_90;
  559. case display::Display::ROTATE_180:
  560. return WL_OUTPUT_TRANSFORM_180;
  561. case display::Display::ROTATE_270:
  562. return WL_OUTPUT_TRANSFORM_270;
  563. }
  564. NOTREACHED();
  565. return WL_OUTPUT_TRANSFORM_NORMAL;
  566. }
  567. void WaylandRemoteShell::SendDisplayMetrics() {
  568. if (!needs_send_display_metrics_)
  569. return;
  570. needs_send_display_metrics_ = false;
  571. const display::Screen* screen = display::Screen::GetScreen();
  572. double default_dsf = GetDefaultDeviceScaleFactor();
  573. for (const auto& display : screen->GetAllDisplays()) {
  574. double device_scale_factor = display.device_scale_factor();
  575. uint32_t display_id_hi = static_cast<uint32_t>(display.id() >> 32);
  576. uint32_t display_id_lo = static_cast<uint32_t>(display.id());
  577. gfx::Size size_in_pixel = display.GetSizeInPixel();
  578. wl_array data;
  579. wl_array_init(&data);
  580. const auto& bytes =
  581. WMHelper::GetInstance()->GetDisplayIdentificationData(display.id());
  582. for (uint8_t byte : bytes) {
  583. uint8_t* ptr =
  584. static_cast<uint8_t*>(wl_array_add(&data, sizeof(uint8_t)));
  585. DCHECK(ptr);
  586. *ptr = byte;
  587. }
  588. if (wl_resource_get_version(remote_shell_resource_) >=
  589. event_mapping_.send_workspace_info_since_version) {
  590. // Apply the scale factor used on the remote shell client (ARC).
  591. const gfx::Rect& bounds = display.bounds();
  592. // Note: The origin is used just to identify the workspace on the client
  593. // side, and does not account the actual pixel size of other workspace
  594. // on the client side.
  595. int x_px = base::ClampRound(bounds.x() * default_dsf);
  596. int y_px = base::ClampRound(bounds.y() * default_dsf);
  597. float server_to_client_pixel_scale = default_dsf / device_scale_factor;
  598. gfx::Size size_in_client_pixel =
  599. gfx::ScaleToRoundedSize(size_in_pixel, server_to_client_pixel_scale);
  600. gfx::Insets insets_in_client_pixel = GetWorkAreaInsetsInPixel(
  601. display, default_dsf, size_in_client_pixel, display.work_area());
  602. gfx::Insets stable_insets_in_client_pixel =
  603. GetWorkAreaInsetsInPixel(display, default_dsf, size_in_client_pixel,
  604. GetStableWorkArea(display));
  605. // TODO(b/148977363): Fix the issue and remove the hack.
  606. MaybeApplyCTSHack(layout_mode_, size_in_pixel, &insets_in_client_pixel,
  607. &stable_insets_in_client_pixel);
  608. int systemui_visibility = SystemUiVisibility(display);
  609. if (event_mapping_.send_workspace_info)
  610. event_mapping_.send_workspace_info(
  611. remote_shell_resource_, display_id_hi, display_id_lo, x_px, y_px,
  612. size_in_client_pixel.width(), size_in_client_pixel.height(),
  613. insets_in_client_pixel.left(), insets_in_client_pixel.top(),
  614. insets_in_client_pixel.right(), insets_in_client_pixel.bottom(),
  615. stable_insets_in_client_pixel.left(),
  616. stable_insets_in_client_pixel.top(),
  617. stable_insets_in_client_pixel.right(),
  618. stable_insets_in_client_pixel.bottom(), systemui_visibility,
  619. DisplayTransform(display.rotation()), display.IsInternal(), &data);
  620. } else {
  621. NOTREACHED() << "The remote shell resource version being used ("
  622. << wl_resource_get_version(remote_shell_resource_)
  623. << ") is not supported.";
  624. }
  625. wl_array_release(&data);
  626. }
  627. if (event_mapping_.send_configure)
  628. event_mapping_.send_configure(remote_shell_resource_, layout_mode_);
  629. base::flat_set<wl_client*> clients;
  630. clients.insert(wl_resource_get_client(remote_shell_resource_));
  631. for (const auto& bounds_change : pending_bounds_changes_) {
  632. SendBoundsChanged(bounds_change.first, bounds_change.second.display_id,
  633. bounds_change.second.bounds_in_display,
  634. bounds_change.second.reason);
  635. clients.insert(wl_resource_get_client(bounds_change.first));
  636. }
  637. pending_bounds_changes_.clear();
  638. for (auto* client : clients)
  639. wl_client_flush(client);
  640. }
  641. void WaylandRemoteShell::OnSurfaceFocused(Surface* gained_focus,
  642. Surface* lost_focus,
  643. bool has_focused_client) {
  644. FocusedSurfaceChanged(gained_focus, lost_focus, has_focused_client);
  645. }
  646. void WaylandRemoteShell::FocusedSurfaceChanged(Surface* gained_active_surface,
  647. Surface* lost_active_surface,
  648. bool has_focused_client) {
  649. if (gained_active_surface == lost_active_surface &&
  650. last_has_focused_client_ == has_focused_client) {
  651. return;
  652. }
  653. last_has_focused_client_ = has_focused_client;
  654. wl_resource* gained_active_surface_resource =
  655. gained_active_surface ? GetSurfaceResource(gained_active_surface)
  656. : nullptr;
  657. wl_resource* lost_active_surface_resource =
  658. lost_active_surface ? GetSurfaceResource(lost_active_surface) : nullptr;
  659. wl_client* client = wl_resource_get_client(remote_shell_resource_);
  660. // If surface that gained active is not owned by remote shell client then
  661. // set it to null.
  662. if (gained_active_surface_resource &&
  663. wl_resource_get_client(gained_active_surface_resource) != client) {
  664. gained_active_surface_resource = nullptr;
  665. }
  666. // If surface that lost active is not owned by remote shell client then
  667. // set it to null.
  668. if (lost_active_surface_resource &&
  669. wl_resource_get_client(lost_active_surface_resource) != client) {
  670. lost_active_surface_resource = nullptr;
  671. }
  672. if (wl_resource_get_version(remote_shell_resource_) >=
  673. event_mapping_.desktop_focus_state_changed_since_version) {
  674. uint32_t focus_state;
  675. if (gained_active_surface_resource) {
  676. focus_state = ZCR_REMOTE_SHELL_V1_DESKTOP_FOCUS_STATE_CLIENT_FOCUSED;
  677. } else if (has_focused_client) {
  678. focus_state =
  679. ZCR_REMOTE_SHELL_V1_DESKTOP_FOCUS_STATE_OTHER_CLIENT_FOCUSED;
  680. } else {
  681. focus_state = ZCR_REMOTE_SHELL_V1_DESKTOP_FOCUS_STATE_NO_FOCUS;
  682. }
  683. event_mapping_.send_desktop_focus_state_changed(remote_shell_resource_,
  684. focus_state);
  685. }
  686. if (event_mapping_.send_activated) {
  687. event_mapping_.send_activated(remote_shell_resource_,
  688. gained_active_surface_resource,
  689. lost_active_surface_resource);
  690. }
  691. wl_client_flush(client);
  692. }
  693. void WaylandRemoteShell::OnRemoteSurfaceBoundsChanged(
  694. wl_resource* resource,
  695. WindowStateType current_state,
  696. WindowStateType requested_state,
  697. int64_t display_id,
  698. const gfx::Rect& bounds_in_display,
  699. bool resize,
  700. int bounds_change) {
  701. zcr_remote_surface_v1_bounds_change_reason reason =
  702. ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_RESIZE;
  703. if (!resize)
  704. reason = ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_MOVE;
  705. if (current_state == WindowStateType::kPip)
  706. reason = ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_PIP;
  707. if (bounds_change & ash::WindowResizer::kBoundsChange_Resizes) {
  708. reason = ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_DRAG_RESIZE;
  709. } else if (bounds_change & ash::WindowResizer::kBoundsChange_Repositions) {
  710. reason = ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_DRAG_MOVE;
  711. }
  712. // Override the reason only if the window enters snapped mode. If the window
  713. // resizes by dragging in snapped mode, we need to keep the original reason.
  714. if (requested_state != current_state) {
  715. if (requested_state == WindowStateType::kPrimarySnapped) {
  716. reason = ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_SNAP_TO_LEFT;
  717. } else if (requested_state == WindowStateType::kSecondarySnapped) {
  718. reason = ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_SNAP_TO_RIGHT;
  719. }
  720. }
  721. if (in_display_update_ || needs_send_display_metrics_) {
  722. // We store only the latest bounds for each |resource|.
  723. pending_bounds_changes_.insert_or_assign(
  724. std::move(resource),
  725. BoundsChangeData(display_id, bounds_in_display, reason));
  726. return;
  727. }
  728. SendBoundsChanged(resource, display_id, bounds_in_display, reason);
  729. wl_client_flush(wl_resource_get_client(resource));
  730. }
  731. void WaylandRemoteShell::SendBoundsChanged(
  732. wl_resource* resource,
  733. int64_t display_id,
  734. const gfx::Rect& bounds_in_display,
  735. zcr_remote_surface_v1_bounds_change_reason reason) {
  736. if (event_mapping_.send_bounds_changed)
  737. event_mapping_.send_bounds_changed(
  738. resource, static_cast<uint32_t>(display_id >> 32),
  739. static_cast<uint32_t>(display_id), bounds_in_display.x(),
  740. bounds_in_display.y(), bounds_in_display.width(),
  741. bounds_in_display.height(), reason);
  742. if (wl_resource_get_version(resource) >=
  743. event_mapping_.bounds_changed_in_output_since_version) {
  744. wl_resource* output = output_provider_.Run(display_id);
  745. if (output == nullptr) {
  746. LOG(WARNING) << "Failed to get wayland_output resource for display_id: "
  747. << display_id;
  748. return;
  749. }
  750. event_mapping_.send_bounds_changed_in_output(
  751. resource, output, bounds_in_display.x(), bounds_in_display.y(),
  752. bounds_in_display.width(), bounds_in_display.height(), reason);
  753. }
  754. }
  755. void WaylandRemoteShell::OnRemoteSurfaceStateChanged(
  756. wl_resource* resource,
  757. WindowStateType old_state_type,
  758. WindowStateType new_state_type) {
  759. DCHECK_NE(old_state_type, new_state_type);
  760. LOG_IF(ERROR, pending_bounds_changes_.count(resource) > 0)
  761. << "Sending window state while there is a pending bounds change. This "
  762. "should not happen.";
  763. uint32_t state_type = ZCR_REMOTE_SHELL_V1_STATE_TYPE_NORMAL;
  764. switch (new_state_type) {
  765. case WindowStateType::kMinimized:
  766. state_type = ZCR_REMOTE_SHELL_V1_STATE_TYPE_MINIMIZED;
  767. break;
  768. case WindowStateType::kMaximized:
  769. state_type = ZCR_REMOTE_SHELL_V1_STATE_TYPE_MAXIMIZED;
  770. break;
  771. case WindowStateType::kFullscreen:
  772. state_type = ZCR_REMOTE_SHELL_V1_STATE_TYPE_FULLSCREEN;
  773. break;
  774. case WindowStateType::kPinned:
  775. state_type = ZCR_REMOTE_SHELL_V1_STATE_TYPE_PINNED;
  776. break;
  777. case WindowStateType::kTrustedPinned:
  778. state_type = ZCR_REMOTE_SHELL_V1_STATE_TYPE_TRUSTED_PINNED;
  779. break;
  780. case WindowStateType::kPrimarySnapped:
  781. state_type = ZCR_REMOTE_SHELL_V1_STATE_TYPE_LEFT_SNAPPED;
  782. break;
  783. case WindowStateType::kSecondarySnapped:
  784. state_type = ZCR_REMOTE_SHELL_V1_STATE_TYPE_RIGHT_SNAPPED;
  785. break;
  786. case WindowStateType::kPip:
  787. state_type = ZCR_REMOTE_SHELL_V1_STATE_TYPE_PIP;
  788. break;
  789. default:
  790. break;
  791. }
  792. event_mapping_.send_state_type_changed(resource, state_type);
  793. wl_client_flush(wl_resource_get_client(resource));
  794. }
  795. void WaylandRemoteShell::OnRemoteSurfaceChangeZoomLevel(wl_resource* resource,
  796. ZoomChange change) {
  797. int32_t value = 0;
  798. switch (change) {
  799. case ZoomChange::IN:
  800. value = ZCR_REMOTE_SURFACE_V1_ZOOM_CHANGE_IN;
  801. break;
  802. case ZoomChange::OUT:
  803. value = ZCR_REMOTE_SURFACE_V1_ZOOM_CHANGE_OUT;
  804. break;
  805. case ZoomChange::RESET:
  806. value = ZCR_REMOTE_SURFACE_V1_ZOOM_CHANGE_RESET;
  807. break;
  808. }
  809. event_mapping_.send_change_zoom_level(resource, value);
  810. wl_client_flush(wl_resource_get_client(resource));
  811. }
  812. void WaylandRemoteShell::OnRemoteSurfaceGeometryChanged(
  813. wl_resource* resource,
  814. const gfx::Rect& geometry) {
  815. LOG_IF(ERROR, pending_bounds_changes_.count(resource) > 0)
  816. << "Sending the new window geometry while there is a pending bounds "
  817. "change. This should not happen.";
  818. event_mapping_.send_window_geometry_changed(resource, geometry.x(),
  819. geometry.y(), geometry.width(),
  820. geometry.height());
  821. wl_client_flush(wl_resource_get_client(resource));
  822. }
  823. namespace switches {
  824. // This flag can be used to emulate device scale factor for remote shell.
  825. constexpr char kForceRemoteShellScale[] = "force-remote-shell-scale";
  826. } // namespace switches
  827. using chromeos::WindowStateType;
  828. namespace zcr_remote_shell {
  829. // Returns the scale factor to be used by remote shell clients.
  830. double GetDefaultDeviceScaleFactor() {
  831. // A flag used by VM to emulate a device scale for a particular board.
  832. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  833. if (command_line->HasSwitch(switches::kForceRemoteShellScale)) {
  834. std::string value =
  835. command_line->GetSwitchValueASCII(switches::kForceRemoteShellScale);
  836. double scale = 1.0;
  837. if (base::StringToDouble(value, &scale))
  838. return std::max(1.0, scale);
  839. }
  840. return WMHelper::GetInstance()->GetDefaultDeviceScaleFactor();
  841. }
  842. // Scale the |child_bounds| in such a way that if it should fill the
  843. // |parent_size|'s width/height, it returns the |parent_size_in_pixel|'s
  844. // width/height.
  845. gfx::Rect ScaleBoundsToPixelSnappedToParent(
  846. const gfx::Size& parent_size_in_pixel,
  847. const gfx::Size& parent_size,
  848. float device_scale_factor,
  849. const gfx::Rect& child_bounds) {
  850. int right = child_bounds.right();
  851. int bottom = child_bounds.bottom();
  852. int new_x = base::ClampRound(child_bounds.x() * device_scale_factor);
  853. int new_y = base::ClampRound(child_bounds.y() * device_scale_factor);
  854. int new_right = right == parent_size.width()
  855. ? parent_size_in_pixel.width()
  856. : base::ClampRound(right * device_scale_factor);
  857. int new_bottom = bottom == parent_size.height()
  858. ? parent_size_in_pixel.height()
  859. : base::ClampRound(bottom * device_scale_factor);
  860. return gfx::Rect(new_x, new_y, new_right - new_x, new_bottom - new_y);
  861. }
  862. void ScaleSkRegion(const SkRegion& src, float scale, SkRegion* dst) {
  863. SkRegion::Iterator iter(src);
  864. for (; !iter.done(); iter.next()) {
  865. SkIRect r;
  866. r.fLeft = base::ClampFloor(iter.rect().fLeft * scale);
  867. r.fTop = base::ClampFloor(iter.rect().fTop * scale);
  868. r.fRight = base::ClampCeil(iter.rect().fRight * scale);
  869. r.fBottom = base::ClampCeil(iter.rect().fBottom * scale);
  870. dst->op(r, SkRegion::kUnion_Op);
  871. }
  872. }
  873. int Component(uint32_t direction) {
  874. switch (direction) {
  875. case ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_NONE:
  876. return HTNOWHERE;
  877. case ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_TOP:
  878. return HTTOP;
  879. case ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_TOPRIGHT:
  880. return HTTOPRIGHT;
  881. case ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_RIGHT:
  882. return HTRIGHT;
  883. case ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_BOTTOMRIGHT:
  884. return HTBOTTOMRIGHT;
  885. case ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_BOTTOM:
  886. return HTBOTTOM;
  887. case ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_BOTTOMLEFT:
  888. return HTBOTTOMLEFT;
  889. case ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_LEFT:
  890. return HTLEFT;
  891. case ZCR_REMOTE_SURFACE_V1_RESIZE_DIRECTION_TOPLEFT:
  892. return HTTOPLEFT;
  893. default:
  894. VLOG(2) << "Unknown direction:" << direction;
  895. break;
  896. }
  897. return HTNOWHERE;
  898. }
  899. uint32_t CaptionButtonMask(uint32_t mask) {
  900. uint32_t caption_button_icon_mask = 0;
  901. if (mask & ZCR_REMOTE_SURFACE_V1_FRAME_BUTTON_TYPE_BACK)
  902. caption_button_icon_mask |= 1 << views::CAPTION_BUTTON_ICON_BACK;
  903. if (mask & ZCR_REMOTE_SURFACE_V1_FRAME_BUTTON_TYPE_MENU)
  904. caption_button_icon_mask |= 1 << views::CAPTION_BUTTON_ICON_MENU;
  905. if (mask & ZCR_REMOTE_SURFACE_V1_FRAME_BUTTON_TYPE_MINIMIZE)
  906. caption_button_icon_mask |= 1 << views::CAPTION_BUTTON_ICON_MINIMIZE;
  907. if (mask & ZCR_REMOTE_SURFACE_V1_FRAME_BUTTON_TYPE_MAXIMIZE_RESTORE)
  908. caption_button_icon_mask |= 1
  909. << views::CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE;
  910. if (mask & ZCR_REMOTE_SURFACE_V1_FRAME_BUTTON_TYPE_CLOSE)
  911. caption_button_icon_mask |= 1 << views::CAPTION_BUTTON_ICON_CLOSE;
  912. if (mask & ZCR_REMOTE_SURFACE_V1_FRAME_BUTTON_TYPE_ZOOM)
  913. caption_button_icon_mask |= 1 << views::CAPTION_BUTTON_ICON_ZOOM;
  914. if (mask & ZCR_REMOTE_SURFACE_V1_FRAME_BUTTON_TYPE_CENTER)
  915. caption_button_icon_mask |= 1 << views::CAPTION_BUTTON_ICON_CENTER;
  916. return caption_button_icon_mask;
  917. }
  918. ////////////////////////////////////////////////////////////////////////////////
  919. // remote_surface_interface:
  920. SurfaceFrameType RemoteShellSurfaceFrameType(uint32_t frame_type) {
  921. switch (frame_type) {
  922. case ZCR_REMOTE_SURFACE_V1_FRAME_TYPE_NONE:
  923. return SurfaceFrameType::NONE;
  924. case ZCR_REMOTE_SURFACE_V1_FRAME_TYPE_NORMAL:
  925. return SurfaceFrameType::NORMAL;
  926. case ZCR_REMOTE_SURFACE_V1_FRAME_TYPE_SHADOW:
  927. return SurfaceFrameType::SHADOW;
  928. case ZCR_REMOTE_SURFACE_V1_FRAME_TYPE_AUTOHIDE:
  929. return SurfaceFrameType::AUTOHIDE;
  930. case ZCR_REMOTE_SURFACE_V1_FRAME_TYPE_OVERLAY:
  931. return SurfaceFrameType::OVERLAY;
  932. default:
  933. VLOG(2) << "Unknown remote-shell frame type: " << frame_type;
  934. return SurfaceFrameType::NONE;
  935. }
  936. }
  937. void remote_surface_set_app_id(wl_client* client,
  938. wl_resource* resource,
  939. const char* app_id) {
  940. GetUserDataAs<ShellSurfaceBase>(resource)->SetApplicationId(app_id);
  941. }
  942. void remote_surface_set_window_geometry(wl_client* client,
  943. wl_resource* resource,
  944. int32_t x,
  945. int32_t y,
  946. int32_t width,
  947. int32_t height) {
  948. // DEPRECATED - Use set_bounds to send bounds info with a display_id.
  949. GetUserDataAs<ShellSurfaceBase>(resource)->SetGeometry(
  950. gfx::Rect(x, y, width, height));
  951. }
  952. void remote_surface_set_orientation(wl_client* client,
  953. wl_resource* resource,
  954. int32_t orientation) {
  955. GetUserDataAs<ClientControlledShellSurface>(resource)->SetOrientation(
  956. orientation == ZCR_REMOTE_SURFACE_V1_ORIENTATION_PORTRAIT
  957. ? Orientation::PORTRAIT
  958. : Orientation::LANDSCAPE);
  959. }
  960. void remote_surface_set_scale(wl_client* client,
  961. wl_resource* resource,
  962. wl_fixed_t scale) {
  963. // DEPRECATED (b/141715728) - The server updates the client's scale.
  964. GetUserDataAs<ClientControlledShellSurface>(resource)->SetScale(
  965. wl_fixed_to_double(scale));
  966. }
  967. void remote_surface_set_rectangular_shadow_DEPRECATED(wl_client* client,
  968. wl_resource* resource,
  969. int32_t x,
  970. int32_t y,
  971. int32_t width,
  972. int32_t height) {
  973. NOTREACHED();
  974. }
  975. void remote_surface_set_rectangular_shadow_background_opacity_DEPRECATED(
  976. wl_client* client,
  977. wl_resource* resource,
  978. wl_fixed_t opacity) {
  979. NOTREACHED();
  980. }
  981. void remote_surface_set_title(wl_client* client,
  982. wl_resource* resource,
  983. const char* title) {
  984. GetUserDataAs<ShellSurfaceBase>(resource)->SetTitle(
  985. std::u16string(base::UTF8ToUTF16(title)));
  986. }
  987. void remote_surface_set_top_inset(wl_client* client,
  988. wl_resource* resource,
  989. int32_t height) {
  990. GetUserDataAs<ClientControlledShellSurface>(resource)->SetTopInset(height);
  991. }
  992. void remote_surface_activate(wl_client* client,
  993. wl_resource* resource,
  994. uint32_t serial) {
  995. ShellSurfaceBase* shell_surface = GetUserDataAs<ShellSurfaceBase>(resource);
  996. shell_surface->Activate();
  997. }
  998. void remote_surface_maximize(wl_client* client, wl_resource* resource) {
  999. GetUserDataAs<ClientControlledShellSurface>(resource)->SetMaximized();
  1000. }
  1001. void remote_surface_minimize(wl_client* client, wl_resource* resource) {
  1002. GetUserDataAs<ClientControlledShellSurface>(resource)->SetMinimized();
  1003. }
  1004. void remote_surface_restore(wl_client* client, wl_resource* resource) {
  1005. GetUserDataAs<ClientControlledShellSurface>(resource)->SetRestored();
  1006. }
  1007. void remote_surface_fullscreen(wl_client* client, wl_resource* resource) {
  1008. GetUserDataAs<ClientControlledShellSurface>(resource)->SetFullscreen(true);
  1009. }
  1010. void remote_surface_unfullscreen(wl_client* client, wl_resource* resource) {
  1011. GetUserDataAs<ClientControlledShellSurface>(resource)->SetFullscreen(false);
  1012. }
  1013. void remote_surface_pin(wl_client* client,
  1014. wl_resource* resource,
  1015. int32_t trusted) {
  1016. GetUserDataAs<ClientControlledShellSurface>(resource)->SetPinned(
  1017. trusted ? chromeos::WindowPinType::kTrustedPinned
  1018. : chromeos::WindowPinType::kPinned);
  1019. }
  1020. void remote_surface_unpin(wl_client* client, wl_resource* resource) {
  1021. GetUserDataAs<ClientControlledShellSurface>(resource)->SetPinned(
  1022. chromeos::WindowPinType::kNone);
  1023. }
  1024. void remote_surface_set_system_modal(wl_client* client, wl_resource* resource) {
  1025. GetUserDataAs<ClientControlledShellSurface>(resource)->SetSystemModal(true);
  1026. }
  1027. void remote_surface_unset_system_modal(wl_client* client,
  1028. wl_resource* resource) {
  1029. GetUserDataAs<ClientControlledShellSurface>(resource)->SetSystemModal(false);
  1030. }
  1031. void remote_surface_set_rectangular_surface_shadow(wl_client* client,
  1032. wl_resource* resource,
  1033. int32_t x,
  1034. int32_t y,
  1035. int32_t width,
  1036. int32_t height) {
  1037. // Shadow Bounds are set in pixels, and should not be scaled.
  1038. ClientControlledShellSurface* shell_surface =
  1039. GetUserDataAs<ClientControlledShellSurface>(resource);
  1040. shell_surface->SetShadowBounds(gfx::Rect(x, y, width, height));
  1041. }
  1042. void remote_surface_set_systemui_visibility(wl_client* client,
  1043. wl_resource* resource,
  1044. uint32_t visibility) {
  1045. GetUserDataAs<ClientControlledShellSurface>(resource)->SetSystemUiVisibility(
  1046. visibility != ZCR_REMOTE_SURFACE_V1_SYSTEMUI_VISIBILITY_STATE_VISIBLE);
  1047. }
  1048. void remote_surface_set_always_on_top(wl_client* client,
  1049. wl_resource* resource) {
  1050. GetUserDataAs<ClientControlledShellSurface>(resource)->SetAlwaysOnTop(true);
  1051. }
  1052. void remote_surface_unset_always_on_top(wl_client* client,
  1053. wl_resource* resource) {
  1054. GetUserDataAs<ClientControlledShellSurface>(resource)->SetAlwaysOnTop(false);
  1055. }
  1056. void remote_surface_ack_configure_DEPRECATED(wl_client* client,
  1057. wl_resource* resource,
  1058. uint32_t serial) {
  1059. NOTREACHED();
  1060. }
  1061. void remote_surface_move_DEPRECATED(wl_client* client, wl_resource* resource) {
  1062. NOTREACHED();
  1063. }
  1064. void remote_surface_set_window_type(wl_client* client,
  1065. wl_resource* resource,
  1066. uint32_t type) {
  1067. auto* widget = GetUserDataAs<ShellSurfaceBase>(resource)->GetWidget();
  1068. if (!widget)
  1069. return;
  1070. switch (type) {
  1071. case ZCR_REMOTE_SURFACE_V1_WINDOW_TYPE_NORMAL:
  1072. widget->GetNativeWindow()->SetProperty(ash::kHideInOverviewKey, false);
  1073. break;
  1074. case ZCR_REMOTE_SURFACE_V1_WINDOW_TYPE_SYSTEM_UI:
  1075. // TODO(takise): Consider removing this as this window type was added for
  1076. // the old assistant and is not longer used.
  1077. widget->GetNativeWindow()->SetProperty(ash::kHideInOverviewKey, true);
  1078. wm::SetWindowVisibilityAnimationType(
  1079. widget->GetNativeWindow(), wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
  1080. break;
  1081. case ZCR_REMOTE_SURFACE_V1_WINDOW_TYPE_HIDDEN_IN_OVERVIEW:
  1082. widget->GetNativeWindow()->SetProperty(ash::kHideInOverviewKey, true);
  1083. break;
  1084. }
  1085. }
  1086. void remote_surface_resize_DEPRECATED(wl_client* client,
  1087. wl_resource* resource) {
  1088. // DEPRECATED
  1089. NOTREACHED();
  1090. }
  1091. void remote_surface_set_resize_outset_DEPRECATED(wl_client* client,
  1092. wl_resource* resource,
  1093. int32_t outset) {
  1094. // DEPRECATED
  1095. NOTREACHED();
  1096. }
  1097. void remote_surface_start_move(wl_client* client,
  1098. wl_resource* resource,
  1099. int32_t x,
  1100. int32_t y) {
  1101. ClientControlledShellSurface* shell_surface =
  1102. GetUserDataAs<ClientControlledShellSurface>(resource);
  1103. float scale = shell_surface->GetClientToDpScale();
  1104. gfx::PointF p(x, y);
  1105. shell_surface->StartDrag(HTCAPTION, gfx::ScalePoint(p, scale));
  1106. }
  1107. void remote_surface_set_can_maximize(wl_client* client, wl_resource* resource) {
  1108. GetUserDataAs<ClientControlledShellSurface>(resource)->SetCanMaximize(true);
  1109. }
  1110. void remote_surface_unset_can_maximize(wl_client* client,
  1111. wl_resource* resource) {
  1112. GetUserDataAs<ClientControlledShellSurface>(resource)->SetCanMaximize(false);
  1113. }
  1114. void remote_surface_set_min_size(wl_client* client,
  1115. wl_resource* resource,
  1116. int32_t width,
  1117. int32_t height) {
  1118. ClientControlledShellSurface* shell_surface =
  1119. GetUserDataAs<ClientControlledShellSurface>(resource);
  1120. float scale = shell_surface->GetClientToDpScale();
  1121. gfx::Size s(width, height);
  1122. shell_surface->SetMinimumSize(gfx::ScaleToRoundedSize(s, scale));
  1123. }
  1124. void remote_surface_set_max_size(wl_client* client,
  1125. wl_resource* resource,
  1126. int32_t width,
  1127. int32_t height) {
  1128. ClientControlledShellSurface* shell_surface =
  1129. GetUserDataAs<ClientControlledShellSurface>(resource);
  1130. float scale = shell_surface->GetClientToDpScale();
  1131. gfx::Size s(width, height);
  1132. shell_surface->SetMaximumSize(gfx::ScaleToRoundedSize(s, scale));
  1133. }
  1134. void remote_surface_set_aspect_ratio(wl_client* client,
  1135. wl_resource* resource,
  1136. int32_t aspect_ratio_width,
  1137. int32_t aspect_ratio_height) {
  1138. GetUserDataAs<ClientControlledShellSurface>(resource)->SetAspectRatio(
  1139. gfx::SizeF(aspect_ratio_width, aspect_ratio_height));
  1140. }
  1141. void remote_surface_set_snapped_to_left(wl_client* client,
  1142. wl_resource* resource) {
  1143. GetUserDataAs<ClientControlledShellSurface>(resource)->SetSnappedToPrimary();
  1144. }
  1145. void remote_surface_set_snapped_to_right(wl_client* client,
  1146. wl_resource* resource) {
  1147. GetUserDataAs<ClientControlledShellSurface>(resource)
  1148. ->SetSnappedToSecondary();
  1149. }
  1150. void remote_surface_start_resize(wl_client* client,
  1151. wl_resource* resource,
  1152. uint32_t direction,
  1153. int32_t x,
  1154. int32_t y) {
  1155. ClientControlledShellSurface* shell_surface =
  1156. GetUserDataAs<ClientControlledShellSurface>(resource);
  1157. float scale = shell_surface->GetClientToDpScale();
  1158. gfx::PointF p(x, y);
  1159. shell_surface->StartDrag(Component(direction), gfx::ScalePoint(p, scale));
  1160. }
  1161. void remote_surface_set_frame(wl_client* client,
  1162. wl_resource* resource,
  1163. uint32_t type) {
  1164. ClientControlledShellSurface* shell_surface =
  1165. GetUserDataAs<ClientControlledShellSurface>(resource);
  1166. shell_surface->root_surface()->SetFrame(RemoteShellSurfaceFrameType(type));
  1167. }
  1168. void remote_surface_set_frame_buttons(wl_client* client,
  1169. wl_resource* resource,
  1170. uint32_t visible_button_mask,
  1171. uint32_t enabled_button_mask) {
  1172. GetUserDataAs<ClientControlledShellSurface>(resource)->SetFrameButtons(
  1173. CaptionButtonMask(visible_button_mask),
  1174. CaptionButtonMask(enabled_button_mask));
  1175. }
  1176. void remote_surface_set_extra_title(wl_client* client,
  1177. wl_resource* resource,
  1178. const char* extra_title) {
  1179. GetUserDataAs<ClientControlledShellSurface>(resource)->SetExtraTitle(
  1180. std::u16string(base::UTF8ToUTF16(extra_title)));
  1181. }
  1182. chromeos::OrientationType OrientationLock(uint32_t orientation_lock) {
  1183. switch (orientation_lock) {
  1184. case ZCR_REMOTE_SURFACE_V1_ORIENTATION_LOCK_NONE:
  1185. return chromeos::OrientationType::kAny;
  1186. case ZCR_REMOTE_SURFACE_V1_ORIENTATION_LOCK_CURRENT:
  1187. return chromeos::OrientationType::kCurrent;
  1188. case ZCR_REMOTE_SURFACE_V1_ORIENTATION_LOCK_PORTRAIT:
  1189. return chromeos::OrientationType::kPortrait;
  1190. case ZCR_REMOTE_SURFACE_V1_ORIENTATION_LOCK_LANDSCAPE:
  1191. return chromeos::OrientationType::kLandscape;
  1192. case ZCR_REMOTE_SURFACE_V1_ORIENTATION_LOCK_PORTRAIT_PRIMARY:
  1193. return chromeos::OrientationType::kPortraitPrimary;
  1194. case ZCR_REMOTE_SURFACE_V1_ORIENTATION_LOCK_PORTRAIT_SECONDARY:
  1195. return chromeos::OrientationType::kPortraitSecondary;
  1196. case ZCR_REMOTE_SURFACE_V1_ORIENTATION_LOCK_LANDSCAPE_PRIMARY:
  1197. return chromeos::OrientationType::kLandscapePrimary;
  1198. case ZCR_REMOTE_SURFACE_V1_ORIENTATION_LOCK_LANDSCAPE_SECONDARY:
  1199. return chromeos::OrientationType::kLandscapeSecondary;
  1200. }
  1201. VLOG(2) << "Unexpected value of orientation_lock: " << orientation_lock;
  1202. return chromeos::OrientationType::kAny;
  1203. }
  1204. void remote_surface_set_orientation_lock(wl_client* client,
  1205. wl_resource* resource,
  1206. uint32_t orientation_lock) {
  1207. GetUserDataAs<ClientControlledShellSurface>(resource)->SetOrientationLock(
  1208. OrientationLock(orientation_lock));
  1209. }
  1210. void remote_surface_pip(wl_client* client, wl_resource* resource) {
  1211. GetUserDataAs<ClientControlledShellSurface>(resource)->SetPip();
  1212. }
  1213. void remote_surface_set_bounds(wl_client* client,
  1214. wl_resource* resource,
  1215. uint32_t display_id_hi,
  1216. uint32_t display_id_lo,
  1217. int32_t x,
  1218. int32_t y,
  1219. int32_t width,
  1220. int32_t height) {
  1221. // Bounds are set in pixels, and should not be scaled.
  1222. GetUserDataAs<ClientControlledShellSurface>(resource)->SetBounds(
  1223. static_cast<int64_t>(display_id_hi) << 32 | display_id_lo,
  1224. gfx::Rect(x, y, width, height));
  1225. }
  1226. void remote_surface_block_ime(wl_client* client, wl_resource* resource) {
  1227. NOTIMPLEMENTED();
  1228. }
  1229. void remote_surface_unblock_ime(wl_client* client, wl_resource* resource) {
  1230. NOTIMPLEMENTED();
  1231. }
  1232. void remote_surface_set_accessibility_id(wl_client* client,
  1233. wl_resource* resource,
  1234. int32_t accessibility_id) {
  1235. GetUserDataAs<ClientControlledShellSurface>(resource)
  1236. ->SetClientAccessibilityId(accessibility_id);
  1237. }
  1238. void remote_surface_set_pip_original_window(wl_client* client,
  1239. wl_resource* resource) {
  1240. auto* widget = GetUserDataAs<ShellSurfaceBase>(resource)->GetWidget();
  1241. if (!widget) {
  1242. LOG(ERROR) << "no widget found for setting pip original window";
  1243. return;
  1244. }
  1245. widget->GetNativeWindow()->SetProperty(ash::kPipOriginalWindowKey, true);
  1246. }
  1247. void remote_surface_unset_pip_original_window(wl_client* client,
  1248. wl_resource* resource) {
  1249. auto* widget = GetUserDataAs<ShellSurfaceBase>(resource)->GetWidget();
  1250. if (!widget) {
  1251. LOG(ERROR) << "no widget found for unsetting pip original window";
  1252. return;
  1253. }
  1254. widget->GetNativeWindow()->SetProperty(ash::kPipOriginalWindowKey, false);
  1255. }
  1256. void remote_surface_set_system_gesture_exclusion(wl_client* client,
  1257. wl_resource* resource,
  1258. wl_resource* region_resource) {
  1259. auto* shell_surface = GetUserDataAs<ClientControlledShellSurface>(resource);
  1260. auto* widget = shell_surface->GetWidget();
  1261. if (!widget) {
  1262. LOG(ERROR) << "no widget found for setting system gesture exclusion";
  1263. return;
  1264. }
  1265. if (region_resource) {
  1266. SkRegion* dst = new SkRegion;
  1267. ScaleSkRegion(*GetUserDataAs<SkRegion>(region_resource),
  1268. shell_surface->GetClientToDpScale(), dst);
  1269. widget->GetNativeWindow()->SetProperty(ash::kSystemGestureExclusionKey,
  1270. dst);
  1271. } else {
  1272. widget->GetNativeWindow()->ClearProperty(ash::kSystemGestureExclusionKey);
  1273. }
  1274. }
  1275. void remote_surface_set_resize_lock(wl_client* client, wl_resource* resource) {
  1276. GetUserDataAs<ClientControlledShellSurface>(resource)->SetResizeLockType(
  1277. ash::ArcResizeLockType::RESIZE_DISABLED_TOGGLABLE);
  1278. }
  1279. void remote_surface_unset_resize_lock(wl_client* client,
  1280. wl_resource* resource) {
  1281. GetUserDataAs<ClientControlledShellSurface>(resource)->SetResizeLockType(
  1282. ash::ArcResizeLockType::NONE);
  1283. }
  1284. void remote_surface_set_bounds_in_output(wl_client* client,
  1285. wl_resource* resource,
  1286. wl_resource* output_resource,
  1287. int32_t x,
  1288. int32_t y,
  1289. int32_t width,
  1290. int32_t height) {
  1291. WaylandDisplayHandler* display_handler =
  1292. GetUserDataAs<WaylandDisplayHandler>(output_resource);
  1293. // Bounds are set in pixels, and should not be scaled.
  1294. GetUserDataAs<ClientControlledShellSurface>(resource)->SetBounds(
  1295. display_handler->id(), gfx::Rect(x, y, width, height));
  1296. }
  1297. void remote_surface_set_resize_lock_type(wl_client* client,
  1298. wl_resource* resource,
  1299. uint32_t type) {
  1300. GetUserDataAs<ClientControlledShellSurface>(resource)->SetResizeLockType(
  1301. static_cast<ash::ArcResizeLockType>(type));
  1302. }
  1303. ////////////////////////////////////////////////////////////////////////////////
  1304. // notification_surface_interface:
  1305. void notification_surface_set_app_id(wl_client* client,
  1306. wl_resource* resource,
  1307. const char* app_id) {
  1308. GetUserDataAs<NotificationSurface>(resource)->SetApplicationId(app_id);
  1309. }
  1310. ////////////////////////////////////////////////////////////////////////////////
  1311. // input_method_surface_interface:
  1312. void input_method_surface_set_bounds(wl_client* client,
  1313. wl_resource* resource,
  1314. uint32_t display_id_hi,
  1315. uint32_t display_id_lo,
  1316. int32_t x,
  1317. int32_t y,
  1318. int32_t width,
  1319. int32_t height) {
  1320. GetUserDataAs<InputMethodSurface>(resource)->SetBounds(
  1321. static_cast<int64_t>(display_id_hi) << 32 | display_id_lo,
  1322. gfx::Rect(x, y, width, height));
  1323. }
  1324. void input_method_surface_set_bounds_in_output(wl_client* client,
  1325. wl_resource* resource,
  1326. wl_resource* output_resource,
  1327. int32_t x,
  1328. int32_t y,
  1329. int32_t width,
  1330. int32_t height) {
  1331. WaylandDisplayHandler* display_handler =
  1332. GetUserDataAs<WaylandDisplayHandler>(output_resource);
  1333. GetUserDataAs<InputMethodSurface>(resource)->SetBounds(
  1334. display_handler->id(), gfx::Rect(x, y, width, height));
  1335. }
  1336. ////////////////////////////////////////////////////////////////////////////////
  1337. // toast_surface_interface:
  1338. void toast_surface_set_position(wl_client* client,
  1339. wl_resource* resource,
  1340. uint32_t display_id_hi,
  1341. uint32_t display_id_lo,
  1342. int32_t x,
  1343. int32_t y) {
  1344. const int64_t display_id =
  1345. static_cast<int64_t>(display_id_hi) << 32 | display_id_lo;
  1346. GetUserDataAs<ToastSurface>(resource)->SetBoundsOrigin(display_id,
  1347. gfx::Point(x, y));
  1348. }
  1349. void toast_surface_set_size(wl_client* client,
  1350. wl_resource* resource,
  1351. int32_t width,
  1352. int32_t height) {
  1353. GetUserDataAs<ToastSurface>(resource)->SetBoundsSize(
  1354. gfx::Size(width, height));
  1355. }
  1356. void toast_surface_set_bounds_in_output(wl_client* client,
  1357. wl_resource* resource,
  1358. wl_resource* output_resource,
  1359. int32_t x,
  1360. int32_t y,
  1361. int32_t width,
  1362. int32_t height) {
  1363. WaylandDisplayHandler* display_handler =
  1364. GetUserDataAs<WaylandDisplayHandler>(output_resource);
  1365. GetUserDataAs<ToastSurface>(resource)->SetBounds(
  1366. display_handler->id(), gfx::Rect(x, y, width, height));
  1367. }
  1368. ////////////////////////////////////////////////////////////////////////////////
  1369. // remote_shell_interface:
  1370. void remote_shell_set_use_default_scale_cancellation(
  1371. wl_client*,
  1372. wl_resource* resource,
  1373. int32_t use_default_scale_cancellation) {
  1374. auto* shell = GetUserDataAs<WaylandRemoteShell>(resource);
  1375. if (wl_resource_get_version(resource) <
  1376. shell->event_mapping_.set_use_default_scale_cancellation_since_version) {
  1377. return;
  1378. }
  1379. shell->SetUseDefaultScaleCancellation(use_default_scale_cancellation != 0);
  1380. }
  1381. } // namespace zcr_remote_shell
  1382. } // namespace wayland
  1383. } // namespace exo