summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editor/editor_settings.cpp8
-rw-r--r--editor/editor_themes.cpp9
-rw-r--r--editor/project_manager.cpp8
-rw-r--r--main/main.cpp4
-rw-r--r--misc/dist/html/default.html2
-rw-r--r--modules/gdscript/SCsub3
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp (renamed from modules/gdscript/gdscript_highlighter.cpp)73
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.h (renamed from modules/gdscript/gdscript_highlighter.h)14
-rw-r--r--modules/gdscript/register_types.cpp2
-rw-r--r--platform/javascript/engine.js4
-rw-r--r--platform/javascript/os_javascript.cpp12
-rw-r--r--platform/osx/os_osx.mm61
-rw-r--r--platform/windows/os_windows.cpp44
-rw-r--r--platform/x11/os_x11.cpp42
-rw-r--r--scene/gui/text_edit.cpp3
15 files changed, 245 insertions, 44 deletions
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index c4e6d18163..b741c432ce 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -596,6 +596,10 @@ void EditorSettings::_load_default_text_editor_theme() {
_initial_set("text_editor/highlighting/word_highlighted_color", Color(0.8, 0.9, 0.9, 0.15));
_initial_set("text_editor/highlighting/search_result_color", Color(0.05, 0.25, 0.05, 1));
_initial_set("text_editor/highlighting/search_result_border_color", Color(0.1, 0.45, 0.1, 1));
+
+ // GDScript highlighter
+ _initial_set("text_editor/highlighting/gdscript/function_definition_color", Color::html("#01e1ff"));
+ _initial_set("text_editor/highlighting/gdscript/node_path_color", Color::html("#64c15a"));
}
bool EditorSettings::_save_text_editor_theme(String p_file) {
@@ -632,6 +636,10 @@ bool EditorSettings::_save_text_editor_theme(String p_file) {
cf->set_value(theme_section, "search_result_color", ((Color)get("text_editor/highlighting/search_result_color")).to_html());
cf->set_value(theme_section, "search_result_border_color", ((Color)get("text_editor/highlighting/search_result_border_color")).to_html());
+ //GDScript highlighter
+ cf->set_value(theme_section, "gdscript/function_definition_color", ((Color)get("text_editor/highlighting/gdscript/function_definition_color")).to_html());
+ cf->set_value(theme_section, "gdscript/node_path_color", ((Color)get("text_editor/highlighting/gdscript/node_path_color")).to_html());
+
Error err = cf->save(p_file);
if (err == OK) {
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index bf7236cc2b..d0b842f231 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -1047,6 +1047,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
const Color comment_color = dim_color;
const Color string_color = Color::html(dark_theme ? "#ffd942" : "#ffd118").linear_interpolate(mono_color, dark_theme ? 0.5 : 0.3);
+ const Color function_definition_color = Color::html(dark_theme ? "#01e1ff" : "#00a5ba");
+ const Color node_path_color = Color::html(dark_theme ? "64c15a" : "#518b4b");
+
const Color te_background_color = Color(0, 0, 0, 0);
const Color completion_background_color = base_color;
const Color completion_selected_color = alpha1;
@@ -1105,6 +1108,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
setting->set_initial_value("text_editor/highlighting/code_folding_color", code_folding_color, true);
setting->set_initial_value("text_editor/highlighting/search_result_color", search_result_color, true);
setting->set_initial_value("text_editor/highlighting/search_result_border_color", search_result_border_color, true);
+
+ setting->set_initial_value("text_editor/highlighting/gdscript/function_definition_color", function_definition_color, true);
+ setting->set_initial_value("text_editor/highlighting/gdscript/node_path_color", node_path_color, true);
} else if (text_editor_color_theme == "Default") {
setting->set_initial_value("text_editor/highlighting/symbol_color", Color::html("badfff"), true);
setting->set_initial_value("text_editor/highlighting/keyword_color", Color::html("ffffb3"), true);
@@ -1136,6 +1142,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
setting->set_initial_value("text_editor/highlighting/code_folding_color", Color(0.8, 0.8, 0.8, 0.8), true);
setting->set_initial_value("text_editor/highlighting/search_result_color", Color(0.05, 0.25, 0.05, 1), true);
setting->set_initial_value("text_editor/highlighting/search_result_border_color", Color(0.1, 0.45, 0.1, 1), true);
+
+ setting->set_initial_value("text_editor/highlighting/gdscript/function_definition_color", Color::html("#01e1ff"), true);
+ setting->set_initial_value("text_editor/highlighting/gdscript/node_path_color", Color::html("#64c15a"), true);
}
return theme;
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 666f08cb2d..97d3a070ab 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -725,9 +725,11 @@ void ProjectManager::_update_project_buttons() {
}
}
- erase_btn->set_disabled(selected_list.size() < 1);
- open_btn->set_disabled(selected_list.size() < 1);
- rename_btn->set_disabled(selected_list.size() < 1);
+ bool empty_selection = selected_list.empty();
+ erase_btn->set_disabled(empty_selection);
+ open_btn->set_disabled(empty_selection);
+ rename_btn->set_disabled(empty_selection);
+ run_btn->set_disabled(empty_selection);
}
void ProjectManager::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) {
diff --git a/main/main.cpp b/main/main.cpp
index 1c5540fd19..9c8474cb5b 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1150,14 +1150,14 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
if (id) {
- if (bool(GLOBAL_DEF("input/pointing_devices/emulate_touch_from_mouse", false)) && !(editor || project_manager)) {
+ if (bool(GLOBAL_DEF("input_devices/pointing/emulate_touch_from_mouse", false)) && !(editor || project_manager)) {
if (!OS::get_singleton()->has_touchscreen_ui_hint()) {
//only if no touchscreen ui hint, set emulation
id->set_emulate_touch_from_mouse(true);
}
}
- id->set_emulate_mouse_from_touch(bool(GLOBAL_DEF("input/pointing_devices/emulate_mouse_from_touch", true)));
+ id->set_emulate_mouse_from_touch(bool(GLOBAL_DEF("input_devices/pointing/emulate_mouse_from_touch", true)));
}
MAIN_PRINT("Main: Load Remaps");
diff --git a/misc/dist/html/default.html b/misc/dist/html/default.html
index 4e3515a7b6..4aa9347fec 100644
--- a/misc/dist/html/default.html
+++ b/misc/dist/html/default.html
@@ -195,7 +195,7 @@ $GODOT_HEAD_INCLUDE
</head>
<body>
<div id="container">
- <canvas id="canvas" oncontextmenu="event.preventDefault();" width="640" height="480">
+ <canvas id="canvas" width="640" height="480">
HTML5 canvas appears to be unsupported in the current browser.<br />
Please try updating or use a different browser.
</canvas>
diff --git a/modules/gdscript/SCsub b/modules/gdscript/SCsub
index 13870170a5..73f09f1659 100644
--- a/modules/gdscript/SCsub
+++ b/modules/gdscript/SCsub
@@ -7,4 +7,7 @@ env_gdscript = env_modules.Clone()
env_gdscript.add_source_files(env.modules_sources, "*.cpp")
+if env['tools']:
+ env_gdscript.add_source_files(env.modules_sources, "./editor/*.cpp")
+
Export('env')
diff --git a/modules/gdscript/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp
index 4e89851bf2..ea3efff9cf 100644
--- a/modules/gdscript/gdscript_highlighter.cpp
+++ b/modules/gdscript/editor/gdscript_highlighter.cpp
@@ -29,6 +29,8 @@
/*************************************************************************/
#include "gdscript_highlighter.h"
+#include "../gdscript_tokenizer.h"
+#include "editor/editor_settings.h"
#include "scene/gui/text_edit.h"
inline bool _is_symbol(CharType c) {
@@ -61,12 +63,20 @@ static bool _is_hex_symbol(CharType c) {
Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_highlighting(int p_line) {
Map<int, TextEdit::HighlighterInfo> color_map;
+ Type next_type = NONE;
+ Type current_type = NONE;
+ Type previous_type = NONE;
+
+ String previous_text = "";
+ int previous_column = 0;
+
bool prev_is_char = false;
bool prev_is_number = false;
bool in_keyword = false;
bool in_word = false;
bool in_function_name = false;
bool in_member_variable = false;
+ bool in_node_path = false;
bool is_hex_notation = false;
Color keyword_color;
Color color;
@@ -214,18 +224,64 @@ Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_
in_member_variable = false;
}
- if (in_region >= 0)
+ if (!in_node_path && in_region == -1 && str[j] == '$') {
+ in_node_path = true;
+ } else if (in_region != -1 || (is_symbol && str[j] != '/')) {
+ in_node_path = false;
+ }
+
+ if (in_region >= 0) {
+ next_type = REGION;
color = text_editor->_get_color_region(in_region).color;
- else if (in_keyword)
+ } else if (in_node_path) {
+ next_type = NODE_PATH;
+ color = node_path_color;
+ } else if (in_keyword) {
+ next_type = KEYWORD;
color = keyword_color;
- else if (in_member_variable)
+ } else if (in_member_variable) {
+ next_type = MEMBER;
color = member_color;
- else if (in_function_name)
- color = function_color;
- else if (is_symbol)
+ } else if (in_function_name) {
+ next_type = FUNCTION;
+
+ if (previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::TK_PR_FUNCTION)) {
+ color = function_definition_color;
+ } else {
+ color = function_color;
+ }
+ } else if (is_symbol) {
+ next_type = SYMBOL;
color = symbol_color;
- else if (is_number)
+ } else if (is_number) {
+ next_type = NUMBER;
color = number_color;
+ } else {
+ next_type = IDENTIFIER;
+ }
+
+ if (next_type != current_type) {
+ if (current_type == NONE) {
+ current_type = next_type;
+ } else {
+ previous_type = current_type;
+ current_type = next_type;
+
+ // no need to store regions...
+ if (previous_type == REGION) {
+ previous_text = "";
+ previous_column = j;
+ } else {
+ String text = str.substr(previous_column, j - previous_column).strip_edges();
+ previous_column = j;
+
+ // ignore if just whitespace
+ if (text != "") {
+ previous_text = text;
+ }
+ }
+ }
+ }
prev_is_char = is_char;
prev_is_number = is_number;
@@ -255,6 +311,9 @@ void GDScriptSyntaxHighlighter::_update_cache() {
function_color = text_editor->get_color("function_color");
number_color = text_editor->get_color("number_color");
member_color = text_editor->get_color("member_variable_color");
+
+ function_definition_color = EDITOR_DEF("text_editor/highlighting/gdscript/function_definition_color", Color::html("#01e1ff"));
+ node_path_color = EDITOR_DEF("text_editor/highlighting/gdscript/node_path_color", Color::html("#64c15a"));
}
SyntaxHighlighter *GDScriptSyntaxHighlighter::create() {
diff --git a/modules/gdscript/gdscript_highlighter.h b/modules/gdscript/editor/gdscript_highlighter.h
index ef1bdd4103..0296ab7652 100644
--- a/modules/gdscript/gdscript_highlighter.h
+++ b/modules/gdscript/editor/gdscript_highlighter.h
@@ -35,13 +35,27 @@
class GDScriptSyntaxHighlighter : public SyntaxHighlighter {
private:
+ enum Type {
+ NONE,
+ REGION,
+ NODE_PATH,
+ SYMBOL,
+ NUMBER,
+ FUNCTION,
+ KEYWORD,
+ MEMBER,
+ IDENTIFIER
+ };
+
// colours
Color font_color;
Color symbol_color;
Color function_color;
+ Color function_definition_color;
Color built_in_type_color;
Color number_color;
Color member_color;
+ Color node_path_color;
public:
static SyntaxHighlighter *create();
diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp
index 85c94c3596..422223370b 100644
--- a/modules/gdscript/register_types.cpp
+++ b/modules/gdscript/register_types.cpp
@@ -30,8 +30,8 @@
#include "register_types.h"
+#include "editor/gdscript_highlighter.h"
#include "gdscript.h"
-#include "gdscript_highlighter.h"
#include "gdscript_tokenizer.h"
#include "io/file_access_encrypted.h"
#include "io/resource_loader.h"
diff --git a/platform/javascript/engine.js b/platform/javascript/engine.js
index e4839af433..e3a28083a0 100644
--- a/platform/javascript/engine.js
+++ b/platform/javascript/engine.js
@@ -161,6 +161,10 @@
actualCanvas.style.padding = 0;
actualCanvas.style.borderWidth = 0;
actualCanvas.style.borderStyle = 'none';
+ // disable right-click context menu
+ actualCanvas.addEventListener('contextmenu', function(ev) {
+ ev.preventDefault();
+ }, false);
// until context restoration is implemented
actualCanvas.addEventListener('webglcontextlost', function(ev) {
alert("WebGL context lost, please reload the page");
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 1b5463e40d..6c6e4d2d1c 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -167,10 +167,9 @@ static EM_BOOL _mousebutton_callback(int event_type, const EmscriptenMouseEvent
int mask = _input->get_mouse_button_mask();
int button_flag = 1 << (ev->get_button_index() - 1);
if (ev->is_pressed()) {
- // since the event is consumed, focus manually
- if (!is_canvas_focused()) {
- focus_canvas();
- }
+ // Since the event is consumed, focus manually. The containing iframe,
+ // if used, may not have focus yet, so focus even if already focused.
+ focus_canvas();
mask |= button_flag;
} else if (mask & button_flag) {
mask &= ~button_flag;
@@ -181,7 +180,8 @@ static EM_BOOL _mousebutton_callback(int event_type, const EmscriptenMouseEvent
ev->set_button_mask(mask);
_input->parse_input_event(ev);
- // prevent selection dragging
+ // Prevent multi-click text selection and wheel-click scrolling anchor.
+ // Context menu is prevented through contextmenu event.
return true;
}
@@ -204,7 +204,7 @@ static EM_BOOL _mousemove_callback(int event_type, const EmscriptenMouseEvent *m
ev->set_position(pos);
ev->set_global_position(ev->get_position());
- ev->set_relative(ev->get_position() - _input->get_mouse_position());
+ ev->set_relative(Vector2(mouse_event->movementX, mouse_event->movementY));
_input->set_mouse_position(ev->get_position());
ev->set_speed(_input->get_last_mouse_speed());
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index eaf89f7d0f..80d466f4b6 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -1513,39 +1513,78 @@ void OS_OSX::set_cursor_shape(CursorShape p_shape) {
void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
if (p_cursor.is_valid()) {
Ref<Texture> texture = p_cursor;
- Ref<Image> image = texture->get_data();
+ Ref<AtlasTexture> atlas_texture = p_cursor;
+ Ref<Image> image;
+ Size2 texture_size;
+ Rect2 atlas_rect;
- ERR_FAIL_COND(texture->get_width() > 256 || texture->get_height() > 256);
+ if (texture.is_valid()) {
+ image = texture->get_data();
+ }
+
+ if (!image.is_valid() && atlas_texture.is_valid()) {
+ texture = atlas_texture->get_atlas();
+
+ atlas_rect.size.width = texture->get_width();
+ atlas_rect.size.height = texture->get_height();
+ atlas_rect.position.x = atlas_texture->get_region().position.x;
+ atlas_rect.position.y = atlas_texture->get_region().position.y;
+
+ texture_size.width = atlas_texture->get_region().size.x;
+ texture_size.height = atlas_texture->get_region().size.y;
+ } else if (image.is_valid()) {
+ texture_size.width = texture->get_width();
+ texture_size.height = texture->get_height();
+ }
+
+ ERR_FAIL_COND(!texture.is_valid());
+ ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256);
+
+ image = texture->get_data();
NSBitmapImageRep *imgrep = [[[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:NULL
- pixelsWide:image->get_width()
- pixelsHigh:image->get_height()
+ pixelsWide:int(texture_size.width)
+ pixelsHigh:int(texture_size.height)
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
- bytesPerRow:image->get_width() * 4
+ bytesPerRow:int(texture_size.width) * 4
bitsPerPixel:32] autorelease];
ERR_FAIL_COND(imgrep == nil);
uint8_t *pixels = [imgrep bitmapData];
- int len = image->get_width() * image->get_height();
+ int len = int(texture_size.width * texture_size.height);
PoolVector<uint8_t> data = image->get_data();
PoolVector<uint8_t>::Read r = data.read();
+ image->lock();
+
/* Premultiply the alpha channel */
for (int i = 0; i < len; i++) {
- uint8_t alpha = r[i * 4 + 3];
- pixels[i * 4 + 0] = (uint8_t)(((uint16_t)r[i * 4 + 0] * alpha) / 255);
- pixels[i * 4 + 1] = (uint8_t)(((uint16_t)r[i * 4 + 1] * alpha) / 255);
- pixels[i * 4 + 2] = (uint8_t)(((uint16_t)r[i * 4 + 2] * alpha) / 255);
+ int row_index = floor(i / texture_size.width) + atlas_rect.position.y;
+ int column_index = (i % int(texture_size.width)) + atlas_rect.position.x;
+
+ if (atlas_texture.is_valid()) {
+ column_index = MIN(column_index, atlas_rect.size.width - 1);
+ row_index = MIN(row_index, atlas_rect.size.height - 1);
+ }
+
+ uint32_t color = image->get_pixel(column_index, row_index).to_argb32();
+
+ uint8_t alpha = (color >> 24) & 0xFF;
+ pixels[i * 4 + 0] = ((color >> 16) & 0xFF) * alpha / 255;
+ pixels[i * 4 + 1] = ((color >> 8) & 0xFF) * alpha / 255;
+ pixels[i * 4 + 2] = ((color)&0xFF) * alpha / 255;
pixels[i * 4 + 3] = alpha;
}
- NSImage *nsimage = [[[NSImage alloc] initWithSize:NSMakeSize(image->get_width(), image->get_height())] autorelease];
+ image->unlock();
+
+ NSImage *nsimage = [[[NSImage alloc] initWithSize:NSMakeSize(texture_size.width, texture_size.height)] autorelease];
[nsimage addRepresentation:imgrep];
NSCursor *cursor = [[NSCursor alloc] initWithImage:nsimage hotSpot:NSMakePoint(p_hotspot.x, p_hotspot.y)];
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 54a5d91eb4..2850d38ce4 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -2033,27 +2033,57 @@ void OS_Windows::set_cursor_shape(CursorShape p_shape) {
void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
if (p_cursor.is_valid()) {
Ref<Texture> texture = p_cursor;
- Ref<Image> image = texture->get_data();
+ Ref<AtlasTexture> atlas_texture = p_cursor;
+ Ref<Image> image;
+ Size2 texture_size;
+ Rect2 atlas_rect;
- UINT image_size = texture->get_width() * texture->get_height();
- UINT size = sizeof(UINT) * image_size;
+ if (texture.is_valid()) {
+ image = texture->get_data();
+ }
+
+ if (!image.is_valid() && atlas_texture.is_valid()) {
+ texture = atlas_texture->get_atlas();
+
+ atlas_rect.size.width = texture->get_width();
+ atlas_rect.size.height = texture->get_height();
+ atlas_rect.position.x = atlas_texture->get_region().position.x;
+ atlas_rect.position.y = atlas_texture->get_region().position.y;
+
+ texture_size.width = atlas_texture->get_region().size.x;
+ texture_size.height = atlas_texture->get_region().size.y;
+ } else if (image.is_valid()) {
+ texture_size.width = texture->get_width();
+ texture_size.height = texture->get_height();
+ }
- ERR_FAIL_COND(texture->get_width() > 256 || texture->get_height() > 256);
+ ERR_FAIL_COND(!texture.is_valid());
+ ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256);
+
+ image = texture->get_data();
+
+ UINT image_size = texture_size.width * texture_size.height;
+ UINT size = sizeof(UINT) * image_size;
// Create the BITMAP with alpha channel
COLORREF *buffer = (COLORREF *)malloc(sizeof(COLORREF) * image_size);
image->lock();
for (UINT index = 0; index < image_size; index++) {
- int row_index = floor(index / texture->get_width());
- int column_index = index % texture->get_width();
+ int row_index = floor(index / texture_size.width) + atlas_rect.position.y;
+ int column_index = (index % int(texture_size.width)) + atlas_rect.position.x;
+
+ if (atlas_texture.is_valid()) {
+ column_index = MIN(column_index, atlas_rect.size.width - 1);
+ row_index = MIN(row_index, atlas_rect.size.height - 1);
+ }
*(buffer + index) = image->get_pixel(column_index, row_index).to_argb32();
}
image->unlock();
// Using 4 channels, so 4 * 8 bits
- HBITMAP bitmap = CreateBitmap(texture->get_width(), texture->get_height(), 1, 4 * 8, buffer);
+ HBITMAP bitmap = CreateBitmap(texture_size.width, texture_size.height, 1, 4 * 8, buffer);
COLORREF clrTransparent = -1;
// Create the AND and XOR masks for the bitmap
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index d1b87dac6f..117995ea48 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -2420,13 +2420,38 @@ void OS_X11::set_cursor_shape(CursorShape p_shape) {
void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
if (p_cursor.is_valid()) {
Ref<Texture> texture = p_cursor;
- Ref<Image> image = texture->get_data();
+ Ref<AtlasTexture> atlas_texture = p_cursor;
+ Ref<Image> image;
+ Size2 texture_size;
+ Rect2 atlas_rect;
- ERR_FAIL_COND(texture->get_width() > 256 || texture->get_height() > 256);
+ if (texture.is_valid()) {
+ image = texture->get_data();
+ }
+
+ if (!image.is_valid() && atlas_texture.is_valid()) {
+ texture = atlas_texture->get_atlas();
+
+ atlas_rect.size.width = texture->get_width();
+ atlas_rect.size.height = texture->get_height();
+ atlas_rect.position.x = atlas_texture->get_region().position.x;
+ atlas_rect.position.y = atlas_texture->get_region().position.y;
+
+ texture_size.width = atlas_texture->get_region().size.x;
+ texture_size.height = atlas_texture->get_region().size.y;
+ } else if (image.is_valid()) {
+ texture_size.width = texture->get_width();
+ texture_size.height = texture->get_height();
+ }
+
+ ERR_FAIL_COND(!texture.is_valid());
+ ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256);
+
+ image = texture->get_data();
// Create the cursor structure
- XcursorImage *cursor_image = XcursorImageCreate(texture->get_width(), texture->get_height());
- XcursorUInt image_size = texture->get_width() * texture->get_height();
+ XcursorImage *cursor_image = XcursorImageCreate(texture_size.width, texture_size.height);
+ XcursorUInt image_size = texture_size.width * texture_size.height;
XcursorDim size = sizeof(XcursorPixel) * image_size;
cursor_image->version = 1;
@@ -2440,8 +2465,13 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
image->lock();
for (XcursorPixel index = 0; index < image_size; index++) {
- int row_index = floor(index / texture->get_width());
- int column_index = index % texture->get_width();
+ int row_index = floor(index / texture_size.width) + atlas_rect.position.y;
+ int column_index = (index % int(texture_size.width)) + atlas_rect.position.x;
+
+ if (atlas_texture.is_valid()) {
+ column_index = MIN(column_index, atlas_rect.size.width - 1);
+ row_index = MIN(row_index, atlas_rect.size.height - 1);
+ }
*(cursor_image->pixels + index) = image->get_pixel(column_index, row_index).to_argb32();
}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 4c9f515ced..4ff74dbb3f 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -4236,6 +4236,7 @@ void TextEdit::paste() {
String clipboard = OS::get_singleton()->get_clipboard();
+ begin_complex_operation();
if (selection.active) {
selection.active = false;
@@ -4252,6 +4253,8 @@ void TextEdit::paste() {
}
_insert_text_at_cursor(clipboard);
+ end_complex_operation();
+
update();
}