For the UNO control property browser, switching focus away
from the property browser to the document while an Edit in the property
browser has focus and then back to the property browser results in the
controls of the property browsers getting disposed and new ones created
when processing the focus event. Backtrace of how the Edit gets
disposed (for the "Name" edit):
1 VclReferenceBase::disposeOnce vclreferencebase.cxx 37 0x7f62fdb3d82a
2 VclPtr<vcl::Window>::disposeAndClear vclptr.hxx 207 0x7f62fd6aebc5
3 VclBuilder::disposeBuilder builder.cxx 831 0x7f62fd68ca34
4 VclBuilder::~VclBuilder builder.cxx 823 0x7f62fd68c8c7
5 VclBuilder::~VclBuilder builder.cxx 822 0x7f62fd68cba9
6 std::default_delete<VclBuilder>::operator() unique_ptr.h 93 0x7f62fd748b78
7 std::__uniq_ptr_impl<VclBuilder, std::default_delete<VclBuilder>>::reset unique_ptr.h 205 0x7f62fd77c9f8
8 std::unique_ptr<VclBuilder, std::default_delete<VclBuilder>>::reset unique_ptr.h 504 0x7f62fd77bf4d
9 SalInstanceBuilder::~SalInstanceBuilder salvtables.cxx 7578 0x7f62fe038f8a
10 SalInstanceBuilder::~SalInstanceBuilder salvtables.cxx 7573 0x7f62fe038fe9
11 std::default_delete<weld::Builder>::operator() unique_ptr.h 93 0x7f62dcf9a3ab
12 std::__uniq_ptr_impl<weld::Builder, std::default_delete<weld::Builder>>::reset unique_ptr.h 205 0x7f62dd101868
13 std::unique_ptr<weld::Builder, std::default_delete<weld::Builder>>::reset unique_ptr.h 504 0x7f62dd0f7a5d
14 pcr::CommonBehaviourControl<com::sun::star::inspection::XPropertyControl, weld::Entry>::clear_widgetry commoncontrol.hxx 150 0x7f62dd15ad8d
15 pcr::CommonBehaviourControl<com::sun::star::inspection::XPropertyControl, weld::Entry>::disposing commoncontrol.hxx 156 0x7f62dd1552d5
16 cppu::WeakComponentImplHelperBase::dispose implbase.cxx 104 0x7f6304f3db00
17 cppu::PartialWeakComponentImplHelper<com::sun::star::inspection::XPropertyControl>::dispose compbase.hxx 90 0x7f62dd1545b5
18 pcr::(anonymous namespace)::lcl_implDisposeControl_nothrow browserlistbox.cxx 678 0x7f62dcf9f864
19 pcr::OBrowserListBox::Clear browserlistbox.cxx 694 0x7f62dcf9c8d1
20 pcr::OBrowserListBox::~OBrowserListBox browserlistbox.cxx 324 0x7f62dcf9c717
21 o3tl::default_delete<pcr::OBrowserListBox>::operator() deleter.hxx 46 0x7f62dcfae757
22 std::unique_ptr<pcr::OBrowserListBox, o3tl::default_delete<pcr::OBrowserListBox>>::~unique_ptr unique_ptr.h 399 0x7f62dcfae54f
23 pcr::OBrowserPage::~OBrowserPage browserpage.cxx 38 0x7f62dcfae348
24 std::default_delete<pcr::OBrowserPage>::operator() unique_ptr.h 93 0x7f62dd136577
25 std::unique_ptr<pcr::OBrowserPage, std::default_delete<pcr::OBrowserPage>>::~unique_ptr unique_ptr.h 399 0x7f62dd13373f
26 pcr::OPropertyEditor::PropertyPage::~PropertyPage propertyeditor.hxx 43 0x7f62dd1336ed
27 std::pair<unsigned short const, pcr::OPropertyEditor::PropertyPage>::~pair stl_pair.h 284 0x7f62dd1341a9
28 std::destroy_at<std::pair<unsigned short const, pcr::OPropertyEditor::PropertyPage>> stl_construct.h 88 0x7f62dd134185
29 std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<unsigned short const, pcr::OPropertyEditor::PropertyPage>>>>::destroy<std::pair<unsigned short const, pcr::OPropertyEditor::PropertyPage>> alloc_traits.h 593 0x7f62dd1340b5
30 std::_Rb_tree<unsigned short, std::pair<unsigned short const, pcr::OPropertyEditor::PropertyPage>, std::_Select1st<std::pair<unsigned short const, pcr::OPropertyEditor::PropertyPage>>, std::less<unsigned short>, std::allocator<std::pair<unsigned short const, pcr::OPropertyEditor::PropertyPage>>>::_M_destroy_node stl_tree.h 621 0x7f62dd1340b5
31 std::_Rb_tree<unsigned short, std::pair<unsigned short const, pcr::OPropertyEditor::PropertyPage>, std::_Select1st<std::pair<unsigned short const, pcr::OPropertyEditor::PropertyPage>>, std::less<unsigned short>, std::allocator<std::pair<unsigned short const, pcr::OPropertyEditor::PropertyPage>>>::_M_drop_node stl_tree.h 629 0x7f62dd134051
32 std::_Rb_tree<unsigned short, std::pair<unsigned short const, pcr::OPropertyEditor::PropertyPage>, std::_Select1st<std::pair<unsigned short const, pcr::OPropertyEditor::PropertyPage>>, std::less<unsigned short>, std::allocator<std::pair<unsigned short const, pcr::OPropertyEditor::PropertyPage>>>::_M_erase stl_tree.h 1934 0x7f62dd133f9e
33 std::_Rb_tree<unsigned short, std::pair<unsigned short const, pcr::OPropertyEditor::PropertyPage>, std::_Select1st<std::pair<unsigned short const, pcr::OPropertyEditor::PropertyPage>>, std::less<unsigned short>, std::allocator<std::pair<unsigned short const, pcr::OPropertyEditor::PropertyPage>>>::clear stl_tree.h 1251 0x7f62dd1371e5
34 std::__cxx1998::map<unsigned short, pcr::OPropertyEditor::PropertyPage>::clear stl_map.h 1183 0x7f62dd136e25
35 std::map<unsigned short, pcr::OPropertyEditor::PropertyPage>::clear map.h 573 0x7f62dd132b68
36 pcr::OPropertyEditor::ClearAll propertyeditor.cxx 62 0x7f62dd130570
37 pcr::OPropertyBrowserController::stopInspection propcontroller.cxx 839 0x7f62dd0e7e58
38 pcr::OPropertyBrowserController::impl_rebindToInspectee_nothrow propcontroller.cxx 916 0x7f62dd0e94be
39 pcr::OPropertyBrowserController::inspect propcontroller.cxx 246 0x7f62dd0e9c1a
40 pcr::FormController::setFastPropertyValue_NoBroadcast formcontroller.cxx 190 0x7f62dd06dcca
41 cppu::OPropertySetHelper::setFastPropertyValue propshlp.cxx 524 0x7f6304f873a8
42 cppu::OPropertySetHelper::setPropertyValue propshlp.cxx 264 0x7f6304f859bb
43 basctl::PropBrw::implSetNewObject propbrw.cxx 303 0x7f62e8b185db
44 basctl::PropBrw::ImplUpdate propbrw.cxx 501 0x7f62e8b16549
45 basctl::PropBrw::Update propbrw.cxx 64 0x7f62e8b15f4a
46 basctl::DialogWindowLayout::UpdatePropertyBrowser baside3.cxx 1256 0x7f62e89e805b
47 basctl::DialogWindow::UpdateBrowser baside3.cxx 599 0x7f62e89e8009
48 basctl::Shell::Activate basides1.cxx 1602 0x7f62e8a0669a
49 SfxShell::DoActivate_Impl shell.cxx 326 0x7f630301e7a3
50 SfxDispatcher::DoActivate_Impl dispatch.cxx 600 0x7f6302fc9bc8
51 SfxViewFrame::DoActivate viewfrm.cxx 1197 0x7f63036313f4
52 SfxApplication::SetViewFrame_Impl app.cxx 261 0x7f6302e4e59e
53 SfxViewFrame::SetViewFrame viewfrm.cxx 3731 0x7f63036313ad
54 SfxViewFrame::MakeActive_Impl viewfrm.cxx 2332 0x7f63036365e4
55 SfxFrameWindow_Impl::EventNotify frame2.cxx 108 0x7f63035c383c
56 vcl::Window::CompatNotify window.cxx 3943 0x7f62fd8cae40
57 vcl::Window::EventNotify event.cxx 213 0x7f62fd77eec7
58 vcl::Window::CompatNotify window.cxx 3943 0x7f62fd8cae40
59 vcl::Window::EventNotify event.cxx 213 0x7f62fd77eec7
60 vcl::Window::CompatNotify window.cxx 3943 0x7f62fd8cae40
61 vcl::Window::EventNotify event.cxx 213 0x7f62fd77eec7
62 DockingWindow::EventNotify dockwin.cxx 581 0x7f62fd778931
63 vcl::Window::CompatNotify window.cxx 3943 0x7f62fd8cae40
64 vcl::Window::EventNotify event.cxx 213 0x7f62fd77eec7
65 vcl::Window::CompatNotify window.cxx 3943 0x7f62fd8cae40
66 vcl::Window::EventNotify event.cxx 213 0x7f62fd77eec7
67 vcl::Window::CompatNotify window.cxx 3943 0x7f62fd8cae40
68 vcl::Window::EventNotify event.cxx 213 0x7f62fd77eec7
69 Control::EventNotify ctrl.cxx 253 0x7f62fd939845
70 TabControl::EventNotify tabctrl.cxx 1618 0x7f62fda32eac
71 vcl::Window::CompatNotify window.cxx 3943 0x7f62fd8cae40
72 vcl::Window::EventNotify event.cxx 213 0x7f62fd77eec7
73 vcl::Window::CompatNotify window.cxx 3943 0x7f62fd8cae40
74 vcl::Window::EventNotify event.cxx 213 0x7f62fd77eec7
75 vcl::Window::CompatNotify window.cxx 3943 0x7f62fd8cae40
76 vcl::Window::EventNotify event.cxx 213 0x7f62fd77eec7
77 vcl::Window::CompatNotify window.cxx 3943 0x7f62fd8cae40
78 vcl::Window::EventNotify event.cxx 213 0x7f62fd77eec7
79 VclScrolledWindow::EventNotify layout.cxx 2181 0x7f62fd79e326
80 vcl::Window::CompatNotify window.cxx 3943 0x7f62fd8cae40
81 vcl::Window::EventNotify event.cxx 213 0x7f62fd77eec7
82 vcl::Window::CompatNotify window.cxx 3943 0x7f62fd8cae40
83 vcl::Window::EventNotify event.cxx 213 0x7f62fd77eec7
84 vcl::Window::CompatNotify window.cxx 3943 0x7f62fd8cae40
85 vcl::Window::EventNotify event.cxx 213 0x7f62fd77eec7
86 vcl::Window::CompatNotify window.cxx 3943 0x7f62fd8cae40
87 vcl::Window::EventNotify event.cxx 213 0x7f62fd77eec7
88 vcl::Window::CompatNotify window.cxx 3943 0x7f62fd8cae40
89 vcl::Window::EventNotify event.cxx 213 0x7f62fd77eec7
90 vcl::Window::CompatNotify window.cxx 3943 0x7f62fd8cae40
91 vcl::Window::EventNotify event.cxx 213 0x7f62fd77eec7
92 Control::EventNotify ctrl.cxx 253 0x7f62fd939845
93 vcl::Window::CompatNotify window.cxx 3943 0x7f62fd8cae40
94 vcl::Window::GetFocus window.cxx 1855 0x7f62fd8cb109
95 Edit::GetFocus edit.cxx 1838 0x7f62fd94ab69
96 vcl::Window::CompatGetFocus window.cxx 3903 0x7f62fd8d602f
97 vcl::Window::ImplGrabFocus mouse.cxx 384 0x7f62fd8052c7
98 vcl::Window::GrabFocus window.cxx 2990 0x7f62fd8c4a67
99 vcl::Window::ImplAsyncFocusHdl winproc.cxx 2059 0x7f62fd8eb787
100 vcl::Window::LinkStubImplAsyncFocusHdl winproc.cxx 2033 0x7f62fd8eb5ad
101 Link<void *, void>::Call link.hxx 101 0x7f62fd8f39e1
102 ImplHandleUserEvent winproc.cxx 2285 0x7f62fd8efbe1
103 ImplWindowFrameProc winproc.cxx 2849 0x7f62fd8ecb1a
104 SalFrame::CallCallback salframe.hxx 311 0x7f62fe4ad65c
105 SalGenericDisplay::ProcessEvent gendisp.cxx 66 0x7f62fe4d596f
106 SalUserEventList::DispatchUserEvents(bool)::$_0::operator()() const salusereventlist.cxx 119 0x7f62fdff0d7d
107 SalUserEventList::DispatchUserEvents salusereventlist.cxx 120 0x7f62fdff0c56
108 SalGenericDisplay::DispatchInternalEvent gendisp.cxx 51 0x7f62fe4d58c5
109 SalX11Display::Yield saldisp.cxx 1860 0x7f62f3910ad4
110 DisplayYield saldisp.cxx 321 0x7f62f3905b2f
111 (anonymous namespace)::YieldEntry::HandleNextEvent saldata.cxx 559 0x7f62f390169c
112 SalXLib::Yield saldata.cxx 655 0x7f62f3900f09
113 X11SalInstance::DoYield salinst.cxx 193 0x7f62f391df3d
114 ImplYield svapp.cxx 385 0x7f62fe0bdd46
115 Application::Yield svapp.cxx 488 0x7f62fe0bd65f
116 Application::Execute svapp.cxx 360 0x7f62fe0bd440
117 desktop::Desktop::Main app.cxx 1679 0x7f6306f27f39
118 ImplSVMain svmain.cxx 230 0x7f62fe0df1c6
119 SVMain svmain.cxx 248 0x7f62fe0e0db9
120 soffice_main sofficemain.cxx 121 0x7f6306fa181a
121 sal_main main.c 51 0x55f5d611da6d
122 main main.c 49 0x55f5d611da47
As a consequence, the subsequent call to
GetSettings().GetStyleSettings().GetSelectionOptions();
in Edit::GetFocus (s. frame 95 above) triggers a crash
because the `mpWindowImpl` of the disposed Edit is null.
To prevent this, check whether the Edit is disposed
after the call to vcl::Window::GetFocus and return
early if that is the case.
For the property browser, that restores the behavior from
before
commit b2b43e83cc
Author: Michael Weghorn <m.weghorn@posteo.de>
Date: Thu Sep 7 15:42:57 2023 +0200
a11y: Call base class impl at beginning of Edit::GetFocus
, where the app doesn't crash, but the previously focused
"Name" edit no longer has focus after switching back and forth
(as it has actually been replaced by a new edit).
(The cursor blinks once in the edit, then disappears.)
Without being familiar with the underlying property browser
logic, it's unclear to me whether the underlying problem there
could be solved in a better way, e.g. whether skipping the
logic for the `OwnPropertyId::INTROSPECTEDOBJECT` case in
FormController::setFastPropertyValue_NoBroadcast (s. frame 40 above)
could be skipped if the previously inspected object (`m_xCurrentInspectee`)
is already the same as the "new" object to inspect (`_rValue`)
or whether that logic is required to ensure displayed values get
updated in specific scenarios where they might have changed
in the meantime.
Change-Id: I0e441fe9f5dfb487bf832206bcdec08d87e7ae2a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180168
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
LibreOffice
LibreOffice is an integrated office suite based on copyleft licenses and compatible with most document formats and standards. Libreoffice is backed by The Document Foundation, which represents a large independent community of enterprises, developers and other volunteers moved by the common goal of bringing to the market the best software for personal productivity. LibreOffice is open source, and free to download, use and distribute.
A quick overview of the LibreOffice code structure.
Overview
You can develop for LibreOffice in one of two ways, one recommended and one much less so. First the somewhat less recommended way: it is possible to use the SDK to develop an extension, for which you can read the API docs and Developers Guide. This re-uses the (extremely generic) UNO APIs that are also used by macro scripting in StarBasic.
The best way to add a generally useful feature to LibreOffice is to work on the code base however. Overall this way makes it easier to compile and build your code, it avoids any arbitrary limitations of our scripting APIs, and in general is far more simple and intuitive - if you are a reasonably able C++ programmer.
The Build Chain and Runtime Baselines
These are the current minimal operating system and compiler versions to run and compile LibreOffice, also used by the TDF builds:
- Windows:
- Runtime: Windows 10
- Build: Cygwin + Visual Studio 2019 version 16.10
- macOS:
- Runtime: 10.15
- Build: 12 (13 for aarch64) + Xcode 14
- Linux:
- Runtime: RHEL 8 or CentOS 8 and comparable
- Build: either GCC 12; or Clang 12 with libstdc++ 10
- iOS (only for LibreOfficeKit):
- Runtime: 11.4 (only support for newer i devices == 64 bit)
- Build: Xcode 9.3 and iPhone SDK 11.4
- Android:
- Build: NDK r23 and SDK 30.0.3
- Emscripten / WASM:
- Runtime: a browser with SharedMemory support (threads + atomics)
- Build: Qt 5.15 with Qt supported Emscripten 1.39.8
- See README.wasm
Java is required for building many parts of LibreOffice. In TDF Wiki article Development/Java, the exact modules that depend on Java are listed.
The baseline for Java is Java Development Kit (JDK) Version 17 or later.
The baseline for Python is version 3.11. It follows the version available in SUSE Linux Enterprise Desktop and the Maintenance Support version of Red Hat Enterprise Linux.
If you want to use Clang with the LibreOffice compiler plugins, the minimal version of Clang is 12.0.1. Since Xcode doesn't provide the compiler plugin headers, you have to compile your own Clang to use them on macOS.
You can find the TDF configure switches in the distro-configs/ directory.
To setup your initial build environment on Windows and macOS, we provide the LibreOffice Development Environment (LODE) scripts.
For more information see the build instructions for your platform in the TDF wiki.
The Important Bits of Code
Each module should have a README.md file inside it which has some
degree of documentation for that module; patches are most welcome to
improve those. We have those turned into a web page here:
However, there are two hundred modules, many of them of only peripheral interest for a specialist audience. So - where is the good stuff, the code that is most useful. Here is a quick overview of the most important ones:
| Module | Description |
|---|---|
| sal/ | this provides a simple System Abstraction Layer |
| tools/ | this provides basic internal types: Rectangle, Color etc. |
| vcl/ | this is the widget toolkit library and one rendering abstraction |
| framework/ | UNO framework, responsible for building toolbars, menus, status bars, and the chrome around the document using widgets from VCL, and XML descriptions from /uiconfig/ files |
| sfx2/ | legacy core framework used by Writer/Calc/Draw: document model / load/save / signals for actions etc. |
| svx/ | drawing model related helper code, including much of Draw/Impress |
Then applications
| Module | Description |
|---|---|
| desktop/ | this is where the main() for the application lives, init / bootstrap. the name dates back to an ancient StarOffice that also drew a desktop |
| sw/ | Writer |
| sc/ | Calc |
| sd/ | Draw / Impress |
There are several other libraries that are helpful from a graphical perspective:
| Module | Description |
|---|---|
| basegfx/ | algorithms and data-types for graphics as used in the canvas |
| canvas/ | new (UNO) canvas rendering model with various backends |
| cppcanvas/ | C++ helper classes for using the UNO canvas |
| drawinglayer/ | View code to render drawable objects and break them down into primitives we can render more easily. |
Rules for #include Directives (C/C++)
Use the "..." form if and only if the included file is found next to the
including file. Otherwise, use the <...> form. (For further details, see the
mail Re: C[++]: Normalizing include syntax ("" vs
<>).)
The UNO API include files should consistently use double quotes, for the benefit of external users of this API.
loplugin:includeform (compilerplugins/clang/includeform.cxx) enforces these rules.
Finding Out More
Beyond this, you can read the README.md files, send us patches, ask
on the mailing list libreoffice@lists.freedesktop.org (no subscription
required) or poke people on IRC #libreoffice-dev on irc.libera.chat -
we're a friendly and generally helpful mob. We know the code can be
hard to get into at first, and so there are no silly questions.
SAST Tools
PVS-Studio - static analyzer for C, C++, C#, and Java code.