glfw / glfw

A multi-platform library for OpenGL, OpenGL ES, Vulkan, window and input
https://www.glfw.org
zlib License
13.06k stars 5.26k forks source link

Theme support #2257

Open ws909 opened 1 year ago

ws909 commented 1 year ago

This is a feature request for adding basic theming support to GLFW.

Goals:

Similar issues and PRs:

This is a very rough idea of what this API might look like:

typedef struct GLFWtheme
{
    int baseTheme; // light/dark
    int hasColor;
    float color[4];
} GLFWtheme;

#define GLFW_THEME_LIGHT 0
#define GLFW_THEME_DARK 1

typedef void (* GLFWthemefun)(GLFWtheme* theme);

/*! @brief Notifies the application when the system default theme changes.
 *
 */
GLFWAPI void glfwSetSystemThemeCallback(GLFWthemefun callback);

/*! @brief Sets the theme for a window.
 *
 *  @param[in] window The window to set the theme for.
 *  @param[in] theme The theme to set. Pass `NULL` to set it to the system default.
 */
GLFWAPI void glfwSetTheme(GLFWwindow* window, GLFWtheme* theme);
GLFWAPI GLFWtheme* glfwGetTheme(GLFWwindow* window);
GLFWAPI GLFWtheme* glfwGetSystemDefaultTheme();

Windows supports custom colours for its window borders and title bars. The libdecor decorations for Wayland likely supports this too. MacOS does not support custom colours, but does support light/dark modes. MacOS does however have an accent colour, which is used for text, borders, etc, in the Cocoa UI. The accent colour is both gettable and settable.

The initial proposal for GLFW themes, only has dark and light modes. Some platforms support more than just these modes; Cocoa for instance, supports a total of 8 modes. These are a combination of light/dark, vibrant/non-vibrant, normal-contrast/high-contrast. It may be beneficial to support as many of these modes as possible.

The GLFW_THEME defines can denote bit flags instead of integer values; bits:

Other platforms may support other forms of named themes. More research is needed.

elmindreda commented 1 year ago

I agree with all of these goals. Thank you for making an issue collecting them! Heading to the PR for comments on the proposed API.

ws909 commented 1 year ago

@elmindreda I just noticed a branch of yours from 1.5 years ago, and it seems like you did some work on getting theming into GLFW. You only implemented dark/light mode querying on Cocoa. May I ask what the status of the other platforms is?

elmindreda commented 1 year ago

Oh, yup, I poked the problem a tiny bit but I have no code beyond what you found and I kept that mostly as a reminder. The combination of needing terrible hacks on every other platform and other features having higher priority made me put it aside.

ws909 commented 1 year ago

@elmindreda I have no experience with the other platforms, but I don’t want my PR to linger to death, so if too much time passes without anyone helping with the implementations for these platforms, I may get a VM and have a look at this myself, so if you have any knowledge of how this must be implemented on these platforms, that would be great. It would also help with designing the API. For instance, the current «vibrancy» attribute is very MacOS specific, and should probably be removed (doesn’t even seem to work in my PR’s implementation), but the more knowledge I have of the other platforms, the better. And if I do implement this myself, it would be great to have some basis to go off from. It doesn’t seem so far as if WL or X11 support theming, but I assume linking to dynamic libraries, and reading system properties, are fine. So if you could share what you figured out from your research back then, that would be great.

Any chance you could comment on the current state of the PR, btw? I left some comments. Monologues are great, but more opinions are better. :)

elmindreda commented 1 year ago

@ws909 Sorry, lost all usable time for a bit. I'll leave feedback as soon as I'm able.

ws909 commented 1 year ago

@elmindreda The absence of any work on this, has led me to realize that the API I designed isn't very good. It doesn't provide adequate means of checking if a window's theme properties are inherited from the system theme, if the system has these properties at all, or if they've been set by the user. So, in short, don't prioritize looking at my PR.