https://bugs.kde.org/show_bug.cgi?id=446581
Bug ID: 446581 Summary: plasmashell and Firefox hang when Firefox attempts to update the clipboard and show a notification at the same time Product: plasmashell Version: 5.23.4 Platform: Other OS: Linux Status: REPORTED Severity: normal Priority: NOR Component: Notifications Assignee: k...@privat.broulik.de Reporter: nyanpas...@tuta.io CC: plasma-b...@kde.org Target Milestone: 1.0 SUMMARY On KDE Plasma X11, with Klipper (clipboard history) added to plasmashell, and Firefox with "Copy Selected Tabs to Clipboard" installed, trying to use the extension often causes Firefox and plasmashell (and any app trying to paste) to deadlock and hang. STEPS TO REPRODUCE 1. Install Firefox and https://addons.mozilla.org/en-US/firefox/addon/copy-selected-tabs-to-clipboar/. 2. Add the Clipboard applet to a plasmashell panel. (Unsure if necessary, my System Tray applet also has a clipboard icon! I'm not sure how to show/hide it.) 3. With Plasma X11 running (doesn't happen on Wayland), right-click a Firefox tab, expand the "Copy to Clipboard" menu, and click "URL". OBSERVED RESULT Around 50% of the time, Firefox and plasmashell (and any app I try pasting into) hang for 10 seconds. Afterwards, plasmashell gives up trying to grab clipboard contents, the notification gets shown, and the clipboard is updated but Klipper is missing the clipboard entry. EXPECTED RESULT The notification gets shown, the clipboard is updated, and Klipper contains the new entry. SOFTWARE/OS VERSIONS Operating System: Arch Linux KDE Plasma Version: 5.23.4 KDE Frameworks Version: 5.88.0 Qt Version: 5.15.2 Kernel Version: 5.15.4-zen1-1-zen (64-bit) Graphics Platform: X11 Processors: 12 × AMD Ryzen 5 5600X 6-Core Processor Memory: 15.6 GiB of RAM Graphics Processor: NVIDIA GeForce GT 730/PCIe/SSE2 Firefox 94.0.2 (64-bit) Copy Selected Tabs to Clipboard: 1.4.3 ADDITIONAL INFORMATION When you use the extension to copy a tab list, Firefox sends a "clipboard changed" event (through X11 I assume, not sure) and attempts to send a notification through D-Bus (`notify_notification_show () at /usr/lib/libnotify.so.4` blocks on `g_dbus_connection_send_message_with_reply_sync`). Meanwhile plasmashell can't process the notification and unblock Firefox, because the Klipper plasmashell plugin is blocked trying to grab the clipboard contents (`QMimeData::text()` blocks on `QXcbClipboard::getSelection` and `QXcbClipboard::waitForClipboardEvent`). IDK exactly how X11 clipboards work, but I assume plasmashell/Klipper asks Xorg to ask Firefox for clipboard contents. But Firefox can't provide clipboard contents until it's done showing a notification, and plasmashell won't show the notification until it gets the clipboard contents. And both apps lock up for 10 seconds (I think plasmashell takes two 5-second timeouts to give up). And in the end, plasmashell gives up trying to grab clipboard contents, processes the notification, and both programs get unblocked (but Klipper is missing the clipboard entry). Which app is at fault and should be fixed? Firefox? plasmashell? "Copy Selected Tabs to Clipboard"? Klipper? Firefox backtrace during hang (recorded a few months ago): (gdb) bt #0 0x00007f8086af6b2f in poll () at /usr/lib/libc.so.6 #1 0x00007f808549d819 in g_main_context_poll (priority=<optimized out>, n_fds=1, fds=0x7f80412e7488, timeout=<optimized out>, context=0x7f8032c6a190) at ../glib/glib/gmain.c:4478 #2 g_main_context_iterate.constprop.0 (context=0x7f8032c6a190, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/glib/gmain.c:4170 #3 0x00007f8085447663 in g_main_loop_run (loop=0x7f803989b4a0) at ../glib/glib/gmain.c:4373 #4 0x00007f8085324a14 in g_dbus_connection_send_message_with_reply_sync (connection=0x7f8086769d00, message=0x7f802610f470, flags=G_DBUS_SEND_MESSAGE_FLAGS_NONE, timeout_msec=-1, out_serial=0x0, cancellable=0x0, error=0x7fff9df3cd40) at ../glib/gio/gdbusconnection.c:2179 #5 0x00007f808533276d in g_dbus_connection_call_sync_internal (connection=0x7f8086769d00, bus_name=0x7f803989b3d0 ":1.36749", object_path=0x7f8038014740 "/org/freedesktop/Notifications", interface_name=0x7f80380144e0 "org.freedesktop.Notifications", method_name=0x7f8045e7d24b "Notify", parameters=0x7f803a81eca0, reply_type=0x7f808538d99c, flags=G_DBUS_CALL_FLAGS_NONE, timeout_msec=-1, fd_list=0x0, out_fd_list=0x0, cancellable=0x0, error=0x7fff9df3d088) at ../glib/gio/gdbusconnection.c:6121 #6 0x00007f808533ba77 in g_dbus_proxy_call_sync_internal (proxy=0x7f803804e650, method_name=<optimized out>, parameters=0x7f803a81eca0, flags=G_DBUS_CALL_FLAGS_NONE, timeout_msec=<optimized out>, fd_list=fd_list@entry=0x0, out_fd_list=0x0, cancellable=0x0, error=0x7fff9df3d088) at ../glib/gio/gdbusproxy.c:2845 #7 0x00007f808533bc48 in g_dbus_proxy_call_sync (proxy=<optimized out>, method_name=<optimized out>, parameters=<optimized out>, flags=<optimized out>, timeout_msec=<optimized out>, cancellable=<optimized out>, error=0x7fff9df3d088) at ../glib/gio/gdbusproxy.c:3037 #8 0x00007f8045e7b75d in notify_notification_show () at /usr/lib/libnotify.so.4 #9 0x00007f807ff40a11 in () at /usr/lib/firefox/libxul.so ... #30 0x000055aafdb4ebdd in () #31 0x00007f8086a2ab25 in __libc_start_main () at /usr/lib/libc.so.6 #32 0x000055aafdbca4ae in _start () plasmashell backtrace during hang: (gdb) bt #0 0x00007ffff49e28ca in __futex_abstimed_wait_common64 () at /usr/lib/libpthread.so.0 #1 0x00007ffff49dc574 in pthread_cond_timedwait@@GLIBC_2.3.2 () at /usr/lib/libpthread.so.0 #2 0x00007ffff5a4e9a4 in QWaitConditionPrivate::wait_relative(QDeadlineTimer) (deadline=..., this=0x555555650de0) at thread/qwaitcondition_unix.cpp:136 #3 QWaitConditionPrivate::wait(QDeadlineTimer) (deadline=..., deadline=..., this=0x555555650de0) at thread/qwaitcondition_unix.cpp:144 #4 QWaitCondition::wait(QMutex*, QDeadlineTimer) (this=<optimized out>, mutex=0x5555556332f8, deadline=...) at thread/qwaitcondition_unix.cpp:225 #5 0x00007ffff5a4eabd in QWaitCondition::wait(QMutex*, unsigned long) (this=0x555555633300, mutex=0x5555556332f8, time=<optimized out>) at thread/qwaitcondition_unix.cpp:209 #6 0x00007ffff0960906 in QXcbEventQueue::waitForNewEvents(QXcbEventNode const*, unsigned long) (this=this@entry=0x555555633290, sinceFlushedTail=sinceFlushedTail@entry=0x7ffff0a45ed8 <QXcbEventQueue::qXcbEventNodeFactory(xcb_generic_event_t*)::qXcbNodePool+24>, time=3417) at qxcbeventqueue.cpp:362 #7 0x00007ffff09348f4 in QXcbClipboard::waitForClipboardEvent(unsigned int, int, bool) (this=this@entry=0x7fffec0047a0, window=window@entry=90177613, type=type@entry=31, checkManager=checkManager@entry=false) at qxcbclipboard.cpp:815 #8 0x00007ffff0934ff0 in QXcbClipboard::getSelection(unsigned int, unsigned int, unsigned int, unsigned int) (this=0x7fffec0047a0, selection=326, target=target@entry=590, property=333, time=194042584, time@entry=0) at qxcbclipboard.cpp:906 #9 0x00007ffff0937132 in QXcbClipboard::getDataInFormat(unsigned int, unsigned int) (fmtAtom=590, modeAtom=<optimized out>, this=<optimized out>) at qxcbclipboard.cpp:891 #10 QXcbClipboardMime::retrieveData_sys(QString const&, QVariant::Type) const (this=<optimized out>, fmt=..., type=<optimized out>) at qxcbclipboard.cpp:147 #11 0x00007ffff60396b8 in QInternalMimeData::retrieveData(QString const&, QVariant::Type) const (this=0x5555563594b0, mimeType=..., type=QVariant::String) at kernel/qinternalmimedata.cpp:113 #12 0x00007ffff5c635e0 in QMimeDataPrivate::retrieveTypedData(QString const&, QMetaType::Type) const (this=0x555555cd36a0, format=..., type=QMetaType::QString) at kernel/qmimedata.cpp:119 #13 0x00007ffff5c64281 in QMimeData::text() const (this=<optimized out>) at kernel/qmimedata.cpp:409 #14 0x00007fffc809ea4b in HistoryItem::create(QMimeData const*) () at /usr/lib/qt/plugins/plasma/dataengine/plasma_engine_clipboard.so #15 0x00007fffc80899be in Klipper::applyClipChanges(QMimeData const*) () at /usr/lib/qt/plugins/plasma/dataengine/plasma_engine_clipboard.so #16 0x00007fffc808bf51 in Klipper::checkClipData(bool) () at /usr/lib/qt/plugins/plasma/dataengine/plasma_engine_clipboard.so #17 0x00007ffff5c73915 in QtPrivate::QSlotObjectBase::call(QObject*, void**) (a=0x7fffffffdb70, r=<optimized out>, this=0x7fffec00b4c0) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398 #18 doActivate<false>(QObject*, int, void**) (sender=0x7fffec008410, signal_index=3, argv=0x7fffffffdb70) at kernel/qobject.cpp:3886 #19 0x00007fffc80b2363 in SystemClipboard::changed(QClipboard::Mode) () at /usr/lib/qt/plugins/plasma/dataengine/plasma_engine_clipboard.so #20 0x00007ffff5c73915 in QtPrivate::QSlotObjectBase::call(QObject*, void**) (a=0x7fffffffdc80, r=<optimized out>, this=0x555556815b00) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398 #21 doActivate<false>(QObject*, int, void**) (sender=0x555555e685f0, signal_index=3, argv=0x7fffffffdc80) at kernel/qobject.cpp:3886 #22 0x00007ffff5c6cee7 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (sender=<optimized out>, m=m@entry=0x7ffff65b1a00 <QClipboard::staticMetaObject>, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7fffffffdc80) at kernel/qobject.cpp:3946 #23 0x00007ffff649ed63 in QClipboard::changed(QClipboard::Mode) (this=<optimized out>, _t1=<optimized out>) at .moc/moc_qclipboard.cpp:168 #24 0x00007ffff6029670 in QClipboard::emitChanged(QClipboard::Mode) (this=<optimized out>, mode=<optimized out>) at kernel/qclipboard.cpp:608 #25 0x00007ffff600a4fd in QPlatformClipboard::emitChanged(QClipboard::Mode) (this=<optimized out>, mode=<optimized out>) at kernel/qplatformclipboard.cpp:125 #26 0x00007ffff093525f in QXcbClipboard::handleXFixesSelectionRequest(xcb_xfixes_selection_notify_event_t*) (this=<optimized out>, event=event@entry=0x7fffec00c660) at qxcbclipboard.cpp:679 #27 0x00007ffff0938d56 in QXcbConnection::handleXcbEvent(xcb_generic_event_t*) (this=this@entry=0x55555563f620, event=event@entry=0x7fffec00c660) at qxcbconnection.cpp:685 #28 0x00007ffff093a2d1 in QXcbConnection::processXcbEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x55555563f620, flags=...) at qxcbconnection.cpp:1014 #29 0x00007ffff09617f8 in xcbSourceDispatch(GSource*, GSourceFunc, gpointer) (source=<optimized out>) at qxcbeventdispatcher.cpp:103 #30 0x00007ffff3f090ec in g_main_dispatch (context=0x7fffec005000) at ../glib/glib/gmain.c:3381 #31 g_main_context_dispatch (context=0x7fffec005000) at ../glib/glib/gmain.c:4099 #32 0x00007ffff3f5e889 in g_main_context_iterate.constprop.0 (context=context@entry=0x7fffec005000, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/glib/gmain.c:4175 #33 0x00007ffff3f06735 in g_main_context_iteration (context=0x7fffec005000, may_block=1) at ../glib/glib/gmain.c:4240 #34 0x00007ffff5c95b2a in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x5555556ea750, flags=...) at kernel/qeventdispatcher_glib.cpp:423 #35 0x00007ffff5c3aabb in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (this=this@entry=0x7fffffffdf40, flags=..., flags@entry=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:69 #36 0x00007ffff5c432a8 in QCoreApplication::exec() () at ../../include/QtCore/../../src/corelib/global/qflags.h:121 #37 0x0000555555573136 in main () -- You are receiving this mail because: You are watching all bug changes.