diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c index 38b10142df..1deb3fc04f 100644 --- a/gdk/x11/gdkdisplay-x11.c +++ b/gdk/x11/gdkdisplay-x11.c @@ -1405,6 +1405,70 @@ gdk_x11_display_init_leader_surface (GdkX11Display *self) self->leader_window_title_set = FALSE; } +static void +voidXFree (gpointer data) +{ + XFree (data); +} + +static void +gdk_x11_display_check_color_state (GdkX11Display *self) +{ + GdkDisplay *display = GDK_DISPLAY (self); + GdkX11Screen *screen; + char *atom_name; + Atom type; + int result; + int format; + gulong nitems; + gulong bytes_after; + guchar *data; + GBytes *bytes; + + screen = self->screen; + if (screen->screen_num > 0) + atom_name = g_strdup_printf ("_ICC_PROFILE_%d", screen->screen_num); + else + atom_name = g_strdup ("_ICC_PROFILE"); + + g_set_object (&self->color_state, gdk_color_state_get_srgb ()); + + gdk_x11_display_error_trap_push (display); + result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), + screen->xroot_window, + gdk_x11_get_xatom_by_name_for_display (display, atom_name), + 0, G_MAXLONG, False, XA_CARDINAL, &type, + &format, &nitems, + &bytes_after, &data); + gdk_x11_display_error_trap_pop_ignored (display); + + g_free (atom_name); + + if (result != Success || type != XA_CARDINAL || nitems <= 0) + return; + + switch (format) + { + case 8: + bytes = g_bytes_new_with_free_func (data, nitems, voidXFree, data); + break; + case 16: + bytes = g_bytes_new_with_free_func (data, sizeof (short) * nitems, voidXFree, data); + break; + case 32: + bytes = g_bytes_new_with_free_func (data, sizeof (long) * nitems, voidXFree, data); + break; + default: + XFree (data); + return; + } + + g_clear_object (&self->color_state); + self->color_state = gdk_color_state_new_from_icc_profile (bytes, NULL); + if (!self->color_state) + self->color_state = g_object_ref (gdk_color_state_get_srgb ()); +} + /** * gdk_x11_display_open: * @display_name: (nullable): name of the X display. @@ -1475,6 +1539,9 @@ gdk_x11_display_open (const char *display_name) /* initialize the display's screens */ display_x11->screen = _gdk_x11_screen_new (display, DefaultScreen (display_x11->xdisplay)); + /* We want this for the leader surface already */ + gdk_x11_display_check_color_state (display_x11); + /* If GL is available we want to pick better default/rgba visuals, * as we care about GLX details such as alpha/depth/stencil depth, * stereo and double buffering @@ -1923,15 +1990,17 @@ gdk_x11_display_ungrab (GdkDisplay *display) static void gdk_x11_display_dispose (GObject *object) { - GdkX11Display *display_x11 = GDK_X11_DISPLAY (object); + GdkX11Display *self = GDK_X11_DISPLAY (object); - if (display_x11->event_source) + if (self->event_source) { - g_source_destroy (display_x11->event_source); - g_source_unref (display_x11->event_source); - display_x11->event_source = NULL; + g_source_destroy (self->event_source); + g_source_unref (self->event_source); + self->event_source = NULL; } + g_clear_object (&self->color_state); + G_OBJECT_CLASS (gdk_x11_display_parent_class)->dispose (object); } diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h index bb263b5648..18d9d5ef8c 100644 --- a/gdk/x11/gdkdisplay-x11.h +++ b/gdk/x11/gdkdisplay-x11.h @@ -127,6 +127,9 @@ struct _GdkX11Display guint have_damage; #endif + /* Stored in the ICC_PROFILE rootwindow prop */ + GdkColorState *color_state; + /* If GL is not supported, store the error here */ GError *gl_error; diff --git a/gdk/x11/gdksurface-x11.c b/gdk/x11/gdksurface-x11.c index c0a618494b..29ade008ef 100644 --- a/gdk/x11/gdksurface-x11.c +++ b/gdk/x11/gdksurface-x11.c @@ -926,6 +926,8 @@ setup_toplevel_window (GdkSurface *surface) /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME */ XSetWMProperties (xdisplay, xid, NULL, NULL, NULL, 0, NULL, NULL, NULL); + + gdk_surface_set_color_state (surface, GDK_X11_DISPLAY (display)->color_state); if (!gdk_running_in_sandbox ()) {