Porting Notes

General Guide

https://developer.gnome.org/Gnome3PortingGuide/

https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html

References need to be changed to GTK#3, can be done with the MonoDevelop GTK# integration settings option menu.

MonoDevelop now has a GTK# 3 starter template available, use the add-in manager to download it.

See http://nullreference.me for the biggest and best list of blog posts from the hackfest.

GTK#3 2.99.1 beta release: http://lists.ximian.com/pipermail/gtk-sharp-list/2013-September/011323.html

GTK#3 packages for Ubuntu: https://launchpad.net/~meebey/+archive/mono-preview

Existing Ported Applications

Partially Ported Applications

  • Pinta
  • F-Spot

Known Type/Method Changes

  • All interfaces are now prefixed with an I
    • Gtk.TreeModel -> Gtk.ITreeModel

  • Gtk.Dialog.HasSeparator property has been removed, dialogs always have a separator

  • Gtk.Dialog.VBox -> Gtk.Dialog.ContentArea

  • Gtk.Table -> Gtk.Grid

  • Gtk.StatusIcon.Tooltip -> Gtk.StatusIcon.TooltipText (Or any other widget with a tooltip)

  • Gtk.Box.PackStart(widget) -> Gtk.Box.PackStart(widget, false, false, 0)

  • new Gtk.ComboBoxEntry() -> Gtk.ComboBox.NewWithEntry()

  • Gtk.Spinner -> Remove your own spinner implementations!

  • Gtk.Label -> Use <a href=""></a> in .Markup to create links and remove your link implementation.

  • Widget.State = Gtk.StateType.Normal -> Widget.SetStateFlags (Gtk.StateFlags.Normal, true);

  • Gtk.TagAppliedArgs : args.StartChar -> args.Start

  • Gtk.Widget.HideAll() -> Gtk.Widget.Hide()

  • Resize grips have moved from Statusbar to Window : status_bar.HasResizeGrip = true; -> HasResizeGrip = true;

  • Replace GLib.Signal.Lookup (this, "name").AddDelegate (handler) by AddSignalHandler ("name", handler). Similar for RemoveDelegate.

Major API Breakages

All drawing is now with Cairo, most everything Gdk has been removed.

RulerWidget has been removed.

For custom widgets: as mentioned in the general porting guide, OnExposeEvent (Gdk.Window) (absolute coordinate) has been replaced by Draw (Cairo.Context cr) (relative coordinate)

GetSize () has been replaced with public override void OnGetPreferredWidth (out int width) and equivalent for height

Behavior Changes

  • For the mouse scroll wheel to work with a custom widget, you now need to set the ScrollMask EventMask:

    • WindowAttr attributes = new WindowAttr ();

      attributes.EventMask = (int)(EventMask.ScrollMask);

Settings Changes

Migrate from GConf to GSettings, in package gio-sharp

See https://developer.gnome.org/gio/2.38/ch31.html for general overview.

If your app has a GConf schema (was optional, is mandatory in GSettings), you can convert it with https://developer.gnome.org/gio/2.38/ch31s06.html

To manually install a schema:

  • sudo cp data/org.gnome.tomboy.gschema.xml /usr/share/glib-2.0/schemas/ && sudo glib-compile-schemas /usr/share/glib-2.0/schemas/

See Tomboy (gtk3-dev branch) or Banshee for makefile integration and translation of schemas.

Migrating from Stetic to GtkBuilder

Stetic, the GUI development tool of MonoDevelop, doesn't support GTK+ 3.x for now. The easiest solution is to use GtkBuilder instead.

Both Smuxi and Mono.Addins did this. Pinta should have done this! The GTK#3 Start project add-in for MonoDevelop uses this approach.

Take the old gui.stetic file and use an xslt transformer with this: https://github.com/xDarkice/stetic2ui

The new .ui files need to be opened and saved once in glade to get rid of properties that no longer exist. They will also probably need some manual tweaking for fill/expand properties. Some people have experienced them not working in glade, but working anyway with GtkBuilder! In the project they should be added as embedded resources.

Rename the gtk-ui folder to stop MonoDevelop from trying to use Stetic on everything there. Remove the partial modifier from your classes since they are no no longer combined with auto-generated classes. Add this statement: using UI = Gtk.Builder.ObjectAttribute; then define all the objects that you reference in your no-longer partial class, i.e. [UI] Entry pathEntry; etc. Manually wire all of your button listeners etc.

Example of a new independent window opening a dialog wired with GtkBuilder, where the dialog has some custom widgets (custom widgets are represented in ui files with boxes without children):

  public static Gtk.Window Show (Gtk.Window parent)
  {
        Gtk.Builder builder = new Gtk.Builder (null, "Mono.Addins.GuiGtk3.interfaces.AddinManagerDialog.ui", null);
        AddinManagerDialog dlg = new AddinManagerDialog (builder, builder.GetObject ("AddinManagerDialog").Handle);
        InitDialog (dlg);
        parent.Add (dlg);
        dlg.Show ();
        return dlg;
  }

  public AddinManagerDialog (Builder builder, IntPtr handle): base (handle)
  {
        builder.Autoconnect (this);
        addininfoGallery = new AddinInfoView ();
        addininfoGallery.InstallClicked += OnInstallClicked;
        addininfoGallery.UninstallClicked += OnUninstallClicked;
        addininfoGallery.UpdateClicked += OnUpdateClicked;
        addininfoGallery.EnableDisableClicked += OnEnableDisableClicked;
        eventbox1.Child = addininfoGallery;

        ...

        //Wiring more buttons
        buttonUpdateAll.Clicked += OnUpdateAll;
        buttonRefreshUpdates.Clicked += OnButtonRefreshClicked;
        buttonRefresh.Clicked += OnButtonRefreshClicked;
        buttonInstallFromFile.Clicked += OnButtonInstallFromFileClicked;
        repoCombo.Changed += OnRepoComboChanged;

        ...

        ShowAll ();
  }

It is important to call ShowAll() at the end of the constructor

Example of an independent custom widget that doesn't get constructed by a parent window:

  public AddinInfoView ()
  {
        Builder builder = new Gtk.Builder (null, "Mono.Addins.GuiGtk3.interfaces.AddinInfoView.ui", null);
        builder.Autoconnect (this);
        Add ((Box) builder.GetObject ("AddinInfoView"));
        AllowInstall = true;
        titleWidth = labelName.SizeRequest ().Width;
        
        ...

        //Enable our buttons for clicking
        btnDisable.Clicked += OnBtnDisableClicked;
        btnInstall.Clicked += OnBtnInstallClicked;
        btnUninstall.Clicked += OnBtnUninstallClicked;
        btnUpdate.Clicked += OnBtnUpdateClicked;
        urlButton.Clicked += OnUrlButtonClicked;

        ShowAll ();
  }

Hackfests/dotNET2013/PortingNotes (last edited 2014-12-16 06:44:18 by JordiMas)