Non-compliance with the Desktop Menu Specification
ib opened this issue · 0 comments
The specification says:
- The first pass processes elements that can match any desktop entry (i.e.
<Menu>
with<NotOnlyUnallocated>
, which is the default). - During this pass, each desktop entry is marked as allocated according to whether it was matched.
- The second pass processes only
<Menu>
elements that are restricted to unallocated desktop entries (i.e.<OnlyUnallocated>
). - During the second pass, queries may only match desktop entries that were not marked as allocated during the first pass.
menu-cache, however, already allocates for all <Menu>
during the first pass and removes entries in the second pass from such <Menu>
with <OnlyUnallocated>
, which leads to wrong results.
Let's run a test case (all files attached) in /tmp/test
.
The menu (only the essential parts):
<Menu>
<Name>Menu1</Name>
<Directory>1.directory</Directory>
<Include>
<And>
<Category>One</Category>
<Not><Category>Three</Category></Not>
</And>
</Include>
</Menu>
<Menu>
<Name>Menu2</Name>
<Directory>2.directory</Directory>
<OnlyUnallocated/>
<Include>
<Not><Category>Foo</Category></Not>
</Include>
</Menu>
<Menu>
<Name>Menu3</Name>
<Directory>3.directory</Directory>
<OnlyUnallocated/>
<Include>
<Category>Three</Category>
</Include>
</Menu>
The test application:
[Desktop Entry]
Type=Application
Name=Test
Categories=One;Three;
In the first pass, the application is not allocated to Menu1 (which is correct), but to Menu3 (which is wrong, because this one is defined <OnlyUnallocated>
, thus a second pass <Menu>
).
In the second pass, the unallocated application was supposed to be allocated to Menu2, but instead it ends up in Menu3.
Here is the (truncated) debug output:
... entering Menu1 (1 dirs 1 apps)
found dir file /tmp/test/1.directory
... do matching
check test.desktop in /tmp/test: 1
menu_app_match_tag: entering <And>
menu_app_match_tag: entering <Category>
menu_app_match_tag test.desktop: leaving <Category>: 1
menu_app_match_tag: entering <Not>
menu_app_match_tag: entering <Category>
menu_app_match_tag test.desktop: leaving <Category>: 1
menu_app_match_tag test.desktop: leaving <Not>: 0
menu_app_match_tag test.desktop: leaving <And>: 0
... compose (available=0)
composing Merge type 2
composing Merge type 1
... cleanup
... done Menu1
+++ composing menu Menu1 (Menu1)
No match. Okay.
... entering Menu2 (1 dirs 1 apps)
Already wrong during the first pass.
found dir file /tmp/test/2.directory
... do matching
check test.desktop in /tmp/test: 1
menu_app_match_tag: entering <Not>
menu_app_match_tag: entering <Category>
menu_app_match_tag test.desktop: leaving <Category>: 0
menu_app_match_tag test.desktop: leaving <Not>: 1
found match: test.desktop excluded:0
Now the application is allocated, which is wrong.
... compose (available=1)
composing Merge type 2
composing Merge type 1
+++ composing app test.desktop
... cleanup
... done Menu2
+++ composing menu Menu2 (Menu2)
... entering Menu3 (1 dirs 1 apps)
Already wrong during the first pass.
found dir file /tmp/test/3.directory
... do matching
check test.desktop in /tmp/test: 1
menu_app_match_tag: entering <Category>
menu_app_match_tag test.desktop: leaving <Category>: 1
found match: test.desktop excluded:0
As wrong as for Menu2 above.
... compose (available=1)
composing Merge type 2
composing Merge type 1
+++ composing app test.desktop
... cleanup
... done Menu3
+++ composing menu Menu3 (Menu3)
composing Merge type 1
... cleanup
... done Applications
stage 2: entered 'Applications'
stage 2: entered 'Menu1'
stage 2: counted 'Menu1': 0
stage 2: entered 'Menu2'
removing from Menu2 as only_unallocated test.desktop
It should not have been allocated to Menu3 at all!
stage 2: counted 'Menu2': 0
stage 2: entered 'Menu3'
stage 2: counted 'Menu3': 1
stage 2: counted 'Applications': 1
stage 2: deleting empty 'Menu2'
stage 2: deleting empty 'Menu1'
In the end, the application is in the wrong <Menu>
(3 instead of 2).
BTW, the xfce menu builder does it right.