diff options
author | Darin Adler <darin@src.gnome.org> | 2001-01-26 18:56:57 +0000 |
---|---|---|
committer | Darin Adler <darin@src.gnome.org> | 2001-01-26 18:56:57 +0000 |
commit | 2717a5cdd36e86d5c90ecd56ebecc4f9d79dbdbb (patch) | |
tree | 05cd09009acc3f686478362f84141ab7255698b2 | |
parent | 3d2e30943a3b12856e50754f912dc5a44eb79463 (diff) | |
download | nautilus-2717a5cdd36e86d5c90ecd56ebecc4f9d79dbdbb.tar.gz |
reviewed by: John Sullivan <sullivan@eazel.com>
Some preparation work for doing async. activation. This amounts
to another pass cleaning up the legendary "state machine" as well
as some other cleanups in the async. activation code.
* libnautilus-extensions/nautilus-bonobo-extensions.h:
* libnautilus-extensions/nautilus-bonobo-extensions.c:
(oaf_activation_callback), (nautilus_bonobo_activate_from_id),
(nautilus_bonobo_activate_cancel): Fix interface of activation to
be cleaner. Also handle case where callback is called right away.
Add queuing to NautilusView so that all incoming CORBA calls are
dispatched at idle time. This can fix some otherwise-difficult
re-entrancy problems. The widget destroy call can still come in at
any time though. Also this same fix may be needed for the
NautilusViewFrame side.
* libnautilus/nautilus-view.h:
* libnautilus/nautilus-view.c: (execute_queued_calls): Function
to dequeue and execute calls.
(dequeue_calls_at_idle): Cover to call it at idle time.
(discard_queued_calls): Discard calls without executing them, for
use at destroy time.
(queue_incoming_call): Simple cover to queue and schedule an
idle-time dequeue pass.
(nautilus_g_list_from_uri_list): Need to make a full copy, not
a shallow copy, now that we are queuing things for a hile.
(call_load_location), (call_stop_loading),
(call_selection_changed), (call_title_changed),
(call_history_changed): Simple functions that get queued.
(list_deep_free_cover): GDestroyNotify-compatible function for one
destroy case.
(history_dup): Function to copy the history list, since that is
now queued instead of used right away.
(impl_Nautilus_View_load_location),
(impl_Nautilus_View_stop_loading),
(impl_Nautilus_View_selection_changed),
(impl_Nautilus_View_title_changed),
(impl_Nautilus_View_history_changed): Change these all to queue
the incoming call instead of doing work right away.
(nautilus_view_destroy): Discard the queue.
* src/nautilus-view-frame-corba.c:
(impl_Nautilus_ViewFrame_open_location_force_new_window),
(impl_Nautilus_ViewFrame_report_selection_change): These calls now
use the deep copy, since the shallow one is no longer available.
This is good since we probably will be doing queuing here later,
so we'll need the deep copy.
* src/nautilus-view-frame.h:
* src/nautilus-view-frame.c:
(nautilus_view_frame_initialize_class): Set up a map default signal
handler to activate the control. This is better than the old way,
where we had an explicit call to do it.
(nautilus_view_frame_destroy_client): Remove unused
CORBA_Environment.
(view_frame_activated): Remove unneeded ACTIVATING state. Also
send the client_loaded signal in here, so you can't "forget".
(view_frame_wait), (view_frame_underway),
(view_frame_wait_is_over), (view_frame_loaded),
(view_frame_failed): Remove unneeded ACTIVATING state.
(check_if_view_is_gone): Simplify logic and make sure to check the
value of the exception and not just the function result.
(attach_client): Fix CORBA_Exception that was allocated twice and
that could also be allocated and not freed in some cases.
(activation_callback), (nautilus_view_frame_load_client_async):
Better names, use new API, still not tested.
(nautilus_view_frame_load_client): Get rid of function result and
use unified interface for telling about success and failure so that
sync. and async. interfaces will be the same.
(nautilus_view_frame_stop): Renamed this single function, which
will soon stop either activation that's in process or loading
that's in process with a single call. For now it's just the same
as the old stop_loading call.
(nautilus_view_frame_map): New override to activate the control.
This replaces the old explicit activate call.
(send_history), (nautilus_view_frame_get_is_underway): Remove
unneeded ACTIVATING state.
* src/nautilus-window.h:
* src/nautilus-window-manage-views.c:
(location_has_really_changed): Assume that new_content_view is not
NULL. The old code was trying to be inappropriately "general".
(disconnect_destroy_unref_view): Remove now-unused function.
(load_content_view): Don't use a return value any more, since it's
important to set up new_content_view before any signals happen.
Get rid of code that handles failure right at the start, since
we now get all failures through the signal handler.
(handle_view_failure): Add FIXME comments. Minor refactoring.
(cancel_location_change): Eliminated now-uneeded views_shown and
view_bombed_out booleans.
(load_view_for_new_location): New load_content_view doesn't return
a value any more.
(update_state): Changed this to be a loop instead of returning a
boolean and always being called in a loop. Also simplified logic
so that views_shown and view_bombed_out aren't needed any more.
(nautilus_window_end_location_change_callback): Use update_state
directly instead of calling the old clunky change_state cover.
(nautilus_window_begin_location_change): Use update_state directly
instead of calling the old clunky change_state cover.
(stop_loading): Call the new simple nautilus_view_frame_stop
instead of nautilus_view_frame_stop_loading.
(natuilus_window_stop_loading): Use update_state directly instead
of calling the old clunky change_state cover.
(nautilus_window_set_content_view): Use update_state directly instead
of calling the old clunky change_state cover.
(nautilus_window_set_sidebar_panels): Handle failures with
callback instead of looking at return value (which no longer
exists).
(client_loaded_callback): Add this new callback that's done when
the view is activated and ready to go.
(failed_callback): Use update_state directly instead of calling
the old clunky change_state cover.
(load_underway_callback): Use update_state directly instead of
calling the old clunky change_state cover.
(load_complete_callback): Use update_state directly instead of
calling the old clunky change_state cover.
* src/nautilus-window.c:
(nautilus_window_set_content_view_widget): Get rid of explicit
activation, no longer needed now that NautilusViewFrame handles it
directly.
* test/test-nautilus-async-activation.c: (activation_callback),
(main): Change to use new async. API.
* user-guide/gnufdl/.cvsignore: Add to ignore some missing files.
-rw-r--r-- | ChangeLog | 131 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-bonobo-extensions.c | 127 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-bonobo-extensions.h | 123 | ||||
-rw-r--r-- | libnautilus-private/nautilus-bonobo-extensions.c | 127 | ||||
-rw-r--r-- | libnautilus-private/nautilus-bonobo-extensions.h | 123 | ||||
-rw-r--r-- | libnautilus/nautilus-view.c | 237 | ||||
-rw-r--r-- | libnautilus/nautilus-view.h | 2 | ||||
-rw-r--r-- | src/nautilus-navigation-window.c | 5 | ||||
-rw-r--r-- | src/nautilus-navigation-window.h | 2 | ||||
-rw-r--r-- | src/nautilus-object-window.c | 5 | ||||
-rw-r--r-- | src/nautilus-object-window.h | 2 | ||||
-rw-r--r-- | src/nautilus-spatial-window.c | 5 | ||||
-rw-r--r-- | src/nautilus-spatial-window.h | 2 | ||||
-rw-r--r-- | src/nautilus-view-frame-corba.c | 8 | ||||
-rw-r--r-- | src/nautilus-view-frame.c | 242 | ||||
-rw-r--r-- | src/nautilus-view-frame.h | 7 | ||||
-rw-r--r-- | src/nautilus-window-manage-views.c | 419 | ||||
-rw-r--r-- | src/nautilus-window.c | 5 | ||||
-rw-r--r-- | src/nautilus-window.h | 2 | ||||
-rw-r--r-- | test/test-nautilus-async-activation.c | 46 | ||||
-rw-r--r-- | user-guide/gnufdl/.cvsignore | 2 |
21 files changed, 839 insertions, 783 deletions
@@ -1,3 +1,134 @@ +2001-01-25 Darin Adler <darin@eazel.com> + + reviewed by: John Sullivan <sullivan@eazel.com> + + Some preparation work for doing async. activation. This amounts + to another pass cleaning up the legendary "state machine" as well + as some other cleanups in the async. activation code. + + * libnautilus-extensions/nautilus-bonobo-extensions.h: + * libnautilus-extensions/nautilus-bonobo-extensions.c: + (oaf_activation_callback), (nautilus_bonobo_activate_from_id), + (nautilus_bonobo_activate_cancel): Fix interface of activation to + be cleaner. Also handle case where callback is called right away. + + Add queuing to NautilusView so that all incoming CORBA calls are + dispatched at idle time. This can fix some otherwise-difficult + re-entrancy problems. The widget destroy call can still come in at + any time though. Also this same fix may be needed for the + NautilusViewFrame side. + + * libnautilus/nautilus-view.h: + * libnautilus/nautilus-view.c: (execute_queued_calls): Function + to dequeue and execute calls. + (dequeue_calls_at_idle): Cover to call it at idle time. + (discard_queued_calls): Discard calls without executing them, for + use at destroy time. + (queue_incoming_call): Simple cover to queue and schedule an + idle-time dequeue pass. + (nautilus_g_list_from_uri_list): Need to make a full copy, not + a shallow copy, now that we are queuing things for a hile. + (call_load_location), (call_stop_loading), + (call_selection_changed), (call_title_changed), + (call_history_changed): Simple functions that get queued. + (list_deep_free_cover): GDestroyNotify-compatible function for one + destroy case. + (history_dup): Function to copy the history list, since that is + now queued instead of used right away. + (impl_Nautilus_View_load_location), + (impl_Nautilus_View_stop_loading), + (impl_Nautilus_View_selection_changed), + (impl_Nautilus_View_title_changed), + (impl_Nautilus_View_history_changed): Change these all to queue + the incoming call instead of doing work right away. + (nautilus_view_destroy): Discard the queue. + + * src/nautilus-view-frame-corba.c: + (impl_Nautilus_ViewFrame_open_location_force_new_window), + (impl_Nautilus_ViewFrame_report_selection_change): These calls now + use the deep copy, since the shallow one is no longer available. + This is good since we probably will be doing queuing here later, + so we'll need the deep copy. + + * src/nautilus-view-frame.h: + * src/nautilus-view-frame.c: + (nautilus_view_frame_initialize_class): Set up a map default signal + handler to activate the control. This is better than the old way, + where we had an explicit call to do it. + (nautilus_view_frame_destroy_client): Remove unused + CORBA_Environment. + (view_frame_activated): Remove unneeded ACTIVATING state. Also + send the client_loaded signal in here, so you can't "forget". + (view_frame_wait), (view_frame_underway), + (view_frame_wait_is_over), (view_frame_loaded), + (view_frame_failed): Remove unneeded ACTIVATING state. + (check_if_view_is_gone): Simplify logic and make sure to check the + value of the exception and not just the function result. + (attach_client): Fix CORBA_Exception that was allocated twice and + that could also be allocated and not freed in some cases. + (activation_callback), (nautilus_view_frame_load_client_async): + Better names, use new API, still not tested. + (nautilus_view_frame_load_client): Get rid of function result and + use unified interface for telling about success and failure so that + sync. and async. interfaces will be the same. + (nautilus_view_frame_stop): Renamed this single function, which + will soon stop either activation that's in process or loading + that's in process with a single call. For now it's just the same + as the old stop_loading call. + (nautilus_view_frame_map): New override to activate the control. + This replaces the old explicit activate call. + (send_history), (nautilus_view_frame_get_is_underway): Remove + unneeded ACTIVATING state. + + * src/nautilus-window.h: + * src/nautilus-window-manage-views.c: + (location_has_really_changed): Assume that new_content_view is not + NULL. The old code was trying to be inappropriately "general". + (disconnect_destroy_unref_view): Remove now-unused function. + (load_content_view): Don't use a return value any more, since it's + important to set up new_content_view before any signals happen. + Get rid of code that handles failure right at the start, since + we now get all failures through the signal handler. + (handle_view_failure): Add FIXME comments. Minor refactoring. + (cancel_location_change): Eliminated now-uneeded views_shown and + view_bombed_out booleans. + (load_view_for_new_location): New load_content_view doesn't return + a value any more. + (update_state): Changed this to be a loop instead of returning a + boolean and always being called in a loop. Also simplified logic + so that views_shown and view_bombed_out aren't needed any more. + (nautilus_window_end_location_change_callback): Use update_state + directly instead of calling the old clunky change_state cover. + (nautilus_window_begin_location_change): Use update_state directly + instead of calling the old clunky change_state cover. + (stop_loading): Call the new simple nautilus_view_frame_stop + instead of nautilus_view_frame_stop_loading. + (natuilus_window_stop_loading): Use update_state directly instead + of calling the old clunky change_state cover. + (nautilus_window_set_content_view): Use update_state directly instead + of calling the old clunky change_state cover. + (nautilus_window_set_sidebar_panels): Handle failures with + callback instead of looking at return value (which no longer + exists). + (client_loaded_callback): Add this new callback that's done when + the view is activated and ready to go. + (failed_callback): Use update_state directly instead of calling + the old clunky change_state cover. + (load_underway_callback): Use update_state directly instead of + calling the old clunky change_state cover. + (load_complete_callback): Use update_state directly instead of + calling the old clunky change_state cover. + + * src/nautilus-window.c: + (nautilus_window_set_content_view_widget): Get rid of explicit + activation, no longer needed now that NautilusViewFrame handles it + directly. + + * test/test-nautilus-async-activation.c: (activation_callback), + (main): Change to use new async. API. + + * user-guide/gnufdl/.cvsignore: Add to ignore some missing files. + 2001-01-25 Maciej Stachowiak <mjs@eazel.com> * src/nautilus-window-manage-views.c diff --git a/libnautilus-extensions/nautilus-bonobo-extensions.c b/libnautilus-extensions/nautilus-bonobo-extensions.c index 4f580d6e7..8ff95b72a 100644 --- a/libnautilus-extensions/nautilus-bonobo-extensions.c +++ b/libnautilus-extensions/nautilus-bonobo-extensions.c @@ -26,13 +26,19 @@ #include <config.h> #include "nautilus-bonobo-extensions.h" -#include "nautilus-string.h" +#include "nautilus-string.h" #include <bonobo/bonobo-ui-util.h> #include <libgnomevfs/gnome-vfs-utils.h> - #include <liboaf/oaf-async.h> +struct NautilusBonoboActivationHandle { + NautilusBonoboActivationHandle **early_completion_hook; + NautilusBonoboActivationCallback callback; + gpointer callback_data; + gboolean cancel; +}; + void nautilus_bonobo_set_accelerator (BonoboUIComponent *ui, const char *path, @@ -423,44 +429,33 @@ nautilus_bonobo_set_icon (BonoboUIComponent *ui, "filename", NULL); } -struct _NautilusBonoboActivate { - NautilusBonoboActivateCallback activation_callback; - gpointer callback_data; - gboolean stop_activation; -}; - static void -oaf_activation_callback (CORBA_Object object_reference, +oaf_activation_callback (Bonobo_Unknown activated_object, const char *error_reason, - gpointer user_data) + gpointer callback_data) { - NautilusBonoboActivate *activate_struct; + NautilusBonoboActivationHandle *handle; CORBA_Environment ev; - activate_struct = (NautilusBonoboActivate *) user_data; - CORBA_exception_init (&ev); - - if (CORBA_Object_is_nil (object_reference, &ev)) { - /* error */ - activate_struct->activation_callback (CORBA_OBJECT_NIL, - activate_struct->callback_data); + handle = (NautilusBonoboActivationHandle *) callback_data; - } else if (!activate_struct->stop_activation) { - - /* report activation to caller */ - activate_struct->activation_callback (object_reference, - activate_struct->callback_data); - - } else if (activate_struct->stop_activation) { - activate_struct->stop_activation = FALSE; - - Bonobo_Unknown_unref (object_reference, &ev); - /* it is no use to check for exception here since we - have no way of reporting it... */ + if (handle->cancel) { + CORBA_exception_init (&ev); + Bonobo_Unknown_unref (activated_object, &ev); + CORBA_exception_free (&ev); + } else { + (* handle->callback) (handle, + activated_object, + handle->callback_data); } - CORBA_exception_free (&ev); -} + if (handle->early_completion_hook != NULL) { + g_assert (*handle->early_completion_hook == handle); + *handle->early_completion_hook = NULL; + } + + g_free (handle); +} /** * nautilus_bonobo_activate_from_id: @@ -469,67 +464,53 @@ oaf_activation_callback (CORBA_Object object_reference, * @user_data: data to pass to callback when activation finished. * * This function will return NULL if something bad happened during - * activation. Alternatively, it will return a structure you are - * supposed to free yourself when you have received a call in your - * callback. + * activation. */ -NautilusBonoboActivate * -nautilus_bonobo_activate_from_id (const char *iid, - NautilusBonoboActivateCallback callback, - gpointer user_data) +NautilusBonoboActivationHandle * +nautilus_bonobo_activate_from_id (const char *iid, + NautilusBonoboActivationCallback callback, + gpointer callback_data) { - NautilusBonoboActivate *activate_structure; - CORBA_Environment ev; + NautilusBonoboActivationHandle *handle; - if (iid == NULL || callback == NULL) { - return NULL; - } + g_return_val_if_fail (iid != NULL, NULL); + g_return_val_if_fail (callback != NULL, NULL); - activate_structure = g_new0 (NautilusBonoboActivate, 1); + handle = g_new0 (NautilusBonoboActivationHandle, 1); - activate_structure->stop_activation = FALSE; - activate_structure->activation_callback = callback; - activate_structure->callback_data = user_data; + handle->early_completion_hook = &handle; + handle->callback = callback; + handle->callback_data = callback_data; - CORBA_exception_init (&ev); - oaf_activate_from_id_async ((const OAF_ActivationID) iid, 0, oaf_activation_callback, - activate_structure , &ev); + oaf_activate_from_id_async ((char *) iid, 0, + oaf_activation_callback, + handle, NULL); - if (ev._major != CORBA_NO_EXCEPTION) { - return NULL; + if (handle != NULL) { + handle->early_completion_hook = NULL; } - CORBA_exception_free (&ev); - - return activate_structure; + return handle; } /** - * nautilus_bonobo_activate_from_id: + * nautilus_bonobo_activate_stop: * @iid: iid of component to activate. * @callback: callback to call when activation finished. * @user_data: data to pass to callback when activation finished. * * Stops activation of a component. Your callback will not be called * after this call. - * you should free your %NautilusBonoboActivate structure through - * nautilus_bonobo_activate_free after this call. */ void -nautilus_bonobo_activate_stop (NautilusBonoboActivate *activate_structure) +nautilus_bonobo_activate_cancel (NautilusBonoboActivationHandle *handle) { - activate_structure->stop_activation = TRUE; -} - -/** - * nautilus_bonobo_activate_free: - * @activate_structure: structure to free. - * - * Frees the corresponding structure. - */ -void -nautilus_bonobo_activate_free (NautilusBonoboActivate *activate_structure) -{ - g_free (activate_structure); + if (handle != NULL) { + handle->cancel = TRUE; + if (handle->early_completion_hook != NULL) { + g_assert (*handle->early_completion_hook == handle); + *handle->early_completion_hook = NULL; + } + } } diff --git a/libnautilus-extensions/nautilus-bonobo-extensions.h b/libnautilus-extensions/nautilus-bonobo-extensions.h index d380939dc..f013a6cd2 100644 --- a/libnautilus-extensions/nautilus-bonobo-extensions.h +++ b/libnautilus-extensions/nautilus-bonobo-extensions.h @@ -30,71 +30,66 @@ #include <bonobo/bonobo-ui-component.h> #include <gdk-pixbuf/gdk-pixbuf.h> -void nautilus_bonobo_set_accelerator (BonoboUIComponent *ui, - const char *path, - const char *accelerator); -char * nautilus_bonobo_get_label (BonoboUIComponent *ui, - const char *path); -void nautilus_bonobo_set_label (BonoboUIComponent *ui, - const char *path, - const char *label); -void nautilus_bonobo_set_tip (BonoboUIComponent *ui, - const char *path, - const char *tip); -void nautilus_bonobo_set_sensitive (BonoboUIComponent *ui, - const char *path, - gboolean sensitive); -void nautilus_bonobo_set_toggle_state (BonoboUIComponent *ui, - const char *path, - gboolean state); -void nautilus_bonobo_set_hidden (BonoboUIComponent *ui, - const char *path, - gboolean hidden); -gboolean nautilus_bonobo_get_hidden (BonoboUIComponent *ui, - const char *path); -void nautilus_bonobo_add_numbered_menu_item (BonoboUIComponent *ui, - const char *container_path, - guint index, - const char *label, - GdkPixbuf *pixbuf); -void nautilus_bonobo_add_numbered_toggle_menu_item (BonoboUIComponent *ui, - const char *container_path, - guint index, - const char *label); -char *nautilus_bonobo_get_numbered_menu_item_command - (BonoboUIComponent *ui, - const char *container_path, - guint index); -char *nautilus_bonobo_get_numbered_menu_item_path - (BonoboUIComponent *ui, - const char *container_path, - guint index); -void nautilus_bonobo_add_submenu (BonoboUIComponent *ui, - const char *container_path, - const char *label); -void nautilus_bonobo_add_menu_separator (BonoboUIComponent *ui, - const char *path); -void nautilus_bonobo_remove_menu_items_and_commands - (BonoboUIComponent *ui, - const char *container_path); -void nautilus_bonobo_set_label_for_menu_item_and_command - (BonoboUIComponent *ui, - const char *menu_item_path, - const char *command_path, - const char *label_with_underscore); -void nautilus_bonobo_set_icon (BonoboUIComponent *ui, - const char *path, - const char *icon_relative_path); +typedef struct NautilusBonoboActivationHandle NautilusBonoboActivationHandle; -typedef struct _NautilusBonoboActivate NautilusBonoboActivate; - -typedef void (*NautilusBonoboActivateCallback) (CORBA_Object object_reference, gpointer data); - -NautilusBonoboActivate *nautilus_bonobo_activate_from_id (const char *iid, - NautilusBonoboActivateCallback callback, - gpointer user_data); -void nautilus_bonobo_activate_stop (NautilusBonoboActivate *activate_structure); -void nautilus_bonobo_activate_free (NautilusBonoboActivate *activate_structure); +typedef void (*NautilusBonoboActivationCallback) (NautilusBonoboActivationHandle *handle, + Bonobo_Unknown activated_object, + gpointer callback_data); +void nautilus_bonobo_set_accelerator (BonoboUIComponent *ui, + const char *path, + const char *accelerator); +char * nautilus_bonobo_get_label (BonoboUIComponent *ui, + const char *path); +void nautilus_bonobo_set_label (BonoboUIComponent *ui, + const char *path, + const char *label); +void nautilus_bonobo_set_tip (BonoboUIComponent *ui, + const char *path, + const char *tip); +void nautilus_bonobo_set_sensitive (BonoboUIComponent *ui, + const char *path, + gboolean sensitive); +void nautilus_bonobo_set_toggle_state (BonoboUIComponent *ui, + const char *path, + gboolean state); +void nautilus_bonobo_set_hidden (BonoboUIComponent *ui, + const char *path, + gboolean hidden); +gboolean nautilus_bonobo_get_hidden (BonoboUIComponent *ui, + const char *path); +void nautilus_bonobo_add_numbered_menu_item (BonoboUIComponent *ui, + const char *container_path, + guint index, + const char *label, + GdkPixbuf *pixbuf); +void nautilus_bonobo_add_numbered_toggle_menu_item (BonoboUIComponent *ui, + const char *container_path, + guint index, + const char *label); +char * nautilus_bonobo_get_numbered_menu_item_command (BonoboUIComponent *ui, + const char *container_path, + guint index); +char * nautilus_bonobo_get_numbered_menu_item_path (BonoboUIComponent *ui, + const char *container_path, + guint index); +void nautilus_bonobo_add_submenu (BonoboUIComponent *ui, + const char *container_path, + const char *label); +void nautilus_bonobo_add_menu_separator (BonoboUIComponent *ui, + const char *path); +void nautilus_bonobo_remove_menu_items_and_commands (BonoboUIComponent *ui, + const char *container_path); +void nautilus_bonobo_set_label_for_menu_item_and_command (BonoboUIComponent *ui, + const char *menu_item_path, + const char *command_path, + const char *label_with_underscore); +void nautilus_bonobo_set_icon (BonoboUIComponent *ui, + const char *path, + const char *icon_relative_path); +NautilusBonoboActivationHandle *nautilus_bonobo_activate_from_id (const char *iid, + NautilusBonoboActivationCallback callback, + gpointer callback_data); +void nautilus_bonobo_activate_cancel (NautilusBonoboActivationHandle *handle); #endif /* NAUTILUS_BONOBO_EXTENSIONS_H */ diff --git a/libnautilus-private/nautilus-bonobo-extensions.c b/libnautilus-private/nautilus-bonobo-extensions.c index 4f580d6e7..8ff95b72a 100644 --- a/libnautilus-private/nautilus-bonobo-extensions.c +++ b/libnautilus-private/nautilus-bonobo-extensions.c @@ -26,13 +26,19 @@ #include <config.h> #include "nautilus-bonobo-extensions.h" -#include "nautilus-string.h" +#include "nautilus-string.h" #include <bonobo/bonobo-ui-util.h> #include <libgnomevfs/gnome-vfs-utils.h> - #include <liboaf/oaf-async.h> +struct NautilusBonoboActivationHandle { + NautilusBonoboActivationHandle **early_completion_hook; + NautilusBonoboActivationCallback callback; + gpointer callback_data; + gboolean cancel; +}; + void nautilus_bonobo_set_accelerator (BonoboUIComponent *ui, const char *path, @@ -423,44 +429,33 @@ nautilus_bonobo_set_icon (BonoboUIComponent *ui, "filename", NULL); } -struct _NautilusBonoboActivate { - NautilusBonoboActivateCallback activation_callback; - gpointer callback_data; - gboolean stop_activation; -}; - static void -oaf_activation_callback (CORBA_Object object_reference, +oaf_activation_callback (Bonobo_Unknown activated_object, const char *error_reason, - gpointer user_data) + gpointer callback_data) { - NautilusBonoboActivate *activate_struct; + NautilusBonoboActivationHandle *handle; CORBA_Environment ev; - activate_struct = (NautilusBonoboActivate *) user_data; - CORBA_exception_init (&ev); - - if (CORBA_Object_is_nil (object_reference, &ev)) { - /* error */ - activate_struct->activation_callback (CORBA_OBJECT_NIL, - activate_struct->callback_data); + handle = (NautilusBonoboActivationHandle *) callback_data; - } else if (!activate_struct->stop_activation) { - - /* report activation to caller */ - activate_struct->activation_callback (object_reference, - activate_struct->callback_data); - - } else if (activate_struct->stop_activation) { - activate_struct->stop_activation = FALSE; - - Bonobo_Unknown_unref (object_reference, &ev); - /* it is no use to check for exception here since we - have no way of reporting it... */ + if (handle->cancel) { + CORBA_exception_init (&ev); + Bonobo_Unknown_unref (activated_object, &ev); + CORBA_exception_free (&ev); + } else { + (* handle->callback) (handle, + activated_object, + handle->callback_data); } - CORBA_exception_free (&ev); -} + if (handle->early_completion_hook != NULL) { + g_assert (*handle->early_completion_hook == handle); + *handle->early_completion_hook = NULL; + } + + g_free (handle); +} /** * nautilus_bonobo_activate_from_id: @@ -469,67 +464,53 @@ oaf_activation_callback (CORBA_Object object_reference, * @user_data: data to pass to callback when activation finished. * * This function will return NULL if something bad happened during - * activation. Alternatively, it will return a structure you are - * supposed to free yourself when you have received a call in your - * callback. + * activation. */ -NautilusBonoboActivate * -nautilus_bonobo_activate_from_id (const char *iid, - NautilusBonoboActivateCallback callback, - gpointer user_data) +NautilusBonoboActivationHandle * +nautilus_bonobo_activate_from_id (const char *iid, + NautilusBonoboActivationCallback callback, + gpointer callback_data) { - NautilusBonoboActivate *activate_structure; - CORBA_Environment ev; + NautilusBonoboActivationHandle *handle; - if (iid == NULL || callback == NULL) { - return NULL; - } + g_return_val_if_fail (iid != NULL, NULL); + g_return_val_if_fail (callback != NULL, NULL); - activate_structure = g_new0 (NautilusBonoboActivate, 1); + handle = g_new0 (NautilusBonoboActivationHandle, 1); - activate_structure->stop_activation = FALSE; - activate_structure->activation_callback = callback; - activate_structure->callback_data = user_data; + handle->early_completion_hook = &handle; + handle->callback = callback; + handle->callback_data = callback_data; - CORBA_exception_init (&ev); - oaf_activate_from_id_async ((const OAF_ActivationID) iid, 0, oaf_activation_callback, - activate_structure , &ev); + oaf_activate_from_id_async ((char *) iid, 0, + oaf_activation_callback, + handle, NULL); - if (ev._major != CORBA_NO_EXCEPTION) { - return NULL; + if (handle != NULL) { + handle->early_completion_hook = NULL; } - CORBA_exception_free (&ev); - - return activate_structure; + return handle; } /** - * nautilus_bonobo_activate_from_id: + * nautilus_bonobo_activate_stop: * @iid: iid of component to activate. * @callback: callback to call when activation finished. * @user_data: data to pass to callback when activation finished. * * Stops activation of a component. Your callback will not be called * after this call. - * you should free your %NautilusBonoboActivate structure through - * nautilus_bonobo_activate_free after this call. */ void -nautilus_bonobo_activate_stop (NautilusBonoboActivate *activate_structure) +nautilus_bonobo_activate_cancel (NautilusBonoboActivationHandle *handle) { - activate_structure->stop_activation = TRUE; -} - -/** - * nautilus_bonobo_activate_free: - * @activate_structure: structure to free. - * - * Frees the corresponding structure. - */ -void -nautilus_bonobo_activate_free (NautilusBonoboActivate *activate_structure) -{ - g_free (activate_structure); + if (handle != NULL) { + handle->cancel = TRUE; + if (handle->early_completion_hook != NULL) { + g_assert (*handle->early_completion_hook == handle); + *handle->early_completion_hook = NULL; + } + } } diff --git a/libnautilus-private/nautilus-bonobo-extensions.h b/libnautilus-private/nautilus-bonobo-extensions.h index d380939dc..f013a6cd2 100644 --- a/libnautilus-private/nautilus-bonobo-extensions.h +++ b/libnautilus-private/nautilus-bonobo-extensions.h @@ -30,71 +30,66 @@ #include <bonobo/bonobo-ui-component.h> #include <gdk-pixbuf/gdk-pixbuf.h> -void nautilus_bonobo_set_accelerator (BonoboUIComponent *ui, - const char *path, - const char *accelerator); -char * nautilus_bonobo_get_label (BonoboUIComponent *ui, - const char *path); -void nautilus_bonobo_set_label (BonoboUIComponent *ui, - const char *path, - const char *label); -void nautilus_bonobo_set_tip (BonoboUIComponent *ui, - const char *path, - const char *tip); -void nautilus_bonobo_set_sensitive (BonoboUIComponent *ui, - const char *path, - gboolean sensitive); -void nautilus_bonobo_set_toggle_state (BonoboUIComponent *ui, - const char *path, - gboolean state); -void nautilus_bonobo_set_hidden (BonoboUIComponent *ui, - const char *path, - gboolean hidden); -gboolean nautilus_bonobo_get_hidden (BonoboUIComponent *ui, - const char *path); -void nautilus_bonobo_add_numbered_menu_item (BonoboUIComponent *ui, - const char *container_path, - guint index, - const char *label, - GdkPixbuf *pixbuf); -void nautilus_bonobo_add_numbered_toggle_menu_item (BonoboUIComponent *ui, - const char *container_path, - guint index, - const char *label); -char *nautilus_bonobo_get_numbered_menu_item_command - (BonoboUIComponent *ui, - const char *container_path, - guint index); -char *nautilus_bonobo_get_numbered_menu_item_path - (BonoboUIComponent *ui, - const char *container_path, - guint index); -void nautilus_bonobo_add_submenu (BonoboUIComponent *ui, - const char *container_path, - const char *label); -void nautilus_bonobo_add_menu_separator (BonoboUIComponent *ui, - const char *path); -void nautilus_bonobo_remove_menu_items_and_commands - (BonoboUIComponent *ui, - const char *container_path); -void nautilus_bonobo_set_label_for_menu_item_and_command - (BonoboUIComponent *ui, - const char *menu_item_path, - const char *command_path, - const char *label_with_underscore); -void nautilus_bonobo_set_icon (BonoboUIComponent *ui, - const char *path, - const char *icon_relative_path); +typedef struct NautilusBonoboActivationHandle NautilusBonoboActivationHandle; -typedef struct _NautilusBonoboActivate NautilusBonoboActivate; - -typedef void (*NautilusBonoboActivateCallback) (CORBA_Object object_reference, gpointer data); - -NautilusBonoboActivate *nautilus_bonobo_activate_from_id (const char *iid, - NautilusBonoboActivateCallback callback, - gpointer user_data); -void nautilus_bonobo_activate_stop (NautilusBonoboActivate *activate_structure); -void nautilus_bonobo_activate_free (NautilusBonoboActivate *activate_structure); +typedef void (*NautilusBonoboActivationCallback) (NautilusBonoboActivationHandle *handle, + Bonobo_Unknown activated_object, + gpointer callback_data); +void nautilus_bonobo_set_accelerator (BonoboUIComponent *ui, + const char *path, + const char *accelerator); +char * nautilus_bonobo_get_label (BonoboUIComponent *ui, + const char *path); +void nautilus_bonobo_set_label (BonoboUIComponent *ui, + const char *path, + const char *label); +void nautilus_bonobo_set_tip (BonoboUIComponent *ui, + const char *path, + const char *tip); +void nautilus_bonobo_set_sensitive (BonoboUIComponent *ui, + const char *path, + gboolean sensitive); +void nautilus_bonobo_set_toggle_state (BonoboUIComponent *ui, + const char *path, + gboolean state); +void nautilus_bonobo_set_hidden (BonoboUIComponent *ui, + const char *path, + gboolean hidden); +gboolean nautilus_bonobo_get_hidden (BonoboUIComponent *ui, + const char *path); +void nautilus_bonobo_add_numbered_menu_item (BonoboUIComponent *ui, + const char *container_path, + guint index, + const char *label, + GdkPixbuf *pixbuf); +void nautilus_bonobo_add_numbered_toggle_menu_item (BonoboUIComponent *ui, + const char *container_path, + guint index, + const char *label); +char * nautilus_bonobo_get_numbered_menu_item_command (BonoboUIComponent *ui, + const char *container_path, + guint index); +char * nautilus_bonobo_get_numbered_menu_item_path (BonoboUIComponent *ui, + const char *container_path, + guint index); +void nautilus_bonobo_add_submenu (BonoboUIComponent *ui, + const char *container_path, + const char *label); +void nautilus_bonobo_add_menu_separator (BonoboUIComponent *ui, + const char *path); +void nautilus_bonobo_remove_menu_items_and_commands (BonoboUIComponent *ui, + const char *container_path); +void nautilus_bonobo_set_label_for_menu_item_and_command (BonoboUIComponent *ui, + const char *menu_item_path, + const char *command_path, + const char *label_with_underscore); +void nautilus_bonobo_set_icon (BonoboUIComponent *ui, + const char *path, + const char *icon_relative_path); +NautilusBonoboActivationHandle *nautilus_bonobo_activate_from_id (const char *iid, + NautilusBonoboActivationCallback callback, + gpointer callback_data); +void nautilus_bonobo_activate_cancel (NautilusBonoboActivationHandle *handle); #endif /* NAUTILUS_BONOBO_EXTENSIONS_H */ diff --git a/libnautilus/nautilus-view.c b/libnautilus/nautilus-view.c index 7174badd2..3af307d62 100644 --- a/libnautilus/nautilus-view.c +++ b/libnautilus/nautilus-view.c @@ -4,7 +4,7 @@ * libnautilus: A library for nautilus view implementations. * * Copyright (C) 1999, 2000 Red Hat, Inc. - * Copyright (C) 2000 Eazel, Inc. + * Copyright (C) 2000, 2001 Eazel, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,6 +22,7 @@ * * Authors: Elliot Lee <sopwith@redhat.com> * Maciej Stachowiak <mjs@eazel.com> + * Darin Adler <darin@eazel.com> * */ @@ -36,7 +37,9 @@ #include <bonobo/bonobo-control.h> #include <bonobo/bonobo-main.h> #include <bonobo/bonobo-ui-util.h> +#include <gtk/gtkmain.h> #include <gtk/gtksignal.h> +#include <libgnomevfs/gnome-vfs-utils.h> #include <libnautilus-extensions/nautilus-gtk-macros.h> enum { @@ -52,6 +55,8 @@ static guint signals[LAST_SIGNAL]; struct NautilusViewDetails { BonoboControl *control; + GList *call_queue; + guint dequeue_calls_at_idle_id; }; typedef struct { @@ -59,6 +64,15 @@ typedef struct { NautilusView *bonobo_object; } impl_POA_Nautilus_View; +typedef void (* ViewFunction) (NautilusView *view, + gpointer callback_data); + +typedef struct { + ViewFunction call; + gpointer callback_data; + GDestroyNotify destroy_callback_data; +} IncomingCall; + static void impl_Nautilus_View_load_location (PortableServer_Servant servant, CORBA_char *location, CORBA_Environment *ev); @@ -97,11 +111,92 @@ static POA_Nautilus_View__vepv impl_Nautilus_View_vepv = &libnautilus_Nautilus_View_epv }; -/* Makes a GList but does not copy the strings. - * Free the list with g_list_free. - */ +static void +execute_queued_calls (NautilusView *view) +{ + GList *queue, *node; + IncomingCall *call; + + /* We could receive more incoming calls while dispatching + * these, so keep going until the call queue is empty. + */ + while (view->details->call_queue != NULL) { + queue = g_list_reverse (view->details->call_queue); + view->details->call_queue = NULL; + + for (node = queue; node != NULL; node = node->next) { + call = node->data; + + (* call->call) (view, call->callback_data); + if (call->destroy_callback_data != NULL) { + (* call->destroy_callback_data) (call->callback_data); + } + } + + g_list_free (queue); + } +} + +static gboolean +dequeue_calls_at_idle (gpointer callback_data) +{ + NautilusView *view; + + view = NAUTILUS_VIEW (callback_data); + execute_queued_calls (view); + view->details->dequeue_calls_at_idle_id = 0; + return FALSE; +} + +static void +discard_queued_calls (NautilusView *view) +{ + GList *queue, *node; + IncomingCall *call; + + queue = view->details->call_queue; + view->details->call_queue = NULL; + + for (node = queue; node != NULL; node = node->next) { + call = node->data; + + if (call->destroy_callback_data != NULL) { + (* call->destroy_callback_data) (call->callback_data); + } + } + + g_list_free (queue); + + g_assert (view->details->call_queue == NULL); +} + +static void +queue_incoming_call (PortableServer_Servant servant, + ViewFunction call, + gpointer callback_data, + GDestroyNotify destroy_callback_data) +{ + NautilusView *view; + IncomingCall *incoming_call; + + view = ((impl_POA_Nautilus_View *) servant)->bonobo_object; + + incoming_call = g_new (IncomingCall, 1); + incoming_call->call = call; + incoming_call->callback_data = callback_data; + incoming_call->destroy_callback_data = destroy_callback_data; + + view->details->call_queue = g_list_prepend + (view->details->call_queue, incoming_call); + + if (view->details->dequeue_calls_at_idle_id == 0) { + view->details->dequeue_calls_at_idle_id = gtk_idle_add + (dequeue_calls_at_idle, view); + } +} + GList * -nautilus_shallow_g_list_from_uri_list (const Nautilus_URIList *uri_list) +nautilus_g_list_from_uri_list (const Nautilus_URIList *uri_list) { GList *list; guint i; @@ -109,7 +204,7 @@ nautilus_shallow_g_list_from_uri_list (const Nautilus_URIList *uri_list) list = NULL; for (i = 0; i < uri_list->_length; i++) { list = g_list_prepend - (list, uri_list->_buffer[i]); + (list, g_strdup (uri_list->_buffer[i])); } return g_list_reverse (list); } @@ -141,21 +236,96 @@ nautilus_uri_list_from_g_list (GList *list) } static void +call_load_location (NautilusView *view, + gpointer callback_data) +{ + gtk_signal_emit (GTK_OBJECT (view), + signals[LOAD_LOCATION], + callback_data); +} + +static void +call_stop_loading (NautilusView *view, + gpointer callback_data) +{ + gtk_signal_emit (GTK_OBJECT (view), + signals[STOP_LOADING]); +} + +static void +call_selection_changed (NautilusView *view, + gpointer callback_data) +{ + gtk_signal_emit (GTK_OBJECT (view), + signals[SELECTION_CHANGED], + callback_data); +} + +static void +call_title_changed (NautilusView *view, + gpointer callback_data) +{ + gtk_signal_emit (GTK_OBJECT (view), + signals[TITLE_CHANGED], + callback_data); +} + +static void +call_history_changed (NautilusView *view, + gpointer callback_data) +{ + gtk_signal_emit (GTK_OBJECT (view), + signals[HISTORY_CHANGED], + callback_data); +} + +static void +list_deep_free_cover (gpointer callback_data) +{ + gnome_vfs_list_deep_free (callback_data); +} + +static Nautilus_History * +history_dup (const Nautilus_History *history) +{ + Nautilus_History *dup; + int length, i; + + length = history->_length; + + dup = Nautilus_History__alloc (); + dup->_maximum = length; + dup->_length = length; + dup->_buffer = CORBA_sequence_Nautilus_HistoryItem_allocbuf (length); + for (i = 0; i < length; i++) { + dup->_buffer[i].title = CORBA_string_dup (history->_buffer[i].title); + dup->_buffer[i].location = CORBA_string_dup (history->_buffer[i].location); + dup->_buffer[i].icon = CORBA_string_dup (history->_buffer[i].icon); + } + CORBA_sequence_set_release (dup, CORBA_TRUE); + + return dup; +} + +static void impl_Nautilus_View_load_location (PortableServer_Servant servant, CORBA_char *location, CORBA_Environment *ev) { - gtk_signal_emit (GTK_OBJECT (((impl_POA_Nautilus_View *) servant)->bonobo_object), - signals[LOAD_LOCATION], - location); + queue_incoming_call (servant, + call_load_location, + g_strdup (location), + g_free); } static void impl_Nautilus_View_stop_loading (PortableServer_Servant servant, CORBA_Environment *ev) { - gtk_signal_emit (GTK_OBJECT (((impl_POA_Nautilus_View *) servant)->bonobo_object), - signals[STOP_LOADING]); + queue_incoming_call (servant, + call_stop_loading, + NULL, + NULL); } static void @@ -163,15 +333,10 @@ impl_Nautilus_View_selection_changed (PortableServer_Servant servant, const Nautilus_URIList *selection, CORBA_Environment *ev) { - GList *selection_as_g_list; - - selection_as_g_list = nautilus_shallow_g_list_from_uri_list (selection); - - gtk_signal_emit (GTK_OBJECT (((impl_POA_Nautilus_View *) servant)->bonobo_object), - signals[SELECTION_CHANGED], - selection_as_g_list); - - g_list_free (selection_as_g_list); + queue_incoming_call (servant, + call_selection_changed, + nautilus_g_list_from_uri_list (selection), + list_deep_free_cover); } static void @@ -179,9 +344,10 @@ impl_Nautilus_View_title_changed (PortableServer_Servant servant, const CORBA_char *title, CORBA_Environment *ev) { - gtk_signal_emit (GTK_OBJECT (((impl_POA_Nautilus_View *) servant)->bonobo_object), - signals[TITLE_CHANGED], - title); + queue_incoming_call (servant, + call_title_changed, + g_strdup (title), + g_free); } static void @@ -189,13 +355,15 @@ impl_Nautilus_View_history_changed (PortableServer_Servant servant, const Nautilus_History *history, CORBA_Environment *ev) { - gtk_signal_emit (GTK_OBJECT (((impl_POA_Nautilus_View *) servant)->bonobo_object), - signals[HISTORY_CHANGED], - history); + queue_incoming_call (servant, + call_history_changed, + history_dup (history), + CORBA_free); } static void -impl_Nautilus_View__destroy (BonoboObject *object, PortableServer_Servant servant) +impl_Nautilus_View__destroy (BonoboObject *object, + PortableServer_Servant servant) { PortableServer_ObjectId *object_id; CORBA_Environment ev; @@ -320,7 +488,6 @@ nautilus_view_construct (NautilusView *view, (view, bonobo_control_new (widget)); } - NautilusView * nautilus_view_construct_from_bonobo_control (NautilusView *view, BonoboControl *control) @@ -335,12 +502,20 @@ nautilus_view_construct_from_bonobo_control (NautilusView *view, return view; } - - static void nautilus_view_destroy (GtkObject *object) { - g_free (NAUTILUS_VIEW (object)->details); + NautilusView *view; + + view = NAUTILUS_VIEW (object); + + discard_queued_calls (view); + + if (view->details->dequeue_calls_at_idle_id != 0) { + gtk_idle_remove (view->details->dequeue_calls_at_idle_id); + } + + g_free (view->details); NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); } diff --git a/libnautilus/nautilus-view.h b/libnautilus/nautilus-view.h index 7bd49bfec..8a7af2de8 100644 --- a/libnautilus/nautilus-view.h +++ b/libnautilus/nautilus-view.h @@ -91,7 +91,7 @@ void nautilus_view_set_title (NautilusV * which is why they are public. */ Nautilus_URIList * nautilus_uri_list_from_g_list (GList *list); -GList * nautilus_shallow_g_list_from_uri_list (const Nautilus_URIList *uri_list); +GList * nautilus_g_list_from_uri_list (const Nautilus_URIList *uri_list); /* Simpler API for setting up and getting the UI component. */ BonoboUIComponent *nautilus_view_set_up_ui (NautilusView *view, diff --git a/src/nautilus-navigation-window.c b/src/nautilus-navigation-window.c index fa25347fe..b629df7cd 100644 --- a/src/nautilus-navigation-window.c +++ b/src/nautilus-navigation-window.c @@ -1553,9 +1553,7 @@ nautilus_window_set_content_view_widget (NautilusWindow *window, if (new_view != NULL) { gtk_widget_show (GTK_WIDGET (new_view)); - - nautilus_view_frame_activate (new_view); - + /* FIXME bugzilla.eazel.com 1243: * We should use inheritance instead of these special cases * for the desktop window. @@ -1577,7 +1575,6 @@ nautilus_window_set_content_view_widget (NautilusWindow *window, gtk_widget_hide (window->zoom_control); } - window->content_view = new_view; } diff --git a/src/nautilus-navigation-window.h b/src/nautilus-navigation-window.h index 64cd4fd34..e1fa56533 100644 --- a/src/nautilus-navigation-window.h +++ b/src/nautilus-navigation-window.h @@ -125,8 +125,6 @@ struct NautilusWindow { NautilusLocationChangeType location_change_type; guint location_change_distance; - gboolean views_shown; - gboolean view_bombed_out; gboolean view_activation_complete; gboolean sent_update_view; gboolean cv_progress_initial; diff --git a/src/nautilus-object-window.c b/src/nautilus-object-window.c index fa25347fe..b629df7cd 100644 --- a/src/nautilus-object-window.c +++ b/src/nautilus-object-window.c @@ -1553,9 +1553,7 @@ nautilus_window_set_content_view_widget (NautilusWindow *window, if (new_view != NULL) { gtk_widget_show (GTK_WIDGET (new_view)); - - nautilus_view_frame_activate (new_view); - + /* FIXME bugzilla.eazel.com 1243: * We should use inheritance instead of these special cases * for the desktop window. @@ -1577,7 +1575,6 @@ nautilus_window_set_content_view_widget (NautilusWindow *window, gtk_widget_hide (window->zoom_control); } - window->content_view = new_view; } diff --git a/src/nautilus-object-window.h b/src/nautilus-object-window.h index 64cd4fd34..e1fa56533 100644 --- a/src/nautilus-object-window.h +++ b/src/nautilus-object-window.h @@ -125,8 +125,6 @@ struct NautilusWindow { NautilusLocationChangeType location_change_type; guint location_change_distance; - gboolean views_shown; - gboolean view_bombed_out; gboolean view_activation_complete; gboolean sent_update_view; gboolean cv_progress_initial; diff --git a/src/nautilus-spatial-window.c b/src/nautilus-spatial-window.c index fa25347fe..b629df7cd 100644 --- a/src/nautilus-spatial-window.c +++ b/src/nautilus-spatial-window.c @@ -1553,9 +1553,7 @@ nautilus_window_set_content_view_widget (NautilusWindow *window, if (new_view != NULL) { gtk_widget_show (GTK_WIDGET (new_view)); - - nautilus_view_frame_activate (new_view); - + /* FIXME bugzilla.eazel.com 1243: * We should use inheritance instead of these special cases * for the desktop window. @@ -1577,7 +1575,6 @@ nautilus_window_set_content_view_widget (NautilusWindow *window, gtk_widget_hide (window->zoom_control); } - window->content_view = new_view; } diff --git a/src/nautilus-spatial-window.h b/src/nautilus-spatial-window.h index 64cd4fd34..e1fa56533 100644 --- a/src/nautilus-spatial-window.h +++ b/src/nautilus-spatial-window.h @@ -125,8 +125,6 @@ struct NautilusWindow { NautilusLocationChangeType location_change_type; guint location_change_distance; - gboolean views_shown; - gboolean view_bombed_out; gboolean view_activation_complete; gboolean sent_update_view; gboolean cv_progress_initial; diff --git a/src/nautilus-view-frame-corba.c b/src/nautilus-view-frame-corba.c index ae832a860..eeebbf484 100644 --- a/src/nautilus-view-frame-corba.c +++ b/src/nautilus-view-frame-corba.c @@ -174,10 +174,10 @@ impl_Nautilus_ViewFrame_open_location_force_new_window (PortableServer_Servant s if (view == NULL) { return; } - selection_as_g_list = nautilus_shallow_g_list_from_uri_list (selection); + selection_as_g_list = nautilus_g_list_from_uri_list (selection); nautilus_view_frame_open_location_force_new_window (view, location, selection_as_g_list); - g_list_free (selection_as_g_list); + nautilus_g_list_free_deep (selection_as_g_list); } static void @@ -192,10 +192,10 @@ impl_Nautilus_ViewFrame_report_selection_change (PortableServer_Servant servant, if (view == NULL) { return; } - selection_as_g_list = nautilus_shallow_g_list_from_uri_list (selection); + selection_as_g_list = nautilus_g_list_from_uri_list (selection); nautilus_view_frame_report_selection_change (view, selection_as_g_list); - g_list_free (selection_as_g_list); + nautilus_g_list_free_deep (selection_as_g_list); } static void diff --git a/src/nautilus-view-frame.c b/src/nautilus-view-frame.c index af5007571..62d2b0b55 100644 --- a/src/nautilus-view-frame.c +++ b/src/nautilus-view-frame.c @@ -34,6 +34,8 @@ #include "nautilus-component-adapter-factory.h" #include "nautilus-signaller.h" #include "nautilus-window.h" +#include <bonobo/bonobo-zoomable-frame.h> +#include <bonobo/bonobo-zoomable.h> #include <gtk/gtksignal.h> #include <libnautilus-extensions/nautilus-bonobo-extensions.h> #include <libnautilus-extensions/nautilus-gtk-extensions.h> @@ -41,9 +43,10 @@ #include <libnautilus-extensions/nautilus-undo-manager.h> #include <libnautilus/nautilus-view.h> -#include <bonobo/bonobo-zoomable-frame.h> -#include <bonobo/bonobo-zoomable.h> - +/* FIXME bugzilla.eazel.com 2456: Is a hard-coded 12 seconds wait to + * detect that a view is gone acceptable? Can a component that is + * working still take 12 seconds to respond? + */ /* Milliseconds */ #define ATTACH_CLIENT_TIMEOUT 12000 @@ -67,7 +70,6 @@ enum { typedef enum { VIEW_FRAME_EMPTY, - VIEW_FRAME_ACTIVATING, VIEW_FRAME_NO_LOCATION, VIEW_FRAME_WAITING, VIEW_FRAME_UNDERWAY, @@ -86,13 +88,14 @@ struct NautilusViewFrameDetails { guint check_if_view_is_gone_timeout_id; char *activation_iid; - NautilusBonoboActivate *activate_structure; + NautilusBonoboActivationHandle *activation_handle; }; static void nautilus_view_frame_initialize (NautilusViewFrame *view); static void nautilus_view_frame_destroy (GtkObject *view); static void nautilus_view_frame_finalize (GtkObject *view); static void nautilus_view_frame_initialize_class (NautilusViewFrameClass *klass); +static void nautilus_view_frame_map (GtkWidget *view); static void send_history (NautilusViewFrame *view); static guint signals[LAST_SIGNAL]; @@ -105,10 +108,15 @@ static void nautilus_view_frame_initialize_class (NautilusViewFrameClass *klass) { GtkObjectClass *object_class; + GtkWidgetClass *widget_class; object_class = GTK_OBJECT_CLASS (klass); + widget_class = GTK_WIDGET_CLASS (klass); + object_class->destroy = nautilus_view_frame_destroy; object_class->finalize = nautilus_view_frame_finalize; + + widget_class->map = nautilus_view_frame_map; signals[CHANGE_SELECTION] = gtk_signal_new ("change_selection", @@ -246,14 +254,10 @@ nautilus_view_frame_initialize (NautilusViewFrame *view) static void nautilus_view_frame_destroy_client (NautilusViewFrame *view) { - CORBA_Environment ev; - if (view->iid == NULL) { return; } - CORBA_exception_init (&ev); - g_free (view->iid); view->iid = NULL; @@ -271,8 +275,6 @@ nautilus_view_frame_destroy_client (NautilusViewFrame *view) */ view->zoomable_frame = NULL; - CORBA_exception_free (&ev); - if (view->details->ui_container->win != NULL) { bonobo_window_deregister_dead_components (view->details->ui_container->win); } @@ -313,52 +315,6 @@ nautilus_view_frame_finalize (GtkObject *object) NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object)); } -/* stimulus: successful load_client call */ -static void -view_frame_activating (NautilusViewFrame *view) -{ - g_assert (NAUTILUS_IS_VIEW_FRAME (view)); - - switch (view->details->state) { - case VIEW_FRAME_EMPTY: - view->details->state = VIEW_FRAME_ACTIVATING; - return; - case VIEW_FRAME_ACTIVATING: - case VIEW_FRAME_NO_LOCATION: - case VIEW_FRAME_UNDERWAY: - case VIEW_FRAME_LOADED: - case VIEW_FRAME_WAITING: - case VIEW_FRAME_FAILED: - g_assert_not_reached (); - return; - } - - g_assert_not_reached (); -} - -/* stimulus: unsuccessful activated_component call */ -static void -view_frame_not_activated (NautilusViewFrame *view) -{ - g_assert (NAUTILUS_IS_VIEW_FRAME (view)); - - switch (view->details->state) { - case VIEW_FRAME_ACTIVATING: - view->details->state = VIEW_FRAME_FAILED; - return; - case VIEW_FRAME_EMPTY: - case VIEW_FRAME_NO_LOCATION: - case VIEW_FRAME_UNDERWAY: - case VIEW_FRAME_LOADED: - case VIEW_FRAME_WAITING: - case VIEW_FRAME_FAILED: - g_assert_not_reached (); - return; - } - - g_assert_not_reached (); -} - /* stimulus: successful activated_component call */ static void view_frame_activated (NautilusViewFrame *view) @@ -366,34 +322,11 @@ view_frame_activated (NautilusViewFrame *view) g_assert (NAUTILUS_IS_VIEW_FRAME (view)); switch (view->details->state) { - case VIEW_FRAME_ACTIVATING: + case VIEW_FRAME_EMPTY: view->details->state = VIEW_FRAME_NO_LOCATION; + gtk_signal_emit (GTK_OBJECT (view), signals[CLIENT_LOADED]); send_history (view); return; - case VIEW_FRAME_EMPTY: - case VIEW_FRAME_NO_LOCATION: - case VIEW_FRAME_UNDERWAY: - case VIEW_FRAME_LOADED: - case VIEW_FRAME_WAITING: - case VIEW_FRAME_FAILED: - g_assert_not_reached (); - return; - } - - g_assert_not_reached (); -} - -/* stimulus: stop activation */ -static void -view_frame_stop_activation (NautilusViewFrame *view) -{ - g_assert (NAUTILUS_IS_VIEW_FRAME (view)); - - switch (view->details->state) { - case VIEW_FRAME_EMPTY: - case VIEW_FRAME_ACTIVATING: - view->details->state = VIEW_FRAME_EMPTY; - return; case VIEW_FRAME_NO_LOCATION: case VIEW_FRAME_UNDERWAY: case VIEW_FRAME_LOADED: @@ -416,9 +349,6 @@ view_frame_wait (NautilusViewFrame *view) case VIEW_FRAME_EMPTY: g_warning ("tried to load location in an empty view frame"); break; - case VIEW_FRAME_ACTIVATING: - view->details->state = VIEW_FRAME_FAILED; - break; case VIEW_FRAME_NO_LOCATION: case VIEW_FRAME_UNDERWAY: case VIEW_FRAME_LOADED: @@ -443,7 +373,6 @@ view_frame_underway (NautilusViewFrame *view) switch (view->details->state) { case VIEW_FRAME_EMPTY: case VIEW_FRAME_FAILED: - case VIEW_FRAME_ACTIVATING: g_assert_not_reached (); return; case VIEW_FRAME_NO_LOCATION: @@ -476,7 +405,6 @@ view_frame_wait_is_over (NautilusViewFrame *view) switch (view->details->state) { case VIEW_FRAME_EMPTY: case VIEW_FRAME_FAILED: - case VIEW_FRAME_ACTIVATING: g_assert_not_reached (); return; case VIEW_FRAME_NO_LOCATION: @@ -502,7 +430,6 @@ view_frame_loaded (NautilusViewFrame *view) switch (view->details->state) { case VIEW_FRAME_EMPTY: case VIEW_FRAME_FAILED: - case VIEW_FRAME_ACTIVATING: g_assert_not_reached (); return; case VIEW_FRAME_NO_LOCATION: @@ -529,7 +456,6 @@ view_frame_failed (NautilusViewFrame *view) g_assert (NAUTILUS_IS_VIEW_FRAME (view)); switch (view->details->state) { - case VIEW_FRAME_ACTIVATING: case VIEW_FRAME_EMPTY: case VIEW_FRAME_LOADED: case VIEW_FRAME_NO_LOCATION: @@ -588,29 +514,35 @@ get_CORBA_object (NautilusViewFrame *view) } static gboolean -check_if_view_is_gone (gpointer data) +check_if_view_is_gone (gpointer callback_data) { NautilusViewFrame *view; CORBA_Environment ev; - gboolean ok; + gboolean view_is_gone; - view = NAUTILUS_VIEW_FRAME (data); + view = NAUTILUS_VIEW_FRAME (callback_data); CORBA_exception_init (&ev); - ok = TRUE; - if (CORBA_Object_non_existent (get_CORBA_object (view), &ev)) { - view->details->check_if_view_is_gone_timeout_id = 0; - bonobo_window_deregister_dead_components (view->details->ui_container->win); - view_frame_failed (view); - ok = FALSE; + view_is_gone = CORBA_Object_non_existent (get_CORBA_object (view), &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + view_is_gone = TRUE; } CORBA_exception_free (&ev); - return ok; + if (!view_is_gone) { + return TRUE; + } + + view->details->check_if_view_is_gone_timeout_id = 0; + bonobo_window_deregister_dead_components (view->details->ui_container->win); + view_frame_failed (view); + return FALSE; } static void -zoom_level_changed_callback (BonoboZoomableFrame *zframe, float zoom_level, NautilusViewFrame *view) +zoom_level_changed_callback (BonoboZoomableFrame *zframe, + float zoom_level, + NautilusViewFrame *view) { g_return_if_fail (zframe != NULL); g_return_if_fail (BONOBO_IS_ZOOMABLE_FRAME (zframe)); @@ -621,7 +553,8 @@ zoom_level_changed_callback (BonoboZoomableFrame *zframe, float zoom_level, Naut } static void -zoom_parameters_changed_callback (BonoboZoomableFrame *zframe, NautilusViewFrame *view) +zoom_parameters_changed_callback (BonoboZoomableFrame *zframe, + NautilusViewFrame *view) { g_return_if_fail (zframe != NULL); g_return_if_fail (BONOBO_IS_ZOOMABLE_FRAME (zframe)); @@ -643,8 +576,6 @@ attach_client (NautilusViewFrame *view, BonoboObjectClient *client) g_return_val_if_fail (NAUTILUS_IS_VIEW_FRAME (view), FALSE); - CORBA_exception_init (&ev); - /* Either create an adapter or query for the Nautilus:View * interface. Either way, we don't need to keep the original * reference around once that happens. @@ -693,16 +624,19 @@ attach_client (NautilusViewFrame *view, BonoboObjectClient *client) GTK_SIGNAL_FUNC (zoom_parameters_changed_callback), view); bonobo_zoomable_frame_bind_to_zoomable (view->zoomable_frame, zoomable); - bonobo_object_release_unref (zoomable, &ev); + bonobo_object_release_unref (zoomable, NULL); } /* Start with a view frame interface. */ view->view_frame = impl_Nautilus_ViewFrame__create (view, &ev); if (ev._major != CORBA_NO_EXCEPTION) { /* FIXME bugzilla.eazel.com 5041: Cleanup needed here. */ + CORBA_exception_free (&ev); return FALSE; } + CORBA_exception_free (&ev); + /* Add a control frame interface. */ control_frame = bonobo_control_frame_new (bonobo_object_corba_objref (BONOBO_OBJECT (view->details->ui_container))); bonobo_object_add_interface (BONOBO_OBJECT (view->view_frame), @@ -724,8 +658,6 @@ attach_client (NautilusViewFrame *view, BonoboObjectClient *client) bonobo_object_release_unref (control, NULL); - CORBA_exception_free (&ev); - view->iid = g_strdup (view->details->activation_iid); gtk_signal_connect_while_alive @@ -743,9 +675,6 @@ attach_client (NautilusViewFrame *view, BonoboObjectClient *client) gtk_container_add (GTK_CONTAINER (view), view->client_widget); gtk_widget_show (view->client_widget); - /* FIXME bugzilla.eazel.com 2456: - * Is a hard-coded timeout acceptable? - */ g_assert (view->details->check_if_view_is_gone_timeout_id == 0); view->details->check_if_view_is_gone_timeout_id = g_timeout_add (ATTACH_CLIENT_TIMEOUT, check_if_view_is_gone, view); @@ -754,99 +683,66 @@ attach_client (NautilusViewFrame *view, BonoboObjectClient *client) } static void -activation_callback (CORBA_Object object_reference, gpointer data) +activation_callback (NautilusBonoboActivationHandle *handle, + Bonobo_Unknown activated_object, + gpointer callback_data) { NautilusViewFrame *view; BonoboObjectClient *bonobo_object; - view = (NautilusViewFrame *) data; + view = NAUTILUS_VIEW_FRAME (callback_data); + g_assert (view->details->activation_handle == handle); - bonobo_object = bonobo_object_client_from_corba (object_reference); + view->details->activation_handle = NULL; + bonobo_object = bonobo_object_client_from_corba (activated_object); attach_client (view, bonobo_object); - - gtk_signal_emit (GTK_OBJECT (view), signals[CLIENT_LOADED], - bonobo_object); } void nautilus_view_frame_load_client_async (NautilusViewFrame *view, const char *iid) { - NautilusBonoboActivate *activate_structure; - if (view->details->state == VIEW_FRAME_FAILED) { return; } - view_frame_activating (view); view->details->activation_iid = g_strdup (iid); - activate_structure = nautilus_bonobo_activate_from_id + view->details->activation_handle = nautilus_bonobo_activate_from_id (iid, activation_callback, view); - - view->details->activate_structure = activate_structure; } -/* I left this function around because I was lazy to make the sidebar activation - * use the async model in the main state machine... there are 2 reasons for not - * doing so: - * - * - sidebar components should NOT take long to load. - * - hacking the state machine might take me as long as it took me to get - * the core stuff working so... I am not eager to get into this game. - * - * As a consequence, the following function does quite a few calls to - * the state changing functions to simulate async activation. - */ -gboolean /* returns TRUE if successful */ +void nautilus_view_frame_load_client (NautilusViewFrame *view, const char *iid) { BonoboObjectClient *component; - g_return_val_if_fail (NAUTILUS_IS_VIEW_FRAME (view), FALSE); + g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); if (view->details->state == VIEW_FRAME_FAILED) { - return FALSE; + return; } - g_return_val_if_fail (view->details->state == VIEW_FRAME_EMPTY, FALSE); + g_return_if_fail (view->details->state == VIEW_FRAME_EMPTY); if (iid == NULL) { - return FALSE; + view_frame_failed (view); + return; } - view_frame_activating (view); - component = bonobo_object_activate (iid, 0); if (component == NULL) { - view_frame_not_activated (view); - return FALSE; + view_frame_failed (view); + return; } view->details->activation_iid = g_strdup (iid); if (!attach_client (view, component)) { - view_frame_not_activated (view); - return FALSE; - } - - view_frame_activated (view); - - return TRUE; -} - -void -nautilus_view_frame_stop_activation (NautilusViewFrame *view) -{ - g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); - - if (view->details->state == VIEW_FRAME_FAILED) { + view_frame_failed (view); return; } - nautilus_bonobo_activate_stop (view->details->activate_structure); - view_frame_stop_activation (view); - nautilus_bonobo_activate_free (view->details->activate_structure); - view->details->activate_structure = NULL; + view_frame_activated (view); } void @@ -878,7 +774,7 @@ nautilus_view_frame_load_location (NautilusViewFrame *view, } void -nautilus_view_frame_stop_loading (NautilusViewFrame *view) +nautilus_view_frame_stop (NautilusViewFrame *view) { CORBA_Environment ev; @@ -1322,15 +1218,27 @@ nautilus_view_frame_set_label (NautilusViewFrame *view, } /* Calls activate on the underlying control frame. */ -void -nautilus_view_frame_activate (NautilusViewFrame *view) +static void +nautilus_view_frame_map (GtkWidget *view_as_widget) { + NautilusViewFrame *view; BonoboControlFrame *control_frame; - - g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); - if (view->details->state == VIEW_FRAME_FAILED) { + view = NAUTILUS_VIEW_FRAME (view_as_widget); + + NAUTILUS_CALL_PARENT_CLASS (GTK_WIDGET_CLASS, map, (view_as_widget)); + + switch (view->details->state) { + case VIEW_FRAME_EMPTY: + case VIEW_FRAME_NO_LOCATION: + case VIEW_FRAME_WAITING: + g_warning ("a view frame was mapped before it was underway"); + break; + case VIEW_FRAME_FAILED: return; + case VIEW_FRAME_UNDERWAY: + case VIEW_FRAME_LOADED: + break; } control_frame = BONOBO_CONTROL_FRAME (bonobo_object_query_local_interface @@ -1361,7 +1269,6 @@ send_history (NautilusViewFrame *view) switch (view->details->state) { case VIEW_FRAME_EMPTY: - case VIEW_FRAME_ACTIVATING: case VIEW_FRAME_FAILED: return; case VIEW_FRAME_NO_LOCATION: @@ -1393,7 +1300,6 @@ nautilus_view_frame_get_is_underway (NautilusViewFrame *view) switch (view->details->state) { case VIEW_FRAME_EMPTY: - case VIEW_FRAME_ACTIVATING: case VIEW_FRAME_NO_LOCATION: case VIEW_FRAME_FAILED: case VIEW_FRAME_WAITING: diff --git a/src/nautilus-view-frame.h b/src/nautilus-view-frame.h index f7940aa2d..cc88b4ad1 100644 --- a/src/nautilus-view-frame.h +++ b/src/nautilus-view-frame.h @@ -104,17 +104,16 @@ typedef struct { GtkType nautilus_view_frame_get_type (void); NautilusViewFrame * nautilus_view_frame_new (BonoboUIContainer *ui_container, NautilusUndoManager *undo_manager); -gboolean nautilus_view_frame_load_client (NautilusViewFrame *view, +void nautilus_view_frame_load_client (NautilusViewFrame *view, const char *iid); void nautilus_view_frame_load_client_async (NautilusViewFrame *view, const char *iid); -void nautilus_view_frame_stop_activation (NautilusViewFrame *view); const char * nautilus_view_frame_get_iid (NautilusViewFrame *view); +void nautilus_view_frame_stop (NautilusViewFrame *view); /* calls to Nautilus:View functions */ void nautilus_view_frame_load_location (NautilusViewFrame *view, const char *location); -void nautilus_view_frame_stop_loading (NautilusViewFrame *view); void nautilus_view_frame_selection_changed (NautilusViewFrame *view, GList *selection); void nautilus_view_frame_title_changed (NautilusViewFrame *view, @@ -138,8 +137,6 @@ gboolean nautilus_view_frame_is_zoomable (NautilusVie char * nautilus_view_frame_get_label (NautilusViewFrame *view); void nautilus_view_frame_set_label (NautilusViewFrame *view, const char *label); -void nautilus_view_frame_activate (NautilusViewFrame *view); - /* view state */ char * nautilus_view_frame_get_title (NautilusViewFrame *view); gboolean nautilus_view_frame_get_is_underway (NautilusViewFrame *view); diff --git a/src/nautilus-window-manage-views.c b/src/nautilus-window-manage-views.c index 144ca06e3..9e367c155 100644 --- a/src/nautilus-window-manage-views.c +++ b/src/nautilus-window-manage-views.c @@ -92,15 +92,10 @@ typedef struct { char *label; } ViewFrameInfo; -static void connect_view (NautilusWindow *window, +static void connect_view (NautilusWindow *window, NautilusViewFrame *view); -static void disconnect_view (NautilusWindow *window, +static void disconnect_view (NautilusWindow *window, NautilusViewFrame *view); -static void disconnect_view_and_destroy (NautilusWindow *window, - NautilusViewFrame *view); -static void disconnect_and_destroy_sidebar_panel (NautilusWindow *window, - NautilusViewFrame *view); - static void cancel_location_change (NautilusWindow *window); static void @@ -586,35 +581,32 @@ static void location_has_really_changed (NautilusWindow *window) { /* Switch to the new content view. */ - if (window->new_content_view != NULL) { - if (GTK_WIDGET (window->new_content_view)->parent == NULL) { - /* If we don't unref the old view until idle - * time, we avoid certain kinds of problems in - * in-process components, since they won't - * lose their ViewFrame in the middle of some - * operation. This still doesn't necessarily - * help for out of process components. - */ - if (window->content_view != NULL) { - ref_now_unref_at_idle_time (GTK_OBJECT (window->content_view)); - } - - disconnect_view (window, window->content_view); - nautilus_window_set_content_view_widget (window, window->new_content_view); + if (GTK_WIDGET (window->new_content_view)->parent == NULL) { + /* If we don't unref the old view until idle + * time, we avoid certain kinds of problems in + * in-process components, since they won't + * lose their ViewFrame in the middle of some + * operation. This still doesn't necessarily + * help for out of process components. + */ + if (window->content_view != NULL) { + ref_now_unref_at_idle_time (GTK_OBJECT (window->content_view)); } - gtk_object_unref (GTK_OBJECT (window->new_content_view)); - window->new_content_view = NULL; - /* Update displayed view in menu. Only do this if we're not switching - * locations though, because if we are switching locations we'll - * install a whole new set of views in the menu later (the current - * views in the menu are for the old location). - */ - if (window->pending_ni == NULL) { - nautilus_window_synch_view_as_menu (window); - } - } - + disconnect_view (window, window->content_view); + nautilus_window_set_content_view_widget (window, window->new_content_view); + } + gtk_object_unref (GTK_OBJECT (window->new_content_view)); + window->new_content_view = NULL; + + /* Update displayed view in menu. Only do this if we're not switching + * locations though, because if we are switching locations we'll + * install a whole new set of views in the menu later (the current + * views in the menu are for the old location). + */ + if (window->pending_ni == NULL) { + nautilus_window_synch_view_as_menu (window); + } /* Tell the window we are finished. */ if (window->pending_ni != NULL) { @@ -803,21 +795,10 @@ report_nascent_content_view_failure_to_user (NautilusWindow *window, } static void -disconnect_destroy_unref_view (NautilusWindow *window, NautilusViewFrame *view_frame) -{ - g_assert (NAUTILUS_IS_WINDOW (window)); - g_assert (NAUTILUS_IS_VIEW_FRAME (view_frame)); - - disconnect_view_and_destroy (window, view_frame); - gtk_widget_unref (GTK_WIDGET (view_frame)); -} - -static NautilusViewFrame * load_content_view (NautilusWindow *window, NautilusViewIdentifier *id) { const char *iid; - NautilusViewFrame *content_view; NautilusViewFrame *new_view; /* FIXME bugzilla.eazel.com 1243: @@ -831,7 +812,7 @@ load_content_view (NautilusWindow *window, */ iid = NAUTILUS_DESKTOP_ICON_VIEW_IID; } else { - g_return_val_if_fail (id, NULL); + g_return_if_fail (id != NULL); iid = id->iid; } @@ -847,44 +828,33 @@ load_content_view (NautilusWindow *window, FALSE); bonobo_ui_component_thaw (window->details->shell_ui, NULL); + + nautilus_view_identifier_free (window->content_view_id); + window->content_view_id = nautilus_view_identifier_copy (id); - content_view = window->content_view; - if (content_view == NULL - || strcmp (nautilus_view_frame_get_iid (content_view), iid) != 0) { - + if (window->content_view == NULL + || strcmp (nautilus_view_frame_get_iid (window->content_view), iid) != 0) { + new_view = nautilus_view_frame_new (window->details->ui_container, window->application->undo_manager); + window->new_content_view = new_view; gtk_object_ref (GTK_OBJECT (new_view)); gtk_object_sink (GTK_OBJECT (new_view)); set_view_frame_info (new_view, FALSE, id->name); connect_view (window, new_view); - if (!nautilus_view_frame_load_client (new_view, iid)) { - /* FIXME bugzilla.eazel.com 5039: We need a way to report the specific - error that happens in this case - adapter - factory not found, component failed to - load, etc. */ - report_nascent_content_view_failure_to_user (window, new_view); - disconnect_destroy_unref_view (window, new_view); - - new_view = NULL; - } - /* Avoid being fooled by extra done notifications from the last view. This is a HACK because the state machine SUCKS. */ window->cv_progress_done = FALSE; window->cv_progress_error = FALSE; + + nautilus_view_frame_load_client (new_view, iid); } else { - gtk_object_ref (GTK_OBJECT (window->content_view)); new_view = window->content_view; + window->new_content_view = new_view; + gtk_object_ref (GTK_OBJECT (new_view)); + window->view_activation_complete = TRUE; } - - if (new_view != NULL) { - nautilus_view_identifier_free (window->content_view_id); - window->content_view_id = nautilus_view_identifier_copy (id); - } - - return new_view; } @@ -915,10 +885,19 @@ report_sidebar_panel_failure_to_user (NautilusWindow *window, NautilusViewFrame } static void +disconnect_and_destroy_sidebar_panel (NautilusWindow *window, NautilusViewFrame *view) +{ + disconnect_view (window, view); + nautilus_window_remove_sidebar_panel (window, view); + gtk_widget_destroy (GTK_WIDGET (view)); +} + +static void handle_view_failure (NautilusWindow *window, NautilusViewFrame *view) { - const char* current_iid; + const char *current_iid; + if (view_frame_is_sidebar_panel (view)) { report_sidebar_panel_failure_to_user (window, view); current_iid = nautilus_view_frame_get_iid (view); @@ -930,14 +909,25 @@ handle_view_failure (NautilusWindow *window, gtk_container_remove (GTK_CONTAINER (GTK_WIDGET (window->content_view)->parent), GTK_WIDGET (window->content_view)); } + /* FIXME bugzilla.eazel.com 5039: We need a + * way to report the specific error that + * happens in this case - adapter factory not + * found, component failed to load, etc. + */ report_current_content_view_failure_to_user (window, view); + window->content_view = NULL; - window->cv_progress_error = TRUE; } else { window->reset_to_idle = TRUE; - window->cv_progress_error = TRUE; + + /* FIXME bugzilla.eazel.com 5039: We need a + * way to report the specific error that + * happens in this case - adapter factory not + * found, component failed to load, etc. + */ report_nascent_content_view_failure_to_user (window, view); } + window->cv_progress_error = TRUE; } } @@ -956,7 +946,8 @@ free_location_change (NautilusWindow *window) if (window->new_content_view != NULL) { if (window->new_content_view != window->content_view) { - disconnect_view_and_destroy (window, window->new_content_view); + disconnect_view (window, window->new_content_view); + gtk_widget_destroy (GTK_WIDGET (window->new_content_view)); } gtk_object_unref (GTK_OBJECT (window->new_content_view)); window->new_content_view = NULL; @@ -990,8 +981,6 @@ cancel_location_change (NautilusWindow *window) free_location_change (window); - window->views_shown = FALSE; - window->view_bombed_out = FALSE; window->view_activation_complete = FALSE; window->cv_progress_initial = FALSE; window->cv_progress_done = FALSE; @@ -1001,12 +990,12 @@ cancel_location_change (NautilusWindow *window) } static void -load_view_for_new_location (NautilusWindow *window) +load_content_view_for_new_location (NautilusWindow *window) { NautilusViewIdentifier *content_id; content_id = nautilus_navigation_info_get_initial_content_id (window->pending_ni); - window->new_content_view = load_content_view (window, content_id); + load_content_view (window, content_id); nautilus_view_identifier_free (content_id); } @@ -1044,154 +1033,69 @@ set_view_location_and_selection (NautilusWindow *window) g_free (location); } -static gboolean -update_state (gpointer data) +static void +update_state (NautilusWindow *window) { - NautilusWindow *window; - GList *p; + GList *node; gboolean made_changes; - window = data; - if (window->making_changes) { - return FALSE; + return; } - made_changes = FALSE; window->making_changes++; - /* Now make any needed state changes based on available information */ - - if (window->view_bombed_out) { - window->view_bombed_out = FALSE; - - for (p = window->error_views; p != NULL; p = p->next) { - handle_view_failure (window, NAUTILUS_VIEW_FRAME (p->data)); - gtk_widget_unref (GTK_WIDGET (p->data)); - } - - g_list_free (window->error_views); - window->error_views = NULL; - - made_changes = TRUE; - } - - if (window->reset_to_idle) { - window->reset_to_idle = FALSE; - - cancel_location_change (window); - - made_changes = TRUE; - } - - if (window->pending_ni != NULL - && window->new_content_view == NULL - && !window->cv_progress_error - && !window->view_activation_complete) { - - load_view_for_new_location (window); - - window->view_activation_complete = TRUE; - made_changes = TRUE; - } - - if (window->view_activation_complete - && !window->sent_update_view) { - - set_view_location_and_selection (window); - - window->sent_update_view = TRUE; - made_changes = TRUE; - } - - if (!window->cv_progress_error - && window->view_activation_complete - && window->cv_progress_initial - && !window->views_shown) { - - location_has_really_changed (window); - - window->views_shown = TRUE; - made_changes = TRUE; - } - - if (window->cv_progress_error - || window->cv_progress_done) { - made_changes = TRUE; - window->reset_to_idle = TRUE; - } - - window->making_changes--; - - return made_changes; -} - -typedef enum { - INITIAL_VIEW_SELECTED, - LOAD_DONE, - LOAD_UNDERWAY, - NEW_CONTENT_VIEW_READY, - STOP, - VIEW_FAILED, -} Stimulus; + do { + made_changes = FALSE; -static void -change_state (NautilusWindow *window, - Stimulus stimulus, - NautilusNavigationInfo *info, - NautilusViewFrame *new_view) -{ - /* Ensure that changes happen in-order */ - while (update_state (window)) { } - - switch (stimulus) { - case INITIAL_VIEW_SELECTED: /* The information needed for a location change to continue has been received */ - window->pending_ni = info; - window->cancel_tag = NULL; - break; + /* Now make any needed state changes based on available information */ - case VIEW_FAILED: - g_warning ("A view failed. The UI will handle this with a dialog but this should be debugged."); - window->view_bombed_out = TRUE; - gtk_object_ref (GTK_OBJECT (new_view)); - window->error_views = g_list_prepend (window->error_views, new_view); - break; + if (window->error_views != NULL) { + for (node = window->error_views; node != NULL; node = node->next) { + handle_view_failure (window, NAUTILUS_VIEW_FRAME (node->data)); + gtk_widget_unref (GTK_WIDGET (node->data)); + } + g_list_free (window->error_views); + window->error_views = NULL; + made_changes = TRUE; + } - case NEW_CONTENT_VIEW_READY: - g_return_if_fail (window->new_content_view == NULL); - - /* Don't ref here, reference is held by widget hierarchy. */ - window->new_content_view = new_view; - /* We only come here in cases where the location does not change, - * so the sidebar panels don't change either. - */ - if (window->pending_ni == NULL) { - window->view_activation_complete = TRUE; + if (window->reset_to_idle) { + window->reset_to_idle = FALSE; + cancel_location_change (window); + made_changes = TRUE; } - window->views_shown = FALSE; - break; - case LOAD_UNDERWAY: /* We have received an "I am loading" indication from the content view */ - nautilus_window_allow_stop (window, TRUE); /* for the case where we are "re-underway" */ - window->cv_progress_initial = TRUE; - window->cv_progress_done = FALSE; - break; + if (window->pending_ni != NULL + && window->new_content_view == NULL + && !window->cv_progress_error) { + load_content_view_for_new_location (window); + made_changes = TRUE; + } - case LOAD_DONE: /* The content view is done loading */ - window->cv_progress_initial = TRUE; - window->cv_progress_done = TRUE; - break; + if (window->view_activation_complete + && !window->sent_update_view) { + set_view_location_and_selection (window); + window->sent_update_view = TRUE; + made_changes = TRUE; + } - case STOP: /* Someone pressed the stop button or something */ - window->reset_to_idle = TRUE; - break; + if (!window->cv_progress_error + && window->view_activation_complete + && window->cv_progress_initial + && window->new_content_view != NULL) { + location_has_really_changed (window); + made_changes = TRUE; + } - default: - g_assert_not_reached (); - break; - } + if (window->cv_progress_error + || window->cv_progress_done) { + window->reset_to_idle = TRUE; + made_changes = TRUE; + } + } while (made_changes); - while (update_state (window)) { } + window->making_changes--; } static void @@ -1259,9 +1163,6 @@ nautilus_window_end_location_change_callback (NautilusNavigationResult result_co window->location_change_end_reached = TRUE; if (result_code == NAUTILUS_NAVIGATION_RESULT_OK) { - /* Navigation successful. */ - window->cancel_tag = navigation_info; - /* If the window is not yet showing (as is the case for nascent * windows), position and show it only after we've got the * metadata (since position info is stored there). @@ -1279,8 +1180,12 @@ nautilus_window_end_location_change_callback (NautilusNavigationResult result_co g_free (location); } - - change_state (window, INITIAL_VIEW_SELECTED, navigation_info, NULL); + + window->cancel_tag = navigation_info; + update_state (window); + window->pending_ni = navigation_info; + window->cancel_tag = NULL; + update_state (window); return; } @@ -1468,7 +1373,9 @@ nautilus_window_begin_location_change (NautilusWindow *window, || type == NAUTILUS_LOCATION_CHANGE_FORWARD || distance == 0); - change_state (window, STOP, NULL, NULL); + update_state (window); + window->reset_to_idle = TRUE; + update_state (window); window->location_change_type = type; window->location_change_distance = distance; @@ -1501,7 +1408,7 @@ static void stop_loading (NautilusViewFrame *view) { if (view != NULL) { - nautilus_view_frame_stop_loading (view); + nautilus_view_frame_stop (view); } } @@ -1515,22 +1422,27 @@ stop_loading_cover (gpointer data, gpointer callback_data) void nautilus_window_stop_loading (NautilusWindow *window) { + update_state (window); stop_loading (window->content_view); stop_loading (window->new_content_view); g_list_foreach (window->sidebar_panels, stop_loading_cover, NULL); - change_state (window, STOP, NULL, NULL); + window->reset_to_idle = TRUE; + update_state (window); } void -nautilus_window_set_content_view (NautilusWindow *window, NautilusViewIdentifier *id) +nautilus_window_set_content_view (NautilusWindow *window, + NautilusViewIdentifier *id) { NautilusFile *file; - NautilusViewFrame *view; g_return_if_fail (NAUTILUS_IS_WINDOW (window)); g_return_if_fail (window->location != NULL); + g_return_if_fail (window->new_content_view == NULL); g_return_if_fail (id != NULL); + update_state (window); + file = nautilus_file_get (window->location); nautilus_mime_set_default_component_for_file (file, id->iid); @@ -1538,8 +1450,9 @@ nautilus_window_set_content_view (NautilusWindow *window, NautilusViewIdentifier nautilus_window_allow_stop (window, TRUE); - view = load_content_view (window, id); - change_state (window, NEW_CONTENT_VIEW_READY, NULL, view); + load_content_view (window, id); + + update_state (window); } static int @@ -1559,7 +1472,6 @@ nautilus_window_set_sidebar_panels (NautilusWindow *window, NautilusViewFrame *sidebar_panel; NautilusViewIdentifier *identifier; const char *current_iid; - gboolean load_succeeded; g_return_if_fail (NAUTILUS_IS_WINDOW (window)); @@ -1608,14 +1520,7 @@ nautilus_window_set_sidebar_panels (NautilusWindow *window, nautilus_view_frame_set_label (sidebar_panel, identifier->name); set_view_frame_info (sidebar_panel, TRUE, identifier->name); connect_view (window, sidebar_panel); - load_succeeded = nautilus_view_frame_load_client (sidebar_panel, identifier->iid); - - /* If the load failed, tell the user. */ - if (!load_succeeded) { - report_sidebar_panel_failure_to_user (window, sidebar_panel); - disconnect_destroy_unref_view (window, sidebar_panel); - continue; - } + nautilus_view_frame_load_client (sidebar_panel, identifier->iid); /* tell panel about the location and selection, if we have them */ if (window->location != NULL) { @@ -1785,12 +1690,27 @@ change_status_callback (NautilusViewFrame *view, } static void +client_loaded_callback (NautilusViewFrame *view, + NautilusWindow *window) +{ + g_assert (NAUTILUS_IS_WINDOW (window)); + + if (view == window->new_content_view) { + window->view_activation_complete = TRUE; + } + update_state (window); +} + +static void failed_callback (NautilusViewFrame *view, NautilusWindow *window) { g_assert (NAUTILUS_IS_WINDOW (window)); - change_state (window, VIEW_FAILED, NULL, view); + g_warning ("A view failed. The UI will handle this with a dialog but this should be debugged."); + gtk_object_ref (GTK_OBJECT (view)); + window->error_views = g_list_prepend (window->error_views, view); + update_state (window); } static void @@ -1810,7 +1730,11 @@ load_underway_callback (NautilusViewFrame *view, if (view == window->new_content_view || view == window->content_view) { - change_state (window, LOAD_UNDERWAY, NULL, NULL); + update_state (window); + nautilus_window_allow_stop (window, TRUE); /* for the case where we are "re-underway" */ + window->cv_progress_initial = TRUE; + window->cv_progress_done = FALSE; + update_state (window); } } @@ -1820,14 +1744,21 @@ load_complete_callback (NautilusViewFrame *view, { g_assert (NAUTILUS_IS_WINDOW (window)); - /* We intentionally ignore progress from sidebar panels. Some - sidebar panels may get their own progress indicators - later. */ + /* FIXME bugzilla.eazel.com 2460: We intentionally ignore + * progress from sidebar panels. Some sidebar panels may get + * their own progress indicators later. + */ + + /* FIXME bugzilla.eazel.com 2461: Is progress from either old + * or new really equally interesting? + */ - /* FIXME bugzilla.eazel.com 2461: Is progress from either old or new really equally interesting? */ if (view == window->new_content_view || view == window->content_view) { - change_state (window, LOAD_DONE, NULL, NULL); + update_state (window); + g_assert (window->cv_progress_initial); + window->cv_progress_done = TRUE; + update_state (window); } } @@ -1890,6 +1821,7 @@ title_changed_callback (NautilusViewFrame *view, #define FOR_EACH_NAUTILUS_WINDOW_SIGNAL(macro) \ macro (change_selection) \ macro (change_status) \ + macro (client_loaded) \ macro (failed) \ macro (get_history_list) \ macro (load_complete) \ @@ -1938,21 +1870,6 @@ disconnect_view (NautilusWindow *window, NautilusViewFrame *view) } static void -disconnect_and_destroy_sidebar_panel (NautilusWindow *window, NautilusViewFrame *view) -{ - disconnect_view (window, view); - nautilus_window_remove_sidebar_panel (window, view); - gtk_widget_destroy (GTK_WIDGET (view)); -} - -static void -disconnect_view_and_destroy (NautilusWindow *window, NautilusViewFrame *view) -{ - disconnect_view (window, view); - gtk_widget_destroy (GTK_WIDGET (view)); -} - -static void disconnect_view_callback (gpointer list_item_data, gpointer callback_data) { disconnect_view (NAUTILUS_WINDOW (callback_data), diff --git a/src/nautilus-window.c b/src/nautilus-window.c index fa25347fe..b629df7cd 100644 --- a/src/nautilus-window.c +++ b/src/nautilus-window.c @@ -1553,9 +1553,7 @@ nautilus_window_set_content_view_widget (NautilusWindow *window, if (new_view != NULL) { gtk_widget_show (GTK_WIDGET (new_view)); - - nautilus_view_frame_activate (new_view); - + /* FIXME bugzilla.eazel.com 1243: * We should use inheritance instead of these special cases * for the desktop window. @@ -1577,7 +1575,6 @@ nautilus_window_set_content_view_widget (NautilusWindow *window, gtk_widget_hide (window->zoom_control); } - window->content_view = new_view; } diff --git a/src/nautilus-window.h b/src/nautilus-window.h index 64cd4fd34..e1fa56533 100644 --- a/src/nautilus-window.h +++ b/src/nautilus-window.h @@ -125,8 +125,6 @@ struct NautilusWindow { NautilusLocationChangeType location_change_type; guint location_change_distance; - gboolean views_shown; - gboolean view_bombed_out; gboolean view_activation_complete; gboolean sent_update_view; gboolean cv_progress_initial; diff --git a/test/test-nautilus-async-activation.c b/test/test-nautilus-async-activation.c index f0485f6b7..ba3d29406 100644 --- a/test/test-nautilus-async-activation.c +++ b/test/test-nautilus-async-activation.c @@ -19,6 +19,7 @@ Author: Mathieu Lacage <mathieu@eazel.com> */ + #ifdef HAVE_CONFIG_H #include <config.h> #endif @@ -31,36 +32,33 @@ #define IID "OAFIID:bonobo_calculator:fab8c2a7-9576-437c-aa3a-a8617408970f" - - -static void -activation_callback (CORBA_Object object_reference, gpointer data) +static void +activation_callback (NautilusBonoboActivationHandle *handle, + Bonobo_Unknown activated_object, + gpointer callback_data) { GtkWidget *window; GtkWidget *control; - CORBA_Environment exc; - window = GTK_WIDGET (data); + window = GTK_WIDGET (callback_data); - if (CORBA_Object_is_nil (object_reference, &exc)) { - /* no activation */ + if (activated_object == CORBA_OBJECT_NIL) { g_print ("activation failed\n"); - gtk_main_quit (); + } else { + control = bonobo_widget_new_control_from_objref (activated_object, + CORBA_OBJECT_NIL); + gtk_container_add (GTK_CONTAINER (window), control); + gtk_widget_show (GTK_WIDGET (control)); + + g_print ("activation suceeded\n"); } - - control = bonobo_widget_new_control_from_objref (object_reference, CORBA_OBJECT_NIL); - gtk_container_add (GTK_CONTAINER (window), control); - gtk_widget_show (GTK_WIDGET (control)); - - g_print ("activation suceeded\n"); } - - -int main (int argc, char *argv[]) +int +main (int argc, char *argv[]) { - NautilusBonoboActivate *activate; GtkWidget *window; + NautilusBonoboActivationHandle *handle; gtk_init (&argc, &argv); oaf_init (argc, argv); @@ -72,15 +70,13 @@ int main (int argc, char *argv[]) gtk_signal_connect (GTK_OBJECT (window), "destroy", gtk_main_quit, NULL); gtk_widget_show_all (GTK_WIDGET (window)); - - - activate = nautilus_bonobo_activate_from_id (IID, activation_callback, window); - + + + handle = nautilus_bonobo_activate_from_id (IID, activation_callback, window); #if 0 - nautilus_bonobo_activate_stop (activate); + nautilus_bonobo_activate_stop (handle); #endif bonobo_main (); return 0; } - diff --git a/user-guide/gnufdl/.cvsignore b/user-guide/gnufdl/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/user-guide/gnufdl/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in |