webui-dev / webui

Use any web browser or WebView as GUI, with your preferred language in the backend and modern web technologies in the frontend, all in a lightweight portable library.
https://webui.me
MIT License
2.9k stars 164 forks source link

`webui_set_icon` does not work? #181

Closed ttytm closed 1 year ago

ttytm commented 1 year ago

For a reproduction, we can update the minimal/main.c example on windows as it already has as win.ico icon in the compiler directories that can be used.

Setting the icon like this will not work:

#include "webui.h"

int main() {
    size_t my_window = webui_new_window();
    const char* my_html = "<!DOCTYPE html>"
    "<html>"
    "  <body>"
    "    Hello!"
    "  </body>"
    "</html>";
    webui_set_icon(my_window, "win.ico", "image/x-icon");
    webui_show(my_window, my_html);
    webui_wait();
    return 0;
}

#if defined(_MSC_VER)
    int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) {
        return main();
    }
#endif

While the equivalent when setting it in the html head does work:

#include "webui.h"

int main() {
    size_t my_window = webui_new_window();
    const char* my_html = "<!DOCTYPE html>"
    "<html>"
    "  <head>"
    "    <link href=\"win.ico\" rel=\"icon\" type=\"image/x-icon\">"
    "  </head>"
    "  <body>"
    "    Hello!"
    "  </body>"
    "</html>";
    webui_show(my_window, my_html);
    webui_wait();
    return 0;
}

#if defined(_MSC_VER)
    int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) {
        return main();
    }
#endif
hassandraga commented 1 year ago

Sorry, webui_set_icon() is for embedded HTML application. For example, embedding an SVG icon. But thank you for reporting this, I will update it to support local file as well. Also, this API need to be documented.

hassandraga commented 1 year ago

I just realized that there is a reason why I did this a long time ago... It's better if simply the end-user uses the HTML <link href="myFile.ico">, This makes the browser send one request.

While using webui_set_icon() makes the browser ask for a random favicon... most browsers ask for favicon.ico, Then WebUI need to send back a redirection request to the icon file set by webui_set_icon().

I prefer to keep webui_set_icon() for users who want to embed the HTML & icon in their one portable executable application. But we need to document this.

hassandraga commented 1 year ago

Also, I prefer to keep minimal example as it is. Minimal code as possible (I would like to remove APIENTRY WinMain but will break Win32 compilation).

ttytm commented 1 year ago

Also, I prefer to keep minimal example as it is. Minimal code as possible (I would like to remove APIENTRY WinMain but will break Win32 compilation).

Oh yes, I didn't meant to update the minimal example. I just mentioned it that it can be used for reproduction!

Can you share an example of what would work with the set_icon function? I don't fully get through yet.

malisipi commented 1 year ago

I guess this image url should work

data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='white' class='bi bi-twitter' viewBox='0 0 16 16'%3E%3Cpath d='M5.026 15c6.038 0 9.341-5.003 9.341-9.334 0-.14 0-.282-.006-.422A6.685 6.685 0 0 0 16 3.542a6.658 6.658 0 0 1-1.889.518 3.301 3.301 0 0 0 1.447-1.817 6.533 6.533 0 0 1-2.087.793A3.286 3.286 0 0 0 7.875 6.03a9.325 9.325 0 0 1-6.767-3.429 3.289 3.289 0 0 0 1.018 4.382A3.323 3.323 0 0 1 .64 6.575v.045a3.288 3.288 0 0 0 2.632 3.218 3.203 3.203 0 0 1-.865.115 3.23 3.23 0 0 1-.614-.057 3.283 3.283 0 0 0 3.067 2.277A6.588 6.588 0 0 1 .78 13.58a6.32 6.32 0 0 1-.78-.045A9.344 9.344 0 0 0 5.026 15z'/%3E%3C/svg%3E

hassandraga commented 1 year ago

Code not tested/compiled.

#include "webui.h"

// SVG Icon
const char* myIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\">  ... </svg>";
const char* myIconType = "image/svg+xml"

// PNG Icon
// const char* myIcon = "data:image/...";
// const char* myIconType = "image/png"

int main() {
    size_t my_window = webui_new_window();
    const char* my_html = "<html>...</html>";

    webui_set_icon(my_window, myIcon, myIconType);

    webui_show(my_window, my_html);
    webui_wait();
    return 0;
}
hassandraga commented 1 year ago

Perhaps we should rename the API from webui_set_icon() to webui_set_favicon()...

ttytm commented 1 year ago

Currently, the default icon that is used when webui_set_icon is not called is the webui logo.

I think there is a use case for a function that works like the one I tried to use: webui_set_icon(my_window, "win.ico", "image/x-icon"); to set the default icon for all windows of an application. Then a user would not need to specify it in the html for every window.

If a function like this is not implemented, a fully working example of how the current function works would do the trick to help to understand it. A rename is not required, I think.

Regarding the examples: Thanks to both of you for the code! I tried to get something working based on this. It didn't work unfortunately. But it did produce a change so it wasn't just the default symbol when an icon is missing, but it was a black box. E.g.

#include "webui.h"

// SVG Icon
const char* myIcon = "<svg role=\"img\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><title>.ENV</title><path d=\"M24 0v24H0V0h24ZM10.933 15.89H6.84v5.52h4.198v-.93H7.955v-1.503h2.77v-.93h-2.77v-1.224h2.978v-.934Zm2.146 0h-1.084v5.52h1.035v-3.6l2.226 3.6h1.118v-5.52h-1.036v3.686l-2.259-3.687Zm5.117 0h-1.208l1.973 5.52h1.19l1.976-5.52h-1.182l-1.352 4.085-1.397-4.086ZM5.4 19.68H3.72v1.68H5.4v-1.68Z\"/></svg>";
const char* myIconType = "image/svg+xml";

int main() {
    size_t my_window = webui_new_window();
    const char* my_html = "<!DOCTYPE html>"
    "<html>"
    "  <body>"
    "    Hello!"
    "  </body>"
    "</html>";
    webui_set_icon(my_window, myIcon, myIconType);
    webui_show(my_window, my_html);
    webui_wait();
    return 0;
}

#if defined(_MSC_VER)
    int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) {
        return main();
    }
#endif
malisipi commented 1 year ago

I think the svg icon should be formatted as data url.

If I need to give an example, this should be show white twitter icon (that taken from bootstrap icons) in favicon.

const char* myIcon = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='white' class='bi bi-twitter' viewBox='0 0 16 16'%3E%3Cpath d='M5.026 15c6.038 0 9.341-5.003 9.341-9.334 0-.14 0-.282-.006-.422A6.685 6.685 0 0 0 16 3.542a6.658 6.658 0 0 1-1.889.518 3.301 3.301 0 0 0 1.447-1.817 6.533 6.533 0 0 1-2.087.793A3.286 3.286 0 0 0 7.875 6.03a9.325 9.325 0 0 1-6.767-3.429 3.289 3.289 0 0 0 1.018 4.382A3.323 3.323 0 0 1 .64 6.575v.045a3.288 3.288 0 0 0 2.632 3.218 3.203 3.203 0 0 1-.865.115 3.23 3.23 0 0 1-.614-.057 3.283 3.283 0 0 0 3.067 2.277A6.588 6.588 0 0 1 .78 13.58a6.32 6.32 0 0 1-.78-.045A9.344 9.344 0 0 0 5.026 15z'/%3E%3C/svg%3E";

ttytm commented 1 year ago

I tried it based on the earlier response, and retrying it now with the code for the twitter icon, it still does not work. Maybe I'm doing something wrong. Does it work for you?

hassandraga commented 1 year ago

The lib is correctly providing the icon to the browser, but the icon is incorrect.

image

.

image

hassandraga commented 1 year ago

To test it, you can simply save it to an .svg file, and open it in a web browser.

image

ttytm commented 1 year ago

Thanks @hassandraga I can reproduce this. Then it runs correctly using the approach you provided before and with the code I sent. Ala:

const char* myIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\">  ... </svg>";

That I'm not seeing it in the window frame is probably due to the windows virtual machine I'm testing this on without proper graphics divers. But it's correctly set in the browser and extracting the Icon works.

A "data:image/svg+xml.. will not work as far as I can test.

hassandraga commented 1 year ago

Docs updated (C) https://github.com/webui-dev/website/commit/98d4d26ce0b84cc2562a17fca287115feea7ba72