Bug Summary

File:home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx
Warning:line 1976, column 10
Called C++ object pointer is null

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 winproc.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/winproc.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 <sal/config.h>
21
22#include <o3tl/safeint.hxx>
23#include <tools/debug.hxx>
24#include <tools/time.hxx>
25#include <sal/log.hxx>
26
27#include <unotools/localedatawrapper.hxx>
28
29#include <comphelper/lok.hxx>
30#include <vcl/QueueInfo.hxx>
31#include <vcl/timer.hxx>
32#include <vcl/event.hxx>
33#include <vcl/GestureEvent.hxx>
34#include <vcl/settings.hxx>
35#include <vcl/svapp.hxx>
36#include <vcl/cursor.hxx>
37#include <vcl/wrkwin.hxx>
38#include <vcl/floatwin.hxx>
39#include <vcl/toolkit/dialog.hxx>
40#include <vcl/help.hxx>
41#include <vcl/dockwin.hxx>
42#include <vcl/menu.hxx>
43#include <vcl/virdev.hxx>
44#include <vcl/uitest/logger.hxx>
45#include <vcl/ptrstyle.hxx>
46
47#include <svdata.hxx>
48#include <salwtype.hxx>
49#include <salframe.hxx>
50#include <accmgr.hxx>
51#include <print.h>
52#include <window.h>
53#include <helpwin.hxx>
54#include <brdwin.hxx>
55#include <dndlistenercontainer.hxx>
56
57#include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
58#include <com/sun/star/awt/MouseEvent.hpp>
59
60#define IMPL_MIN_NEEDSYSWIN49 49
61
62bool ImplCallPreNotify( NotifyEvent& rEvt )
63{
64 return rEvt.GetWindow()->CompatPreNotify( rEvt );
65}
66
67static bool ImplHandleMouseFloatMode( vcl::Window* pChild, const Point& rMousePos,
68 sal_uInt16 nCode, MouseNotifyEvent nSVEvent,
69 bool bMouseLeave )
70{
71 ImplSVData* pSVData = ImplGetSVData();
72
73 if (pSVData->mpWinData->mpFirstFloat && !pSVData->mpWinData->mpCaptureWin
74 && !pSVData->mpWinData->mpFirstFloat->ImplIsFloatPopupModeWindow(pChild))
75 {
76 /*
77 * #93895# since floats are system windows, coordinates have
78 * to be converted to float relative for the hittest
79 */
80 bool bHitTestInsideRect = false;
81 FloatingWindow* pFloat = pSVData->mpWinData->mpFirstFloat->ImplFloatHitTest( pChild, rMousePos, bHitTestInsideRect );
82 if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
83 {
84 if ( bMouseLeave )
85 return true;
86
87 if ( !pFloat || bHitTestInsideRect )
88 {
89 if ( ImplGetSVHelpData().mpHelpWin && !ImplGetSVHelpData().mbKeyboardHelp )
90 ImplDestroyHelpWindow( true );
91 pChild->ImplGetFrame()->SetPointer( PointerStyle::Arrow );
92 return true;
93 }
94 }
95 else
96 {
97 if ( nCode & MOUSE_LEFT(sal_uInt16(0x0001)) )
98 {
99 if ( nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN )
100 {
101 if ( !pFloat )
102 {
103 FloatingWindow* pLastLevelFloat = pSVData->mpWinData->mpFirstFloat->ImplFindLastLevelFloat();
104 pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
105 return true;
106 }
107 else if ( bHitTestInsideRect )
108 {
109 pFloat->ImplSetMouseDown();
110 return true;
111 }
112 }
113 else
114 {
115 if ( pFloat )
116 {
117 if ( bHitTestInsideRect )
118 {
119 if ( pFloat->ImplIsMouseDown() )
120 pFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel );
121 return true;
122 }
123 }
124 else
125 {
126 FloatingWindow* pLastLevelFloat = pSVData->mpWinData->mpFirstFloat->ImplFindLastLevelFloat();
127 FloatWinPopupFlags nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
128 if ( !(nPopupFlags & FloatWinPopupFlags::NoMouseUpClose) )
129 {
130 pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
131 return true;
132 }
133 }
134 }
135 }
136 else
137 {
138 if ( !pFloat )
139 {
140 FloatingWindow* pLastLevelFloat = pSVData->mpWinData->mpFirstFloat->ImplFindLastLevelFloat();
141 FloatWinPopupFlags nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
142 if ( nPopupFlags & FloatWinPopupFlags::AllMouseButtonClose )
143 {
144 if ( (nPopupFlags & FloatWinPopupFlags::NoMouseUpClose) &&
145 (nSVEvent == MouseNotifyEvent::MOUSEBUTTONUP) )
146 return true;
147 pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
148 return true;
149 }
150 else
151 return true;
152 }
153 }
154 }
155 }
156
157 return false;
158}
159
160static void ImplHandleMouseHelpRequest( vcl::Window* pChild, const Point& rMousePos )
161{
162 ImplSVHelpData& aHelpData = ImplGetSVHelpData();
163 if ( aHelpData.mpHelpWin &&
164 ( aHelpData.mpHelpWin->IsWindowOrChild( pChild ) ||
165 pChild->IsWindowOrChild( aHelpData.mpHelpWin ) ))
166 return;
167
168 HelpEventMode nHelpMode = HelpEventMode::NONE;
169 if ( aHelpData.mbQuickHelp )
170 nHelpMode = HelpEventMode::QUICK;
171 if ( aHelpData.mbBalloonHelp )
172 nHelpMode |= HelpEventMode::BALLOON;
173 if ( !(bool(nHelpMode)) )
174 return;
175
176 if ( pChild->IsInputEnabled() && !pChild->IsInModalMode() )
177 {
178 HelpEvent aHelpEvent( rMousePos, nHelpMode );
179 aHelpData.mbRequestingHelp = true;
180 pChild->RequestHelp( aHelpEvent );
181 aHelpData.mbRequestingHelp = false;
182 }
183 // #104172# do not kill keyboard activated tooltips
184 else if ( aHelpData.mpHelpWin && !aHelpData.mbKeyboardHelp)
185 {
186 ImplDestroyHelpWindow( true );
187 }
188}
189
190static void ImplSetMousePointer( vcl::Window const * pChild )
191{
192 if ( ImplGetSVHelpData().mbExtHelpMode )
193 pChild->ImplGetFrame()->SetPointer( PointerStyle::Help );
194 else
195 pChild->ImplGetFrame()->SetPointer( pChild->ImplGetMousePointer() );
196}
197
198static bool ImplCallCommand( const VclPtr<vcl::Window>& pChild, CommandEventId nEvt, void const * pData = nullptr,
199 bool bMouse = false, Point const * pPos = nullptr )
200{
201 Point aPos;
202 if ( pPos )
203 aPos = *pPos;
204 else
205 {
206 if( bMouse )
207 aPos = pChild->GetPointerPosPixel();
208 else
209 {
210 // simulate mouseposition at center of window
211 Size aSize( pChild->GetOutputSizePixel() );
212 aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
213 }
214 }
215
216 CommandEvent aCEvt( aPos, nEvt, bMouse, pData );
217 NotifyEvent aNCmdEvt( MouseNotifyEvent::COMMAND, pChild, &aCEvt );
218 bool bPreNotify = ImplCallPreNotify( aNCmdEvt );
219 if ( pChild->IsDisposed() )
220 return false;
221 if ( !bPreNotify )
222 {
223 pChild->ImplGetWindowImpl()->mbCommand = false;
224 pChild->Command( aCEvt );
225
226 if( pChild->IsDisposed() )
227 return false;
228 pChild->ImplNotifyKeyMouseCommandEventListeners( aNCmdEvt );
229 if ( pChild->IsDisposed() )
230 return false;
231 if ( pChild->ImplGetWindowImpl()->mbCommand )
232 return true;
233 }
234
235 return false;
236}
237
238/* #i34277# delayed context menu activation;
239* necessary if there already was a popup menu running.
240*/
241
242namespace {
243
244struct ContextMenuEvent
245{
246 VclPtr<vcl::Window> pWindow;
247 Point aChildPos;
248};
249
250}
251
252static void ContextMenuEventLink( void* pCEvent, void* )
253{
254 ContextMenuEvent* pEv = static_cast<ContextMenuEvent*>(pCEvent);
255
256 if( ! pEv->pWindow->IsDisposed() )
257 {
258 ImplCallCommand( pEv->pWindow, CommandEventId::ContextMenu, nullptr, true, &pEv->aChildPos );
259 }
260 delete pEv;
261}
262
263bool ImplHandleMouseEvent( const VclPtr<vcl::Window>& xWindow, MouseNotifyEvent nSVEvent, bool bMouseLeave,
264 long nX, long nY, sal_uInt64 nMsgTime,
265 sal_uInt16 nCode, MouseEventModifiers nMode )
266{
267 ImplSVHelpData& aHelpData = ImplGetSVHelpData();
268 ImplSVData* pSVData = ImplGetSVData();
269 Point aMousePos( nX, nY );
270 VclPtr<vcl::Window> pChild;
271 bool bRet(false);
272 sal_uInt16 nClicks(0);
273 ImplFrameData* pWinFrameData = xWindow->ImplGetFrameData();
274 sal_uInt16 nOldCode = pWinFrameData->mnMouseCode;
275
276 // we need a mousemove event, before we get a mousebuttondown or a
277 // mousebuttonup event
278 if ( (nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN) || (nSVEvent == MouseNotifyEvent::MOUSEBUTTONUP) )
279 {
280 if ( (nSVEvent == MouseNotifyEvent::MOUSEBUTTONUP) && aHelpData.mbExtHelpMode )
281 Help::EndExtHelp();
282 if ( aHelpData.mpHelpWin )
283 {
284 if( xWindow->ImplGetWindow() == aHelpData.mpHelpWin )
285 {
286 ImplDestroyHelpWindow( false );
287 return true; // xWindow is dead now - avoid crash!
288 }
289 else
290 ImplDestroyHelpWindow( true );
291 }
292
293 if ( (pWinFrameData->mnLastMouseX != nX) ||
294 (pWinFrameData->mnLastMouseY != nY) )
295 {
296 sal_uInt16 nMoveCode = nCode & ~(MOUSE_LEFT(sal_uInt16(0x0001)) | MOUSE_RIGHT(sal_uInt16(0x0004)) | MOUSE_MIDDLE(sal_uInt16(0x0002)));
297 ImplHandleMouseEvent(xWindow, MouseNotifyEvent::MOUSEMOVE, false, nX, nY, nMsgTime, nMoveCode, nMode);
298 }
299 }
300
301 // update frame data
302 pWinFrameData->mnBeforeLastMouseX = pWinFrameData->mnLastMouseX;
303 pWinFrameData->mnBeforeLastMouseY = pWinFrameData->mnLastMouseY;
304 pWinFrameData->mnLastMouseX = nX;
305 pWinFrameData->mnLastMouseY = nY;
306 pWinFrameData->mnMouseCode = nCode;
307 MouseEventModifiers const nTmpMask = MouseEventModifiers::SYNTHETIC | MouseEventModifiers::MODIFIERCHANGED;
308 pWinFrameData->mnMouseMode = nMode & ~nTmpMask;
309 if ( bMouseLeave )
310 {
311 pWinFrameData->mbMouseIn = false;
312 if ( ImplGetSVHelpData().mpHelpWin && !ImplGetSVHelpData().mbKeyboardHelp )
313 {
314 ImplDestroyHelpWindow( true );
315
316 if ( xWindow->IsDisposed() )
317 return true; // xWindow is dead now - avoid crash! (#122045#)
318 }
319 }
320 else
321 pWinFrameData->mbMouseIn = true;
322
323 DBG_ASSERT(!pSVData->mpWinData->mpTrackWindo { if (true && (!(!pSVData->mpWinData->mpTrackWin
|| (pSVData->mpWinData->mpTrackWin == pSVData->mpWinData
->mpCaptureWin)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "325" ": "), "%s", "ImplHandleMouseEvent: TrackWin != CaptureWin"
); } } while (false)
324 || (pSVData->mpWinData->mpTrackWin == pSVData->mpWinData->mpCaptureWin),do { if (true && (!(!pSVData->mpWinData->mpTrackWin
|| (pSVData->mpWinData->mpTrackWin == pSVData->mpWinData
->mpCaptureWin)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "325" ": "), "%s", "ImplHandleMouseEvent: TrackWin != CaptureWin"
); } } while (false)
325 "ImplHandleMouseEvent: TrackWin != CaptureWin")do { if (true && (!(!pSVData->mpWinData->mpTrackWin
|| (pSVData->mpWinData->mpTrackWin == pSVData->mpWinData
->mpCaptureWin)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "325" ": "), "%s", "ImplHandleMouseEvent: TrackWin != CaptureWin"
); } } while (false)
;
326
327 // AutoScrollMode
328 if (pSVData->mpWinData->mpAutoScrollWin && (nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN))
329 {
330 pSVData->mpWinData->mpAutoScrollWin->EndAutoScroll();
331 return true;
332 }
333
334 // find mouse window
335 if (pSVData->mpWinData->mpCaptureWin)
336 {
337 pChild = pSVData->mpWinData->mpCaptureWin;
338
339 SAL_WARN_IF( xWindow != pChild->ImplGetFrameWindow(), "vcl",do { if (true && (xWindow != pChild->ImplGetFrameWindow
())) { 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
() << "ImplHandleMouseEvent: mouse event is not sent to capture window"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "340" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "ImplHandleMouseEvent: mouse event is not sent to capture window"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ImplHandleMouseEvent: mouse event is not sent to capture window"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"),
("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "340" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "ImplHandleMouseEvent: mouse event is not sent to capture window"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "340" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "ImplHandleMouseEvent: mouse event is not sent to capture window"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ImplHandleMouseEvent: mouse event is not sent to capture window"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"),
("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "340" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
340 "ImplHandleMouseEvent: mouse event is not sent to capture window" )do { if (true && (xWindow != pChild->ImplGetFrameWindow
())) { 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
() << "ImplHandleMouseEvent: mouse event is not sent to capture window"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "340" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "ImplHandleMouseEvent: mouse event is not sent to capture window"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ImplHandleMouseEvent: mouse event is not sent to capture window"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"),
("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "340" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "ImplHandleMouseEvent: mouse event is not sent to capture window"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "340" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "ImplHandleMouseEvent: mouse event is not sent to capture window"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ImplHandleMouseEvent: mouse event is not sent to capture window"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"),
("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "340" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
341
342 // java client cannot capture mouse correctly
343 if ( xWindow != pChild->ImplGetFrameWindow() )
344 return false;
345
346 if ( bMouseLeave )
347 return false;
348 }
349 else
350 {
351 if ( bMouseLeave )
352 pChild = nullptr;
353 else
354 pChild = xWindow->ImplFindWindow( aMousePos );
355 }
356
357 // test this because mouse events are buffered in the remote version
358 // and size may not be in sync
359 if ( !pChild && !bMouseLeave )
360 return false;
361
362 // execute a few tests and catch the message or implement the status
363 if ( pChild )
364 {
365 if( pChild->ImplIsAntiparallel() )
366 {
367 // re-mirror frame pos at pChild
368 const OutputDevice *pChildWinOutDev = pChild->GetOutDev();
369 pChildWinOutDev->ReMirror( aMousePos );
370 }
371
372 // no mouse messages to disabled windows
373 // #106845# if the window was disabled during capturing we have to pass the mouse events to release capturing
374 if (pSVData->mpWinData->mpCaptureWin.get() != pChild
375 && (!pChild->IsEnabled() || !pChild->IsInputEnabled() || pChild->IsInModalMode()))
376 {
377 ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave );
378 if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
379 {
380 ImplHandleMouseHelpRequest( pChild, aMousePos );
381 if( pWinFrameData->mpMouseMoveWin.get() != pChild )
382 nMode |= MouseEventModifiers::ENTERWINDOW;
383 }
384
385 // Call the hook also, if Window is disabled
386 Point aChildPos = pChild->ImplFrameToOutput( aMousePos );
387 MouseEvent aMEvt( aChildPos, pWinFrameData->mnClickCount, nMode, nCode, nCode );
388 NotifyEvent aNEvt( nSVEvent, pChild, &aMEvt );
389
390 if ( nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN )
391 return true;
392 else
393 {
394 // Set normal MousePointer for disabled windows
395 if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
396 ImplSetMousePointer( pChild );
397
398 return false;
399 }
400 }
401
402 // End ExtTextInput-Mode, if the user click in the same TopLevel Window
403 if (pSVData->mpWinData->mpExtTextInputWin
404 && ((nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN)
405 || (nSVEvent == MouseNotifyEvent::MOUSEBUTTONUP)))
406 pSVData->mpWinData->mpExtTextInputWin->EndExtTextInput();
407 }
408
409 // determine mouse event data
410 if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
411 {
412 // check if MouseMove belongs to same window and if the
413 // status did not change
414 if ( pChild )
415 {
416 Point aChildMousePos = pChild->ImplFrameToOutput( aMousePos );
417 if ( !bMouseLeave &&
418 (pChild == pWinFrameData->mpMouseMoveWin) &&
419 (aChildMousePos.X() == pWinFrameData->mnLastMouseWinX) &&
420 (aChildMousePos.Y() == pWinFrameData->mnLastMouseWinY) &&
421 (nOldCode == pWinFrameData->mnMouseCode) )
422 {
423 // set mouse pointer anew, as it could have changed
424 // due to the mode switch
425 ImplSetMousePointer( pChild );
426 return false;
427 }
428
429 pWinFrameData->mnLastMouseWinX = aChildMousePos.X();
430 pWinFrameData->mnLastMouseWinY = aChildMousePos.Y();
431 }
432
433 // mouse click
434 nClicks = pWinFrameData->mnClickCount;
435
436 // call Start-Drag handler if required
437 // Warning: should be called before Move, as otherwise during
438 // fast mouse movements the applications move to the selection state
439 vcl::Window* pMouseDownWin = pWinFrameData->mpMouseDownWin;
440 if ( pMouseDownWin )
441 {
442 // check for matching StartDrag mode. We only compare
443 // the status of the mouse buttons, such that e. g. Mod1 can
444 // change immediately to the copy mode
445 const MouseSettings& rMSettings = pMouseDownWin->GetSettings().GetMouseSettings();
446 if ( (nCode & (MOUSE_LEFT(sal_uInt16(0x0001)) | MOUSE_RIGHT(sal_uInt16(0x0004)) | MOUSE_MIDDLE(sal_uInt16(0x0002)))) ==
447 (MouseSettings::GetStartDragCode() & (MOUSE_LEFT(sal_uInt16(0x0001)) | MOUSE_RIGHT(sal_uInt16(0x0004)) | MOUSE_MIDDLE(sal_uInt16(0x0002)))) )
448 {
449 if ( !pMouseDownWin->ImplGetFrameData()->mbStartDragCalled )
450 {
451 long nDragW = rMSettings.GetStartDragWidth();
452 long nDragH = rMSettings.GetStartDragHeight();
453 //long nMouseX = nX;
454 //long nMouseY = nY;
455 long nMouseX = aMousePos.X(); // #106074# use the possibly re-mirrored coordinates (RTL) ! nX,nY are unmodified !
456 long nMouseY = aMousePos.Y();
457 if ( (((nMouseX-nDragW) > pMouseDownWin->ImplGetFrameData()->mnFirstMouseX) ||
458 ((nMouseX+nDragW) < pMouseDownWin->ImplGetFrameData()->mnFirstMouseX)) ||
459 (((nMouseY-nDragH) > pMouseDownWin->ImplGetFrameData()->mnFirstMouseY) ||
460 ((nMouseY+nDragH) < pMouseDownWin->ImplGetFrameData()->mnFirstMouseY)) )
461 {
462 pMouseDownWin->ImplGetFrameData()->mbStartDragCalled = true;
463
464 // Check if drag source provides its own recognizer
465 if( pMouseDownWin->ImplGetFrameData()->mbInternalDragGestureRecognizer )
466 {
467 // query DropTarget from child window
468 css::uno::Reference< css::datatransfer::dnd::XDragGestureRecognizer > xDragGestureRecognizer(
469 pMouseDownWin->ImplGetWindowImpl()->mxDNDListenerContainer,
470 css::uno::UNO_QUERY );
471
472 if( xDragGestureRecognizer.is() )
473 {
474 // retrieve mouse position relative to mouse down window
475 Point relLoc = pMouseDownWin->ImplFrameToOutput( Point(
476 pMouseDownWin->ImplGetFrameData()->mnFirstMouseX,
477 pMouseDownWin->ImplGetFrameData()->mnFirstMouseY ) );
478
479 // create a UNO mouse event out of the available data
480 css::awt::MouseEvent aMouseEvent( static_cast < css::uno::XInterface * > ( nullptr ),
481#ifdef MACOSX
482 nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3),
483#else
484 nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2),
485#endif
486 nCode & (MOUSE_LEFT(sal_uInt16(0x0001)) | MOUSE_RIGHT(sal_uInt16(0x0004)) | MOUSE_MIDDLE(sal_uInt16(0x0002))),
487 nMouseX,
488 nMouseY,
489 nClicks,
490 false );
491
492 SolarMutexReleaser aReleaser;
493
494 // FIXME: where do I get Action from ?
495 css::uno::Reference< css::datatransfer::dnd::XDragSource > xDragSource = pMouseDownWin->GetDragSource();
496
497 if( xDragSource.is() )
498 {
499 static_cast < DNDListenerContainer * > ( xDragGestureRecognizer.get() )->fireDragGestureEvent( 0,
500 relLoc.X(), relLoc.Y(), xDragSource, css::uno::makeAny( aMouseEvent ) );
501 }
502 }
503 }
504 }
505 }
506 }
507 else
508 pMouseDownWin->ImplGetFrameData()->mbStartDragCalled = true;
509 }
510
511 // test for mouseleave and mouseenter
512 VclPtr<vcl::Window> pMouseMoveWin = pWinFrameData->mpMouseMoveWin;
513 if ( pChild != pMouseMoveWin )
514 {
515 if ( pMouseMoveWin )
516 {
517 Point aLeaveMousePos = pMouseMoveWin->ImplFrameToOutput( aMousePos );
518 MouseEvent aMLeaveEvt( aLeaveMousePos, nClicks, nMode | MouseEventModifiers::LEAVEWINDOW, nCode, nCode );
519 NotifyEvent aNLeaveEvt( MouseNotifyEvent::MOUSEMOVE, pMouseMoveWin, &aMLeaveEvt );
520 pWinFrameData->mbInMouseMove = true;
521 pMouseMoveWin->ImplGetWinData()->mbMouseOver = false;
522
523 // A MouseLeave can destroy this window
524 if ( !ImplCallPreNotify( aNLeaveEvt ) )
525 {
526 pMouseMoveWin->MouseMove( aMLeaveEvt );
527 if( !pMouseMoveWin->IsDisposed() )
528 aNLeaveEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNLeaveEvt );
529 }
530
531 pWinFrameData->mpMouseMoveWin = nullptr;
532 pWinFrameData->mbInMouseMove = false;
533
534 if ( pChild && pChild->IsDisposed() )
535 pChild = nullptr;
536 if ( pMouseMoveWin->IsDisposed() )
537 return true;
538 }
539
540 nMode |= MouseEventModifiers::ENTERWINDOW;
541 }
542 pWinFrameData->mpMouseMoveWin = pChild;
543 if( pChild )
544 pChild->ImplGetWinData()->mbMouseOver = true;
545
546 // MouseLeave
547 if ( !pChild )
548 return false;
549 }
550 else
551 {
552 if (pChild)
553 {
554 // mouse click
555 if ( nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN )
556 {
557 const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
558 sal_uInt64 nDblClkTime = rMSettings.GetDoubleClickTime();
559 long nDblClkW = rMSettings.GetDoubleClickWidth();
560 long nDblClkH = rMSettings.GetDoubleClickHeight();
561 //long nMouseX = nX;
562 //long nMouseY = nY;
563 long nMouseX = aMousePos.X(); // #106074# use the possibly re-mirrored coordinates (RTL) ! nX,nY are unmodified !
564 long nMouseY = aMousePos.Y();
565
566 if ( (pChild == pChild->ImplGetFrameData()->mpMouseDownWin) &&
567 (nCode == pChild->ImplGetFrameData()->mnFirstMouseCode) &&
568 ((nMsgTime-pChild->ImplGetFrameData()->mnMouseDownTime) < nDblClkTime) &&
569 ((nMouseX-nDblClkW) <= pChild->ImplGetFrameData()->mnFirstMouseX) &&
570 ((nMouseX+nDblClkW) >= pChild->ImplGetFrameData()->mnFirstMouseX) &&
571 ((nMouseY-nDblClkH) <= pChild->ImplGetFrameData()->mnFirstMouseY) &&
572 ((nMouseY+nDblClkH) >= pChild->ImplGetFrameData()->mnFirstMouseY) )
573 {
574 pChild->ImplGetFrameData()->mnClickCount++;
575 pChild->ImplGetFrameData()->mbStartDragCalled = true;
576 }
577 else
578 {
579 pChild->ImplGetFrameData()->mpMouseDownWin = pChild;
580 pChild->ImplGetFrameData()->mnClickCount = 1;
581 pChild->ImplGetFrameData()->mnFirstMouseX = nMouseX;
582 pChild->ImplGetFrameData()->mnFirstMouseY = nMouseY;
583 pChild->ImplGetFrameData()->mnFirstMouseCode = nCode;
584 pChild->ImplGetFrameData()->mbStartDragCalled = (nCode & (MOUSE_LEFT(sal_uInt16(0x0001)) | MOUSE_RIGHT(sal_uInt16(0x0004)) | MOUSE_MIDDLE(sal_uInt16(0x0002)))) !=
585 (MouseSettings::GetStartDragCode() & (MOUSE_LEFT(sal_uInt16(0x0001)) | MOUSE_RIGHT(sal_uInt16(0x0004)) | MOUSE_MIDDLE(sal_uInt16(0x0002))));
586 }
587 pChild->ImplGetFrameData()->mnMouseDownTime = nMsgTime;
588 }
589 nClicks = pChild->ImplGetFrameData()->mnClickCount;
590 }
591
592 pSVData->maAppData.mnLastInputTime = tools::Time::GetSystemTicks();
593 }
594
595 SAL_WARN_IF( !pChild, "vcl", "ImplHandleMouseEvent: pChild == NULL" )do { if (true && (!pChild)) { 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() << "ImplHandleMouseEvent: pChild == NULL"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "595" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "ImplHandleMouseEvent: pChild == NULL"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ImplHandleMouseEvent: pChild == NULL"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "595" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "ImplHandleMouseEvent: pChild == NULL") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "595" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "ImplHandleMouseEvent: pChild == NULL"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ImplHandleMouseEvent: pChild == NULL"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "595" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
596
597 if (!pChild)
598 return false;
599
600 // create mouse event
601 Point aChildPos = pChild->ImplFrameToOutput( aMousePos );
602 MouseEvent aMEvt( aChildPos, nClicks, nMode, nCode, nCode );
603
604
605 // tracking window gets the mouse events
606 if (pSVData->mpWinData->mpTrackWin)
607 pChild = pSVData->mpWinData->mpTrackWin;
608
609 // handle FloatingMode
610 if (!pSVData->mpWinData->mpTrackWin && pSVData->mpWinData->mpFirstFloat)
611 {
612 if ( ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave ) )
613 {
614 if ( !pChild->IsDisposed() )
615 {
616 pChild->ImplGetFrameData()->mbStartDragCalled = true;
617 }
618 return true;
619 }
620 }
621
622 // call handler
623 bool bCallHelpRequest = true;
624 SAL_WARN_IF( !pChild, "vcl", "ImplHandleMouseEvent: pChild is NULL" )do { if (true && (!pChild)) { 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() << "ImplHandleMouseEvent: pChild is NULL"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "624" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "ImplHandleMouseEvent: pChild is NULL"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ImplHandleMouseEvent: pChild is NULL"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "624" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "ImplHandleMouseEvent: pChild is NULL") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "624" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "ImplHandleMouseEvent: pChild is NULL"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ImplHandleMouseEvent: pChild is NULL"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "624" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
625
626 if (!pChild)
627 return false;
628
629 NotifyEvent aNEvt( nSVEvent, pChild, &aMEvt );
630 if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
631 pChild->ImplGetFrameData()->mbInMouseMove = true;
632
633 // bring window into foreground on mouseclick
634 if ( nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN )
635 {
636 if (!pSVData->mpWinData->mpFirstFloat
637 && // totop for floating windows in popup would change the focus and would close them immediately
638 !(pChild->ImplGetFrameWindow()->GetStyle()
639 & WB_OWNERDRAWDECORATION)) // ownerdrawdecorated windows must never grab focus
640 pChild->ToTop();
641 if ( pChild->IsDisposed() )
642 return true;
643 }
644
645 if ( ImplCallPreNotify( aNEvt ) || pChild->IsDisposed() )
646 bRet = true;
647 else
648 {
649 bRet = false;
650 if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
651 {
652 if (pSVData->mpWinData->mpTrackWin)
653 {
654 TrackingEvent aTEvt( aMEvt );
655 pChild->Tracking( aTEvt );
656 if ( !pChild->IsDisposed() )
657 {
658 // When ScrollRepeat, we restart the timer
659 if (pSVData->mpWinData->mpTrackTimer
660 && (pSVData->mpWinData->mnTrackFlags & StartTrackingFlags::ScrollRepeat))
661 pSVData->mpWinData->mpTrackTimer->Start();
662 }
663 bCallHelpRequest = false;
664 bRet = true;
665 }
666 else
667 {
668 // Auto-ToTop
669 if (!pSVData->mpWinData->mpCaptureWin
670 && (pChild->GetSettings().GetMouseSettings().GetOptions()
671 & MouseSettingsOptions::AutoFocus))
672 pChild->ToTop( ToTopFlags::NoGrabFocus );
673
674 if( pChild->IsDisposed() )
675 bCallHelpRequest = false;
676 else
677 {
678 // if the MouseMove handler changes the help window's visibility
679 // the HelpRequest handler should not be called anymore
680 vcl::Window* pOldHelpTextWin = ImplGetSVHelpData().mpHelpWin;
681 pChild->MouseMove( aMEvt );
682 if ( pOldHelpTextWin != ImplGetSVHelpData().mpHelpWin )
683 bCallHelpRequest = false;
684 }
685 }
686 }
687 else if ( nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN )
688 {
689 if ( pSVData->mpWinData->mpTrackWin )
690 bRet = true;
691 else
692 {
693 pChild->ImplGetWindowImpl()->mbMouseButtonDown = false;
694 pChild->MouseButtonDown( aMEvt );
695 }
696 }
697 else
698 {
699 if (pSVData->mpWinData->mpTrackWin)
700 {
701 pChild->EndTracking();
702 bRet = true;
703 }
704 else
705 {
706 pChild->ImplGetWindowImpl()->mbMouseButtonUp = false;
707 pChild->MouseButtonUp( aMEvt );
708 }
709 }
710
711 assert(aNEvt.GetWindow() == pChild)(static_cast <bool> (aNEvt.GetWindow() == pChild) ? void
(0) : __assert_fail ("aNEvt.GetWindow() == pChild", "/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
, 711, __extension__ __PRETTY_FUNCTION__))
;
712
713 if (!pChild->IsDisposed())
714 pChild->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
715 }
716
717 if (pChild->IsDisposed())
718 return true;
719
720 if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
721 pChild->ImplGetWindowImpl()->mpFrameData->mbInMouseMove = false;
722
723 if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
724 {
725 if ( bCallHelpRequest && !ImplGetSVHelpData().mbKeyboardHelp )
726 ImplHandleMouseHelpRequest( pChild, pChild->OutputToScreenPixel( aMEvt.GetPosPixel() ) );
727 bRet = true;
728 }
729 else if ( !bRet )
730 {
731 if ( nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN )
732 {
733 if ( !pChild->ImplGetWindowImpl()->mbMouseButtonDown )
734 bRet = true;
735 }
736 else
737 {
738 if ( !pChild->ImplGetWindowImpl()->mbMouseButtonUp )
739 bRet = true;
740 }
741 }
742
743 if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
744 {
745 // set new mouse pointer
746 if ( !bMouseLeave )
747 ImplSetMousePointer( pChild );
748 }
749 else if ( (nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN) || (nSVEvent == MouseNotifyEvent::MOUSEBUTTONUP) )
750 {
751 // Command-Events
752 if ( /*!bRet &&*/ (nClicks == 1) && (nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN) &&
753 (nCode == MOUSE_MIDDLE(sal_uInt16(0x0002))) )
754 {
755 MouseMiddleButtonAction nMiddleAction = pChild->GetSettings().GetMouseSettings().GetMiddleButtonAction();
756 if ( nMiddleAction == MouseMiddleButtonAction::AutoScroll )
757 bRet = !ImplCallCommand( pChild, CommandEventId::StartAutoScroll, nullptr, true, &aChildPos );
758 else if ( nMiddleAction == MouseMiddleButtonAction::PasteSelection )
759 bRet = !ImplCallCommand( pChild, CommandEventId::PasteSelection, nullptr, true, &aChildPos );
760 }
761 else
762 {
763 // ContextMenu
764 if ( (nCode == MouseSettings::GetContextMenuCode()) &&
765 (nClicks == MouseSettings::GetContextMenuClicks()) )
766 {
767 bool bContextMenu = (nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN);
768 if ( bContextMenu )
769 {
770 if( pSVData->maAppData.mpActivePopupMenu )
771 {
772 /* #i34277# there already is a context menu open
773 * that was probably just closed with EndPopupMode.
774 * We need to give the eventual corresponding
775 * PopupMenu::Execute a chance to end properly.
776 * Therefore delay context menu command and
777 * issue only after popping one frame of the
778 * Yield stack.
779 */
780 ContextMenuEvent* pEv = new ContextMenuEvent;
781 pEv->pWindow = pChild;
782 pEv->aChildPos = aChildPos;
783 Application::PostUserEvent( Link<void*,void>( pEv, ContextMenuEventLink ) );
784 }
785 else
786 bRet = ! ImplCallCommand( pChild, CommandEventId::ContextMenu, nullptr, true, &aChildPos );
787 }
788 }
789 }
790 }
791
792 return bRet;
793}
794
795static vcl::Window* ImplGetKeyInputWindow( vcl::Window* pWindow )
796{
797 ImplSVData* pSVData = ImplGetSVData();
798
799 // determine last input time
800 pSVData->maAppData.mnLastInputTime = tools::Time::GetSystemTicks();
801
802 // #127104# workaround for destroyed windows
803 if( pWindow->ImplGetWindowImpl() == nullptr )
804 return nullptr;
805
806 // find window - is every time the window which has currently the
807 // focus or the last time the focus.
808
809 // the first floating window always has the focus, try it, or any parent floating windows, first
810 vcl::Window* pChild = pSVData->mpWinData->mpFirstFloat;
811 while (pChild)
812 {
813 if (pChild->ImplGetWindowImpl()->mbFloatWin)
814 {
815 if (static_cast<FloatingWindow *>(pChild)->GrabsFocus())
816 break;
817 }
818 else if (pChild->ImplGetWindowImpl()->mbDockWin)
819 {
820 vcl::Window* pParent = pChild->GetWindow(GetWindowType::RealParent);
821 if (pParent && pParent->ImplGetWindowImpl()->mbFloatWin &&
822 static_cast<FloatingWindow *>(pParent)->GrabsFocus())
823 break;
824 }
825 pChild = pChild->GetParent();
826 }
827
828 if (!pChild)
829 pChild = pWindow;
830
831 pChild = pChild->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
832
833 // no child - then no input
834 if ( !pChild )
835 return nullptr;
836
837 // We call also KeyInput if we haven't the focus, because on Unix
838 // system this is often the case when a Lookup Choice Window has
839 // the focus - because this windows send the KeyInput directly to
840 // the window without resetting the focus
841
842 // no keyinput to disabled windows
843 if ( !pChild->IsEnabled() || !pChild->IsInputEnabled() || pChild->IsInModalMode() )
844 return nullptr;
845
846 return pChild;
847}
848
849static bool ImplHandleKey( vcl::Window* pWindow, MouseNotifyEvent nSVEvent,
850 sal_uInt16 nKeyCode, sal_uInt16 nCharCode, sal_uInt16 nRepeat, bool bForward )
851{
852 ImplSVData* pSVData = ImplGetSVData();
853 vcl::KeyCode aKeyCode( nKeyCode, nKeyCode );
854 sal_uInt16 nEvCode = aKeyCode.GetCode();
855
856 // allow application key listeners to remove the key event
857 // but make sure we're not forwarding external KeyEvents, (ie where bForward is false)
858 // because those are coming back from the listener itself and MUST be processed
859 if( bForward )
860 {
861 VclEventId nVCLEvent;
862 switch( nSVEvent )
863 {
864 case MouseNotifyEvent::KEYINPUT:
865 nVCLEvent = VclEventId::WindowKeyInput;
866 break;
867 case MouseNotifyEvent::KEYUP:
868 nVCLEvent = VclEventId::WindowKeyUp;
869 break;
870 default:
871 nVCLEvent = VclEventId::NONE;
872 break;
873 }
874 KeyEvent aKeyEvent(static_cast<sal_Unicode>(nCharCode), aKeyCode, nRepeat);
875 if (nVCLEvent != VclEventId::NONE && Application::HandleKey(nVCLEvent, pWindow, &aKeyEvent))
876 return true;
877 }
878
879 // #i1820# use locale specific decimal separator
880 if( nEvCode == KEY_DECIMAL )
881 {
882 if( Application::GetSettings().GetMiscSettings().GetEnableLocalizedDecimalSep() )
883 {
884 OUString aSep( pWindow->GetSettings().GetLocaleDataWrapper().getNumDecimalSep() );
885 nCharCode = static_cast<sal_uInt16>(aSep[0]);
886 }
887 }
888
889 bool bCtrlF6 = (aKeyCode.GetCode() == KEY_F6) && aKeyCode.IsMod1();
890
891 // determine last input time
892 pSVData->maAppData.mnLastInputTime = tools::Time::GetSystemTicks();
893
894 // handle tracking window
895 if ( nSVEvent == MouseNotifyEvent::KEYINPUT )
896 {
897 if ( ImplGetSVHelpData().mbExtHelpMode )
898 {
899 Help::EndExtHelp();
900 if ( nEvCode == KEY_ESCAPE )
901 return true;
902 }
903 if ( ImplGetSVHelpData().mpHelpWin )
904 ImplDestroyHelpWindow( false );
905
906 // AutoScrollMode
907 if (pSVData->mpWinData->mpAutoScrollWin)
908 {
909 pSVData->mpWinData->mpAutoScrollWin->EndAutoScroll();
910 if ( nEvCode == KEY_ESCAPE )
911 return true;
912 }
913
914 if (pSVData->mpWinData->mpTrackWin)
915 {
916 sal_uInt16 nOrigCode = aKeyCode.GetCode();
917
918 if ( nOrigCode == KEY_ESCAPE )
919 {
920 pSVData->mpWinData->mpTrackWin->EndTracking( TrackingEventFlags::Cancel | TrackingEventFlags::Key );
921 if (pSVData->mpWinData->mpFirstFloat)
922 {
923 FloatingWindow* pLastLevelFloat = pSVData->mpWinData->mpFirstFloat->ImplFindLastLevelFloat();
924 if ( !(pLastLevelFloat->GetPopupModeFlags() & FloatWinPopupFlags::NoKeyClose) )
925 {
926 sal_uInt16 nEscCode = aKeyCode.GetCode();
927
928 if ( nEscCode == KEY_ESCAPE )
929 pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
930 }
931 }
932 return true;
933 }
934 else if ( nOrigCode == KEY_RETURN )
935 {
936 pSVData->mpWinData->mpTrackWin->EndTracking( TrackingEventFlags::Key );
937 return true;
938 }
939 else
940 return true;
941 }
942
943 // handle FloatingMode
944 if (pSVData->mpWinData->mpFirstFloat)
945 {
946 FloatingWindow* pLastLevelFloat = pSVData->mpWinData->mpFirstFloat->ImplFindLastLevelFloat();
947 if ( !(pLastLevelFloat->GetPopupModeFlags() & FloatWinPopupFlags::NoKeyClose) )
948 {
949 sal_uInt16 nCode = aKeyCode.GetCode();
950
951 if ( (nCode == KEY_ESCAPE) || bCtrlF6)
952 {
953 pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
954 if( !bCtrlF6 )
955 return true;
956 }
957 }
958 }
959
960 // test for accel
961 if ( pSVData->maAppData.mpAccelMgr )
962 {
963 if ( pSVData->maAppData.mpAccelMgr->IsAccelKey( aKeyCode ) )
964 return true;
965 }
966 }
967
968 // find window
969 VclPtr<vcl::Window> pChild = ImplGetKeyInputWindow( pWindow );
970 if ( !pChild )
971 return false;
972
973 // RTL: mirror cursor keys
974 const OutputDevice *pChildOutDev = pChild->GetOutDev();
975 if( (aKeyCode.GetCode() == KEY_LEFT || aKeyCode.GetCode() == KEY_RIGHT) &&
976 pChildOutDev->HasMirroredGraphics() && pChild->IsRTLEnabled() )
977 aKeyCode = vcl::KeyCode( aKeyCode.GetCode() == KEY_LEFT ? KEY_RIGHT : KEY_LEFT, aKeyCode.GetModifier() );
978
979 KeyEvent aKeyEvt( static_cast<sal_Unicode>(nCharCode), aKeyCode, nRepeat );
980 NotifyEvent aNotifyEvt( nSVEvent, pChild, &aKeyEvt );
981 bool bKeyPreNotify = ImplCallPreNotify( aNotifyEvt );
982 bool bRet = true;
983
984 if ( !bKeyPreNotify && !pChild->IsDisposed() )
985 {
986 if ( nSVEvent == MouseNotifyEvent::KEYINPUT )
987 {
988 UITestLogger::getInstance().logKeyInput(pChild, aKeyEvt);
989 pChild->ImplGetWindowImpl()->mbKeyInput = false;
990 pChild->KeyInput( aKeyEvt );
991 }
992 else
993 {
994 pChild->ImplGetWindowImpl()->mbKeyUp = false;
995 pChild->KeyUp( aKeyEvt );
996 }
997 if( !pChild->IsDisposed() )
998 aNotifyEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNotifyEvt );
999 }
1000
1001 if ( pChild->IsDisposed() )
1002 return true;
1003
1004 if ( nSVEvent == MouseNotifyEvent::KEYINPUT )
1005 {
1006 if ( !bKeyPreNotify && pChild->ImplGetWindowImpl()->mbKeyInput )
1007 {
1008 sal_uInt16 nCode = aKeyCode.GetCode();
1009
1010 // #101999# is focus in or below toolbox
1011 bool bToolboxFocus=false;
1012 if( (nCode == KEY_F1) && aKeyCode.IsShift() )
1013 {
1014 vcl::Window *pWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1015 while( pWin )
1016 {
1017 if( pWin->ImplGetWindowImpl()->mbToolBox )
1018 {
1019 bToolboxFocus = true;
1020 break;
1021 }
1022 else
1023 pWin = pWin->GetParent();
1024 }
1025 }
1026
1027 // ContextMenu
1028 if ( (nCode == KEY_CONTEXTMENU) || ((nCode == KEY_F10) && aKeyCode.IsShift() && !aKeyCode.IsMod1() && !aKeyCode.IsMod2() ) )
1029 bRet = !ImplCallCommand( pChild, CommandEventId::ContextMenu );
1030 else if ( ( (nCode == KEY_F2) && aKeyCode.IsShift() ) || ( (nCode == KEY_F1) && aKeyCode.IsMod1() ) ||
1031 // #101999# no active help when focus in toolbox, simulate BalloonHelp instead
1032 ( (nCode == KEY_F1) && aKeyCode.IsShift() && bToolboxFocus ) )
1033 {
1034 // TipHelp via Keyboard (Shift-F2 or Ctrl-F1)
1035 // simulate mouseposition at center of window
1036
1037 Size aSize = pChild->GetOutputSize();
1038 Point aPos( aSize.getWidth()/2, aSize.getHeight()/2 );
1039 aPos = pChild->OutputToScreenPixel( aPos );
1040
1041 HelpEvent aHelpEvent( aPos, HelpEventMode::BALLOON );
1042 aHelpEvent.SetKeyboardActivated( true );
1043 ImplGetSVHelpData().mbSetKeyboardHelp = true;
1044 pChild->RequestHelp( aHelpEvent );
1045 ImplGetSVHelpData().mbSetKeyboardHelp = false;
1046 }
1047 else if ( (nCode == KEY_F1) || (nCode == KEY_HELP) )
1048 {
1049 if ( !aKeyCode.GetModifier() )
1050 {
1051 if ( ImplGetSVHelpData().mbContextHelp )
1052 {
1053 Point aMousePos = pChild->OutputToScreenPixel( pChild->GetPointerPosPixel() );
1054 HelpEvent aHelpEvent( aMousePos, HelpEventMode::CONTEXT );
1055 pChild->RequestHelp( aHelpEvent );
1056 }
1057 else
1058 bRet = false;
1059 }
1060 else if ( aKeyCode.IsShift() )
1061 {
1062 if ( ImplGetSVHelpData().mbExtHelp )
1063 Help::StartExtHelp();
1064 else
1065 bRet = false;
1066 }
1067 }
1068 else
1069 bRet = false;
1070 }
1071 }
1072 else
1073 {
1074 if ( !bKeyPreNotify && pChild->ImplGetWindowImpl()->mbKeyUp )
1075 bRet = false;
1076 }
1077
1078 // #105591# send keyinput to parent if we are a floating window and the key was not processed yet
1079 if( !bRet && pWindow->ImplGetWindowImpl() && pWindow->ImplGetWindowImpl()->mbFloatWin && pWindow->GetParent() && (pWindow->ImplGetWindowImpl()->mpFrame != pWindow->GetParent()->ImplGetWindowImpl()->mpFrame) )
1080 {
1081 pChild = pWindow->GetParent();
1082
1083 // call handler
1084 NotifyEvent aNEvt( nSVEvent, pChild, &aKeyEvt );
1085 bool bPreNotify = ImplCallPreNotify( aNEvt );
1086 if ( pChild->IsDisposed() )
1087 return true;
1088
1089 if ( !bPreNotify )
1090 {
1091 if ( nSVEvent == MouseNotifyEvent::KEYINPUT )
1092 {
1093 pChild->ImplGetWindowImpl()->mbKeyInput = false;
1094 pChild->KeyInput( aKeyEvt );
1095 }
1096 else
1097 {
1098 pChild->ImplGetWindowImpl()->mbKeyUp = false;
1099 pChild->KeyUp( aKeyEvt );
1100 }
1101
1102 if( !pChild->IsDisposed() )
1103 aNEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
1104 if ( pChild->IsDisposed() )
1105 return true;
1106 }
1107
1108 if( bPreNotify || !pChild->ImplGetWindowImpl()->mbKeyInput )
1109 bRet = true;
1110 }
1111
1112 return bRet;
1113}
1114
1115static bool ImplHandleExtTextInput( vcl::Window* pWindow,
1116 const OUString& rText,
1117 const ExtTextInputAttr* pTextAttr,
1118 sal_Int32 nCursorPos, sal_uInt16 nCursorFlags )
1119{
1120 ImplSVData* pSVData = ImplGetSVData();
1121 vcl::Window* pChild = nullptr;
1122
1123 int nTries = 200;
1124 while( nTries-- )
1125 {
1126 pChild = pSVData->mpWinData->mpExtTextInputWin;
1127 if ( !pChild )
1128 {
1129 pChild = ImplGetKeyInputWindow( pWindow );
1130 if ( !pChild )
1131 return false;
1132 }
1133 if( !pChild->ImplGetWindowImpl()->mpFrameData->mnFocusId )
1134 break;
1135
1136 if (comphelper::LibreOfficeKit::isActive())
1137 {
1138 SAL_WARN("vcl", "Failed to get ext text input context")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
() << "Failed to get ext text input context") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "1138" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Failed to get ext text input context"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Failed to get ext text input context"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "1138" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Failed to get ext text input context") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "1138" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Failed to get ext text input context"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Failed to get ext text input context"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "1138" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1139 break;
1140 }
1141 Application::Yield();
1142 }
1143
1144 // If it is the first ExtTextInput call, we inform the information
1145 // and allocate the data, which we must store in this mode
1146 ImplWinData* pWinData = pChild->ImplGetWinData();
1147 if ( !pChild->ImplGetWindowImpl()->mbExtTextInput )
1148 {
1149 pChild->ImplGetWindowImpl()->mbExtTextInput = true;
1150 pWinData->mpExtOldText = OUString();
1151 pWinData->mpExtOldAttrAry.reset();
1152 pSVData->mpWinData->mpExtTextInputWin = pChild;
1153 ImplCallCommand( pChild, CommandEventId::StartExtTextInput );
1154 }
1155
1156 // be aware of being recursively called in StartExtTextInput
1157 if ( !pChild->ImplGetWindowImpl()->mbExtTextInput )
1158 return false;
1159
1160 // Test for changes
1161 bool bOnlyCursor = false;
1162 sal_Int32 nMinLen = std::min( pWinData->mpExtOldText->getLength(), rText.getLength() );
1163 sal_Int32 nDeltaStart = 0;
1164 while ( nDeltaStart < nMinLen )
1165 {
1166 if ( (*pWinData->mpExtOldText)[nDeltaStart] != rText[nDeltaStart] )
1167 break;
1168 nDeltaStart++;
1169 }
1170 if ( pWinData->mpExtOldAttrAry || pTextAttr )
1171 {
1172 if ( !pWinData->mpExtOldAttrAry || !pTextAttr )
1173 nDeltaStart = 0;
1174 else
1175 {
1176 sal_Int32 i = 0;
1177 while ( i < nDeltaStart )
1178 {
1179 if ( pWinData->mpExtOldAttrAry[i] != pTextAttr[i] )
1180 {
1181 nDeltaStart = i;
1182 break;
1183 }
1184 i++;
1185 }
1186 }
1187 }
1188 if ( (nDeltaStart >= nMinLen) &&
1189 (pWinData->mpExtOldText->getLength() == rText.getLength()) )
1190 bOnlyCursor = true;
1191
1192 // Call Event and store the information
1193 CommandExtTextInputData aData( rText, pTextAttr,
1194 nCursorPos, nCursorFlags,
1195 bOnlyCursor );
1196 *pWinData->mpExtOldText = rText;
1197 pWinData->mpExtOldAttrAry.reset();
1198 if ( pTextAttr )
1199 {
1200 pWinData->mpExtOldAttrAry.reset( new ExtTextInputAttr[rText.getLength()] );
1201 memcpy( pWinData->mpExtOldAttrAry.get(), pTextAttr, rText.getLength()*sizeof( ExtTextInputAttr ) );
1202 }
1203 return !ImplCallCommand( pChild, CommandEventId::ExtTextInput, &aData );
1204}
1205
1206static bool ImplHandleEndExtTextInput()
1207{
1208 ImplSVData* pSVData = ImplGetSVData();
1209 vcl::Window* pChild = pSVData->mpWinData->mpExtTextInputWin;
1210 bool bRet = false;
1211
1212 if ( pChild )
1213 {
1214 pChild->ImplGetWindowImpl()->mbExtTextInput = false;
1215 pSVData->mpWinData->mpExtTextInputWin = nullptr;
1216 ImplWinData* pWinData = pChild->ImplGetWinData();
1217 pWinData->mpExtOldText.reset();
1218 pWinData->mpExtOldAttrAry.reset();
1219 bRet = !ImplCallCommand( pChild, CommandEventId::EndExtTextInput );
1220 }
1221
1222 return bRet;
1223}
1224
1225static void ImplHandleExtTextInputPos( vcl::Window* pWindow,
1226 tools::Rectangle& rRect, long& rInputWidth,
1227 bool * pVertical )
1228{
1229 ImplSVData* pSVData = ImplGetSVData();
1230 vcl::Window* pChild = pSVData->mpWinData->mpExtTextInputWin;
1231
1232 if ( !pChild )
1233 pChild = ImplGetKeyInputWindow( pWindow );
1234 else
1235 {
1236 // Test, if the Window is related to the frame
1237 if ( !pWindow->ImplIsWindowOrChild( pChild ) )
1238 pChild = ImplGetKeyInputWindow( pWindow );
1239 }
1240
1241 if ( pChild )
1242 {
1243 const OutputDevice *pChildOutDev = pChild->GetOutDev();
1244 ImplCallCommand( pChild, CommandEventId::CursorPos );
1245 const tools::Rectangle* pRect = pChild->GetCursorRect();
1246 if ( pRect )
1247 rRect = pChildOutDev->ImplLogicToDevicePixel( *pRect );
1248 else
1249 {
1250 vcl::Cursor* pCursor = pChild->GetCursor();
1251 if ( pCursor )
1252 {
1253 Point aPos = pChildOutDev->ImplLogicToDevicePixel( pCursor->GetPos() );
1254 Size aSize = pChild->LogicToPixel( pCursor->GetSize() );
1255 if ( !aSize.Width() )
1256 aSize.setWidth( pChild->GetSettings().GetStyleSettings().GetCursorSize() );
1257 rRect = tools::Rectangle( aPos, aSize );
1258 }
1259 else
1260 rRect = tools::Rectangle( Point( pChild->GetOutOffXPixel(), pChild->GetOutOffYPixel() ), Size() );
1261 }
1262 rInputWidth = pChild->ImplLogicWidthToDevicePixel( pChild->GetCursorExtTextInputWidth() );
1263 if ( !rInputWidth )
1264 rInputWidth = rRect.GetWidth();
1265 }
1266 if (pVertical != nullptr)
1267 *pVertical
1268 = pChild != nullptr && pChild->GetInputContext().GetFont().IsVertical();
1269}
1270
1271static bool ImplHandleInputContextChange( vcl::Window* pWindow )
1272{
1273 vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
1274 CommandInputContextData aData;
1275 return !ImplCallCommand( pChild, CommandEventId::InputContextChange, &aData );
1276}
1277
1278static bool ImplCallWheelCommand( const VclPtr<vcl::Window>& pWindow, const Point& rPos,
1279 const CommandWheelData* pWheelData )
1280{
1281 Point aCmdMousePos = pWindow->ImplFrameToOutput( rPos );
1282 CommandEvent aCEvt( aCmdMousePos, CommandEventId::Wheel, true, pWheelData );
1283 NotifyEvent aNCmdEvt( MouseNotifyEvent::COMMAND, pWindow, &aCEvt );
1284 bool bPreNotify = ImplCallPreNotify( aNCmdEvt );
1285 if ( pWindow->IsDisposed() )
1286 return false;
1287 if ( !bPreNotify )
1288 {
1289 pWindow->ImplGetWindowImpl()->mbCommand = false;
1290 pWindow->Command( aCEvt );
1291 if ( pWindow->IsDisposed() )
1292 return false;
1293 if ( pWindow->ImplGetWindowImpl()->mbCommand )
1294 return true;
1295 }
1296 return false;
1297}
1298
1299static bool acceptableWheelScrollTarget(const vcl::Window *pMouseWindow)
1300{
1301 return (pMouseWindow && !pMouseWindow->isDisposed() && pMouseWindow->IsInputEnabled() && !pMouseWindow->IsInModalMode());
1302}
1303
1304//If the last event at the same absolute screen position was handled by a
1305//different window then reuse that window if the event occurs within 1/2 a
1306//second, i.e. so scrolling down something like the calc sidebar that contains
1307//widgets that respond to wheel events will continue to send the event to the
1308//scrolling widget in favour of the widget that happens to end up under the
1309//mouse.
1310static bool shouldReusePreviousMouseWindow(const SalWheelMouseEvent& rPrevEvt, const SalWheelMouseEvent& rEvt)
1311{
1312 return (rEvt.mnX == rPrevEvt.mnX && rEvt.mnY == rPrevEvt.mnY && rEvt.mnTime-rPrevEvt.mnTime < 500/*ms*/);
1313}
1314
1315namespace {
1316
1317class HandleGestureEventBase
1318{
1319protected:
1320 ImplSVData* m_pSVData;
1321 VclPtr<vcl::Window> m_pWindow;
1322 Point m_aMousePos;
1323
1324public:
1325 HandleGestureEventBase(vcl::Window *pWindow, const Point &rMousePos)
1326 : m_pSVData(ImplGetSVData())
1327 , m_pWindow(pWindow)
1328 , m_aMousePos(rMousePos)
1329 {
1330 }
1331 bool Setup();
1332 vcl::Window* FindTarget();
1333 vcl::Window* Dispatch(vcl::Window* pTarget);
1334 virtual bool CallCommand(vcl::Window *pWindow, const Point &rMousePos) = 0;
1335 virtual ~HandleGestureEventBase() {}
1336};
1337
1338}
1339
1340bool HandleGestureEventBase::Setup()
1341{
1342
1343 if (m_pSVData->mpWinData->mpAutoScrollWin)
1344 m_pSVData->mpWinData->mpAutoScrollWin->EndAutoScroll();
1345 if (ImplGetSVHelpData().mpHelpWin)
1346 ImplDestroyHelpWindow( true );
1347 return !m_pWindow->IsDisposed();
1348}
1349
1350vcl::Window* HandleGestureEventBase::FindTarget()
1351{
1352 // first check any floating window ( eg. drop down listboxes)
1353 vcl::Window *pMouseWindow = nullptr;
1354
1355 if (m_pSVData->mpWinData->mpFirstFloat && !m_pSVData->mpWinData->mpCaptureWin &&
1356 !m_pSVData->mpWinData->mpFirstFloat->ImplIsFloatPopupModeWindow( m_pWindow ) )
1357 {
1358 bool bHitTestInsideRect = false;
1359 pMouseWindow = m_pSVData->mpWinData->mpFirstFloat->ImplFloatHitTest( m_pWindow, m_aMousePos, bHitTestInsideRect );
1360 if (!pMouseWindow)
1361 pMouseWindow = m_pSVData->mpWinData->mpFirstFloat;
1362 }
1363 // then try the window directly beneath the mouse
1364 if( !pMouseWindow )
1365 {
1366 pMouseWindow = m_pWindow->ImplFindWindow( m_aMousePos );
1367 }
1368 else
1369 {
1370 // transform coordinates to float window frame coordinates
1371 pMouseWindow = pMouseWindow->ImplFindWindow(
1372 pMouseWindow->OutputToScreenPixel(
1373 pMouseWindow->AbsoluteScreenToOutputPixel(
1374 m_pWindow->OutputToAbsoluteScreenPixel(
1375 m_pWindow->ScreenToOutputPixel( m_aMousePos ) ) ) ) );
1376 }
1377
1378 while (acceptableWheelScrollTarget(pMouseWindow))
1379 {
1380 if (pMouseWindow->IsEnabled())
1381 break;
1382 //try the parent if this one is disabled
1383 pMouseWindow = pMouseWindow->GetParent();
1384 }
1385
1386 return pMouseWindow;
1387}
1388
1389vcl::Window *HandleGestureEventBase::Dispatch(vcl::Window* pMouseWindow)
1390{
1391 vcl::Window *pDispatchedTo = nullptr;
1392
1393 if (acceptableWheelScrollTarget(pMouseWindow) && pMouseWindow->IsEnabled())
1394 {
1395 // transform coordinates to float window frame coordinates
1396 Point aRelMousePos( pMouseWindow->OutputToScreenPixel(
1397 pMouseWindow->AbsoluteScreenToOutputPixel(
1398 m_pWindow->OutputToAbsoluteScreenPixel(
1399 m_pWindow->ScreenToOutputPixel( m_aMousePos ) ) ) ) );
1400 bool bPropogate = CallCommand(pMouseWindow, aRelMousePos);
1401 if (!bPropogate)
1402 pDispatchedTo = pMouseWindow;
1403 }
1404
1405 // if the command was not handled try the focus window
1406 if (!pDispatchedTo)
1407 {
1408 vcl::Window* pFocusWindow = m_pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1409 if ( pFocusWindow && (pFocusWindow != pMouseWindow) &&
1410 (pFocusWindow == m_pSVData->mpWinData->mpFocusWin) )
1411 {
1412 // no wheel-messages to disabled windows
1413 if ( pFocusWindow->IsEnabled() && pFocusWindow->IsInputEnabled() && ! pFocusWindow->IsInModalMode() )
1414 {
1415 // transform coordinates to focus window frame coordinates
1416 Point aRelMousePos( pFocusWindow->OutputToScreenPixel(
1417 pFocusWindow->AbsoluteScreenToOutputPixel(
1418 m_pWindow->OutputToAbsoluteScreenPixel(
1419 m_pWindow->ScreenToOutputPixel( m_aMousePos ) ) ) ) );
1420 bool bPropogate = CallCommand(pFocusWindow, aRelMousePos);
1421 if (!bPropogate)
1422 pDispatchedTo = pMouseWindow;
1423 }
1424 }
1425 }
1426 return pDispatchedTo;
1427}
1428
1429namespace {
1430
1431class HandleWheelEvent : public HandleGestureEventBase
1432{
1433private:
1434 CommandWheelData m_aWheelData;
1435public:
1436 HandleWheelEvent(vcl::Window *pWindow, const SalWheelMouseEvent& rEvt)
1437 : HandleGestureEventBase(pWindow, Point(rEvt.mnX, rEvt.mnY))
1438 {
1439 CommandWheelMode nMode;
1440 sal_uInt16 nCode = rEvt.mnCode;
1441 bool bHorz = rEvt.mbHorz;
1442 bool bPixel = rEvt.mbDeltaIsPixel;
1443 if ( nCode & KEY_MOD1 )
1444 nMode = CommandWheelMode::ZOOM;
1445 else if ( nCode & KEY_MOD2 )
1446 nMode = CommandWheelMode::DATAZOOM;
1447 else
1448 {
1449 nMode = CommandWheelMode::SCROLL;
1450 // #i85450# interpret shift-wheel as horizontal wheel action
1451 if( (nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)) == KEY_SHIFT )
1452 bHorz = true;
1453 }
1454
1455 m_aWheelData = CommandWheelData(rEvt.mnDelta, rEvt.mnNotchDelta, rEvt.mnScrollLines, nMode, nCode, bHorz, bPixel);
1456
1457 }
1458 virtual bool CallCommand(vcl::Window *pWindow, const Point &rMousePos) override
1459 {
1460 return ImplCallWheelCommand(pWindow, rMousePos, &m_aWheelData);
1461 }
1462 bool HandleEvent(const SalWheelMouseEvent& rEvt);
1463};
1464
1465}
1466
1467bool HandleWheelEvent::HandleEvent(const SalWheelMouseEvent& rEvt)
1468{
1469 if (!Setup())
1470 return false;
1471
1472 VclPtr<vcl::Window> xMouseWindow = FindTarget();
1473
1474 ImplSVData* pSVData = ImplGetSVData();
1475
1476 // avoid the problem that scrolling via wheel to this point brings a widget
1477 // under the mouse that also accepts wheel commands, so stick with the old
1478 // widget if the time gap is very small
1479 if (shouldReusePreviousMouseWindow(pSVData->mpWinData->maLastWheelEvent, rEvt) &&
1480 acceptableWheelScrollTarget(pSVData->mpWinData->mpLastWheelWindow))
1481 {
1482 xMouseWindow = pSVData->mpWinData->mpLastWheelWindow;
1483 }
1484
1485 pSVData->mpWinData->maLastWheelEvent = rEvt;
1486
1487 pSVData->mpWinData->mpLastWheelWindow = Dispatch(xMouseWindow);
1488
1489 return pSVData->mpWinData->mpLastWheelWindow;
1490}
1491
1492namespace {
1493
1494class HandleGestureEvent : public HandleGestureEventBase
1495{
1496public:
1497 HandleGestureEvent(vcl::Window *pWindow, const Point &rMousePos)
1498 : HandleGestureEventBase(pWindow, rMousePos)
1499 {
1500 }
1501 bool HandleEvent();
1502};
1503
1504}
1505
1506bool HandleGestureEvent::HandleEvent()
1507{
1508 if (!Setup())
1509 return false;
1510
1511 vcl::Window *pTarget = FindTarget();
1512
1513 bool bHandled = Dispatch(pTarget) != nullptr;
1514 return bHandled;
1515}
1516
1517static bool ImplHandleWheelEvent(vcl::Window* pWindow, const SalWheelMouseEvent& rEvt)
1518{
1519 HandleWheelEvent aHandler(pWindow, rEvt);
1520 return aHandler.HandleEvent(rEvt);
1521}
1522
1523namespace {
1524
1525class HandleSwipeEvent : public HandleGestureEvent
1526{
1527private:
1528 CommandSwipeData m_aSwipeData;
1529public:
1530 HandleSwipeEvent(vcl::Window *pWindow, const SalSwipeEvent& rEvt)
1531 : HandleGestureEvent(pWindow, Point(rEvt.mnX, rEvt.mnY)),
1532 m_aSwipeData(rEvt.mnVelocityX)
1533 {
1534 }
1535 virtual bool CallCommand(vcl::Window *pWindow, const Point &/*rMousePos*/) override
1536 {
1537 return ImplCallCommand(pWindow, CommandEventId::Swipe, &m_aSwipeData);
1538 }
1539};
1540
1541}
1542
1543static bool ImplHandleSwipe(vcl::Window *pWindow, const SalSwipeEvent& rEvt)
1544{
1545 HandleSwipeEvent aHandler(pWindow, rEvt);
1546 return aHandler.HandleEvent();
1547}
1548
1549namespace {
1550
1551class HandleLongPressEvent : public HandleGestureEvent
1552{
1553private:
1554 CommandLongPressData m_aLongPressData;
1555public:
1556 HandleLongPressEvent(vcl::Window *pWindow, const SalLongPressEvent& rEvt)
1557 : HandleGestureEvent(pWindow, Point(rEvt.mnX, rEvt.mnY)),
1558 m_aLongPressData(rEvt.mnX, rEvt.mnY)
1559 {
1560 }
1561 virtual bool CallCommand(vcl::Window *pWindow, const Point &/*rMousePos*/) override
1562 {
1563 return ImplCallCommand(pWindow, CommandEventId::LongPress, &m_aLongPressData);
1564 }
1565};
1566
1567}
1568
1569static bool ImplHandleLongPress(vcl::Window *pWindow, const SalLongPressEvent& rEvt)
1570{
1571 HandleLongPressEvent aHandler(pWindow, rEvt);
1572 return aHandler.HandleEvent();
1573}
1574
1575namespace {
1576
1577class HandleGeneralGestureEvent : public HandleGestureEvent
1578{
1579private:
1580 CommandGestureData m_aGestureData;
1581
1582public:
1583 HandleGeneralGestureEvent(vcl::Window* pWindow, const SalGestureEvent& rEvent)
1584 : HandleGestureEvent(pWindow, Point(rEvent.mnX, rEvent.mnY))
1585 , m_aGestureData(rEvent.mnX, rEvent.mnY, rEvent.meEventType, rEvent.mfOffset, rEvent.meOrientation)
1586 {
1587 }
1588
1589 virtual bool CallCommand(vcl::Window* pWindow, const Point& /*rMousePos*/) override
1590 {
1591 return ImplCallCommand(pWindow, CommandEventId::Gesture, &m_aGestureData);
1592 }
1593};
1594
1595}
1596
1597static bool ImplHandleGestureEvent(vcl::Window* pWindow, const SalGestureEvent& rEvent)
1598{
1599 HandleGeneralGestureEvent aHandler(pWindow, rEvent);
1600 return aHandler.HandleEvent();
1601}
1602
1603static void ImplHandlePaint( vcl::Window* pWindow, const tools::Rectangle& rBoundRect, bool bImmediateUpdate )
1604{
1605 // system paint events must be checked for re-mirroring
1606 pWindow->ImplGetWindowImpl()->mnPaintFlags |= ImplPaintFlags::CheckRtl;
1607
1608 // trigger paint for all windows that live in the new paint region
1609 vcl::Region aRegion( rBoundRect );
1610 pWindow->ImplInvalidateOverlapFrameRegion( aRegion );
1611 if( bImmediateUpdate )
1612 {
1613 // #i87663# trigger possible pending resize notifications
1614 // (GetSizePixel does that for us)
1615 pWindow->GetSizePixel();
1616 // force drawing immediately
1617 pWindow->PaintImmediately();
1618 }
1619}
1620
1621static void KillOwnPopups( vcl::Window const * pWindow )
1622{
1623 ImplSVData* pSVData = ImplGetSVData();
1624 vcl::Window *pParent = pWindow->ImplGetWindowImpl()->mpFrameWindow;
1625 vcl::Window *pChild = pSVData->mpWinData->mpFirstFloat;
1626 if ( pChild && pParent->ImplIsWindowOrChild( pChild, true ) )
1627 {
1628 if (!(pSVData->mpWinData->mpFirstFloat->GetPopupModeFlags()
1629 & FloatWinPopupFlags::NoAppFocusClose))
1630 pSVData->mpWinData->mpFirstFloat->EndPopupMode(FloatWinPopupEndFlags::Cancel
1631 | FloatWinPopupEndFlags::CloseAll);
1632 }
1633}
1634
1635void ImplHandleResize( vcl::Window* pWindow, long nNewWidth, long nNewHeight )
1636{
1637 const bool bChanged = (nNewWidth != pWindow->GetOutputWidthPixel()) || (nNewHeight != pWindow->GetOutputHeightPixel());
1638 if (bChanged && pWindow->GetStyle() & (WB_MOVEABLE|WB_SIZEABLE))
1639 {
1640 KillOwnPopups( pWindow );
1641 if( pWindow->ImplGetWindow() != ImplGetSVHelpData().mpHelpWin )
1642 ImplDestroyHelpWindow( true );
1643 }
1644
1645 if (
1646 (nNewWidth > 0 && nNewHeight > 0) ||
1647 pWindow->ImplGetWindow()->ImplGetWindowImpl()->mbAllResize
1648 )
1649 {
1650 if (bChanged)
1651 {
1652 pWindow->mnOutWidth = nNewWidth;
1653 pWindow->mnOutHeight = nNewHeight;
1654 pWindow->ImplGetWindowImpl()->mbWaitSystemResize = false;
1655 if ( pWindow->IsReallyVisible() )
1656 pWindow->ImplSetClipFlag();
1657 if ( pWindow->IsVisible() || pWindow->ImplGetWindow()->ImplGetWindowImpl()->mbAllResize ||
1658 ( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplGetWindowImpl()->mpClientWindow ) ) // propagate resize for system border windows
1659 {
1660 bool bStartTimer = true;
1661 // use resize buffering for user resizes
1662 // ownerdraw decorated windows and floating windows can be resized immediately (i.e. synchronously)
1663 if( pWindow->ImplGetWindowImpl()->mbFrame && (pWindow->GetStyle() & WB_SIZEABLE)
1664 && !(pWindow->GetStyle() & WB_OWNERDRAWDECORATION) // synchronous resize for ownerdraw decorated windows (toolbars)
1665 && !pWindow->ImplGetWindowImpl()->mbFloatWin ) // synchronous resize for floating windows, #i43799#
1666 {
1667 if( pWindow->ImplGetWindowImpl()->mpClientWindow )
1668 {
1669 // #i42750# presentation wants to be informed about resize
1670 // as early as possible
1671 WorkWindow* pWorkWindow = dynamic_cast<WorkWindow*>(pWindow->ImplGetWindowImpl()->mpClientWindow.get());
1672 if( ! pWorkWindow || pWorkWindow->IsPresentationMode() )
1673 bStartTimer = false;
1674 }
1675 else
1676 {
1677 WorkWindow* pWorkWindow = dynamic_cast<WorkWindow*>(pWindow);
1678 if( ! pWorkWindow || pWorkWindow->IsPresentationMode() )
1679 bStartTimer = false;
1680 }
1681 }
1682 else
1683 bStartTimer = false;
1684
1685 if( bStartTimer )
1686 pWindow->ImplGetWindowImpl()->mpFrameData->maResizeIdle.Start();
1687 else
1688 pWindow->ImplCallResize(); // otherwise menus cannot be positioned
1689 }
1690 else
1691 pWindow->ImplGetWindowImpl()->mbCallResize = true;
1692
1693 if (pWindow->SupportsDoubleBuffering() && pWindow->ImplGetWindowImpl()->mbFrame)
1694 {
1695 // Propagate resize for the frame's buffer.
1696 pWindow->ImplGetWindowImpl()->mpFrameData->mpBuffer->SetOutputSizePixel(pWindow->GetOutputSizePixel());
1697 }
1698 }
1699 }
1700
1701 pWindow->ImplGetWindowImpl()->mpFrameData->mbNeedSysWindow = (nNewWidth < IMPL_MIN_NEEDSYSWIN49) ||
1702 (nNewHeight < IMPL_MIN_NEEDSYSWIN49);
1703 bool bMinimized = (nNewWidth <= 0) || (nNewHeight <= 0);
1704 if( bMinimized != pWindow->ImplGetWindowImpl()->mpFrameData->mbMinimized )
1705 pWindow->ImplGetWindowImpl()->mpFrameWindow->ImplNotifyIconifiedState( bMinimized );
1706 pWindow->ImplGetWindowImpl()->mpFrameData->mbMinimized = bMinimized;
1707}
1708
1709static void ImplHandleMove( vcl::Window* pWindow )
1710{
1711 if( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplIsFloatingWindow() && pWindow->IsReallyVisible() )
1712 {
1713 static_cast<FloatingWindow*>(pWindow)->EndPopupMode( FloatWinPopupEndFlags::TearOff );
1714 pWindow->ImplCallMove();
1715 }
1716
1717 if( pWindow->GetStyle() & (WB_MOVEABLE|WB_SIZEABLE) )
1718 {
1719 KillOwnPopups( pWindow );
1720 if( pWindow->ImplGetWindow() != ImplGetSVHelpData().mpHelpWin )
1721 ImplDestroyHelpWindow( true );
1722 }
1723
1724 if ( pWindow->IsVisible() )
1725 pWindow->ImplCallMove();
1726 else
1727 pWindow->ImplGetWindowImpl()->mbCallMove = true; // make sure the framepos will be updated on the next Show()
1728
1729 if ( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplGetWindowImpl()->mpClientWindow )
1730 pWindow->ImplGetWindowImpl()->mpClientWindow->ImplCallMove(); // notify client to update geometry
1731
1732}
1733
1734static void ImplHandleMoveResize( vcl::Window* pWindow, long nNewWidth, long nNewHeight )
1735{
1736 ImplHandleMove( pWindow );
1737 ImplHandleResize( pWindow, nNewWidth, nNewHeight );
1738}
1739
1740static void ImplActivateFloatingWindows( vcl::Window const * pWindow, bool bActive )
1741{
1742 // First check all overlapping windows
1743 vcl::Window* pTempWindow = pWindow->ImplGetWindowImpl()->mpFirstOverlap;
1744 while ( pTempWindow )
1745 {
1746 if ( pTempWindow->GetActivateMode() == ActivateModeFlags::NONE )
1747 {
1748 if ( (pTempWindow->GetType() == WindowType::BORDERWINDOW) &&
1749 (pTempWindow->ImplGetWindow()->GetType() == WindowType::FLOATINGWINDOW) )
1750 static_cast<ImplBorderWindow*>(pTempWindow)->SetDisplayActive( bActive );
1751 }
1752
1753 ImplActivateFloatingWindows( pTempWindow, bActive );
1754 pTempWindow = pTempWindow->ImplGetWindowImpl()->mpNext;
1755 }
1756}
1757
1758IMPL_LINK_NOARG(vcl::Window, ImplAsyncFocusHdl, void*, void)void vcl::Window::LinkStubImplAsyncFocusHdl(void * instance, void
* data) { return static_cast<vcl::Window *>(instance)->
ImplAsyncFocusHdl(data); } void vcl::Window::ImplAsyncFocusHdl
(__attribute__ ((unused)) void*)
1759{
1760 ImplGetWindowImpl()->mpFrameData->mnFocusId = nullptr;
1761
1762 // If the status has been preserved, because we got back the focus
1763 // in the meantime, we do nothing
1764 bool bHasFocus = ImplGetWindowImpl()->mpFrameData->mbHasFocus || ImplGetWindowImpl()->mpFrameData->mbSysObjFocus;
1765
1766 // next execute the delayed functions
1767 if ( bHasFocus )
1768 {
1769 // redraw all floating windows inactive
1770 if ( ImplGetWindowImpl()->mpFrameData->mbStartFocusState != bHasFocus )
1771 ImplActivateFloatingWindows( this, bHasFocus );
1772
1773 if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin )
1774 {
1775 bool bHandled = false;
1776 if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsInputEnabled() &&
1777 ! ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsInModalMode() )
1778 {
1779 if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsEnabled() )
1780 {
1781 ImplGetWindowImpl()->mpFrameData->mpFocusWin->GrabFocus();
1782 bHandled = true;
1783 }
1784 else if( ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplHasDlgCtrl() )
1785 {
1786 // #109094# if the focus is restored to a disabled dialog control (was disabled meanwhile)
1787 // try to move it to the next control
1788 ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplDlgCtrlNextWindow();
1789 bHandled = true;
1790 }
1791 }
1792 if ( !bHandled )
1793 {
1794 ImplSVData* pSVData = ImplGetSVData();
1795 vcl::Window* pTopLevelWindow = ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplGetFirstOverlapWindow();
1796
1797 if ((!pTopLevelWindow->IsInputEnabled() || pTopLevelWindow->IsInModalMode())
1798 && !pSVData->mpWinData->mpExecuteDialogs.empty())
1799 pSVData->mpWinData->mpExecuteDialogs.back()->ToTop(ToTopFlags::RestoreWhenMin | ToTopFlags::GrabFocusOnly);
1800 else
1801 pTopLevelWindow->GrabFocus();
1802 }
1803 }
1804 else
1805 GrabFocus();
1806 }
1807 else
1808 {
1809 vcl::Window* pFocusWin = ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1810 if ( pFocusWin )
1811 {
1812 ImplSVData* pSVData = ImplGetSVData();
1813
1814 if (pSVData->mpWinData->mpFocusWin == pFocusWin)
1815 {
1816 // transfer the FocusWindow
1817 vcl::Window* pOverlapWindow = pFocusWin->ImplGetFirstOverlapWindow();
1818 pOverlapWindow->ImplGetWindowImpl()->mpLastFocusWindow = pFocusWin;
1819 pSVData->mpWinData->mpFocusWin = nullptr;
1820
1821 if ( pFocusWin->ImplGetWindowImpl()->mpCursor )
1822 pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide();
1823
1824 // call the Deactivate
1825 vcl::Window* pOldOverlapWindow = pFocusWin->ImplGetFirstOverlapWindow();
1826 vcl::Window* pOldRealWindow = pOldOverlapWindow->ImplGetWindow();
1827
1828 pOldOverlapWindow->ImplGetWindowImpl()->mbActive = false;
1829 pOldOverlapWindow->Deactivate();
1830 if ( pOldRealWindow != pOldOverlapWindow )
1831 {
1832 pOldRealWindow->ImplGetWindowImpl()->mbActive = false;
1833 pOldRealWindow->Deactivate();
1834 }
1835
1836 // TrackingMode is ended in ImplHandleLoseFocus
1837#ifdef _WIN32
1838 // To avoid problems with the Unix IME
1839 pFocusWin->EndExtTextInput();
1840#endif
1841
1842 NotifyEvent aNEvt(MouseNotifyEvent::LOSEFOCUS, pFocusWin);
1843 if (!ImplCallPreNotify(aNEvt))
1844 pFocusWin->CompatLoseFocus();
1845 pFocusWin->ImplCallDeactivateListeners(nullptr);
1846 }
1847 }
1848
1849 // Redraw all floating window inactive
1850 if ( ImplGetWindowImpl()->mpFrameData->mbStartFocusState != bHasFocus )
1851 ImplActivateFloatingWindows( this, bHasFocus );
1852 }
1853}
1854
1855static void ImplHandleGetFocus( vcl::Window* pWindow )
1856{
1857 pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus = true;
1858
1859 // execute Focus-Events after a delay, such that SystemChildWindows
1860 // do not blink when they receive focus
1861 if ( !pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId )
1862 {
1863 pWindow->ImplGetWindowImpl()->mpFrameData->mbStartFocusState = !pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus;
1864 pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId = Application::PostUserEvent( LINK( pWindow, vcl::Window, ImplAsyncFocusHdl )::tools::detail::makeLink( ::tools::detail::castTo<vcl::Window
*>(pWindow), &vcl::Window::LinkStubImplAsyncFocusHdl)
, nullptr, true);
1865 vcl::Window* pFocusWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1866 if ( pFocusWin && pFocusWin->ImplGetWindowImpl()->mpCursor )
1867 pFocusWin->ImplGetWindowImpl()->mpCursor->ImplShow();
1868 }
1869}
1870
1871static void ImplHandleLoseFocus( vcl::Window* pWindow )
1872{
1873 ImplSVData* pSVData = ImplGetSVData();
1874
1875 // Abort the autoscroll if the frame loses focus
1876 if (pSVData->mpWinData->mpAutoScrollWin)
1877 pSVData->mpWinData->mpAutoScrollWin->EndAutoScroll();
1878
1879 // Abort tracking if the frame loses focus
1880 if (pSVData->mpWinData->mpTrackWin)
1881 {
1882 if (pSVData->mpWinData->mpTrackWin->ImplGetWindowImpl()->mpFrameWindow == pWindow)
1883 pSVData->mpWinData->mpTrackWin->EndTracking(TrackingEventFlags::Cancel);
1884 }
1885
1886 pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus = false;
1887
1888 // execute Focus-Events after a delay, such that SystemChildWindows
1889 // do not flicker when they receive focus
1890 if ( !pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId )
1891 {
1892 pWindow->ImplGetWindowImpl()->mpFrameData->mbStartFocusState = !pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus;
1893 pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId = Application::PostUserEvent( LINK( pWindow, vcl::Window, ImplAsyncFocusHdl )::tools::detail::makeLink( ::tools::detail::castTo<vcl::Window
*>(pWindow), &vcl::Window::LinkStubImplAsyncFocusHdl)
, nullptr, true );
1894 }
1895
1896 vcl::Window* pFocusWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1897 if ( pFocusWin && pFocusWin->ImplGetWindowImpl()->mpCursor )
1898 pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide();
1899
1900 // Make sure that no menu is visible when a toplevel window loses focus.
1901 VclPtr<FloatingWindow> pFirstFloat = pSVData->mpWinData->mpFirstFloat;
1902 if (pFirstFloat && !pWindow->GetParent())
1903 pFirstFloat->EndPopupMode(FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll);
1904}
1905
1906namespace {
1907
1908struct DelayedCloseEvent
1909{
1910 VclPtr<vcl::Window> pWindow;
1911};
1912
1913}
1914
1915static void DelayedCloseEventLink( void* pCEvent, void* )
1916{
1917 DelayedCloseEvent* pEv = static_cast<DelayedCloseEvent*>(pCEvent);
1918
1919 if( ! pEv->pWindow->IsDisposed() )
1920 {
1921 // dispatch to correct window type
1922 if( pEv->pWindow->IsSystemWindow() )
1923 static_cast<SystemWindow*>(pEv->pWindow.get())->Close();
1924 else if( pEv->pWindow->IsDockingWindow() )
1925 static_cast<DockingWindow*>(pEv->pWindow.get())->Close();
1926 }
1927 delete pEv;
1928}
1929
1930static void ImplHandleClose( const vcl::Window* pWindow )
1931{
1932 ImplSVData* pSVData = ImplGetSVData();
1933
1934 bool bWasPopup = false;
1935 if( pWindow->ImplIsFloatingWindow() &&
6
Assuming the condition is false
1936 static_cast<const FloatingWindow*>(pWindow)->ImplIsInPrivatePopupMode() )
1937 {
1938 bWasPopup = true;
1939 }
1940
1941 // on Close stop all floating modes and end popups
1942 if (pSVData->mpWinData->mpFirstFloat)
7
Taking false branch
1943 {
1944 FloatingWindow* pLastLevelFloat;
1945 pLastLevelFloat = pSVData->mpWinData->mpFirstFloat->ImplFindLastLevelFloat();
1946 pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
1947 }
1948 if ( ImplGetSVHelpData().mbExtHelpMode )
8
Assuming field 'mbExtHelpMode' is false
9
Taking false branch
1949 Help::EndExtHelp();
1950 if ( ImplGetSVHelpData().mpHelpWin )
10
Taking false branch
1951 ImplDestroyHelpWindow( false );
1952 // AutoScrollMode
1953 if (pSVData->mpWinData->mpAutoScrollWin)
11
Taking false branch
1954 pSVData->mpWinData->mpAutoScrollWin->EndAutoScroll();
1955
1956 if (pSVData->mpWinData->mpTrackWin)
12
Taking false branch
1957 pSVData->mpWinData->mpTrackWin->EndTracking( TrackingEventFlags::Cancel | TrackingEventFlags::Key );
1958
1959 if (bWasPopup
12.1
'bWasPopup' is false
)
13
Taking false branch
1960 return;
1961
1962 vcl::Window *pWin = pWindow->ImplGetWindow();
14
'pWin' initialized here
1963 SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(pWin);
1964 if (pSysWin)
15
Assuming 'pSysWin' is null
16
Taking false branch
1965 {
1966 // See if the custom close handler is set.
1967 const Link<SystemWindow&,void>& rLink = pSysWin->GetCloseHdl();
1968 if (rLink.IsSet())
1969 {
1970 rLink.Call(*pSysWin);
1971 return;
1972 }
1973 }
1974
1975 // check whether close is allowed
1976 if ( pWin->IsEnabled() && pWin->IsInputEnabled() && !pWin->IsInModalMode() )
17
Called C++ object pointer is null
1977 {
1978 DelayedCloseEvent* pEv = new DelayedCloseEvent;
1979 pEv->pWindow = pWin;
1980 Application::PostUserEvent( Link<void*,void>( pEv, DelayedCloseEventLink ) );
1981 }
1982}
1983
1984static void ImplHandleUserEvent( ImplSVEvent* pSVEvent )
1985{
1986 if ( pSVEvent )
1987 {
1988 if ( pSVEvent->mbCall )
1989 {
1990 pSVEvent->maLink.Call( pSVEvent->mpData );
1991 }
1992
1993 delete pSVEvent;
1994 }
1995}
1996
1997static MouseEventModifiers ImplGetMouseMoveMode( SalMouseEvent const * pEvent )
1998{
1999 MouseEventModifiers nMode = MouseEventModifiers::NONE;
2000 if ( !pEvent->mnCode )
2001 nMode |= MouseEventModifiers::SIMPLEMOVE;
2002 if ( (pEvent->mnCode & MOUSE_LEFT(sal_uInt16(0x0001))) && !(pEvent->mnCode & KEY_MOD1) )
2003 nMode |= MouseEventModifiers::DRAGMOVE;
2004 if ( (pEvent->mnCode & MOUSE_LEFT(sal_uInt16(0x0001))) && (pEvent->mnCode & KEY_MOD1) )
2005 nMode |= MouseEventModifiers::DRAGCOPY;
2006 return nMode;
2007}
2008
2009static MouseEventModifiers ImplGetMouseButtonMode( SalMouseEvent const * pEvent )
2010{
2011 MouseEventModifiers nMode = MouseEventModifiers::NONE;
2012 if ( pEvent->mnButton == MOUSE_LEFT(sal_uInt16(0x0001)) )
2013 nMode |= MouseEventModifiers::SIMPLECLICK;
2014 if ( (pEvent->mnButton == MOUSE_LEFT(sal_uInt16(0x0001))) && !(pEvent->mnCode & (MOUSE_MIDDLE(sal_uInt16(0x0002)) | MOUSE_RIGHT(sal_uInt16(0x0004)))) )
2015 nMode |= MouseEventModifiers::SELECT;
2016 if ( (pEvent->mnButton == MOUSE_LEFT(sal_uInt16(0x0001))) && (pEvent->mnCode & KEY_MOD1) &&
2017 !(pEvent->mnCode & (MOUSE_MIDDLE(sal_uInt16(0x0002)) | MOUSE_RIGHT(sal_uInt16(0x0004)) | KEY_SHIFT)) )
2018 nMode |= MouseEventModifiers::MULTISELECT;
2019 if ( (pEvent->mnButton == MOUSE_LEFT(sal_uInt16(0x0001))) && (pEvent->mnCode & KEY_SHIFT) &&
2020 !(pEvent->mnCode & (MOUSE_MIDDLE(sal_uInt16(0x0002)) | MOUSE_RIGHT(sal_uInt16(0x0004)) | KEY_MOD1)) )
2021 nMode |= MouseEventModifiers::RANGESELECT;
2022 return nMode;
2023}
2024
2025static bool ImplHandleSalMouseLeave( vcl::Window* pWindow, SalMouseEvent const * pEvent )
2026{
2027 return ImplHandleMouseEvent( pWindow, MouseNotifyEvent::MOUSEMOVE, true,
2028 pEvent->mnX, pEvent->mnY,
2029 pEvent->mnTime, pEvent->mnCode,
2030 ImplGetMouseMoveMode( pEvent ) );
2031}
2032
2033static bool ImplHandleSalMouseMove( vcl::Window* pWindow, SalMouseEvent const * pEvent )
2034{
2035 return ImplHandleMouseEvent( pWindow, MouseNotifyEvent::MOUSEMOVE, false,
2036 pEvent->mnX, pEvent->mnY,
2037 pEvent->mnTime, pEvent->mnCode,
2038 ImplGetMouseMoveMode( pEvent ) );
2039}
2040
2041static bool ImplHandleSalMouseButtonDown( vcl::Window* pWindow, SalMouseEvent const * pEvent )
2042{
2043 return ImplHandleMouseEvent( pWindow, MouseNotifyEvent::MOUSEBUTTONDOWN, false,
2044 pEvent->mnX, pEvent->mnY,
2045 pEvent->mnTime,
2046#ifdef MACOSX
2047 pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)),
2048#else
2049 pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
2050#endif
2051 ImplGetMouseButtonMode( pEvent ) );
2052}
2053
2054static bool ImplHandleSalMouseButtonUp( vcl::Window* pWindow, SalMouseEvent const * pEvent )
2055{
2056 return ImplHandleMouseEvent( pWindow, MouseNotifyEvent::MOUSEBUTTONUP, false,
2057 pEvent->mnX, pEvent->mnY,
2058 pEvent->mnTime,
2059#ifdef MACOSX
2060 pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)),
2061#else
2062 pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
2063#endif
2064 ImplGetMouseButtonMode( pEvent ) );
2065}
2066
2067static bool ImplHandleMenuEvent( vcl::Window const * pWindow, SalMenuEvent* pEvent, SalEvent nEvent )
2068{
2069 // Find SystemWindow and its Menubar and let it dispatch the command
2070 bool bRet = false;
2071 vcl::Window *pWin = pWindow->ImplGetWindowImpl()->mpFirstChild;
2072 while ( pWin )
2073 {
2074 if ( pWin->ImplGetWindowImpl()->mbSysWin )
2075 break;
2076 pWin = pWin->ImplGetWindowImpl()->mpNext;
2077 }
2078 if( pWin )
2079 {
2080 MenuBar *pMenuBar = static_cast<SystemWindow*>(pWin)->GetMenuBar();
2081 if( pMenuBar )
2082 {
2083 switch( nEvent )
2084 {
2085 case SalEvent::MenuActivate:
2086 pMenuBar->HandleMenuActivateEvent( static_cast<Menu*>(pEvent->mpMenu) );
2087 bRet = true;
2088 break;
2089 case SalEvent::MenuDeactivate:
2090 pMenuBar->HandleMenuDeActivateEvent( static_cast<Menu*>(pEvent->mpMenu) );
2091 bRet = true;
2092 break;
2093 case SalEvent::MenuHighlight:
2094 bRet = pMenuBar->HandleMenuHighlightEvent( static_cast<Menu*>(pEvent->mpMenu), pEvent->mnId );
2095 break;
2096 case SalEvent::MenuButtonCommand:
2097 bRet = pMenuBar->HandleMenuButtonEvent( pEvent->mnId );
2098 break;
2099 case SalEvent::MenuCommand:
2100 bRet = pMenuBar->HandleMenuCommandEvent( static_cast<Menu*>(pEvent->mpMenu), pEvent->mnId );
2101 break;
2102 default:
2103 break;
2104 }
2105 }
2106 }
2107 return bRet;
2108}
2109
2110static void ImplHandleSalKeyMod( vcl::Window* pWindow, SalKeyModEvent const * pEvent )
2111{
2112 ImplSVData* pSVData = ImplGetSVData();
2113 vcl::Window* pTrackWin = pSVData->mpWinData->mpTrackWin;
2114 if ( pTrackWin )
2115 pWindow = pTrackWin;
2116#ifdef MACOSX
2117 sal_uInt16 nOldCode = pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3);
2118#else
2119 sal_uInt16 nOldCode = pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
2120#endif
2121 sal_uInt16 nNewCode = pEvent->mnCode;
2122 if ( nOldCode != nNewCode )
2123 {
2124#ifdef MACOSX
2125 nNewCode |= pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & ~(KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3);
2126#else
2127 nNewCode |= pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & ~(KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
2128#endif
2129 pWindow->ImplGetWindowImpl()->mpFrameWindow->ImplCallMouseMove( nNewCode, true );
2130 }
2131
2132 // #105224# send commandevent to allow special treatment of Ctrl-LeftShift/Ctrl-RightShift etc.
2133 // + auto-accelerator feature, tdf#92630
2134
2135 // try to find a key input window...
2136 vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
2137 //...otherwise fail safe...
2138 if (!pChild)
2139 pChild = pWindow;
2140
2141 CommandModKeyData data( pEvent->mnModKeyCode, pEvent->mbDown );
2142 ImplCallCommand( pChild, CommandEventId::ModKeyChange, &data );
2143}
2144
2145static void ImplHandleInputLanguageChange( vcl::Window* pWindow )
2146{
2147 // find window
2148 vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
2149 if ( !pChild )
2150 return;
2151
2152 ImplCallCommand( pChild, CommandEventId::InputLanguageChange );
2153}
2154
2155static void ImplHandleSalSettings( SalEvent nEvent )
2156{
2157 Application* pApp = GetpApp();
2158 if ( !pApp )
2159 return;
2160
2161 if ( nEvent == SalEvent::SettingsChanged )
2162 {
2163 AllSettings aSettings = Application::GetSettings();
2164 Application::MergeSystemSettings( aSettings );
2165 pApp->OverrideSystemSettings( aSettings );
2166 Application::SetSettings( aSettings );
2167 }
2168 else
2169 {
2170 DataChangedEventType nType;
2171 switch ( nEvent )
2172 {
2173 case SalEvent::PrinterChanged:
2174 ImplDeletePrnQueueList();
2175 nType = DataChangedEventType::PRINTER;
2176 break;
2177 case SalEvent::DisplayChanged:
2178 nType = DataChangedEventType::DISPLAY;
2179 break;
2180 case SalEvent::FontChanged:
2181 OutputDevice::ImplUpdateAllFontData( true );
2182 nType = DataChangedEventType::FONTS;
2183 break;
2184 default:
2185 nType = DataChangedEventType::NONE;
2186 break;
2187 }
2188
2189 if ( nType != DataChangedEventType::NONE )
2190 {
2191 DataChangedEvent aDCEvt( nType );
2192 Application::ImplCallEventListenersApplicationDataChanged(&aDCEvt);
2193 Application::NotifyAllWindows( aDCEvt );
2194 }
2195 }
2196}
2197
2198static void ImplHandleSalExtTextInputPos( vcl::Window* pWindow, SalExtTextInputPosEvent* pEvt )
2199{
2200 tools::Rectangle aCursorRect;
2201 ImplHandleExtTextInputPos( pWindow, aCursorRect, pEvt->mnExtWidth, &pEvt->mbVertical );
2202 if ( aCursorRect.IsEmpty() )
2203 {
2204 pEvt->mnX = -1;
2205 pEvt->mnY = -1;
2206 pEvt->mnWidth = -1;
2207 pEvt->mnHeight = -1;
2208 }
2209 else
2210 {
2211 pEvt->mnX = aCursorRect.Left();
2212 pEvt->mnY = aCursorRect.Top();
2213 pEvt->mnWidth = aCursorRect.GetWidth();
2214 pEvt->mnHeight = aCursorRect.GetHeight();
2215 }
2216}
2217
2218static bool ImplHandleShowDialog( vcl::Window* pWindow, ShowDialogId nDialogId )
2219{
2220 if( ! pWindow )
2221 return false;
2222
2223 if( pWindow->GetType() == WindowType::BORDERWINDOW )
2224 {
2225 vcl::Window* pWrkWin = pWindow->GetWindow( GetWindowType::Client );
2226 if( pWrkWin )
2227 pWindow = pWrkWin;
2228 }
2229 CommandDialogData aCmdData( nDialogId );
2230 return ImplCallCommand( pWindow, CommandEventId::ShowDialog, &aCmdData );
2231}
2232
2233static void ImplHandleSurroundingTextRequest( vcl::Window *pWindow,
2234 OUString& rText,
2235 Selection &rSelRange )
2236{
2237 vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
2238
2239 if ( !pChild )
2240 {
2241 rText.clear();
2242 rSelRange.setMin( 0 );
2243 rSelRange.setMax( 0 );
2244 }
2245 else
2246 {
2247 rText = pChild->GetSurroundingText();
2248 Selection aSel = pChild->GetSurroundingTextSelection();
2249 rSelRange.setMin( aSel.Min() );
2250 rSelRange.setMax( aSel.Max() );
2251 }
2252}
2253
2254static void ImplHandleSalSurroundingTextRequest( vcl::Window *pWindow,
2255 SalSurroundingTextRequestEvent *pEvt )
2256{
2257 Selection aSelRange;
2258 ImplHandleSurroundingTextRequest( pWindow, pEvt->maText, aSelRange );
2259
2260 aSelRange.Justify();
2261
2262 if( aSelRange.Min() < 0 )
2263 pEvt->mnStart = 0;
2264 else if( aSelRange.Min() > pEvt->maText.getLength() )
2265 pEvt->mnStart = pEvt->maText.getLength();
2266 else
2267 pEvt->mnStart = aSelRange.Min();
2268
2269 if( aSelRange.Max() < 0 )
2270 pEvt->mnStart = 0;
2271 else if( aSelRange.Max() > pEvt->maText.getLength() )
2272 pEvt->mnEnd = pEvt->maText.getLength();
2273 else
2274 pEvt->mnEnd = aSelRange.Max();
2275}
2276
2277static void ImplHandleSurroundingTextSelectionChange( vcl::Window *pWindow,
2278 sal_uLong nStart,
2279 sal_uLong nEnd )
2280{
2281 vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
2282 if( pChild )
2283 {
2284 CommandSelectionChangeData data( nStart, nEnd );
2285 ImplCallCommand( pChild, CommandEventId::SelectionChange, &data );
2286 }
2287}
2288
2289static void ImplHandleStartReconversion( vcl::Window *pWindow )
2290{
2291 vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
2292 if( pChild )
2293 ImplCallCommand( pChild, CommandEventId::PrepareReconversion );
2294}
2295
2296static void ImplHandleSalQueryCharPosition( vcl::Window *pWindow,
2297 SalQueryCharPositionEvent *pEvt )
2298{
2299 pEvt->mbValid = false;
2300 pEvt->mbVertical = false;
2301 pEvt->mnCursorBoundX = 0;
2302 pEvt->mnCursorBoundY = 0;
2303 pEvt->mnCursorBoundWidth = 0;
2304 pEvt->mnCursorBoundHeight = 0;
2305
2306 ImplSVData* pSVData = ImplGetSVData();
2307 vcl::Window* pChild = pSVData->mpWinData->mpExtTextInputWin;
2308
2309 if ( !pChild )
2310 pChild = ImplGetKeyInputWindow( pWindow );
2311 else
2312 {
2313 // Test, if the Window is related to the frame
2314 if ( !pWindow->ImplIsWindowOrChild( pChild ) )
2315 pChild = ImplGetKeyInputWindow( pWindow );
2316 }
2317
2318 if( !pChild )
2319 return;
2320
2321 ImplCallCommand( pChild, CommandEventId::QueryCharPosition );
2322
2323 ImplWinData* pWinData = pChild->ImplGetWinData();
2324 if ( !(pWinData->mpCompositionCharRects && pEvt->mnCharPos < o3tl::make_unsigned( pWinData->mnCompositionCharRects )) )
2325 return;
2326
2327 const OutputDevice *pChildOutDev = pChild->GetOutDev();
2328 const tools::Rectangle& aRect = pWinData->mpCompositionCharRects[ pEvt->mnCharPos ];
2329 tools::Rectangle aDeviceRect = pChildOutDev->ImplLogicToDevicePixel( aRect );
2330 Point aAbsScreenPos = pChild->OutputToAbsoluteScreenPixel( pChild->ScreenToOutputPixel(aDeviceRect.TopLeft()) );
2331 pEvt->mnCursorBoundX = aAbsScreenPos.X();
2332 pEvt->mnCursorBoundY = aAbsScreenPos.Y();
2333 pEvt->mnCursorBoundWidth = aDeviceRect.GetWidth();
2334 pEvt->mnCursorBoundHeight = aDeviceRect.GetHeight();
2335 pEvt->mbVertical = pWinData->mbVertical;
2336 pEvt->mbValid = true;
2337}
2338
2339bool ImplWindowFrameProc( vcl::Window* _pWindow, SalEvent nEvent, const void* pEvent )
2340{
2341 DBG_TESTSOLARMUTEX()do { DbgTestSolarMutex(); } while(false);
1
Loop condition is false. Exiting loop
2342
2343 // Ensure the window survives during this method.
2344 VclPtr<vcl::Window> pWindow( _pWindow );
2345
2346 bool bRet = false;
2347
2348 // #119709# for some unknown reason it is possible to receive events (in this case key events)
2349 // although the corresponding VCL window must have been destroyed already
2350 // at least ImplGetWindowImpl() was NULL in these cases, so check this here
2351 if( pWindow->ImplGetWindowImpl() == nullptr )
2
Assuming the condition is false
3
Taking false branch
2352 return false;
2353
2354 switch ( nEvent )
4
Control jumps to 'case Close:' at line 2510
2355 {
2356 case SalEvent::MouseMove:
2357 bRet = ImplHandleSalMouseMove( pWindow, static_cast<SalMouseEvent const *>(pEvent) );
2358 break;
2359 case SalEvent::ExternalMouseMove:
2360 {
2361 MouseEvent const * pMouseEvt = static_cast<MouseEvent const *>(pEvent);
2362 SalMouseEvent aSalMouseEvent;
2363
2364 aSalMouseEvent.mnTime = tools::Time::GetSystemTicks();
2365 aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
2366 aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
2367 aSalMouseEvent.mnButton = 0;
2368 aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
2369
2370 bRet = ImplHandleSalMouseMove( pWindow, &aSalMouseEvent );
2371 }
2372 break;
2373 case SalEvent::MouseLeave:
2374 bRet = ImplHandleSalMouseLeave( pWindow, static_cast<SalMouseEvent const *>(pEvent) );
2375 break;
2376 case SalEvent::MouseButtonDown:
2377 bRet = ImplHandleSalMouseButtonDown( pWindow, static_cast<SalMouseEvent const *>(pEvent) );
2378 break;
2379 case SalEvent::ExternalMouseButtonDown:
2380 {
2381 MouseEvent const * pMouseEvt = static_cast<MouseEvent const *>(pEvent);
2382 SalMouseEvent aSalMouseEvent;
2383
2384 aSalMouseEvent.mnTime = tools::Time::GetSystemTicks();
2385 aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
2386 aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
2387 aSalMouseEvent.mnButton = pMouseEvt->GetButtons();
2388 aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
2389
2390 bRet = ImplHandleSalMouseButtonDown( pWindow, &aSalMouseEvent );
2391 }
2392 break;
2393 case SalEvent::MouseButtonUp:
2394 bRet = ImplHandleSalMouseButtonUp( pWindow, static_cast<SalMouseEvent const *>(pEvent) );
2395 break;
2396 case SalEvent::ExternalMouseButtonUp:
2397 {
2398 MouseEvent const * pMouseEvt = static_cast<MouseEvent const *>(pEvent);
2399 SalMouseEvent aSalMouseEvent;
2400
2401 aSalMouseEvent.mnTime = tools::Time::GetSystemTicks();
2402 aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
2403 aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
2404 aSalMouseEvent.mnButton = pMouseEvt->GetButtons();
2405 aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
2406
2407 bRet = ImplHandleSalMouseButtonUp( pWindow, &aSalMouseEvent );
2408 }
2409 break;
2410 case SalEvent::MouseActivate:
2411 bRet = false;
2412 break;
2413 case SalEvent::KeyInput:
2414 {
2415 SalKeyEvent const * pKeyEvt = static_cast<SalKeyEvent const *>(pEvent);
2416 bRet = ImplHandleKey( pWindow, MouseNotifyEvent::KEYINPUT,
2417 pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat, true );
2418 }
2419 break;
2420 case SalEvent::ExternalKeyInput:
2421 {
2422 KeyEvent const * pKeyEvt = static_cast<KeyEvent const *>(pEvent);
2423 bRet = ImplHandleKey( pWindow, MouseNotifyEvent::KEYINPUT,
2424 pKeyEvt->GetKeyCode().GetFullCode(), pKeyEvt->GetCharCode(), pKeyEvt->GetRepeat(), false );
2425 }
2426 break;
2427 case SalEvent::KeyUp:
2428 {
2429 SalKeyEvent const * pKeyEvt = static_cast<SalKeyEvent const *>(pEvent);
2430 bRet = ImplHandleKey( pWindow, MouseNotifyEvent::KEYUP,
2431 pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat, true );
2432 }
2433 break;
2434 case SalEvent::ExternalKeyUp:
2435 {
2436 KeyEvent const * pKeyEvt = static_cast<KeyEvent const *>(pEvent);
2437 bRet = ImplHandleKey( pWindow, MouseNotifyEvent::KEYUP,
2438 pKeyEvt->GetKeyCode().GetFullCode(), pKeyEvt->GetCharCode(), pKeyEvt->GetRepeat(), false );
2439 }
2440 break;
2441 case SalEvent::KeyModChange:
2442 ImplHandleSalKeyMod( pWindow, static_cast<SalKeyModEvent const *>(pEvent) );
2443 break;
2444
2445 case SalEvent::InputLanguageChange:
2446 ImplHandleInputLanguageChange( pWindow );
2447 break;
2448
2449 case SalEvent::MenuActivate:
2450 case SalEvent::MenuDeactivate:
2451 case SalEvent::MenuHighlight:
2452 case SalEvent::MenuCommand:
2453 case SalEvent::MenuButtonCommand:
2454 bRet = ImplHandleMenuEvent( pWindow, const_cast<SalMenuEvent *>(static_cast<SalMenuEvent const *>(pEvent)), nEvent );
2455 break;
2456
2457 case SalEvent::WheelMouse:
2458 bRet = ImplHandleWheelEvent( pWindow, *static_cast<const SalWheelMouseEvent*>(pEvent));
2459 break;
2460
2461 case SalEvent::Paint:
2462 {
2463 SalPaintEvent const * pPaintEvt = static_cast<SalPaintEvent const *>(pEvent);
2464
2465 if( AllSettings::GetLayoutRTL() )
2466 {
2467 SalFrame* pSalFrame = pWindow->ImplGetWindowImpl()->mpFrame;
2468 const_cast<SalPaintEvent *>(pPaintEvt)->mnBoundX = pSalFrame->maGeometry.nWidth-pPaintEvt->mnBoundWidth-pPaintEvt->mnBoundX;
2469 }
2470
2471 tools::Rectangle aBoundRect( Point( pPaintEvt->mnBoundX, pPaintEvt->mnBoundY ),
2472 Size( pPaintEvt->mnBoundWidth, pPaintEvt->mnBoundHeight ) );
2473 ImplHandlePaint( pWindow, aBoundRect, pPaintEvt->mbImmediateUpdate );
2474 }
2475 break;
2476
2477 case SalEvent::Move:
2478 ImplHandleMove( pWindow );
2479 break;
2480
2481 case SalEvent::Resize:
2482 {
2483 long nNewWidth;
2484 long nNewHeight;
2485 pWindow->ImplGetWindowImpl()->mpFrame->GetClientSize( nNewWidth, nNewHeight );
2486 ImplHandleResize( pWindow, nNewWidth, nNewHeight );
2487 }
2488 break;
2489
2490 case SalEvent::MoveResize:
2491 {
2492 SalFrameGeometry g = pWindow->ImplGetWindowImpl()->mpFrame->GetGeometry();
2493 ImplHandleMoveResize( pWindow, g.nWidth, g.nHeight );
2494 }
2495 break;
2496
2497 case SalEvent::ClosePopups:
2498 {
2499 KillOwnPopups( pWindow );
2500 }
2501 break;
2502
2503 case SalEvent::GetFocus:
2504 ImplHandleGetFocus( pWindow );
2505 break;
2506 case SalEvent::LoseFocus:
2507 ImplHandleLoseFocus( pWindow );
2508 break;
2509
2510 case SalEvent::Close:
2511 ImplHandleClose( pWindow );
5
Calling 'ImplHandleClose'
2512 break;
2513
2514 case SalEvent::Shutdown:
2515 {
2516 static bool bInQueryExit = false;
2517 if( !bInQueryExit )
2518 {
2519 bInQueryExit = true;
2520 if ( GetpApp()->QueryExit() )
2521 {
2522 // end the message loop
2523 Application::Quit();
2524 return false;
2525 }
2526 else
2527 {
2528 bInQueryExit = false;
2529 return true;
2530 }
2531 }
2532 return false;
2533 }
2534
2535 case SalEvent::SettingsChanged:
2536 case SalEvent::PrinterChanged:
2537 case SalEvent::DisplayChanged:
2538 case SalEvent::FontChanged:
2539 ImplHandleSalSettings( nEvent );
2540 break;
2541
2542 case SalEvent::UserEvent:
2543 ImplHandleUserEvent( const_cast<ImplSVEvent *>(static_cast<ImplSVEvent const *>(pEvent)) );
2544 break;
2545
2546 case SalEvent::ExtTextInput:
2547 {
2548 SalExtTextInputEvent const * pEvt = static_cast<SalExtTextInputEvent const *>(pEvent);
2549 bRet = ImplHandleExtTextInput( pWindow,
2550 pEvt->maText, pEvt->mpTextAttr,
2551 pEvt->mnCursorPos, pEvt->mnCursorFlags );
2552 }
2553 break;
2554 case SalEvent::EndExtTextInput:
2555 bRet = ImplHandleEndExtTextInput();
2556 break;
2557 case SalEvent::ExtTextInputPos:
2558 ImplHandleSalExtTextInputPos( pWindow, const_cast<SalExtTextInputPosEvent *>(static_cast<SalExtTextInputPosEvent const *>(pEvent)) );
2559 break;
2560 case SalEvent::InputContextChange:
2561 bRet = ImplHandleInputContextChange( pWindow );
2562 break;
2563 case SalEvent::ShowDialog:
2564 {
2565 ShowDialogId nLOKWindowId = static_cast<ShowDialogId>(reinterpret_cast<sal_IntPtr>(pEvent));
2566 bRet = ImplHandleShowDialog( pWindow, nLOKWindowId );
2567 }
2568 break;
2569 case SalEvent::SurroundingTextRequest:
2570 ImplHandleSalSurroundingTextRequest( pWindow, const_cast<SalSurroundingTextRequestEvent *>(static_cast<SalSurroundingTextRequestEvent const *>(pEvent)) );
2571 break;
2572 case SalEvent::SurroundingTextSelectionChange:
2573 {
2574 SalSurroundingTextSelectionChangeEvent const * pEvt
2575 = static_cast<SalSurroundingTextSelectionChangeEvent const *>(pEvent);
2576 ImplHandleSurroundingTextSelectionChange( pWindow,
2577 pEvt->mnStart,
2578 pEvt->mnEnd );
2579 [[fallthrough]]; // TODO: Fallthrough really intended?
2580 }
2581 case SalEvent::StartReconversion:
2582 ImplHandleStartReconversion( pWindow );
2583 break;
2584
2585 case SalEvent::QueryCharPosition:
2586 ImplHandleSalQueryCharPosition( pWindow, const_cast<SalQueryCharPositionEvent *>(static_cast<SalQueryCharPositionEvent const *>(pEvent)) );
2587 break;
2588
2589 case SalEvent::Swipe:
2590 bRet = ImplHandleSwipe(pWindow, *static_cast<const SalSwipeEvent*>(pEvent));
2591 break;
2592
2593 case SalEvent::LongPress:
2594 bRet = ImplHandleLongPress(pWindow, *static_cast<const SalLongPressEvent*>(pEvent));
2595 break;
2596
2597 case SalEvent::ExternalGesture:
2598 {
2599 auto const * pGestureEvent = static_cast<GestureEvent const *>(pEvent);
2600
2601 SalGestureEvent aSalGestureEvent;
2602 aSalGestureEvent.mfOffset = pGestureEvent->mnOffset;
2603 aSalGestureEvent.mnX = pGestureEvent->mnX;
2604 aSalGestureEvent.mnY = pGestureEvent->mnY;
2605 aSalGestureEvent.meEventType = pGestureEvent->meEventType;
2606 aSalGestureEvent.meOrientation = pGestureEvent->meOrientation;
2607
2608 bRet = ImplHandleGestureEvent(pWindow, aSalGestureEvent);
2609 }
2610 break;
2611 case SalEvent::Gesture:
2612 {
2613 auto const * aSalGestureEvent = static_cast<SalGestureEvent const *>(pEvent);
2614 bRet = ImplHandleGestureEvent(pWindow, *aSalGestureEvent);
2615 }
2616 break;
2617 default:
2618 SAL_WARN( "vcl.layout", "ImplWindowFrameProc(): unknown event (" << static_cast<int>(nEvent) << ")" )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() << "ImplWindowFrameProc(): unknown event ("
<< static_cast<int>(nEvent) << ")") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "2618" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "ImplWindowFrameProc(): unknown event ("
<< static_cast<int>(nEvent) << ")"), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ImplWindowFrameProc(): unknown event (" << static_cast
<int>(nEvent) << ")"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "2618" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "ImplWindowFrameProc(): unknown event (" <<
static_cast<int>(nEvent) << ")") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "2618" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "ImplWindowFrameProc(): unknown event ("
<< static_cast<int>(nEvent) << ")"), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ImplWindowFrameProc(): unknown event (" << static_cast
<int>(nEvent) << ")"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx"
":" "2618" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2619 break;
2620 }
2621
2622 return bRet;
2623}
2624
2625/* vim:set shiftwidth=4 softtabstop=4 expandtab: */