You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Menus with dynamically added/removed entries are not resized correctly before showing. This can result in too much unused space or invisible entries (below the bottom of the menu).
I have again created the following small examples recreating the issue to make sure that it isn't a problem with one particular KSNI implementation:
Right-click the tray icon several times and it will rotate between One/Two/Three menu items, but the geometry always lacks one behind, i.e. either shows too many or one to few entries.
Using Qt/QSystemTrayIcon (this example also demonstrates that the menu geometry is updated correctly in a window menu):
fromPyQt5.QtWidgetsimport (
QAction, QApplication, QMainWindow, QMenu, QSystemTrayIcon)
importitertoolsimportsignalimportsysdefmain():
app=QApplication(sys.argv)
window=QMainWindow()
winmenu=TrayMenu(window.menuBar().addMenu('&File'))
window.show()
style=app.style()
trayicon=QSystemTrayIcon(
style.standardIcon(style.SP_MessageBoxCritical))
traymenu=TrayMenu()
trayicon.setContextMenu(traymenu.menu)
trayicon.show()
signal.signal(signal.SIGINT, signal.SIG_DFL)
app.exec_()
classTrayMenu:
def__init__(self, menu=None):
self.menu=menuorQMenu()
self.menu.aboutToShow.connect(self.update)
# Show different number of menuitems each time for demo purposes:self.counter=itertools.count()
# Needed to prevent garbage collection of actions:self.actions= []
# Populate menu initially, so libdbusmenu does not ignore the# 'about-to-show':self.update()
defupdate(self):
foractioninself.actions:
self.menu.removeAction(action)
self.actions.clear()
num_items=next(self.counter) %3print("num_items={}".format(num_items))
foriinrange(num_items):
action=QAction('Item {}'.format(i+1))
self.menu.addAction(action)
self.actions.append(action)
quit=QAction('&Quit')
quit.triggered.connect(QApplication.quit)
self.menu.addAction(quit)
self.actions.append(quit)
if__name__=='__main__':
main()
And here using ``Gtk/AppIndicator3`:
fromgiimportrequire_versionrequire_version('Gtk', '3.0')
require_version('AppIndicator3', '0.1')
importitertoolsimportsignalfromgi.repositoryimportGtkfromgi.repositoryimportAppIndicator3defmain():
indicator=AppIndicator3.Indicator.new(
'checkbox-test-app', 'dialog-error',
AppIndicator3.IndicatorCategory.OTHER)
indicator.set_status(AppIndicator3.IndicatorStatus.PASSIVE)
traymenu=TrayMenu()
traymenu.set_indicator(indicator)
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()
classTrayMenu:
def__init__(self, menu=None):
self.counter=itertools.count()
self.menu=Gtk.Menu()
# Populate menu initially, so libdbusmenu does not ignore the# 'about-to-show':self.update()
defupdate(self):
foriteminself.menu.get_children():
self.menu.remove(item)
num_items=next(self.counter) %3print("num_items={}".format(num_items))
foriinrange(num_items):
self.menu.append(Gtk.MenuItem(label='Item {}'.format(i)))
quit=Gtk.MenuItem(label='Quit')
quit.connect('activate', lambda_: Gtk.main_quit())
self.menu.append(quit)
self.menu.show_all()
defset_indicator(self, indicator):
self.indicator=indicatorindicator.set_menu(self.menu)
# Get notified before menu is shown, see:# https://bugs.launchpad.net/screenlets/+bug/522152/comments/15dbusmenuserver=indicator.get_property('dbus-menu-server')
dbusmenuitem=dbusmenuserver.get_property('root-node')
dbusmenuitem.connect('about-to-show', self.update)
if__name__=='__main__':
main()
And here is yet another variant that shows that the geometry of tray submenus seems to be updated correctly:
fromgiimportrequire_versionrequire_version('Gtk', '3.0')
require_version('AppIndicator3', '0.1')
importitertoolsimportsignalfromgi.repositoryimportGtkfromgi.repositoryimportAppIndicator3defmain():
indicator=AppIndicator3.Indicator.new(
'checkbox-test-app', 'dialog-error',
AppIndicator3.IndicatorCategory.OTHER)
indicator.set_status(AppIndicator3.IndicatorStatus.PASSIVE)
traymenu=TrayMenu()
traymenu.set_indicator(indicator)
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()
classTrayMenu:
def__init__(self, menu=None):
self.counter=itertools.count()
self.submenu=Gtk.Menu()
submenu=Gtk.MenuItem(label='Items')
submenu.set_submenu(self.submenu)
quit=Gtk.MenuItem(label='Quit')
quit.connect('activate', lambda_: Gtk.main_quit())
self.menu=Gtk.Menu()
self.menu.append(submenu)
self.menu.append(quit)
self.menu.show_all()
# Populate menu initially, so libdbusmenu does not ignore the# 'about-to-show':# self.update()defupdate(self):
foriteminself.submenu.get_children():
self.submenu.remove(item)
num_items=next(self.counter) %3+1print("num_items={}".format(num_items))
foriinrange(num_items):
self.submenu.append(Gtk.CheckMenuItem(label='Item {}'.format(i)))
self.submenu.show_all()
defset_indicator(self, indicator):
self.indicator=indicatorindicator.set_menu(self.menu)
# Get notified before menu is shown, see:# https://bugs.launchpad.net/screenlets/+bug/522152/comments/15dbusmenuserver=indicator.get_property('dbus-menu-server')
dbusmenuitem=dbusmenuserver.get_property('root-node')
dbusmenuitem.connect('about-to-show', self.update)
if__name__=='__main__':
main()
again, not sure whether this is a wayland, waybar or sway problem.
This one is more interesting.
We pass all tray menu handling to the libdbusmenu library which is pretty much dead upstream. Apparently it does not adjust the window size/position if the entries were updated when the menu is visible (AboutToShow is sent right before realizing the menu with the current data and the response will be handled way after that).
I already crossed out any weird gtk and layer-shell interactions by providing a regular xdg surface implementation for the bar. Didn't affect the issue at all.
Need to check if it's possible to work around that without modifying and vendoring the library code. If anyone wants to look at some seasoned and unmaintained C code before I find time for that, feel free 😃
Hi,
Menus with dynamically added/removed entries are not resized correctly before showing. This can result in too much unused space or invisible entries (below the bottom of the menu).
I have again created the following small examples recreating the issue to make sure that it isn't a problem with one particular KSNI implementation:
Right-click the tray icon several times and it will rotate between One/Two/Three menu items, but the geometry always lacks one behind, i.e. either shows too many or one to few entries.
Using Qt/QSystemTrayIcon (this example also demonstrates that the menu geometry is updated correctly in a window menu):
And here using ``Gtk/AppIndicator3`:
And here is yet another variant that shows that the geometry of tray submenus seems to be updated correctly:
again, not sure whether this is a wayland, waybar or sway problem.
(Issue from coldfix/udiskie#199)
Best, Thomas
The text was updated successfully, but these errors were encountered: