From 9800d2f78d5d21f5239b7b9ce306c8ec149dfe1c Mon Sep 17 00:00:00 2001 From: Daemo Date: Mon, 10 Aug 2026 15:31:09 +0200 Subject: [PATCH] Added mlx_set_window_icon --- example/main.c | 4 +++- includes/mlx.h | 19 ++++++++++++++----- runtime/Includes/Core/Application.inl | 2 +- runtime/Includes/Core/SDLManager.h | 2 ++ runtime/Includes/Platform/Window.h | 2 ++ runtime/Includes/Renderer/Image.h | 2 ++ runtime/Includes/Utils/Buffer.h | 2 ++ runtime/Sources/Core/Bridge.cpp | 14 +++++++++++++- runtime/Sources/Core/SDLManager.cpp | 26 +++++++++++++++++++++++++- runtime/Sources/Renderer/Image.cpp | 13 +++++++++++++ 10 files changed, 77 insertions(+), 9 deletions(-) diff --git a/example/main.c b/example/main.c index 80e13bd..f8c6b23 100644 --- a/example/main.c +++ b/example/main.c @@ -177,6 +177,8 @@ int main(void) mlx.logo_png = mlx_new_image_from_file(mlx.mlx, "42_logo.png", &dummy, &dummy); mlx.logo_jpg = mlx_new_image_from_file(mlx.mlx, "42_logo.jpg", &dummy, &dummy); + mlx_set_window_icon(mlx.mlx, mlx.win, mlx.logo_png); + mlx_pixel_put(mlx.mlx, mlx.win, 200, 10, (mlx_color){ .rgba = 0xFF00FFFF }); mlx_put_image_to_window(mlx.mlx, mlx.win, mlx.logo_png, 0, 0); @@ -193,7 +195,7 @@ int main(void) mlx_destroy_image(mlx.mlx, mlx.logo_bmp); mlx_destroy_image(mlx.mlx, mlx.img); mlx_destroy_window(mlx.mlx, mlx.win); - + mlx_destroy_context(mlx.mlx); return 0; diff --git a/includes/mlx.h b/includes/mlx.h index ce9d630..f95cb7a 100644 --- a/includes/mlx.h +++ b/includes/mlx.h @@ -148,7 +148,7 @@ MLX_API void mlx_set_window_position(mlx_context mlx, mlx_window win, int x, int * @brief Sets window size * * @param mlx Internal MLX application - * @param win Internal window to move + * @param win Internal window to resize * @param width New width * @param height New height */ @@ -158,16 +158,25 @@ MLX_API void mlx_set_window_size(mlx_context mlx, mlx_window win, int width, int * @brief Sets window title * * @param mlx Internal MLX application - * @param win Internal window to move + * @param win Internal window to modify * @param title New title */ MLX_API void mlx_set_window_title(mlx_context mlx, mlx_window win, const char* title); +/** + * @brief Sets window icon + * + * @param mlx Internal MLX application + * @param win Internal window to modify + * @param image New icon image + */ +MLX_API void mlx_set_window_icon(mlx_context mlx, mlx_window win, mlx_image image); + /** * @brief Enables/Disables window fullscreen mode * * @param mlx Internal MLX application - * @param win Internal window to move + * @param win Internal window to modify * @param enable Switch or not to fullscreen */ MLX_API void mlx_set_window_fullscreen(mlx_context mlx, mlx_window win, bool enable); @@ -176,7 +185,7 @@ MLX_API void mlx_set_window_fullscreen(mlx_context mlx, mlx_window win, bool ena * @brief Gets window position * * @param mlx Internal MLX application - * @param win Internal window to move + * @param win Internal window to get from * @param x Pointers to get position of the window * @param y Pointers to get position of the window */ @@ -186,7 +195,7 @@ MLX_API void mlx_get_window_position(mlx_context mlx, mlx_window win, int* x, in * @brief Gets window size * * @param mlx Internal MLX application - * @param win Internal window to move + * @param win Internal window to get from * @param x Pointers to get size of the window * @param y Pointers to get size of the window */ diff --git a/runtime/Includes/Core/Application.inl b/runtime/Includes/Core/Application.inl index edb70d7..8d6a307 100644 --- a/runtime/Includes/Core/Application.inl +++ b/runtime/Includes/Core/Application.inl @@ -70,7 +70,7 @@ namespace mlx } if (info->title == nullptr) { - mlx::Error("invalid window title (NULL)"); + Error("invalid window title (NULL)"); return nullptr; } diff --git a/runtime/Includes/Core/SDLManager.h b/runtime/Includes/Core/SDLManager.h index 415cc7e..71697f2 100644 --- a/runtime/Includes/Core/SDLManager.h +++ b/runtime/Includes/Core/SDLManager.h @@ -3,6 +3,7 @@ #include #include +#include namespace mlx { @@ -26,6 +27,7 @@ namespace mlx void SetWindowPosition(Handle window, int x, int y) const noexcept; void SetWindowSize(Handle window, int x, int y) const noexcept; void SetWindowTitle(Handle window, std::string_view title) const noexcept; + void SetWindowIcon(Handle window, NonOwningPtr texture) const noexcept; void SetWindowFullscreen(Handle window, bool enable) const noexcept; void SetWindowMaxSize(Handle window, int x, int y) const noexcept; void SetWindowMinSize(Handle window, int x, int y) const noexcept; diff --git a/runtime/Includes/Platform/Window.h b/runtime/Includes/Platform/Window.h index 5bb919a..5b9a752 100644 --- a/runtime/Includes/Platform/Window.h +++ b/runtime/Includes/Platform/Window.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace mlx { @@ -24,6 +25,7 @@ namespace mlx MLX_FORCEINLINE void SetPosition(int x, int y) { SDLManager::Get().SetWindowPosition(p_window, x, y); } MLX_FORCEINLINE void SetSize(int x, int y) { SDLManager::Get().SetWindowSize(p_window, x, y); m_width = x; m_height = y; } MLX_FORCEINLINE void SetTitle(std::string title) { SDLManager::Get().SetWindowTitle(p_window, title); m_name = std::move(title); } + MLX_FORCEINLINE void SetIcon(NonOwningPtr texture) {SDLManager::Get().SetWindowIcon(p_window, texture); } MLX_FORCEINLINE void SetFullscreen(bool enable) { SDLManager::Get().SetWindowFullscreen(p_window, enable); } MLX_FORCEINLINE void SetMaxSize(int x, int y) { SDLManager::Get().SetWindowMaxSize(p_window, x, y); } MLX_FORCEINLINE void SetMinSize(int x, int y) { SDLManager::Get().SetWindowMinSize(p_window, x, y); } diff --git a/runtime/Includes/Renderer/Image.h b/runtime/Includes/Renderer/Image.h index 5121f27..36a41bd 100644 --- a/runtime/Includes/Renderer/Image.h +++ b/runtime/Includes/Renderer/Image.h @@ -94,6 +94,8 @@ namespace mlx void Swap(Texture& texture) noexcept; + mlx_color* GetBufferCopy() noexcept; + // If a valid cmd buffer is passed, this function takes ownership and makes it invalid after void SyncCPUBuffer(VkCommandBuffer cmd = VK_NULL_HANDLE); void Update(VkCommandBuffer cmd); diff --git a/runtime/Includes/Utils/Buffer.h b/runtime/Includes/Utils/Buffer.h index fe95d25..6c3970e 100644 --- a/runtime/Includes/Utils/Buffer.h +++ b/runtime/Includes/Utils/Buffer.h @@ -1,6 +1,8 @@ #ifndef __MLX_CPU_BUFFER__ #define __MLX_CPU_BUFFER__ +#include + namespace mlx { class CPUBuffer diff --git a/runtime/Sources/Core/Bridge.cpp b/runtime/Sources/Core/Bridge.cpp index dc90707..fd61393 100644 --- a/runtime/Sources/Core/Bridge.cpp +++ b/runtime/Sources/Core/Bridge.cpp @@ -90,18 +90,30 @@ extern "C" void mlx_set_window_title(mlx_context mlx, mlx_window win, const char* title) { + MLX_CHECK_APPLICATION_POINTER(mlx); if (title == nullptr) { mlx::Error("invalid window title (NULL)"); return; } - MLX_CHECK_APPLICATION_POINTER(mlx); mlx::NonOwningPtr gs = mlx->app->GetGraphicsSupport(win); if(!gs && !gs->HasWindow()) return; gs->GetWindow()->SetTitle(title); } + void mlx_set_window_icon(mlx_context mlx, mlx_window win, mlx_image image) + { + MLX_CHECK_APPLICATION_POINTER(mlx); + mlx::NonOwningPtr gs = mlx->app->GetGraphicsSupport(win); + if(!gs && !gs->HasWindow()) + return; + mlx::NonOwningPtr texture = mlx->app->GetTexture(image); + if(!texture) + return; + gs->GetWindow()->SetIcon(texture); + } + void mlx_set_window_fullscreen(mlx_context mlx, mlx_window win, bool enable) { MLX_CHECK_APPLICATION_POINTER(mlx); diff --git a/runtime/Sources/Core/SDLManager.cpp b/runtime/Sources/Core/SDLManager.cpp index 08cb991..04244fc 100644 --- a/runtime/Sources/Core/SDLManager.cpp +++ b/runtime/Sources/Core/SDLManager.cpp @@ -1,3 +1,4 @@ +#include "Utils/Buffer.h" #include "mlx.h" #include #include @@ -57,7 +58,12 @@ namespace mlx infos->window = SDL_CreateWindow(info->title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, info->width, info->height, flags); if(!infos->window) FatalError("SDL: unable to open a new window; %", SDL_GetError()); - infos->icon = SDL_CreateRGBSurfaceFrom(static_cast(logo_mlx), logo_mlx_width, logo_mlx_height, 32, 4 * logo_mlx_width, Rmask(), Gmask(), Bmask(), Amask()); + + mlx_color* buffer = new mlx_color[logo_mlx_size]; + std::memcpy(buffer, logo_mlx, logo_mlx_size); + infos->icon = SDL_CreateRGBSurfaceFrom(buffer, logo_mlx_width, logo_mlx_height, 32, logo_mlx_width * 4, Rmask(), Gmask(), Bmask(), Amask()); + if(!infos->icon) + FatalError("SDL: unable to create a window icon; %", SDL_GetError()); SDL_SetWindowIcon(infos->window, infos->icon); m_windows_registry.insert(infos); @@ -75,7 +81,10 @@ namespace mlx if(infos->window != nullptr) SDL_DestroyWindow(infos->window); if(infos->icon != nullptr) + { + delete[] (mlx_color*)infos->icon->pixels; SDL_FreeSurface(infos->icon); + } m_windows_registry.erase(infos); delete infos; @@ -153,6 +162,21 @@ namespace mlx SDL_SetWindowTitle(static_cast(window)->window, title.data()); } + void SDLManager::SetWindowIcon(Handle window, NonOwningPtr texture) const noexcept + { + Internal::WindowInfos* infos = static_cast(window); + if(infos->icon != nullptr) + { + delete[] (mlx_color*)infos->icon->pixels; + SDL_FreeSurface(infos->icon); + } + + int width = texture->GetWidth(), height = texture->GetHeight(); + + infos->icon = SDL_CreateRGBSurfaceFrom(texture->GetBufferCopy(), width, height, 32, width * 4, Rmask(), Gmask(), Bmask(), Amask()); + SDL_SetWindowIcon(infos->window, infos->icon); + } + void SDLManager::SetWindowFullscreen(Handle window, bool enable) const noexcept { SDL_SetWindowFullscreen(static_cast(window)->window, (enable ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)); diff --git a/runtime/Sources/Renderer/Image.cpp b/runtime/Sources/Renderer/Image.cpp index f4766c8..4d77ae5 100644 --- a/runtime/Sources/Renderer/Image.cpp +++ b/runtime/Sources/Renderer/Image.cpp @@ -1,3 +1,5 @@ +#include "Utils/Buffer.h" +#include "mlx.h" #include #include #include @@ -349,6 +351,17 @@ namespace mlx m_has_been_modified = false; } + mlx_color* Texture::GetBufferCopy() noexcept + { + MLX_PROFILE_FUNCTION(); + if(!m_staging_buffer.has_value()) + OpenCPUBuffer(); + + mlx_color* dst = new mlx_color[m_width * m_height]; + std::memcpy(dst, m_staging_buffer->GetMap(), m_width * m_height * sizeof(mlx_color)); + return dst; + } + void Texture::OpenCPUBuffer() { MLX_PROFILE_FUNCTION();