Browse Source

X11TK: Implement high contrast, dark themes and fix up some more positioning code (#14055)

eafton 1 week ago
parent
commit
cd9919dc51
1 changed files with 103 additions and 18 deletions
  1. 103 18
      src/video/x11/SDL_x11toolkit.c

+ 103 - 18
src/video/x11/SDL_x11toolkit.c

@@ -25,6 +25,9 @@
 
 
 #include "../../SDL_list.h"
 #include "../../SDL_list.h"
 #include "SDL_x11video.h"
 #include "SDL_x11video.h"
+#ifdef SDL_USE_LIBDBUS
+#include "../../core/linux/SDL_system_theme.h"
+#endif
 #include "SDL_x11dyn.h"
 #include "SDL_x11dyn.h"
 #include "SDL_x11toolkit.h"
 #include "SDL_x11toolkit.h"
 #include "SDL_x11settings.h"
 #include "SDL_x11settings.h"
@@ -135,6 +138,35 @@ static const SDL_MessageBoxColor g_default_colors[SDL_MESSAGEBOX_COLOR_COUNT] =
     { 235, 235, 235 },  // SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED,
     { 235, 235, 235 },  // SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED,
 };
 };
 
 
+#ifdef SDL_USE_LIBDBUS
+static const SDL_MessageBoxColor g_default_colors_dark[SDL_MESSAGEBOX_COLOR_COUNT] = {
+    { 20, 20, 20 },    // SDL_MESSAGEBOX_COLOR_BACKGROUND,
+    { 192, 192, 192 }, // SDL_MESSAGEBOX_COLOR_TEXT,
+    { 12, 12, 12 }, // SDL_MESSAGEBOX_COLOR_BUTTON_BORDER,
+    { 20, 20, 20 },  // SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND,
+    { 36, 36, 36 },  // SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED,
+};
+
+#if 0
+static const SDL_MessageBoxColor g_default_colors_dark_high_contrast[SDL_MESSAGEBOX_COLOR_COUNT] = {
+    { 0, 0, 0 },    // SDL_MESSAGEBOX_COLOR_BACKGROUND,
+    { 255, 255, 255 }, // SDL_MESSAGEBOX_COLOR_TEXT,
+    { 20, 235, 255 }, // SDL_MESSAGEBOX_COLOR_BUTTON_BORDER,
+    { 0, 0, 0 },  // SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND,
+    { 125, 5, 125 },  // SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED,
+};
+
+static const SDL_MessageBoxColor g_default_colors_light_high_contrast[SDL_MESSAGEBOX_COLOR_COUNT] = {
+    { 255, 255, 255 },    // SDL_MESSAGEBOX_COLOR_BACKGROUND,
+    { 0, 0, 0 }, // SDL_MESSAGEBOX_COLOR_TEXT,
+    { 0, 0, 0 }, // SDL_MESSAGEBOX_COLOR_BUTTON_BORDER,
+    { 255, 255, 255 },  // SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND,
+    { 20, 230, 255 },  // SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED,
+};
+#endif
+
+#endif
+
 static int g_shm_error;
 static int g_shm_error;
 static int (*g_old_error_handler)(Display *, XErrorEvent *) = NULL;
 static int (*g_old_error_handler)(Display *, XErrorEvent *) = NULL;
 
 
@@ -545,6 +577,9 @@ SDL_ToolkitWindowX11 *X11Toolkit_CreateWindowStruct(SDL_Window *parent, SDL_Tool
 {
 {
     SDL_ToolkitWindowX11 *window;
     SDL_ToolkitWindowX11 *window;
     int i;
     int i;
+#ifdef SDL_USE_LIBDBUS
+    SDL_SystemTheme theme;
+#endif
     #define ErrorFreeRetNull(x, y) SDL_SetError(x); SDL_free(y); return NULL;
     #define ErrorFreeRetNull(x, y) SDL_SetError(x); SDL_free(y); return NULL;
     #define ErrorCloseFreeRetNull(x, y, z) X11_XCloseDisplay(z->display); SDL_SetError(x, y); SDL_free(z); return NULL;
     #define ErrorCloseFreeRetNull(x, y, z) X11_XCloseDisplay(z->display); SDL_SetError(x, y); SDL_free(z); return NULL;
 
 
@@ -637,8 +672,33 @@ SDL_ToolkitWindowX11 *X11Toolkit_CreateWindowStruct(SDL_Window *parent, SDL_Tool
     X11Toolkit_InitWindowFonts(window);
     X11Toolkit_InitWindowFonts(window);
     
     
     /* Color hints */
     /* Color hints */
+#ifdef SDL_USE_LIBDBUS
+    theme = SDL_SYSTEM_THEME_LIGHT; 
+    if (SDL_SystemTheme_Init()) {
+        theme = SDL_SystemTheme_Get(); 
+    }
+#endif
+
     if (!colorhints) {
     if (!colorhints) {
+#ifdef SDL_USE_LIBDBUS
+        switch (theme) {
+            case SDL_SYSTEM_THEME_DARK:
+                colorhints = g_default_colors_dark;
+                break;
+#if 0
+            case SDL_SYSTEM_THEME_LIGHT_HIGH_CONTRAST:
+                colorhints = g_default_colors_light_high_contrast;
+                break;
+            case SDL_SYSTEM_THEME_DARK_HIGH_CONTRAST:
+                colorhints = g_default_colors_dark_high_contrast;
+                break;
+#endif
+            default:
+                colorhints = g_default_colors;
+        }
+#else
         colorhints = g_default_colors;
         colorhints = g_default_colors;
+#endif
     }
     }
     window->color_hints = colorhints;
     window->color_hints = colorhints;
 
 
@@ -1421,19 +1481,19 @@ static void X11Toolkit_DrawIconControl(SDL_ToolkitControlX11 *control) {
 static void X11Toolkit_CalculateIconControl(SDL_ToolkitControlX11 *base_control) {
 static void X11Toolkit_CalculateIconControl(SDL_ToolkitControlX11 *base_control) {
     SDL_ToolkitIconControlX11 *control;
     SDL_ToolkitIconControlX11 *control;
     int icon_char_w;
     int icon_char_w;
-    int icon_char_max;
+    int icon_wh;
 
 
     control = (SDL_ToolkitIconControlX11 *)base_control;
     control = (SDL_ToolkitIconControlX11 *)base_control;
     X11Toolkit_GetTextWidthHeightForFont(control->icon_char_font, &control->icon_char, 1, &icon_char_w, &control->icon_char_h, &control->icon_char_a);
     X11Toolkit_GetTextWidthHeightForFont(control->icon_char_font, &control->icon_char, 1, &icon_char_w, &control->icon_char_h, &control->icon_char_a);
-    base_control->rect.w = icon_char_w + SDL_TOOLKIT_X11_ELEMENT_PADDING * 2 * base_control->window->iscale;
-    base_control->rect.h = control->icon_char_h + SDL_TOOLKIT_X11_ELEMENT_PADDING * 2 * base_control->window->iscale;
-    icon_char_max = SDL_max(base_control->rect.w, base_control->rect.h) + 2;
-    base_control->rect.w = icon_char_max;
-    base_control->rect.h = icon_char_max;
+    base_control->rect.w = icon_char_w;
+    base_control->rect.h = control->icon_char_h;
+    icon_wh = SDL_max(icon_char_w, control->icon_char_h) + SDL_TOOLKIT_X11_ELEMENT_PADDING * 2 * base_control->window->iscale;
+    base_control->rect.w = icon_wh;
+    base_control->rect.h = icon_wh;
     base_control->rect.y = 0;
     base_control->rect.y = 0;
     base_control->rect.x = 0;
     base_control->rect.x = 0;
     control->icon_char_y = control->icon_char_a + (base_control->rect.h - control->icon_char_h)/2;
     control->icon_char_y = control->icon_char_a + (base_control->rect.h - control->icon_char_h)/2;
-    control->icon_char_x = (base_control->rect.w - icon_char_w)/2 + 1;
+    control->icon_char_x = (base_control->rect.w - icon_char_w)/2;
     base_control->rect.w += 2 * base_control->window->iscale;
     base_control->rect.w += 2 * base_control->window->iscale;
     base_control->rect.h += 2 * base_control->window->iscale;
     base_control->rect.h += 2 * base_control->window->iscale;
 }
 }
@@ -1547,9 +1607,29 @@ SDL_ToolkitControlX11 *X11Toolkit_CreateIconControl(SDL_ToolkitWindowX11 *window
         return NULL;
         return NULL;
     }
     }
     control->xcolor_bg_shadow.flags = DoRed|DoGreen|DoBlue;
     control->xcolor_bg_shadow.flags = DoRed|DoGreen|DoBlue;
-    control->xcolor_bg_shadow.red = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].red - 12500, 0, 65535);
-    control->xcolor_bg_shadow.green = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].green - 12500, 0, 65535);
-    control->xcolor_bg_shadow.blue = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].blue - 12500, 0, 65535);
+    if (window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].red > 32896) {
+        control->xcolor_bg_shadow.red = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].red - 12500, 0, 65535);    
+    } else if (window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].red == 0) {
+        control->xcolor_bg_shadow.red = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].red + 9000, 0, 65535);
+    } else {
+        control->xcolor_bg_shadow.red = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].red - 3000, 0, 65535);
+    }  
+    
+    if (window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].green > 32896) {
+        control->xcolor_bg_shadow.green = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].green - 12500, 0, 65535);    
+    } else if (window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].green == 0) {
+        control->xcolor_bg_shadow.green = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].green + 9000, 0, 65535);
+    } else {
+        control->xcolor_bg_shadow.green = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].green - 3000, 0, 65535);
+    }  
+    
+    if (window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].blue > 32896) {
+        control->xcolor_bg_shadow.blue = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].blue - 12500, 0, 65535);    
+    } else if (window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].blue == 0) {
+        control->xcolor_bg_shadow.blue = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].blue + 9000, 0, 65535);
+    } else {
+        control->xcolor_bg_shadow.blue = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].blue - 3000, 0, 65535);
+    }  
     X11_XAllocColor(window->display, window->cmap, &control->xcolor_bg_shadow);
     X11_XAllocColor(window->display, window->cmap, &control->xcolor_bg_shadow);
 
 
     /* Sizing and positioning */
     /* Sizing and positioning */
@@ -1889,36 +1969,39 @@ static void X11Toolkit_DestroyLabelControl(SDL_ToolkitControlX11 *control) {
     SDL_free(label_control);
     SDL_free(label_control);
 }
 }
 
 
-
 static void X11Toolkit_CalculateLabelControl(SDL_ToolkitControlX11 *base_control) {
 static void X11Toolkit_CalculateLabelControl(SDL_ToolkitControlX11 *base_control) {
     SDL_ToolkitLabelControlX11 *control;
     SDL_ToolkitLabelControlX11 *control;
+     int last_h;
     int ascent;
     int ascent;
     int descent;
     int descent;
     int w;
     int w;
     int h;
     int h;
     int i;
     int i;
-
+    
+    last_h = 0;
     control = (SDL_ToolkitLabelControlX11 *)base_control;
     control = (SDL_ToolkitLabelControlX11 *)base_control;
     for (i = 0; i < control->sz; i++) {
     for (i = 0; i < control->sz; i++) {
         X11Toolkit_GetTextWidthHeight(base_control->window, control->lines[i], control->szs[i], &w, &h, &ascent, &descent);
         X11Toolkit_GetTextWidthHeight(base_control->window, control->lines[i], control->szs[i], &w, &h, &ascent, &descent);
 
 
         if (i > 0) {
         if (i > 0) {
             control->y[i] = ascent + descent + control->y[i-1];
             control->y[i] = ascent + descent + control->y[i-1];
-            base_control->rect.h += ascent + descent + h;
         } else {
         } else {
             control->y[i] = ascent;
             control->y[i] = ascent;
-            base_control->rect.h = h;
         }
         }
+        
+        last_h = h;
     }
     }
+    base_control->rect.h = control->y[control->sz -1] + last_h;
 }
 }
 
 
 SDL_ToolkitControlX11 *X11Toolkit_CreateLabelControl(SDL_ToolkitWindowX11 *window, char *utf8) {
 SDL_ToolkitControlX11 *X11Toolkit_CreateLabelControl(SDL_ToolkitWindowX11 *window, char *utf8) {
     SDL_ToolkitLabelControlX11 *control;
     SDL_ToolkitLabelControlX11 *control;
     SDL_ToolkitControlX11 *base_control;
     SDL_ToolkitControlX11 *base_control;
+     int last_h;
     int ascent;
     int ascent;
     int descent;
     int descent;
     int i;
     int i;
-
+    
     if (!utf8) {
     if (!utf8) {
         return NULL;
         return NULL;
     }
     }
@@ -1945,6 +2028,7 @@ SDL_ToolkitControlX11 *X11Toolkit_CreateLabelControl(SDL_ToolkitWindowX11 *windo
     control->lines = (char **)SDL_malloc(sizeof(char *) * control->sz);
     control->lines = (char **)SDL_malloc(sizeof(char *) * control->sz);
     control->y = (int *)SDL_calloc(control->sz, sizeof(int));
     control->y = (int *)SDL_calloc(control->sz, sizeof(int));
     control->szs = (size_t *)SDL_calloc(control->sz, sizeof(size_t));
     control->szs = (size_t *)SDL_calloc(control->sz, sizeof(size_t));
+    last_h = 0;
     for (i = 0; i < control->sz; i++) {
     for (i = 0; i < control->sz; i++) {
         const char *lf = SDL_strchr(utf8, '\n');
         const char *lf = SDL_strchr(utf8, '\n');
         const int length = lf ? (lf - utf8) : SDL_strlen(utf8);
         const int length = lf ? (lf - utf8) : SDL_strlen(utf8);
@@ -1962,19 +2046,20 @@ SDL_ToolkitControlX11 *X11Toolkit_CreateLabelControl(SDL_ToolkitWindowX11 *windo
 
 
         if (i > 0) {
         if (i > 0) {
             control->y[i] = ascent + descent + control->y[i-1];
             control->y[i] = ascent + descent + control->y[i-1];
-            base_control->rect.h += ascent + descent + h;
         } else {
         } else {
             control->y[i] = ascent;
             control->y[i] = ascent;
-            base_control->rect.h = h;
         }
         }
+        last_h = h;
         utf8 += length + 1;
         utf8 += length + 1;
 
 
         if (!lf) {
         if (!lf) {
             break;
             break;
         }
         }
-    }
+    }    
+    base_control->rect.h = control->y[control->sz -1] + last_h;
 
 
     X11Toolkit_AddControlToWindow(window, base_control);
     X11Toolkit_AddControlToWindow(window, base_control);
+    
     return base_control;
     return base_control;
 }
 }