gnome-dash-fix icon indicating copy to clipboard operation
gnome-dash-fix copied to clipboard

Completely broken for many apps

Open Yuri6037 opened this issue 3 years ago • 2 comments

On my system a lot of apps are in wrong categories or not categorized at all whereas ArcMenu or Gnome Applications Menu can do it properly:

  • Absolutely ALL wine apps are unsorted NOT a single one sorted.
  • The Document Scanner is in the wrong category: should be "Utilities" not "System Tools"
  • The Terminal should be in "Utilities" not "System Tools"
  • Your script does not even generate this "Utilities" category

It seem that your script does not respect the sorting rules applied under Ubuntu and PopOS.

Yuri6037 avatar Mar 24 '21 17:03 Yuri6037

I just found a solution to the problem but it relies on the use of libgnome-menu-3-dev and unfortunatly the simplest way to access it is by either C or Vala, so I wrote an implementation in Vala.

class Category
{
	public string name_id { get; private set; }
	public string name { get; private set; }
	public string id { get; private set; }
	public Gee.List<string> apps { get; private set; }

	public Category(string n, string i)
	{
		id = i;
		name = n;
		name_id = name.down().replace(" ", "-").replace("&", "-");
		apps = new Gee.ArrayList<string>();
	}
}

void load_category(GMenu.TreeDirectory dir, Category category)
{
	var iter = dir.iter();
	var type = GMenu.TreeItemType.INVALID; //Unfortunatly valac is stupid as hell: not even able to understand how a do while loop work!
	do
	{
		type = iter.next();
		if (type == GMenu.TreeItemType.DIRECTORY)
		{
			var subdir = iter.get_directory();
			load_category(subdir, category);
		}
		else if (type == GMenu.TreeItemType.ENTRY)
		{
			var entry = iter.get_entry();
			category.apps.add(entry.get_desktop_file_id());
		}
	}
	while (type != GMenu.TreeItemType.INVALID);
}

Gee.List<Category> load_root(GMenu.TreeDirectory dir)
{
	var unsorted = new Category("", "");
	var categories = new Gee.ArrayList<Category>();
	var iter = dir.iter();
	var type = GMenu.TreeItemType.INVALID; //Unfortunatly valac is stupid as hell: not even able to understand how a do while loop work!
	do
	{
		type = iter.next();
		if (type == GMenu.TreeItemType.DIRECTORY)
		{
			var subdir = iter.get_directory();
			var category = new Category(subdir.get_name(), subdir.get_menu_id());
			load_category(subdir, category);
			categories.add(category);
		}
		else if (type == GMenu.TreeItemType.ENTRY)
		{
			var entry = iter.get_entry();
			unsorted.apps.add(entry.get_desktop_file_id());
		}
	}
	while (type != GMenu.TreeItemType.INVALID);
	if (unsorted.apps.size > 0)
		categories.add(unsorted);
	return categories;
}

void main()
{
	try
	{
		var menu = new GMenu.Tree("applications.menu", 0);
		menu.load_sync();
		var root = menu.get_root_directory();
		var categories = load_root(root);
		var catcmd = "gsettings set org.gnome.desktop.app-folders folder-children \"[";
		var catcmds = new Gee.ArrayList<string>();
		foreach (var c in categories)
		{
			catcmd += "'" + c.name_id + "', ";
			var namecmd = "gsettings set org.gnome.desktop.app-folders.folder:/org/gnome/desktop/app-folders/folders/" + c.name_id + "/ name '" + c.name + "'";
			catcmds.add(namecmd);
			var appscmd = "gsettings set org.gnome.desktop.app-folders.folder:/org/gnome/desktop/app-folders/folders/" + c.name_id + "/ apps \"[";
			foreach (var a in c.apps)
			{
				appscmd += "'" + a + "', ";
			}
			appscmd = appscmd.substring(0, appscmd.length - 2);	
			appscmd += "]\"";
			catcmds.add(appscmd);
		}
		catcmd = catcmd.substring(0, catcmd.length - 2);
		catcmd += "]\"";
		GLib.Process.spawn_command_line_sync(catcmd);
		foreach (var cmd in catcmds)
		{
			GLib.Process.spawn_command_line_sync(cmd);
		}
	}
	catch (GLib.Error e)
	{
		print("Error code: %d\n", e.code);
		print("Error domain: %s\n", e.domain.to_string());
		print("Error message: %s\n", e.message);
	}
}

The vala compile command is a bit complicated due to an annoying #ifndef #error from GNOME: valac --pkg gee-0.8 --pkg libgnome-menu-3.0 -X -DGMENU_I_KNOW_THIS_IS_UNSTABLE -o gnome-dash-fix-fixed main.vala

In addition you need to run two commands as root before you can compile (this is only for compiling, running does not need any root commands):

  • sudo apt install libgnome-menu-3-dev
  • sudo apt install libgee-0.8-dev

Yuri6037 avatar Mar 25 '21 17:03 Yuri6037

Hi, @Yuri6037! Thanks for investigating this and finding a solution. Apologies it has taken me so long to respond to you, my semester at university just ended.

I dabbled with Vala once or twice but never wrote anything useful, this could be a great opportunity to learn more since you have written a lot of the base I would need.

BenJetson avatar May 29 '21 18:05 BenJetson