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

2017-04-01 Thread David C. Rankin
On 04/01/2017 01:04 PM, cecas...@aol.com wrote:
> 
> 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
> 

Thank you Eric,

  I will tinker with what you have tried and see if I can figure out more how
GFileMonitor signal handling is different from default GTK. I've gotten some
suggestions on StackOverflow, but more simply confirm your and my findings.
Since GIO handling of the emission and blocking of "changed" is a big black
box without picking though the source code, there are suggestions to just save
the file 'stat' information and compare against any changed signal for foreign
modification and setting a 'save' flag to ignore the "changed" signal during
normal file saves.

  It's frustrating that the GFileMonitor "changed" signal handler block
doesn't follow the normal block/unblock convention based on 'instance' and
'handler_id' alone. That certainly would provide a much more elegant solution.
Worse case, I can always resort to the original 'inotify' implementation as
the custom signal works fine with block/unblock. I'll just have to play with
invoking the read from pselect with a g_idle_add of the callback that does
that. I haven't played with that yet (as I've been chasing my tail on the
GFileMonitor issue in spare time).


-- 
David C. Rankin, J.D.,P.E.
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


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

2017-04-01 Thread Eric Cashon via gtk-app-devel-list

 
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

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(1);
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;
  }


 

 



___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list