use fam for recent files
This commit is contained in:
parent
80fa9f89b4
commit
3645684405
405
gtk+-2.10.3-fam.patch
Normal file
405
gtk+-2.10.3-fam.patch
Normal file
@ -0,0 +1,405 @@
|
||||
--- gtk+-2.10.3/gtk/gtkrecentmanager.c.fam 2006-08-18 11:30:57.000000000 -0400
|
||||
+++ gtk+-2.10.3/gtk/gtkrecentmanager.c 2006-09-05 11:33:48.000000000 -0400
|
||||
@@ -38,6 +38,9 @@
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkmarshalers.h"
|
||||
+
|
||||
+#include <fam.h>
|
||||
+
|
||||
#include "gtkalias.h"
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
@@ -110,6 +113,9 @@
|
||||
|
||||
time_t last_mtime;
|
||||
guint poll_timeout;
|
||||
+
|
||||
+ FAMRequest *fam_request;
|
||||
+ guint changed_timeout;
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -274,6 +280,309 @@
|
||||
g_type_class_add_private (klass, sizeof (GtkRecentManagerPrivate));
|
||||
}
|
||||
|
||||
+
|
||||
+/* fam support */
|
||||
+#undef DEBUG_FAM
|
||||
+
|
||||
+static FAMConnection fam_connection;
|
||||
+static gboolean opened_connection = FALSE;
|
||||
+static gboolean failed_to_connect = FALSE;
|
||||
+static guint fam_io_watch = 0;
|
||||
+
|
||||
+static int (*fam_open) (FAMConnection *fc) = NULL;
|
||||
+static int (*fam_close) (FAMConnection *fc) = NULL;
|
||||
+static int (*fam_pending) (FAMConnection *fc) = NULL;
|
||||
+static int (*fam_next_event) (FAMConnection *fc,
|
||||
+ FAMEvent *fe) = NULL;
|
||||
+static int (*fam_monitor_file) (FAMConnection *fc,
|
||||
+ const char *filename,
|
||||
+ FAMRequest *fr,
|
||||
+ void *userData) = NULL;
|
||||
+static int (*fam_cancel_monitor) (FAMConnection *fc,
|
||||
+ const FAMRequest *fr) = NULL;
|
||||
+
|
||||
+
|
||||
+static struct FamDlMapping
|
||||
+{
|
||||
+ const char *fn_name;
|
||||
+ gpointer fn_ptr_ref;
|
||||
+} fam_dl_mapping[] = {
|
||||
+ { "FAMOpen", &fam_open },
|
||||
+ { "FAMClose", &fam_close },
|
||||
+ { "FAMPending", &fam_pending },
|
||||
+ { "FAMNextEvent", &fam_next_event },
|
||||
+ { "FAMMonitorFile", &fam_monitor_file },
|
||||
+ { "FAMCancelMonitor", &fam_cancel_monitor }
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+open_libfam (void)
|
||||
+{
|
||||
+ static gboolean done = FALSE;
|
||||
+
|
||||
+ if (!done)
|
||||
+ {
|
||||
+ int i;
|
||||
+ GModule *fam;
|
||||
+
|
||||
+ done = TRUE;
|
||||
+
|
||||
+ fam = g_module_open ("libfam.so.0", G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
|
||||
+ if (!fam)
|
||||
+ {
|
||||
+ g_warning ("Can't open libfam '%s'\n", g_module_error ());
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < G_N_ELEMENTS (fam_dl_mapping); i++)
|
||||
+ {
|
||||
+ if (!g_module_symbol (fam, fam_dl_mapping[i].fn_name,
|
||||
+ fam_dl_mapping[i].fn_ptr_ref))
|
||||
+ {
|
||||
+ g_warning ("Missing symbol '%s' in libfam\n",
|
||||
+ fam_dl_mapping[i].fn_name);
|
||||
+ g_module_close (fam);
|
||||
+ for (i = 0; i < G_N_ELEMENTS (fam_dl_mapping); i++)
|
||||
+ fam_dl_mapping[i].fn_ptr_ref = NULL;
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static gboolean
|
||||
+changed_timeout (gpointer data)
|
||||
+{
|
||||
+ GtkRecentManager *manager;
|
||||
+
|
||||
+ GDK_THREADS_ENTER ();
|
||||
+
|
||||
+ manager = (GtkRecentManager *)data;
|
||||
+ manager->priv->changed_timeout = 0;
|
||||
+
|
||||
+ gtk_recent_manager_changed (manager);
|
||||
+
|
||||
+ GDK_THREADS_LEAVE ();
|
||||
+
|
||||
+ return FALSE;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+handle_fam_event (GtkRecentManager *manager,
|
||||
+ FAMEvent *event)
|
||||
+{
|
||||
+ GtkRecentManagerPrivate *priv = manager->priv;
|
||||
+
|
||||
+ /* try to group delete-create pairs */
|
||||
+ if (event->code == FAMDeleted)
|
||||
+ {
|
||||
+ if (priv->changed_timeout == 0)
|
||||
+ priv->changed_timeout = g_timeout_add (500, changed_timeout, manager);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (priv->changed_timeout != 0)
|
||||
+ {
|
||||
+ g_source_remove (priv->changed_timeout);
|
||||
+ priv->changed_timeout = 0;
|
||||
+ }
|
||||
+ gtk_recent_manager_changed (manager);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+#ifdef DEBUG_FAM
|
||||
+static inline void
|
||||
+debug_event (FAMEvent *event)
|
||||
+{
|
||||
+#define PRINT_EVENT(str) g_print ("Got event: %d %s <" str ">\n", event->code, event->filename);
|
||||
+
|
||||
+ switch (event->code)
|
||||
+ {
|
||||
+ case FAMChanged:
|
||||
+ PRINT_EVENT ("changed");
|
||||
+ break;
|
||||
+ case FAMDeleted:
|
||||
+ PRINT_EVENT ("deleted");
|
||||
+ break;
|
||||
+ case FAMStartExecuting:
|
||||
+ PRINT_EVENT ("start-executing");
|
||||
+ break;
|
||||
+ case FAMStopExecuting:
|
||||
+ PRINT_EVENT ("stop-executing");
|
||||
+ break;
|
||||
+ case FAMCreated:
|
||||
+ PRINT_EVENT ("created");
|
||||
+ break;
|
||||
+ case FAMAcknowledge:
|
||||
+ PRINT_EVENT ("acknowledge");
|
||||
+ break;
|
||||
+ case FAMExists:
|
||||
+ PRINT_EVENT ("exists");
|
||||
+ break;
|
||||
+ case FAMEndExist:
|
||||
+ PRINT_EVENT ("end-exist");
|
||||
+ break;
|
||||
+ case FAMMoved:
|
||||
+ PRINT_EVENT ("moved");
|
||||
+ break;
|
||||
+ default:
|
||||
+ PRINT_EVENT ("invalid");
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+#undef PRINT_EVENT
|
||||
+}
|
||||
+#else
|
||||
+#define debug_event(event)
|
||||
+#endif
|
||||
+
|
||||
+static gboolean
|
||||
+process_fam_events (void)
|
||||
+{
|
||||
+ if (failed_to_connect)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ while (fam_pending (&fam_connection))
|
||||
+ {
|
||||
+ FAMEvent event;
|
||||
+
|
||||
+ if (fam_next_event (&fam_connection, &event) != 1)
|
||||
+ {
|
||||
+ g_warning ("Failed to read next event from FAM");
|
||||
+ failed_to_connect = TRUE;
|
||||
+ fam_close (&fam_connection);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ debug_event (&event);
|
||||
+
|
||||
+ if (event.code != FAMChanged &&
|
||||
+ event.code != FAMCreated &&
|
||||
+ event.code != FAMDeleted)
|
||||
+ continue;
|
||||
+
|
||||
+ handle_fam_event (event.userdata, &event);
|
||||
+ }
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+static gboolean
|
||||
+fam_data_pending (GIOChannel *source,
|
||||
+ GIOCondition condition)
|
||||
+{
|
||||
+ g_assert (condition == G_IO_IN || condition == G_IO_PRI);
|
||||
+
|
||||
+ if (!process_fam_events ())
|
||||
+ {
|
||||
+ fam_io_watch = 0;
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ return TRUE; /* do come again */
|
||||
+}
|
||||
+
|
||||
+static FAMConnection *
|
||||
+get_fam_connection (void)
|
||||
+{
|
||||
+ if (!opened_connection)
|
||||
+ {
|
||||
+ opened_connection = TRUE;
|
||||
+
|
||||
+ open_libfam ();
|
||||
+
|
||||
+ if (fam_open != NULL &&
|
||||
+ fam_open (&fam_connection) == 0)
|
||||
+ {
|
||||
+ GIOChannel *io_channel;
|
||||
+
|
||||
+ io_channel = g_io_channel_unix_new (fam_connection.fd);
|
||||
+ fam_io_watch = g_io_add_watch (io_channel,
|
||||
+ G_IO_IN|G_IO_PRI,
|
||||
+ (GIOFunc) fam_data_pending,
|
||||
+ NULL);
|
||||
+ g_io_channel_unref (io_channel);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ g_warning ("Failed to connect to the FAM server");
|
||||
+ failed_to_connect = TRUE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return failed_to_connect ? NULL : &fam_connection;
|
||||
+}
|
||||
+
|
||||
+static FAMRequest *
|
||||
+register_fam_monitor (const gchar *path,
|
||||
+ gpointer user_data)
|
||||
+{
|
||||
+ FAMConnection *fam_connection;
|
||||
+ FAMRequest *request;
|
||||
+
|
||||
+ if ((fam_connection = get_fam_connection ()) == NULL)
|
||||
+ {
|
||||
+ g_warning ("Not adding file monitor on '%s', "
|
||||
+ "failed to connect to FAM server\n",
|
||||
+ path);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ /* Need to process any pending events, otherwise we may block
|
||||
+ * on write - i.e. the FAM sever is blocked because its write
|
||||
+ * buffer is full notifying us of events, we need to read those
|
||||
+ * events before it can process our new request.
|
||||
+ */
|
||||
+ if (!process_fam_events ())
|
||||
+ {
|
||||
+ g_source_remove (fam_io_watch);
|
||||
+ fam_io_watch = 0;
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ request = g_new0 (FAMRequest, 1);
|
||||
+
|
||||
+ if (fam_monitor_file (fam_connection, path, request, user_data) != 0)
|
||||
+ {
|
||||
+ g_warning ("Failed to add file monitor on '%s'", path);
|
||||
+ g_free (request);
|
||||
+
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+#ifdef DEBUG_FAM
|
||||
+ g_print ("registering file monitor for '%s'\n", path);
|
||||
+#endif
|
||||
+
|
||||
+ return request;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+unregister_fam_monitor (FAMRequest *request)
|
||||
+{
|
||||
+ if (failed_to_connect)
|
||||
+ return;
|
||||
+
|
||||
+ if (request != NULL)
|
||||
+ fam_cancel_monitor (&fam_connection, request);
|
||||
+
|
||||
+ /* Need to process any remaining events for this monitor
|
||||
+ */
|
||||
+ if (!process_fam_events ())
|
||||
+ {
|
||||
+ g_source_remove (fam_io_watch);
|
||||
+ fam_io_watch = 0;
|
||||
+ }
|
||||
+
|
||||
+#ifdef DEBUG_FAM
|
||||
+ g_print ("unregistering file monitor\n");
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+/* end of fam support */
|
||||
+
|
||||
+
|
||||
static void
|
||||
gtk_recent_manager_init (GtkRecentManager *manager)
|
||||
{
|
||||
@@ -296,9 +605,12 @@
|
||||
priv->filename = g_build_filename (g_get_home_dir (),
|
||||
GTK_RECENTLY_USED_FILE,
|
||||
NULL);
|
||||
- priv->poll_timeout = g_timeout_add (POLL_DELTA,
|
||||
- gtk_recent_manager_poll_timeout,
|
||||
- manager);
|
||||
+
|
||||
+ priv->fam_request = register_fam_monitor (priv->filename, manager);
|
||||
+ if (priv->fam_request == NULL)
|
||||
+ priv->poll_timeout = g_timeout_add (POLL_DELTA,
|
||||
+ gtk_recent_manager_poll_timeout,
|
||||
+ manager);
|
||||
|
||||
build_recent_items_list (manager);
|
||||
}
|
||||
@@ -356,10 +668,19 @@
|
||||
GtkRecentManager *manager = GTK_RECENT_MANAGER (object);
|
||||
GtkRecentManagerPrivate *priv = manager->priv;
|
||||
|
||||
+ if (priv->fam_request)
|
||||
+ {
|
||||
+ unregister_fam_monitor (priv->fam_request);
|
||||
+ g_free (priv->fam_request);
|
||||
+ priv->fam_request = NULL;
|
||||
+ }
|
||||
+ if (priv->changed_timeout)
|
||||
+ g_source_remove (priv->changed_timeout);
|
||||
+
|
||||
/* remove the poll timeout */
|
||||
if (priv->poll_timeout)
|
||||
g_source_remove (priv->poll_timeout);
|
||||
-
|
||||
+
|
||||
if (priv->filename)
|
||||
g_free (priv->filename);
|
||||
|
||||
@@ -499,18 +820,28 @@
|
||||
if (!filename || filename[0] == '\0')
|
||||
return;
|
||||
|
||||
- g_free (manager->priv->filename);
|
||||
+ g_free (priv->filename);
|
||||
|
||||
- if (manager->priv->poll_timeout)
|
||||
+ if (priv->fam_request)
|
||||
{
|
||||
- g_source_remove (manager->priv->poll_timeout);
|
||||
- manager->priv->poll_timeout = 0;
|
||||
+ unregister_fam_monitor (priv->fam_request);
|
||||
+ g_free (priv->fam_request);
|
||||
+ priv->fam_request = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (priv->poll_timeout)
|
||||
+ {
|
||||
+ g_source_remove (priv->poll_timeout);
|
||||
+ priv->poll_timeout = 0;
|
||||
}
|
||||
|
||||
priv->filename = g_strdup (filename);
|
||||
- priv->poll_timeout = g_timeout_add (POLL_DELTA,
|
||||
- gtk_recent_manager_poll_timeout,
|
||||
- manager);
|
||||
+
|
||||
+ priv->fam_request = register_fam_monitor (priv->filename, manager);
|
||||
+ if (priv->fam_request == NULL)
|
||||
+ priv->poll_timeout = g_timeout_add (POLL_DELTA,
|
||||
+ gtk_recent_manager_poll_timeout,
|
||||
+ manager);
|
||||
|
||||
/* mark us clean, so that we can re-read the list
|
||||
* of recently used resources
|
13
gtk2.spec
13
gtk2.spec
@ -16,7 +16,7 @@
|
||||
Summary: The GIMP ToolKit (GTK+), a library for creating GUIs for X
|
||||
Name: gtk2
|
||||
Version: %{base_version}
|
||||
Release: 1%{?dist}
|
||||
Release: 2%{?dist}
|
||||
License: LGPL
|
||||
Group: System Environment/Libraries
|
||||
Source: gtk+-%{version}.tar.bz2
|
||||
@ -28,11 +28,14 @@ Patch0: gtk+-2.4.1-lib64.patch
|
||||
Patch1: gtk+-2.8.10-set-invisible-char-to-bullet.patch
|
||||
# Filechooser search
|
||||
Patch2: gtk+-2.10.3-search.patch
|
||||
# use fam for recent-files
|
||||
Patch3: gtk+-2.10.3-fam.patch
|
||||
|
||||
# backport from HEAD
|
||||
Patch7: gtk+-2.10.2-cursor-blink.patch
|
||||
Patch8: gtk+-2.10.2-im-reset.patch
|
||||
|
||||
|
||||
BuildPrereq: atk-devel >= %{atk_version}
|
||||
BuildPrereq: pango-devel >= %{pango_version}
|
||||
BuildPrereq: glib2-devel >= %{glib2_version}
|
||||
@ -50,6 +53,8 @@ BuildRequires: libXrender-devel
|
||||
BuildRequires: libXcursor-devel
|
||||
BuildRequires: libXfixes-devel
|
||||
BuildRequires: libXinerama-devel
|
||||
# for patch 3
|
||||
BuildRequires: gamin-devel
|
||||
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
Obsoletes: gtk+-gtkbeta
|
||||
@ -112,6 +117,7 @@ tar xzf %{SOURCE1}
|
||||
%patch0 -p1 -b .lib64
|
||||
%patch1 -p1 -b .set-invisible-char-to-bullet
|
||||
%patch2 -p1 -b .search
|
||||
%patch3 -p1 -b .fam
|
||||
|
||||
%patch7 -p0 -b .cursor-blink
|
||||
%patch8 -p1 -b .im-reset
|
||||
@ -124,6 +130,8 @@ done
|
||||
libtoolize --force
|
||||
|
||||
# Patch3 modifies gdk-pixbuf/Makefile.am
|
||||
# Patch9 modifies configure.in
|
||||
autoheader
|
||||
aclocal-1.7
|
||||
automake-1.7
|
||||
|
||||
@ -286,6 +294,9 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%doc tmpdocs/examples
|
||||
|
||||
%changelog
|
||||
* Mon Sep 5 2006 Matthias Clasen <mclasen@redhat.com> - 2.10.3-2.fc6
|
||||
- Use fam for recent files
|
||||
|
||||
* Tue Sep 5 2006 Matthias Clasen <mclasen@redhat.com> - 2.10.3-1.fc6
|
||||
- Update to 2.10.3
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user