[gnome-panel/bonobo-less: 91/93] [panel] Use a gio extension point to handle applets
- From: Vincent Untz <vuntz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-panel/bonobo-less: 91/93] [panel] Use a gio extension point to handle applets
- Date: Wed, 26 May 2010 08:33:55 +0000 (UTC)
commit bd8305fde4c52f6766d13fdac4842f95ecd78cc1
Author: Vincent Untz <vuntz gnome org>
Date: Wed May 26 05:29:33 2010 +0200
[panel] Use a gio extension point to handle applets
This way, we can have an external module to load bonobo applets.
configure.in | 4 +
gnome-panel/Makefile.am | 24 +-
gnome-panel/libpanel-applet-private/Makefile.am | 37 +
.../panel-applet-container.c | 0
.../panel-applet-container.h | 0
.../panel-applet-frame-dbus.c | 468 ++++++++
.../panel-applet-frame-dbus.h | 61 +
.../libpanel-applet-private/panel-applet-mini.c | 5 +
.../panel-applets-manager-dbus.c | 610 ++++++++++
.../panel-applets-manager-dbus.h | 56 +
gnome-panel/main.c | 2 -
gnome-panel/panel-applet-frame.c | 1188 +++++++++-----------
gnome-panel/panel-applet-frame.h | 80 ++-
gnome-panel/panel-applet-info.c | 111 ++
gnome-panel/panel-applet-info.h | 47 +
gnome-panel/panel-applets-manager.c | 580 ++--------
gnome-panel/panel-applets-manager.h | 71 +-
gnome-panel/panel-modules.c | 78 ++
gnome-panel/panel-modules.h | 30 +
gnome-panel/panel-test-applets.c | 40 +-
20 files changed, 2264 insertions(+), 1228 deletions(-)
---
diff --git a/configure.in b/configure.in
index 70ace27..fe04238 100644
--- a/configure.in
+++ b/configure.in
@@ -269,6 +269,9 @@ else
have_randr=no
fi
+dnl Modules dir
+AC_SUBST([modulesdir],"\$(libdir)/gnome-panel/modules")
+
dnl Applets dir
AC_SUBST([appletsdir],"\$(datadir)/gnome-panel/applets")
@@ -325,6 +328,7 @@ icons/48x48/Makefile
icons/scalable/Makefile
gnome-panel/Makefile
gnome-panel/libegg/Makefile
+gnome-panel/libpanel-applet-private/Makefile
gnome-panel/libpanel-util/Makefile
gnome-panel/gnome-panel.desktop.in
libpanel-applet/libpanelapplet-2.0.pc
diff --git a/gnome-panel/Makefile.am b/gnome-panel/Makefile.am
index be9e130..0993dfe 100644
--- a/gnome-panel/Makefile.am
+++ b/gnome-panel/Makefile.am
@@ -1,6 +1,6 @@
## We require new-style dependency handling.
AUTOMAKE_OPTIONS = 1.3
-SUBDIRS = libegg libpanel-util
+SUBDIRS = libegg libpanel-applet-private libpanel-util
NULL =
@@ -14,6 +14,7 @@ INCLUDES = \
-DBUILDERDIR=\""$(uidir)"\" \
-DICONDIR=\""$(datadir)/gnome-panel/pixmaps"\" \
-DDATADIR=\""$(datadir)"\" \
+ -DPANEL_MODULES_DIR=\"$(modulesdir)\" \
-DPANEL_APPLETS_DIR=\"$(appletsdir)\" \
-DGMENU_I_KNOW_THIS_IS_UNSTABLE \
$(DISABLE_DEPRECATED_CFLAGS) \
@@ -63,7 +64,6 @@ panel_sources = \
panel-context-menu.c \
launcher.c \
panel-applet-frame.c \
- panel-applet-container.c \
panel-applets-manager.c \
panel-shell.c \
panel-background.c \
@@ -88,6 +88,8 @@ panel_sources = \
panel-lockdown.c \
panel-addto.c \
panel-ditem-editor.c \
+ panel-modules.c \
+ panel-applet-info.c \
$(NULL)
panel_headers = \
@@ -110,7 +112,6 @@ panel_headers = \
panel-context-menu.h \
launcher.h \
panel-applet-frame.h \
- panel-applet-container.h \
panel-applets-manager.h \
panel-shell.h \
panel-background.h \
@@ -137,6 +138,8 @@ panel_headers = \
panel-addto.h \
panel-ditem-editor.h \
panel-icon-names.h \
+ panel-modules.h \
+ panel-applet-info.h \
$(NULL)
gnome_panel_SOURCES = \
@@ -145,9 +148,10 @@ gnome_panel_SOURCES = \
$(NULL)
gnome_panel_LDADD = \
- $(top_builddir)/gnome-panel/libegg/libegg.la \
- $(top_builddir)/gnome-panel/libpanel-util/libpanel-util.la \
- $(PANEL_LIBS) \
+ $(top_builddir)/gnome-panel/libegg/libegg.la \
+ $(top_builddir)/gnome-panel/libpanel-applet-private/libpanel-applet-private.la \
+ $(top_builddir)/gnome-panel/libpanel-util/libpanel-util.la \
+ $(PANEL_LIBS) \
$(X_LIBS)
gnome_panel_LDFLAGS = -export-dynamic
@@ -182,13 +186,17 @@ gnome-panel-add: gnome-panel-add.in Makefile
$(AM_V_at)chmod a+x $@
panel_test_applets_SOURCES = \
- panel-applet-container.c \
+ panel-modules.c \
+ panel-applet-info.c \
panel-applets-manager.c \
panel-marshal.c \
panel-test-applets.c
panel_test_applets_LDFLAGS = -export-dynamic
-panel_test_applets_LDADD = $(PANEL_LIBS)
+panel_test_applets_LDADD = \
+ $(top_builddir)/gnome-panel/libpanel-applet-private/libpanel-applet-private-mini.la \
+ $(top_builddir)/gnome-panel/libpanel-util/libpanel-util.la \
+ $(PANEL_LIBS)
EXTRA_DIST = \
$(ui_DATA) \
diff --git a/gnome-panel/libpanel-applet-private/Makefile.am b/gnome-panel/libpanel-applet-private/Makefile.am
new file mode 100644
index 0000000..0782d3e
--- /dev/null
+++ b/gnome-panel/libpanel-applet-private/Makefile.am
@@ -0,0 +1,37 @@
+NULL =
+
+INCLUDES = \
+ -I. \
+ -I$(srcdir) \
+ -I$(top_builddir)/gnome-panel \
+ -I$(top_builddir)/gnome-panel/libpanel-applets-private \
+ -I$(top_builddir)/gnome-panel/libpanel-util \
+ -DDATADIR=\""$(datadir)"\" \
+ -DPANEL_APPLETS_DIR=\"$(appletsdir)\" \
+ $(DISABLE_DEPRECATED_CFLAGS) \
+ $(PANEL_CFLAGS) \
+ $(WARN_CFLAGS) \
+ $(NULL)
+
+noinst_LTLIBRARIES= \
+ libpanel-applet-private.la \
+ libpanel-applet-private-mini.la
+
+libpanel_applet_private_la_SOURCES= \
+ panel-applets-manager-dbus.c \
+ panel-applets-manager-dbus.h \
+ panel-applet-container.c \
+ panel-applet-container.h \
+ panel-applet-frame-dbus.c \
+ panel-applet-frame-dbus.h \
+ $(NULL)
+
+libpanel_applet_private_mini_la_SOURCES= \
+ panel-applet-mini.c \
+ panel-applets-manager-dbus.c \
+ panel-applets-manager-dbus.h \
+ panel-applet-container.c \
+ panel-applet-container.h \
+ $(NULL)
+
+-include $(top_srcdir)/git.mk
diff --git a/gnome-panel/panel-applet-container.c b/gnome-panel/libpanel-applet-private/panel-applet-container.c
similarity index 100%
rename from gnome-panel/panel-applet-container.c
rename to gnome-panel/libpanel-applet-private/panel-applet-container.c
diff --git a/gnome-panel/panel-applet-container.h b/gnome-panel/libpanel-applet-private/panel-applet-container.h
similarity index 100%
rename from gnome-panel/panel-applet-container.h
rename to gnome-panel/libpanel-applet-private/panel-applet-container.h
diff --git a/gnome-panel/libpanel-applet-private/panel-applet-frame-dbus.c b/gnome-panel/libpanel-applet-private/panel-applet-frame-dbus.c
new file mode 100644
index 0000000..dd1d1e6
--- /dev/null
+++ b/gnome-panel/libpanel-applet-private/panel-applet-frame-dbus.c
@@ -0,0 +1,468 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * panel-applet-frame-dbus.c: panel side container for applets
+ *
+ * Copyright (C) 2001 - 2003 Sun Microsystems, Inc.
+ * Copyright (C) 2010 Carlos Garcia Campos <carlosgc gnome org>
+ * Copyright (C) 2010 Vincent Untz <vuntz gnome 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 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
+ * 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.
+ *
+ * Authors:
+ * Mark McLoughlin <mark skynet ie>
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <panel-applet-frame.h>
+#include <panel-applets-manager.h>
+
+#include "panel-applet-container.h"
+
+#include "panel-applet-frame-dbus.h"
+
+G_DEFINE_TYPE (PanelAppletFrameDBus,
+ panel_applet_frame_dbus,
+ PANEL_TYPE_APPLET_FRAME)
+
+struct _PanelAppletFrameDBusPrivate
+{
+ PanelAppletContainer *container;
+ GCancellable *bg_cancellable;
+};
+
+/* Keep in sync with panel-applet.h. Uggh. */
+typedef enum {
+ APPLET_FLAGS_NONE = 0,
+ APPLET_EXPAND_MAJOR = 1 << 0,
+ APPLET_EXPAND_MINOR = 1 << 1,
+ APPLET_HAS_HANDLE = 1 << 2
+} PanelAppletFlags;
+
+
+static guint
+get_panel_applet_orient (PanelOrientation orientation)
+{
+ /* For some reason libpanel-applet and panel use a different logic for
+ * orientation, so we need to convert it. We should fix this. */
+ switch (orientation) {
+ case PANEL_ORIENTATION_TOP:
+ return 1;
+ case PANEL_ORIENTATION_BOTTOM:
+ return 0;
+ case PANEL_ORIENTATION_LEFT:
+ return 3;
+ case PANEL_ORIENTATION_RIGHT:
+ return 2;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+}
+
+static void
+panel_applet_frame_dbus_update_flags (PanelAppletFrame *frame,
+ GVariant *value)
+{
+ guint32 flags;
+ gboolean major;
+ gboolean minor;
+ gboolean has_handle;
+
+ flags = g_variant_get_uint32 (value);
+
+ major = (flags & APPLET_EXPAND_MAJOR) != 0;
+ minor = (flags & APPLET_EXPAND_MINOR) != 0;
+ has_handle = (flags & APPLET_HAS_HANDLE) != 0;
+
+ _panel_applet_frame_update_flags (frame, major, minor, has_handle);
+}
+
+
+static void
+panel_applet_frame_dbus_get_flags_cb (PanelAppletContainer *container,
+ GAsyncResult *res,
+ PanelAppletFrame *frame)
+{
+ GVariant *value;
+ GError *error = NULL;
+
+ value = panel_applet_container_child_get_finish (container, res, &error);
+ if (!value) {
+ g_warning ("%s\n", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ panel_applet_frame_dbus_update_flags (frame, value);
+ g_variant_unref (value);
+}
+
+static void
+panel_applet_frame_dbus_get_size_hints_cb (PanelAppletContainer *container,
+ GAsyncResult *res,
+ PanelAppletFrame *frame)
+{
+ GVariant *value;
+ const gint *sz;
+ gint *size_hints = NULL;
+ gsize n_elements;
+ GError *error = NULL;
+
+ value = panel_applet_container_child_get_finish (container, res, &error);
+ if (!value) {
+ g_warning ("%s\n", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ sz = g_variant_get_fixed_array (value, &n_elements, sizeof (gint32));
+ if (n_elements > 0) {
+ size_hints = g_new (gint32, n_elements);
+ memcpy (size_hints, sz, n_elements * sizeof (gint32));
+ }
+
+ _panel_applet_frame_update_size_hints (frame, size_hints, n_elements);
+ g_variant_unref (value);
+}
+
+static void
+panel_applet_frame_dbus_init_properties (PanelAppletFrame *frame)
+{
+ PanelAppletFrameDBus *dbus_frame = PANEL_APPLET_FRAME_DBUS (frame);
+
+ panel_applet_container_child_get (dbus_frame->priv->container, "flags", NULL,
+ (GAsyncReadyCallback) panel_applet_frame_dbus_get_flags_cb,
+ frame);
+ panel_applet_container_child_get (dbus_frame->priv->container, "size-hints", NULL,
+ (GAsyncReadyCallback) panel_applet_frame_dbus_get_size_hints_cb,
+ frame);
+}
+
+static void
+panel_applet_frame_dbus_sync_menu_state (PanelAppletFrame *frame,
+ gboolean movable,
+ gboolean removable,
+ gboolean lockable,
+ gboolean locked,
+ gboolean locked_down)
+{
+ PanelAppletFrameDBus *dbus_frame = PANEL_APPLET_FRAME_DBUS (frame);
+
+ panel_applet_container_child_set (dbus_frame->priv->container,
+ "locked", g_variant_new_boolean (lockable && locked),
+ NULL, NULL, NULL);
+ panel_applet_container_child_set (dbus_frame->priv->container,
+ "locked-down", g_variant_new_boolean (locked_down),
+ NULL, NULL, NULL);
+}
+
+static void
+panel_applet_frame_dbus_popup_menu (PanelAppletFrame *frame,
+ guint button,
+ guint32 timestamp)
+{
+ PanelAppletFrameDBus *dbus_frame = PANEL_APPLET_FRAME_DBUS (frame);
+
+ panel_applet_container_child_popup_menu (dbus_frame->priv->container,
+ button, timestamp,
+ NULL, NULL, NULL);
+}
+
+static void
+change_orientation_cb (PanelAppletContainer *container,
+ GAsyncResult *res,
+ PanelAppletFrame *frame)
+{
+ GError *error = NULL;
+
+ if (!panel_applet_container_child_set_finish (container, res, &error)) {
+ g_warning ("%s\n", error->message);
+ g_error_free (error);
+
+ return;
+ }
+
+ gtk_widget_queue_resize (GTK_WIDGET (frame));
+}
+
+static void
+panel_applet_frame_dbus_change_orientation (PanelAppletFrame *frame,
+ PanelOrientation orientation)
+{
+ PanelAppletFrameDBus *dbus_frame = PANEL_APPLET_FRAME_DBUS (frame);
+
+ panel_applet_container_child_set (dbus_frame->priv->container,
+ "orient",
+ g_variant_new_uint32 (get_panel_applet_orient (orientation)),
+ NULL,
+ (GAsyncReadyCallback)change_orientation_cb,
+ frame);
+}
+
+static void
+panel_applet_frame_dbus_change_size (PanelAppletFrame *frame,
+ guint size)
+{
+ PanelAppletFrameDBus *dbus_frame = PANEL_APPLET_FRAME_DBUS (frame);
+
+ panel_applet_container_child_set (dbus_frame->priv->container,
+ "size", g_variant_new_uint32 (size),
+ NULL, NULL, NULL);
+}
+
+static void
+container_child_background_set (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ PanelAppletContainer *container = PANEL_APPLET_CONTAINER (source_object);
+ PanelAppletFrameDBus *frame = PANEL_APPLET_FRAME_DBUS (user_data);
+
+ panel_applet_container_child_set_finish (container, res, NULL);
+
+ if (frame->priv->bg_cancellable)
+ g_object_unref (frame->priv->bg_cancellable);
+ frame->priv->bg_cancellable = NULL;
+}
+
+static void
+panel_applet_frame_dbus_change_background (PanelAppletFrame *frame,
+ PanelBackgroundType type)
+{
+ PanelAppletFrameDBus *dbus_frame = PANEL_APPLET_FRAME_DBUS (frame);
+ char *bg_str;
+
+ bg_str = _panel_applet_frame_get_background_string (
+ frame, PANEL_WIDGET (GTK_WIDGET (frame)->parent), type);
+
+ if (bg_str != NULL) {
+ if (dbus_frame->priv->bg_cancellable)
+ g_cancellable_cancel (dbus_frame->priv->bg_cancellable);
+ dbus_frame->priv->bg_cancellable = g_cancellable_new ();
+
+ panel_applet_container_child_set (dbus_frame->priv->container,
+ "background",
+ g_variant_new_string (bg_str),
+ dbus_frame->priv->bg_cancellable,
+ container_child_background_set,
+ dbus_frame);
+ g_free (bg_str);
+ }
+}
+
+static void
+panel_applet_frame_dbus_flags_changed (PanelAppletContainer *container,
+ const gchar *prop_name,
+ GVariant *value,
+ PanelAppletFrame *frame)
+{
+ panel_applet_frame_dbus_update_flags (frame, value);
+}
+
+static void
+panel_applet_frame_dbus_size_hints_changed (PanelAppletContainer *container,
+ const gchar *prop_name,
+ GVariant *value,
+ PanelAppletFrame *frame)
+{
+ const gint *sz;
+ gint *size_hints = NULL;
+ gsize n_elements;
+
+ sz = g_variant_get_fixed_array (value, &n_elements, sizeof (gint32));
+ if (n_elements > 0) {
+ size_hints = g_new (gint32, n_elements);
+ memcpy (size_hints, sz, n_elements * sizeof (gint32));
+ }
+
+ _panel_applet_frame_update_size_hints (frame, size_hints, n_elements);
+}
+
+static void
+panel_applet_frame_dbus_applet_broken (PanelAppletContainer *container,
+ PanelAppletFrame *frame)
+{
+ _panel_applet_frame_applet_broken (frame);
+}
+
+static void
+panel_applet_frame_dbus_applet_remove (PanelAppletContainer *container,
+ PanelAppletFrame *frame)
+{
+ _panel_applet_frame_applet_remove (frame);
+}
+
+static void
+panel_applet_frame_dbus_applet_move (PanelAppletContainer *container,
+ PanelAppletFrame *frame)
+{
+ _panel_applet_frame_applet_move (frame);
+}
+
+static void
+panel_applet_frame_dbus_applet_lock (PanelAppletContainer *container,
+ gboolean locked,
+ PanelAppletFrame *frame)
+{
+ _panel_applet_frame_applet_lock (frame, locked);
+}
+
+static void
+panel_applet_frame_dbus_finalize (GObject *object)
+{
+ PanelAppletFrameDBus *frame = PANEL_APPLET_FRAME_DBUS (object);
+
+ if (frame->priv->bg_cancellable)
+ g_object_unref (frame->priv->bg_cancellable);
+ frame->priv->bg_cancellable = NULL;
+
+ G_OBJECT_CLASS (panel_applet_frame_dbus_parent_class)->finalize (object);
+}
+
+static void
+panel_applet_frame_dbus_init (PanelAppletFrameDBus *frame)
+{
+ GtkWidget *container;
+
+ frame->priv = G_TYPE_INSTANCE_GET_PRIVATE (frame,
+ PANEL_TYPE_APPLET_FRAME_DBUS,
+ PanelAppletFrameDBusPrivate);
+
+ container = panel_applet_container_new ();
+ gtk_widget_show (container);
+ gtk_container_add (GTK_CONTAINER (frame), container);
+ frame->priv->container = PANEL_APPLET_CONTAINER (container);
+
+ g_signal_connect (container, "child-property-changed::flags",
+ G_CALLBACK (panel_applet_frame_dbus_flags_changed),
+ frame);
+ g_signal_connect (container, "child-property-changed::size-hints",
+ G_CALLBACK (panel_applet_frame_dbus_size_hints_changed),
+ frame);
+ g_signal_connect (container, "applet-broken",
+ G_CALLBACK (panel_applet_frame_dbus_applet_broken),
+ frame);
+ g_signal_connect (container, "applet-remove",
+ G_CALLBACK (panel_applet_frame_dbus_applet_remove),
+ frame);
+ g_signal_connect (container, "applet-move",
+ G_CALLBACK (panel_applet_frame_dbus_applet_move),
+ frame);
+ g_signal_connect (container, "applet-lock",
+ G_CALLBACK (panel_applet_frame_dbus_applet_lock),
+ frame);
+}
+
+static void
+panel_applet_frame_dbus_class_init (PanelAppletFrameDBusClass *class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+ PanelAppletFrameClass *frame_class = PANEL_APPLET_FRAME_CLASS (class);
+
+ gobject_class->finalize = panel_applet_frame_dbus_finalize;
+
+ frame_class->init_properties = panel_applet_frame_dbus_init_properties;
+ frame_class->sync_menu_state = panel_applet_frame_dbus_sync_menu_state;
+ frame_class->popup_menu = panel_applet_frame_dbus_popup_menu;
+ frame_class->change_orientation = panel_applet_frame_dbus_change_orientation;
+ frame_class->change_size = panel_applet_frame_dbus_change_size;
+ frame_class->change_background = panel_applet_frame_dbus_change_background;
+
+ g_type_class_add_private (class, sizeof (PanelAppletFrameDBusPrivate));
+}
+
+static void
+panel_applet_frame_dbus_activated (PanelAppletContainer *container,
+ GAsyncResult *res,
+ PanelAppletFrame *frame)
+{
+ PanelAppletFrameActivating *frame_act;
+ GError *error = NULL;
+
+ if (!panel_applet_container_add_finish (container, res, &error))
+ g_assert (error != NULL);
+
+ frame_act = g_object_get_data (G_OBJECT (frame), "panel-applet-frame-activating");
+ g_object_set_data (G_OBJECT (frame), "panel-applet-frame-activating", NULL);
+
+ _panel_applet_frame_activated (frame, frame_act, error);
+}
+
+gboolean
+panel_applet_frame_dbus_load (const gchar *iid,
+ PanelAppletFrameActivating *frame_act)
+{
+ PanelAppletFrameDBus *dbus_frame;
+ PanelAppletFrame *frame;
+ GVariantBuilder builder;
+ gchar *conf_path;
+ gchar *background;
+ guint orient;
+
+ g_return_val_if_fail (iid != NULL, FALSE);
+ g_return_val_if_fail (frame_act != NULL, FALSE);
+
+ if (!panel_applets_manager_factory_activate (iid))
+ return FALSE;
+
+ dbus_frame = g_object_new (PANEL_TYPE_APPLET_FRAME_DBUS, NULL);
+ frame = PANEL_APPLET_FRAME (dbus_frame);
+ _panel_applet_frame_set_iid (frame, iid);
+
+ orient = get_panel_applet_orient (panel_applet_frame_activating_get_orientation (frame_act));
+ conf_path = panel_applet_frame_activating_get_conf_path (frame_act);
+ /* we can't really get a background string at this point since we don't
+ * know the position of the applet */
+ background = NULL;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
+ g_variant_builder_add (&builder, "{sv}",
+ "prefs-key",
+ g_variant_new_string (conf_path));
+ g_variant_builder_add (&builder, "{sv}",
+ "orient",
+ g_variant_new_uint32 (orient));
+ g_variant_builder_add (&builder, "{sv}",
+ "size",
+ g_variant_new_uint32 (panel_applet_frame_activating_get_size (frame_act)));
+ g_variant_builder_add (&builder, "{sv}",
+ "locked",
+ g_variant_new_boolean (panel_applet_frame_activating_get_locked (frame_act)));
+ g_variant_builder_add (&builder, "{sv}",
+ "locked-down",
+ g_variant_new_boolean (panel_applet_frame_activating_get_locked_down (frame_act)));
+ if (background) {
+ g_variant_builder_add (&builder, "{sv}",
+ "background",
+ g_variant_new_string (background));
+ }
+
+ g_object_set_data (G_OBJECT (frame), "panel-applet-frame-activating", frame_act);
+
+ panel_applet_container_add (dbus_frame->priv->container,
+ iid, NULL,
+ (GAsyncReadyCallback) panel_applet_frame_dbus_activated,
+ frame,
+ g_variant_builder_end (&builder));
+
+ g_free (conf_path);
+ g_free (background);
+
+ return TRUE;
+}
diff --git a/gnome-panel/libpanel-applet-private/panel-applet-frame-dbus.h b/gnome-panel/libpanel-applet-private/panel-applet-frame-dbus.h
new file mode 100644
index 0000000..cb133b0
--- /dev/null
+++ b/gnome-panel/libpanel-applet-private/panel-applet-frame-dbus.h
@@ -0,0 +1,61 @@
+/*
+ * panel-applet-frame-dbus.h: panel side container for applets
+ *
+ * Copyright (C) 2001 - 2003 Sun Microsystems, Inc.
+ * Copyright (C) 2010 Vincent Untz <vuntz gnome 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 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
+ * 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.
+ *
+ * Authors:
+ * Mark McLoughlin <mark skynet ie>
+ */
+
+#ifndef __PANEL_APPLET_FRAME_DBUS_H__
+#define __PANEL_APPLET_FRAME_DBUS_H__
+
+#include <panel-applet-frame.h>
+
+G_BEGIN_DECLS
+
+#define PANEL_TYPE_APPLET_FRAME_DBUS (panel_applet_frame_dbus_get_type ())
+#define PANEL_APPLET_FRAME_DBUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PANEL_TYPE_APPLET_FRAME_DBUS, PanelAppletFrameDBus))
+#define PANEL_APPLET_FRAME_DBUS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PANEL_TYPE_APPLET_FRAME_DBUS, PanelAppletFrameDBusClass))
+#define PANEL_IS_APPLET_FRAME_DBUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PANEL_TYPE_APPLET_FRAME_DBUS))
+#define PANEL_IS_APPLET_FRAME_DBUS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PANEL_TYPE_APPLET_FRAME_DBUS))
+#define PANEL_APPLET_FRAME_DBUS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), PANEL_TYPE_APPLET_FRAME_DBUS, PanelAppletFrameDBusClass))
+
+typedef struct _PanelAppletFrameDBus PanelAppletFrameDBus;
+typedef struct _PanelAppletFrameDBusClass PanelAppletFrameDBusClass;
+typedef struct _PanelAppletFrameDBusPrivate PanelAppletFrameDBusPrivate;
+
+struct _PanelAppletFrameDBusClass {
+ PanelAppletFrameClass parent_class;
+};
+
+struct _PanelAppletFrameDBus{
+ PanelAppletFrame parent;
+
+ PanelAppletFrameDBusPrivate *priv;
+};
+
+GType panel_applet_frame_dbus_get_type (void) G_GNUC_CONST;
+
+gboolean panel_applet_frame_dbus_load (const gchar *iid,
+ PanelAppletFrameActivating *frame_act);
+
+G_END_DECLS
+
+#endif /* __PANEL_APPLET_FRAME_DBUS_H__ */
diff --git a/gnome-panel/libpanel-applet-private/panel-applet-mini.c b/gnome-panel/libpanel-applet-private/panel-applet-mini.c
new file mode 100644
index 0000000..e9c498e
--- /dev/null
+++ b/gnome-panel/libpanel-applet-private/panel-applet-mini.c
@@ -0,0 +1,5 @@
+/* Symbols needed for libpanel-applet-private-mini, which is used by the test
+ * program */
+#include <glib.h>
+gboolean panel_applet_frame_dbus_load (const gchar *iid, gpointer frame_act);
+gboolean panel_applet_frame_dbus_load (const gchar *iid, gpointer frame_act) { return FALSE; }
diff --git a/gnome-panel/libpanel-applet-private/panel-applets-manager-dbus.c b/gnome-panel/libpanel-applet-private/panel-applets-manager-dbus.c
new file mode 100644
index 0000000..67eed60
--- /dev/null
+++ b/gnome-panel/libpanel-applet-private/panel-applets-manager-dbus.c
@@ -0,0 +1,610 @@
+/*
+ * panel-applets-manager-dbus.c
+ *
+ * Copyright (C) 2010 Carlos Garcia Campos <carlosgc gnome org>
+ * Copyright (C) 2010 Vincent Untz <vuntz gnome 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 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
+ * 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.
+ */
+
+#include <config.h>
+
+#include <gio/gio.h>
+#include <gmodule.h>
+#include <string.h>
+
+#include <panel-applets-manager.h>
+
+#include "panel-applet-frame-dbus.h"
+
+#include "panel-applets-manager-dbus.h"
+
+G_DEFINE_TYPE_WITH_CODE (PanelAppletsManagerDBus,
+ panel_applets_manager_dbus,
+ PANEL_TYPE_APPLETS_MANAGER,
+ g_io_extension_point_implement (PANEL_APPLETS_MANAGER_EXTENSION_POINT_NAME,
+ g_define_type_id,
+ "dbus",
+ 5))
+
+struct _PanelAppletsManagerDBusPrivate
+{
+ GHashTable *applet_factories;
+ GList *monitors;
+};
+
+typedef gint (* ActivateAppletFunc) (void);
+
+typedef struct _PanelAppletFactoryInfo {
+ gchar *id;
+ gchar *location;
+ gboolean in_process;
+ GModule *module;
+ ActivateAppletFunc activate_applet;
+ guint n_applets;
+
+ gchar *srcdir;
+
+ GList *applet_list;
+ gboolean has_old_ids;
+} PanelAppletFactoryInfo;
+
+#define PANEL_APPLET_FACTORY_GROUP "Applet Factory"
+#define PANEL_APPLETS_EXTENSION ".panel-applet"
+
+static void
+panel_applet_factory_info_free (PanelAppletFactoryInfo *info)
+{
+ if (!info)
+ return;
+
+ g_free (info->id);
+ g_free (info->location);
+ g_list_foreach (info->applet_list,
+ (GFunc)panel_applet_info_free,
+ NULL);
+ g_list_free (info->applet_list);
+ info->applet_list = NULL;
+ g_free (info->srcdir);
+
+ g_slice_free (PanelAppletFactoryInfo, info);
+}
+
+static PanelAppletInfo *
+_panel_applets_manager_get_applet_info (GKeyFile *applet_file,
+ const gchar *group,
+ const gchar *factory_id)
+{
+ PanelAppletInfo *info;
+ char *iid;
+ char *name;
+ char *comment;
+ char *icon;
+ char **old_ids;
+
+ iid = g_strdup_printf ("%s::%s", factory_id, group);
+ name = g_key_file_get_locale_string (applet_file, group,
+ "Name", NULL, NULL);
+ comment = g_key_file_get_locale_string (applet_file, group,
+ "Description", NULL, NULL);
+ icon = g_key_file_get_string (applet_file, group, "Icon", NULL);
+ /* Bonobo compatibility */
+ old_ids = g_key_file_get_string_list (applet_file, group,
+ "BonoboId", NULL, NULL);
+
+ info = panel_applet_info_new (iid, name, comment, icon, (const char **) old_ids);
+
+ g_free (iid);
+ g_free (name);
+ g_free (comment);
+ g_free (icon);
+ g_strfreev (old_ids);
+
+ return info;
+}
+
+static PanelAppletFactoryInfo *
+panel_applets_manager_get_applet_factory_info_from_file (const gchar *filename)
+{
+ PanelAppletFactoryInfo *info;
+ GKeyFile *applet_file;
+ gchar **groups;
+ gsize n_groups;
+ gint i;
+ GError *error = NULL;
+
+ applet_file = g_key_file_new ();
+ if (!g_key_file_load_from_file (applet_file, filename, G_KEY_FILE_NONE, &error)) {
+ g_warning ("Error opening panel applet file %s: %s",
+ filename, error->message);
+ g_error_free (error);
+ g_key_file_free (applet_file);
+
+ return NULL;
+ }
+
+ info = g_slice_new0 (PanelAppletFactoryInfo);
+ info->id = g_key_file_get_string (applet_file, PANEL_APPLET_FACTORY_GROUP, "Id", NULL);
+ if (!info->id) {
+ g_warning ("Bad panel applet file %s: Could not find 'Id' in group '%s'",
+ filename, PANEL_APPLET_FACTORY_GROUP);
+ panel_applet_factory_info_free (info);
+ g_key_file_free (applet_file);
+
+ return NULL;
+ }
+
+ info->in_process = g_key_file_get_boolean (applet_file, PANEL_APPLET_FACTORY_GROUP,
+ "InProcess", NULL);
+ if (info->in_process) {
+ info->location = g_key_file_get_string (applet_file, PANEL_APPLET_FACTORY_GROUP,
+ "Location", NULL);
+ if (!info->location) {
+ g_warning ("Bad panel applet file %s: In-process applet without 'Location'",
+ filename);
+ panel_applet_factory_info_free (info);
+ g_key_file_free (applet_file);
+
+ return NULL;
+ }
+ }
+
+ info->has_old_ids = FALSE;
+
+ groups = g_key_file_get_groups (applet_file, &n_groups);
+ for (i = 0; i < n_groups; i++) {
+ PanelAppletInfo *ainfo;
+
+ if (g_strcmp0 (groups[i], PANEL_APPLET_FACTORY_GROUP) == 0)
+ continue;
+
+ ainfo = _panel_applets_manager_get_applet_info (applet_file,
+ groups[i], info->id);
+ if (panel_applet_info_get_old_ids (ainfo) != NULL)
+ info->has_old_ids = TRUE;
+
+ info->applet_list = g_list_prepend (info->applet_list, ainfo);
+ }
+ g_strfreev (groups);
+
+ g_key_file_free (applet_file);
+
+ if (!info->applet_list) {
+ panel_applet_factory_info_free (info);
+ return NULL;
+ }
+
+ info->srcdir = g_path_get_dirname (filename);
+
+ return info;
+}
+
+static GSList *
+panel_applets_manager_get_applets_dirs (void)
+{
+ const gchar *dir = NULL;
+ gchar **paths;
+ guint i;
+ GSList *retval = NULL;
+
+ dir = g_getenv ("GNOME_PANEL_APPLETS_DIR");
+ if (!dir || g_strcmp0 (dir, "") == 0) {
+ return g_slist_prepend (NULL, g_strdup (PANEL_APPLETS_DIR));
+ }
+
+ paths = g_strsplit (dir, ":", 0);
+ for (i = 0; paths[i]; i++) {
+ if (g_slist_find_custom (retval, paths[i], (GCompareFunc)g_strcmp0))
+ continue;
+ retval = g_slist_prepend (retval, g_strdup (paths[i]));
+ }
+ g_strfreev (paths);
+
+ return g_slist_reverse (retval);
+}
+
+static void
+applets_directory_changed (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
+{
+ PanelAppletsManagerDBus *manager = PANEL_APPLETS_MANAGER_DBUS (user_data);
+
+ switch (event_type) {
+ case G_FILE_MONITOR_EVENT_CHANGED:
+ case G_FILE_MONITOR_EVENT_CREATED: {
+ PanelAppletFactoryInfo *info;
+ PanelAppletFactoryInfo *old_info;
+ gchar *filename;
+ GSList *dirs, *d;
+
+ filename = g_file_get_path (file);
+ if (!g_str_has_suffix (filename, PANEL_APPLETS_EXTENSION)) {
+ g_free (filename);
+ return;
+ }
+
+ info = panel_applets_manager_get_applet_factory_info_from_file (filename);
+ g_free (filename);
+
+ if (!info)
+ return;
+
+ old_info = g_hash_table_lookup (manager->priv->applet_factories, info->id);
+ if (!old_info) {
+ /* New applet, just insert it */
+ g_hash_table_insert (manager->priv->applet_factories, g_strdup (info->id), info);
+ return;
+ }
+
+ /* Make sure we don't update an applet
+ * that has changed in another source dir
+ * unless it takes precedence over the
+ * current one
+ */
+ if (g_strcmp0 (info->srcdir, old_info->srcdir) == 0) {
+ g_hash_table_insert (manager->priv->applet_factories, g_strdup (info->id), info);
+ return;
+ }
+
+ dirs = panel_applets_manager_get_applets_dirs ();
+
+ for (d = dirs; d; d = g_slist_next (d)) {
+ gchar *path = (gchar *)d->data;
+
+ if (g_strcmp0 (path, old_info->srcdir) == 0) {
+ panel_applet_factory_info_free (info);
+ break;
+ } else if (g_strcmp0 (path, info->srcdir) == 0) {
+ g_hash_table_insert (manager->priv->applet_factories, g_strdup (info->id), info);
+ break;
+ }
+ }
+
+ g_slist_foreach (dirs, (GFunc)g_free, NULL);
+ g_slist_free (dirs);
+ }
+ break;
+ default:
+ /* Ignore any other change */
+ break;
+ }
+}
+
+static gboolean
+panel_applets_manager_load_applet_infos (PanelAppletsManagerDBus *manager)
+{
+ GSList *dirs, *d;
+ GDir *dir;
+ const gchar *dirent;
+ GError *error = NULL;
+ gboolean retval = FALSE;
+
+ dirs = panel_applets_manager_get_applets_dirs ();
+ for (d = dirs; d; d = g_slist_next (d)) {
+ GFileMonitor *monitor;
+ GFile *dir_file;
+ gchar *path = (gchar *)d->data;
+
+ dir = g_dir_open (path, 0, &error);
+ if (!dir) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ g_free (path);
+
+ continue;
+ }
+
+ /* Monitor dir */
+ dir_file = g_file_new_for_path (path);
+ monitor = g_file_monitor_directory (dir_file,
+ G_FILE_MONITOR_NONE,
+ NULL, NULL);
+ if (monitor) {
+ g_signal_connect (monitor, "changed",
+ G_CALLBACK (applets_directory_changed),
+ manager);
+ manager->priv->monitors = g_list_prepend (manager->priv->monitors, monitor);
+ }
+ g_object_unref (dir_file);
+
+ while ((dirent = g_dir_read_name (dir))) {
+ PanelAppletFactoryInfo *info;
+ gchar *file;
+
+ if (!g_str_has_suffix (dirent, PANEL_APPLETS_EXTENSION))
+ continue;
+
+ file = g_build_filename (path, dirent, NULL);
+ info = panel_applets_manager_get_applet_factory_info_from_file (file);
+ g_free (file);
+
+ if (!info)
+ continue;
+
+ if (g_hash_table_lookup (manager->priv->applet_factories, info->id)) {
+ panel_applet_factory_info_free (info);
+ continue;
+ }
+
+ g_hash_table_insert (manager->priv->applet_factories, g_strdup (info->id), info);
+ retval = TRUE;
+ }
+
+ g_dir_close (dir);
+ g_free (path);
+ }
+
+ g_slist_free (dirs);
+
+ return retval;
+}
+
+static GList *
+panel_applets_manager_dbus_get_applets (PanelAppletsManager *manager)
+{
+ PanelAppletsManagerDBus *dbus_manager = PANEL_APPLETS_MANAGER_DBUS (manager);
+
+ GHashTableIter iter;
+ gpointer key, value;
+ GList *retval = NULL;
+
+ g_hash_table_iter_init (&iter, dbus_manager->priv->applet_factories);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ PanelAppletFactoryInfo *info;
+
+ info = (PanelAppletFactoryInfo *)value;
+ retval = g_list_concat (retval, g_list_copy (info->applet_list));
+ }
+
+ return retval;
+}
+
+static PanelAppletFactoryInfo *
+get_applet_factory_info (PanelAppletsManager *manager,
+ const gchar *iid)
+{
+ PanelAppletsManagerDBus *dbus_manager = PANEL_APPLETS_MANAGER_DBUS (manager);
+
+ PanelAppletFactoryInfo *info;
+ const gchar *sp;
+ gchar *factory_id;
+
+ sp = g_strrstr (iid, "::");
+ if (!sp)
+ return NULL;
+
+ factory_id = g_strndup (iid, strlen (iid) - strlen (sp));
+ info = g_hash_table_lookup (dbus_manager->priv->applet_factories, factory_id);
+ g_free (factory_id);
+
+ return info;
+}
+
+static gboolean
+panel_applets_manager_dbus_factory_activate (PanelAppletsManager *manager,
+ const gchar *iid)
+{
+ PanelAppletFactoryInfo *info;
+ ActivateAppletFunc activate_applet;
+
+ info = get_applet_factory_info (manager, iid);
+ if (!info)
+ return FALSE;
+
+ /* Out-of-process applets are activated by the session bus */
+ if (!info->in_process)
+ return TRUE;
+
+ if (info->module) {
+ if (info->n_applets == 0) {
+ if (info->activate_applet () != 0) {
+ g_warning ("Failed to reactivate factory %s\n", iid);
+ return FALSE;
+ }
+ }
+ info->n_applets++;
+
+ return TRUE;
+ }
+
+ info->module = g_module_open (info->location, G_MODULE_BIND_LAZY);
+ if (!info->module) {
+ /* FIXME: use a GError? */
+ g_warning ("Failed to load applet %s: %s\n",
+ iid, g_module_error ());
+ return FALSE;
+ }
+
+ if (!g_module_symbol (info->module, "_panel_applet_shlib_factory", (gpointer *)&activate_applet)) {
+ /* FIXME: use a GError? */
+ g_warning ("Failed to load applet %s: %s\n",
+ iid, g_module_error ());
+ g_module_close (info->module);
+ info->module = NULL;
+
+ return FALSE;
+ }
+
+ /* Activate the applet */
+ if (activate_applet () != 0) {
+ /* FIXME: use a GError? */
+ g_warning ("Failed to load applet %s\n", iid);
+ g_module_close (info->module);
+ info->module = NULL;
+
+ return FALSE;
+ }
+ info->activate_applet = activate_applet;
+
+ info->n_applets = 1;
+
+ return TRUE;
+}
+
+static gboolean
+panel_applets_manager_dbus_factory_deactivate (PanelAppletsManager *manager,
+ const gchar *iid)
+{
+ PanelAppletFactoryInfo *info;
+
+ info = get_applet_factory_info (manager, iid);
+ if (!info)
+ return FALSE;
+
+ /* Out-of-process applets are deactivated by the session bus */
+ if (!info->in_process)
+ return TRUE;
+
+ if (!info->module)
+ return TRUE;
+
+ if (--info->n_applets == 0) {
+ /* FIXME: we should close the module here,
+ * however applet types are registered static
+ */
+#if 0
+ g_module_close (info->module);
+ info->module = NULL;
+#endif
+ }
+
+ return TRUE;
+}
+
+static PanelAppletInfo *
+panel_applets_manager_dbus_get_applet_info (PanelAppletsManager *manager,
+ const gchar *iid)
+{
+ PanelAppletFactoryInfo *info;
+ GList *l;
+
+ info = get_applet_factory_info (manager, iid);
+ if (!info)
+ return NULL;
+
+ for (l = info->applet_list; l; l = g_list_next (l)) {
+ PanelAppletInfo *ainfo = (PanelAppletInfo *)l->data;
+
+ if (g_strcmp0 (panel_applet_info_get_iid (ainfo), iid) == 0)
+ return ainfo;
+ }
+
+ return NULL;
+}
+
+static PanelAppletInfo *
+panel_applets_manager_dbus_get_applet_info_from_old_id (PanelAppletsManager *manager,
+ const gchar *iid)
+{
+ PanelAppletsManagerDBus *dbus_manager = PANEL_APPLETS_MANAGER_DBUS (manager);
+
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_hash_table_iter_init (&iter, dbus_manager->priv->applet_factories);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ PanelAppletFactoryInfo *info;
+ GList *l;
+
+ info = (PanelAppletFactoryInfo *)value;
+ if (!info->has_old_ids)
+ continue;
+
+ for (l = info->applet_list; l; l = g_list_next (l)) {
+ PanelAppletInfo *ainfo;
+ gint i = 0;
+ const gchar * const *old_ids;
+
+ ainfo = (PanelAppletInfo *)l->data;
+
+ old_ids = panel_applet_info_get_old_ids (ainfo);
+
+ if (old_ids == NULL)
+ continue;
+
+ while (old_ids[i]) {
+ if (g_strcmp0 (old_ids[i], iid) == 0)
+ return ainfo;
+ i++;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static gboolean
+panel_applets_manager_dbus_load_applet (PanelAppletsManager *manager,
+ const gchar *iid,
+ PanelAppletFrameActivating *frame_act)
+{
+ return panel_applet_frame_dbus_load (iid, frame_act);
+}
+
+static void
+panel_applets_manager_dbus_finalize (GObject *object)
+{
+ PanelAppletsManagerDBus *manager = PANEL_APPLETS_MANAGER_DBUS (object);
+
+ if (manager->priv->monitors) {
+ g_list_foreach (manager->priv->monitors, (GFunc)g_object_unref, NULL);
+ g_list_free (manager->priv->monitors);
+ manager->priv->monitors = NULL;
+ }
+
+ if (manager->priv->applet_factories) {
+ g_hash_table_destroy (manager->priv->applet_factories);
+ manager->priv->applet_factories = NULL;
+ }
+
+ G_OBJECT_CLASS (panel_applets_manager_dbus_parent_class)->finalize (object);
+}
+
+static void
+panel_applets_manager_dbus_init (PanelAppletsManagerDBus *manager)
+{
+ manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
+ PANEL_TYPE_APPLETS_MANAGER_DBUS,
+ PanelAppletsManagerDBusPrivate);
+
+ manager->priv->applet_factories = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) panel_applet_factory_info_free);
+
+ panel_applets_manager_load_applet_infos (manager);
+}
+
+static void
+panel_applets_manager_dbus_class_init (PanelAppletsManagerDBusClass *class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+ PanelAppletsManagerClass *manager_class = PANEL_APPLETS_MANAGER_CLASS (class);
+
+ gobject_class->finalize = panel_applets_manager_dbus_finalize;
+
+ manager_class->get_applets = panel_applets_manager_dbus_get_applets;
+ manager_class->factory_activate = panel_applets_manager_dbus_factory_activate;
+ manager_class->factory_deactivate = panel_applets_manager_dbus_factory_deactivate;
+ manager_class->get_applet_info = panel_applets_manager_dbus_get_applet_info;
+ manager_class->get_applet_info_from_old_id = panel_applets_manager_dbus_get_applet_info_from_old_id;
+ manager_class->load_applet = panel_applets_manager_dbus_load_applet;
+
+ g_type_class_add_private (class, sizeof (PanelAppletsManagerDBusPrivate));
+}
diff --git a/gnome-panel/libpanel-applet-private/panel-applets-manager-dbus.h b/gnome-panel/libpanel-applet-private/panel-applets-manager-dbus.h
new file mode 100644
index 0000000..9d2705e
--- /dev/null
+++ b/gnome-panel/libpanel-applet-private/panel-applets-manager-dbus.h
@@ -0,0 +1,56 @@
+/*
+ * panel-applets-manager-dbus.h
+ *
+ * Copyright (C) 2010 Carlos Garcia Campos <carlosgc gnome org>
+ * Copyright (C) 2010 Vincent Untz <vuntz gnome 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 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
+ * 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.
+ */
+
+#ifndef __PANEL_APPLETS_MANAGER_DBUS_H__
+#define __PANEL_APPLETS_MANAGER_DBUS_H__
+
+#include <panel-applets-manager.h>
+
+G_BEGIN_DECLS
+
+#define PANEL_TYPE_APPLETS_MANAGER_DBUS (panel_applets_manager_dbus_get_type ())
+#define PANEL_APPLETS_MANAGER_DBUS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PANEL_TYPE_APPLETS_MANAGER_DBUS, PanelAppletsManagerDBus))
+#define PANEL_APPLETS_MANAGER_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANEL_TYPE_APPLETS_MANAGER_DBUS, PanelAppletsManagerDBusClass))
+#define PANEL_IS_APPLETS_MANAGER_DBUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PANEL_TYPE_APPLETS_MANAGER_DBUS))
+#define PANEL_IS_APPLETS_MANAGER_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANEL_TYPE_APPLETS_MANAGER_DBUS))
+#define PANEL_APPLETS_MANAGER_DBUS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PANEL_TYPE_APPLETS_MANAGER_DBUS, PanelAppletsManagerDBusClass))
+
+typedef struct _PanelAppletsManagerDBus PanelAppletsManagerDBus;
+typedef struct _PanelAppletsManagerDBusClass PanelAppletsManagerDBusClass;
+typedef struct _PanelAppletsManagerDBusPrivate PanelAppletsManagerDBusPrivate;
+
+struct _PanelAppletsManagerDBusClass {
+ PanelAppletsManagerClass parent_class;
+};
+
+struct _PanelAppletsManagerDBus {
+ PanelAppletsManager parent;
+
+ /*< private > */
+ PanelAppletsManagerDBusPrivate *priv;
+};
+
+GType panel_applets_manager_dbus_get_type (void);
+
+G_END_DECLS
+
+#endif /* __PANEL_APPLETS_MANAGER_DBUS_H__ */
diff --git a/gnome-panel/main.c b/gnome-panel/main.c
index e314e1d..0f09ee3 100644
--- a/gnome-panel/main.c
+++ b/gnome-panel/main.c
@@ -100,7 +100,6 @@ main (int argc, char **argv)
return -1;
}
- panel_applets_manager_init ();
panel_action_protocol_init ();
panel_multiscreen_init ();
panel_init_stock_icons_and_items ();
@@ -132,7 +131,6 @@ main (int argc, char **argv)
gtk_main ();
panel_lockdown_finalize ();
- panel_applets_manager_shutdown ();
gconf_client_remove_dir (panel_gconf_get_client (),
"/desktop/gnome/interface",
diff --git a/gnome-panel/panel-applet-frame.c b/gnome-panel/panel-applet-frame.c
index 3d6c418..36db459 100644
--- a/gnome-panel/panel-applet-frame.c
+++ b/gnome-panel/panel-applet-frame.c
@@ -33,10 +33,8 @@
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
-#include "panel-applet-frame.h"
#include "panel-applets-manager.h"
#include "panel-profile.h"
-#include "panel-util.h"
#include "panel.h"
#include "applet.h"
#include "panel-marshal.h"
@@ -46,7 +44,32 @@
#include "xstuff.h"
#include "panel-compatibility.h"
-G_DEFINE_TYPE (PanelAppletFrame, panel_applet_frame, PANEL_TYPE_APPLET_CONTAINER)
+#include "panel-applet-frame.h"
+
+static void panel_applet_frame_activating_free (PanelAppletFrameActivating *frame_act);
+
+static void panel_applet_frame_loading_failed (const char *iid,
+ PanelWidget *panel,
+ const char *id);
+
+static void panel_applet_frame_load (const gchar *iid,
+ PanelWidget *panel,
+ gboolean locked,
+ int position,
+ gboolean exactpos,
+ const char *id);
+
+struct _PanelAppletFrameActivating {
+ gboolean locked;
+ PanelWidget *panel;
+ int position;
+ gboolean exactpos;
+ char *id;
+};
+
+/* PanelAppletFrame implementation */
+
+G_DEFINE_TYPE (PanelAppletFrame, panel_applet_frame, GTK_TYPE_BIN)
#define PANEL_APPLET_FRAME_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_APPLET_FRAME, PanelAppletFramePrivate))
@@ -65,625 +88,9 @@ struct _PanelAppletFramePrivate {
GdkRectangle handle_rect;
guint has_handle : 1;
-
- GCancellable *bg_cancellable;
-};
-
-typedef struct {
- gboolean locked;
- int position;
- gboolean exactpos;
- char *id;
-} PanelAppletFrameActivating;
-
-/* Keep in sync with panel-applet.h. Uggh.
- */
-typedef enum {
- APPLET_FLAGS_NONE = 0,
- APPLET_EXPAND_MAJOR = 1 << 0,
- APPLET_EXPAND_MINOR = 1 << 1,
- APPLET_HAS_HANDLE = 1 << 2
-} PanelAppletFlags;
-
-static GSList *no_reload_applets = NULL;
-
-static char *panel_applet_frame_get_background_string (PanelAppletFrame *frame,
- PanelWidget *panel,
- PanelBackgroundType type);
-
-static void
-panel_applet_frame_update_flags (PanelAppletFrame *frame,
- guint flags)
-{
- gboolean major;
- gboolean minor;
- gboolean old_has_handle;
-
- major = flags & APPLET_EXPAND_MAJOR;
- minor = flags & APPLET_EXPAND_MINOR;
-
- panel_widget_set_applet_expandable (
- frame->priv->panel, GTK_WIDGET (frame), major, minor);
-
- old_has_handle = frame->priv->has_handle;
- frame->priv->has_handle = (flags & APPLET_HAS_HANDLE) != 0;
-
- if (!old_has_handle && frame->priv->has_handle) {
- /* we've added an handle, so we need to get the background for
- * it */
- PanelBackground *background;
-
- background = &frame->priv->panel->background;
- panel_applet_frame_change_background (frame, background->type);
- }
-}
-
-static void
-panel_applet_frame_update_size_hints (PanelAppletFrame *frame,
- gint *size_hints,
- guint n_elements)
-{
- if (frame->priv->has_handle) {
- gint extra_size = HANDLE_SIZE + 1;
- gint i;
-
- for (i = 0; i < n_elements; i++)
- size_hints[i] += extra_size;
- }
-
- /* It takes the ownership of size-hints array */
- panel_widget_set_applet_size_hints (frame->priv->panel,
- GTK_WIDGET (frame),
- size_hints,
- n_elements);
-}
-
-static void
-panel_applet_frame_get_flags_cb (PanelAppletContainer *container,
- GAsyncResult *res,
- PanelAppletFrame *frame)
-{
- GVariant *value;
- GError *error = NULL;
-
- value = panel_applet_container_child_get_finish (container, res, &error);
- if (!value) {
- g_warning ("%s\n", error->message);
- g_error_free (error);
- return;
- }
-
- panel_applet_frame_update_flags (frame, g_variant_get_uint32 (value));
- g_variant_unref (value);
-}
-
-static void
-panel_applet_frame_get_size_hints_cb (PanelAppletContainer *container,
- GAsyncResult *res,
- PanelAppletFrame *frame)
-{
- GVariant *value;
- const gint *sz;
- gint *size_hints = NULL;
- gsize n_elements;
- GError *error = NULL;
-
- value = panel_applet_container_child_get_finish (container, res, &error);
- if (!value) {
- g_warning ("%s\n", error->message);
- g_error_free (error);
- return;
- }
-
- sz = g_variant_get_fixed_array (value, &n_elements, sizeof (gint32));
- if (n_elements > 0) {
- size_hints = g_new (gint32, n_elements);
- memcpy (size_hints, sz, n_elements * sizeof (gint32));
- }
- panel_applet_frame_update_size_hints (frame, size_hints, n_elements);
- g_variant_unref (value);
-}
-
-static void
-panel_applet_frame_flags_changed (PanelAppletContainer *container,
- const gchar *prop_name,
- GVariant *value,
- PanelAppletFrame *frame)
-{
- panel_applet_frame_update_flags (frame, g_variant_get_uint32 (value));
-}
-
-static void
-panel_applet_frame_size_hints_changed (PanelAppletContainer *container,
- const gchar *prop_name,
- GVariant *value,
- PanelAppletFrame *frame)
-{
- const gint *sz;
- gint *size_hints = NULL;
- gsize n_elements;
-
- sz = g_variant_get_fixed_array (value, &n_elements, sizeof (gint32));
- if (n_elements > 0) {
- size_hints = g_new (gint32, n_elements);
- memcpy (size_hints, sz, n_elements * sizeof (gint32));
- }
- panel_applet_frame_update_size_hints (frame, size_hints, n_elements);
-}
-
-static void
-panel_applet_frame_init_properties (PanelAppletFrame *frame)
-{
- PanelAppletContainer *container = PANEL_APPLET_CONTAINER (frame);
-
- panel_applet_container_child_get (container, "flags", NULL,
- (GAsyncReadyCallback)panel_applet_frame_get_flags_cb,
- frame);
- panel_applet_container_child_get (container, "size-hints", NULL,
- (GAsyncReadyCallback)panel_applet_frame_get_size_hints_cb,
- frame);
- g_signal_connect (container, "child-property-changed::flags",
- G_CALLBACK (panel_applet_frame_flags_changed),
- frame);
- g_signal_connect (container, "child-property-changed::size-hints",
- G_CALLBACK (panel_applet_frame_size_hints_changed),
- frame);
-}
-
-void
-panel_applet_frame_sync_menu_state (PanelAppletFrame *frame)
-{
- PanelWidget *panel_widget;
- gboolean locked_down;
- gboolean locked;
- gboolean lockable;
- gboolean movable;
- gboolean removable;
-
- panel_widget = PANEL_WIDGET (GTK_WIDGET (frame)->parent);
-
- lockable = panel_applet_lockable (frame->priv->applet_info);
- movable = panel_applet_can_freely_move (frame->priv->applet_info);
- removable = panel_profile_id_lists_are_writable ();
-
- locked = panel_widget_get_applet_locked (panel_widget, GTK_WIDGET (frame));
- locked_down = panel_lockdown_get_locked_down ();
-
- panel_applet_container_child_set (PANEL_APPLET_CONTAINER (frame),
- "locked", g_variant_new_boolean (lockable && locked),
- NULL, NULL, NULL);
- panel_applet_container_child_set (PANEL_APPLET_CONTAINER (frame),
- "locked-down", g_variant_new_boolean (locked_down),
- NULL, NULL, NULL);
-}
-
-enum {
- LOADING_FAILED_RESPONSE_DONT_DELETE,
- LOADING_FAILED_RESPONSE_DELETE
};
static void
-panel_applet_frame_loading_failed_response (GtkWidget *dialog,
- guint response,
- char *id)
-{
- gtk_widget_destroy (dialog);
-
- if (response == LOADING_FAILED_RESPONSE_DELETE &&
- !panel_lockdown_get_locked_down () &&
- panel_profile_id_lists_are_writable ()) {
- GSList *item;
-
- item = g_slist_find_custom (no_reload_applets, id,
- (GCompareFunc) strcmp);
- if (item) {
- g_free (item->data);
- no_reload_applets = g_slist_delete_link (no_reload_applets,
- item);
- }
-
- panel_profile_remove_from_list (PANEL_GCONF_APPLETS, id);
- }
-
- g_free (id);
-}
-
-static void
-panel_applet_frame_loading_failed (PanelAppletFrame *frame,
- const char *id)
-{
- GtkWidget *dialog;
- char *problem_txt;
- gboolean locked_down;
-
- no_reload_applets = g_slist_prepend (no_reload_applets,
- g_strdup (id));
-
- locked_down = panel_lockdown_get_locked_down ();
-
- problem_txt = g_strdup_printf (_("The panel encountered a problem "
- "while loading \"%s\"."),
- frame->priv->iid);
-
- dialog = gtk_message_dialog_new (NULL, 0,
- locked_down ? GTK_MESSAGE_INFO : GTK_MESSAGE_WARNING,
- GTK_BUTTONS_NONE,
- "%s", problem_txt);
- g_free (problem_txt);
-
- if (locked_down) {
- gtk_dialog_add_buttons (GTK_DIALOG (dialog),
- GTK_STOCK_OK, LOADING_FAILED_RESPONSE_DONT_DELETE,
- NULL);
- } else {
- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
- _("Do you want to delete the applet "
- "from your configuration?"));
- gtk_dialog_add_buttons (GTK_DIALOG (dialog),
- PANEL_STOCK_DONT_DELETE, LOADING_FAILED_RESPONSE_DONT_DELETE,
- GTK_STOCK_DELETE, LOADING_FAILED_RESPONSE_DELETE,
- NULL);
- }
-
- gtk_dialog_set_default_response (GTK_DIALOG (dialog),
- LOADING_FAILED_RESPONSE_DONT_DELETE);
-
- gtk_window_set_screen (GTK_WINDOW (dialog),
- gtk_window_get_screen (GTK_WINDOW (frame->priv->panel->toplevel)));
-
- g_signal_connect (dialog, "response",
- G_CALLBACK (panel_applet_frame_loading_failed_response),
- g_strdup (id));
-
- panel_widget_register_open_dialog (frame->priv->panel, dialog);
- gtk_window_set_urgency_hint (GTK_WINDOW (dialog), TRUE);
- /* FIXME: http://bugzilla.gnome.org/show_bug.cgi?id=165132 */
- gtk_window_set_title (GTK_WINDOW (dialog), _("Error"));
-
- gtk_widget_show_all (dialog);
-
- g_free (frame->priv->iid);
- frame->priv->iid = NULL;
-
- gtk_widget_destroy (GTK_WIDGET (frame));
-}
-
-static guint
-get_panel_applet_orient (PanelOrientation orientation)
-{
- /* For some reason libpanel-applet and panel use
- * a different logic for orientation, so we need
- * to convert it. We should fix this.
- */
- switch (orientation) {
- case PANEL_ORIENTATION_TOP:
- return 1;
- case PANEL_ORIENTATION_BOTTOM:
- return 0;
- case PANEL_ORIENTATION_LEFT:
- return 3;
- case PANEL_ORIENTATION_RIGHT:
- return 2;
- default:
- g_assert_not_reached ();
- break;
- }
-}
-
-static void
-panel_applet_frame_activated (PanelAppletContainer *container,
- GAsyncResult *res,
- PanelAppletFrameActivating *frame_act)
-{
- PanelAppletFrame *frame = PANEL_APPLET_FRAME (container);
- GtkWidget *widget = NULL;
- AppletInfo *info;
- GError *error = NULL;
-
- if (!panel_applet_container_add_finish (container, res, &error)) {
- g_warning (G_STRLOC ": failed to load applet %s:\n%s",
- frame->priv->iid, error->message);
- g_error_free (error);
- goto error_out;
- }
-
- gtk_widget_show_all (GTK_WIDGET (frame));
-
- info = panel_applet_register (GTK_WIDGET (frame), GTK_WIDGET (frame),
- NULL, frame->priv->panel,
- frame_act->locked, frame_act->position,
- frame_act->exactpos, PANEL_OBJECT_APPLET,
- frame_act->id);
- frame->priv->applet_info = info;
-
- panel_widget_set_applet_size_constrained (frame->priv->panel,
- GTK_WIDGET (frame), TRUE);
-
- panel_applet_frame_sync_menu_state (frame);
- panel_applet_frame_init_properties (frame);
-
- panel_lockdown_notify_add (G_CALLBACK (panel_applet_frame_sync_menu_state),
- frame);
-
- panel_applet_stop_loading (frame_act->id);
- g_free (frame_act->id);
- g_free (frame_act);
-
- return;
-
-error_out:
- panel_applet_frame_loading_failed (frame, frame_act->id);
- if (widget)
- g_object_unref (widget);
- panel_applet_stop_loading (frame_act->id);
- g_free (frame_act->id);
- g_free (frame_act);
-}
-
-static void
-panel_applet_frame_load (const gchar *iid,
- PanelWidget *panel,
- gboolean locked,
- int position,
- gboolean exactpos,
- const char *id)
-{
- PanelAppletFrame *frame;
- PanelAppletFrameActivating *frame_act;
- GVariantBuilder builder;
- gchar *prefs_key;
- gchar *background;
- guint orient;
-
- g_return_if_fail (iid != NULL);
- g_return_if_fail (panel != NULL);
- g_return_if_fail (id != NULL);
-
- if (g_slist_find_custom (no_reload_applets, id,
- (GCompareFunc) strcmp))
- return;
-
- if (panel_lockdown_is_applet_disabled (iid))
- return;
-
- frame = g_object_new (PANEL_TYPE_APPLET_FRAME, NULL);
- frame->priv->panel = panel;
- frame->priv->iid = g_strdup (iid);
-
- if (!panel_applets_manager_factory_activate (iid)) {
- panel_applet_frame_loading_failed (frame, id);
- panel_applet_stop_loading (id);
-
- return;
- }
-
- frame_act = g_new (PanelAppletFrameActivating, 1);
- frame_act->locked = locked;
- frame_act->position = position;
- frame_act->exactpos = exactpos;
- frame_act->id = g_strdup (id);
-
- prefs_key = g_strdup_printf (PANEL_APPLET_PREFS_KEY, frame_act->id);
- background = panel_applet_frame_get_background_string (frame,
- frame->priv->panel,
- frame->priv->panel->background.type);
- orient = get_panel_applet_orient (panel_widget_get_applet_orientation (frame->priv->panel));
-
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
- g_variant_builder_add (&builder, "{sv}",
- "prefs-key",
- g_variant_new_string (prefs_key));
- g_variant_builder_add (&builder, "{sv}",
- "orient",
- g_variant_new_uint32 (orient));
- g_variant_builder_add (&builder, "{sv}",
- "size",
- g_variant_new_uint32 (frame->priv->panel->sz));
- g_variant_builder_add (&builder, "{sv}",
- "locked",
- g_variant_new_boolean (locked));
- g_variant_builder_add (&builder, "{sv}",
- "locked-down",
- g_variant_new_boolean (panel_lockdown_get_locked_down ()));
- if (background) {
- g_variant_builder_add (&builder, "{sv}",
- "background",
- g_variant_new_string (background));
- }
-
- panel_applet_container_add (PANEL_APPLET_CONTAINER (frame),
- frame->priv->iid, NULL,
- (GAsyncReadyCallback)panel_applet_frame_activated,
- frame_act,
- g_variant_builder_end (&builder));
- g_free (prefs_key);
- g_free (background);
-}
-
-void
-panel_applet_frame_load_from_gconf (PanelWidget *panel_widget,
- gboolean locked,
- int position,
- const char *id)
-{
- gchar *applet_iid;
-
- g_return_if_fail (panel_widget != NULL);
- g_return_if_fail (id != NULL);
-
- applet_iid = panel_compatiblity_get_applet_iid (id);
- if (!applet_iid)
- return;
-
- panel_applet_frame_load (applet_iid, panel_widget,
- locked, position, TRUE, id);
-
- g_free (applet_iid);
-}
-
-void
-panel_applet_frame_create (PanelToplevel *toplevel,
- int position,
- const char *iid)
-{
- GConfClient *client;
- const char *key;
- char *id;
-
- g_return_if_fail (iid != NULL);
-
- client = panel_gconf_get_client ();
-
- id = panel_profile_prepare_object (PANEL_OBJECT_APPLET, toplevel, position, FALSE);
-
- key = panel_gconf_full_key (PANEL_GCONF_APPLETS, id, "applet_iid");
- gconf_client_set_string (client, key, iid, NULL);
-
- panel_profile_add_to_list (PANEL_GCONF_APPLETS, id);
-
- g_free (id);
-}
-
-static void
-change_orientation_cb (PanelAppletContainer *container,
- GAsyncResult *res)
-{
- GError *error = NULL;
-
- if (!panel_applet_container_child_set_finish (container, res, &error)) {
- g_warning ("%s\n", error->message);
- g_error_free (error);
-
- return;
- }
-
- gtk_widget_queue_resize (GTK_WIDGET (container));
-}
-
-void
-panel_applet_frame_change_orientation (PanelAppletFrame *frame,
- PanelOrientation orientation)
-{
- if (orientation == frame->priv->orientation)
- return;
-
- frame->priv->orientation = orientation;
- panel_applet_container_child_set (PANEL_APPLET_CONTAINER (frame),
- "orient",
- g_variant_new_uint32 (get_panel_applet_orient (orientation)),
- NULL,
- (GAsyncReadyCallback)change_orientation_cb,
- NULL);
-}
-
-void
-panel_applet_frame_change_size (PanelAppletFrame *frame,
- guint size)
-{
- panel_applet_container_child_set (PANEL_APPLET_CONTAINER (frame),
- "size", g_variant_new_uint32 (size),
- NULL, NULL, NULL);
-}
-
-static char *
-panel_applet_frame_get_background_string (PanelAppletFrame *frame,
- PanelWidget *panel,
- PanelBackgroundType type)
-{
- int x;
- int y;
-
- x = GTK_WIDGET (frame)->allocation.x;
- y = GTK_WIDGET (frame)->allocation.y;
-
- if (frame->priv->has_handle) {
- switch (frame->priv->orientation) {
- case PANEL_ORIENTATION_TOP:
- case PANEL_ORIENTATION_BOTTOM:
- if (gtk_widget_get_direction (GTK_WIDGET (frame)) !=
- GTK_TEXT_DIR_RTL)
- x += frame->priv->handle_rect.width;
- break;
- case PANEL_ORIENTATION_LEFT:
- case PANEL_ORIENTATION_RIGHT:
- y += frame->priv->handle_rect.height;
- break;
- default:
- g_assert_not_reached ();
- break;
- }
- }
-
- return panel_background_make_string (&panel->background, x, y);
-}
-
-static void
-container_child_background_set (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- PanelAppletContainer *container = PANEL_APPLET_CONTAINER (source_object);
- PanelAppletFrame *frame = PANEL_APPLET_FRAME (source_object);
-
- panel_applet_container_child_set_finish (container, res, NULL);
-
- if (frame->priv->bg_cancellable)
- g_object_unref (frame->priv->bg_cancellable);
- frame->priv->bg_cancellable = NULL;
-}
-
-void
-panel_applet_frame_change_background (PanelAppletFrame *frame,
- PanelBackgroundType type)
-{
- char *bg_str;
-
- g_return_if_fail (PANEL_IS_APPLET_FRAME (frame));
- g_return_if_fail (PANEL_IS_WIDGET (GTK_WIDGET (frame)->parent));
-
- if (frame->priv->has_handle) {
- PanelBackground *background;
-
- background = &PANEL_WIDGET (GTK_WIDGET (frame)->parent)->background;
- panel_background_change_background_on_widget (background,
- GTK_WIDGET (frame));
- }
-
- bg_str = panel_applet_frame_get_background_string (
- frame, PANEL_WIDGET (GTK_WIDGET (frame)->parent), type);
-
- if (bg_str != NULL) {
- if (frame->priv->bg_cancellable)
- g_cancellable_cancel (frame->priv->bg_cancellable);
- frame->priv->bg_cancellable = g_cancellable_new ();
-
- panel_applet_container_child_set (PANEL_APPLET_CONTAINER (frame),
- "background",
- g_variant_new_string (bg_str),
- frame->priv->bg_cancellable,
- container_child_background_set,
- NULL);
- g_free (bg_str);
- }
-}
-
-static void
-panel_applet_frame_finalize (GObject *object)
-{
- PanelAppletFrame *frame = PANEL_APPLET_FRAME (object);
-
- panel_applets_manager_factory_deactivate (frame->priv->iid);
-
- panel_lockdown_notify_remove (G_CALLBACK (panel_applet_frame_sync_menu_state),
- frame);
-
- g_free (frame->priv->iid);
- frame->priv->iid = NULL;
-
- G_OBJECT_CLASS (panel_applet_frame_parent_class)->finalize (object);
-}
-
-static void
panel_applet_frame_paint (GtkWidget *widget,
GdkRectangle *area)
{
@@ -732,7 +139,6 @@ panel_applet_frame_expose (GtkWidget *widget,
GTK_WIDGET_CLASS (panel_applet_frame_parent_class)->expose_event (widget, event);
panel_applet_frame_paint (widget, &event->area);
-
}
return FALSE;
@@ -771,10 +177,9 @@ panel_applet_frame_size_request (GtkWidget *widget,
frame = PANEL_APPLET_FRAME (widget);
bin = GTK_BIN (widget);
- if (!frame->priv->has_handle) {
- GTK_WIDGET_CLASS (panel_applet_frame_parent_class)->size_request (widget, requisition);
- return;
- }
+ /* This is a GtkBin subclass, so we have to implement size request
+ * ourselves in all cases, without relying on the parent class
+ * implementation */
requisition->width = 0;
requisition->height = 0;
@@ -786,6 +191,9 @@ panel_applet_frame_size_request (GtkWidget *widget,
requisition->height = child_requisition.height;
}
+ if (!frame->priv->has_handle)
+ return;
+
requisition->width += GTK_CONTAINER (widget)->border_width;
requisition->height += GTK_CONTAINER (widget)->border_width;
@@ -821,9 +229,14 @@ panel_applet_frame_size_allocate (GtkWidget *widget,
frame = PANEL_APPLET_FRAME (widget);
bin = GTK_BIN (widget);
+ /* This is a GtkBin subclass, so we have to implement size allocation
+ * ourselves in all cases, without relying on the parent class
+ * implementation */
+
if (!frame->priv->has_handle) {
- GTK_WIDGET_CLASS (panel_applet_frame_parent_class)->size_allocate (widget,
- allocation);
+ if (bin->child && gtk_widget_get_visible (bin->child))
+ gtk_widget_size_allocate (bin->child, allocation);
+
panel_applet_frame_update_background_size (frame,
&old_allocation,
allocation);
@@ -947,14 +360,12 @@ panel_applet_frame_button_changed (GtkWidget *widget,
case 3:
if (event->type == GDK_BUTTON_PRESS ||
event->type == GDK_2BUTTON_PRESS) {
- PanelAppletContainer *container;
-
- container = PANEL_APPLET_CONTAINER (frame);
gdk_pointer_ungrab (GDK_CURRENT_TIME);
- panel_applet_container_child_popup_menu (container,
- event->button,
- event->time,
- NULL, NULL, NULL);
+
+ PANEL_APPLET_FRAME_GET_CLASS (frame)->popup_menu (frame,
+ event->button,
+ event->time);
+
handled = TRUE;
} else if (event->type == GDK_BUTTON_RELEASE)
handled = TRUE;
@@ -967,6 +378,255 @@ panel_applet_frame_button_changed (GtkWidget *widget,
}
static void
+panel_applet_frame_finalize (GObject *object)
+{
+ PanelAppletFrame *frame = PANEL_APPLET_FRAME (object);
+
+ panel_applets_manager_factory_deactivate (frame->priv->iid);
+
+ panel_lockdown_notify_remove (G_CALLBACK (panel_applet_frame_sync_menu_state),
+ frame);
+
+ g_free (frame->priv->iid);
+ frame->priv->iid = NULL;
+
+ G_OBJECT_CLASS (panel_applet_frame_parent_class)->finalize (object);
+}
+
+static void
+panel_applet_frame_class_init (PanelAppletFrameClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+ GtkWidgetClass *widget_class = (GtkWidgetClass *) klass;
+
+ gobject_class->finalize = panel_applet_frame_finalize;
+
+ widget_class->expose_event = panel_applet_frame_expose;
+ widget_class->size_request = panel_applet_frame_size_request;
+ widget_class->size_allocate = panel_applet_frame_size_allocate;
+ widget_class->button_press_event = panel_applet_frame_button_changed;
+ widget_class->button_release_event = panel_applet_frame_button_changed;
+
+ g_type_class_add_private (klass, sizeof (PanelAppletFramePrivate));
+}
+
+static void
+panel_applet_frame_init (PanelAppletFrame *frame)
+{
+ frame->priv = PANEL_APPLET_FRAME_GET_PRIVATE (frame);
+
+ frame->priv->panel = NULL;
+ frame->priv->orientation = PANEL_ORIENTATION_TOP;
+ frame->priv->applet_info = NULL;
+ frame->priv->has_handle = FALSE;
+}
+
+static void
+panel_applet_frame_init_properties (PanelAppletFrame *frame)
+{
+ PANEL_APPLET_FRAME_GET_CLASS (frame)->init_properties (frame);
+}
+
+void
+panel_applet_frame_sync_menu_state (PanelAppletFrame *frame)
+{
+ PanelWidget *panel_widget;
+ gboolean locked_down;
+ gboolean locked;
+ gboolean lockable;
+ gboolean movable;
+ gboolean removable;
+
+ panel_widget = PANEL_WIDGET (GTK_WIDGET (frame)->parent);
+
+ movable = panel_applet_can_freely_move (frame->priv->applet_info);
+ removable = panel_profile_id_lists_are_writable ();
+ lockable = panel_applet_lockable (frame->priv->applet_info);
+
+ locked = panel_widget_get_applet_locked (panel_widget, GTK_WIDGET (frame));
+ locked_down = panel_lockdown_get_locked_down ();
+
+ PANEL_APPLET_FRAME_GET_CLASS (frame)->sync_menu_state (frame, movable, removable, lockable, locked, locked_down);
+}
+
+void
+panel_applet_frame_change_orientation (PanelAppletFrame *frame,
+ PanelOrientation orientation)
+{
+ if (orientation == frame->priv->orientation)
+ return;
+
+ frame->priv->orientation = orientation;
+ PANEL_APPLET_FRAME_GET_CLASS (frame)->change_orientation (frame, orientation);
+}
+
+void
+panel_applet_frame_change_size (PanelAppletFrame *frame,
+ guint size)
+{
+ PANEL_APPLET_FRAME_GET_CLASS (frame)->change_size (frame, size);
+}
+
+void
+panel_applet_frame_change_background (PanelAppletFrame *frame,
+ PanelBackgroundType type)
+{
+ g_return_if_fail (PANEL_IS_APPLET_FRAME (frame));
+ g_return_if_fail (PANEL_IS_WIDGET (GTK_WIDGET (frame)->parent));
+
+ if (frame->priv->has_handle) {
+ PanelBackground *background;
+
+ background = &PANEL_WIDGET (GTK_WIDGET (frame)->parent)->background;
+ panel_background_change_background_on_widget (background,
+ GTK_WIDGET (frame));
+ }
+
+ PANEL_APPLET_FRAME_GET_CLASS (frame)->change_background (frame, type);
+}
+
+void
+panel_applet_frame_set_panel (PanelAppletFrame *frame,
+ PanelWidget *panel)
+{
+ g_return_if_fail (PANEL_IS_APPLET_FRAME (frame));
+ g_return_if_fail (PANEL_IS_WIDGET (panel));
+
+ frame->priv->panel = panel;
+}
+
+void
+_panel_applet_frame_set_iid (PanelAppletFrame *frame,
+ const gchar *iid)
+{
+ if (frame->priv->iid)
+ g_free (frame->priv->iid);
+ frame->priv->iid = g_strdup (iid);
+}
+
+void
+_panel_applet_frame_activated (PanelAppletFrame *frame,
+ PanelAppletFrameActivating *frame_act,
+ GError *error)
+{
+ AppletInfo *info;
+
+ g_assert (frame->priv->iid != NULL);
+
+ if (error != NULL) {
+ g_warning ("Failed to load applet %s:\n%s",
+ frame->priv->iid, error->message);
+ g_error_free (error);
+
+ panel_applet_frame_loading_failed (frame->priv->iid,
+ frame_act->panel,
+ frame_act->id);
+ panel_applet_frame_activating_free (frame_act);
+ gtk_widget_destroy (GTK_WIDGET (frame));
+
+ return;
+ }
+
+ frame->priv->panel = frame_act->panel;
+ gtk_widget_show_all (GTK_WIDGET (frame));
+
+ info = panel_applet_register (GTK_WIDGET (frame), GTK_WIDGET (frame),
+ NULL, frame->priv->panel,
+ frame_act->locked, frame_act->position,
+ frame_act->exactpos, PANEL_OBJECT_APPLET,
+ frame_act->id);
+ frame->priv->applet_info = info;
+
+ panel_widget_set_applet_size_constrained (frame->priv->panel,
+ GTK_WIDGET (frame), TRUE);
+
+ panel_applet_frame_sync_menu_state (frame);
+ panel_applet_frame_init_properties (frame);
+
+ panel_lockdown_notify_add (G_CALLBACK (panel_applet_frame_sync_menu_state),
+ frame);
+
+ panel_applet_stop_loading (frame_act->id);
+ panel_applet_frame_activating_free (frame_act);
+}
+
+void
+_panel_applet_frame_update_flags (PanelAppletFrame *frame,
+ gboolean major,
+ gboolean minor,
+ gboolean has_handle)
+{
+ gboolean old_has_handle;
+
+ panel_widget_set_applet_expandable (
+ frame->priv->panel, GTK_WIDGET (frame), major, minor);
+
+ old_has_handle = frame->priv->has_handle;
+ frame->priv->has_handle = has_handle;
+
+ if (!old_has_handle && frame->priv->has_handle) {
+ /* we've added an handle, so we need to get the background for
+ * it */
+ PanelBackground *background;
+
+ background = &frame->priv->panel->background;
+ panel_applet_frame_change_background (frame, background->type);
+ }
+}
+
+void
+_panel_applet_frame_update_size_hints (PanelAppletFrame *frame,
+ gint *size_hints,
+ guint n_elements)
+{
+ if (frame->priv->has_handle) {
+ gint extra_size = HANDLE_SIZE + 1;
+ gint i;
+
+ for (i = 0; i < n_elements; i++)
+ size_hints[i] += extra_size;
+ }
+
+ /* It takes the ownership of size-hints array */
+ panel_widget_set_applet_size_hints (frame->priv->panel,
+ GTK_WIDGET (frame),
+ size_hints,
+ n_elements);
+}
+
+char *
+_panel_applet_frame_get_background_string (PanelAppletFrame *frame,
+ PanelWidget *panel,
+ PanelBackgroundType type)
+{
+ int x;
+ int y;
+
+ x = GTK_WIDGET (frame)->allocation.x;
+ y = GTK_WIDGET (frame)->allocation.y;
+
+ if (frame->priv->has_handle) {
+ switch (frame->priv->orientation) {
+ case PANEL_ORIENTATION_TOP:
+ case PANEL_ORIENTATION_BOTTOM:
+ if (gtk_widget_get_direction (GTK_WIDGET (frame)) !=
+ GTK_TEXT_DIR_RTL)
+ x += frame->priv->handle_rect.width;
+ break;
+ case PANEL_ORIENTATION_LEFT:
+ case PANEL_ORIENTATION_RIGHT:
+ y += frame->priv->handle_rect.height;
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ }
+
+ return panel_background_make_string (&panel->background, x, y);
+}
+
+static void
panel_applet_frame_reload_response (GtkWidget *dialog,
int response,
PanelAppletFrame *frame)
@@ -1018,14 +678,13 @@ panel_applet_frame_reload_response (GtkWidget *dialog,
gtk_widget_destroy (dialog);
}
-static void
-panel_applet_frame_applet_broken (PanelAppletContainer *container)
+void
+_panel_applet_frame_applet_broken (PanelAppletFrame *frame)
{
- PanelAppletFrame *frame = PANEL_APPLET_FRAME (container);
- GtkWidget *dialog;
- GdkScreen *screen;
- const char *applet_name = NULL;
- char *dialog_txt;
+ GtkWidget *dialog;
+ GdkScreen *screen;
+ const char *applet_name = NULL;
+ char *dialog_txt;
screen = gtk_widget_get_screen (GTK_WIDGET (frame));
@@ -1077,10 +736,24 @@ panel_applet_frame_applet_broken (PanelAppletContainer *container)
g_free (dialog_txt);
}
-static void
-panel_applet_frame_applet_move (PanelAppletContainer *container)
+void
+_panel_applet_frame_applet_remove (PanelAppletFrame *frame)
{
- GtkWidget *widget = GTK_WIDGET (container);
+ AppletInfo *info;
+
+ if (!frame->priv->applet_info)
+ return;
+
+ info = frame->priv->applet_info;
+ frame->priv->applet_info = NULL;
+
+ panel_profile_delete_object (info);
+}
+
+void
+_panel_applet_frame_applet_move (PanelAppletFrame *frame)
+{
+ GtkWidget *widget = GTK_WIDGET (frame);
if (!PANEL_IS_WIDGET (widget->parent))
return;
@@ -1091,74 +764,221 @@ panel_applet_frame_applet_move (PanelAppletContainer *container)
GDK_CURRENT_TIME);
}
-static void
-panel_applet_frame_applet_remove (PanelAppletContainer *container)
+void
+_panel_applet_frame_applet_lock (PanelAppletFrame *frame,
+ gboolean locked)
{
- PanelAppletFrame *frame = PANEL_APPLET_FRAME (container);
- AppletInfo *info;
+ PanelWidget *panel_widget = PANEL_WIDGET (GTK_WIDGET (frame)->parent);
- if (!frame->priv->applet_info)
+ if (panel_widget_get_applet_locked (panel_widget, GTK_WIDGET (frame)) == locked)
return;
- info = frame->priv->applet_info;
- frame->priv->applet_info = NULL;
+ panel_applet_toggle_locked (frame->priv->applet_info);
+}
- panel_profile_delete_object (info);
+/* Generic methods */
+
+static GSList *no_reload_applets = NULL;
+
+enum {
+ LOADING_FAILED_RESPONSE_DONT_DELETE,
+ LOADING_FAILED_RESPONSE_DELETE
+};
+
+static void
+panel_applet_frame_activating_free (PanelAppletFrameActivating *frame_act)
+{
+ g_free (frame_act->id);
+ g_slice_free (PanelAppletFrameActivating, frame_act);
+}
+
+PanelOrientation
+panel_applet_frame_activating_get_orientation (PanelAppletFrameActivating *frame_act)
+{
+ return panel_widget_get_applet_orientation (frame_act->panel);
+}
+
+guint32
+panel_applet_frame_activating_get_size (PanelAppletFrameActivating *frame_act)
+{
+ return frame_act->panel->sz;
+}
+
+gboolean
+panel_applet_frame_activating_get_locked (PanelAppletFrameActivating *frame_act)
+{
+ return frame_act->locked;
+}
+
+gboolean
+panel_applet_frame_activating_get_locked_down (PanelAppletFrameActivating *frame_act)
+{
+ return panel_lockdown_get_locked_down ();
+}
+
+gchar *
+panel_applet_frame_activating_get_conf_path (PanelAppletFrameActivating *frame_act)
+{
+ return g_strdup_printf (PANEL_APPLET_PREFS_KEY, frame_act->id);
}
static void
-panel_applet_frame_applet_lock (PanelAppletContainer *container,
- gboolean locked)
+panel_applet_frame_loading_failed_response (GtkWidget *dialog,
+ guint response,
+ char *id)
{
- PanelAppletFrame *frame = PANEL_APPLET_FRAME (container);
- PanelWidget *panel_widget = PANEL_WIDGET (GTK_WIDGET (frame)->parent);
+ gtk_widget_destroy (dialog);
- if (panel_widget_get_applet_locked (panel_widget, GTK_WIDGET (frame)) == locked)
- return;
+ if (response == LOADING_FAILED_RESPONSE_DELETE &&
+ !panel_lockdown_get_locked_down () &&
+ panel_profile_id_lists_are_writable ()) {
+ GSList *item;
- panel_applet_toggle_locked (frame->priv->applet_info);
+ item = g_slist_find_custom (no_reload_applets, id,
+ (GCompareFunc) strcmp);
+ if (item) {
+ g_free (item->data);
+ no_reload_applets = g_slist_delete_link (no_reload_applets,
+ item);
+ }
+
+ panel_profile_remove_from_list (PANEL_GCONF_APPLETS, id);
+ }
+
+ g_free (id);
}
static void
-panel_applet_frame_class_init (PanelAppletFrameClass *klass)
+panel_applet_frame_loading_failed (const char *iid,
+ PanelWidget *panel,
+ const char *id)
{
- GObjectClass *gobject_class = (GObjectClass *) klass;
- GtkWidgetClass *widget_class = (GtkWidgetClass *) klass;
- PanelAppletContainerClass *container_class = (PanelAppletContainerClass *) klass;
+ GtkWidget *dialog;
+ char *problem_txt;
+ gboolean locked_down;
- gobject_class->finalize = panel_applet_frame_finalize;
+ panel_applet_stop_loading (id);
+ no_reload_applets = g_slist_prepend (no_reload_applets,
+ g_strdup (id));
- widget_class->expose_event = panel_applet_frame_expose;
- widget_class->size_request = panel_applet_frame_size_request;
- widget_class->size_allocate = panel_applet_frame_size_allocate;
- widget_class->button_press_event = panel_applet_frame_button_changed;
- widget_class->button_release_event = panel_applet_frame_button_changed;
+ locked_down = panel_lockdown_get_locked_down ();
- container_class->applet_broken = panel_applet_frame_applet_broken;
- container_class->applet_move = panel_applet_frame_applet_move;
- container_class->applet_remove = panel_applet_frame_applet_remove;
- container_class->applet_lock = panel_applet_frame_applet_lock;
+ problem_txt = g_strdup_printf (_("The panel encountered a problem "
+ "while loading \"%s\"."),
+ iid);
- g_type_class_add_private (klass, sizeof (PanelAppletFramePrivate));
+ dialog = gtk_message_dialog_new (NULL, 0,
+ locked_down ? GTK_MESSAGE_INFO : GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE,
+ "%s", problem_txt);
+ g_free (problem_txt);
+
+ if (locked_down) {
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+ GTK_STOCK_OK, LOADING_FAILED_RESPONSE_DONT_DELETE,
+ NULL);
+ } else {
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ _("Do you want to delete the applet "
+ "from your configuration?"));
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+ PANEL_STOCK_DONT_DELETE, LOADING_FAILED_RESPONSE_DONT_DELETE,
+ GTK_STOCK_DELETE, LOADING_FAILED_RESPONSE_DELETE,
+ NULL);
+ }
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog),
+ LOADING_FAILED_RESPONSE_DONT_DELETE);
+
+ gtk_window_set_screen (GTK_WINDOW (dialog),
+ gtk_window_get_screen (GTK_WINDOW (panel->toplevel)));
+
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (panel_applet_frame_loading_failed_response),
+ g_strdup (id));
+
+ panel_widget_register_open_dialog (panel, dialog);
+ gtk_window_set_urgency_hint (GTK_WINDOW (dialog), TRUE);
+ /* FIXME: http://bugzilla.gnome.org/show_bug.cgi?id=165132 */
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Error"));
+
+ gtk_widget_show_all (dialog);
}
static void
-panel_applet_frame_init (PanelAppletFrame *frame)
+panel_applet_frame_load (const gchar *iid,
+ PanelWidget *panel,
+ gboolean locked,
+ int position,
+ gboolean exactpos,
+ const char *id)
{
- frame->priv = PANEL_APPLET_FRAME_GET_PRIVATE (frame);
+ PanelAppletFrameActivating *frame_act;
- frame->priv->panel = NULL;
- frame->priv->orientation = PANEL_ORIENTATION_TOP;
- frame->priv->applet_info = NULL;
- frame->priv->has_handle = FALSE;
+ g_return_if_fail (iid != NULL);
+ g_return_if_fail (panel != NULL);
+ g_return_if_fail (id != NULL);
+
+ if (g_slist_find_custom (no_reload_applets, id,
+ (GCompareFunc) strcmp))
+ return;
+
+ if (panel_lockdown_is_applet_disabled (iid))
+ return;
+
+ frame_act = g_slice_new0 (PanelAppletFrameActivating);
+ frame_act->locked = locked;
+ frame_act->panel = panel;
+ frame_act->position = position;
+ frame_act->exactpos = exactpos;
+ frame_act->id = g_strdup (id);
+
+ if (!panel_applets_manager_load_applet (iid, frame_act)) {
+ panel_applet_frame_loading_failed (iid, panel, id);
+ panel_applet_frame_activating_free (frame_act);
+ }
}
void
-panel_applet_frame_set_panel (PanelAppletFrame *frame,
- PanelWidget *panel)
+panel_applet_frame_load_from_gconf (PanelWidget *panel_widget,
+ gboolean locked,
+ int position,
+ const char *id)
{
- g_return_if_fail (PANEL_IS_APPLET_FRAME (frame));
- g_return_if_fail (PANEL_IS_WIDGET (panel));
+ gchar *applet_iid;
- frame->priv->panel = panel;
+ g_return_if_fail (panel_widget != NULL);
+ g_return_if_fail (id != NULL);
+
+ applet_iid = panel_compatiblity_get_applet_iid (id);
+ if (!applet_iid)
+ return;
+
+ panel_applet_frame_load (applet_iid, panel_widget,
+ locked, position, TRUE, id);
+
+ g_free (applet_iid);
+}
+
+void
+panel_applet_frame_create (PanelToplevel *toplevel,
+ int position,
+ const char *iid)
+{
+ GConfClient *client;
+ const char *key;
+ char *id;
+
+ g_return_if_fail (iid != NULL);
+
+ client = panel_gconf_get_client ();
+
+ id = panel_profile_prepare_object (PANEL_OBJECT_APPLET, toplevel, position, FALSE);
+
+ key = panel_gconf_full_key (PANEL_GCONF_APPLETS, id, "applet_iid");
+ gconf_client_set_string (client, key, iid, NULL);
+
+ panel_profile_add_to_list (PANEL_GCONF_APPLETS, id);
+
+ g_free (id);
}
diff --git a/gnome-panel/panel-applet-frame.h b/gnome-panel/panel-applet-frame.h
index 7dc635c..fbb780d 100644
--- a/gnome-panel/panel-applet-frame.h
+++ b/gnome-panel/panel-applet-frame.h
@@ -27,7 +27,6 @@
#include <gtk/gtk.h>
-#include "panel-applet-container.h"
#include "panel-widget.h"
#include "applet.h"
@@ -44,14 +43,36 @@ typedef struct _PanelAppletFrame PanelAppletFrame;
typedef struct _PanelAppletFrameClass PanelAppletFrameClass;
typedef struct _PanelAppletFramePrivate PanelAppletFramePrivate;
-struct _PanelAppletFrame{
- PanelAppletContainer container;
+struct _PanelAppletFrameClass {
+ GtkBinClass parent_class;
- PanelAppletFramePrivate *priv;
+ void (*init_properties) (PanelAppletFrame *frame);
+
+ void (*sync_menu_state) (PanelAppletFrame *frame,
+ gboolean movable,
+ gboolean removable,
+ gboolean lockable,
+ gboolean locked,
+ gboolean locked_down);
+
+ void (*popup_menu) (PanelAppletFrame *frame,
+ guint button,
+ guint32 timestamp);
+
+ void (*change_orientation) (PanelAppletFrame *frame,
+ PanelOrientation orientation);
+
+ void (*change_size) (PanelAppletFrame *frame,
+ guint size);
+
+ void (*change_background) (PanelAppletFrame *frame,
+ PanelBackgroundType type);
};
-struct _PanelAppletFrameClass {
- PanelAppletContainerClass container_class;
+struct _PanelAppletFrame {
+ GtkBin parent;
+
+ PanelAppletFramePrivate *priv;
};
GType panel_applet_frame_get_type (void) G_GNUC_CONST;
@@ -60,6 +81,11 @@ void panel_applet_frame_create (PanelToplevel *toplevel,
int position,
const char *iid);
+void panel_applet_frame_load_from_gconf (PanelWidget *panel_widget,
+ gboolean locked,
+ int position,
+ const char *id);
+
void panel_applet_frame_sync_menu_state (PanelAppletFrame *frame);
void panel_applet_frame_change_orientation (PanelAppletFrame *frame,
@@ -71,14 +97,46 @@ void panel_applet_frame_change_size (PanelAppletFrame *frame,
void panel_applet_frame_change_background (PanelAppletFrame *frame,
PanelBackgroundType type);
-void panel_applet_frame_load_from_gconf (PanelWidget *panel_widget,
- gboolean locked,
- int position,
- const char *id);
-
void panel_applet_frame_set_panel (PanelAppletFrame *frame,
PanelWidget *panel);
+
+/* For module implementations only */
+
+typedef struct _PanelAppletFrameActivating PanelAppletFrameActivating;
+
+PanelOrientation panel_applet_frame_activating_get_orientation (PanelAppletFrameActivating *frame_act);
+guint32 panel_applet_frame_activating_get_size (PanelAppletFrameActivating *frame_act);
+gboolean panel_applet_frame_activating_get_locked (PanelAppletFrameActivating *frame_act);
+gboolean panel_applet_frame_activating_get_locked_down (PanelAppletFrameActivating *frame_act);
+gchar *panel_applet_frame_activating_get_conf_path (PanelAppletFrameActivating *frame_act);
+
+void _panel_applet_frame_set_iid (PanelAppletFrame *frame,
+ const gchar *iid);
+
+void _panel_applet_frame_activated (PanelAppletFrame *frame,
+ PanelAppletFrameActivating *frame_act,
+ GError *error);
+
+void _panel_applet_frame_update_flags (PanelAppletFrame *frame,
+ gboolean major,
+ gboolean minor,
+ gboolean has_handle);
+
+void _panel_applet_frame_update_size_hints (PanelAppletFrame *frame,
+ gint *size_hints,
+ guint n_elements);
+
+char *_panel_applet_frame_get_background_string (PanelAppletFrame *frame,
+ PanelWidget *panel,
+ PanelBackgroundType type);
+
+void _panel_applet_frame_applet_broken (PanelAppletFrame *frame);
+
+void _panel_applet_frame_applet_remove (PanelAppletFrame *frame);
+void _panel_applet_frame_applet_move (PanelAppletFrame *frame);
+void _panel_applet_frame_applet_lock (PanelAppletFrame *frame,
+ gboolean locked);
G_END_DECLS
#endif /* __PANEL_APPLET_FRAME_H__ */
diff --git a/gnome-panel/panel-applet-info.c b/gnome-panel/panel-applet-info.c
new file mode 100644
index 0000000..4c376d9
--- /dev/null
+++ b/gnome-panel/panel-applet-info.c
@@ -0,0 +1,111 @@
+/*
+ * panel-applet-info.c
+ *
+ * Copyright (C) 2010 Carlos Garcia Campos <carlosgc gnome org>
+ * Copyright (C) 2010 Vincent Untz <vuntz gnome 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 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
+ * 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.
+ */
+
+#include <config.h>
+
+#include "panel-applet-info.h"
+
+struct _PanelAppletInfo {
+ gchar *iid;
+
+ gchar *name;
+ gchar *comment;
+ gchar *icon;
+
+ gchar **old_ids;
+};
+
+PanelAppletInfo *
+panel_applet_info_new (const gchar *iid,
+ const gchar *name,
+ const gchar *comment,
+ const gchar *icon,
+ const gchar **old_ids)
+{
+ PanelAppletInfo *info;
+ int len;
+
+ info = g_slice_new0 (PanelAppletInfo);
+
+ info->iid = g_strdup (iid);
+ info->name = g_strdup (name);
+ info->comment = g_strdup (comment);
+ info->icon = g_strdup (icon);
+
+ /* Bonobo compatibility */
+ len = g_strv_length ((gchar **) old_ids);
+ if (len > 0) {
+ int i;
+
+ info->old_ids = g_new0 (gchar *, len + 1);
+
+ for (i = 0; i < len; i++)
+ info->old_ids[i] = g_strdup (old_ids[i]);
+ }
+
+ return info;
+}
+
+void
+panel_applet_info_free (PanelAppletInfo *info)
+{
+ if (!info)
+ return;
+
+ g_free (info->iid);
+ g_free (info->name);
+ g_free (info->comment);
+ g_free (info->icon);
+ g_strfreev (info->old_ids);
+
+ g_slice_free (PanelAppletInfo, info);
+}
+
+const gchar *
+panel_applet_info_get_iid (PanelAppletInfo *info)
+{
+ return info->iid;
+}
+
+const gchar *
+panel_applet_info_get_name (PanelAppletInfo *info)
+{
+ return info->name;
+}
+
+const gchar *
+panel_applet_info_get_description (PanelAppletInfo *info)
+{
+ return info->comment;
+}
+
+const gchar *
+panel_applet_info_get_icon (PanelAppletInfo *info)
+{
+ return info->icon;
+}
+
+const gchar * const *
+panel_applet_info_get_old_ids (PanelAppletInfo *info)
+{
+ return (const gchar * const *) info->old_ids;
+}
diff --git a/gnome-panel/panel-applet-info.h b/gnome-panel/panel-applet-info.h
new file mode 100644
index 0000000..6e1a7a7
--- /dev/null
+++ b/gnome-panel/panel-applet-info.h
@@ -0,0 +1,47 @@
+/*
+ * panel-applet-info.h
+ *
+ * Copyright (C) 2010 Carlos Garcia Campos <carlosgc gnome org>
+ * Copyright (C) 2010 Vincent Untz <vuntz gnome 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 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
+ * 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.
+ */
+
+#ifndef __PANEL_APPLET_INFO_H__
+#define __PANEL_APPLET_INFO_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _PanelAppletInfo PanelAppletInfo;
+
+PanelAppletInfo *panel_applet_info_new (const gchar *iid,
+ const gchar *name,
+ const gchar *comment,
+ const gchar *icon,
+ const gchar **old_ids);
+void panel_applet_info_free (PanelAppletInfo *info);
+
+const gchar *panel_applet_info_get_iid (PanelAppletInfo *info);
+const gchar *panel_applet_info_get_name (PanelAppletInfo *info);
+const gchar *panel_applet_info_get_description (PanelAppletInfo *info);
+const gchar *panel_applet_info_get_icon (PanelAppletInfo *info);
+const gchar * const *panel_applet_info_get_old_ids (PanelAppletInfo *info);
+
+G_END_DECLS
+
+#endif /* __PANEL_APPLET_INFO_H__ */
diff --git a/gnome-panel/panel-applets-manager.c b/gnome-panel/panel-applets-manager.c
index 9a0dfd8..b4760ed 100644
--- a/gnome-panel/panel-applets-manager.c
+++ b/gnome-panel/panel-applets-manager.c
@@ -1,7 +1,8 @@
/*
- * panel-applets-manmanger.c
+ * panel-applets-manager.c
*
* Copyright (C) 2010 Carlos Garcia Campos <carlosgc gnome org>
+ * Copyright (C) 2010 Vincent Untz <vuntz gnome org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -22,522 +23,138 @@
#include <config.h>
#include <gio/gio.h>
-#include <gmodule.h>
-#include <string.h>
-#include "panel-applets-manager.h"
-
-static GHashTable *applet_factories;
-static GList *monitors = NULL;
-
-typedef gint (* ActivateAppletFunc) (void);
-
-typedef struct _PanelAppletFactoryInfo {
- gchar *id;
- gchar *location;
- gboolean in_process;
- GModule *module;
- ActivateAppletFunc activate_applet;
- guint n_applets;
-
- gchar *srcdir;
-
- GList *applet_list;
- gboolean has_old_ids;
-} PanelAppletFactoryInfo;
-
-struct _PanelAppletInfo {
- gchar *iid;
+#include <libpanel-util/panel-cleanup.h>
- gchar *name;
- gchar *comment;
- gchar *icon;
+#include "panel-modules.h"
- gchar **old_ids;
-};
+#include "panel-applets-manager.h"
-#define PANEL_APPLET_FACTORY_GROUP "Applet Factory"
-#define PANEL_APPLETS_EXTENSION ".panel-applet"
+G_DEFINE_ABSTRACT_TYPE (PanelAppletsManager, panel_applets_manager, G_TYPE_OBJECT)
static void
-panel_applet_info_free (PanelAppletInfo *info)
+panel_applets_manager_init (PanelAppletsManager *manager)
{
- if (!info)
- return;
-
- g_free (info->iid);
- g_free (info->name);
- g_free (info->comment);
- g_free (info->icon);
- g_strfreev (info->old_ids);
-
- g_slice_free (PanelAppletInfo, info);
}
static void
-panel_applet_factory_info_free (PanelAppletFactoryInfo *info)
-{
- if (!info)
- return;
-
- g_free (info->id);
- g_free (info->location);
- g_list_foreach (info->applet_list,
- (GFunc)panel_applet_info_free,
- NULL);
- g_list_free (info->applet_list);
- info->applet_list = NULL;
- g_free (info->srcdir);
-
- g_slice_free (PanelAppletFactoryInfo, info);
-}
-
-static PanelAppletInfo *
-_panel_applets_manager_get_applet_info (GKeyFile *applet_file,
- const gchar *group,
- const gchar *factory_id)
+panel_applets_manager_class_init (PanelAppletsManagerClass *class)
{
- PanelAppletInfo *info;
-
- info = g_slice_new0 (PanelAppletInfo);
-
- info->iid = g_strdup_printf ("%s::%s", factory_id, group);
- info->name = g_key_file_get_locale_string (applet_file, group,
- "Name", NULL, NULL);
- info->comment = g_key_file_get_locale_string (applet_file, group,
- "Description", NULL, NULL);
- info->icon = g_key_file_get_string (applet_file, group, "Icon", NULL);
-
- /* Bonobo compatibility */
- info->old_ids = g_key_file_get_string_list (applet_file, group,
- "BonoboId", NULL, NULL);
-
- return info;
}
-static PanelAppletFactoryInfo *
-panel_applets_manager_get_applet_factory_info_from_file (const gchar *filename)
-{
- PanelAppletFactoryInfo *info;
- GKeyFile *applet_file;
- gchar **groups;
- gsize n_groups;
- gint i;
- GError *error = NULL;
-
- applet_file = g_key_file_new ();
- if (!g_key_file_load_from_file (applet_file, filename, G_KEY_FILE_NONE, &error)) {
- g_warning ("Error opening panel applet file %s: %s",
- filename, error->message);
- g_error_free (error);
- g_key_file_free (applet_file);
-
- return NULL;
- }
-
- info = g_slice_new0 (PanelAppletFactoryInfo);
- info->id = g_key_file_get_string (applet_file, PANEL_APPLET_FACTORY_GROUP, "Id", NULL);
- if (!info->id) {
- g_warning ("Bad panel applet file %s: Could not find 'Id' in group '%s'",
- filename, PANEL_APPLET_FACTORY_GROUP);
- panel_applet_factory_info_free (info);
- g_key_file_free (applet_file);
-
- return NULL;
- }
-
- info->in_process = g_key_file_get_boolean (applet_file, PANEL_APPLET_FACTORY_GROUP,
- "InProcess", NULL);
- if (info->in_process) {
- info->location = g_key_file_get_string (applet_file, PANEL_APPLET_FACTORY_GROUP,
- "Location", NULL);
- if (!info->location) {
- g_warning ("Bad panel applet file %s: In-process applet without 'Location'",
- filename);
- panel_applet_factory_info_free (info);
- g_key_file_free (applet_file);
-
- return NULL;
- }
- }
-
- info->has_old_ids = FALSE;
-
- groups = g_key_file_get_groups (applet_file, &n_groups);
- for (i = 0; i < n_groups; i++) {
- PanelAppletInfo *ainfo;
-
- if (strcmp (groups[i], PANEL_APPLET_FACTORY_GROUP) == 0)
- continue;
-
- ainfo = _panel_applets_manager_get_applet_info (applet_file,
- groups[i], info->id);
- if (ainfo->old_ids)
- info->has_old_ids = TRUE;
-
- info->applet_list = g_list_prepend (info->applet_list, ainfo);
- }
- g_strfreev (groups);
-
- g_key_file_free (applet_file);
-
- if (!info->applet_list) {
- panel_applet_factory_info_free (info);
- return NULL;
- }
+/* Generic methods */
- info->srcdir = g_path_get_dirname (filename);
+static GSList *panel_applets_managers = NULL;
- return info;
-}
-
-static GSList *
-panel_applets_manager_get_applets_dirs (void)
+static void
+_panel_applets_manager_cleanup (gpointer data)
{
- const gchar *dir = NULL;
- gchar **paths;
- guint i;
- GSList *retval = NULL;
-
- dir = g_getenv ("PANEL_APPLETS_DIR");
- if (!dir || strcmp (dir, "") == 0) {
- return g_slist_prepend (NULL, g_strdup (PANEL_APPLETS_DIR));
- }
-
- paths = g_strsplit (dir, ":", 0);
- for (i = 0; paths[i]; i++) {
- if (g_slist_find_custom (retval, paths[i], (GCompareFunc)strcmp))
- continue;
- retval = g_slist_prepend (retval, g_strdup (paths[i]));
- }
- g_strfreev (paths);
-
- return g_slist_reverse (retval);
+ g_slist_foreach (panel_applets_managers, (GFunc) g_object_unref, NULL);
+ g_slist_free (panel_applets_managers);
+ panel_applets_managers = NULL;
}
static void
-applets_directory_changed (GFileMonitor *monitor,
- GFile *file,
- GFile *other_file,
- GFileMonitorEvent event_type,
- gpointer user_data)
+_panel_applets_managers_ensure_loaded (void)
{
- switch (event_type) {
- case G_FILE_MONITOR_EVENT_CHANGED:
- case G_FILE_MONITOR_EVENT_CREATED: {
- PanelAppletFactoryInfo *info;
- PanelAppletFactoryInfo *old_info;
- gchar *filename;
- GSList *dirs, *d;
-
- filename = g_file_get_path (file);
- if (!g_str_has_suffix (filename, PANEL_APPLETS_EXTENSION)) {
- g_free (filename);
- return;
- }
-
- info = panel_applets_manager_get_applet_factory_info_from_file (filename);
- g_free (filename);
-
- if (!info)
- return;
-
- old_info = g_hash_table_lookup (applet_factories, info->id);
- if (!old_info) {
- /* New applet, just insert it */
- g_hash_table_insert (applet_factories, g_strdup (info->id), info);
- return;
- }
-
- /* Make sure we don't update an applet
- * that has changed in another source dir
- * unless it takes precedence over the
- * current one
- */
- if (strcmp (info->srcdir, old_info->srcdir) == 0) {
- g_hash_table_insert (applet_factories, g_strdup (info->id), info);
- return;
- }
-
- dirs = panel_applets_manager_get_applets_dirs ();
-
- for (d = dirs; d; d = g_slist_next (d)) {
- gchar *path = (gchar *)d->data;
-
- if (strcmp (path, old_info->srcdir) == 0) {
- panel_applet_factory_info_free (info);
- break;
- } else if (strcmp (path, info->srcdir) == 0) {
- g_hash_table_insert (applet_factories, g_strdup (info->id), info);
- break;
- }
- }
+ GIOExtensionPoint *point;
+ GList *extensions, *l;
- g_slist_foreach (dirs, (GFunc)g_free, NULL);
- g_slist_free (dirs);
- }
- break;
- default:
- /* Ignore any other change */
- break;
- }
-}
-
-static gboolean
-_panel_applets_manager_init (void)
-{
- GSList *dirs, *d;
- GDir *dir;
- const gchar *dirent;
- GError *error = NULL;
- gboolean retval = FALSE;
-
- dirs = panel_applets_manager_get_applets_dirs ();
- for (d = dirs; d; d = g_slist_next (d)) {
- GFileMonitor *monitor;
- GFile *dir_file;
- gchar *path = (gchar *)d->data;
-
- dir = g_dir_open (path, 0, &error);
- if (!dir) {
- g_warning ("%s", error->message);
- g_error_free (error);
- g_free (path);
+ if (panel_applets_managers != NULL)
+ return;
- continue;
- }
-
- /* Monitor dir */
- dir_file = g_file_new_for_path (path);
- monitor = g_file_monitor_directory (dir_file,
- G_FILE_MONITOR_NONE,
- NULL, NULL);
- if (monitor) {
- g_signal_connect (monitor, "changed",
- G_CALLBACK (applets_directory_changed),
- NULL);
- monitors = g_list_prepend (monitors, monitor);
- }
- g_object_unref (dir_file);
-
- while ((dirent = g_dir_read_name (dir))) {
- PanelAppletFactoryInfo *info;
- gchar *file;
-
- if (!g_str_has_suffix (dirent, PANEL_APPLETS_EXTENSION))
- continue;
-
- file = g_build_filename (path, dirent, NULL);
- info = panel_applets_manager_get_applet_factory_info_from_file (file);
- g_free (file);
-
- if (!info)
- continue;
-
- if (g_hash_table_lookup (applet_factories, info->id)) {
- panel_applet_factory_info_free (info);
- continue;
- }
-
- g_hash_table_insert (applet_factories, g_strdup (info->id), info);
- retval = TRUE;
- }
-
- g_dir_close (dir);
- g_free (path);
- }
+ panel_cleanup_register (PANEL_CLEAN_FUNC (_panel_applets_manager_cleanup), NULL);
- g_slist_free (dirs);
+ panel_modules_ensure_loaded ();
- return retval;
-}
+ point = g_io_extension_point_lookup (PANEL_APPLETS_MANAGER_EXTENSION_POINT_NAME);
-gboolean
-panel_applets_manager_init (void)
-{
- if (applet_factories)
- return TRUE;
+ extensions = g_io_extension_point_get_extensions (point);
- applet_factories = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- (GDestroyNotify)g_free,
- (GDestroyNotify)panel_applet_factory_info_free);
+ if (extensions == NULL)
+ g_error ("No PanelAppletsManager implementations exist.");
- return _panel_applets_manager_init ();
-}
+ for (l = extensions; l != NULL; l = l->next) {
+ GIOExtension *extension;
+ GType type;
+ GObject *object;
-void
-panel_applets_manager_shutdown (void)
-{
- if (monitors) {
- g_list_foreach (monitors, (GFunc)g_object_unref, NULL);
- g_list_free (monitors);
- monitors = NULL;
+ extension = l->data;
+ type = g_io_extension_get_type (extension);
+ object = g_object_new (type, NULL);
+ panel_applets_managers = g_slist_prepend (panel_applets_managers, object);
}
- if (applet_factories) {
- g_hash_table_destroy (applet_factories);
- applet_factories = NULL;
- }
+ panel_applets_managers = g_slist_reverse (panel_applets_managers);
}
GList *
panel_applets_manager_get_applets (void)
{
- GHashTableIter iter;
- gpointer key, value;
- GList *retval = NULL;
+ GSList *l;
+ GList *retval = NULL;
- g_hash_table_iter_init (&iter, applet_factories);
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- PanelAppletFactoryInfo *info;
+ _panel_applets_managers_ensure_loaded ();
- info = (PanelAppletFactoryInfo *)value;
- retval = g_list_concat (retval, g_list_copy (info->applet_list));
+ for (l = panel_applets_managers; l != NULL; l = l->next) {
+ GList *applets;
+ PanelAppletsManager *manager = PANEL_APPLETS_MANAGER (l->data);
+
+ applets = PANEL_APPLETS_MANAGER_GET_CLASS (manager)->get_applets (manager);
+ if (applets)
+ retval = g_list_concat (retval, applets);
}
return retval;
}
-static PanelAppletFactoryInfo *
-get_applet_factory_info (const gchar *iid)
-{
- PanelAppletFactoryInfo *info;
- const gchar *sp;
- gchar *factory_id;
-
- if (!applet_factories)
- return NULL;
-
- sp = g_strrstr (iid, "::");
- if (!sp)
- return NULL;
-
- factory_id = g_strndup (iid, strlen (iid) - strlen (sp));
- info = g_hash_table_lookup (applet_factories, factory_id);
- g_free (factory_id);
-
- return info;
-}
-
gboolean
panel_applets_manager_factory_activate (const gchar *iid)
{
- PanelAppletFactoryInfo *info;
- ActivateAppletFunc activate_applet;
-
- info = get_applet_factory_info (iid);
- if (!info)
- return FALSE;
-
- /* Out process applets are activated
- * by the session bus
- */
- if (!info->in_process)
- return TRUE;
-
- if (info->module) {
- if (info->n_applets == 0) {
- if (info->activate_applet () != 0) {
- g_warning ("Failed to reactivate factory %s\n", iid);
- return FALSE;
- }
- }
- info->n_applets++;
-
- return TRUE;
- }
-
- info->module = g_module_open (info->location, G_MODULE_BIND_LAZY);
- if (!info->module) {
- /* FIXME: use a GError? */
- g_warning ("Failed to load applet %s: %s\n",
- iid, g_module_error ());
- return FALSE;
- }
-
- if (!g_module_symbol (info->module, "_panel_applet_shlib_factory", (gpointer *)&activate_applet)) {
- /* FIXME: use a GError? */
- g_warning ("Failed to load applet %s: %s\n",
- iid, g_module_error ());
- g_module_close (info->module);
- info->module = NULL;
+ GSList *l;
- return FALSE;
- }
+ _panel_applets_managers_ensure_loaded ();
- /* Activate the applet */
- if (activate_applet () != 0) {
- /* FIXME: use a GError? */
- g_warning ("Failed to load applet %s\n", iid);
- g_module_close (info->module);
- info->module = NULL;
+ for (l = panel_applets_managers; l != NULL; l = l->next) {
+ PanelAppletsManager *manager = PANEL_APPLETS_MANAGER (l->data);
- return FALSE;
+ if (PANEL_APPLETS_MANAGER_GET_CLASS (manager)->factory_activate (manager, iid))
+ return TRUE;
}
- info->activate_applet = activate_applet;
-
- info->n_applets = 1;
- return TRUE;
+ return FALSE;
}
void
panel_applets_manager_factory_deactivate (const gchar *iid)
{
- PanelAppletFactoryInfo *info;
+ GSList *l;
- info = get_applet_factory_info (iid);
- if (!info)
- return;
+ _panel_applets_managers_ensure_loaded ();
- /* Out process applets are deactivated
- * by the session bus
- */
- if (!info->in_process)
- return;
+ for (l = panel_applets_managers; l != NULL; l = l->next) {
+ PanelAppletsManager *manager = PANEL_APPLETS_MANAGER (l->data);
- if (!info->module)
- return;
-
- if (--info->n_applets == 0) {
- /* FIXME: we should close the module here,
- * however applet types are registered static
- */
-#if 0
- g_module_close (info->module);
- info->module = NULL;
-#endif
+ if (PANEL_APPLETS_MANAGER_GET_CLASS (manager)->factory_deactivate (manager, iid))
+ return;
}
}
-gboolean
-panel_applets_manager_is_factory_in_process (const gchar *iid)
-{
- PanelAppletFactoryInfo *info;
-
- info = get_applet_factory_info (iid);
- if (!info)
- return FALSE;
-
- return info->in_process;
-}
-
PanelAppletInfo *
panel_applets_manager_get_applet_info (const gchar *iid)
{
- PanelAppletFactoryInfo *info;
- GList *l;
+ GSList *l;
+ PanelAppletInfo *retval = NULL;
+
+ _panel_applets_managers_ensure_loaded ();
- info = get_applet_factory_info (iid);
- if (!info)
- return NULL;
+ for (l = panel_applets_managers; l != NULL; l = l->next) {
+ PanelAppletsManager *manager = PANEL_APPLETS_MANAGER (l->data);
- for (l = info->applet_list; l; l = g_list_next (l)) {
- PanelAppletInfo *ainfo = (PanelAppletInfo *)l->data;
+ retval = PANEL_APPLETS_MANAGER_GET_CLASS (manager)->get_applet_info (manager, iid);
- if (strcmp (ainfo->iid, iid) == 0)
- return ainfo;
+ if (retval != NULL)
+ return retval;
}
return NULL;
@@ -546,60 +163,39 @@ panel_applets_manager_get_applet_info (const gchar *iid)
PanelAppletInfo *
panel_applets_manager_get_applet_info_from_old_id (const gchar *iid)
{
- GHashTableIter iter;
- gpointer key, value;
+ GSList *l;
+ PanelAppletInfo *retval = NULL;
- g_hash_table_iter_init (&iter, applet_factories);
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- PanelAppletFactoryInfo *info;
- GList *l;
+ _panel_applets_managers_ensure_loaded ();
- info = (PanelAppletFactoryInfo *)value;
- if (!info->has_old_ids)
- continue;
-
- for (l = info->applet_list; l; l = g_list_next (l)) {
- PanelAppletInfo *ainfo;
- gint i = 0;
+ for (l = panel_applets_managers; l != NULL; l = l->next) {
+ PanelAppletsManager *manager = PANEL_APPLETS_MANAGER (l->data);
- ainfo = (PanelAppletInfo *)l->data;
+ retval = PANEL_APPLETS_MANAGER_GET_CLASS (manager)->get_applet_info_from_old_id (manager, iid);
- if (!ainfo->old_ids)
- continue;
-
- while (ainfo->old_ids[i]) {
- if (strcmp (ainfo->old_ids[i], iid) == 0)
- return ainfo;
- i++;
- }
- }
+ if (retval != NULL)
+ return retval;
}
return NULL;
}
-const gchar *
-panel_applet_info_get_iid (PanelAppletInfo *info)
+gboolean
+panel_applets_manager_load_applet (const gchar *iid,
+ PanelAppletFrameActivating *frame_act)
{
- return info->iid;
-}
+ GSList *l;
-const gchar *
-panel_applet_info_get_name (PanelAppletInfo *info)
-{
- return info->name;
-}
+ _panel_applets_managers_ensure_loaded ();
-const gchar *
-panel_applet_info_get_description (PanelAppletInfo *info)
-{
- return info->comment;
-}
+ for (l = panel_applets_managers; l != NULL; l = l->next) {
+ PanelAppletsManager *manager = PANEL_APPLETS_MANAGER (l->data);
-const gchar *
-panel_applet_info_get_icon (PanelAppletInfo *info)
-{
- return info->icon;
-}
+ if (!PANEL_APPLETS_MANAGER_GET_CLASS (manager)->get_applet_info (manager, iid))
+ continue;
+ return PANEL_APPLETS_MANAGER_GET_CLASS (manager)->load_applet (manager, iid, frame_act);
+ }
+ return FALSE;
+}
diff --git a/gnome-panel/panel-applets-manager.h b/gnome-panel/panel-applets-manager.h
index 235a18c..f36c1c3 100644
--- a/gnome-panel/panel-applets-manager.h
+++ b/gnome-panel/panel-applets-manager.h
@@ -1,7 +1,8 @@
/*
- * panel-applets-manmanger.h
+ * panel-applets-manager.h
*
* Copyright (C) 2010 Carlos Garcia Campos <carlosgc gnome org>
+ * Copyright (C) 2010 Vincent Untz <vuntz gnome org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -22,27 +23,67 @@
#ifndef __PANEL_APPLETS_MANAGER_H__
#define __PANEL_APPLETS_MANAGER_H__
-#include <glib.h>
+#include <glib-object.h>
+
+#include "panel-applet-frame.h"
+#include "panel-applet-info.h"
G_BEGIN_DECLS
-typedef struct _PanelAppletInfo PanelAppletInfo;
+#define PANEL_TYPE_APPLETS_MANAGER (panel_applets_manager_get_type ())
+#define PANEL_APPLETS_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PANEL_TYPE_APPLETS_MANAGER, PanelAppletsManager))
+#define PANEL_APPLETS_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANEL_TYPE_APPLETS_MANAGER, PanelAppletsManagerClass))
+#define PANEL_IS_APPLETS_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PANEL_TYPE_APPLETS_MANAGER))
+#define PANEL_IS_APPLETS_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANEL_TYPE_APPLETS_MANAGER))
+#define PANEL_APPLETS_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PANEL_TYPE_APPLETS_MANAGER, PanelAppletsManagerClass))
+
+/**
+ * PANEL_APPLETS_MANAGER_EXTENSION_POINT_NAME:
+ *
+ * Extension point for #PanelAppletsManager functionality.
+ **/
+#define PANEL_APPLETS_MANAGER_EXTENSION_POINT_NAME "panel-applets-manager"
+
+typedef struct _PanelAppletsManager PanelAppletsManager;
+typedef struct _PanelAppletsManagerClass PanelAppletsManagerClass;
+
+struct _PanelAppletsManagerClass {
+ GObjectClass parent_class;
+
+ GList * (*get_applets) (PanelAppletsManager *manager);
+
+ gboolean (*factory_activate) (PanelAppletsManager *manager,
+ const gchar *iid);
+ gboolean (*factory_deactivate) (PanelAppletsManager *manager,
+ const gchar *iid);
+
+ PanelAppletInfo * (*get_applet_info) (PanelAppletsManager *manager,
+ const gchar *iid);
+
+ PanelAppletInfo * (*get_applet_info_from_old_id) (PanelAppletsManager *manager,
+ const gchar *iid);
+
+ gboolean (*load_applet) (PanelAppletsManager *manager,
+ const gchar *iid,
+ PanelAppletFrameActivating *frame_act);
+};
+
+struct _PanelAppletsManager {
+ GObject parent;
+};
+
+GType panel_applets_manager_get_type (void);
-gboolean panel_applets_manager_init (void);
-void panel_applets_manager_shutdown (void);
-GList *panel_applets_manager_get_applets (void);
+GList *panel_applets_manager_get_applets (void);
-gboolean panel_applets_manager_factory_activate (const gchar *iid);
-void panel_applets_manager_factory_deactivate (const gchar *iid);
+gboolean panel_applets_manager_factory_activate (const gchar *iid);
+void panel_applets_manager_factory_deactivate (const gchar *iid);
-gboolean panel_applets_manager_is_factory_in_process (const gchar *iid);
-PanelAppletInfo *panel_applets_manager_get_applet_info (const gchar *iid);
-PanelAppletInfo *panel_applets_manager_get_applet_info_from_old_id (const gchar *iid);
+PanelAppletInfo *panel_applets_manager_get_applet_info (const gchar *iid);
+PanelAppletInfo *panel_applets_manager_get_applet_info_from_old_id (const gchar *iid);
-const gchar *panel_applet_info_get_iid (PanelAppletInfo *info);
-const gchar *panel_applet_info_get_name (PanelAppletInfo *info);
-const gchar *panel_applet_info_get_description (PanelAppletInfo *info);
-const gchar *panel_applet_info_get_icon (PanelAppletInfo *info);
+gboolean panel_applets_manager_load_applet (const gchar *iid,
+ PanelAppletFrameActivating *frame_act);
G_END_DECLS
diff --git a/gnome-panel/panel-modules.c b/gnome-panel/panel-modules.c
new file mode 100644
index 0000000..7719385
--- /dev/null
+++ b/gnome-panel/panel-modules.c
@@ -0,0 +1,78 @@
+/*
+ * panel-modules.c
+ *
+ * Copyright (C) 2010 Vincent Untz <vuntz gnome 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 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
+ * 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.
+ *
+ * Authors:
+ * Vincent Untz <vuntz gnome org>
+ */
+
+#include <config.h>
+
+#include <gio/gio.h>
+
+#include <libpanel-applet-private/panel-applets-manager-dbus.h>
+
+#include "panel-applets-manager.h"
+
+#include "panel-modules.h"
+
+static void
+panel_modules_ensure_extension_points_registered (void)
+{
+ static gboolean registered_extensions = FALSE;
+ GIOExtensionPoint *ep;
+
+ if (!registered_extensions) {
+ registered_extensions = TRUE;
+
+ ep = g_io_extension_point_register (PANEL_APPLETS_MANAGER_EXTENSION_POINT_NAME);
+ g_io_extension_point_set_required_type (ep, PANEL_TYPE_APPLETS_MANAGER);
+ }
+ }
+
+void
+panel_modules_ensure_loaded (void)
+{
+ static gboolean loaded_dirs = FALSE;
+ const char *module_path;
+
+ panel_modules_ensure_extension_points_registered ();
+
+ if (!loaded_dirs) {
+ loaded_dirs = TRUE;
+
+ g_io_modules_scan_all_in_directory (PANEL_MODULES_DIR);
+
+ module_path = g_getenv ("GNOME_PANEL_EXTRA_MODULES");
+
+ if (module_path) {
+ gchar **paths;
+ int i;
+
+ paths = g_strsplit (module_path, ":", 0);
+
+ for (i = 0; paths[i] != NULL; i++)
+ g_io_modules_scan_all_in_directory (paths[i]);
+
+ g_strfreev (paths);
+ }
+
+ panel_applets_manager_dbus_get_type ();
+ }
+}
diff --git a/gnome-panel/panel-modules.h b/gnome-panel/panel-modules.h
new file mode 100644
index 0000000..02ddd04
--- /dev/null
+++ b/gnome-panel/panel-modules.h
@@ -0,0 +1,30 @@
+/*
+ * panel-modules.h
+ *
+ * Copyright (C) 2010 Vincent Untz <vuntz gnome 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 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
+ * 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.
+ *
+ * Authors:
+ * Vincent Untz <vuntz gnome org>
+ */
+
+#ifndef __PANEL_MODULES_H__
+#define __PANEL_MODULES_H__
+
+void panel_modules_ensure_loaded (void);
+
+#endif /* __PANEL_MODULES_H__ */
diff --git a/gnome-panel/panel-test-applets.c b/gnome-panel/panel-test-applets.c
index 283e7dd..58b1a3a 100644
--- a/gnome-panel/panel-test-applets.c
+++ b/gnome-panel/panel-test-applets.c
@@ -12,8 +12,12 @@
#include <gtk/gtk.h>
#include <gconf/gconf.h>
-#include <gnome-panel/panel-applet-container.h>
-#include <gnome-panel/panel-applets-manager.h>
+#include <libpanel-util/panel-cleanup.h>
+
+#include <libpanel-applet-private/panel-applet-container.h>
+#include <libpanel-applet-private/panel-applets-manager-dbus.h>
+
+#include "panel-modules.h"
G_GNUC_UNUSED void on_execute_button_clicked (GtkButton *button, gpointer dummy);
@@ -253,13 +257,14 @@ setup_combo (GtkWidget *combo_box,
static void
setup_options (void)
{
- GList *applet_list, *l;
- int i;
- char *prefs_dir;
- char *unique_key;
- GtkListStore *model;
- GtkTreeIter iter;
- GtkCellRenderer *renderer;
+ PanelAppletsManager *manager;
+ GList *applet_list, *l;
+ int i;
+ char *prefs_dir;
+ char *unique_key;
+ GtkListStore *model;
+ GtkTreeIter iter;
+ GtkCellRenderer *renderer;
model = gtk_list_store_new (NUMBER_COLUMNS,
G_TYPE_STRING,
@@ -268,7 +273,8 @@ setup_options (void)
gtk_combo_box_set_model (GTK_COMBO_BOX (applet_combo),
GTK_TREE_MODEL (model));
- applet_list = panel_applets_manager_get_applets ();
+ manager = g_object_new (PANEL_TYPE_APPLETS_MANAGER_DBUS, NULL);
+ applet_list = PANEL_APPLETS_MANAGER_GET_CLASS (manager)->get_applets (manager);
for (l = applet_list, i = 1; l; l = g_list_next (l), i++) {
PanelAppletInfo *info = (PanelAppletInfo *)l->data;
@@ -279,6 +285,7 @@ setup_options (void)
-1);
}
g_list_free (applet_list);
+ g_object_unref (manager);
renderer = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (applet_combo),
@@ -325,18 +332,19 @@ main (int argc, char **argv)
return 1;
}
+ panel_modules_ensure_loaded ();
+
if (g_file_test ("../libpanel-applet", G_FILE_TEST_IS_DIR)) {
applets_dir = g_strdup_printf ("%s:../libpanel-applet", PANEL_APPLETS_DIR);
- g_setenv ("PANEL_APPLETS_DIR", applets_dir, FALSE);
+ g_setenv ("GNOME_PANEL_APPLETS_DIR", applets_dir, FALSE);
g_free (applets_dir);
}
- panel_applets_manager_init ();
-
if (cli_iid) {
load_applet_from_command_line ();
gtk_main ();
- panel_applets_manager_shutdown ();
+ panel_cleanup_do ();
+
return 0;
}
@@ -349,7 +357,7 @@ main (int argc, char **argv)
if (error) {
g_warning ("Error loading \"%s\": %s", uifile, error->message);
g_error_free (error);
- panel_applets_manager_shutdown ();
+ panel_cleanup_do ();
return 1;
}
@@ -374,7 +382,7 @@ main (int argc, char **argv)
gtk_main ();
- panel_applets_manager_shutdown ();
+ panel_cleanup_do ();
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]