Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tray: implement d-bus menu #5161

Closed
wants to merge 8 commits into from
Closed

tray: implement d-bus menu #5161

wants to merge 8 commits into from

Conversation

ianyfan
Copy link
Contributor

@ianyfan ianyfan commented Mar 30, 2020

See #5161 (comment)

Help test please.

Or just use to your heart's content because basic menu operations work (i.e. just opening and clicking), so probably like 98% of what normal users do.
Not sure whether to change rendering style or expose some configuration options.
Waiting on #4781 too, so that we don't have to change the bar layer in order to render the popup over other applications.

TODO:

  • icons by name
  • touch, but I don't have a touch-enabled device to test on;
  • submenus, but not many applications implement it;
  • keyboard shortcuts, but I couldn't get keyboard focus to enter and leave properly, not sure whether this is a bug in sway or not...
  • some events (and properties), but I'm not sure what they do because the documentation sucks.

@artizirk
Copy link

artizirk commented Mar 30, 2020

OS: Arch Linux
Quassel IRC and Electron based Riot.im menus work, nothing else yet.

EDIT:
nm-applet via xembed-sni-proxy also works, at least some times the menu opens.
xorgnmapplet

@ianyfan
Copy link
Contributor Author

ianyfan commented Mar 30, 2020

@artizirk by nothing else, do you mean tested or works? If the latter, which ones?

X embedded menus don't work with this. (probably)

@artizirk
Copy link

By works I mean that menus open and are functional. Other applications like Slack and Dropbox do nothing currently

@artizirk
Copy link

looks like you are correct and xembed-sni-proxy does not use the dbusmenu at all.

I tried out nm-applet that is compiled with appindicator support but with that menus don't work.

@ianyfan
Copy link
Contributor Author

ianyfan commented Mar 31, 2020

Dropbox appears to be very badly behaved and will require further treatment.

I can't even get Slack show its icon, but I don't use it otherwise, so maybe someone can help me with this.

@artizirk
Copy link

Slack and maybe other Electron based apps might require XDG_CURRENT_DESKTOP=Unity env variable for appindicator to work electron/electron#10619

@loligans
Copy link

loligans commented Apr 7, 2020

What could I do to test this PR? I am running Arch. Could I install this branch through the AUR?

@nmschulte
Copy link
Contributor

nm-applet --indicator works for me with these changes, though it seems [click event] cursor positioning doesn't align visually; I had to click about 1 inch down (and ~1" left) on my mode 3840x2160 scale 2 HiDPI 15" display.

None of the menus display where I would expect, even relative to each other.

20200407_22h14m35s_grim

@ianyfan
Copy link
Contributor Author

ianyfan commented Apr 8, 2020

@nmschulte I think I fixed it, but I don't know whether it's a good fix.

@loligans You can't install this branch through the AUR, I'm afraid, but you can pull this branch directly using git (relevant StackOverflow link if it helps), and then follow the instructions here to compile it manually. Thanks for the help!

@nmschulte
Copy link
Contributor

Fails to build with new wlroots: swaywm/wlroots@6977f3a; master (c9fa751) builds fine.

git clean -dxf && mkdir subprojects && ln -s ../../wlroots subprojects/ && meson build --prefix=$HOME/.local && ninja -C build

ninja: Entering directory `build'
[265/504] Compiling C object 'sway/345c74e@@sway@exe/desktop_output.c.o'
FAILED: sway/345c74e@@sway@exe/desktop_output.c.o 
cc -Isway/345c74e@@sway@exe -Isway -I../sway -Iinclude -I../include -Isubprojects/wlroots -I../subprojects/wlroots -Isubprojects/wlroots/include -I../subprojects/wlroots/include -Iprotocols -I/usr/include/cairo -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/uuid -I/usr/include/json-c -I/usr/include/libevdev-1.0/ -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/fribidi -I/usr/include/libdrm -fdiagnostics-color=always -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -Werror -std=c11 -g -DWLR_USE_UNSTABLE -Wno-unused-parameter -Wno-unused-result -Wno-missing-braces -Wundef -Wvla '-DSYSCONFDIR="//home/nmschulte/.local/etc"' '-DSWAY_VERSION="1.4-4cea004d (" __DATE__ ", branch '"'"'tray'"'"')"' -fmacro-prefix-map=../= -MD -MQ 'sway/345c74e@@sway@exe/desktop_output.c.o' -MF 'sway/345c74e@@sway@exe/desktop_output.c.o.d' -o 'sway/345c74e@@sway@exe/desktop_output.c.o' -c ../sway/desktop/output.c
../sway/desktop/output.c: In function ‘scan_out_fullscreen_view’:
../sway/desktop/output.c:507:6: error: invalid use of void expression
  507 |  if (!wlr_output_attach_buffer(wlr_output, &surface->buffer->base)) {
      |      ^
[274/504] Linking target subprojects/wlroots/libwlroots.so.5
ninja: build stopped: subcommand failed.

@emersion
Copy link
Member

emersion commented Apr 8, 2020

You just need to rebase against master.

@nmschulte
Copy link
Contributor

nmschulte commented Apr 8, 2020

Menus appear in the correct place and click interaction works. pasystray doesn't always show the icon (:frowning_face: instead); this seemed like a race condition: it would typically show the icon if first I killall pulseaudio.

For the record, pasystray and nm-applet --indicator both use sub-menus.

udiskie --tray --appindicator shows no response to left or right clicks; maybe this is expected. There is a PyGIWarning about AppIndicator things though:

/usr/lib/python3/dist-packages/udiskie/appindicator.py:6: PyGIWarning: AppIndicator3 was imported without specifying a version first. Use gi.require_version('AppIndicator3', '0.1') before import to ensure that the right version gets loaded.
  from gi.repository import AppIndicator3

udiskie --tray --appindicator never seems to show the icon (:frowning_face: instead). If it matters, both udiskie and pasystray output a dbind-WARNING on my system:

AT-SPI: Error retrieving accessibility bus address: org.freedesktop.DBus.Error.ServiceUnknown: The name org.a11y.Bus was not provided by any .service files

@ianyfan
Copy link
Contributor Author

ianyfan commented Apr 11, 2020

00:00:00.876 [swaybar/tray/item.c:153] :1.110/org/ayatana/NotificationItem/udiskie IconThemePath = ''
00:00:00.876 [swaybar/tray/item.c:153] :1.110/org/ayatana/NotificationItem/udiskie Status = 'Active'
00:00:00.876 [swaybar/tray/item.c:153] :1.110/org/ayatana/NotificationItem/udiskie IconName = 'drive-removable-media'
00:00:00.891 [swaybar/tray/item.c:122] :1.110/org/ayatana/NotificationItem/udiskie IconPixmap: No such property “IconPixmap”
00:00:00.891 [swaybar/tray/item.c:153] :1.110/org/ayatana/NotificationItem/udiskie AttentionIconName = ''
00:00:00.892 [swaybar/tray/item.c:122] :1.110/org/ayatana/NotificationItem/udiskie AttentionIconPixmap: No such property “AttentionIconPixmap”
00:00:00.892 [swaybar/tray/item.c:122] :1.110/org/ayatana/NotificationItem/udiskie ItemIsMenu: No such property “ItemIsMenu”
00:00:00.892 [swaybar/tray/item.c:153] :1.110/org/ayatana/NotificationItem/udiskie Menu = '/org/ayatana/NotificationItem/udiskie/Menu'

00:00:02.172 [swaybar/tray/item.c:403] Clicked on :1.110/org/ayatana/NotificationItem/udiskie
00:00:02.182 [swaybar/tray/menu.c:394] :1.110/org/ayatana/NotificationItem/udiskie/Menu failed to read IconThemePath: No such device or address
00:00:02.184 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 0 children-display = 'submenu'
00:00:02.185 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 2 enabled = 'false'
00:00:02.185 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 2 visible = 'false'
00:00:02.185 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 2 label = 'No external devices'
00:00:02.185 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 3 enabled = 'true'
00:00:02.186 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 3 type = 'separator'
00:00:02.186 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 3 visible = 'false'
00:00:02.187 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 4 icon-data = '<success>'
00:00:02.187 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 4 visible = 'false'
00:00:02.188 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 4 label = 'Mount disc image'
00:00:02.188 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 5 enabled = 'true'
00:00:02.188 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 5 type = 'separator'
00:00:02.189 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 5 visible = 'false'
00:00:02.189 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 6 toggle-state = 'on'
00:00:02.189 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 6 visible = 'false'
00:00:02.189 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 6 toggle-type = 'checkmark'
00:00:02.190 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 6 label = 'Enable automounting'
00:00:02.190 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 7 toggle-state = 'on'
00:00:02.190 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 7 visible = 'false'
00:00:02.191 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 7 toggle-type = 'checkmark'
00:00:02.191 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 7 label = 'Enable notifications'
00:00:02.191 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 8 enabled = 'true'
00:00:02.192 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 8 type = 'separator'
00:00:02.192 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 8 visible = 'false'
00:00:02.193 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 9 icon-data = '<success>'
00:00:02.193 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 9 visible = 'false'
00:00:02.194 [swaybar/tray/menu.c:185] :1.110/org/ayatana/NotificationItem/udiskie/Menu id 9 label = 'Quit'

udiskie doesn't provide the icon or set any of the menu items visible so it's not our problem

@progandy
Copy link
Contributor

progandy commented Apr 11, 2020

udiskie doesn't provide the icon or set any of the menu items visible so it's not our problem

Do you call the AboutToShow method? I believe udiskie uses it to choose which items should be visible.

@ianyfan
Copy link
Contributor Author

ianyfan commented Apr 11, 2020

That does work, thanks. However, this change, along with submenus, requires fixing some logic paths, so I can't push it yet.

@progandy progandy mentioned this pull request Apr 12, 2020
@schickst
Copy link
Contributor

Hi, this is an interesting pull request, but didn't get updated for some time.
@ianyfan What is the state of this? Which logic paths, you mentioned above, need to be fixed? How can we help to move this PR forward and get at least a basic version merged?

@ianyfan
Copy link
Contributor Author

ianyfan commented Jul 22, 2020

Sorry, I'm not sure when I will be able to work on this. Also, it's been a while since I worked on this, so I don't have all the ideas in my head any more.

However, I believe the main problem was that I had originally written everything with the intention of loading everything as lazily as possible, which meant that every step of the process of opening a popup had its own callback, which then (sometimes conditionally) called the next callback in the process. Unfortunately, I had also made several simplifications in the process in order to get something done, namely not including submenus by only having a single popup instance, and not using the AboutToCall method, which adds a surprising amount of complexity to opening the popup, and it was starting to look like a callback hell.

So the main fix, which I had started working on (and left commented), was to allow popups to nest, but keeping the required singleton Wayland interfaces, which needs defining new structs (including good names) and fix the logic in places that open popups so that they can open a specific submenu. However, along with the logic paths that were introduced with using the AboutToCall method, I wasn't sure whether I could keep adding on to what I had written or whether I needed to rethink the code structure.

I am more than happy (and sorry) for someone else to take this up, and I can try to help by answering questions about it, but again, I'm not sure when I can come back to writing the code for it.

Also, I had basically given up on keyboard and touch events, so if nothing has changed, I'm happy to drop that goal. However, I'm reticent to drop submenus since it is such a relatively large change in both UX and the code.

@schickst
Copy link
Contributor

Thank you for your answer and your work so far! I agree with you about the dropping of keyboard and touch event goals and even submenus for now. I would prefer to have some basic functionality and then evolve from there.
I guess, that I will dig into your work so far and try to continue. But as my C skills lay bare for a few years and my also limited time, it will be a few weeks until I have some thing to show.

@chaoticryptidz
Copy link

Works great for me.

@ianyfan
Copy link
Contributor Author

ianyfan commented Sep 26, 2020

Hi all, sorry for taking so long, but I think I got submenus working somewhat. However, I haven't been able to test it much so let me know if you have any problems with it.

Unless keyboard events have miraculously begun working since I last worked on this, this will be the last feature I plan on implementing., and I will now be focused on cleaning up code paths, though I'm not sure how long that will take.

If anyone else has been working on this in the meantime, your input is still welcome.

Thanks all for trying this out.

@mirko
Copy link

mirko commented Nov 8, 2020

I manage to crash swaybar with the traybar changes when clicking around seemingly randomly (no pattern figured out so far).

Here's a backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x000055555556edd0 in popup_pointer_button (data=0x5555555972e0, wl_pointer=0x555555597ac0, serial=24068, time_=133513064, button=272, state=1) at ../swaybar/tray/menu.c:940
940	../swaybar/tray/menu.c: No such file or directory.
(gdb) bt
#0  0x000055555556edd0 in popup_pointer_button (data=0x5555555972e0, wl_pointer=0x555555597ac0, serial=24068, time_=133513064, button=272, state=1) at ../swaybar/tray/menu.c:940
#1  0x000055555555fc26 in wl_pointer_button (data=0x5555555972e0, wl_pointer=0x555555597ac0, serial=24068, time=133513064, button=272, state=1) at ../swaybar/input.c:183
#2  0x00007ffff6ed4ccd in ?? () from /lib/x86_64-linux-gnu/libffi.so.7
#3  0x00007ffff6ed425a in ?? () from /lib/x86_64-linux-gnu/libffi.so.7
#4  0x00007ffff7b1d2d2 in ?? () from /lib/x86_64-linux-gnu/libwayland-client.so.0
#5  0x00007ffff7b1997a in ?? () from /lib/x86_64-linux-gnu/libwayland-client.so.0
#6  0x00007ffff7b1b03c in wl_display_dispatch_queue_pending () from /lib/x86_64-linux-gnu/libwayland-client.so.0
#7  0x000055555555d693 in display_in (fd=5, mask=1, data=0x55555557fbc0 <swaybar>) at ../swaybar/bar.c:464
#8  0x000055555557193d in loop_poll (loop=0x555555590060) at ../common/loop.c:84
#9  0x000055555555d89a in bar_run (bar=0x55555557fbc0 <swaybar>) at ../swaybar/bar.c:505
#10 0x0000555555562ed7 in main (argc=3, argv=0x7fffffffe2c8) at ../swaybar/main.c:101
(gdb) 

on commit 600cf38cdaaa0faef0c1facaf2d041df8e218559 (HEAD, ianyfan/tray, master)

No complaint, just wondering whether it's just me: I still experience frequent crashes of swaybar with the traybar changes merged in. So far only using nm-applet --indicator and hence clicking around there triggering this.

@nmschulte
Copy link
Contributor

I receive a SIGSEGV with VLC: right click the icon (to show the menu) and then left click the icon (to toggle the window; regardless of window state, and regardless of the menu shown or hidden) causes a crash.

00:00:05.646 [swaybar/i3bar.c:260] Rendering last received json
00:00:07.832 [swaybar/tray/menu.c:914] button: 273 - state: 1
00:00:07.832 [swaybar/tray/item.c:404] Clicked on org.kde.StatusNotifierItem-12696-2/StatusNotifierItem
00:00:07.832 [swaybar/tray/item.c:365] click with method ContextMenu
00:00:07.832 [swaybar/tray/menu.c:794] org.kde.StatusNotifierItem-12696-2/MenuBar opening popup
00:00:07.832 [swaybar/tray/menu.c:393] org.kde.StatusNotifierItem-12696-2/MenuBar failed to read IconThemePath: Invalid request descriptor
00:00:07.836 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 0 children-display = 'submenu'
00:00:07.836 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 20 enabled = 'true'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 20 icon-data = '<success>'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 20 label = '_Hide VLC media player in taskbar'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 20 visible = 'true'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 19 type = 'separator'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 19 visible = 'true'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 18 enabled = 'true'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 18 icon-data = '<success>'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 18 label = '_Play'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 18 visible = 'true'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 17 enabled = 'false'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 17 icon-data = '<success>'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 17 label = '_Stop'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 17 visible = 'true'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 16 enabled = 'false'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 16 icon-data = '<success>'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 16 label = 'Pre_vious'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 16 visible = 'true'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 15 enabled = 'false'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 15 icon-data = '<success>'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 15 label = 'Ne_xt'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 15 visible = 'true'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 14 enabled = 'false'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 14 icon-data = '<success>'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 14 label = 'Record'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 14 visible = 'true'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 13 type = 'separator'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 13 visible = 'true'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 12 children-display = 'submenu'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 12 enabled = 'true'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 12 label = 'Sp_eed'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 12 visible = 'true'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 3 enabled = 'true'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 3 icon-data = '<success>'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 3 label = 'Faster (fine)'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 3 visible = 'true'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 2 enabled = 'true'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 2 label = 'N_ormal Speed'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 2 visible = 'true'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 1 enabled = 'true'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 1 icon-data = '<success>'
00:00:07.837 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 1 label = 'Slower (fine)'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 1 visible = 'true'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 11 type = 'separator'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 11 visible = 'true'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 10 type = 'separator'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 10 visible = 'true'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 9 enabled = 'true'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 9 icon-data = '<success>'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 9 label = '_Increase Volume'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 9 visible = 'true'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 8 enabled = 'true'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 8 icon-data = '<success>'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 8 label = 'D_ecrease Volume'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 8 visible = 'true'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 7 enabled = 'true'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 7 icon-data = '<success>'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 7 label = '_Mute'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 7 visible = 'true'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 6 type = 'separator'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 6 visible = 'true'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 5 enabled = 'true'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 5 icon-data = '<success>'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 5 label = '_Open Media'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 5 visible = 'true'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 4 enabled = 'true'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 4 icon-data = '<success>'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 4 label = '_Quit'
00:00:07.838 [swaybar/tray/menu.c:184] org.kde.StatusNotifierItem-12696-2/MenuBar 4 visible = 'true'
00:00:07.838 [swaybar/tray/menu.c:523] org.kde.StatusNotifierItem-12696-2/MenuBar showing popup for id 0
00:00:07.852 [swaybar/tray/menu.c:745] org.kde.StatusNotifierItem-12696-2/MenuBar opened id 0
00:00:07.936 [swaybar/tray/menu.c:914] button: 273 - state: 0
00:00:08.847 [swaybar/tray/menu.c:914] button: 272 - state: 1
00:00:08.847 [swaybar/tray/menu.c:927] closing unfocused open popup
00:00:08.847 [swaybar/tray/menu.c:448] closing popup
00:00:08.847 [swaybar/tray/menu.c:438] org.kde.StatusNotifierItem-12696-2/MenuBar closed id 0
00:00:08.847 [swaybar/tray/item.c:404] Clicked on org.kde.StatusNotifierItem-12696-2/StatusNotifierItem
00:00:08.847 [swaybar/tray/item.c:365] click with method Activate
00:00:08.847 [swaybar/tray/item.c:390] Guessing click position at (1818, 1068)
00:00:08.849 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.849 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.849 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.849 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.849 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.849 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.849 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.850 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.850 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.850 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.850 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.850 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.850 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.850 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.850 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.850 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.850 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.850 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.850 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.851 [swaybar/tray/menu.c:291] org.kde.StatusNotifierItem-12696-2/MenuBar layout updated
00:00:08.851 [swaybar/tray/menu.c:302] org.kde.StatusNotifierItem-12696-2/MenuBar item properties updated

Program received signal SIGSEGV, Segmentation fault.
handle_items_properties_updated (msg=0x55555574d410, data=0x5555556e2d30, error=0x7fffffffd730) at ../swaybar/tray/menu.c:310
310			update_item_properties(*menu_find_item(&sni->menu, id), msg);
(gdb) bt
#0  handle_items_properties_updated (msg=0x55555574d410, data=0x5555556e2d30, error=0x7fffffffd730) at ../swaybar/tray/menu.c:310
#1  0x00007ffff7a78199 in  () at /lib/x86_64-linux-gnu/libsystemd.so.0
#2  0x00007ffff7a77c60 in  () at /lib/x86_64-linux-gnu/libsystemd.so.0
#3  0x00007ffff7a77c3a in  () at /lib/x86_64-linux-gnu/libsystemd.so.0
#4  0x00007ffff7a77c60 in  () at /lib/x86_64-linux-gnu/libsystemd.so.0
#5  0x00007ffff7a77c3a in  () at /lib/x86_64-linux-gnu/libsystemd.so.0
#6  0x00007ffff7a77c60 in  () at /lib/x86_64-linux-gnu/libsystemd.so.0
#7  0x00007ffff7a77c3a in  () at /lib/x86_64-linux-gnu/libsystemd.so.0
#8  0x00007ffff7a77c60 in  () at /lib/x86_64-linux-gnu/libsystemd.so.0
#9  0x00007ffff7a77c3a in  () at /lib/x86_64-linux-gnu/libsystemd.so.0
#10 0x00007ffff7a77c60 in  () at /lib/x86_64-linux-gnu/libsystemd.so.0
#11 0x00007ffff7a77bce in  () at /lib/x86_64-linux-gnu/libsystemd.so.0
#12 0x00007ffff7a781ff in  () at /lib/x86_64-linux-gnu/libsystemd.so.0
#13 0x00007ffff7a96c48 in  () at /lib/x86_64-linux-gnu/libsystemd.so.0
#14 0x00007ffff7a9fed2 in  () at /lib/x86_64-linux-gnu/libsystemd.so.0
#15 0x000055555556f6f4 in tray_in (fd=7, mask=1, data=0x55555561c8d0) at ../swaybar/tray/tray.c:97
#16 0x0000555555571caa in loop_poll (loop=0x555555590090) at ../common/loop.c:84
#17 0x000055555555d89a in bar_run (bar=0x55555557fbc0 <swaybar>) at ../swaybar/bar.c:505
#18 0x0000555555562f2b in main (argc=4, argv=0x7fffffffe318) at ../swaybar/main.c:101
(gdb) print menu_find_item(&sni->menu, id)
$1 = (struct swaybar_menu_item **) 0x0

@johan-bjareholt
Copy link
Contributor

Another issue with this DBus implementation is that if the menu contains a checkbox that changes state, it will simply not redraw and always seem on/off even if the action is performed when pressing the checlbox.

I am maintainer of ActivityWatch and have been using this patch for a couple of weeks and this is the only issue I've found (no crashes which others mention).

@sunweaver
Copy link

Hi! Ayatana Indicators upstream maintainer here. The implementation in GTK and Qt also update the menus while open. E.g. network-manager applet (nm-applet) updates the seen WiFi network while the indicator's menu is open. This should be part of this implementation IMHO.

@sunweaver
Copy link

Furthermore, AppIndicator support via SNI DBus interface is only part of the Indicators implemention. It would be really cool, to see sway support Ayatana System Indicators.

A render implementation for GTK is available in libayatana-indicator:
https://github.com/AyatanaIndicators/libayatana-indicator

As reference for a renderer applet implementation you can take a look at mate-indicator-applet:
https://github.com/mate-desktop/mate-indicator-applet

The Ayatana System Indicators are actually the more generic approach. In Ayatana Indicators we have one indicator (ayatana-indicator-application) providing a widget toolkit indepdent implementation of an AppIndicator.

So maybe, providing system indicator support in Sway would be the much more generic approach (because AppIndicators would come with that out-of-the box).

@emersion
Copy link
Member

emersion commented Nov 24, 2020

This PR is about SNI menus only. If you want support for Ayatana System Indicators (or anything else), please create a separate issue.


struct swaybar_popup *popup = sni->tray->popup;
if (popup->sni == sni) {
close_popup(popup); // TODO enhancement: redraw instead of closing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clicking an item on the first tray menu interaction with Zoom's icon consistently crashes.

The issue is due to ItemsPropertiesUpdated signalling during the first interaction; Zoom updates the "Choose a Language" submenu to indicate the chosen language.

What happens is that close_popup is called before the AboutToShow callback triggers, and so the popup remains open and clicking on it causes SIGSEGV, as close_popup has set sni = NULL.

Copy link
Contributor

@nmschulte nmschulte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took this change one step further and tried to make LayoutUpdated and ItemsPropertiesUpdated signals automatically re-open the popup. It seems to be working, but is rather hacky with the popup_open global variable. https://github.com/nmschulte/sway/compare/master...nmschulte:fix-tray-updates?expand=1#diff-8acf2d71366c39e6519fbc4b635110efdb128c74ee2e17a06d9e09e4ef2354d8R400

It's not clear, but perhaps popup->sni is supposed to indicate that the popup "is open" ("is open": has opened after signalling AboutToShow and should not signal again until actually closed, not just close_popup called). popup->sni's lifecycle seems similar/same to popup->popup_surface.

With all of this, there is the popup hierarchy to worry about still: popup_surface->child; I think this is the main reason popup->sni's lifecycle is not quite the same as the popup_open cycle.

}

struct swaybar_popup *popup = sni->tray->popup;
if (popup->sni == sni) {
Copy link
Contributor

@nmschulte nmschulte Jan 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This additional constraint allows Zoom's menu to function; the ItemsPropertiesUpdated callback changes are successfully applied, although they are to a submenu that isn't drawn in the first popup. I think perhaps this will need to traverse popup_surface->child hierarchy and additional logic to work in all cases; input on how to do this @ianyfan?

Suggested change
if (popup->sni == sni) {
if (popup->sni == sni && popup->popup_surface) {

@nmschulte
Copy link
Contributor

nmschulte commented Jan 17, 2021

opened after signalling AboutToShow and should not signal again until actually closed

Udiskie sends a LayoutUpdated signal after every AboutToShow, regardless of any signaled Events (opened, closed), hence the reason for the stated behavior.


Something strange is happening with Zoom; swaybar receives ItemsPropertiesUpdated signals for non-Zoom-SNI, with zoom-SNI item ids, for SNIs that have the pattern org.kde.StatusNotifierItem-* (vs e.g. */org/ayatana/StatusNotifierItem/*).
dbus-monitor doesn't show these strange signals, so this must be a bug in swaybar's signal matching logic somehow. It only occurs for the first open_popup invocation though; subsequent clicks do not have this occur. Exiting and restarting Zoom causes it's first menu interaction to show this strangeness again.
zoom


Icon's in popups are not scaled according to DPI: 4K with scale 2 and bar config height 64:
image


As well, focus doesn't seem correct: I can type into Firefox and switch containers and workspaces after opening a menu, by both keyboard and mouse (e.g. scrolling, or putting cursor over the container). Clicking on a container that does not have focus will close the menu, but does not give it input/keyboard focus (it already has active/focus by way of cursor movement).

@ianyfan
Copy link
Contributor Author

ianyfan commented Jan 17, 2021

Thanks for looking into this. I haven't really looked at this PR for a while because I got really frustrated with it. I couldn't figure out why the udiskie behaviour you described occured in this patch but not in waybar, which uses the gtk libraries, which, I suppose, magically works everything out.

Besides that is this problematic scenario: suppose the user has opened a sequence of submenus 0 -> a -> b -> c ... and then the application updates the menu, replacing some items with new items, such that 0 -> a -> b are still valid items that can be opened, but c -> ... onwards are not (they have been replaced by new ones). It seems like the best solution would be to close those invalid submenus, and redraw the valid submenus, but a) from the user's perspective it looks like we've just closed some of their submenus for no reason, and b) we either need to reposition the layer shells (which is defined in the protocol, but not implemented yet I believe) or destroy them and reopen them again (which I don't know if you can do because I don't know if you can regrab a pointer) which in either case requires new logic.

It's a very unfun exercise. I hate edge cases. Apologies to all for the hold-up.

P.S. I'm not sure about the scaling thing but it sounds like a simple fix, not sure where though.

@nmschulte
Copy link
Contributor

nmschulte commented Jan 17, 2021

@ianyfan give my branch a test if you have a chance: https://github.com/nmschulte/sway/tree/fix-tray-updates; it's master + tray + <fixes-and-such>.

Which application has (updating) multiple nested menus I could test with?


Fixed icon scaling, but I wonder if the scale should happen after the icon search when using an icon by name.

@nmschulte
Copy link
Contributor

nmschulte commented Jan 19, 2021

As well, focus doesn't seem correct:

Also, maybe related:
When choosing a non-disabled menu item near the top of a menu, if I'm panning the cursor when I perform the click (or, slightly move the cursor while clicking), my focused workspace and output changes as though I scrolled the mouse wheel.

I initially thought this to be a rf-related hardware bug/flaw, specific to toggling bluetooth on and off; see the hw.bug.* files with relevant libinput debug-events listings (hw.bug.*) that seem to indicate it's not. I captured these by opening the menu with the terminal in focus and marking with a bunch of newlines, hence the beginning released event. It's very strange it is so specific, though.

hw.bug.1.log, hw.bug.2.log, hw.bug.3.log

@nmschulte
Copy link
Contributor

nmschulte commented Jan 19, 2021

It seems like the best solution would be to close those invalid submenus, and redraw the valid submenus

I feel like item ids can be re-used across layout updates; if an application wants to retain submenus open it needs to re-use the ids. Dealing with the UX is a different problem entirely; the application has some control of this too w/re: timing of updates. I guess it could even consider hovered events if it wanted.

I think NetworkManager is intelligent in this regard; we'll have to test i3 and other desktops. With my branch, issuing nmcli device wifi scan will cause the popup to close and re-open, unless the "more networks" submenu is open in which case both menus close and remain closed.

we either need to reposition the layer shells (which is defined in the protocol, but not implemented yet I believe) or destroy them and reopen them again (which I don't know if you can do because I don't know if you can regrab a pointer)

I only know these protocols by name right now, but show_popup_id isn't difficult to follow. I don't know about grabbing pointers, but I think I took a stab at the "destroy and reopen," but it of course does not account for submenus.

@nmschulte
Copy link
Contributor

nmschulte commented Jan 20, 2021

As well, focus doesn't seem correct:

This is the behavior with my work atop 62ec528 / swaywm/wlroots@306cf11:
image

You can see that after clicking the menu, if the cursor moves the focus changes. I think this is expected.
You can also see that changing container focus with the menu open does not change the input focus.
As well, if the container focus remains different than the input focus when the menu closes, moving the cursor of the (focused) container does not give it input focus; container focus must be removed/gained to get the desired state.


my focused workspace and output changes as though I scrolled the mouse wheel.

I am able to see my containers and workspaces switch by simply clicking on active menu items. It does not always occur, but it happens quite a lot, and especially so with blueman-applet's "turn bluetooth on/off," it still seems relegated to menu items near the top of the menu.

@nmschulte
Copy link
Contributor

I'd love to help, see this make its way into v1.6: #5970 (https://github.com/swaywm/sway/milestone/7).

@kennylevinsen
Copy link
Member

@nmschulte Have you considered making a PR with your changes on top of @ianyfan's?

@nmschulte
Copy link
Contributor

nmschulte commented Mar 11, 2021

@kennylevinsen indeed that is my plan. Presently with latest masters, some of my branch is not working (though, not crashing). I haven't checked this branch alone yet but I suspect it will present the same problems.

I'm hoping to see this branch, at least, make it to v1.6. If this branch needs more work (e.g. my efforts), then I'm happy to "take over" for @ianyfan, or push separately.

@FlexW FlexW mentioned this pull request May 2, 2021
@@ -363,7 +363,7 @@ static void handle_global(void *data, struct wl_registry *registry,
}
} else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
bar->layer_shell = wl_registry_bind(
registry, name, &zwlr_layer_shell_v1_interface, 1);
registry, name, &zwlr_layer_shell_v1_interface, 2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@FlexW any idea why @ianyfan bumped this to ver 2?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC xdg-popup support in layer-shell is only available since v2?

@emersion emersion added the enhancement New feature or incremental improvement label Dec 21, 2021
@ianyfan
Copy link
Contributor Author

ianyfan commented Feb 27, 2023

Closed to due being severely outdated, but development continues in #6249.

@ianyfan ianyfan closed this Feb 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or incremental improvement
Development

Successfully merging this pull request may close these issues.