Fixed bug 1919 - Window icon disappears as soon as a renderer is created
authorSam Lantinga <slouken@libsdl.org>
Sun, 14 Jul 2013 18:17:28 -0700
changeset 7523 9e9ab1dc3811
parent 7522 b186724247dd
child 7524 6d8fd70e1477
Fixed bug 1919 - Window icon disappears as soon as a renderer is created Sebastian Setting a window icon works just fine until a renderer is added to the window. After adding the renderer the icon disappears. Reproduce by: - Take the example code from the wiki: http://wiki.libsdl.org/moin.fcg/SDL_SetWindowIcon - Add the following two lines after SDL_FreeSurface(surface); SDL_Delay(1000); SDL_Renderer* ren = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); -compile and run You will see the window icon correctly at first. After the Delay the Icon will disappear.
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/windows/SDL_windowswindow.c
src/video/x11/SDL_x11window.c
--- a/src/video/SDL_sysvideo.h	Sat Jul 27 00:49:34 2013 -0700
+++ b/src/video/SDL_sysvideo.h	Sun Jul 14 18:17:28 2013 -0700
@@ -73,6 +73,7 @@
     const void *magic;
     Uint32 id;
     char *title;
+    SDL_Surface *icon;
     int x, y;
     int w, h;
     int min_w, min_h;
--- a/src/video/SDL_video.c	Sat Jul 27 00:49:34 2013 -0700
+++ b/src/video/SDL_video.c	Sun Jul 14 18:17:28 2013 -0700
@@ -1297,6 +1297,7 @@
 SDL_RecreateWindow(SDL_Window * window, Uint32 flags)
 {
     char *title = window->title;
+    SDL_Surface *icon = window->icon;
 
     if ((flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) {
         return SDL_SetError("No OpenGL support in video driver");
@@ -1335,6 +1336,7 @@
     }
 
     window->title = NULL;
+    window->icon = NULL;
     window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN);
 
     if (_this->CreateWindow && !(flags & SDL_WINDOW_FOREIGN)) {
@@ -1350,6 +1352,10 @@
         SDL_SetWindowTitle(window, title);
         SDL_free(title);
     }
+    if (icon) {
+        SDL_SetWindowIcon(window, icon);
+        SDL_FreeSurface(icon);
+    }
     SDL_FinishWindowCreation(window, flags);
 
     return 0;
@@ -1426,8 +1432,18 @@
         return;
     }
 
+    if (window->icon) {
+        SDL_FreeSurface(window->icon);
+    }
+
+    /* Convert the icon into ARGB8888 */
+    window->icon = SDL_ConvertSurfaceFormat(icon, SDL_PIXELFORMAT_ARGB8888, 0);
+    if (!window->icon) {
+        return;
+    }
+
     if (_this->SetWindowIcon) {
-        _this->SetWindowIcon(_this, window, icon);
+        _this->SetWindowIcon(_this, window, window->icon);
     }
 }
 
@@ -2167,6 +2183,9 @@
     if (window->title) {
         SDL_free(window->title);
     }
+    if (window->icon) {
+        SDL_FreeSurface(window->icon);
+    }
     if (window->gamma) {
         SDL_free(window->gamma);
     }
--- a/src/video/windows/SDL_windowswindow.c	Sat Jul 27 00:49:34 2013 -0700
+++ b/src/video/windows/SDL_windowswindow.c	Sun Jul 14 18:17:28 2013 -0700
@@ -22,6 +22,7 @@
 
 #if SDL_VIDEO_DRIVER_WINDOWS
 
+#include "SDL_assert.h"
 #include "../SDL_sysvideo.h"
 #include "../SDL_pixels_c.h"
 #include "../../events/SDL_keyboard_c.h"
@@ -292,7 +293,6 @@
     BYTE *icon_bmp;
     int icon_len;
     SDL_RWops *dst;
-    SDL_Surface *surface;
 
     /* Create temporary bitmap buffer */
     icon_len = 40 + icon->h * icon->w * 4;
@@ -316,19 +316,16 @@
     SDL_WriteLE32(dst, 0);
     SDL_WriteLE32(dst, 0);
 
-    /* Convert the icon to a 32-bit surface with alpha channel */
-    surface = SDL_ConvertSurfaceFormat(icon, SDL_PIXELFORMAT_ARGB8888, 0);
-    if (surface) {
-        /* Write the pixels upside down into the bitmap buffer */
-        int y = surface->h;
-        while (y--) {
-            Uint8 *src = (Uint8 *) surface->pixels + y * surface->pitch;
-            SDL_RWwrite(dst, src, surface->pitch, 1);
-        }
-        SDL_FreeSurface(surface);
+    /* Write the pixels upside down into the bitmap buffer */
+    SDL_assert(icon->format->format == SDL_PIXELFORMAT_ARGB8888);
+    int y = icon->h;
+    while (y--) {
+        Uint8 *src = (Uint8 *) icon->pixels + y * icon->pitch;
+        SDL_RWwrite(dst, src, icon->pitch, 1);
+    }
 
-        hicon = CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000);
-    }
+    hicon = CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000);
+
     SDL_RWclose(dst);
     SDL_stack_free(icon_bmp);
 
--- a/src/video/x11/SDL_x11window.c	Sat Jul 27 00:49:34 2013 -0700
+++ b/src/video/x11/SDL_x11window.c	Sun Jul 14 18:17:28 2013 -0700
@@ -22,6 +22,7 @@
 
 #if SDL_VIDEO_DRIVER_X11
 
+#include "SDL_assert.h"
 #include "SDL_hints.h"
 #include "../SDL_sysvideo.h"
 #include "../SDL_pixels_c.h"
@@ -698,19 +699,11 @@
     Atom _NET_WM_ICON = data->videodata->_NET_WM_ICON;
 
     if (icon) {
-        SDL_PixelFormat format;
-        SDL_Surface *surface;
         int propsize;
         long *propdata;
 
-        /* Convert the icon to ARGB for modern window managers */
-        SDL_InitFormat(&format, SDL_PIXELFORMAT_ARGB8888);
-        surface = SDL_ConvertSurface(icon, &format, 0);
-        if (!surface) {
-            return;
-        }
-
         /* Set the _NET_WM_ICON property */
+        SDL_assert(icon->format->format == SDL_PIXELFORMAT_ARGB8888);
         propsize = 2 + (icon->w * icon->h);
         propdata = SDL_malloc(propsize * sizeof(long));
         if (propdata) {
@@ -722,7 +715,7 @@
             propdata[1] = icon->h;
             dst = &propdata[2];
             for (y = 0; y < icon->h; ++y) {
-                src = (Uint32*)((Uint8*)surface->pixels + y * surface->pitch);
+                src = (Uint32*)((Uint8*)icon->pixels + y * icon->pitch);
                 for (x = 0; x < icon->w; ++x) {
                     *dst++ = *src++;
                 }
@@ -732,7 +725,6 @@
                             propsize);
         }
         SDL_free(propdata);
-        SDL_FreeSurface(surface);
     } else {
         XDeleteProperty(display, data->xwindow, _NET_WM_ICON);
     }