summaryrefslogtreecommitdiff
path: root/scene/main/window.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/main/window.cpp')
-rw-r--r--scene/main/window.cpp303
1 files changed, 202 insertions, 101 deletions
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index bf50ca0956..64869b2936 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -32,9 +32,13 @@
#include "core/config/project_settings.h"
#include "core/debugger/engine_debugger.h"
+#include "core/input/shortcut.h"
#include "core/string/translation.h"
+#include "core/variant/variant_parser.h"
#include "scene/gui/control.h"
#include "scene/scene_string_names.h"
+#include "scene/theme/theme_db.h"
+#include "scene/theme/theme_owner.h"
void Window::set_title(const String &p_title) {
title = p_title;
@@ -385,9 +389,24 @@ void Window::_event_callback(DisplayServer::WindowEvent p_event) {
_propagate_window_notification(this, NOTIFICATION_WM_DPI_CHANGE);
emit_signal(SNAME("dpi_changed"));
} break;
+ case DisplayServer::WINDOW_EVENT_TITLEBAR_CHANGE: {
+ emit_signal(SNAME("titlebar_changed"));
+ } break;
}
}
+void Window::update_mouse_cursor_shape() {
+ // The default shape is set in Viewport::_gui_input_event. To instantly
+ // see the shape in the viewport we need to trigger a mouse motion event.
+ Ref<InputEventMouseMotion> mm;
+ Vector2 pos = get_mouse_position();
+ Transform2D xform = get_global_canvas_transform().affine_inverse();
+ mm.instantiate();
+ mm->set_position(pos);
+ mm->set_global_position(xform.xform(pos));
+ push_input(mm);
+}
+
void Window::show() {
set_visible(true);
}
@@ -796,6 +815,19 @@ Viewport *Window::_get_embedder() const {
void Window::_notification(int p_what) {
switch (p_what) {
+ case NOTIFICATION_POSTINITIALIZE: {
+ _invalidate_theme_cache();
+ _update_theme_item_cache();
+ } break;
+
+ case NOTIFICATION_PARENTED: {
+ theme_owner->assign_theme_on_parented(this);
+ } break;
+
+ case NOTIFICATION_UNPARENTED: {
+ theme_owner->clear_theme_on_unparented(this);
+ } break;
+
case NOTIFICATION_ENTER_TREE: {
bool embedded = false;
{
@@ -848,21 +880,13 @@ void Window::_notification(int p_what) {
RS::get_singleton()->viewport_set_active(get_viewport_rid(), true);
}
- if (theme.is_null()) {
- Control *parent_c = cast_to<Control>(get_parent());
- if (parent_c && (parent_c->data.theme_owner || parent_c->data.theme_owner_window)) {
- theme_owner = parent_c->data.theme_owner;
- theme_owner_window = parent_c->data.theme_owner_window;
- notification(NOTIFICATION_THEME_CHANGED);
- } else {
- Window *parent_w = cast_to<Window>(get_parent());
- if (parent_w && (parent_w->theme_owner || parent_w->theme_owner_window)) {
- theme_owner = parent_w->theme_owner;
- theme_owner_window = parent_w->theme_owner_window;
- notification(NOTIFICATION_THEME_CHANGED);
- }
- }
- }
+ notification(NOTIFICATION_THEME_CHANGED);
+ } break;
+
+ case NOTIFICATION_THEME_CHANGED: {
+ emit_signal(SceneStringNames::get_singleton()->theme_changed);
+ _invalidate_theme_cache();
+ _update_theme_item_cache();
} break;
case NOTIFICATION_READY: {
@@ -872,6 +896,9 @@ void Window::_notification(int p_what) {
} break;
case NOTIFICATION_TRANSLATION_CHANGED: {
+ _invalidate_theme_cache();
+ _update_theme_item_cache();
+
if (embedder) {
embedder->_sub_window_update(this);
} else if (window_id != DisplayServer::INVALID_WINDOW_ID) {
@@ -1029,9 +1056,31 @@ bool Window::_can_consume_input_events() const {
void Window::_window_input(const Ref<InputEvent> &p_ev) {
if (EngineDebugger::is_active()) {
- // Quit from game window using F8.
+ // Quit from game window using the stop shortcut (F8 by default).
+ // The custom shortcut is provided via environment variable when running from the editor.
+ if (debugger_stop_shortcut.is_null()) {
+ String shortcut_str = OS::get_singleton()->get_environment("__GODOT_EDITOR_STOP_SHORTCUT__");
+ if (!shortcut_str.is_empty()) {
+ Variant shortcut_var;
+
+ VariantParser::StreamString ss;
+ ss.s = shortcut_str;
+
+ String errs;
+ int line;
+ VariantParser::parse(&ss, shortcut_var, errs, line);
+ debugger_stop_shortcut = shortcut_var;
+ }
+
+ if (debugger_stop_shortcut.is_null()) {
+ // Define a default shortcut if it wasn't provided or is invalid.
+ debugger_stop_shortcut.instantiate();
+ debugger_stop_shortcut->set_events({ (Variant)InputEventKey::create_reference(Key::F8) });
+ }
+ }
+
Ref<InputEventKey> k = p_ev;
- if (k.is_valid() && k->is_pressed() && !k->is_echo() && k->get_keycode() == Key::F8) {
+ if (k.is_valid() && k->is_pressed() && !k->is_echo() && debugger_stop_shortcut->matches_event(k)) {
EngineDebugger::get_singleton()->send_message("request_quit", Array());
}
}
@@ -1107,7 +1156,7 @@ void Window::popup_centered_clamped(const Size2i &p_size, float p_fallback_ratio
Rect2 parent_rect;
if (is_embedded()) {
- parent_rect = get_parent_viewport()->get_visible_rect();
+ parent_rect = _get_embedder()->get_visible_rect();
} else {
DisplayServer::WindowID parent_id = get_parent_visible_window()->get_window_id();
int parent_screen = DisplayServer::get_singleton()->window_get_current_screen(parent_id);
@@ -1133,7 +1182,7 @@ void Window::popup_centered(const Size2i &p_minsize) {
Rect2 parent_rect;
if (is_embedded()) {
- parent_rect = get_parent_viewport()->get_visible_rect();
+ parent_rect = _get_embedder()->get_visible_rect();
} else {
DisplayServer::WindowID parent_id = get_parent_visible_window()->get_window_id();
int parent_screen = DisplayServer::get_singleton()->window_get_current_screen(parent_id);
@@ -1161,7 +1210,7 @@ void Window::popup_centered_ratio(float p_ratio) {
Rect2 parent_rect;
if (is_embedded()) {
- parent_rect = get_parent_viewport()->get_visible_rect();
+ parent_rect = _get_embedder()->get_visible_rect();
} else {
DisplayServer::WindowID parent_id = get_parent_visible_window()->get_window_id();
int parent_screen = DisplayServer::get_singleton()->window_get_current_screen(parent_id);
@@ -1214,6 +1263,15 @@ void Window::popup(const Rect2i &p_screen_rect) {
set_transient(true);
set_visible(true);
+
+ int screen_id = DisplayServer::get_singleton()->window_get_current_screen(get_window_id());
+ Rect2i screen_rect = DisplayServer::get_singleton()->screen_get_usable_rect(screen_id);
+ if (screen_rect != Rect2i() && !screen_rect.intersects(Rect2i(position, size))) {
+ ERR_PRINT(vformat("Window %d spawned at invalid position: %s.", get_window_id(), position));
+ // Window appeared on unavailable screen area, so force it to the center.
+ set_position(screen_rect.size / 2 - size / 2);
+ }
+
_post_popup();
notification(NOTIFICATION_POST_POPUP);
}
@@ -1250,39 +1308,27 @@ Rect2i Window::get_usable_parent_rect() const {
}
void Window::add_child_notify(Node *p_child) {
- Control *child_c = Object::cast_to<Control>(p_child);
-
- if (child_c && child_c->data.theme.is_null() && (theme_owner || theme_owner_window)) {
- Control::_propagate_theme_changed(child_c, theme_owner, theme_owner_window); //need to propagate here, since many controls may require setting up stuff
- }
-
- Window *child_w = Object::cast_to<Window>(p_child);
-
- if (child_w && child_w->theme.is_null() && (theme_owner || theme_owner_window)) {
- Control::_propagate_theme_changed(child_w, theme_owner, theme_owner_window); //need to propagate here, since many controls may require setting up stuff
- }
-
if (is_inside_tree() && wrap_controls) {
child_controls_changed();
}
}
void Window::remove_child_notify(Node *p_child) {
- Control *child_c = Object::cast_to<Control>(p_child);
-
- if (child_c && (child_c->data.theme_owner || child_c->data.theme_owner_window) && child_c->data.theme.is_null()) {
- Control::_propagate_theme_changed(child_c, nullptr, nullptr);
+ if (is_inside_tree() && wrap_controls) {
+ child_controls_changed();
}
+}
- Window *child_w = Object::cast_to<Window>(p_child);
+void Window::set_theme_owner_node(Node *p_node) {
+ theme_owner->set_owner_node(p_node);
+}
- if (child_w && (child_w->theme_owner || child_w->theme_owner_window) && child_w->theme.is_null()) {
- Control::_propagate_theme_changed(child_w, nullptr, nullptr);
- }
+Node *Window::get_theme_owner_node() const {
+ return theme_owner->get_owner_node();
+}
- if (is_inside_tree() && wrap_controls) {
- child_controls_changed();
- }
+bool Window::has_theme_owner_node() const {
+ return theme_owner->has_owner_node();
}
void Window::set_theme(const Ref<Theme> &p_theme) {
@@ -1290,134 +1336,183 @@ void Window::set_theme(const Ref<Theme> &p_theme) {
return;
}
+ if (theme.is_valid()) {
+ theme->disconnect("changed", callable_mp(this, &Window::_theme_changed));
+ }
+
theme = p_theme;
+ if (theme.is_valid()) {
+ theme_owner->propagate_theme_changed(this, this, is_inside_tree(), true);
+ theme->connect("changed", callable_mp(this, &Window::_theme_changed), CONNECT_DEFERRED);
+ return;
+ }
- if (!p_theme.is_null()) {
- theme_owner = nullptr;
- theme_owner_window = this;
- Control::_propagate_theme_changed(this, nullptr, this);
- } else {
- Control *parent_c = cast_to<Control>(get_parent());
- if (parent_c && (parent_c->data.theme_owner || parent_c->data.theme_owner_window)) {
- Control::_propagate_theme_changed(this, parent_c->data.theme_owner, parent_c->data.theme_owner_window);
- } else {
- Window *parent_w = cast_to<Window>(get_parent());
- if (parent_w && (parent_w->theme_owner || parent_w->theme_owner_window)) {
- Control::_propagate_theme_changed(this, parent_w->theme_owner, parent_w->theme_owner_window);
- } else {
- Control::_propagate_theme_changed(this, nullptr, nullptr);
- }
- }
+ Control *parent_c = Object::cast_to<Control>(get_parent());
+ if (parent_c && parent_c->has_theme_owner_node()) {
+ theme_owner->propagate_theme_changed(this, parent_c->get_theme_owner_node(), is_inside_tree(), true);
+ return;
}
+
+ Window *parent_w = cast_to<Window>(get_parent());
+ if (parent_w && parent_w->has_theme_owner_node()) {
+ theme_owner->propagate_theme_changed(this, parent_w->get_theme_owner_node(), is_inside_tree(), true);
+ return;
+ }
+
+ theme_owner->propagate_theme_changed(this, nullptr, is_inside_tree(), true);
}
Ref<Theme> Window::get_theme() const {
return theme;
}
+void Window::_theme_changed() {
+ if (is_inside_tree()) {
+ theme_owner->propagate_theme_changed(this, this, true, false);
+ }
+}
+
+void Window::_invalidate_theme_cache() {
+ theme_icon_cache.clear();
+ theme_style_cache.clear();
+ theme_font_cache.clear();
+ theme_font_size_cache.clear();
+ theme_color_cache.clear();
+ theme_constant_cache.clear();
+}
+
+void Window::_update_theme_item_cache() {
+}
+
void Window::set_theme_type_variation(const StringName &p_theme_type) {
theme_type_variation = p_theme_type;
- Control::_propagate_theme_changed(this, theme_owner, theme_owner_window);
+ if (is_inside_tree()) {
+ notification(NOTIFICATION_THEME_CHANGED);
+ }
}
StringName Window::get_theme_type_variation() const {
return theme_type_variation;
}
-void Window::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const {
- if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_type_variation) {
- if (Theme::get_project_default().is_valid() && Theme::get_project_default()->get_type_variation_base(theme_type_variation) != StringName()) {
- Theme::get_project_default()->get_type_dependencies(get_class_name(), theme_type_variation, p_list);
- } else {
- Theme::get_default()->get_type_dependencies(get_class_name(), theme_type_variation, p_list);
- }
- } else {
- Theme::get_default()->get_type_dependencies(p_theme_type, StringName(), p_list);
+Ref<Texture2D> Window::get_theme_icon(const StringName &p_name, const StringName &p_theme_type) const {
+ if (theme_icon_cache.has(p_theme_type) && theme_icon_cache[p_theme_type].has(p_name)) {
+ return theme_icon_cache[p_theme_type][p_name];
}
-}
-Ref<Texture2D> Window::get_theme_icon(const StringName &p_name, const StringName &p_theme_type) const {
List<StringName> theme_types;
- _get_theme_type_dependencies(p_theme_type, &theme_types);
- return Control::get_theme_item_in_types<Ref<Texture2D>>(theme_owner, theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types);
+ theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types);
+ Ref<Texture2D> icon = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_ICON, p_name, theme_types);
+ theme_icon_cache[p_theme_type][p_name] = icon;
+ return icon;
}
Ref<StyleBox> Window::get_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const {
+ if (theme_style_cache.has(p_theme_type) && theme_style_cache[p_theme_type].has(p_name)) {
+ return theme_style_cache[p_theme_type][p_name];
+ }
+
List<StringName> theme_types;
- _get_theme_type_dependencies(p_theme_type, &theme_types);
- return Control::get_theme_item_in_types<Ref<StyleBox>>(theme_owner, theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types);
+ theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types);
+ Ref<StyleBox> style = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_STYLEBOX, p_name, theme_types);
+ theme_style_cache[p_theme_type][p_name] = style;
+ return style;
}
Ref<Font> Window::get_theme_font(const StringName &p_name, const StringName &p_theme_type) const {
+ if (theme_font_cache.has(p_theme_type) && theme_font_cache[p_theme_type].has(p_name)) {
+ return theme_font_cache[p_theme_type][p_name];
+ }
+
List<StringName> theme_types;
- _get_theme_type_dependencies(p_theme_type, &theme_types);
- return Control::get_theme_item_in_types<Ref<Font>>(theme_owner, theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types);
+ theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types);
+ Ref<Font> font = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_FONT, p_name, theme_types);
+ theme_font_cache[p_theme_type][p_name] = font;
+ return font;
}
int Window::get_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const {
+ if (theme_font_size_cache.has(p_theme_type) && theme_font_size_cache[p_theme_type].has(p_name)) {
+ return theme_font_size_cache[p_theme_type][p_name];
+ }
+
List<StringName> theme_types;
- _get_theme_type_dependencies(p_theme_type, &theme_types);
- return Control::get_theme_item_in_types<int>(theme_owner, theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types);
+ theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types);
+ int font_size = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types);
+ theme_font_size_cache[p_theme_type][p_name] = font_size;
+ return font_size;
}
Color Window::get_theme_color(const StringName &p_name, const StringName &p_theme_type) const {
+ if (theme_color_cache.has(p_theme_type) && theme_color_cache[p_theme_type].has(p_name)) {
+ return theme_color_cache[p_theme_type][p_name];
+ }
+
List<StringName> theme_types;
- _get_theme_type_dependencies(p_theme_type, &theme_types);
- return Control::get_theme_item_in_types<Color>(theme_owner, theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types);
+ theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types);
+ Color color = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_COLOR, p_name, theme_types);
+ theme_color_cache[p_theme_type][p_name] = color;
+ return color;
}
int Window::get_theme_constant(const StringName &p_name, const StringName &p_theme_type) const {
+ if (theme_constant_cache.has(p_theme_type) && theme_constant_cache[p_theme_type].has(p_name)) {
+ return theme_constant_cache[p_theme_type][p_name];
+ }
+
List<StringName> theme_types;
- _get_theme_type_dependencies(p_theme_type, &theme_types);
- return Control::get_theme_item_in_types<int>(theme_owner, theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types);
+ theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types);
+ int constant = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_CONSTANT, p_name, theme_types);
+ theme_constant_cache[p_theme_type][p_name] = constant;
+ return constant;
}
bool Window::has_theme_icon(const StringName &p_name, const StringName &p_theme_type) const {
List<StringName> theme_types;
- _get_theme_type_dependencies(p_theme_type, &theme_types);
- return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types);
+ theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types);
+ return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_ICON, p_name, theme_types);
}
bool Window::has_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const {
List<StringName> theme_types;
- _get_theme_type_dependencies(p_theme_type, &theme_types);
- return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types);
+ theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types);
+ return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_STYLEBOX, p_name, theme_types);
}
bool Window::has_theme_font(const StringName &p_name, const StringName &p_theme_type) const {
List<StringName> theme_types;
- _get_theme_type_dependencies(p_theme_type, &theme_types);
- return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types);
+ theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types);
+ return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_FONT, p_name, theme_types);
}
bool Window::has_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const {
List<StringName> theme_types;
- _get_theme_type_dependencies(p_theme_type, &theme_types);
- return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types);
+ theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types);
+ return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types);
}
bool Window::has_theme_color(const StringName &p_name, const StringName &p_theme_type) const {
List<StringName> theme_types;
- _get_theme_type_dependencies(p_theme_type, &theme_types);
- return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types);
+ theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types);
+ return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_COLOR, p_name, theme_types);
}
bool Window::has_theme_constant(const StringName &p_name, const StringName &p_theme_type) const {
List<StringName> theme_types;
- _get_theme_type_dependencies(p_theme_type, &theme_types);
- return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types);
+ theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types);
+ return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_CONSTANT, p_name, theme_types);
}
float Window::get_theme_default_base_scale() const {
- return Control::fetch_theme_default_base_scale(theme_owner, theme_owner_window);
+ return theme_owner->get_theme_default_base_scale();
}
Ref<Font> Window::get_theme_default_font() const {
- return Control::fetch_theme_default_font(theme_owner, theme_owner_window);
+ return theme_owner->get_theme_default_font();
}
int Window::get_theme_default_font_size() const {
- return Control::fetch_theme_default_font_size(theme_owner, theme_owner_window);
+ return theme_owner->get_theme_default_font_size();
}
Rect2i Window::get_parent_rect() const {
@@ -1518,9 +1613,9 @@ void Window::_validate_property(PropertyInfo &p_property) const {
// Only the default theme and the project theme are used for the list of options.
// This is an imposed limitation to simplify the logic needed to leverage those options.
- Theme::get_default()->get_type_variation_list(get_class_name(), &names);
- if (Theme::get_project_default().is_valid()) {
- Theme::get_project_default()->get_type_variation_list(get_class_name(), &names);
+ ThemeDB::get_singleton()->get_default_theme()->get_type_variation_list(get_class_name(), &names);
+ if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
+ ThemeDB::get_singleton()->get_project_theme()->get_type_variation_list(get_class_name(), &names);
}
names.sort_custom<StringName::AlphCompare>();
@@ -1681,6 +1776,7 @@ void Window::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "transparent"), "set_flag", "get_flag", FLAG_TRANSPARENT);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "unfocusable"), "set_flag", "get_flag", FLAG_NO_FOCUS);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "popup_window"), "set_flag", "get_flag", FLAG_POPUP);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "extend_to_title"), "set_flag", "get_flag", FLAG_EXTEND_TO_TITLE);
ADD_GROUP("Limits", "");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "min_size", PROPERTY_HINT_NONE, "suffix:px"), "set_min_size", "get_min_size");
@@ -1710,8 +1806,10 @@ void Window::_bind_methods() {
ADD_SIGNAL(MethodInfo("visibility_changed"));
ADD_SIGNAL(MethodInfo("about_to_popup"));
ADD_SIGNAL(MethodInfo("theme_changed"));
+ ADD_SIGNAL(MethodInfo("titlebar_changed"));
BIND_CONSTANT(NOTIFICATION_VISIBILITY_CHANGED);
+ BIND_CONSTANT(NOTIFICATION_THEME_CHANGED);
BIND_ENUM_CONSTANT(MODE_WINDOWED);
BIND_ENUM_CONSTANT(MODE_MINIMIZED);
@@ -1725,6 +1823,7 @@ void Window::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_TRANSPARENT);
BIND_ENUM_CONSTANT(FLAG_NO_FOCUS);
BIND_ENUM_CONSTANT(FLAG_POPUP);
+ BIND_ENUM_CONSTANT(FLAG_EXTEND_TO_TITLE);
BIND_ENUM_CONSTANT(FLAG_MAX);
BIND_ENUM_CONSTANT(CONTENT_SCALE_MODE_DISABLED);
@@ -1744,8 +1843,10 @@ void Window::_bind_methods() {
}
Window::Window() {
+ theme_owner = memnew(ThemeOwner);
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED);
}
Window::~Window() {
+ memdelete(theme_owner);
}