Re: GFileMonitor - g_signal_handler_block "changed" signal doesn't block handler?




 
Hi David,

Not sure about this one. I tested some code out to see if I could figure it out. Had the same problem that 
you had with the "changed" signal not being blocked. If I change the rate of the file monitor and try to 
spool out the events, I can block the "changed" signal. Not something that I would recommend doing outside of 
testing so I suspect there is a better way to go about it. Blocking the "changed" signal isn't going to solve 
the problem of knowing where the change is coming from which can come from another process at any time. Maybe 
if you had a pid in the "changed" callback, then you could compare it with your program pid to see if the 
change is coming from your program or someplace else.

The following is what I tried using gedit and the terminal. Hopefully you get some better ideas.

Eric


/*
    gcc -Wall file_monitor1.c -o file_monitor1 `pkg-config --cflags --libs gtk+-3.0`
    Tested on Ubuntu16.04, GTK3.18 and gedit.
*/

#include<gtk/gtk.h>

guint signal_id=0;
GFileMonitor *filemon=NULL;
//The file to append to. Just the .c file that is in the same folder as the program.
gchar *path="file_monitor1.c";  

//Check file changes from gedit and the file_monitor1 program.
static void file_changed(GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, 
gpointer user_data)
  {
    g_print("File Changed\n");
  }
static void button_clicked(GtkWidget *button, GFile *gfile)
  {
    g_print("Block\n");
    g_signal_handler_block(filemon, signal_id);
    GError *err=NULL;
    GFileOutputStream *stream=g_file_append_to(gfile, G_FILE_CREATE_NONE, NULL, &err);
    if(err!=NULL) g_print("%s\n", err->message);
    g_output_stream_write((GOutputStream*)stream, "//\n", 3, NULL, &err);
    if(err!=NULL) g_print("%s\n", err->message);
    g_output_stream_close((GOutputStream*)stream, NULL, &err);
    if(err!=NULL) g_print("%s\n", err->message);
    g_object_unref(stream);

    /*
      Give GIO some time to post the event. This is a test. Don't do this otherwise.
      From gfilemonitor.c
      #define DEFAULT_RATE_LIMIT_MSECS 800 for filemon.
    */
    g_file_monitor_set_rate_limit(filemon, 100);
    g_usleep(10000);
    while(gtk_events_pending()) gtk_main_iteration();
    g_file_monitor_set_rate_limit(filemon, 800);

    g_signal_handler_unblock(filemon, signal_id);
    g_print("Unblock\n");
    if(err!=NULL) g_error_free(err);
  }
int main(int argc, char *argv[])
  {
    gtk_init(&argc, &argv);

    GtkWidget *window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "File Monitor");
    gtk_window_set_default_size(GTK_WINDOW(window), 200, 100);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_container_set_border_width(GTK_CONTAINER(window), 20);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    
    GFile *gfile=g_file_new_for_path(path);
    filemon=g_file_monitor_file(gfile, G_FILE_MONITOR_NONE, NULL, NULL);
    signal_id=g_signal_connect(filemon, "changed", G_CALLBACK(file_changed), NULL);

    GtkWidget *button=gtk_button_new_with_label("Append to file_monitor1.c");
    gtk_widget_set_hexpand(button, TRUE);
    gtk_widget_set_vexpand(button, TRUE);
    g_signal_connect(button, "clicked", G_CALLBACK(button_clicked), gfile);

    GtkWidget *grid=gtk_grid_new();
    gtk_grid_attach(GTK_GRID(grid), button, 0, 0, 1, 1);

    gtk_container_add(GTK_CONTAINER(window), grid);

    gtk_widget_show_all(window);
    
    gtk_main();

    g_object_unref(gfile);
    g_object_unref(filemon);

    return 0;
  }


 

 





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