I found the reason why it didn't work before the `gtk_widget_show_all` call
Basically, the `gtk_widget_show_all` function creates the `GdkWindow`, since to create the `GdkWindow` you need to realize the `GtkWindow`, which the `gtk_widget_show_all` function does. But there are other functions that realize the `GtkWindow`, one of them is `gtk_widget_realize`, which only realize the `GtkWindow`, without showing the window or anything else. So if we call `gtk_widget_realize` before the `gtk_widget_get_window` function, we can get the `GdkWindow`.
So the __Perfect Code__ is
### Perfect Code ```c #include <gtk/gtk.h> #include <windows.h> #include <dwmapi.h> #include <gdk/gdkwin32.h>
BOOL ShouldAppsUseDarkMode() { BOOL isLight = TRUE; DWORD val, dataSize = sizeof(val); const char *REG_PATH = "Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"; const char *REG_VAR = "AppsUseLightTheme"; if (RegGetValueA(HKEY_CURRENT_USER, REG_PATH, REG_VAR, RRF_RT_DWORD, NULL, &val, &dataSize) == ERROR_SUCCESS) { isLight = val; } else { g_warning("Failed to get AppsUseLightTheme from Reg."); } return !isLight; }
void current_mode_titlebar(GtkWidget *window) { GdkWindow *gdk_window = gtk_widget_get_window(window); if (gdk_window) { HWND hwnd = (HWND)gdk_win32_window_get_handle(gdk_window); if (hwnd) { BOOL use_dark_mode = ShouldAppsUseDarkMode(); DwmSetWindowAttribute(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &use_dark_mode, sizeof(use_dark_mode)); } else { g_warning("Failed to get HWND from GdkWindow."); } } else { g_warning("Failed to get GdkWindow from GtkWidget."); } }
int main(int argc, char *argv[]) { GtkWidget *window;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Dark Mode Title Bar"); gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_realize(window); current_mode_titlebar(window);
gtk_widget_show_all(window);
gtk_main();
return 0; } ```