Fix X11 memory leak after drag & drop file into the editor

This commit is contained in:
Haoyu Qiu 2022-03-04 17:50:28 +08:00
parent cf970aab26
commit 9d6f4a76d1
1 changed files with 20 additions and 13 deletions

View File

@ -98,6 +98,15 @@
static const double abs_resolution_mult = 10000.0; static const double abs_resolution_mult = 10000.0;
static const double abs_resolution_range_mult = 10.0; static const double abs_resolution_range_mult = 10.0;
static String get_atom_name(Display *p_disp, Atom p_atom) {
char *name = XGetAtomName(p_disp, p_atom);
ERR_FAIL_NULL_V_MSG(name, String(), "Atom is invalid.");
String ret;
ret.parse_utf8(name);
XFree(name);
return ret;
}
void OS_X11::initialize_core() { void OS_X11::initialize_core() {
crash_handler.initialize(); crash_handler.initialize();
@ -2265,7 +2274,7 @@ static Atom pick_target_from_list(Display *p_display, Atom *p_list, int p_count)
for (int i = 0; i < p_count; i++) { for (int i = 0; i < p_count; i++) {
Atom atom = p_list[i]; Atom atom = p_list[i];
if (atom != None && String(XGetAtomName(p_display, atom)) == target_type) { if (atom != None && get_atom_name(p_display, atom) == target_type) {
return atom; return atom;
} }
} }
@ -2274,15 +2283,15 @@ static Atom pick_target_from_list(Display *p_display, Atom *p_list, int p_count)
static Atom pick_target_from_atoms(Display *p_disp, Atom p_t1, Atom p_t2, Atom p_t3) { static Atom pick_target_from_atoms(Display *p_disp, Atom p_t1, Atom p_t2, Atom p_t3) {
static const char *target_type = "text/uri-list"; static const char *target_type = "text/uri-list";
if (p_t1 != None && String(XGetAtomName(p_disp, p_t1)) == target_type) { if (p_t1 != None && get_atom_name(p_disp, p_t1) == target_type) {
return p_t1; return p_t1;
} }
if (p_t2 != None && String(XGetAtomName(p_disp, p_t2)) == target_type) { if (p_t2 != None && get_atom_name(p_disp, p_t2) == target_type) {
return p_t2; return p_t2;
} }
if (p_t3 != None && String(XGetAtomName(p_disp, p_t3)) == target_type) { if (p_t3 != None && get_atom_name(p_disp, p_t3) == target_type) {
return p_t3; return p_t3;
} }
@ -2880,6 +2889,7 @@ void OS_X11::process_xevents() {
Property p = read_property(x11_display, x11_window, XInternAtom(x11_display, "PRIMARY", 0)); Property p = read_property(x11_display, x11_window, XInternAtom(x11_display, "PRIMARY", 0));
Vector<String> files = String((char *)p.data).split("\n", false); Vector<String> files = String((char *)p.data).split("\n", false);
XFree(p.data);
for (int i = 0; i < files.size(); i++) { for (int i = 0; i < files.size(); i++) {
files.write[i] = files[i].replace("file://", "").http_unescape().strip_edges(); files.write[i] = files[i].replace("file://", "").http_unescape().strip_edges();
} }
@ -2914,6 +2924,7 @@ void OS_X11::process_xevents() {
if (more_than_3) { if (more_than_3) {
Property p = read_property(x11_display, source, XInternAtom(x11_display, "XdndTypeList", False)); Property p = read_property(x11_display, source, XInternAtom(x11_display, "XdndTypeList", False));
requested = pick_target_from_list(x11_display, (Atom *)p.data, p.nitems); requested = pick_target_from_list(x11_display, (Atom *)p.data, p.nitems);
XFree(p.data);
} else { } else {
requested = pick_target_from_atoms(x11_display, event.xclient.data.l[2], event.xclient.data.l[3], event.xclient.data.l[4]); requested = pick_target_from_atoms(x11_display, event.xclient.data.l[2], event.xclient.data.l[3], event.xclient.data.l[4]);
} }
@ -3990,10 +4001,10 @@ OS::LatinKeyboardVariant OS_X11::get_latin_keyboard_variant() const {
ERR_FAIL_COND_V(!xkbdesc->names, LATIN_KEYBOARD_QWERTY); ERR_FAIL_COND_V(!xkbdesc->names, LATIN_KEYBOARD_QWERTY);
ERR_FAIL_COND_V(!xkbdesc->names->symbols, LATIN_KEYBOARD_QWERTY); ERR_FAIL_COND_V(!xkbdesc->names->symbols, LATIN_KEYBOARD_QWERTY);
char *layout = XGetAtomName(x11_display, xkbdesc->names->symbols); String layout = get_atom_name(x11_display, xkbdesc->names->symbols);
ERR_FAIL_COND_V(!layout, LATIN_KEYBOARD_QWERTY); ERR_FAIL_COND_V(layout.empty(), LATIN_KEYBOARD_QWERTY);
Vector<String> info = String(layout).split("+"); Vector<String> info = layout.split("+");
ERR_FAIL_INDEX_V(1, info.size(), LATIN_KEYBOARD_QWERTY); ERR_FAIL_INDEX_V(1, info.size(), LATIN_KEYBOARD_QWERTY);
if (info[1].find("colemak") != -1) { if (info[1].find("colemak") != -1) {
@ -4066,8 +4077,7 @@ String OS_X11::keyboard_get_layout_language(int p_index) const {
Atom names = kbd->names->symbols; Atom names = kbd->names->symbols;
if (names != None) { if (names != None) {
char *name = XGetAtomName(x11_display, names); Vector<String> info = get_atom_name(x11_display, names).split("+");
Vector<String> info = String(name).split("+");
if (p_index >= 0 && p_index < _group_count) { if (p_index >= 0 && p_index < _group_count) {
if (p_index + 1 < info.size()) { if (p_index + 1 < info.size()) {
ret = info[p_index + 1]; // Skip "pc" at the start and "inet"/"group" at the end of symbols. ret = info[p_index + 1]; // Skip "pc" at the start and "inet"/"group" at the end of symbols.
@ -4077,7 +4087,6 @@ String OS_X11::keyboard_get_layout_language(int p_index) const {
} else { } else {
ERR_PRINT("Index " + itos(p_index) + "is out of bounds (" + itos(_group_count) + ")."); ERR_PRINT("Index " + itos(p_index) + "is out of bounds (" + itos(_group_count) + ").");
} }
XFree(name);
} }
XkbFreeKeyboard(kbd, 0, true); XkbFreeKeyboard(kbd, 0, true);
} }
@ -4104,9 +4113,7 @@ String OS_X11::keyboard_get_layout_name(int p_index) const {
} }
if (p_index >= 0 && p_index < _group_count) { if (p_index >= 0 && p_index < _group_count) {
char *full_name = XGetAtomName(x11_display, groups[p_index]); ret = get_atom_name(x11_display, groups[p_index]);
ret.parse_utf8(full_name);
XFree(full_name);
} else { } else {
ERR_PRINT("Index " + itos(p_index) + "is out of bounds (" + itos(_group_count) + ")."); ERR_PRINT("Index " + itos(p_index) + "is out of bounds (" + itos(_group_count) + ").");
} }