Bug 477299 - Multi-line menu text for menu items displayed incorrectly
Summary: Multi-line menu text for menu items displayed incorrectly
Status: RESOLVED FIXED
Alias: None
Product: Breeze
Classification: Plasma
Component: QStyle (show other bugs)
Version: 5.27.9
Platform: openSUSE Linux
: NOR normal
Target Milestone: ---
Assignee: Plasma Bugs List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-11-20 21:36 UTC by Ilya Bizyaev
Modified: 2024-01-31 22:24 UTC (History)
4 users (show)

See Also:
Latest Commit:
Version Fixed In: 6.0


Attachments
A minimal example (870 bytes, text/x-python)
2023-11-20 21:37 UTC, Ilya Bizyaev
Details
Screenshot of the issue (90.38 KB, image/png)
2023-11-20 21:38 UTC, Ilya Bizyaev
Details
Updated SNI example (Qt 6) (1020 bytes, text/x-python)
2024-01-26 00:00 UTC, Ilya Bizyaev
Details
Sample app (PyQt6) (1.13 KB, text/x-python)
2024-01-26 00:00 UTC, Ilya Bizyaev
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ilya Bizyaev 2023-11-20 21:36:39 UTC
SUMMARY
Currently, system tray menus with two-line action labels are displayed incorrectly (see the attached minimal program and a screenshot of it). However, I couldn't find anywhere in the spec that actions must not contain newlines.

On X11, this is somewhat alleviated by apps drawing their own menus for tray icons, and GTK has no issues with multiline menu items. On Wayland, however, all the tray menus have to be displayed through SNI and rendered by Plasma. Currently, Plasma uses a simple QMenu for that, and QMenus don't support multiline actions natively (or maybe it's up to the widget style to support them, and Breeze doesn't).

Since there are programs out there that rely on multiline action labels in their system tray menus, and the spec seems to be permissive in this regard, I think Plasma should ensure that such menus are displayed correctly, even if it requires using a custom component. If that is impossible, Plasma should at least replace newlines with spaces to avoid the obvious rendering defect.

STEPS TO REPRODUCE
Run the attached script (PyQt5).

OBSERVED RESULT
See the attached screenshot.

EXPECTED RESULT
Multiline action names in system tray menus exposed via SNI are displayed correctly.
Comment 1 Ilya Bizyaev 2023-11-20 21:37:27 UTC
Created attachment 163323 [details]
A minimal example
Comment 2 Ilya Bizyaev 2023-11-20 21:38:35 UTC
Created attachment 163324 [details]
Screenshot of the issue
Comment 3 Ilya Bizyaev 2023-11-20 21:47:26 UTC
Note that the QMenu in the script is not the QMenu that is actually displayed to the user, it is only used to export the intended menu items to D-Bus. In a GTK program, it would be a GTK menu object, etc.
Comment 4 Bug Janitor Service 2024-01-25 23:58:09 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/breeze/-/merge_requests/414
Comment 5 Ilya Bizyaev 2024-01-26 00:00:09 UTC
Created attachment 165222 [details]
Updated SNI example (Qt 6)
Comment 6 Ilya Bizyaev 2024-01-26 00:00:48 UTC
Created attachment 165223 [details]
Sample app (PyQt6)
Comment 7 Ilya Bizyaev 2024-01-30 11:19:40 UTC
Git commit a4d892f68ce77198812fccbeabfb79f97ce36688 by Ilya Bizyaev.
Committed on 30/01/2024 at 11:19.
Pushed by ilyabizyaev into branch 'master'.

Fix display of multiline menu items

Currently, multiline text in menu items is displayed incorrectly: the bounding rectangle is calculated ignoring newlines, while the newline is displayed in the resulting menu, and the text is cropped.

This commit makes it so the newline is considered in the calculation as well. To do so, we get text metrics ourselves instead of delegating it to the ancient QMenu code that forces `Qt::TextSingleLine`.

Note that this approach is not new:

* In Breeze, the code right below for `QStyleOptionMenuItem::Separator` also gets text metrics.
* In Qt, the Fusion style also requests font metrics: https://invent.kde.org/qt/qt/qtbase/-/blob/dev/src/widgets/styles/qfusionstyle.cpp#L3084-3088

Note that this commit does not imply that it is a good idea to use multiline menu item text in KDE apps from now on; it merely fixes an existing rendering defect that caused multiline actions to look wrong in StatusNotifierItems.

Before:

![Screenshot_20240126_002332.png](/uploads/655175fb8ac21ac0b558a0898d7e61de/Screenshot_20240126_002332.png)

After:

![Screenshot_20240126_002406.png](/uploads/b1d791c82b40d46030a7aad83f3d83e3/Screenshot_20240126_002406.png)

With icons:

![Screenshot_20240126_005541](/uploads/fe3632884c8b4b4c78a3ace7d70d5340/Screenshot_20240126_005541.png)

In a very imaginary app:

![Screenshot_20240126_005700.png](/uploads/b7dda2780c8933d36117611e455cfcce/Screenshot_20240126_005700.png)

M  +10   -2    kstyle/breezestyle.cpp

https://invent.kde.org/plasma/breeze/-/commit/a4d892f68ce77198812fccbeabfb79f97ce36688
Comment 8 Ilya Bizyaev 2024-01-30 11:51:03 UTC
Git commit a5f463e236639370ba2770b7bc0e28dbe777b0eb by Ilya Bizyaev, on behalf of Ilya Bizyaev.
Committed on 30/01/2024 at 11:44.
Pushed by ilyabizyaev into branch 'Plasma/6.0'.

Fix display of multiline menu items

Currently, multiline text in menu items is displayed incorrectly: the
bounding rectangle is calculated ignoring newlines, while the newline is
displayed in the resulting menu, and the text is cropped.

This commit makes it so the newline is considered in the calculation as
well. To do so, we get text metrics ourselves instead of delegating it
to the ancient QMenu code that forces `Qt::TextSingleLine`.

Note that this approach is not new:
* In Breeze, the code right below for QStyleOptionMenuItem::Separator
  also gets text metrics.
* In Qt, the Fusion style also requests font metrics:
  https://invent.kde.org/qt/qt/qtbase/-/blob/dev/src/widgets/styles/qfusionstyle.cpp#L3084-3088

Note that this commit does not imply that it is a good idea to use
multiline menu item text in KDE apps from now on; it merely fixes an
existing rendering defect that caused multiline actions to look wrong in
StatusNotifierItems.


(cherry picked from commit 7c5809b6dacc56d3c10893c68fb702278f7717ce)

M  +10   -2    kstyle/breezestyle.cpp

https://invent.kde.org/plasma/breeze/-/commit/a5f463e236639370ba2770b7bc0e28dbe777b0eb