I have done it again.




    Yes, the API broke.  Skip to the bottom of this mail to figure out 
how to fix your programs.  Here's what changed this time:

	Global Changes
	--------------

	    . In the past, query_interface was implemented in Bonobo
	      by making the GtkType name match the repo ID of the
	      CORBA object (interface) which that GtkType exported.
	      Now that ORBit has CORBA_Object_is_a, we don't need to
	      use that hack anymore.  So I changed all of the type
	      names in all the bonobo_thingy_get_type functions so
	      that they are no longer repo IDs.

	      Now, this means that you need to have a new ORBit in
	      order for QI to work for you.  Which sucks because
	      Elliot hasn't release a new ORBit which has toe
	      CORBA_Object_is_a stuff in it.  Elliot?  Pwease?

	    . In the process of making that last change, I noticed
	      that most of the QI calls that we make inside Bonobo
	      actually query for interfaces inside the IDL:GNOME
	      module.  Oops!  So I changed all the QI calls to query
	      for interfaces in the Bonobo module.

	      Incidentally, this means that we were never really using
	      the CORBA_Object_is_a QI mechanism, since our QI
	      implementation checks the GtkType name first, and *then*
	      tries is_a.  But since the GtkType names were matching
	      the repo IDs we were QIing for (and the actual repo ids
	      did not match!), the is_a was never invoked.

	      It's better now.

        BonoboUIHandler Changes
        -----------------------

            . I split the UIHandler menu and toolbar code off into
              bonobo-uih-menu.c and bonobo-uih-toolbar.c.  This should
              make things more digestible, and makes it clear what the
              common code (stuff left in bonobo-ui-handler.c) is.  If
              I missed some menu/toolbar-specific stuff and left it in
              bonobo-ui-handler, please let me know.

              Note that this does not mean that I split the UIHandler
              into separate GtkObjects or separate CORBA interfaces.
              I just split the code.  That file was taking Emacs far
              too long to fontify ;-)

	      The bonobo-uih-private.h file contains all the internal
	      data structure definitions and function prototypes which
	      are common to the UIHandler .c files.

	    . I added a whole new set of functionality to shut
	      everyone up on the stupid toolbar issue.  You can now
	      add/delete/manipulate dock items remotely via the
	      UIHandler.  The code to do this is in bonobo-uih-dock.c
	      if you want to check it out.

	      There is currently a problem with reparenting controls
	      which means that, if you drag a dock containing a
	      control outside of the application, the control will
	      disappear.  More on that later.

	    . I added bonobo_ui_handler_get_app when I noticed (with
	      horror) that people were accessing the UIHandler's
	      internal data structures directly to get at the
	      GnomeApp.  I then made BonoboUIHandlerTopLevelData
	      private so that doesn't happen again.

	    . Some bugs were fixed.  It's kind of hard to remember
	      what these were, and impossible to figure out with cvs,
	      since I moved all the code to new files.

        Controls
        --------

	    . Ettore discovered a pretty obnoxious misdesign to do with
	      menu merging and BonoboControls.  In brief, the way you
	      created a control on the container side was something
	      like:

			cf = bonobo_control_frame_new ();
			bonobo_control_frame_set_ui_handler (cf, my_app_uih);
			bonobo_control_bind_to_control (cf, remote_control);

	      And then when the control wants to merge menus, it asks
	      its ControlFrame for the UIHanmdler and talks to it.
	      But the music goes into minor mode and it begins to rain
	      when the container author reorders his code thusly:

			cf = bonobo_control_frame_new ();
			bonobo_control_bind_to_control (cf, remote_control);
			bonobo_control_frame_set_ui_handler (cf, my_app_uih);

	      When the guy binds to the control, the BonoboControl
	      emits a "set_frame" signal.  It is at this point that
	      the Control will want to merge its menu/toolbar items.
	      The problem, though, is that it has no way of getting a
	      refernece to the container's UIHandler, since the
	      ControlFrame doesn't know what the UIHandler is yet.

	      It was a tossup between adding another signal
	      ("set_uih") and conflating the control_frame_new/set_uih
	      functions.  A new signal seemed like a big pain (and
	      made me question the utility of set_frame in the first
	      place) so I conflated them.

	      And herein lies the API breakage.  You now have to
	      specify your BonoboUIHandler at ControlFrame creation
	      time.  You will find a list of updated entry points at
	      the end of this mail, in an appendix I have codenamed
	      "Cheeky Monkey."

	    . Controls now create their associated BonoboUIHandler
	      automatically.  It seemed silly to require that people 
	      do this manually.  So the bonobo_control_set_ui_handler
	      call no longer exists, but bonobo_control_get_ui_handler
	      works fine.

	    . Controls can now automatically be activated.  Check out
	      bonobo_control_frame_set_autoactivate; when
	      autoactivation is turned on, Controls will automatically
	      be activated when they get focus and deactivated when
	      they lose it.  Autoactivation is off by default, but if
	      you use BonoboWidget to create your control, then it's
	      on.  

	      The activation semantics for BonoboViews are, of course,
	      different -- we use the BonoboWrapper for that still,
	      and you have to double-click on the wrapper or hit ENTER
	      on it to activate a BonoboView.

	    . Fixed a bug in BonoboControlFrame where we weren't
	      calling gdk_flush before passing the XID to the Control.
	      This is a problem because, apparently, XIDs can be
	      allocated on the client side without any communication
	      with the X server.  So if you transmit the XID from one
	      client to another, and the new client tries to use it,
	      there will be issues.  Calling gdk_flush notifies the X
	      server of the presence of the new XID.

	      I never saw this bug triggered in practice, but Federico
	      noticed it while we were trying to debug the Control
	      reparenting issue.  Speaking of which...

	    . I tried to fix reparenting in Controls.  It doesn't
	      work, at least for the dock.  See my previous mail if
	      you want to help make it work.

	    . The BonoboControlFrame now proxies GtkWidgetState
	      changes to the remote Control.  This means that if you
	      do something like:

	         c = bonobo_widget_new_control ("goad_id", ...);

		 gtk_widget_set_sensitive (c, FALSE);

	      The remote BonoboControl will be desensitized.  I had to
	      add a CORBA method to the Control interface to do this.

	      Autostate propagation is on by default, but you can
	      disable it with bonobo_control_frame_set_autostate.

	    . Controls are now capable of automatically merging and
	      unmerging menu and toolbar items when they are
	      activated.  This makes it a lot easier to implement
	      menu/toolbar merging.  It goes a little something like
	      this:

	      		control = bonobo_control_new (calc);
			bonobo_control_set_automerge (control, TRUE);
			bonobo_control_set_menus_with_data (
			      control, control_menus, calc);
			 

	      Where control_menus is a GnomeUIInfo tree.  This should
	      minimize the difficulty of Bonobizing traditional Gnome
	      applications.  You can do the same with toolbars, too.

	      Of course, using the GnomeUIInfo structures means that
	      you can't do things like embed controls in toolbars.
	      You'll still have to manually connect to the "activate"
	      signal to do that.  But you'll only have to handle the
	      activation case in your signal handler if you have
	      automerge turned on, since the automerging code
	      automatically deletes all your control's
	      toolbar/menu/dock items when it is deactivated.

        Miscellaneous Changes
        ---------------------

	    . The Bonobo::GenericFactory::supports method wasn't
	      implemented, so I filled it in.

	    . I added those NoPermission exceptions to the Stream
	      interface, but we need to fill that stuff out.

	    . I added the bonobo_object_query_local_interface method,
	      which returns a BonoboObject* instead of a CORBA_Object.
	      This should be somewhat useful, and I guess Martijn is
	      happy now :-).  The name can be debated.

	    . Fixed some small bugs.  Cleaned up some of components to
	      actually work.


Appendix A: "Cheeky Monkey"
---------------------------

How to fix your code:

    (alpha) When people created controls in the past, they typically
            did stuff like:

		      c = bonobo_control_new (widget);
		      uih = bonobo_ui_handler_new ();
		      bonobo_control_set_ui_handler (c, uih);

	    Those people need to delete the last two lines.  The
	    BonoboUIHandler is now created automatically for you.

	    The same applies to BonoboViews.

    (beta) s/IDL:GNOME/IDL:Bonobo/g

	   Remember to do this in your .gnorba files too!

    (gamma) BonoboUIHandlerTopLevelData is now a private structure.
            People were using this in the past to get direct access to
            the GnomeApp that's stored there (uih->top->app).  Bad!
            Use bonobo_ui_handler_get_app now.

    (delta) For containers, you now have to specify the UIHandler
            whenever you create a ControlFrame (or a ViewFrame).  This
            means that the following functions now take a UIHandler
            argument:

			bonobo_widget_new_control
			bonobo_widget_new_control_from_objref
			bonobo_widget_new_subdoc

			bonobo_client_site_new_view
			bonobo_client_site_new_view_full

			bonobo_view_frame_new
			bonobo_control_frame_new

            You actually have to pass a CORBA Objref in there, not the
            BonoboUIHandler* GtkObject.  So it'll look something like:

   		 view_frame = bonobo_client_site_new_view (
   			 component->client_site,
   			 bonobo_object_corba_objref (BONOBO_OBJECT (
   				 component->container->uih)));

    (epsilon) 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]