/* Quit application depending on daemon mode and force parameter */
static void _xfdashboard_application_quit(XfdashboardApplication *self, gboolean inForceQuit)
{
XfdashboardApplicationPrivate *priv;
gboolean shouldQuit;
GSList *stages, *entry;
g_return_if_fail(XFDASHBOARD_IS_APPLICATION(self));
priv=self->priv;
shouldQuit=FALSE;
/* Check if we should really quit this instance */
if(inForceQuit==TRUE || priv->isDaemon==FALSE) shouldQuit=TRUE;
/* Do nothing if application is already quitting. This can happen if
* application is running in daemon mode (primary instance) and another
* instance was called with "quit" or "restart" parameter which would
* cause this function to be called twice.
*/
if(priv->isQuitting) return;
/* If application is not in daemon mode or if forced is set to TRUE
* destroy all stage windows ...
*/
if(shouldQuit==TRUE)
{
/* Set flag that application is going to quit */
priv->isQuitting=TRUE;
/* If application is told to quit, set the restart style to something
* where it won't restart itself.
*/
if(priv->sessionManagementClient &&
XFCE_IS_SM_CLIENT(priv->sessionManagementClient))
{
xfce_sm_client_set_restart_style(priv->sessionManagementClient, XFCE_SM_CLIENT_RESTART_NORMAL);
}
/* Destroy stages */
stages=clutter_stage_manager_list_stages(clutter_stage_manager_get_default());
for(entry=stages; entry!=NULL; entry=g_slist_next(entry)) clutter_actor_destroy(CLUTTER_ACTOR(entry->data));
g_slist_free(stages);
/* Emit "quit" signal */
g_signal_emit(self, XfdashboardApplicationSignals[SIGNAL_QUIT], 0);
/* Really quit application here and now */
if(priv->inited) clutter_main_quit();
}
/* ... otherwise emit "suspend" signal */
else
{
/* Only send signal if not suspended already */
if(!priv->isSuspended)
{
/* Send signal */
g_signal_emit(self, XfdashboardApplicationSignals[SIGNAL_SUSPEND], 0);
/* Set flag for suspension */
priv->isSuspended=TRUE;
g_object_notify_by_pspec(G_OBJECT(self), XfdashboardApplicationProperties[PROP_SUSPENDED]);
}
}
}
void
mnb_zones_preview_change_workspace (MnbZonesPreview *preview,
gint workspace)
{
gboolean reset_anim;
MnbZonesPreviewPrivate *priv = preview->priv;
/* If we're already going towards this workspace, ignore */
if ((priv->dest_workspace == workspace) && priv->anim_phase)
return;
/* Figure out what we need to be doing with this animation */
switch (priv->anim_phase)
{
default:
case MNB_ZP_STATIC:
/* We weren't animating, start a new one */
reset_anim = TRUE;
break;
case MNB_ZP_ZOOM_OUT:
/* If we're on the right workspace, zoom in and finish, otherwise
* continue the animation like normal.
*/
if (priv->dest_workspace == workspace)
{
priv->anim_phase = MNB_ZP_PAN;
reset_anim = TRUE;
}
else
reset_anim = FALSE;
break;
case MNB_ZP_PAN:
/* If we're heading towards the right workspace, continue the
* animation, otherwise change direction.
*/
if (priv->dest_workspace != workspace)
{
priv->anim_phase = MNB_ZP_ZOOM_OUT;
reset_anim = TRUE;
}
else
reset_anim = FALSE;
break;
case MNB_ZP_ZOOM_IN:
/* Restart the animation if we're not heading towards the right
* workspace.
*/
if (priv->dest_workspace != workspace)
{
priv->anim_phase = MNB_ZP_STATIC;
reset_anim = TRUE;
}
else
reset_anim = FALSE;
break;
}
priv->dest_workspace = workspace;
if (reset_anim)
{
ClutterAnimation *animation =
clutter_actor_get_animation (CLUTTER_ACTOR (preview));
if (animation)
g_signal_handlers_disconnect_by_func (animation,
mnb_zones_preview_completed_cb,
preview);
mnb_zones_preview_completed_cb (animation, preview);
}
}
//.........这里部分代码省略.........
* This method returns a new #ClutterActor for a given #GIcon. If the
* icon isn't loaded already, the texture will be filled
* asynchronously.
*
* Return Value: (transfer none): A new #ClutterActor for the icon, or %NULL if not found
*/
ClutterActor *
st_texture_cache_load_gicon (StTextureCache *cache,
StThemeNode *theme_node,
GIcon *icon,
gint size,
gint scale)
{
AsyncTextureLoadData *request;
ClutterActor *texture;
char *gicon_string;
char *key;
GtkIconTheme *theme;
GtkIconInfo *info;
StTextureCachePolicy policy;
StIconColors *colors = NULL;
StIconStyle icon_style = ST_ICON_STYLE_REQUESTED;
GtkIconLookupFlags lookup_flags;
if (theme_node)
{
colors = st_theme_node_get_icon_colors (theme_node);
icon_style = st_theme_node_get_icon_style (theme_node);
}
/* Do theme lookups in the main thread to avoid thread-unsafety */
theme = cache->priv->icon_theme;
lookup_flags = GTK_ICON_LOOKUP_USE_BUILTIN;
if (icon_style == ST_ICON_STYLE_REGULAR)
lookup_flags |= GTK_ICON_LOOKUP_FORCE_REGULAR;
else if (icon_style == ST_ICON_STYLE_SYMBOLIC)
lookup_flags |= GTK_ICON_LOOKUP_FORCE_SYMBOLIC;
if (clutter_get_default_text_direction () == CLUTTER_TEXT_DIRECTION_RTL)
lookup_flags |= GTK_ICON_LOOKUP_DIR_RTL;
else
lookup_flags |= GTK_ICON_LOOKUP_DIR_LTR;
info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, icon, size, scale, lookup_flags);
if (info == NULL)
return NULL;
gicon_string = g_icon_to_string (icon);
/* A return value of NULL indicates that the icon can not be serialized,
* so don't have a unique identifier for it as a cache key, and thus can't
* be cached. If it is cachable, we hardcode a policy of FOREVER here for
* now; we should actually blow this away on icon theme changes probably */
policy = gicon_string != NULL ? ST_TEXTURE_CACHE_POLICY_FOREVER
: ST_TEXTURE_CACHE_POLICY_NONE;
if (colors)
{
/* This raises some doubts about the practice of using string keys */
key = g_strdup_printf (CACHE_PREFIX_ICON "%s,size=%d,scale=%d,style=%d,colors=%2x%2x%2x%2x,%2x%2x%2x%2x,%2x%2x%2x%2x,%2x%2x%2x%2x",
gicon_string, size, scale, icon_style,
colors->foreground.red, colors->foreground.blue, colors->foreground.green, colors->foreground.alpha,
colors->warning.red, colors->warning.blue, colors->warning.green, colors->warning.alpha,
colors->error.red, colors->error.blue, colors->error.green, colors->error.alpha,
colors->success.red, colors->success.blue, colors->success.green, colors->success.alpha);
}
else
{
key = g_strdup_printf (CACHE_PREFIX_ICON "%s,size=%d,scale=%d,style=%d",
gicon_string, size, scale, icon_style);
}
g_free (gicon_string);
texture = (ClutterActor *) create_default_texture ();
clutter_actor_set_size (texture, size * scale, size * scale);
if (ensure_request (cache, key, policy, &request, texture))
{
/* If there's an outstanding request, we've just added ourselves to it */
g_object_unref (info);
g_free (key);
}
else
{
/* Else, make a new request */
request->cache = cache;
/* Transfer ownership of key */
request->key = key;
request->policy = policy;
request->colors = colors ? st_icon_colors_ref (colors) : NULL;
request->icon_info = info;
request->width = request->height = size;
request->scale = scale;
load_texture_async (cache, request);
}
return CLUTTER_ACTOR (texture);
}
static gboolean
st_container_navigate_focus (StWidget *widget,
ClutterActor *from,
GtkDirectionType direction)
{
StContainer *container = ST_CONTAINER (widget);
ClutterActor *container_actor, *focus_child;
GList *children, *l;
container_actor = CLUTTER_ACTOR (widget);
if (from == container_actor)
return FALSE;
/* Figure out if @from is a descendant of @container, and if so,
* set @focus_child to the immediate child of @container that
* contains (or *is*) @from.
*/
focus_child = from;
while (focus_child && clutter_actor_get_parent (focus_child) != container_actor)
focus_child = clutter_actor_get_parent (focus_child);
if (st_widget_get_can_focus (widget))
{
if (!focus_child)
{
/* Accept focus from outside */
clutter_actor_grab_key_focus (container_actor);
return TRUE;
}
else
{
/* Yield focus from within: since @container itself is
* focusable we don't allow the focus to be navigated
* within @container.
*/
return FALSE;
}
}
/* See if we can navigate within @focus_child */
if (focus_child && ST_IS_WIDGET (focus_child))
{
if (st_widget_navigate_focus (ST_WIDGET (focus_child), from, direction, FALSE))
return TRUE;
}
/* At this point we know that we want to navigate focus to one of
* @container's immediate children; the next one after @focus_child,
* or the first one if @focus_child is %NULL. (With "next" and
* "first" being determined by @direction.)
*/
children = st_container_get_focus_chain (container);
if (direction == GTK_DIR_TAB_FORWARD ||
direction == GTK_DIR_TAB_BACKWARD)
{
if (direction == GTK_DIR_TAB_BACKWARD)
children = g_list_reverse (children);
if (focus_child)
{
/* Remove focus_child and any earlier children */
while (children && children->data != focus_child)
children = g_list_delete_link (children, children);
if (children)
children = g_list_delete_link (children, children);
}
}
else /* direction is an arrow key, not tab */
{
StContainerChildSortData sort_data;
/* Compute the allocation box of the previous focused actor, in
* @container's coordinate space. If there was no previous focus,
* use the coordinates of the appropriate edge of @container.
*
* Note that all of this code assumes the actors are not
* transformed (or at most, they are all scaled by the same
* amount). If @container or any of its children is rotated, or
* any child is inconsistently scaled, then the focus chain will
* probably be unpredictable.
*/
if (focus_child)
{
clutter_actor_get_allocation_box (focus_child, &sort_data.box);
}
else
{
clutter_actor_get_allocation_box (CLUTTER_ACTOR (container), &sort_data.box);
switch (direction)
{
case GTK_DIR_UP:
sort_data.box.y1 = sort_data.box.y2;
break;
case GTK_DIR_DOWN:
sort_data.box.y2 = sort_data.box.y1;
break;
case GTK_DIR_LEFT:
sort_data.box.x1 = sort_data.box.x2;
break;
//.........这里部分代码省略.........
请发表评论