static void xfdesktop_special_file_icon_changed(GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event, XfdesktopSpecialFileIcon *special_file_icon) { g_return_if_fail(G_IS_FILE_MONITOR(monitor)); g_return_if_fail(G_IS_FILE(file)); g_return_if_fail(XFDESKTOP_IS_SPECIAL_FILE_ICON(special_file_icon)); /* We don't care about change events only created/deleted */ if(event == G_FILE_MONITOR_EVENT_CHANGED || event == G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED || event == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT) return; /* release the old file information */ if(special_file_icon->priv->file_info) { g_object_unref(special_file_icon->priv->file_info); special_file_icon->priv->file_info = NULL; } /* release the old file system information */ if(special_file_icon->priv->filesystem_info) { g_object_unref(special_file_icon->priv->filesystem_info); special_file_icon->priv->filesystem_info = NULL; } /* reload the file information */ special_file_icon->priv->file_info = g_file_query_info(special_file_icon->priv->file, XFDESKTOP_FILE_INFO_NAMESPACE, G_FILE_QUERY_INFO_NONE, NULL, NULL); /* reload the file system information */ special_file_icon->priv->filesystem_info = g_file_query_filesystem_info(special_file_icon->priv->file, XFDESKTOP_FILESYSTEM_INFO_NAMESPACE, NULL, NULL); /* update the trash full state */ if(special_file_icon->priv->type == XFDESKTOP_SPECIAL_FILE_ICON_TRASH) xfdesktop_special_file_icon_update_trash_count(special_file_icon); /* invalidate the tooltip */ g_free(special_file_icon->priv->tooltip); special_file_icon->priv->tooltip = NULL; /* update the icon */ xfdesktop_file_icon_invalidate_icon(XFDESKTOP_FILE_ICON(special_file_icon)); xfdesktop_icon_invalidate_pixbuf(XFDESKTOP_ICON(special_file_icon)); xfdesktop_icon_pixbuf_changed(XFDESKTOP_ICON(special_file_icon)); }
/** * g_file_monitor_is_cancelled: * @monitor: a #GFileMonitor * * Returns whether the monitor is canceled. * * Returns: %TRUE if monitor is canceled. %FALSE otherwise. **/ gboolean g_file_monitor_is_cancelled (GFileMonitor *monitor) { gboolean res; g_return_val_if_fail (G_IS_FILE_MONITOR (monitor), FALSE); G_LOCK (cancelled); res = monitor->priv->cancelled; G_UNLOCK (cancelled); return res; }
/** * g_file_monitor_set_rate_limit: * @monitor: a #GFileMonitor. * @limit_msecs: a integer with the limit in milliseconds to * poll for changes. * * Sets the rate limit to which the @monitor will report * consecutive change events to the same file. * **/ void g_file_monitor_set_rate_limit (GFileMonitor *monitor, int limit_msecs) { GFileMonitorPrivate *priv; g_return_if_fail (G_IS_FILE_MONITOR (monitor)); priv = monitor->priv; if (priv->rate_limit_msec != limit_msecs) { monitor->priv->rate_limit_msec = limit_msecs; g_object_notify (G_OBJECT (monitor), "rate-limit"); } }
/** * g_file_monitor_cancel: * @monitor: a #GFileMonitor. * * Cancels a file monitor. * * Returns: %TRUE if monitor was cancelled. **/ gboolean g_file_monitor_cancel (GFileMonitor* monitor) { GFileMonitorClass *klass; g_return_val_if_fail (G_IS_FILE_MONITOR (monitor), FALSE); G_LOCK (cancelled); if (monitor->priv->cancelled) { G_UNLOCK (cancelled); return TRUE; } monitor->priv->cancelled = TRUE; G_UNLOCK (cancelled); g_object_notify (G_OBJECT (monitor), "cancelled"); klass = G_FILE_MONITOR_GET_CLASS (monitor); return (* klass->cancel) (monitor); }
/** * g_file_monitor_emit_event: * @monitor: a #GFileMonitor. * @child: a #GFile. * @other_file: a #GFile. * @event_type: a set of #GFileMonitorEvent flags. * * Emits the #GFileMonitor::changed signal if a change * has taken place. Should be called from file monitor * implementations only. * * The signal will be emitted from an idle handler (in the <link * linkend="g-main-context-push-thread-default">thread-default main * context</link>). **/ void g_file_monitor_emit_event (GFileMonitor *monitor, GFile *child, GFile *other_file, GFileMonitorEvent event_type) { guint32 time_now, since_last; gboolean emit_now; RateLimiter *limiter; g_return_if_fail (G_IS_FILE_MONITOR (monitor)); g_return_if_fail (G_IS_FILE (child)); limiter = g_hash_table_lookup (monitor->priv->rate_limiter, child); if (event_type != G_FILE_MONITOR_EVENT_CHANGED) { if (limiter) { rate_limiter_send_delayed_change_now (monitor, limiter, get_time_msecs ()); if (event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT) limiter->send_virtual_changes_done_at = 0; else rate_limiter_send_virtual_changes_done_now (monitor, limiter); update_rate_limiter_timeout (monitor, 0); } emit_in_idle (monitor, child, other_file, event_type); } else { /* Changed event, rate limit */ time_now = get_time_msecs (); emit_now = TRUE; if (limiter) { since_last = time_difference (limiter->last_sent_change_time, time_now); if (since_last < monitor->priv->rate_limit_msec) { /* We ignore this change, but arm a timer so that we can fire it later if we don't get any other events (that kill this timeout) */ emit_now = FALSE; if (limiter->send_delayed_change_at == 0) { limiter->send_delayed_change_at = time_now + monitor->priv->rate_limit_msec; update_rate_limiter_timeout (monitor, limiter->send_delayed_change_at); } } } if (limiter == NULL) limiter = new_limiter (monitor, child); if (emit_now) { emit_in_idle (monitor, child, other_file, event_type); limiter->last_sent_change_time = time_now; limiter->send_delayed_change_at = 0; /* Set a timeout of 2*rate limit so that we can clear out the change from the hash eventualy */ update_rate_limiter_timeout (monitor, time_now + 2 * monitor->priv->rate_limit_msec); } /* Schedule a virtual change done. This is removed if we get a real one, and postponed if we get more change events. */ limiter->send_virtual_changes_done_at = time_now + DEFAULT_VIRTUAL_CHANGES_DONE_DELAY_SECS * 1000; update_rate_limiter_timeout (monitor, limiter->send_virtual_changes_done_at); } }