[gnome-builder] buffer: try even harder to detect changes



commit 1828c1bae0f7c102497356c6046eedb586610c00
Author: Christian Hergert <christian hergert me>
Date:   Sun May 17 19:22:16 2015 -0700

    buffer: try even harder to detect changes
    
    Lots of little inconsistencies all over the place here. But this seems
    to be catching them.
    
    One thing not handled yet.
    
     - File changes
     - User ignores change
     - File changes
     * No additional change notification
    
    However, save will continue to work.

 libide/ide-buffer-manager.c |   38 +++++++++++++++++++++++++++++++++++++-
 libide/ide-buffer.c         |   43 +++++++++++++++++++++++++++++++++----------
 2 files changed, 70 insertions(+), 11 deletions(-)
---
diff --git a/libide/ide-buffer-manager.c b/libide/ide-buffer-manager.c
index 7410028..25ceb12 100644
--- a/libide/ide-buffer-manager.c
+++ b/libide/ide-buffer-manager.c
@@ -794,6 +794,35 @@ ide_buffer_manager_load_file_finish (IdeBufferManager  *self,
 }
 
 static void
+ide_buffer_manager__buffer_reload_mtime_cb (GObject      *object,
+                                            GAsyncResult *result,
+                                            gpointer      user_data)
+{
+  GFile *file = (GFile *)object;
+  g_autoptr(GFileInfo) file_info = NULL;
+  g_autoptr(GTask) task = user_data;
+  SaveState *state;
+
+  g_assert (G_IS_TASK (task));
+
+  state = g_task_get_task_data (task);
+  g_assert (state != NULL);
+  g_assert (IDE_IS_BUFFER (state->buffer));
+
+  if ((file_info = g_file_query_info_finish (file, result, NULL)))
+    {
+      GTimeVal tv;
+
+      g_file_info_get_modification_time (file_info, &tv);
+      _ide_buffer_set_mtime (state->buffer, &tv);
+    }
+
+  _ide_buffer_set_changed_on_volume (state->buffer, FALSE);
+
+  g_task_return_boolean (task, TRUE);
+}
+
+static void
 ide_buffer_manager_save_file__save_cb (GObject      *object,
                                        GAsyncResult *result,
                                        gpointer      user_data)
@@ -842,7 +871,14 @@ ide_buffer_manager_save_file__save_cb (GObject      *object,
   g_signal_emit (self, gSignals [BUFFER_SAVED], 0, state->buffer);
   g_signal_emit_by_name (state->buffer, "saved");
 
-  g_task_return_boolean (task, TRUE);
+  /* Reload the mtime for the buffer */
+  g_file_query_info_async (gfile,
+                           G_FILE_ATTRIBUTE_TIME_MODIFIED,
+                           G_FILE_QUERY_INFO_NONE,
+                           G_PRIORITY_DEFAULT,
+                           g_task_get_cancellable (task),
+                           ide_buffer_manager__buffer_reload_mtime_cb,
+                           g_object_ref (task));
 }
 
 static void
diff --git a/libide/ide-buffer.c b/libide/ide-buffer.c
index 44e82d3..a9ae57c 100644
--- a/libide/ide-buffer.c
+++ b/libide/ide-buffer.c
@@ -802,13 +802,15 @@ do_check_modified (gpointer user_data)
   IdeBuffer *self = user_data;
   IdeBufferPrivate *priv = ide_buffer_get_instance_private (self);
 
+  IDE_ENTRY;
+
   g_assert (IDE_IS_BUFFER (self));
 
   priv->check_modified_timeout = 0;
 
   ide_buffer_check_for_volume_change (self);
 
-  return G_SOURCE_REMOVE;
+  IDE_RETURN (G_SOURCE_REMOVE);
 }
 
 static void
@@ -836,6 +838,8 @@ ide_buffer__file_monitor_changed (IdeBuffer         *self,
                                   GFileMonitorEvent  event,
                                   GFileMonitor      *file_monitor)
 {
+  IDE_ENTRY;
+
   g_assert (IDE_IS_BUFFER (self));
   g_assert (G_IS_FILE (file));
   g_assert (G_IS_FILE_MONITOR (file_monitor));
@@ -844,21 +848,24 @@ ide_buffer__file_monitor_changed (IdeBuffer         *self,
     {
     case G_FILE_MONITOR_EVENT_CHANGED:
     case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+    case G_FILE_MONITOR_EVENT_MOVED:
+    case G_FILE_MONITOR_EVENT_RENAMED:
+    case G_FILE_MONITOR_EVENT_CREATED:
+    case G_FILE_MONITOR_EVENT_DELETED:
+      IDE_TRACE_MSG ("buffer change event = %d", (int)event);
       ide_buffer_queue_modify_check (self);
       break;
 
-    case G_FILE_MONITOR_EVENT_DELETED:
-    case G_FILE_MONITOR_EVENT_CREATED:
-    case G_FILE_MONITOR_EVENT_RENAMED:
     case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
     case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
     case G_FILE_MONITOR_EVENT_UNMOUNTED:
-    case G_FILE_MONITOR_EVENT_MOVED:
     case G_FILE_MONITOR_EVENT_MOVED_IN:
     case G_FILE_MONITOR_EVENT_MOVED_OUT:
     default:
       break;
     }
+
+  IDE_EXIT;
 }
 
 static void
@@ -882,13 +889,23 @@ ide_buffer__file_notify_file (IdeBuffer  *self,
 
   if (gfile != NULL)
     {
+      GError *error = NULL;
+
       priv->file_monitor = g_file_monitor_file (gfile, G_FILE_MONITOR_NONE, NULL, NULL);
+
       if (priv->file_monitor != NULL)
-        g_signal_connect_object (priv->file_monitor,
-                                 "changed",
-                                 G_CALLBACK (ide_buffer__file_monitor_changed),
-                                 self,
-                                 G_CONNECT_SWAPPED);
+        {
+          g_signal_connect_object (priv->file_monitor,
+                                   "changed",
+                                   G_CALLBACK (ide_buffer__file_monitor_changed),
+                                   self,
+                                   G_CONNECT_SWAPPED);
+        }
+      else
+        {
+          g_debug ("Failed to create GFileMonitor: %s", error->message);
+          g_clear_error (&error);
+        }
     }
 }
 
@@ -1356,6 +1373,12 @@ ide_buffer_set_file (IdeBuffer *self,
       ide_buffer_reload_change_monitor (self);
       ide_buffer_reload_highlighter (self);
       ide_buffer_reload_symbol_provider (self);
+      /*
+       * FIXME: More hack for 3.16.3. This all needs refactorying.
+       *        In particular, IdeFile should probably subclass GtkSourceFile.
+       */
+      if (file != NULL)
+        ide_buffer__file_notify_file (self, NULL, file);
       ide_buffer_update_title (self);
       g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_FILE]);
       g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_TITLE]);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]