[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