window.cpp 124 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506
  1. /**************************************************************************/
  2. /* window.cpp */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /**************************************************************************/
  30. #include "window.h"
  31. #include "core/config/project_settings.h"
  32. #include "core/debugger/engine_debugger.h"
  33. #include "core/string/translation_server.h"
  34. #include "scene/gui/control.h"
  35. #include "scene/theme/theme_db.h"
  36. #include "scene/theme/theme_owner.h"
  37. // Editor integration.
  38. int Window::root_layout_direction = 0;
  39. void Window::set_root_layout_direction(int p_root_dir) {
  40. root_layout_direction = p_root_dir;
  41. }
  42. // Dynamic properties.
  43. Window *Window::focused_window = nullptr;
  44. bool Window::_set(const StringName &p_name, const Variant &p_value) {
  45. ERR_MAIN_THREAD_GUARD_V(false);
  46. String name = p_name;
  47. if (!name.begins_with("theme_override")) {
  48. return false;
  49. }
  50. if (p_value.get_type() == Variant::NIL || (p_value.get_type() == Variant::OBJECT && (Object *)p_value == nullptr)) {
  51. if (name.begins_with("theme_override_icons/")) {
  52. String dname = name.get_slicec('/', 1);
  53. if (theme_icon_override.has(dname)) {
  54. theme_icon_override[dname]->disconnect_changed(callable_mp(this, &Window::_notify_theme_override_changed));
  55. }
  56. theme_icon_override.erase(dname);
  57. _notify_theme_override_changed();
  58. } else if (name.begins_with("theme_override_styles/")) {
  59. String dname = name.get_slicec('/', 1);
  60. if (theme_style_override.has(dname)) {
  61. theme_style_override[dname]->disconnect_changed(callable_mp(this, &Window::_notify_theme_override_changed));
  62. }
  63. theme_style_override.erase(dname);
  64. _notify_theme_override_changed();
  65. } else if (name.begins_with("theme_override_fonts/")) {
  66. String dname = name.get_slicec('/', 1);
  67. if (theme_font_override.has(dname)) {
  68. theme_font_override[dname]->disconnect_changed(callable_mp(this, &Window::_notify_theme_override_changed));
  69. }
  70. theme_font_override.erase(dname);
  71. _notify_theme_override_changed();
  72. } else if (name.begins_with("theme_override_font_sizes/")) {
  73. String dname = name.get_slicec('/', 1);
  74. theme_font_size_override.erase(dname);
  75. _notify_theme_override_changed();
  76. } else if (name.begins_with("theme_override_colors/")) {
  77. String dname = name.get_slicec('/', 1);
  78. theme_color_override.erase(dname);
  79. _notify_theme_override_changed();
  80. } else if (name.begins_with("theme_override_constants/")) {
  81. String dname = name.get_slicec('/', 1);
  82. theme_constant_override.erase(dname);
  83. _notify_theme_override_changed();
  84. } else {
  85. return false;
  86. }
  87. } else {
  88. if (name.begins_with("theme_override_icons/")) {
  89. String dname = name.get_slicec('/', 1);
  90. add_theme_icon_override(dname, p_value);
  91. } else if (name.begins_with("theme_override_styles/")) {
  92. String dname = name.get_slicec('/', 1);
  93. add_theme_style_override(dname, p_value);
  94. } else if (name.begins_with("theme_override_fonts/")) {
  95. String dname = name.get_slicec('/', 1);
  96. add_theme_font_override(dname, p_value);
  97. } else if (name.begins_with("theme_override_font_sizes/")) {
  98. String dname = name.get_slicec('/', 1);
  99. add_theme_font_size_override(dname, p_value);
  100. } else if (name.begins_with("theme_override_colors/")) {
  101. String dname = name.get_slicec('/', 1);
  102. add_theme_color_override(dname, p_value);
  103. } else if (name.begins_with("theme_override_constants/")) {
  104. String dname = name.get_slicec('/', 1);
  105. add_theme_constant_override(dname, p_value);
  106. } else {
  107. return false;
  108. }
  109. }
  110. return true;
  111. }
  112. bool Window::_get(const StringName &p_name, Variant &r_ret) const {
  113. ERR_READ_THREAD_GUARD_V(false);
  114. String sname = p_name;
  115. if (!sname.begins_with("theme_override")) {
  116. return false;
  117. }
  118. if (sname.begins_with("theme_override_icons/")) {
  119. String name = sname.get_slicec('/', 1);
  120. r_ret = theme_icon_override.has(name) ? Variant(theme_icon_override[name]) : Variant();
  121. } else if (sname.begins_with("theme_override_styles/")) {
  122. String name = sname.get_slicec('/', 1);
  123. r_ret = theme_style_override.has(name) ? Variant(theme_style_override[name]) : Variant();
  124. } else if (sname.begins_with("theme_override_fonts/")) {
  125. String name = sname.get_slicec('/', 1);
  126. r_ret = theme_font_override.has(name) ? Variant(theme_font_override[name]) : Variant();
  127. } else if (sname.begins_with("theme_override_font_sizes/")) {
  128. String name = sname.get_slicec('/', 1);
  129. r_ret = theme_font_size_override.has(name) ? Variant(theme_font_size_override[name]) : Variant();
  130. } else if (sname.begins_with("theme_override_colors/")) {
  131. String name = sname.get_slicec('/', 1);
  132. r_ret = theme_color_override.has(name) ? Variant(theme_color_override[name]) : Variant();
  133. } else if (sname.begins_with("theme_override_constants/")) {
  134. String name = sname.get_slicec('/', 1);
  135. r_ret = theme_constant_override.has(name) ? Variant(theme_constant_override[name]) : Variant();
  136. } else {
  137. return false;
  138. }
  139. return true;
  140. }
  141. void Window::_get_property_list(List<PropertyInfo> *p_list) const {
  142. ERR_READ_THREAD_GUARD;
  143. Ref<Theme> default_theme = ThemeDB::get_singleton()->get_default_theme();
  144. p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Theme Overrides", "theme_override_"), PROPERTY_HINT_NONE, "theme_override_", PROPERTY_USAGE_GROUP));
  145. {
  146. List<StringName> names;
  147. default_theme->get_color_list(get_class_name(), &names);
  148. for (const StringName &E : names) {
  149. uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
  150. if (theme_color_override.has(E)) {
  151. usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
  152. }
  153. p_list->push_back(PropertyInfo(Variant::COLOR, PNAME("theme_override_colors") + String("/") + E, PROPERTY_HINT_NONE, "", usage));
  154. }
  155. }
  156. {
  157. List<StringName> names;
  158. default_theme->get_constant_list(get_class_name(), &names);
  159. for (const StringName &E : names) {
  160. uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
  161. if (theme_constant_override.has(E)) {
  162. usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
  163. }
  164. p_list->push_back(PropertyInfo(Variant::INT, PNAME("theme_override_constants") + String("/") + E, PROPERTY_HINT_RANGE, "-16384,16384", usage));
  165. }
  166. }
  167. {
  168. List<StringName> names;
  169. default_theme->get_font_list(get_class_name(), &names);
  170. for (const StringName &E : names) {
  171. uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
  172. if (theme_font_override.has(E)) {
  173. usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
  174. }
  175. p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_fonts") + String("/") + E, PROPERTY_HINT_RESOURCE_TYPE, "Font", usage));
  176. }
  177. }
  178. {
  179. List<StringName> names;
  180. default_theme->get_font_size_list(get_class_name(), &names);
  181. for (const StringName &E : names) {
  182. uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
  183. if (theme_font_size_override.has(E)) {
  184. usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
  185. }
  186. p_list->push_back(PropertyInfo(Variant::INT, PNAME("theme_override_font_sizes") + String("/") + E, PROPERTY_HINT_RANGE, "1,256,1,or_greater,suffix:px", usage));
  187. }
  188. }
  189. {
  190. List<StringName> names;
  191. default_theme->get_icon_list(get_class_name(), &names);
  192. for (const StringName &E : names) {
  193. uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
  194. if (theme_icon_override.has(E)) {
  195. usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
  196. }
  197. p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_icons") + String("/") + E, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", usage));
  198. }
  199. }
  200. {
  201. List<StringName> names;
  202. default_theme->get_stylebox_list(get_class_name(), &names);
  203. for (const StringName &E : names) {
  204. uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
  205. if (theme_style_override.has(E)) {
  206. usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
  207. }
  208. p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_styles") + String("/") + E, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", usage));
  209. }
  210. }
  211. }
  212. void Window::_validate_property(PropertyInfo &p_property) const {
  213. if (p_property.name == "position") {
  214. if (initial_position != WINDOW_INITIAL_POSITION_ABSOLUTE) {
  215. p_property.usage = PROPERTY_USAGE_NONE;
  216. }
  217. } else if (p_property.name == "current_screen") {
  218. if (initial_position != WINDOW_INITIAL_POSITION_CENTER_OTHER_SCREEN) {
  219. p_property.usage = PROPERTY_USAGE_NONE;
  220. }
  221. } else if (Engine::get_singleton()->is_editor_hint() && p_property.name == "theme_type_variation") {
  222. List<StringName> names;
  223. ThemeDB::get_singleton()->get_default_theme()->get_type_variation_list(get_class_name(), &names);
  224. // Iterate to find all themes.
  225. Control *tmp_control = Object::cast_to<Control>(get_parent());
  226. Window *tmp_window = Object::cast_to<Window>(get_parent());
  227. while (tmp_control || tmp_window) {
  228. // We go up and any non Control/Window will break the chain.
  229. if (tmp_control) {
  230. if (tmp_control->get_theme().is_valid()) {
  231. tmp_control->get_theme()->get_type_variation_list(get_class_name(), &names);
  232. }
  233. tmp_window = Object::cast_to<Window>(tmp_control->get_parent());
  234. tmp_control = Object::cast_to<Control>(tmp_control->get_parent());
  235. } else { // Window.
  236. if (tmp_window->get_theme().is_valid()) {
  237. tmp_window->get_theme()->get_type_variation_list(get_class_name(), &names);
  238. }
  239. tmp_control = Object::cast_to<Control>(tmp_window->get_parent());
  240. tmp_window = Object::cast_to<Window>(tmp_window->get_parent());
  241. }
  242. }
  243. if (get_theme().is_valid()) {
  244. get_theme()->get_type_variation_list(get_class_name(), &names);
  245. }
  246. if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
  247. ThemeDB::get_singleton()->get_project_theme()->get_type_variation_list(get_class_name(), &names);
  248. }
  249. names.sort_custom<StringName::AlphCompare>();
  250. Vector<StringName> unique_names;
  251. String hint_string;
  252. for (const StringName &E : names) {
  253. // Skip duplicate values.
  254. if (unique_names.has(E)) {
  255. continue;
  256. }
  257. hint_string += String(E) + ",";
  258. unique_names.append(E);
  259. }
  260. p_property.hint_string = hint_string;
  261. }
  262. }
  263. //
  264. Window *Window::get_from_id(DisplayServer::WindowID p_window_id) {
  265. if (p_window_id == DisplayServer::INVALID_WINDOW_ID) {
  266. return nullptr;
  267. }
  268. return ObjectDB::get_instance<Window>(DisplayServer::get_singleton()->window_get_attached_instance_id(p_window_id));
  269. }
  270. void Window::set_title(const String &p_title) {
  271. ERR_MAIN_THREAD_GUARD;
  272. title = p_title;
  273. _update_displayed_title();
  274. emit_signal("title_changed");
  275. }
  276. String Window::get_title() const {
  277. ERR_READ_THREAD_GUARD_V(String());
  278. return title;
  279. }
  280. String Window::get_displayed_title() const {
  281. ERR_READ_THREAD_GUARD_V(String());
  282. return displayed_title;
  283. }
  284. void Window::_settings_changed() {
  285. if (visible && initial_position != WINDOW_INITIAL_POSITION_ABSOLUTE && is_in_edited_scene_root()) {
  286. Size2 screen_size = Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height"));
  287. position = (screen_size - size) / 2;
  288. if (embedder) {
  289. embedder->_sub_window_update(this);
  290. }
  291. }
  292. }
  293. void Window::set_initial_position(Window::WindowInitialPosition p_initial_position) {
  294. ERR_MAIN_THREAD_GUARD;
  295. initial_position = p_initial_position;
  296. _settings_changed();
  297. notify_property_list_changed();
  298. }
  299. Window::WindowInitialPosition Window::get_initial_position() const {
  300. ERR_READ_THREAD_GUARD_V(WINDOW_INITIAL_POSITION_ABSOLUTE);
  301. return initial_position;
  302. }
  303. void Window::set_current_screen(int p_screen) {
  304. ERR_MAIN_THREAD_GUARD;
  305. current_screen = p_screen;
  306. if (window_id == DisplayServer::INVALID_WINDOW_ID) {
  307. return;
  308. }
  309. DisplayServer::get_singleton()->window_set_current_screen(p_screen, window_id);
  310. }
  311. int Window::get_current_screen() const {
  312. ERR_READ_THREAD_GUARD_V(0);
  313. if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  314. current_screen = DisplayServer::get_singleton()->window_get_current_screen(window_id);
  315. }
  316. return current_screen;
  317. }
  318. void Window::set_position(const Point2i &p_position) {
  319. ERR_MAIN_THREAD_GUARD;
  320. position = p_position;
  321. if (embedder) {
  322. embedder->_sub_window_update(this);
  323. } else if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  324. DisplayServer::get_singleton()->window_set_position(p_position, window_id);
  325. }
  326. }
  327. Point2i Window::get_position() const {
  328. ERR_READ_THREAD_GUARD_V(Point2i());
  329. return position;
  330. }
  331. void Window::move_to_center() {
  332. ERR_MAIN_THREAD_GUARD;
  333. ERR_FAIL_COND(!is_inside_tree());
  334. Rect2 parent_rect;
  335. if (is_embedded()) {
  336. parent_rect = get_embedder()->get_visible_rect();
  337. } else {
  338. int parent_screen = DisplayServer::get_singleton()->window_get_current_screen(get_window_id());
  339. parent_rect.position = DisplayServer::get_singleton()->screen_get_position(parent_screen);
  340. parent_rect.size = DisplayServer::get_singleton()->screen_get_size(parent_screen);
  341. }
  342. if (parent_rect != Rect2()) {
  343. set_position(parent_rect.position + (parent_rect.size - get_size()) / 2);
  344. }
  345. }
  346. void Window::set_size(const Size2i &p_size) {
  347. ERR_MAIN_THREAD_GUARD;
  348. #if defined(ANDROID_ENABLED)
  349. if (!get_parent() && is_inside_tree()) {
  350. // Can't set root window size on Android.
  351. return;
  352. }
  353. #endif
  354. size = p_size;
  355. _update_window_size();
  356. _settings_changed();
  357. }
  358. Size2i Window::get_size() const {
  359. ERR_READ_THREAD_GUARD_V(Size2i());
  360. return size;
  361. }
  362. void Window::reset_size() {
  363. ERR_MAIN_THREAD_GUARD;
  364. set_size(Size2i());
  365. }
  366. Point2i Window::get_position_with_decorations() const {
  367. ERR_READ_THREAD_GUARD_V(Point2i());
  368. if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  369. return DisplayServer::get_singleton()->window_get_position_with_decorations(window_id);
  370. }
  371. if (visible && is_embedded() && !get_flag(Window::FLAG_BORDERLESS)) {
  372. Size2 border_offset;
  373. if (theme_cache.embedded_border.is_valid()) {
  374. border_offset = theme_cache.embedded_border->get_offset();
  375. }
  376. if (theme_cache.embedded_unfocused_border.is_valid()) {
  377. border_offset = border_offset.max(theme_cache.embedded_unfocused_border->get_offset());
  378. }
  379. return position - border_offset;
  380. }
  381. return position;
  382. }
  383. Size2i Window::get_size_with_decorations() const {
  384. ERR_READ_THREAD_GUARD_V(Size2i());
  385. if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  386. return DisplayServer::get_singleton()->window_get_size_with_decorations(window_id);
  387. }
  388. if (visible && is_embedded() && !get_flag(Window::FLAG_BORDERLESS)) {
  389. Size2 border_size;
  390. if (theme_cache.embedded_border.is_valid()) {
  391. border_size = theme_cache.embedded_border->get_minimum_size();
  392. }
  393. if (theme_cache.embedded_unfocused_border.is_valid()) {
  394. border_size = border_size.max(theme_cache.embedded_unfocused_border->get_minimum_size());
  395. }
  396. return size + border_size;
  397. }
  398. return size;
  399. }
  400. Size2i Window::_clamp_limit_size(const Size2i &p_limit_size) {
  401. // Force window limits to respect size limitations of rendering server.
  402. Size2i max_window_size = RS::get_singleton()->get_maximum_viewport_size();
  403. if (max_window_size != Size2i()) {
  404. return p_limit_size.clamp(Vector2i(), max_window_size);
  405. } else {
  406. return p_limit_size.maxi(0);
  407. }
  408. }
  409. void Window::_validate_limit_size() {
  410. // When max_size is invalid, max_size_used falls back to respect size limitations of rendering server.
  411. bool max_size_valid = (max_size.x > 0 || max_size.y > 0) && max_size.x >= min_size.x && max_size.y >= min_size.y;
  412. max_size_used = max_size_valid ? max_size : RS::get_singleton()->get_maximum_viewport_size();
  413. }
  414. void Window::set_max_size(const Size2i &p_max_size) {
  415. ERR_MAIN_THREAD_GUARD;
  416. #if defined(ANDROID_ENABLED)
  417. if (!get_parent() && is_inside_tree()) {
  418. // Can't set root window size on Android.
  419. return;
  420. }
  421. #endif
  422. Size2i max_size_clamped = _clamp_limit_size(p_max_size);
  423. if (max_size == max_size_clamped) {
  424. return;
  425. }
  426. max_size = max_size_clamped;
  427. _validate_limit_size();
  428. _update_window_size();
  429. }
  430. Size2i Window::get_max_size() const {
  431. ERR_READ_THREAD_GUARD_V(Size2i());
  432. return max_size;
  433. }
  434. void Window::set_min_size(const Size2i &p_min_size) {
  435. ERR_MAIN_THREAD_GUARD;
  436. #if defined(ANDROID_ENABLED)
  437. if (!get_parent() && is_inside_tree()) {
  438. // Can't set root window size on Android.
  439. return;
  440. }
  441. #endif
  442. Size2i min_size_clamped = _clamp_limit_size(p_min_size);
  443. if (min_size == min_size_clamped) {
  444. return;
  445. }
  446. min_size = min_size_clamped;
  447. _validate_limit_size();
  448. _update_window_size();
  449. }
  450. Size2i Window::get_min_size() const {
  451. ERR_READ_THREAD_GUARD_V(Size2i());
  452. return min_size;
  453. }
  454. void Window::set_mode(Mode p_mode) {
  455. ERR_MAIN_THREAD_GUARD;
  456. mode = p_mode;
  457. if (embedder) {
  458. embedder->_sub_window_update(this);
  459. } else if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  460. DisplayServer::get_singleton()->window_set_mode(DisplayServer::WindowMode(p_mode), window_id);
  461. }
  462. }
  463. Window::Mode Window::get_mode() const {
  464. ERR_READ_THREAD_GUARD_V(MODE_WINDOWED);
  465. if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  466. mode = (Mode)DisplayServer::get_singleton()->window_get_mode(window_id);
  467. }
  468. return mode;
  469. }
  470. void Window::set_flag(Flags p_flag, bool p_enabled) {
  471. ERR_MAIN_THREAD_GUARD;
  472. ERR_FAIL_INDEX(p_flag, FLAG_MAX);
  473. flags[p_flag] = p_enabled;
  474. if (p_flag == FLAG_TRANSPARENT) {
  475. set_transparent_background(p_enabled);
  476. }
  477. if (embedder) {
  478. embedder->_sub_window_update(this);
  479. } else if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  480. if (!is_in_edited_scene_root()) {
  481. DisplayServer::get_singleton()->window_set_flag(DisplayServer::WindowFlags(p_flag), p_enabled, window_id);
  482. }
  483. }
  484. }
  485. bool Window::get_flag(Flags p_flag) const {
  486. ERR_READ_THREAD_GUARD_V(false);
  487. ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
  488. if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  489. if (!is_in_edited_scene_root()) {
  490. flags[p_flag] = DisplayServer::get_singleton()->window_get_flag(DisplayServer::WindowFlags(p_flag), window_id);
  491. }
  492. }
  493. return flags[p_flag];
  494. }
  495. bool Window::is_popup() const {
  496. return get_flag(Window::FLAG_POPUP) || get_flag(Window::FLAG_NO_FOCUS);
  497. }
  498. bool Window::is_maximize_allowed() const {
  499. ERR_READ_THREAD_GUARD_V(false);
  500. if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  501. return DisplayServer::get_singleton()->window_is_maximize_allowed(window_id);
  502. }
  503. return true;
  504. }
  505. void Window::request_attention() {
  506. ERR_MAIN_THREAD_GUARD;
  507. if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  508. DisplayServer::get_singleton()->window_request_attention(window_id);
  509. }
  510. }
  511. #ifndef DISABLE_DEPRECATED
  512. void Window::move_to_foreground() {
  513. WARN_DEPRECATED_MSG(R"*(The "move_to_foreground()" method is deprecated, use "grab_focus()" instead.)*");
  514. grab_focus();
  515. }
  516. #endif // DISABLE_DEPRECATED
  517. bool Window::can_draw() const {
  518. ERR_READ_THREAD_GUARD_V(false);
  519. if (!is_inside_tree()) {
  520. return false;
  521. }
  522. if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  523. return DisplayServer::get_singleton()->window_can_draw(window_id);
  524. }
  525. return visible;
  526. }
  527. void Window::set_ime_active(bool p_active) {
  528. ERR_MAIN_THREAD_GUARD;
  529. if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  530. DisplayServer::get_singleton()->window_set_ime_active(p_active, window_id);
  531. }
  532. }
  533. void Window::set_ime_position(const Point2i &p_pos) {
  534. ERR_MAIN_THREAD_GUARD;
  535. if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  536. DisplayServer::get_singleton()->window_set_ime_position(p_pos, window_id);
  537. }
  538. }
  539. bool Window::is_embedded() const {
  540. ERR_READ_THREAD_GUARD_V(false);
  541. return get_embedder() != nullptr;
  542. }
  543. bool Window::is_in_edited_scene_root() const {
  544. ERR_READ_THREAD_GUARD_V(false);
  545. #ifdef TOOLS_ENABLED
  546. return is_part_of_edited_scene();
  547. #else
  548. return false;
  549. #endif
  550. }
  551. void Window::_make_window() {
  552. ERR_FAIL_COND(window_id != DisplayServer::INVALID_WINDOW_ID);
  553. if (transient && transient_to_focused) {
  554. _make_transient();
  555. }
  556. uint32_t f = 0;
  557. for (int i = 0; i < FLAG_MAX; i++) {
  558. if (flags[i]) {
  559. f |= (1 << i);
  560. }
  561. }
  562. DisplayServer::VSyncMode vsync_mode = DisplayServer::get_singleton()->window_get_vsync_mode(DisplayServer::MAIN_WINDOW_ID);
  563. Rect2i window_rect;
  564. if (initial_position == WINDOW_INITIAL_POSITION_ABSOLUTE) {
  565. window_rect = Rect2i(position, size);
  566. } else if (initial_position == WINDOW_INITIAL_POSITION_CENTER_PRIMARY_SCREEN) {
  567. window_rect = Rect2i(DisplayServer::get_singleton()->screen_get_position(DisplayServer::SCREEN_PRIMARY) + (DisplayServer::get_singleton()->screen_get_size(DisplayServer::SCREEN_PRIMARY) - size) / 2, size);
  568. } else if (initial_position == WINDOW_INITIAL_POSITION_CENTER_MAIN_WINDOW_SCREEN) {
  569. window_rect = Rect2i(DisplayServer::get_singleton()->screen_get_position(DisplayServer::SCREEN_OF_MAIN_WINDOW) + (DisplayServer::get_singleton()->screen_get_size(DisplayServer::SCREEN_OF_MAIN_WINDOW) - size) / 2, size);
  570. } else if (initial_position == WINDOW_INITIAL_POSITION_CENTER_OTHER_SCREEN) {
  571. window_rect = Rect2i(DisplayServer::get_singleton()->screen_get_position(current_screen) + (DisplayServer::get_singleton()->screen_get_size(current_screen) - size) / 2, size);
  572. } else if (initial_position == WINDOW_INITIAL_POSITION_CENTER_SCREEN_WITH_MOUSE_FOCUS) {
  573. window_rect = Rect2i(DisplayServer::get_singleton()->screen_get_position(DisplayServer::SCREEN_WITH_MOUSE_FOCUS) + (DisplayServer::get_singleton()->screen_get_size(DisplayServer::SCREEN_WITH_MOUSE_FOCUS) - size) / 2, size);
  574. } else if (initial_position == WINDOW_INITIAL_POSITION_CENTER_SCREEN_WITH_KEYBOARD_FOCUS) {
  575. window_rect = Rect2i(DisplayServer::get_singleton()->screen_get_position(DisplayServer::SCREEN_WITH_KEYBOARD_FOCUS) + (DisplayServer::get_singleton()->screen_get_size(DisplayServer::SCREEN_WITH_KEYBOARD_FOCUS) - size) / 2, size);
  576. }
  577. window_id = DisplayServer::get_singleton()->create_sub_window(DisplayServer::WindowMode(mode), vsync_mode, f, window_rect, is_in_edited_scene_root() ? false : exclusive, transient_parent ? transient_parent->window_id : DisplayServer::INVALID_WINDOW_ID);
  578. ERR_FAIL_COND(window_id == DisplayServer::INVALID_WINDOW_ID);
  579. DisplayServer::get_singleton()->window_set_max_size(Size2i(), window_id);
  580. DisplayServer::get_singleton()->window_set_min_size(Size2i(), window_id);
  581. DisplayServer::get_singleton()->window_set_mouse_passthrough(mpath, window_id);
  582. DisplayServer::get_singleton()->window_set_title(displayed_title, window_id);
  583. DisplayServer::get_singleton()->window_attach_instance_id(get_instance_id(), window_id);
  584. _update_window_size();
  585. if (transient_parent) {
  586. for (const Window *E : transient_children) {
  587. if (E->window_id != DisplayServer::INVALID_WINDOW_ID) {
  588. DisplayServer::get_singleton()->window_set_transient(E->window_id, transient_parent->window_id);
  589. }
  590. }
  591. }
  592. _update_window_callbacks();
  593. RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_VISIBLE);
  594. DisplayServer::get_singleton()->show_window(window_id);
  595. }
  596. void Window::_update_from_window() {
  597. ERR_FAIL_COND(window_id == DisplayServer::INVALID_WINDOW_ID);
  598. mode = (Mode)DisplayServer::get_singleton()->window_get_mode(window_id);
  599. for (int i = 0; i < FLAG_MAX; i++) {
  600. flags[i] = DisplayServer::get_singleton()->window_get_flag(DisplayServer::WindowFlags(i), window_id);
  601. }
  602. }
  603. void Window::_clear_window() {
  604. ERR_FAIL_COND(window_id == DisplayServer::INVALID_WINDOW_ID);
  605. bool had_focus = has_focus();
  606. if (transient_parent && transient_parent->window_id != DisplayServer::INVALID_WINDOW_ID) {
  607. DisplayServer::get_singleton()->window_set_transient(window_id, DisplayServer::INVALID_WINDOW_ID);
  608. }
  609. for (const Window *E : transient_children) {
  610. if (E->window_id != DisplayServer::INVALID_WINDOW_ID) {
  611. DisplayServer::get_singleton()->window_set_transient(E->window_id, DisplayServer::INVALID_WINDOW_ID);
  612. }
  613. }
  614. _update_from_window();
  615. DisplayServer::get_singleton()->delete_sub_window(window_id);
  616. window_id = DisplayServer::INVALID_WINDOW_ID;
  617. // If closing window was focused and has a parent, return focus.
  618. if (had_focus && transient_parent) {
  619. transient_parent->grab_focus();
  620. }
  621. _update_viewport_size();
  622. RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED);
  623. if (transient && transient_to_focused) {
  624. _clear_transient();
  625. }
  626. }
  627. void Window::_rect_changed_callback(const Rect2i &p_callback) {
  628. //we must always accept this as the truth
  629. if (size == p_callback.size && position == p_callback.position) {
  630. return;
  631. }
  632. if (position != p_callback.position) {
  633. position = p_callback.position;
  634. _propagate_window_notification(this, NOTIFICATION_WM_POSITION_CHANGED);
  635. }
  636. if (size != p_callback.size) {
  637. size = p_callback.size;
  638. _update_viewport_size();
  639. }
  640. if (window_id != DisplayServer::INVALID_WINDOW_ID && !DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_SELF_FITTING_WINDOWS)) {
  641. Vector2 sz_out = DisplayServer::get_singleton()->window_get_size_with_decorations(window_id);
  642. Vector2 pos_out = DisplayServer::get_singleton()->window_get_position_with_decorations(window_id);
  643. Vector2 sz_in = DisplayServer::get_singleton()->window_get_size(window_id);
  644. Vector2 pos_in = DisplayServer::get_singleton()->window_get_position(window_id);
  645. DisplayServer::get_singleton()->accessibility_set_window_rect(window_id, Rect2(pos_out, sz_out), Rect2(pos_in, sz_in));
  646. }
  647. queue_accessibility_update();
  648. }
  649. void Window::_propagate_window_notification(Node *p_node, int p_notification) {
  650. p_node->notification(p_notification);
  651. for (int i = 0; i < p_node->get_child_count(); i++) {
  652. Node *child = p_node->get_child(i);
  653. Window *window = Object::cast_to<Window>(child);
  654. if (window) {
  655. continue;
  656. }
  657. _propagate_window_notification(child, p_notification);
  658. }
  659. }
  660. void Window::_event_callback(DisplayServer::WindowEvent p_event) {
  661. switch (p_event) {
  662. case DisplayServer::WINDOW_EVENT_MOUSE_ENTER: {
  663. if (!is_inside_tree()) {
  664. return;
  665. }
  666. Window *root = get_tree()->get_root();
  667. if (mouse_in_window && root->gui.windowmanager_window_over == this) {
  668. return;
  669. }
  670. if (root->gui.windowmanager_window_over) {
  671. #ifdef DEV_ENABLED
  672. WARN_PRINT_ONCE("Entering a window while a window is hovered should never happen in DisplayServer.");
  673. #endif // DEV_ENABLED
  674. root->gui.windowmanager_window_over->_event_callback(DisplayServer::WINDOW_EVENT_MOUSE_EXIT);
  675. }
  676. _propagate_window_notification(this, NOTIFICATION_WM_MOUSE_ENTER);
  677. root->gui.windowmanager_window_over = this;
  678. mouse_in_window = true;
  679. if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_CURSOR_SHAPE)) {
  680. DisplayServer::get_singleton()->cursor_set_shape(DisplayServer::CURSOR_ARROW); //restore cursor shape
  681. }
  682. } break;
  683. case DisplayServer::WINDOW_EVENT_MOUSE_EXIT: {
  684. if (!is_inside_tree()) {
  685. return;
  686. }
  687. // Ensure keeping the order of input events and window events when input events are buffered or accumulated.
  688. Input::get_singleton()->flush_buffered_events();
  689. Window *root = get_tree()->get_root();
  690. if (!root->gui.windowmanager_window_over) {
  691. #ifdef DEV_ENABLED
  692. WARN_PRINT_ONCE("Exiting a window while no window is hovered should never happen in DisplayServer.");
  693. #endif // DEV_ENABLED
  694. return;
  695. }
  696. mouse_in_window = false;
  697. root->gui.windowmanager_window_over->_mouse_leave_viewport();
  698. root->gui.windowmanager_window_over = nullptr;
  699. _propagate_window_notification(this, NOTIFICATION_WM_MOUSE_EXIT);
  700. } break;
  701. case DisplayServer::WINDOW_EVENT_FOCUS_IN: {
  702. focused = true;
  703. focused_window = this;
  704. _propagate_window_notification(this, NOTIFICATION_WM_WINDOW_FOCUS_IN);
  705. emit_signal(SceneStringName(focus_entered));
  706. } break;
  707. case DisplayServer::WINDOW_EVENT_FOCUS_OUT: {
  708. focused = false;
  709. if (focused_window == this) {
  710. focused_window = nullptr;
  711. }
  712. _propagate_window_notification(this, NOTIFICATION_WM_WINDOW_FOCUS_OUT);
  713. emit_signal(SceneStringName(focus_exited));
  714. } break;
  715. case DisplayServer::WINDOW_EVENT_CLOSE_REQUEST: {
  716. if (exclusive_child != nullptr) {
  717. break; //has an exclusive child, can't get events until child is closed
  718. }
  719. _propagate_window_notification(this, NOTIFICATION_WM_CLOSE_REQUEST);
  720. emit_signal(SNAME("close_requested"));
  721. } break;
  722. case DisplayServer::WINDOW_EVENT_GO_BACK_REQUEST: {
  723. _propagate_window_notification(this, NOTIFICATION_WM_GO_BACK_REQUEST);
  724. emit_signal(SNAME("go_back_requested"));
  725. } break;
  726. case DisplayServer::WINDOW_EVENT_DPI_CHANGE: {
  727. _update_viewport_size();
  728. _propagate_window_notification(this, NOTIFICATION_WM_DPI_CHANGE);
  729. emit_signal(SNAME("dpi_changed"));
  730. } break;
  731. case DisplayServer::WINDOW_EVENT_TITLEBAR_CHANGE: {
  732. emit_signal(SNAME("titlebar_changed"));
  733. } break;
  734. case DisplayServer::WINDOW_EVENT_FORCE_CLOSE: {
  735. hide();
  736. } break;
  737. }
  738. }
  739. void Window::update_mouse_cursor_state() {
  740. ERR_MAIN_THREAD_GUARD;
  741. // Update states based on mouse cursor position.
  742. // This includes updated mouse_enter or mouse_exit signals or the current mouse cursor shape.
  743. // These details are set in Viewport::_gui_input_event. To instantly
  744. // see the changes in the viewport, we need to trigger a mouse motion event.
  745. // This function should be called whenever scene tree changes affect the mouse cursor.
  746. Ref<InputEventMouseMotion> mm;
  747. Vector2 pos = get_mouse_position();
  748. Transform2D xform = get_global_canvas_transform().affine_inverse();
  749. mm.instantiate();
  750. mm->set_position(pos);
  751. mm->set_global_position(xform.xform(pos));
  752. mm->set_device(InputEvent::DEVICE_ID_INTERNAL);
  753. push_input(mm, true);
  754. }
  755. void Window::show() {
  756. ERR_MAIN_THREAD_GUARD;
  757. set_visible(true);
  758. }
  759. void Window::hide() {
  760. ERR_MAIN_THREAD_GUARD;
  761. set_visible(false);
  762. }
  763. void Window::_accessibility_notify_enter(Node *p_node) {
  764. p_node->queue_accessibility_update();
  765. if (p_node != this) {
  766. const Window *window = Object::cast_to<Window>(p_node);
  767. if (window) {
  768. return;
  769. }
  770. }
  771. for (int i = 0; i < p_node->get_child_count(); i++) {
  772. _accessibility_notify_enter(p_node->get_child(i));
  773. }
  774. }
  775. void Window::_accessibility_notify_exit(Node *p_node) {
  776. p_node->notification(Node::NOTIFICATION_ACCESSIBILITY_INVALIDATE);
  777. if (p_node != this) {
  778. const Window *window = Object::cast_to<Window>(p_node);
  779. if (window) {
  780. return;
  781. }
  782. }
  783. for (int i = 0; i < p_node->get_child_count(); i++) {
  784. _accessibility_notify_exit(p_node->get_child(i));
  785. }
  786. }
  787. void Window::set_visible(bool p_visible) {
  788. ERR_MAIN_THREAD_GUARD;
  789. if (visible == p_visible) {
  790. return;
  791. }
  792. if (!is_inside_tree()) {
  793. visible = p_visible;
  794. return;
  795. }
  796. ERR_FAIL_NULL_MSG(get_parent(), "Can't change visibility of main window.");
  797. visible = p_visible;
  798. // Stop any queued resizing, as the window will be resized right now.
  799. updating_child_controls = false;
  800. Viewport *embedder_vp = get_embedder();
  801. if (!embedder_vp) {
  802. if (!p_visible && window_id != DisplayServer::INVALID_WINDOW_ID) {
  803. _clear_window();
  804. }
  805. if (p_visible && window_id == DisplayServer::INVALID_WINDOW_ID) {
  806. _make_window();
  807. }
  808. } else {
  809. if (visible) {
  810. embedder = embedder_vp;
  811. if (initial_position != WINDOW_INITIAL_POSITION_ABSOLUTE) {
  812. if (is_in_edited_scene_root()) {
  813. Size2 screen_size = Size2(GLOBAL_GET_CACHED(real_t, "display/window/size/viewport_width"), GLOBAL_GET_CACHED(real_t, "display/window/size/viewport_height"));
  814. position = (screen_size - size) / 2;
  815. } else {
  816. position = (embedder->get_visible_rect().size - size) / 2;
  817. }
  818. }
  819. embedder->_sub_window_register(this);
  820. RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE);
  821. } else {
  822. embedder->_sub_window_remove(this);
  823. embedder = nullptr;
  824. RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED);
  825. }
  826. _update_window_size();
  827. }
  828. if (visible) {
  829. if (get_tree() && get_tree()->is_accessibility_supported()) {
  830. get_tree()->_accessibility_force_update();
  831. _accessibility_notify_enter(this);
  832. }
  833. } else {
  834. if (get_tree() && get_tree()->is_accessibility_supported()) {
  835. _accessibility_notify_exit(this);
  836. }
  837. focused = false;
  838. if (focused_window == this) {
  839. focused_window = nullptr;
  840. }
  841. }
  842. if (get_parent()) {
  843. get_parent()->queue_accessibility_update();
  844. }
  845. if (embedder) {
  846. embedder->queue_accessibility_update();
  847. }
  848. notification(NOTIFICATION_VISIBILITY_CHANGED);
  849. emit_signal(SceneStringName(visibility_changed));
  850. RS::get_singleton()->viewport_set_active(get_viewport_rid(), visible);
  851. //update transient exclusive
  852. if (transient_parent) {
  853. _set_transient_exclusive_child(true);
  854. }
  855. }
  856. void Window::_clear_transient() {
  857. if (transient_parent) {
  858. if (transient_parent->window_id != DisplayServer::INVALID_WINDOW_ID && window_id != DisplayServer::INVALID_WINDOW_ID) {
  859. DisplayServer::get_singleton()->window_set_transient(window_id, DisplayServer::INVALID_WINDOW_ID);
  860. }
  861. transient_parent->transient_children.erase(this);
  862. if (transient_parent->exclusive_child == this) {
  863. transient_parent->exclusive_child = nullptr;
  864. }
  865. transient_parent = nullptr;
  866. }
  867. }
  868. void Window::_make_transient() {
  869. if (!get_parent()) {
  870. //main window, can't be transient
  871. return;
  872. }
  873. //find transient parent
  874. Window *window = nullptr;
  875. if (!is_embedded() && transient_to_focused) {
  876. DisplayServer::WindowID focused_window_id = DisplayServer::get_singleton()->get_focused_window();
  877. if (focused_window_id != DisplayServer::INVALID_WINDOW_ID) {
  878. window = Window::get_from_id(focused_window_id);
  879. }
  880. }
  881. if (!window) {
  882. Viewport *vp = get_parent()->get_viewport();
  883. while (vp) {
  884. window = Object::cast_to<Window>(vp);
  885. if (window) {
  886. break;
  887. }
  888. if (!vp->get_parent()) {
  889. break;
  890. }
  891. vp = vp->get_parent()->get_viewport();
  892. }
  893. }
  894. if (window) {
  895. transient_parent = window;
  896. window->transient_children.insert(this);
  897. _set_transient_exclusive_child();
  898. }
  899. //see if we can make transient
  900. if (transient_parent->window_id != DisplayServer::INVALID_WINDOW_ID && window_id != DisplayServer::INVALID_WINDOW_ID) {
  901. DisplayServer::get_singleton()->window_set_transient(window_id, transient_parent->window_id);
  902. }
  903. }
  904. void Window::_set_transient_exclusive_child(bool p_clear_invalid) {
  905. if (exclusive && visible && is_inside_tree()) {
  906. if (!is_in_edited_scene_root()) {
  907. // Transient parent has another exclusive child.
  908. if (transient_parent->exclusive_child && transient_parent->exclusive_child != this) {
  909. ERR_PRINT(vformat("Attempting to make child window exclusive, but the parent window already has another exclusive child. This window: %s, parent window: %s, current exclusive child window: %s", get_description(), transient_parent->get_description(), transient_parent->exclusive_child->get_description()));
  910. }
  911. transient_parent->exclusive_child = this;
  912. }
  913. } else if (p_clear_invalid) {
  914. if (transient_parent->exclusive_child == this) {
  915. transient_parent->exclusive_child = nullptr;
  916. }
  917. }
  918. }
  919. void Window::set_transient(bool p_transient) {
  920. ERR_MAIN_THREAD_GUARD;
  921. if (transient == p_transient) {
  922. return;
  923. }
  924. transient = p_transient;
  925. if (!is_inside_tree()) {
  926. return;
  927. }
  928. if (transient) {
  929. if (!transient_to_focused) {
  930. _make_transient();
  931. }
  932. } else {
  933. _clear_transient();
  934. }
  935. }
  936. bool Window::is_transient() const {
  937. return transient;
  938. }
  939. void Window::set_transient_to_focused(bool p_transient_to_focused) {
  940. ERR_MAIN_THREAD_GUARD;
  941. if (transient_to_focused == p_transient_to_focused) {
  942. return;
  943. }
  944. transient_to_focused = p_transient_to_focused;
  945. }
  946. bool Window::is_transient_to_focused() const {
  947. ERR_READ_THREAD_GUARD_V(false);
  948. return transient_to_focused;
  949. }
  950. void Window::set_exclusive(bool p_exclusive) {
  951. ERR_MAIN_THREAD_GUARD;
  952. if (exclusive == p_exclusive) {
  953. return;
  954. }
  955. exclusive = p_exclusive;
  956. if (!embedder && window_id != DisplayServer::INVALID_WINDOW_ID) {
  957. if (is_in_edited_scene_root()) {
  958. DisplayServer::get_singleton()->window_set_exclusive(window_id, false);
  959. } else {
  960. DisplayServer::get_singleton()->window_set_exclusive(window_id, exclusive);
  961. }
  962. }
  963. if (transient_parent) {
  964. _set_transient_exclusive_child(true);
  965. }
  966. }
  967. bool Window::is_exclusive() const {
  968. ERR_READ_THREAD_GUARD_V(false);
  969. return exclusive;
  970. }
  971. bool Window::is_visible() const {
  972. ERR_READ_THREAD_GUARD_V(false);
  973. return visible;
  974. }
  975. Size2i Window::_clamp_window_size(const Size2i &p_size) {
  976. Size2i window_size_clamped = p_size;
  977. Size2 minsize = get_clamped_minimum_size();
  978. window_size_clamped = window_size_clamped.max(minsize);
  979. if (max_size_used != Size2i()) {
  980. window_size_clamped = window_size_clamped.min(max_size_used);
  981. }
  982. return window_size_clamped;
  983. }
  984. void Window::_update_window_size() {
  985. Size2i size_limit = get_clamped_minimum_size();
  986. if (!embedder && window_id != DisplayServer::INVALID_WINDOW_ID && keep_title_visible) {
  987. Size2i title_size = DisplayServer::get_singleton()->window_get_title_size(displayed_title, window_id);
  988. size_limit = size_limit.max(title_size);
  989. }
  990. size = size.max(size_limit);
  991. bool reset_min_first = false;
  992. if (max_size_used != Size2i()) {
  993. // Force window size to respect size limitations of max_size_used.
  994. size = size.min(max_size_used);
  995. if (size_limit.x > max_size_used.x) {
  996. size_limit.x = max_size_used.x;
  997. reset_min_first = true;
  998. }
  999. if (size_limit.y > max_size_used.y) {
  1000. size_limit.y = max_size_used.y;
  1001. reset_min_first = true;
  1002. }
  1003. }
  1004. if (embedder) {
  1005. size = size.maxi(1);
  1006. embedder->_sub_window_update(this);
  1007. } else if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  1008. // When main window embedded in the editor, we can't resize the main window.
  1009. if (window_id != DisplayServer::MAIN_WINDOW_ID || !Engine::get_singleton()->is_embedded_in_editor()) {
  1010. if (reset_min_first && wrap_controls) {
  1011. // Avoid an error if setting max_size to a value between min_size and the previous size_limit.
  1012. DisplayServer::get_singleton()->window_set_min_size(Size2i(), window_id);
  1013. }
  1014. DisplayServer::get_singleton()->window_set_max_size(max_size_used, window_id);
  1015. DisplayServer::get_singleton()->window_set_min_size(size_limit, window_id);
  1016. DisplayServer::get_singleton()->window_set_size(size, window_id);
  1017. }
  1018. }
  1019. //update the viewport
  1020. _update_viewport_size();
  1021. }
  1022. void Window::_update_viewport_size() {
  1023. //update the viewport part
  1024. Size2i final_size;
  1025. Size2 final_size_override;
  1026. Rect2i attach_to_screen_rect(Point2i(), size);
  1027. window_transform = Transform2D();
  1028. if (content_scale_stretch == Window::CONTENT_SCALE_STRETCH_INTEGER) {
  1029. // We always want to make sure that the content scale factor is a whole
  1030. // number, else there will be pixel wobble no matter what.
  1031. content_scale_factor = Math::floor(content_scale_factor);
  1032. // A content scale factor of zero is pretty useless.
  1033. if (content_scale_factor < 1) {
  1034. content_scale_factor = 1;
  1035. }
  1036. }
  1037. if (content_scale_mode == CONTENT_SCALE_MODE_DISABLED || content_scale_size.x == 0 || content_scale_size.y == 0) {
  1038. final_size = size;
  1039. final_size_override = Size2(size) / content_scale_factor;
  1040. } else {
  1041. //actual screen video mode
  1042. Size2 video_mode = size;
  1043. Size2 desired_res = content_scale_size;
  1044. Size2 viewport_size;
  1045. Size2 screen_size;
  1046. float viewport_aspect = desired_res.aspect();
  1047. float video_mode_aspect = video_mode.aspect();
  1048. if (content_scale_aspect == CONTENT_SCALE_ASPECT_IGNORE || Math::is_equal_approx(viewport_aspect, video_mode_aspect)) {
  1049. //same aspect or ignore aspect
  1050. viewport_size = desired_res;
  1051. screen_size = video_mode;
  1052. } else if (viewport_aspect < video_mode_aspect) {
  1053. // screen ratio is smaller vertically
  1054. if (content_scale_aspect == CONTENT_SCALE_ASPECT_KEEP_HEIGHT || content_scale_aspect == CONTENT_SCALE_ASPECT_EXPAND) {
  1055. //will stretch horizontally
  1056. viewport_size.x = desired_res.y * video_mode_aspect;
  1057. viewport_size.y = desired_res.y;
  1058. screen_size = video_mode;
  1059. } else {
  1060. //will need black bars
  1061. viewport_size = desired_res;
  1062. screen_size.x = video_mode.y * viewport_aspect;
  1063. screen_size.y = video_mode.y;
  1064. }
  1065. } else {
  1066. //screen ratio is smaller horizontally
  1067. if (content_scale_aspect == CONTENT_SCALE_ASPECT_KEEP_WIDTH || content_scale_aspect == CONTENT_SCALE_ASPECT_EXPAND) {
  1068. //will stretch horizontally
  1069. viewport_size.x = desired_res.x;
  1070. viewport_size.y = desired_res.x / video_mode_aspect;
  1071. screen_size = video_mode;
  1072. } else {
  1073. //will need black bars
  1074. viewport_size = desired_res;
  1075. screen_size.x = video_mode.x;
  1076. screen_size.y = video_mode.x / viewport_aspect;
  1077. }
  1078. }
  1079. screen_size = screen_size.floor();
  1080. viewport_size = viewport_size.floor();
  1081. if (content_scale_stretch == Window::CONTENT_SCALE_STRETCH_INTEGER) {
  1082. Size2i screen_scale = (screen_size / viewport_size).floor();
  1083. int scale_factor = MIN(screen_scale.x, screen_scale.y);
  1084. if (scale_factor < 1) {
  1085. scale_factor = 1;
  1086. }
  1087. screen_size = viewport_size * scale_factor;
  1088. }
  1089. Size2 margin;
  1090. Size2 offset;
  1091. if (screen_size.x < video_mode.x) {
  1092. margin.x = Math::round((video_mode.x - screen_size.x) / 2.0);
  1093. offset.x = Math::round(margin.x * viewport_size.y / screen_size.y);
  1094. }
  1095. if (screen_size.y < video_mode.y) {
  1096. margin.y = Math::round((video_mode.y - screen_size.y) / 2.0);
  1097. offset.y = Math::round(margin.y * viewport_size.x / screen_size.x);
  1098. }
  1099. switch (content_scale_mode) {
  1100. case CONTENT_SCALE_MODE_DISABLED: {
  1101. } break;
  1102. case CONTENT_SCALE_MODE_CANVAS_ITEMS: {
  1103. final_size = screen_size;
  1104. final_size_override = viewport_size / content_scale_factor;
  1105. attach_to_screen_rect = Rect2(margin, screen_size);
  1106. window_transform.translate_local(margin);
  1107. } break;
  1108. case CONTENT_SCALE_MODE_VIEWPORT: {
  1109. final_size = (viewport_size / content_scale_factor).floor();
  1110. attach_to_screen_rect = Rect2(margin, screen_size);
  1111. window_transform.translate_local(margin);
  1112. if (final_size.x != 0 && final_size.y != 0) {
  1113. Transform2D scale_transform;
  1114. scale_transform.scale(Vector2(attach_to_screen_rect.size) / Vector2(final_size));
  1115. window_transform *= scale_transform;
  1116. }
  1117. } break;
  1118. }
  1119. }
  1120. bool allocate = is_inside_tree() && visible && (window_id != DisplayServer::INVALID_WINDOW_ID || embedder != nullptr);
  1121. _set_size(final_size, final_size_override, allocate);
  1122. if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  1123. RenderingServer::get_singleton()->viewport_attach_to_screen(get_viewport_rid(), attach_to_screen_rect, window_id);
  1124. } else if (!is_embedded()) {
  1125. RenderingServer::get_singleton()->viewport_attach_to_screen(get_viewport_rid(), Rect2i(), DisplayServer::INVALID_WINDOW_ID);
  1126. }
  1127. notification(NOTIFICATION_WM_SIZE_CHANGED);
  1128. if (embedder) {
  1129. float scale = MIN(embedder->stretch_transform.get_scale().width, embedder->stretch_transform.get_scale().height);
  1130. Viewport::set_oversampling_override(scale);
  1131. Size2 s = Size2(final_size.width * scale, final_size.height * scale).ceil();
  1132. RS::get_singleton()->viewport_set_global_canvas_transform(get_viewport_rid(), global_canvas_transform * scale * content_scale_factor);
  1133. RS::get_singleton()->viewport_set_size(get_viewport_rid(), s.width, s.height);
  1134. embedder->_sub_window_update(this);
  1135. }
  1136. }
  1137. void Window::_update_window_callbacks() {
  1138. DisplayServer::get_singleton()->window_set_rect_changed_callback(callable_mp(this, &Window::_rect_changed_callback), window_id);
  1139. DisplayServer::get_singleton()->window_set_window_event_callback(callable_mp(this, &Window::_event_callback), window_id);
  1140. DisplayServer::get_singleton()->window_set_input_event_callback(callable_mp(this, &Window::_window_input), window_id);
  1141. DisplayServer::get_singleton()->window_set_input_text_callback(callable_mp(this, &Window::_window_input_text), window_id);
  1142. DisplayServer::get_singleton()->window_set_drop_files_callback(callable_mp(this, &Window::_window_drop_files), window_id);
  1143. }
  1144. void Window::set_force_native(bool p_force_native) {
  1145. if (force_native == p_force_native) {
  1146. return;
  1147. }
  1148. if (is_visible() && !is_in_edited_scene_root()) {
  1149. ERR_FAIL_MSG("Can't change \"force_native\" while a window is displayed. Consider hiding window before changing this value.");
  1150. }
  1151. if (window_id == DisplayServer::MAIN_WINDOW_ID) {
  1152. return;
  1153. }
  1154. force_native = p_force_native;
  1155. if (!is_in_edited_scene_root() && is_inside_tree() && get_tree()->get_root()->is_embedding_subwindows()) {
  1156. set_embedding_subwindows(force_native);
  1157. }
  1158. }
  1159. bool Window::get_force_native() const {
  1160. return force_native;
  1161. }
  1162. Viewport *Window::get_embedder() const {
  1163. ERR_READ_THREAD_GUARD_V(nullptr);
  1164. if (force_native && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_SUBWINDOWS) && !is_in_edited_scene_root()) {
  1165. return nullptr;
  1166. }
  1167. Viewport *vp = get_parent_viewport();
  1168. while (vp) {
  1169. if (vp->is_embedding_subwindows()) {
  1170. return vp;
  1171. }
  1172. if (vp->get_parent()) {
  1173. vp = vp->get_parent()->get_viewport();
  1174. } else {
  1175. vp = nullptr;
  1176. }
  1177. }
  1178. return nullptr;
  1179. }
  1180. RID Window::get_accessibility_element() const {
  1181. if (!visible || is_part_of_edited_scene()) {
  1182. return RID();
  1183. }
  1184. if (get_embedder() || is_popup()) {
  1185. return Node::get_accessibility_element();
  1186. } else if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  1187. return DisplayServer::get_singleton()->accessibility_get_window_root(window_id);
  1188. } else {
  1189. return RID();
  1190. }
  1191. }
  1192. RID Window::get_focused_accessibility_element() const {
  1193. if (window_id == DisplayServer::MAIN_WINDOW_ID) {
  1194. if (get_child_count() > 0) {
  1195. return get_child(0)->get_focused_accessibility_element(); // Try scene tree root node.
  1196. }
  1197. }
  1198. return Node::get_focused_accessibility_element();
  1199. }
  1200. void Window::_notification(int p_what) {
  1201. ERR_MAIN_THREAD_GUARD;
  1202. switch (p_what) {
  1203. case NOTIFICATION_ACCESSIBILITY_INVALIDATE: {
  1204. accessibility_title_element = RID();
  1205. accessibility_announcement_element = RID();
  1206. } break;
  1207. case NOTIFICATION_ACCESSIBILITY_UPDATE: {
  1208. RID ae = get_accessibility_element();
  1209. ERR_FAIL_COND(ae.is_null());
  1210. DisplayServer::get_singleton()->accessibility_update_set_role(ae, DisplayServer::AccessibilityRole::ROLE_WINDOW);
  1211. if (accessibility_name.is_empty()) {
  1212. DisplayServer::get_singleton()->accessibility_update_set_name(ae, displayed_title);
  1213. } else {
  1214. DisplayServer::get_singleton()->accessibility_update_set_name(ae, accessibility_name);
  1215. }
  1216. DisplayServer::get_singleton()->accessibility_update_set_description(ae, accessibility_description);
  1217. DisplayServer::get_singleton()->accessibility_update_set_flag(ae, DisplayServer::AccessibilityFlags::FLAG_MODAL, exclusive);
  1218. DisplayServer::get_singleton()->accessibility_update_add_action(ae, DisplayServer::AccessibilityAction::ACTION_FOCUS, callable_mp(this, &Window::_accessibility_action_grab_focus));
  1219. DisplayServer::get_singleton()->accessibility_update_set_flag(ae, DisplayServer::AccessibilityFlags::FLAG_HIDDEN, !visible);
  1220. if (get_embedder() || is_popup()) {
  1221. Control *parent_ctrl = Object::cast_to<Control>(get_parent());
  1222. Transform2D parent_tr = parent_ctrl ? parent_ctrl->get_global_transform() : Transform2D();
  1223. Transform2D tr;
  1224. if (window_id == DisplayServer::INVALID_WINDOW_ID) {
  1225. tr.set_origin(position);
  1226. } else {
  1227. Window *np = get_non_popup_window();
  1228. if (np) {
  1229. tr.set_origin(get_position() - np->get_position());
  1230. }
  1231. }
  1232. DisplayServer::get_singleton()->accessibility_update_set_transform(ae, parent_tr.affine_inverse() * tr);
  1233. DisplayServer::get_singleton()->accessibility_update_set_bounds(ae, Rect2(Point2(), size));
  1234. if (accessibility_title_element.is_null()) {
  1235. accessibility_title_element = DisplayServer::get_singleton()->accessibility_create_sub_element(ae, DisplayServer::AccessibilityRole::ROLE_TITLE_BAR);
  1236. }
  1237. int w = get_theme_constant(SNAME("title_height"));
  1238. DisplayServer::get_singleton()->accessibility_update_set_name(accessibility_title_element, displayed_title);
  1239. DisplayServer::get_singleton()->accessibility_update_set_bounds(accessibility_title_element, Rect2(Vector2(0, -w), Size2(size.x, w)));
  1240. } else {
  1241. DisplayServer::get_singleton()->accessibility_update_set_transform(ae, get_final_transform());
  1242. if (_get_size_2d_override() != Size2()) {
  1243. DisplayServer::get_singleton()->accessibility_update_set_bounds(ae, Rect2(Point2(), _get_size_2d_override()));
  1244. } else {
  1245. DisplayServer::get_singleton()->accessibility_update_set_bounds(ae, Rect2(Point2(), _get_size()));
  1246. }
  1247. if (accessibility_announcement_element.is_null()) {
  1248. accessibility_announcement_element = DisplayServer::get_singleton()->accessibility_create_sub_element(ae, DisplayServer::AccessibilityRole::ROLE_STATIC_TEXT);
  1249. }
  1250. if (announcement.is_empty()) {
  1251. DisplayServer::get_singleton()->accessibility_update_set_live(accessibility_announcement_element, DisplayServer::LIVE_OFF);
  1252. } else {
  1253. DisplayServer::get_singleton()->accessibility_update_set_name(accessibility_announcement_element, announcement);
  1254. DisplayServer::get_singleton()->accessibility_update_set_live(accessibility_announcement_element, DisplayServer::LIVE_ASSERTIVE);
  1255. }
  1256. }
  1257. } break;
  1258. case NOTIFICATION_POSTINITIALIZE: {
  1259. initialized = true;
  1260. _invalidate_theme_cache();
  1261. _update_theme_item_cache();
  1262. } break;
  1263. case NOTIFICATION_PARENTED: {
  1264. theme_owner->assign_theme_on_parented(this);
  1265. } break;
  1266. case NOTIFICATION_UNPARENTED: {
  1267. theme_owner->clear_theme_on_unparented(this);
  1268. } break;
  1269. case NOTIFICATION_ENTER_TREE: {
  1270. if (is_in_edited_scene_root()) {
  1271. if (!ProjectSettings::get_singleton()->is_connected("settings_changed", callable_mp(this, &Window::_settings_changed))) {
  1272. ProjectSettings::get_singleton()->connect("settings_changed", callable_mp(this, &Window::_settings_changed));
  1273. }
  1274. } else if (get_parent() && get_tree()->get_root()->is_embedding_subwindows()) {
  1275. // Is not the main window and main window is embedding.
  1276. set_embedding_subwindows(force_native);
  1277. }
  1278. bool embedded = false;
  1279. {
  1280. embedder = get_embedder();
  1281. if (embedder) {
  1282. embedded = true;
  1283. if (!visible) {
  1284. embedder = nullptr; // Not yet since not visible.
  1285. }
  1286. }
  1287. }
  1288. if (embedded) {
  1289. // Create as embedded.
  1290. if (embedder) {
  1291. if (initial_position != WINDOW_INITIAL_POSITION_ABSOLUTE) {
  1292. if (is_in_edited_scene_root()) {
  1293. Size2 screen_size = Size2(GLOBAL_GET_CACHED(real_t, "display/window/size/viewport_width"), GLOBAL_GET_CACHED(real_t, "display/window/size/viewport_height"));
  1294. position = (screen_size - size) / 2;
  1295. } else {
  1296. position = (embedder->get_visible_rect().size - size) / 2;
  1297. }
  1298. }
  1299. embedder->_sub_window_register(this);
  1300. RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE);
  1301. _update_window_size();
  1302. }
  1303. } else {
  1304. if (!get_parent()) {
  1305. // It's the root window!
  1306. visible = true; // Always visible.
  1307. window_id = DisplayServer::MAIN_WINDOW_ID;
  1308. focused_window = this;
  1309. DisplayServer::get_singleton()->window_attach_instance_id(get_instance_id(), window_id);
  1310. _update_from_window();
  1311. // Since this window already exists (created on start), we must update pos and size from it.
  1312. {
  1313. position = DisplayServer::get_singleton()->window_get_position(window_id);
  1314. size = DisplayServer::get_singleton()->window_get_size(window_id);
  1315. focused = DisplayServer::get_singleton()->window_is_focused(window_id);
  1316. }
  1317. _update_window_size(); // Inform DisplayServer of minimum and maximum size.
  1318. _update_viewport_size(); // Then feed back to the viewport.
  1319. _update_window_callbacks();
  1320. // Simulate mouse-enter event when mouse is over the window, since OS event might arrive before setting callbacks.
  1321. if (!mouse_in_window && Rect2(position, size).has_point(DisplayServer::get_singleton()->mouse_get_position())) {
  1322. _event_callback(DisplayServer::WINDOW_EVENT_MOUSE_ENTER);
  1323. }
  1324. RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_VISIBLE);
  1325. if (DisplayServer::get_singleton()->window_get_flag(DisplayServer::WindowFlags(FLAG_TRANSPARENT), window_id)) {
  1326. set_transparent_background(true);
  1327. }
  1328. } else {
  1329. // Create.
  1330. if (visible) {
  1331. _make_window();
  1332. }
  1333. }
  1334. }
  1335. if (transient && !transient_to_focused) {
  1336. _make_transient();
  1337. }
  1338. if (visible) {
  1339. if (window_id != DisplayServer::MAIN_WINDOW_ID && get_tree() && get_tree()->is_accessibility_supported()) {
  1340. get_tree()->_accessibility_force_update();
  1341. _accessibility_notify_enter(this);
  1342. }
  1343. notification(NOTIFICATION_VISIBILITY_CHANGED);
  1344. emit_signal(SceneStringName(visibility_changed));
  1345. RS::get_singleton()->viewport_set_active(get_viewport_rid(), true);
  1346. if (get_parent()) {
  1347. get_parent()->queue_accessibility_update();
  1348. }
  1349. if (embedder) {
  1350. embedder->queue_accessibility_update();
  1351. }
  1352. }
  1353. // Emits NOTIFICATION_THEME_CHANGED internally.
  1354. set_theme_context(ThemeDB::get_singleton()->get_nearest_theme_context(this));
  1355. } break;
  1356. case NOTIFICATION_READY: {
  1357. if (wrap_controls) {
  1358. // Finish any resizing immediately so it doesn't interfere on stuff overriding _ready().
  1359. _update_child_controls();
  1360. }
  1361. } break;
  1362. case NOTIFICATION_THEME_CHANGED: {
  1363. emit_signal(SceneStringName(theme_changed));
  1364. _invalidate_theme_cache();
  1365. _update_theme_item_cache();
  1366. } break;
  1367. case NOTIFICATION_TRANSLATION_CHANGED: {
  1368. _invalidate_theme_cache();
  1369. _update_theme_item_cache();
  1370. _update_displayed_title();
  1371. } break;
  1372. case NOTIFICATION_VISIBILITY_CHANGED: {
  1373. if (unparent_when_invisible && !is_visible()) {
  1374. Node *p = get_parent();
  1375. if (p) {
  1376. p->remove_child(this);
  1377. }
  1378. }
  1379. } break;
  1380. case NOTIFICATION_EXIT_TREE: {
  1381. if (ProjectSettings::get_singleton()->is_connected("settings_changed", callable_mp(this, &Window::_settings_changed))) {
  1382. ProjectSettings::get_singleton()->disconnect("settings_changed", callable_mp(this, &Window::_settings_changed));
  1383. }
  1384. set_theme_context(nullptr, false);
  1385. if (visible && window_id != DisplayServer::MAIN_WINDOW_ID) {
  1386. if (get_tree() && get_tree()->is_accessibility_supported()) {
  1387. _accessibility_notify_exit(this);
  1388. if (get_parent()) {
  1389. get_parent()->queue_accessibility_update();
  1390. }
  1391. if (embedder) {
  1392. embedder->queue_accessibility_update();
  1393. }
  1394. }
  1395. }
  1396. accessibility_title_element = RID();
  1397. accessibility_announcement_element = RID();
  1398. if (transient) {
  1399. _clear_transient();
  1400. }
  1401. if (!is_embedded() && window_id != DisplayServer::INVALID_WINDOW_ID) {
  1402. if (window_id == DisplayServer::MAIN_WINDOW_ID) {
  1403. RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED);
  1404. _update_window_callbacks();
  1405. } else {
  1406. _clear_window();
  1407. }
  1408. } else {
  1409. if (embedder) {
  1410. embedder->_sub_window_remove(this);
  1411. embedder = nullptr;
  1412. RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED);
  1413. }
  1414. _update_viewport_size(); //called by clear and make, which does not happen here
  1415. }
  1416. RS::get_singleton()->viewport_set_active(get_viewport_rid(), false);
  1417. } break;
  1418. case NOTIFICATION_VP_MOUSE_ENTER: {
  1419. emit_signal(SceneStringName(mouse_entered));
  1420. } break;
  1421. case NOTIFICATION_VP_MOUSE_EXIT: {
  1422. emit_signal(SceneStringName(mouse_exited));
  1423. } break;
  1424. }
  1425. }
  1426. void Window::set_content_scale_size(const Size2i &p_size) {
  1427. ERR_MAIN_THREAD_GUARD;
  1428. ERR_FAIL_COND(p_size.x < 0);
  1429. ERR_FAIL_COND(p_size.y < 0);
  1430. content_scale_size = p_size;
  1431. _update_viewport_size();
  1432. }
  1433. Size2i Window::get_content_scale_size() const {
  1434. ERR_READ_THREAD_GUARD_V(Size2i());
  1435. return content_scale_size;
  1436. }
  1437. void Window::set_content_scale_mode(ContentScaleMode p_mode) {
  1438. ERR_MAIN_THREAD_GUARD;
  1439. content_scale_mode = p_mode;
  1440. _update_viewport_size();
  1441. }
  1442. Window::ContentScaleMode Window::get_content_scale_mode() const {
  1443. ERR_READ_THREAD_GUARD_V(CONTENT_SCALE_MODE_DISABLED);
  1444. return content_scale_mode;
  1445. }
  1446. void Window::set_content_scale_aspect(ContentScaleAspect p_aspect) {
  1447. ERR_MAIN_THREAD_GUARD;
  1448. content_scale_aspect = p_aspect;
  1449. _update_viewport_size();
  1450. }
  1451. Window::ContentScaleAspect Window::get_content_scale_aspect() const {
  1452. ERR_READ_THREAD_GUARD_V(CONTENT_SCALE_ASPECT_IGNORE);
  1453. return content_scale_aspect;
  1454. }
  1455. void Window::set_content_scale_stretch(ContentScaleStretch p_stretch) {
  1456. content_scale_stretch = p_stretch;
  1457. _update_viewport_size();
  1458. }
  1459. Window::ContentScaleStretch Window::get_content_scale_stretch() const {
  1460. return content_scale_stretch;
  1461. }
  1462. void Window::set_keep_title_visible(bool p_title_visible) {
  1463. if (keep_title_visible == p_title_visible) {
  1464. return;
  1465. }
  1466. keep_title_visible = p_title_visible;
  1467. if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  1468. _update_window_size();
  1469. }
  1470. }
  1471. bool Window::get_keep_title_visible() const {
  1472. return keep_title_visible;
  1473. }
  1474. void Window::set_content_scale_factor(real_t p_factor) {
  1475. ERR_MAIN_THREAD_GUARD;
  1476. ERR_FAIL_COND(p_factor <= 0);
  1477. content_scale_factor = p_factor;
  1478. _update_viewport_size();
  1479. }
  1480. real_t Window::get_content_scale_factor() const {
  1481. ERR_READ_THREAD_GUARD_V(0);
  1482. return content_scale_factor;
  1483. }
  1484. DisplayServer::WindowID Window::get_window_id() const {
  1485. ERR_READ_THREAD_GUARD_V(DisplayServer::INVALID_WINDOW_ID);
  1486. if (get_embedder()) {
  1487. #ifdef TOOLS_ENABLED
  1488. if (is_part_of_edited_scene()) {
  1489. return DisplayServer::MAIN_WINDOW_ID;
  1490. }
  1491. #endif
  1492. return parent->get_window_id();
  1493. }
  1494. return window_id;
  1495. }
  1496. void Window::set_mouse_passthrough_polygon(const Vector<Vector2> &p_region) {
  1497. ERR_MAIN_THREAD_GUARD;
  1498. mpath = p_region;
  1499. if (window_id == DisplayServer::INVALID_WINDOW_ID) {
  1500. return;
  1501. }
  1502. DisplayServer::get_singleton()->window_set_mouse_passthrough(mpath, window_id);
  1503. }
  1504. Vector<Vector2> Window::get_mouse_passthrough_polygon() const {
  1505. return mpath;
  1506. }
  1507. void Window::set_wrap_controls(bool p_enable) {
  1508. ERR_MAIN_THREAD_GUARD;
  1509. wrap_controls = p_enable;
  1510. if (!is_inside_tree()) {
  1511. return;
  1512. }
  1513. if (updating_child_controls) {
  1514. _update_child_controls();
  1515. } else {
  1516. _update_window_size();
  1517. }
  1518. }
  1519. bool Window::is_wrapping_controls() const {
  1520. ERR_READ_THREAD_GUARD_V(false);
  1521. return wrap_controls;
  1522. }
  1523. Size2 Window::_get_contents_minimum_size() const {
  1524. Size2 max;
  1525. for (int i = 0; i < get_child_count(); i++) {
  1526. Control *c = Object::cast_to<Control>(get_child(i));
  1527. if (c) {
  1528. Point2i pos = c->get_position();
  1529. Size2i min = c->get_combined_minimum_size();
  1530. max = max.max(pos + min);
  1531. }
  1532. }
  1533. return max * content_scale_factor;
  1534. }
  1535. void Window::child_controls_changed() {
  1536. ERR_MAIN_THREAD_GUARD;
  1537. if (!is_inside_tree() || !visible || updating_child_controls) {
  1538. return;
  1539. }
  1540. updating_child_controls = true;
  1541. callable_mp(this, &Window::_update_child_controls).call_deferred();
  1542. }
  1543. void Window::_update_child_controls() {
  1544. if (!updating_child_controls) {
  1545. return;
  1546. }
  1547. _update_window_size();
  1548. updating_child_controls = false;
  1549. }
  1550. bool Window::_can_consume_input_events() const {
  1551. return exclusive_child == nullptr;
  1552. }
  1553. void Window::_window_input(const Ref<InputEvent> &p_ev) {
  1554. ERR_MAIN_THREAD_GUARD;
  1555. if (exclusive_child != nullptr) {
  1556. if (!is_embedding_subwindows()) { // Not embedding, no need for event.
  1557. return;
  1558. }
  1559. }
  1560. // If the event needs to be handled in a Window-derived class, then it should overwrite
  1561. // `_input_from_window` instead of subscribing to the `window_input` signal, because the signal
  1562. // filters out internal events.
  1563. _input_from_window(p_ev);
  1564. if (p_ev->get_device() != InputEvent::DEVICE_ID_INTERNAL && is_inside_tree()) {
  1565. emit_signal(SceneStringName(window_input), p_ev);
  1566. }
  1567. if (is_inside_tree()) {
  1568. push_input(p_ev);
  1569. }
  1570. }
  1571. void Window::_window_input_text(const String &p_text) {
  1572. push_text_input(p_text);
  1573. }
  1574. void Window::_window_drop_files(const Vector<String> &p_files) {
  1575. emit_signal(SNAME("files_dropped"), p_files);
  1576. }
  1577. Viewport *Window::get_parent_viewport() const {
  1578. ERR_READ_THREAD_GUARD_V(nullptr);
  1579. if (get_parent()) {
  1580. return get_parent()->get_viewport();
  1581. } else {
  1582. return nullptr;
  1583. }
  1584. }
  1585. Window *Window::get_non_popup_window() const {
  1586. Window *w = const_cast<Window *>(this);
  1587. while (w && w->is_popup()) {
  1588. w = w->get_parent_visible_window();
  1589. }
  1590. return w;
  1591. }
  1592. Window *Window::get_parent_visible_window() const {
  1593. ERR_READ_THREAD_GUARD_V(nullptr);
  1594. Viewport *vp = get_parent_viewport();
  1595. Window *window = nullptr;
  1596. while (vp) {
  1597. window = Object::cast_to<Window>(vp);
  1598. if (window && window->visible) {
  1599. break;
  1600. }
  1601. if (!vp->get_parent()) {
  1602. break;
  1603. }
  1604. vp = vp->get_parent()->get_viewport();
  1605. }
  1606. return window;
  1607. }
  1608. void Window::popup_on_parent(const Rect2i &p_parent_rect) {
  1609. ERR_MAIN_THREAD_GUARD;
  1610. ERR_FAIL_COND(!is_inside_tree());
  1611. ERR_FAIL_COND_MSG(window_id == DisplayServer::MAIN_WINDOW_ID, "Can't popup the main window.");
  1612. if (!is_embedded()) {
  1613. Window *window = get_parent_visible_window();
  1614. if (!window) {
  1615. popup(p_parent_rect);
  1616. } else {
  1617. popup(Rect2i(window->get_position() + p_parent_rect.position, p_parent_rect.size));
  1618. }
  1619. } else {
  1620. popup(p_parent_rect);
  1621. }
  1622. }
  1623. void Window::popup_centered_clamped(const Size2i &p_size, float p_fallback_ratio) {
  1624. ERR_MAIN_THREAD_GUARD;
  1625. ERR_FAIL_COND(!is_inside_tree());
  1626. ERR_FAIL_COND_MSG(window_id == DisplayServer::MAIN_WINDOW_ID, "Can't popup the main window.");
  1627. // Consider the current size when calling with the default value.
  1628. Size2i expected_size = p_size == Size2i() ? size : p_size;
  1629. Rect2 parent_rect;
  1630. if (is_embedded()) {
  1631. parent_rect = get_embedder()->get_visible_rect();
  1632. } else {
  1633. DisplayServer::WindowID parent_id = get_parent_visible_window()->get_window_id();
  1634. int parent_screen = DisplayServer::get_singleton()->window_get_current_screen(parent_id);
  1635. parent_rect.position = DisplayServer::get_singleton()->screen_get_position(parent_screen);
  1636. parent_rect.size = DisplayServer::get_singleton()->screen_get_size(parent_screen);
  1637. }
  1638. Vector2i size_ratio = parent_rect.size * p_fallback_ratio;
  1639. Rect2i popup_rect;
  1640. popup_rect.size = size_ratio.min(expected_size);
  1641. popup_rect.size = _clamp_window_size(popup_rect.size);
  1642. if (parent_rect != Rect2()) {
  1643. popup_rect.position = parent_rect.position + (parent_rect.size - popup_rect.size) / 2;
  1644. }
  1645. popup(popup_rect);
  1646. }
  1647. void Window::popup_centered(const Size2i &p_minsize) {
  1648. ERR_MAIN_THREAD_GUARD;
  1649. ERR_FAIL_COND(!is_inside_tree());
  1650. ERR_FAIL_COND_MSG(window_id == DisplayServer::MAIN_WINDOW_ID, "Can't popup the main window.");
  1651. // Consider the current size when calling with the default value.
  1652. Size2i expected_size = p_minsize == Size2i() ? size : p_minsize;
  1653. Rect2 parent_rect;
  1654. if (is_embedded()) {
  1655. parent_rect = get_embedder()->get_visible_rect();
  1656. } else {
  1657. DisplayServer::WindowID parent_id = get_parent_visible_window()->get_window_id();
  1658. int parent_screen = DisplayServer::get_singleton()->window_get_current_screen(parent_id);
  1659. parent_rect.position = DisplayServer::get_singleton()->screen_get_position(parent_screen);
  1660. parent_rect.size = DisplayServer::get_singleton()->screen_get_size(parent_screen);
  1661. }
  1662. Rect2i popup_rect;
  1663. popup_rect.size = _clamp_window_size(expected_size);
  1664. if (parent_rect != Rect2()) {
  1665. popup_rect.position = parent_rect.position + (parent_rect.size - popup_rect.size) / 2;
  1666. }
  1667. popup(popup_rect);
  1668. }
  1669. void Window::popup_centered_ratio(float p_ratio) {
  1670. ERR_MAIN_THREAD_GUARD;
  1671. ERR_FAIL_COND(!is_inside_tree());
  1672. ERR_FAIL_COND_MSG(window_id == DisplayServer::MAIN_WINDOW_ID, "Can't popup the main window.");
  1673. ERR_FAIL_COND_MSG(p_ratio <= 0.0 || p_ratio > 1.0, "Ratio must be between 0.0 and 1.0!");
  1674. Rect2 parent_rect;
  1675. if (is_embedded()) {
  1676. parent_rect = get_embedder()->get_visible_rect();
  1677. } else {
  1678. DisplayServer::WindowID parent_id = get_parent_visible_window()->get_window_id();
  1679. int parent_screen = DisplayServer::get_singleton()->window_get_current_screen(parent_id);
  1680. parent_rect.position = DisplayServer::get_singleton()->screen_get_position(parent_screen);
  1681. parent_rect.size = DisplayServer::get_singleton()->screen_get_size(parent_screen);
  1682. }
  1683. Rect2i popup_rect;
  1684. if (parent_rect != Rect2()) {
  1685. popup_rect.size = parent_rect.size * p_ratio;
  1686. popup_rect.size = _clamp_window_size(popup_rect.size);
  1687. popup_rect.position = parent_rect.position + (parent_rect.size - popup_rect.size) / 2;
  1688. }
  1689. popup(popup_rect);
  1690. }
  1691. void Window::popup(const Rect2i &p_screen_rect) {
  1692. ERR_MAIN_THREAD_GUARD;
  1693. emit_signal(SNAME("about_to_popup"));
  1694. _pre_popup();
  1695. if (!get_embedder() && get_flag(FLAG_POPUP)) {
  1696. // Send a focus-out notification when opening a Window Manager Popup.
  1697. SceneTree *scene_tree = get_tree();
  1698. if (scene_tree) {
  1699. scene_tree->notify_group_flags(SceneTree::GROUP_CALL_DEFERRED, "_viewports", NOTIFICATION_WM_WINDOW_FOCUS_OUT);
  1700. }
  1701. }
  1702. // Update window size to calculate the actual window size based on contents minimum size and minimum size.
  1703. _update_window_size();
  1704. bool should_fit = is_embedded() || !DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_SELF_FITTING_WINDOWS);
  1705. if (p_screen_rect != Rect2i()) {
  1706. set_position(p_screen_rect.position);
  1707. if (should_fit) {
  1708. int screen_id = DisplayServer::get_singleton()->get_screen_from_rect(p_screen_rect);
  1709. Size2i screen_size = DisplayServer::get_singleton()->screen_get_usable_rect(screen_id).size;
  1710. Size2i new_size = p_screen_rect.size.min(screen_size);
  1711. set_size(new_size);
  1712. } else {
  1713. set_size(p_screen_rect.size);
  1714. }
  1715. }
  1716. Rect2i adjust = _popup_adjust_rect();
  1717. if (adjust != Rect2i()) {
  1718. set_position(adjust.position);
  1719. set_size(adjust.size);
  1720. }
  1721. int scr = DisplayServer::get_singleton()->get_screen_count();
  1722. for (int i = 0; i < scr; i++) {
  1723. Rect2i r = DisplayServer::get_singleton()->screen_get_usable_rect(i);
  1724. if (r.has_point(position)) {
  1725. current_screen = i;
  1726. break;
  1727. }
  1728. }
  1729. set_transient(true);
  1730. set_visible(true);
  1731. Rect2i parent_rect;
  1732. if (is_embedded()) {
  1733. parent_rect = get_embedder()->get_visible_rect();
  1734. } else {
  1735. int screen_id = DisplayServer::get_singleton()->window_get_current_screen(get_window_id());
  1736. parent_rect = DisplayServer::get_singleton()->screen_get_usable_rect(screen_id);
  1737. }
  1738. if (should_fit && parent_rect != Rect2i() && !parent_rect.intersects(Rect2i(position, size))) {
  1739. ERR_PRINT(vformat("Window %d spawned at invalid position: %s.", get_window_id(), position));
  1740. set_position((parent_rect.size - size) / 2);
  1741. }
  1742. if (parent_rect != Rect2i() && is_clamped_to_embedder() && is_embedded()) {
  1743. Rect2i new_rect = fit_rect_in_parent(Rect2i(position, size), parent_rect);
  1744. set_position(new_rect.position);
  1745. set_size(new_rect.size);
  1746. }
  1747. _post_popup();
  1748. notification(NOTIFICATION_POST_POPUP);
  1749. }
  1750. bool Window::_try_parent_dialog(Node *p_from_node) {
  1751. ERR_FAIL_NULL_V(p_from_node, false);
  1752. ERR_FAIL_COND_V_MSG(is_inside_tree(), false, "Attempting to parent and popup a dialog that already has a parent.");
  1753. Window *w = p_from_node->get_last_exclusive_window();
  1754. if (w && w != this) {
  1755. w->add_child(this);
  1756. return true;
  1757. }
  1758. return false;
  1759. }
  1760. void Window::popup_exclusive(Node *p_from_node, const Rect2i &p_screen_rect) {
  1761. if (_try_parent_dialog(p_from_node)) {
  1762. popup(p_screen_rect);
  1763. }
  1764. }
  1765. void Window::popup_exclusive_on_parent(Node *p_from_node, const Rect2i &p_parent_rect) {
  1766. if (_try_parent_dialog(p_from_node)) {
  1767. popup_on_parent(p_parent_rect);
  1768. }
  1769. }
  1770. void Window::popup_exclusive_centered(Node *p_from_node, const Size2i &p_minsize) {
  1771. if (_try_parent_dialog(p_from_node)) {
  1772. popup_centered(p_minsize);
  1773. }
  1774. }
  1775. void Window::popup_exclusive_centered_ratio(Node *p_from_node, float p_ratio) {
  1776. if (_try_parent_dialog(p_from_node)) {
  1777. popup_centered_ratio(p_ratio);
  1778. }
  1779. }
  1780. void Window::popup_exclusive_centered_clamped(Node *p_from_node, const Size2i &p_size, float p_fallback_ratio) {
  1781. if (_try_parent_dialog(p_from_node)) {
  1782. popup_centered_clamped(p_size, p_fallback_ratio);
  1783. }
  1784. }
  1785. Rect2i Window::fit_rect_in_parent(Rect2i p_rect, const Rect2i &p_parent_rect) const {
  1786. ERR_READ_THREAD_GUARD_V(Rect2i());
  1787. Size2i limit = p_parent_rect.size;
  1788. if (p_rect.position.x + p_rect.size.x > limit.x) {
  1789. p_rect.position.x = limit.x - p_rect.size.x;
  1790. }
  1791. if (p_rect.position.y + p_rect.size.y > limit.y) {
  1792. p_rect.position.y = limit.y - p_rect.size.y;
  1793. }
  1794. if (p_rect.position.x < 0) {
  1795. p_rect.position.x = 0;
  1796. }
  1797. int title_height = get_flag(Window::FLAG_BORDERLESS) ? 0 : theme_cache.title_height;
  1798. if (p_rect.position.y < title_height) {
  1799. p_rect.position.y = title_height;
  1800. }
  1801. return p_rect;
  1802. }
  1803. Size2 Window::get_contents_minimum_size() const {
  1804. ERR_READ_THREAD_GUARD_V(Size2());
  1805. Vector2 ms;
  1806. if (GDVIRTUAL_CALL(_get_contents_minimum_size, ms)) {
  1807. return ms;
  1808. }
  1809. return _get_contents_minimum_size();
  1810. }
  1811. Size2 Window::get_clamped_minimum_size() const {
  1812. ERR_READ_THREAD_GUARD_V(Size2());
  1813. if (!wrap_controls) {
  1814. return min_size;
  1815. }
  1816. return min_size.max(get_contents_minimum_size() * get_content_scale_factor());
  1817. }
  1818. void Window::grab_focus() {
  1819. ERR_MAIN_THREAD_GUARD;
  1820. if (embedder) {
  1821. embedder->_sub_window_grab_focus(this);
  1822. } else if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  1823. DisplayServer::get_singleton()->window_move_to_foreground(window_id);
  1824. }
  1825. }
  1826. bool Window::has_focus() const {
  1827. ERR_READ_THREAD_GUARD_V(false);
  1828. if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  1829. return DisplayServer::get_singleton()->window_is_focused(window_id);
  1830. }
  1831. return focused;
  1832. }
  1833. bool Window::has_focus_or_active_popup() const {
  1834. ERR_READ_THREAD_GUARD_V(false);
  1835. if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  1836. return DisplayServer::get_singleton()->window_is_focused(window_id) || (DisplayServer::get_singleton()->window_get_active_popup() == window_id);
  1837. }
  1838. return focused;
  1839. }
  1840. void Window::start_drag() {
  1841. ERR_MAIN_THREAD_GUARD;
  1842. if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  1843. DisplayServer::get_singleton()->window_start_drag(window_id);
  1844. } else if (embedder) {
  1845. embedder->_window_start_drag(this);
  1846. }
  1847. }
  1848. void Window::start_resize(DisplayServer::WindowResizeEdge p_edge) {
  1849. ERR_MAIN_THREAD_GUARD;
  1850. if (get_flag(FLAG_RESIZE_DISABLED)) {
  1851. return;
  1852. }
  1853. if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  1854. DisplayServer::get_singleton()->window_start_resize(p_edge, window_id);
  1855. } else if (embedder) {
  1856. switch (p_edge) {
  1857. case DisplayServer::WINDOW_EDGE_TOP_LEFT: {
  1858. embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_TOP_LEFT, this);
  1859. } break;
  1860. case DisplayServer::WINDOW_EDGE_TOP: {
  1861. embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_TOP, this);
  1862. } break;
  1863. case DisplayServer::WINDOW_EDGE_TOP_RIGHT: {
  1864. embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_TOP_RIGHT, this);
  1865. } break;
  1866. case DisplayServer::WINDOW_EDGE_LEFT: {
  1867. embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_LEFT, this);
  1868. } break;
  1869. case DisplayServer::WINDOW_EDGE_RIGHT: {
  1870. embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_RIGHT, this);
  1871. } break;
  1872. case DisplayServer::WINDOW_EDGE_BOTTOM_LEFT: {
  1873. embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_BOTTOM_LEFT, this);
  1874. } break;
  1875. case DisplayServer::WINDOW_EDGE_BOTTOM: {
  1876. embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_BOTTOM, this);
  1877. } break;
  1878. case DisplayServer::WINDOW_EDGE_BOTTOM_RIGHT: {
  1879. embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_BOTTOM_RIGHT, this);
  1880. } break;
  1881. default:
  1882. break;
  1883. }
  1884. }
  1885. }
  1886. Rect2i Window::get_usable_parent_rect() const {
  1887. ERR_READ_THREAD_GUARD_V(Rect2i());
  1888. ERR_FAIL_COND_V(!is_inside_tree(), Rect2());
  1889. Rect2i parent_rect;
  1890. if (is_embedded()) {
  1891. parent_rect = get_embedder()->get_visible_rect();
  1892. } else {
  1893. const Window *w = is_visible() ? this : get_parent_visible_window();
  1894. //find a parent that can contain us
  1895. ERR_FAIL_NULL_V(w, Rect2());
  1896. parent_rect = DisplayServer::get_singleton()->screen_get_usable_rect(DisplayServer::get_singleton()->window_get_current_screen(w->get_window_id()));
  1897. }
  1898. return parent_rect;
  1899. }
  1900. void Window::set_accessibility_name(const String &p_name) {
  1901. ERR_MAIN_THREAD_GUARD;
  1902. if (accessibility_name != p_name) {
  1903. accessibility_name = p_name;
  1904. queue_accessibility_update();
  1905. update_configuration_warnings();
  1906. }
  1907. }
  1908. String Window::get_accessibility_name() const {
  1909. return tr(accessibility_name);
  1910. }
  1911. void Window::set_accessibility_description(const String &p_description) {
  1912. ERR_MAIN_THREAD_GUARD;
  1913. if (accessibility_description != p_description) {
  1914. accessibility_description = p_description;
  1915. queue_accessibility_update();
  1916. }
  1917. }
  1918. String Window::get_accessibility_description() const {
  1919. return tr(accessibility_description);
  1920. }
  1921. void Window::accessibility_announcement(const String &p_announcement) {
  1922. ERR_MAIN_THREAD_GUARD;
  1923. announcement = p_announcement;
  1924. queue_accessibility_update();
  1925. }
  1926. void Window::add_child_notify(Node *p_child) {
  1927. if (is_inside_tree() && wrap_controls) {
  1928. child_controls_changed();
  1929. }
  1930. }
  1931. void Window::remove_child_notify(Node *p_child) {
  1932. if (is_inside_tree() && wrap_controls) {
  1933. child_controls_changed();
  1934. }
  1935. }
  1936. // Theming.
  1937. void Window::set_theme_owner_node(Node *p_node) {
  1938. ERR_MAIN_THREAD_GUARD;
  1939. theme_owner->set_owner_node(p_node);
  1940. }
  1941. Node *Window::get_theme_owner_node() const {
  1942. ERR_READ_THREAD_GUARD_V(nullptr);
  1943. return theme_owner->get_owner_node();
  1944. }
  1945. bool Window::has_theme_owner_node() const {
  1946. ERR_READ_THREAD_GUARD_V(false);
  1947. return theme_owner->has_owner_node();
  1948. }
  1949. void Window::set_theme_context(ThemeContext *p_context, bool p_propagate) {
  1950. ERR_MAIN_THREAD_GUARD;
  1951. theme_owner->set_owner_context(p_context, p_propagate);
  1952. }
  1953. void Window::set_theme(const Ref<Theme> &p_theme) {
  1954. ERR_MAIN_THREAD_GUARD;
  1955. if (theme == p_theme) {
  1956. return;
  1957. }
  1958. if (theme.is_valid()) {
  1959. theme->disconnect_changed(callable_mp(this, &Window::_theme_changed));
  1960. }
  1961. theme = p_theme;
  1962. if (theme.is_valid()) {
  1963. theme_owner->propagate_theme_changed(this, this, is_inside_tree(), true);
  1964. theme->connect_changed(callable_mp(this, &Window::_theme_changed), CONNECT_DEFERRED);
  1965. return;
  1966. }
  1967. Control *parent_c = Object::cast_to<Control>(get_parent());
  1968. if (parent_c && parent_c->has_theme_owner_node()) {
  1969. theme_owner->propagate_theme_changed(this, parent_c->get_theme_owner_node(), is_inside_tree(), true);
  1970. return;
  1971. }
  1972. Window *parent_w = cast_to<Window>(get_parent());
  1973. if (parent_w && parent_w->has_theme_owner_node()) {
  1974. theme_owner->propagate_theme_changed(this, parent_w->get_theme_owner_node(), is_inside_tree(), true);
  1975. return;
  1976. }
  1977. theme_owner->propagate_theme_changed(this, nullptr, is_inside_tree(), true);
  1978. }
  1979. Ref<Theme> Window::get_theme() const {
  1980. ERR_READ_THREAD_GUARD_V(Ref<Theme>());
  1981. return theme;
  1982. }
  1983. void Window::_theme_changed() {
  1984. if (is_inside_tree()) {
  1985. theme_owner->propagate_theme_changed(this, this, true, false);
  1986. }
  1987. }
  1988. void Window::_notify_theme_override_changed() {
  1989. if (!bulk_theme_override && is_inside_tree()) {
  1990. notification(NOTIFICATION_THEME_CHANGED);
  1991. }
  1992. }
  1993. void Window::_invalidate_theme_cache() {
  1994. theme_icon_cache.clear();
  1995. theme_style_cache.clear();
  1996. theme_font_cache.clear();
  1997. theme_font_size_cache.clear();
  1998. theme_color_cache.clear();
  1999. theme_constant_cache.clear();
  2000. }
  2001. void Window::_update_theme_item_cache() {
  2002. // Request an update on the next frame to reflect theme changes.
  2003. // Updating without a delay can cause a lot of lag.
  2004. if (!wrap_controls) {
  2005. updating_embedded_window = true;
  2006. callable_mp(this, &Window::_update_embedded_window).call_deferred();
  2007. } else {
  2008. child_controls_changed();
  2009. }
  2010. ThemeDB::get_singleton()->update_class_instance_items(this);
  2011. }
  2012. void Window::_update_embedded_window() {
  2013. if (!updating_embedded_window) {
  2014. return;
  2015. }
  2016. if (embedder) {
  2017. embedder->_sub_window_update(this);
  2018. };
  2019. updating_embedded_window = false;
  2020. }
  2021. void Window::set_theme_type_variation(const StringName &p_theme_type) {
  2022. ERR_MAIN_THREAD_GUARD;
  2023. theme_type_variation = p_theme_type;
  2024. if (is_inside_tree()) {
  2025. notification(NOTIFICATION_THEME_CHANGED);
  2026. }
  2027. }
  2028. StringName Window::get_theme_type_variation() const {
  2029. ERR_READ_THREAD_GUARD_V(StringName());
  2030. return theme_type_variation;
  2031. }
  2032. /// Theme property lookup.
  2033. Ref<Texture2D> Window::get_theme_icon(const StringName &p_name, const StringName &p_theme_type) const {
  2034. ERR_READ_THREAD_GUARD_V(Ref<Texture2D>());
  2035. if (!initialized) {
  2036. WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", get_description()));
  2037. }
  2038. if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_type_variation) {
  2039. const Ref<Texture2D> *tex = theme_icon_override.getptr(p_name);
  2040. if (tex) {
  2041. return *tex;
  2042. }
  2043. }
  2044. if (theme_icon_cache.has(p_theme_type) && theme_icon_cache[p_theme_type].has(p_name)) {
  2045. return theme_icon_cache[p_theme_type][p_name];
  2046. }
  2047. Vector<StringName> theme_types;
  2048. theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types);
  2049. Ref<Texture2D> icon = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_ICON, p_name, theme_types);
  2050. theme_icon_cache[p_theme_type][p_name] = icon;
  2051. return icon;
  2052. }
  2053. Ref<StyleBox> Window::get_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const {
  2054. ERR_READ_THREAD_GUARD_V(Ref<StyleBox>());
  2055. if (!initialized) {
  2056. WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", get_description()));
  2057. }
  2058. if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_type_variation) {
  2059. const Ref<StyleBox> *style = theme_style_override.getptr(p_name);
  2060. if (style) {
  2061. return *style;
  2062. }
  2063. }
  2064. if (theme_style_cache.has(p_theme_type) && theme_style_cache[p_theme_type].has(p_name)) {
  2065. return theme_style_cache[p_theme_type][p_name];
  2066. }
  2067. Vector<StringName> theme_types;
  2068. theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types);
  2069. Ref<StyleBox> style = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_STYLEBOX, p_name, theme_types);
  2070. theme_style_cache[p_theme_type][p_name] = style;
  2071. return style;
  2072. }
  2073. Ref<Font> Window::get_theme_font(const StringName &p_name, const StringName &p_theme_type) const {
  2074. ERR_READ_THREAD_GUARD_V(Ref<Font>());
  2075. if (!initialized) {
  2076. WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", get_description()));
  2077. }
  2078. if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_type_variation) {
  2079. const Ref<Font> *font = theme_font_override.getptr(p_name);
  2080. if (font) {
  2081. return *font;
  2082. }
  2083. }
  2084. if (theme_font_cache.has(p_theme_type) && theme_font_cache[p_theme_type].has(p_name)) {
  2085. return theme_font_cache[p_theme_type][p_name];
  2086. }
  2087. Vector<StringName> theme_types;
  2088. theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types);
  2089. Ref<Font> font = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_FONT, p_name, theme_types);
  2090. theme_font_cache[p_theme_type][p_name] = font;
  2091. return font;
  2092. }
  2093. int Window::get_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const {
  2094. ERR_READ_THREAD_GUARD_V(0);
  2095. if (!initialized) {
  2096. WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", get_description()));
  2097. }
  2098. if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_type_variation) {
  2099. const int *font_size = theme_font_size_override.getptr(p_name);
  2100. if (font_size && (*font_size) > 0) {
  2101. return *font_size;
  2102. }
  2103. }
  2104. if (theme_font_size_cache.has(p_theme_type) && theme_font_size_cache[p_theme_type].has(p_name)) {
  2105. return theme_font_size_cache[p_theme_type][p_name];
  2106. }
  2107. Vector<StringName> theme_types;
  2108. theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types);
  2109. int font_size = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types);
  2110. theme_font_size_cache[p_theme_type][p_name] = font_size;
  2111. return font_size;
  2112. }
  2113. Color Window::get_theme_color(const StringName &p_name, const StringName &p_theme_type) const {
  2114. ERR_READ_THREAD_GUARD_V(Color());
  2115. if (!initialized) {
  2116. WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", get_description()));
  2117. }
  2118. if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_type_variation) {
  2119. const Color *color = theme_color_override.getptr(p_name);
  2120. if (color) {
  2121. return *color;
  2122. }
  2123. }
  2124. if (theme_color_cache.has(p_theme_type) && theme_color_cache[p_theme_type].has(p_name)) {
  2125. return theme_color_cache[p_theme_type][p_name];
  2126. }
  2127. Vector<StringName> theme_types;
  2128. theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types);
  2129. Color color = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_COLOR, p_name, theme_types);
  2130. theme_color_cache[p_theme_type][p_name] = color;
  2131. return color;
  2132. }
  2133. int Window::get_theme_constant(const StringName &p_name, const StringName &p_theme_type) const {
  2134. ERR_READ_THREAD_GUARD_V(0);
  2135. if (!initialized) {
  2136. WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", get_description()));
  2137. }
  2138. if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_type_variation) {
  2139. const int *constant = theme_constant_override.getptr(p_name);
  2140. if (constant) {
  2141. return *constant;
  2142. }
  2143. }
  2144. if (theme_constant_cache.has(p_theme_type) && theme_constant_cache[p_theme_type].has(p_name)) {
  2145. return theme_constant_cache[p_theme_type][p_name];
  2146. }
  2147. Vector<StringName> theme_types;
  2148. theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types);
  2149. int constant = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_CONSTANT, p_name, theme_types);
  2150. theme_constant_cache[p_theme_type][p_name] = constant;
  2151. return constant;
  2152. }
  2153. Variant Window::get_theme_item(Theme::DataType p_data_type, const StringName &p_name, const StringName &p_theme_type) const {
  2154. switch (p_data_type) {
  2155. case Theme::DATA_TYPE_COLOR:
  2156. return get_theme_color(p_name, p_theme_type);
  2157. case Theme::DATA_TYPE_CONSTANT:
  2158. return get_theme_constant(p_name, p_theme_type);
  2159. case Theme::DATA_TYPE_FONT:
  2160. return get_theme_font(p_name, p_theme_type);
  2161. case Theme::DATA_TYPE_FONT_SIZE:
  2162. return get_theme_font_size(p_name, p_theme_type);
  2163. case Theme::DATA_TYPE_ICON:
  2164. return get_theme_icon(p_name, p_theme_type);
  2165. case Theme::DATA_TYPE_STYLEBOX:
  2166. return get_theme_stylebox(p_name, p_theme_type);
  2167. case Theme::DATA_TYPE_MAX:
  2168. break; // Can't happen, but silences warning.
  2169. }
  2170. return Variant();
  2171. }
  2172. #ifdef TOOLS_ENABLED
  2173. Ref<Texture2D> Window::get_editor_theme_icon(const StringName &p_name) const {
  2174. return get_theme_icon(p_name, SNAME("EditorIcons"));
  2175. }
  2176. Ref<Texture2D> Window::get_editor_theme_native_menu_icon(const StringName &p_name, bool p_global_menu, bool p_dark_mode) const {
  2177. if (!p_global_menu) {
  2178. return get_theme_icon(p_name, SNAME("EditorIcons"));
  2179. }
  2180. if (p_dark_mode && has_theme_icon(String(p_name) + "Dark", SNAME("EditorIcons"))) {
  2181. return get_theme_icon(String(p_name) + "Dark", SNAME("EditorIcons"));
  2182. } else if (!p_dark_mode && has_theme_icon(String(p_name) + "Light", SNAME("EditorIcons"))) {
  2183. return get_theme_icon(String(p_name) + "Light", SNAME("EditorIcons"));
  2184. }
  2185. return get_theme_icon(p_name, SNAME("EditorIcons"));
  2186. }
  2187. #endif
  2188. bool Window::has_theme_icon(const StringName &p_name, const StringName &p_theme_type) const {
  2189. ERR_READ_THREAD_GUARD_V(false);
  2190. if (!initialized) {
  2191. WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", get_description()));
  2192. }
  2193. if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_type_variation) {
  2194. if (has_theme_icon_override(p_name)) {
  2195. return true;
  2196. }
  2197. }
  2198. Vector<StringName> theme_types;
  2199. theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types);
  2200. return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_ICON, p_name, theme_types);
  2201. }
  2202. bool Window::has_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const {
  2203. ERR_READ_THREAD_GUARD_V(false);
  2204. if (!initialized) {
  2205. WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", get_description()));
  2206. }
  2207. if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_type_variation) {
  2208. if (has_theme_stylebox_override(p_name)) {
  2209. return true;
  2210. }
  2211. }
  2212. Vector<StringName> theme_types;
  2213. theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types);
  2214. return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_STYLEBOX, p_name, theme_types);
  2215. }
  2216. bool Window::has_theme_font(const StringName &p_name, const StringName &p_theme_type) const {
  2217. ERR_READ_THREAD_GUARD_V(false);
  2218. if (!initialized) {
  2219. WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", get_description()));
  2220. }
  2221. if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_type_variation) {
  2222. if (has_theme_font_override(p_name)) {
  2223. return true;
  2224. }
  2225. }
  2226. Vector<StringName> theme_types;
  2227. theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types);
  2228. return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_FONT, p_name, theme_types);
  2229. }
  2230. bool Window::has_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const {
  2231. ERR_READ_THREAD_GUARD_V(false);
  2232. if (!initialized) {
  2233. WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", get_description()));
  2234. }
  2235. if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_type_variation) {
  2236. if (has_theme_font_size_override(p_name)) {
  2237. return true;
  2238. }
  2239. }
  2240. Vector<StringName> theme_types;
  2241. theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types);
  2242. return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types);
  2243. }
  2244. bool Window::has_theme_color(const StringName &p_name, const StringName &p_theme_type) const {
  2245. ERR_READ_THREAD_GUARD_V(false);
  2246. if (!initialized) {
  2247. WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", get_description()));
  2248. }
  2249. if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_type_variation) {
  2250. if (has_theme_color_override(p_name)) {
  2251. return true;
  2252. }
  2253. }
  2254. Vector<StringName> theme_types;
  2255. theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types);
  2256. return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_COLOR, p_name, theme_types);
  2257. }
  2258. bool Window::has_theme_constant(const StringName &p_name, const StringName &p_theme_type) const {
  2259. ERR_READ_THREAD_GUARD_V(false);
  2260. if (!initialized) {
  2261. WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", get_description()));
  2262. }
  2263. if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_type_variation) {
  2264. if (has_theme_constant_override(p_name)) {
  2265. return true;
  2266. }
  2267. }
  2268. Vector<StringName> theme_types;
  2269. theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types);
  2270. return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_CONSTANT, p_name, theme_types);
  2271. }
  2272. /// Local property overrides.
  2273. void Window::add_theme_icon_override(const StringName &p_name, const Ref<Texture2D> &p_icon) {
  2274. ERR_MAIN_THREAD_GUARD;
  2275. ERR_FAIL_COND(p_icon.is_null());
  2276. if (theme_icon_override.has(p_name)) {
  2277. theme_icon_override[p_name]->disconnect_changed(callable_mp(this, &Window::_notify_theme_override_changed));
  2278. }
  2279. theme_icon_override[p_name] = p_icon;
  2280. theme_icon_override[p_name]->connect_changed(callable_mp(this, &Window::_notify_theme_override_changed), CONNECT_REFERENCE_COUNTED);
  2281. _notify_theme_override_changed();
  2282. }
  2283. void Window::add_theme_style_override(const StringName &p_name, const Ref<StyleBox> &p_style) {
  2284. ERR_MAIN_THREAD_GUARD;
  2285. ERR_FAIL_COND(p_style.is_null());
  2286. if (theme_style_override.has(p_name)) {
  2287. theme_style_override[p_name]->disconnect_changed(callable_mp(this, &Window::_notify_theme_override_changed));
  2288. }
  2289. theme_style_override[p_name] = p_style;
  2290. theme_style_override[p_name]->connect_changed(callable_mp(this, &Window::_notify_theme_override_changed), CONNECT_REFERENCE_COUNTED);
  2291. _notify_theme_override_changed();
  2292. }
  2293. void Window::add_theme_font_override(const StringName &p_name, const Ref<Font> &p_font) {
  2294. ERR_MAIN_THREAD_GUARD;
  2295. ERR_FAIL_COND(p_font.is_null());
  2296. if (theme_font_override.has(p_name)) {
  2297. theme_font_override[p_name]->disconnect_changed(callable_mp(this, &Window::_notify_theme_override_changed));
  2298. }
  2299. theme_font_override[p_name] = p_font;
  2300. theme_font_override[p_name]->connect_changed(callable_mp(this, &Window::_notify_theme_override_changed), CONNECT_REFERENCE_COUNTED);
  2301. _notify_theme_override_changed();
  2302. }
  2303. void Window::add_theme_font_size_override(const StringName &p_name, int p_font_size) {
  2304. ERR_MAIN_THREAD_GUARD;
  2305. theme_font_size_override[p_name] = p_font_size;
  2306. _notify_theme_override_changed();
  2307. }
  2308. void Window::add_theme_color_override(const StringName &p_name, const Color &p_color) {
  2309. ERR_MAIN_THREAD_GUARD;
  2310. theme_color_override[p_name] = p_color;
  2311. _notify_theme_override_changed();
  2312. }
  2313. void Window::add_theme_constant_override(const StringName &p_name, int p_constant) {
  2314. ERR_MAIN_THREAD_GUARD;
  2315. theme_constant_override[p_name] = p_constant;
  2316. _notify_theme_override_changed();
  2317. }
  2318. void Window::remove_theme_icon_override(const StringName &p_name) {
  2319. ERR_MAIN_THREAD_GUARD;
  2320. if (theme_icon_override.has(p_name)) {
  2321. theme_icon_override[p_name]->disconnect_changed(callable_mp(this, &Window::_notify_theme_override_changed));
  2322. }
  2323. theme_icon_override.erase(p_name);
  2324. _notify_theme_override_changed();
  2325. }
  2326. void Window::remove_theme_style_override(const StringName &p_name) {
  2327. ERR_MAIN_THREAD_GUARD;
  2328. if (theme_style_override.has(p_name)) {
  2329. theme_style_override[p_name]->disconnect_changed(callable_mp(this, &Window::_notify_theme_override_changed));
  2330. }
  2331. theme_style_override.erase(p_name);
  2332. _notify_theme_override_changed();
  2333. }
  2334. void Window::remove_theme_font_override(const StringName &p_name) {
  2335. ERR_MAIN_THREAD_GUARD;
  2336. if (theme_font_override.has(p_name)) {
  2337. theme_font_override[p_name]->disconnect_changed(callable_mp(this, &Window::_notify_theme_override_changed));
  2338. }
  2339. theme_font_override.erase(p_name);
  2340. _notify_theme_override_changed();
  2341. }
  2342. void Window::remove_theme_font_size_override(const StringName &p_name) {
  2343. ERR_MAIN_THREAD_GUARD;
  2344. theme_font_size_override.erase(p_name);
  2345. _notify_theme_override_changed();
  2346. }
  2347. void Window::remove_theme_color_override(const StringName &p_name) {
  2348. ERR_MAIN_THREAD_GUARD;
  2349. theme_color_override.erase(p_name);
  2350. _notify_theme_override_changed();
  2351. }
  2352. void Window::remove_theme_constant_override(const StringName &p_name) {
  2353. ERR_MAIN_THREAD_GUARD;
  2354. theme_constant_override.erase(p_name);
  2355. _notify_theme_override_changed();
  2356. }
  2357. bool Window::has_theme_icon_override(const StringName &p_name) const {
  2358. ERR_READ_THREAD_GUARD_V(false);
  2359. const Ref<Texture2D> *tex = theme_icon_override.getptr(p_name);
  2360. return tex != nullptr;
  2361. }
  2362. bool Window::has_theme_stylebox_override(const StringName &p_name) const {
  2363. ERR_READ_THREAD_GUARD_V(false);
  2364. const Ref<StyleBox> *style = theme_style_override.getptr(p_name);
  2365. return style != nullptr;
  2366. }
  2367. bool Window::has_theme_font_override(const StringName &p_name) const {
  2368. ERR_READ_THREAD_GUARD_V(false);
  2369. const Ref<Font> *font = theme_font_override.getptr(p_name);
  2370. return font != nullptr;
  2371. }
  2372. bool Window::has_theme_font_size_override(const StringName &p_name) const {
  2373. ERR_READ_THREAD_GUARD_V(false);
  2374. const int *font_size = theme_font_size_override.getptr(p_name);
  2375. return font_size != nullptr;
  2376. }
  2377. bool Window::has_theme_color_override(const StringName &p_name) const {
  2378. ERR_READ_THREAD_GUARD_V(false);
  2379. const Color *color = theme_color_override.getptr(p_name);
  2380. return color != nullptr;
  2381. }
  2382. bool Window::has_theme_constant_override(const StringName &p_name) const {
  2383. ERR_READ_THREAD_GUARD_V(false);
  2384. const int *constant = theme_constant_override.getptr(p_name);
  2385. return constant != nullptr;
  2386. }
  2387. /// Default theme properties.
  2388. float Window::get_theme_default_base_scale() const {
  2389. ERR_READ_THREAD_GUARD_V(0);
  2390. return theme_owner->get_theme_default_base_scale();
  2391. }
  2392. Ref<Font> Window::get_theme_default_font() const {
  2393. ERR_READ_THREAD_GUARD_V(Ref<Font>());
  2394. return theme_owner->get_theme_default_font();
  2395. }
  2396. int Window::get_theme_default_font_size() const {
  2397. ERR_READ_THREAD_GUARD_V(0);
  2398. return theme_owner->get_theme_default_font_size();
  2399. }
  2400. /// Bulk actions.
  2401. void Window::begin_bulk_theme_override() {
  2402. ERR_MAIN_THREAD_GUARD;
  2403. bulk_theme_override = true;
  2404. }
  2405. void Window::end_bulk_theme_override() {
  2406. ERR_MAIN_THREAD_GUARD;
  2407. ERR_FAIL_COND(!bulk_theme_override);
  2408. bulk_theme_override = false;
  2409. _notify_theme_override_changed();
  2410. }
  2411. //
  2412. Rect2i Window::get_parent_rect() const {
  2413. ERR_READ_THREAD_GUARD_V(Rect2i());
  2414. ERR_FAIL_COND_V(!is_inside_tree(), Rect2i());
  2415. if (is_embedded()) {
  2416. //viewport
  2417. Node *n = get_parent();
  2418. ERR_FAIL_NULL_V(n, Rect2i());
  2419. Viewport *p = n->get_viewport();
  2420. ERR_FAIL_NULL_V(p, Rect2i());
  2421. return p->get_visible_rect();
  2422. } else {
  2423. int x = get_position().x;
  2424. int closest_dist = 0x7FFFFFFF;
  2425. Rect2i closest_rect;
  2426. for (int i = 0; i < DisplayServer::get_singleton()->get_screen_count(); i++) {
  2427. Rect2i s(DisplayServer::get_singleton()->screen_get_position(i), DisplayServer::get_singleton()->screen_get_size(i));
  2428. int d;
  2429. if (x >= s.position.x && x < s.size.x) {
  2430. //contained
  2431. closest_rect = s;
  2432. break;
  2433. } else if (x < s.position.x) {
  2434. d = s.position.x - x;
  2435. } else {
  2436. d = x - (s.position.x + s.size.x);
  2437. }
  2438. if (d < closest_dist) {
  2439. closest_dist = d;
  2440. closest_rect = s;
  2441. }
  2442. }
  2443. return closest_rect;
  2444. }
  2445. }
  2446. void Window::set_clamp_to_embedder(bool p_enable) {
  2447. ERR_MAIN_THREAD_GUARD;
  2448. clamp_to_embedder = p_enable;
  2449. }
  2450. bool Window::is_clamped_to_embedder() const {
  2451. ERR_READ_THREAD_GUARD_V(false);
  2452. return clamp_to_embedder;
  2453. }
  2454. void Window::set_unparent_when_invisible(bool p_unparent) {
  2455. unparent_when_invisible = p_unparent;
  2456. }
  2457. void Window::set_layout_direction(Window::LayoutDirection p_direction) {
  2458. ERR_MAIN_THREAD_GUARD;
  2459. ERR_FAIL_INDEX(p_direction, LAYOUT_DIRECTION_MAX);
  2460. layout_dir = p_direction;
  2461. propagate_notification(Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED);
  2462. }
  2463. Window::LayoutDirection Window::get_layout_direction() const {
  2464. ERR_READ_THREAD_GUARD_V(LAYOUT_DIRECTION_INHERITED);
  2465. return layout_dir;
  2466. }
  2467. bool Window::is_layout_rtl() const {
  2468. ERR_READ_THREAD_GUARD_V(false);
  2469. if (layout_dir == LAYOUT_DIRECTION_INHERITED) {
  2470. #ifdef TOOLS_ENABLED
  2471. if (is_part_of_edited_scene() && GLOBAL_GET_CACHED(bool, "internationalization/rendering/force_right_to_left_layout_direction")) {
  2472. return true;
  2473. }
  2474. if (is_inside_tree()) {
  2475. Node *edited_scene_root = get_tree()->get_edited_scene_root();
  2476. if (edited_scene_root == this) {
  2477. int proj_root_layout_direction = GLOBAL_GET_CACHED(int, "internationalization/rendering/root_node_layout_direction");
  2478. if (proj_root_layout_direction == 1) {
  2479. return false;
  2480. } else if (proj_root_layout_direction == 2) {
  2481. return true;
  2482. } else if (proj_root_layout_direction == 3) {
  2483. String locale = OS::get_singleton()->get_locale();
  2484. return TS->is_locale_right_to_left(locale);
  2485. } else {
  2486. const Ref<Translation> &t = TranslationServer::get_singleton()->get_translation_object(TranslationServer::get_singleton()->get_locale());
  2487. String locale = t.is_valid() ? t->get_locale() : TranslationServer::get_singleton()->get_fallback_locale();
  2488. return TS->is_locale_right_to_left(locale);
  2489. }
  2490. }
  2491. }
  2492. #else
  2493. if (GLOBAL_GET_CACHED(bool, "internationalization/rendering/force_right_to_left_layout_direction")) {
  2494. return true;
  2495. }
  2496. #endif
  2497. Node *parent_node = get_parent();
  2498. while (parent_node) {
  2499. Control *parent_control = Object::cast_to<Control>(parent_node);
  2500. if (parent_control) {
  2501. return parent_control->is_layout_rtl();
  2502. }
  2503. Window *parent_window = Object::cast_to<Window>(parent_node);
  2504. if (parent_window) {
  2505. return parent_window->is_layout_rtl();
  2506. }
  2507. parent_node = parent_node->get_parent();
  2508. }
  2509. if (root_layout_direction == 1) {
  2510. return false;
  2511. } else if (root_layout_direction == 2) {
  2512. return true;
  2513. } else if (root_layout_direction == 3) {
  2514. String locale = OS::get_singleton()->get_locale();
  2515. return TS->is_locale_right_to_left(locale);
  2516. } else {
  2517. String locale = TranslationServer::get_singleton()->get_tool_locale();
  2518. return TS->is_locale_right_to_left(locale);
  2519. }
  2520. } else if (layout_dir == LAYOUT_DIRECTION_APPLICATION_LOCALE) {
  2521. if (GLOBAL_GET_CACHED(bool, "internationalization/rendering/force_right_to_left_layout_direction")) {
  2522. return true;
  2523. } else {
  2524. String locale = TranslationServer::get_singleton()->get_tool_locale();
  2525. return TS->is_locale_right_to_left(locale);
  2526. }
  2527. } else if (layout_dir == LAYOUT_DIRECTION_SYSTEM_LOCALE) {
  2528. if (GLOBAL_GET_CACHED(bool, "internationalization/rendering/force_right_to_left_layout_direction")) {
  2529. return true;
  2530. } else {
  2531. String locale = OS::get_singleton()->get_locale();
  2532. return TS->is_locale_right_to_left(locale);
  2533. }
  2534. } else {
  2535. return (layout_dir == LAYOUT_DIRECTION_RTL);
  2536. }
  2537. }
  2538. #ifndef DISABLE_DEPRECATED
  2539. void Window::set_use_font_oversampling(bool p_oversampling) {
  2540. Viewport::set_use_oversampling(p_oversampling);
  2541. }
  2542. bool Window::is_using_font_oversampling() const {
  2543. return Viewport::is_using_oversampling();
  2544. }
  2545. void Window::set_auto_translate(bool p_enable) {
  2546. ERR_MAIN_THREAD_GUARD;
  2547. set_auto_translate_mode(p_enable ? AUTO_TRANSLATE_MODE_ALWAYS : AUTO_TRANSLATE_MODE_DISABLED);
  2548. }
  2549. bool Window::is_auto_translating() const {
  2550. ERR_READ_THREAD_GUARD_V(false);
  2551. return can_auto_translate();
  2552. }
  2553. #endif
  2554. Transform2D Window::get_final_transform() const {
  2555. ERR_READ_THREAD_GUARD_V(Transform2D());
  2556. return window_transform * stretch_transform * global_canvas_transform;
  2557. }
  2558. Transform2D Window::get_screen_transform_internal(bool p_absolute_position) const {
  2559. ERR_READ_THREAD_GUARD_V(Transform2D());
  2560. Transform2D embedder_transform;
  2561. if (get_embedder()) {
  2562. embedder_transform.translate_local(get_position());
  2563. embedder_transform = get_embedder()->get_screen_transform_internal(p_absolute_position) * embedder_transform;
  2564. } else if (p_absolute_position) {
  2565. embedder_transform.translate_local(get_position());
  2566. }
  2567. return embedder_transform * get_final_transform();
  2568. }
  2569. Transform2D Window::get_popup_base_transform_native() const {
  2570. ERR_READ_THREAD_GUARD_V(Transform2D());
  2571. if (!DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_SUBWINDOWS)) {
  2572. return Transform2D();
  2573. }
  2574. Transform2D popup_base_transform;
  2575. popup_base_transform.set_origin(get_position());
  2576. popup_base_transform *= get_final_transform();
  2577. if (get_embedder()) {
  2578. return get_embedder()->get_popup_base_transform_native() * popup_base_transform;
  2579. }
  2580. return popup_base_transform;
  2581. }
  2582. Transform2D Window::get_popup_base_transform() const {
  2583. ERR_READ_THREAD_GUARD_V(Transform2D());
  2584. if (is_embedding_subwindows()) {
  2585. return Transform2D();
  2586. }
  2587. Transform2D popup_base_transform;
  2588. popup_base_transform.set_origin(get_position());
  2589. popup_base_transform *= get_final_transform();
  2590. if (get_embedder()) {
  2591. return get_embedder()->get_popup_base_transform() * popup_base_transform;
  2592. }
  2593. return popup_base_transform;
  2594. }
  2595. Viewport *Window::get_section_root_viewport() const {
  2596. if (get_embedder()) {
  2597. return get_embedder()->get_section_root_viewport();
  2598. }
  2599. if (is_inside_tree()) {
  2600. // Native window.
  2601. return SceneTree::get_singleton()->get_root();
  2602. }
  2603. Window *vp = const_cast<Window *>(this);
  2604. return vp;
  2605. }
  2606. bool Window::is_attached_in_viewport() const {
  2607. return get_embedder();
  2608. }
  2609. void Window::_update_mouse_over(Vector2 p_pos) {
  2610. if (!mouse_in_window) {
  2611. if (is_embedded()) {
  2612. mouse_in_window = true;
  2613. _propagate_window_notification(this, NOTIFICATION_WM_MOUSE_ENTER);
  2614. }
  2615. }
  2616. bool new_in = get_visible_rect().has_point(p_pos);
  2617. if (new_in == gui.mouse_in_viewport) {
  2618. if (new_in) {
  2619. Viewport::_update_mouse_over(p_pos);
  2620. }
  2621. return;
  2622. }
  2623. if (new_in) {
  2624. notification(NOTIFICATION_VP_MOUSE_ENTER);
  2625. Viewport::_update_mouse_over(p_pos);
  2626. } else {
  2627. Viewport::_mouse_leave_viewport();
  2628. }
  2629. }
  2630. void Window::_mouse_leave_viewport() {
  2631. Viewport::_mouse_leave_viewport();
  2632. if (is_embedded()) {
  2633. mouse_in_window = false;
  2634. _propagate_window_notification(this, NOTIFICATION_WM_MOUSE_EXIT);
  2635. }
  2636. }
  2637. void Window::_update_displayed_title() {
  2638. displayed_title = atr(title);
  2639. #ifdef DEBUG_ENABLED
  2640. if (window_id == DisplayServer::MAIN_WINDOW_ID && !Engine::get_singleton()->is_project_manager_hint()) {
  2641. // Append a suffix to the window title to denote that the project is running
  2642. // from a debug build (including the editor, excluding the project manager).
  2643. // Since this results in lower performance, this should be clearly presented
  2644. // to the user.
  2645. displayed_title = vformat("%s (DEBUG)", displayed_title);
  2646. }
  2647. #endif
  2648. if (embedder) {
  2649. embedder->_sub_window_update(this);
  2650. } else if (window_id != DisplayServer::INVALID_WINDOW_ID) {
  2651. DisplayServer::get_singleton()->window_set_title(displayed_title, window_id);
  2652. if (keep_title_visible) {
  2653. Size2i title_size = DisplayServer::get_singleton()->window_get_title_size(displayed_title, window_id);
  2654. Size2i size_limit = get_clamped_minimum_size();
  2655. if (title_size.x > size_limit.x || title_size.y > size_limit.y) {
  2656. _update_window_size();
  2657. }
  2658. }
  2659. }
  2660. #ifdef DEBUG_ENABLED
  2661. if (EngineDebugger::get_singleton() && window_id == DisplayServer::MAIN_WINDOW_ID && !Engine::get_singleton()->is_project_manager_hint()) {
  2662. Array arr = { displayed_title };
  2663. EngineDebugger::get_singleton()->send_message("window:title", arr);
  2664. }
  2665. #endif
  2666. queue_accessibility_update();
  2667. }
  2668. void Window::_bind_methods() {
  2669. ClassDB::bind_method(D_METHOD("set_title", "title"), &Window::set_title);
  2670. ClassDB::bind_method(D_METHOD("get_title"), &Window::get_title);
  2671. ClassDB::bind_method(D_METHOD("set_initial_position", "initial_position"), &Window::set_initial_position);
  2672. ClassDB::bind_method(D_METHOD("get_initial_position"), &Window::get_initial_position);
  2673. ClassDB::bind_method(D_METHOD("set_current_screen", "index"), &Window::set_current_screen);
  2674. ClassDB::bind_method(D_METHOD("get_current_screen"), &Window::get_current_screen);
  2675. ClassDB::bind_method(D_METHOD("set_position", "position"), &Window::set_position);
  2676. ClassDB::bind_method(D_METHOD("get_position"), &Window::get_position);
  2677. ClassDB::bind_method(D_METHOD("move_to_center"), &Window::move_to_center);
  2678. ClassDB::bind_method(D_METHOD("set_size", "size"), &Window::set_size);
  2679. ClassDB::bind_method(D_METHOD("get_size"), &Window::get_size);
  2680. ClassDB::bind_method(D_METHOD("reset_size"), &Window::reset_size);
  2681. ClassDB::bind_method(D_METHOD("get_position_with_decorations"), &Window::get_position_with_decorations);
  2682. ClassDB::bind_method(D_METHOD("get_size_with_decorations"), &Window::get_size_with_decorations);
  2683. ClassDB::bind_method(D_METHOD("set_max_size", "max_size"), &Window::set_max_size);
  2684. ClassDB::bind_method(D_METHOD("get_max_size"), &Window::get_max_size);
  2685. ClassDB::bind_method(D_METHOD("set_min_size", "min_size"), &Window::set_min_size);
  2686. ClassDB::bind_method(D_METHOD("get_min_size"), &Window::get_min_size);
  2687. ClassDB::bind_method(D_METHOD("set_mode", "mode"), &Window::set_mode);
  2688. ClassDB::bind_method(D_METHOD("get_mode"), &Window::get_mode);
  2689. ClassDB::bind_method(D_METHOD("set_flag", "flag", "enabled"), &Window::set_flag);
  2690. ClassDB::bind_method(D_METHOD("get_flag", "flag"), &Window::get_flag);
  2691. ClassDB::bind_method(D_METHOD("is_maximize_allowed"), &Window::is_maximize_allowed);
  2692. ClassDB::bind_method(D_METHOD("request_attention"), &Window::request_attention);
  2693. #ifndef DISABLE_DEPRECATED
  2694. ClassDB::bind_method(D_METHOD("move_to_foreground"), &Window::move_to_foreground);
  2695. #endif // DISABLE_DEPRECATED
  2696. ClassDB::bind_method(D_METHOD("set_visible", "visible"), &Window::set_visible);
  2697. ClassDB::bind_method(D_METHOD("is_visible"), &Window::is_visible);
  2698. ClassDB::bind_method(D_METHOD("hide"), &Window::hide);
  2699. ClassDB::bind_method(D_METHOD("show"), &Window::show);
  2700. ClassDB::bind_method(D_METHOD("set_transient", "transient"), &Window::set_transient);
  2701. ClassDB::bind_method(D_METHOD("is_transient"), &Window::is_transient);
  2702. ClassDB::bind_method(D_METHOD("set_transient_to_focused", "enable"), &Window::set_transient_to_focused);
  2703. ClassDB::bind_method(D_METHOD("is_transient_to_focused"), &Window::is_transient_to_focused);
  2704. ClassDB::bind_method(D_METHOD("set_exclusive", "exclusive"), &Window::set_exclusive);
  2705. ClassDB::bind_method(D_METHOD("is_exclusive"), &Window::is_exclusive);
  2706. ClassDB::bind_method(D_METHOD("set_unparent_when_invisible", "unparent"), &Window::set_unparent_when_invisible);
  2707. ClassDB::bind_method(D_METHOD("can_draw"), &Window::can_draw);
  2708. ClassDB::bind_method(D_METHOD("has_focus"), &Window::has_focus);
  2709. ClassDB::bind_method(D_METHOD("grab_focus"), &Window::grab_focus);
  2710. ClassDB::bind_method(D_METHOD("start_drag"), &Window::start_drag);
  2711. ClassDB::bind_method(D_METHOD("start_resize", "edge"), &Window::start_resize);
  2712. ClassDB::bind_method(D_METHOD("set_ime_active", "active"), &Window::set_ime_active);
  2713. ClassDB::bind_method(D_METHOD("set_ime_position", "position"), &Window::set_ime_position);
  2714. ClassDB::bind_method(D_METHOD("is_embedded"), &Window::is_embedded);
  2715. ClassDB::bind_method(D_METHOD("get_contents_minimum_size"), &Window::get_contents_minimum_size);
  2716. ClassDB::bind_method(D_METHOD("set_force_native", "force_native"), &Window::set_force_native);
  2717. ClassDB::bind_method(D_METHOD("get_force_native"), &Window::get_force_native);
  2718. ClassDB::bind_method(D_METHOD("set_content_scale_size", "size"), &Window::set_content_scale_size);
  2719. ClassDB::bind_method(D_METHOD("get_content_scale_size"), &Window::get_content_scale_size);
  2720. ClassDB::bind_method(D_METHOD("set_content_scale_mode", "mode"), &Window::set_content_scale_mode);
  2721. ClassDB::bind_method(D_METHOD("get_content_scale_mode"), &Window::get_content_scale_mode);
  2722. ClassDB::bind_method(D_METHOD("set_content_scale_aspect", "aspect"), &Window::set_content_scale_aspect);
  2723. ClassDB::bind_method(D_METHOD("get_content_scale_aspect"), &Window::get_content_scale_aspect);
  2724. ClassDB::bind_method(D_METHOD("set_content_scale_stretch", "stretch"), &Window::set_content_scale_stretch);
  2725. ClassDB::bind_method(D_METHOD("get_content_scale_stretch"), &Window::get_content_scale_stretch);
  2726. ClassDB::bind_method(D_METHOD("set_keep_title_visible", "title_visible"), &Window::set_keep_title_visible);
  2727. ClassDB::bind_method(D_METHOD("get_keep_title_visible"), &Window::get_keep_title_visible);
  2728. ClassDB::bind_method(D_METHOD("set_content_scale_factor", "factor"), &Window::set_content_scale_factor);
  2729. ClassDB::bind_method(D_METHOD("get_content_scale_factor"), &Window::get_content_scale_factor);
  2730. ClassDB::bind_method(D_METHOD("set_mouse_passthrough_polygon", "polygon"), &Window::set_mouse_passthrough_polygon);
  2731. ClassDB::bind_method(D_METHOD("get_mouse_passthrough_polygon"), &Window::get_mouse_passthrough_polygon);
  2732. ClassDB::bind_method(D_METHOD("set_wrap_controls", "enable"), &Window::set_wrap_controls);
  2733. ClassDB::bind_method(D_METHOD("is_wrapping_controls"), &Window::is_wrapping_controls);
  2734. ClassDB::bind_method(D_METHOD("child_controls_changed"), &Window::child_controls_changed);
  2735. ClassDB::bind_method(D_METHOD("set_theme", "theme"), &Window::set_theme);
  2736. ClassDB::bind_method(D_METHOD("get_theme"), &Window::get_theme);
  2737. ClassDB::bind_method(D_METHOD("set_theme_type_variation", "theme_type"), &Window::set_theme_type_variation);
  2738. ClassDB::bind_method(D_METHOD("get_theme_type_variation"), &Window::get_theme_type_variation);
  2739. ClassDB::bind_method(D_METHOD("begin_bulk_theme_override"), &Window::begin_bulk_theme_override);
  2740. ClassDB::bind_method(D_METHOD("end_bulk_theme_override"), &Window::end_bulk_theme_override);
  2741. ClassDB::bind_method(D_METHOD("add_theme_icon_override", "name", "texture"), &Window::add_theme_icon_override);
  2742. ClassDB::bind_method(D_METHOD("add_theme_stylebox_override", "name", "stylebox"), &Window::add_theme_style_override);
  2743. ClassDB::bind_method(D_METHOD("add_theme_font_override", "name", "font"), &Window::add_theme_font_override);
  2744. ClassDB::bind_method(D_METHOD("add_theme_font_size_override", "name", "font_size"), &Window::add_theme_font_size_override);
  2745. ClassDB::bind_method(D_METHOD("add_theme_color_override", "name", "color"), &Window::add_theme_color_override);
  2746. ClassDB::bind_method(D_METHOD("add_theme_constant_override", "name", "constant"), &Window::add_theme_constant_override);
  2747. ClassDB::bind_method(D_METHOD("remove_theme_icon_override", "name"), &Window::remove_theme_icon_override);
  2748. ClassDB::bind_method(D_METHOD("remove_theme_stylebox_override", "name"), &Window::remove_theme_style_override);
  2749. ClassDB::bind_method(D_METHOD("remove_theme_font_override", "name"), &Window::remove_theme_font_override);
  2750. ClassDB::bind_method(D_METHOD("remove_theme_font_size_override", "name"), &Window::remove_theme_font_size_override);
  2751. ClassDB::bind_method(D_METHOD("remove_theme_color_override", "name"), &Window::remove_theme_color_override);
  2752. ClassDB::bind_method(D_METHOD("remove_theme_constant_override", "name"), &Window::remove_theme_constant_override);
  2753. ClassDB::bind_method(D_METHOD("get_theme_icon", "name", "theme_type"), &Window::get_theme_icon, DEFVAL(StringName()));
  2754. ClassDB::bind_method(D_METHOD("get_theme_stylebox", "name", "theme_type"), &Window::get_theme_stylebox, DEFVAL(StringName()));
  2755. ClassDB::bind_method(D_METHOD("get_theme_font", "name", "theme_type"), &Window::get_theme_font, DEFVAL(StringName()));
  2756. ClassDB::bind_method(D_METHOD("get_theme_font_size", "name", "theme_type"), &Window::get_theme_font_size, DEFVAL(StringName()));
  2757. ClassDB::bind_method(D_METHOD("get_theme_color", "name", "theme_type"), &Window::get_theme_color, DEFVAL(StringName()));
  2758. ClassDB::bind_method(D_METHOD("get_theme_constant", "name", "theme_type"), &Window::get_theme_constant, DEFVAL(StringName()));
  2759. ClassDB::bind_method(D_METHOD("has_theme_icon_override", "name"), &Window::has_theme_icon_override);
  2760. ClassDB::bind_method(D_METHOD("has_theme_stylebox_override", "name"), &Window::has_theme_stylebox_override);
  2761. ClassDB::bind_method(D_METHOD("has_theme_font_override", "name"), &Window::has_theme_font_override);
  2762. ClassDB::bind_method(D_METHOD("has_theme_font_size_override", "name"), &Window::has_theme_font_size_override);
  2763. ClassDB::bind_method(D_METHOD("has_theme_color_override", "name"), &Window::has_theme_color_override);
  2764. ClassDB::bind_method(D_METHOD("has_theme_constant_override", "name"), &Window::has_theme_constant_override);
  2765. ClassDB::bind_method(D_METHOD("has_theme_icon", "name", "theme_type"), &Window::has_theme_icon, DEFVAL(StringName()));
  2766. ClassDB::bind_method(D_METHOD("has_theme_stylebox", "name", "theme_type"), &Window::has_theme_stylebox, DEFVAL(StringName()));
  2767. ClassDB::bind_method(D_METHOD("has_theme_font", "name", "theme_type"), &Window::has_theme_font, DEFVAL(StringName()));
  2768. ClassDB::bind_method(D_METHOD("has_theme_font_size", "name", "theme_type"), &Window::has_theme_font_size, DEFVAL(StringName()));
  2769. ClassDB::bind_method(D_METHOD("has_theme_color", "name", "theme_type"), &Window::has_theme_color, DEFVAL(StringName()));
  2770. ClassDB::bind_method(D_METHOD("has_theme_constant", "name", "theme_type"), &Window::has_theme_constant, DEFVAL(StringName()));
  2771. ClassDB::bind_method(D_METHOD("get_theme_default_base_scale"), &Window::get_theme_default_base_scale);
  2772. ClassDB::bind_method(D_METHOD("get_theme_default_font"), &Window::get_theme_default_font);
  2773. ClassDB::bind_method(D_METHOD("get_theme_default_font_size"), &Window::get_theme_default_font_size);
  2774. ClassDB::bind_method(D_METHOD("get_window_id"), &Window::get_window_id);
  2775. ClassDB::bind_method(D_METHOD("set_accessibility_name", "name"), &Window::set_accessibility_name);
  2776. ClassDB::bind_method(D_METHOD("get_accessibility_name"), &Window::get_accessibility_name);
  2777. ClassDB::bind_method(D_METHOD("set_accessibility_description", "description"), &Window::set_accessibility_description);
  2778. ClassDB::bind_method(D_METHOD("get_accessibility_description"), &Window::get_accessibility_description);
  2779. ClassDB::bind_static_method("Window", D_METHOD("get_focused_window"), &Window::get_focused_window);
  2780. ClassDB::bind_method(D_METHOD("set_layout_direction", "direction"), &Window::set_layout_direction);
  2781. ClassDB::bind_method(D_METHOD("get_layout_direction"), &Window::get_layout_direction);
  2782. ClassDB::bind_method(D_METHOD("is_layout_rtl"), &Window::is_layout_rtl);
  2783. #ifndef DISABLE_DEPRECATED
  2784. ClassDB::bind_method(D_METHOD("set_auto_translate", "enable"), &Window::set_auto_translate);
  2785. ClassDB::bind_method(D_METHOD("is_auto_translating"), &Window::is_auto_translating);
  2786. ClassDB::bind_method(D_METHOD("set_use_font_oversampling", "enable"), &Window::set_use_font_oversampling);
  2787. ClassDB::bind_method(D_METHOD("is_using_font_oversampling"), &Window::is_using_font_oversampling);
  2788. #endif
  2789. ClassDB::bind_method(D_METHOD("popup", "rect"), &Window::popup, DEFVAL(Rect2i()));
  2790. ClassDB::bind_method(D_METHOD("popup_on_parent", "parent_rect"), &Window::popup_on_parent);
  2791. ClassDB::bind_method(D_METHOD("popup_centered", "minsize"), &Window::popup_centered, DEFVAL(Size2i()));
  2792. ClassDB::bind_method(D_METHOD("popup_centered_ratio", "ratio"), &Window::popup_centered_ratio, DEFVAL(0.8));
  2793. ClassDB::bind_method(D_METHOD("popup_centered_clamped", "minsize", "fallback_ratio"), &Window::popup_centered_clamped, DEFVAL(Size2i()), DEFVAL(0.75));
  2794. ClassDB::bind_method(D_METHOD("popup_exclusive", "from_node", "rect"), &Window::popup_exclusive, DEFVAL(Rect2i()));
  2795. ClassDB::bind_method(D_METHOD("popup_exclusive_on_parent", "from_node", "parent_rect"), &Window::popup_exclusive_on_parent);
  2796. ClassDB::bind_method(D_METHOD("popup_exclusive_centered", "from_node", "minsize"), &Window::popup_exclusive_centered, DEFVAL(Size2i()));
  2797. ClassDB::bind_method(D_METHOD("popup_exclusive_centered_ratio", "from_node", "ratio"), &Window::popup_exclusive_centered_ratio, DEFVAL(0.8));
  2798. ClassDB::bind_method(D_METHOD("popup_exclusive_centered_clamped", "from_node", "minsize", "fallback_ratio"), &Window::popup_exclusive_centered_clamped, DEFVAL(Size2i()), DEFVAL(0.75));
  2799. // Keep the enum values in sync with the `Mode` enum.
  2800. ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Windowed,Minimized,Maximized,Fullscreen,Exclusive Fullscreen"), "set_mode", "get_mode");
  2801. ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title");
  2802. // Keep the enum values in sync with the `WindowInitialPosition` enum.
  2803. ADD_PROPERTY(PropertyInfo(Variant::INT, "initial_position", PROPERTY_HINT_ENUM, "Absolute,Center of Primary Screen,Center of Main Window Screen,Center of Other Screen,Center of Screen With Mouse Pointer,Center of Screen With Keyboard Focus"), "set_initial_position", "get_initial_position");
  2804. ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "position", PROPERTY_HINT_NONE, "suffix:px"), "set_position", "get_position");
  2805. ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "size", PROPERTY_HINT_NONE, "suffix:px"), "set_size", "get_size");
  2806. ADD_PROPERTY(PropertyInfo(Variant::INT, "current_screen", PROPERTY_HINT_RANGE, "0,64,1,or_greater"), "set_current_screen", "get_current_screen");
  2807. ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "mouse_passthrough_polygon"), "set_mouse_passthrough_polygon", "get_mouse_passthrough_polygon");
  2808. ADD_GROUP("Flags", "");
  2809. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible");
  2810. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "wrap_controls"), "set_wrap_controls", "is_wrapping_controls");
  2811. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "transient"), "set_transient", "is_transient");
  2812. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "transient_to_focused"), "set_transient_to_focused", "is_transient_to_focused");
  2813. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exclusive"), "set_exclusive", "is_exclusive");
  2814. ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "unresizable"), "set_flag", "get_flag", FLAG_RESIZE_DISABLED);
  2815. ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "borderless"), "set_flag", "get_flag", FLAG_BORDERLESS);
  2816. ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "always_on_top"), "set_flag", "get_flag", FLAG_ALWAYS_ON_TOP);
  2817. ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "transparent"), "set_flag", "get_flag", FLAG_TRANSPARENT);
  2818. ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "unfocusable"), "set_flag", "get_flag", FLAG_NO_FOCUS);
  2819. ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "popup_window"), "set_flag", "get_flag", FLAG_POPUP);
  2820. ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "extend_to_title"), "set_flag", "get_flag", FLAG_EXTEND_TO_TITLE);
  2821. ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "mouse_passthrough"), "set_flag", "get_flag", FLAG_MOUSE_PASSTHROUGH);
  2822. ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "sharp_corners"), "set_flag", "get_flag", FLAG_SHARP_CORNERS);
  2823. ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "exclude_from_capture"), "set_flag", "get_flag", FLAG_EXCLUDE_FROM_CAPTURE);
  2824. ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "popup_wm_hint"), "set_flag", "get_flag", FLAG_POPUP_WM_HINT);
  2825. ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "minimize_disabled"), "set_flag", "get_flag", FLAG_MINIMIZE_DISABLED);
  2826. ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "maximize_disabled"), "set_flag", "get_flag", FLAG_MAXIMIZE_DISABLED);
  2827. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_native"), "set_force_native", "get_force_native");
  2828. ADD_GROUP("Limits", "");
  2829. ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "min_size", PROPERTY_HINT_NONE, "suffix:px"), "set_min_size", "get_min_size");
  2830. ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "max_size", PROPERTY_HINT_NONE, "suffix:px"), "set_max_size", "get_max_size");
  2831. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_title_visible"), "set_keep_title_visible", "get_keep_title_visible");
  2832. ADD_GROUP("Content Scale", "content_scale_");
  2833. ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "content_scale_size"), "set_content_scale_size", "get_content_scale_size");
  2834. ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_mode", PROPERTY_HINT_ENUM, "Disabled,Canvas Items,Viewport"), "set_content_scale_mode", "get_content_scale_mode");
  2835. ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_aspect", PROPERTY_HINT_ENUM, "Ignore,Keep,Keep Width,Keep Height,Expand"), "set_content_scale_aspect", "get_content_scale_aspect");
  2836. ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_stretch", PROPERTY_HINT_ENUM, "Fractional,Integer"), "set_content_scale_stretch", "get_content_scale_stretch");
  2837. ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "content_scale_factor", PROPERTY_HINT_RANGE, "0.5,8.0,0.01"), "set_content_scale_factor", "get_content_scale_factor");
  2838. #ifndef DISABLE_DEPRECATED
  2839. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_translate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_auto_translate", "is_auto_translating");
  2840. #endif
  2841. ADD_GROUP("Accessibility", "accessibility_");
  2842. ADD_PROPERTY(PropertyInfo(Variant::STRING, "accessibility_name"), "set_accessibility_name", "get_accessibility_name");
  2843. ADD_PROPERTY(PropertyInfo(Variant::STRING, "accessibility_description"), "set_accessibility_description", "get_accessibility_description");
  2844. ADD_GROUP("Theme", "theme_");
  2845. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme");
  2846. ADD_PROPERTY(PropertyInfo(Variant::STRING, "theme_type_variation", PROPERTY_HINT_ENUM_SUGGESTION), "set_theme_type_variation", "get_theme_type_variation");
  2847. ADD_SIGNAL(MethodInfo("window_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
  2848. ADD_SIGNAL(MethodInfo("files_dropped", PropertyInfo(Variant::PACKED_STRING_ARRAY, "files")));
  2849. ADD_SIGNAL(MethodInfo("mouse_entered"));
  2850. ADD_SIGNAL(MethodInfo("mouse_exited"));
  2851. ADD_SIGNAL(MethodInfo("focus_entered"));
  2852. ADD_SIGNAL(MethodInfo("focus_exited"));
  2853. ADD_SIGNAL(MethodInfo("close_requested"));
  2854. ADD_SIGNAL(MethodInfo("go_back_requested"));
  2855. ADD_SIGNAL(MethodInfo("visibility_changed"));
  2856. ADD_SIGNAL(MethodInfo("about_to_popup"));
  2857. ADD_SIGNAL(MethodInfo("theme_changed"));
  2858. ADD_SIGNAL(MethodInfo("dpi_changed"));
  2859. ADD_SIGNAL(MethodInfo("titlebar_changed"));
  2860. ADD_SIGNAL(MethodInfo("title_changed"));
  2861. BIND_CONSTANT(NOTIFICATION_VISIBILITY_CHANGED);
  2862. BIND_CONSTANT(NOTIFICATION_THEME_CHANGED);
  2863. BIND_ENUM_CONSTANT(MODE_WINDOWED);
  2864. BIND_ENUM_CONSTANT(MODE_MINIMIZED);
  2865. BIND_ENUM_CONSTANT(MODE_MAXIMIZED);
  2866. BIND_ENUM_CONSTANT(MODE_FULLSCREEN);
  2867. BIND_ENUM_CONSTANT(MODE_EXCLUSIVE_FULLSCREEN);
  2868. BIND_ENUM_CONSTANT(FLAG_RESIZE_DISABLED);
  2869. BIND_ENUM_CONSTANT(FLAG_BORDERLESS);
  2870. BIND_ENUM_CONSTANT(FLAG_ALWAYS_ON_TOP);
  2871. BIND_ENUM_CONSTANT(FLAG_TRANSPARENT);
  2872. BIND_ENUM_CONSTANT(FLAG_NO_FOCUS);
  2873. BIND_ENUM_CONSTANT(FLAG_POPUP);
  2874. BIND_ENUM_CONSTANT(FLAG_EXTEND_TO_TITLE);
  2875. BIND_ENUM_CONSTANT(FLAG_MOUSE_PASSTHROUGH);
  2876. BIND_ENUM_CONSTANT(FLAG_SHARP_CORNERS);
  2877. BIND_ENUM_CONSTANT(FLAG_EXCLUDE_FROM_CAPTURE);
  2878. BIND_ENUM_CONSTANT(FLAG_POPUP_WM_HINT);
  2879. BIND_ENUM_CONSTANT(FLAG_MINIMIZE_DISABLED);
  2880. BIND_ENUM_CONSTANT(FLAG_MAXIMIZE_DISABLED);
  2881. BIND_ENUM_CONSTANT(FLAG_MAX);
  2882. BIND_ENUM_CONSTANT(CONTENT_SCALE_MODE_DISABLED);
  2883. BIND_ENUM_CONSTANT(CONTENT_SCALE_MODE_CANVAS_ITEMS);
  2884. BIND_ENUM_CONSTANT(CONTENT_SCALE_MODE_VIEWPORT);
  2885. BIND_ENUM_CONSTANT(CONTENT_SCALE_ASPECT_IGNORE);
  2886. BIND_ENUM_CONSTANT(CONTENT_SCALE_ASPECT_KEEP);
  2887. BIND_ENUM_CONSTANT(CONTENT_SCALE_ASPECT_KEEP_WIDTH);
  2888. BIND_ENUM_CONSTANT(CONTENT_SCALE_ASPECT_KEEP_HEIGHT);
  2889. BIND_ENUM_CONSTANT(CONTENT_SCALE_ASPECT_EXPAND);
  2890. BIND_ENUM_CONSTANT(CONTENT_SCALE_STRETCH_FRACTIONAL);
  2891. BIND_ENUM_CONSTANT(CONTENT_SCALE_STRETCH_INTEGER);
  2892. BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_INHERITED);
  2893. BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_APPLICATION_LOCALE);
  2894. BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_LTR);
  2895. BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_RTL);
  2896. BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_SYSTEM_LOCALE);
  2897. BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_MAX);
  2898. #ifndef DISABLE_DEPRECATED
  2899. BIND_ENUM_CONSTANT(LAYOUT_DIRECTION_LOCALE);
  2900. #endif // DISABLE_DEPRECATED
  2901. BIND_ENUM_CONSTANT(WINDOW_INITIAL_POSITION_ABSOLUTE);
  2902. BIND_ENUM_CONSTANT(WINDOW_INITIAL_POSITION_CENTER_PRIMARY_SCREEN);
  2903. BIND_ENUM_CONSTANT(WINDOW_INITIAL_POSITION_CENTER_MAIN_WINDOW_SCREEN);
  2904. BIND_ENUM_CONSTANT(WINDOW_INITIAL_POSITION_CENTER_OTHER_SCREEN);
  2905. BIND_ENUM_CONSTANT(WINDOW_INITIAL_POSITION_CENTER_SCREEN_WITH_MOUSE_FOCUS);
  2906. BIND_ENUM_CONSTANT(WINDOW_INITIAL_POSITION_CENTER_SCREEN_WITH_KEYBOARD_FOCUS);
  2907. GDVIRTUAL_BIND(_get_contents_minimum_size);
  2908. BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, Window, embedded_border);
  2909. BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, Window, embedded_unfocused_border);
  2910. BIND_THEME_ITEM(Theme::DATA_TYPE_FONT, Window, title_font);
  2911. BIND_THEME_ITEM(Theme::DATA_TYPE_FONT_SIZE, Window, title_font_size);
  2912. BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, Window, title_color);
  2913. BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Window, title_height);
  2914. BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, Window, title_outline_modulate);
  2915. BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Window, title_outline_size);
  2916. BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, Window, close);
  2917. BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, Window, close_pressed);
  2918. BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Window, close_h_offset);
  2919. BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Window, close_v_offset);
  2920. BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Window, resize_margin);
  2921. }
  2922. Window::Window() {
  2923. RenderingServer *rendering_server = RenderingServer::get_singleton();
  2924. if (rendering_server) {
  2925. max_size = rendering_server->get_maximum_viewport_size();
  2926. max_size_used = max_size; // Update max_size_used.
  2927. }
  2928. theme_owner = memnew(ThemeOwner(this));
  2929. RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED);
  2930. }
  2931. Window::~Window() {
  2932. if (focused_window == this) {
  2933. focused_window = nullptr;
  2934. }
  2935. memdelete(theme_owner);
  2936. // Resources need to be disconnected.
  2937. for (KeyValue<StringName, Ref<Texture2D>> &E : theme_icon_override) {
  2938. E.value->disconnect_changed(callable_mp(this, &Window::_notify_theme_override_changed));
  2939. }
  2940. for (KeyValue<StringName, Ref<StyleBox>> &E : theme_style_override) {
  2941. E.value->disconnect_changed(callable_mp(this, &Window::_notify_theme_override_changed));
  2942. }
  2943. for (KeyValue<StringName, Ref<Font>> &E : theme_font_override) {
  2944. E.value->disconnect_changed(callable_mp(this, &Window::_notify_theme_override_changed));
  2945. }
  2946. // Then override maps can be simply cleared.
  2947. theme_icon_override.clear();
  2948. theme_style_override.clear();
  2949. theme_font_override.clear();
  2950. theme_font_size_override.clear();
  2951. theme_color_override.clear();
  2952. theme_constant_override.clear();
  2953. }