Bug Summary

File:home/maarten/src/libreoffice/core/vcl/source/window/window.cxx
Warning:line 2787, column 14
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name window.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/glm -isystem /usr/include/glib-2.0 -isystem /usr/lib64/glib-2.0/include -isystem /usr/include/libmount -isystem /usr/include/blkid -isystem /usr/include/cairo -isystem /usr/include/glib-2.0 -isystem /usr/lib64/glib-2.0/include -isystem /usr/include/pixman-1 -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -isystem /usr/include/libxml2 -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -isystem /usr/include/dbus-1.0 -isystem /usr/lib64/dbus-1.0/include -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D VCL_DLLIMPLEMENTATION -D DLLIMPLEMENTATION_UITEST -D CUI_DLL_NAME="libcuilo.so" -D DESKTOP_DETECTOR_DLL_NAME="libdesktop_detectorlo.so" -D TK_DLL_NAME="libtklo.so" -D SYSTEM_ZLIB -D GLM_FORCE_CTOR_INIT -D SK_USER_CONFIG_HEADER=</home/maarten/src/libreoffice/core/config_host/config_skia.h> -D SKIA_DLL -D ENABLE_CUPS -D HAVE_VALGRIND_HEADERS -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/epoxy/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/core -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/effects -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/gpu -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/config -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/ports -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/third_party/vulkan -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/tools/gpu -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia -I /home/maarten/src/libreoffice/core/external/skia/inc/ -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/mdds/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/lcms2/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/harfbuzz/src -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/graphite/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium/public -D COMPONENT_BUILD -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/libpng -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/libjpeg-turbo -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/vcl/inc -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libxml2 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/vcl/source/window/window.cxx

/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <rtl/strbuf.hxx>
21#include <sal/log.hxx>
22
23#include <sal/types.h>
24#include <vcl/salgtype.hxx>
25#include <vcl/event.hxx>
26#include <vcl/help.hxx>
27#include <vcl/cursor.hxx>
28#include <vcl/svapp.hxx>
29#include <vcl/transfer.hxx>
30#include <vcl/vclevent.hxx>
31#include <vcl/window.hxx>
32#include <vcl/syswin.hxx>
33#include <vcl/dockwin.hxx>
34#include <vcl/wall.hxx>
35#include <vcl/toolkit/fixed.hxx>
36#include <vcl/taskpanelist.hxx>
37#include <vcl/toolkit/unowrap.hxx>
38#include <vcl/lazydelete.hxx>
39#include <vcl/virdev.hxx>
40#include <vcl/settings.hxx>
41#include <vcl/sysdata.hxx>
42#include <vcl/ptrstyle.hxx>
43#include <vcl/IDialogRenderable.hxx>
44
45#include <vcl/uitest/uiobject.hxx>
46
47#include <salframe.hxx>
48#include <salobj.hxx>
49#include <salinst.hxx>
50#include <salgdi.hxx>
51#include <svdata.hxx>
52#include <window.h>
53#include <toolbox.h>
54#include <outdev.h>
55#include <brdwin.hxx>
56#include <helpwin.hxx>
57
58#include <com/sun/star/accessibility/AccessibleRelation.hpp>
59#include <com/sun/star/accessibility/XAccessible.hpp>
60#include <com/sun/star/awt/XWindowPeer.hpp>
61#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
62#include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
63#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
64#include <com/sun/star/rendering/CanvasFactory.hpp>
65#include <com/sun/star/rendering/XSpriteCanvas.hpp>
66#include <comphelper/lok.hxx>
67#include <comphelper/processfactory.hxx>
68#include <unotools/configmgr.hxx>
69#include <osl/diagnose.h>
70#include <tools/debug.hxx>
71#include <tools/json_writer.hxx>
72#include <boost/property_tree/ptree.hpp>
73
74#include <cassert>
75#include <typeinfo>
76
77#ifdef _WIN32 // see #140456#
78#include <win/salframe.h>
79#endif
80
81
82using namespace ::com::sun::star::uno;
83using namespace ::com::sun::star::lang;
84using namespace ::com::sun::star::datatransfer::clipboard;
85using namespace ::com::sun::star::datatransfer::dnd;
86
87namespace vcl {
88
89Window::Window( WindowType nType )
90 : OutputDevice(OUTDEV_WINDOW)
91 , mpWindowImpl(new WindowImpl( nType ))
92{
93 // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
94 mbEnableRTL = AllSettings::GetLayoutRTL();
95}
96
97Window::Window( vcl::Window* pParent, WinBits nStyle )
98 : OutputDevice(OUTDEV_WINDOW)
99 , mpWindowImpl(new WindowImpl( WindowType::WINDOW ))
100{
101 // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
102 mbEnableRTL = AllSettings::GetLayoutRTL();
103
104 ImplInit( pParent, nStyle, nullptr );
105}
106
107#if OSL_DEBUG_LEVEL1 > 0
108namespace
109{
110 OString lcl_createWindowInfo(const vcl::Window* pWindow)
111 {
112 // skip border windows, they do not carry information that
113 // would help with diagnosing the problem
114 const vcl::Window* pTempWin( pWindow );
115 while ( pTempWin && pTempWin->GetType() == WindowType::BORDERWINDOW ) {
116 pTempWin = pTempWin->GetWindow( GetWindowType::FirstChild );
117 }
118 // check if pTempWin is not null, otherwise use the
119 // original address
120 if ( pTempWin ) {
121 pWindow = pTempWin;
122 }
123
124 OStringBuffer aErrorString;
125 aErrorString.append(' ');
126 aErrorString.append(typeid( *pWindow ).name());
127 aErrorString.append("(");
128 aErrorString.append(
129 OUStringToOString(
130 pWindow->GetText(),
131 RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76))
132 )
133 );
134 aErrorString.append(")");
135 return aErrorString.makeStringAndClear();
136 }
137}
138#endif
139
140bool Window::IsDisposed() const
141{
142 return !mpWindowImpl;
143}
144
145void Window::dispose()
146{
147 assert( mpWindowImpl )(static_cast <bool> (mpWindowImpl) ? void (0) : __assert_fail
("mpWindowImpl", "/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
, 147, __extension__ __PRETTY_FUNCTION__))
;
148 assert( !mpWindowImpl->mbInDispose )(static_cast <bool> (!mpWindowImpl->mbInDispose) ? void
(0) : __assert_fail ("!mpWindowImpl->mbInDispose", "/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
, 148, __extension__ __PRETTY_FUNCTION__))
; // should only be called from disposeOnce()
149 assert( (!mpWindowImpl->mpParent ||(static_cast <bool> ((!mpWindowImpl->mpParent || !mpWindowImpl
->mpParent->IsDisposed()) && "vcl::Window child should have its parent disposed first"
) ? void (0) : __assert_fail ("(!mpWindowImpl->mpParent || !mpWindowImpl->mpParent->IsDisposed()) && \"vcl::Window child should have its parent disposed first\""
, "/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
, 151, __extension__ __PRETTY_FUNCTION__))
150 !mpWindowImpl->mpParent->IsDisposed()) &&(static_cast <bool> ((!mpWindowImpl->mpParent || !mpWindowImpl
->mpParent->IsDisposed()) && "vcl::Window child should have its parent disposed first"
) ? void (0) : __assert_fail ("(!mpWindowImpl->mpParent || !mpWindowImpl->mpParent->IsDisposed()) && \"vcl::Window child should have its parent disposed first\""
, "/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
, 151, __extension__ __PRETTY_FUNCTION__))
151 "vcl::Window child should have its parent disposed first" )(static_cast <bool> ((!mpWindowImpl->mpParent || !mpWindowImpl
->mpParent->IsDisposed()) && "vcl::Window child should have its parent disposed first"
) ? void (0) : __assert_fail ("(!mpWindowImpl->mpParent || !mpWindowImpl->mpParent->IsDisposed()) && \"vcl::Window child should have its parent disposed first\""
, "/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
, 151, __extension__ __PRETTY_FUNCTION__))
;
152
153 // remove Key and Mouse events issued by Application::PostKey/MouseEvent
154 Application::RemoveMouseAndKeyEvents( this );
155
156 // Dispose of the canvas implementation (which, currently, has an
157 // own wrapper window as a child to this one.
158 Reference< css::rendering::XCanvas > xCanvas( mpWindowImpl->mxCanvas );
159 if( xCanvas.is() )
160 {
161 Reference < XComponent > xCanvasComponent( xCanvas, UNO_QUERY );
162 if( xCanvasComponent.is() )
163 xCanvasComponent->dispose();
164 }
165
166 mpWindowImpl->mbInDispose = true;
167
168 CallEventListeners( VclEventId::ObjectDying );
169
170 // do not send child events for frames that were registered as native frames
171 if( !ImplIsAccessibleNativeFrame() && mpWindowImpl->mbReallyVisible )
172 if ( ImplIsAccessibleCandidate() && GetAccessibleParentWindow() )
173 GetAccessibleParentWindow()->CallEventListeners( VclEventId::WindowChildDestroyed, this );
174
175 // remove associated data structures from dockingmanager
176 ImplGetDockingManager()->RemoveWindow( this );
177
178 // remove ownerdraw decorated windows from list in the top-most frame window
179 if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
180 {
181 ::std::vector< VclPtr<vcl::Window> >& rList = ImplGetOwnerDrawList();
182 auto p = ::std::find( rList.begin(), rList.end(), VclPtr<vcl::Window>(this) );
183 if( p != rList.end() )
184 rList.erase( p );
185 }
186
187 // shutdown drag and drop
188 Reference < XComponent > xDnDComponent( mpWindowImpl->mxDNDListenerContainer, UNO_QUERY );
189
190 if( xDnDComponent.is() )
191 xDnDComponent->dispose();
192
193 if( mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData )
194 {
195 try
196 {
197 // deregister drop target listener
198 if( mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
199 {
200 Reference< XDragGestureRecognizer > xDragGestureRecognizer(mpWindowImpl->mpFrameData->mxDragSource, UNO_QUERY);
201 if( xDragGestureRecognizer.is() )
202 {
203 xDragGestureRecognizer->removeDragGestureListener(
204 Reference< XDragGestureListener > (mpWindowImpl->mpFrameData->mxDropTargetListener, UNO_QUERY));
205 }
206
207 mpWindowImpl->mpFrameData->mxDropTarget->removeDropTargetListener( mpWindowImpl->mpFrameData->mxDropTargetListener );
208 mpWindowImpl->mpFrameData->mxDropTargetListener.clear();
209 }
210
211 // shutdown drag and drop for this frame window
212 Reference< XComponent > xComponent( mpWindowImpl->mpFrameData->mxDropTarget, UNO_QUERY );
213
214 // DNDEventDispatcher does not hold a reference of the DropTarget,
215 // so it's ok if it does not support XComponent
216 if( xComponent.is() )
217 xComponent->dispose();
218 }
219 catch (const Exception&)
220 {
221 // can be safely ignored here.
222 }
223 }
224
225 UnoWrapperBase* pWrapper = UnoWrapperBase::GetUnoWrapper( false );
226 if ( pWrapper )
227 pWrapper->WindowDestroyed( this );
228
229 // MT: Must be called after WindowDestroyed!
230 // Otherwise, if the accessible is a VCLXWindow, it will try to destroy this window again!
231 // But accessibility implementations from applications need this dispose.
232 if ( mpWindowImpl->mxAccessible.is() )
233 {
234 Reference< XComponent> xC( mpWindowImpl->mxAccessible, UNO_QUERY );
235 if ( xC.is() )
236 xC->dispose();
237 }
238
239 ImplSVData* pSVData = ImplGetSVData();
240
241 if ( ImplGetSVHelpData().mpHelpWin && (ImplGetSVHelpData().mpHelpWin->GetParent() == this) )
242 ImplDestroyHelpWindow( true );
243
244 SAL_WARN_IF(pSVData->mpWinData->mpTrackWin.get() == this, "vcl.window",do { if (true && (pSVData->mpWinData->mpTrackWin
.get() == this)) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Window::~Window(): Window is in TrackingMode"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "245" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window::~Window(): Window is in TrackingMode"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Window::~Window(): Window is in TrackingMode"; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"),
("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "245" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Window::~Window(): Window is in TrackingMode") ==
1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "245" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window::~Window(): Window is in TrackingMode"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Window::~Window(): Window is in TrackingMode"; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"),
("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "245" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
245 "Window::~Window(): Window is in TrackingMode")do { if (true && (pSVData->mpWinData->mpTrackWin
.get() == this)) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Window::~Window(): Window is in TrackingMode"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "245" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window::~Window(): Window is in TrackingMode"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Window::~Window(): Window is in TrackingMode"; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"),
("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "245" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Window::~Window(): Window is in TrackingMode") ==
1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "245" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window::~Window(): Window is in TrackingMode"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Window::~Window(): Window is in TrackingMode"; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"),
("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "245" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
246 SAL_WARN_IF(IsMouseCaptured(), "vcl.window",do { if (true && (IsMouseCaptured())) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_WARN, "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "Window::~Window(): Window has the mouse captured"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "247" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window::~Window(): Window has the mouse captured"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Window::~Window(): Window has the mouse captured";
::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "247" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Window::~Window(): Window has the mouse captured"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "247" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window::~Window(): Window has the mouse captured"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Window::~Window(): Window has the mouse captured";
::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "247" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
247 "Window::~Window(): Window has the mouse captured")do { if (true && (IsMouseCaptured())) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_WARN, "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "Window::~Window(): Window has the mouse captured"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "247" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window::~Window(): Window has the mouse captured"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Window::~Window(): Window has the mouse captured";
::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "247" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Window::~Window(): Window has the mouse captured"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "247" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window::~Window(): Window has the mouse captured"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Window::~Window(): Window has the mouse captured";
::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "247" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
248
249 // due to old compatibility
250 if (pSVData->mpWinData->mpTrackWin == this)
251 EndTracking();
252 if (IsMouseCaptured())
253 ReleaseMouse();
254
255#if OSL_DEBUG_LEVEL1 > 0
256 // always perform these tests in debug builds
257 {
258 OStringBuffer aErrorStr;
259 bool bError = false;
260 vcl::Window* pTempWin;
261
262 if ( mpWindowImpl->mpFirstChild )
263 {
264 OStringBuffer aTempStr("Window (");
265 aTempStr.append(lcl_createWindowInfo(this));
266 aTempStr.append(") with live children destroyed: ");
267 pTempWin = mpWindowImpl->mpFirstChild;
268 while ( pTempWin )
269 {
270 aTempStr.append(lcl_createWindowInfo(pTempWin));
271 pTempWin = pTempWin->mpWindowImpl->mpNext;
272 }
273 OSL_FAIL( aTempStr.getStr() )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "273" ": "), "%s", aTempStr.getStr()); } } while (false)
;
274 Application::Abort(OStringToOUString(aTempStr.makeStringAndClear(), RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)))); // abort in debug builds, this must be fixed!
275 }
276
277 if (mpWindowImpl->mpFrameData != nullptr)
278 {
279 pTempWin = mpWindowImpl->mpFrameData->mpFirstOverlap;
280 while ( pTempWin )
281 {
282 if ( ImplIsRealParentPath( pTempWin ) )
283 {
284 bError = true;
285 aErrorStr.append(lcl_createWindowInfo(pTempWin));
286 }
287 pTempWin = pTempWin->mpWindowImpl->mpNextOverlap;
288 }
289 if ( bError )
290 {
291 OStringBuffer aTempStr;
292 aTempStr.append("Window (");
293 aTempStr.append(lcl_createWindowInfo(this));
294 aTempStr.append(") with live SystemWindows destroyed: ");
295 aTempStr.append(aErrorStr.toString());
296 OSL_FAIL(aTempStr.getStr())do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "296" ": "), "%s", aTempStr.getStr()); } } while (false)
;
297 // abort in debug builds, must be fixed!
298 Application::Abort(OStringToOUString(
299 aTempStr.makeStringAndClear(), RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76))));
300 }
301 }
302
303 bError = false;
304 pTempWin = pSVData->maFrameData.mpFirstFrame;
305 while ( pTempWin )
306 {
307 if ( ImplIsRealParentPath( pTempWin ) )
308 {
309 bError = true;
310 aErrorStr.append(lcl_createWindowInfo(pTempWin));
311 }
312 pTempWin = pTempWin->mpWindowImpl->mpFrameData->mpNextFrame;
313 }
314 if ( bError )
315 {
316 OStringBuffer aTempStr( "Window (" );
317 aTempStr.append(lcl_createWindowInfo(this));
318 aTempStr.append(") with live SystemWindows destroyed: ");
319 aTempStr.append(aErrorStr.toString());
320 OSL_FAIL( aTempStr.getStr() )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "320" ": "), "%s", aTempStr.getStr()); } } while (false)
;
321 Application::Abort(OStringToOUString(aTempStr.makeStringAndClear(), RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)))); // abort in debug builds, this must be fixed!
322 }
323
324 if ( mpWindowImpl->mpFirstOverlap )
325 {
326 OStringBuffer aTempStr("Window (");
327 aTempStr.append(lcl_createWindowInfo(this));
328 aTempStr.append(") with live SystemWindows destroyed: ");
329 pTempWin = mpWindowImpl->mpFirstOverlap;
330 while ( pTempWin )
331 {
332 aTempStr.append(lcl_createWindowInfo(pTempWin));
333 pTempWin = pTempWin->mpWindowImpl->mpNext;
334 }
335 OSL_FAIL( aTempStr.getStr() )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "335" ": "), "%s", aTempStr.getStr()); } } while (false)
;
336 Application::Abort(OStringToOUString(aTempStr.makeStringAndClear(), RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)))); // abort in debug builds, this must be fixed!
337 }
338
339 vcl::Window* pMyParent = GetParent();
340 SystemWindow* pMySysWin = nullptr;
341
342 while ( pMyParent )
343 {
344 if ( pMyParent->IsSystemWindow() )
345 {
346 pMySysWin = dynamic_cast<SystemWindow *>(pMyParent);
347 }
348 pMyParent = pMyParent->GetParent();
349 }
350 if ( pMySysWin && pMySysWin->ImplIsInTaskPaneList( this ) )
351 {
352 OStringBuffer aTempStr("Window (");
353 aTempStr.append(lcl_createWindowInfo(this));
354 aTempStr.append(") still in TaskPanelList!");
355 OSL_FAIL( aTempStr.getStr() )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "355" ": "), "%s", aTempStr.getStr()); } } while (false)
;
356 Application::Abort(OStringToOUString(aTempStr.makeStringAndClear(), RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)))); // abort in debug builds, this must be fixed!
357 }
358 }
359#endif
360
361 if( mpWindowImpl->mbIsInTaskPaneList )
362 {
363 vcl::Window* pMyParent = GetParent();
364 SystemWindow* pMySysWin = nullptr;
365
366 while ( pMyParent )
367 {
368 if ( pMyParent->IsSystemWindow() )
369 {
370 pMySysWin = dynamic_cast<SystemWindow *>(pMyParent);
371 }
372 pMyParent = pMyParent->GetParent();
373 }
374 if ( pMySysWin && pMySysWin->ImplIsInTaskPaneList( this ) )
375 {
376 pMySysWin->GetTaskPaneList()->RemoveWindow( this );
377 }
378 else
379 {
380 SAL_WARN( "vcl", "Window (" << GetText() << ") not found in TaskPanelList")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Window (" << GetText() << ") not found in TaskPanelList"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "380" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window (" << GetText() <<
") not found in TaskPanelList"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "Window (" <<
GetText() << ") not found in TaskPanelList"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "380" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Window (" << GetText() << ") not found in TaskPanelList"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "380" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window (" << GetText() <<
") not found in TaskPanelList"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "Window (" <<
GetText() << ") not found in TaskPanelList"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "380" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
381 }
382 }
383
384 // remove from size-group if necessary
385 remove_from_all_size_groups();
386
387 // clear mnemonic labels
388 std::vector<VclPtr<FixedText> > aMnemonicLabels(list_mnemonic_labels());
389 for (auto const& mnemonicLabel : aMnemonicLabels)
390 {
391 remove_mnemonic_label(mnemonicLabel);
392 }
393
394 // hide window in order to trigger the Paint-Handling
395 Hide();
396
397 // EndExtTextInputMode
398 if (pSVData->mpWinData->mpExtTextInputWin == this)
399 {
400 EndExtTextInput();
401 if (pSVData->mpWinData->mpExtTextInputWin == this)
402 pSVData->mpWinData->mpExtTextInputWin = nullptr;
403 }
404
405 // check if the focus window is our child
406 bool bHasFocusedChild = false;
407 if (pSVData->mpWinData->mpFocusWin && ImplIsRealParentPath(pSVData->mpWinData->mpFocusWin))
408 {
409 // #122232#, this must not happen and is an application bug ! but we try some cleanup to hopefully avoid crashes, see below
410 bHasFocusedChild = true;
411#if OSL_DEBUG_LEVEL1 > 0
412 OUString aTempStr = "Window (" + GetText() +
413 ") with focused child window destroyed ! THIS WILL LEAD TO CRASHES AND MUST BE FIXED !";
414 SAL_WARN( "vcl", aTempStr )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << aTempStr) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "414" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << aTempStr), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << aTempStr; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "414" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << aTempStr) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "414" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << aTempStr), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << aTempStr; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "414" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
415 Application::Abort(aTempStr); // abort in debug build version, this must be fixed!
416#endif
417 }
418
419 // if we get focus pass focus to another window
420 vcl::Window* pOverlapWindow = ImplGetFirstOverlapWindow();
421 if (pSVData->mpWinData->mpFocusWin == this
422 || bHasFocusedChild) // #122232#, see above, try some cleanup
423 {
424 if ( mpWindowImpl->mbFrame )
425 {
426 pSVData->mpWinData->mpFocusWin = nullptr;
427 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = nullptr;
428 }
429 else
430 {
431 vcl::Window* pParent = GetParent();
432 vcl::Window* pBorderWindow = mpWindowImpl->mpBorderWindow;
433 // when windows overlap, give focus to the parent
434 // of the next FrameWindow
435 if ( pBorderWindow )
436 {
437 if ( pBorderWindow->ImplIsOverlapWindow() )
438 pParent = pBorderWindow->mpWindowImpl->mpOverlapWindow;
439 }
440 else if ( ImplIsOverlapWindow() )
441 pParent = mpWindowImpl->mpOverlapWindow;
442
443 if ( pParent && pParent->IsEnabled() && pParent->IsInputEnabled() && ! pParent->IsInModalMode() )
444 pParent->GrabFocus();
445 else
446 mpWindowImpl->mpFrameWindow->GrabFocus();
447
448 // If the focus was set back to 'this' set it to nothing
449 if (pSVData->mpWinData->mpFocusWin == this)
450 {
451 pSVData->mpWinData->mpFocusWin = nullptr;
452 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = nullptr;
453 }
454 }
455 }
456
457 if ( pOverlapWindow != nullptr &&
458 pOverlapWindow->mpWindowImpl->mpLastFocusWindow == this )
459 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = nullptr;
460
461 // reset hint for DefModalDialogParent
462 if( pSVData->maFrameData.mpActiveApplicationFrame == this )
463 pSVData->maFrameData.mpActiveApplicationFrame = nullptr;
464
465 // reset hint of what was the last wheeled window
466 if (pSVData->mpWinData->mpLastWheelWindow == this)
467 pSVData->mpWinData->mpLastWheelWindow = nullptr;
468
469 // reset marked windows
470 if ( mpWindowImpl->mpFrameData != nullptr )
471 {
472 if ( mpWindowImpl->mpFrameData->mpFocusWin == this )
473 mpWindowImpl->mpFrameData->mpFocusWin = nullptr;
474 if ( mpWindowImpl->mpFrameData->mpMouseMoveWin == this )
475 mpWindowImpl->mpFrameData->mpMouseMoveWin = nullptr;
476 if ( mpWindowImpl->mpFrameData->mpMouseDownWin == this )
477 mpWindowImpl->mpFrameData->mpMouseDownWin = nullptr;
478 }
479
480 // reset Deactivate-Window
481 if (pSVData->mpWinData->mpLastDeacWin == this)
482 pSVData->mpWinData->mpLastDeacWin = nullptr;
483
484 if ( mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData )
485 {
486 if ( mpWindowImpl->mpFrameData->mnFocusId )
487 Application::RemoveUserEvent( mpWindowImpl->mpFrameData->mnFocusId );
488 mpWindowImpl->mpFrameData->mnFocusId = nullptr;
489 if ( mpWindowImpl->mpFrameData->mnMouseMoveId )
490 Application::RemoveUserEvent( mpWindowImpl->mpFrameData->mnMouseMoveId );
491 mpWindowImpl->mpFrameData->mnMouseMoveId = nullptr;
492 }
493
494 // release SalGraphics
495 OutputDevice *pOutDev = GetOutDev();
496 pOutDev->ReleaseGraphics();
497
498 // remove window from the lists
499 ImplRemoveWindow( true );
500
501 // de-register as "top window child" at our parent, if necessary
502 if ( mpWindowImpl->mbFrame )
503 {
504 bool bIsTopWindow
505 = mpWindowImpl->mpWinData && (mpWindowImpl->mpWinData->mnIsTopWindow == 1);
506 if ( mpWindowImpl->mpRealParent && bIsTopWindow )
507 {
508 ImplWinData* pParentWinData = mpWindowImpl->mpRealParent->ImplGetWinData();
509
510 auto myPos = ::std::find( pParentWinData->maTopWindowChildren.begin(),
511 pParentWinData->maTopWindowChildren.end(), VclPtr<vcl::Window>(this) );
512 SAL_WARN_IF( myPos == pParentWinData->maTopWindowChildren.end(), "vcl.window", "Window::~Window: inconsistency in top window chain!" )do { if (true && (myPos == pParentWinData->maTopWindowChildren
.end())) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Window::~Window: inconsistency in top window chain!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "512" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window::~Window: inconsistency in top window chain!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Window::~Window: inconsistency in top window chain!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "512" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Window::~Window: inconsistency in top window chain!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "512" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window::~Window: inconsistency in top window chain!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Window::~Window: inconsistency in top window chain!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "512" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
513 if ( myPos != pParentWinData->maTopWindowChildren.end() )
514 pParentWinData->maTopWindowChildren.erase( myPos );
515 }
516 }
517
518 delete mpWindowImpl->mpWinData;
519 mpWindowImpl->mpWinData = nullptr;
520
521 // remove BorderWindow or Frame window data
522 mpWindowImpl->mpBorderWindow.disposeAndClear();
523 if ( mpWindowImpl->mbFrame )
524 {
525 if ( pSVData->maFrameData.mpFirstFrame == this )
526 pSVData->maFrameData.mpFirstFrame = mpWindowImpl->mpFrameData->mpNextFrame;
527 else
528 {
529 sal_Int32 nWindows = 0;
530 vcl::Window* pSysWin = pSVData->maFrameData.mpFirstFrame;
531 while ( pSysWin && pSysWin->mpWindowImpl->mpFrameData->mpNextFrame.get() != this )
532 {
533 pSysWin = pSysWin->mpWindowImpl->mpFrameData->mpNextFrame;
534 nWindows++;
535 }
536
537 if ( pSysWin )
538 {
539 assert (mpWindowImpl->mpFrameData->mpNextFrame.get() != pSysWin)(static_cast <bool> (mpWindowImpl->mpFrameData->mpNextFrame
.get() != pSysWin) ? void (0) : __assert_fail ("mpWindowImpl->mpFrameData->mpNextFrame.get() != pSysWin"
, "/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
, 539, __extension__ __PRETTY_FUNCTION__))
;
540 pSysWin->mpWindowImpl->mpFrameData->mpNextFrame = mpWindowImpl->mpFrameData->mpNextFrame;
541 }
542 else // if it is not in the list, we can't remove it.
543 SAL_WARN("vcl.window", "Window " << this << " marked as frame window, "do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Window " << this
<< " marked as frame window, " "is missing from list of "
<< nWindows << " frames") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "544" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window " << this << " marked as frame window, "
"is missing from list of " << nWindows << " frames"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Window " << this << " marked as frame window, "
"is missing from list of " << nWindows << " frames"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "544" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Window " << this << " marked as frame window, "
"is missing from list of " << nWindows << " frames"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "544" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window " << this << " marked as frame window, "
"is missing from list of " << nWindows << " frames"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Window " << this << " marked as frame window, "
"is missing from list of " << nWindows << " frames"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "544" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
544 "is missing from list of " << nWindows << " frames")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Window " << this
<< " marked as frame window, " "is missing from list of "
<< nWindows << " frames") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "544" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window " << this << " marked as frame window, "
"is missing from list of " << nWindows << " frames"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Window " << this << " marked as frame window, "
"is missing from list of " << nWindows << " frames"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "544" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Window " << this << " marked as frame window, "
"is missing from list of " << nWindows << " frames"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "544" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window " << this << " marked as frame window, "
"is missing from list of " << nWindows << " frames"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Window " << this << " marked as frame window, "
"is missing from list of " << nWindows << " frames"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "544" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
545 }
546 if (mpWindowImpl->mpFrame) // otherwise exception during init
547 {
548 mpWindowImpl->mpFrame->SetCallback( nullptr, nullptr );
549 pSVData->mpDefInst->DestroyFrame( mpWindowImpl->mpFrame );
550 }
551 assert (mpWindowImpl->mpFrameData->mnFocusId == nullptr)(static_cast <bool> (mpWindowImpl->mpFrameData->mnFocusId
== nullptr) ? void (0) : __assert_fail ("mpWindowImpl->mpFrameData->mnFocusId == nullptr"
, "/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
, 551, __extension__ __PRETTY_FUNCTION__))
;
552 assert (mpWindowImpl->mpFrameData->mnMouseMoveId == nullptr)(static_cast <bool> (mpWindowImpl->mpFrameData->mnMouseMoveId
== nullptr) ? void (0) : __assert_fail ("mpWindowImpl->mpFrameData->mnMouseMoveId == nullptr"
, "/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
, 552, __extension__ __PRETTY_FUNCTION__))
;
553
554 mpWindowImpl->mpFrameData->mpBuffer.disposeAndClear();
555 delete mpWindowImpl->mpFrameData;
556 mpWindowImpl->mpFrameData = nullptr;
557 }
558
559 // should be the last statements
560 mpWindowImpl.reset();
561
562 OutputDevice::dispose();
563}
564
565Window::~Window()
566{
567 disposeOnce();
568}
569
570// We will eventually being removing the inheritance of OutputDevice
571// from Window. It will be replaced with a transient relationship such
572// that the OutputDevice is only live for the scope of the Paint method.
573// In the meantime this can help move us towards a Window use an
574// OutputDevice, not being one.
575
576::OutputDevice const* Window::GetOutDev() const
577{
578 return this;
579}
580
581::OutputDevice* Window::GetOutDev()
582{
583 return this;
584}
585
586Color Window::GetBackgroundColor() const
587{
588 return GetDisplayBackground().GetColor();
589}
590
591} /* namespace vcl */
592
593WindowImpl::WindowImpl( WindowType nType )
594{
595 maZoom = Fraction( 1, 1 );
596 maWinRegion = vcl::Region(true);
597 maWinClipRegion = vcl::Region(true);
598 mpWinData = nullptr; // Extra Window Data, that we don't need for all windows
599 mpFrameData = nullptr; // Frame Data
600 mpFrame = nullptr; // Pointer to frame window
601 mpSysObj = nullptr;
602 mpFrameWindow = nullptr; // window to top level parent (same as frame window)
603 mpOverlapWindow = nullptr; // first overlap parent
604 mpBorderWindow = nullptr; // Border-Window
605 mpClientWindow = nullptr; // Client-Window of a FrameWindow
606 mpParent = nullptr; // parent (incl. BorderWindow)
607 mpRealParent = nullptr; // real parent (excl. BorderWindow)
608 mpFirstChild = nullptr; // first child window
609 mpLastChild = nullptr; // last child window
610 mpFirstOverlap = nullptr; // first overlap window (only set in overlap windows)
611 mpLastOverlap = nullptr; // last overlap window (only set in overlap windows)
612 mpPrev = nullptr; // prev window
613 mpNext = nullptr; // next window
614 mpNextOverlap = nullptr; // next overlap window of frame
615 mpLastFocusWindow = nullptr; // window for focus restore
616 mpDlgCtrlDownWindow = nullptr; // window for dialog control
617 mnEventListenersIteratingCount = 0;
618 mnChildEventListenersIteratingCount = 0;
619 mpCursor = nullptr; // cursor
620 maPointer = PointerStyle::Arrow;
621 mpVCLXWindow = nullptr;
622 mpAccessibleInfos = nullptr;
623 maControlForeground = COL_TRANSPARENT; // no foreground set
624 maControlBackground = COL_TRANSPARENT; // no background set
625 mnLeftBorder = 0; // left border
626 mnTopBorder = 0; // top border
627 mnRightBorder = 0; // right border
628 mnBottomBorder = 0; // bottom border
629 mnWidthRequest = -1; // width request
630 mnHeightRequest = -1; // height request
631 mnOptimalWidthCache = -1; // optimal width cache
632 mnOptimalHeightCache = -1; // optimal height cache
633 mnX = 0; // X-Position to Parent
634 mnY = 0; // Y-Position to Parent
635 mnAbsScreenX = 0; // absolute X-position on screen, used for RTL window positioning
636 mpChildClipRegion = nullptr; // Child-Clip-Region when ClipChildren
637 mpPaintRegion = nullptr; // Paint-ClipRegion
638 mnStyle = 0; // style (init in ImplInitWindow)
639 mnPrevStyle = 0; // prevstyle (set in SetStyle)
640 mnExtendedStyle = WindowExtendedStyle::NONE; // extended style (init in ImplInitWindow)
641 mnType = nType; // type
642 mnGetFocusFlags = GetFocusFlags::NONE; // Flags for GetFocus()-Call
643 mnWaitCount = 0; // Wait-Count (>1 == "wait" mouse pointer)
644 mnPaintFlags = ImplPaintFlags::NONE; // Flags for ImplCallPaint
645 mnParentClipMode = ParentClipMode::NONE; // Flags for Parent-ClipChildren-Mode
646 mnActivateMode = ActivateModeFlags::NONE; // Will be converted in System/Overlap-Windows
647 mnDlgCtrlFlags = DialogControlFlags::NONE; // DialogControl-Flags
648 meAlwaysInputMode = AlwaysInputNone; // AlwaysEnableInput not called
649 meHalign = VclAlign::Fill;
650 meValign = VclAlign::Fill;
651 mePackType = VclPackType::Start;
652 mnPadding = 0;
653 mnGridHeight = 1;
654 mnGridLeftAttach = -1;
655 mnGridTopAttach = -1;
656 mnGridWidth = 1;
657 mnBorderWidth = 0;
658 mnMarginLeft = 0;
659 mnMarginRight = 0;
660 mnMarginTop = 0;
661 mnMarginBottom = 0;
662 mbFrame = false; // true: Window is a frame window
663 mbBorderWin = false; // true: Window is a border window
664 mbOverlapWin = false; // true: Window is an overlap window
665 mbSysWin = false; // true: SystemWindow is the base class
666 mbDialog = false; // true: Dialog is the base class
667 mbDockWin = false; // true: DockingWindow is the base class
668 mbFloatWin = false; // true: FloatingWindow is the base class
669 mbPushButton = false; // true: PushButton is the base class
670 mbToolBox = false; // true: ToolBox is the base class
671 mbMenuFloatingWindow = false; // true: MenuFloatingWindow is the base class
672 mbToolbarFloatingWindow = false; // true: ImplPopupFloatWin is the base class, used for subtoolbars
673 mbSplitter = false; // true: Splitter is the base class
674 mbVisible = false; // true: Show( true ) called
675 mbOverlapVisible = false; // true: Hide called for visible window from ImplHideAllOverlapWindow()
676 mbDisabled = false; // true: Enable( false ) called
677 mbInputDisabled = false; // true: EnableInput( false ) called
678 mbNoUpdate = false; // true: SetUpdateMode( false ) called
679 mbNoParentUpdate = false; // true: SetParentUpdateMode( false ) called
680 mbActive = false; // true: Window Active
681 mbReallyVisible = false; // true: this and all parents to an overlapped window are visible
682 mbReallyShown = false; // true: this and all parents to an overlapped window are shown
683 mbInInitShow = false; // true: we are in InitShow
684 mbChildPtrOverwrite = false; // true: PointerStyle overwrites Child-Pointer
685 mbNoPtrVisible = false; // true: ShowPointer( false ) called
686 mbPaintFrame = false; // true: Paint is visible, but not painted
687 mbInPaint = false; // true: Inside PaintHdl
688 mbMouseButtonDown = false; // true: BaseMouseButtonDown called
689 mbMouseButtonUp = false; // true: BaseMouseButtonUp called
690 mbKeyInput = false; // true: BaseKeyInput called
691 mbKeyUp = false; // true: BaseKeyUp called
692 mbCommand = false; // true: BaseCommand called
693 mbDefPos = true; // true: Position is not Set
694 mbDefSize = true; // true: Size is not Set
695 mbCallMove = true; // true: Move must be called by Show
696 mbCallResize = true; // true: Resize must be called by Show
697 mbWaitSystemResize = true; // true: Wait for System-Resize
698 mbInitWinClipRegion = true; // true: Calc Window Clip Region
699 mbInitChildRegion = false; // true: InitChildClipRegion
700 mbWinRegion = false; // true: Window Region
701 mbClipChildren = false; // true: Child-window should be clipped
702 mbClipSiblings = false; // true: Adjacent Child-window should be clipped
703 mbChildTransparent = false; // true: Child-windows are allowed to switch to transparent (incl. Parent-CLIPCHILDREN)
704 mbPaintTransparent = false; // true: Paints should be executed on the Parent
705 mbMouseTransparent = false; // true: Window is transparent for Mouse
706 mbDlgCtrlStart = false; // true: From here on own Dialog-Control
707 mbFocusVisible = false; // true: Focus Visible
708 mbUseNativeFocus = false;
709 mbNativeFocusVisible = false; // true: native Focus Visible
710 mbInShowFocus = false; // prevent recursion
711 mbInHideFocus = false; // prevent recursion
712 mbTrackVisible = false; // true: Tracking Visible
713 mbControlForeground = false; // true: Foreground-Property set
714 mbControlBackground = false; // true: Background-Property set
715 mbAlwaysOnTop = false; // true: always visible for all others windows
716 mbCompoundControl = false; // true: Composite Control => Listener...
717 mbCompoundControlHasFocus = false; // true: Composite Control has focus somewhere
718 mbPaintDisabled = false; // true: Paint should not be executed
719 mbAllResize = false; // true: Also sent ResizeEvents with 0,0
720 mbInDispose = false; // true: We're still in Window::dispose()
721 mbExtTextInput = false; // true: ExtTextInput-Mode is active
722 mbInFocusHdl = false; // true: Within GetFocus-Handler
723 mbCreatedWithToolkit = false;
724 mbSuppressAccessibilityEvents = false; // true: do not send any accessibility events
725 mbDrawSelectionBackground = false; // true: draws transparent window background to indicate (toolbox) selection
726 mbIsInTaskPaneList = false; // true: window was added to the taskpanelist in the topmost system window
727 mnNativeBackground = ControlPart::NONE; // initialize later, depends on type
728 mbHelpTextDynamic = false; // true: append help id in HELP_DEBUG case
729 mbFakeFocusSet = false; // true: pretend as if the window has focus.
730 mbHexpand = false;
731 mbVexpand = false;
732 mbExpand = false;
733 mbFill = true;
734 mbSecondary = false;
735 mbNonHomogeneous = false;
736 static bool bDoubleBuffer = getenv("VCL_DOUBLEBUFFERING_FORCE_ENABLE");
737 mbDoubleBufferingRequested = bDoubleBuffer; // when we are not sure, assume it cannot do double-buffering via RenderContext
738 mpLOKNotifier = nullptr;
739 mnLOKWindowId = 0;
740 mbLOKParentNotifier = false;
741}
742
743WindowImpl::~WindowImpl()
744{
745 mpChildClipRegion.reset();
746 mpAccessibleInfos.reset();
747}
748
749ImplWinData::ImplWinData() :
750 mnCursorExtWidth(0),
751 mbVertical(false),
752 mnCompositionCharRects(0),
753 mnTrackFlags(ShowTrackFlags::NONE),
754 mnIsTopWindow(sal_uInt16(~0)), // not initialized yet, 0/1 will indicate TopWindow (see IsTopWindow())
755 mbMouseOver(false),
756 mbEnableNativeWidget(false)
757{
758}
759
760ImplWinData::~ImplWinData()
761{
762 mpCompositionCharRects.reset();
763}
764
765ImplFrameData::ImplFrameData( vcl::Window *pWindow )
766{
767 ImplSVData* pSVData = ImplGetSVData();
768 assert (pSVData->maFrameData.mpFirstFrame.get() != pWindow)(static_cast <bool> (pSVData->maFrameData.mpFirstFrame
.get() != pWindow) ? void (0) : __assert_fail ("pSVData->maFrameData.mpFirstFrame.get() != pWindow"
, "/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
, 768, __extension__ __PRETTY_FUNCTION__))
;
769 mpNextFrame = pSVData->maFrameData.mpFirstFrame;
770 pSVData->maFrameData.mpFirstFrame = pWindow;
771 mpFirstOverlap = nullptr;
772 mpFocusWin = nullptr;
773 mpMouseMoveWin = nullptr;
774 mpMouseDownWin = nullptr;
775 mxFontCollection = pSVData->maGDIData.mxScreenFontList;
776 mxFontCache = pSVData->maGDIData.mxScreenFontCache;
777 mnFocusId = nullptr;
778 mnMouseMoveId = nullptr;
779 mnLastMouseX = -1;
780 mnLastMouseY = -1;
781 mnBeforeLastMouseX = -1;
782 mnBeforeLastMouseY = -1;
783 mnFirstMouseX = -1;
784 mnFirstMouseY = -1;
785 mnLastMouseWinX = -1;
786 mnLastMouseWinY = -1;
787 mnModalMode = 0;
788 mnMouseDownTime = 0;
789 mnClickCount = 0;
790 mnFirstMouseCode = 0;
791 mnMouseCode = 0;
792 mnMouseMode = MouseEventModifiers::NONE;
793 mbHasFocus = false;
794 mbInMouseMove = false;
795 mbMouseIn = false;
796 mbStartDragCalled = false;
797 mbNeedSysWindow = false;
798 mbMinimized = false;
799 mbStartFocusState = false;
800 mbInSysObjFocusHdl = false;
801 mbInSysObjToTopHdl = false;
802 mbSysObjFocus = false;
803 maPaintIdle.SetPriority( TaskPriority::REPAINT );
804 maPaintIdle.SetInvokeHandler( LINK( pWindow, vcl::Window, ImplHandlePaintHdl )::tools::detail::makeLink( ::tools::detail::castTo<vcl::Window
*>(pWindow), &vcl::Window::LinkStubImplHandlePaintHdl
)
);
805 maPaintIdle.SetDebugName( "vcl::Window maPaintIdle" );
806 maResizeIdle.SetPriority( TaskPriority::RESIZE );
807 maResizeIdle.SetInvokeHandler( LINK( pWindow, vcl::Window, ImplHandleResizeTimerHdl )::tools::detail::makeLink( ::tools::detail::castTo<vcl::Window
*>(pWindow), &vcl::Window::LinkStubImplHandleResizeTimerHdl
)
);
808 maResizeIdle.SetDebugName( "vcl::Window maResizeIdle" );
809 mbInternalDragGestureRecognizer = false;
810 mbInBufferedPaint = false;
811 mnDPIX = 96;
812 mnDPIY = 96;
813 mnTouchPanPosition = -1;
814}
815
816namespace vcl {
817
818bool Window::AcquireGraphics() const
819{
820 DBG_TESTSOLARMUTEX()do { DbgTestSolarMutex(); } while(false);
821
822 if ( mpGraphics )
823 return true;
824
825 mbInitLineColor = true;
826 mbInitFillColor = true;
827 mbInitFont = true;
828 mbInitTextColor = true;
829 mbInitClipRegion = true;
830
831 ImplSVData* pSVData = ImplGetSVData();
832
833 mpGraphics = mpWindowImpl->mpFrame->AcquireGraphics();
834 // try harder if no wingraphics was available directly
835 if ( !mpGraphics )
836 {
837 // find another output device in the same frame
838 OutputDevice* pReleaseOutDev = pSVData->maGDIData.mpLastWinGraphics;
839 while ( pReleaseOutDev )
840 {
841 if ( static_cast<vcl::Window*>(pReleaseOutDev)->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame )
842 break;
843 pReleaseOutDev = pReleaseOutDev->mpPrevGraphics;
844 }
845
846 if ( pReleaseOutDev )
847 {
848 // steal the wingraphics from the other outdev
849 mpGraphics = pReleaseOutDev->mpGraphics;
850 pReleaseOutDev->ReleaseGraphics( false );
851 }
852 else
853 {
854 // if needed retry after releasing least recently used wingraphics
855 while ( !mpGraphics )
856 {
857 if ( !pSVData->maGDIData.mpLastWinGraphics )
858 break;
859 pSVData->maGDIData.mpLastWinGraphics->ReleaseGraphics();
860 mpGraphics = mpWindowImpl->mpFrame->AcquireGraphics();
861 }
862 }
863 }
864
865 if ( mpGraphics )
866 {
867 // update global LRU list of wingraphics
868 mpNextGraphics = pSVData->maGDIData.mpFirstWinGraphics;
869 pSVData->maGDIData.mpFirstWinGraphics = const_cast<vcl::Window*>(this);
870 if ( mpNextGraphics )
871 mpNextGraphics->mpPrevGraphics = const_cast<vcl::Window*>(this);
872 if ( !pSVData->maGDIData.mpLastWinGraphics )
873 pSVData->maGDIData.mpLastWinGraphics = const_cast<vcl::Window*>(this);
874
875 mpGraphics->SetXORMode( (RasterOp::Invert == meRasterOp) || (RasterOp::Xor == meRasterOp), RasterOp::Invert == meRasterOp );
876 mpGraphics->setAntiAlias(bool(mnAntialiasing & AntialiasingFlags::Enable));
877 }
878
879 return mpGraphics != nullptr;
880}
881
882void Window::ReleaseGraphics( bool bRelease )
883{
884 DBG_TESTSOLARMUTEX()do { DbgTestSolarMutex(); } while(false);
885
886 if ( !mpGraphics )
887 return;
888
889 // release the fonts of the physically released graphics device
890 if( bRelease )
891 ImplReleaseFonts();
892
893 ImplSVData* pSVData = ImplGetSVData();
894
895 vcl::Window* pWindow = this;
896
897 if ( bRelease )
898 pWindow->mpWindowImpl->mpFrame->ReleaseGraphics( mpGraphics );
899 // remove from global LRU list of window graphics
900 if ( mpPrevGraphics )
901 mpPrevGraphics->mpNextGraphics = mpNextGraphics;
902 else
903 pSVData->maGDIData.mpFirstWinGraphics = mpNextGraphics;
904 if ( mpNextGraphics )
905 mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
906 else
907 pSVData->maGDIData.mpLastWinGraphics = mpPrevGraphics;
908
909 mpGraphics = nullptr;
910 mpPrevGraphics = nullptr;
911 mpNextGraphics = nullptr;
912}
913
914static sal_Int32 CountDPIScaleFactor(sal_Int32 nDPI)
915{
916#ifndef MACOSX
917 // Setting of HiDPI is unfortunately all only a heuristic; and to add
918 // insult to an injury, the system is constantly lying to us about
919 // the DPI and whatnot
920 // eg. fdo#77059 - set the value from which we do consider the
921 // screen HiDPI to greater than 168
922 if (nDPI > 216) // 96 * 2 + 96 / 4
923 return 250;
924 else if (nDPI > 168) // 96 * 2 - 96 / 4
925 return 200;
926 else if (nDPI > 120) // 96 * 1.5 - 96 / 4
927 return 150;
928#else
929 (void)nDPI;
930#endif
931
932 return 100;
933}
934
935void Window::ImplInit( vcl::Window* pParent, WinBits nStyle, SystemParentData* pSystemParentData )
936{
937 SAL_WARN_IF( !mpWindowImpl->mbFrame && !pParent && GetType() != WindowType::FIXEDIMAGE, "vcl.window",do { if (true && (!mpWindowImpl->mbFrame &&
!pParent && GetType() != WindowType::FIXEDIMAGE)) { switch
(sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "vcl.window"
)) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Window::Window(): pParent == NULL") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "938" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window::Window(): pParent == NULL"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Window::Window(): pParent == NULL"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "938" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Window::Window(): pParent == NULL") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "938" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window::Window(): pParent == NULL"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Window::Window(): pParent == NULL"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "938" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
938 "Window::Window(): pParent == NULL" )do { if (true && (!mpWindowImpl->mbFrame &&
!pParent && GetType() != WindowType::FIXEDIMAGE)) { switch
(sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "vcl.window"
)) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Window::Window(): pParent == NULL") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "938" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window::Window(): pParent == NULL"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Window::Window(): pParent == NULL"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "938" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Window::Window(): pParent == NULL") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "938" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Window::Window(): pParent == NULL"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Window::Window(): pParent == NULL"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "938" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
939
940 ImplSVData* pSVData = ImplGetSVData();
941 vcl::Window* pRealParent = pParent;
942
943 // inherit 3D look
944 if ( !mpWindowImpl->mbOverlapWin && pParent && (pParent->GetStyle() & WB_3DLOOK) )
945 nStyle |= WB_3DLOOK;
946
947 // create border window if necessary
948 if ( !mpWindowImpl->mbFrame && !mpWindowImpl->mbBorderWin && !mpWindowImpl->mpBorderWindow
949 && (nStyle & (WB_BORDER | WB_SYSTEMCHILDWINDOW) ) )
950 {
951 BorderWindowStyle nBorderTypeStyle = BorderWindowStyle::NONE;
952 if( nStyle & WB_SYSTEMCHILDWINDOW )
953 {
954 // handle WB_SYSTEMCHILDWINDOW
955 // these should be analogous to a top level frame; meaning they
956 // should have a border window with style BorderWindowStyle::Frame
957 // which controls their size
958 nBorderTypeStyle |= BorderWindowStyle::Frame;
959 nStyle |= WB_BORDER;
960 }
961 VclPtrInstance<ImplBorderWindow> pBorderWin( pParent, nStyle & (WB_BORDER | WB_DIALOGCONTROL | WB_NODIALOGCONTROL), nBorderTypeStyle );
962 static_cast<vcl::Window*>(pBorderWin)->mpWindowImpl->mpClientWindow = this;
963 pBorderWin->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
964 mpWindowImpl->mpBorderWindow = pBorderWin;
965 pParent = mpWindowImpl->mpBorderWindow;
966 }
967 else if( !mpWindowImpl->mbFrame && ! pParent )
968 {
969 mpWindowImpl->mbOverlapWin = true;
970 mpWindowImpl->mbFrame = true;
971 }
972
973 // insert window in list
974 ImplInsertWindow( pParent );
975 mpWindowImpl->mnStyle = nStyle;
976
977 if( pParent && ! mpWindowImpl->mbFrame )
978 mbEnableRTL = AllSettings::GetLayoutRTL();
979
980 // test for frame creation
981 if ( mpWindowImpl->mbFrame )
982 {
983 // create frame
984 SalFrameStyleFlags nFrameStyle = SalFrameStyleFlags::NONE;
985
986 if ( nStyle & WB_MOVEABLE )
987 nFrameStyle |= SalFrameStyleFlags::MOVEABLE;
988 if ( nStyle & WB_SIZEABLE )
989 nFrameStyle |= SalFrameStyleFlags::SIZEABLE;
990 if ( nStyle & WB_CLOSEABLE )
991 nFrameStyle |= SalFrameStyleFlags::CLOSEABLE;
992 if ( nStyle & WB_APP )
993 nFrameStyle |= SalFrameStyleFlags::DEFAULT;
994 // check for undecorated floating window
995 if( // 1. floating windows that are not moveable/sizeable (only closeable allowed)
996 ( !(nFrameStyle & ~SalFrameStyleFlags::CLOSEABLE) &&
997 ( mpWindowImpl->mbFloatWin || ((GetType() == WindowType::BORDERWINDOW) && static_cast<ImplBorderWindow*>(this)->mbFloatWindow) || (nStyle & WB_SYSTEMFLOATWIN) ) ) ||
998 // 2. borderwindows of floaters with ownerdraw decoration
999 ((GetType() == WindowType::BORDERWINDOW) && static_cast<ImplBorderWindow*>(this)->mbFloatWindow && (nStyle & WB_OWNERDRAWDECORATION) ) )
1000 {
1001 nFrameStyle = SalFrameStyleFlags::FLOAT;
1002 if( nStyle & WB_OWNERDRAWDECORATION )
1003 nFrameStyle |= SalFrameStyleFlags::OWNERDRAWDECORATION | SalFrameStyleFlags::NOSHADOW;
1004 }
1005 else if( mpWindowImpl->mbFloatWin )
1006 nFrameStyle |= SalFrameStyleFlags::TOOLWINDOW;
1007
1008 if( nStyle & WB_INTROWIN )
1009 nFrameStyle |= SalFrameStyleFlags::INTRO;
1010 if( nStyle & WB_TOOLTIPWIN )
1011 nFrameStyle |= SalFrameStyleFlags::TOOLTIP;
1012
1013 if( nStyle & WB_NOSHADOW )
1014 nFrameStyle |= SalFrameStyleFlags::NOSHADOW;
1015
1016 if( nStyle & WB_SYSTEMCHILDWINDOW )
1017 nFrameStyle |= SalFrameStyleFlags::SYSTEMCHILD;
1018
1019 switch (mpWindowImpl->mnType)
1020 {
1021 case WindowType::DIALOG:
1022 case WindowType::TABDIALOG:
1023 case WindowType::MODELESSDIALOG:
1024 case WindowType::MESSBOX:
1025 case WindowType::INFOBOX:
1026 case WindowType::WARNINGBOX:
1027 case WindowType::ERRORBOX:
1028 case WindowType::QUERYBOX:
1029 nFrameStyle |= SalFrameStyleFlags::DIALOG;
1030 break;
1031 default:
1032 break;
1033 }
1034
1035 SalFrame* pParentFrame = nullptr;
1036 if ( pParent )
1037 pParentFrame = pParent->mpWindowImpl->mpFrame;
1038 SalFrame* pFrame;
1039 if ( pSystemParentData )
1040 pFrame = pSVData->mpDefInst->CreateChildFrame( pSystemParentData, nFrameStyle | SalFrameStyleFlags::PLUG );
1041 else
1042 pFrame = pSVData->mpDefInst->CreateFrame( pParentFrame, nFrameStyle );
1043 if ( !pFrame )
1044 {
1045 // do not abort but throw an exception, may be the current thread terminates anyway (plugin-scenario)
1046 throw RuntimeException(
1047 "Could not create system window!",
1048 Reference< XInterface >() );
1049 }
1050
1051 pFrame->SetCallback( this, ImplWindowFrameProc );
1052
1053 // set window frame data
1054 mpWindowImpl->mpFrameData = new ImplFrameData( this );
1055 mpWindowImpl->mpFrame = pFrame;
1056 mpWindowImpl->mpFrameWindow = this;
1057 mpWindowImpl->mpOverlapWindow = this;
1058
1059 if (!(nStyle & WB_DEFAULTWIN) && mpWindowImpl->mbDoubleBufferingRequested)
1060 RequestDoubleBuffering(true);
1061
1062 if ( pRealParent && IsTopWindow() )
1063 {
1064 ImplWinData* pParentWinData = pRealParent->ImplGetWinData();
1065 pParentWinData->maTopWindowChildren.emplace_back(this );
1066 }
1067 }
1068
1069 // init data
1070 mpWindowImpl->mpRealParent = pRealParent;
1071
1072 // #99318: make sure fontcache and list is available before call to SetSettings
1073 mxFontCollection = mpWindowImpl->mpFrameData->mxFontCollection;
1074 mxFontCache = mpWindowImpl->mpFrameData->mxFontCache;
1075
1076 if ( mpWindowImpl->mbFrame )
1077 {
1078 if ( pParent )
1079 {
1080 mpWindowImpl->mpFrameData->mnDPIX = pParent->mpWindowImpl->mpFrameData->mnDPIX;
1081 mpWindowImpl->mpFrameData->mnDPIY = pParent->mpWindowImpl->mpFrameData->mnDPIY;
1082 }
1083 else
1084 {
1085 OutputDevice *pOutDev = GetOutDev();
1086 if ( pOutDev->AcquireGraphics() )
1087 {
1088 mpGraphics->GetResolution( mpWindowImpl->mpFrameData->mnDPIX, mpWindowImpl->mpFrameData->mnDPIY );
1089 }
1090 }
1091
1092 // add ownerdraw decorated frame windows to list in the top-most frame window
1093 // so they can be hidden on lose focus
1094 if( nStyle & WB_OWNERDRAWDECORATION )
1095 ImplGetOwnerDrawList().emplace_back(this );
1096
1097 // delay settings initialization until first "real" frame
1098 // this relies on the IntroWindow not needing any system settings
1099 if ( !pSVData->maAppData.mbSettingsInit &&
1100 ! (nStyle & (WB_INTROWIN|WB_DEFAULTWIN))
1101 )
1102 {
1103 // side effect: ImplUpdateGlobalSettings does an ImplGetFrame()->UpdateSettings
1104 ImplUpdateGlobalSettings( *pSVData->maAppData.mpSettings );
1105 OutputDevice::SetSettings( *pSVData->maAppData.mpSettings );
1106 pSVData->maAppData.mbSettingsInit = true;
1107 }
1108
1109 // If we create a Window with default size, query this
1110 // size directly, because we want resize all Controls to
1111 // the correct size before we display the window
1112 if ( nStyle & (WB_MOVEABLE | WB_SIZEABLE | WB_APP) )
1113 mpWindowImpl->mpFrame->GetClientSize( mnOutWidth, mnOutHeight );
1114 }
1115 else
1116 {
1117 if ( pParent )
1118 {
1119 if ( !ImplIsOverlapWindow() )
1120 {
1121 mpWindowImpl->mbDisabled = pParent->mpWindowImpl->mbDisabled;
1122 mpWindowImpl->mbInputDisabled = pParent->mpWindowImpl->mbInputDisabled;
1123 mpWindowImpl->meAlwaysInputMode = pParent->mpWindowImpl->meAlwaysInputMode;
1124 }
1125
1126 if (!utl::ConfigManager::IsFuzzing())
1127 OutputDevice::SetSettings( pParent->GetSettings() );
1128 }
1129
1130 }
1131
1132 // setup the scale factor for HiDPI displays
1133 mnDPIScalePercentage = CountDPIScaleFactor(mpWindowImpl->mpFrameData->mnDPIY);
1134 mnDPIX = mpWindowImpl->mpFrameData->mnDPIX;
1135 mnDPIY = mpWindowImpl->mpFrameData->mnDPIY;
1136
1137 if (!utl::ConfigManager::IsFuzzing())
1138 {
1139 const StyleSettings& rStyleSettings = mxSettings->GetStyleSettings();
1140 maFont = rStyleSettings.GetAppFont();
1141
1142 if ( nStyle & WB_3DLOOK )
1143 {
1144 SetTextColor( rStyleSettings.GetButtonTextColor() );
1145 SetBackground( Wallpaper( rStyleSettings.GetFaceColor() ) );
1146 }
1147 else
1148 {
1149 SetTextColor( rStyleSettings.GetWindowTextColor() );
1150 SetBackground( Wallpaper( rStyleSettings.GetWindowColor() ) );
1151 }
1152 }
1153 else
1154 {
1155 maFont = GetDefaultFont( DefaultFontType::FIXED, LANGUAGE_ENGLISH_USLanguageType(0x0409), GetDefaultFontFlags::NONE );
1156 }
1157
1158 ImplPointToLogic(*this, maFont);
1159
1160 (void)ImplUpdatePos();
1161
1162 // calculate app font res (except for the Intro Window or the default window)
1163 if ( mpWindowImpl->mbFrame && !pSVData->maGDIData.mnAppFontX && ! (nStyle & (WB_INTROWIN|WB_DEFAULTWIN)) )
1164 ImplInitAppFontData( this );
1165}
1166
1167void Window::ImplInitAppFontData( vcl::Window const * pWindow )
1168{
1169 ImplSVData* pSVData = ImplGetSVData();
1170 long nTextHeight = pWindow->GetTextHeight();
1171 long nTextWidth = pWindow->approximate_char_width() * 8;
1172 long nSymHeight = nTextHeight*4;
1173 // Make the basis wider if the font is too narrow
1174 // such that the dialog looks symmetrical and does not become too narrow.
1175 // Add some extra space when the dialog has the same width,
1176 // as a little more space is better.
1177 if ( nSymHeight > nTextWidth )
1178 nTextWidth = nSymHeight;
1179 else if ( nSymHeight+5 > nTextWidth )
1180 nTextWidth = nSymHeight+5;
1181 pSVData->maGDIData.mnAppFontX = nTextWidth * 10 / 8;
1182 pSVData->maGDIData.mnAppFontY = nTextHeight * 10;
1183
1184#ifdef MACOSX
1185 // FIXME: this is currently only on macOS, check with other
1186 // platforms
1187 if( pSVData->maNWFData.mbNoFocusRects )
1188 {
1189 // try to find out whether there is a large correction
1190 // of control sizes, if yes, make app font scalings larger
1191 // so dialog positioning is not completely off
1192 ImplControlValue aControlValue;
1193 tools::Rectangle aCtrlRegion( Point(), Size( nTextWidth < 10 ? 10 : nTextWidth, nTextHeight < 10 ? 10 : nTextHeight ) );
1194 tools::Rectangle aBoundingRgn( aCtrlRegion );
1195 tools::Rectangle aContentRgn( aCtrlRegion );
1196 if( pWindow->GetNativeControlRegion( ControlType::Editbox, ControlPart::Entire, aCtrlRegion,
1197 ControlState::ENABLED, aControlValue,
1198 aBoundingRgn, aContentRgn ) )
1199 {
1200 // comment: the magical +6 is for the extra border in bordered
1201 // (which is the standard) edit fields
1202 if( aContentRgn.GetHeight() - nTextHeight > (nTextHeight+4)/4 )
1203 pSVData->maGDIData.mnAppFontY = (aContentRgn.GetHeight()-4) * 10;
1204 }
1205 }
1206#endif
1207}
1208
1209ImplWinData* Window::ImplGetWinData() const
1210{
1211 if (!mpWindowImpl->mpWinData)
1212 {
1213 static const char* pNoNWF = getenv( "SAL_NO_NWF" );
1214
1215 const_cast<vcl::Window*>(this)->mpWindowImpl->mpWinData = new ImplWinData;
1216 mpWindowImpl->mpWinData->mbEnableNativeWidget = !(pNoNWF && *pNoNWF); // true: try to draw this control with native theme API
1217 }
1218
1219 return mpWindowImpl->mpWinData;
1220}
1221
1222
1223void Window::CopyDeviceArea( SalTwoRect& aPosAry, bool bWindowInvalidate )
1224{
1225 if (aPosAry.mnSrcWidth == 0 || aPosAry.mnSrcHeight == 0 || aPosAry.mnDestWidth == 0 || aPosAry.mnDestHeight == 0)
1226 return;
1227
1228 if (bWindowInvalidate)
1229 {
1230 const tools::Rectangle aSrcRect(Point(aPosAry.mnSrcX, aPosAry.mnSrcY),
1231 Size(aPosAry.mnSrcWidth, aPosAry.mnSrcHeight));
1232
1233 ImplMoveAllInvalidateRegions(aSrcRect,
1234 aPosAry.mnDestX-aPosAry.mnSrcX,
1235 aPosAry.mnDestY-aPosAry.mnSrcY,
1236 false);
1237
1238 mpGraphics->CopyArea(aPosAry.mnDestX, aPosAry.mnDestY,
1239 aPosAry.mnSrcX, aPosAry.mnSrcY,
1240 aPosAry.mnSrcWidth, aPosAry.mnSrcHeight,
1241 this);
1242
1243 return;
1244 }
1245
1246 OutputDevice::CopyDeviceArea(aPosAry, bWindowInvalidate);
1247}
1248
1249const OutputDevice* Window::DrawOutDevDirectCheck(const OutputDevice* pSrcDev) const
1250{
1251 const OutputDevice* pSrcDevChecked;
1252 if ( this == pSrcDev )
1253 pSrcDevChecked = nullptr;
1254 else if (GetOutDevType() != pSrcDev->GetOutDevType())
1255 pSrcDevChecked = pSrcDev;
1256 else if (this->mpWindowImpl->mpFrameWindow == static_cast<const vcl::Window*>(pSrcDev)->mpWindowImpl->mpFrameWindow)
1257 pSrcDevChecked = nullptr;
1258 else
1259 pSrcDevChecked = pSrcDev;
1260
1261 return pSrcDevChecked;
1262}
1263
1264void Window::DrawOutDevDirectProcess( const OutputDevice* pSrcDev, SalTwoRect& rPosAry, SalGraphics* pSrcGraphics )
1265{
1266 mpGraphics->CopyBits( rPosAry, pSrcGraphics, this, pSrcDev );
1267}
1268
1269SalGraphics* Window::ImplGetFrameGraphics() const
1270{
1271 if ( mpWindowImpl->mpFrameWindow->mpGraphics )
1272 {
1273 mpWindowImpl->mpFrameWindow->mbInitClipRegion = true;
1274 }
1275 else
1276 {
1277 OutputDevice* pFrameWinOutDev = mpWindowImpl->mpFrameWindow;
1278 if ( ! pFrameWinOutDev->AcquireGraphics() )
1279 {
1280 return nullptr;
1281 }
1282 }
1283 mpWindowImpl->mpFrameWindow->mpGraphics->ResetClipRegion();
1284 return mpWindowImpl->mpFrameWindow->mpGraphics;
1285}
1286
1287void Window::ImplSetReallyVisible()
1288{
1289 // #i43594# it is possible that INITSHOW was never send, because the visibility state changed between
1290 // ImplCallInitShow() and ImplSetReallyVisible() when called from Show()
1291 // mbReallyShown is a useful indicator
1292 if( !mpWindowImpl->mbReallyShown )
1293 ImplCallInitShow();
1294
1295 bool bBecameReallyVisible = !mpWindowImpl->mbReallyVisible;
1296
1297 mbDevOutput = true;
1298 mpWindowImpl->mbReallyVisible = true;
1299 mpWindowImpl->mbReallyShown = true;
1300
1301 // the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge.
1302 // For this, the data member of the event must not be NULL.
1303 // Previously, we did this in Window::Show, but there some events got lost in certain situations. Now
1304 // we're doing it when the visibility really changes
1305 if( bBecameReallyVisible && ImplIsAccessibleCandidate() )
1306 CallEventListeners( VclEventId::WindowShow, this );
1307 // TODO. It's kind of a hack that we're re-using the VclEventId::WindowShow. Normally, we should
1308 // introduce another event which explicitly triggers the Accessibility implementations.
1309
1310 vcl::Window* pWindow = mpWindowImpl->mpFirstOverlap;
1311 while ( pWindow )
1312 {
1313 if ( pWindow->mpWindowImpl->mbVisible )
1314 pWindow->ImplSetReallyVisible();
1315 pWindow = pWindow->mpWindowImpl->mpNext;
1316 }
1317
1318 pWindow = mpWindowImpl->mpFirstChild;
1319 while ( pWindow )
1320 {
1321 if ( pWindow->mpWindowImpl->mbVisible )
1322 pWindow->ImplSetReallyVisible();
1323 pWindow = pWindow->mpWindowImpl->mpNext;
1324 }
1325}
1326
1327void Window::ImplInitResolutionSettings()
1328{
1329 // recalculate AppFont-resolution and DPI-resolution
1330 if (mpWindowImpl->mbFrame)
1331 {
1332 mnDPIX = mpWindowImpl->mpFrameData->mnDPIX;
1333 mnDPIY = mpWindowImpl->mpFrameData->mnDPIY;
1334
1335 // setup the scale factor for HiDPI displays
1336 mnDPIScalePercentage = CountDPIScaleFactor(mpWindowImpl->mpFrameData->mnDPIY);
1337 const StyleSettings& rStyleSettings = mxSettings->GetStyleSettings();
1338 SetPointFont(*this, rStyleSettings.GetAppFont());
1339 }
1340 else if ( mpWindowImpl->mpParent )
1341 {
1342 mnDPIX = mpWindowImpl->mpParent->mnDPIX;
1343 mnDPIY = mpWindowImpl->mpParent->mnDPIY;
1344 mnDPIScalePercentage = mpWindowImpl->mpParent->mnDPIScalePercentage;
1345 }
1346
1347 // update the recalculated values for logical units
1348 // and also tools belonging to the values
1349 if (IsMapModeEnabled())
1350 {
1351 MapMode aMapMode = GetMapMode();
1352 SetMapMode();
1353 SetMapMode( aMapMode );
1354 }
1355}
1356
1357void Window::ImplPointToLogic(vcl::RenderContext const & rRenderContext, vcl::Font& rFont) const
1358{
1359 Size aSize = rFont.GetFontSize();
1360
1361 if (aSize.Width())
1362 {
1363 aSize.setWidth( aSize.Width() * ( mpWindowImpl->mpFrameData->mnDPIX) );
1364 aSize.AdjustWidth(72 / 2 );
1365 aSize.setWidth( aSize.Width() / 72 );
1366 }
1367 aSize.setHeight( aSize.Height() * ( mpWindowImpl->mpFrameData->mnDPIY) );
1368 aSize.AdjustHeight(72/2 );
1369 aSize.setHeight( aSize.Height() / 72 );
1370
1371 if (rRenderContext.IsMapModeEnabled())
1372 aSize = rRenderContext.PixelToLogic(aSize);
1373
1374 rFont.SetFontSize(aSize);
1375}
1376
1377void Window::ImplLogicToPoint(vcl::RenderContext const & rRenderContext, vcl::Font& rFont) const
1378{
1379 Size aSize = rFont.GetFontSize();
1380
1381 if (rRenderContext.IsMapModeEnabled())
1382 aSize = rRenderContext.LogicToPixel(aSize);
1383
1384 if (aSize.Width())
1385 {
1386 aSize.setWidth( aSize.Width() * 72 );
1387 aSize.AdjustWidth(mpWindowImpl->mpFrameData->mnDPIX / 2 );
1388 aSize.setWidth( aSize.Width() / ( mpWindowImpl->mpFrameData->mnDPIX) );
1389 }
1390 aSize.setHeight( aSize.Height() * 72 );
1391 aSize.AdjustHeight(mpWindowImpl->mpFrameData->mnDPIY / 2 );
1392 aSize.setHeight( aSize.Height() / ( mpWindowImpl->mpFrameData->mnDPIY) );
1393
1394 rFont.SetFontSize(aSize);
1395}
1396
1397bool Window::ImplUpdatePos()
1398{
1399 bool bSysChild = false;
1400
1401 if ( ImplIsOverlapWindow() )
1402 {
1403 mnOutOffX = mpWindowImpl->mnX;
1404 mnOutOffY = mpWindowImpl->mnY;
1405 }
1406 else
1407 {
1408 vcl::Window* pParent = ImplGetParent();
1409
1410 mnOutOffX = mpWindowImpl->mnX + pParent->mnOutOffX;
1411 mnOutOffY = mpWindowImpl->mnY + pParent->mnOutOffY;
1412 }
1413
1414 VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
1415 while ( pChild )
1416 {
1417 if ( pChild->ImplUpdatePos() )
1418 bSysChild = true;
1419 pChild = pChild->mpWindowImpl->mpNext;
1420 }
1421
1422 if ( mpWindowImpl->mpSysObj )
1423 bSysChild = true;
1424
1425 return bSysChild;
1426}
1427
1428void Window::ImplUpdateSysObjPos()
1429{
1430 if ( mpWindowImpl->mpSysObj )
1431 mpWindowImpl->mpSysObj->SetPosSize( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight );
1432
1433 VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
1434 while ( pChild )
1435 {
1436 pChild->ImplUpdateSysObjPos();
1437 pChild = pChild->mpWindowImpl->mpNext;
1438 }
1439}
1440
1441void Window::ImplPosSizeWindow( long nX, long nY,
1442 long nWidth, long nHeight, PosSizeFlags nFlags )
1443{
1444 bool bNewPos = false;
1445 bool bNewSize = false;
1446 bool bCopyBits = false;
1447 long nOldOutOffX = mnOutOffX;
1448 long nOldOutOffY = mnOutOffY;
1449 long nOldOutWidth = mnOutWidth;
1450 long nOldOutHeight = mnOutHeight;
1451 std::unique_ptr<vcl::Region> pOverlapRegion;
1452 std::unique_ptr<vcl::Region> pOldRegion;
1453
1454 if ( IsReallyVisible() )
1455 {
1456 tools::Rectangle aOldWinRect( Point( nOldOutOffX, nOldOutOffY ),
1457 Size( nOldOutWidth, nOldOutHeight ) );
1458 pOldRegion.reset( new vcl::Region( aOldWinRect ) );
1459 if ( mpWindowImpl->mbWinRegion )
1460 pOldRegion->Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
1461
1462 if ( mnOutWidth && mnOutHeight && !mpWindowImpl->mbPaintTransparent &&
1463 !mpWindowImpl->mbInitWinClipRegion && !mpWindowImpl->maWinClipRegion.IsEmpty() &&
1464 !HasPaintEvent() )
1465 bCopyBits = true;
1466 }
1467
1468 bool bnXRecycled = false; // avoid duplicate mirroring in RTL case
1469 if ( nFlags & PosSizeFlags::Width )
1470 {
1471 if(!( nFlags & PosSizeFlags::X ))
1472 {
1473 nX = mpWindowImpl->mnX;
1474 nFlags |= PosSizeFlags::X;
1475 bnXRecycled = true; // we're using a mnX which was already mirrored in RTL case
1476 }
1477
1478 if ( nWidth < 0 )
1479 nWidth = 0;
1480 if ( nWidth != mnOutWidth )
1481 {
1482 mnOutWidth = nWidth;
1483 bNewSize = true;
1484 bCopyBits = false;
1485 }
1486 }
1487 if ( nFlags & PosSizeFlags::Height )
1488 {
1489 if ( nHeight < 0 )
1490 nHeight = 0;
1491 if ( nHeight != mnOutHeight )
1492 {
1493 mnOutHeight = nHeight;
1494 bNewSize = true;
1495 bCopyBits = false;
1496 }
1497 }
1498
1499 if ( nFlags & PosSizeFlags::X )
1500 {
1501 long nOrgX = nX;
1502 Point aPtDev( Point( nX+mnOutOffX, 0 ) );
1503 OutputDevice *pOutDev = GetOutDev();
1504 if( pOutDev->HasMirroredGraphics() )
1505 {
1506 aPtDev.setX( mpGraphics->mirror2( aPtDev.X(), this ) );
1507
1508 // #106948# always mirror our pos if our parent is not mirroring, even
1509 // if we are also not mirroring
1510 // RTL: check if parent is in different coordinates
1511 if( !bnXRecycled && mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() )
1512 {
1513 nX = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - nX;
1514 }
1515 /* #i99166# An LTR window in RTL UI that gets sized only would be
1516 expected to not moved its upper left point
1517 */
1518 if( bnXRecycled )
1519 {
1520 if( ImplIsAntiparallel() )
1521 {
1522 aPtDev.setX( mpWindowImpl->mnAbsScreenX );
1523 nOrgX = mpWindowImpl->maPos.X();
1524 }
1525 }
1526 }
1527 else if( !bnXRecycled && mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() )
1528 {
1529 // mirrored window in LTR UI
1530 nX = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - nX;
1531 }
1532
1533 // check maPos as well, as it could have been changed for client windows (ImplCallMove())
1534 if ( mpWindowImpl->mnAbsScreenX != aPtDev.X() || nX != mpWindowImpl->mnX || nOrgX != mpWindowImpl->maPos.X() )
1535 {
1536 if ( bCopyBits && !pOverlapRegion )
1537 {
1538 pOverlapRegion.reset( new vcl::Region() );
1539 ImplCalcOverlapRegion( tools::Rectangle( Point( mnOutOffX, mnOutOffY ),
1540 Size( mnOutWidth, mnOutHeight ) ),
1541 *pOverlapRegion, false, true );
1542 }
1543 mpWindowImpl->mnX = nX;
1544 mpWindowImpl->maPos.setX( nOrgX );
1545 mpWindowImpl->mnAbsScreenX = aPtDev.X();
1546 bNewPos = true;
1547 }
1548 }
1549 if ( nFlags & PosSizeFlags::Y )
1550 {
1551 // check maPos as well, as it could have been changed for client windows (ImplCallMove())
1552 if ( nY != mpWindowImpl->mnY || nY != mpWindowImpl->maPos.Y() )
1553 {
1554 if ( bCopyBits && !pOverlapRegion )
1555 {
1556 pOverlapRegion.reset( new vcl::Region() );
1557 ImplCalcOverlapRegion( tools::Rectangle( Point( mnOutOffX, mnOutOffY ),
1558 Size( mnOutWidth, mnOutHeight ) ),
1559 *pOverlapRegion, false, true );
1560 }
1561 mpWindowImpl->mnY = nY;
1562 mpWindowImpl->maPos.setY( nY );
1563 bNewPos = true;
1564 }
1565 }
1566
1567 if ( !(bNewPos || bNewSize) )
1568 return;
1569
1570 bool bUpdateSysObjPos = false;
1571 if ( bNewPos )
1572 bUpdateSysObjPos = ImplUpdatePos();
1573
1574 // the borderwindow always specifies the position for its client window
1575 if ( mpWindowImpl->mpBorderWindow )
1576 mpWindowImpl->maPos = mpWindowImpl->mpBorderWindow->mpWindowImpl->maPos;
1577
1578 if ( mpWindowImpl->mpClientWindow )
1579 {
1580 mpWindowImpl->mpClientWindow->ImplPosSizeWindow( mpWindowImpl->mpClientWindow->mpWindowImpl->mnLeftBorder,
1581 mpWindowImpl->mpClientWindow->mpWindowImpl->mnTopBorder,
1582 mnOutWidth-mpWindowImpl->mpClientWindow->mpWindowImpl->mnLeftBorder-mpWindowImpl->mpClientWindow->mpWindowImpl->mnRightBorder,
1583 mnOutHeight-mpWindowImpl->mpClientWindow->mpWindowImpl->mnTopBorder-mpWindowImpl->mpClientWindow->mpWindowImpl->mnBottomBorder,
1584 PosSizeFlags::X | PosSizeFlags::Y |
1585 PosSizeFlags::Width | PosSizeFlags::Height );
1586 // If we have a client window, then this is the position
1587 // of the Application's floating windows
1588 mpWindowImpl->mpClientWindow->mpWindowImpl->maPos = mpWindowImpl->maPos;
1589 if ( bNewPos )
1590 {
1591 if ( mpWindowImpl->mpClientWindow->IsVisible() )
1592 {
1593 mpWindowImpl->mpClientWindow->ImplCallMove();
1594 }
1595 else
1596 {
1597 mpWindowImpl->mpClientWindow->mpWindowImpl->mbCallMove = true;
1598 }
1599 }
1600 }
1601
1602 // Move()/Resize() will be called only for Show(), such that
1603 // at least one is called before Show()
1604 if ( IsVisible() )
1605 {
1606 if ( bNewPos )
1607 {
1608 ImplCallMove();
1609 }
1610 if ( bNewSize )
1611 {
1612 ImplCallResize();
1613 }
1614 }
1615 else
1616 {
1617 if ( bNewPos )
1618 mpWindowImpl->mbCallMove = true;
1619 if ( bNewSize )
1620 mpWindowImpl->mbCallResize = true;
1621 }
1622
1623 bool bUpdateSysObjClip = false;
1624 if ( IsReallyVisible() )
1625 {
1626 if ( bNewPos || bNewSize )
1627 {
1628 // set Clip-Flag
1629 bUpdateSysObjClip = !ImplSetClipFlag( true );
1630 }
1631
1632 // invalidate window content ?
1633 if ( bNewPos || (mnOutWidth > nOldOutWidth) || (mnOutHeight > nOldOutHeight) )
1634 {
1635 if ( bNewPos )
1636 {
1637 bool bInvalidate = false;
1638 bool bParentPaint = true;
1639 if ( !ImplIsOverlapWindow() )
1640 bParentPaint = mpWindowImpl->mpParent->IsPaintEnabled();
1641 if ( bCopyBits && bParentPaint && !HasPaintEvent() )
1642 {
1643 Point aPoint( mnOutOffX, mnOutOffY );
1644 vcl::Region aRegion( tools::Rectangle( aPoint,
1645 Size( mnOutWidth, mnOutHeight ) ) );
1646 if ( mpWindowImpl->mbWinRegion )
1647 aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
1648 ImplClipBoundaries( aRegion, false, true );
1649 if ( !pOverlapRegion->IsEmpty() )
1650 {
1651 pOverlapRegion->Move( mnOutOffX-nOldOutOffX, mnOutOffY-nOldOutOffY );
1652 aRegion.Exclude( *pOverlapRegion );
1653 }
1654 if ( !aRegion.IsEmpty() )
1655 {
1656 // adapt Paint areas
1657 ImplMoveAllInvalidateRegions( tools::Rectangle( Point( nOldOutOffX, nOldOutOffY ),
1658 Size( nOldOutWidth, nOldOutHeight ) ),
1659 mnOutOffX-nOldOutOffX, mnOutOffY-nOldOutOffY,
1660 true );
1661 SalGraphics* pGraphics = ImplGetFrameGraphics();
1662 if ( pGraphics )
1663 {
1664
1665 OutputDevice *pOutDev = GetOutDev();
1666 const bool bSelectClipRegion = pOutDev->SelectClipRegion( aRegion, pGraphics );
1667 if ( bSelectClipRegion )
1668 {
1669 pGraphics->CopyArea( mnOutOffX, mnOutOffY,
1670 nOldOutOffX, nOldOutOffY,
1671 nOldOutWidth, nOldOutHeight,
1672 this );
1673 }
1674 else
1675 bInvalidate = true;
1676 }
1677 else
1678 bInvalidate = true;
1679 if ( !bInvalidate )
1680 {
1681 if ( !pOverlapRegion->IsEmpty() )
1682 ImplInvalidateFrameRegion( pOverlapRegion.get(), InvalidateFlags::Children );
1683 }
1684 }
1685 else
1686 bInvalidate = true;
1687 }
1688 else
1689 bInvalidate = true;
1690 if ( bInvalidate )
1691 ImplInvalidateFrameRegion( nullptr, InvalidateFlags::Children );
1692 }
1693 else
1694 {
1695 Point aPoint( mnOutOffX, mnOutOffY );
1696 vcl::Region aRegion( tools::Rectangle( aPoint,
1697 Size( mnOutWidth, mnOutHeight ) ) );
1698 aRegion.Exclude( *pOldRegion );
1699 if ( mpWindowImpl->mbWinRegion )
1700 aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
1701 ImplClipBoundaries( aRegion, false, true );
1702 if ( !aRegion.IsEmpty() )
1703 ImplInvalidateFrameRegion( &aRegion, InvalidateFlags::Children );
1704 }
1705 }
1706
1707 // invalidate Parent or Overlaps
1708 if ( bNewPos ||
1709 (mnOutWidth < nOldOutWidth) || (mnOutHeight < nOldOutHeight) )
1710 {
1711 vcl::Region aRegion( *pOldRegion );
1712 if ( !mpWindowImpl->mbPaintTransparent )
1713 ImplExcludeWindowRegion( aRegion );
1714 ImplClipBoundaries( aRegion, false, true );
1715 if ( !aRegion.IsEmpty() && !mpWindowImpl->mpBorderWindow )
1716 ImplInvalidateParentFrameRegion( aRegion );
1717 }
1718 }
1719
1720 // adapt system objects
1721 if ( bUpdateSysObjClip )
1722 ImplUpdateSysObjClip();
1723 if ( bUpdateSysObjPos )
1724 ImplUpdateSysObjPos();
1725 if ( bNewSize && mpWindowImpl->mpSysObj )
1726 mpWindowImpl->mpSysObj->SetPosSize( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight );
1727}
1728
1729void Window::ImplNewInputContext()
1730{
1731 ImplSVData* pSVData = ImplGetSVData();
1732 vcl::Window* pFocusWin = pSVData->mpWinData->mpFocusWin;
1733 if ( !pFocusWin || pFocusWin->IsDisposed() )
1734 return;
1735
1736 // Is InputContext changed?
1737 const InputContext& rInputContext = pFocusWin->GetInputContext();
1738 if ( rInputContext == pFocusWin->mpWindowImpl->mpFrameData->maOldInputContext )
1739 return;
1740
1741 pFocusWin->mpWindowImpl->mpFrameData->maOldInputContext = rInputContext;
1742
1743 SalInputContext aNewContext;
1744 const vcl::Font& rFont = rInputContext.GetFont();
1745 const OUString& rFontName = rFont.GetFamilyName();
1746 rtl::Reference<LogicalFontInstance> pFontInstance;
1747 aNewContext.mpFont = nullptr;
1748 if (!rFontName.isEmpty())
1749 {
1750 OutputDevice *pFocusWinOutDev = pFocusWin->GetOutDev();
1751 Size aSize = pFocusWinOutDev->ImplLogicToDevicePixel( rFont.GetFontSize() );
1752 if ( !aSize.Height() )
1753 {
1754 // only set default sizes if the font height in logical
1755 // coordinates equals 0
1756 if ( rFont.GetFontSize().Height() )
1757 aSize.setHeight( 1 );
1758 else
1759 aSize.setHeight( (12*pFocusWin->mnDPIY)/72 );
1760 }
1761 pFontInstance = pFocusWin->mxFontCache->GetFontInstance( pFocusWin->mxFontCollection.get(),
1762 rFont, aSize, static_cast<float>(aSize.Height()) );
1763 if ( pFontInstance )
1764 aNewContext.mpFont = pFontInstance;
1765 }
1766 aNewContext.mnOptions = rInputContext.GetOptions();
1767 pFocusWin->ImplGetFrame()->SetInputContext( &aNewContext );
1768}
1769
1770void Window::SetDumpAsPropertyTreeHdl(const Link<tools::JsonWriter&, void>& rLink)
1771{
1772 if (mpWindowImpl) // may be called after dispose
1773 {
1774 mpWindowImpl->maDumpAsPropertyTreeHdl = rLink;
1775 }
1776}
1777
1778void Window::SetModalHierarchyHdl(const Link<bool, void>& rLink)
1779{
1780 ImplGetFrame()->SetModalHierarchyHdl(rLink);
1781}
1782
1783void Window::SetParentToDefaultWindow()
1784{
1785 Show(false);
1786 SetParent(ImplGetDefaultWindow());
1787}
1788
1789KeyIndicatorState Window::GetIndicatorState() const
1790{
1791 return mpWindowImpl->mpFrame->GetIndicatorState();
1792}
1793
1794void Window::SimulateKeyPress( sal_uInt16 nKeyCode ) const
1795{
1796 mpWindowImpl->mpFrame->SimulateKeyPress(nKeyCode);
1797}
1798
1799void Window::KeyInput( const KeyEvent& rKEvt )
1800{
1801 KeyCode cod = rKEvt.GetKeyCode ();
1802 bool autoacc = ImplGetSVData()->maNWFData.mbAutoAccel;
1803
1804 // do not respond to accelerators unless Alt or Ctrl is held */
1805 if (cod.GetCode () >= 0x200 && cod.GetCode () <= 0x219)
1806 {
1807 if (autoacc && cod.GetModifier () != KEY_MOD2 && !(cod.GetModifier() & KEY_MOD1))
1808 return;
1809 }
1810
1811 NotifyEvent aNEvt( MouseNotifyEvent::KEYINPUT, this, &rKEvt );
1812 if ( !CompatNotify( aNEvt ) )
1813 mpWindowImpl->mbKeyInput = true;
1814}
1815
1816void Window::KeyUp( const KeyEvent& rKEvt )
1817{
1818 NotifyEvent aNEvt( MouseNotifyEvent::KEYUP, this, &rKEvt );
1819 if ( !CompatNotify( aNEvt ) )
1820 mpWindowImpl->mbKeyUp = true;
1821}
1822
1823void Window::Draw( OutputDevice*, const Point&, DrawFlags )
1824{
1825}
1826
1827void Window::Move() {}
1828
1829void Window::Resize() {}
1830
1831void Window::Activate() {}
1832
1833void Window::Deactivate() {}
1834
1835void Window::GetFocus()
1836{
1837 if ( HasFocus() && mpWindowImpl->mpLastFocusWindow && !(mpWindowImpl->mnDlgCtrlFlags & DialogControlFlags::WantFocus) )
1838 {
1839 VclPtr<vcl::Window> xWindow(this);
1840 mpWindowImpl->mpLastFocusWindow->GrabFocus();
1841 if( xWindow->IsDisposed() )
1842 return;
1843 }
1844
1845 NotifyEvent aNEvt( MouseNotifyEvent::GETFOCUS, this );
1846 CompatNotify( aNEvt );
1847}
1848
1849void Window::LoseFocus()
1850{
1851 NotifyEvent aNEvt( MouseNotifyEvent::LOSEFOCUS, this );
1852 CompatNotify( aNEvt );
1853}
1854
1855void Window::SetHelpHdl(const Link<vcl::Window&, bool>& rLink)
1856{
1857 if (mpWindowImpl) // may be called after dispose
1858 {
1859 mpWindowImpl->maHelpRequestHdl = rLink;
1860 }
1861}
1862
1863void Window::RequestHelp( const HelpEvent& rHEvt )
1864{
1865 // if Balloon-Help is requested, show the balloon
1866 // with help text set
1867 if ( rHEvt.GetMode() & HelpEventMode::BALLOON )
1868 {
1869 OUString rStr = GetHelpText();
1870 if ( rStr.isEmpty() )
1871 rStr = GetQuickHelpText();
1872 if ( rStr.isEmpty() && ImplGetParent() && !ImplIsOverlapWindow() )
1873 ImplGetParent()->RequestHelp( rHEvt );
1874 else
1875 {
1876 Point aPos = GetPosPixel();
1877 if ( ImplGetParent() && !ImplIsOverlapWindow() )
1878 aPos = OutputToScreenPixel(Point(0, 0));
1879 tools::Rectangle aRect( aPos, GetSizePixel() );
1880
1881 Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), aRect, rStr );
1882 }
1883 }
1884 else if ( rHEvt.GetMode() & HelpEventMode::QUICK )
1885 {
1886 const OUString& rStr = GetQuickHelpText();
1887 if ( rStr.isEmpty() && ImplGetParent() && !ImplIsOverlapWindow() )
1888 ImplGetParent()->RequestHelp( rHEvt );
1889 else
1890 {
1891 Point aPos = GetPosPixel();
1892 if ( ImplGetParent() && !ImplIsOverlapWindow() )
1893 aPos = OutputToScreenPixel(Point(0, 0));
1894 tools::Rectangle aRect( aPos, GetSizePixel() );
1895 Help::ShowQuickHelp( this, aRect, rStr, QuickHelpFlags::CtrlText );
1896 }
1897 }
1898 else if (!mpWindowImpl->maHelpRequestHdl.IsSet() || mpWindowImpl->maHelpRequestHdl.Call(*this))
1899 {
1900 OUString aStrHelpId( OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)) ) );
1901 if ( aStrHelpId.isEmpty() && ImplGetParent() )
1902 ImplGetParent()->RequestHelp( rHEvt );
1903 else
1904 {
1905 Help* pHelp = Application::GetHelp();
1906 if ( pHelp )
1907 {
1908 if( !aStrHelpId.isEmpty() )
1909 pHelp->Start( aStrHelpId, this );
1910 else
1911 pHelp->Start( OOO_HELP_INDEX".help:index", this );
1912 }
1913 }
1914 }
1915}
1916
1917void Window::Command( const CommandEvent& rCEvt )
1918{
1919 CallEventListeners( VclEventId::WindowCommand, const_cast<CommandEvent *>(&rCEvt) );
1920
1921 NotifyEvent aNEvt( MouseNotifyEvent::COMMAND, this, &rCEvt );
1922 if ( !CompatNotify( aNEvt ) )
1923 mpWindowImpl->mbCommand = true;
1924}
1925
1926void Window::Tracking( const TrackingEvent& rTEvt )
1927{
1928
1929 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1930 if( pWrapper )
1931 pWrapper->Tracking( rTEvt );
1932}
1933
1934void Window::StateChanged(StateChangedType eType)
1935{
1936 switch (eType)
1937 {
1938 //stuff that doesn't invalidate the layout
1939 case StateChangedType::ControlForeground:
1940 case StateChangedType::ControlBackground:
1941 case StateChangedType::UpdateMode:
1942 case StateChangedType::ReadOnly:
1943 case StateChangedType::Enable:
1944 case StateChangedType::State:
1945 case StateChangedType::Data:
1946 case StateChangedType::InitShow:
1947 case StateChangedType::ControlFocus:
1948 break;
1949 //stuff that does invalidate the layout
1950 default:
1951 queue_resize(eType);
1952 break;
1953 }
1954}
1955
1956void Window::SetStyle( WinBits nStyle )
1957{
1958 if ( mpWindowImpl && mpWindowImpl->mnStyle != nStyle )
1959 {
1960 mpWindowImpl->mnPrevStyle = mpWindowImpl->mnStyle;
1961 mpWindowImpl->mnStyle = nStyle;
1962 CompatStateChanged( StateChangedType::Style );
1963 }
1964}
1965
1966void Window::SetExtendedStyle( WindowExtendedStyle nExtendedStyle )
1967{
1968
1969 if ( mpWindowImpl->mnExtendedStyle == nExtendedStyle )
1970 return;
1971
1972 vcl::Window* pWindow = ImplGetBorderWindow();
1973 if( ! pWindow )
1974 pWindow = this;
1975 if( pWindow->mpWindowImpl->mbFrame )
1976 {
1977 SalExtStyle nExt = 0;
1978 if( nExtendedStyle & WindowExtendedStyle::Document )
1979 nExt |= SAL_FRAME_EXT_STYLE_DOCUMENTSalExtStyle(0x00000001);
1980 if( nExtendedStyle & WindowExtendedStyle::DocModified )
1981 nExt |= SAL_FRAME_EXT_STYLE_DOCMODIFIEDSalExtStyle(0x00000002);
1982
1983 pWindow->ImplGetFrame()->SetExtendedFrameStyle( nExt );
1984 }
1985 mpWindowImpl->mnExtendedStyle = nExtendedStyle;
1986}
1987
1988void Window::SetBorderStyle( WindowBorderStyle nBorderStyle )
1989{
1990
1991 if ( !mpWindowImpl->mpBorderWindow )
1
Taking false branch
1992 return;
1993
1994 if( nBorderStyle == WindowBorderStyle::REMOVEBORDER &&
2
Assuming 'nBorderStyle' is equal to REMOVEBORDER
4
Taking true branch
1995 ! mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame &&
3
Assuming field 'mbFrame' is false
1996 mpWindowImpl->mpBorderWindow->mpWindowImpl->mpParent
1997 )
1998 {
1999 // this is a little awkward: some controls (e.g. svtools ProgressBar)
2000 // cannot avoid getting constructed with WB_BORDER but want to disable
2001 // borders in case of NWF drawing. So they need a method to remove their border window
2002 VclPtr<vcl::Window> pBorderWin = mpWindowImpl->mpBorderWindow;
2003 // remove us as border window's client
2004 pBorderWin->mpWindowImpl->mpClientWindow = nullptr;
2005 mpWindowImpl->mpBorderWindow = nullptr;
2006 mpWindowImpl->mpRealParent = pBorderWin->mpWindowImpl->mpParent;
2007 // reparent us above the border window
2008 SetParent( pBorderWin->mpWindowImpl->mpParent );
2009 // set us to the position and size of our previous border
2010 Point aBorderPos( pBorderWin->GetPosPixel() );
2011 Size aBorderSize( pBorderWin->GetSizePixel() );
2012 setPosSizePixel( aBorderPos.X(), aBorderPos.Y(), aBorderSize.Width(), aBorderSize.Height() );
5
Calling 'Window::setPosSizePixel'
2013 // release border window
2014 pBorderWin.disposeAndClear();
2015
2016 // set new style bits
2017 SetStyle( GetStyle() & (~WB_BORDER) );
2018 }
2019 else
2020 {
2021 if ( mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW )
2022 static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->SetBorderStyle( nBorderStyle );
2023 else
2024 mpWindowImpl->mpBorderWindow->SetBorderStyle( nBorderStyle );
2025 }
2026}
2027
2028WindowBorderStyle Window::GetBorderStyle() const
2029{
2030
2031 if ( mpWindowImpl->mpBorderWindow )
2032 {
2033 if ( mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW )
2034 return static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->GetBorderStyle();
2035 else
2036 return mpWindowImpl->mpBorderWindow->GetBorderStyle();
2037 }
2038
2039 return WindowBorderStyle::NONE;
2040}
2041
2042long Window::CalcTitleWidth() const
2043{
2044
2045 if ( mpWindowImpl->mpBorderWindow )
2046 {
2047 if ( mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW )
2048 return static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->CalcTitleWidth();
2049 else
2050 return mpWindowImpl->mpBorderWindow->CalcTitleWidth();
2051 }
2052 else if ( mpWindowImpl->mbFrame && (mpWindowImpl->mnStyle & WB_MOVEABLE) )
2053 {
2054 // we guess the width for frame windows as we do not know the
2055 // border of external dialogs
2056 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
2057 vcl::Font aFont = GetFont();
2058 const_cast<vcl::Window*>(this)->SetPointFont(*const_cast<Window*>(this), rStyleSettings.GetTitleFont());
2059 long nTitleWidth = GetTextWidth( GetText() );
2060 const_cast<vcl::Window*>(this)->SetFont( aFont );
2061 nTitleWidth += rStyleSettings.GetTitleHeight() * 3;
2062 nTitleWidth += StyleSettings::GetBorderSize() * 2;
2063 nTitleWidth += 10;
2064 return nTitleWidth;
2065 }
2066
2067 return 0;
2068}
2069
2070void Window::SetInputContext( const InputContext& rInputContext )
2071{
2072
2073 mpWindowImpl->maInputContext = rInputContext;
2074 if ( !mpWindowImpl->mbInFocusHdl && HasFocus() )
2075 ImplNewInputContext();
2076}
2077
2078void Window::PostExtTextInputEvent(VclEventId nType, const OUString& rText)
2079{
2080 switch (nType)
2081 {
2082 case VclEventId::ExtTextInput:
2083 {
2084 std::unique_ptr<ExtTextInputAttr[]> pAttr(new ExtTextInputAttr[rText.getLength()]);
2085 for (int i = 0; i < rText.getLength(); ++i) {
2086 pAttr[i] = ExtTextInputAttr::Underline;
2087 }
2088 SalExtTextInputEvent aEvent { rText, pAttr.get(), rText.getLength(), EXTTEXTINPUT_CURSOR_OVERWRITE(sal_uInt16(0x0002)) };
2089 ImplWindowFrameProc(this, SalEvent::ExtTextInput, &aEvent);
2090 }
2091 break;
2092 case VclEventId::EndExtTextInput:
2093 ImplWindowFrameProc(this, SalEvent::EndExtTextInput, nullptr);
2094 break;
2095 default:
2096 assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail (
"false", "/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
, 2096, __extension__ __PRETTY_FUNCTION__))
;
2097 }
2098}
2099
2100void Window::EndExtTextInput()
2101{
2102 if ( mpWindowImpl->mbExtTextInput )
2103 ImplGetFrame()->EndExtTextInput( EndExtTextInputFlags::Complete );
2104}
2105
2106void Window::SetCursorRect( const tools::Rectangle* pRect, long nExtTextInputWidth )
2107{
2108
2109 ImplWinData* pWinData = ImplGetWinData();
2110 if ( pWinData->mpCursorRect )
2111 {
2112 if ( pRect )
2113 pWinData->mpCursorRect = *pRect;
2114 else
2115 pWinData->mpCursorRect.reset();
2116 }
2117 else
2118 {
2119 if ( pRect )
2120 pWinData->mpCursorRect = *pRect;
2121 }
2122
2123 pWinData->mnCursorExtWidth = nExtTextInputWidth;
2124
2125}
2126
2127const tools::Rectangle* Window::GetCursorRect() const
2128{
2129
2130 ImplWinData* pWinData = ImplGetWinData();
2131 return pWinData->mpCursorRect ? &*pWinData->mpCursorRect : nullptr;
2132}
2133
2134long Window::GetCursorExtTextInputWidth() const
2135{
2136
2137 ImplWinData* pWinData = ImplGetWinData();
2138 return pWinData->mnCursorExtWidth;
2139}
2140
2141void Window::SetCompositionCharRect( const tools::Rectangle* pRect, long nCompositionLength, bool bVertical ) {
2142
2143 ImplWinData* pWinData = ImplGetWinData();
2144 pWinData->mpCompositionCharRects.reset();
2145 pWinData->mbVertical = bVertical;
2146 pWinData->mnCompositionCharRects = nCompositionLength;
2147 if ( pRect && (nCompositionLength > 0) )
2148 {
2149 pWinData->mpCompositionCharRects.reset( new tools::Rectangle[nCompositionLength] );
2150 for (long i = 0; i < nCompositionLength; ++i)
2151 pWinData->mpCompositionCharRects[i] = pRect[i];
2152 }
2153}
2154
2155void Window::CollectChildren(::std::vector<vcl::Window *>& rAllChildren )
2156{
2157 rAllChildren.push_back( this );
2158
2159 VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
2160 while ( pChild )
2161 {
2162 pChild->CollectChildren( rAllChildren );
2163 pChild = pChild->mpWindowImpl->mpNext;
2164 }
2165}
2166
2167void Window::SetPointFont(vcl::RenderContext& rRenderContext, const vcl::Font& rFont)
2168{
2169 vcl::Font aFont = rFont;
2170 ImplPointToLogic(rRenderContext, aFont);
2171 rRenderContext.SetFont(aFont);
2172}
2173
2174vcl::Font Window::GetPointFont(vcl::RenderContext const & rRenderContext) const
2175{
2176 vcl::Font aFont = rRenderContext.GetFont();
2177 ImplLogicToPoint(rRenderContext, aFont);
2178 return aFont;
2179}
2180
2181void Window::Show(bool bVisible, ShowFlags nFlags)
2182{
2183 if ( IsDisposed() || mpWindowImpl->mbVisible == bVisible )
2184 return;
2185
2186 VclPtr<vcl::Window> xWindow(this);
2187
2188 bool bRealVisibilityChanged = false;
2189 mpWindowImpl->mbVisible = bVisible;
2190
2191 if ( !bVisible )
2192 {
2193 ImplHideAllOverlaps();
2194 if( xWindow->IsDisposed() )
2195 return;
2196
2197 if ( mpWindowImpl->mpBorderWindow )
2198 {
2199 bool bOldUpdate = mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate;
2200 if ( mpWindowImpl->mbNoParentUpdate )
2201 mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate = true;
2202 mpWindowImpl->mpBorderWindow->Show( false, nFlags );
2203 mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate = bOldUpdate;
2204 }
2205 else if ( mpWindowImpl->mbFrame )
2206 {
2207 mpWindowImpl->mbSuppressAccessibilityEvents = true;
2208 mpWindowImpl->mpFrame->Show( false );
2209 }
2210
2211 CompatStateChanged( StateChangedType::Visible );
2212
2213 if ( mpWindowImpl->mbReallyVisible )
2214 {
2215 if ( mpWindowImpl->mbInitWinClipRegion )
2216 ImplInitWinClipRegion();
2217
2218 vcl::Region aInvRegion = mpWindowImpl->maWinClipRegion;
2219
2220 if( xWindow->IsDisposed() )
2221 return;
2222
2223 bRealVisibilityChanged = mpWindowImpl->mbReallyVisible;
2224 ImplResetReallyVisible();
2225 ImplSetClipFlag();
2226
2227 if ( ImplIsOverlapWindow() && !mpWindowImpl->mbFrame )
2228 {
2229 // convert focus
2230 if ( !(nFlags & ShowFlags::NoFocusChange) && HasChildPathFocus() )
2231 {
2232 if ( mpWindowImpl->mpOverlapWindow->IsEnabled() &&
2233 mpWindowImpl->mpOverlapWindow->IsInputEnabled() &&
2234 ! mpWindowImpl->mpOverlapWindow->IsInModalMode()
2235 )
2236 mpWindowImpl->mpOverlapWindow->GrabFocus();
2237 }
2238 }
2239
2240 if ( !mpWindowImpl->mbFrame )
2241 {
2242 if (mpWindowImpl->mpWinData && mpWindowImpl->mpWinData->mbEnableNativeWidget)
2243 {
2244 /*
2245 * #i48371# native theming: some themes draw outside the control
2246 * area we tell them to (bad thing, but we cannot do much about it ).
2247 * On hiding these controls they get invalidated with their window rectangle
2248 * which leads to the parts outside the control area being left and not
2249 * invalidated. Workaround: invalidate an area on the parent, too
2250 */
2251 const int workaround_border = 5;
2252 tools::Rectangle aBounds( aInvRegion.GetBoundRect() );
2253 aBounds.AdjustLeft( -workaround_border );
2254 aBounds.AdjustTop( -workaround_border );
2255 aBounds.AdjustRight(workaround_border );
2256 aBounds.AdjustBottom(workaround_border );
2257 aInvRegion = aBounds;
2258 }
2259 if ( !mpWindowImpl->mbNoParentUpdate )
2260 {
2261 if ( !aInvRegion.IsEmpty() )
2262 ImplInvalidateParentFrameRegion( aInvRegion );
2263 }
2264 ImplGenerateMouseMove();
2265 }
2266 }
2267 }
2268 else
2269 {
2270 // inherit native widget flag for form controls
2271 // required here, because frames never show up in the child hierarchy - which should be fixed...
2272 // eg, the drop down of a combobox which is a system floating window
2273 if( mpWindowImpl->mbFrame && GetParent() && GetParent()->IsCompoundControl() &&
2274 GetParent()->IsNativeWidgetEnabled() != IsNativeWidgetEnabled() &&
2275 !(GetStyle() & WB_TOOLTIPWIN) )
2276 {
2277 EnableNativeWidget( GetParent()->IsNativeWidgetEnabled() );
2278 }
2279
2280 if ( mpWindowImpl->mbCallMove )
2281 {
2282 ImplCallMove();
2283 }
2284 if ( mpWindowImpl->mbCallResize )
2285 {
2286 ImplCallResize();
2287 }
2288
2289 CompatStateChanged( StateChangedType::Visible );
2290
2291 vcl::Window* pTestParent;
2292 if ( ImplIsOverlapWindow() )
2293 pTestParent = mpWindowImpl->mpOverlapWindow;
2294 else
2295 pTestParent = ImplGetParent();
2296 if ( mpWindowImpl->mbFrame || pTestParent->mpWindowImpl->mbReallyVisible )
2297 {
2298 // if a window becomes visible, send all child windows a StateChange,
2299 // such that these can initialise themselves
2300 ImplCallInitShow();
2301
2302 // If it is a SystemWindow it automatically pops up on top of
2303 // all other windows if needed.
2304 if ( ImplIsOverlapWindow() && !(nFlags & ShowFlags::NoActivate) )
2305 {
2306 ImplStartToTop(( nFlags & ShowFlags::ForegroundTask ) ? ToTopFlags::ForegroundTask : ToTopFlags::NONE );
2307 ImplFocusToTop( ToTopFlags::NONE, false );
2308 }
2309
2310 // adjust mpWindowImpl->mbReallyVisible
2311 bRealVisibilityChanged = !mpWindowImpl->mbReallyVisible;
2312 ImplSetReallyVisible();
2313
2314 // assure clip rectangles will be recalculated
2315 ImplSetClipFlag();
2316
2317 if ( !mpWindowImpl->mbFrame )
2318 {
2319 InvalidateFlags nInvalidateFlags = InvalidateFlags::Children;
2320 if( ! IsPaintTransparent() )
2321 nInvalidateFlags |= InvalidateFlags::NoTransparent;
2322 ImplInvalidate( nullptr, nInvalidateFlags );
2323 ImplGenerateMouseMove();
2324 }
2325 }
2326
2327 if ( mpWindowImpl->mpBorderWindow )
2328 mpWindowImpl->mpBorderWindow->Show( true, nFlags );
2329 else if ( mpWindowImpl->mbFrame )
2330 {
2331 // #106431#, hide SplashScreen
2332 ImplSVData* pSVData = ImplGetSVData();
2333 if ( !pSVData->mpIntroWindow )
2334 {
2335 // The right way would be just to call this (not even in the 'if')
2336 auto pApp = GetpApp();
2337 if ( pApp )
2338 pApp->InitFinished();
2339 }
2340 else if ( !ImplIsWindowOrChild( pSVData->mpIntroWindow ) )
2341 {
2342 // ... but the VCL splash is broken, and it needs this
2343 // (for ./soffice .uno:NewDoc)
2344 pSVData->mpIntroWindow->Hide();
2345 }
2346
2347 //SAL_WARN_IF( mpWindowImpl->mbSuppressAccessibilityEvents, "vcl", "Window::Show() - Frame reactivated");
2348 mpWindowImpl->mbSuppressAccessibilityEvents = false;
2349
2350 mpWindowImpl->mbPaintFrame = true;
2351 if (!Application::IsHeadlessModeEnabled())
2352 {
2353 bool bNoActivate(nFlags & (ShowFlags::NoActivate|ShowFlags::NoFocusChange));
2354 mpWindowImpl->mpFrame->Show( true, bNoActivate );
2355 }
2356 if( xWindow->IsDisposed() )
2357 return;
2358
2359 // Query the correct size of the window, if we are waiting for
2360 // a system resize
2361 if ( mpWindowImpl->mbWaitSystemResize )
2362 {
2363 long nOutWidth;
2364 long nOutHeight;
2365 mpWindowImpl->mpFrame->GetClientSize( nOutWidth, nOutHeight );
2366 ImplHandleResize( this, nOutWidth, nOutHeight );
2367 }
2368
2369 if (mpWindowImpl->mpFrameData->mpBuffer && mpWindowImpl->mpFrameData->mpBuffer->GetOutputSizePixel() != GetOutputSizePixel())
2370 // Make sure that the buffer size matches the window size, even if no resize was needed.
2371 mpWindowImpl->mpFrameData->mpBuffer->SetOutputSizePixel(GetOutputSizePixel());
2372 }
2373
2374 if( xWindow->IsDisposed() )
2375 return;
2376
2377 ImplShowAllOverlaps();
2378 }
2379
2380 if( xWindow->IsDisposed() )
2381 return;
2382
2383 // the SHOW/HIDE events also serve as indicators to send child creation/destroy events to the access bridge
2384 // However, the access bridge only uses this event if the data member is not NULL (it's kind of a hack that
2385 // we re-use the SHOW/HIDE events this way, with this particular semantics).
2386 // Since #104887#, the notifications for the access bridge are done in Impl(Set|Reset)ReallyVisible. Here, we
2387 // now only notify with a NULL data pointer, for all other clients except the access bridge.
2388 if ( !bRealVisibilityChanged )
2389 CallEventListeners( mpWindowImpl->mbVisible ? VclEventId::WindowShow : VclEventId::WindowHide );
2390 if( xWindow->IsDisposed() )
2391 return;
2392
2393}
2394
2395Size Window::GetSizePixel() const
2396{
2397 if (!mpWindowImpl)
2398 {
2399 SAL_WARN("vcl.layout", "WTF no windowimpl")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "vcl.layout")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "WTF no windowimpl") ==
1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "2399" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "WTF no windowimpl"), 0); } else { ::
std::ostringstream sal_detail_stream; sal_detail_stream <<
"WTF no windowimpl"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "2399" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "WTF no windowimpl") == 1) { ::sal_detail_log( (::
SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "2399" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "WTF no windowimpl"), 0); } else { ::
std::ostringstream sal_detail_stream; sal_detail_stream <<
"WTF no windowimpl"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "2399" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2400 return Size(0,0);
2401 }
2402
2403 // #i43257# trigger pending resize handler to assure correct window sizes
2404 if( mpWindowImpl->mpFrameData->maResizeIdle.IsActive() )
2405 {
2406 VclPtr<vcl::Window> xWindow( const_cast<Window*>(this) );
2407 mpWindowImpl->mpFrameData->maResizeIdle.Stop();
2408 mpWindowImpl->mpFrameData->maResizeIdle.Invoke( nullptr );
2409 if( xWindow->IsDisposed() )
2410 return Size(0,0);
2411 }
2412
2413 return Size( mnOutWidth+mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder,
2414 mnOutHeight+mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder );
2415}
2416
2417void Window::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
2418 sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
2419{
2420 rLeftBorder = mpWindowImpl->mnLeftBorder;
2421 rTopBorder = mpWindowImpl->mnTopBorder;
2422 rRightBorder = mpWindowImpl->mnRightBorder;
2423 rBottomBorder = mpWindowImpl->mnBottomBorder;
2424}
2425
2426void Window::Enable( bool bEnable, bool bChild )
2427{
2428 if ( IsDisposed() )
2429 return;
2430
2431 if ( !bEnable )
2432 {
2433 // the tracking mode will be stopped or the capture will be stolen
2434 // when a window is disabled,
2435 if ( IsTracking() )
2436 EndTracking( TrackingEventFlags::Cancel );
2437 if ( IsMouseCaptured() )
2438 ReleaseMouse();
2439 // try to pass focus to the next control
2440 // if the window has focus and is contained in the dialog control
2441 // mpWindowImpl->mbDisabled should only be set after a call of ImplDlgCtrlNextWindow().
2442 // Otherwise ImplDlgCtrlNextWindow() should be used
2443 if ( HasFocus() )
2444 ImplDlgCtrlNextWindow();
2445 }
2446
2447 if ( mpWindowImpl->mpBorderWindow )
2448 {
2449 mpWindowImpl->mpBorderWindow->Enable( bEnable, false );
2450 if ( (mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW) &&
2451 static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->mpMenuBarWindow )
2452 static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->mpMenuBarWindow->Enable( bEnable );
2453 }
2454
2455 // #i56102# restore app focus win in case the
2456 // window was disabled when the frame focus changed
2457 ImplSVData* pSVData = ImplGetSVData();
2458 if (bEnable && pSVData->mpWinData->mpFocusWin == nullptr
2459 && mpWindowImpl->mpFrameData->mbHasFocus && mpWindowImpl->mpFrameData->mpFocusWin == this)
2460 pSVData->mpWinData->mpFocusWin = this;
2461
2462 if ( mpWindowImpl->mbDisabled != !bEnable )
2463 {
2464 mpWindowImpl->mbDisabled = !bEnable;
2465 if ( mpWindowImpl->mpSysObj )
2466 mpWindowImpl->mpSysObj->Enable( bEnable && !mpWindowImpl->mbInputDisabled );
2467 CompatStateChanged( StateChangedType::Enable );
2468
2469 CallEventListeners( bEnable ? VclEventId::WindowEnabled : VclEventId::WindowDisabled );
2470 }
2471
2472 if ( bChild )
2473 {
2474 VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
2475 while ( pChild )
2476 {
2477 pChild->Enable( bEnable, bChild );
2478 pChild = pChild->mpWindowImpl->mpNext;
2479 }
2480 }
2481
2482 if ( IsReallyVisible() )
2483 ImplGenerateMouseMove();
2484}
2485
2486void Window::EnableInput( bool bEnable, bool bChild )
2487{
2488 if (!mpWindowImpl)
2489 return;
2490
2491 bool bNotify = (bEnable != mpWindowImpl->mbInputDisabled);
2492 if ( mpWindowImpl->mpBorderWindow )
2493 {
2494 mpWindowImpl->mpBorderWindow->EnableInput( bEnable, false );
2495 if ( (mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW) &&
2496 static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->mpMenuBarWindow )
2497 static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->mpMenuBarWindow->EnableInput( bEnable );
2498 }
2499
2500 if ( (!bEnable && mpWindowImpl->meAlwaysInputMode != AlwaysInputEnabled) || bEnable )
2501 {
2502 // automatically stop the tracking mode or steal capture
2503 // if the window is disabled
2504 if ( !bEnable )
2505 {
2506 if ( IsTracking() )
2507 EndTracking( TrackingEventFlags::Cancel );
2508 if ( IsMouseCaptured() )
2509 ReleaseMouse();
2510 }
2511
2512 if ( mpWindowImpl->mbInputDisabled != !bEnable )
2513 {
2514 mpWindowImpl->mbInputDisabled = !bEnable;
2515 if ( mpWindowImpl->mpSysObj )
2516 mpWindowImpl->mpSysObj->Enable( !mpWindowImpl->mbDisabled && bEnable );
2517 }
2518 }
2519
2520 // #i56102# restore app focus win in case the
2521 // window was disabled when the frame focus changed
2522 ImplSVData* pSVData = ImplGetSVData();
2523 if (bEnable && pSVData->mpWinData->mpFocusWin == nullptr
2524 && mpWindowImpl->mpFrameData->mbHasFocus && mpWindowImpl->mpFrameData->mpFocusWin == this)
2525 pSVData->mpWinData->mpFocusWin = this;
2526
2527 if ( bChild )
2528 {
2529 VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
2530 while ( pChild )
2531 {
2532 pChild->EnableInput( bEnable, bChild );
2533 pChild = pChild->mpWindowImpl->mpNext;
2534 }
2535 }
2536
2537 if ( IsReallyVisible() )
2538 ImplGenerateMouseMove();
2539
2540 // #104827# notify parent
2541 if ( bNotify && bEnable )
2542 {
2543 NotifyEvent aNEvt( MouseNotifyEvent::INPUTENABLE, this );
2544 CompatNotify( aNEvt );
2545 }
2546}
2547
2548void Window::EnableInput( bool bEnable, const vcl::Window* pExcludeWindow )
2549{
2550 if (!mpWindowImpl)
2551 return;
2552
2553 EnableInput( bEnable );
2554
2555 // pExecuteWindow is the first Overlap-Frame --> if this
2556 // shouldn't be the case, then this must be changed in dialog.cxx
2557 if( pExcludeWindow )
2558 pExcludeWindow = pExcludeWindow->ImplGetFirstOverlapWindow();
2559 vcl::Window* pSysWin = mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrameData->mpFirstOverlap;
2560 while ( pSysWin )
2561 {
2562 // Is Window in the path from this window
2563 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pSysWin, true ) )
2564 {
2565 // Is Window not in the exclude window path or not the
2566 // exclude window, then change the status
2567 if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( pSysWin, true ) )
2568 pSysWin->EnableInput( bEnable );
2569 }
2570 pSysWin = pSysWin->mpWindowImpl->mpNextOverlap;
2571 }
2572
2573 // enable/disable floating system windows as well
2574 vcl::Window* pFrameWin = ImplGetSVData()->maFrameData.mpFirstFrame;
2575 while ( pFrameWin )
2576 {
2577 if( pFrameWin->ImplIsFloatingWindow() )
2578 {
2579 // Is Window in the path from this window
2580 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pFrameWin, true ) )
2581 {
2582 // Is Window not in the exclude window path or not the
2583 // exclude window, then change the status
2584 if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( pFrameWin, true ) )
2585 pFrameWin->EnableInput( bEnable );
2586 }
2587 }
2588 pFrameWin = pFrameWin->mpWindowImpl->mpFrameData->mpNextFrame;
2589 }
2590
2591 // the same for ownerdraw floating windows
2592 if( !mpWindowImpl->mbFrame )
2593 return;
2594
2595 ::std::vector< VclPtr<vcl::Window> >& rList = mpWindowImpl->mpFrameData->maOwnerDrawList;
2596 for (auto const& elem : rList)
2597 {
2598 // Is Window in the path from this window
2599 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( elem, true ) )
2600 {
2601 // Is Window not in the exclude window path or not the
2602 // exclude window, then change the status
2603 if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( elem, true ) )
2604 elem->EnableInput( bEnable );
2605 }
2606 }
2607}
2608
2609void Window::AlwaysEnableInput( bool bAlways, bool bChild )
2610{
2611
2612 if ( mpWindowImpl->mpBorderWindow )
2613 mpWindowImpl->mpBorderWindow->AlwaysEnableInput( bAlways, false );
2614
2615 if( bAlways && mpWindowImpl->meAlwaysInputMode != AlwaysInputEnabled )
2616 {
2617 mpWindowImpl->meAlwaysInputMode = AlwaysInputEnabled;
2618 EnableInput(true, false);
2619 }
2620 else if( ! bAlways && mpWindowImpl->meAlwaysInputMode == AlwaysInputEnabled )
2621 {
2622 mpWindowImpl->meAlwaysInputMode = AlwaysInputNone;
2623 }
2624
2625 if ( bChild )
2626 {
2627 VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
2628 while ( pChild )
2629 {
2630 pChild->AlwaysEnableInput( bAlways, bChild );
2631 pChild = pChild->mpWindowImpl->mpNext;
2632 }
2633 }
2634}
2635
2636void Window::SetActivateMode( ActivateModeFlags nMode )
2637{
2638
2639 if ( mpWindowImpl->mpBorderWindow )
2640 mpWindowImpl->mpBorderWindow->SetActivateMode( nMode );
2641
2642 if ( mpWindowImpl->mnActivateMode == nMode )
2643 return;
2644
2645 mpWindowImpl->mnActivateMode = nMode;
2646
2647 // possibly trigger Deactivate/Activate
2648 if ( mpWindowImpl->mnActivateMode != ActivateModeFlags::NONE )
2649 {
2650 if ( (mpWindowImpl->mbActive || (GetType() == WindowType::BORDERWINDOW)) &&
2651 !HasChildPathFocus( true ) )
2652 {
2653 mpWindowImpl->mbActive = false;
2654 Deactivate();
2655 }
2656 }
2657 else
2658 {
2659 if ( !mpWindowImpl->mbActive || (GetType() == WindowType::BORDERWINDOW) )
2660 {
2661 mpWindowImpl->mbActive = true;
2662 Activate();
2663 }
2664 }
2665}
2666
2667void Window::setPosSizePixel( long nX, long nY,
2668 long nWidth, long nHeight, PosSizeFlags nFlags )
2669{
2670 bool bHasValidSize = !mpWindowImpl->mbDefSize;
6
Assuming field 'mbDefSize' is true
2671
2672 if ( nFlags & PosSizeFlags::Pos )
7
Taking true branch
2673 mpWindowImpl->mbDefPos = false;
2674 if ( nFlags & PosSizeFlags::Size )
8
Taking true branch
2675 mpWindowImpl->mbDefSize = false;
2676
2677 // The top BorderWindow is the window which is to be positioned
2678 VclPtr<vcl::Window> pWindow = this;
2679 while ( pWindow->mpWindowImpl->mpBorderWindow )
9
Loop condition is true. Entering loop body
23
Loop condition is false. Execution continues on line 2682
2680 pWindow = pWindow->mpWindowImpl->mpBorderWindow;
10
Calling implicit copy assignment operator for 'VclPtr<vcl::Window>'
11
Calling copy assignment operator for 'Reference<vcl::Window>'
21
Returning; memory was released
22
Returning; memory was released
2681
2682 if ( pWindow->mpWindowImpl->mbFrame )
24
Assuming field 'mbFrame' is false
25
Taking false branch
2683 {
2684 // Note: if we're positioning a frame, the coordinates are interpreted
2685 // as being the top-left corner of the window's client area and NOT
2686 // as the position of the border ! (due to limitations of several UNIX window managers)
2687 long nOldWidth = pWindow->mnOutWidth;
2688
2689 if ( !(nFlags & PosSizeFlags::Width) )
2690 nWidth = pWindow->mnOutWidth;
2691 if ( !(nFlags & PosSizeFlags::Height) )
2692 nHeight = pWindow->mnOutHeight;
2693
2694 sal_uInt16 nSysFlags=0;
2695 VclPtr<vcl::Window> pParent = GetParent();
2696 VclPtr<vcl::Window> pWinParent = pWindow->GetParent();
2697
2698 if( nFlags & PosSizeFlags::Width )
2699 nSysFlags |= SAL_FRAME_POSSIZE_WIDTH(sal_uInt16(0x0004));
2700 if( nFlags & PosSizeFlags::Height )
2701 nSysFlags |= SAL_FRAME_POSSIZE_HEIGHT(sal_uInt16(0x0008));
2702 if( nFlags & PosSizeFlags::X )
2703 {
2704 nSysFlags |= SAL_FRAME_POSSIZE_X(sal_uInt16(0x0001));
2705 if( pWinParent && (pWindow->GetStyle() & WB_SYSTEMCHILDWINDOW) )
2706 {
2707 nX += pWinParent->mnOutOffX;
2708 }
2709 if( pParent && pParent->ImplIsAntiparallel() )
2710 {
2711 tools::Rectangle aRect( Point ( nX, nY ), Size( nWidth, nHeight ) );
2712 const OutputDevice *pParentOutDev = pParent->GetOutDev();
2713 pParentOutDev->ReMirror( aRect );
2714 nX = aRect.Left();
2715 }
2716 }
2717 if( !(nFlags & PosSizeFlags::X) && bHasValidSize && pWindow->mpWindowImpl->mpFrame->maGeometry.nWidth )
2718 {
2719 // RTL: make sure the old right aligned position is not changed
2720 // system windows will always grow to the right
2721 if ( pWinParent )
2722 {
2723 OutputDevice *pParentOutDev = pWinParent->GetOutDev();
2724 if( pParentOutDev->HasMirroredGraphics() )
2725 {
2726 const SalFrameGeometry& aSysGeometry = mpWindowImpl->mpFrame->GetUnmirroredGeometry();
2727 const SalFrameGeometry& aParentSysGeometry =
2728 pWinParent->mpWindowImpl->mpFrame->GetUnmirroredGeometry();
2729 long myWidth = nOldWidth;
2730 if( !myWidth )
2731 myWidth = aSysGeometry.nWidth;
2732 if( !myWidth )
2733 myWidth = nWidth;
2734 nFlags |= PosSizeFlags::X;
2735 nSysFlags |= SAL_FRAME_POSSIZE_X(sal_uInt16(0x0001));
2736 nX = aParentSysGeometry.nX - aSysGeometry.nLeftDecoration + aParentSysGeometry.nWidth
2737 - myWidth - 1 - aSysGeometry.nX;
2738 }
2739 }
2740 }
2741 if( nFlags & PosSizeFlags::Y )
2742 {
2743 nSysFlags |= SAL_FRAME_POSSIZE_Y(sal_uInt16(0x0002));
2744 if( pWinParent && (pWindow->GetStyle() & WB_SYSTEMCHILDWINDOW) )
2745 {
2746 nY += pWinParent->mnOutOffY;
2747 }
2748 }
2749
2750 if( nSysFlags & (SAL_FRAME_POSSIZE_WIDTH(sal_uInt16(0x0004))|SAL_FRAME_POSSIZE_HEIGHT(sal_uInt16(0x0008))) )
2751 {
2752 // check for min/max client size and adjust size accordingly
2753 // otherwise it may happen that the resize event is ignored, i.e. the old size remains
2754 // unchanged but ImplHandleResize() is called with the wrong size
2755 SystemWindow *pSystemWindow = dynamic_cast< SystemWindow* >( pWindow.get() );
2756 if( pSystemWindow )
2757 {
2758 Size aMinSize = pSystemWindow->GetMinOutputSizePixel();
2759 Size aMaxSize = pSystemWindow->GetMaxOutputSizePixel();
2760 if( nWidth < aMinSize.Width() )
2761 nWidth = aMinSize.Width();
2762 if( nHeight < aMinSize.Height() )
2763 nHeight = aMinSize.Height();
2764
2765 if( nWidth > aMaxSize.Width() )
2766 nWidth = aMaxSize.Width();
2767 if( nHeight > aMaxSize.Height() )
2768 nHeight = aMaxSize.Height();
2769 }
2770 }
2771
2772 pWindow->mpWindowImpl->mpFrame->SetPosSize( nX, nY, nWidth, nHeight, nSysFlags );
2773
2774 // Adjust resize with the hack of different client size and frame geometries to fix
2775 // native menu bars. Eventually this should be replaced by proper mnTopBorder usage.
2776 pWindow->mpWindowImpl->mpFrame->GetClientSize(nWidth, nHeight);
2777
2778 // Resize should be called directly. If we haven't
2779 // set the correct size, we get a second resize from
2780 // the system with the correct size. This can be happened
2781 // if the size is too small or too large.
2782 ImplHandleResize( pWindow, nWidth, nHeight );
2783 }
2784 else
2785 {
2786 pWindow->ImplPosSizeWindow( nX, nY, nWidth, nHeight, nFlags );
2787 if ( IsReallyVisible() )
26
Use of memory after it is freed
2788 ImplGenerateMouseMove();
2789 }
2790}
2791
2792Point Window::GetPosPixel() const
2793{
2794 return mpWindowImpl->maPos;
2795}
2796
2797tools::Rectangle Window::GetDesktopRectPixel() const
2798{
2799 tools::Rectangle rRect;
2800 mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrame->GetWorkArea( rRect );
2801 return rRect;
2802}
2803
2804Point Window::OutputToScreenPixel( const Point& rPos ) const
2805{
2806 // relative to top level parent
2807 return Point( rPos.X()+mnOutOffX, rPos.Y()+mnOutOffY );
2808}
2809
2810Point Window::ScreenToOutputPixel( const Point& rPos ) const
2811{
2812 // relative to top level parent
2813 return Point( rPos.X()-mnOutOffX, rPos.Y()-mnOutOffY );
2814}
2815
2816long Window::ImplGetUnmirroredOutOffX()
2817{
2818 // revert mnOutOffX changes that were potentially made in ImplPosSizeWindow
2819 long offx = mnOutOffX;
2820 OutputDevice *pOutDev = GetOutDev();
2821 if( pOutDev->HasMirroredGraphics() )
2822 {
2823 if( mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() )
2824 {
2825 if ( !ImplIsOverlapWindow() )
2826 offx -= mpWindowImpl->mpParent->mnOutOffX;
2827
2828 offx = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - offx;
2829
2830 if ( !ImplIsOverlapWindow() )
2831 offx += mpWindowImpl->mpParent->mnOutOffX;
2832
2833 }
2834 }
2835 return offx;
2836}
2837
2838// normalized screen pixel are independent of mirroring
2839Point Window::OutputToNormalizedScreenPixel( const Point& rPos ) const
2840{
2841 // relative to top level parent
2842 long offx = const_cast<vcl::Window*>(this)->ImplGetUnmirroredOutOffX();
2843 return Point( rPos.X()+offx, rPos.Y()+mnOutOffY );
2844}
2845
2846Point Window::NormalizedScreenToOutputPixel( const Point& rPos ) const
2847{
2848 // relative to top level parent
2849 long offx = const_cast<vcl::Window*>(this)->ImplGetUnmirroredOutOffX();
2850 return Point( rPos.X()-offx, rPos.Y()-mnOutOffY );
2851}
2852
2853Point Window::OutputToAbsoluteScreenPixel( const Point& rPos ) const
2854{
2855 // relative to the screen
2856 Point p = OutputToScreenPixel( rPos );
2857 SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
2858 p.AdjustX(g.nX );
2859 p.AdjustY(g.nY );
2860 return p;
2861}
2862
2863Point Window::AbsoluteScreenToOutputPixel( const Point& rPos ) const
2864{
2865 // relative to the screen
2866 Point p = ScreenToOutputPixel( rPos );
2867 SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
2868 p.AdjustX( -(g.nX) );
2869 p.AdjustY( -(g.nY) );
2870 return p;
2871}
2872
2873tools::Rectangle Window::ImplOutputToUnmirroredAbsoluteScreenPixel( const tools::Rectangle &rRect ) const
2874{
2875 // this method creates unmirrored screen coordinates to be compared with the desktop
2876 // and is used for positioning of RTL popup windows correctly on the screen
2877 SalFrameGeometry g = mpWindowImpl->mpFrame->GetUnmirroredGeometry();
2878
2879 Point p1 = OutputToScreenPixel( rRect.TopRight() );
2880 p1.setX( g.nX+g.nWidth-p1.X() );
2881 p1.AdjustY(g.nY );
2882
2883 Point p2 = OutputToScreenPixel( rRect.BottomLeft() );
2884 p2.setX( g.nX+g.nWidth-p2.X() );
2885 p2.AdjustY(g.nY );
2886
2887 return tools::Rectangle( p1, p2 );
2888}
2889
2890tools::Rectangle Window::GetWindowExtentsRelative(const vcl::Window *pRelativeWindow) const
2891{
2892 // with decoration
2893 return ImplGetWindowExtentsRelative( pRelativeWindow );
2894}
2895
2896tools::Rectangle Window::ImplGetWindowExtentsRelative(const vcl::Window *pRelativeWindow) const
2897{
2898 SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry();
2899 // make sure we use the extent of our border window,
2900 // otherwise we miss a few pixels
2901 const vcl::Window *pWin = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow : this;
2902
2903 Point aPos( pWin->OutputToScreenPixel( Point(0,0) ) );
2904 aPos.AdjustX(g.nX );
2905 aPos.AdjustY(g.nY );
2906 Size aSize ( pWin->GetSizePixel() );
2907 // #104088# do not add decoration to the workwindow to be compatible to java accessibility api
2908 if( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame && GetType() != WindowType::WORKWINDOW) )
2909 {
2910 aPos.AdjustX( -sal_Int32(g.nLeftDecoration) );
2911 aPos.AdjustY( -sal_Int32(g.nTopDecoration) );
2912 aSize.AdjustWidth(g.nLeftDecoration + g.nRightDecoration );
2913 aSize.AdjustHeight(g.nTopDecoration + g.nBottomDecoration );
2914 }
2915 if( pRelativeWindow )
2916 {
2917 // #106399# express coordinates relative to borderwindow
2918 const vcl::Window *pRelWin = pRelativeWindow->mpWindowImpl->mpBorderWindow ? pRelativeWindow->mpWindowImpl->mpBorderWindow.get() : pRelativeWindow;
2919 aPos = pRelWin->AbsoluteScreenToOutputPixel( aPos );
2920 }
2921 return tools::Rectangle( aPos, aSize );
2922}
2923
2924void Window::Scroll( long nHorzScroll, long nVertScroll, ScrollFlags nFlags )
2925{
2926
2927 ImplScroll( tools::Rectangle( Point( mnOutOffX, mnOutOffY ),
2928 Size( mnOutWidth, mnOutHeight ) ),
2929 nHorzScroll, nVertScroll, nFlags & ~ScrollFlags::Clip );
2930}
2931
2932void Window::Scroll( long nHorzScroll, long nVertScroll,
2933 const tools::Rectangle& rRect, ScrollFlags nFlags )
2934{
2935 OutputDevice *pOutDev = GetOutDev();
2936 tools::Rectangle aRect = pOutDev->ImplLogicToDevicePixel( rRect );
2937 aRect.Intersection( tools::Rectangle( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ) );
2938 if ( !aRect.IsEmpty() )
2939 ImplScroll( aRect, nHorzScroll, nVertScroll, nFlags );
2940}
2941
2942void Window::Flush()
2943{
2944 if (mpWindowImpl)
2945 {
2946 const tools::Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
2947 mpWindowImpl->mpFrame->Flush( aWinRect );
2948 }
2949}
2950
2951void Window::SetUpdateMode( bool bUpdate )
2952{
2953 if (mpWindowImpl)
2954 {
2955 mpWindowImpl->mbNoUpdate = !bUpdate;
2956 CompatStateChanged( StateChangedType::UpdateMode );
2957 }
2958}
2959
2960void Window::GrabFocus()
2961{
2962 ImplGrabFocus( GetFocusFlags::NONE );
2963}
2964
2965bool Window::HasFocus() const
2966{
2967 return (this == ImplGetSVData()->mpWinData->mpFocusWin);
2968}
2969
2970void Window::GrabFocusToDocument()
2971{
2972 ImplGrabFocusToDocument(GetFocusFlags::NONE);
2973}
2974
2975VclPtr<vcl::Window> Window::GetFocusedWindow() const
2976{
2977 if (mpWindowImpl && mpWindowImpl->mpFrameData)
2978 return mpWindowImpl->mpFrameData->mpFocusWin;
2979 else
2980 return VclPtr<vcl::Window>();
2981}
2982
2983void Window::SetFakeFocus( bool bFocus )
2984{
2985 ImplGetWindowImpl()->mbFakeFocusSet = bFocus;
2986}
2987
2988bool Window::HasChildPathFocus( bool bSystemWindow ) const
2989{
2990
2991 vcl::Window* pFocusWin = ImplGetSVData()->mpWinData->mpFocusWin;
2992 if ( pFocusWin )
2993 return ImplIsWindowOrChild( pFocusWin, bSystemWindow );
2994 return false;
2995}
2996
2997void Window::SetCursor( vcl::Cursor* pCursor )
2998{
2999
3000 if ( mpWindowImpl->mpCursor != pCursor )
3001 {
3002 if ( mpWindowImpl->mpCursor )
3003 mpWindowImpl->mpCursor->ImplHide();
3004 mpWindowImpl->mpCursor = pCursor;
3005 if ( pCursor )
3006 pCursor->ImplShow();
3007 }
3008}
3009
3010void Window::SetText( const OUString& rStr )
3011{
3012 if (!mpWindowImpl || rStr == mpWindowImpl->maText)
3013 return;
3014
3015 OUString oldTitle( mpWindowImpl->maText );
3016 mpWindowImpl->maText = rStr;
3017
3018 if ( mpWindowImpl->mpBorderWindow )
3019 mpWindowImpl->mpBorderWindow->SetText( rStr );
3020 else if ( mpWindowImpl->mbFrame )
3021 mpWindowImpl->mpFrame->SetTitle( rStr );
3022
3023 CallEventListeners( VclEventId::WindowFrameTitleChanged, &oldTitle );
3024
3025 // #107247# needed for accessibility
3026 // The VclEventId::WindowFrameTitleChanged is (mis)used to notify accessible name changes.
3027 // Therefore a window, which is labeled by this window, must also notify an accessible
3028 // name change.
3029 if ( IsReallyVisible() )
3030 {
3031 vcl::Window* pWindow = GetAccessibleRelationLabelFor();
3032 if ( pWindow && pWindow != this )
3033 pWindow->CallEventListeners( VclEventId::WindowFrameTitleChanged, &oldTitle );
3034 }
3035
3036 CompatStateChanged( StateChangedType::Text );
3037}
3038
3039OUString Window::GetText() const
3040{
3041
3042 return mpWindowImpl->maText;
3043}
3044
3045OUString Window::GetDisplayText() const
3046{
3047
3048 return GetText();
3049}
3050
3051const Wallpaper& Window::GetDisplayBackground() const
3052{
3053 // FIXME: fix issue 52349, need to fix this really in
3054 // all NWF enabled controls
3055 const ToolBox* pTB = dynamic_cast<const ToolBox*>(this);
3056 if( pTB && IsNativeWidgetEnabled() )
3057 return pTB->ImplGetToolBoxPrivateData()->maDisplayBackground;
3058
3059 if( !IsBackground() )
3060 {
3061 if( mpWindowImpl->mpParent )
3062 return mpWindowImpl->mpParent->GetDisplayBackground();
3063 }
3064
3065 const Wallpaper& rBack = GetBackground();
3066 if( ! rBack.IsBitmap() &&
3067 ! rBack.IsGradient() &&
3068 rBack.GetColor()== COL_TRANSPARENT &&
3069 mpWindowImpl->mpParent )
3070 return mpWindowImpl->mpParent->GetDisplayBackground();
3071 return rBack;
3072}
3073
3074const OUString& Window::GetHelpText() const
3075{
3076 OUString aStrHelpId( OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)) ) );
3077 bool bStrHelpId = !aStrHelpId.isEmpty();
3078
3079 if ( !mpWindowImpl->maHelpText.getLength() && bStrHelpId )
3080 {
3081 if ( !IsDialog() && (mpWindowImpl->mnType != WindowType::TABPAGE) && (mpWindowImpl->mnType != WindowType::FLOATINGWINDOW) )
3082 {
3083 Help* pHelp = Application::GetHelp();
3084 if ( pHelp )
3085 {
3086 mpWindowImpl->maHelpText = pHelp->GetHelpText(aStrHelpId, this);
3087 mpWindowImpl->mbHelpTextDynamic = false;
3088 }
3089 }
3090 }
3091 else if( mpWindowImpl->mbHelpTextDynamic && bStrHelpId )
3092 {
3093 static const char* pEnv = getenv( "HELP_DEBUG" );
3094 if( pEnv && *pEnv )
3095 {
3096 OUString aTxt = mpWindowImpl->maHelpText + "\n------------------\n" + aStrHelpId;
3097 mpWindowImpl->maHelpText = aTxt;
3098 }
3099 mpWindowImpl->mbHelpTextDynamic = false;
3100 }
3101
3102 //Fallback to Window::GetAccessibleDescription without reentry to GetHelpText()
3103 if (mpWindowImpl->maHelpText.isEmpty() && mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleDescription)
3104 return *mpWindowImpl->mpAccessibleInfos->pAccessibleDescription;
3105 return mpWindowImpl->maHelpText;
3106}
3107
3108void Window::SetWindowPeer( Reference< css::awt::XWindowPeer > const & xPeer, VCLXWindow* pVCLXWindow )
3109{
3110 if (!mpWindowImpl)
3111 return;
3112
3113 // be safe against re-entrance: first clear the old ref, then assign the new one
3114 mpWindowImpl->mxWindowPeer.clear();
3115 mpWindowImpl->mxWindowPeer = xPeer;
3116
3117 mpWindowImpl->mpVCLXWindow = pVCLXWindow;
3118}
3119
3120Reference< css::awt::XWindowPeer > Window::GetComponentInterface( bool bCreate )
3121{
3122 if ( !mpWindowImpl->mxWindowPeer.is() && bCreate )
3123 {
3124 UnoWrapperBase* pWrapper = UnoWrapperBase::GetUnoWrapper();
3125 if ( pWrapper )
3126 mpWindowImpl->mxWindowPeer = pWrapper->GetWindowInterface( this );
3127 }
3128 return mpWindowImpl->mxWindowPeer;
3129}
3130
3131void Window::SetComponentInterface( Reference< css::awt::XWindowPeer > const & xIFace )
3132{
3133 UnoWrapperBase* pWrapper = UnoWrapperBase::GetUnoWrapper();
3134 SAL_WARN_IF( !pWrapper, "vcl.window", "SetComponentInterface: No Wrapper!" )do { if (true && (!pWrapper)) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_WARN, "vcl.window")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "SetComponentInterface: No Wrapper!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "3134" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SetComponentInterface: No Wrapper!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SetComponentInterface: No Wrapper!"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "3134" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SetComponentInterface: No Wrapper!") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "3134" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SetComponentInterface: No Wrapper!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SetComponentInterface: No Wrapper!"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.window"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
":" "3134" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
3135 if ( pWrapper )
3136 pWrapper->SetWindowInterface( this, xIFace );
3137}
3138
3139typedef std::map<vcl::LOKWindowId, VclPtr<vcl::Window>> LOKWindowsMap;
3140
3141namespace {
3142
3143LOKWindowsMap& GetLOKWindowsMap()
3144{
3145 // Map to remember the LOKWindowId <-> Window binding.
3146 static LOKWindowsMap s_aLOKWindowsMap;
3147
3148 return s_aLOKWindowsMap;
3149}
3150
3151}
3152
3153void Window::SetLOKNotifier(const vcl::ILibreOfficeKitNotifier* pNotifier, bool bParent)
3154{
3155 // don't allow setting this twice
3156 assert(mpWindowImpl->mpLOKNotifier == nullptr)(static_cast <bool> (mpWindowImpl->mpLOKNotifier == nullptr
) ? void (0) : __assert_fail ("mpWindowImpl->mpLOKNotifier == nullptr"
, "/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
, 3156, __extension__ __PRETTY_FUNCTION__))
;
3157 assert(pNotifier)(static_cast <bool> (pNotifier) ? void (0) : __assert_fail
("pNotifier", "/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
, 3157, __extension__ __PRETTY_FUNCTION__))
;
3158 // never use this in the desktop case
3159 assert(comphelper::LibreOfficeKit::isActive())(static_cast <bool> (comphelper::LibreOfficeKit::isActive
()) ? void (0) : __assert_fail ("comphelper::LibreOfficeKit::isActive()"
, "/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
, 3159, __extension__ __PRETTY_FUNCTION__))
;
3160
3161 if (!bParent)
3162 {
3163 // Counter to be able to have unique id's for each window.
3164 static vcl::LOKWindowId sLastLOKWindowId = 1;
3165
3166 // assign the LOK window id
3167 assert(mpWindowImpl->mnLOKWindowId == 0)(static_cast <bool> (mpWindowImpl->mnLOKWindowId == 0
) ? void (0) : __assert_fail ("mpWindowImpl->mnLOKWindowId == 0"
, "/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
, 3167, __extension__ __PRETTY_FUNCTION__))
;
3168 mpWindowImpl->mnLOKWindowId = sLastLOKWindowId++;
3169 GetLOKWindowsMap().emplace(mpWindowImpl->mnLOKWindowId, this);
3170 }
3171 else
3172 mpWindowImpl->mbLOKParentNotifier = true;
3173
3174 mpWindowImpl->mpLOKNotifier = pNotifier;
3175}
3176
3177VclPtr<Window> Window::FindLOKWindow(vcl::LOKWindowId nWindowId)
3178{
3179 const auto it = GetLOKWindowsMap().find(nWindowId);
3180 if (it != GetLOKWindowsMap().end())
3181 return it->second;
3182
3183 return VclPtr<Window>();
3184}
3185
3186bool Window::IsLOKWindowsEmpty()
3187{
3188 return GetLOKWindowsMap().empty();
3189}
3190
3191void Window::ReleaseLOKNotifier()
3192{
3193 // unregister the LOK window binding
3194 if (mpWindowImpl->mnLOKWindowId > 0)
3195 GetLOKWindowsMap().erase(mpWindowImpl->mnLOKWindowId);
3196
3197 mpWindowImpl->mpLOKNotifier = nullptr;
3198 mpWindowImpl->mnLOKWindowId = 0;
3199}
3200
3201ILibreOfficeKitNotifier::~ILibreOfficeKitNotifier()
3202{
3203 if (!comphelper::LibreOfficeKit::isActive())
3204 {
3205 return;
3206 }
3207
3208 for (auto it = GetLOKWindowsMap().begin(); it != GetLOKWindowsMap().end();)
3209 {
3210 WindowImpl* pWindowImpl = it->second->ImplGetWindowImpl();
3211 if (pWindowImpl && pWindowImpl->mpLOKNotifier == this)
3212 {
3213 pWindowImpl->mpLOKNotifier = nullptr;
3214 pWindowImpl->mnLOKWindowId = 0;
3215 it = GetLOKWindowsMap().erase(it);
3216 continue;
3217 }
3218
3219 ++it;
3220 }
3221}
3222
3223const vcl::ILibreOfficeKitNotifier* Window::GetLOKNotifier() const
3224{
3225 return mpWindowImpl->mpLOKNotifier;
3226}
3227
3228vcl::LOKWindowId Window::GetLOKWindowId() const
3229{
3230 return mpWindowImpl->mnLOKWindowId;
3231}
3232
3233VclPtr<vcl::Window> Window::GetParentWithLOKNotifier()
3234{
3235 VclPtr<vcl::Window> pWindow(this);
3236
3237 while (pWindow && !pWindow->GetLOKNotifier())
3238 pWindow = pWindow->GetParent();
3239
3240 return pWindow;
3241}
3242
3243namespace
3244{
3245
3246const char* windowTypeName(WindowType nWindowType)
3247{
3248 switch (nWindowType)
3249 {
3250 case WindowType::NONE: return "none";
3251 case WindowType::MESSBOX: return "messagebox";
3252 case WindowType::INFOBOX: return "infobox";
3253 case WindowType::WARNINGBOX: return "warningbox";
3254 case WindowType::ERRORBOX: return "errorbox";
3255 case WindowType::QUERYBOX: return "querybox";
3256 case WindowType::WINDOW: return "window";
3257 case WindowType::WORKWINDOW: return "workwindow";
3258 case WindowType::CONTAINER: return "container";
3259 case WindowType::FLOATINGWINDOW: return "floatingwindow";
3260 case WindowType::DIALOG: return "dialog";
3261 case WindowType::MODELESSDIALOG: return "modelessdialog";
3262 case WindowType::CONTROL: return "control";
3263 case WindowType::PUSHBUTTON: return "pushbutton";
3264 case WindowType::OKBUTTON: return "okbutton";
3265 case WindowType::CANCELBUTTON: return "cancelbutton";
3266 case WindowType::HELPBUTTON: return "helpbutton";
3267 case WindowType::IMAGEBUTTON: return "imagebutton";
3268 case WindowType::MENUBUTTON: return "menubutton";
3269 case WindowType::MOREBUTTON: return "morebutton";
3270 case WindowType::SPINBUTTON: return "spinbutton";
3271 case WindowType::RADIOBUTTON: return "radiobutton";
3272 case WindowType::CHECKBOX: return "checkbox";
3273 case WindowType::TRISTATEBOX: return "tristatebox";
3274 case WindowType::EDIT: return "edit";
3275 case WindowType::MULTILINEEDIT: return "multilineedit";
3276 case WindowType::COMBOBOX: return "combobox";
3277 case WindowType::LISTBOX: return "listbox";
3278 case WindowType::MULTILISTBOX: return "multilistbox";
3279 case WindowType::FIXEDTEXT: return "fixedtext";
3280 case WindowType::FIXEDLINE: return "fixedline";
3281 case WindowType::FIXEDBITMAP: return "fixedbitmap";
3282 case WindowType::FIXEDIMAGE: return "fixedimage";
3283 case WindowType::GROUPBOX: return "groupbox";
3284 case WindowType::SCROLLBAR: return "scrollbar";
3285 case WindowType::SCROLLBARBOX: return "scrollbarbox";
3286 case WindowType::SPLITTER: return "splitter";
3287 case WindowType::SPLITWINDOW: return "splitwindow";
3288 case WindowType::SPINFIELD: return "spinfield";
3289 case WindowType::PATTERNFIELD: return "patternfield";
3290 case WindowType::METRICFIELD: return "metricfield";
3291 case WindowType::FORMATTEDFIELD: return "formattedfield";
3292 case WindowType::CURRENCYFIELD: return "currencyfield";
3293 case WindowType::DATEFIELD: return "datefield";
3294 case WindowType::TIMEFIELD: return "timefield";
3295 case WindowType::PATTERNBOX: return "patternbox";
3296 case WindowType::NUMERICBOX: return "numericbox";
3297 case WindowType::METRICBOX: return "metricbox";
3298 case WindowType::CURRENCYBOX: return "currencybox";
3299 case WindowType::DATEBOX: return "datebox";
3300 case WindowType::TIMEBOX: return "timebox";
3301 case WindowType::LONGCURRENCYBOX: return "longcurrencybox";
3302 case WindowType::SCROLLWINDOW: return "scrollwindow";
3303 case WindowType::TOOLBOX: return "toolbox";
3304 case WindowType::DOCKINGWINDOW: return "dockingwindow";
3305 case WindowType::STATUSBAR: return "statusbar";
3306 case WindowType::TABPAGE: return "tabpage";
3307 case WindowType::TABCONTROL: return "tabcontrol";
3308 case WindowType::TABDIALOG: return "tabdialog";
3309 case WindowType::BORDERWINDOW: return "borderwindow";
3310 case WindowType::BUTTONDIALOG: return "buttondialog";
3311 case WindowType::SYSTEMCHILDWINDOW: return "systemchildwindow";
3312 case WindowType::SLIDER: return "slider";
3313 case WindowType::MENUBARWINDOW: return "menubarwindow";
3314 case WindowType::TREELISTBOX: return "treelistbox";
3315 case WindowType::HELPTEXTWINDOW: return "helptextwindow";
3316 case WindowType::INTROWINDOW: return "introwindow";
3317 case WindowType::LISTBOXWINDOW: return "listboxwindow";
3318 case WindowType::DOCKINGAREA: return "dockingarea";
3319 case WindowType::RULER: return "ruler";
3320 case WindowType::CALCINPUTLINE: return "calcinputline";
3321 case WindowType::HEADERBAR: return "headerbar";
3322 case WindowType::VERTICALTABCONTROL: return "verticaltabcontrol";
3323
3324 // nothing to do here, but for completeness
3325 case WindowType::TOOLKIT_FRAMEWINDOW: return "toolkit_framewindow";
3326 case WindowType::TOOLKIT_SYSTEMCHILDWINDOW: return "toolkit_systemchildwindow";
3327 }
3328
3329 return "none";
3330}
3331
3332}
3333
3334void Window::DumpAsPropertyTree(tools::JsonWriter& rJsonWriter)
3335{
3336 rJsonWriter.put("id", get_id()); // TODO could be missing - sort out
3337 rJsonWriter.put("type", windowTypeName(GetType()));
3338 rJsonWriter.put("text", GetText());
3339 rJsonWriter.put("enabled", IsEnabled());
3340
3341 if (vcl::Window* pChild = mpWindowImpl->mpFirstChild)
3342 {
3343 auto childrenNode = rJsonWriter.startNode("children");
3344 while (pChild)
3345 {
3346 if (pChild->IsVisible()) {
3347 auto childNode = rJsonWriter.startNode("");
3348 pChild->DumpAsPropertyTree(rJsonWriter);
3349 sal_Int32 nLeft = pChild->get_grid_left_attach();
3350 sal_Int32 nTop = pChild->get_grid_top_attach();
3351 if (nLeft != -1 && nTop != -1)
3352 {
3353 rJsonWriter.put("left", nLeft);
3354 rJsonWriter.put("top", nTop);
3355 }
3356 }
3357 pChild = pChild->mpWindowImpl->mpNext;
3358 }
3359 }
3360
3361 mpWindowImpl->maDumpAsPropertyTreeHdl.Call(rJsonWriter);
3362}
3363
3364void Window::ImplCallDeactivateListeners( vcl::Window *pNew )
3365{
3366 // no deactivation if the newly activated window is my child
3367 if ( !pNew || !ImplIsChild( pNew ) )
3368 {
3369 VclPtr<vcl::Window> xWindow(this);
3370 CallEventListeners( VclEventId::WindowDeactivate, pNew );
3371 if( xWindow->IsDisposed() )
3372 return;
3373
3374 // #100759#, avoid walking the wrong frame's hierarchy
3375 // eg, undocked docking windows (ImplDockFloatWin)
3376 if ( ImplGetParent() && mpWindowImpl->mpFrameWindow == ImplGetParent()->mpWindowImpl->mpFrameWindow )
3377 ImplGetParent()->ImplCallDeactivateListeners( pNew );
3378 }
3379}
3380
3381void Window::ImplCallActivateListeners( vcl::Window *pOld )
3382{
3383 // no activation if the old active window is my child
3384 if ( pOld && ImplIsChild( pOld ))
3385 return;
3386
3387 VclPtr<vcl::Window> xWindow(this);
3388 CallEventListeners( VclEventId::WindowActivate, pOld );
3389 if( xWindow->IsDisposed() )
3390 return;
3391
3392 if ( ImplGetParent() )
3393 ImplGetParent()->ImplCallActivateListeners( pOld );
3394 else if( (mpWindowImpl->mnStyle & WB_INTROWIN) == 0 )
3395 {
3396 // top level frame reached: store hint for DefModalDialogParent
3397 ImplGetSVData()->maFrameData.mpActiveApplicationFrame = mpWindowImpl->mpFrameWindow;
3398 }
3399}
3400
3401void Window::SetClipboard(Reference<XClipboard> const & xClipboard)
3402{
3403 if (mpWindowImpl->mpFrameData)
3404 mpWindowImpl->mpFrameData->mxClipboard = xClipboard;
3405}
3406
3407Reference< XClipboard > Window::GetClipboard()
3408{
3409 if (!mpWindowImpl->mpFrameData)
3410 return static_cast<XClipboard*>(nullptr);
3411 if (!mpWindowImpl->mpFrameData->mxClipboard.is())
3412 mpWindowImpl->mpFrameData->mxClipboard = GetSystemClipboard();
3413 return mpWindowImpl->mpFrameData->mxClipboard;
3414}
3415
3416Reference< XClipboard > Window::GetPrimarySelection()
3417{
3418 if (!mpWindowImpl->mpFrameData)
3419 return static_cast<XClipboard*>(nullptr);
3420 if (!mpWindowImpl->mpFrameData->mxSelection.is())
3421 mpWindowImpl->mpFrameData->mxSelection = GetSystemPrimarySelection();
3422 return mpWindowImpl->mpFrameData->mxSelection;
3423}
3424
3425void Window::RecordLayoutData( vcl::ControlLayoutData* pLayout, const tools::Rectangle& rRect )
3426{
3427 assert(mpOutDevData)(static_cast <bool> (mpOutDevData) ? void (0) : __assert_fail
("mpOutDevData", "/home/maarten/src/libreoffice/core/vcl/source/window/window.cxx"
, 3427, __extension__ __PRETTY_FUNCTION__))
;
3428 mpOutDevData->mpRecordLayout = pLayout;
3429 mpOutDevData->maRecordRect = rRect;
3430 Paint(*this, rRect);
3431 mpOutDevData->mpRecordLayout = nullptr;
3432}
3433
3434void Window::DrawSelectionBackground( const tools::Rectangle& rRect,
3435 sal_uInt16 highlight,
3436 bool bChecked,
3437 bool bDrawBorder
3438 )
3439{
3440 if( rRect.IsEmpty() )
3441 return;
3442
3443 const StyleSettings& rStyles = GetSettings().GetStyleSettings();
3444
3445 // colors used for item highlighting
3446 Color aSelectionBorderCol( rStyles.GetHighlightColor() );
3447 Color aSelectionFillCol( aSelectionBorderCol );
3448
3449 bool bDark = rStyles.GetFaceColor().IsDark();
3450 bool bBright = ( rStyles.GetFaceColor() == COL_WHITE );
3451
3452 int c1 = aSelectionBorderCol.GetLuminance();
3453 int c2 = GetBackgroundColor().GetLuminance();
3454
3455 if( !bDark && !bBright && abs( c2-c1 ) < 75 )
3456 {
3457 // contrast too low
3458 sal_uInt16 h,s,b;
3459 aSelectionFillCol.RGBtoHSB( h, s, b );
3460 if( b > 50 ) b -= 40;
3461 else b += 40;
3462 aSelectionFillCol = Color::HSBtoRGB( h, s, b );
3463 aSelectionBorderCol = aSelectionFillCol;
3464 }
3465
3466 tools::Rectangle aRect( rRect );
3467 Color oldFillCol = GetFillColor();
3468 Color oldLineCol = GetLineColor();
3469
3470 if( bDrawBorder )
3471 SetLineColor( bDark ? COL_WHITE : ( bBright ? COL_BLACK : aSelectionBorderCol ) );
3472 else
3473 SetLineColor();
3474
3475 sal_uInt16 nPercent = 0;
3476 if( !highlight )
3477 {
3478 if( bDark )
3479 aSelectionFillCol = COL_BLACK;
3480 else
3481 nPercent = 80; // just checked (light)
3482 }
3483 else
3484 {
3485 if( bChecked && highlight == 2 )
3486 {
3487 if( bDark )
3488 aSelectionFillCol = COL_LIGHTGRAY;
3489 else if ( bBright )
3490 {
3491 aSelectionFillCol = COL_BLACK;
3492 SetLineColor( COL_BLACK );
3493 nPercent = 0;
3494 }
3495 else
3496 nPercent = 20; // selected, pressed or checked ( very dark )
3497 }
3498 else if( bChecked || highlight == 1 )
3499 {
3500 if( bDark )
3501 aSelectionFillCol = COL_GRAY;
3502 else if ( bBright )
3503 {
3504 aSelectionFillCol = COL_BLACK;
3505 SetLineColor( COL_BLACK );
3506 nPercent = 0;
3507 }
3508 else
3509 nPercent = 35; // selected, pressed or checked ( very dark )
3510 }
3511 else
3512 {
3513 if( bDark )
3514 aSelectionFillCol = COL_LIGHTGRAY;
3515 else if ( bBright )
3516 {
3517 aSelectionFillCol = COL_BLACK;
3518 SetLineColor( COL_BLACK );
3519 if( highlight == 3 )
3520 nPercent = 80;
3521 else
3522 nPercent = 0;
3523 }
3524 else
3525 nPercent = 70; // selected ( dark )
3526 }
3527 }
3528
3529 SetFillColor( aSelectionFillCol );
3530
3531 if( bDark )
3532 {
3533 DrawRect( aRect );
3534 }
3535 else
3536 {
3537 tools::Polygon aPoly( aRect );
3538 tools::PolyPolygon aPolyPoly( aPoly );
3539 DrawTransparent( aPolyPoly, nPercent );
3540 }
3541
3542 SetFillColor( oldFillCol );
3543 SetLineColor( oldLineCol );
3544}
3545
3546bool Window::IsScrollable() const
3547{
3548 // check for scrollbars
3549 VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
3550 while( pChild )
3551 {
3552 if( pChild->GetType() == WindowType::SCROLLBAR )
3553 return true;
3554 else
3555 pChild = pChild->mpWindowImpl->mpNext;
3556 }
3557 return false;
3558}
3559
3560void Window::ImplMirrorFramePos( Point &pt ) const
3561{
3562 pt.setX( mpWindowImpl->mpFrame->maGeometry.nWidth-1-pt.X() );
3563}
3564
3565// frame based modal counter (dialogs are not modal to the whole application anymore)
3566bool Window::IsInModalMode() const
3567{
3568 return (mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrameData->mnModalMode != 0);
3569}
3570
3571void Window::IncModalCount()
3572{
3573 vcl::Window* pFrameWindow = mpWindowImpl->mpFrameWindow;
3574 vcl::Window* pParent = pFrameWindow;
3575 while( pFrameWindow )
3576 {
3577 pFrameWindow->mpWindowImpl->mpFrameData->mnModalMode++;
3578 while( pParent && pParent->mpWindowImpl->mpFrameWindow == pFrameWindow )
3579 {
3580 pParent = pParent->GetParent();
3581 }
3582 pFrameWindow = pParent ? pParent->mpWindowImpl->mpFrameWindow.get() : nullptr;
3583 }
3584}
3585void Window::DecModalCount()
3586{
3587 vcl::Window* pFrameWindow = mpWindowImpl->mpFrameWindow;
3588 vcl::Window* pParent = pFrameWindow;
3589 while( pFrameWindow )
3590 {
3591 pFrameWindow->mpWindowImpl->mpFrameData->mnModalMode--;
3592 while( pParent && pParent->mpWindowImpl->mpFrameWindow == pFrameWindow )
3593 {
3594 pParent = pParent->GetParent();
3595 }
3596 pFrameWindow = pParent ? pParent->mpWindowImpl->mpFrameWindow.get() : nullptr;
3597 }
3598}
3599
3600void Window::ImplIsInTaskPaneList( bool mbIsInTaskList )
3601{
3602 mpWindowImpl->mbIsInTaskPaneList = mbIsInTaskList;
3603}
3604
3605void Window::ImplNotifyIconifiedState( bool bIconified )
3606{
3607 mpWindowImpl->mpFrameWindow->CallEventListeners( bIconified ? VclEventId::WindowMinimize : VclEventId::WindowNormalize );
3608 // #109206# notify client window as well to have toolkit topwindow listeners notified
3609 if( mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow && mpWindowImpl->mpFrameWindow != mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow )
3610 mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow->CallEventListeners( bIconified ? VclEventId::WindowMinimize : VclEventId::WindowNormalize );
3611}
3612
3613bool Window::HasActiveChildFrame() const
3614{
3615 bool bRet = false;
3616 vcl::Window *pFrameWin = ImplGetSVData()->maFrameData.mpFirstFrame;
3617 while( pFrameWin )
3618 {
3619 if( pFrameWin != mpWindowImpl->mpFrameWindow )
3620 {
3621 bool bDecorated = false;
3622 VclPtr< vcl::Window > pChildFrame = pFrameWin->ImplGetWindow();
3623 // #i15285# unfortunately WB_MOVEABLE is the same as WB_TABSTOP which can
3624 // be removed for ToolBoxes to influence the keyboard accessibility
3625 // thus WB_MOVEABLE is no indicator for decoration anymore
3626 // but FloatingWindows carry this information in their TitleType...
3627 // TODO: avoid duplicate WinBits !!!
3628 if( pChildFrame && pChildFrame->ImplIsFloatingWindow() )
3629 bDecorated = static_cast<FloatingWindow*>(pChildFrame.get())->GetTitleType() != FloatWinTitleType::NONE;
3630 if( bDecorated || (pFrameWin->mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE) ) )
3631 if( pChildFrame && pChildFrame->IsVisible() && pChildFrame->IsActive() )
3632 {
3633 if( ImplIsChild( pChildFrame, true ) )
3634 {
3635 bRet = true;
3636 break;
3637 }
3638 }
3639 }
3640 pFrameWin = pFrameWin->mpWindowImpl->mpFrameData->mpNextFrame;
3641 }
3642 return bRet;
3643}
3644
3645LanguageType Window::GetInputLanguage() const
3646{
3647 return mpWindowImpl->mpFrame->GetInputLanguage();
3648}
3649
3650void Window::EnableNativeWidget( bool bEnable )
3651{
3652 static const char* pNoNWF = getenv( "SAL_NO_NWF" );
3653 if( pNoNWF && *pNoNWF )
3654 bEnable = false;
3655
3656 if( bEnable != ImplGetWinData()->mbEnableNativeWidget )
3657 {
3658 ImplGetWinData()->mbEnableNativeWidget = bEnable;
3659
3660 // send datachanged event to allow for internal changes required for NWF
3661 // like clipmode, transparency, etc.
3662 DataChangedEvent aDCEvt( DataChangedEventType::SETTINGS, mxSettings.get(), AllSettingsFlags::STYLE );
3663 CompatDataChanged( aDCEvt );
3664
3665 // sometimes the borderwindow is queried, so keep it in sync
3666 if( mpWindowImpl->mpBorderWindow )
3667 mpWindowImpl->mpBorderWindow->ImplGetWinData()->mbEnableNativeWidget = bEnable;
3668 }
3669
3670 // push down, useful for compound controls
3671 VclPtr< vcl::Window > pChild = mpWindowImpl->mpFirstChild;
3672 while( pChild )
3673 {
3674 pChild->EnableNativeWidget( bEnable );
3675 pChild = pChild->mpWindowImpl->mpNext;
3676 }
3677}
3678
3679bool Window::IsNativeWidgetEnabled() const
3680{
3681 return ImplGetWinData()->mbEnableNativeWidget;
3682}
3683
3684Reference< css::rendering::XCanvas > Window::ImplGetCanvas( bool bSpriteCanvas ) const
3685{
3686 // try to retrieve hard reference from weak member
3687 Reference< css::rendering::XCanvas > xCanvas( mpWindowImpl->mxCanvas );
3688
3689 // canvas still valid? Then we're done.
3690 if( xCanvas.is() )
3691 return xCanvas;
3692
3693 Sequence< Any > aArg(5);
3694
3695 // Feed any with operating system's window handle
3696
3697 // common: first any is VCL pointer to window (for VCL canvas)
3698 aArg[ 0 ] <<= reinterpret_cast<sal_Int64>(this);
3699 aArg[ 1 ] <<= css::awt::Rectangle( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight );
3700 aArg[ 2 ] <<= mpWindowImpl->mbAlwaysOnTop;
3701 aArg[ 3 ] <<= Reference< css::awt::XWindow >(
3702 const_cast<vcl::Window*>(this)->GetComponentInterface(),
3703 UNO_QUERY );
3704 aArg[ 4 ] = GetSystemGfxDataAny();
3705
3706 Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
3707
3708 // Create canvas instance with window handle
3709
3710 static vcl::DeleteUnoReferenceOnDeinit<XMultiComponentFactory> xStaticCanvasFactory(
3711 css::rendering::CanvasFactory::create( xContext ) );
3712 Reference<XMultiComponentFactory> xCanvasFactory(xStaticCanvasFactory.get());
3713
3714 if(xCanvasFactory.is())
3715 {
3716#ifdef _WIN32
3717 // see #140456# - if we're running on a multiscreen setup,
3718 // request special, multi-screen safe sprite canvas
3719 // implementation (not DX5 canvas, as it cannot cope with
3720 // surfaces spanning multiple displays). Note: canvas
3721 // (without sprite) stays the same)
3722 const sal_uInt32 nDisplay = static_cast< WinSalFrame* >( mpWindowImpl->mpFrame )->mnDisplay;
3723 if( nDisplay >= Application::GetScreenCount() )
3724 {
3725 xCanvas.set( xCanvasFactory->createInstanceWithArgumentsAndContext(
3726 bSpriteCanvas ?
3727 OUString( "com.sun.star.rendering.SpriteCanvas.MultiScreen" ) :
3728 OUString( "com.sun.star.rendering.Canvas.MultiScreen" ),
3729 aArg,
3730 xContext ),
3731 UNO_QUERY );
3732
3733 }
3734 else
3735#endif
3736 {
3737 xCanvas.set( xCanvasFactory->createInstanceWithArgumentsAndContext(
3738 bSpriteCanvas ?
3739 OUString( "com.sun.star.rendering.SpriteCanvas" ) :
3740 OUString( "com.sun.star.rendering.Canvas" ),
3741 aArg,
3742 xContext ),
3743 UNO_QUERY );
3744
3745 }
3746 mpWindowImpl->mxCanvas = xCanvas;
3747 }
3748
3749 // no factory??? Empty reference, then.
3750 return xCanvas;
3751}
3752
3753Reference< css::rendering::XCanvas > Window::GetCanvas() const
3754{
3755 return ImplGetCanvas( false );
3756}
3757
3758Reference< css::rendering::XSpriteCanvas > Window::GetSpriteCanvas() const
3759{
3760 Reference< css::rendering::XSpriteCanvas > xSpriteCanvas(
3761 ImplGetCanvas( true ), UNO_QUERY );
3762 return xSpriteCanvas;
3763}
3764
3765OUString Window::GetSurroundingText() const
3766{
3767 return OUString();
3768}
3769
3770Selection Window::GetSurroundingTextSelection() const
3771{
3772 return Selection( 0, 0 );
3773}
3774
3775bool Window::UsePolyPolygonForComplexGradient()
3776{
3777 return meRasterOp != RasterOp::OverPaint;
3778}
3779
3780void Window::ApplySettings(vcl::RenderContext& /*rRenderContext*/)
3781{
3782}
3783
3784const SystemEnvData* Window::GetSystemData() const
3785{
3786
3787 return mpWindowImpl->mpFrame ? mpWindowImpl->mpFrame->GetSystemData() : nullptr;
3788}
3789
3790bool Window::SupportsDoubleBuffering() const
3791{
3792 return mpWindowImpl->mpFrameData->mpBuffer;
3793}
3794
3795void Window::RequestDoubleBuffering(bool bRequest)
3796{
3797 if (bRequest)
3798 {
3799 mpWindowImpl->mpFrameData->mpBuffer = VclPtrInstance<VirtualDevice>();
3800 // Make sure that the buffer size matches the frame size.
3801 mpWindowImpl->mpFrameData->mpBuffer->SetOutputSizePixel(mpWindowImpl->mpFrameWindow->GetOutputSizePixel());
3802 }
3803 else
3804 mpWindowImpl->mpFrameData->mpBuffer.reset();
3805}
3806
3807/*
3808 * The rationale here is that we moved destructors to
3809 * dispose and this altered a lot of code paths, that
3810 * are better left unchanged for now.
3811 */
3812#define COMPAT_BODY(method,args)if (!mpWindowImpl || mpWindowImpl->mbInDispose) Window::method
args; else method args;
\
3813 if (!mpWindowImpl || mpWindowImpl->mbInDispose) \
3814 Window::method args; \
3815 else \
3816 method args;
3817
3818void Window::CompatGetFocus()
3819{
3820 COMPAT_BODY(GetFocus,())if (!mpWindowImpl || mpWindowImpl->mbInDispose) Window::GetFocus
(); else GetFocus ();
3821}
3822
3823void Window::CompatLoseFocus()
3824{
3825 COMPAT_BODY(LoseFocus,())if (!mpWindowImpl || mpWindowImpl->mbInDispose) Window::LoseFocus
(); else LoseFocus ();
3826}
3827
3828void Window::CompatStateChanged( StateChangedType nStateChange )
3829{
3830 COMPAT_BODY(StateChanged,(nStateChange))if (!mpWindowImpl || mpWindowImpl->mbInDispose) Window::StateChanged
(nStateChange); else StateChanged (nStateChange);
3831}
3832
3833void Window::CompatDataChanged( const DataChangedEvent& rDCEvt )
3834{
3835 COMPAT_BODY(DataChanged,(rDCEvt))if (!mpWindowImpl || mpWindowImpl->mbInDispose) Window::DataChanged
(rDCEvt); else DataChanged (rDCEvt);
3836}
3837
3838bool Window::CompatPreNotify( NotifyEvent& rNEvt )
3839{
3840 if (!mpWindowImpl || mpWindowImpl->mbInDispose)
3841 return Window::PreNotify( rNEvt );
3842 else
3843 return PreNotify( rNEvt );
3844}
3845
3846bool Window::CompatNotify( NotifyEvent& rNEvt )
3847{
3848 if (!mpWindowImpl || mpWindowImpl->mbInDispose)
3849 return Window::EventNotify( rNEvt );
3850 else
3851 return EventNotify( rNEvt );
3852}
3853
3854void Window::set_id(const OUString& rID)
3855{
3856 mpWindowImpl->maID = rID;
3857}
3858
3859const OUString& Window::get_id() const
3860{
3861 return mpWindowImpl->maID;
3862}
3863
3864FactoryFunction Window::GetUITestFactory() const
3865{
3866 return WindowUIObject::create;
3867}
3868
3869} /* namespace vcl */
3870
3871/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/rtl/ref.hxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody)
77 m_pBody->acquire();
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody)
113 m_pBody->release();
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody
12.1
'pBody' is non-null
12.1
'pBody' is non-null
12.1
'pBody' is non-null
)
13
Taking true branch
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld
13.1
'pOld' is non-null
13.1
'pOld' is non-null
13.1
'pOld' is non-null
)
14
Taking true branch
127 pOld->release();
15
Calling 'VclReferenceBase::release'
19
Returning; memory was released
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
12
Calling 'Reference::set'
20
Returning; memory was released
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody)
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclreferencebase.hxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19#ifndef INCLUDED_VCL_Reference_HXX
20#define INCLUDED_VCL_Reference_HXX
21
22#include <vcl/dllapi.h>
23#include <osl/interlck.h>
24
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
32 void acquire() const
33 {
34 osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1);
35 }
36
37 void release() const
38 {
39 if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0)
16
Assuming the condition is true
17
Taking true branch
40 delete this;
18
Memory is released
41 }
42#ifdef DBG_UTIL
43#ifndef _WIN32
44 sal_Int32 getRefCount() const { return mnRefCnt; }
45#endif
46#endif
47
48
49private:
50 VclReferenceBase(const VclReferenceBase&) = delete;
51 VclReferenceBase& operator=(const VclReferenceBase&) = delete;
52
53 bool mbDisposed : 1;
54
55protected:
56 VclReferenceBase();
57protected:
58 virtual ~VclReferenceBase();
59
60protected:
61 virtual void dispose();
62
63public:
64 void disposeOnce();
65 bool isDisposed() const { return mbDisposed; }
66
67};
68#endif