summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/os/os.h4
-rw-r--r--editor/editor_data.cpp2
-rw-r--r--editor/editor_node.cpp10
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp94
-rw-r--r--editor/plugins/spatial_editor_plugin.h10
-rw-r--r--editor/scene_tree_dock.cpp4
-rw-r--r--editor/scene_tree_editor.cpp6
-rwxr-xr-x[-rw-r--r--]main/main.cpp2
-rw-r--r--modules/gdnative/gdnative.cpp40
-rw-r--r--modules/gdnative/gdnative.h8
-rw-r--r--modules/gdnative/gdnative/gdnative.cpp4
-rw-r--r--modules/gdnative/gdnative_api.json8
-rw-r--r--modules/gdnative/include/gdnative/gdnative.h3
-rw-r--r--platform/x11/os_x11.cpp84
-rw-r--r--platform/x11/os_x11.h3
-rw-r--r--scene/2d/camera_2d.cpp6
-rw-r--r--scene/2d/parallax_background.cpp10
-rw-r--r--scene/2d/parallax_background.h3
-rw-r--r--scene/2d/parallax_layer.cpp20
-rw-r--r--scene/2d/parallax_layer.h4
20 files changed, 212 insertions, 113 deletions
diff --git a/core/os/os.h b/core/os/os.h
index 474cb60627..e48e5c6d70 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -90,13 +90,15 @@ public:
bool fullscreen;
bool resizable;
bool borderless_window;
+ bool maximized;
float get_aspect() const { return (float)width / (float)height; }
- VideoMode(int p_width = 1024, int p_height = 600, bool p_fullscreen = false, bool p_resizable = true, bool p_borderless_window = false) {
+ VideoMode(int p_width = 1024, int p_height = 600, bool p_fullscreen = false, bool p_resizable = true, bool p_borderless_window = false, bool p_maximized = false) {
width = p_width;
height = p_height;
fullscreen = p_fullscreen;
resizable = p_resizable;
borderless_window = p_borderless_window;
+ maximized = p_maximized;
}
};
diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index 2cb5340b8b..443004f820 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -913,8 +913,8 @@ void EditorSelection::update() {
if (!changed)
return;
- emit_signal("selection_changed");
changed = false;
+ emit_signal("selection_changed");
}
List<Node *> &EditorSelection::get_selected_node_list() {
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index ded12db766..c0e2e46f14 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -403,7 +403,15 @@ void EditorNode::_fs_changed() {
// ensures export_project does not loop infinitely, because notifications may
// come during the export
export_defer.preset = "";
- platform->export_project(preset, export_defer.debug, export_defer.path, /*p_flags*/ 0);
+ if (!preset->is_runnable() && (export_defer.path.ends_with(".pck") || export_defer.path.ends_with(".zip"))) {
+ if (export_defer.path.ends_with(".zip")) {
+ platform->save_zip(preset, export_defer.path);
+ } else if (export_defer.path.ends_with(".pck")) {
+ platform->save_pack(preset, export_defer.path);
+ }
+ } else {
+ platform->export_project(preset, export_defer.debug, export_defer.path, /*p_flags*/ 0);
+ }
}
}
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index b3d3d5e13a..448daab226 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -1097,7 +1097,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (get_selected_count() == 0)
break; //bye
- //handle rotate
+ //handle scale
_edit.mode = TRANSFORM_SCALE;
_compute_edit(b->get_position());
break;
@@ -1385,6 +1385,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
continue;
}
+ if (sp->has_meta("_edit_lock_")) {
+ continue;
+ }
+
Transform original = se->original;
Transform original_local = se->original_local;
Transform base = Transform(Basis(), _edit.center);
@@ -1509,6 +1513,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
continue;
}
+ if (sp->has_meta("_edit_lock_")) {
+ continue;
+ }
+
Transform original = se->original;
Transform t;
@@ -1605,6 +1613,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (!se)
continue;
+ if (sp->has_meta("_edit_lock_")) {
+ continue;
+ }
+
Transform t;
if (local_coords) {
@@ -4094,6 +4106,44 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
settings_dialog->popup_centered(settings_vbc->get_combined_minimum_size() + Size2(50, 50));
} break;
+ case MENU_LOCK_SELECTED: {
+
+ List<Node *> &selection = editor_selection->get_selected_node_list();
+
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+
+ Spatial *spatial = Object::cast_to<Spatial>(E->get());
+ if (!spatial || !spatial->is_visible_in_tree())
+ continue;
+
+ if (spatial->get_viewport() != EditorNode::get_singleton()->get_scene_root())
+ continue;
+
+ spatial->set_meta("_edit_lock_", true);
+ emit_signal("item_lock_status_changed");
+ }
+
+ _refresh_menu_icons();
+ } break;
+ case MENU_UNLOCK_SELECTED: {
+
+ List<Node *> &selection = editor_selection->get_selected_node_list();
+
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+
+ Spatial *spatial = Object::cast_to<Spatial>(E->get());
+ if (!spatial || !spatial->is_visible_in_tree())
+ continue;
+
+ if (spatial->get_viewport() != EditorNode::get_singleton()->get_scene_root())
+ continue;
+
+ spatial->set_meta("_edit_lock_", Variant());
+ emit_signal("item_lock_status_changed");
+ }
+
+ _refresh_menu_icons();
+ } break;
}
}
@@ -4477,6 +4527,28 @@ bool SpatialEditor::is_any_freelook_active() const {
return false;
}
+void SpatialEditor::_refresh_menu_icons() {
+
+ bool all_locked = true;
+
+ List<Node *> &selection = editor_selection->get_selected_node_list();
+
+ if (selection.empty()) {
+ all_locked = false;
+ } else {
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+ if (Object::cast_to<Spatial>(E->get()) && !Object::cast_to<Spatial>(E->get())->has_meta("_edit_lock_")) {
+ all_locked = false;
+ break;
+ }
+ }
+ }
+
+ tool_button[TOOL_LOCK_SELECTED]->set_visible(!all_locked);
+ tool_button[TOOL_LOCK_SELECTED]->set_disabled(selection.empty());
+ tool_button[TOOL_UNLOCK_SELECTED]->set_visible(all_locked);
+}
+
void SpatialEditor::_unhandled_key_input(Ref<InputEvent> p_event) {
if (!is_visible_in_tree() || get_viewport()->gui_has_modal_stack())
@@ -4515,6 +4587,8 @@ void SpatialEditor::_notification(int p_what) {
tool_button[SpatialEditor::TOOL_MODE_ROTATE]->set_icon(get_icon("ToolRotate", "EditorIcons"));
tool_button[SpatialEditor::TOOL_MODE_SCALE]->set_icon(get_icon("ToolScale", "EditorIcons"));
tool_button[SpatialEditor::TOOL_MODE_LIST_SELECT]->set_icon(get_icon("ListSelect", "EditorIcons"));
+ tool_button[SpatialEditor::TOOL_LOCK_SELECTED]->set_icon(get_icon("Lock", "EditorIcons"));
+ tool_button[SpatialEditor::TOOL_UNLOCK_SELECTED]->set_icon(get_icon("Unlock", "EditorIcons"));
view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), get_icon("Panels1", "EditorIcons"));
view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), get_icon("Panels2", "EditorIcons"));
@@ -4525,7 +4599,11 @@ void SpatialEditor::_notification(int p_what) {
_menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT);
+ _refresh_menu_icons();
+
get_tree()->connect("node_removed", this, "_node_removed");
+ EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor()->connect("node_changed", this, "_refresh_menu_icons");
+ editor_selection->connect("selection_changed", this, "_refresh_menu_icons");
}
if (p_what == NOTIFICATION_ENTER_TREE) {
@@ -4668,8 +4746,10 @@ void SpatialEditor::_bind_methods() {
ClassDB::bind_method("_get_editor_data", &SpatialEditor::_get_editor_data);
ClassDB::bind_method("_request_gizmo", &SpatialEditor::_request_gizmo);
ClassDB::bind_method("_toggle_maximize_view", &SpatialEditor::_toggle_maximize_view);
+ ClassDB::bind_method("_refresh_menu_icons", &SpatialEditor::_refresh_menu_icons);
ADD_SIGNAL(MethodInfo("transform_key_request"));
+ ADD_SIGNAL(MethodInfo("item_lock_status_changed"));
}
void SpatialEditor::clear() {
@@ -4771,6 +4851,18 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_LIST_SELECT]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_MODE_LIST_SELECT]->set_tooltip(TTR("Show a list of all objects at the position clicked\n(same as Alt+RMB in select mode)."));
+ tool_button[TOOL_LOCK_SELECTED] = memnew(ToolButton);
+ hbc_menu->add_child(tool_button[TOOL_LOCK_SELECTED]);
+ button_binds[0] = MENU_LOCK_SELECTED;
+ tool_button[TOOL_LOCK_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds);
+ tool_button[TOOL_LOCK_SELECTED]->set_tooltip(TTR("Lock the selected object in place (can't be moved)."));
+
+ tool_button[TOOL_UNLOCK_SELECTED] = memnew(ToolButton);
+ hbc_menu->add_child(tool_button[TOOL_UNLOCK_SELECTED]);
+ button_binds[0] = MENU_UNLOCK_SELECTED;
+ tool_button[TOOL_UNLOCK_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds);
+ tool_button[TOOL_UNLOCK_SELECTED]->set_tooltip(TTR("Unlock the selected object (can be moved)."));
+
vs = memnew(VSeparator);
hbc_menu->add_child(vs);
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index c986e45f43..ad11ec33df 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -391,6 +391,8 @@ public:
TOOL_MODE_ROTATE,
TOOL_MODE_SCALE,
TOOL_MODE_LIST_SELECT,
+ TOOL_LOCK_SELECTED,
+ TOOL_UNLOCK_SELECTED,
TOOL_MAX
};
@@ -479,7 +481,8 @@ private:
MENU_VIEW_ORIGIN,
MENU_VIEW_GRID,
MENU_VIEW_CAMERA_SETTINGS,
-
+ MENU_LOCK_SELECTED,
+ MENU_UNLOCK_SELECTED
};
Button *tool_button[TOOL_MAX];
@@ -487,6 +490,9 @@ private:
MenuButton *transform_menu;
MenuButton *view_menu;
+ ToolButton *lock_button;
+ ToolButton *unlock_button;
+
AcceptDialog *accept;
ConfirmationDialog *snap_dialog;
@@ -543,6 +549,8 @@ private:
bool is_any_freelook_active() const;
+ void _refresh_menu_icons();
+
protected:
void _notification(int p_what);
//void _gui_input(InputEvent p_event);
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index f866a158f3..e7e57a7079 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -745,6 +745,10 @@ void SceneTreeDock::_notification(int p_what) {
canvas_item_plugin->get_canvas_item_editor()->connect("item_group_status_changed", scene_tree, "_update_tree");
scene_tree->connect("node_changed", canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), "update");
}
+
+ SpatialEditorPlugin *spatial_editor_plugin = Object::cast_to<SpatialEditorPlugin>(editor_data->get_editor("3D"));
+ spatial_editor_plugin->get_spatial_editor()->connect("item_lock_status_changed", scene_tree, "_update_tree");
+
button_add->set_icon(get_icon("Add", "EditorIcons"));
button_instance->set_icon(get_icon("Instance", "EditorIcons"));
button_create_script->set_icon(get_icon("ScriptCreate", "EditorIcons"));
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index c4b86c6b2b..dfda8a780d 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -88,7 +88,7 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
} else if (p_id == BUTTON_LOCK) {
- if (n->is_class("CanvasItem")) {
+ if (n->is_class("CanvasItem") || n->is_class("Spatial")) {
n->set_meta("_edit_lock_", Variant());
_update_tree();
emit_signal("node_changed");
@@ -266,6 +266,10 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
_update_visibility_color(p_node, item);
} else if (p_node->is_class("Spatial")) {
+ bool is_locked = p_node->has_meta("_edit_lock_");
+ if (is_locked)
+ item->add_button(0, get_icon("Lock", "EditorIcons"), BUTTON_LOCK, false, TTR("Node is locked.\nClick to unlock"));
+
bool v = p_node->call("is_visible");
if (v)
item->add_button(0, get_icon("Visible", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
diff --git a/main/main.cpp b/main/main.cpp
index c4bca94b44..5410aae1d2 100644..100755
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -427,6 +427,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "-m" || I->get() == "--maximized") { // force maximized window
init_maximized = true;
+ video_mode.maximized = true;
} else if (I->get() == "-w" || I->get() == "--windowed") { // force windowed window
init_windowed = true;
@@ -748,6 +749,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
Engine::get_singleton()->set_editor_hint(true);
main_args.push_back("--editor");
init_maximized = true;
+ video_mode.maximized = true;
use_custom_res = false;
}
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp
index 7949ca182f..f98a16a5d7 100644
--- a/modules/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative.cpp
@@ -64,7 +64,6 @@ void GDNativeLibrary::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_current_library_path"), &GDNativeLibrary::get_current_library_path);
ClassDB::bind_method(D_METHOD("get_current_dependencies"), &GDNativeLibrary::get_current_dependencies);
- ClassDB::bind_method(D_METHOD("is_current_library_statically_linked"), &GDNativeLibrary::is_current_library_statically_linked);
ClassDB::bind_method(D_METHOD("should_load_once"), &GDNativeLibrary::should_load_once);
ClassDB::bind_method(D_METHOD("is_singleton"), &GDNativeLibrary::is_singleton);
@@ -119,7 +118,7 @@ bool GDNative::initialize() {
}
String lib_path = library->get_current_library_path();
- if (lib_path.empty() && !library->is_current_library_statically_linked()) {
+ if (lib_path.empty()) {
ERR_PRINT("No library set for this platform");
return false;
}
@@ -140,7 +139,7 @@ bool GDNative::initialize() {
}
Error err = OS::get_singleton()->open_dynamic_library(path, native_handle);
- if (err != OK && !library->is_current_library_statically_linked()) {
+ if (err != OK) {
return false;
}
@@ -154,8 +153,7 @@ bool GDNative::initialize() {
initialized = false;
if (err || !library_init) {
- if (!library->is_current_library_statically_linked())
- OS::get_singleton()->close_dynamic_library(native_handle);
+ OS::get_singleton()->close_dynamic_library(native_handle);
native_handle = NULL;
ERR_PRINT("Failed to obtain godot_gdnative_init symbol");
return false;
@@ -374,40 +372,8 @@ RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_or
}
}
- bool is_statically_linked = false;
- {
-
- List<String> static_linking_keys;
- config->get_section_keys("static_linking", &static_linking_keys);
-
- for (List<String>::Element *E = static_linking_keys.front(); E; E = E->next()) {
- String key = E->get();
-
- Vector<String> tags = key.split(".");
-
- bool skip = false;
-
- for (int i = 0; i < tags.size(); i++) {
- bool has_feature = OS::get_singleton()->has_feature(tags[i]);
-
- if (!has_feature) {
- skip = true;
- break;
- }
- }
-
- if (skip) {
- continue;
- }
-
- is_statically_linked = config->get_value("static_linking", key);
- break;
- }
- }
-
lib->current_library_path = entry_lib_path;
lib->current_dependencies = dependency_paths;
- lib->current_library_statically_linked = is_statically_linked;
return lib;
}
diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h
index 061dff9267..052ce1fef1 100644
--- a/modules/gdnative/gdnative.h
+++ b/modules/gdnative/gdnative.h
@@ -55,7 +55,6 @@ class GDNativeLibrary : public Resource {
String current_library_path;
Vector<String> current_dependencies;
- bool current_library_statically_linked;
bool singleton;
bool load_once;
@@ -75,9 +74,6 @@ public:
_FORCE_INLINE_ Vector<String> get_current_dependencies() const {
return current_dependencies;
}
- _FORCE_INLINE_ bool is_current_library_statically_linked() const {
- return current_library_statically_linked;
- }
// things that are a property of the library itself, not platform specific
_FORCE_INLINE_ bool should_load_once() const {
@@ -103,12 +99,10 @@ public:
static void _bind_methods();
};
-typedef godot_variant (*native_call_cb)(void *, godot_array *);
-
struct GDNativeCallRegistry {
static GDNativeCallRegistry *singleton;
- inline GDNativeCallRegistry *get_singleton() {
+ inline static GDNativeCallRegistry *get_singleton() {
return singleton;
}
diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp
index 34b73558d5..92a88e354b 100644
--- a/modules/gdnative/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative/gdnative.cpp
@@ -115,6 +115,10 @@ godot_dictionary GDAPI godot_get_global_constants() {
}
// System functions
+void GDAPI godot_register_native_call_type(const char *p_call_type, native_call_cb p_callback) {
+ GDNativeCallRegistry::get_singleton()->register_native_call_type(StringName(p_call_type), p_callback);
+}
+
void GDAPI *godot_alloc(int p_bytes) {
return memalloc(p_bytes);
}
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index 0a1c5095d4..007c7955d4 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -5549,6 +5549,14 @@
]
},
{
+ "name": "godot_register_native_call_type",
+ "return_type": "void",
+ "arguments": [
+ ["const char *", "call_type"],
+ ["native_call_cb", "p_callback"]
+ ]
+ },
+ {
"name": "godot_alloc",
"return_type": "void *",
"arguments": [
diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h
index e8d509508e..0a884e6106 100644
--- a/modules/gdnative/include/gdnative/gdnative.h
+++ b/modules/gdnative/include/gdnative/gdnative.h
@@ -274,6 +274,9 @@ typedef godot_variant (*godot_gdnative_procedure_fn)(godot_array *);
////// System Functions
+typedef godot_variant (*native_call_cb)(void *, godot_array *);
+void GDAPI godot_register_native_call_type(const char *p_call_type, native_call_cb p_callback);
+
//using these will help Godot track how much memory is in use in debug mode
void GDAPI *godot_alloc(int p_bytes);
void GDAPI *godot_realloc(void *p_ptr, int p_bytes);
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index c1d744215d..d1aa129e77 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -250,41 +250,13 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
}
-
- // borderless fullscreen window mode
- if (current_videomode.fullscreen) {
- // set bypass compositor hint
- Atom bypass_compositor = XInternAtom(x11_display, "_NET_WM_BYPASS_COMPOSITOR", False);
- unsigned long compositing_disable_on = 1;
- XChangeProperty(x11_display, x11_window, bypass_compositor, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&compositing_disable_on, 1);
-
- // needed for lxde/openbox, possibly others
- Hints hints;
- Atom property;
- hints.flags = 2;
- hints.decorations = 0;
- property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
- XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5);
- XMapRaised(x11_display, x11_window);
- XWindowAttributes xwa;
- XGetWindowAttributes(x11_display, DefaultRootWindow(x11_display), &xwa);
- XMoveResizeWindow(x11_display, x11_window, 0, 0, xwa.width, xwa.height);
-
- // code for netwm-compliants
- XEvent xev;
- Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
- Atom fullscreen = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", False);
-
- memset(&xev, 0, sizeof(xev));
- xev.type = ClientMessage;
- xev.xclient.window = x11_window;
- xev.xclient.message_type = wm_state;
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = 1;
- xev.xclient.data.l[1] = fullscreen;
- xev.xclient.data.l[2] = 0;
-
- XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev);
+ if (current_videomode.maximized) {
+ current_videomode.maximized = false;
+ set_window_maximized(true);
+ // borderless fullscreen window mode
+ } else if (current_videomode.fullscreen) {
+ current_videomode.fullscreen = false;
+ set_window_fullscreen(true);
} else if (current_videomode.borderless_window) {
Hints hints;
Atom property;
@@ -467,8 +439,17 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
_ensure_user_data_dir();
power_manager = memnew(PowerX11);
+
+ XEvent xevent;
+ while (XCheckIfEvent(x11_display, &xevent, _check_window_events, NULL)) {
+ _window_changed(&xevent);
+ }
}
+int OS_X11::_check_window_events(Display *display, XEvent *event, char *arg) {
+ if (event->type == ConfigureNotify) return 1;
+ return 0;
+}
void OS_X11::xim_destroy_callback(::XIM im, ::XPointer client_data,
::XPointer call_data) {
@@ -648,6 +629,9 @@ void OS_X11::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) con
}
void OS_X11::set_wm_fullscreen(bool p_enabled) {
+ if (current_videomode.fullscreen == p_enabled)
+ return;
+
if (p_enabled && !is_window_resizable()) {
// Set the window as resizable to prevent window managers to ignore the fullscreen state flag.
XSizeHints *xsh;
@@ -971,6 +955,9 @@ bool OS_X11::is_window_minimized() const {
}
void OS_X11::set_window_maximized(bool p_enabled) {
+ if (is_window_maximized() == p_enabled)
+ return;
+
// Using EWMH -- Extended Window Manager Hints
XEvent xev;
Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
@@ -1417,6 +1404,20 @@ static Atom pick_target_from_atoms(Display *p_disp, Atom p_t1, Atom p_t2, Atom p
return None;
}
+void OS_X11::_window_changed(XEvent *event) {
+
+ if (xic) {
+ // Not portable.
+ set_ime_position(Point2(0, 1));
+ }
+ if ((event->xconfigure.width == current_videomode.width) &&
+ (event->xconfigure.height == current_videomode.height))
+ return;
+
+ current_videomode.width = event->xconfigure.width;
+ current_videomode.height = event->xconfigure.height;
+}
+
void OS_X11::process_xevents() {
//printf("checking events %i\n", XPending(x11_display));
@@ -1498,18 +1499,7 @@ void OS_X11::process_xevents() {
break;
case ConfigureNotify:
- if (xic) {
- // Not portable.
- set_ime_position(Point2(0, 1));
- }
- /* call resizeGLScene only if our window-size changed */
-
- if ((event.xconfigure.width == current_videomode.width) &&
- (event.xconfigure.height == current_videomode.height))
- break;
-
- current_videomode.width = event.xconfigure.width;
- current_videomode.height = event.xconfigure.height;
+ _window_changed(&event);
break;
case ButtonPress:
case ButtonRelease: {
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index 67f3807d99..a74e6ee5f3 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -187,6 +187,9 @@ protected:
virtual void set_main_loop(MainLoop *p_main_loop);
+ void _window_changed(XEvent *xevent);
+ static int _check_window_events(Display *display, XEvent *xevent, char *arg);
+
public:
virtual String get_name();
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index d65a3bfe80..3164344d15 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -52,7 +52,11 @@ void Camera2D::_update_scroll() {
if (viewport) {
viewport->set_canvas_transform(xform);
}
- get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, group_name, "_camera_moved", xform);
+
+ Size2 screen_size = viewport->get_visible_rect().size;
+ Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5) : Point2());
+
+ get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, group_name, "_camera_moved", xform, screen_offset);
};
}
diff --git a/scene/2d/parallax_background.cpp b/scene/2d/parallax_background.cpp
index a13ce6278e..b9012e37b2 100644
--- a/scene/2d/parallax_background.cpp
+++ b/scene/2d/parallax_background.cpp
@@ -47,10 +47,12 @@ void ParallaxBackground::_notification(int p_what) {
}
}
-void ParallaxBackground::_camera_moved(const Transform2D &p_transform) {
+void ParallaxBackground::_camera_moved(const Transform2D &p_transform, const Point2 &p_screen_offset) {
+
+ screen_offset = p_screen_offset;
set_scroll_scale(p_transform.get_scale().dot(Vector2(0.5, 0.5)));
- set_scroll_offset(p_transform.get_origin() / p_transform.get_scale());
+ set_scroll_offset(p_transform.get_origin());
}
void ParallaxBackground::set_scroll_scale(float p_scale) {
@@ -106,9 +108,9 @@ void ParallaxBackground::_update_scroll() {
continue;
if (ignore_camera_zoom)
- l->set_base_offset_and_scale(ofs, 1.0);
+ l->set_base_offset_and_scale(ofs, 1.0, screen_offset);
else
- l->set_base_offset_and_scale(ofs, scale);
+ l->set_base_offset_and_scale(ofs, scale, screen_offset);
}
}
diff --git a/scene/2d/parallax_background.h b/scene/2d/parallax_background.h
index 0dad1daeab..e37ec0db99 100644
--- a/scene/2d/parallax_background.h
+++ b/scene/2d/parallax_background.h
@@ -42,6 +42,7 @@ class ParallaxBackground : public CanvasLayer {
float scale;
Point2 base_offset;
Point2 base_scale;
+ Point2 screen_offset;
String group_name;
Point2 limit_begin;
Point2 limit_end;
@@ -51,7 +52,7 @@ class ParallaxBackground : public CanvasLayer {
void _update_scroll();
protected:
- void _camera_moved(const Transform2D &p_transform);
+ void _camera_moved(const Transform2D &p_transform, const Point2 &p_screen_offset);
void _notification(int p_what);
static void _bind_methods();
diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp
index 8fe651cb5f..4a69841975 100644
--- a/scene/2d/parallax_layer.cpp
+++ b/scene/2d/parallax_layer.cpp
@@ -40,7 +40,7 @@ void ParallaxLayer::set_motion_scale(const Size2 &p_scale) {
if (pb && is_inside_tree()) {
Vector2 ofs = pb->get_final_offset();
float scale = pb->get_scroll_scale();
- set_base_offset_and_scale(ofs, scale);
+ set_base_offset_and_scale(ofs, scale, screen_offset);
}
}
@@ -57,7 +57,7 @@ void ParallaxLayer::set_motion_offset(const Size2 &p_offset) {
if (pb && is_inside_tree()) {
Vector2 ofs = pb->get_final_offset();
float scale = pb->get_scroll_scale();
- set_base_offset_and_scale(ofs, scale);
+ set_base_offset_and_scale(ofs, scale, screen_offset);
}
}
@@ -106,26 +106,28 @@ void ParallaxLayer::_notification(int p_what) {
}
}
-void ParallaxLayer::set_base_offset_and_scale(const Point2 &p_offset, float p_scale) {
+void ParallaxLayer::set_base_offset_and_scale(const Point2 &p_offset, float p_scale, const Point2 &p_screen_offset) {
+ screen_offset = p_screen_offset;
if (!is_inside_tree())
return;
if (Engine::get_singleton()->is_editor_hint())
return;
- Point2 new_ofs = ((orig_offset + p_offset) * motion_scale) * p_scale + motion_offset;
+
+ Point2 new_ofs = (screen_offset + (p_offset - screen_offset) * motion_scale) + motion_offset * p_scale + orig_offset * p_scale;
+
+ Vector2 mirror = Vector2(1, 1);
if (mirroring.x) {
- double den = mirroring.x * p_scale;
- new_ofs.x -= den * ceil(new_ofs.x / den);
+ mirror.x = -1;
}
if (mirroring.y) {
- double den = mirroring.y * p_scale;
- new_ofs.y -= den * ceil(new_ofs.y / den);
+ mirror.y = -1;
}
set_position(new_ofs);
- set_scale(Vector2(1, 1) * p_scale);
+ set_scale(mirror * p_scale * orig_scale);
}
String ParallaxLayer::get_configuration_warning() const {
diff --git a/scene/2d/parallax_layer.h b/scene/2d/parallax_layer.h
index 95ca27c41a..6feb1fad67 100644
--- a/scene/2d/parallax_layer.h
+++ b/scene/2d/parallax_layer.h
@@ -43,6 +43,8 @@ class ParallaxLayer : public Node2D {
Vector2 mirroring;
void _update_mirroring();
+ Point2 screen_offset;
+
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -57,7 +59,7 @@ public:
void set_mirroring(const Size2 &p_mirroring);
Size2 get_mirroring() const;
- void set_base_offset_and_scale(const Point2 &p_offset, float p_scale);
+ void set_base_offset_and_scale(const Point2 &p_offset, float p_scale, const Point2 &p_screen_offset);
virtual String get_configuration_warning() const;
ParallaxLayer();