Author: kelnos
Date: 2006-07-16 10:06:10 +0000 (Sun, 16 Jul 2006)
New Revision: 22460
Added:
xfce-utils/trunk/xfrun/org.xfce.RunDialog.service.in
xfce-utils/trunk/xfrun/xfrun-dbus.c
Modified:
xfce-utils/trunk/configure.in.in
xfce-utils/trunk/po/POTFILES.in
xfce-utils/trunk/xfrun/Makefile.am
xfce-utils/trunk/xfrun/xfrun-dialog.c
xfce-utils/trunk/xfrun/xfrun-dialog.h
Log:
dbus daemon support for xfrun, a few memleak fixes, etc.
Modified: xfce-utils/trunk/configure.in.in
===================================================================
--- xfce-utils/trunk/configure.in.in 2006-07-16 08:17:54 UTC (rev 22459)
+++ xfce-utils/trunk/configure.in.in 2006-07-16 10:06:10 UTC (rev 22460)
@@ -37,8 +37,8 @@
dnl Check for standard header files
AC_HEADER_STDC
-AC_CHECK_HEADERS([unistd.h string.h])
-AC_CHECK_FUNCS([setsid])
+AC_CHECK_HEADERS([errno.h unistd.h string.h])
+AC_CHECK_FUNCS([daemon setsid])
dnl Check for X11 installed
XDT_CHECK_LIBX11_REQUIRE
Modified: xfce-utils/trunk/po/POTFILES.in
===================================================================
--- xfce-utils/trunk/po/POTFILES.in 2006-07-16 08:17:54 UTC (rev 22459)
+++ xfce-utils/trunk/po/POTFILES.in 2006-07-16 10:06:10 UTC (rev 22460)
@@ -2,3 +2,5 @@
xfce4-about/info.c
xfrun/xfrun.c
+xfrun/xfrun-dbus.c
+xfrun/xfrun-dialog.c
Modified: xfce-utils/trunk/xfrun/Makefile.am
===================================================================
--- xfce-utils/trunk/xfrun/Makefile.am 2006-07-16 08:17:54 UTC (rev 22459)
+++ xfce-utils/trunk/xfrun/Makefile.am 2006-07-16 10:06:10 UTC (rev 22460)
@@ -4,20 +4,21 @@
xfrun-dialog.c \
xfrun-dialog.h
-#if HAVE_DBUS
+if HAVE_DBUS
-#xfrun4_SOURCES += \
-# xfrun-dbus.c
+xfrun4_SOURCES += \
+ xfrun-dbus.c
-#else
+else
xfrun4_SOURCES += \
xfrun.c
-#endif
+endif
xfrun4_CFLAGS = \
-DLOCALEDIR=\"$(localedir)\" \
+ -DDBUS_API_SUBJECT_TO_CHANGE \
@LIBXFCE4UTIL_CFLAGS@ \
@LIBXFCEGUI4_CFLAGS@ \
@GTK_CFLAGS@ \
@@ -29,7 +30,23 @@
@GTK_LIBS@ \
@DBUS_LIBS@
+
+if HAVE_DBUS
+
+service_in_files = org.xfce.RunDialog.service.in
+
+servicedir = $(datadir)/dbus-1/services
+service_DATA = $(service_in_files:.service.in=.service)
+
+%.service: %.service.in
+ sed -e "s,[EMAIL PROTECTED]@,$(bindir),g" < $< > $@
+
+DISTCLEANFILES = \
+ $(service_DATA)
+
+endif
+
EXTRA_DIST = \
xfrun.c \
-
-# xfrun-dbus.c
+ xfrun-dbus.c \
+ $(service_in_files)
Added: xfce-utils/trunk/xfrun/org.xfce.RunDialog.service.in
===================================================================
--- xfce-utils/trunk/xfrun/org.xfce.RunDialog.service.in
(rev 0)
+++ xfce-utils/trunk/xfrun/org.xfce.RunDialog.service.in 2006-07-16
10:06:10 UTC (rev 22460)
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.xfce.RunDialog
[EMAIL PROTECTED]@/xfrun4 --daemon
Added: xfce-utils/trunk/xfrun/xfrun-dbus.c
===================================================================
--- xfce-utils/trunk/xfrun/xfrun-dbus.c (rev 0)
+++ xfce-utils/trunk/xfrun/xfrun-dbus.c 2006-07-16 10:06:10 UTC (rev 22460)
@@ -0,0 +1,377 @@
+/*
+ * xfrun - a simple quick run dialog with saved history and completion
+ * Jannis Pohlmann <[EMAIL PROTECTED]>
+ * Jani Monoses <[EMAIL PROTECTED]>
+ *
+ * Copyright (c) 2006 Brian J. Tarricone <[EMAIL PROTECTED]>
+ *
+ * This program is free software; you can redistribute 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 License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include <libxfce4util/libxfce4util.h>
+#include <libxfcegui4/libxfcegui4.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "xfrun-dialog.h"
+
+/**
+ * method: org.xfce.RunDialog.OpenDialog
+ * param: display_name (DBUS_TYPE_STRING)
+ * param: working_directory (DBUS_TYPE_STRING)
+ * param: run_argument (DBUS_TYPE_STRING)
+ * return: success, or org.xfce.RunDialog.ErrorGeneral
+ * description: shows the run dialog on the specified display. will execute
+ * the command in the specified working directory. an optional
+ * argument can be passed that will be passed to the program that
+ * is executed.
+ **
+ * method: org.xfce.RunDialog.Quit
+ * description: instructs the xfrun daemon to quit.
+ */
+#define RUNDIALOG_DBUS_SERVICE "org.xfce.RunDialog"
+#define RUNDIALOG_DBUS_INTERFACE "org.xfce.RunDialog"
+#define RUNDIALOG_DBUS_PATH "/org/xfce/RunDialog"
+#define RUNDIALOG_DBUS_METHOD_OPEN "OpenDialog"
+#define RUNDIALOG_DBUS_METHOD_QUIT "Quit"
+#define RUNDIALOG_DBUS_ERROR_GENERAL "org.xfce.RunDialog.ErrorGeneral"
+
+
+static GtkWidget *static_dialog = NULL;
+static gboolean static_dialog_in_use = FALSE;
+
+static void
+xfrun_static_dialog_closed(XfrunDialog *dialog,
+ gpointer user_data)
+{
+ static_dialog_in_use = FALSE;
+}
+
+/* gdk_display_close() is essentially broken on X11. so every time we call
+ * gdk_display_open(), we can't close it, and thus leak memory. instead, let's
+ * keep a cache of all open displays, and, in normal situations we'll only have
+ * one display open per screen.
+ */
+static GdkDisplay *
+xfrun_find_or_open_display(const gchar *display_name)
+{
+ static GHashTable *open_displays = NULL;
+ GdkDisplay *gdpy = NULL;
+
+ if(G_UNLIKELY(!open_displays)) {
+ open_displays = g_hash_table_new_full(g_str_hash, g_str_equal,
+ (GDestroyNotify)g_free, NULL);
+ }
+
+ gdpy = g_hash_table_lookup(open_displays, display_name);
+ if(!gdpy) {
+ gdpy = gdk_display_open(display_name);
+ if(gdpy)
+ g_hash_table_insert(open_displays, g_strdup(display_name), gdpy);
+ }
+
+ return gdpy;
+}
+
+
+/* server message handler */
+static DBusHandlerResult
+xfrun_handle_dbus_message(DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data)
+{
+ if(dbus_message_is_method_call(message,
+ RUNDIALOG_DBUS_INTERFACE,
+ RUNDIALOG_DBUS_METHOD_OPEN))
+ {
+ DBusMessage *reply = NULL;
+ DBusError derror;
+ gchar *display_name = NULL, *cwd = NULL, *run_argument = NULL;
+
+ dbus_error_init(&derror);
+
+ if(!dbus_message_get_args(message, &derror,
+ DBUS_TYPE_STRING, &display_name,
+ DBUS_TYPE_STRING, &cwd,
+ DBUS_TYPE_STRING, &run_argument,
+ DBUS_TYPE_INVALID))
+ {
+ reply = dbus_message_new_error(message,
RUNDIALOG_DBUS_ERROR_GENERAL,
+ derror.message);
+ dbus_error_free(&derror);
+ } else {
+ GdkDisplay *gdpy;
+ GdkScreen *gscreen = NULL;
+
+ gdpy = xfrun_find_or_open_display(display_name);
+ if(!gdpy) {
+ gchar *msgstr = g_strdup_printf(_("Unable to open display
\"%s\"."),
+ display_name);
+ reply = dbus_message_new_error(message,
+ RUNDIALOG_DBUS_ERROR_GENERAL,
+ msgstr);
+ g_free(msgstr);
+ } else {
+ GtkWidget *dialog;
+
+ gscreen = gdk_display_get_default_screen(gdpy);
+
+ if(!strlen(run_argument))
+ run_argument = NULL;
+
+ if(static_dialog_in_use) {
+ dialog = xfrun_dialog_new(run_argument);
+ xfrun_dialog_set_destroy_on_close(XFRUN_DIALOG(dialog),
+ TRUE);
+ xfrun_dialog_set_working_directory(XFRUN_DIALOG(dialog),
+ cwd);
+ } else {
+ dialog = static_dialog;
+ xfrun_dialog_set_run_argument(XFRUN_DIALOG(dialog),
+ run_argument);
+ xfrun_dialog_set_working_directory(XFRUN_DIALOG(dialog),
+ cwd);
+ if(GTK_WIDGET_REALIZED(dialog)) {
+ gdk_x11_window_set_user_time(dialog->window,
+
gdk_x11_get_server_time(dialog->window));
+ }
+ static_dialog_in_use = TRUE;
+ }
+
+ /* this handles setting the dialog to the right screen */
+ xfce_gtk_window_center_on_monitor(GTK_WINDOW(dialog),
+ gscreen, 0);
+ gtk_widget_show(dialog);
+
+ reply = dbus_message_new_method_return(message);
+
+ }
+ }
+
+ dbus_connection_send(connection, reply, NULL);
+ dbus_message_unref(reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+ } else if(dbus_message_is_method_call(message,
+ RUNDIALOG_DBUS_INTERFACE,
+ RUNDIALOG_DBUS_METHOD_QUIT))
+ {
+ DBusMessage *reply = dbus_message_new_method_return(message);
+ dbus_connection_send(connection, reply, NULL);
+ dbus_message_unref(reply);
+
+ gtk_main_quit();
+ } else if(dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL,
+ "Disconnected"))
+ {
+ g_printerr(_("D-BUS message bus disconnected. Exiting ...\n"));
+ gtk_main_quit();
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+/* server registration */
+static gboolean
+xfrun_register_dbus_service()
+{
+ static const struct DBusObjectPathVTable vtable = {
+ NULL,
+ xfrun_handle_dbus_message,
+ NULL,
+ };
+ DBusConnection *connection;
+ DBusError derror;
+
+ dbus_error_init(&derror);
+ connection = dbus_bus_get(DBUS_BUS_SESSION, &derror);
+ if(G_UNLIKELY(!connection)) {
+ dbus_error_free(&derror);
+ return FALSE;
+ }
+
+ dbus_connection_setup_with_g_main(connection, NULL);
+
+ if(dbus_bus_request_name(connection, RUNDIALOG_DBUS_SERVICE, 0, &derror) <
0) {
+ dbus_error_free(&derror);
+ return FALSE;
+ }
+
+ if(!dbus_connection_register_object_path(connection, RUNDIALOG_DBUS_PATH,
+ &vtable, NULL))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* client handler */
+static gboolean
+xfrun_show_dialog(const gchar *run_argument)
+{
+ DBusConnection *connection;
+ DBusMessage *method;
+ DBusMessage *result;
+ DBusError derror;
+ gchar *cwd, *display_name, *dummy_run_argument = NULL;
+
+ dbus_error_init(&derror);
+ connection = dbus_bus_get(DBUS_BUS_SESSION, &derror);
+ if(!connection) {
+ dbus_error_free(&derror);
+ return FALSE;
+ }
+
+ method = dbus_message_new_method_call(RUNDIALOG_DBUS_SERVICE,
+ RUNDIALOG_DBUS_PATH,
+ RUNDIALOG_DBUS_INTERFACE,
+ RUNDIALOG_DBUS_METHOD_OPEN);
+ dbus_message_set_auto_start(method, TRUE);
+
+ display_name = gdk_screen_make_display_name(gdk_screen_get_default());
+ cwd = g_get_current_dir();
+
+ if(!run_argument)
+ run_argument = dummy_run_argument = g_strdup("");
+
+ dbus_message_append_args(method,
+ DBUS_TYPE_STRING, &display_name,
+ DBUS_TYPE_STRING, &cwd,
+ DBUS_TYPE_STRING, &run_argument,
+ DBUS_TYPE_INVALID);
+
+ g_free(display_name);
+ g_free(cwd);
+ g_free(dummy_run_argument);
+
+ result = dbus_connection_send_with_reply_and_block(connection, method,
+ 5000, &derror);
+ dbus_message_unref(method);
+ if(!result) {
+ dbus_error_free(&derror);
+ return FALSE;
+ }
+
+ dbus_message_unref(result);
+
+ return TRUE;
+}
+
+/* send quit message */
+static void
+xfrun_send_quit()
+{
+ DBusConnection *connection;
+ DBusMessage *method, *result;
+
+ connection = dbus_bus_get(DBUS_BUS_SESSION, NULL);
+ if(!connection)
+ return;
+
+ method = dbus_message_new_method_call(RUNDIALOG_DBUS_SERVICE,
+ RUNDIALOG_DBUS_PATH,
+ RUNDIALOG_DBUS_INTERFACE,
+ RUNDIALOG_DBUS_METHOD_QUIT);
+ dbus_message_set_auto_start(method, FALSE);
+
+ result = dbus_connection_send_with_reply_and_block(connection, method,
+ 5000, NULL);
+ dbus_message_unref(method);
+ if(result)
+ dbus_message_unref(result);
+}
+
+int
+main(int argc,
+ char **argv)
+{
+ if(argc > 1 && !strcmp(argv[1], "--quit"))
+ xfrun_send_quit();
+ else if(argc > 1 && !strcmp(argv[1], "--daemon")) {
+ if(argc == 2 || strcmp(argv[2], "--no-detach")) { /* for debugging
purposes... */
+#ifdef HAVE_DAEMON
+ if(daemon(1, 1)) {
+ xfce_message_dialog(NULL, _("System Error"),
+ GTK_STOCK_DIALOG_ERROR,
+ _("Unable to fork to background:"),
+ strerror(errno), GTK_STOCK_QUIT,
+ GTK_RESPONSE_ACCEPT, NULL);
+ return 1;
+ }
+#else
+ switch(fork()) {
+ case -1:
+ /* failed */
+ xfce_message_dialog(NULL, _("System Error"),
+ GTK_STOCK_DIALOG_ERROR,
+ _("Unable to fork to background:"),
+ strerror(errno), GTK_STOCK_QUIT,
+ GTK_RESPONSE_ACCEPT, NULL);
+ return 1;
+ case 0:
+ /* child (daemon) */
+# ifdef HAVE_SETSID
+ setsid();
+# endif
+ break;
+ default:
+ /* parent */
+ _exit(0);
+ }
+#endif
+ }
+
+ gtk_init(&argc, &argv);
+
+ static_dialog = xfrun_dialog_new(NULL);
+ xfrun_dialog_set_destroy_on_close(XFRUN_DIALOG(static_dialog), FALSE);
+ g_signal_connect(G_OBJECT(static_dialog), "closed",
+ G_CALLBACK(xfrun_static_dialog_closed), NULL);
+ static_dialog_in_use = FALSE;
+
+ xfrun_register_dbus_service();
+
+ gtk_main();
+ } else {
+ gdk_init(&argc, &argv);
+
+ xfrun_show_dialog(argc > 1 ? argv[1] : NULL);
+ }
+
+ return 0;
+}
Modified: xfce-utils/trunk/xfrun/xfrun-dialog.c
===================================================================
--- xfce-utils/trunk/xfrun/xfrun-dialog.c 2006-07-16 08:17:54 UTC (rev
22459)
+++ xfce-utils/trunk/xfrun/xfrun-dialog.c 2006-07-16 10:06:10 UTC (rev
22460)
@@ -51,6 +51,7 @@
gchar *run_argument;
gboolean destroy_on_close;
+ gchar *working_directory;
gchar *entry_val_tmp;
};
@@ -59,6 +60,7 @@
{
PROP0,
PROP_RUN_ARGUMENT,
+ PROP_WORKING_DIRECTORY,
};
enum
@@ -110,6 +112,7 @@
GtkTreeModel *model,
GtkTreeIter *iter,
gpointer user_data);
+static void xfrun_setup_entry_completion(XfrunDialog *dialog);
static GtkTreeModel *xfrun_create_completion_model(XfrunDialog *dialog);
guint __signals[N_SIGS] = { 0, };
@@ -145,14 +148,19 @@
"1st argument to pass
to the program run",
NULL,
G_PARAM_READWRITE));
+
+ g_object_class_install_property(gobject_class, PROP_WORKING_DIRECTORY,
+ g_param_spec_string("working-directory",
+ "Working directory",
+ "Directory to chdir()
to before running the command",
+ NULL,
+ G_PARAM_READWRITE));
}
static void
xfrun_dialog_init(XfrunDialog *dialog)
{
GtkWidget *entry, *chk, *btn, *vbox, *bbox, *hbox, *arrow;
- GtkEntryCompletion *completion;
- GtkTreeModel *completion_model;
GtkTreeIter itr;
gchar *first_item = NULL;
@@ -170,18 +178,10 @@
gtk_widget_show(hbox);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
- completion = gtk_entry_completion_new();
- dialog->priv->completion_model = completion_model =
xfrun_create_completion_model(dialog);
- gtk_entry_completion_set_model(completion, completion_model);
- gtk_entry_completion_set_text_column(completion, XFRUN_COL_COMMAND);
- gtk_entry_completion_set_popup_completion(completion, TRUE);
- gtk_entry_completion_set_inline_completion(completion, TRUE);
- g_signal_connect(G_OBJECT(completion), "match-selected",
- G_CALLBACK(xfrun_match_selected), dialog);
dialog->priv->entry = entry = gtk_entry_new();
- gtk_entry_set_completion(GTK_ENTRY(entry), completion);
gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
+ xfrun_setup_entry_completion(dialog);
gtk_widget_show(entry);
gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
g_signal_connect(G_OBJECT(entry), "focus-out-event",
@@ -189,8 +189,8 @@
g_signal_connect(G_OBJECT(entry), "key-press-event",
G_CALLBACK(xfrun_entry_key_press), dialog);
- if(gtk_tree_model_get_iter_first(completion_model, &itr)) {
- gtk_tree_model_get(completion_model, &itr,
+ if(gtk_tree_model_get_iter_first(dialog->priv->completion_model, &itr)) {
+ gtk_tree_model_get(dialog->priv->completion_model, &itr,
XFRUN_COL_COMMAND, &first_item,
-1);
if(first_item) {
@@ -248,6 +248,11 @@
xfrun_dialog_set_run_argument(dialog, g_value_get_string(value));
break;
+ case PROP_WORKING_DIRECTORY:
+ xfrun_dialog_set_working_directory(dialog,
+ g_value_get_string(value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
break;
@@ -267,6 +272,11 @@
g_value_set_string(value, xfrun_dialog_get_run_argument(dialog));
break;
+ case PROP_WORKING_DIRECTORY:
+ g_value_set_string(value,
+ xfrun_dialog_get_working_directory(dialog));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
break;
@@ -279,8 +289,12 @@
XfrunDialog *dialog = XFRUN_DIALOG(object);
g_free(dialog->priv->run_argument);
+ g_free(dialog->priv->working_directory);
g_free(dialog->priv->entry_val_tmp);
+ if(dialog->priv->completion_model)
+ g_object_unref(G_OBJECT(dialog->priv->completion_model));
+
g_free(dialog->priv);
}
@@ -302,16 +316,39 @@
{
XfrunDialog *dialog = XFRUN_DIALOG(widget);
+ g_signal_emit(G_OBJECT(widget), __signals[SIG_CLOSED], 0);
+
if(dialog->priv->destroy_on_close)
gtk_widget_destroy(widget);
else
gtk_widget_hide(widget);
- g_signal_emit(G_OBJECT(widget), __signals[SIG_CLOSED], 0);
-
return TRUE;
}
+static void
+xfrun_setup_entry_completion(XfrunDialog *dialog)
+{
+ GtkEntryCompletion *completion = gtk_entry_completion_new();
+ GtkTreeModel *completion_model;
+
+ /* clear out the old completion and resources, if any */
+ gtk_entry_set_completion(GTK_ENTRY(dialog->priv->entry), NULL);
+ if(dialog->priv->completion_model)
+ g_object_unref(dialog->priv->completion_model);
+
+ dialog->priv->completion_model = completion_model =
xfrun_create_completion_model(dialog);
+ gtk_entry_completion_set_model(completion, completion_model);
+ gtk_entry_completion_set_text_column(completion, XFRUN_COL_COMMAND);
+ gtk_entry_completion_set_popup_completion(completion, TRUE);
+ gtk_entry_completion_set_inline_completion(completion, TRUE);
+ g_signal_connect(G_OBJECT(completion), "match-selected",
+ G_CALLBACK(xfrun_match_selected), dialog);
+
+ gtk_entry_set_completion(GTK_ENTRY(dialog->priv->entry), completion);
+ g_object_unref(G_OBJECT(completion));
+}
+
static gchar **
xfrun_get_histfile_content()
{
@@ -324,6 +361,8 @@
g_free(contents);
}
+ g_free(histfile);
+
return lines;
}
@@ -511,9 +550,13 @@
if(!lines) {
fp = fopen(histfile, "w");
- fprintf(fp, "%d:%s\n", in_terminal ? 1 : 0, command);
- fclose(fp);
+ if(fp) {
+ fprintf(fp, "%d:%s\n", in_terminal ? 1 : 0, command);
+ fclose(fp);
+ }
} else {
+ gchar *new_line;
+
for(i = 0; lines[i]; ++i) {
if(strlen(lines[i]) < 3 || lines[i][1] != ':')
continue;
@@ -522,14 +565,17 @@
new_lines = g_list_append(new_lines, lines[i]);
}
- new_lines = g_list_prepend(new_lines, g_strdup_printf("%d:%s",
- in_terminal ? 1
: 0,
- command));
+ new_line = g_strdup_printf("%d:%s", in_terminal ? 1 : 0, command);
+ new_lines = g_list_prepend(new_lines, new_line);
fp = fopen(histfile, "w");
- for(l = new_lines, i = 0; l && i < MAX_ENTRIES; l = l->next, ++i)
- fprintf(fp, "%s\n", (char *)l->data);
- fclose(fp);
+ if(fp) {
+ for(l = new_lines, i = 0; l && i < MAX_ENTRIES; l = l->next, ++i)
+ fprintf(fp, "%s\n", (char *)l->data);
+ fclose(fp);
+ }
+
+ g_free(new_line);
}
histfile1 = g_strdup(histfile);
@@ -545,36 +591,54 @@
}
static void
+xfrun_spawn_child_setup(gpointer data)
+{
+#if !defined(G_OS_WIN32) && defined(HAVE_SETSID)
+ setsid();
+#endif
+}
+
+static void
xfrun_run_clicked(GtkWidget *widget,
gpointer user_data)
{
XfrunDialog *dialog = XFRUN_DIALOG(user_data);
- gchar *entry_str, *display_name, *command;
+ gchar *entry_str, **argv;
gboolean in_terminal;
GdkScreen *gscreen;
GError *error = NULL;
+ gint i = 0;
entry_str = gtk_editable_get_chars(GTK_EDITABLE(dialog->priv->entry), 0,
-1);
in_terminal =
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->priv->terminal_chk));
gscreen = gtk_widget_get_screen(widget);
- display_name = gdk_screen_make_display_name(gscreen);
- if(dialog->priv->run_argument) {
- command = g_strdup_printf("env DISPLAY=\"%s\" \"%s\" \"%s\"",
- display_name, entry_str,
- dialog->priv->run_argument);
- } else {
- command = g_strdup_printf("env DISPLAY=\"%s\" \"%s\"", display_name,
- entry_str);
+ argv = g_new0(gchar *, 5);
+
+ if(in_terminal) {
+ argv[i++] = "xfterm4";
+ argv[i++] = "-e";
}
+ argv[i++] = entry_str;
+ if(dialog->priv->run_argument)
+ argv[i++] = dialog->priv->run_argument;
+ argv[i++] = NULL;
- if(xfce_exec(command, in_terminal, FALSE, &error)) {
+ if(xfce_gdk_spawn_on_screen(gscreen, dialog->priv->working_directory,
+ argv, NULL, G_SPAWN_SEARCH_PATH,
+ xfrun_spawn_child_setup, NULL, NULL, &error))
+ {
xfrun_add_to_history(entry_str, in_terminal);
+ if(!dialog->priv->destroy_on_close) {
+ /* assume we're going to use this again */
+ xfrun_setup_entry_completion(dialog);
+ gtk_widget_grab_focus(dialog->priv->entry);
+ }
xfrun_dialog_delete_event(GTK_WIDGET(dialog), NULL);
} else {
gchar *primary = g_strdup_printf(_("The command \"%s\" failed to
run:"),
- command);
+ entry_str);
xfce_message_dialog(GTK_WINDOW(dialog), _("Run Error"),
GTK_STOCK_DIALOG_ERROR, primary, error->message,
GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL);
@@ -583,7 +647,7 @@
}
g_free(entry_str);
- g_free(command);
+ g_free(argv);
}
static gboolean
@@ -688,3 +752,20 @@
g_return_val_if_fail(XFRUN_IS_DIALOG(dialog), FALSE);
return dialog->priv->destroy_on_close;
}
+
+void
+xfrun_dialog_set_working_directory(XfrunDialog *dialog,
+ const gchar *working_directory)
+{
+ g_return_if_fail(XFRUN_IS_DIALOG(dialog));
+
+ g_free(dialog->priv->working_directory);
+ dialog->priv->working_directory = g_strdup(working_directory);
+}
+
+G_CONST_RETURN gchar *
+xfrun_dialog_get_working_directory(XfrunDialog *dialog)
+{
+ g_return_val_if_fail(XFRUN_IS_DIALOG(dialog), NULL);
+ return dialog->priv->working_directory;
+}
Modified: xfce-utils/trunk/xfrun/xfrun-dialog.h
===================================================================
--- xfce-utils/trunk/xfrun/xfrun-dialog.h 2006-07-16 08:17:54 UTC (rev
22459)
+++ xfce-utils/trunk/xfrun/xfrun-dialog.h 2006-07-16 10:06:10 UTC (rev
22460)
@@ -49,6 +49,8 @@
void (*closed)(XfrunDialog *dialog);
};
+GType xfrun_dialog_get_type () G_GNUC_CONST;
+
GtkWidget *xfrun_dialog_new (const gchar *run_argument);
void xfrun_dialog_set_run_argument (XfrunDialog *dialog,
@@ -59,6 +61,11 @@
gboolean destroy_on_close);
gboolean xfrun_dialog_get_destroy_on_close (XfrunDialog *dialog);
+void xfrun_dialog_set_working_directory (XfrunDialog *dialog,
+ const gchar
*working_directory);
+G_CONST_RETURN gchar *xfrun_dialog_get_working_directory
+ (XfrunDialog *dialog);
+
G_END_DECLS
#endif /* __XFRUN_DIALOG_H__ */
_______________________________________________
Xfce4-commits mailing list
[email protected]
http://foo-projects.org/mailman/listinfo/xfce4-commits