diff options
Diffstat (limited to 'scene/main/window.cpp')
-rw-r--r-- | scene/main/window.cpp | 107 |
1 files changed, 51 insertions, 56 deletions
diff --git a/scene/main/window.cpp b/scene/main/window.cpp index d40b82f5eb..68037a1211 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -349,7 +349,9 @@ void Window::_event_callback(DisplayServer::WindowEvent p_event) { _propagate_window_notification(this, NOTIFICATION_WM_MOUSE_ENTER); emit_signal(SNAME("mouse_entered")); notification(NOTIFICATION_VP_MOUSE_ENTER); - DisplayServer::get_singleton()->cursor_set_shape(DisplayServer::CURSOR_ARROW); //restore cursor shape + if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_CURSOR_SHAPE)) { + DisplayServer::get_singleton()->cursor_set_shape(DisplayServer::CURSOR_ARROW); //restore cursor shape + } } break; case DisplayServer::WINDOW_EVENT_MOUSE_EXIT: { notification(NOTIFICATION_VP_MOUSE_EXIT); @@ -846,21 +848,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); - } - } - } + // Need to defer here, because theme owner information might be set in + // add_child_notify, which doesn't get called until right after this. + call_deferred(SNAME("notification"), NOTIFICATION_THEME_CHANGED); + } break; + + case NOTIFICATION_THEME_CHANGED: { + emit_signal(SceneStringNames::get_singleton()->theme_changed); } break; case NOTIFICATION_READY: { @@ -1248,16 +1242,10 @@ 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 + // We propagate when this node uses a custom theme, so it can pass it on to its children. + if (theme_owner || theme_owner_window) { + // `p_notify` is false here as `NOTIFICATION_THEME_CHANGED` will be handled by `NOTIFICATION_ENTER_TREE`. + Control::_propagate_theme_changed(this, theme_owner, theme_owner_window, false, true); } if (is_inside_tree() && wrap_controls) { @@ -1266,16 +1254,9 @@ void Window::add_child_notify(Node *p_child) { } 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); - } - - Window *child_w = Object::cast_to<Window>(p_child); - - 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); + // If the removed child isn't inheriting any theme items through this node, then there's no need to propagate. + if (theme_owner || theme_owner_window) { + Control::_propagate_theme_changed(this, nullptr, nullptr, false, true); } if (is_inside_tree() && wrap_controls) { @@ -1288,34 +1269,47 @@ 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()) { + Control::_propagate_theme_changed(this, nullptr, 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->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, is_inside_tree(), true); + return; } + + 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, is_inside_tree(), true); + return; + } + + Control::_propagate_theme_changed(this, nullptr, nullptr, is_inside_tree(), true); } Ref<Theme> Window::get_theme() const { return theme; } +void Window::_theme_changed() { + if (is_inside_tree()) { + Control::_propagate_theme_changed(this, nullptr, this, true, false); + } +} + 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 { @@ -1510,8 +1504,8 @@ bool Window::is_auto_translating() const { return auto_translate; } -void Window::_validate_property(PropertyInfo &property) const { - if (property.name == "theme_type_variation") { +void Window::_validate_property(PropertyInfo &p_property) const { + if (p_property.name == "theme_type_variation") { List<StringName> names; // Only the default theme and the project theme are used for the list of options. @@ -1534,7 +1528,7 @@ void Window::_validate_property(PropertyInfo &property) const { unique_names.append(E); } - property.hint_string = hint_string; + p_property.hint_string = hint_string; } } @@ -1710,6 +1704,7 @@ void Window::_bind_methods() { ADD_SIGNAL(MethodInfo("theme_changed")); BIND_CONSTANT(NOTIFICATION_VISIBILITY_CHANGED); + BIND_CONSTANT(NOTIFICATION_THEME_CHANGED); BIND_ENUM_CONSTANT(MODE_WINDOWED); BIND_ENUM_CONSTANT(MODE_MINIMIZED); |