Bug 431821 - Task Manager is not reflecting dynamic WM_CLASS changes
Summary: Task Manager is not reflecting dynamic WM_CLASS changes
Status: RESOLVED INTENTIONAL
Alias: None
Product: plasmashell
Classification: Plasma
Component: Task Manager and Icons-Only Task Manager (show other bugs)
Version: master
Platform: Other Linux
: NOR normal
Target Milestone: 1.0
Assignee: Eike Hein
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-01-19 17:18 UTC by Ivo Šmerek
Modified: 2023-03-17 16:48 UTC (History)
3 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ivo Šmerek 2021-01-19 17:18:10 UTC
We encountered a problem with WM_CLASS changing dynamically while the application is running, described here: https://github.com/BlueManCZ/SIF/issues/16. I would expect the Task Manager to dynamically change an icon associated with .desktop file according to the new WM_CLASS as "Dash to Dock" or "Plank" do.

STEPS TO REPRODUCE
1. Run an application
2. Change its WM_CLASS in runtime with xprop

OBSERVED RESULT
Task manager does not change the icon of the application.

EXPECTED RESULT
Task manager should adapt the application icon to the new WM_CLASS.
Comment 1 David Redondo 2021-01-20 08:36:47 UTC
Documentation of WM_CLASS says:

> This property must be present when the window leaves the Withdrawn state and may be changed only while the window is in the Withdrawn state. Window managers may examine the property only when they start up and when the window leaves the Withdrawn state, but there should be no need for a client to change its state dynamically.

Are you going through Withdrawn?
Comment 2 Ivo Šmerek 2021-02-01 13:58:13 UTC
(In reply to David Redondo from comment #1)
> Documentation of WM_CLASS says:
> 
> > This property must be present when the window leaves the Withdrawn state and may be changed only while the window is in the Withdrawn state. Window managers may examine the property only when they start up and when the window leaves the Withdrawn state, but there should be no need for a client to change its state dynamically.
> 
> Are you going through Withdrawn?

I probably need a little guidance here. What is Withdrawn state and how can I go through it?

I change WM_CLASS of target application with this command and I use it only for applications with missing WM_CLASS.

> xprop -name "something" -f WM_CLASS 8s -set WM_CLASS "new wm class"
Comment 3 David Redondo 2021-02-01 14:10:04 UTC
If I read the spec correctly the window manager can assume that WM_CLASS of a window basically never changes once it is mapped. So I assume that when you use xprop it is to late because the window is mapped. See

https://www.x.org/releases/X11R7.6/doc/xorg-docs/specs/ICCCM/icccm.html#wm_class_property
and 
https://www.x.org/releases/X11R7.6/doc/xorg-docs/specs/ICCCM/icccm.html#changing_window_state
Comment 4 Ivo Šmerek 2021-02-01 14:39:41 UTC
I understand, but I'm looking for a way how to add a WM_CLASS to the window, which has this property missing from the start. I guess I can't force a window to go to the withdrawn state and back?

As I said, this xprop workaround works fine with Gnome dash and Plank task managers. Devs probably implemented something differently?

Couldn't Plasma task manager improve a way how windows with missing WM_CLASS property are handled? I mean, maybe keep checking them and if WM_CLASS appears, map them again and then stop checking?
Comment 5 Ivo Šmerek 2021-02-01 17:14:16 UTC
I tried to change WM_CLASS and then WM_STATE property of the window with xprop to Withdrawn and back to Normal.

To Withdrawn:
> xprop -f WM_STATE 32ih -set WM_STATE "0,0"

To Normal:
> xprop -f WM_STATE 32ih -set WM_STATE "1,0"

The property changes according to xprop, but Task Manager seems to not detect the change. It does not work like this?
Comment 6 David Redondo 2021-02-02 08:18:21 UTC
I took a look at the taskmanager code and actually it seems we support changing WM_CLASS
https://invent.kde.org/plasma/plasma-workspace/-/blob/master/libtaskmanager/xwindowtasksmodel.cpp#L327 

However the way we seem to resolve info depends on a bunch of other properties,
do you have a simple example/testcase where you think WM_CLASS changing should change the result?
Comment 7 Ivo Šmerek 2021-02-02 10:04:44 UTC
When is this `windowChanged` method called?

All examples/test cases I know are Steam games. For example, all games listed in this JSON attribute have WM_CLASS missing. All those games have WM_NAME property though.

https://github.com/BlueManCZ/SIF/blob/master/wm-class-database.json#L92-L129

The simple and free test case would be free-to-play game Team Fortress 2. This game has an icon in many icon packs:

https://github.com/PapirusDevelopmentTeam/papirus-icon-theme/blob/master/Papirus/64x64/apps/team-fortress2.svg
https://github.com/numixproject/numix-icon-theme-circle/blob/master/Numix-Circle/48/apps/steam_icon_440.svg
https://github.com/gusbemacbe/suru-plus/blob/master/Suru%2B%2B/apps/scalable/team-fortress2.svg

But without WM_CLASS it is impossible to display this icon when the game is running. So I came with this simple xprop fix, that seems to not work with KDE task manager. This fix simply mirrors WM_NAME to WM_CLASS.

https://github.com/BlueManCZ/SIF/blob/master/fix-wm-class.sh

The easiest way how to set up this fix correctly is the script I wrote.

https://github.com/BlueManCZ/SIF

It finds installed Steam games supported by icon packs, creates .desktop files with correct icons and WM_CLASSes and if necessary, insert this xprop fix to game launch options.

Let me know if I can help in any way.
Comment 8 Ivo Šmerek 2021-02-02 10:13:16 UTC
Oh, I just realized that Team Fortess 2 has WM_CLASS from start, but in this case, it must be changed to distinguish it from other games in the source engine. All these games have the same WM_CLASS. (Half-Life 2, Portal, Team Fortress 2, Left 4 Dead 2, Garry's Mod, etc.)
Comment 9 David Redondo 2021-02-02 10:15:07 UTC
If you just want it for the icon, could just setting _NET_WM_ICON_NAME work?
Comment 10 Ivo Šmerek 2021-02-02 10:46:30 UTC
I tested it and it does nothing. I tried _NET_WM_ICON_NAME and WM_ICON_NAME. Games often provide some default icon that I don't see in any property listed by xprop and this default icon is displayed in task manager together with WM_NAME.

> If you just want it for the icon
I don't want it only for the icon. Currently, the displayed name in some games is messy and user is unable to pin the launcher to the dock. This option is without WM_CLASS disabled and grey.
Comment 11 Ivo Šmerek 2021-02-02 10:59:32 UTC
And I can confirm that WM_CLASS is changed, appropriate .desktop file with the StartupWMClass created. But KDE task manager seems to completely disregard this.
Comment 12 Ivo Šmerek 2021-02-02 12:21:28 UTC
I recorded a short video to demonstrate what I'm talking about.

https://youtu.be/RxoQ3G_kexM

Excuse the Czech locale.
Comment 13 Ivo Šmerek 2021-02-15 16:59:02 UTC
Alright, I managed to get this working. It is related to the fact, that WM_CLASS property has two variables. Look at these two following commands.

Command 1:

> xprop -name "Talos - Linux - 64bit" -f WM_CLASS 8s -set WM_CLASS "Talos - Linux - 64bit"
Leads to:

> $ xprop WM_CLASS                                                                                                             
> WM_CLASS(STRING) = "Talos - Linux - 64bit"

Command 2:

> xdotool search --onlyvisible --name "Talos - Linux - 64bit" set_window --class "Talos - Linux - 64bit"
Leads to:

> $ xprop WM_CLASS
> WM_CLASS(STRING) = "", "Talos - Linux - 64bit"

In xdotool they distinguish these variables as --classname and --class. When I change --class, KDE Task Manager react properly and remap particular .desktop file. But when I change only --classname, nothing happens.

So if you think Task Manager works correctly, feel free to close this issue.