]> code.delx.au - gnu-emacs/blobdiff - src/gfilenotify.c
* test/lisp/help-fns-tests.el: Add several tests for 'describe-function'.
[gnu-emacs] / src / gfilenotify.c
index 1439666f5f82c7a749c127843a6fc239a4edf94d..3b1f2fc516ac3b36feaae01783c84cbf1d57b25c 100644 (file)
@@ -1,12 +1,12 @@
 /* Filesystem notifications support with glib API.
-   Copyright (C) 2013-2015 Free Software Foundation, Inc.
+   Copyright (C) 2013-2016 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -23,13 +23,11 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <gio/gio.h>
 #include "lisp.h"
 #include "coding.h"
-#include "frame.h"
 #include "termhooks.h"
 #include "keyboard.h"
-#include "process.h"
 
 \f
-/* This is a list, elements are triples (DESCRIPTOR FILE CALLBACK)  */
+/* This is a list, elements are triples (DESCRIPTOR FILE FLAGS CALLBACK)  */
 static Lisp_Object watch_list;
 
 /* This is the callback function for arriving signals from
@@ -42,7 +40,7 @@ dir_monitor_callback (GFileMonitor *monitor,
                      GFileMonitorEvent event_type,
                      gpointer user_data)
 {
-  Lisp_Object symbol, monitor_object, watch_object;
+  Lisp_Object symbol, monitor_object, watch_object, flags;
   char *name = g_file_get_parse_name (file);
   char *oname = other_file ? g_file_get_parse_name (other_file) : NULL;
 
@@ -84,26 +82,36 @@ dir_monitor_callback (GFileMonitor *monitor,
 
   if (CONSP (watch_object))
     {
-      /* Construct an event.  */
       struct input_event event;
       Lisp_Object otail = oname ? list1 (build_string (oname)) : Qnil;
-      EVENT_INIT (event);
-      event.kind = FILE_NOTIFY_EVENT;
-      event.frame_or_window = Qnil;
-      event.arg = list2 (Fcons (monitor_object,
-                               Fcons (symbol,
-                                      Fcons (build_string (name),
-                                             otail))),
-                        XCAR (XCDR (XCDR (watch_object))));
-
-      /* Store it into the input event queue.  */
-      kbd_buffer_store_event (&event);
+
+      /* Check, whether event_type is expected.  */
+      flags = XCAR (XCDR (XCDR (watch_object)));
+      if ((!NILP (Fmember (Qchange, flags)) &&
+          !NILP (Fmember (symbol, list5 (Qchanged, Qchanges_done_hint,
+                                         Qdeleted, Qcreated, Qmoved)))) ||
+         (!NILP (Fmember (Qattribute_change, flags)) &&
+          ((EQ (symbol, Qattribute_changed)))))
+       {
+         /* Construct an event.  */
+         EVENT_INIT (event);
+         event.kind = FILE_NOTIFY_EVENT;
+         event.frame_or_window = Qnil;
+         event.arg = list2 (Fcons (monitor_object,
+                                   Fcons (symbol,
+                                          Fcons (build_string (name),
+                                                 otail))),
+                            XCAR (XCDR (XCDR (XCDR (watch_object)))));
+
+         /* Store it into the input event queue.  */
+         kbd_buffer_store_event (&event);
+         // XD_DEBUG_MESSAGE ("%s", XD_OBJECT_TO_STRING (event.arg));
+       }
 
       /* Cancel monitor if file or directory is deleted.  */
-      if (((event_type == G_FILE_MONITOR_EVENT_DELETED) ||
-          (event_type == G_FILE_MONITOR_EVENT_MOVED)) &&
+      if (!NILP (Fmember (symbol, list2 (Qdeleted, Qmoved))) &&
          (strcmp (name, SSDATA (XCAR (XCDR (watch_object)))) == 0) &&
-         (!g_file_monitor_is_cancelled (monitor)))
+         !g_file_monitor_is_cancelled (monitor))
        g_file_monitor_cancel (monitor);
     }
 
@@ -127,9 +135,13 @@ watched for some reason, this function signals a `file-notify-error' error.
 FLAGS is a list of conditions to set what will be watched for.  It can
 include the following symbols:
 
-  `watch-mounts' -- watch for mount events
-  `send-moved'   -- pair `deleted' and `created' events caused by file
-                    renames and send a single `renamed' event instead
+  `change'           -- watch for file changes
+  `attribute-change' -- watch for file attributes changes, like
+                        permissions or modification time
+  `watch-mounts'     -- watch for mount events
+  `send-moved'       -- pair `deleted' and `created' events caused by
+                        file renames and send a single `renamed' event
+                        instead
 
 When any event happens, Emacs will call the CALLBACK function passing
 it a single argument EVENT, which is of the form
@@ -182,6 +194,7 @@ will be reported only in case of the `moved' event.  */)
 
   /* Enable watch.  */
   monitor = g_file_monitor (gfile, gflags, NULL, &gerror);
+  g_object_unref (gfile);
   if (gerror)
     {
       char msg[1024];
@@ -202,17 +215,21 @@ will be reported only in case of the `moved' event.  */)
                file);
     }
 
+  /* The default rate limit is 800 msec.  We adapt this.  */
+  g_file_monitor_set_rate_limit (monitor, 100);
+
+  /* Subscribe to the "changed" signal.  */
   g_signal_connect (monitor, "changed",
                    (GCallback) dir_monitor_callback, NULL);
 
   /* Store watch object in watch list.  */
-  watch_object = list3 (watch_descriptor, file, callback);
+  watch_object = list4 (watch_descriptor, file, flags, callback);
   watch_list = Fcons (watch_object, watch_list);
 
   return watch_descriptor;
 }
 
-DEFUN ("gfile-rm-watc", Fgfile_rm_watch, Sgfile_rm_watch, 1, 1, 0,
+DEFUN ("gfile-rm-watch", Fgfile_rm_watch, Sgfile_rm_watch, 1, 1, 0,
        doc: /* Remove an existing WATCH-DESCRIPTOR.
 
 WATCH-DESCRIPTOR should be an object returned by `gfile-add-watch'.  */)
@@ -279,6 +296,8 @@ syms_of_gfilenotify (void)
   defsubr (&Sgfile_valid_p);
 
   /* Filter objects.  */
+  DEFSYM (Qchange, "change");
+  DEFSYM (Qattribute_change, "attribute-change");
   DEFSYM (Qwatch_mounts, "watch-mounts"); /* G_FILE_MONITOR_WATCH_MOUNTS  */
   DEFSYM (Qsend_moved, "send-moved");  /* G_FILE_MONITOR_SEND_MOVED  */