[Xfce-bugs] [Bug 1598] Implement D-BUS support for xfrun4
bugzilla-daemon at xfce.org
bugzilla-daemon at xfce.org
Mon Mar 27 16:07:46 CEST 2006
Do NOT reply to this email. To make further comments on this bug, use
the URL below:
http://bugzilla.xfce.org/show_bug.cgi?id=1598
------- Comment #5 from info at sten-net.de 2006-03-27 14:07 UTC -------
(From update of attachment 487)
Index: xfce-utils/xfrun/org.xfce.RunDialog.service.in
===================================================================
--- xfce-utils/xfrun/org.xfce.RunDialog.service.in (revision 0)
+++ xfce-utils/xfrun/org.xfce.RunDialog.service.in (revision 0)
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.xfce.RunDialog
+Exec=@bindir@/xfrun4 --daemon
Index: xfce-utils/xfrun/xfrun.c
===================================================================
--- xfce-utils/xfrun/xfrun.c (revision 20510)
+++ xfce-utils/xfrun/xfrun.c (working copy)
@@ -2,6 +2,8 @@
* xfrun - a simple quick run dialog with saved history and completion
*
* Copyright (c) 2006 Brian J. Tarricone <bjt23 at cornell.edu>
+ * Jani Monoses <jani.monoses at gmail.com>
+ * Jannis Pohlmann <jannis at xfce.org>
*
* 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
@@ -32,6 +34,20 @@
#include <unistd.h>
#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_DBUS
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#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_ERROR_GENERAL "org.xfce.RunDialog.ErrorGeneral"
+#endif
+
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
@@ -59,7 +75,200 @@
XFRUN_N_COLS,
};
+static XfrunDialog *xfrun_dialog;
+static void
+xfrun_shutdown (void)
+{
+ if (G_LIKELY (xfrun_dialog != NULL))
+ g_free (xfrun_dialog);
+}
+
+static void
+xfrun_dialog_show (GtkWidget *dialog)
+{
+ gtk_widget_show(dialog);
+ gtk_widget_set_size_request(dialog, -1, -1);
+}
+
+static gboolean daemon_mode = FALSE;
+
+static void
+xfrun_quit (GtkWidget *dialog)
+{
+ if (daemon_mode)
+ gtk_widget_hide (dialog);
+ else
+ {
+ xfrun_shutdown ();
+ gtk_main_quit();
+ }
+}
+
+#ifdef HAVE_DBUS
+/*
+ * Call the org.xfce.RunDialog.OpenDialog(dir, display) method on whichever
+ * object owns that name on the session D-BUS
+ */
+static gboolean
+xfrun_remote_dialog (int argc,
+ char **argv)
+{
+ DBusConnection *connection;
+ DBusMessage *method;
+ DBusMessage *result;
+ DBusError derror;
+
+ GdkScreen *screen;
+
+ gchar *directory;
+ gchar *display;
+
+ gdk_init (&argc, &argv);
+
+ dbus_error_init (&derror);
+
+ /* Try establishing a connection to the session bus */
+ connection = dbus_bus_get (DBUS_BUS_SESSION, &derror);
+
+ if (connection == NULL)
+ return FALSE;
+
+ /* Create org.xfce.RunDialog.OpenDialog method message */
+ 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);
+
+ /* Dete the active display */
+ screen = gdk_screen_get_default ();
+ display = gdk_screen_make_display_name (screen);
+
+ /* Dete working directory */
+ directory = g_get_current_dir ();
+
+ /* Append method arguments */
+ dbus_message_append_args (method, DBUS_TYPE_STRING, &directory,
+ DBUS_TYPE_STRING, &display,
+ DBUS_TYPE_INVALID);
+
+ /* Send D-BUS message */
+ result = dbus_connection_send_with_reply_and_block (connection, method,
2000, &derror);
+
+ /* Free data */
+ dbus_message_unref (method);
+ g_free (display);
+ g_free (directory);
+
+ if (result == NULL)
+ return FALSE;
+
+ dbus_message_unref (result);
+
+ return TRUE;
+}
+
+static DBusHandlerResult
+xfrun_handle_dbus_message (DBusConnection *connection,
+ DBusMessage *message,
+ GtkWidget *dialog)
+{
+ DBusMessage *reply;
+ DBusError derror;
+ uid_t user_id;
+ gchar *directory;
+ gchar *display;
+ GdkScreen *screen;
+
+ if (dbus_message_is_method_call (message,
+ RUNDIALOG_DBUS_INTERFACE,
+ RUNDIALOG_DBUS_METHOD_OPEN))
+ {
+ dbus_error_init (&derror);
+
+ /* Query the list of arguments to this call */
+ if (!dbus_message_get_args (message, &derror,
+ DBUS_TYPE_STRING, &directory,
+ DBUS_TYPE_STRING, &display,
+ DBUS_TYPE_INVALID))
+ {
+ /* Reply an error message */
+ reply = dbus_message_new_error (message,
RUNDIALOG_DBUS_ERROR_GENERAL, derror.message);
+
+ /* Free error data */
+ dbus_error_free (&derror);
+ }
+ else
+ {
+ /* Get default screen of display */
+ screen = gdk_display_get_default_screen (gdk_display_open
(display));
+
+ /* Set screen for xfrun dialog */
+ gtk_window_set_screen (GTK_WINDOW (dialog), screen);
+
+ /* Show xfrun dialog */
+ xfrun_dialog_show (dialog);
+
+ /* Reply a success message */
+ reply = dbus_message_new_method_return (message);
+ }
+
+ /* Send reply */
+ dbus_connection_send (connection, reply, NULL);
+
+ /* Destroy reply message object */
+ dbus_message_unref (reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ else if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL,
"Disconnected"))
+ {
+ g_printerr (_("D-BUS message bus disconnected. Exiting ...\n"));
+ xfrun_quit (dialog);
+ }
+ else
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static gboolean
+xfrun_register_dbus_service (GtkWidget *dialog)
+{
+ static const struct DBusObjectPathVTable vtable = { NULL,
(DBusObjectPathMessageFunction)xfrun_handle_dbus_message, NULL, NULL, NULL,
NULL };
+
+ DBusConnection *connection;
+ DBusError derror;
+
+ dbus_error_init (&derror);
+
+ /* Try connecting to the session bus */
+ connection = dbus_bus_get (DBUS_BUS_SESSION, &derror);
+
+ if (G_UNLIKELY (connection == NULL))
+ {
+ dbus_error_free (&derror);
+ return FALSE;
+ }
+
+ /* Register D-BUS connection with GLib main loop */
+ dbus_connection_setup_with_g_main (connection, NULL);
+
+ /* Try to request ownership of our D-BUS service */
+ if (dbus_bus_request_name (connection, RUNDIALOG_DBUS_SERVICE, 0, &derror) <
0)
+ {
+ dbus_error_free (&derror);
+ return FALSE;
+ }
+
+ /* Register the application object */
+ if (!dbus_connection_register_object_path (connection, RUNDIALOG_DBUS_PATH,
&vtable, dialog))
+ return FALSE;
+
+ return TRUE;
+}
+#endif
+
/* this stuff is here so i don't have to link to libxfcegui4 */
static void
@@ -244,10 +453,14 @@
gsize length = 0;
histfile = xfce_resource_lookup(XFCE_RESOURCE_CACHE,
"xfce4/xfrun4/history");
+
if(histfile && g_file_get_contents(histfile, &contents, &length, NULL)) {
lines = g_strsplit(contents, "\n", -1);
g_free(contents);
}
+
+ if (G_LIKELY (histfile != NULL))
+ g_free (histfile);
return lines;
}
@@ -255,10 +468,10 @@
static gboolean
xfrun_key_press(GtkWidget *widget,
GdkEventKey *evt,
- gpointer user_data)
+ GtkWidget *window)
{
if(evt->keyval == GDK_Escape) {
- gtk_main_quit();
+ xfrun_quit(window);
return TRUE;
}
@@ -490,7 +703,7 @@
gscreen = gtk_widget_get_screen(widget);
if(xfrun_exec_on_screen(gscreen, command, in_terminal, &error)) {
xfrun_add_to_history(command, in_terminal);
- gtk_main_quit();
+ xfrun_quit(xfrun_dialog->window);
} else {
gchar *primary = g_strdup_printf(_("The command \"%s\" failed to
run:"),
command);
@@ -557,36 +770,33 @@
return GTK_TREE_MODEL(ls);
}
-int
-main(int argc,
- char **argv)
+GtkWidget*
+xfrun_setup(int argc,
+ char **argv)
{
- XfrunDialog xfrun_dialog;
+ xfrun_dialog = g_malloc (sizeof (XfrunDialog));
+
gchar title[8192], *first_item;
GtkWidget *win, *entry, *chk, *btn, *vbox, *bbox, *hbox, *arrow;
GtkEntryCompletion *completion;
GtkTreeModel *completion_model;
GtkTreeIter itr;
- xfce_textdomain(GETTEXT_PACKAGE, LOCALEDIR, "UTF-8");
-
- gtk_init(&argc, &argv);
-
if(argc >= 2) {
g_snprintf(title, 8192, _("Open %s with what program?"), argv[1]);
- xfrun_dialog.run_argument = argv[1];
+ xfrun_dialog->run_argument = argv[1];
} else {
g_strlcpy(title, _("Run program"), 8192);
- xfrun_dialog.run_argument = NULL;
+ xfrun_dialog->run_argument = NULL;
}
- xfrun_dialog.window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ xfrun_dialog->window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(win), title);
gtk_widget_set_size_request(win, 400, -1);
g_signal_connect(G_OBJECT(win), "delete-event",
- G_CALLBACK(gtk_main_quit), NULL);
+ G_CALLBACK(xfrun_quit), xfrun_dialog->window);
g_signal_connect(G_OBJECT(win), "key-press-event",
- G_CALLBACK(xfrun_key_press), NULL);
+ G_CALLBACK(xfrun_key_press), xfrun_dialog->window);
vbox = gtk_vbox_new(FALSE, BORDER/2);
gtk_container_set_border_width(GTK_CONTAINER(vbox), BORDER);
@@ -598,21 +808,21 @@
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
completion = gtk_entry_completion_new();
- xfrun_dialog.completion_model = completion_model =
xfrun_create_completion_model(&xfrun_dialog);
+ xfrun_dialog->completion_model = completion_model =
xfrun_create_completion_model(xfrun_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), &xfrun_dialog);
+ G_CALLBACK(xfrun_match_selected), xfrun_dialog);
- xfrun_dialog.entry = entry = gtk_entry_new();
+ xfrun_dialog->entry = entry = gtk_entry_new();
gtk_entry_set_completion(GTK_ENTRY(entry), completion);
gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
gtk_widget_show(entry);
gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
g_signal_connect(G_OBJECT(entry), "focus-out-event",
- G_CALLBACK(xfrun_entry_focus_out), &xfrun_dialog);
+ G_CALLBACK(xfrun_entry_focus_out), xfrun_dialog);
if(gtk_tree_model_get_iter_first(completion_model, &itr)) {
gtk_tree_model_get(completion_model, &itr,
@@ -624,18 +834,18 @@
}
}
- xfrun_dialog.arrow_btn = btn = gtk_button_new();
+ xfrun_dialog->arrow_btn = btn = gtk_button_new();
gtk_container_set_border_width(GTK_CONTAINER(btn), 0);
gtk_widget_show(btn);
gtk_box_pack_start(GTK_BOX(hbox), btn, FALSE, FALSE, 0);
g_signal_connect(G_OBJECT(btn), "clicked",
- G_CALLBACK(xfrun_menu_button_clicked), &xfrun_dialog);
+ G_CALLBACK(xfrun_menu_button_clicked), xfrun_dialog);
arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE);
gtk_widget_show(arrow);
gtk_container_add(GTK_CONTAINER(btn), arrow);
- xfrun_dialog.terminal_chk = chk =
gtk_check_button_new_with_mnemonic(_("Run in _terminal"));
+ xfrun_dialog->terminal_chk = chk =
gtk_check_button_new_with_mnemonic(_("Run in _terminal"));
gtk_widget_show(chk);
gtk_box_pack_start(GTK_BOX(vbox), chk, FALSE, FALSE, 0);
@@ -649,7 +859,7 @@
gtk_widget_show(btn);
gtk_box_pack_end(GTK_BOX(bbox), btn, FALSE, FALSE, 0);
g_signal_connect(G_OBJECT(btn), "clicked",
- G_CALLBACK(gtk_main_quit), NULL);
+ G_CALLBACK(xfrun_quit), xfrun_dialog->window);
btn = xfrun_create_mixed_button(GTK_STOCK_EXECUTE, _("_Run"));
gtk_widget_show(btn);
@@ -657,13 +867,49 @@
GTK_WIDGET_SET_FLAGS(btn, GTK_CAN_DEFAULT);
gtk_widget_grab_default(btn);
g_signal_connect(G_OBJECT(btn), "clicked",
- G_CALLBACK(xfrun_run_clicked), &xfrun_dialog);
+ G_CALLBACK(xfrun_run_clicked), xfrun_dialog);
xfrun_gtk_window_center_on_monitor_with_pointer(GTK_WINDOW(win));
- gtk_widget_show(win);
- gtk_widget_set_size_request(win, -1, -1);
- gtk_main();
-
- return 0;
+ return xfrun_dialog->window;
}
+
+int main(int argc,
+ char **argv)
+{
+ GtkWidget *dialog;
+
+ xfce_textdomain (GETTEXT_PACKAGE, LOCALEDIR, "UTF-8");
+
+#ifdef HAVE_DBUS
+ if (argc == 1)
+ {
+ if (xfrun_remote_dialog (argc, argv))
+ return EXIT_SUCCESS;
+ }
+ else if (argc >= 2 && !strcmp ("--daemon", argv[1]))
+ {
+ daemon_mode = TRUE;
+ argc = 1;
+ }
+#endif
+
+ gtk_init (&argc, &argv);
+
+ dialog = xfrun_setup (argc, argv);
+
+#ifdef HAVE_DBUS
+ if (daemon_mode)
+ {
+ if (xfrun_register_dbus_service (dialog) == FALSE)
+ return EXIT_FAILURE;
+ }
+#endif
+
+ if (!daemon_mode)
+ xfrun_dialog_show (dialog);
+
+ gtk_main ();
+
+ return EXIT_SUCCESS;
+}
Index: xfce-utils/xfrun/Makefile.am
===================================================================
--- xfce-utils/xfrun/Makefile.am (revision 20510)
+++ xfce-utils/xfrun/Makefile.am (working copy)
@@ -1,12 +1,28 @@
bin_PROGRAMS = xfrun4
-xfrun4_SOURCES = xfrun.c
+xfrun4_SOURCES = \
+ xfrun.c
xfrun4_CFLAGS = \
@LIBXFCE4UTIL_CFLAGS@ \
@GTK_CFLAGS@ \
+ @DBUS_CFLAGS@ \
+ -DDBUS_API_SUBJECT_TO_CHANGE \
-DLOCALEDIR=\"$(localedir)\"
xfrun4_LDADD = \
@LIBXFCE4UTIL_LIBS@ \
- @GTK_LIBS@
+ @GTK_LIBS@ \
+ @DBUS_LIBS@
+
+if HAVE_DBUS
+servicedir = $(datadir)/dbus-1/services
+service_in_files = org.xfce.RunDialog.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+%.service: %.service.in
+ sed -e "s,\@bindir\@,$(bindir),g" < $< > $@
+DISTCLEANFILES = \
+ $(service_DATA)
+EXTRA_DIST = \
+ $(service_in_files)
+endif
Index: xfce-utils/configure.ac
===================================================================
--- xfce-utils/configure.ac (revision 20505)
+++ xfce-utils/configure.ac (working copy)
@@ -95,6 +95,10 @@
XDT_CHECK_PACKAGE([LIBXFCE4UTIL], [libxfce4util-1.0], [4.3.0])
XDT_CHECK_PACKAGE([LIBXFCEGUI4], [libxfcegui4-1.0], [4.3.0])
+dnl Check for optional packages
+XDT_CHECK_OPTIONAL_PACKAGE([DBUS], [dbus-glib-1],
+ [0.33], [dbus], [D-BUS support])
+
dnl configure the mcs plugin
XDT_XFCE_MCS_PLUGIN([XFCE_MCS_MANAGER], [4.3.0])
--
Configure bugmail: http://bugzilla.xfce.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
More information about the Xfce-bugs
mailing list