summaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
7 hoursgb_Trace_EndRange MOC instead of CXX (CustomTarget_wasm-qt5-mandelbrot_moc)Julien Nabet1-1/+1
Change-Id: Idb1457933a784b5ee4364e435d439f544ae28013 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166653 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
33 hourstdf#160598 SwNavigator enhancement to delete footnotes/endnotesJim Raykowski2-8/+136
m_bDocHasChanged is checked first in the tooltip and mouse move handlers to prevent crashes/asserts that happen when SfxPoolItemHolder m_aAttr references a delete poolitem or poolitem data. Without this check the following types of crashes/asserts can happen: ---- Unspecified Application Error Fatal exception: Signal 6 Stack: 0 sal::backtrace_get(unsigned int) at /home/lo/Dev/LO1/core/sal/osl/ unx/backtraceapi.cxx:42 (discriminator 3) 1 (anonymous namespace)::printStack(int) at /home/lo/Dev/LO1/core/sal/ osl/unx/signal.cxx:289 2 (anonymous namespace)::callSystemHandler(int, siginfo_t*, void*) at / home/lo/Dev/LO1/core/sal/osl/unx/signal.cxx:330 3 (anonymous namespace)::signalHandlerFunction(int, siginfo_t*, void*) at /home/lo/Dev/LO1/core/sal/osl/unx/signal.cxx:427 4 __restore_rt at libc_sigaction.c:? 5 __pthread_kill_implementation at ./nptl/pthread_kill.c:44 6 __GI_raise at ./signal/../sysdeps/posix/raise.c:27 7 __GI_abort at ./stdlib/abort.c:81 (discriminator 21) 8 SalAbort(rtl::OUString const&, bool) at /home/lo/Dev/LO1/core/vcl/ source/app/salplug.cxx:412 9 Application::Abort(rtl::OUString const&) at /home/lo/Dev/LO1/core/ vcl/source/app/svapp.cxx:316 10 desktop::Desktop::Exception(ExceptionCategory) at /home/lo/Dev/LO1/ core/desktop/source/app/app.cxx:1203 (discriminator 2) 11 VCLExceptionSignal_impl(void*, oslSignalInfo*) at /home/lo/Dev/LO1/ core/vcl/source/app/svmain.cxx:176 12 callSignalHandler(oslSignalInfo*) at /home/lo/Dev/LO1/core/sal/osl/ all/signalshared.cxx:47 13 (anonymous namespace)::signalHandlerFunction(int, siginfo_t*, void*) at /home/lo/Dev/LO1/core/sal/osl/unx/signal.cxx:423 14 __restore_rt at libc_sigaction.c:? 15 SfxPoolItem::Which() const at /home/lo/Dev/LO1/core/include/svl/ poolitem.hxx:225 16 SfxPoolItemHolder::Which() const at /home/lo/Dev/LO1/core/include/ svl/itemset.hxx:74 (discriminator 1) 17 SwTextAttr::GetFootnote() const at /home/lo/Dev/LO1/core/sw/inc/ txatbase.hxx:223 (discriminator 1) 18 SwContentTree::QueryTooltipHdl(weld::TreeIter const&) at /home/lo/ Dev/LO1/core/sw/source/uibase/utlui/content.cxx:4974 19 SwContentTree::LinkStubQueryTooltipHdl(void*, weld::TreeIter const&) at /home/lo/Dev/LO1/core/sw/source/uibase/utlui/content.cxx:4895 20 Link<weld::TreeIter const&, rtl::OUString>::Call(weld::TreeIter const&) const at /home/lo/Dev/LO1/core/include/tools/link.hxx:111 21 weld::TreeView::signal_query_tooltip(weld::TreeIter const&) at / home/lo/Dev/LO1/core/include/vcl/weld.hxx:977 22 SalInstanceTreeView::TooltipHdl(SvTreeListEntry*) at /home/lo/Dev/ LO1/core/vcl/source/app/salvtables.cxx:5154 23 SalInstanceTreeView::LinkStubTooltipHdl(void*, SvTreeListEntry*) at /home/lo/Dev/LO1/core/vcl/source/app/salvtables.cxx:5151 24 Link<SvTreeListEntry*, rtl::OUString>::Call(SvTreeListEntry*) const at /home/lo/Dev/LO1/core/include/tools/link.hxx:111 25 SvTreeListBox::RequestHelp(HelpEvent const&) at /home/lo/Dev/LO1/ core/vcl/source/treelist/treelistbox.cxx:3284 26 ImplHandleMouseHelpRequest(vcl::Window*, Point const&) at /home/lo/ Dev/LO1/core/vcl/source/window/winproc.cxx:186 27 ImplHandleMouseEvent(VclPtr<vcl::Window> const&, NotifyEventType, bool, long, long, unsigned long, unsigned short, MouseEventModifiers) at /home/lo/Dev/LO1/core/vcl/source/window/winproc.cxx:740 28 ImplHandleSalMouseMove(vcl::Window*, SalMouseEvent const*) at /home/ lo/Dev/LO1/core/vcl/source/window/winproc.cxx:2332 29 ImplWindowFrameProc(vcl::Window*, SalEvent, void const*) at /home/ lo/Dev/LO1/core/vcl/source/window/winproc.cxx:2665 (discriminator 1) 30 SalFrame::CallCallback(SalEvent, void const*) const at /home/lo/Dev/ LO1/core/vcl/inc/salframe.hxx:312 (discriminator 1) 31 QtFrame::CallCallback(SalEvent, void const*) const at /home/lo/Dev/ LO1/core/vcl/inc/qt5/QtFrame.hxx:228 32 QtWidget::mouseMoveEvent(QMouseEvent*) at /home/lo/Dev/LO1/core/vcl/ qt5/QtWidget.cxx:202 33 QWidget::event(QEvent*) in /lib/x86_64-linux-gnu/libQt5Widgets.so.5 34 QtWidget::event(QEvent*) at /home/lo/Dev/LO1/core/vcl/qt5/ QtWidget.cxx:738 (discriminator 2) 35 QApplicationPrivate::notify_helper(QObject*, QEvent*) in /lib/ x86_64-linux-gnu/libQt5Widgets.so.5 36 QApplication::notify(QObject*, QEvent*) in /lib/x86_64-linux-gnu/ libQt5Widgets.so.5 37 QCoreApplication::notifyInternal2(QObject*, QEvent*) in /lib/x86_64- linux-gnu/libQt5Core.so.5 38 QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) in /lib/ x86_64-linux-gnu/libQt5Widgets.so.5 39 QDesktopWidget::qt_metacall(QMetaObject::Call, int, void**) in /lib/ x86_64-linux-gnu/libQt5Widgets.so.5 40 QDesktopWidget::qt_metacall(QMetaObject::Call, int, void**) in /lib/ x86_64-linux-gnu/libQt5Widgets.so.5 41 QApplicationPrivate::notify_helper(QObject*, QEvent*) in /lib/ x86_64-linux-gnu/libQt5Widgets.so.5 42 QCoreApplication::notifyInternal2(QObject*, QEvent*) in /lib/x86_64- linux-gnu/libQt5Core.so.5 43 QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) in /lib/x86_64-linux-gnu/libQt5Gui.so.5 44 QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) in /lib/x86_64-linux-gnu/libQt5Gui.so.5 45 QXcbNativeInterface::dumpNativeWindows(unsigned long long) const in /lib/x86_64-linux-gnu/libQt5XcbQpa.so.5 46 g_main_context_dispatch in /lib/x86_64-linux-gnu/libglib-2.0.so.0 48 g_main_context_iteration in /lib/x86_64-linux-gnu/libglib-2.0.so.0 49 QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) in /lib/x86_64-linux-gnu/libQt5Core.so.5 50 QtInstance::ImplYield(bool, bool) at /home/lo/Dev/LO1/core/vcl/qt5/ QtInstance.cxx:453 51 QtInstance::DoYield(bool, bool) at /home/lo/Dev/LO1/core/vcl/qt5/ QtInstance.cxx:464 52 ImplYield(bool, bool) at /home/lo/Dev/LO1/core/vcl/source/app/ svapp.cxx:395 53 Application::Yield() at /home/lo/Dev/LO1/core/vcl/source/app/ svapp.cxx:483 54 Application::Execute() at /home/lo/Dev/LO1/core/vcl/source/app/ svapp.cxx:370 55 desktop::Desktop::Main() at /home/lo/Dev/LO1/core/desktop/source/ app/app.cxx:1617 56 ImplSVMain() at /home/lo/Dev/LO1/core/vcl/source/app/svmain.cxx:229 57 SVMain() at /home/lo/Dev/LO1/core/vcl/source/app/svmain.cxx:262 58 soffice_main at /home/lo/Dev/LO1/core/desktop/source/app/ sofficemain.cxx:93 59 sal_main at /home/lo/Dev/LO1/core/desktop/source/app/main.c:51 60 main at /home/lo/Dev/LO1/core/desktop/source/app/main.c:49 61 __libc_start_call_main at ./csu/../sysdeps/nptl/ libc_start_call_main.h:58 62 call_init at ./csu/../csu/libc-start.c:128 63 _start in /home/lo/Dev/LO1/core/instdir/program/soffice.bin ---- soffice.bin: /home/lo/Dev/LO1/core/sw/inc/txatbase.hxx:223: const SwFormatFootnote& SwTextAttr::GetFootnote() const: Assertion `m_aAttr && m_aAttr.Which() == RES_TXTATR_FTN' failed. Fatal exception: Signal 6 Stack: 0 sal::backtrace_get(unsigned int) at /home/lo/Dev/LO1/core/sal/osl/ unx/backtraceapi.cxx:42 (discriminator 3) 1 (anonymous namespace)::printStack(int) at /home/lo/Dev/LO1/core/sal/ osl/unx/signal.cxx:289 2 (anonymous namespace)::callSystemHandler(int, siginfo_t*, void*) at / home/lo/Dev/LO1/core/sal/osl/unx/signal.cxx:330 3 (anonymous namespace)::signalHandlerFunction(int, siginfo_t*, void*) at /home/lo/Dev/LO1/core/sal/osl/unx/signal.cxx:427 4 __restore_rt at libc_sigaction.c:? 5 __pthread_kill_implementation at ./nptl/pthread_kill.c:44 6 __GI_raise at ./signal/../sysdeps/posix/raise.c:27 7 __GI_abort at ./stdlib/abort.c:81 (discriminator 21) 8 _nl_load_domain at ./intl/loadmsgcat.c:1177 9 __GI___assert_fail at :? 10 SwTextAttr::GetFootnote() const at /home/lo/Dev/LO1/core/sw/inc/ txatbase.hxx:224 11 SwContentTree::QueryTooltipHdl(weld::TreeIter const&) at /home/lo/ Dev/LO1/core/sw/source/uibase/utlui/content.cxx:4974 12 SwContentTree::LinkStubQueryTooltipHdl(void*, weld::TreeIter const&) at /home/lo/Dev/LO1/core/sw/source/uibase/utlui/content.cxx:4895 13 Link<weld::TreeIter const&, rtl::OUString>::Call(weld::TreeIter const&) const at /home/lo/Dev/LO1/core/include/tools/link.hxx:111 14 weld::TreeView::signal_query_tooltip(weld::TreeIter const&) at / home/lo/Dev/LO1/core/include/vcl/weld.hxx:977 15 (anonymous namespace)::GtkInstanceTreeView::signalQueryTooltip(_GtkWidget*, int, int, int, _GtkTooltip*, void*) at /home/lo/Dev/LO1/core/vcl/unx/gtk3/ gtkinst.cxx:14701 (discriminator 2) 16 gtk_socket_add_id in /lib/x86_64-linux-gnu/libgtk-3.so.0 17 g_closure_invoke in /lib/x86_64-linux-gnu/libgobject-2.0.so.0 18 g_signal_handlers_destroy in /lib/x86_64-linux-gnu/ libgobject-2.0.so.0 19 g_signal_emit_valist in /lib/x86_64-linux-gnu/libgobject-2.0.so.0 20 g_signal_emit in /lib/x86_64-linux-gnu/libgobject-2.0.so.0 21 gtk_tooltip_set_icon_from_gicon in /lib/x86_64-linux-gnu/ libgtk-3.so.0 22 gtk_tooltip_set_icon_from_gicon in /lib/x86_64-linux-gnu/ libgtk-3.so.0 23 gtk_main_do_event in /lib/x86_64-linux-gnu/libgtk-3.so.0 24 gdk_drawing_context_get_clip in /lib/x86_64-linux-gnu/libgdk-3.so.0 25 gdk_x11_drag_context_get_type in /lib/x86_64-linux-gnu/libgdk-3.so.0 26 g_main_context_dispatch in /lib/x86_64-linux-gnu/libglib-2.0.so.0 27 g_io_channel_new_file in /lib/x86_64-linux-gnu/libglib-2.0.so.0 28 g_main_loop_run in /lib/x86_64-linux-gnu/libglib-2.0.so.0 29 main_loop_run(_GMainLoop*) at /home/lo/Dev/LO1/core/vcl/inc/unx/gtk/ gtkdata.hxx:63 30 (anonymous namespace)::DialogRunner::run() at /home/lo/Dev/LO1/core/ vcl/unx/gtk3/gtkinst.cxx:6747 (discriminator 13) 31 (anonymous namespace)::GtkInstanceDialog::run() at /home/lo/Dev/LO1/ core/vcl/unx/gtk3/gtkinst.cxx:10046 32 weld::DialogController::run() at /home/lo/Dev/LO1/core/include/vcl/ weld.hxx:2669 33 (anonymous namespace)::RecoveryUI::impl_doEmergencySave() at /home/ lo/Dev/LO1/core/svx/source/unodraw/recoveryui.cxx:258 (discriminator 1) 34 (anonymous namespace)::RecoveryUI::dispatchWithReturnValue(com::sun::star::util::URL const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&) at /home/lo/Dev/LO1/core/svx/source/unodraw/recoveryui.cxx:148 35 desktop::(anonymous namespace)::impl_callRecoveryUI(bool, bool) at / home/lo/Dev/LO1/core/desktop/source/app/app.cxx:1022 (discriminator 5) 36 desktop::Desktop::Exception(ExceptionCategory) at /home/lo/Dev/LO1/ core/desktop/source/app/app.cxx:1177 37 VCLExceptionSignal_impl(void*, oslSignalInfo*) at /home/lo/Dev/LO1/ core/vcl/source/app/svmain.cxx:176 38 callSignalHandler(oslSignalInfo*) at /home/lo/Dev/LO1/core/sal/osl/ all/signalshared.cxx:47 39 (anonymous namespace)::signalHandlerFunction(int, siginfo_t*, void*) at /home/lo/Dev/LO1/core/sal/osl/unx/signal.cxx:423 40 __restore_rt at libc_sigaction.c:? 41 SfxPoolItem::Which() const at /home/lo/Dev/LO1/core/include/svl/ poolitem.hxx:225 42 SfxPoolItemHolder::Which() const at /home/lo/Dev/LO1/core/include/ svl/itemset.hxx:74 (discriminator 1) 43 SwTextAttr::GetFootnote() const at /home/lo/Dev/LO1/core/sw/inc/ txatbase.hxx:223 (discriminator 1) 44 SwContentTree::QueryTooltipHdl(weld::TreeIter const&) at /home/lo/ Dev/LO1/core/sw/source/uibase/utlui/content.cxx:4974 45 SwContentTree::LinkStubQueryTooltipHdl(void*, weld::TreeIter const&) at /home/lo/Dev/LO1/core/sw/source/uibase/utlui/content.cxx:4895 46 Link<weld::TreeIter const&, rtl::OUString>::Call(weld::TreeIter const&) const at /home/lo/Dev/LO1/core/include/tools/link.hxx:111 47 weld::TreeView::signal_query_tooltip(weld::TreeIter const&) at / home/lo/Dev/LO1/core/include/vcl/weld.hxx:977 48 (anonymous namespace)::GtkInstanceTreeView::signalQueryTooltip(_GtkWidget*, int, int, int, _GtkTooltip*, void*) at /home/lo/Dev/LO1/core/vcl/unx/gtk3/ gtkinst.cxx:14701 (discriminator 2) 49 gtk_socket_add_id in /lib/x86_64-linux-gnu/libgtk-3.so.0 50 g_closure_invoke in /lib/x86_64-linux-gnu/libgobject-2.0.so.0 51 g_signal_handlers_destroy in /lib/x86_64-linux-gnu/ libgobject-2.0.so.0 52 g_signal_emit_valist in /lib/x86_64-linux-gnu/libgobject-2.0.so.0 53 g_signal_emit in /lib/x86_64-linux-gnu/libgobject-2.0.so.0 54 gtk_tooltip_set_icon_from_gicon in /lib/x86_64-linux-gnu/ libgtk-3.so.0 55 gtk_tooltip_set_icon_from_gicon in /lib/x86_64-linux-gnu/ libgtk-3.so.0 56 gtk_tooltip_trigger_tooltip_query in /lib/x86_64-linux-gnu/ libgtk-3.so.0 57 GtkSalFrame::ShowTooltip(rtl::OUString const&, tools::Rectangle const&) at /home/lo/Dev/LO1/core/vcl/unx/gtk3/gtkframe.cxx:3154 58 ImplShowHelpWindow(vcl::Window*, unsigned short, QuickHelpFlags, rtl::OUString const&, Point const&, tools::Rectangle const&) at /home/ lo/Dev/LO1/core/vcl/source/app/help.cxx:492 59 Help::ShowQuickHelp(vcl::Window*, tools::Rectangle const&, rtl::OUString const&, QuickHelpFlags) at /home/lo/Dev/LO1/core/vcl/ source/app/help.cxx:191 (discriminator 5) 60 vcl::Window::RequestHelp(HelpEvent const&) at /home/lo/Dev/LO1/core/ vcl/source/window/window.cxx:1928 61 ImplBorderWindow::RequestHelp(HelpEvent const&) at /home/lo/Dev/LO1/ core/vcl/source/window/brdwin.cxx:1673 62 vcl::Window::RequestHelp(HelpEvent const&) at /home/lo/Dev/LO1/core/ vcl/source/window/window.cxx:1928 63 vcl::Window::RequestHelp(HelpEvent const&) at /home/lo/Dev/LO1/core/ vcl/source/window/window.cxx:1928 64 ImplBorderWindow::RequestHelp(HelpEvent const&) at /home/lo/Dev/LO1/ core/vcl/source/window/brdwin.cxx:1673 65 vcl::Window::RequestHelp(HelpEvent const&) at /home/lo/Dev/LO1/core/ vcl/source/window/window.cxx:1928 66 vcl::Window::RequestHelp(HelpEvent const&) at /home/lo/Dev/LO1/core/ vcl/source/window/window.cxx:1928 67 SplitWindow::RequestHelp(HelpEvent const&) at /home/lo/Dev/LO1/core/ vcl/source/window/splitwin.cxx:2117 68 vcl::Window::RequestHelp(HelpEvent const&) at /home/lo/Dev/LO1/core/ vcl/source/window/window.cxx:1928 69 vcl::Window::RequestHelp(HelpEvent const&) at /home/lo/Dev/LO1/core/ vcl/source/window/window.cxx:1928 70 vcl::Window::RequestHelp(HelpEvent const&) at /home/lo/Dev/LO1/core/ vcl/source/window/window.cxx:1928 71 vcl::Window::RequestHelp(HelpEvent const&) at /home/lo/Dev/LO1/core/ vcl/source/window/window.cxx:1928 72 ImplHandleMouseHelpRequest(vcl::Window*, Point const&) at /home/lo/ Dev/LO1/core/vcl/source/window/winproc.cxx:186 73 ImplHandleMouseEvent(VclPtr<vcl::Window> const&, NotifyEventType, bool, long, long, unsigned long, unsigned short, MouseEventModifiers) at /home/lo/Dev/LO1/core/vcl/source/window/winproc.cxx:740 74 ImplHandleSalMouseMove(vcl::Window*, SalMouseEvent const*) at /home/ lo/Dev/LO1/core/vcl/source/window/winproc.cxx:2332 75 ImplWindowFrameProc(vcl::Window*, SalEvent, void const*) at /home/ lo/Dev/LO1/core/vcl/source/window/winproc.cxx:2665 (discriminator 1) 76 SalFrame::CallCallback(SalEvent, void const*) const at /home/lo/Dev/ LO1/core/vcl/inc/salframe.hxx:312 (discriminator 1) 77 GtkSalFrame::CallCallbackExc(SalEvent, void const*) const at /home/ lo/Dev/LO1/core/vcl/unx/gtk3/gtkframe.cxx:6388 78 GtkSalFrame::DrawingAreaMotion(int, int, unsigned int, unsigned int) at /home/lo/Dev/LO1/core/vcl/unx/gtk3/gtkframe.cxx:3719 79 GtkSalFrame::signalMotion(_GtkWidget*, _GdkEventMotion*, void*) at / home/lo/Dev/LO1/core/vcl/unx/gtk3/gtkframe.cxx:3756 80 gtk_socket_add_id in /lib/x86_64-linux-gnu/libgtk-3.so.0 81 g_closure_invoke in /lib/x86_64-linux-gnu/libgobject-2.0.so.0 82 g_signal_handlers_destroy in /lib/x86_64-linux-gnu/ libgobject-2.0.so.0 83 g_signal_emit_valist in /lib/x86_64-linux-gnu/libgobject-2.0.so.0 84 g_signal_emit in /lib/x86_64-linux-gnu/libgobject-2.0.so.0 85 gtk_widget_init_template in /lib/x86_64-linux-gnu/libgtk-3.so.0 86 gtk_grab_remove in /lib/x86_64-linux-gnu/libgtk-3.so.0 87 gtk_main_do_event in /lib/x86_64-linux-gnu/libgtk-3.so.0 88 gdk_drawing_context_get_clip in /lib/x86_64-linux-gnu/libgdk-3.so.0 89 gdk_x11_drag_context_get_type in /lib/x86_64-linux-gnu/libgdk-3.so.0 90 g_main_context_dispatch in /lib/x86_64-linux-gnu/libglib-2.0.so.0 91 g_io_channel_new_file in /lib/x86_64-linux-gnu/libglib-2.0.so.0 92 g_main_context_iteration in /lib/x86_64-linux-gnu/libglib-2.0.so.0 93 GtkSalData::Yield(bool, bool) at /home/lo/Dev/LO1/core/vcl/unx/gtk3/ gtkdata.cxx:405 (discriminator 6) 94 GtkInstance::DoYield(bool, bool) at /home/lo/Dev/LO1/core/vcl/unx/ gtk3/gtkinst.cxx:436 95 ImplYield(bool, bool) at /home/lo/Dev/LO1/core/vcl/source/app/ svapp.cxx:395 96 Application::Yield() at /home/lo/Dev/LO1/core/vcl/source/app/ svapp.cxx:483 97 Application::Execute() at /home/lo/Dev/LO1/core/vcl/source/app/ svapp.cxx:370 98 desktop::Desktop::Main() at /home/lo/Dev/LO1/core/desktop/source/ app/app.cxx:1617 99 ImplSVMain() at /home/lo/Dev/LO1/core/vcl/source/app/svmain.cxx:229 100 SVMain() at /home/lo/Dev/LO1/core/vcl/source/app/svmain.cxx:262 101 soffice_main at /home/lo/Dev/LO1/core/desktop/source/app/ sofficemain.cxx:93 102 sal_main at /home/lo/Dev/LO1/core/desktop/source/app/main.c:51 103 main at /home/lo/Dev/LO1/core/desktop/source/app/main.c:49 104 __libc_start_call_main at ./csu/../sysdeps/nptl/ libc_start_call_main.h:58 105 call_init at ./csu/../csu/libc-start.c:128 106 _start in /home/lo/Dev/LO1/core/instdir/program/soffice.bin Change-Id: Id2bad55221a8603a1e12f870bdc1479e7709ee58 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166414 Tested-by: Jenkins Reviewed-by: Jim Raykowski <raykowj@gmail.com>
6 daysgtk3 a11y: Set a11y relations for custom combobox implMichael Weghorn1-0/+15
As described in more detail in the previous commit Change-Id: If5faf77c5f82836c376c04bb6e4e42ce5a3023a2 Author: Michael Weghorn <m.weghorn@posteo.de> Date: Thu Apr 18 14:02:25 2024 +0200 tdf#159910 gtk3 a11y: Keep a11y props for combobox , the gtk3 VCL plugin uses a custom combobox implementation rather than the stock GtkComboBox. Similar to how the above commit makes sure that accessible role, name and description set for the stock GtkComboBox are also set in the custom implementation, do the same for the accessible relations as well, by taking over the relations from the GtkComboBox to the toggle button of the custom implementation as well. One particularly relevant relation in practice is `ATK_RELATION_LABELLED_BY`, because the target set via that relation is what screen readers tend to announce when a combobox receives focus and doesn't have an accessible name set for itself. With this change in place, the Orca screen reader announces the corresponding label e.g. in the "Format" -> "Character" dialog in Writer, tab "Font Effects", so e.g. "Overlining:, combobox" is announced by Orca when the combobox for setting the value for the overlining receives focus, rather than just saying "combobox", which wouldn't make clear to the user what this combobox is for. (This also matches what Orca already does for the qt6 VCL plugin.) This change only takes over the relations set for the combobox itself. Usually, relations are set both ways (e.g. the target of the `ATK_RELATION_LABELLED_BY` relation would itself have an `ATK_RELATION_LABEL_FOR` relation with the combobox as a target). If necessary, this solution could be extended to also iterate over all the target objects and check whether they have relations with the combobox as a target and set corresponding relations to the toggle button as well (or instead). Change-Id: I05e39ef5606ffa49ca7673039de3e1aa74fc8649 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166259 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
6 daystdf#159910 gtk3 a11y: Keep a11y props for comboboxMichael Weghorn2-0/+17
Due to various issues with GtkComboBox, the gtk3 VCL plugin does not use the original GtkComboBox, but a custom implementation, originally introduced in commit bc0e0f633b05c4f91b6695488fc9e5c127507ba5 Date: Thu Apr 9 11:41:00 2020 +0100 tdf#131120 use a replacement for GtkComboBox (See full commit message for more details and reasons.) This means that the accessible role, name and description from the .ui file are not set automatically for the GtkToggleButton widget that acts as the combobox instead and receives keyboard focus. In order to make these available for AT, explicitly take these over from the original GtkComboBox. With this in place, the Orca screen reader now e.g. properly announces the comboboxes in Writer's Navigator as "Navigate By, combobox" and "Active window, combobox" (similar to how it already does for the qt6 VCL plugin), rather than just saying "toggle button, not pressed", which didn't give any hint to the user what the currently focused UI element is about and how to interact with it. Also set a default a11y role of combo-box in the replacement's .ui file. (The role from the GtkComboBox's AtkObject should always override that in practice, though.) Change-Id: If5faf77c5f82836c376c04bb6e4e42ce5a3023a2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166248 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
6 daystdf#159910 sw a11y: Set a11y name for Navigator comboboxMichael Weghorn1-0/+5
Set a11y name for this combobox in the Navigator to "Navigate By". This is in line with the tooltip shown when hovering over the combobox, which is set for the combobox's parent, the panel. This makes Orca with the qt6 VCL plugin now announce the a11y name of the combobox with the corresponding role, rather than the panel ("Navigator, panel, Navigate By, combobox" instead of "Navigator, panel, Navigate by, panel, combobox"). For gtk3, Orca still doesn't announce the combobox or it's a11y name set in the .ui file, but still just says "Toggle button, not pressed", which will have to be addressed separately. This is because while there is a combobox with accessible name "Navigate By" in the AT-SPI tree now, the object that gets focus is a toggle button that doesn't have a name set for the gtk3 VCL plugin, which will be addressed in a separate commit. Change-Id: Id6b615f033c78d318611b520d49332714fa40eb0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166246 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-04-11tdf#160176 svx: Reset help text when form control has noneMichael Weghorn1-16/+15
In `FmFormPage::RequestHelp`, also call `Help::ShowQuickHelp`/`Help::ShowBalloon` when the help text is empty, as that is the way to unset the help text/remove the tooltip again, see `ImplShowHelpWindow` in `vcl/source/app/help.cxx`: For the case of non-native tooltips (e.g. the gen VCL plugin on Linux), the `bRemoveHelp = true` code path is relevant. For qt5/qt6/kf5/kf6 which use native tooltips, the call to pParent->ImplGetFrame()->ShowTooltip(rHelpText, rHelpArea) further up sets the `QtFrame`'s `m_aTooltipText` member to an empty string, which prevents showing the outdated help text for the `QEvent::ToolTip` event in `QtWidget::handleEvent`. Change-Id: Iceb2424d9c72ae46333a718c677629122e517f11 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166006 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-04-11related tdf#160176 qt: Create dummy Qt widget in main threadMichael Weghorn1-6/+17
Always run `QtGraphics_Controls::getNativeControlRegion` in the main thread, as it may create a dummy `QLineEdit` (see the `ControlType::MultilineEditbox` and `ControlType::Editbox` cases) and creating Qt widgets is only allowed in the main thread. Without the following scenario runs into an assert with a current Qt 6 dev debug build when using the qt6 VCL plugin: 1) open sample document attachment 193089 from tdf#160176 2) enable Form Design Toolbar 3) switch to Design mode 4) select label next to "Labelfield2" label 5) right-click, "Control Properties" 6) type anything for the help text and tab to the next UI element Backtrace: ASSERT failure in QWidget: "Widgets must be created in the GUI thread.", file /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp, line 956 Thread 45 "browserlistbox" received signal SIGABRT, Aborted. [Switching to Thread 0x7fff8d08d6c0 (LWP 203558)] __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 44 ./nptl/pthread_kill.c: No such file or directory. (gdb) bt #0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 #1 0x00007ffff78a81cf in __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78 #2 0x00007ffff785a472 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #3 0x00007ffff78444b2 in __GI_abort () at ./stdlib/abort.c:79 #4 0x00007fffe32f8540 in qAbort() () at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:49 #5 0x00007fffe330c393 in qt_message_fatal<QString&>(QtMsgType, QMessageLogContext const&, QString&) (context=..., message=...) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:2056 #6 0x00007fffe3305344 in qt_message(QtMsgType, const QMessageLogContext &, const char *, typedef __va_list_tag __va_list_tag *) (msgType=QtFatalMsg, context=..., msg=0x7fffe3981990 "ASSERT failure in %s: \"%s\", file %s, line %d", ap=0x7fff8d086178) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:374 #7 0x00007fffe330740f in QMessageLogger::fatal(char const*, ...) const (this=0x7fff8d0863c0, msg=0x7fffe3981990 "ASSERT failure in %s: \"%s\", file %s, line %d") at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:874 #8 0x00007fffe32f8613 in qt_assert_x(char const*, char const*, char const*, int) (where=0x7fffe1becdf3 "QWidget", what=0x7fffe1becdc8 "Widgets must be created in the GUI thread.", file=0x7fffe1becca0 "/home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp", line=956) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:114 #9 0x00007fffe144118c in QWidgetPrivate::init(QWidget*, QFlags<Qt::WindowType>) (this=0x7fff780054d0, parentWidget=0x0, f=...) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:956 #10 0x00007fffe1440ca1 in QWidget::QWidget(QWidgetPrivate&, QWidget*, QFlags<Qt::WindowType>) (this=0x7fff8d086d00, dd=..., parent=0x0, f=...) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:872 #11 0x00007fffe16a7d22 in QLineEdit::QLineEdit(QString const&, QWidget*) (this=0x7fff8d086d00, contents=..., parent=0x0) at /home/michi/development/git/qt5/qtbase/src/widgets/widgets/qlineedit.cpp:253 #12 0x00007fffe16a7c98 in QLineEdit::QLineEdit(QWidget*) (this=0x7fff8d086d00, parent=0x0) at /home/michi/development/git/qt5/qtbase/src/widgets/widgets/qlineedit.cpp:239 #13 0x00007fffe404aebc in QtGraphics_Controls::getNativeControlRegion(ControlType, ControlPart, tools::Rectangle const&, ControlState, ImplControlValue const&, rtl::OUString const&, tools::Rectangle&, tools::Rectangle&) (this=0x55555cbb13e0, type=ControlType::Editbox, part=ControlPart::Entire, controlRegion=..., controlState=(ControlState::ENABLED | ControlState::ROLLOVER), val=..., nativeBoundingRegion=..., nativeContentRegion=...) at vcl/qt6/../qt5/QtGraphics_Controls.cxx:784 #14 0x00007fffee72945e in SalGraphics::GetNativeControlRegion(ControlType, ControlPart, tools::Rectangle const&, ControlState, ImplControlValue const&, tools::Rectangle&, tools::Rectangle&, OutputDevice const&) (this=0x55555eb28920, nType=ControlType::Editbox, nPart=ControlPart::Entire, rControlRegion=..., nState=(ControlState::ENABLED | ControlState::ROLLOVER), aValue=..., rNativeBoundingRegion=..., rNativeContentRegion=..., rOutDev=...) at /home/michi/development/git/libreoffice/vcl/source/gdi/salgdilayout.cxx:834 #15 0x00007fffee3a7195 in OutputDevice::GetNativeControlRegion(ControlType, ControlPart, tools::Rectangle const&, ControlState, ImplControlValue const&, tools::Rectangle&, tools::Rectangle&) const (this=0x5555607cd870, nType=ControlType::Editbox, nPart=ControlPart::Entire, rControlRegion=..., nState=(ControlState::ENABLED | ControlState::ROLLOVER), aValue=..., rNativeBoundingRegion=..., rNativeContentRegion=...) at /home/michi/development/git/libreoffice/vcl/source/outdev/nativecontrols.cxx:313 #16 0x00007fffede63b9d in ImplSmallBorderWindowView::DrawWindow(OutputDevice&, Point const*) (this=0x5555607c7c10, rRenderContext=...) at /home/michi/development/git/libreoffice/vcl/source/window/brdwin.cxx:699 #17 0x00007fffede69900 in ImplBorderWindow::Paint(OutputDevice&, tools::Rectangle const&) (this=0x5555607c7ca0, rRenderContext=...) at /home/michi/development/git/libreoffice/vcl/source/window/brdwin.cxx:1628 #18 0x00007fffede3e241 in PaintHelper::DoPaint(vcl::Region const*) (this=0x7fff8d088188, pRegion=0x7fff78006480) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:313 #19 0x00007fffede3feff in vcl::Window::ImplCallPaint(vcl::Region const*, ImplPaintFlags) (this=0x5555607c7ca0, pRegion=0x7fff78006480, nPaintFlags=(ImplPaintFlags::PaintAllChildren | ImplPaintFlags::PaintChildren | ImplPaintFlags::Erase)) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:617 #20 0x00007fffede3f791 in PaintHelper::~PaintHelper() (this=0x7fff8d0883c8) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:552 #21 0x00007fffede3ff86 in vcl::Window::ImplCallPaint(vcl::Region const*, ImplPaintFlags) (this=0x55556002ead0, pRegion=0x7fff78005ec0, nPaintFlags=(ImplPaintFlags::PaintAllChildren | ImplPaintFlags::PaintChildren | ImplPaintFlags::Erase)) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:623 #22 0x00007fffede3f791 in PaintHelper::~PaintHelper() (this=0x7fff8d088608) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:552 #23 0x00007fffede3ff86 in vcl::Window::ImplCallPaint(vcl::Region const*, ImplPaintFlags) (this=0x55555edac0e0, pRegion=0x7fff78005dc0, nPaintFlags=(ImplPaintFlags::PaintAllChildren | ImplPaintFlags::PaintChildren | ImplPaintFlags::Erase)) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:623 #24 0x00007fffede3f791 in PaintHelper::~PaintHelper() (this=0x7fff8d088848) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:552 #25 0x00007fffede3ff86 in vcl::Window::ImplCallPaint(vcl::Region const*, ImplPaintFlags) (this=0x55555edab480, pRegion=0x7fff78005d80, nPaintFlags=(ImplPaintFlags::PaintAllChildren | ImplPaintFlags::PaintChildren | ImplPaintFlags::Erase)) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:623 #26 0x00007fffede3f791 in PaintHelper::~PaintHelper() (this=0x7fff8d088a88) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:552 #27 0x00007fffede3ff86 in vcl::Window::ImplCallPaint(vcl::Region const*, ImplPaintFlags) (this=0x55555edaa900, pRegion=0x7fff78004c40, nPaintFlags=(ImplPaintFlags::PaintAllChildren | ImplPaintFlags::PaintChildren | ImplPaintFlags::Erase)) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:623 #28 0x00007fffede3f791 in PaintHelper::~PaintHelper() (this=0x7fff8d088cc8) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:552 #29 0x00007fffede3ff86 in vcl::Window::ImplCallPaint(vcl::Region const*, ImplPaintFlags) (this=0x55555ed29400, pRegion=0x7fff78004c00, nPaintFlags=(ImplPaintFlags::PaintAllChildren | ImplPaintFlags::PaintChildren | ImplPaintFlags::Erase)) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:623 #30 0x00007fffede3f791 in PaintHelper::~PaintHelper() (this=0x7fff8d088f08) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:552 #31 0x00007fffede3ff86 in vcl::Window::ImplCallPaint(vcl::Region const*, ImplPaintFlags) (this=0x55555eccc910, pRegion=0x7fff78005d40, nPaintFlags=(ImplPaintFlags::PaintAllChildren | ImplPaintFlags::PaintChildren | ImplPaintFlags::Erase)) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:623 #32 0x00007fffede3f791 in PaintHelper::~PaintHelper() (this=0x7fff8d089148) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:552 #33 0x00007fffede3ff86 in vcl::Window::ImplCallPaint(vcl::Region const*, ImplPaintFlags) (this=0x55555eda7a70, pRegion=0x7fff78004ac0, nPaintFlags=(ImplPaintFlags::PaintAllChildren | ImplPaintFlags::PaintChildren | ImplPaintFlags::Erase)) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:623 --Type <RET> for more, q to quit, c to continue without paging-- #34 0x00007fffede3f791 in PaintHelper::~PaintHelper() (this=0x7fff8d089388) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:552 #35 0x00007fffede3ff86 in vcl::Window::ImplCallPaint(vcl::Region const*, ImplPaintFlags) (this=0x55555eda2210, pRegion=0x7fff78001230, nPaintFlags=(ImplPaintFlags::PaintAllChildren | ImplPaintFlags::PaintChildren | ImplPaintFlags::Erase)) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:623 #36 0x00007fffede3f791 in PaintHelper::~PaintHelper() (this=0x7fff8d0895c8) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:552 #37 0x00007fffede3ff86 in vcl::Window::ImplCallPaint(vcl::Region const*, ImplPaintFlags) (this=0x55555ecd5d20, pRegion=0x7fff78002510, nPaintFlags=(ImplPaintFlags::PaintAllChildren | ImplPaintFlags::PaintChildren | ImplPaintFlags::Erase)) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:623 #38 0x00007fffede3f791 in PaintHelper::~PaintHelper() (this=0x7fff8d089808) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:552 #39 0x00007fffede3ff86 in vcl::Window::ImplCallPaint(vcl::Region const*, ImplPaintFlags) (this=0x55555ecdae90, pRegion=0x7fff78001ae0, nPaintFlags=(ImplPaintFlags::PaintAllChildren | ImplPaintFlags::PaintChildren | ImplPaintFlags::Erase)) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:623 #40 0x00007fffede3f791 in PaintHelper::~PaintHelper() (this=0x7fff8d089a48) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:552 #41 0x00007fffede3ff86 in vcl::Window::ImplCallPaint(vcl::Region const*, ImplPaintFlags) (this=0x55555bb5ddb0, pRegion=0x55555eb4e340, nPaintFlags=(ImplPaintFlags::PaintAllChildren | ImplPaintFlags::PaintChildren | ImplPaintFlags::Erase)) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:623 #42 0x00007fffede3f791 in PaintHelper::~PaintHelper() (this=0x7fff8d089c88) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:552 #43 0x00007fffede3ff86 in vcl::Window::ImplCallPaint(vcl::Region const*, ImplPaintFlags) (this=0x55555ed5c6e0, pRegion=0x7fff78001310, nPaintFlags=(ImplPaintFlags::PaintAllChildren | ImplPaintFlags::PaintChildren | ImplPaintFlags::Erase)) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:623 #44 0x00007fffede3f791 in PaintHelper::~PaintHelper() (this=0x7fff8d089ec8) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:552 #45 0x00007fffede3ff86 in vcl::Window::ImplCallPaint(vcl::Region const*, ImplPaintFlags) (this=0x55555eb3aa10, pRegion=0x0, nPaintFlags=(ImplPaintFlags::PaintAllChildren | ImplPaintFlags::PaintChildren | ImplPaintFlags::Erase)) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:623 #46 0x00007fffede41a32 in vcl::Window::PaintImmediately() (this=0x5555607c7ca0) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:1340 #47 0x00007fffede415a0 in vcl::Window::PaintImmediately() (this=0x5555607c49b0) at /home/michi/development/git/libreoffice/vcl/source/window/paint.cxx:1280 #48 0x00007fffee17f7ac in Edit::ImplInvalidateOrRepaint() (this=0x5555607c49b0) at /home/michi/development/git/libreoffice/vcl/source/control/edit.cxx:451 #49 0x00007fffee182a52 in Edit::ImplAlignAndPaint() (this=0x5555607c49b0) at /home/michi/development/git/libreoffice/vcl/source/control/edit.cxx:1170 #50 0x00007fffee183ef0 in Edit::ImplInsertText(rtl::OUString const&, Selection const*, bool) (this=0x5555607c49b0, rStr="ee", pNewSel=0x7fff8d08a6b8, bIsUserInput=false) at /home/michi/development/git/libreoffice/vcl/source/control/edit.cxx:885 #51 0x00007fffee1841ca in Edit::ImplSetText(rtl::OUString const&, Selection const*) (this=0x5555607c49b0, rText="ee", pNewSelection=0x7fff8d08a6b8) at /home/michi/development/git/libreoffice/vcl/source/control/edit.cxx:918 #52 0x00007fffee18cfd4 in Edit::SetText(rtl::OUString const&) (this=0x5555607c49b0, rStr="ee") at /home/michi/development/git/libreoffice/vcl/source/control/edit.cxx:2560 #53 0x00007fffee8d974a in SalInstanceEntry::set_text(rtl::OUString const&) (this=0x5555607c4200, rText="ee") at /home/michi/development/git/libreoffice/vcl/source/app/salvtables.cxx:3383 #54 0x00007fff7ef6054a in pcr::OEditControl::setValue(com::sun::star::uno::Any const&) (this=0x5555607c7660, _rValue=uno::Any("string": "ee")) at /home/michi/development/git/libreoffice/extensions/source/propctrlr/standardcontrol.cxx:200 #55 0x00007fff7ed96819 in pcr::OBrowserListBox::impl_setControlAsPropertyValue(pcr::ListBoxLine const&, com::sun::star::uno::Any const&) (_rLine=..., _rPropertyValue=uno::Any("string": "ee")) at /home/michi/development/git/libreoffice/extensions/source/propctrlr/browserlistbox.cxx:551 #56 0x00007fff7ed96485 in pcr::OBrowserListBox::SetPropertyValue(rtl::OUString const&, com::sun::star::uno::Any const&, bool) (this=0x55555eda22b0, _rEntryName="HelpText", _rValue=uno::Any("string": "ee"), _bUnknownValue=false) at /home/michi/development/git/libreoffice/extensions/source/propctrlr/browserlistbox.cxx:403 #57 0x00007fff7ef432e8 in pcr::OPropertyEditor::SetPropertyValue(rtl::OUString const&, com::sun::star::uno::Any const&, bool) (this=0x55555ecdb3e0, rEntryName="HelpText", _rValue=uno::Any("string": "ee"), _bUnknownValue=false) at /home/michi/development/git/libreoffice/extensions/source/propctrlr/propertyeditor.cxx:277 #58 0x00007fff7ef01d4f in pcr::OPropertyBrowserController::Commit(rtl::OUString const&, com::sun::star::uno::Any const&) (this=0x55555c5f1b40, rName="HelpText", _rValue=uno::Any("string": "ee")) at /home/michi/development/git/libreoffice/extensions/source/propctrlr/propcontroller.cxx:1337 #59 0x00007fff7ed954ae in pcr::OBrowserListBox::valueChanged(com::sun::star::uno::Reference<com::sun::star::inspection::XPropertyControl> const&) (this=0x55555eda22b0, _rxControl=uno::Reference to (pcr::OEditControl *) 0x5555607c76b0) at /home/michi/development/git/libreoffice/extensions/source/propctrlr/browserlistbox.cxx:637 #60 0x00007fff7ed95268 in pcr::PropertyControlContext_Impl::impl_processEvent_throw(comphelper::AnyEvent const&) (this=0x55555ed29270, _rEvent=...) at /home/michi/development/git/libreoffice/extensions/source/propctrlr/browserlistbox.cxx:291 #61 0x00007fff7ed950b9 in pcr::PropertyControlContext_Impl::processEvent(comphelper::AnyEvent const&) (this=0x55555ed29270, _rEvent=...) at /home/michi/development/git/libreoffice/extensions/source/propctrlr/browserlistbox.cxx:272 #62 0x00007ffff6118a2e in comphelper::AsyncEventNotifierBase::execute() (this=0x5555568d6620) at /home/michi/development/git/libreoffice/comphelper/source/misc/asyncnotification.cxx:139 #63 0x00007ffff6119165 in comphelper::AsyncEventNotifier::execute() (this=0x5555568d6620) at /home/michi/development/git/libreoffice/comphelper/source/misc/asyncnotification.cxx:156 #64 0x00007ffff7d0f6ec in salhelper::Thread::run() (this=0x5555568d6630) at /home/michi/development/git/libreoffice/salhelper/source/thread.cxx:39 #65 0x00007ffff7d0ff2e in threadFunc(void*) (param=0x5555568d6640) at include/osl/thread.hxx:189 #66 0x00007ffff7fa4b2d in osl_thread_start_Impl(void*) (pData=0x55555ecc3e40) at /home/michi/development/git/libreoffice/sal/osl/unx/thread.cxx:237 #67 0x00007ffff78a645c in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:444 #68 0x00007ffff7926bbc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81 Change-Id: I9e0b0d973997e3f4f50a9a31e9692325664fd262 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165995 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-04-04Improved documentation (Emscripten, Qt5 usage, WASM examples)Moritz Duge1-13/+15
Sentence about Emscripten was probably obsolete since around commit 12a6b57c Change-Id: Ide59154439f8a069c2dbd58420c1c93844790a79 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165754 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <thorsten.behrens@allotropia.de>
2024-03-15gtk4 a11y: Add initial text attribute handlingMichael Weghorn1-7/+66
Implement initial handling for reporting text attributes in `lo_accessible_text_get_attributes`. Initially, only the font family attribute is handled, but more can be added in the future (s.a. the gtk3/atk and Qt implementations). With this in place, formatting some text in a Writer paragraph with font "Linux Libertine G" now shows the "family-name" text attribute with a value of "Linux Libertine G" as expected in Accerciser when selecting the paragraph object in Accerciser's treeview of the LO a11y tree and choosing an appropriate offset when using the gtk4 VCL plugin, just as with the gtk3 or qt6 VCL plugins. (Implementation inspired by GTK's internal `gtk_text_view_accessible_text_get_attributes` [1]) [1] https://gitlab.gnome.org/GNOME/gtk/-/blob/fe4cd7cf0f497ace134a39243b0a44ef09e181be/gtk/gtktextview.c#L10459 Change-Id: Iba565753b3143548492ccc817a159ebfb92a8c88 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164858 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-03-13tdf#159915 qt: Force Qt::HighDpiScaleFactorRoundingPolicy::RoundMichael Weghorn1-0/+5
For now, force `Qt::HighDpiScaleFactorRoundingPolicy::Round` for the HighDPI-scale factor rounding policy [1], which is the default for Qt 5, while Qt 6 defaults to `Qt::HighDpiScaleFactorRoundingPolicy::PassThrough` (see [2]), which resulted in broken rendering (e.g. "Help" -> "About" dialog not showing the whole content) when fractional display scaling like 150 % is configured in the KDE Plasma display settings (in contrast to manually setting the `QT_SCALE_FACTOR=1.5` env variable to apply scaling, which was working fine). Quoting from [3]: > The two principal options are whether fractional scale factors should be > rounded to an integer or not. Keeping the scale factor as-is will make > the user interface size match the OS setting exactly, but may cause > painting errors, for example with the Windows style. Manually setting the env variable `QT_SCALE_FACTOR_ROUNDING_POLICY="Round"` has the same effect (and can be used with LO versions not yet containing this fix). (There might be a way to adjust the way that scaling happens to make other policies work, but for now, just hard-code to the policy that is known to work.) [1] https://doc.qt.io/qt-6/qt.html#HighDpiScaleFactorRoundingPolicy-enum [2] https://doc.qt.io/qt-6/highdpi.html#environment-variable-reference [3] https://doc.qt.io/qt-6/qguiapplication.html#setHighDpiScaleFactorRoundingPolicy Change-Id: I8eb6911d4dd5faf00912b8f15a58e0bdace1995a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164768 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-03-01tdf#159837 Drop unneeded TabBar EventNotify KEYINPUT handling codeJim Raykowski2-13/+1
to make qt and windows VCL backends respond to shortcuts when the keyboard focus is on a TabBar tab. commit 51f8e04eaaea50b779e3882e87628a6e625e0fd8 done to make the Shift+Ctrl+F10 short cut, used to dock/undock the sidebar, work from the sidebar tabbar appears no longer necessary. Simply passing the KEYINPUT event on to InterimItemWindow::EventNotify seems to be enough. Change-Id: Idfa8be4260d31e686acf1b49e89549deb9463a41 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164051 Tested-by: Jenkins Reviewed-by: Jim Raykowski <raykowj@gmail.com>
2024-02-29tdf#158030 qt a11y: Implement new QAccessibleAttributesInterfaceMichael Weghorn2-0/+89
Implement the new `QAccessibleAttributesInterface` just added upstream to Qt in qtbase commit [1] commit fb5ffe862688a87cfc136113e067bcba0c49a7ae Author: Michael Weghorn <m.weghorn@posteo.de> AuthorDate: Fri Nov 10 18:25:02 2023 +0100 Commit: Volker Hilsheimer <volker.hilsheimer@qt.io> CommitDate: Thu Feb 29 04:44:22 2024 +0000 a11y: Add new QAccessibleAttributesInterface , see also QTBUG-119057. [2] This API is available with Qt >= 6.8. That interface makes it possible to report object attributes that are bridged to the platform a11y layers. Use it to bridge the attributes retrieved from the `XAccessibleExtendedAttributes` UNO interface. Together with the pending upstream qtbase change that implements the AT-SPI bridge for Linux [3], the "level" AT-SPI object attribute for headings in Writer is correctly reported to AT-SPI, making the Orca screen reader announce "Heading level N" as expected. For now, map not explicitly handled attributes as key-value pairs to Qt via the special `QAccessible::Attribute::Custom` attribute, which causes them to be mapped to AT-SPI unchanged, and can e.g. be used for testing the tdf#158030 scenario. For common attributes - like those specified in the Core Accessibility API Mappings specification [4] - suggesting to add new enum values to the `QAccessible::Attribute` enum to upstream Qt and using those instead should be considered for the future. Related commit for gtk4: commit 3aca2d9776a871f15009a1aa70628ba3a03ee147 Author: Michael Weghorn <m.weghorn@posteo.de> Date: Thu Nov 9 15:31:57 2023 +0100 gtk4 a11y: Handle the "level" object attribute [1] https://code.qt.io/cgit/qt/qtbase.git/commit/?id=fb5ffe862688a87cfc136113e067bcba0c49a7ae [2] https://bugreports.qt.io/browse/QTBUG-119057 [3] https://codereview.qt-project.org/c/qt/qtbase/+/517526 [4] https://www.w3.org/TR/core-aam-1.2/ Change-Id: Ibe357bfd72bb2dc6e44ad941e62737d5cac21e1c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159309 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-02-28tdf#159910 a11y: Dispose VCLXAccessibleList childrenMichael Weghorn2-3/+9
In `VCLXAccessibleList::HandleChangedItemList`, don't just clear the vector of list items, but dispose them first. To avoid code duplication, extract a helper method from `VCLXAccessibleList::disposing` which already disposes the children since commit 51de048ae97cbd371457dbc07120e30db9ee4187 Author: Michael Weghorn <m.weghorn@posteo.de> Date: Mon Sep 4 17:19:03 2023 +0200 tdf#157088 a11y: Dispose list items with list This fixes a similar crash/assert on exit, seen after using the Navigator in Writer (in particular the combo/listboxes in there) with the qt6 VCL plugin and the Orca screen reader running. stderr showed this: soffice.bin: .../libreoffice/comphelper/source/misc/accessibleeventnotifier.cxx:142: bool (anonymous namespace)::implLookupClient(const AccessibleEventNotifier::TClientId, ClientMap::iterator &): Assertion `rClients.end() != rPos && "AccessibleEventNotifier::implLookupClient: invalid client id " "(did you register your client?)!"' failed. Aborted Backtrace: 1 __pthread_kill_implementation pthread_kill.c 44 0x7f0e1a4a816c 2 __pthread_kill_internal pthread_kill.c 78 0x7f0e1a4a81cf 3 __GI_raise raise.c 26 0x7f0e1a45a472 4 __GI_abort abort.c 79 0x7f0e1a4444b2 5 __assert_fail_base assert.c 92 0x7f0e1a4443d5 6 __assert_fail assert.c 101 0x7f0e1a4533a2 7 (anonymous namespace)::implLookupClient accessibleeventnotifier.cxx 140 0x7f0e18ce59ac 8 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing accessibleeventnotifier.cxx 185 0x7f0e18ce5e68 9 VCLXAccessibleListItem::disposing vclxaccessiblelistitem.cxx 164 0x7f0ddf7d237f 10 cppu::WeakComponentImplHelperBase::dispose implbase.cxx 104 0x7f0e1873f544 11 cppu::PartialWeakComponentImplHelper<com::sun::star::accessibility::XAccessible, com::sun::star::accessibility::XAccessibleContext, com::sun::star::accessibility::XAccessibleComponent, com::sun::star::accessibility::XAccessibleEventBroadcaster, com::sun::star::accessibility::XAccessibleText, com::sun::star::lang::XServiceInfo>::dispose compbase.hxx 90 0x7f0ddf7cb7c5 12 cppu::WeakComponentImplHelperBase::release implbase.cxx 79 0x7f0e1873f1fe 13 cppu::PartialWeakComponentImplHelper<com::sun::star::accessibility::XAccessible, com::sun::star::accessibility::XAccessibleContext, com::sun::star::accessibility::XAccessibleComponent, com::sun::star::accessibility::XAccessibleEventBroadcaster, com::sun::star::accessibility::XAccessibleText, com::sun::star::lang::XServiceInfo>::release compbase.hxx 86 0x7f0ddf7cd0c5 14 com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible>::~Reference Reference.hxx 114 0x7f0e06bbccbe 15 QtAccessibleWidget::~QtAccessibleWidget QtAccessibleWidget.hxx 39 0x7f0e06bd618d 16 QtAccessibleWidget::~QtAccessibleWidget QtAccessibleWidget.hxx 39 0x7f0e06bd6219 17 QAccessibleCache::deleteInterface qaccessiblecache.cpp 173 0x7f0e05545319 18 QAccessibleCache::~QAccessibleCache qaccessiblecache.cpp 31 0x7f0e0554492a 19 QAccessibleCache::~QAccessibleCache qaccessiblecache.cpp 32 0x7f0e055449b0 20 cleanupAccessibleCache qaccessiblecache.cpp 24 0x7f0e05544896 21 qt_call_post_routines qcoreapplication.cpp 332 0x7f0e05faf826 22 QApplication::~QApplication qapplication.cpp 665 0x7f0e0419e24a 23 QApplication::~QApplication qapplication.cpp 722 0x7f0e0419e55c 24 std::default_delete<QApplication>::operator() unique_ptr.h 99 0x7f0e06c5d63c 25 std::__uniq_ptr_impl<QApplication, std::default_delete<QApplication>>::reset unique_ptr.h 211 0x7f0e06c5df7c 26 std::unique_ptr<QApplication, std::default_delete<QApplication>>::reset unique_ptr.h 509 0x7f0e06c58bfd 27 QtInstance::~QtInstance QtInstance.cxx 305 0x7f0e06c51184 28 QtInstance::~QtInstance QtInstance.cxx 302 0x7f0e06c51279 29 DestroySalInstance salplug.cxx 368 0x7f0e114c0a18 30 DeInitVCL svmain.cxx 625 0x7f0e115c5e7d 31 ImplSVMain svmain.cxx 254 0x7f0e115c4031 32 SVMain svmain.cxx 261 0x7f0e115c5f79 33 soffice_main sofficemain.cxx 94 0x7f0e1a7a4ba3 34 sal_main main.c 51 0x559ce9c67a5d 35 main main.c 49 0x559ce9c67a37 Change-Id: Ic5121645a6920a8ac35154dda1dcfa1974ab9d4a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164062 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-02-22Framework for some UNOIDL to test the Embind UNO binding withStephan Bergmann12-3/+168
It is only built for --enable-dbgutil builds. Load instdir/program/qt_soffice.html in a browser and see "Running embindtest" in its console. For now, it only contains a Test singleton with an empty XTest interface, which is meant to grow additional methods over time. (The code needs to reside in the unotest rather than in the static module, or else the wasm build would run into cyclic dependencies.) Change-Id: I6f65f0c904648a4fd96fc6215c8d59a1544f48a2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163693 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
2024-02-18tdf#130857 VclBuilder: Use VclPtr instead of raw vcl::Window*Michael Weghorn1-3/+2
`VclBuilder::handleObject` returns a `VclPtr<vcl::Window>`. Use the same for the local variable `pCurrentChild` that the return value of the former is assigned to. There's no reason to use a raw pointer here and explicitly calling `VclPtr<vcl::Window>::get()` also makes it harder to reuse/share the existing code for an upcoming `QtBuilder`, s. Omkar's comment in his pending Gerrit change [1]. While at it, also move the declaration of `pCurrentChild` closer to its first use. [1] https://gerrit.libreoffice.org/c/core/+/163103/comments/f37a6add_b0f00eb1 Change-Id: I30520d5d18453c78150b2b0c9af044e043a1c74f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163528 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-02-16tdf#92389 sw a11y: Use SolarMutex in SidebarWinAccessibleContextMichael Weghorn1-6/+4
Hold the SolarMutex instead of of using a custom mutex, since `SwAccessibleMap` methods that get called require the SolarMutex to be held. Fixes a crash/assert when interacting with Writer comments using the mouse while the Orca screen reader is running when using the qt6 VCL plugin. Backtrace: Thread 1 received signal SIGABRT, Aborted. __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 44 ./nptl/pthread_kill.c: No such file or directory. (gdb) bt #0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 #1 0x00007f0a462a81cf in __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78 #2 0x00007f0a4625a472 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #3 0x00007f0a462444b2 in __GI_abort () at ./stdlib/abort.c:79 #4 0x00007f0a462443d5 in __assert_fail_base (fmt=0x7f0a463b8dc8 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x7f0a3d775838 "ImplGetSVData()->mpDefInst->GetYieldMutex()->IsCurrentThread() && \"SolarMutex not owned!\"", file=file@entry=0x7f0a3d7757f0 ".../libreoffice/vcl/source/app/dbggui.cxx", line=line@entry=35, function=function@entry=0x7f0a3d7757cc "void ImplDbgTestSolarMutex()") at ./assert/assert.c:92 #5 0x00007f0a462533a2 in __assert_fail (assertion=0x7f0a3d775838 "ImplGetSVData()->mpDefInst->GetYieldMutex()->IsCurrentThread() && \"SolarMutex not owned!\"", file=0x7f0a3d7757f0 ".../libreoffice/vcl/source/app/dbggui.cxx", line=35, function=0x7f0a3d7757cc "void ImplDbgTestSolarMutex()") at ./assert/assert.c:101 #6 0x00007f0a3ca733b4 in ImplDbgTestSolarMutex() () at .../libreoffice/vcl/source/app/dbggui.cxx:35 #7 0x00007f0a452ccfbb in DbgTestSolarMutex() () at .../libreoffice/tools/source/debug/debug.cxx:54 #8 0x00007f09f8fd3903 in SwAccessibleMap::GetContext(SwFrame const*, bool) (this=0x55fa8fd89930, pFrame=0x55fa8ecddb00, bCreate=false) at .../libreoffice/sw/source/core/access/accmap.cxx:1777 #9 0x00007f09f906f684 in sw::sidebarwindows::(anonymous namespace)::SidebarWinAccessibleContext::getAccessibleParent() (this=0x55fa8f83e600) at .../libreoffice/sw/source/uibase/docvw/SidebarWinAcc.cxx:65 #10 0x00007f0a31e6244c in QtAccessibleWidget::parent() const (this=0x7f0a280b6150) at .../libreoffice/vcl/qt6/../qt5/QtAccessibleWidget.cxx:322 #11 0x00007f0a3095b51a in AtSpiAdaptor::accessibleInterface(QAccessibleInterface*, QString const&, QDBusMessage const&, QDBusConnection const&) (this=0x55fa884876c0, interface=0x7f0a280b6150, function=..., message=..., connection=...) at .../qt5/qtbase/src/gui/accessible/linux/atspiadaptor.cpp:1592 #12 0x00007f0a30959934 in AtSpiAdaptor::handleMessage(QDBusMessage const&, QDBusConnection const&) (this=0x55fa884876c0, message=..., connection=...) at .../qt5/qtbase/src/gui/accessible/linux/atspiadaptor.cpp:1460 #13 0x00007f0a2ee88ad3 in QDBusConnectionPrivate::activateObject(QDBusConnectionPrivate::ObjectTreeNode&, QDBusMessage const&, int) (this=0x7f0a28010b60, node=..., msg=..., pathStartPos=27) at .../qt5/qtbase/src/dbus/qdbusintegrator.cpp:1448 #14 0x00007f0a2ee897b8 in QDBusActivateObjectEvent::placeMetaCall(QObject*) (this=0x7f0a280b8400) at .../qt5/qtbase/src/dbus/qdbusintegrator.cpp:1604 #15 0x00007f0a31445095 in QObject::event(QEvent*) (this=0x55fa884876c0, e=0x7f0a280b8400) at .../qt5/qtbase/src/corelib/kernel/qobject.cpp:1447 #16 0x00007f0a2f5a696c in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=0x55fa872f63e0, receiver=0x55fa884876c0, e=0x7f0a280b8400) at .../qt5/qtbase/src/widgets/kernel/qapplication.cpp:3298 #17 0x00007f0a2f5a677d in QApplication::notify(QObject*, QEvent*) (this=0x55fa873956b0, receiver=0x55fa884876c0, e=0x7f0a280b8400) at .../qt5/qtbase/src/widgets/kernel/qapplication.cpp:3249 #18 0x00007f0a313b1162 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x55fa884876c0, event=0x7f0a280b8400) at .../qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1138 #19 0x00007f0a313b1d0b in QCoreApplication::sendEvent(QObject*, QEvent*) (receiver=0x55fa884876c0, event=0x7f0a280b8400) at .../qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1581 #20 0x00007f0a313b33c4 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (receiver=0x0, event_type=0, data=0x55fa87311df0) at .../qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1936 #21 0x00007f0a313b255e in QCoreApplication::sendPostedEvents(QObject*, int) (receiver=0x0, event_type=0) at .../qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1770 #22 0x00007f0a318384ac in postEventSourceDispatch(GSource*, GSourceFunc, gpointer) (s=0x55fa873b8c20) at .../qt5/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:244 #23 0x00007f0a38d111f4 in () at /lib/x86_64-linux-gnu/libglib-2.0.so.0 #24 0x00007f0a38d14317 in () at /lib/x86_64-linux-gnu/libglib-2.0.so.0 #25 0x00007f0a38d14930 in g_main_context_iteration () at /lib/x86_64-linux-gnu/libglib-2.0.so.0 #26 0x00007f0a31838d41 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x55fa873987a0, flags=...) at .../qt5/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:394 #27 0x00007f0a30b5c418 in QPAEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x55fa873987a0, flags=...) at .../qt5/qtbase/src/gui/platform/unix/qeventdispatcher_glib.cpp:87 #28 0x00007f0a31ed9a40 in QtInstance::ImplYield(bool, bool) (this=0x55fa873d30f0, bWait=true, bHandleAllCurrentEvents=false) at .../libreoffice/vcl/qt6/../qt5/QtInstance.cxx:453 #29 0x00007f0a31ed9b69 in QtInstance::DoYield(bool, bool) (this=0x55fa873d30f0, bWait=true, bHandleAllCurrentEvents=false) at .../libreoffice/vcl/qt6/../qt5/QtInstance.cxx:464 #30 0x00007f0a3cb39434 in ImplYield(bool, bool) (i_bWait=true, i_bAllEvents=false) at .../libreoffice/vcl/source/app/svapp.cxx:390 #31 0x00007f0a3cb3a1d2 in Application::Yield() () at .../libreoffice/vcl/source/app/svapp.cxx:474 #32 0x00007f0a3cb39127 in Application::Execute() () at .../libreoffice/vcl/source/app/svapp.cxx:368 #33 0x00007f0a46437216 in desktop::Desktop::Main() (this=0x7ffd0478dce0) at .../libreoffice/desktop/source/app/app.cxx:1614 #34 0x00007f0a3cb585f6 in ImplSVMain() () at .../libreoffice/vcl/source/app/svmain.cxx:229 #35 0x00007f0a3cb5890b in SVMain() () at .../libreoffice/vcl/source/app/svmain.cxx:261 #36 0x00007f0a464a4367 in soffice_main() () at .../libreoffice/desktop/source/app/sofficemain.cxx:94 #37 0x000055fa860a09d4 in sal_main () at .../libreoffice/desktop/source/app/main.c:51 #38 0x000055fa860a09ba in main (argc=3, argv=0x7ffd0478df08) at .../libreoffice/desktop/source/app/main.c:49 Change-Id: If6df884fe94b2aac74be1b9fb13356bf765119d2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163379 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-02-16tdf#156562 qt: Don't crash on null clipboard contentMichael Weghorn1-0/+3
Since commit 1db5b87fe69c2375f1d66974dafcd563303c76db Author: Michael Weghorn <m.weghorn@posteo.de> Date: Tue Feb 13 13:23:17 2024 +0100 tdf#156562 qt: Sync with system clipboard content if necessary , mime data are updated from the system clipboard when there's a mismatch. Quoting Stephan Bergmann's [1]: > PS2, Line 174: setMimeData(pCurrentClipboardData); > At least for my Qt6-based Emscripten build, `pCurrentClipboardData` > can be null here, so setting `QtTransferable::m_pMimeData` to null here, > and a later call to `QtTransferable::getTransferDataFlavors` will > call `m_pMimeData->formats()` and crash. Add a corresponding null check. From what I can see, other methods shouldn't need an explicit check, as they use the result of `QtTransferable::getTransferData` (e.g. `QtTransferable::getTransferData` returns early if `QtTransferable::isDataFlavorSupported` returns false, which in turn calls `QtTransferable::getTransferData` that now has this null check). [1] https://gerrit.libreoffice.org/c/core/+/163304/comment/8872708d_1abdef81 Change-Id: Ibec756c2b073b1e19a3b4761e57c35576b44adc3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163423 Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de> Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-02-15tdf#130857 qt weld: Set msg dialog parentMichael Weghorn1-1/+15
If a parent is passed to `QtInstance::CreateMessageDialog`, also set a parent for the `QMessageBox` that gets created there: If the passed parent is a native Qt one, use that one. Otherwise, fall back to using the current active top-level window, which is what usually makes most sense and is better than having no parent at all. With this change in place, the message dialog shown when doing 1) start Writer 2) "File" -> "Properties" -> "Security" -> "Protect" 3) type 2 different passwords and confirm is now modal and centered on top of the "Enter Password" dialog on KDE Plasma Wayland when using the qt6 VCL plugin, while it used to open at the top left of the screen and was non-modal before. The new behavior is in line with how it behaves for the SAL_VCL_QT_NO_WELDED_WIDGETS=1 case. Change-Id: Ibe95c2f0407edeba0fd9f76744bc087be7df6437 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163362 Tested-by: Jenkins Reviewed-by: Omkar Acharekar <omkaracharekar12@gmail.com> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-02-15tdf#130857 qt weld: Implement QtInstanceDialog::{g,s}et_modalMichael Weghorn2-3/+3
Change-Id: I975d10ccc73c79b34da733411097a7970c8bf916 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163361 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-02-15tdf#130857 qt weld: Move QWidget* member to QtInstanceWidgetMichael Weghorn6-6/+22
Move the `m_pWidget` member from `QtInstanceWindow` to the base class `QtInstanceWidget` and add a getter for it. This allows to get the `QWidget` directly from the base class, which will be used in an upcoming commit. Change-Id: I9c41b48936e5a6051afb9721dae2fac5add22e4b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163360 Tested-by: Jenkins Reviewed-by: Omkar Acharekar <omkaracharekar12@gmail.com> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-02-14scp2: Take ENABLE_{KF,QT}6 into accountMichael Weghorn2-2/+2
The qt6 and kf6 VCL plugins are also part of the kde install set, so take `ENABLE_QT6` and `ENABLE_KF6` into account when deciding whether to install it. This makes packaging these VCL plugins work when building with `--enable-qt6` and/or `--enable-kf6`, but without `--enable-qt5` and `--enable-kf5`. Command that can be used for testing: make DESTDIR=/tmp/dummy distro-pack-install -o build -o check (Then, check whether the "installation" in /tmp/dummy contains the VCL plugins as expected.) Thanks to Andreas Sturmlechner for reporting the issue on IRC #libreoffice-dev on 2024-02-12. Change-Id: Ieea67468e3388f8b7b66f53221574c6225516b44 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163313 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-02-13tdf#156562 qt: Sync with system clipboard content if necessaryMichael Weghorn2-15/+27
If the `QtClipboardTransferable`'s mime data gets out of sync with the system clipboard's one, no longer cease operation and stop reporting any transfer data, but sync with the clipboard data, i.e. update the mime data with those currently in the system clipboard. For the "Paste Special" dialog with qt6 on Wayland (see tdf#156562), an external clipboard update gets triggered between the point in time when the std::shared_ptr<const TransferableDataHelper> aDataHelper in the `SID_PASTE_SPECIAL` case in `SwBaseShell::ExecClpbrd` gets assigned and when the callback set via `pDlg->StartExecuteAsync` gets called, even if there was no user interaction with the system clipboard at all. This however meant that the `aDataHelper` used in the callback would no longer return any transfer/mime data, so pasting wouldn't work. Handle that case by updating the `QtClipboardTransferable` mime data with the current system clipboard's data, but keep emitting a warning at least. As a consequence, opening the "Paste Special" dialog, then copying something else to the clipboard, then confirming the dialog will copy the newly copied data rather than what was in the clipboard when the dialog was initially started. That's the same for gtk3 already, but on Windows, the original clipboard content would still be pasted. (Retrieving the clipboard content anew in the callback using `TransferableDataHelper::CreateFromSystemClipboard` instead of passing the original `aDataHelper` into the callback would have a similar effect. However, on other platforms, reusing the previously copied data from the clipboard when the actual system clipboard was changed in between may be what's desired.) The observed extra/unexpected clipboard change event may be related/similar to what the following commit was addressing for the case of LO itself being the clipboard owner: commit 71471a36b125f6bdc915d5dbcae92ebcaa7ff5a4 Date: Tue Apr 6 01:41:08 2021 +0200 tdf#140404 Qt ignore "unchanged" clipboard events LO gets a Qt signal on all clipboard changes. For X11 you get one signal when you set the clipboard. Anything else normally signals lost of clipboard ownership. But on Wayland LO somehow gets a second notification without any actual change. AFAIK it's not triggered by any LO actions and isOwner still indicates, that LO has the ownership. This breaks the single notification assumption, the code was relying on. (...) Backtrace showing how the clipboard update gets triggered (with mode `QClipboardMode::Clipboard`, not just `QClipboardMode::Selection`; qtbase dev as of 0d0810e2dcc8a9ee28935af5daadc2ef36ed25a2): 1 QtClipboard::handleChanged QtClipboard.cxx 156 0x7f6284c7a7a8 2 QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<QClipboard::Mode>, void, void (QtClipboard:: *)(QClipboard::Mode)>::call(void (QtClipboard:: *)(QClipboard::Mode), QtClipboard *, void * *)::{lambda()#1}::operator()() const qobjectdefs_impl.h 153 0x7f6284c8450f 3 QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<QClipboard::Mode>, void, void (QtClipboard:: *)(QClipboard::Mode)>::call(void (QtClipboard:: *)(QClipboard::Mode), QtClipboard *, void * *)::{lambda()#1}>(void * *, QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<QClipboard::Mode>, void, void (QtClipboard:: *)(QClipboard::Mode)>::call(void (QtClipboard:: *)(QClipboard::Mode), QtClipboard *, void * *)::{lambda()#1}&&) qobjectdefs_impl.h 72 0x7f6284c8500b 4 QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<QClipboard::Mode>, void, void (QtClipboard:: *)(QClipboard::Mode)>::call qobjectdefs_impl.h 152 0x7f6284c8457f 5 QtPrivate::FunctionPointer<void (QtClipboard:: *)(QClipboard::Mode)>::call<QtPrivate::List<QClipboard::Mode>, void> qobjectdefs_impl.h 200 0x7f6284c833ee 6 QtPrivate::QCallableObject<void (QtClipboard:: *)(QClipboard::Mode), QtPrivate::List<QClipboard::Mode>, void>::impl qobjectdefs_impl.h 571 0x7f6284c81f81 7 QtPrivate::QSlotObjectBase::call qobjectdefs_impl.h 487 0x7f62841b863f 8 doActivate<false> qobject.cpp 4116 0x7f628425772e 9 QMetaObject::activate qobject.cpp 4176 0x7f628424cdef 10 QClipboard::changed moc_qclipboard.cpp 182 0x7f62831e9fcc 11 QClipboard::emitChanged qclipboard.cpp 558 0x7f62831e9bc1 12 QPlatformClipboard::emitChanged qplatformclipboard.cpp 89 0x7f628324ed69 13 QtWaylandClient::QWaylandDataDevice::data_device_selection qwaylanddatadevice.cpp 295 0x7f6281b8eaf1 14 QtWayland::wl_data_device::handle_selection qwayland-wayland.cpp 985 0x7f6281b7389a 15 ?? 0x7f629681a40e 16 ?? 0x7f629681971d 17 ffi_call 0x7f6296819ef3 18 ?? 0x7f629955c921 19 ?? 0x7f6299558c09 20 wl_display_dispatch_queue_pending 0x7f629955a5ac 21 QtWaylandClient::EventThread::dispatchQueuePending qwaylanddisplay.cpp 227 0x7f6281afd5f4 22 QtWaylandClient::EventThread::readAndDispatchEvents qwaylanddisplay.cpp 109 0x7f6281afd124 23 QtWaylandClient::QWaylandDisplay::flushRequests qwaylanddisplay.cpp 508 0x7f6281af5b98 24 QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (QtWaylandClient::QWaylandDisplay:: *)()>::call(void (QtWaylandClient::QWaylandDisplay:: *)(), QtWaylandClient::QWaylandDisplay *, void * *)::{lambda()#1}::operator()() const qobjectdefs_impl.h 153 0x7f6281b13ebb 25 QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (QtWaylandClient::QWaylandDisplay:: *)()>::call(void (QtWaylandClient::QWaylandDisplay:: *)(), QtWaylandClient::QWaylandDisplay *, void * *)::{lambda()#1}>(void * *, QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (QtWaylandClient::QWaylandDisplay:: *)()>::call(void (QtWaylandClient::QWaylandDisplay:: *)(), QtWaylandClient::QWaylandDisplay *, void * *)::{lambda()#1}&&) qobjectdefs_impl.h 72 0x7f6281b151f0 26 QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (QtWaylandClient::QWaylandDisplay:: *)()>::call(void (QtWaylandClient::QWaylandDisplay:: *)(), QtWaylandClient::QWaylandDisplay *, void * *) qobjectdefs_impl.h 152 0x7f6281b13f1c 27 QtPrivate::FunctionPointer<void (QtWaylandClient::QWaylandDisplay:: *)()>::call<QtPrivate::List<>, void>(void (QtWaylandClient::QWaylandDisplay:: *)(), QtWaylandClient::QWaylandDisplay *, void * *) qobjectdefs_impl.h 200 0x7f6281b11250 28 QtPrivate::QCallableObject<void (QtWaylandClient::QWaylandDisplay:: *)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void * *, bool *) qobjectdefs_impl.h 571 0x7f6281b0d5e3 29 QtPrivate::QSlotObjectBase::call qobjectdefs_impl.h 487 0x7f62841b863f 30 QMetaCallEvent::placeMetaCall qobject.cpp 650 0x7f6284243bf9 31 QObject::event qobject.cpp 1447 0x7f6284245095 32 QApplicationPrivate::notify_helper qapplication.cpp 3298 0x7f62823a696c 33 QApplication::notify qapplication.cpp 3249 0x7f62823a677d 34 QCoreApplication::notifyInternal2 qcoreapplication.cpp 1138 0x7f62841b1162 35 QCoreApplication::sendEvent qcoreapplication.cpp 1581 0x7f62841b1d0b 36 QCoreApplicationPrivate::sendPostedEvents qcoreapplication.cpp 1936 0x7f62841b33c4 37 QCoreApplication::sendPostedEvents qcoreapplication.cpp 1770 0x7f62841b255e 38 postEventSourceDispatch qeventdispatcher_glib.cpp 244 0x7f62846384ac 39 ?? 0x7f628b9111f4 40 ?? 0x7f628b914317 41 g_main_context_iteration 0x7f628b914930 42 QEventDispatcherGlib::processEvents qeventdispatcher_glib.cpp 394 0x7f6284638d41 43 QPAEventDispatcherGlib::processEvents qeventdispatcher_glib.cpp 87 0x7f628395c418 44 QtInstance::ImplYield QtInstance.cxx 453 0x7f6284cd9a40 45 QtInstance::DoYield QtInstance.cxx 464 0x7f6284cd9b69 46 ImplYield svapp.cxx 390 0x7f628f739c32 47 Application::Yield svapp.cxx 474 0x7f628f73a9d0 48 Application::Execute svapp.cxx 368 0x7f628f739925 49 desktop::Desktop::Main app.cxx 1614 0x7f6299037216 50 ImplSVMain svmain.cxx 229 0x7f628f758df4 51 SVMain svmain.cxx 261 0x7f628f759109 52 soffice_main sofficemain.cxx 94 0x7f62990a4367 53 sal_main main.c 51 0x56508cf899d4 54 main main.c 49 0x56508cf899ba Change-Id: I1720d8acd72dca4ef6bc32935b920b2c1ff4d8f1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163304 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-02-13tdf#156562 qt: Don't cache supported mime types/data flavorsMichael Weghorn2-14/+1
Drop the optimization to remember the supported data flavors in `QtTransferable::m_aMimeTypeSeq` and evaluate them each time instead. This is in preparation of allowing to change the mime data in an upcoming commit. Another alternative would be to (re-)calculate `QtTransferable::m_aMimeTypeSeq` only at the point in time that the mime data are set. Keep that in mind for further consideration in case this should ever become relevant from a performance perspective. Change-Id: Ic1792f6c2a19bf4c8f642a6288e9f3413fe7c893 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163303 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-02-12tdf#125934 qt: Support module-specific window icons on WaylandMichael Weghorn1-0/+14
As discussed in QTBUG-77182 [1], Qt currently doesn't provide API to directly set the app_id for a single window/toplevel on Wayland, but the one set for the application is used when the window gets shown. Make use of that by temporarily setting the app's desktop file name and doing a hide/show cycle in `QtFrame::SetIcon` on Wayland. A big thanks for David Redondo for mentioning that possibility in QTBUG-77182! An alternative would be to use private Qt API and low-level wayland API to set the app_id directly, s. discussion in QTBUG-77182. [1] https://bugreports.qt.io/browse/QTBUG-77182 Change-Id: I2a93cd39756e2ebf55b91486927d73d3896245b3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163249 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-02-10qt: Set desktop file name without ".desktop" suffixMichael Weghorn1-1/+1
This fixes this warning when starting LO with the qt6 VCL plugin on Wayland (using a local qtbase dev build): > QGuiApplication::setDesktopFileName: the specified desktop file name ends with .desktop. > For compatibility reasons, the .desktop suffix will be removed. Please specify a desktop file name without .desktop suffix The icon is also still shown fine with qt5/kf5 (qtbase at 5.15.10+dfsg-6 from Debian testing). Change-Id: I0eca1b3767ff65653d5f6b3104550fb0d8aea293 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163204 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-02-10tdf#158947 sw: Don't unrelatedly overwrite system clipboard on pasteMichael Weghorn1-1/+2
In `SwTransferable::RemoveDDELinkFormat`, only update the clipboard content with this `SwTransferable` after removing the `SotClipboardFormatId::LINK` from the supported formats if the `SwTransferable` was the clipboard content before already. Doing so always would unrelatedly overwrite what was previously copied from another application to the clipboard for the tdf#158947 scenario of pasting clipboard content of another application over a selection when using the Qt-based VCL plugins on Wayland (s. backtrace below that shows how the clipboard content was overwritten, frame #17 is the method changed in this commit). My assumption why the clipboard content is explicitly overwritten at all is to make sure that the system clipboard on some platforms gets notified about the change in supported formats/mime types after removing one. But that isn't necessary when the transfer data modified here aren't the current clipboard content in the first place. Backtrace for how clipboard content was previously overwritten for the tdf#158947 scenario with the qt6 VCL plugin on Wayland: ~"#0 QtClipboard::handleChanged(QClipboard::Mode) (this=0x557f90457770, aMode=QClipboard::Clipboard) at .../libreoffice/vcl/qt6/../qt5/QtClipboard.cxx:156\n" ~"#1 0x00007f26f08844ff in QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<QClipboard::Mode>, void, void (QtClipboard::*)(QClipboard::Mode)>::call(void (QtClipboard::*)(QClipboard::Mode), QtClipboard*, void**)::{lambda()#1}::operator()() const (__closure=0x7ffe889a2c20) at .../qt5/qtbase/src/corelib/kernel/qobjectdefs_impl.h:153\n" ~"#2 0x00007f26f0884ffb in QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<QClipboard::Mode>, void, void (QtClipboard::*)(QClipboard::Mode)>::call(void (QtClipboard::*)(QClipboard::Mode), QtClipboard*, void**)::{lambda()#1}>(void**, QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<QClipboard::Mode>, void, void (QtClipboard::*)(QClipboard::Mode)>::call(void (QtClipboard::*)(QClipboard::Mode), QtClipboard*, void**)::{lambda()#1}&&) (args=0x7ffe889a2ed0, fn=...) at .../qt5/qtbase/src/corelib/kernel/qobjectdefs_impl.h:72\n" ~"#3 0x00007f26f088456f in QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<QClipboard::Mode>, void, void (QtClipboard::*)(QClipboard::Mode)>::call(void (QtClipboard::*)(QClipboard::Mode), QtClipboard*, void**) (f=(void (QtClipboard::*)(QtClipboard * const, QClipboard::Mode)) 0x7f26f087a76e <QtClipboard::handleChanged(QClipboard::Mode)>, o=0x557f90457770, arg=0x7ffe889a2ed0) at .../qt5/qtbase/src/corelib/kernel/qobjectdefs_impl.h:152\n" ~"#4 0x00007f26f08833de in QtPrivate::FunctionPointer<void (QtClipboard::*)(QClipboard::Mode)>::call<QtPrivate::List<QClipboard::Mode>, void>(void (QtClipboard::*)(QClipboard::Mode), QtClipboard*, void**) (f=(void (QtClipboard::*)(QtClipboard * const, QClipboard::Mode)) 0x7f26f087a76e <QtClipboard::handleChanged(QClipboard::Mode)>, o=0x557f90457770, arg=0x7ffe889a2ed0) at .../qt5/qtbase/src/corelib/kernel/qobjectdefs_impl.h:200\n" ~"#5 0x00007f26f0881f71 in QtPrivate::QCallableObject<void (QtClipboard::*)(QClipboard::Mode), QtPrivate::List<QClipboard::Mode>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (which=1, this_=0x557f904555f0, r=0x557f90457770, a=0x7ffe889a2ed0, ret=0x0) at .../qt5/qtbase/src/corelib/kernel/qobjectdefs_impl.h:571\n" ~"#6 0x00007f26efdb863f in QtPrivate::QSlotObjectBase::call(QObject*, void**) (this=0x557f904555f0, r=0x557f90457770, a=0x7ffe889a2ed0) at .../qt5/qtbase/src/corelib/kernel/qobjectdefs_impl.h:487\n" ~"#7 0x00007f26efe5772e in doActivate<false>(QObject*, int, void**) (sender=0x557f8d510fd0, signal_index=3, argv=0x7ffe889a2ed0) at .../qt5/qtbase/src/corelib/kernel/qobject.cpp:4116\n" ~"#8 0x00007f26efe4cdef in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (sender=0x557f8d510fd0, m=0x7f26efa47cc0 <QClipboard::staticMetaObject>, local_signal_index=0, argv=0x7ffe889a2ed0) at .../qt5/qtbase/src/corelib/kernel/qobject.cpp:4176\n" ~"#9 0x00007f26eede9fcc in QClipboard::changed(QClipboard::Mode) (this=0x557f8d510fd0, _t1=QClipboard::Clipboard) at .../qt5/qtbase/src/gui/Gui_autogen/include/moc_qclipboard.cpp:182\n" ~"#10 0x00007f26eede9bc1 in QClipboard::emitChanged(QClipboard::Mode) (this=0x557f8d510fd0, mode=QClipboard::Clipboard) at .../qt5/qtbase/src/gui/kernel/qclipboard.cpp:558\n" ~"#11 0x00007f26eee4ed69 in QPlatformClipboard::emitChanged(QClipboard::Mode) (this=0x557f88019c20, mode=QClipboard::Clipboard) at .../qt5/qtbase/src/gui/kernel/qplatformclipboard.cpp:89\n" ~"#12 0x00007f26ed78809e in QtWaylandClient::QWaylandClipboard::setMimeData(QMimeData*, QClipboard::Mode) (this=0x557f88019c20, data=0x557f8fb87930, mode=QClipboard::Clipboard) at .../qt5/qtwayland/src/client/qwaylandclipboard.cpp:89\n" ~"#13 0x00007f26eede99de in QClipboard::setMimeData(QMimeData*, QClipboard::Mode) (this=0x557f8d510fd0, src=0x557f8fb87930, mode=QClipboard::Clipboard) at .../qt5/qtbase/src/gui/kernel/qclipboard.cpp:447\n" ~"#14 0x00007f26f087a5b5 in QtClipboard::setContents(com::sun::star::uno::Reference<com::sun::star::datatransfer::XTransferable> const&, com::sun::star::uno::Reference<com::sun::star::datatransfer::clipboard::XClipboardOwner> const&) (this=0x557f8d50cbb0, xTrans=uno::Reference to (SwTransferable *) 0x557f90440118, xClipboardOwner=uno::Reference to (SwTransferable *) 0x557f90440120) at .../libreoffice/vcl/qt6/../qt5/QtClipboard.cxx:137\n" ~"#15 0x00007f26fb05bacc in TransferableHelper::CopyToClipboard(com::sun::star::uno::Reference<com::sun::star::datatransfer::clipboard::XClipboard> const&) const (this=0x557f904400f0, rClipboard=uno::Reference to (QtClipboard *) 0x557f8d50cc10) at .../libreoffice/vcl/source/treelist/transfer.cxx:942\n" ~"#16 0x00007f26fb05bc77 in TransferableHelper::CopyToClipboard(vcl::Window*) const (this=0x557f904400f0, pWindow=0x557f8932d1f0) at .../libreoffice/vcl/source/treelist/transfer.cxx:957\n" ~"#17 0x00007f26b5130940 in SwTransferable::RemoveDDELinkFormat(vcl::Window&) (this=0x557f904400f0, rWin=...) at .../libreoffice/sw/source/uibase/dochdl/swdtflvr.cxx:385\n" ~"#18 0x00007f26b51440ab in SwTransferDdeLink::DataChanged(rtl::OUString const&, com::sun::star::uno::Any const&) (this=0x557f8fb864e0) at .../libreoffice/sw/source/uibase/dochdl/swdtflvr.cxx:4447\n" ~"#19 0x00007f270120fa0e in sfx2::SvLinkSource::NotifyDataChanged() (this=0x557f8fb8bbe0) at .../libreoffice/sfx2/source/appl/linksrc.cxx:291\n" ~"#20 0x00007f26b43210ba in SwServerObject::SendDataChanged(SwPaM const&) (this=0x557f8fb8bbe0, rRange=SwPaM = {...}) at .../libreoffice/sw/source/core/doc/swserv.cxx:177\n" ~"#21 0x00007f26b43217c2 in SwDataChanged::~SwDataChanged() (this=0x7ffe889a3520, __in_chrg=<optimized out>) at .../libreoffice/sw/source/core/doc/swserv.cxx:308\n" ~"#22 0x00007f26b4233c8b in sw::DocumentContentOperationsManager::DeleteRangeImplImpl(SwPaM&, SwDeleteFlags) (this=0x557f8d2b8000, rPam=SwPaM = {...}, flags=SwDeleteFlags::Default) at .../libreoffice/sw/source/core/doc/DocumentContentOperationsManager.cxx:4474\n" ~"#23 0x00007f26b4233826 in sw::DocumentContentOperationsManager::DeleteRangeImpl(SwPaM&, SwDeleteFlags) (this=0x557f8d2b8000, rPam=SwPaM = {...}, flags=SwDeleteFlags::Default) at .../libreoffice/sw/source/core/doc/DocumentContentOperationsManager.cxx:4419\n" ~"#24 0x00007f26b4233681 in sw::DocumentContentOperationsManager::DeleteAndJoinImpl(SwPaM&, SwDeleteFlags) (this=0x557f8d2b8000, rPam=SwPaM = {...}, flags=SwDeleteFlags::Default) at .../libreoffice/sw/source/core/doc/DocumentContentOperationsManager.cxx:4391\n" ~"#25 0x00007f26b421edb7 in (anonymous namespace)::lcl_DoWithBreaks(sw::DocumentContentOperationsManager&, SwPaM&, SwDeleteFlags, bool (sw::DocumentContentOperationsManager::*)(sw::DocumentContentOperationsManager* const, SwPaM&, SwDeleteFlags)) (rDocumentContentOperations=..., rPam=SwPaM = {...}, flags=SwDeleteFlags::Default, pFunc=(bool (sw::DocumentContentOperationsManager::*)(sw::DocumentContentOperationsManager * const, SwPaM &, SwDeleteFlags)) 0x7f26b4233632 <sw::DocumentContentOperationsManager::DeleteAndJoinImpl(SwPaM&, SwDeleteFlags)>) at .../libreoffice/sw/source/core/doc/DocumentContentOperationsManager.cxx:681\n" ~"#26 0x00007f26b42279df in sw::DocumentContentOperationsManager::DeleteAndJoin(SwPaM&, SwDeleteFlags) (this=0x557f8d2b8000, rPam=SwPaM = {...}, flags=SwDeleteFlags::Default) at .../libreoffice/sw/source/core/doc/DocumentContentOperationsManager.cxx:2367\n" ~"#27 0x00007f26b44a71f6 in SwEditShell::DeleteSel(SwPaM&, bool, bool, bool*) (this=0x557f8d51b300, rPam=SwPaM = {...}, isArtificialSelection=false, goLeft=false, pUndo=0x7ffe889a3be6) at .../libreoffice/sw/source/core/edit/eddel.cxx:122\n" ~"#28 0x00007f26b44a7671 in SwEditShell::Delete(bool, bool) (this=0x557f8d51b300, isArtificialSelection=false, goLeft=false) at .../libreoffice/sw/source/core/edit/eddel.cxx:164\n" ~"#29 0x00007f26b5604933 in SwWrtShell::DelRight(bool) (this=0x557f8d51b300, isReplaceHeuristic=false) at .../libreoffice/sw/source/uibase/wrtsh/delete.cxx:312\n" ~"#30 0x00007f26b512fe14 in (anonymous namespace)::SwTrnsfrActionAndUndo::SwTrnsfrActionAndUndo(SwWrtShell*, bool, SwPasteContext*) (this=0x557f9045b020, pS=0x557f8d51b300, bDelSel=true, pContext=0x7ffe889a4220) at .../libreoffice/sw/source/uibase/dochdl/swdtflvr.cxx:236\n" ~"#31 0x00007f26b51377c1 in SwTransferable::PasteData(TransferableDataHelper const&, SwWrtShell&, unsigned char, SotExchangeActionFlags, SotClipboardFormatId, SotExchangeDest, bool, bool, Point const*, signed char, bool, RndStdIds, bool, SwPasteContext*, PasteTableType) (rData=..., rSh=..., nAction=36 '$', nActionFlags=(SotExchangeActionFlags::InsertImageMap | SotExchangeActionFlags::InsertTargetUrl), nFormat=SotClipboardFormatId::HTML, nDestination=SotExchangeDest::SWDOC_FREE_AREA, bIsPasteFormat=false, bIsDefault=false, pPt=0x0, nDropAction=0 '\\000', bPasteSelection=false, nAnchorType=RndStdIds::FLY_AT_PARA, bIgnoreComments=false, pContext=0x7ffe889a4220, ePasteTable=PasteTableType::PASTE_DEFAULT) at .../libreoffice/sw/source/uibase/dochdl/swdtflvr.cxx:1768\n" ~"#32 0x00007f26b5137333 in SwTransferable::Paste(SwWrtShell&, TransferableDataHelper&, RndStdIds, bool, PasteTableType) (rSh=..., rData=..., nAnchorType=RndStdIds::FLY_AT_PARA, bIgnoreComments=false, ePasteTable=PasteTableType::PASTE_DEFAULT) at .../libreoffice/sw/source/uibase/dochdl/swdtflvr.cxx:1687\n" ~"#33 0x00007f26b52d29e9 in SwBaseShell::ExecClpbrd(SfxRequest&) (this=0x557f8db64330, rReq=...) at .../libreoffice/sw/source/uibase/shells/basesh.cxx:365\n" ~"#34 0x00007f26b52d1681 in SfxStubSwBaseShellExecClpbrd(SfxShell*, SfxRequest&) (pShell=0x557f8db64330, rReq=...) at .../libreoffice/workdir/SdiTarget/sw/sdi/swslots.hxx:2219\n" ~"#35 0x00007f27012d14dc in SfxDispatcher::Call_Impl(SfxShell&, SfxSlot const&, SfxRequest&, bool) (this=0x557f8d4f46b0, rShell=..., rSlot=..., rReq=..., bRecord=true) at .../libreoffice/sfx2/source/control/dispatch.cxx:254\n" ~"#36 0x00007f27012d4b34 in SfxDispatcher::Execute_(SfxShell&, SfxSlot const&, SfxRequest&, SfxCallMode) (this=0x557f8d4f46b0, rShell=..., rSlot=..., rReq=..., eCallMode=SfxCallMode::RECORD) at .../libreoffice/sfx2/source/control/dispatch.cxx:753\n" ~"#37 0x00007f27012c05d4 in SfxBindings::Execute_Impl(SfxRequest&, SfxSlot const*, SfxShell*) (this=0x557f8d503240, aReq=..., pSlot=0x7f26b6cf5360 <aSwBaseShellSlots_Impl+1440>, pShell=0x557f8db64330) at .../libreoffice/sfx2/source/control/bindings.cxx:1057\n" ~"#38 0x00007f270139813d in SfxDispatchController_Impl::dispatch(com::sun::star::util::URL const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&, com::sun::star::uno::Reference<com::sun::star::frame::XDispatchResultListener> const&) (this=0x557f8db682a0, aURL=..., aArgs=empty uno::Sequence, rListener=empty uno::Reference) at .../libreoffice/sfx2/source/control/unoctitm.cxx:688\n" ~"#39 0x00007f2701395dbf in SfxOfficeDispatch::dispatch(com::sun::star::util::URL const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&) (this=0x557f8db68200, aURL=..., aArgs=empty uno::Sequence) at .../libreoffice/sfx2/source/control/unoctitm.cxx:250\n" ~"#40 0x00007f26fe03d948 in svt::(anonymous namespace)::AsyncAccelExec::impl_ts_asyncCallback(LinkParamNone*) (this=0x557f8fb8e070) at .../libreoffice/svtools/source/misc/acceleratorexecute.cxx:508\n" ~"#41 0x00007f26fe03d869 in svt::(anonymous namespace)::AsyncAccelExec::LinkStubimpl_ts_asyncCallback(void*, LinkParamNone*) (instance=0x557f8fb8e070, data=0x0) at .../libreoffice/svtools/source/misc/acceleratorexecute.cxx:500\n" ~"#42 0x00007f26fab0db3b in Link<LinkParamNone*, void>::Call(LinkParamNone*) const (this=0x557f8fb8e110, data=0x0) at .../libreoffice/include/tools/link.hxx:111\n" ~"#43 0x00007f26fb469f3d in vcl::EventPoster::DoEvent_Impl(void*) (this=0x557f8fb8e108) at .../libreoffice/vcl/source/helper/evntpost.cxx:52\n" ~"#44 0x00007f26fb469f05 in vcl::EventPoster::LinkStubDoEvent_Impl(void*, void*) (instance=0x557f8fb8e108, data=0x0) at .../libreoffice/vcl/source/helper/evntpost.cxx:48\n" ~"#45 0x00007f26fadc2373 in Link<void*, void>::Call(void*) const (this=0x7f26e80153b8, data=0x0) at .../libreoffice/include/tools/link.hxx:111\n" ~"#46 0x00007f26fadbf458 in ImplHandleUserEvent(ImplSVEvent*) (pSVEvent=0x7f26e80153b0) at .../libreoffice/vcl/source/window/winproc.cxx:2287\n" ~"#47 0x00007f26fadc1385 in ImplWindowFrameProc(vcl::Window*, SalEvent, void const*) (_pWindow=0x557f897d0e90, nEvent=SalEvent::UserEvent, pEvent=0x7f26e80153b0) at .../libreoffice/vcl/source/window/winproc.cxx:2851\n" ~"#48 0x00007f26f08b6bae in SalFrame::CallCallback(SalEvent, void const*) const (this=0x557f8800cf80, nEvent=SalEvent::UserEvent, pEvent=0x7f26e80153b0) at .../libreoffice/vcl/inc/salframe.hxx:310\n" ~"#49 0x00007f26f08d9dbf in QtInstance::ProcessEvent(SalUserEventList::SalUserEvent) (this=0x557f88020780, aEvent=...) at .../libreoffice/vcl/qt6/../qt5/QtInstance.cxx:516\n" ~"#50 0x00007f26fb47b97f in operator()() const (__closure=0x7ffe889a50e0) at .../libreoffice/vcl/source/app/salusereventlist.cxx:119\n" ~"#51 0x00007f26fb47bc53 in SalUserEventList::DispatchUserEvents(bool) (this=0x557f880207b8, bHandleAllCurrentEvents=false) at .../libreoffice/vcl/source/app/salusereventlist.cxx:120\n" ~"#52 0x00007f26f08d98a4 in QtInstance::ImplYield(bool, bool) (this=0x557f88020780, bWait=true, bHandleAllCurrentEvents=false) at .../libreoffice/vcl/qt6/../qt5/QtInstance.cxx:442\n" ~"#53 0x00007f26f08d9a4f in QtInstance::DoYield(bool, bool) (this=0x557f88020780, bWait=true, bHandleAllCurrentEvents=false) at .../libreoffice/vcl/qt6/../qt5/QtInstance.cxx:464\n" ~"#54 0x00007f26fb5390d0 in ImplYield(bool, bool) (i_bWait=true, i_bAllEvents=false) at .../libreoffice/vcl/source/app/svapp.cxx:390\n" ~"#55 0x00007f26fb539e6e in Application::Yield() () at .../libreoffice/vcl/source/app/svapp.cxx:474\n" ~"#56 0x00007f26fb538dc3 in Application::Execute() () at .../libreoffice/vcl/source/app/svapp.cxx:368\n" ~"#57 0x00007f2704e371b6 in desktop::Desktop::Main() (this=0x7ffe889a5c10) at .../libreoffice/desktop/source/app/app.cxx:1614\n" ~"#58 0x00007f26fb558292 in ImplSVMain() () at .../libreoffice/vcl/source/app/svmain.cxx:229\n" ~"#59 0x00007f26fb5585a7 in SVMain() () at .../libreoffice/vcl/source/app/svmain.cxx:261\n" ~"#60 0x00007f2704ea4307 in soffice_main() () at .../libreoffice/desktop/source/app/sofficemain.cxx:94\n" ~"#61 0x0000557f862d19d4 in sal_main () at .../libreoffice/desktop/source/app/main.c:51\n" ~"#62 0x0000557f862d19ba in main (argc=3, argv=0x7ffe889a5e38) at .../libreoffice/desktop/source/app/main.c:49\n" 2906^done (gdb) Change-Id: I1f517d441eeb3e77e969062b884d9a425038b22a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163202 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-02-08tdf#130857 VclBuilder: Extract static methods to new base classMichael Weghorn2-10/+17
Extract static methods from VclBuilder to a new base class BuilderBase that can be reused by other builder implementations (like the upcoming one for the Qt-based VCL plugins) in the future. Change-Id: I719ab5fe1b8a6b36050815204550aae3e3dd25e0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162917 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-02-05Allow qmake, moc to be explicitly set in autogen.inputStephan Bergmann1-4/+0
(I need that for a wasm cross-build with Qt6, where MOC6 needs to explicitly be set to the build-time moc tool, not a non-existing anyway host moc tool.) Change-Id: I4a779ccc1b12b80a2e67bbaa5cd7ec04861a5d43 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162984 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
2024-02-04tdf#130857 qt weld: Support asnyc running of msg dialogsMichael Weghorn4-1/+83
Implement methods required to run a welded Qt message dialog asynchronously: `QtInstanceMessageDialog::runAsync` and `QtInstanceMessageDialog::response`. Run the dialog asynchronously using `QDialog::open` and connect to the `QDialog::finished` signal to be notified when the dialog gets closed. Similar to how the gtk-based implementation, use local variables for the `std::shared_ptr`s and reset the members right away, not only at the end of the slot, since resetting the relevant one set in the corresponding `runAsync` overload will result in the object getting deallocated, thus the members can no longer be accessed safely. Take the solar mutex before calling the callback function as that seems to be expected (e.g. otherwise triggers an assert for the below example where the callback functions modifies VCL widgets). With this in place, running welded Qt message dialogs asynchronously works instead of not showing up at all, e.g. 1) start Writer with qt6 VCL plugin and without `SAL_VCL_QT_NO_WELDED_WIDGETS` set 2) open "File" -> "Properties" -> "Security" 3) click the "Protect..." button 4) enter 2 different passwords and press "OK" button Change-Id: Ic1b1bfc7d89c1be8a9f9dee59bc86cf3da37a280 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162948 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-01-31qtcreator: Fix generating .pro files for externalsMichael Weghorn1-3/+4
Since commit 3460799175e6c5795aa07c784e16d10ba9081d49 Date: Thu Jan 25 23:41:52 2024 +0600 Clear gb_GbuildToJson_DENYLISTEDMODULES, allow these modules , externals are taken into account in the generation of IDE integrations, causing errors like this when running `make qtcreator-ide-integration` to generate the *.pro files for the QtCreator IDE integration: cd /home/michi/development/git/libreoffice && bin/gbuild-to-ide --ide qtcreator --make make ERROR : creating pro file=/home/michi/development/git/libreoffice/clucene/clucene.pro [Errno 2] No such file or directory: '/home/michi/development/git/libreoffice/clucene/clucene.pro' Traceback (most recent call last): File "/home/michi/development/git/libreoffice/bin/gbuild-to-ide", line 1787, in emit with open(qt_pro_file, mode) as fpro: ^^^^^^^^^^^^^^^^^^^^^^^ FileNotFoundError: [Errno 2] No such file or directory: '/home/michi/development/git/libreoffice/clucene/clucene.pro' Fix this by creating the .pro files in a directory that has the same relative path to the $(BUILDDIR) as the corresponding .mk files have in the $(SRCDIR) rather than in $(BUILDDIR)/$(LIBNAME)/. While both are the same for LO's internal modules, the latter directory does not exist for externals, since they're located underneath a top-level directory called "external". For the simple case of an in-tree build, this now e.g. creates a file `external/clucene/clucene.pro` instead of failing to create a `clucene/clucene.pro` because there's no top-level "clucene" directory. An alternative approach might to just ignore the externals, as this commit implemented it for the codelite integration: commit 41c8e0957369b7b53a3b9cf4b4cf1e49a982a414 Date: Sat Jan 27 21:54:10 2024 +0200 fix codelite-ide-integration externals seems to be part of the list of modules now, but I don't know how to deal with that, so just ignore them. (In that case, they wouldn't be part of the project, speeding up update of the clang code model after changes, but then not providing features like code navigation and autocompletion etc.) Change-Id: Idb04af5f7445955e5dbf9ec3fd8626bbcb09ab11 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162837 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-01-29Experimental support for latest Emscripten (and Qt6)Stephan Bergmann9-9/+218
What I'm after in the context of our Embind-related code is the claim at <https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#memory-management>: "JavaScript only gained support for finalizers in ECMAScript 2021, or ECMA-262 Edition 12. The new API is called FinalizationRegistry and it still does not offer any guarantees that the provided finalization callback will be called. Embind uses this for cleanup if available, but only for smart pointers, and only as a last resort." However, with the recommended emsdk 2.0.31 my tests did not show any use of that finalization support. So I wanted to try with the latest emsdk 3.1.51 instead. But then, linking vcldemo failed with > wasm-ld: error: ~/allotropia-qt5/lib/libQt5Core.a(qlogging.o): undefined symbol: std::__2::__vector_base_common<true>::__throw_length_error() const etc., so I gave it a try to rather build against latest Qt6.7, with > --with-distro=LibreOfficeWASM32 > --disable-qt5 > --enable-qt6 > QT6DIR=... TODO: The result is highly experimental, and it uses ENABLE_QT5 (i.e., the recommended setup with emsdk 2.0.31 and the <https://github.com/allotropia/qt5.git> v5.15.2+wasm branch) vs. ENABLE_QT6 (i.e., my experimental setup with emsdk 3.1.51 and the <https://github.com/qt/qt5.git> 6.7 branch) not only to distinguish between Qt5- vs. Qt6-specific behavior, but also to distinguish between old- vs. new-Emscripten-specific behavior. Of note: * The startup code appears to have changed substantially (and required setting -s MODULARIZE=1 and -s EXPORT_NAME=soffice_entry now, and telling emcc to build just soffice.js and not the wrapper soffice.html. TODO: This also required hacking into qt_soffice.html: (1) The command-line arguments (--norestore, --nologo, --writer, and the exammple.odt; all of which we should eventually get rid of, anyway). (2) Saving the generated instance as window.Module (and adapting the embindmaker-generated code, cf. the changes to static/README.wasm.md). * There were some symbol clashes between external/argon2 and libQt6Core.a(qcryptographichash.cpp.o, so renamed the problematic symbols in external/argon2. Change-Id: I5420ab566d560b11954ac6613249bfc53d8acb31 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162695 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
2024-01-28tdf#159323 qt weld: Remember VCL response code, don't try to mapMichael Weghorn1-73/+12
Set the VCL return code of a button as a property "response-code" for the `QPushButton` and use that instead of trying to map the VCL response code for a button to a `QMessageBox::ButtonRole` and then mapping that back to the original VCL return code. While the previous approach worked fine for return codes from the `VclResponseType` enum, it turns out that any arbitrary int can be used, and supporting that needs a different approach. One example (s. tdf#159323 comment 7) is `SbRtl_MsgBox` (in basic/source/runtime/methods.cxx) which uses values from the `BasicResponse` enum defined in there that has a `BasicResponse::Yes = 6`, but the `VclResponseType` enum has nothing for the value 6. Just use `QMessageBox::ButtonRole::ActionRole` for all buttons, since there's no clear way to map from the VCL response code to the `QMessageBox::ButtonRole::ActionRole` in general. Change-Id: I1782512d4eb47b2dcf71214d16e64d56127e9e3f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162560 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-01-28tdf#159323 qt weld: Set standard buttons via weld APIMichael Weghorn3-32/+32
Instead of mapping the `VclButtonsType` to the corresponding `QMessageBox::StandardButtons` and using that to set the standard buttons for the `QMessageBox` using `QMessageBox::setStandardButtons`, use `weld::MessageDialog::add_button` to add all of the buttons manually, using their standard button texts. While the former is somewhat nicer, it depends on the ability to map between the VCL response code and a `QMessageBox::ButtonRole`. While there is currently a mapping in place (s. `lcl_vclResponseTypeToQtMessageBoxButtonRole` and `lcl_qtMessageBoxButtonRoleToVclResponseType`), this turned out to not be sufficient, since the VCL return code cannot only be one of the enum values in `VclResponseType` (which are currently handled) but any int. This commit is in preparation of an upcoming one that will replace the current mapping to support arbitrary int response codes. Change-Id: Icca68f2ccec182f8ff6ae3c64680a4d28bd687d0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162559 Tested-by: Jenkins Reviewed-by: Omkar Acharekar <omkaracharekar12@gmail.com> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-01-25sw a11y: Send SELECTION_CHANGED_{ADD,REMOVE} event for docMichael Weghorn1-9/+14
`AccessibleEventId::SELECTION_CHANGED_ADD` and `AccessibleEventId::SELECTION_CHANGED_REMOVE` events need to be sent for the selection container whose selection changed, not the child that was (un)selected. The latter should be set as the `NewValue` of the event, see the doc in offapi/com/sun/star/accessibility/AccessibleEventId.idl . Therefore, adjust the handling for (un)selected shapes in Writer: Set the doc view's a11y object as the source, just as it is already done for the `AccessibleEventId::SELECTION_CHANGED_WITHIN` case, and set the (un)selected shape as the `NewValue`. With a Writer doc having two shapes and the first one selected, clicking on the other one to switch selection to that one would previously result in this warning when using the qt6 VCL plugin with Orca running: warn:vcl.qt:114611:114611:vcl/qt6/../qt5/QtAccessibleEventListener.cxx:363: Selection add/remove event without the (un)selected accessible set warn:vcl.qt:114611:114611:vcl/qt6/../qt5/QtAccessibleEventListener.cxx:363: Selection add/remove event without the (un)selected accessible set Using gtk3 and this pyatspi script: #!/usr/bin/python3 import pyatspi def listener(e): try: if e.host_application.name != 'soffice': return except: return print(e) pyatspi.Registry.registerEventListener(listener, 'object:state-changed:selected') pyatspi.Registry.registerEventListener(listener, 'object:selection-changed') pyatspi.Registry.start() would previously give this output for that case: object:state-changed:selected(0, 0, 0) source: [panel | Shape 1] host_application: [application | soffice] sender: [application | soffice] object:selection-changed(0, 0, 0) source: [panel | Shape 1] host_application: [application | soffice] sender: [application | soffice] object:state-changed:selected(1, 0, 0) source: [panel | Shape 2] host_application: [application | soffice] sender: [application | soffice] object:selection-changed(0, 0, 0) source: [panel | Shape 2] host_application: [application | soffice] sender: [application | soffice] (i.e. both, the "state-changed:selected" as well as the "selection-changed" AT-SPI events were previously sent for the shapes.) With this change in place, this gives the expected output: object:state-changed:selected(0, 0, 0) source: [panel | Shape 1] host_application: [application | soffice] sender: [application | soffice] object:selection-changed(0, 0, 0) source: [document text | Untitled 1 - LibreOfficeDev Document] host_application: [application | soffice] sender: [application | soffice] object:state-changed:selected(1, 0, 0) source: [panel | Shape 2] host_application: [application | soffice] sender: [application | soffice] object:selection-changed(0, 0, 0) source: [document text | Untitled 1 - LibreOfficeDev Document] host_application: [application | soffice] sender: [application | soffice] Change-Id: Id2017f70a8e53043b4c303f69464ddd39f280097 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162519 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-01-24svx a11y: Notify listeners when disposing shapeMichael Weghorn1-1/+1
In `AccessibleShape::disposing`, call the same method of the base class, i.e. `AccessibleContextBase::disposing`, not `AccessibleContextBase::dispose`. The code was moved from `AccessibleShape::dispose` to `AccessibleShape::disposing` in commit f11b151dc08ccfcb7e78bfd9a24c77670942ea63 Date: Tue Apr 30 13:30:10 2002 +0000 #95585# Moved code from dispose to disposing(). and it seems likely that adjusting the base class method to call was just forgotten/missed. This resulted in the accessible getting disposed without listeners getting notified (since `AccessibleContextBase::disposing` takes care of that). This resulted in a crash for the following scenario with the qt6 VCL plugin when the Orca screen reader is running: 1) start LO Writer 2) click on the "Basic shapes" toolbar button 3) click + drag to insert a shape into the document 4) click somewhere else Backtrace is below. `AtSpiAdaptor::handleMessage` (frame #12 in the bt) checks whether the accessible is valid and returns early otherwise. But since listeners were not notified when the object got disposed, `QtAccessibleEventListener::disposing` wasn't called, which would have taken care of invalidating the `QtAccessibleWidget`, in which case this early return would have happened instead of the crash. This behaves as expected now with this commit in place. stderr output of the crash: terminate called after throwing an instance of 'com::sun::star::lang::DisposedException' Backtrace: Thread 1 received signal SIGABRT, Aborted. __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 44 ./nptl/pthread_kill.c: No such file or directory. (gdb) bt #0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 #1 0x00007f5bc1ca815f in __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78 #2 0x00007f5bc1c5a472 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #3 0x00007f5bc1c444b2 in __GI_abort () at ./stdlib/abort.c:79 #4 0x00007f5bc18a09eb in () at /lib/x86_64-linux-gnu/libstdc++.so.6 #5 0x00007f5bc18affca in () at /lib/x86_64-linux-gnu/libstdc++.so.6 #6 0x00007f5bc18b0035 in () at /lib/x86_64-linux-gnu/libstdc++.so.6 #7 0x00007f5bc18b0288 in () at /lib/x86_64-linux-gnu/libstdc++.so.6 #8 0x00007f5bc02b4550 in accessibility::AccessibleContextBase::ThrowIfDisposed() (this=0x55a6fc7e7da0) at .../libreoffice/editeng/source/accessibility/AccessibleContextBase.cxx:494 #9 0x00007f5bbcf7d54e in accessibility::AccessibleShape::getAccessibleName() (this=0x55a6fc7e7da0) at .../libreoffice/svx/source/accessibility/AccessibleShape.cxx:280 #10 0x00007f5bada62107 in QtAccessibleWidget::text(QAccessible::Text) const (this=0x55a6fad4fe20, text=QAccessible::Name) at .../libreoffice/vcl/qt6/../qt5/QtAccessibleWidget.cxx:362 #11 0x00007f5bac5552d2 in AtSpiAdaptor::accessibleInterface(QAccessibleInterface*, QString const&, QDBusMessage const&, QDBusConnection const&) (this=0x55a6f769bce0, interface=0x55a6fad4fe20, function=..., message=..., connection=...) at .../qt5/qtbase/src/gui/accessible/linux/atspiadaptor.cpp:1545 #12 0x00007f5bac553cce in AtSpiAdaptor::handleMessage(QDBusMessage const&, QDBusConnection const&) (this=0x55a6f769bce0, message=..., connection=...) at .../qt5/qtbase/src/gui/accessible/linux/atspiadaptor.cpp:1432 #13 0x00007f5baaa88943 in QDBusConnectionPrivate::activateObject(QDBusConnectionPrivate::ObjectTreeNode&, QDBusMessage const&, int) (this=0x7f5ba4010f30, node=..., msg=..., pathStartPos=27) at .../qt5/qtbase/src/dbus/qdbusintegrator.cpp:1448 #14 0x00007f5baaa89628 in QDBusActivateObjectEvent::placeMetaCall(QObject*) (this=0x7f5ba4026980) at .../qt5/qtbase/src/dbus/qdbusintegrator.cpp:1604 #15 0x00007f5bad044013 in QObject::event(QEvent*) (this=0x55a6f769bce0, e=0x7f5ba4026980) at .../qt5/qtbase/src/corelib/kernel/qobject.cpp:1447 #16 0x00007f5bab1a6986 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=0x55a6f631c3e0, receiver=0x55a6f769bce0, e=0x7f5ba4026980) at .../qt5/qtbase/src/widgets/kernel/qapplication.cpp:3298 #17 0x00007f5bab1a6797 in QApplication::notify(QObject*, QEvent*) (this=0x55a6f63bb840, receiver=0x55a6f769bce0, e=0x7f5ba4026980) at .../qt5/qtbase/src/widgets/kernel/qapplication.cpp:3249 #18 0x00007f5bacfb0212 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x55a6f769bce0, event=0x7f5ba4026980) at .../qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1138 #19 0x00007f5bacfb0dbb in QCoreApplication::sendEvent(QObject*, QEvent*) (receiver=0x55a6f769bce0, event=0x7f5ba4026980) at .../qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1581 #20 0x00007f5bacfb2474 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (receiver=0x0, event_type=0, data=0x55a6f6337df0) at .../qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1936 #21 0x00007f5bacfb160e in QCoreApplication::sendPostedEvents(QObject*, int) (receiver=0x0, event_type=0) at .../qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1770 #22 0x00007f5bad43441c in postEventSourceDispatch(GSource*, GSourceFunc, gpointer) (s=0x55a6f642f710) at .../qt5/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:244 #23 0x00007f5bb47111f4 in () at /lib/x86_64-linux-gnu/libglib-2.0.so.0 #24 0x00007f5bb4714317 in () at /lib/x86_64-linux-gnu/libglib-2.0.so.0 #25 0x00007f5bb4714930 in g_main_context_iteration () at /lib/x86_64-linux-gnu/libglib-2.0.so.0 #26 0x00007f5bad434cb1 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x55a6f6435dc0, flags=...) at .../qt5/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:394 #27 0x00007f5baa929e18 in QXcbGlibEventDispatcher::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x55a6f6435dc0, flags=...) at .../qt5/qtbase/src/plugins/platforms/xcb/qxcbeventdispatcher.cpp:96 #28 0x00007f5badad8bea in QtInstance::ImplYield(bool, bool) (this=0x55a6f6442080, bWait=true, bHandleAllCurrentEvents=false) at .../libreoffice/vcl/qt6/../qt5/QtInstance.cxx:424 #29 0x00007f5badad8d13 in QtInstance::DoYield(bool, bool) (this=0x55a6f6442080, bWait=true, bHandleAllCurrentEvents=false) at .../libreoffice/vcl/qt6/../qt5/QtInstance.cxx:435 #30 0x00007f5bb8734af6 in ImplYield(bool, bool) (i_bWait=true, i_bAllEvents=false) at .../libreoffice/vcl/source/app/svapp.cxx:386 #31 0x00007f5bb8735894 in Application::Yield() () at .../libreoffice/vcl/source/app/svapp.cxx:470 #32 0x00007f5bb87347e9 in Application::Execute() () at .../libreoffice/vcl/source/app/svapp.cxx:364 #33 0x00007f5bc1e36e66 in desktop::Desktop::Main() (this=0x7ffc62160570) at .../libreoffice/desktop/source/app/app.cxx:1614 #34 0x00007f5bb8753ca0 in ImplSVMain() () at .../libreoffice/vcl/source/app/svmain.cxx:229 #35 0x00007f5bb8753fb5 in SVMain() () at .../libreoffice/vcl/source/app/svmain.cxx:261 #36 0x00007f5bc1ea4101 in soffice_main() () at .../libreoffice/desktop/source/app/sofficemain.cxx:94 #37 0x000055a6f46e19d4 in sal_main () at .../libreoffice/desktop/source/app/main.c:51 #38 0x000055a6f46e19ba in main (argc=2, argv=0x7ffc62160798) at .../libreoffice/desktop/source/app/main.c:49 Change-Id: Iae8a9ff61df99094b4cd73da895d1f6ac850c0c9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162493 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-01-24tdf#154381 qt weld: Allow setting message box default buttonMichael Weghorn2-0/+21
Implement `QtInstanceMessageDialog::set_default_response` by identifying the `QPushButton` in the `QMessageBox` that has the `QMessageBox::ButtonRole` corresponding to the given VCL return type and setting that as the default button in the `QMessageBox`. With this in place, the qt6 welded message dialog that shows up when opening a file that's already open in another instance of LibreOffice (s. `AlreadyOpenQueryBox::AlreadyOpenQueryBox`) has initial focus on the "Open Read-Only" button when it opens, just as is the case for the non-welded one (whose use can be forced by setting env var `SAL_VCL_QT_NO_WELDED_WIDGETS=1`). Change-Id: I6d543b43cb6adec2dde9646e1452aa03bdcbf331 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162441 Tested-by: Jenkins Reviewed-by: Omkar Acharekar <omkaracharekar12@gmail.com> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-01-24tdf#154381 qt weld: Add button handling for message boxMichael Weghorn2-0/+88
Override the `QtInstanceDialog` methods `add_button` and `run` in `QtInstanceMessageDialog`, and implement handling for these buttons with the native `QMessageBox` that is used internally: Implement `QtInstanceMessageDialog::add_button` to make adding buttons to the welded message dialog work. Map the VCL response type to a corresponding `QMessageBox::ButtonRole`. Some mappings are straightforward, others are a bit more arbitrary, but the only essential thing is that the mapping back to the VCL response code is consistent. `QMessageBox::exec` [1] overrides `QDialog::exec` [2], and while the int returned by the latter corresponds to a `QDialog::DialogCode` code, the int returned by the former corresponds to a `QMessageBox::StandardButton` value. Since the current `QtInstanceDialog::run` implementation relies on the `QDialog` behaviour, override it for the message dialog case. Since the `QMessageBox::ButtonRole` is set in `QtInstanceMessageDialog::add_button`, retrieve the corresponding role from the clicked button instead of using the return value of the `QMessageBox::exec` to be able to get the correct VCL return code again. With this in place, the qt6 welded message dialog that shows up when opening a file that's already open in another instance of LibreOffice (s. `AlreadyOpenQueryBox::AlreadyOpenQueryBox`) shows buttons and clicking any of them behaves as expected, just as is the case for the non-welded one (whose use can be forced by setting env var `SAL_VCL_QT_NO_WELDED_WIDGETS=1`). [1] https://doc.qt.io/qt-6/qmessagebox.html#exec` [2] https://doc.qt.io/qt-6/qdialog.html#exec Change-Id: Ie37573951302f13eab758f889d478dc9351e9c07 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162440 Tested-by: Jenkins Reviewed-by: Omkar Acharekar <omkaracharekar12@gmail.com> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-01-24qt: Move VCL -> Qt accelerator text handling to QtToolsMichael Weghorn4-17/+16
Move the functionality to convert a string (potentially) containing a VCL-style accelerator ('~') to the Qt equivalent from `QtMenu::NativeItemText` to a new helper function `vclToQtStringtWithAccelerator` in QtTools.hxx This will be reused for button text in welded message dialogs in an upcoming commit. Change-Id: Ibedabb7937b97d195244045799c092463810d766 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162439 Tested-by: Jenkins Reviewed-by: Omkar Acharekar <omkaracharekar12@gmail.com> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-01-24qt weld: Add assert on unhandled VCLButtonsTypeMichael Weghorn1-1/+2
`vclButtonsTypeToQtButton` handles all of the 6 existing `vclButtonsTypeToQtButton` enum values, so there's no need to add more. Therefore, replace the comment with a failing assert for the default case that should never get hit. (If more `VclButtonsType` enum values should get added in the future, those should explicitly be handled here.) Change-Id: Iddb891399798156a266657c88cf6aed77a77f6a7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162438 Tested-by: Jenkins Reviewed-by: Omkar Acharekar <omkaracharekar12@gmail.com> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-01-24tdf#154381 qt weld: Implement QtInstanceWindow::{g,s}et_titleMichael Weghorn3-4/+19
Implement methods to set and get the window title. In order to do that, add a `m_pWidget` member to `QtInstanceWindow`. For the `QtInstanceDialog` case, that widget is a pointer to the same dialog that `QtInstanceDialog::m_pDialog` points to, which is a unique_ptr and thus takes care of the memory management. The non-dialog case is not supported yet, s.a. this commit adding support for simple welded message dialogs initially: commit 1ace888823443b85d4a81b94656844f1b27e2987 Date: Wed Dec 20 19:13:50 2023 +0530 tdf#130857 Use native qt widgets - simple message dialog With this in place, the qt6 welded message dialog that shows up when opening a file that's already open in another instance of LO has the correct title ("Document in Use"), just as is the case for the non-welded one (whose use can be forced by setting env var `SAL_VCL_QT_NO_WELDED_WIDGETS=1`). Change-Id: I35f323cdfa70fb953b6bc73aaf726fb1f3098c45 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162437 Tested-by: Jenkins Reviewed-by: Omkar Acharekar <omkaracharekar12@gmail.com> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-01-24qt weld: Make QtInstanceDialog::m_pDialog privateMichael Weghorn1-2/+2
Change-Id: I757849beb06d0ce986be352feb34af463430333b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162436 Tested-by: Jenkins Reviewed-by: Omkar Acharekar <omkaracharekar12@gmail.com> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-01-23tdf#159333 qt a11y: Process shortcuts only onceMichael Weghorn1-0/+3
As described in commit 69e708868f6046cada955a16bca966370ce3218a Author: Michael Weghorn <m.weghorn@posteo.de> Date: Thu Feb 20 08:14:36 2020 +0100 tdf#130794 qt5: Actually, ignore non-spontaneous QEvent::ShortcutOverride and the previous commit 034f56015c1c7a61faede33fb5306f63b5585632 Author: Michael Weghorn <m.weghorn@posteo.de> Date: Mon Feb 17 10:38:15 2020 +0100 tdf#126785 qt5: Ignore external QEvent::ShortcutOverride it refers to, duplicate events of type `QEvent::ShortcutOverride` are received when a11y is active, so those commits introduced ignoring of the non-spontaneous one, and leaving processing for the spontaneous event only, thus preventing duplication of typed text. However, keyboard shortcuts like Ctrl+V were still processed twice: While they're only processed once in `QtWidget::handleEvent` (for the spontaneous event of type `QEvent::ShortcutOverride`), the keyboard shortcut was additionally handled as the shortcut to activate the action that's used for the menu entries, e.g. the "Edit" -> "Paste" menu entry for Ctrl+V (s. class `QtMenu`, where those are set). Accept the non-spontaneous `QEvent::ShortcutOverride` event to prevent that from happening. Quoting the `QEvent::ShortcutOverride` doc [1]: > Key press in child, for overriding shortcut key handling (QKeyEvent). > When a shortcut is about to trigger, ShortcutOverride is sent to the > active window. This allows clients (e.g. widgets) to signal that they > will handle the shortcut themselves, by accepting the event. If the > shortcut override is accepted, the event is delivered as a normal key > press to the focus widget. Otherwise, it triggers the shortcut action, > if one exists. With this commit in place, the shortcut is only processed once, as expected. Potentially, this should ideally be addressed on Qt side in the future, see the discussion in tdf#126785. The duplication happens since this qtbase commit (no longer with a local revert of it): [2] commit 7c532891e0be2cf78c89738e175b3d312d305e4e Date: Tue Apr 17 16:45:09 2018 +0200 Send ShortcutOverride event when receiving a non-spontaneous key press Since 2020, there a pending Qt change by Alexander Volkov suggesting to avoid the duplicate events by filtering them out in `QSpiApplicationAdaptor::eventFilter` on qtbase side: [3] With that change not being merged yet, fix this on LO side for now. [1] https://doc.qt.io/qt-6/qevent.html#Type-enum [2] https://code.qt.io/cgit/qt/qtbase.git/commit/?id=7c532891e0be2cf78c89738e175b3d312d305e4e [3] https://codereview.qt-project.org/c/qt/qtbase/+/295892 Change-Id: I28cb11914ae81284e050bff0deb39d95e8073ce0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162430 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-01-18-Werror,-Wdeprecated-enum-float-conversion (Emscripten)Stephan Bergmann1-4/+1
> static/source/qt5-mandelbrot/renderthread.cxx:61:62: error: arithmetic between floating-point type 'double' and enumeration type 'RenderThread::(unnamed enum at workdir/CustomTarget/static/qt5-mandelbrot/../../../../static/source/qt5-mandelbrot/renderthread.h:92:5)' is deprecated [-Werror,-Wdeprecated-enum-float-conversion] > m_colormap[i] = rgbFromWaveLength(380.0 + (i * 400.0 / ColormapSize)); > ~~~~~~~~~ ^ ~~~~~~~~~~~~ Change-Id: I97dab1d11177a6e20ddd6703c146e31e316e0071 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162251 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
2024-01-16tdf#159213: fix Base crash when choosing "Help" in relations design (kf5)Julien Nabet2-1/+11
There are 2 parts here: 1) in vcl/qt5: - for release versions: avoid to call QtAccessibleRegistry::getQObject on a null object - for debug version: add an assertion on object to check it's not null 2) in svtools: the specific root cause was in EditBrowseBox::DeactivateCell, we must check m_aImpl->m_xActiveCell in addition to isAccessibleAlive() Import remark: I had a very naive/bandaid patch at the beginning this one is entirely thanks to Michael Weghorn Change-Id: I90214e9c5b7c0aa45481915d7be6020a7dc8c42e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162182 Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> Tested-by: Jenkins
2024-01-08tdf#130857 Use native qt widgets - simple message dialogOmkarAcharekar29-0/+950
- Implements CreateMessageDialog method for QtInstance which would create message dialogs using native qt widgets. Example - MasterPasswordCreateDialog ( https://git.libreoffice.org/core/+/5e8c0575e877795aaca91346548cd0136fa22048/uui/source/masterpasscrtdlg.cxx#64 ). To trigger this : a) Go to "Tools" -> "Options". b) Select "LibreOfficeDev" -> "Security", then check "Persistently save passwords for web connections". c) In the master password dialog, enter two different passwords and click "OK". The message dialog appears now uses native qt widgets. - adds Env variable SAL_VCL_QT_NO_WELDED_WIDGETS which reverts to previous behavior using VCL widgets. Note: most of the methods from weld::Widget hierarchy are currently just dummy implementations for Qt case, only what's needed for simple message dialogs has been implemented in this patch. Change-Id: I522489b8befb92f0092eb248ea2b81ecfbadd737 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161073 Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> Tested-by: Jenkins
2023-12-24qt: Rename SAL_VCL_{QT5 -> QT}_NO_NATIVEMichael Weghorn2-2/+2
Similar to Change-Id: I01b427648ef14f918cc692b30c80a7427455324f Author: Michael Weghorn <m.weghorn@posteo.de> Date: Sun Dec 24 00:13:25 2023 +0100 qt: Rename SAL_VCL_QT5_NO_NATIVE and use for all Qt-based VCLs , drop the version name in the env var to evaluate to decide whether to use fontconfig or not, since there's no reason this should only apply for qt5-based VCLs and not qt6-based ones. (Other than for the above-mentioned commit, the env variable would already be evaluated for all Qt-based VCL plugins, not just the qt5 one.) Change-Id: I2e239bf78916c37133f3992f49bb5dfa385c5801 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161263 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-12-24qt: Rename SAL_VCL_QT5_NO_NATIVE and use for all Qt-based VCLsMichael Weghorn2-5/+2
Instead of evaluating a `SAL_VCL_QT5_NO_NATIVE` environment variable to determine whether to disable drawing of widgets using the `QStyle`, evaluate `SAL_VCL_QT_NO_NATIVE` (i.e. without a Qt version number in the name), and do this for all Qt-based VCL plugins (qt5, qt6, kf5, kf6), not only qt5. I don't see a reason why this should be qt5-specific. Change-Id: I01b427648ef14f918cc692b30c80a7427455324f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161262 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-12-20gtk4 a11y: Remember LoAccessible for XAccessibleMichael Weghorn7-18/+103
Don't create a new `LoAccessible` for an `XAccessible` each time, but add a `GtkAccessibleRegistry` class that remembers the corresponding `LoAccessible` for an `XAccessible` in a map. Remove the entry from the map again in `GtkAccessibleEventListener::disposing`. This prevents Libreoffice from becoming unresponsive in local WIP branches of both, gtk and LO that add handling for changes to the focused state, when used with the Orca screen reader. This commit is very similar to what was added for the Qt-based VCL plugins in commit 812fe185fba48b439fb1229517d62aa67c209016 Author: Michael Weghorn <m.weghorn@posteo.de> Date: Wed Aug 24 11:42:04 2022 +0200 qt a11y: Remember and reuse existing QObject for XAccessible Change-Id: Ib217b477bf15abf255fcf254bf607ab8fc11a040 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161061 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-12-19tdf#123864 gtk3 a11y: Consider states when mapping BUTTON_DROPDOWNMichael Weghorn4-10/+17
Take the checkable state into account when mapping the `AccessibleRole::BUTTON_DROPDOWN` role. There is no direct ATK equivalent for `AccessibleRole::BUTTON_DROPDOWN`. Don't always use ATK_ROLE_PUSH_BUTTON, but use ATK_ROLE_TOGGLE_BUTTON when the button is CHECKABLE, i.e. it can be toggled. With this in place, Orca now announces the state of the underline button (on/off) when using the gtk3 VCL plugin. Related Orca source code that requires the toggle button role: [1] The state is not announced when using the qt6 VCL plugin yet, and Qt currently doesn't have a toggle button role, so that would have to be added there first to do something similar there. For gtk4, mapping could probably be done similarly, but more is missing for Orca to announce things in custom widgets (e.g. event handling), so leave that for later. [1] https://gitlab.gnome.org/GNOME/orca/-/blob/b80bb951a651f5f12a5ddfb2a5b1c151568d045b/src/orca/scripts/apps/soffice/speech_generator.py#L177 Change-Id: If69e08d2e4939cc709d44e89cc2fd1d01691a70b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160904 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-12-19gtk4 a11y: Add initial event handlingMichael Weghorn4-0/+111
Add a `GtkAccessibleEventListener` that is in charge of handling a11y events for the gtk4 VCL plugin. This is inspired by how the Qt-based VCL plugins do it (see `QtAccessibleEventListener`). Initially, only handle the `css::accessibility::AccessibleEventId::STATE_CHANGED` for the `AccessibleStateType::CHECKED` state by updating the value for the corresponding Gtk state. With this in place, toggling e.g. the "Bold" toggle button in Writer's formatting toolbar now properly updates the "checked" state of the corresponding a11y object in Accerciser's tree view of LO's a11y hierarchy. Gtk takes care of sending a corresponding "state-changed" event on the AT-SPI layer: 10.8 object:state-changed:checked(1, 0, 0) source: [toggle button | Bold] application: [application | soffice] Handling state changes to other states that map to a `GtkAccessibleState` should be possible in a similar way. However, other states - like the FOCUSED state - map to a `GtkAccessiblePlatformState` in Gtk 4, and the function `gtk_accessible_platform_changed` to update these that is used by Gtk's own widgets is private API for now, so cannot be used by LibreOffice, so I currently don't see a way to handle these without changes on Gtk side (see [1]). [1] https://gitlab.gnome.org/GNOME/gtk/-/issues/6272 Change-Id: I2a5ca4448ad14a61dc96aef7b22af36baeeed5c4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160929 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>