Skip to content

Commit cd9919d

Browse files
authored
X11TK: Implement high contrast, dark themes and fix up some more positioning code (#14055)
1 parent 1d2a482 commit cd9919d

File tree

1 file changed

+103
-18
lines changed

1 file changed

+103
-18
lines changed

src/video/x11/SDL_x11toolkit.c

Lines changed: 103 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525

2626
#include "../../SDL_list.h"
2727
#include "SDL_x11video.h"
28+
#ifdef SDL_USE_LIBDBUS
29+
#include "../../core/linux/SDL_system_theme.h"
30+
#endif
2831
#include "SDL_x11dyn.h"
2932
#include "SDL_x11toolkit.h"
3033
#include "SDL_x11settings.h"
@@ -135,6 +138,35 @@ static const SDL_MessageBoxColor g_default_colors[SDL_MESSAGEBOX_COLOR_COUNT] =
135138
{ 235, 235, 235 }, // SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED,
136139
};
137140

141+
#ifdef SDL_USE_LIBDBUS
142+
static const SDL_MessageBoxColor g_default_colors_dark[SDL_MESSAGEBOX_COLOR_COUNT] = {
143+
{ 20, 20, 20 }, // SDL_MESSAGEBOX_COLOR_BACKGROUND,
144+
{ 192, 192, 192 }, // SDL_MESSAGEBOX_COLOR_TEXT,
145+
{ 12, 12, 12 }, // SDL_MESSAGEBOX_COLOR_BUTTON_BORDER,
146+
{ 20, 20, 20 }, // SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND,
147+
{ 36, 36, 36 }, // SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED,
148+
};
149+
150+
#if 0
151+
static const SDL_MessageBoxColor g_default_colors_dark_high_contrast[SDL_MESSAGEBOX_COLOR_COUNT] = {
152+
{ 0, 0, 0 }, // SDL_MESSAGEBOX_COLOR_BACKGROUND,
153+
{ 255, 255, 255 }, // SDL_MESSAGEBOX_COLOR_TEXT,
154+
{ 20, 235, 255 }, // SDL_MESSAGEBOX_COLOR_BUTTON_BORDER,
155+
{ 0, 0, 0 }, // SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND,
156+
{ 125, 5, 125 }, // SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED,
157+
};
158+
159+
static const SDL_MessageBoxColor g_default_colors_light_high_contrast[SDL_MESSAGEBOX_COLOR_COUNT] = {
160+
{ 255, 255, 255 }, // SDL_MESSAGEBOX_COLOR_BACKGROUND,
161+
{ 0, 0, 0 }, // SDL_MESSAGEBOX_COLOR_TEXT,
162+
{ 0, 0, 0 }, // SDL_MESSAGEBOX_COLOR_BUTTON_BORDER,
163+
{ 255, 255, 255 }, // SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND,
164+
{ 20, 230, 255 }, // SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED,
165+
};
166+
#endif
167+
168+
#endif
169+
138170
static int g_shm_error;
139171
static int (*g_old_error_handler)(Display *, XErrorEvent *) = NULL;
140172

@@ -545,6 +577,9 @@ SDL_ToolkitWindowX11 *X11Toolkit_CreateWindowStruct(SDL_Window *parent, SDL_Tool
545577
{
546578
SDL_ToolkitWindowX11 *window;
547579
int i;
580+
#ifdef SDL_USE_LIBDBUS
581+
SDL_SystemTheme theme;
582+
#endif
548583
#define ErrorFreeRetNull(x, y) SDL_SetError(x); SDL_free(y); return NULL;
549584
#define ErrorCloseFreeRetNull(x, y, z) X11_XCloseDisplay(z->display); SDL_SetError(x, y); SDL_free(z); return NULL;
550585

@@ -637,8 +672,33 @@ SDL_ToolkitWindowX11 *X11Toolkit_CreateWindowStruct(SDL_Window *parent, SDL_Tool
637672
X11Toolkit_InitWindowFonts(window);
638673

639674
/* Color hints */
675+
#ifdef SDL_USE_LIBDBUS
676+
theme = SDL_SYSTEM_THEME_LIGHT;
677+
if (SDL_SystemTheme_Init()) {
678+
theme = SDL_SystemTheme_Get();
679+
}
680+
#endif
681+
640682
if (!colorhints) {
683+
#ifdef SDL_USE_LIBDBUS
684+
switch (theme) {
685+
case SDL_SYSTEM_THEME_DARK:
686+
colorhints = g_default_colors_dark;
687+
break;
688+
#if 0
689+
case SDL_SYSTEM_THEME_LIGHT_HIGH_CONTRAST:
690+
colorhints = g_default_colors_light_high_contrast;
691+
break;
692+
case SDL_SYSTEM_THEME_DARK_HIGH_CONTRAST:
693+
colorhints = g_default_colors_dark_high_contrast;
694+
break;
695+
#endif
696+
default:
697+
colorhints = g_default_colors;
698+
}
699+
#else
641700
colorhints = g_default_colors;
701+
#endif
642702
}
643703
window->color_hints = colorhints;
644704

@@ -1421,19 +1481,19 @@ static void X11Toolkit_DrawIconControl(SDL_ToolkitControlX11 *control) {
14211481
static void X11Toolkit_CalculateIconControl(SDL_ToolkitControlX11 *base_control) {
14221482
SDL_ToolkitIconControlX11 *control;
14231483
int icon_char_w;
1424-
int icon_char_max;
1484+
int icon_wh;
14251485

14261486
control = (SDL_ToolkitIconControlX11 *)base_control;
14271487
X11Toolkit_GetTextWidthHeightForFont(control->icon_char_font, &control->icon_char, 1, &icon_char_w, &control->icon_char_h, &control->icon_char_a);
1428-
base_control->rect.w = icon_char_w + SDL_TOOLKIT_X11_ELEMENT_PADDING * 2 * base_control->window->iscale;
1429-
base_control->rect.h = control->icon_char_h + SDL_TOOLKIT_X11_ELEMENT_PADDING * 2 * base_control->window->iscale;
1430-
icon_char_max = SDL_max(base_control->rect.w, base_control->rect.h) + 2;
1431-
base_control->rect.w = icon_char_max;
1432-
base_control->rect.h = icon_char_max;
1488+
base_control->rect.w = icon_char_w;
1489+
base_control->rect.h = control->icon_char_h;
1490+
icon_wh = SDL_max(icon_char_w, control->icon_char_h) + SDL_TOOLKIT_X11_ELEMENT_PADDING * 2 * base_control->window->iscale;
1491+
base_control->rect.w = icon_wh;
1492+
base_control->rect.h = icon_wh;
14331493
base_control->rect.y = 0;
14341494
base_control->rect.x = 0;
14351495
control->icon_char_y = control->icon_char_a + (base_control->rect.h - control->icon_char_h)/2;
1436-
control->icon_char_x = (base_control->rect.w - icon_char_w)/2 + 1;
1496+
control->icon_char_x = (base_control->rect.w - icon_char_w)/2;
14371497
base_control->rect.w += 2 * base_control->window->iscale;
14381498
base_control->rect.h += 2 * base_control->window->iscale;
14391499
}
@@ -1547,9 +1607,29 @@ SDL_ToolkitControlX11 *X11Toolkit_CreateIconControl(SDL_ToolkitWindowX11 *window
15471607
return NULL;
15481608
}
15491609
control->xcolor_bg_shadow.flags = DoRed|DoGreen|DoBlue;
1550-
control->xcolor_bg_shadow.red = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].red - 12500, 0, 65535);
1551-
control->xcolor_bg_shadow.green = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].green - 12500, 0, 65535);
1552-
control->xcolor_bg_shadow.blue = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].blue - 12500, 0, 65535);
1610+
if (window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].red > 32896) {
1611+
control->xcolor_bg_shadow.red = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].red - 12500, 0, 65535);
1612+
} else if (window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].red == 0) {
1613+
control->xcolor_bg_shadow.red = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].red + 9000, 0, 65535);
1614+
} else {
1615+
control->xcolor_bg_shadow.red = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].red - 3000, 0, 65535);
1616+
}
1617+
1618+
if (window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].green > 32896) {
1619+
control->xcolor_bg_shadow.green = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].green - 12500, 0, 65535);
1620+
} else if (window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].green == 0) {
1621+
control->xcolor_bg_shadow.green = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].green + 9000, 0, 65535);
1622+
} else {
1623+
control->xcolor_bg_shadow.green = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].green - 3000, 0, 65535);
1624+
}
1625+
1626+
if (window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].blue > 32896) {
1627+
control->xcolor_bg_shadow.blue = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].blue - 12500, 0, 65535);
1628+
} else if (window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].blue == 0) {
1629+
control->xcolor_bg_shadow.blue = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].blue + 9000, 0, 65535);
1630+
} else {
1631+
control->xcolor_bg_shadow.blue = SDL_clamp(window->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].blue - 3000, 0, 65535);
1632+
}
15531633
X11_XAllocColor(window->display, window->cmap, &control->xcolor_bg_shadow);
15541634

15551635
/* Sizing and positioning */
@@ -1889,36 +1969,39 @@ static void X11Toolkit_DestroyLabelControl(SDL_ToolkitControlX11 *control) {
18891969
SDL_free(label_control);
18901970
}
18911971

1892-
18931972
static void X11Toolkit_CalculateLabelControl(SDL_ToolkitControlX11 *base_control) {
18941973
SDL_ToolkitLabelControlX11 *control;
1974+
int last_h;
18951975
int ascent;
18961976
int descent;
18971977
int w;
18981978
int h;
18991979
int i;
1900-
1980+
1981+
last_h = 0;
19011982
control = (SDL_ToolkitLabelControlX11 *)base_control;
19021983
for (i = 0; i < control->sz; i++) {
19031984
X11Toolkit_GetTextWidthHeight(base_control->window, control->lines[i], control->szs[i], &w, &h, &ascent, &descent);
19041985

19051986
if (i > 0) {
19061987
control->y[i] = ascent + descent + control->y[i-1];
1907-
base_control->rect.h += ascent + descent + h;
19081988
} else {
19091989
control->y[i] = ascent;
1910-
base_control->rect.h = h;
19111990
}
1991+
1992+
last_h = h;
19121993
}
1994+
base_control->rect.h = control->y[control->sz -1] + last_h;
19131995
}
19141996

19151997
SDL_ToolkitControlX11 *X11Toolkit_CreateLabelControl(SDL_ToolkitWindowX11 *window, char *utf8) {
19161998
SDL_ToolkitLabelControlX11 *control;
19171999
SDL_ToolkitControlX11 *base_control;
2000+
int last_h;
19182001
int ascent;
19192002
int descent;
19202003
int i;
1921-
2004+
19222005
if (!utf8) {
19232006
return NULL;
19242007
}
@@ -1945,6 +2028,7 @@ SDL_ToolkitControlX11 *X11Toolkit_CreateLabelControl(SDL_ToolkitWindowX11 *windo
19452028
control->lines = (char **)SDL_malloc(sizeof(char *) * control->sz);
19462029
control->y = (int *)SDL_calloc(control->sz, sizeof(int));
19472030
control->szs = (size_t *)SDL_calloc(control->sz, sizeof(size_t));
2031+
last_h = 0;
19482032
for (i = 0; i < control->sz; i++) {
19492033
const char *lf = SDL_strchr(utf8, '\n');
19502034
const int length = lf ? (lf - utf8) : SDL_strlen(utf8);
@@ -1962,19 +2046,20 @@ SDL_ToolkitControlX11 *X11Toolkit_CreateLabelControl(SDL_ToolkitWindowX11 *windo
19622046

19632047
if (i > 0) {
19642048
control->y[i] = ascent + descent + control->y[i-1];
1965-
base_control->rect.h += ascent + descent + h;
19662049
} else {
19672050
control->y[i] = ascent;
1968-
base_control->rect.h = h;
19692051
}
2052+
last_h = h;
19702053
utf8 += length + 1;
19712054

19722055
if (!lf) {
19732056
break;
19742057
}
1975-
}
2058+
}
2059+
base_control->rect.h = control->y[control->sz -1] + last_h;
19762060

19772061
X11Toolkit_AddControlToWindow(window, base_control);
2062+
19782063
return base_control;
19792064
}
19802065

0 commit comments

Comments
 (0)