[maemo-commits] [maemo-commits] r19040 - in projects/haf/trunk/hildon-control-panel: debian src
From: subversion at stage.maemo.org subversion at stage.maemo.orgDate: Wed Aug 5 09:22:43 EEST 2009
- Previous message: [maemo-commits] r19039 - projects/haf/tags/gtk+
- Next message: [maemo-commits] r19041 - in projects/haf/trunk/libosso: debian src
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: kihamala Date: 2009-08-05 09:22:29 +0300 (Wed, 05 Aug 2009) New Revision: 19040 Modified: projects/haf/trunk/hildon-control-panel/debian/changelog projects/haf/trunk/hildon-control-panel/debian/control projects/haf/trunk/hildon-control-panel/debian/rules projects/haf/trunk/hildon-control-panel/src/Makefile.am projects/haf/trunk/hildon-control-panel/src/hcp-app.c projects/haf/trunk/hildon-control-panel/src/hcp-app.h projects/haf/trunk/hildon-control-panel/src/hcp-program.c projects/haf/trunk/hildon-control-panel/src/hcp-program.h projects/haf/trunk/hildon-control-panel/src/hcp-window.c Log: Changes from David Modified: projects/haf/trunk/hildon-control-panel/debian/changelog =================================================================== --- projects/haf/trunk/hildon-control-panel/debian/changelog 2009-08-04 18:07:02 UTC (rev 19039) +++ projects/haf/trunk/hildon-control-panel/debian/changelog 2009-08-05 06:22:29 UTC (rev 19040) @@ -1,3 +1,18 @@ +hildon-control-panel (1:2.2.12-1~unreleased) unstable; urgency=low + + David Kedves: + * Applets now running in separate processes from HCP + * Applets always transient for hildon-control-panel + * State saving support for multiple applets + * Fixes: NB#98750 - Two instances of Language and Regional settings CPA is + shown + * Fixes: NB#96278 - Closing one instance of the applet does not close the + other. + * Fixes: NB#102740 - The maesync CP dialog is not closed when clicked on the + status area. + + -- Kimmo Hämäläinen <kimmo.hamalainen at nokia.com> Tue, 04 Aug 2009 17:14:28 +0300 + hildon-control-panel (1:2.2.11-2) unstable; urgency=low * Fixes: NB#97295 - Applet order not following UI spec Modified: projects/haf/trunk/hildon-control-panel/debian/control =================================================================== --- projects/haf/trunk/hildon-control-panel/debian/control 2009-08-04 18:07:02 UTC (rev 19039) +++ projects/haf/trunk/hildon-control-panel/debian/control 2009-08-05 06:22:29 UTC (rev 19040) @@ -8,7 +8,7 @@ Package: hildon-control-panel Section: x11 Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, ${launcher:Depends}, hildon-control-panel-l10n-mr | hildon-control-panel-l10n-mr0, osso-app-killer (>= 1.1), osso-system-lock-l10n-mr | osso-system-lock-l10n-mr0 +Depends: ${shlibs:Depends}, ${misc:Depends}, ${launcher:Depends}, hildon-control-panel-l10n-mr | hildon-control-panel-l10n-mr0, osso-app-killer (>= 1.1), osso-system-lock-l10n-mr | osso-system-lock-l10n-mr0, libosso1 (>> 2.23-1) Recommends: hildon-theme-alpha, hildon-keyboard, matchbox-window-manager Suggests: hildon-tests Conflicts: hildon-base Modified: projects/haf/trunk/hildon-control-panel/debian/rules =================================================================== --- projects/haf/trunk/hildon-control-panel/debian/rules 2009-08-04 18:07:02 UTC (rev 19039) +++ projects/haf/trunk/hildon-control-panel/debian/rules 2009-08-05 06:22:29 UTC (rev 19040) @@ -102,6 +102,10 @@ $(CURDIR)/debian/build/usr/bin/controlpanel.launch ln -s /usr/bin/maemo-invoker \ $(CURDIR)/debian/build/usr/bin/controlpanel + mv $(CURDIR)/debian/build/usr/bin/cpa_loader \ + $(CURDIR)/debian/build/usr/bin/cpa_loader.launch + ln -s /usr/bin/maemo-invoker \ + $(CURDIR)/debian/build/usr/bin/cpa_loader endif Modified: projects/haf/trunk/hildon-control-panel/src/Makefile.am =================================================================== --- projects/haf/trunk/hildon-control-panel/src/Makefile.am 2009-08-04 18:07:02 UTC (rev 19039) +++ projects/haf/trunk/hildon-control-panel/src/Makefile.am 2009-08-05 06:22:29 UTC (rev 19040) @@ -33,7 +33,7 @@ hcp-marshalers.c: hcp-marshalers.list $(GLIB_GENMARSHAL) $< --header --body --prefix=hcp_marshal > $@ -bin_PROGRAMS = controlpanel +bin_PROGRAMS = controlpanel cpa_loader controlpanel_SOURCES = \ $(BUILT_SOURCES) \ @@ -53,6 +53,9 @@ hcp-grid.c \ hildon-cp-plugin-interface.h +cpa_loader_SOURCES = \ + hcp-app-loader.c + if USE_MAEMO_TOOLS controlpanel_SOURCES += \ hcp-rfs.c \ @@ -64,9 +67,12 @@ controlpanel_LDFLAGS = $(MAEMO_LAUNCHER_LDFLAGS) -controlpanel_LDADD = \ - $(HCP_DEPS_LIBS) +controlpanel_LDADD = $(HCP_DEPS_LIBS) +cpa_loader_LDFLAGS = $(MAEMO_LAUNCHER_LDFLAGS) + +cpa_loader_LDADD = $(HCP_DEPS_LIBS) + hildon_cp_pluginincludeinstdir=$(includedir)/hildon-cp-plugin hildon_cp_pluginincludeinst_DATA = hildon-cp-plugin-interface.h Modified: projects/haf/trunk/hildon-control-panel/src/hcp-app.c =================================================================== --- projects/haf/trunk/hildon-control-panel/src/hcp-app.c 2009-08-04 18:07:02 UTC (rev 19039) +++ projects/haf/trunk/hildon-control-panel/src/hcp-app.c 2009-08-05 06:22:29 UTC (rev 19040) @@ -26,12 +26,20 @@ #include <config.h> #endif +#define _XOPEN_SOURCE +#include <unistd.h> #include <dlfcn.h> #include <string.h> +#include <strings.h> +#include <ctype.h> +#include <sys/types.h> +#include <signal.h> #include <glib.h> #include <glib/gi18n.h> #include <gtk/gtk.h> +#include <gdk/gdkx.h> +#include <X11/Xatom.h> #include "hcp-program.h" #include "hcp-app.h" @@ -65,20 +73,18 @@ gint item_pos; gint sugg_pos; gchar *text_domain; - void *handle; - hcp_plugin_exec_f *exec; - hcp_plugin_save_state_f *save_state; + gchar *wm_class; + Window xid; + GPid pid; }; typedef struct _PluginLaunchData { HCPApp *app; gboolean user_activated; + char *hcp_xid; } PluginLaunchData; -#define HCP_PLUGIN_EXEC_SYMBOL "execute" -#define HCP_PLUGIN_SAVE_STATE_SYMBOL "save_state" - static void hcp_app_init (HCPApp *app) { @@ -86,147 +92,17 @@ app->priv->name = NULL; app->priv->plugin = NULL; + app->priv->wm_class = NULL; app->priv->icon = NULL; app->priv->category = NULL; app->priv->is_running = FALSE; app->priv->grid = NULL; app->priv->item_pos = -1; app->priv->text_domain = NULL; - app->priv->save_state = NULL; app->priv->sugg_pos = G_MAXINT; } static void -hcp_app_load (HCPApp *app) -{ - gchar *plugin_path = NULL; - HCPAppPrivate *priv; - - g_return_if_fail (app); - g_return_if_fail (HCP_IS_APP (app)); - - priv = app->priv; - - g_return_if_fail (priv->plugin); - - if (*priv->plugin == G_DIR_SEPARATOR) - { - /* .desktop provided fullpath, use that */ - plugin_path = g_strdup (priv->plugin); - } - else - { - plugin_path = g_build_filename (HCP_PLUGIN_DIR, priv->plugin, NULL); - } - - if (!priv->handle) - { - priv->handle = dlopen (plugin_path, RTLD_LAZY); - } - - g_free (plugin_path); - - if (!priv->handle) - { - g_warning ("Could not load hildon-control-panel applet %s: %s", - priv->plugin, - dlerror()); - return; - } - - if (!priv->exec) - { - priv->exec = dlsym (priv->handle, HCP_PLUGIN_EXEC_SYMBOL); - } - - if (!priv->exec) - { - g_warning ("Could not find "HCP_PLUGIN_EXEC_SYMBOL" symbol in " - "hildon-control-panel applet %s: %s", - priv->plugin, - dlerror ()); - - dlclose (priv->handle); - - priv->handle = NULL; - return; - } - - if (!priv->save_state) - { - priv->save_state = dlsym (priv->handle, HCP_PLUGIN_SAVE_STATE_SYMBOL); - } -} - -#if 0 -static void -hcp_app_unload (HCPApp *app) -{ - HCPAppPrivate *priv; - - g_return_if_fail (app); - g_return_if_fail (HCP_IS_APP (app)); - g_return_if_fail (plugin->handle); - - priv = app->priv; - - if (dlclose (priv->handle)) - { - g_warning ("An error occurred when unloading hildon-control-panel " - "applet %s: %s", - priv->plugin, - dlerror ()); - } -} -#endif - -static gboolean -hcp_app_idle_launch (PluginLaunchData *d) -{ - HCPAppPrivate *priv; - HCPProgram *program = hcp_program_get_instance (); - - g_return_val_if_fail (d, FALSE); - g_return_val_if_fail (d->app, FALSE); - g_return_val_if_fail (HCP_IS_APP (d->app), FALSE); - - priv = d->app->priv; - - /* required for checking eg. save_state availability and to be on the safe side */ - hcp_app_load (d->app); - - if (!priv->handle) - goto cleanup; - - priv->is_running = TRUE; - - /* Always use hcp->window as parent. */ - - priv->exec (program->osso, program->window, d->user_activated); - - priv->is_running = FALSE; - - program->execute = 0; - -#if 0 - /* Do not close the module and reuse it to avoid GType related - * errors. */ - hcp_app_unload (d->app, p); -#endif - - /* HCP was launched window less, so we can exit once we are done - * with this applet */ - if (!program->window) - gtk_main_quit (); - -cleanup: - g_object_unref (d->app); - g_free (d); - - return FALSE; -} - -static void hcp_app_finalize (GObject *object) { HCPApp *app; @@ -250,6 +126,12 @@ priv->plugin = NULL; } + if (priv->wm_class != NULL) + { + g_free (priv->wm_class); + priv->wm_class = NULL; + } + if (priv->icon != NULL) { g_free (priv->icon); @@ -331,6 +213,21 @@ } } +static gchar * +wm_class_from_so_name (const gchar* so_name) +{ + char* ret = g_path_get_basename (so_name); + int i, len = strlen (ret); + for (i = 0; i < len; i++) + { + if (!isalpha (ret[i])) + ret[i] = '_'; + else + ret[i] = toupper (ret[i]); + } + return (gchar*) ret; +} + static void hcp_app_set_property (GObject *gobject, guint prop_id, @@ -351,6 +248,8 @@ case PROP_PLUGIN: g_free (priv->plugin); priv->plugin = g_strdup (g_value_get_string (value)); + g_free (priv->wm_class); + priv->wm_class =wm_class_from_so_name (priv->plugin); break; case PROP_ICON: @@ -489,31 +388,170 @@ return app; } +static void +search_window_r (gchar *wm_class, + Atom atom, + Window w, + GSList **result) +{ + unsigned long nItems; + unsigned long bytesAfter; + unsigned char *prop = NULL; + Atom type; + int format; + Window root; + Window parent; + Window *children; + unsigned int count; + unsigned int i; + + /* to avoid HCP exiting on X error ... */ + gdk_error_trap_push (); + + /* Get the _NET_WM_PID property ... */ + if (XGetWindowProperty (GDK_DISPLAY (), w, atom, + 0, 200, False, XA_STRING, &type, &format, &nItems, + &bytesAfter, &prop) == Success) + { + /* in case of hit, prepend to result list */ + if (prop) + { + if (strcasecmp ((char*) prop, wm_class) == 0) + *result = g_slist_append (*result, GUINT_TO_POINTER (w)); + XFree (prop); + } + } + + if (gdk_error_trap_pop () == BadWindow) + return; /* Current 'w' Window is closed meanwhile ... */ + + /* Recursion to child windows ... */ + if (XQueryTree(GDK_DISPLAY (), w, &root, &parent, &children, &count)) + { + for (i = 0; i < count; i++) + search_window_r (wm_class, atom, children[i], result); + } +} + +static Window +get_xid_by_wm_class (gchar *wm_class) +{ + GdkAtom atom_pid; + GSList *results = NULL; + Window ret; + atom_pid = gdk_atom_intern ("WM_CLASS", FALSE); + search_window_r (wm_class, gdk_x11_atom_to_xatom (atom_pid), + GDK_ROOT_WINDOW (), &results); + + if (!results) + ret = None; + else + { + /* Return the topmost window xid */ + ret = GPOINTER_TO_UINT (results->data); + g_slist_free (results); + } + + return ret; +} + +static gboolean +try_focus (HCPApp *app) +{ + GdkWindow *applet; + HCPProgram *program = hcp_program_get_instance (); + g_return_val_if_fail (hcp_app_is_running (app), FALSE); + + if (app->priv->xid == None) + app->priv->xid = get_xid_by_wm_class (app->priv->wm_class); + + if (app->priv->xid == None) + return FALSE; /* applet closed meanwhile ... */ + + applet = gdk_window_foreign_new ((GdkNativeWindow) app->priv->xid); + if (applet == NULL) + return FALSE; /* applet closed meanwhile ... */ + + gdk_window_focus (applet, GDK_CURRENT_TIME); + + /* move to the end of the list (to save proper ordering...) */ + program->running_applets = g_list_remove (program->running_applets, + (gconstpointer) app); + program->running_applets = g_list_append (program->running_applets, + (gpointer) app); + + g_object_unref (applet); + + return TRUE; +} + +static void +cpa_child_watch (GPid pid, + gint status, + PluginLaunchData *d) +{ + HCPApp *app = d->app; + HCPProgram *program = hcp_program_get_instance (); + + app->priv->is_running = FALSE; + app->priv->xid = None; + program->running_applets = g_list_remove (program->running_applets, + (gconstpointer) app); + + g_debug ("CPA process exited with status = '%d'", status); + + g_object_unref (app); + g_free (d->hcp_xid); + g_free (d); + return; +} + void hcp_app_launch (HCPApp *app, gboolean user_activated) { - PluginLaunchData *d; - HCPProgram *program = hcp_program_get_instance (); - g_return_if_fail (app); g_return_if_fail (HCP_IS_APP (app)); - g_return_if_fail (!hcp_app_is_running (app)); - if (!program->execute) + char *argv[6]; + PluginLaunchData *d; + HCPProgram *program = hcp_program_get_instance (); + + if (hcp_app_is_running (app)) { - program->execute = 1; + try_focus (app); + return; + } - d = g_new0 (PluginLaunchData, 1); + program->running_applets = g_list_append (program->running_applets, + (gpointer) app); - d->user_activated = user_activated; - d->app = g_object_ref (app); + d = g_new0 (PluginLaunchData, 1); - /* We launch plugins inside an idle loop so we are still able - * to receive DBus messages */ - g_idle_add ((GSourceFunc) hcp_app_idle_launch, d); - } + d->user_activated = user_activated; + d->app = g_object_ref (app); + d->hcp_xid = g_strdup_printf ("%lu", (unsigned long) GDK_WINDOW_XID + (GTK_WIDGET (program->window)->window)); + + app->priv->is_running = TRUE; + app->priv->xid = None; + + argv[0] = "/usr/bin/cpa_loader"; + argv[1] = app->priv->plugin; + argv[2] = app->priv->wm_class; + argv[3] = ( d->user_activated ? "1" : "0" ); + argv[4] = d->hcp_xid; + argv[5] = NULL; + + g_spawn_async (NULL, (char**) argv, NULL, + (GSpawnFlags) G_SPAWN_DO_NOT_REAP_CHILD, + NULL, NULL, &app->priv->pid, NULL); + + /* For watching applet exiting ... */ + g_child_watch_add (app->priv->pid, + (GChildWatchFunc) cpa_child_watch, d); } + void hcp_app_focus (HCPApp *app) { @@ -538,16 +576,16 @@ void hcp_app_save_state (HCPApp *app) { - HCPAppPrivate *priv; - HCPProgram *program = hcp_program_get_instance (); - g_return_if_fail (app); g_return_if_fail (HCP_IS_APP (app)); + g_return_if_fail (hcp_app_is_running (app)); - priv = app->priv; - - if (priv->save_state) - priv->save_state (program->osso, NULL); + if (app->priv->pid > 0) + { + /* Kill SIGTERM to plugin (to save state ... ) */ + kill ((pid_t) app->priv->pid, 15); +/* g_debug ("hcp_app_save_state ('%s')", app->priv->name); */ + } } gboolean @@ -566,14 +604,8 @@ gboolean hcp_app_can_save_state (HCPApp *app) { - HCPAppPrivate *priv; - - g_return_val_if_fail (app, FALSE); - g_return_val_if_fail (HCP_IS_APP (app), FALSE); - - priv = app->priv; - - return (priv->save_state != NULL); + /* Lets cpa_loader to decide applet can save itself state */ + return TRUE; } gint @@ -588,3 +620,13 @@ return ret; } + +gchar * +hcp_app_get_plugin (HCPApp *app) +{ + g_return_val_if_fail (app, NULL); + g_return_val_if_fail (HCP_IS_APP (app), NULL); + + return app->priv->plugin; +} + Modified: projects/haf/trunk/hildon-control-panel/src/hcp-app.h =================================================================== --- projects/haf/trunk/hildon-control-panel/src/hcp-app.h 2009-08-04 18:07:02 UTC (rev 19039) +++ projects/haf/trunk/hildon-control-panel/src/hcp-app.h 2009-08-05 06:22:29 UTC (rev 19040) @@ -42,15 +42,6 @@ #define HCP_IS_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), HCP_TYPE_APP)) #define HCP_APP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), HCP_TYPE_APP, HCPAppClass)) -typedef osso_return_t (hcp_plugin_exec_f) ( - osso_context_t * osso, - gpointer data, - gboolean user_activated); - -typedef osso_return_t (hcp_plugin_save_state_f) ( - osso_context_t * osso, - gpointer data); - struct _HCPApp { GObject gobject; @@ -81,6 +72,9 @@ gint hcp_app_sort_func (const HCPApp *a, const HCPApp *b); +/* result shouldn't be freed */ +gchar *hcp_app_get_plugin (HCPApp *app); + G_END_DECLS #endif Modified: projects/haf/trunk/hildon-control-panel/src/hcp-program.c =================================================================== --- projects/haf/trunk/hildon-control-panel/src/hcp-program.c 2009-08-04 18:07:02 UTC (rev 19039) +++ projects/haf/trunk/hildon-control-panel/src/hcp-program.c 2009-08-05 06:22:29 UTC (rev 19040) @@ -40,15 +40,13 @@ G_DEFINE_TYPE (HCPProgram, hcp_program, G_TYPE_OBJECT); #define HCP_APP_NAME "controlpanel" -#define HCP_APP_VERSION "0.1" +#define HCP_APP_VERSION "0.2" #define HCP_RPC_SERVICE "com.nokia.controlpanel" #define HCP_RPC_PATH "/com/nokia/controlpanel/rpc" #define HCP_RPC_INTERFACE "com.nokia.controlpanel.rpc" #define HCP_RPC_METHOD_RUN_APPLET "run_applet" -#define HCP_RPC_METHOD_SAVE_STATE_APPLET "save_state_applet" #define HCP_RPC_METHOD_TOP_APPLICATION "top_application" -#define HCP_RPC_METHOD_IS_APPLET_RUNNING "is_applet_running" static void hcp_program_show_window (HCPProgram *program) @@ -93,13 +91,12 @@ if (app) { - if (!hcp_app_is_running (app)) - { - hcp_app_launch (app, user_activated.value.b); - } + if (!program->window) + hcp_program_show_window (program); + else + gtk_window_present (GTK_WINDOW (program->window)); - if (GTK_IS_WINDOW (program->window)) - gtk_window_present (GTK_WINDOW (program->window)); + hcp_app_launch (app, user_activated.value.b); retval->type = DBUS_TYPE_INT32; retval->value.i = 0; @@ -107,66 +104,6 @@ return OSSO_OK; } } - else if ((!strcmp (method, HCP_RPC_METHOD_SAVE_STATE_APPLET))) - { - osso_rpc_t applet; - GHashTable *apps = NULL; - HCPApp *app = NULL; - - if (arguments->len != 1) - goto error; - - applet = g_array_index (arguments, osso_rpc_t, 0); - - if (applet.type != DBUS_TYPE_STRING) - goto error; - - g_object_get (G_OBJECT (program->al), - "apps", &apps, - NULL); - - app = g_hash_table_lookup (apps, applet.value.s); - - if (app) - { - if (hcp_app_is_running (app)) - { - hcp_app_save_state (app); - } - - retval->type = DBUS_TYPE_INT32; - retval->value.i = 0; - - return OSSO_OK; - } - } - else if ((!strcmp (method, HCP_RPC_METHOD_IS_APPLET_RUNNING))) - { - osso_rpc_t applet; - GHashTable *apps = NULL; - HCPApp *app = NULL; - - if (arguments->len != 1) - goto error; - - applet = g_array_index (arguments, osso_rpc_t, 0); - - if (applet.type != DBUS_TYPE_STRING) - goto error; - - g_object_get (G_OBJECT (program->al), - "apps", &apps, - NULL); - - app = g_hash_table_lookup (apps, applet.value.s); - - retval->type = DBUS_TYPE_BOOLEAN; - retval->value.b = (app && hcp_app_is_running (app))? - TRUE: - FALSE; - - return OSSO_OK; - } else if ((!strcmp (method, HCP_RPC_METHOD_TOP_APPLICATION))) { if (!program->window) @@ -226,7 +163,7 @@ static void hcp_program_init (HCPProgram *program) { - program->execute = 0; + program->running_applets = NULL; program->al = (HCPAppList *) hcp_app_list_new (); hcp_app_list_update (program->al); @@ -249,6 +186,11 @@ program = HCP_PROGRAM (object); + if (program->running_applets != NULL) + { + g_list_free (program->running_applets); + } + if (program->al != NULL) { g_object_unref (program->al); Modified: projects/haf/trunk/hildon-control-panel/src/hcp-program.h =================================================================== --- projects/haf/trunk/hildon-control-panel/src/hcp-program.h 2009-08-04 18:07:02 UTC (rev 19039) +++ projects/haf/trunk/hildon-control-panel/src/hcp-program.h 2009-08-05 06:22:29 UTC (rev 19040) @@ -54,7 +54,7 @@ GtkWidget *window; HCPAppList *al; osso_context_t *osso; - gint execute; + GList *running_applets; }; struct _HCPProgramClass Modified: projects/haf/trunk/hildon-control-panel/src/hcp-window.c =================================================================== --- projects/haf/trunk/hildon-control-panel/src/hcp-window.c 2009-08-04 18:07:02 UTC (rev 19039) +++ projects/haf/trunk/hildon-control-panel/src/hcp-window.c 2009-08-05 06:22:29 UTC (rev 19040) @@ -27,6 +27,8 @@ #endif #include <libosso.h> +#include <stdlib.h> +#include <signal.h> #include <hildon/hildon-window.h> #include <hildon/hildon-program.h> #include <hildon/hildon-defines.h> @@ -61,8 +63,8 @@ HCPAppList *al; GtkWidget *view; - /* For state save data */ - gchar *saved_focused_filename; + /* For retrieve/state save data */ + gchar **running_apps; gint scroll_value; }; @@ -71,9 +73,8 @@ #define HCP_MENU_CUD _("copa_me_tools_cud") #define HCP_STATE_GROUP "HildonControlPanel" -#define HCP_STATE_FOCUSED "Focussed" +#define HCP_STATE_FOCUSED "Running" #define HCP_STATE_SCROLL_VALUE "ScrollValue" -#define HCP_STATE_EXECUTE "Execute" #define HCP_OPERATOR_WIZARD_DBUS_SERVICE "operator_wizard" #define HCP_OPERATOR_WIZARD_LAUNCH "launch_operator_wizard" @@ -94,31 +95,44 @@ priv = window->priv; +/* g_debug ("ENFORCE STATE"); */ + /* Actually enforce the saved state */ - /* If the saved focused item filename is defined, try to - * focus on the item. */ - if (priv->saved_focused_filename) + /* Load previously opened applets ... */ + if (priv->running_apps) { GHashTable *apps = NULL; - HCPApp *app = NULL; + HCPApp *app = NULL; + gint i; g_object_get (G_OBJECT (priv->al), "apps", &apps, NULL); - app = g_hash_table_lookup (apps, - priv->saved_focused_filename); + for (i = 0; priv->running_apps && priv->running_apps[i] != NULL; i++) + { +/* g_debug ("reload applet [%d]: '%s'", i, priv->running_apps[i]); */ + app = g_hash_table_lookup (apps, + priv->running_apps[i]); + hcp_app_launch (app, FALSE); /* load/restore applet ... */ + } + /* the latest/topmost applet should be focused : */ if (app) /* hcp_app_focus (app); */ priv->focused_item = app; - g_free (priv->saved_focused_filename); - priv->saved_focused_filename = NULL; + g_strfreev (priv->running_apps); + priv->running_apps = NULL; } +} - /* HCPProgram will start the possible plugin in - * program->execute */ +static void +hcp_window_showed (GtkWidget *unused, + HCPWindow *window) +{ + /* For restoring previous state ... */ + hcp_window_enforce_state (window); } static void @@ -130,15 +144,15 @@ GKeyFile *keyfile = NULL; osso_return_t ret; GError *error = NULL; - gchar *focused = NULL; gint scroll_value; - gboolean execute; g_return_if_fail (window); g_return_if_fail (HCP_IS_WINDOW (window)); priv = window->priv; +/* g_debug ("LOAD STATE"); */ + ret = osso_state_read (program->osso, &state); if (ret != OSSO_OK) @@ -168,10 +182,10 @@ goto cleanup; } - focused = g_key_file_get_string (keyfile, - HCP_STATE_GROUP, - HCP_STATE_FOCUSED, - &error); + priv->running_apps = g_key_file_get_string_list (keyfile, + HCP_STATE_GROUP, + HCP_STATE_FOCUSED, + NULL, &error); if (error) { @@ -180,16 +194,6 @@ goto cleanup; } - if (g_str_has_suffix (focused, ".so")) - { - priv->saved_focused_filename = focused; - } - else - { - priv->saved_focused_filename = NULL; - g_free (focused); - } - scroll_value = g_key_file_get_integer (keyfile, HCP_STATE_GROUP, HCP_STATE_SCROLL_VALUE, @@ -204,20 +208,6 @@ priv->scroll_value = scroll_value; - execute = g_key_file_get_boolean (keyfile, - HCP_STATE_GROUP, - HCP_STATE_EXECUTE, - &error); - - if (error) - { - g_warning ("An error occured when reading application state: %s", - error->message); - goto cleanup; - } - - program->execute = execute; - cleanup: if (error) g_error_free (error); @@ -235,8 +225,9 @@ HCPProgram *program = hcp_program_get_instance (); osso_state_t state = { 0, }; GKeyFile *keyfile = NULL; + GList *temp; + gint i; osso_return_t ret; - gchar *focused = NULL; GError *error = NULL; g_return_if_fail (window); @@ -259,27 +250,36 @@ keyfile = g_key_file_new (); - g_object_get (G_OBJECT (priv->focused_item), - "plugin", &focused, - NULL); +/* ====== Save the running applets with correct ordering ... ====== */ + int length = g_list_length (program->running_applets); + /* yes, i really want a pointer array ... */ + priv->running_apps = g_new0 (gchar*, length + 1); - g_key_file_set_string (keyfile, - HCP_STATE_GROUP, - HCP_STATE_FOCUSED, - priv->focused_item?focused:""); +/* g_debug ("SAVING STATE"); */ - g_free (focused); + /* Get the plugin so-name string array */ + for (temp = program->running_applets, i = 0; + temp != NULL; temp = temp->next, i++) + { + priv->running_apps[i] = hcp_app_get_plugin (((HCPApp*) temp->data)); +/* g_debug ("running_apps[%d] = '%s'", i, priv->running_apps[i]); */ + } + + g_key_file_set_string_list (keyfile, + HCP_STATE_GROUP, + HCP_STATE_FOCUSED, + (const gchar**) priv->running_apps, + (gsize) length); + + g_free (priv->running_apps); + +/* ====== Save scroll value ... ====== */ g_key_file_set_integer (keyfile, HCP_STATE_GROUP, HCP_STATE_SCROLL_VALUE, priv->scroll_value); - g_key_file_set_boolean (keyfile, - HCP_STATE_GROUP, - HCP_STATE_EXECUTE, - program->execute); - state.state_data = g_key_file_to_data (keyfile, &state.state_size, &error); @@ -294,12 +294,11 @@ g_warning ("An error occured when writing application state"); } - /* If a plugin is running, save its state */ - if (program->execute && priv->focused_item && - hcp_app_is_running (priv->focused_item)) - { - hcp_app_save_state (priv->focused_item); - } + /* If some plugins are running, save their state */ + if (program->running_applets) + g_list_foreach (program->running_applets, + (GFunc) hcp_app_save_state, + NULL); cleanup: if (error) @@ -315,6 +314,19 @@ g_key_file_free (keyfile); } +static void +save_state_now (int signal) +{ + if (signal == 15) + { + HCPProgram *program = hcp_program_get_instance (); + hcp_window_save_state (HCP_WINDOW (program->window), FALSE); + + /* Immediatly exit ... */ + exit (0); + } +} + /* Retrieve the configuration (large/small icons) */ static void hcp_window_retrieve_configuration (HCPWindow *window) @@ -391,34 +403,6 @@ #endif static void -hcp_window_topmost_status_change (GObject *gobject, - GParamSpec *arg1, - HCPWindow *window) -{ - HCPWindowPrivate *priv; - HildonProgram *program = HILDON_PROGRAM (gobject); - - g_return_if_fail (window); - g_return_if_fail (HCP_IS_WINDOW (window)); - - priv = window->priv; - - if (hildon_program_get_is_topmost (program)) { - hildon_program_set_can_hibernate (program, FALSE); - } else { - /* Do not set ourselves as background killable if we are - * running an applet which doesn't implement state-saving */ - if (!priv->focused_item || - (!hcp_app_is_running (priv->focused_item) || - hcp_app_can_save_state (priv->focused_item))) - { - hcp_window_save_state (window, FALSE); - hildon_program_set_can_hibernate (program, TRUE); - } - } -} - -static void hcp_window_app_view_focus_cb (HCPAppView *view, HCPApp *app, HCPWindow *window) @@ -481,18 +465,15 @@ hcp_window_enforce_state (window); } +/* Normal quit ... */ static void hcp_window_quit (GtkWidget *widget, HCPWindow *window) { g_return_if_fail (window); g_return_if_fail (HCP_IS_WINDOW (window)); - /* we can only close the window, when no applets are running */ - /**@TODO review this */ - HCPProgram *program = hcp_program_get_instance (); - program->execute = 0; + /* Clear the previously save state */ + hcp_window_save_state (window, TRUE); - hcp_window_save_state (window, FALSE); - gtk_widget_destroy (GTK_WIDGET (window)); gtk_main_quit (); @@ -542,8 +523,8 @@ g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (hcp_window_quit), window); - g_signal_connect(G_OBJECT (program), "notify::is-topmost", - G_CALLBACK (hcp_window_topmost_status_change), window); + g_signal_connect_after (G_OBJECT (window), "show", + G_CALLBACK (hcp_window_showed), window); menu = HILDON_APP_MENU (hildon_app_menu_new ()); @@ -553,9 +534,9 @@ /* Reset Factory Settings */ mi = hildon_button_new_with_text (HILDON_SIZE_AUTO_WIDTH | - HILDON_SIZE_FINGER_HEIGHT, - HILDON_BUTTON_ARRANGEMENT_VERTICAL, - HCP_MENU_RFS, NULL); + HILDON_SIZE_FINGER_HEIGHT, + HILDON_BUTTON_ARRANGEMENT_VERTICAL, + HCP_MENU_RFS, NULL); hildon_helper_set_logical_font (mi, "SmallSystemFont"); hildon_app_menu_append (menu, GTK_BUTTON(mi)); @@ -599,6 +580,9 @@ HILDON_PANNABLE_AREA (scrolled_window), align); + /* hildon-desktop will send SIGTERM (15) signal on bgkilling */ + signal (15, save_state_now); + hildon_program_set_can_hibernate (program, TRUE); } static void @@ -612,7 +596,6 @@ priv = window->priv; priv->focused_item = NULL; - priv->saved_focused_filename = NULL; priv->scroll_value = 0; priv->al = g_object_ref (program->al); @@ -655,49 +638,16 @@ priv->focused_item = NULL; } - if (priv->saved_focused_filename) - { - g_free (priv->saved_focused_filename); - priv->saved_focused_filename = NULL; - } - G_OBJECT_CLASS (hcp_window_parent_class)->finalize (object); } static void -hcp_window_size_allocate (GtkWidget *widget, GtkAllocation *allocation) -{ -/* Buggy applets can crash controlpanel, so disabled for now */ - static gboolean enforce_state = FALSE; - - GTK_WIDGET_CLASS (hcp_window_parent_class)->size_allocate (widget, allocation); - - if (enforce_state) - { - HCPProgram *program = hcp_program_get_instance (); - HCPWindow *window = HCP_WINDOW (widget); - - hcp_window_enforce_state (HCP_WINDOW (widget)); - - if (program->execute == 1 && window->priv->focused_item) - { - program->execute = 0; - hcp_app_launch (window->priv->focused_item, FALSE); - } - enforce_state = FALSE; - } -} - -static void hcp_window_class_init (HCPWindowClass *class) { GObjectClass *g_object_class = (GObjectClass *) class; - GtkWidgetClass *widget_class = (GtkWidgetClass *) class; g_object_class->finalize = hcp_window_finalize; - widget_class->size_allocate = hcp_window_size_allocate; - g_type_class_add_private (g_object_class, sizeof (HCPWindowPrivate)); }
- Previous message: [maemo-commits] r19039 - projects/haf/tags/gtk+
- Next message: [maemo-commits] r19041 - in projects/haf/trunk/libosso: debian src
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]