static ClutterActor * window_backed_app_get_icon (CinnamonApp *app, int size) { MetaWindow *window; ClutterActor *actor; gint scale; CinnamonGlobal *global; StThemeContext *context; global = cinnamon_global_get (); context = st_theme_context_get_for_stage (cinnamon_global_get_stage (global)); g_object_get (context, "scale-factor", &scale, NULL); size *= scale; /* During a state transition from running to not-running for * window-backend apps, it's possible we get a request for the icon. * Avoid asserting here and just return an empty image. */ if (app->running_state == NULL) { actor = clutter_texture_new (); g_object_set (actor, "opacity", 0, "width", (float) size, "height", (float) size, NULL); return actor; } window = window_backed_app_get_window (app); actor = st_texture_cache_bind_pixbuf_property (st_texture_cache_get_default (), G_OBJECT (window), "icon"); g_object_set (actor, "width", (float) size, "height", (float) size, NULL); return actor; }
static gboolean st_icon_update_icon_size (StIcon *icon) { StIconPrivate *priv = icon->priv; int new_size; if (priv->prop_icon_size > 0) new_size = priv->prop_icon_size; else if (priv->theme_icon_size > 0) { gint scale; ClutterActor *stage; StThemeContext *context; /* The theme will give us an already-scaled size, so we * undo it here, as priv->icon_size is in unscaled pixels. */ stage = clutter_actor_get_stage (CLUTTER_ACTOR (icon)); context = st_theme_context_get_for_stage (CLUTTER_STAGE (stage)); g_object_get (context, "scale-factor", &scale, NULL); new_size = (gint) (priv->theme_icon_size / scale); } else new_size = DEFAULT_ICON_SIZE; if (new_size != priv->icon_size) { clutter_actor_queue_relayout (CLUTTER_ACTOR (icon)); priv->icon_size = new_size; return TRUE; } else return FALSE; }
/** * cinnamon_startup_sequence_create_icon: * @sequence: * @size: Size in pixels of icon * * Returns: (transfer none): A new #ClutterTexture containing an icon for the sequence */ ClutterActor * cinnamon_startup_sequence_create_icon (CinnamonStartupSequence *sequence, guint size) { GIcon *themed; const char *icon_name; ClutterActor *texture; icon_name = sn_startup_sequence_get_icon_name ((SnStartupSequence*)sequence); if (!icon_name) { gint scale; CinnamonGlobal *global; StThemeContext *context; texture = clutter_texture_new (); global = cinnamon_global_get (); context = st_theme_context_get_for_stage (cinnamon_global_get_stage (global)); g_object_get (context, "scale-factor", &scale, NULL); clutter_actor_set_size (texture, size * scale, size * scale); return texture; } themed = g_themed_icon_new (icon_name); texture = g_object_new (ST_TYPE_ICON, "gicon", themed, "icon-size", size, NULL); g_object_unref (G_OBJECT (themed)); return texture; }
/** * shell_startup_sequence_create_icon: * @sequence: * @size: Size in pixels of icon * * Returns: (transfer none): A new #ClutterTexture containing an icon for the sequence */ ClutterActor * shell_startup_sequence_create_icon (ShellStartupSequence *sequence, guint size) { GIcon *themed; const char *icon_name; ClutterActor *texture; gint scale; ShellGlobal *global; StThemeContext *context; global = shell_global_get (); context = st_theme_context_get_for_stage (shell_global_get_stage (global)); g_object_get (context, "scale-factor", &scale, NULL); icon_name = sn_startup_sequence_get_icon_name ((SnStartupSequence*)sequence); if (!icon_name) { texture = clutter_texture_new (); clutter_actor_set_size (texture, size * scale, size * scale); return texture; } themed = g_themed_icon_new (icon_name); texture = st_texture_cache_load_gicon (st_texture_cache_get_default (), NULL, themed, size, scale); g_object_unref (G_OBJECT (themed)); return texture; }
static void on_stage_destroy (ClutterStage *stage) { StThemeContext *context = st_theme_context_get_for_stage (stage); g_object_set_data (G_OBJECT (stage), "st-theme-context", NULL); g_object_unref (context); }
static StThemeNode * get_root_theme_node (ClutterStage *stage) { StThemeContext *context = st_theme_context_get_for_stage (stage); if (!g_object_get_data (G_OBJECT (context), "st-theme-initialized")) { g_object_set_data (G_OBJECT (context), "st-theme-initialized", GUINT_TO_POINTER (1)); g_signal_connect (G_OBJECT (context), "changed", G_CALLBACK (on_theme_context_changed), stage); } return st_theme_context_get_root_node (context); }
/** * cinnamon_app_get_faded_icon: * @app: A #CinnamonApp * @size: Size in pixels * * Return an actor with a horizontally faded look. * * Return value: (transfer none): A floating #ClutterActor, or %NULL if no icon */ ClutterActor * cinnamon_app_get_faded_icon (CinnamonApp *app, int size) { CoglHandle texture; ClutterActor *result; char *cache_key; CreateFadedIconData data; gint scale; CinnamonGlobal *global; StThemeContext *context; /* Don't fade for window backed apps for now...easier to reuse the * property tracking bits, and this helps us visually distinguish * app-tracked from not. */ if (!app->entry) return window_backed_app_get_icon (app, size); global = cinnamon_global_get (); context = st_theme_context_get_for_stage (cinnamon_global_get_stage (global)); g_object_get (context, "scale-factor", &scale, NULL); cache_key = g_strdup_printf ("faded-icon:%s,size=%d,scale=%d", cinnamon_app_get_id (app), size, scale); data.app = app; data.size = size; data.scale = scale; texture = st_texture_cache_load (st_texture_cache_get_default (), cache_key, ST_TEXTURE_CACHE_POLICY_FOREVER, cinnamon_app_create_faded_icon_cpu, &data, NULL); g_free (cache_key); if (texture != COGL_INVALID_HANDLE) { result = clutter_texture_new (); clutter_texture_set_cogl_texture (CLUTTER_TEXTURE (result), texture); } else { result = clutter_texture_new (); g_object_set (result, "opacity", 0, "width", (float) size * scale, "height", (float) size * scale, NULL); } return result; }
/** * st_widget_get_theme_node: * @widget: a #StWidget * * Gets the theme node holding style information for the widget. * The theme node is used to access standard and custom CSS * properties of the widget. * * Return value: (transfer none): the theme node for the widget. * This is owned by the widget. When attributes of the widget * or the environment that affect the styling change (for example * the style_class property of the widget), it will be recreated, * and the ::style-changed signal will be emitted on the widget. */ StThemeNode * st_widget_get_theme_node (StWidget *widget) { StWidgetPrivate *priv = widget->priv; if (priv->theme_node == NULL) { StThemeNode *parent_node = NULL; ClutterStage *stage = NULL; ClutterActor *parent; parent = clutter_actor_get_parent (CLUTTER_ACTOR (widget)); while (parent != NULL) { if (parent_node == NULL && ST_IS_WIDGET (parent)) parent_node = st_widget_get_theme_node (ST_WIDGET (parent)); else if (CLUTTER_IS_STAGE (parent)) stage = CLUTTER_STAGE (parent); parent = clutter_actor_get_parent (parent); } if (stage == NULL) { g_error ("st_widget_get_theme_node called on a widget not in a stage"); } if (parent_node == NULL) parent_node = get_root_theme_node (CLUTTER_STAGE (stage)); priv->theme_node = st_theme_node_new (st_theme_context_get_for_stage (stage), parent_node, priv->theme, G_OBJECT_TYPE (widget), clutter_actor_get_name (CLUTTER_ACTOR (widget)), priv->style_class, priv->pseudo_class, priv->inline_style); } return priv->theme_node; }
static void update_font_options (GtkSettings *settings) { StThemeContext *context; ClutterStage *stage; ClutterBackend *backend; gint dpi; gint hinting; gchar *hint_style_str; cairo_hint_style_t hint_style = CAIRO_HINT_STYLE_NONE; gint antialias; cairo_antialias_t antialias_mode = CAIRO_ANTIALIAS_NONE; cairo_font_options_t *options; g_object_get (settings, "gtk-xft-dpi", &dpi, "gtk-xft-antialias", &antialias, "gtk-xft-hinting", &hinting, "gtk-xft-hintstyle", &hint_style_str, NULL); stage = CLUTTER_STAGE (clutter_stage_get_default ()); context = st_theme_context_get_for_stage (stage); if (dpi != -1) /* GTK stores resolution as 1024 * dots/inch */ st_theme_context_set_resolution (context, dpi / 1024); else st_theme_context_set_default_resolution (context); st_tooltip_set_constrain_func (stage, constrain_tooltip, NULL, NULL); /* Clutter (as of 0.9) passes comprehensively wrong font options * override whatever set_font_flags() did above. * * http://bugzilla.openedhand.com/show_bug.cgi?id=1456 */ backend = clutter_get_default_backend (); options = cairo_font_options_create (); cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON); if (hinting >= 0 && !hinting) { hint_style = CAIRO_HINT_STYLE_NONE; } else if (hint_style_str) { if (strcmp (hint_style_str, "hintnone") == 0) hint_style = CAIRO_HINT_STYLE_NONE; else if (strcmp (hint_style_str, "hintslight") == 0) hint_style = CAIRO_HINT_STYLE_SLIGHT; else if (strcmp (hint_style_str, "hintmedium") == 0) hint_style = CAIRO_HINT_STYLE_MEDIUM; else if (strcmp (hint_style_str, "hintfull") == 0) hint_style = CAIRO_HINT_STYLE_FULL; } g_free (hint_style_str); cairo_font_options_set_hint_style (options, hint_style); /* We don't want to turn on subpixel anti-aliasing; since Clutter * doesn't currently have the code to support ARGB masks, * generating them then squashing them back to A8 is pointless. */ antialias_mode = (antialias < 0 || antialias) ? CAIRO_ANTIALIAS_GRAY : CAIRO_ANTIALIAS_NONE; cairo_font_options_set_antialias (options, antialias_mode); clutter_backend_set_font_options (backend, options); cairo_font_options_destroy (options); }
static void st_icon_update (StIcon *icon) { StIconPrivate *priv = icon->priv; StThemeNode *theme_node; StTextureCache *cache; gint scale; ClutterActor *stage; StThemeContext *context; if (priv->pending_texture) { clutter_actor_destroy (priv->pending_texture); g_object_unref (priv->pending_texture); priv->pending_texture = NULL; priv->opacity_handler_id = 0; } theme_node = st_widget_peek_theme_node (ST_WIDGET (icon)); if (theme_node == NULL) return; stage = clutter_actor_get_stage (CLUTTER_ACTOR (icon)); context = st_theme_context_get_for_stage (CLUTTER_STAGE (stage)); g_object_get (context, "scale-factor", &scale, NULL); priv->icon_scale = scale; cache = st_texture_cache_get_default (); if (priv->gicon) { priv->pending_texture = st_texture_cache_load_gicon (cache, (priv->icon_type != ST_ICON_APPLICATION && priv->icon_type != ST_ICON_DOCUMENT) ? theme_node : NULL, priv->gicon, priv->icon_size); } else if (priv->icon_name) { priv->pending_texture = st_texture_cache_load_icon_name (cache, theme_node, priv->icon_name, priv->icon_type, priv->icon_size); } if (priv->pending_texture) { g_object_ref_sink (priv->pending_texture); if (clutter_actor_get_opacity (priv->pending_texture) != 0 || priv->icon_texture == NULL) { /* This icon is ready for showing, or nothing else is already showing */ st_icon_finish_update (icon); } else { /* Will be shown when fully loaded */ priv->opacity_handler_id = g_signal_connect (priv->pending_texture, "notify::opacity", G_CALLBACK (opacity_changed_cb), icon); } } else if (priv->icon_texture) { clutter_actor_destroy (priv->icon_texture); priv->icon_texture = NULL; } }