[gedit/dbus: 4/4] Reimplemented all of the dbus work, untested but compiles
- From: Jesse van den Kieboom <jessevdk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gedit/dbus: 4/4] Reimplemented all of the dbus work, untested but compiles
- Date: Sun, 2 May 2010 16:39:36 +0000 (UTC)
commit 6bfe52d4d245a4a97c929b26c344316df9b11bd1
Author: Jesse van den Kieboom <jessevdk gnome org>
Date: Sun May 2 17:47:56 2010 +0200
Reimplemented all of the dbus work, untested but compiles
gedit/gedit-command-line.c | 20 +-
gedit/gedit-command-line.h | 5 +-
gedit/gedit-commands-file.c | 53 +-
gedit/gedit-commands.h | 8 +-
gedit/gedit-dbus.c | 907 +++++++++++++++++++-
gedit/gedit-dbus.h | 34 +-
gedit/gedit-window.c | 22 +-
gedit/gedit.c | 24 +-
plugin-loaders/python/bindings/geditcommands.defs | 2 +-
.../python/bindings/geditcommands.override | 33 +-
10 files changed, 1058 insertions(+), 50 deletions(-)
---
diff --git a/gedit/gedit-command-line.c b/gedit/gedit-command-line.c
index c3b1903..a61c8e5 100644
--- a/gedit/gedit-command-line.c
+++ b/gedit/gedit-command-line.c
@@ -91,9 +91,16 @@ gedit_command_line_init (GeditCommandLine *self)
}
GeditCommandLine *
-gedit_command_line_new ()
+gedit_command_line_get_default (void)
{
- return g_object_new (GEDIT_TYPE_COMMAND_LINE, NULL);
+ static GeditCommandLine *command_line = NULL;
+
+ if (!command_line)
+ {
+ command_line = g_object_new (GEDIT_TYPE_COMMAND_LINE, NULL);
+ }
+
+ return command_line;
}
static void
@@ -315,6 +322,15 @@ gedit_command_line_get_new_window (GeditCommandLine *command_line)
return command_line->priv->new_window;
}
+void
+gedit_command_line_set_new_window (GeditCommandLine *command_line,
+ gboolean new_window)
+{
+ g_return_if_fail (GEDIT_IS_COMMAND_LINE (command_line));
+
+ command_line->priv->new_window = new_window;
+}
+
gboolean
gedit_command_line_get_new_document (GeditCommandLine *command_line)
{
diff --git a/gedit/gedit-command-line.h b/gedit/gedit-command-line.h
index 48b207a..1e994e9 100644
--- a/gedit/gedit-command-line.h
+++ b/gedit/gedit-command-line.h
@@ -51,11 +51,14 @@ struct _GeditCommandLineClass {
};
GType gedit_command_line_get_type (void) G_GNUC_CONST;
-GeditCommandLine *gedit_command_line_new (void);
+
+GeditCommandLine *gedit_command_line_get_default (void);
gboolean gedit_command_line_parse (GeditCommandLine *command_line, int *argc, char ***argv);
gboolean gedit_command_line_get_new_window (GeditCommandLine *command_line);
+void gedit_command_line_set_new_window (GeditCommandLine *command_line, gboolean new_window);
+
gboolean gedit_command_line_get_new_document (GeditCommandLine *command_line);
gint gedit_command_line_get_line_position (GeditCommandLine *command_line);
gint gedit_command_line_get_column_position (GeditCommandLine *command_line);
diff --git a/gedit/gedit-commands-file.c b/gedit/gedit-commands-file.c
index 1afeb9f..b4d2c54 100644
--- a/gedit/gedit-commands-file.c
+++ b/gedit/gedit-commands-file.c
@@ -118,7 +118,7 @@ is_duplicated_file (GSList *files, GFile *file)
}
/* File loading */
-static gint
+static GSList *
load_file_list (GeditWindow *window,
const GSList *files,
const GeditEncoding *encoding,
@@ -127,11 +127,12 @@ load_file_list (GeditWindow *window,
gboolean create)
{
GeditTab *tab;
- gint loaded_files = 0; /* Number of files to load */
+ GSList *loaded_files = NULL; /* Number of files to load */
gboolean jump_to = TRUE; /* Whether to jump to the new tab */
GList *win_docs;
GSList *files_to_load = NULL;
const GSList *l;
+ gint num_loaded_files = 0;
gedit_debug (DEBUG_COMMANDS);
@@ -165,7 +166,9 @@ load_file_list (GeditWindow *window,
}
}
- ++loaded_files;
+ ++num_loaded_files;
+ loaded_files = g_slist_prepend (loaded_files,
+ gedit_tab_get_document (tab));
}
else
{
@@ -178,8 +181,10 @@ load_file_list (GeditWindow *window,
g_list_free (win_docs);
if (files_to_load == NULL)
- return loaded_files;
-
+ {
+ return g_slist_reverse (loaded_files);
+ }
+
files_to_load = g_slist_reverse (files_to_load);
l = files_to_load;
@@ -206,7 +211,9 @@ load_file_list (GeditWindow *window,
l = g_slist_next (l);
jump_to = FALSE;
- ++loaded_files;
+ ++num_loaded_files;
+ loaded_files = g_slist_prepend (loaded_files,
+ gedit_tab_get_document (tab));
}
}
@@ -225,13 +232,18 @@ load_file_list (GeditWindow *window,
if (tab != NULL)
{
jump_to = FALSE;
- ++loaded_files;
+
+ ++num_loaded_files;
+ loaded_files = g_slist_prepend (loaded_files,
+ gedit_tab_get_document (tab));
}
l = g_slist_next (l);
}
- if (loaded_files == 1)
+ loaded_files = g_slist_reverse (loaded_files);
+
+ if (num_loaded_files == 1)
{
GeditDocument *doc;
gchar *uri_for_display;
@@ -254,8 +266,8 @@ load_file_list (GeditWindow *window,
window->priv->generic_message_cid,
ngettext("Loading %d file\342\200\246",
"Loading %d files\342\200\246",
- loaded_files),
- loaded_files);
+ num_loaded_files),
+ num_loaded_files);
}
/* Free uris_to_load. Note that l points to the first element of uris_to_load */
@@ -278,6 +290,7 @@ gedit_commands_load_location (GeditWindow *window,
{
GSList *locations = NULL;
gchar *uri;
+ GSList *ret;
g_return_if_fail (GEDIT_IS_WINDOW (window));
g_return_if_fail (G_IS_FILE (location));
@@ -289,7 +302,8 @@ gedit_commands_load_location (GeditWindow *window,
locations = g_slist_prepend (locations, location);
- load_file_list (window, locations, encoding, line_pos, column_pos, FALSE);
+ ret = load_file_list (window, locations, encoding, line_pos, column_pos, FALSE);
+ g_slist_free (ret);
g_slist_free (locations);
}
@@ -299,7 +313,7 @@ gedit_commands_load_location (GeditWindow *window,
*
* Ignore non-existing locations
*/
-gint
+GSList *
gedit_commands_load_locations (GeditWindow *window,
const GSList *locations,
const GeditEncoding *encoding,
@@ -319,7 +333,7 @@ gedit_commands_load_locations (GeditWindow *window,
* first doc. Beside specifying a not existing uri creates a
* titled document.
*/
-gint
+GSList *
_gedit_cmd_load_files_from_prompt (GeditWindow *window,
GSList *files,
const GeditEncoding *encoding,
@@ -349,6 +363,7 @@ open_dialog_response_cb (GeditFileChooserDialog *dialog,
{
GSList *files;
const GeditEncoding *encoding;
+ GSList *loaded;
gedit_debug (DEBUG_COMMANDS);
@@ -369,11 +384,13 @@ open_dialog_response_cb (GeditFileChooserDialog *dialog,
/* Remember the folder we navigated to */
_gedit_window_set_default_location (window, files->data);
- gedit_commands_load_locations (window,
- files,
- encoding,
- 0,
- 0);
+ loaded = gedit_commands_load_locations (window,
+ files,
+ encoding,
+ 0,
+ 0);
+
+ g_slist_free (loaded);
g_slist_foreach (files, (GFunc) g_object_unref, NULL);
g_slist_free (files);
diff --git a/gedit/gedit-commands.h b/gedit/gedit-commands.h
index 497e1fb..4f30b01 100644
--- a/gedit/gedit-commands.h
+++ b/gedit/gedit-commands.h
@@ -47,11 +47,11 @@ void gedit_commands_load_location (GeditWindow *window,
gint column_pos);
/* Ignore non-existing URIs */
-gint gedit_commands_load_locations (GeditWindow *window,
+GSList *gedit_commands_load_locations (GeditWindow *window,
const GSList *locations,
const GeditEncoding *encoding,
gint line_pos,
- gint column_pos);
+ gint column_pos) G_GNUC_WARN_UNUSED_RESULT;
void gedit_commands_save_document (GeditWindow *window,
GeditDocument *document);
@@ -63,11 +63,11 @@ void gedit_commands_save_all_documents (GeditWindow *window);
*/
/* Create titled documens for non-existing URIs */
-gint _gedit_cmd_load_files_from_prompt (GeditWindow *window,
+GSList *_gedit_cmd_load_files_from_prompt (GeditWindow *window,
GSList *files,
const GeditEncoding *encoding,
gint line_pos,
- gint column_pos);
+ gint column_pos) G_GNUC_WARN_UNUSED_RESULT;
void _gedit_cmd_file_new (GtkAction *action,
GeditWindow *window);
diff --git a/gedit/gedit-dbus.c b/gedit/gedit-dbus.c
index 47af4b5..98b1249 100644
--- a/gedit/gedit-dbus.c
+++ b/gedit/gedit-dbus.c
@@ -16,14 +16,915 @@
*
* You should have received a copy of the GNU General Public License
* along with gedit; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include "gedit-dbus.h"
+#include <errno.h>
+#include <gdbus/gdbus.h>
+#include <stdlib.h>
+#include <gdk/gdk.h>
+#include "gedit-utils.h"
+#include "gedit-command-line.h"
+#include "gedit-window.h"
+#include "gedit-app.h"
+#include "gedit-commands.h"
-GeditDBusResult
-gedit_dbus_initialize (GeditCommandLine *command_line)
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
+
+typedef struct _WaitData WaitData;
+typedef void (*WaitHandlerFunc)(GObject *object, WaitData *data);
+
+struct _WaitData
+{
+ GeditDBus *dbus;
+ GeditWindow *window;
+ gboolean close_window;
+ guint wait_id;
+
+ guint num_handlers;
+ WaitHandlerFunc func;
+};
+
+#define GEDIT_DBUS_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GEDIT_TYPE_DBUS, GeditDBusPrivate))
+
+struct _GeditDBusPrivate
+{
+ GeditDBusResult result;
+ GMainLoop *main_loop;
+ guint wait_id;
+
+ guint next_wait_id;
+};
+
+G_DEFINE_TYPE (GeditDBus, gedit_dbus, G_TYPE_OBJECT)
+
+static void
+gedit_dbus_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (gedit_dbus_parent_class)->finalize (object);
+}
+
+static void
+gedit_dbus_class_init (GeditDBusClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gedit_dbus_finalize;
+
+ g_type_class_add_private (object_class, sizeof(GeditDBusPrivate));
+}
+
+static void
+gedit_dbus_init (GeditDBus *self)
+{
+ self->priv = GEDIT_DBUS_GET_PRIVATE (self);
+}
+
+GeditDBus *
+gedit_dbus_new ()
+{
+ return g_object_new (GEDIT_TYPE_DBUS, NULL);
+}
+
+static guint32
+get_startup_timestamp (void)
+{
+ const gchar *startup_id_env;
+ gchar *time_str;
+ gchar *end;
+ gulong retval = 0;
+
+ /* we don't unset the env, since startup-notification
+ * may still need it */
+ startup_id_env = g_getenv ("DESKTOP_STARTUP_ID");
+
+ if (startup_id_env == NULL)
+ {
+ return 0;
+ }
+
+ time_str = g_strrstr (startup_id_env, "_TIME");
+
+ if (time_str == NULL)
+ {
+ return 0;
+ }
+
+ errno = 0;
+
+ /* Skip past the "_TIME" part */
+ time_str += 5;
+
+ retval = strtoul (time_str, &end, 0);
+
+ if (end == time_str || errno != 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return retval;
+ }
+}
+
+static GeditDBusResult
+activate_service (GeditDBus *dbus,
+ guint *result)
+{
+ GDBusConnection *conn;
+ GDBusProxy *proxy;
+ GVariant *ret;
+
+ conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+
+ if (conn == NULL)
+ {
+ return GEDIT_DBUS_RESULT_FAILED;
+ }
+
+ proxy = g_dbus_proxy_new_sync (conn,
+ G_TYPE_DBUS_PROXY,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
+ G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+ NULL,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ NULL,
+ NULL);
+
+ if (!proxy)
+ {
+ g_object_unref (conn);
+ return GEDIT_DBUS_RESULT_FAILED;
+ }
+
+ ret = g_dbus_proxy_invoke_method_sync (proxy,
+ "StartServiceByName",
+ g_variant_new ("(su)", "org.gnome.gedit", 0),
+ G_DBUS_INVOKE_METHOD_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL);
+
+ g_object_unref (proxy);
+ g_object_unref (conn);
+
+ if (ret)
+ {
+ if (result)
+ {
+ g_variant_get (ret, "(u)", result);
+ }
+
+ g_variant_unref (ret);
+ return GEDIT_DBUS_RESULT_SUCCESS;
+ }
+ else
+ {
+ return GEDIT_DBUS_RESULT_FAILED;
+ }
+}
+
+static void
+get_display_arguments (GeditDBus *dbus,
+ GeditCommandLine *command_line,
+ const gchar **display_name,
+ gint *screen_number,
+ gint *workspace,
+ gint *viewport_x,
+ gint *viewport_y)
+{
+ GdkScreen *screen;
+ GdkDisplay *display;
+
+ screen = gdk_screen_get_default ();
+ display = gdk_screen_get_display (screen);
+
+ *display_name = gdk_display_get_name (display);
+ *screen_number = gdk_screen_get_number (screen);
+
+ *workspace = gedit_utils_get_current_workspace (screen);
+ gedit_utils_get_current_viewport (screen, viewport_x, viewport_y);
+}
+
+static GVariant *
+compose_open_parameters (GeditDBus *dbus, GeditCommandLine *command_line)
{
+ GVariantBuilder file_list;
+ GSList *files;
+ const GeditEncoding *encoding;
+ const gchar *display_name;
+ gint screen_number;
+ gint workspace;
+ gint viewport_x;
+ gint viewport_y;
+ GVariant *ret;
+
+ g_variant_builder_init (&file_list, G_VARIANT_TYPE_ARRAY);
+
+ for (files = gedit_command_line_get_file_list (command_line); files; files = g_slist_next (files))
+ {
+ gchar *uri = g_file_get_uri (files->data);
+ g_variant_builder_add (&file_list, "s", uri);
+ g_free (uri);
+ }
+
+ encoding = gedit_command_line_get_encoding (command_line);
+
+ get_display_arguments (dbus,
+ command_line,
+ &display_name,
+ &screen_number,
+ &workspace,
+ &viewport_x,
+ &viewport_y);
+
+ ret = g_variant_new ("(assiibbbusiiii)",
+ &file_list,
+ encoding ? gedit_encoding_get_charset (encoding) : "",
+ gedit_command_line_get_line_position (command_line),
+ gedit_command_line_get_column_position (command_line),
+ gedit_command_line_get_new_window (command_line),
+ gedit_command_line_get_new_document (command_line),
+ gedit_command_line_get_wait (command_line),
+ get_startup_timestamp (),
+ display_name,
+ screen_number,
+ workspace,
+ viewport_x,
+ viewport_y);
+
+ g_variant_builder_end (&file_list);
+
+ return ret;
+}
+
+static void
+slave_open_ready_cb (GDBusProxy *proxy,
+ GAsyncResult *result,
+ GeditDBus *dbus)
+{
+ GVariant *ret;
+ GError *error = NULL;
+ GeditCommandLine *command_line;
+
+ ret = g_dbus_proxy_invoke_method_finish (proxy, result, &error);
+ command_line = gedit_command_line_get_default ();
+
+ if (ret == NULL)
+ {
+ g_warning ("Failed to call gedit service: %s", error->message);
+ g_error_free (error);
+
+ dbus->priv->result = GEDIT_DBUS_RESULT_FAILED;
+ g_main_loop_quit (dbus->priv->main_loop);
+ }
+ else
+ {
+ g_variant_get (ret, "(u)", &dbus->priv->wait_id);
+ dbus->priv->result = GEDIT_DBUS_RESULT_SUCCESS;
+
+ if (!gedit_command_line_get_wait (command_line))
+ {
+ g_main_loop_quit (dbus->priv->main_loop);
+ }
+ }
+}
+
+static void
+on_open_proxy_signal (GDBusProxy *proxy,
+ gchar *sender_name,
+ gchar *signal_name,
+ GVariant *parameters,
+ GeditDBus *dbus)
+{
+ if (g_strcmp0 (signal_name, "WaitDone") == 0)
+ {
+ guint wait_id;
+
+ g_variant_get (parameters, "(u)", &wait_id);
+
+ if (wait_id == dbus->priv->wait_id)
+ {
+ g_main_loop_quit (dbus->priv->main_loop);
+ }
+ }
+}
+
+static GeditDBusResult
+handle_slave (GeditDBus *dbus)
+{
+ /* send the requested commands to the master */
+ GDBusConnection *conn;
+ GDBusProxy *proxy;
+ GDBusInvokeMethodFlags flags;
+ GeditCommandLine *command_line;
+
+ conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+
+ if (conn == NULL)
+ {
+ return GEDIT_DBUS_RESULT_FAILED;
+ }
+
+ command_line = gedit_command_line_get_default ();
+
+ flags = G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES;
+
+ if (!gedit_command_line_get_wait (command_line))
+ {
+ flags |= G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS;
+ }
+
+ proxy = g_dbus_proxy_new_sync (conn,
+ G_TYPE_DBUS_PROXY,
+ flags,
+ NULL,
+ "org.gnome.gedit",
+ "/org/gnome/gedit",
+ "org.gnome.gedit.CommandLine",
+ NULL,
+ NULL);
+
+ if (proxy == NULL)
+ {
+ g_object_unref (conn);
+ return GEDIT_DBUS_RESULT_FAILED;
+ }
+
+ if (gedit_command_line_get_wait (command_line))
+ {
+ g_signal_connect (proxy,
+ "g-signal",
+ G_CALLBACK (on_open_proxy_signal),
+ dbus);
+ }
+
+ g_dbus_proxy_invoke_method (proxy,
+ "Open",
+ compose_open_parameters (dbus, command_line),
+ G_DBUS_INVOKE_METHOD_FLAGS_NONE,
+ -1,
+ NULL,
+ (GAsyncReadyCallback)slave_open_ready_cb,
+ dbus);
+
+ g_object_unref (proxy);
+ g_object_unref (conn);
+
+ dbus->priv->main_loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (dbus->priv->main_loop);
+
+ g_main_loop_unref (dbus->priv->main_loop);
+
+ return dbus->priv->result;
+}
+
+static GeditDBusResult
+handle_master (GeditDBus *dbus)
+{
+ /* let the main gedit thing do its thing */
return GEDIT_DBUS_RESULT_PROCEED;
}
+
+static GeditDBusResult
+handle_service (GeditDBus *dbus)
+{
+ guint result;
+ GeditCommandLine *command_line;
+
+ if (activate_service (dbus, &result) == GEDIT_DBUS_RESULT_FAILED)
+ {
+ g_warning ("Could not activate gedit service");
+ return GEDIT_DBUS_RESULT_FAILED;
+ }
+
+ command_line = gedit_command_line_get_default ();
+
+ if (result != 2) /* DBUS_START_REPLY_ALREADY_RUNNING */
+ {
+ /* A new gedit process was launched as a service, this process
+ will have popped up a window, so we want to ignore
+ --new-window here */
+
+ gedit_command_line_set_new_window (command_line, FALSE);
+ }
+
+ /* Finally, act as a slave. */
+ return handle_slave (dbus);
+}
+
+static GSList *
+variant_file_list_to_locations (GVariant *file_list)
+{
+ GSList *ret = NULL;
+ gsize num = g_variant_n_children (file_list);
+ gsize i;
+
+ for (i = 0; i < num; ++i)
+ {
+ gchar *uri;
+ g_variant_get_child (file_list, i, "s", &uri);
+
+ ret = g_slist_prepend (ret, g_file_new_for_uri (uri));
+ g_free (uri);
+ }
+
+ return g_slist_reverse (ret);
+}
+
+static GdkDisplay *
+display_open_if_needed (const gchar *name)
+{
+ GSList *displays;
+ GSList *l;
+ GdkDisplay *display = NULL;
+
+ displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
+
+ for (l = displays; l != NULL; l = l->next)
+ {
+ if (g_strcmp0 (gdk_display_get_name (l->data), name) == 0)
+ {
+ display = l->data;
+ break;
+ }
+ }
+
+ g_slist_free (displays);
+
+ return display != NULL ? display : gdk_display_open (name);
+}
+
+static GeditWindow *
+window_from_display_arguments (gboolean new_window,
+ const gchar *display_name,
+ gint screen_number,
+ gint workspace,
+ gint viewport_x,
+ gint viewport_y,
+ gboolean create)
+{
+ GdkScreen *screen;
+ GeditApp *app;
+ GeditWindow *ret;
+
+ /* get correct screen using the display_name and screen_number */
+ if (display_name != NULL && *display_name)
+ {
+ GdkDisplay *display;
+
+ display = display_open_if_needed (display_name);
+ screen = gdk_display_get_screen (display, screen_number == -1 ? 0 : screen_number);
+ }
+
+ app = gedit_app_get_default ();
+
+ if (new_window)
+ {
+ return gedit_app_create_window (app, screen);
+ }
+
+ if (screen != NULL)
+ {
+ ret = _gedit_app_get_window_in_viewport (app,
+ screen,
+ workspace == -1 ? 0 : workspace,
+ viewport_x == -1 ? 0 : viewport_x,
+ viewport_y == -1 ? 0 : viewport_y);
+ }
+ else
+ {
+ ret = gedit_app_get_active_window (app);
+ }
+
+ if (!ret && create)
+ {
+ return gedit_app_create_window (app, screen);
+ }
+
+ return ret;
+}
+
+static gboolean
+is_empty_window (GeditWindow *window,
+ gboolean check_untouched)
+{
+ GList *views;
+ gboolean ret = FALSE;
+
+ views = gedit_window_get_views (window);
+
+ if (!views)
+ {
+ ret = TRUE;
+ }
+ else if (check_untouched && views->next == NULL)
+ {
+ GeditView *view = GEDIT_VIEW (views->data);
+ GeditDocument *doc = GEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
+
+ if (gedit_document_is_untouched (doc) &&
+ gedit_tab_get_state (gedit_tab_get_from_document (doc)) == GEDIT_TAB_STATE_NORMAL)
+ {
+ ret = TRUE;
+ }
+ }
+
+ g_list_free (views);
+ return ret;
+}
+
+static void
+set_interaction_time_and_present (GeditWindow *window,
+ guint startup_time)
+{
+ /* set the proper interaction time on the window.
+ * Fall back to roundtripping to the X server when we
+ * don't have the timestamp, e.g. when launched from
+ * terminal. We also need to make sure that the window
+ * has been realized otherwise it will not work. lame.
+ */
+
+ if (!GTK_WIDGET_REALIZED (window))
+ {
+ gtk_widget_realize (GTK_WIDGET (window));
+ }
+
+#ifdef GDK_WINDOWING_X11
+ if (startup_time <= 0)
+ {
+ startup_time = gdk_x11_get_server_time (GTK_WIDGET (window)->window);
+ }
+
+ gdk_x11_window_set_user_time (GTK_WIDGET (window)->window, startup_time);
+#endif
+
+ gtk_window_present (GTK_WINDOW (window));
+}
+
+static void
+wait_handler_dbus (GObject *object,
+ WaitData *data)
+{
+ GDBusConnection *conn;
+
+ conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+
+ if (conn == NULL)
+ {
+ g_warning ("Could not emit WaitDone signal because session bus is gone");
+ return;
+ }
+
+ /* Emit the WaitDone signal */
+ g_dbus_connection_emit_signal (conn,
+ NULL,
+ "/org/gnome/gedit",
+ "org.gnome.gedit.CommandLine",
+ "WaitDone",
+ g_variant_new ("(u)", data->wait_id),
+ NULL);
+ g_object_unref (conn);
+
+ if (data->window && object != G_OBJECT (data->window) && data->close_window &&
+ is_empty_window (data->window, FALSE))
+ {
+ /* Close the window */
+ gtk_widget_destroy (GTK_WIDGET (data->window));
+ }
+}
+
+static void
+unref_wait_handler (WaitData *data,
+ GObject *object)
+{
+ if (data->num_handlers == 0)
+ {
+ return;
+ }
+
+ --data->num_handlers;
+
+ if (data->num_handlers == 0)
+ {
+ data->func (object, data);
+
+ /* Free the wait data */
+ g_slice_free (WaitData, data);
+ }
+}
+
+static void
+install_wait_handler (GeditDBus *dbus,
+ WaitData *data,
+ GObject *object,
+ WaitHandlerFunc func)
+{
+ ++data->num_handlers;
+ data->func = func;
+
+ g_object_weak_ref (object, (GWeakNotify)unref_wait_handler, data);
+}
+
+static void
+dbus_handle_open (GeditDBus *dbus,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation)
+{
+ GVariant *file_list;
+ gchar *charset_encoding;
+ gint line_position;
+ gint column_position;
+ gboolean new_window;
+ gboolean new_document;
+ gboolean wait;
+ guint startup_time;
+ gchar *display_name;
+ gint screen_number;
+ gint workspace;
+ gint viewport_x;
+ gint viewport_y;
+ GSList *locations = NULL;
+ const GeditEncoding *encoding = NULL;
+ GeditWindow *window;
+ GSList *loaded_documents = NULL;
+ gboolean empty_window;
+ WaitData *data;
+
+ g_variant_get (parameters,
+ "(assiibbbusiiii)",
+ &file_list,
+ &charset_encoding,
+ &line_position,
+ &column_position,
+ &new_window,
+ &new_document,
+ &wait,
+ &startup_time,
+ &display_name,
+ &screen_number,
+ &workspace,
+ &viewport_x,
+ &viewport_y);
+
+ locations = variant_file_list_to_locations (file_list);
+ g_variant_unref (file_list);
+
+ if (charset_encoding && *charset_encoding)
+ {
+ encoding = gedit_encoding_get_from_charset (charset_encoding);
+ }
+
+ g_free (charset_encoding);
+
+ window = window_from_display_arguments (new_window,
+ display_name,
+ screen_number,
+ workspace,
+ viewport_x,
+ viewport_y,
+ TRUE);
+
+ empty_window = is_empty_window (window, TRUE);
+
+ if (locations)
+ {
+ loaded_documents = _gedit_cmd_load_files_from_prompt (window,
+ locations,
+ encoding,
+ line_position,
+ column_position);
+ }
+
+ if (new_document)
+ {
+ GeditTab *tab;
+ tab = gedit_window_create_tab (window, TRUE);
+
+ loaded_documents = g_slist_append (loaded_documents, gedit_tab_get_document (tab));
+ }
+
+ set_interaction_time_and_present (window, startup_time);
+
+ g_slist_free (locations);
+
+ if (!wait)
+ {
+ g_slist_free (loaded_documents);
+ g_dbus_method_invocation_return_value (invocation,
+ g_variant_new ("(u)", 0));
+ return;
+ }
+
+ data = g_slice_new (WaitData);
+
+ data->dbus = dbus;
+ data->window = window;
+ data->close_window = empty_window;
+ data->wait_id = ++dbus->priv->next_wait_id;
+
+ if (loaded_documents == NULL)
+ {
+ install_wait_handler (dbus,
+ data,
+ G_OBJECT (window),
+ wait_handler_dbus);
+ }
+ else
+ {
+ GSList *item;
+
+ /* Add wait handler on the documents */
+ for (item = loaded_documents; item; item = item->next)
+ {
+ install_wait_handler (dbus,
+ data,
+ G_OBJECT (item->data),
+ wait_handler_dbus);
+ }
+ }
+
+ g_slist_free (loaded_documents);
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(u)", data->wait_id));
+}
+
+static void
+dbus_command_line_method_call_cb (GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ g_message ("%s", object_path);
+ g_return_if_fail (g_strcmp0 (object_path, "/org/gnome/gedit") == 0);
+ g_return_if_fail (g_strcmp0 (interface_name, "org.gnome.gedit.CommandLine") == 0);
+
+ if (g_strcmp0 (method_name, "Open") == 0)
+ {
+ dbus_handle_open (user_data, parameters, invocation);
+ }
+
+ g_warning ("Unsupported method called on gedit service: %s", method_name);
+}
+
+/* Introspection data for the service we are exporting */
+static const GDBusArgInfo in_args[] = {
+ {"files" , "as"},
+ {"encoding" , "s"},
+ {"line_position" , "i"},
+ {"column_position", "i"},
+ {"new_window" , "b"},
+ {"new_document" , "b"},
+ {"wait" , "b"},
+ {"startup_time" , "u"},
+ {"display_name" , "s"},
+ {"screen_number" , "i"},
+ {"workspace" , "i"},
+ {"viewport_x" , "i"},
+ {"viewport_y" , "i"},
+};
+
+static const GDBusArgInfo out_args[] = {
+ {"wait_id" , "u"},
+};
+
+static const GDBusMethodInfo command_line_methods[] = {
+ {"Open", "assiibbbusiiii", 13, in_args, "u", 1, out_args}
+};
+
+static const GDBusArgInfo signal_args[] = {
+ {"wait_id", "u"}
+};
+
+static const GDBusSignalInfo command_line_signals[] = {
+ {"WaitDone", "u", 1, signal_args}
+};
+
+static const GDBusInterfaceInfo command_line_interface = {
+ "org.gnome.gedit.CommandLine",
+ 1, command_line_methods,
+ 1, command_line_signals
+};
+
+static const GDBusInterfaceVTable command_line_vtable = {
+ dbus_command_line_method_call_cb,
+};
+
+static gboolean
+register_dbus_interface (GeditDBus *dbus,
+ GDBusConnection *connection)
+{
+ guint ret;
+
+ ret = g_dbus_connection_register_object (connection,
+ "/org/gnome/gedit",
+ "org.gnome.gedit.CommandLine",
+ &command_line_interface,
+ &command_line_vtable,
+ dbus,
+ NULL,
+ NULL);
+
+ return ret != 0;
+}
+
+static void
+bus_acquired_cb (GDBusConnection *connection,
+ const gchar *name,
+ GeditDBus *dbus)
+{
+ if (connection == NULL)
+ {
+ g_warning ("Failed to acquire dbus connection");
+ dbus->priv->result = GEDIT_DBUS_RESULT_PROCEED;
+
+ g_main_loop_quit (dbus->priv->main_loop);
+ }
+ else
+ {
+ /* setup the dbus interface that other gedit processes can call. we do
+ this here even though we might not own the name, because the docs say
+ it should be done here... */
+ register_dbus_interface (dbus, connection);
+ }
+}
+
+static void
+name_acquired_cb (GDBusConnection *connection,
+ const gchar *name,
+ GeditDBus *dbus)
+{
+ dbus->priv->result = GEDIT_DBUS_RESULT_SUCCESS;
+ g_main_loop_quit (dbus->priv->main_loop);
+}
+
+static void
+name_lost_cb (GDBusConnection *connection,
+ const gchar *name,
+ GeditDBus *dbus)
+{
+ dbus->priv->result = GEDIT_DBUS_RESULT_FAILED;
+ g_main_loop_quit (dbus->priv->main_loop);
+}
+
+GeditDBusResult
+gedit_dbus_run (GeditDBus *dbus)
+{
+ guint id;
+ GeditCommandLine *command_line;
+
+ g_return_val_if_fail (GEDIT_IS_DBUS (dbus), GEDIT_DBUS_RESULT_PROCEED);
+
+ command_line = gedit_command_line_get_default ();
+
+ if (gedit_command_line_get_standalone (command_line))
+ {
+ return GEDIT_DBUS_RESULT_PROCEED;
+ }
+
+ if (gedit_command_line_get_wait (command_line) ||
+ gedit_command_line_get_background (command_line))
+ {
+ return handle_service (dbus);
+ }
+
+ id = g_bus_own_name (G_BUS_TYPE_SESSION,
+ "org.gnome.gedit",
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ (GBusAcquiredCallback)bus_acquired_cb,
+ (GBusNameAcquiredCallback)name_acquired_cb,
+ (GBusNameLostCallback)name_lost_cb,
+ dbus,
+ NULL);
+
+ dbus->priv->main_loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (dbus->priv->main_loop);
+ g_main_loop_unref (dbus->priv->main_loop);
+
+ switch (dbus->priv->result)
+ {
+ case GEDIT_DBUS_RESULT_PROCEED:
+ /* could not initialize dbus, gonna be standalone */
+ return GEDIT_DBUS_RESULT_PROCEED;
+ break;
+ case GEDIT_DBUS_RESULT_FAILED:
+ /* there is already a gedit process */
+ return handle_slave (dbus);
+ break;
+ case GEDIT_DBUS_RESULT_SUCCESS:
+ /* we are the main gedit process */
+ return handle_master (dbus);
+ break;
+ }
+
+ g_assert_not_reached ();
+}
diff --git a/gedit/gedit-dbus.h b/gedit/gedit-dbus.h
index fc38bcd..9532c3c 100644
--- a/gedit/gedit-dbus.h
+++ b/gedit/gedit-dbus.h
@@ -23,7 +23,21 @@
#ifndef __GEDIT_DBUS_H__
#define __GEDIT_DBUS_H__
-#include "gedit-command-line.h"
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_DBUS (gedit_dbus_get_type ())
+#define GEDIT_DBUS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_DBUS, GeditDBus))
+#define GEDIT_DBUS_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_DBUS, GeditDBus const))
+#define GEDIT_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEDIT_TYPE_DBUS, GeditDBusClass))
+#define GEDIT_IS_DBUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEDIT_TYPE_DBUS))
+#define GEDIT_IS_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_DBUS))
+#define GEDIT_DBUS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEDIT_TYPE_DBUS, GeditDBusClass))
+
+typedef struct _GeditDBus GeditDBus;
+typedef struct _GeditDBusClass GeditDBusClass;
+typedef struct _GeditDBusPrivate GeditDBusPrivate;
typedef enum
{
@@ -32,7 +46,23 @@ typedef enum
GEDIT_DBUS_RESULT_PROCEED
} GeditDBusResult;
-GeditDBusResult gedit_dbus_initialize (GeditCommandLine *command_line);
+struct _GeditDBus {
+ GObject parent;
+
+ GeditDBusPrivate *priv;
+};
+
+struct _GeditDBusClass {
+ GObjectClass parent_class;
+};
+
+GType gedit_dbus_get_type (void) G_GNUC_CONST;
+GeditDBus *gedit_dbus_new (void);
+
+GeditDBusResult gedit_dbus_run (GeditDBus *bus);
+
+G_END_DECLS
#endif /* __GEDIT_DBUS_H__ */
+/* ex:ts=8:noet: */
diff --git a/gedit/gedit-window.c b/gedit/gedit-window.c
index bdd919d..957758b 100644
--- a/gedit/gedit-window.c
+++ b/gedit/gedit-window.c
@@ -1201,15 +1201,18 @@ open_recent_file (GFile *location,
GeditWindow *window)
{
GSList *locations = NULL;
+ GSList *loaded = NULL;
locations = g_slist_prepend (locations, (gpointer) location);
-
- if (gedit_commands_load_locations (window, locations, NULL, 0, 0) != 1)
+ loaded = gedit_commands_load_locations (window, locations, NULL, 0, 0);
+
+ if (!loaded || loaded->next) /* if it doesn't contain just 1 element */
{
_gedit_recent_remove (window, location);
}
g_slist_free (locations);
+ g_slist_free (loaded);
}
static void
@@ -2836,7 +2839,8 @@ load_uris_from_drop (GeditWindow *window,
{
GSList *locations = NULL;
gint i;
-
+ GSList *loaded;
+
if (uri_list == NULL)
return;
@@ -2846,11 +2850,13 @@ load_uris_from_drop (GeditWindow *window,
}
locations = g_slist_reverse (locations);
- gedit_commands_load_locations (window,
- locations,
- NULL,
- 0,
- 0);
+ loaded = gedit_commands_load_locations (window,
+ locations,
+ NULL,
+ 0,
+ 0);
+
+ g_slist_free (loaded);
g_slist_foreach (locations, (GFunc) g_object_unref, NULL);
g_slist_free (locations);
diff --git a/gedit/gedit.c b/gedit/gedit.c
index 4f3ea9c..d8e174a 100644
--- a/gedit/gedit.c
+++ b/gedit/gedit.c
@@ -123,12 +123,16 @@ gedit_main (GeditCommandLine *command_line)
if (file_list != NULL)
{
+ GSList *loaded;
+
gedit_debug_message (DEBUG_APP, "Load files");
- _gedit_cmd_load_files_from_prompt (window,
- file_list,
- gedit_command_line_get_encoding (command_line),
- gedit_command_line_get_line_position (command_line),
- gedit_command_line_get_column_position (command_line));
+ loaded = _gedit_cmd_load_files_from_prompt (window,
+ file_list,
+ gedit_command_line_get_encoding (command_line),
+ gedit_command_line_get_line_position (command_line),
+ gedit_command_line_get_column_position (command_line));
+
+ g_slist_free (loaded);
}
else
{
@@ -158,6 +162,7 @@ main (int argc, char *argv[])
gchar *dir;
GeditCommandLine *command_line;
gboolean ret;
+ GeditDBus *dbus;
GeditDBusResult dbusret;
/* Init type system as soon as possible */
@@ -185,7 +190,7 @@ main (int argc, char *argv[])
gedit_osx_initialize ();
/* Parse command line arguments */
- command_line = gedit_command_line_new ();
+ command_line = gedit_command_line_get_default ();
ret = gedit_command_line_parse (command_line, &argc, &argv);
@@ -200,13 +205,16 @@ main (int argc, char *argv[])
gedit_prefs_manager_app_init ();
/* Run over dbus */
- dbusret = gedit_dbus_initialize (command_line);
+ dbus = gedit_dbus_new ();
+ dbusret = gedit_dbus_run (dbus);
switch (dbusret)
{
case GEDIT_DBUS_RESULT_SUCCESS:
case GEDIT_DBUS_RESULT_FAILED: /* fallthrough */
g_object_unref (command_line);
+ g_object_unref (dbus);
+
gedit_prefs_manager_app_shutdown ();
return dbusret == GEDIT_DBUS_RESULT_SUCCESS ? 0 : 1;
@@ -217,6 +225,8 @@ main (int argc, char *argv[])
gedit_main (command_line);
+ g_object_unref (dbus);
+
gedit_prefs_manager_app_shutdown ();
g_object_unref (command_line);
diff --git a/plugin-loaders/python/bindings/geditcommands.defs b/plugin-loaders/python/bindings/geditcommands.defs
index f5ad9ba..ed8121d 100644
--- a/plugin-loaders/python/bindings/geditcommands.defs
+++ b/plugin-loaders/python/bindings/geditcommands.defs
@@ -19,7 +19,7 @@
(define-function load_locations
(c-name "gedit_commands_load_locations")
- (return-type "gint")
+ (return-type "GSList*")
(parameters
'("GeditWindow*" "window")
'("const-GSList*" "locations")
diff --git a/plugin-loaders/python/bindings/geditcommands.override b/plugin-loaders/python/bindings/geditcommands.override
index 3a9f57e..17229d1 100644
--- a/plugin-loaders/python/bindings/geditcommands.override
+++ b/plugin-loaders/python/bindings/geditcommands.override
@@ -72,6 +72,8 @@ _wrap_gedit_commands_load_locations (PyObject *self, PyObject *args, PyObject *k
GeditEncoding *encoding = NULL;
int len;
int i;
+ GSList *loaded;
+ GSList *doc;
if (!PyArg_ParseTupleAndKeywords (args, kwargs, "O!O|Oii:load_locations",
kwlist, &PyGeditWindow_Type,
@@ -116,10 +118,33 @@ _wrap_gedit_commands_load_locations (PyObject *self, PyObject *args, PyObject *k
}
locations = g_slist_reverse (locations);
- gedit_commands_load_locations (GEDIT_WINDOW (window->obj), locations,
- encoding, line_pos, column_pos);
+ loaded = gedit_commands_load_locations (GEDIT_WINDOW (window->obj), locations,
+ encoding, line_pos, column_pos);
g_slist_free (locations);
- Py_INCREF (Py_None);
- return Py_None;
+ if ((list = PyList_New(0)) == NULL)
+ {
+ g_slist_free (loaded);
+ return NULL;
+ }
+
+ for (doc = loaded; doc; doc = g_slist_next (doc))
+ {
+ PyObject *py_obj = pygobject_new (G_OBJECT (doc->data));
+
+ if (py_obj == NULL)
+ {
+ g_slist_free (loaded);
+
+ Py_DECREF(list);
+ return NULL;
+ }
+
+ PyList_Append(list, py_obj);
+ Py_DECREF(py_obj);
+ }
+
+ g_slist_free (loaded);
+
+ return list;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]