lxde/menu-cache

Non-compliance with the Desktop Menu Specification

ib opened this issue · 0 comments

ib commented

The specification says:

  1. The first pass processes elements that can match any desktop entry (i.e. <Menu> with <NotOnlyUnallocated>, which is the default).
  2. During this pass, each desktop entry is marked as allocated according to whether it was matched.
  3. The second pass processes only <Menu> elements that are restricted to unallocated desktop entries (i.e. <OnlyUnallocated>).
  4. 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.

test.zip