Android editor: Enable orientation change in Script Editor

This commit is contained in:
Anish Kumar 2026-01-31 21:12:23 +05:30
parent 634220e9fc
commit 25a203aa34
12 changed files with 97 additions and 1 deletions

View file

@ -6776,6 +6776,8 @@ void EditorNode::set_distraction_free_mode(bool p_enter) {
} else {
editor_dock_manager->set_docks_visible(true);
}
emit_signal(SNAME("distraction_free_mode_changed"), p_enter);
}
bool EditorNode::is_distraction_free_mode_enabled() const {
@ -7797,6 +7799,7 @@ void EditorNode::_bind_methods() {
ADD_SIGNAL(MethodInfo("scene_closed", PropertyInfo(Variant::STRING, "path")));
ADD_SIGNAL(MethodInfo("preview_locale_changed"));
ADD_SIGNAL(MethodInfo("resource_counter_changed"));
ADD_SIGNAL(MethodInfo("distraction_free_mode_changed", PropertyInfo(Variant::BOOL, "enabled")));
}
static Node *_resource_get_edited_scene() {

View file

@ -35,6 +35,8 @@
#ifdef TOOLS_ENABLED
#include "editor/debugger/editor_debugger_node.h"
#include "editor/debugger/script_editor_debugger.h"
#include "editor/editor_node.h"
#include "editor/gui/editor_title_bar.h"
#include "editor/run/editor_run_bar.h"
#include "main/main.h"
#endif
@ -92,4 +94,13 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_editor_utils_EditorUtils_runSc
}
#endif
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_editor_utils_EditorUtils_toggleTitleBar(JNIEnv *p_env, jclass, jboolean p_visible) {
#ifdef TOOLS_ENABLED
EditorTitleBar *title_bar = EditorNode::get_singleton()->get_title_bar();
if (title_bar != nullptr) {
title_bar->call_deferred("set_visible", p_visible);
}
#endif
}
}

View file

@ -34,4 +34,5 @@
extern "C" {
JNIEXPORT void JNICALL Java_org_godotengine_godot_editor_utils_EditorUtils_runScene(JNIEnv *p_env, jclass, jstring p_scene, jobjectArray p_scene_args);
JNIEXPORT void JNICALL Java_org_godotengine_godot_editor_utils_EditorUtils_toggleTitleBar(JNIEnv *p_env, jclass, jboolean p_enable);
}

View file

@ -37,7 +37,9 @@ import android.content.ComponentName
import android.content.ContentResolver
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.os.Build
import android.os.Bundle
import android.os.Debug
@ -155,6 +157,7 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe
internal const val GAME_MENU_ACTION_SET_TIME_SCALE = "setTimeScale"
private const val GAME_WORKSPACE = "Game"
private const val SCRIPT_WORKSPACE = "Script"
internal const val SNACKBAR_SHOW_DURATION_MS = 5000L
@ -203,6 +206,10 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe
private val updatedCommandLineParams = ArrayList<String>()
private var changingOrientationAllowed = false
private var distractionFreeModeEnabled = false
private var activeWorkspace: String? = null
override fun getGodotAppLayout() = R.layout.godot_editor_layout
internal open fun getEditorWindowInfo() = EDITOR_MAIN_INFO
@ -269,6 +276,14 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe
setupGameMenuBar()
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
// Show EditorTitleBar only in landscape due to width limitations in portrait.
// TODO: Enable for portrait once the title bar width is optimized.
EditorUtils.toggleTitleBar(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)
}
override fun onDestroy() {
gradleBuildProvider.buildEnvDisconnect()
super.onDestroy()
@ -696,7 +711,7 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe
/**
* The Godot Android Editor sets its own orientation via its AndroidManifest
*/
protected open fun overrideOrientationRequest() = true
protected open fun overrideOrientationRequest() = !changingOrientationAllowed
protected open fun overrideVolumeButtons() = false
@ -894,6 +909,8 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe
}
override fun onEditorWorkspaceSelected(workspace: String) {
activeWorkspace = workspace
if (workspace == GAME_WORKSPACE && shouldShowGameMenuBar()) {
if (editorMessageDispatcher.bringEditorWindowToFront(EMBEDDED_RUN_GAME_INFO) || editorMessageDispatcher.bringEditorWindowToFront(RUN_GAME_INFO)) {
return
@ -906,6 +923,23 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe
embeddedGameViewContainerWindow?.isVisible = true
}
}
toggleScriptEditorOrientation()
}
override fun onDistractionFreeModeChanged(enabled: Boolean) {
distractionFreeModeEnabled = enabled
toggleScriptEditorOrientation()
}
private fun toggleScriptEditorOrientation() {
if (activeWorkspace == SCRIPT_WORKSPACE && distractionFreeModeEnabled) {
changingOrientationAllowed = true
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER
} else if (changingOrientationAllowed) {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
changingOrientationAllowed = false
}
}
internal open fun bringSelfToFront() {

View file

@ -1308,6 +1308,11 @@ class Godot private constructor(val context: Context) {
primaryHost?.onEditorWorkspaceSelected(workspace)
}
@Keep
private fun nativeOnDistractionFreeModeChanged(enabled: Boolean) {
primaryHost?.onDistractionFreeModeChanged(enabled)
}
@Keep
private fun nativeBuildEnvConnect(callback: GodotCallable): Boolean {
try {

View file

@ -496,6 +496,13 @@ public class GodotFragment extends Fragment implements IDownloaderClient, GodotH
}
}
@Override
public void onDistractionFreeModeChanged(Boolean enabled) {
if (parentHost != null) {
parentHost.onDistractionFreeModeChanged(enabled);
}
}
@Override
public BuildProvider getBuildProvider() {
if (parentHost != null) {

View file

@ -153,6 +153,11 @@ public interface GodotHost {
*/
default void onEditorWorkspaceSelected(String workspace) {}
/**
* Triggered when the editor's distraction-free mode changes.
*/
default void onDistractionFreeModeChanged(Boolean enabled) {}
/**
* Runs the specified action on a host provided thread.
*/

View file

@ -38,4 +38,7 @@ package org.godotengine.godot.editor.utils
object EditorUtils {
@JvmStatic
external fun runScene(scene: String, sceneArgs: Array<String>)
@JvmStatic
external fun toggleTitleBar(visible: Boolean)
}

View file

@ -89,6 +89,7 @@ GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance) {
_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_distraction_free_mode_changed = p_env->GetMethodID(godot_class, "nativeOnDistractionFreeModeChanged", "(Z)V");
_get_activity = p_env->GetMethodID(godot_class, "getActivity", "()Landroid/app/Activity;");
_build_env_connect = p_env->GetMethodID(godot_class, "nativeBuildEnvConnect", "(Lorg/godotengine/godot/variant/Callable;)Z");
_build_env_disconnect = p_env->GetMethodID(godot_class, "nativeBuildEnvDisconnect", "()V");
@ -615,6 +616,15 @@ void GodotJavaWrapper::on_editor_workspace_selected(const String &p_workspace) {
}
}
void GodotJavaWrapper::on_distraction_free_mode_changed(bool p_enabled) {
if (_on_distraction_free_mode_changed) {
JNIEnv *env = get_jni_env();
ERR_FAIL_NULL(env);
env->CallVoidMethod(godot_instance, _on_distraction_free_mode_changed, p_enabled);
}
}
bool GodotJavaWrapper::build_env_connect(const Callable &p_callback) {
if (_build_env_connect) {
JNIEnv *env = get_jni_env();

View file

@ -83,6 +83,7 @@ private:
jmethodID _is_in_immersive_mode = nullptr;
jmethodID _set_window_color = nullptr;
jmethodID _on_editor_workspace_selected = nullptr;
jmethodID _on_distraction_free_mode_changed = nullptr;
jmethodID _get_activity = nullptr;
jmethodID _build_env_connect = nullptr;
jmethodID _build_env_disconnect = nullptr;
@ -146,6 +147,7 @@ public:
void set_window_color(const Color &p_color);
void on_editor_workspace_selected(const String &p_workspace);
void on_distraction_free_mode_changed(bool p_enabled);
bool build_env_connect(const Callable &p_callback);
void build_env_disconnect();

View file

@ -361,6 +361,10 @@ void OS_Android::main_loop_begin() {
if (game_view_plugin != nullptr) {
game_view_plugin->connect("main_screen_changed", callable_mp_static(&OS_Android::_on_main_screen_changed));
}
if (EditorNode::get_singleton() != nullptr) {
EditorNode::get_singleton()->connect("distraction_free_mode_changed", callable_mp_static(&OS_Android::_on_distraction_free_mode_changed));
}
}
#endif
}
@ -393,6 +397,10 @@ void OS_Android::main_loop_end() {
if (game_view_plugin != nullptr) {
game_view_plugin->disconnect("main_screen_changed", callable_mp_static(&OS_Android::_on_main_screen_changed));
}
if (EditorNode::get_singleton() != nullptr) {
EditorNode::get_singleton()->disconnect("distraction_free_mode_changed", callable_mp_static(&OS_Android::_on_distraction_free_mode_changed));
}
}
#endif
@ -411,6 +419,12 @@ void OS_Android::_on_main_screen_changed(const String &p_screen_name) {
OS_Android::get_singleton()->get_godot_java()->on_editor_workspace_selected(p_screen_name);
}
}
void OS_Android::_on_distraction_free_mode_changed(bool p_enable) {
if (OS_Android::get_singleton() != nullptr && OS_Android::get_singleton()->get_godot_java() != nullptr) {
OS_Android::get_singleton()->get_godot_java()->on_distraction_free_mode_changed(p_enable);
}
}
#endif
void OS_Android::main_loop_focusout() {

View file

@ -191,5 +191,6 @@ private:
#ifdef TOOLS_ENABLED
static void _on_main_screen_changed(const String &p_screen_name);
static void _on_distraction_free_mode_changed(bool p_enable);
#endif
};