Repository: godotengine/godot
File: platform/linuxbsd/x11/display_server_x11.cpp (C++)

Code before:
			XFree(xsi);
		}
	} else {
		int count = XScreenCount(x11_display);
		if (p_screen < count) {
			Window root = XRootWindow(x11_display, p_screen);
			XWindowAttributes xwa;
			XGetWindowAttributes(x11_display, root, &xwa);
			rect.position.x = xwa.x;
			rect.position.y = xwa.y;
			rect.size.width = xwa.width;
			rect.size.height = xwa.height;
		} else {
			ERR_PRINT("Invalid screen index: " + itos(p_screen) + "(count: " + itos(count) + ").");
		}
	}

	return rect;
}

Point2i DisplayServerX11::screen_get_position(int p_screen) const {
	_THREAD_SAFE_METHOD_

	return _screen_get_rect(p_screen).position;
}

Size2i DisplayServerX11::screen_get_size(int p_screen) const {
	_THREAD_SAFE_METHOD_

	return _screen_get_rect(p_screen).size;
}

// A Handler to avoid crashing on non-fatal X errors by default.
//
// The original X11 error formatter `_XPrintDefaultError` is defined here:
// https://gitlab.freedesktop.org/xorg/lib/libx11/-/blob/e45ca7b41dcd3ace7681d6897505f85d374640f2/src/XlibInt.c#L1322
// It is not exposed through the API, accesses X11 internals,
// and is much more complex, so this is a less complete simplified error X11 printer.
int default_window_error_handler(Display *display, XErrorEvent *error) {
	static char message[1024];
	XGetErrorText(display, error->error_code, message, sizeof(message));

	ERR_PRINT(vformat("Unhandled XServer error: %s"
					  "\n   Major opcode of failed request: %d"
					  "\n   Serial number of failed request: %d"
					  "\n   Current serial number in output stream: %d",
			String::utf8(message), (uint64_t)error->request_code, (uint64_t)error->minor_code, (uint64_t)error->serial));
	return 0;
}

bool g_bad_window = false;

Review comment (suggestion):
```suggestion
							// For unclear reasons the first GetWindowProperty always returns a length and format of 0. 
							// Otherwise, last chunk, process finished.
```

Code after:
				// Non-blocking wait for next event and remove it from the queue.
				XEvent ev;
				while (XCheckIfEvent(x11_display, &ev, _predicate_clipboard_incr, (XPointer)&transfer_prop)) {
					result = XGetWindowProperty(x11_display, x11_window,
							transfer_prop, // output property
							0, LONG_MAX, // offset - len
							True, // delete property to notify the owner
							AnyPropertyType, // flag
							&type, // return type
							&format, // return format
							&len, &bytes_left, // data length
							&data);

					DEBUG_LOG_X11("PropertyNotify: len=%lu, format=%i\n", len, format);

					if (result == Success) {
						if (data && (len > 0)) {
							uint32_t prev_size = incr_data.size();
							// New chunk, resize to be safe and append data.
							incr_data.resize(MAX(data_size + len, prev_size));
							memcpy(incr_data.ptr() + data_size, data, len);
							data_size += len;
						} else if (!(format == 0 && len == 0)) {
							// For unclear reasons the first GetWindowProperty always returns a length and format of 0.
							// Otherwise, last chunk, process finished.
							done = true;
							success = true;
						}
					} else {
						print_verbose("Failed to get selection data chunk.");
						done = true;
					}

					if (data) {
						XFree(data);
						data = nullptr;
					}

					if (done) {
						break;
					}
				}
			}

			if (success && (data_size > 0)) {
				ret.instantiate();
				PNGDriverCommon::png_to_image(incr_data.ptr(), incr_data.size(), false, ret);
			}
		} else if (bytes_left > 0) {
			if (data) {
				XFree(data);