summaryrefslogtreecommitdiffstats
path: root/src/gui-gtk
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2011-03-24 18:45:51 +0100
committerDenys Vlasenko <dvlasenk@redhat.com>2011-03-24 18:45:51 +0100
commit14e071507d45f1c1668ddf569b0f285e21ea36b3 (patch)
treede008af2122dca8b95e00acca04a3df3f6a9cc79 /src/gui-gtk
parent03f8ae7ca047cd8027ed789ee045655db327de38 (diff)
downloadabrt-14e071507d45f1c1668ddf569b0f285e21ea36b3.tar.gz
abrt-14e071507d45f1c1668ddf569b0f285e21ea36b3.tar.xz
abrt-14e071507d45f1c1668ddf569b0f285e21ea36b3.zip
abrt-gui: add inotify-based reloading of dumps
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Diffstat (limited to 'src/gui-gtk')
-rw-r--r--src/gui-gtk/abrt-gtk.c37
-rw-r--r--src/gui-gtk/abrt-gtk.h5
-rw-r--r--src/gui-gtk/main.c76
3 files changed, 109 insertions, 9 deletions
diff --git a/src/gui-gtk/abrt-gtk.c b/src/gui-gtk/abrt-gtk.c
index ff8575fe..2a52e433 100644
--- a/src/gui-gtk/abrt-gtk.c
+++ b/src/gui-gtk/abrt-gtk.c
@@ -23,7 +23,7 @@
#include "abrt-gtk.h"
#include "libreport-gtk.h"
-static const char * const help_uri ="http://docs.fedoraproject.org/en-US/"
+static const char help_uri[] = "http://docs.fedoraproject.org/en-US/"
"Fedora/14/html/Deployment_Guide/ch-abrt.html";
static GtkListStore *s_dumps_list_store;
@@ -84,6 +84,12 @@ void add_directory_to_dirlist(const char *dirname)
VERB1 log("added: %s", dirname);
}
+void rescan_dirs_and_add_to_dirlist(void)
+{
+ gtk_list_store_clear(s_dumps_list_store);
+ scan_dirs_and_add_to_dirlist();
+}
+
/* create_main_window and helpers */
@@ -143,8 +149,7 @@ static void delete_report(GtkTreeView *treeview)
{
/* Strange. Deletion did not succeed. Someone else deleted it?
* Rescan the whole list */
- gtk_list_store_clear(s_dumps_list_store);
- scan_dirs_and_add_to_dirlist();
+ rescan_dirs_and_add_to_dirlist();
}
/* Try to retain the same cursor position */
@@ -183,9 +188,9 @@ static void on_menu_help_cb(GtkMenuItem *menuitem, gpointer unused)
static void on_menu_about_cb(GtkMenuItem *menuitem, gpointer unused)
{
- const char *copyright_str = "Copyright © 2009, 2010, 2011 Red Hat, Inc";
+ static const char copyright_str[] = "Copyright © 2009, 2010, 2011 Red Hat, Inc";
- const char *license_str = "This program is free software; you can redistribut"
+ static const char license_str[] = "This program is free software; you can redistribut"
"e it and/or modify it under the terms of the GNU General Public License "
"as published by the Free Software Foundation; either version 2 of the Li"
"cense, or (at your option) any later version.\n\nThis program is distrib"
@@ -195,9 +200,9 @@ static void on_menu_about_cb(GtkMenuItem *menuitem, gpointer unused)
"u should have received a copy of the GNU General Public License along wi"
"th this program. If not, see <http://www.gnu.org/licenses/>.";
- const char *website_url = "https://fedorahosted.org/abrt/";
+ static const char website_url[] = "https://fedorahosted.org/abrt/";
- const char *authors[] = {
+ static const char *authors[] = {
"Anton Arapov <aarapov@redhat.com>",
"Karel Klic <kklic@redhat.com>",
"Jiri Moskovcak <jmoskovc@redhat.com>",
@@ -208,7 +213,7 @@ static void on_menu_about_cb(GtkMenuItem *menuitem, gpointer unused)
NULL
};
- const char *artists[] = {
+ static const char *artists[] = {
"Patrick Connelly <pcon@fedoraproject.org>",
"Máirín Duffy <duffy@fedoraproject.org>",
"Lapo Calamandrei",
@@ -413,6 +418,22 @@ GtkWidget *create_main_window(void)
return g_main_window;
}
+GtkTreePath *get_cursor(void)
+{
+ GtkTreeView *treeview = GTK_TREE_VIEW(s_treeview);
+ GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
+ if (selection)
+ {
+ GtkTreeIter iter;
+ GtkTreeModel *store = gtk_tree_view_get_model(treeview);
+ if (gtk_tree_selection_get_selected(selection, &store, &iter) == TRUE)
+ {
+ return gtk_tree_model_get_path(store, &iter);
+ }
+ }
+ return NULL;
+}
+
void sanitize_cursor(GtkTreePath *preferred_path)
{
GtkTreePath *path;
diff --git a/src/gui-gtk/abrt-gtk.h b/src/gui-gtk/abrt-gtk.h
index 5dccc991..259797fa 100644
--- a/src/gui-gtk/abrt-gtk.h
+++ b/src/gui-gtk/abrt-gtk.h
@@ -18,6 +18,9 @@
*/
GtkWidget *create_main_window(void);
void add_directory_to_dirlist(const char *dirname);
+/* May return NULL */
+GtkTreePath *get_cursor(void);
void sanitize_cursor(GtkTreePath *preferred_path);
+void rescan_dirs_and_add_to_dirlist(void);
-void scan_dirs_and_add_to_dirlist();
+void scan_dirs_and_add_to_dirlist(void);
diff --git a/src/gui-gtk/main.c b/src/gui-gtk/main.c
index fd1e9d57..10a15af4 100644
--- a/src/gui-gtk/main.c
+++ b/src/gui-gtk/main.c
@@ -17,6 +17,7 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <gtk/gtk.h>
+#include <sys/inotify.h>
#include "abrtlib.h"
#include "parse_options.h"
#include "abrt-gtk.h"
@@ -26,8 +27,66 @@
#define PROGNAME "abrt-gtk"
+static int inotify_fd = -1;
+static GIOChannel *channel_inotify;
+static int channel_inotify_event_id = -1;
static char **s_dirs;
+static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpointer ptr_unused);
+
+static void init_notify(void)
+{
+ VERB1 log("Initializing inotify");
+ errno = 0;
+ inotify_fd = inotify_init();
+ if (inotify_fd < 0)
+ perror_msg("inotify_init failed");
+ else
+ {
+ close_on_exec_on(inotify_fd);
+ VERB1 log("Adding inotify watch to glib main loop");
+ channel_inotify = g_io_channel_unix_new(inotify_fd);
+ channel_inotify_event_id = g_io_add_watch(channel_inotify,
+ G_IO_IN,
+ handle_inotify_cb,
+ NULL);
+ }
+}
+
+static void close_notify(void)
+{
+ //VERB1 log("g_source_remove:");
+ g_source_remove(channel_inotify_event_id);
+ //VERB1 log("g_io_channel_unref:");
+ g_io_channel_unref(channel_inotify);
+ //VERB1 log("close(inotify_fd):");
+ close(inotify_fd);
+ //VERB1 log("Done");
+}
+
+/* Inotify handler */
+static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpointer ptr_unused)
+{
+ GtkTreePath *old_path = get_cursor();
+ //log("old_path1:'%s'", gtk_tree_path_to_string(old_path)); //leak
+
+ /* We don't bother reading inotify fd. We simply close and reopen it.
+ * This happens rarely enough to not bother making it efficient.
+ */
+ close_notify();
+ init_notify();
+
+ rescan_dirs_and_add_to_dirlist();
+
+ /* Try to restore cursor position */
+ //log("old_path2:'%s'", gtk_tree_path_to_string(old_path)); //leak
+ sanitize_cursor(old_path);
+ if (old_path)
+ gtk_tree_path_free(old_path);
+
+ return TRUE; /* "please don't remove this event" */
+}
+
static void scan_directory_and_add_to_dirlist(const char *path)
{
DIR *dp = opendir(path);
@@ -51,6 +110,21 @@ static void scan_directory_and_add_to_dirlist(const char *path)
free(full_name);
}
closedir(dp);
+
+ if (inotify_fd >= 0 && inotify_add_watch(inotify_fd, path, 0
+ // | IN_ATTRIB // Metadata changed
+ // | IN_CLOSE_WRITE // File opened for writing was closed
+ | IN_CREATE // File/directory created in watched directory
+ | IN_DELETE // File/directory deleted from watched directory
+ | IN_DELETE_SELF // Watched file/directory was itself deleted
+ | IN_MODIFY // File was modified
+ | IN_MOVE_SELF // Watched file/directory was itself moved
+ | IN_MOVED_FROM // File moved out of watched directory
+ | IN_MOVED_TO // File moved into watched directory
+ ) < 0)
+ {
+ perror_msg("inotify_add_watch failed on '%s'", path);
+ }
}
void scan_dirs_and_add_to_dirlist(void)
@@ -110,6 +184,8 @@ int main(int argc, char **argv)
}
s_dirs = argv;
+ init_notify();
+
scan_dirs_and_add_to_dirlist();
gtk_widget_show_all(main_window);