Re: Howto integrate an inotify watch on editor file in GTK+2 event loop?



On 03/28/2017 01:34 PM, David C. Rankin wrote:
On 03/28/2017 02:06 AM, Emmanuele Bassi wrote:
Use GFileMonitor from GIO instead of directly dealing with inotify.

Ciao,
 Emmanuele.


Now that is the type of answer I was looking for! Thanks Emmanuele. That
definitely keeps it much cleaner.


Emmanuele,

  I need more help. I have implemented the watch with 'g_file_monitor_file'
and registered a callback on the "changed" signal for the file, but I cannot
get it to respond to any changes in the underlying file.

  Specifically, I created the GFileMonitor with:

GFileMonitor *file_monitor_add (const gchar *fn)
{
    GFile *gfile = g_file_new_for_path (fn);
    GCancellable *cancellable = g_cancellable_new();
    GError *err=NULL;

    GFileMonitor *filemon = g_file_monitor_file (gfile,
                                    G_FILE_MONITOR_NONE,
                                    cancellable, &err);
    if (!filemon) {
        err_dialog (err->message);
        g_error_free (err);
        g_object_unref (gfile);
        return NULL;
    }

    g_print ("added watch for '%s'\n", fn);

//     g_signal_connect (G_OBJECT(filemon), "changed",
//                     G_CALLBACK (file_monitor_on_changed), NULL);

    g_object_unref (gfile);

    return filemon;
}

NOTE: the first attempt to connect was shown above, but then according to the
documentation "The signal will be emitted in the thread-default main context
of the thread that the monitor was created". That has me confused (in addition
to the fact that the "changed" signal is never caught. I later connect at the
point the file is opened.

  The callback used (for testing purposes) is:

void file_monitor_on_changed (GFileMonitor *mon,
                            GFile *file, GFile *other,
                            GFileMonitorEvent evtype,
                            gpointer data)
{
    g_print ("Monitor Event: File = %s\n", g_file_get_parse_name (file));

    switch (evtype)
    {
        case G_FILE_MONITOR_EVENT_CHANGED:
            dlg_info ("File Changed.", "changed Event Received");
            break;
        case G_FILE_MONITOR_EVENT_DELETED:
            dlg_info ("File Deleted.", "changed Event Received");
            break;
        default:;
    }

    if (mon || other || data) {}
}

In the second attempt to connect, I moved connecting to the callback at the
point of file opening:

        else {  /* opening file */
            file_get_stats (filename, app); /* save file mode, UID, GID */
            gtk_text_buffer_set_modified (buffer , FALSE);    /* opened */
            app->modified = FALSE;
            status = g_strdup_printf ("loaded : '%s'", app->fname);
            gtkwrite_window_set_title (NULL, app);  /* set window title */
            /* add watch on file */
            GFileMonitor *fm = file_monitor_add (app->fname);
            g_signal_connect (G_OBJECT(fm), "changed",
                    G_CALLBACK (file_monitor_on_changed), NULL);

        }

I can switch to a terminal and change, delete, move the opened file and the
callback never fires -- what's the trick? At least with the inotify
implementation, there changes were easy to catch. I think I'm stumbling over the:

"The signal will be emitted in the thread-default main context of the thread
that the monitor was created"

What do I have to do special to insure I'm looking for the signal in the
"thread-default main context". The editor makes no special use of separate
threads. What am I missing here, if anything.


-- 
David C. Rankin, J.D.,P.E.


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