Hi! Sorry to be troublesome yet again, but I'm trying to work with gtk.UIManager--again on the Gtk2 branch--and I've stumbled across a couple issues, and I'm not sure if either are bugs, or if I'm doing something wrong.

The first is that UIManager.getWidget() returns widgets that cannot be downcast. This isn't disastrous for menubars or toolbars, that can just be added to whatever container is necessary. But for popups, it makes them unusable--Since you need the popup() and possible attachToWidget() methods. It can be worked around by using UIManager.getTopLevels(), but that's very inelegant when multiple popups are defined.

The second, is that UIManager.getToplevels(), if told to retrieve GtkUIManagerItemType.MENUBAR or .TOOLBAR, will return a null list, unless UIManager.getUi() has been called first. The return value doesn't even need to be stored; simply calling the method works.

Here's a little test program I put together that shows off the problems.

module uimanagertest;
import std.stdio;

import gtk.UIManager;
import gtk.Menu;
import gtk.MenuBar;
import gtk.Action;
import gtk.ActionGroup;
import gtk.MainWindow;
import gtk.Main;
import gtk.Window;
import gtk.Widget;
import glib.ListSG;
import gtk.Box;
import gtk.VBox;
import gtk.Button;

version (DigitalMars) {
	version (Windows) pragma (lib, "GtkD.lib");
	version (Posix) pragma (lib, "gtkd-1");
}	

class W : MainWindow {
	ActionGroup actions;
	UIManager uiman;
	Button button;
	Menu popup;
	Widget menubar;
	Widget toolbar;
	
	enum uistring = `
		<ui>
		<menubar>
			<menu action="Menu">
				<menuitem action="Click"/>
			</menu>
		</menubar>
		<popup name="Context">
			<menuitem action="Click"/>
		</popup>
		<toolbar name="Toolbar">
			<toolitem action="Click"/>
		</toolbar>
		</ui>
	`;
	
	this() {
		super("UIManager Test");
		actions = new ActionGroup("Test");
		uiman = new UIManager();
		
		auto action = new Action("Click", "Click me", "This is clickable.", StockID.ABOUT);
		action.addOnActivate((Action a) {
			writeln("I've been activated!");
		});
		actions.addAction(action);
		
		action = new Action("Menu", "Menu", "This is a placeholder.", "");
		actions.addAction(action);
		
		uiman.insertActionGroup(actions, 0);
		uiman.addUiFromString(uistring, uistring.length);
		
		auto wincontents = new VBox(false, 0);
		add(wincontents);
		
		auto button = new Button("Click me too!");
		wincontents.packEnd(button, true, true, 0);
		
		//uiman.getUi(); //If this line is commented out, an exception is thrown below. 
		ListSG menulist = uiman.getToplevels(GtkUIManagerItemType.MENUBAR);
		if (menulist is null) writeln("menulist is null");
		
		//These work, since they don't require downcasting.
		menubar = uiman.getWidget("/ui/menubar");
		wincontents.packStart(menubar, false, true, 0);
		
		toolbar = uiman.getWidget("/ui/Toolbar");
		wincontents.packStart(toolbar, false, true, 0);
		
		//This, however, doesn't work. The downcast from Widget to Menu fails.
		
		popup = cast(Menu)(uiman.getWidget("/ui/ Context"));
		if (popup is null) writeln("Returned menu is null.");
		
		//Weirdly, *this* works without calling getUi first. It's a possible
		//workaround to the getWidget() downcasting problem, but less so if there's
		//More than one popup defined.
		ListSG popuplist = uiman.getToplevels(GtkUIManagerItemType.POPUP);
		popup = new Menu(cast(GtkMenu*)(popuplist.data())); 
		
		
		popup.attachToWidget(button, null);
		button.addOnClicked((Button b) {
			popup.popup(1, 0); //The popup menu must be downcast to gtk.Menu for this to work.
		});
		
		wincontents.showAll();
		
	}
}

void main(string[] args) {
	
	Main.init(args);

	auto win = new W();
	
	win.show();
	Main.run();
}