lxqt / lxqt-panel

The LXQt desktop panel
https://lxqt-project.org
GNU Lesser General Public License v2.1
184 stars 136 forks source link

System tray icons applications don't recieve wheel (probably also tooltip) events #1925

Open redtide opened 1 year ago

redtide commented 1 year ago
Expected Behavior

A X11 Qt application using QSystemTrayIcon should recieve QEvent::ToolTip and QEvent::Wheel events.

Current Behavior

No events, except deferred delete on an attached eventFilter.

Possible Solution

IDK.

Steps to Reproduce (for bugs)

Debug an application using QSystemTrayIcon that has an eventFilter on it, it should call it only on deferred delete.

Context

I wrote a standalone application based on lxqt-panel volume plugin that can run alsamixer from QTerminal and use ALSA' normalized/linear volume. Now I want to control the volume by rotating the mouse wheel over the tray icon like in the original plugin, but this works only under Tint2 system tray, (I haven't tried others).

See qtilities/voltrayke#3.

System Information
tsujan commented 1 year ago

I always assumed that ineffectiveness of wheel scrolling over Audacious's tray icon was a bug in Audacious. But it may be related to this report.

probably also tooltip

Tooltips are OK here — I say this as a user, not remembering the code and not having time to reread it for now.

redtide commented 1 year ago

Tooltips are OK here

Tooltips are displayed but I meant that are not captured in eventFilter as events, though IDK how they are supposed to be used. It's in the documentation link, latest lines:

Only on X11, when a tooltip is requested, the QSystemTrayIcon receives a QHelpEvent of type QEvent::ToolTip. Additionally, the QSystemTrayIcon receives wheel events of type QEvent::Wheel. These are not supported on any other platform.

tsujan commented 1 year ago

The doc talks about two protocols: X11 XEmbed (legacy/obsolete), and the DBus-based tray icons. I think by "Only on X11" it means the obsolete one, which it still supports.

Just now, I logged into KDE and saw that Audacious's tray didn't respond to wheel scrolling either. So, this may not be a bug on our side, exactly because it's limited to the legacy protocol.

BTW, it's good to see that Qt doc mentions LXQt alongside KDE and Gnome :)

redtide commented 1 year ago

The doc talks about two protocols: X11 XEmbed (legacy/obsolete), and the DBus-based tray icons. I think by "Only on X11" it means the obsolete one, which it still supports.

I see. Well, it kinda sucks that the only one supporting it is on an old implementation, it's useful having the tray icon responding to mouse wheel. So basically it can work only for panel plugins buttons.

EDIT: I can't see where it talks about the DBus one, can you please point me to it? I'm kinda blind 😝

Just now, I logged into KDE and saw that Audacious's tray didn't respond to wheel scrolling either. So, this may not be a bug on our side, exactly because it's limited to the legacy protocol.

Ok, so I can close this I guess. Would be nice if DBus could support this but I can imagine it may be too much to respond to many, fast wheel events.

BTW, it's good to see that Qt doc mentions LXQt alongside KDE and Gnome :)

Oh, nice! I didn't notice it!

redtide commented 1 year ago

I see a Scroll method in the D-Bus implementation, can't be this called from a handleWheelEvent function?

tsujan commented 1 year ago

I don't know, but I ask myself, "if it was possible, why didn't KDE implement it?" ;)

EDIT: Also, see GNOME's new proposal: https://github.com/lxqt/lxqt/discussions/2295. It's getting like a jungle ;)

redtide commented 1 year ago

or why Qt doesn't support it in QSystemTrayIcon via QDBusInterface?

It's new stuff to me, so I have no much of an idea, but if it works via DBus I don't understand how it could be X11 specific.

tsujan commented 1 year ago

Ok, so I can close this I guess...

It would be nice if you could test your app under KDE too (I guess GNOME doesn't have any tray, and I'm not sure about XFCE's implementation when it comes to Qt).

redtide commented 1 year ago

No luck today: I installed plasma-desktop package, though I don't like KDE and the app crashes there. I need also to redo the QtC configuration which is too old, the debugger is messed up. Hope I can give some feedback soon.

tsujan commented 1 year ago

though I don't like KDE and the app crashes there.

I understand, but, IMHO, KDE may be needed for testing Qt apps thoroughly. I have a full installation for that reason.

redtide commented 1 year ago

That's right. To me QSystemTrayIcon is a problem, I had some crashes before and it's not easy to understand why they happen: the backtrace in QtC is not helpful and it happens in strange ways: sometimes having the app initialized with a different sequence and sometimes I have to show and then hide its context menu. I'm so tempted to try to create a dummy one with a transparent icon, get its rect and put over it a flat QToolButton.

tsujan commented 1 year ago

...get its rect and...

I'm afraid QSystemTrayIcon::geometry() gives you an empty rectangle — unless under some special circumstances, which I've forgotten (as usual).

redtide commented 1 year ago

What do you mean by empty? It doesn't returns the x y w and h of it in the screen coordinates as stated in the docs?

tsujan commented 1 year ago

No, it didn't when I wrestled with it years ago; it was useless.

Whether things have changed since then, I don't know, but I concluded that there was no way to know the rectangle because it belonged to the tray, not to the app.

redtide commented 1 year ago

Then it's really a total crap of API.

tsujan commented 1 year ago

I don't agree. With the old protocol, the tray menus were those of the apps, and so, they might be alien. With the "new" one (which isn't new anymore), all menus are native.

redtide commented 1 year ago

how you call random crashes and a geometry() function that doesn't returns what it should then?

tsujan commented 1 year ago

As for geometry(), I told my theory (please try it; I'm curious to know if something has changed). As for probable crashes, they could and should be fixed ;)

EDIT: Never mind; I tested with FeatherNotes and Qt6, and geometry() returned a null rectangle, as expected.

redtide commented 1 year ago

I did:

it doesn't work neither under KDE. I haven't investigate much but it seems that geometry() should return something if those sys or qpa_sys are not null and the icon is visible, but IDK what is that all about.

redtide commented 1 year ago

@tsujan I started my app from terminal and moving the wheel over it, forgetting for a moment about this issue. I only have it and NM applet active and moving the wheel over the tray (over both) I got some debug messages, so I did a search in lxqt-panel code and found this:

Received click 4 with passed x*y 0 0
Received click 5 with passed x*y 0 0

4 when moving the wheel down and 4 up. Could this be useful in any way?

tsujan commented 1 year ago

Could this be useful in any way?

Maybe. But I have no knowledge of (or don't remember) that code. It seems that it was adapted from KDE.

redtide commented 1 year ago

so I did a search in lxqt-panel code and found this

I haven't realized that SNI stands for StatusNotifierItem: here the link to the interesting part, Scroll. In the link above I haven't noticed that that debug message is called few lines above by a Scroll function (line 529, @palinek work).

I'm afraid QSystemTrayIcon::geometry() gives you an empty rectangle — unless under some special circumstances, which I've forgotten (as usual).

Is this related? (@paulolieuthier work)

The LXQt plugin implements SNI Scroll but I'm not sure how these are related and so how eventually use them from a client application; I haven't found yet an example at least how to do it via QDBus.

tsujan commented 1 year ago

Is this related? (@paulolieuthier work)

You're finding interesting things in those codes! A problem LXQt inherited from KDE, or just something that wasn't possible for some reason? Hopefully @palinek and @paulolieuthier could shed some light on this.

EDIT:

According to the code comment, it may be the latter: // StatusNotifierItem doesn't provide the geometry

redtide commented 12 months ago

According to the code comment, it may be the latter: // StatusNotifierItem doesn't provide the geometry

yes, that's what I wanted to point out with my "this related" link. I guess it is not much an issue, I might use the cursorpos or just make some "overlay popup", important is having the wheel delta and source information.

Now I just noticed that I have 2 plugins for the tray, one (tray) is for the old xembed based applications and one for the new ones (statusnotifier). Trying to disable one makes vanish one of my QSystemTrayIcon based application (the volume control I did based on volume plugin) while another (a JACK control settings interface I made) is on the statusnotifier. But I don't understand which code made this happen to be implemented in one or the other way, I used the same class? Is there any documentation about this?

tsujan commented 12 months ago

What I can say for sure is that a tray icon made by using purely Qt methods doesn't need the obsolete X11 XEmbed protocol and works everywhere. Wayland isn't just a possibility nowadays.

redtide commented 12 months ago

I have no X11 dependencies in both applications, the volume tray app is basically a standalone version of LXQt panel' volume plugin with additional fixes to make work alsamixer as external mixer application and a linear, normalized volume using ALSA (like other volume controls do like PNMixer).

The wheel event works on xembed based panels like tint2, but just by applying an event filter to the tray icon, not using X11 code.

The only difference is that the other one depends to QDBus, but for unrelated reasons: it wraps to a custom dbus service to monitor when the jack application is running and forward its log.

I should investigate the qt code to understand the logic.

sebholt commented 10 months ago

Modern system tray bars use the https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/ DBus interface to setup icons. Qt's QSystemTrayIcon does not implement the Scroll event properly. There already is Qt bug (please upvote): https://bugreports.qt.io/browse/QTBUG-91697

Other applications have the same issue:

tsujan commented 10 months ago

I reopen this with "Qt bug" label just for tracking the Qt bug report more easily.

@sebholt, thanks for the link!

redtide commented 10 months ago

There already is Qt bug (please upvote)

upvoted, I'm still curious to know if this thing is managed somewhere in KDE (but not that much to reinstall plasma :P ).

tsujan commented 10 months ago

I'm still curious to know if this thing is managed somewhere in KDE

It isn't. → https://github.com/lxqt/lxqt-panel/issues/1925#issuecomment-1677208823

sebholt commented 10 months ago

KDE has two system tray icon classes,

The former derives from QSystemTrayIcon and doesn't support wheel events. The latter wraps around a DBus based implementation of https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/ and supports wheel events.

I suppose the icons that support wheel events are based on KStatusNotifierItem.

tsujan commented 10 months ago

As I said, I just launched Audacious and saw that mouse wheel didn't work with its tray under KDE either.

The latter wraps around a DBus based implementation of

That's what LXQt does too.

redtide commented 10 months ago

@tsujan: Is it possible that audacious is using XEmbed? If so maybe some other application could work using the SNI API under KDE; @sebholt seems confirming that there is a dedicated SNI API, and LXQt has one too (I mean the one I "discovered" made by paulolieuthier).

I think this bug could be fixed from LXQt side without caring about what Qt or KDE does if it's based on a protocol on top of DBUS, by catching related messages directly.

tsujan commented 10 months ago

Is it possible that audacious is using XEmbed?

Nope! I'm under Wayland (LXQt+LabWC+Waybar) and there's no difference with Waybar's tray. The results of my test codes were the same too.

sebholt commented 10 months ago

I just discovered QDBUS_DEBUG from here: https://doc.qt.io/qt-5/qtdbus-index.html When I start qasmixer (my Qt based alsamixer) with QDBUS_DEBUG=1 qasmixer and then spin the mouse wheel over the tray icon, it clearly shows the DBus Scroll message. Only the QSystemTrayIcon doesn't make any use of it :(. I'm on KDE/Wayland btw..

redtide commented 10 months ago

it clearly shows the DBus Scroll message.

do you mean something like this?

QDBusConnectionPrivate(0x7efd440178c0) got message (signal): QDBusMessage(type=MethodCall, service=":1.14", path="/StatusNotifierItem", interface="org.kde.StatusNotifierItem", member="Scroll", signature="is", contents=(-120, "vertical") )

(120 or -120 as values only here, with my own VolTrayke volume control app)

sebholt commented 10 months ago

do you mean something like this?

Yes, exactly.

I get +/- 120 as well.

sebholt commented 10 months ago

It seems the 120 are eighths of a degree, so 15 degrees. That's according to https://doc.qt.io/qt-6/qwheelevent.html See QWheelEvent::angleDelta there.

redtide commented 10 months ago

FTR I made a SNI client example simulating a volume control, the only thing I'm not able to make work yet is the volume tooltip when using the wheel (I replaced it with a notification message temporarily).

I used the SNI code from lxqt-qtplugin with some updated code for libdbusmenu-qt from KStatusNotifierItem, might be interesting having some API (a sni library?) instead.

Note that current libdbusmenu-qt6 in Arch seems not working, here at least didn't.

redtide commented 10 months ago

@tsujan I think would be nice to have lxqt SNI as library extracted from qt plugin (plugin-statusnotifier seems to have more code though) like it is for kstatusnotifieritem in Arch for KDE.

Also it seems that the libdbusmenu-qt library required by the above lxqt-panel plugin and in lxqt-qtplugin is not working for qt6 (the one in Arch seems broken even if they patched it, no context menu) and it could possibily be bundled from the one bundled in kstatusnotifieritem instead using it as dependency (it's no more maintained).

Meanwhile I sent a mail to Paulo Lieuthier asking some info about it.

tsujan commented 10 months ago

... is not working for qt6

You need the latest Qt6 branches. It works here.

For the rest, @palinek is the expert. Frankly, I don't see any problem other than that Qt bug, which isn't our job to fix.

tsujan commented 10 months ago

Note that current libdbusmenu-qt6 in Arch seems not working

And we don't use it anymore. See https://github.com/lxqt/lxqt-qtplugin/pull/74/commits/8e8a2b324152f0102300a06888ce3cc511621284

redtide commented 10 months ago

... is not working for qt6

You need the latest Qt6 branches. It works here.

libdbusmenu-qt6 in Arch is not working.

For the rest, @palinek is the expert. Frankly, I don't see any problem other than that Qt bug, which isn't our job to fix.

There is no problem (except is not clear how to use tooltips in lxqt SNI), it's just that by having a library for SNI, clients can use it to write applications that uses that protocol instead depending by KDE stuff.

redtide commented 10 months ago

Note that current libdbusmenu-qt6 in Arch seems not working

And we don't use it anymore. See lxqt/lxqt-qtplugin@8e8a2b3

I didn't even know there was a libdbusmenu-lxqt, nice!

tsujan commented 10 months ago

I didn't even know there was a libdbusmenu-lxqt, nice!

@stefonarch and I use the Qt6 branches since they were made (we also use them under Wayland).

redtide commented 10 months ago

Not following fully LXQt development nor Wayland switch to labwc here yet. BTW statusnotifier plugin should also be updated to use libdbusmenu-lxqt.

tsujan commented 10 months ago

BTW statusnotifier plugin should also be updated to use libdbusmenu-lxqt.

libdbusmenu-lxqt is only for Qt6; lxqt-panel has no Qt6 branch yet (waiting for a stable version of KF6, which should come soon, and also a really usable layer-shell-qt6 with Wayland).

redtide commented 9 months ago

I wonder why DE developers only fork stuff internally instead maintain the original, so now there are a LXQt fork and a bundled one in KDE useless for other people.

redtide commented 9 months ago

I forgot to mention that IIUC the XEmbed protocol should be supported by plugin-tray as a proxy to SNI, but unless it's not the case, it seems it's not working for some reason. @sebholt thoughts?

tsujan commented 9 months ago

Although our main problem was the lack of a stable libdbusmenu-qt6, we might also be enable to fix its probable problems (like https://github.com/lxqt/lxqt-panel/issues/1417) or work around Qt's issues (like https://github.com/lxqt/lxqt-panel/issues/1802) in our fork.

And XEmbed protocol is a relic of old times; new codes shouldn't go near it or anything based on X11.