aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAhmed Khanzada2025-10-25 22:34:11 -0700
committerEli Zaretskii2025-11-02 08:01:41 +0200
commitdd9d1df4fa6c96acecaae94461d962da1d822494 (patch)
tree6c7845a7ca1bb36bd424fe858a4fc26e8fa18668 /src
parent0c6aee302154a0ee0a5f9db0675903dfa9516c9c (diff)
downloademacs-dd9d1df4fa6c96acecaae94461d962da1d822494.tar.gz
emacs-dd9d1df4fa6c96acecaae94461d962da1d822494.zip
Automatically toggle between dark and light mode PGTK widgets
* src/gtkutil.h: Declare 'xg_set_gtk_theme_dark_mode', 'xg_update_dark_mode_for_all_displays', 'xg_set_initial_dark_mode'. * src/gtkutil.c (xg_set_gtk_theme_dark_mode): Toggle PGTK dark mode. (xg_update_dark_mode_for_all_displays): Toggle PGTK dark mode for all displays. (xg_set_initial_dark_mode): Determine PGTK dark mode preference and set. (xg_create_frame_widgets): Set PGTK dark mode preference for widgets. (xg_create_frame_outer_widgets): Set PGTK dark mode preference for outer widgets. * src/xsettings.h: Declare 'xg_get_system_dark_mode'. * src/xsettings.c (something_changed_gsettingsCB): Update PGTK dark mode setting. (xg_get_system_dark_mode): Determine PGTK dark mode preference. GSETTINGS_COLOR_SCHEME: Defined and set to "color-scheme". * etc/NEWS: Document automatic dark mode toggling. (Bug#79689)
Diffstat (limited to 'src')
-rw-r--r--src/gtkutil.c50
-rw-r--r--src/gtkutil.h3
-rw-r--r--src/xsettings.c46
-rw-r--r--src/xsettings.h1
4 files changed, 100 insertions, 0 deletions
diff --git a/src/gtkutil.c b/src/gtkutil.c
index c192102730c..7664e20cc6d 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -36,6 +36,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
36typedef struct x_output xp_output; 36typedef struct x_output xp_output;
37#else 37#else
38#define xp pgtk 38#define xp pgtk
39#include "xsettings.h"
39typedef struct pgtk_output xp_output; 40typedef struct pgtk_output xp_output;
40#endif 41#endif
41#include "blockinput.h" 42#include "blockinput.h"
@@ -1450,6 +1451,47 @@ xg_set_widget_bg (struct frame *f, GtkWidget *w, unsigned long pixel)
1450#endif 1451#endif
1451} 1452}
1452 1453
1454/* Apply dark mode preference to GTK window decorations. */
1455
1456#ifdef HAVE_PGTK
1457void
1458xg_set_gtk_theme_dark_mode (bool dark_mode_p, GtkSettings *settings)
1459{
1460 g_object_set (settings, "gtk-application-prefer-dark-theme",
1461 dark_mode_p ? TRUE : FALSE, NULL);
1462}
1463#endif
1464
1465/* Update all frames' dark mode based on system setting. */
1466
1467#ifdef HAVE_PGTK
1468void
1469xg_update_dark_mode_for_all_displays (bool dark_mode_p)
1470{
1471 struct pgtk_display_info *dpyinfo;
1472 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
1473 {
1474 GdkScreen *screen
1475 = gdk_display_get_default_screen (dpyinfo->gdpy);
1476 GtkSettings *settings
1477 = gtk_settings_get_for_screen (screen);
1478 xg_set_gtk_theme_dark_mode (dark_mode_p, settings);
1479 }
1480}
1481#endif
1482
1483/* Set initial dark mode for a new frame (called during frame
1484 * creation). */
1485
1486#ifdef HAVE_PGTK
1487void
1488xg_set_initial_dark_mode (struct frame *f)
1489{
1490 bool dark_mode_p = xg_get_system_dark_mode ();
1491 xg_update_dark_mode_for_all_displays (dark_mode_p);
1492}
1493#endif
1494
1453/* Callback called when the gtk theme changes. 1495/* Callback called when the gtk theme changes.
1454 We notify lisp code so it can fix faces used for region for example. */ 1496 We notify lisp code so it can fix faces used for region for example. */
1455 1497
@@ -1769,6 +1811,10 @@ xg_create_frame_widgets (struct frame *f)
1769 } 1811 }
1770 } 1812 }
1771 1813
1814#ifdef HAVE_PGTK
1815 xg_set_initial_dark_mode (f);
1816#endif
1817
1772 unblock_input (); 1818 unblock_input ();
1773 1819
1774 return 1; 1820 return 1;
@@ -1872,6 +1918,10 @@ xg_create_frame_outer_widgets (struct frame *f)
1872 } 1918 }
1873 } 1919 }
1874 1920
1921#ifdef HAVE_PGTK
1922 xg_set_initial_dark_mode (f);
1923#endif
1924
1875 unblock_input (); 1925 unblock_input ();
1876} 1926}
1877#endif 1927#endif
diff --git a/src/gtkutil.h b/src/gtkutil.h
index 4aef66fedf4..cabf88da73f 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -184,6 +184,9 @@ extern bool xg_check_special_colors (struct frame *f,
184 Emacs_Color *color); 184 Emacs_Color *color);
185#ifdef HAVE_PGTK 185#ifdef HAVE_PGTK
186extern void xg_create_frame_outer_widgets (struct frame *f); 186extern void xg_create_frame_outer_widgets (struct frame *f);
187extern void xg_set_gtk_theme_dark_mode (bool dark_mode_p, GtkSettings *settings);
188extern void xg_update_dark_mode_for_all_displays (bool dark_mode_p);
189extern void xg_set_initial_dark_mode (struct frame *f);
187#endif 190#endif
188 191
189#ifndef HAVE_PGTK 192#ifndef HAVE_PGTK
diff --git a/src/xsettings.c b/src/xsettings.c
index 30b5ed258ae..72fd70b4b99 100644
--- a/src/xsettings.c
+++ b/src/xsettings.c
@@ -227,6 +227,7 @@ static cairo_font_options_t *font_options;
227#define GSETTINGS_FONT_ANTIALIASING "font-antialiasing" 227#define GSETTINGS_FONT_ANTIALIASING "font-antialiasing"
228#define GSETTINGS_FONT_RGBA_ORDER "font-rgba-order" 228#define GSETTINGS_FONT_RGBA_ORDER "font-rgba-order"
229#define GSETTINGS_FONT_HINTING "font-hinting" 229#define GSETTINGS_FONT_HINTING "font-hinting"
230#define GSETTINGS_COLOR_SCHEME "color-scheme"
230#endif 231#endif
231 232
232/* The single GSettings instance, or NULL if not connected to GSettings. */ 233/* The single GSettings instance, or NULL if not connected to GSettings. */
@@ -448,6 +449,25 @@ something_changed_gsettingsCB (GSettings *settings,
448 apply_gsettings_font_rgba_order (settings); 449 apply_gsettings_font_rgba_order (settings);
449 store_font_options_changed (); 450 store_font_options_changed ();
450 } 451 }
452 else if (!strcmp (key, GSETTINGS_COLOR_SCHEME))
453 {
454 if (xg_settings_key_valid_p (settings, GSETTINGS_COLOR_SCHEME))
455 {
456 val = g_settings_get_value (settings, GSETTINGS_COLOR_SCHEME);
457 if (val)
458 {
459 g_variant_ref_sink (val);
460 if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
461 {
462 const char *color_scheme = g_variant_get_string (val, NULL);
463 /* Check dark mode preference and update all frames. */
464 bool dark_mode_p = (strstr (color_scheme, "dark") != NULL);
465 xg_update_dark_mode_for_all_displays (dark_mode_p);
466 }
467 g_variant_unref (val);
468 }
469 }
470 }
451#endif /* HAVE_PGTK */ 471#endif /* HAVE_PGTK */
452} 472}
453 473
@@ -1109,6 +1129,32 @@ init_gsettings (void)
1109#endif /* HAVE_GSETTINGS */ 1129#endif /* HAVE_GSETTINGS */
1110} 1130}
1111 1131
1132/* Get current system dark mode state. */
1133
1134#ifdef HAVE_PGTK
1135bool
1136xg_get_system_dark_mode (void)
1137{
1138 if (gsettings_client && xg_settings_key_valid_p (gsettings_client, GSETTINGS_COLOR_SCHEME))
1139 {
1140 GVariant *val = g_settings_get_value (gsettings_client, GSETTINGS_COLOR_SCHEME);
1141 if (val)
1142 {
1143 g_variant_ref_sink (val);
1144 if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
1145 {
1146 const char *color_scheme = g_variant_get_string (val, NULL);
1147 bool dark_mode_p = (strstr (color_scheme, "dark") != NULL);
1148 g_variant_unref (val);
1149 return dark_mode_p;
1150 }
1151 g_variant_unref (val);
1152 }
1153 }
1154 return false;
1155}
1156#endif
1157
1112/* Init GConf and read startup values. */ 1158/* Init GConf and read startup values. */
1113 1159
1114static void 1160static void
diff --git a/src/xsettings.h b/src/xsettings.h
index 0234fbf043e..2bb8d0c7379 100644
--- a/src/xsettings.h
+++ b/src/xsettings.h
@@ -45,6 +45,7 @@ extern const char *xsettings_get_system_normal_font (void);
45 45
46#ifdef HAVE_PGTK 46#ifdef HAVE_PGTK
47extern cairo_font_options_t *xsettings_get_font_options (void); 47extern cairo_font_options_t *xsettings_get_font_options (void);
48extern bool xg_get_system_dark_mode (void);
48#endif 49#endif
49 50
50#endif /* XSETTINGS_H */ 51#endif /* XSETTINGS_H */