You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-08 12:40:44 +00:00
Merge pull request #78437 from bruvzg/set_icon
Add error checks and harmonize behavior of the `set_icon` method.
This commit is contained in:
@@ -4880,6 +4880,8 @@ void DisplayServerX11::set_icon(const Ref<Image> &p_icon) {
|
|||||||
Atom net_wm_icon = XInternAtom(x11_display, "_NET_WM_ICON", False);
|
Atom net_wm_icon = XInternAtom(x11_display, "_NET_WM_ICON", False);
|
||||||
|
|
||||||
if (p_icon.is_valid()) {
|
if (p_icon.is_valid()) {
|
||||||
|
ERR_FAIL_COND(p_icon->get_width() <= 0 || p_icon->get_height() <= 0);
|
||||||
|
|
||||||
Ref<Image> img = p_icon->duplicate();
|
Ref<Image> img = p_icon->duplicate();
|
||||||
img->convert(Image::FORMAT_RGBA8);
|
img->convert(Image::FORMAT_RGBA8);
|
||||||
|
|
||||||
|
|||||||
@@ -3609,9 +3609,12 @@ void DisplayServerMacOS::set_native_icon(const String &p_filename) {
|
|||||||
void DisplayServerMacOS::set_icon(const Ref<Image> &p_icon) {
|
void DisplayServerMacOS::set_icon(const Ref<Image> &p_icon) {
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
Ref<Image> img = p_icon;
|
if (p_icon.is_valid()) {
|
||||||
img = img->duplicate();
|
ERR_FAIL_COND(p_icon->get_width() <= 0 || p_icon->get_height() <= 0);
|
||||||
|
|
||||||
|
Ref<Image> img = p_icon->duplicate();
|
||||||
img->convert(Image::FORMAT_RGBA8);
|
img->convert(Image::FORMAT_RGBA8);
|
||||||
|
|
||||||
NSBitmapImageRep *imgrep = [[NSBitmapImageRep alloc]
|
NSBitmapImageRep *imgrep = [[NSBitmapImageRep alloc]
|
||||||
initWithBitmapDataPlanes:nullptr
|
initWithBitmapDataPlanes:nullptr
|
||||||
pixelsWide:img->get_width()
|
pixelsWide:img->get_width()
|
||||||
@@ -3643,6 +3646,9 @@ void DisplayServerMacOS::set_icon(const Ref<Image> &p_icon) {
|
|||||||
|
|
||||||
[nsimg addRepresentation:imgrep];
|
[nsimg addRepresentation:imgrep];
|
||||||
[NSApp setApplicationIconImage:nsimg];
|
[NSApp setApplicationIconImage:nsimg];
|
||||||
|
} else {
|
||||||
|
[NSApp setApplicationIconImage:nil];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayServer *DisplayServerMacOS::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
|
DisplayServer *DisplayServerMacOS::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
|
||||||
|
|||||||
@@ -731,7 +731,9 @@ void DisplayServerWeb::send_window_event_callback(int p_notification) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DisplayServerWeb::set_icon(const Ref<Image> &p_icon) {
|
void DisplayServerWeb::set_icon(const Ref<Image> &p_icon) {
|
||||||
ERR_FAIL_COND(p_icon.is_null());
|
if (p_icon.is_valid()) {
|
||||||
|
ERR_FAIL_COND(p_icon->get_width() <= 0 || p_icon->get_height() <= 0);
|
||||||
|
|
||||||
Ref<Image> icon = p_icon;
|
Ref<Image> icon = p_icon;
|
||||||
if (icon->is_compressed()) {
|
if (icon->is_compressed()) {
|
||||||
icon = icon->duplicate();
|
icon = icon->duplicate();
|
||||||
@@ -760,6 +762,9 @@ void DisplayServerWeb::set_icon(const Ref<Image> &p_icon) {
|
|||||||
ERR_FAIL_COND(!png_image_write_to_memory(&png_meta, png.ptrw(), &len, 0, data.ptr(), 0, nullptr));
|
ERR_FAIL_COND(!png_image_write_to_memory(&png_meta, png.ptrw(), &len, 0, data.ptr(), 0, nullptr));
|
||||||
|
|
||||||
godot_js_display_window_icon_set(png.ptr(), len);
|
godot_js_display_window_icon_set(png.ptr(), len);
|
||||||
|
} else {
|
||||||
|
godot_js_display_window_icon_set(nullptr, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayServerWeb::_dispatch_input_event(const Ref<InputEvent> &p_event) {
|
void DisplayServerWeb::_dispatch_input_event(const Ref<InputEvent> &p_event) {
|
||||||
|
|||||||
@@ -568,16 +568,23 @@ const GodotDisplay = {
|
|||||||
godot_js_display_window_icon_set__sig: 'vii',
|
godot_js_display_window_icon_set__sig: 'vii',
|
||||||
godot_js_display_window_icon_set: function (p_ptr, p_len) {
|
godot_js_display_window_icon_set: function (p_ptr, p_len) {
|
||||||
let link = document.getElementById('-gd-engine-icon');
|
let link = document.getElementById('-gd-engine-icon');
|
||||||
|
const old_icon = GodotDisplay.window_icon;
|
||||||
|
if (p_ptr) {
|
||||||
if (link === null) {
|
if (link === null) {
|
||||||
link = document.createElement('link');
|
link = document.createElement('link');
|
||||||
link.rel = 'icon';
|
link.rel = 'icon';
|
||||||
link.id = '-gd-engine-icon';
|
link.id = '-gd-engine-icon';
|
||||||
document.head.appendChild(link);
|
document.head.appendChild(link);
|
||||||
}
|
}
|
||||||
const old_icon = GodotDisplay.window_icon;
|
|
||||||
const png = new Blob([GodotRuntime.heapSlice(HEAPU8, p_ptr, p_len)], { type: 'image/png' });
|
const png = new Blob([GodotRuntime.heapSlice(HEAPU8, p_ptr, p_len)], { type: 'image/png' });
|
||||||
GodotDisplay.window_icon = URL.createObjectURL(png);
|
GodotDisplay.window_icon = URL.createObjectURL(png);
|
||||||
link.href = GodotDisplay.window_icon;
|
link.href = GodotDisplay.window_icon;
|
||||||
|
} else {
|
||||||
|
if (link) {
|
||||||
|
link.remove();
|
||||||
|
}
|
||||||
|
GodotDisplay.window_icon = null;
|
||||||
|
}
|
||||||
if (old_icon) {
|
if (old_icon) {
|
||||||
URL.revokeObjectURL(old_icon);
|
URL.revokeObjectURL(old_icon);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2194,15 +2194,17 @@ void DisplayServerWindows::set_native_icon(const String &p_filename) {
|
|||||||
void DisplayServerWindows::set_icon(const Ref<Image> &p_icon) {
|
void DisplayServerWindows::set_icon(const Ref<Image> &p_icon) {
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
ERR_FAIL_COND(!p_icon.is_valid());
|
if (p_icon.is_valid()) {
|
||||||
if (icon != p_icon) {
|
ERR_FAIL_COND(p_icon->get_width() <= 0 || p_icon->get_height() <= 0);
|
||||||
icon = p_icon->duplicate();
|
|
||||||
if (icon->get_format() != Image::FORMAT_RGBA8) {
|
Ref<Image> img = p_icon;
|
||||||
icon->convert(Image::FORMAT_RGBA8);
|
if (img != icon) {
|
||||||
|
img = img->duplicate();
|
||||||
|
img->convert(Image::FORMAT_RGBA8);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
int w = icon->get_width();
|
int w = img->get_width();
|
||||||
int h = icon->get_height();
|
int h = img->get_height();
|
||||||
|
|
||||||
// Create temporary bitmap buffer.
|
// Create temporary bitmap buffer.
|
||||||
int icon_len = 40 + h * w * 4;
|
int icon_len = 40 + h * w * 4;
|
||||||
@@ -2223,7 +2225,7 @@ void DisplayServerWindows::set_icon(const Ref<Image> &p_icon) {
|
|||||||
encode_uint32(0, &icon_bmp[36]);
|
encode_uint32(0, &icon_bmp[36]);
|
||||||
|
|
||||||
uint8_t *wr = &icon_bmp[40];
|
uint8_t *wr = &icon_bmp[40];
|
||||||
const uint8_t *r = icon->get_data().ptr();
|
const uint8_t *r = img->get_data().ptr();
|
||||||
|
|
||||||
for (int i = 0; i < h; i++) {
|
for (int i = 0; i < h; i++) {
|
||||||
for (int j = 0; j < w; j++) {
|
for (int j = 0; j < w; j++) {
|
||||||
@@ -2237,12 +2239,20 @@ void DisplayServerWindows::set_icon(const Ref<Image> &p_icon) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HICON hicon = CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000);
|
HICON hicon = CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000);
|
||||||
|
ERR_FAIL_COND(!hicon);
|
||||||
|
|
||||||
|
icon = img;
|
||||||
|
|
||||||
// Set the icon for the window.
|
// Set the icon for the window.
|
||||||
SendMessage(windows[MAIN_WINDOW_ID].hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hicon);
|
SendMessage(windows[MAIN_WINDOW_ID].hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hicon);
|
||||||
|
|
||||||
// Set the icon in the task manager (should we do this?).
|
// Set the icon in the task manager (should we do this?).
|
||||||
SendMessage(windows[MAIN_WINDOW_ID].hWnd, WM_SETICON, ICON_BIG, (LPARAM)hicon);
|
SendMessage(windows[MAIN_WINDOW_ID].hWnd, WM_SETICON, ICON_BIG, (LPARAM)hicon);
|
||||||
|
} else {
|
||||||
|
icon = Ref<Image>();
|
||||||
|
SendMessage(windows[MAIN_WINDOW_ID].hWnd, WM_SETICON, ICON_SMALL, NULL);
|
||||||
|
SendMessage(windows[MAIN_WINDOW_ID].hWnd, WM_SETICON, ICON_BIG, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayServerWindows::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
|
void DisplayServerWindows::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
|
||||||
|
|||||||
Reference in New Issue
Block a user