OSX Xboard 4.7.2 .app

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

JoshPettus
Posts: 730
Joined: Fri Oct 19, 2012 2:23 am

Re: OSX Xboard 4.7.2 .app

Post by JoshPettus »

AFAIK it is all part of the libgtkmacintegration.2.dylib library located for me in the macports /opt/local/lib folder. There isn't a static version of this, does there need to be?

I put

Code: Select all

xboard_LDADD = -lm /opt/local/lib/libgtkmacintegration.2.dylib @FRONTEND_LIBS@ @X_LIBS@ @LIBINTL@ @CAIRO_LIBS@
But that didn't seem to cut it.

I'm not worried about location as the dylibbundler will copy it and link it to the executable inside the app bundle later.[/code]
JoshPettus
Posts: 730
Joined: Fri Oct 19, 2012 2:23 am

Re: OSX Xboard 4.7.2 .app

Post by JoshPettus »

I got it to compile!

I wound up appending this to LDFLAGS

Code: Select all

-lgtkmacintegration
Which is fine as I also have to put commands to have it compile for 10.6 there anyway.
-------------------
Bravo!
This is definitely a great start. It copied all the menubar to the native menubar and everything functions, even the shortcuts!. Unfortunately it didn't hide the old one, but one step at a time :). After we get it to hide we need to remove the duplicate quit in under the file menu and move About Xboard from help to the Application (Xboard) menu.

Image[/code]
User avatar
hgm
Posts: 27796
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: OSX Xboard 4.7.2 .app

Post by hgm »

Hmm, strange that the gtk_widget_hide(menuBar) doesn't seem to have any effect. But we could of course prevent it from becoming part of the main window to start with. The examples are all based on the idea that you could not alter anything in the original creation of the window by GTK, so that you had to undo part of it later by hiding the stuff you did not want. But in XBoard the creation is not hidden inside the interpretation of some .xml file by some library routine, and we have direct access to the routine that does the creation.

So for the menu bar, we can comment out the gtk_table_attach in the BarEnd case just above the new code, by prefixing it with // . You might also add an extra 'top--;' there. ('top' is a counter that counts the number of rows in the table. By default it is incremented for every Option encountered in the description table (mainOptions in dialogs.c in our case). So for options that go onto the same row as a previous one it has to be decremented again, and DropDown and BarEnd belong to the same row as BarBegin. But if even BarBegin does not require a row, because we want to suppress the menu bar completely, we have to undo the increment of 'top' for that one too. 'top--;' subtracts 1 from top. Not sure this is important, however; GTK might be smart enough to collapse a table row with nothing on it to zero height anyway.)

To remove the Quit item from the file menu, you could simply delete (or comment out) the corresponding line from the 'fileMenu' description table in menus.c:

Code: Select all

MenuItem fileMenu[] = {
  &#123;N_("New Game"),             "<Ctrl>n",          "NewGame",              ResetGameEvent&#125;,
  &#123;N_("New Shuffle Game ..."),  NULL,              "NewShuffleGame",       ShuffleMenuProc&#125;,
  &#123;N_("New Variant ..."),      "<Alt><Shift>v",    "NewVariant",           NewVariantProc&#125;,// &#91;HGM&#93; variant&#58; not functional yet
  &#123;"----",                      NULL,               NULL,                  NothingProc&#125;,
  &#123;N_("Load Game"),            "<Ctrl>o",          "LoadGame",             LoadGameProc,           CHECK&#125;,
  &#123;N_("Load Position"),        "<Ctrl><Shift>o",   "LoadPosition",         LoadPositionProc&#125;,
  &#123;N_("Next Position"),        "<Shift>Page_Down", "LoadNextPosition",     LoadNextPositionProc&#125;,
  &#123;N_("Prev Position"),        "<Shift>Page_Up",   "LoadPreviousPosition", LoadPrevPositionProc&#125;,
  &#123;"----",                      NULL,               NULL,                  NothingProc&#125;,
  &#123;N_("Save Game"),            "<Ctrl>s",          "SaveGame",             SaveGameProc&#125;,
  &#123;N_("Save Position"),        "<Ctrl><Shift>s",   "SavePosition",         SavePositionProc&#125;,
  &#123;N_("Save Games as Book"),    NULL,              "CreateBook",           CreateBookDelayed&#125;,
  &#123;"----",                      NULL,               NULL,                  NothingProc&#125;,
  &#123;N_("Mail Move"),             NULL,              "MailMove",             MailMoveEvent&#125;,
  &#123;N_("Reload CMail Message"),  NULL,              "ReloadCMailMessage",   ReloadCmailMsgProc&#125;,
  &#123;"----",                      NULL,               NULL,                  NothingProc&#125;,
  &#123;N_("Quit "),                "<Ctrl>q",          "Quit",                 QuitProc&#125;,
  &#123;NULL,                        NULL,               NULL,                  NULL&#125;
&#125;;
And also the line above it, to get rid of the separator.

This is a bit of a dubious solution, however, as menu.c is supposed to be shared between all front-ends (while xoptions.c in principle could be completely different, and resides in subdirectories .../xaw/, .../gtk/ and possibly .../osx/). Alternatives would be to use the strategy of the example, let GTK create the item as usual, and then hide it afterwards (when it gets to the BarEnd). For the menu bar the hide did not seem to work, however. Yet another way would be to intercept the item in the routine that creates menus, and suppress its creation there. This makes it more difficult to suppress the menu separator above it as well, though.

Let's try this last method

Code: Select all

static GtkWidget *
CreateMenuPopup &#40;Option *opt, int n, int def&#41;
&#123;   // fromList determines if the item texts are taken from a list of strings, or from a menu table
    int i;
    GtkWidget *menu, *entry;
    MenuItem *mb = &#40;MenuItem *) opt->choice;

    menu = gtk_menu_new&#40;);
//    menu = XtCreatePopupShell&#40;opt->name, simpleMenuWidgetClass, parent, NULL, 0&#41;;
    for &#40;i=0; 1; i++)
      &#123;
        char *msg = mb&#91;i&#93;.string;
        if&#40;!msg&#41; break;
        if&#40;!strcmp&#40;msg, "Quit")) continue; // ADDED
        if&#40;!strcmp&#40;msg, "----") && !strcmp&#40;mb&#91;i+1&#93;.string, "Quit")) continue; // ADDED
        if&#40;strcmp&#40;msg, "----")) &#123; //
          if&#40;!&#40;opt->min & NO_GETTEXT&#41;) msg = _&#40;msg&#41;;
The two lines with the trailing comment '// ADDED' have been added to make it ignore any item named 'Quit' (first line) and any separator followed by an item named 'Quit' (second line). More such lines could be added to suppress the creation of other items.
JoshPettus
Posts: 730
Joined: Fri Oct 19, 2012 2:23 am

Re: OSX Xboard 4.7.2 .app

Post by JoshPettus »

Ok I got the menu to disappear finally, just to make sure this was what you meant

Code: Select all

  case BarEnd&#58;
    top--;
//    gtk_table_attach&#40;GTK_TABLE&#40;table&#41;, menuBar, left, left+r, top, top+1, GTK_FILL | GTK_EXPAND, GTK_FILL, 2, 1&#41;;
    top--;

    if&#40;option&#91;i&#93;.target&#41; (&#40;ButtonCallback*&#41;option&#91;i&#93;.target&#41;&#40;boxStart&#41;; // callback that can make sizing decisions
    &#123;
      GtkosxApplication *theApp = g_object_new&#40;GTKOSX_TYPE_APPLICATION, NULL&#41;;
      gtk_widget_hide &#40;menuBar&#41;;
      gtkosx_application_set_menu_bar&#40;theApp, GTK_MENU_SHELL&#40;menuBar&#41;);
      gtkosx_application_ready&#40;theApp&#41;;
    &#125;
    break; 

Unfortunately your added lines didn't capture the quit and the separator. :(
You were right, simply commenting them out in the table works. But if you can think of another method or why it may have failed I'd be happy to go with that.

One day I'd like to look into put all this in, not as a patch + manual cobble, but some sort of actual automated build script for the app bundle. I have seen other projects do it, usually with cmake. It would be a heck of a lot of work, but it should be possible. GNU's jhbuild is suppose to be able to do all this, but for the life of me I can't get it to work, and I'm done trying. (each attempt takes a good 4 hours out of my life) It just won't compile properly. Macports at least has the benefit of a large mac community to test things out, so things tend to compile nicely with little effort. At least with this method, so far, it doesn't matter how GTK is installed; if xboard compiles, it will work.
User avatar
hgm
Posts: 27796
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: OSX Xboard 4.7.2 .app

Post by hgm »

At the moment we are still exploring what is actually needed to get what we want. Once we know that, we can integrate it in the XBoard sources (for as far as it concerns building XBoard).

Because it seems only very few changes are needed compared to the regular GTK version, my thought is that there could probably be an extra option on ./configure, namely --with-OSX. This would basically do the GTK build, but with some extra compiler flags. One of the flags would be -DOSX to define the OSX symbol, so that we could use

#ifdef OSX
#endif

to enclose any code that should only be compiled for OSX version (and #ifndef OSX for code that needs to be selectively removed, such as the Quit menu item in menus.c)

[Edit] Oh, I think I understand why the lines did not work. The message on the Quit menu item was "Quit " (with an extra space at the end), and the added lines checked if it was "Quit" (without space). Perhaps you should try if it works without removing the Quit entry from the fileMenu table, after you correct that.
User avatar
hgm
Posts: 27796
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: OSX Xboard 4.7.2 .app

Post by hgm »

You could similarly suppress the About item by writing some lines below the test for "Quit":

Code: Select all

        &#125; else entry = gtk_separator_menu_item_new&#40;);
        if&#40;strcmp&#40;msg, "About XBoard")) // ADD
        gtk_menu_append&#40;GTK_MENU &#40;menu&#41;, entry&#41;;
        else &#123; // ADD this and next 5 lines
          GtkosxApplication *theApp = g_object_new&#40;GTKOSX_TYPE_APPLICATION, NULL&#41;;
          gtkosx_application_add_app_menu_item  &#40;theApp,
                     gtkosx_application_add_app_menu_group &#40;theApp&#41;,
                                        GTK_MENU_ITEM &#40;entry&#41;);

        &#125;
Unlike with Quit, this proceeds to create the menu item, but once it has it, it does not append it to the GTK menu if it was the About item, but to the App menu instead, as a new menu group.
JoshPettus
Posts: 730
Joined: Fri Oct 19, 2012 2:23 am

Re: OSX Xboard 4.7.2 .app

Post by JoshPettus »

With the patch It would take some consideration as to what to incorporate immediately and what is only useful for building the native app. It is up to the user to decide if they want to go with the Xaw interface (which requires the X11.app to be installed), Gtk2 with X11 (same thing) or Gtk2 with Quartz

A couple things I'm sure you would want to incorporate in the code would be:
Replace a few commands with OSX equivalents:
xdg-open->open
aplay -q->afplay (though this is in the master conf)

And the menu integration with GTK
probably have to add a check for gtkmacintegration/gtkosxapplication.h and libgtkmacintegration-dylib

-----
For my app, I wanted to nix the xterm calls with man and info as X11.app no longer comes pre-installed on the OS. The built in Terminal.app can deal with this but you can't pass it command line arguments. :( The main way to do this for mac users is to use the ever confusing Apple Script which can handle apple events. But as far as I know, though limited, you can't put that into the source code. My method is to have InfoProc and ManProc open .command scripts pointing to the info and man.6. OSX automatically opens Terminal.app when opening .command shell scripts. But I don't know if you guys would like this. It's great for the app but I'd understand if you'd want to leave the xterm calls.

The rest is directory shoehorning that has no place in a normal xboard install but required for xboard to find it's resources inside the app bundle.
JoshPettus
Posts: 730
Joined: Fri Oct 19, 2012 2:23 am

Re: OSX Xboard 4.7.2 .app

Post by JoshPettus »

Excellent now quit is moved properly. (i made sure I removed the comments out of the table)

I'm sorry, where in between should I put the About passage?
I seem to be putting it odd places. :oops:

Code: Select all

	  &#125;;
	  gtk_widget_show&#40;entry&#41;;
	&#125; else entry = gtk_separator_menu_item_new&#40;);
  	if&#40;strcmp&#40;msg, "About XBoard")) // ADD 
	gtk_menu_append&#40;GTK_MENU &#40;menu&#41;, entry&#41;;
	else &#123; // ADD this and next 5 lines
          GtkosxApplication *theApp = g_object_new&#40;GTKOSX_TYPE_APPLICATION, NULL&#41;;
          gtkosx_application_add_app_menu_item  &#40;theApp,
                     gtkosx_application_add_app_menu_group &#40;theApp&#41;,
                                        GTK_MENU_ITEM &#40;entry&#41;);

        &#125; 
//CreateMenuItem&#40;menu, opt->min & NO_GETTEXT ? msg &#58; _&#40;msg&#41;, &#40;XtCallbackProc&#41; ComboSelect, &#40;n<<16&#41;+i&#41;;
	mb&#91;i&#93;.handle = &#40;void*) entry; // save item ID, for enabling / checkmarking
//	if&#40;i==def&#41; &#123;
//	    XtSetArg&#40;arg, XtNpopupOnEntry, entry&#41;;
//	    XtSetValues&#40;menu, &arg, 1&#41;;
//	&#125;
      &#125;
      return menu;
&#125;
correct?

I now get

Code: Select all

Undefined symbols for architecture x86_64&#58;
  "_gtkosx_application_add_app_menu_group", referenced from&#58;
      _CreateMenuPopup in xoptions.o
  "_gtkosx_application_add_app_menu_item", referenced from&#58;
      _CreateMenuPopup in xoptions.o
Which should have been part of the library it scanned..
JoshPettus
Posts: 730
Joined: Fri Oct 19, 2012 2:23 am

Re: OSX Xboard 4.7.2 .app

Post by JoshPettus »

Hmm, I see the routine listed in the example on
http://gtk-osx.sourceforge.net/gtk-mac- ... ation.html

But nowhere else...
User avatar
hgm
Posts: 27796
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: OSX Xboard 4.7.2 .app

Post by hgm »

That is weird. I tried Google, and found this page. This mentions a routine

gtk_application_set_app_menu()

in the standard GTK repertoire (so not specifically gtkosx). It shows a screenshot of OS X, however, and seems to do what we want in a platform-independent way. But this is for GTK+ v3. So perhaps the GTK-OSX library you are using is intended for use with GTK+ v3, and assumes that the function is no longer needed, as it already exists in standard GTK...

You could try if this alternative works in your case.