Skip to content

Non-compliance with the Desktop Menu Specification #22

@ib

Description

@ib

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions