Page 1 of 1

In regards to desktop launchers and the startup notification protocol

Posted: 2020-10-24, 19:43
by EMH_Mark_I
Hello all,

Apologies for this long post.

There was a recent thread on the forum that was reporting an issue of “duplicate” icons seen in panel dock bars on Linux desktops.
viewtopic.php?f=37&t=25344

After speaking with Steve I learned that the launcher is part of the official branding of Pale Moon (Oops; Sorry Steve!) So my feeble ambling lead to rediscovering this thread reporting the same issue which some of you may recall.
viewtopic.php?f=37&t=24090

Then of course the reported issue itself on the repo.
https://repo.palemoon.org/MoonchildProd ... ssues/1781

The PR was later reverted since there were some unanswered questions and concern around the use of quotations (or a lack thereof being requested) and letter cases in the StartupWMClass key value.
https://repo.palemoon.org/MoonchildProd ... bd420b7374

“patch will be backed out until such time as someone can provide conclusive answers to the questions asked.”

------------------------------------------------

Hopefully I can help provide some conclusive answers as well as invoke some insight or input by those of you reading. First off a visual demonstration should help clarify exactly the issue.

This is an example of how pinned applications in a dock bar are expected to function (click the image to play the gif):
Expected behaviour
Expected behaviour
This is a demonstration of how Pale Moon currently functions (click the image to play the gif):
Undesirable behaviour
Undesirable behaviour
Notice how the dockbar treats Pale Moon as a separate unrelated process independent of the launcher it was initially launched from? So far I have only observed this from the GNOME and Unity (now defunct) desktop environment dockbars. A first conclusion would be to assume that it's the fault of the GNOME dockbar, which is probably not too far off, if at all correct.

After looking at a few other dockbar applications this morning (mate-dock-applet, KDE taskmanager, Cinnamon, Plank, and DockBarX) I've realized that only the GNOME and Unity desktop environments are having this issue. I suspect the reason GNOME is behaving in this manner is due to a combination of their launching system (in how it handles grouping opened applications based upon the StartupWMclass key value), and the key value itself in the .desktop launcher code possibly being incorrectly formatted.

I believe that the other desktop environments and dockbar applications are pursuing a heuristic approach to independently handle application grouping whereas GNOME and Unity rely on the application authors to adhere to some additional specifications for integration. (In other words, GNOME wants things correct all the way through while other desktops might try to pickup the slack in corrupt launcher metadata.)

Regardless of this being specific to GNOME, I’ve spent some time and read up on the desktop entry specification to narrow some of it down to present here.

Recognized desktop entry keys: https://specifications.freedesktop.org/ ... 01s06.html

The StartupNotify and StartupWMClass keys are described as being part of the startup notification protocol. Here is a snippet of their documentation covering key-value pairs:

------------------------------------------------

The specific strings sent during startup notification encode a message type, followed by a list of key-value pairs. Here is an example:

Code: Select all

new: NAME="Hello World" PID=252
The startup notification spec describes that a string listing key-value pair works as follows:
  • The entire string must be valid UTF-8. Invalid strings should be discarded as corrupt, as accepting bad data leads to interoperability problems. (Learn from web browsers.)

    Although the string is UTF-8, parsing is specified in terms of bytes not characters in the below specification.
  • All bytes up to the first ':' byte indicate the type of the message. If the message contains no ':' byte it should be discarded as corrupt.
  • To find the start of a key, the ':' byte delimiting the message type must be skipped. Any space (' ') bytes following it must also be skipped. (Other kinds of whitespace must not be skipped.) The first non-' ' byte after the ':' byte is the start of the first key.
  • All bytes until the next '=' byte form the name of the key. The '=' byte should be discarded, as it delimits the key from the value.
  • Parsing of the value begins with the byte immediately following the '=' byte. The value is parsed as follows.

    There are two dimensions, "escaped" and "quoted", creating 4 states:
    • escaped = TRUE quoted = TRUE
      . the current byte is appended literally, and the escaped flag is set to FALSE
    • escaped = TRUE quoted = FALSE
      . the current byte is appended literally, and the escaped flag is set to FALSE
    • escaped = FALSE quoted = FALSE
      . if the current byte is a double quote '"' it is discarded, and the quoted flag is set to TRUE
      . if the current byte is a backslash '\', it is discarded, and the escaped flag is set to TRUE
      . if the current byte is a space ' ' byte or nul byte, the end of the value has been reached
      . any other byte, INCLUDING tabs, newlines, etc., must be appended literally.
    • escaped = FALSE quoted = TRUE:
      . if the current byte is a double quote '"' it is discarded, and the quoted flag is set to FALSE
      . if the current byte is a backslash '\' it is discarded, and the escaped flag is set to TRUE
      . otherwise the current byte is appended literally
    If a nul byte is seen in a state other than escaped = FALSE quoted = FALSE, it is an error, and the message should be discarded as corrupt.

    Note that the escaping here is simpler than either C string literal escaping, or shell quoting. Unlike C string literals, "\n" means "the letter n," not "newline"; unlike quoted shell strings, "\e" means "the letter e," not "backslash followed by the letter e."

    Note that an empty string can be represented by simply not including a value before the first whitespace, as in FOO:

    Code: Select all

    FOO= NAME=Hello
    or by empty quotes as in BAR:

    Code: Select all

    BAR="" NAME=Hello
  • Once the end of the value has been reached, any space (' ') bytes should be skipped. The first non-' ' byte is the first byte of the next key.

    Note that keys are case-sensitive, Foo and FOO are different keys.
------------------------------------------------

I hope that this helps in explaining how the quotes and whitespaces are being parsed. It’s also mentioned in the spec that the StartupWMClass can be provided the "WM class" or "WM name" hint string of the application. You can obtain this information with “xprop WM_CLASS” from a terminal, then selecting the Pale Moon window with your pointer.

To wrap this all up, the key values in a .desktop launcher file are parsed in terms of bytes not characters and quoted values are appended literally.

With the quotes removed and correct letter case applied for StartupWMclass, this will provide better integration with the GNOME desktop. A concern of this however is how other desktops might react to this change? Would any of you here in the Linux board have some additional insight if this would be a welcomed change or perhaps something that could cause havoc? So far I've tested this without issue from MATE, KDE, XFCE, Cinnamon, and GNOME.

One more thing to note, the freedesktop project has described a standard for the desktop entry specification, however it is up to the desktop environments as to whether or not they should follow that standard. (A distributions adherence of the spec would be dependent upon the desktop(s) they have chosen.)

From my own experience, most of the Linux desktop environments I've seen are XDG compliant; XDG being "X Desktop Group" which was the former name of the Freedesktop project. This is all likely to change as well with the advent of Wayland in the near future.

Thanks for reading!

References:
https://specifications.freedesktop.org/ ... index.html
https://specifications.freedesktop.org/ ... on-0.1.txt
https://specifications.freedesktop.org/ ... 01s07.html