2007-07-11 Murray Cumming <murrayc@murrayc.com>
authorMurray Cumming <murrayc@murrayc.com>
Wed, 11 Jul 2007 11:50:59 +0000 (11:50 +0000)
committerMurray Cumming <murrayc@murrayc.com>
Wed, 11 Jul 2007 11:50:59 +0000 (11:50 +0000)
* src/dbus_api/modest-dbus-api.h: Added a define for a
top-application D-Bus method.
* src/dbus_api/modest-dbus-callbacks.c:
(on_top_application),
(modest_dbus_req_handler): Handle the top-application D-Bus
method, which might be an undocumented D-Bus signal sent by
hildon-desktop when it starts the application from the menu.
But I am not sure and I need to test it on the device, because
my scratchbox does not have the application in the menu now.
This method shows the main window, so that it can be invisible
when started, for instance, just for email searching from
osso-global-search.

* src/maemo/modest-main-window.c: (restore_settings),
(modest_main_window_new): Do not show the window immediately
upon creation. We show it later.
* src/modest-widget-memory.c: (save_settings_paned):
Try (unsuccessfully) to avoid saving the paned position when
it is not even visible.
(restore_settings_paned): Do not allow a silly paned position.
This seems necessary when not showing the window at first.

* tests/dbus_api/Makefile.am:
* tests/dbus_api/test_top_application.c: (main): Test for the
new D-Bus method.

pmo-trunk-r2694

ChangeLog
ChangeLog2
src/dbus_api/modest-dbus-api.h
src/dbus_api/modest-dbus-callbacks.c
src/maemo/modest-main-window.c
src/modest-main.c
src/modest-widget-memory.c
tests/dbus_api/Makefile.am
tests/dbus_api/test_top_application.c [new file with mode: 0644]

index acb6b92..48f7a59 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1 +1 @@
-* please check the svn log instead
+ please check the svn log instead
index 2d72bf6..37d4726 100644 (file)
@@ -1,3 +1,31 @@
+2007-07-11  Murray Cumming  <murrayc@murrayc.com>
+
+       * src/dbus_api/modest-dbus-api.h: Added a define for a 
+       top-application D-Bus method.
+       * src/dbus_api/modest-dbus-callbacks.c: 
+       (on_top_application),
+       (modest_dbus_req_handler): Handle the top-application D-Bus 
+       method, which might be an undocumented D-Bus signal sent by 
+       hildon-desktop when it starts the application from the menu.
+       But I am not sure and I need to test it on the device, because 
+       my scratchbox does not have the application in the menu now.
+       This method shows the main window, so that it can be invisible 
+       when started, for instance, just for email searching from 
+       osso-global-search.
+
+       * src/maemo/modest-main-window.c: (restore_settings),
+       (modest_main_window_new): Do not show the window immediately 
+       upon creation. We show it later.
+       * src/modest-widget-memory.c: (save_settings_paned):
+       Try (unsuccessfully) to avoid saving the paned position when 
+       it is not even visible. 
+       (restore_settings_paned): Do not allow a silly paned position.
+       This seems necessary when not showing the window at first.
+
+       * tests/dbus_api/Makefile.am:
+       * tests/dbus_api/test_top_application.c: (main): Test for the 
+       new D-Bus method.
+
 2007-07-10  Murray Cumming  <murrayc@murrayc.com>
 
        * src/modest-ui-dimming-rules.c:
index 278ba39..3acab78 100644 (file)
 #define MODEST_DBUS_METHOD_MAIL_TO "MailTo"
 enum ModestDbusMailToArguments
 {
-       MODEST_DEBUS_MAIL_TO_ARG_URI,
-       MODEST_DEBUS_MAIL_TO_ARGS_COUNT
+       MODEST_DBUS_MAIL_TO_ARG_URI,
+       MODEST_DBUS_MAIL_TO_ARGS_COUNT
 };
 
 #define MODEST_DBUS_METHOD_OPEN_MESSAGE "OpenMessage"
 enum ModestDbusOpenMessageArguments
 {
-       MODEST_DEBUS_OPEN_MESSAGE_ARG_URI,
-       MODEST_DEBUS_OPEN_MESSAGE_ARGS_COUNT
+       MODEST_DBUS_OPEN_MESSAGE_ARG_URI,
+       MODEST_DBUS_OPEN_MESSAGE_ARGS_COUNT
 };
 
 #define MODEST_DBUS_METHOD_SEND_RECEIVE "SendReceive"
@@ -60,20 +60,20 @@ enum ModestDbusOpenMessageArguments
 #define MODEST_DBUS_METHOD_COMPOSE_MAIL "ComposeMail"
 enum ModestDbusComposeMailArguments
 {
-       MODEST_DEBUS_COMPOSE_MAIL_ARG_TO,
-       MODEST_DEBUS_COMPOSE_MAIL_ARG_CC,
-       MODEST_DEBUS_COMPOSE_MAIL_ARG_BCC,
-       MODEST_DEBUS_COMPOSE_MAIL_ARG_SUBJECT,
-       MODEST_DEBUS_COMPOSE_MAIL_ARG_BODY,
-       MODEST_DEBUS_COMPOSE_MAIL_ARG_ATTACHMENTS,
-       MODEST_DEBUS_COMPOSE_MAIL_ARGS_COUNT
+       MODEST_DBUS_COMPOSE_MAIL_ARG_TO,
+       MODEST_DBUS_COMPOSE_MAIL_ARG_CC,
+       MODEST_DBUS_COMPOSE_MAIL_ARG_BCC,
+       MODEST_DBUS_COMPOSE_MAIL_ARG_SUBJECT,
+       MODEST_DBUS_COMPOSE_MAIL_ARG_BODY,
+       MODEST_DBUS_COMPOSE_MAIL_ARG_ATTACHMENTS,
+       MODEST_DBUS_COMPOSE_MAIL_ARGS_COUNT
 };
 
 #define MODEST_DBUS_METHOD_DELETE_MESSAGE "DeleteMessage"
 enum ModestDbusDeleteMessageArguments
 {
-       MODEST_DEBUS_DELETE_MESSAGE_ARG_URI,
-       MODEST_DEBUS_DELETE_MESSAGE_ARGS_COUNT
+       MODEST_DBUS_DELETE_MESSAGE_ARG_URI,
+       MODEST_DBUS_DELETE_MESSAGE_ARGS_COUNT
 };
 
 #define MODEST_DBUS_METHOD_OPEN_DEFAULT_INBOX "OpenDefaultInbox"
@@ -82,5 +82,12 @@ enum ModestDbusDeleteMessageArguments
 #define MODEST_DBUS_METHOD_SEARCH "Search"
 #define MODEST_DBUS_METHOD_GET_FOLDERS "GetFolders"
 
+/** This is an undocumented hildon-desktop method that is 
+ * sent to applications when they are started from the menu,
+ * but not when started from D-Bus activation, so that 
+ * applications can be started without visible UI.
+ * At least, I think so. murrayc.
+ **/
+#define MODEST_DBUS_METHOD_TOP_APPLICATION "top_application"
 
 #endif /* __MODEST_DBUS_API__ */
index 683c60f..ff8c9de 100644 (file)
@@ -293,13 +293,13 @@ on_idle_mail_to(gpointer user_data)
 
 static gint on_mail_to(GArray * arguments, gpointer data, osso_rpc_t * retval)
 {
-       if (arguments->len != MODEST_DEBUS_MAIL_TO_ARGS_COUNT)
+       if (arguments->len != MODEST_DBUS_MAIL_TO_ARGS_COUNT)
        return OSSO_ERROR;
        
     /* Use g_idle to context-switch into the application's thread: */
  
     /* Get the arguments: */
-       osso_rpc_t val = g_array_index(arguments, osso_rpc_t, MODEST_DEBUS_MAIL_TO_ARG_URI);
+       osso_rpc_t val = g_array_index(arguments, osso_rpc_t, MODEST_DBUS_MAIL_TO_ARG_URI);
        gchar *uri = g_strdup (val.value.s);
        
        /* printf("  debug: to=%s\n", idle_data->to); */
@@ -412,29 +412,29 @@ on_idle_compose_mail(gpointer user_data)
 
 static gint on_compose_mail(GArray * arguments, gpointer data, osso_rpc_t * retval)
 {
-       if (arguments->len != MODEST_DEBUS_COMPOSE_MAIL_ARGS_COUNT)
+       if (arguments->len != MODEST_DBUS_COMPOSE_MAIL_ARGS_COUNT)
        return OSSO_ERROR;
        
        /* Use g_idle to context-switch into the application's thread: */
        ComposeMailIdleData *idle_data = g_new0(ComposeMailIdleData, 1); /* Freed in the idle callback. */
        
        /* Get the arguments: */
-       osso_rpc_t val = g_array_index(arguments, osso_rpc_t, MODEST_DEBUS_COMPOSE_MAIL_ARG_TO);
+       osso_rpc_t val = g_array_index(arguments, osso_rpc_t, MODEST_DBUS_COMPOSE_MAIL_ARG_TO);
        idle_data->to = g_strdup (val.value.s);
        
-       val = g_array_index(arguments, osso_rpc_t, MODEST_DEBUS_COMPOSE_MAIL_ARG_CC);
+       val = g_array_index(arguments, osso_rpc_t, MODEST_DBUS_COMPOSE_MAIL_ARG_CC);
        idle_data->cc = g_strdup (val.value.s);
        
-       val = g_array_index(arguments, osso_rpc_t, MODEST_DEBUS_COMPOSE_MAIL_ARG_BCC);
+       val = g_array_index(arguments, osso_rpc_t, MODEST_DBUS_COMPOSE_MAIL_ARG_BCC);
        idle_data->bcc = g_strdup (val.value.s);
        
-       val = g_array_index(arguments, osso_rpc_t, MODEST_DEBUS_COMPOSE_MAIL_ARG_SUBJECT);
+       val = g_array_index(arguments, osso_rpc_t, MODEST_DBUS_COMPOSE_MAIL_ARG_SUBJECT);
        idle_data->subject = g_strdup (val.value.s);
        
-       val = g_array_index(arguments, osso_rpc_t, MODEST_DEBUS_COMPOSE_MAIL_ARG_BODY);
+       val = g_array_index(arguments, osso_rpc_t, MODEST_DBUS_COMPOSE_MAIL_ARG_BODY);
        idle_data->body = g_strdup (val.value.s);
        
-       val = g_array_index(arguments, osso_rpc_t, MODEST_DEBUS_COMPOSE_MAIL_ARG_ATTACHMENTS);
+       val = g_array_index(arguments, osso_rpc_t, MODEST_DBUS_COMPOSE_MAIL_ARG_ATTACHMENTS);
        idle_data->attachments = g_strdup (val.value.s);
 
        g_idle_add(on_idle_compose_mail, (gpointer)idle_data);
@@ -579,13 +579,13 @@ on_idle_open_message (gpointer user_data)
 
 static gint on_open_message(GArray * arguments, gpointer data, osso_rpc_t * retval)
 {
-       if (arguments->len != MODEST_DEBUS_OPEN_MESSAGE_ARGS_COUNT)
+       if (arguments->len != MODEST_DBUS_OPEN_MESSAGE_ARGS_COUNT)
        return OSSO_ERROR;
        
     /* Use g_idle to context-switch into the application's thread: */
 
     /* Get the arguments: */
-       osso_rpc_t val = g_array_index(arguments, osso_rpc_t, MODEST_DEBUS_OPEN_MESSAGE_ARG_URI);
+       osso_rpc_t val = g_array_index(arguments, osso_rpc_t, MODEST_DBUS_OPEN_MESSAGE_ARG_URI);
        gchar *uri = g_strdup (val.value.s);
        
        /* printf("  debug: to=%s\n", idle_data->to); */
@@ -613,13 +613,13 @@ on_delete_message (GArray *arguments, gpointer data, osso_rpc_t *retval)
        const char   *uid;
        gint          res;
 
-       if (arguments->len != MODEST_DEBUS_DELETE_MESSAGE_ARGS_COUNT) {
+       if (arguments->len != MODEST_DBUS_DELETE_MESSAGE_ARGS_COUNT) {
                return OSSO_ERROR;
        }
 
        val = g_array_index (arguments,
                             osso_rpc_t,
-                            MODEST_DEBUS_DELETE_MESSAGE_ARG_URI);
+                            MODEST_DBUS_DELETE_MESSAGE_ARG_URI);
 
        uri = (const char *) val.value.s;
 
@@ -759,6 +759,36 @@ static gint on_open_default_inbox(GArray * arguments, gpointer data, osso_rpc_t
         * because that would be asynchronous. */
        return OSSO_OK;
 }
+
+
+static gboolean on_idle_top_application (gpointer user_data)
+{
+       gdk_threads_enter ();
+
+       ModestWindow *win = 
+               modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
+       if (win) {
+               /* Ideally, we would just use gtk_widget_show(), 
+                * but this widget is not coded correctly to support that: */
+               gtk_widget_show_all (GTK_WIDGET (win));
+               gtk_window_present (GTK_WINDOW (win));
+       }
+
+       gdk_threads_leave ();
+       
+       return FALSE; /* Do not call this callback again. */
+}
+
+static gint on_top_application(GArray * arguments, gpointer data, osso_rpc_t * retval)
+{
+    /* Use g_idle to context-switch into the application's thread: */
+
+    /* This method has no arguments. */
+       
+       g_idle_add(on_idle_top_application, NULL);
+       
+       return OSSO_OK;
+}
                       
 /* Callback for normal D-BUS messages */
 gint modest_dbus_req_handler(const gchar * interface, const gchar * method,
@@ -766,23 +796,27 @@ gint modest_dbus_req_handler(const gchar * interface, const gchar * method,
                       osso_rpc_t * retval)
 {
        
-       g_debug ("debug: %s\n", __FUNCTION__);
+       /* g_debug ("debug: %s\n", __FUNCTION__); */
        g_debug ("debug: %s: method received: %s\n", __FUNCTION__, method);
        
-       if (g_ascii_strcasecmp(method, MODEST_DBUS_METHOD_MAIL_TO) == 0) {
+       if (g_ascii_strcasecmp (method, MODEST_DBUS_METHOD_MAIL_TO) == 0) {
                return on_mail_to (arguments, data, retval);
-       } else if (g_ascii_strcasecmp(method, MODEST_DBUS_METHOD_OPEN_MESSAGE) == 0) {
+       } else if (g_ascii_strcasecmp (method, MODEST_DBUS_METHOD_OPEN_MESSAGE) == 0) {
                return on_open_message (arguments, data, retval);
-       } else if (g_ascii_strcasecmp(method, MODEST_DBUS_METHOD_SEND_RECEIVE) == 0) {
+       } else if (g_ascii_strcasecmp (method, MODEST_DBUS_METHOD_SEND_RECEIVE) == 0) {
                return on_send_receive (arguments, data, retval);
-       } else if (g_ascii_strcasecmp(method, MODEST_DBUS_METHOD_COMPOSE_MAIL) == 0) {
+       } else if (g_ascii_strcasecmp (method, MODEST_DBUS_METHOD_COMPOSE_MAIL) == 0) {
                return on_compose_mail (arguments, data, retval);
-       } else if (g_ascii_strcasecmp(method, MODEST_DBUS_METHOD_DELETE_MESSAGE) == 0) {
+       } else if (g_ascii_strcasecmp (method, MODEST_DBUS_METHOD_DELETE_MESSAGE) == 0) {
                return on_delete_message (arguments,data, retval);
-       } else if (g_ascii_strcasecmp(method, MODEST_DBUS_METHOD_OPEN_DEFAULT_INBOX) == 0) {
+       } else if (g_ascii_strcasecmp (method, MODEST_DBUS_METHOD_OPEN_DEFAULT_INBOX) == 0) {
                return on_open_default_inbox (arguments, data, retval);
+       } else if (g_ascii_strcasecmp (method, MODEST_DBUS_METHOD_TOP_APPLICATION) == 0) {
+               return on_top_application (arguments, data, retval);
        }
        else { 
+               g_debug ("  debug: %s: Unexpected D-Bus method: %s\n", __FUNCTION__, method);
+       
                /* We need to return INVALID here so
                 * libosso will return DBUS_HANDLER_RESULT_NOT_YET_HANDLED,
                 * so that our modest_dbus_req_filter will then be tried instead.
index 459df2b..8f14915 100644 (file)
@@ -385,6 +385,8 @@ modest_main_window_get_child_widget (ModestMainWindow *self,
 static void
 restore_settings (ModestMainWindow *self, gboolean do_folder_view_too)
 {
+       printf ("DEBUGDEBUG: %s\n", __FUNCTION__);
+       
        ModestConf *conf;
        ModestMainWindowPrivate *priv;
 
@@ -896,6 +898,7 @@ modest_main_window_new (void)
        gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
                                      modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR_FULLSCREEN, NULL));
        hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
+       gtk_widget_show (parent_priv->menubar);
 
        /* Get device name */
        modest_maemo_utils_get_device_name ();
@@ -913,9 +916,11 @@ modest_main_window_new (void)
        g_object_set (G_OBJECT (priv->header_view), 
                      "rules-hint", FALSE,
                      NULL);
+       /* gtk_widget_show (priv->header_view); */
 
        /* Empty view */ 
        priv->empty_view = create_empty_view ();
+       gtk_widget_show (priv->empty_view);
                 
        /* Create scrolled windows */
        folder_win = gtk_scrolled_window_new (NULL, NULL);
@@ -926,6 +931,7 @@ modest_main_window_new (void)
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
                                        GTK_POLICY_NEVER,
                                        GTK_POLICY_AUTOMATIC);
+       /* gtk_widget_show (priv->contents_widget); */
 
        /* paned */
        priv->main_paned = gtk_hpaned_new ();
@@ -936,7 +942,8 @@ modest_main_window_new (void)
        /* putting it all together... */
        priv->main_vbox = gtk_vbox_new (FALSE, 6);
        gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
-
+       gtk_widget_show (priv->main_vbox);
+       
        gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
        
        HildonProgram *app = hildon_program_get_instance ();
@@ -955,7 +962,12 @@ modest_main_window_new (void)
                g_object_unref (window_icon);
        }
 
-       restore_settings (MODEST_MAIN_WINDOW(self), FALSE);
+       /* Dont't restore settings here, 
+        * because it requires a gtk_widget_show(), 
+        * and we don't want to do that until later,
+        * so that the UI is not visible for non-menu D-Bus activation.
+        */
+       /* restore_settings (MODEST_MAIN_WINDOW(self), FALSE); */
 
        return MODEST_WINDOW(self);
 }
index edf74b3..4adca14 100644 (file)
@@ -60,6 +60,14 @@ main (int argc, char *argv[])
        }
 
        win = modest_main_window_new ();
+
+       /* TODO: Do not show this now. 
+        * Only show it when we get the "top_application" D-Bus method.
+        * This allows modest to start via D-Bus activation to provide a service, 
+        * without showing the UI.
+        * The UI will be shown later (or just after starting if no otehr D-Bus method was used),
+        * when we receive the "top_application" D-Bus method.
+        */
        gtk_widget_show_all (GTK_WIDGET(win));
                
        if (!win) {
index 94c3b1b..59085d6 100644 (file)
@@ -221,11 +221,15 @@ save_settings_paned (ModestConf *conf, GtkPaned *paned, const gchar *name)
        gchar *key;
        int pos;
 
-       pos = gtk_paned_get_position (paned);
-       
-       key = _modest_widget_memory_get_keyname (name, MODEST_WIDGET_MEMORY_PARAM_POS);
-       modest_conf_set_int (conf, key, pos, NULL);
-       g_free (key);
+       /* Don't save the paned position if it's not visible, 
+        * because it could not be correct: */
+       if (GTK_WIDGET_VISIBLE (GTK_WIDGET (paned)) && GTK_WIDGET_REALIZED (GTK_WIDGET (paned))) {
+               pos = gtk_paned_get_position (paned);
+               
+               key = _modest_widget_memory_get_keyname (name, MODEST_WIDGET_MEMORY_PARAM_POS);
+               modest_conf_set_int (conf, key, pos, NULL);
+               g_free (key);
+       }
        
        return TRUE;
 }
@@ -241,6 +245,16 @@ restore_settings_paned (ModestConf *conf, GtkPaned *paned, const gchar *name)
        
        if (modest_conf_key_exists (conf, key, NULL)) {
                pos = modest_conf_get_int (conf, key, NULL);
+               
+               /* TODO: Remove this hack so that paned positions can really be used.
+                * The paned position is incorrectly saved somehow before its even visible,
+                * when we show the main window only some time after creating it,
+                * so this prevents a wrong value from being used. */
+               const gint max = (GTK_WIDGET(paned)->requisition.width)/3;
+               if (pos > max)
+                       pos = max;
+               
+                       
                gtk_paned_set_position (paned, pos);
        } else {
                /* The initial position must follow the 30/70 rule */
index 3c135d0..110f24c 100644 (file)
@@ -25,7 +25,8 @@ noinst_PROGRAMS = test_mail_to \
                  test_delete_message \
                  test_compose_mail \
                  test_open_default_inbox \
-                 test_get_folders
+                 test_get_folders \
+                 test_top_application
 
 test_mail_to_SOURCES = test_mail_to.c
 test_mail_to_LDADD = $(objects)
@@ -47,3 +48,6 @@ test_open_default_inbox_LDADD = $(objects)
 
 test_get_folders_SOURCES = test_get_folders.c
 test_get_folders_LDADD = $(objects)
+
+test_top_application_SOURCES = test_top_application.c
+test_top_application_LDADD = $(objects)
diff --git a/tests/dbus_api/test_top_application.c b/tests/dbus_api/test_top_application.c
new file mode 100644 (file)
index 0000000..7db8cc0
--- /dev/null
@@ -0,0 +1,37 @@
+#include <src/dbus_api/modest-dbus-api.h>
+#include <libosso.h>
+#include <stdio.h>
+
+int
+main (int argc, char *argv[])
+{
+       
+       osso_context_t * osso_context = osso_initialize ("test_open_default_inbox",
+                                       "0.0.1",
+                                       TRUE,
+                                       NULL);
+              
+       if (osso_context == NULL) {
+               g_printerr ("osso_initialize() failed.\n");
+           return -1;
+       }
+
+       osso_rpc_t retval;
+       const osso_return_t ret = osso_rpc_run_with_defaults(osso_context, 
+                  MODEST_DBUS_NAME, 
+                  MODEST_DBUS_METHOD_TOP_APPLICATION, &retval, 
+                  DBUS_TYPE_INVALID);
+               
+       if (ret != OSSO_OK) {
+               printf("debug: %s: osso_rpc_run() failed.\n", __FUNCTION__);
+               return FALSE;
+       } else {
+               printf("debug: %s: osso_rpc_run() succeeded.\n", __FUNCTION__);
+       }
+       
+       osso_rpc_free_val(&retval);
+       
+       return TRUE;
+               
+       return ret ? 0 : -1;
+}