Browse Source

Merge pull request #109491 from syntaxerror247/window-color

Android: Add method to set root window color at runtime
Thaddeus Crews 2 weeks ago
parent
commit
9283328fe7

+ 8 - 0
doc/classes/DisplayServer.xml

@@ -2261,6 +2261,14 @@
 				Makes the window specified by [param window_id] request attention, which is materialized by the window title and taskbar entry blinking until the window is focused. This usually has no visible effect if the window is currently focused. The exact behavior varies depending on the operating system.
 				Makes the window specified by [param window_id] request attention, which is materialized by the window title and taskbar entry blinking until the window is focused. This usually has no visible effect if the window is currently focused. The exact behavior varies depending on the operating system.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="window_set_color">
+			<return type="void" />
+			<param index="0" name="color" type="Color" />
+			<description>
+				Sets the background color of the root window.
+				[b]Note:[/b] This method is implemented only on Android.
+			</description>
+		</method>
 		<method name="window_set_current_screen">
 		<method name="window_set_current_screen">
 			<return type="void" />
 			<return type="void" />
 			<param index="0" name="screen" type="int" />
 			<param index="0" name="screen" type="int" />

+ 3 - 0
editor/editor_node.cpp

@@ -690,6 +690,9 @@ void EditorNode::_update_theme(bool p_skip_creation) {
 	editor_dock_manager->update_tab_styles();
 	editor_dock_manager->update_tab_styles();
 	editor_dock_manager->update_docks_menu();
 	editor_dock_manager->update_docks_menu();
 	editor_dock_manager->set_tab_icon_max_width(theme->get_constant(SNAME("class_icon_size"), EditorStringName(Editor)));
 	editor_dock_manager->set_tab_icon_max_width(theme->get_constant(SNAME("class_icon_size"), EditorStringName(Editor)));
+#ifdef ANDROID_ENABLED
+	DisplayServer::get_singleton()->window_set_color(theme->get_color(SNAME("background"), EditorStringName(Editor)));
+#endif
 }
 }
 
 
 Ref<Texture2D> EditorNode::_get_editor_theme_native_menu_icon(const StringName &p_name, bool p_global_menu, bool p_dark_mode) const {
 Ref<Texture2D> EditorNode::_get_editor_theme_native_menu_icon(const StringName &p_name, bool p_global_menu, bool p_dark_mode) const {

+ 3 - 0
editor/project_manager/project_manager.cpp

@@ -297,6 +297,9 @@ void ProjectManager::_update_theme(bool p_skip_creation) {
 			asset_library->add_theme_style_override(SceneStringName(panel), memnew(StyleBoxEmpty));
 			asset_library->add_theme_style_override(SceneStringName(panel), memnew(StyleBoxEmpty));
 		}
 		}
 	}
 	}
+#ifdef ANDROID_ENABLED
+	DisplayServer::get_singleton()->window_set_color(theme->get_color(SNAME("background"), EditorStringName(Editor)));
+#endif
 }
 }
 
 
 Button *ProjectManager::_add_main_view(MainViewTab p_id, const String &p_name, const Ref<Texture2D> &p_icon, Control *p_view_control) {
 Button *ProjectManager::_add_main_view(MainViewTab p_id, const String &p_name, const Ref<Texture2D> &p_icon, Control *p_view_control) {

+ 6 - 0
platform/android/display_server_android.cpp

@@ -626,6 +626,12 @@ bool DisplayServerAndroid::can_any_window_draw() const {
 	return true;
 	return true;
 }
 }
 
 
+void DisplayServerAndroid::window_set_color(const Color &p_color) {
+	GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java();
+	ERR_FAIL_NULL(godot_java);
+	godot_java->set_window_color(p_color);
+}
+
 void DisplayServerAndroid::process_events() {
 void DisplayServerAndroid::process_events() {
 	Input::get_singleton()->flush_buffered_events();
 	Input::get_singleton()->flush_buffered_events();
 }
 }

+ 2 - 0
platform/android/display_server_android.h

@@ -220,6 +220,8 @@ public:
 	virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
 	virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
 	virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;
 	virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;
 
 
+	virtual void window_set_color(const Color &p_color) override;
+
 	virtual void process_events() override;
 	virtual void process_events() override;
 
 
 	void process_accelerometer(const Vector3 &p_accelerometer);
 	void process_accelerometer(const Vector3 &p_accelerometer);

+ 16 - 10
platform/android/java/lib/src/org/godotengine/godot/Godot.kt

@@ -260,16 +260,7 @@ class Godot private constructor(val context: Context) {
 					useImmersive.set(true)
 					useImmersive.set(true)
 					newArgs.add(commandLine[i])
 					newArgs.add(commandLine[i])
 				} else if (commandLine[i] == "--background_color") {
 				} else if (commandLine[i] == "--background_color") {
-					val colorStr = commandLine[i + 1]
-					try {
-						backgroundColor = colorStr.toColorInt()
-						Log.d(TAG, "background color = $backgroundColor")
-					} catch (e: java.lang.IllegalArgumentException) {
-						Log.d(TAG, "Failed to parse background color: $colorStr")
-					}
-					runOnHostThread {
-						getActivity()?.window?.decorView?.setBackgroundColor(backgroundColor)
-					}
+					setWindowColor(commandLine[i + 1])
 				} else if (commandLine[i] == "--use_apk_expansion") {
 				} else if (commandLine[i] == "--use_apk_expansion") {
 					useApkExpansion = true
 					useApkExpansion = true
 				} else if (hasExtra && commandLine[i] == "--apk_expansion_md5") {
 				} else if (hasExtra && commandLine[i] == "--apk_expansion_md5") {
@@ -492,6 +483,21 @@ class Godot private constructor(val context: Context) {
 		}
 		}
 	}
 	}
 
 
+	fun setWindowColor(colorStr: String) {
+		val color = try {
+			colorStr.toColorInt()
+		} catch (e: java.lang.IllegalArgumentException) {
+			Log.w(TAG, "Failed to parse background color: $colorStr", e)
+			return
+		}
+		val decorView = getActivity()?.window?.decorView ?: return
+		runOnHostThread {
+			decorView.setBackgroundColor(color)
+			backgroundColor = color
+			setSystemBarsAppearance()
+		}
+	}
+
 	/**
 	/**
 	 * Used to complete initialization of the view used by the engine for rendering.
 	 * Used to complete initialization of the view used by the engine for rendering.
 	 *
 	 *

+ 11 - 0
platform/android/java_godot_wrapper.cpp

@@ -85,6 +85,7 @@ GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance) {
 	_verify_apk = p_env->GetMethodID(godot_class, "nativeVerifyApk", "(Ljava/lang/String;)I");
 	_verify_apk = p_env->GetMethodID(godot_class, "nativeVerifyApk", "(Ljava/lang/String;)I");
 	_enable_immersive_mode = p_env->GetMethodID(godot_class, "nativeEnableImmersiveMode", "(Z)V");
 	_enable_immersive_mode = p_env->GetMethodID(godot_class, "nativeEnableImmersiveMode", "(Z)V");
 	_is_in_immersive_mode = p_env->GetMethodID(godot_class, "isInImmersiveMode", "()Z");
 	_is_in_immersive_mode = p_env->GetMethodID(godot_class, "isInImmersiveMode", "()Z");
+	_set_window_color = p_env->GetMethodID(godot_class, "setWindowColor", "(Ljava/lang/String;)V");
 	_on_editor_workspace_selected = p_env->GetMethodID(godot_class, "nativeOnEditorWorkspaceSelected", "(Ljava/lang/String;)V");
 	_on_editor_workspace_selected = p_env->GetMethodID(godot_class, "nativeOnEditorWorkspaceSelected", "(Ljava/lang/String;)V");
 	_get_activity = p_env->GetMethodID(godot_class, "getActivity", "()Landroid/app/Activity;");
 	_get_activity = p_env->GetMethodID(godot_class, "getActivity", "()Landroid/app/Activity;");
 }
 }
@@ -587,6 +588,16 @@ bool GodotJavaWrapper::is_in_immersive_mode() {
 	}
 	}
 }
 }
 
 
+void GodotJavaWrapper::set_window_color(const Color &p_color) {
+	if (_set_window_color) {
+		JNIEnv *env = get_jni_env();
+		ERR_FAIL_NULL(env);
+		String color = "#" + p_color.to_html(false);
+		jstring jStrColor = env->NewStringUTF(color.utf8().get_data());
+		env->CallVoidMethod(godot_instance, _set_window_color, jStrColor);
+	}
+}
+
 void GodotJavaWrapper::on_editor_workspace_selected(const String &p_workspace) {
 void GodotJavaWrapper::on_editor_workspace_selected(const String &p_workspace) {
 	if (_on_editor_workspace_selected) {
 	if (_on_editor_workspace_selected) {
 		JNIEnv *env = get_jni_env();
 		JNIEnv *env = get_jni_env();

+ 3 - 0
platform/android/java_godot_wrapper.h

@@ -81,6 +81,7 @@ private:
 	jmethodID _verify_apk = nullptr;
 	jmethodID _verify_apk = nullptr;
 	jmethodID _enable_immersive_mode = nullptr;
 	jmethodID _enable_immersive_mode = nullptr;
 	jmethodID _is_in_immersive_mode = nullptr;
 	jmethodID _is_in_immersive_mode = nullptr;
+	jmethodID _set_window_color = nullptr;
 	jmethodID _on_editor_workspace_selected = nullptr;
 	jmethodID _on_editor_workspace_selected = nullptr;
 	jmethodID _get_activity = nullptr;
 	jmethodID _get_activity = nullptr;
 
 
@@ -137,5 +138,7 @@ public:
 	void enable_immersive_mode(bool p_enabled);
 	void enable_immersive_mode(bool p_enabled);
 	bool is_in_immersive_mode();
 	bool is_in_immersive_mode();
 
 
+	void set_window_color(const Color &p_color);
+
 	void on_editor_workspace_selected(const String &p_workspace);
 	void on_editor_workspace_selected(const String &p_workspace);
 };
 };

+ 2 - 0
servers/display_server.cpp

@@ -1476,6 +1476,8 @@ void DisplayServer::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("window_start_drag", "window_id"), &DisplayServer::window_start_drag, DEFVAL(MAIN_WINDOW_ID));
 	ClassDB::bind_method(D_METHOD("window_start_drag", "window_id"), &DisplayServer::window_start_drag, DEFVAL(MAIN_WINDOW_ID));
 	ClassDB::bind_method(D_METHOD("window_start_resize", "edge", "window_id"), &DisplayServer::window_start_resize, DEFVAL(MAIN_WINDOW_ID));
 	ClassDB::bind_method(D_METHOD("window_start_resize", "edge", "window_id"), &DisplayServer::window_start_resize, DEFVAL(MAIN_WINDOW_ID));
 
 
+	ClassDB::bind_method(D_METHOD("window_set_color", "color"), &DisplayServer::window_set_color);
+
 	ClassDB::bind_method(D_METHOD("accessibility_should_increase_contrast"), &DisplayServer::accessibility_should_increase_contrast);
 	ClassDB::bind_method(D_METHOD("accessibility_should_increase_contrast"), &DisplayServer::accessibility_should_increase_contrast);
 	ClassDB::bind_method(D_METHOD("accessibility_should_reduce_animation"), &DisplayServer::accessibility_should_reduce_animation);
 	ClassDB::bind_method(D_METHOD("accessibility_should_reduce_animation"), &DisplayServer::accessibility_should_reduce_animation);
 	ClassDB::bind_method(D_METHOD("accessibility_should_reduce_transparency"), &DisplayServer::accessibility_should_reduce_transparency);
 	ClassDB::bind_method(D_METHOD("accessibility_should_reduce_transparency"), &DisplayServer::accessibility_should_reduce_transparency);

+ 2 - 0
servers/display_server.h

@@ -525,6 +525,8 @@ public:
 
 
 	virtual void window_start_drag(WindowID p_window = MAIN_WINDOW_ID) {}
 	virtual void window_start_drag(WindowID p_window = MAIN_WINDOW_ID) {}
 
 
+	virtual void window_set_color(const Color &p_color) {}
+
 	enum WindowResizeEdge {
 	enum WindowResizeEdge {
 		WINDOW_EDGE_TOP_LEFT,
 		WINDOW_EDGE_TOP_LEFT,
 		WINDOW_EDGE_TOP,
 		WINDOW_EDGE_TOP,