File: | home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx |
Warning: | line 1245, column 41 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | |||||||
62 | bool ImplCallPreNotify( NotifyEvent& rEvt ) | ||||||
63 | { | ||||||
64 | return rEvt.GetWindow()->CompatPreNotify( rEvt ); | ||||||
65 | } | ||||||
66 | |||||||
67 | static 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 | |||||||
160 | static 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 | |||||||
190 | static 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 | |||||||
198 | static 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 | |||||||
242 | namespace { | ||||||
243 | |||||||
244 | struct ContextMenuEvent | ||||||
245 | { | ||||||
246 | VclPtr<vcl::Window> pWindow; | ||||||
247 | Point aChildPos; | ||||||
248 | }; | ||||||
249 | |||||||
250 | } | ||||||
251 | |||||||
252 | static 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 | |||||||
263 | bool 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 | |||||||
795 | static 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 | |||||||
849 | static 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 | |||||||
1115 | static 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 | |||||||
1206 | static 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 | |||||||
1225 | static 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 | |||||||
1271 | static bool ImplHandleInputContextChange( vcl::Window* pWindow ) | ||||||
1272 | { | ||||||
1273 | vcl::Window* pChild = ImplGetKeyInputWindow( pWindow ); | ||||||
1274 | CommandInputContextData aData; | ||||||
1275 | return !ImplCallCommand( pChild, CommandEventId::InputContextChange, &aData ); | ||||||
1276 | } | ||||||
1277 | |||||||
1278 | static 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 | |||||||
1299 | static 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. | ||||||
1310 | static 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 | |||||||
1315 | namespace { | ||||||
1316 | |||||||
1317 | class HandleGestureEventBase | ||||||
1318 | { | ||||||
1319 | protected: | ||||||
1320 | ImplSVData* m_pSVData; | ||||||
1321 | VclPtr<vcl::Window> m_pWindow; | ||||||
1322 | Point m_aMousePos; | ||||||
1323 | |||||||
1324 | public: | ||||||
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 | |||||||
1340 | bool 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 | |||||||
1350 | vcl::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 | |||||||
1389 | vcl::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 | |||||||
1429 | namespace { | ||||||
1430 | |||||||
1431 | class HandleWheelEvent : public HandleGestureEventBase | ||||||
1432 | { | ||||||
1433 | private: | ||||||
1434 | CommandWheelData m_aWheelData; | ||||||
1435 | public: | ||||||
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 | |||||||
1467 | bool 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 | |||||||
1492 | namespace { | ||||||
1493 | |||||||
1494 | class HandleGestureEvent : public HandleGestureEventBase | ||||||
1495 | { | ||||||
1496 | public: | ||||||
1497 | HandleGestureEvent(vcl::Window *pWindow, const Point &rMousePos) | ||||||
1498 | : HandleGestureEventBase(pWindow, rMousePos) | ||||||
1499 | { | ||||||
1500 | } | ||||||
1501 | bool HandleEvent(); | ||||||
1502 | }; | ||||||
1503 | |||||||
1504 | } | ||||||
1505 | |||||||
1506 | bool 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 | |||||||
1517 | static bool ImplHandleWheelEvent(vcl::Window* pWindow, const SalWheelMouseEvent& rEvt) | ||||||
1518 | { | ||||||
1519 | HandleWheelEvent aHandler(pWindow, rEvt); | ||||||
1520 | return aHandler.HandleEvent(rEvt); | ||||||
1521 | } | ||||||
1522 | |||||||
1523 | namespace { | ||||||
1524 | |||||||
1525 | class HandleSwipeEvent : public HandleGestureEvent | ||||||
1526 | { | ||||||
1527 | private: | ||||||
1528 | CommandSwipeData m_aSwipeData; | ||||||
1529 | public: | ||||||
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 | |||||||
1543 | static bool ImplHandleSwipe(vcl::Window *pWindow, const SalSwipeEvent& rEvt) | ||||||
1544 | { | ||||||
1545 | HandleSwipeEvent aHandler(pWindow, rEvt); | ||||||
1546 | return aHandler.HandleEvent(); | ||||||
1547 | } | ||||||
1548 | |||||||
1549 | namespace { | ||||||
1550 | |||||||
1551 | class HandleLongPressEvent : public HandleGestureEvent | ||||||
1552 | { | ||||||
1553 | private: | ||||||
1554 | CommandLongPressData m_aLongPressData; | ||||||
1555 | public: | ||||||
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 | |||||||
1569 | static bool ImplHandleLongPress(vcl::Window *pWindow, const SalLongPressEvent& rEvt) | ||||||
1570 | { | ||||||
1571 | HandleLongPressEvent aHandler(pWindow, rEvt); | ||||||
1572 | return aHandler.HandleEvent(); | ||||||
1573 | } | ||||||
1574 | |||||||
1575 | namespace { | ||||||
1576 | |||||||
1577 | class HandleGeneralGestureEvent : public HandleGestureEvent | ||||||
1578 | { | ||||||
1579 | private: | ||||||
1580 | CommandGestureData m_aGestureData; | ||||||
1581 | |||||||
1582 | public: | ||||||
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 | |||||||
1597 | static bool ImplHandleGestureEvent(vcl::Window* pWindow, const SalGestureEvent& rEvent) | ||||||
1598 | { | ||||||
1599 | HandleGeneralGestureEvent aHandler(pWindow, rEvent); | ||||||
1600 | return aHandler.HandleEvent(); | ||||||
1601 | } | ||||||
1602 | |||||||
1603 | static 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 | |||||||
1621 | static 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 | |||||||
1635 | void 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 | |||||||
1709 | static 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 | |||||||
1734 | static void ImplHandleMoveResize( vcl::Window* pWindow, long nNewWidth, long nNewHeight ) | ||||||
1735 | { | ||||||
1736 | ImplHandleMove( pWindow ); | ||||||
1737 | ImplHandleResize( pWindow, nNewWidth, nNewHeight ); | ||||||
1738 | } | ||||||
1739 | |||||||
1740 | static 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 | |||||||
1758 | IMPL_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 | |||||||
1855 | static 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 | |||||||
1871 | static 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 | |||||||
1906 | namespace { | ||||||
1907 | |||||||
1908 | struct DelayedCloseEvent | ||||||
1909 | { | ||||||
1910 | VclPtr<vcl::Window> pWindow; | ||||||
1911 | }; | ||||||
1912 | |||||||
1913 | } | ||||||
1914 | |||||||
1915 | static 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 | |||||||
1930 | static void ImplHandleClose( const vcl::Window* pWindow ) | ||||||
1931 | { | ||||||
1932 | ImplSVData* pSVData = ImplGetSVData(); | ||||||
1933 | |||||||
1934 | bool bWasPopup = false; | ||||||
1935 | if( pWindow->ImplIsFloatingWindow() && | ||||||
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) | ||||||
1943 | { | ||||||
1944 | FloatingWindow* pLastLevelFloat; | ||||||
1945 | pLastLevelFloat = pSVData->mpWinData->mpFirstFloat->ImplFindLastLevelFloat(); | ||||||
1946 | pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll ); | ||||||
1947 | } | ||||||
1948 | if ( ImplGetSVHelpData().mbExtHelpMode ) | ||||||
1949 | Help::EndExtHelp(); | ||||||
1950 | if ( ImplGetSVHelpData().mpHelpWin ) | ||||||
1951 | ImplDestroyHelpWindow( false ); | ||||||
1952 | // AutoScrollMode | ||||||
1953 | if (pSVData->mpWinData->mpAutoScrollWin) | ||||||
1954 | pSVData->mpWinData->mpAutoScrollWin->EndAutoScroll(); | ||||||
1955 | |||||||
1956 | if (pSVData->mpWinData->mpTrackWin) | ||||||
1957 | pSVData->mpWinData->mpTrackWin->EndTracking( TrackingEventFlags::Cancel | TrackingEventFlags::Key ); | ||||||
1958 | |||||||
1959 | if (bWasPopup) | ||||||
1960 | return; | ||||||
1961 | |||||||
1962 | vcl::Window *pWin = pWindow->ImplGetWindow(); | ||||||
1963 | SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(pWin); | ||||||
1964 | if (pSysWin) | ||||||
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() ) | ||||||
1977 | { | ||||||
1978 | DelayedCloseEvent* pEv = new DelayedCloseEvent; | ||||||
1979 | pEv->pWindow = pWin; | ||||||
1980 | Application::PostUserEvent( Link<void*,void>( pEv, DelayedCloseEventLink ) ); | ||||||
1981 | } | ||||||
1982 | } | ||||||
1983 | |||||||
1984 | static 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 | |||||||
1997 | static 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 | |||||||
2009 | static 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 | |||||||
2025 | static 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 | |||||||
2033 | static 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 | |||||||
2041 | static 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 | |||||||
2054 | static 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 | |||||||
2067 | static 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 | |||||||
2110 | static 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 | |||||||
2145 | static 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 | |||||||
2155 | static 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 | |||||||
2198 | static 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 | |||||||
2218 | static 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 | |||||||
2233 | static 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 | |||||||
2254 | static 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 | |||||||
2277 | static 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 | |||||||
2289 | static void ImplHandleStartReconversion( vcl::Window *pWindow ) | ||||||
2290 | { | ||||||
2291 | vcl::Window* pChild = ImplGetKeyInputWindow( pWindow ); | ||||||
2292 | if( pChild ) | ||||||
2293 | ImplCallCommand( pChild, CommandEventId::PrepareReconversion ); | ||||||
2294 | } | ||||||
2295 | |||||||
2296 | static 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 | |||||||
2339 | bool ImplWindowFrameProc( vcl::Window* _pWindow, SalEvent nEvent, const void* pEvent ) | ||||||
2340 | { | ||||||
2341 | DBG_TESTSOLARMUTEX()do { DbgTestSolarMutex(); } while(false); | ||||||
| |||||||
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 ) | ||||||
2352 | return false; | ||||||
2353 | |||||||
2354 | switch ( nEvent ) | ||||||
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 ); | ||||||
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: */ |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | ||||||
2 | /* | ||||||
3 | * This file is part of the LibreOffice project. | ||||||
4 | * | ||||||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | ||||||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||||
8 | * | ||||||
9 | * This file incorporates work covered by the following license notice: | ||||||
10 | * | ||||||
11 | * Licensed to the Apache Software Foundation (ASF) under one or more | ||||||
12 | * contributor license agreements. See the NOTICE file distributed | ||||||
13 | * with this work for additional information regarding copyright | ||||||
14 | * ownership. The ASF licenses this file to you under the Apache | ||||||
15 | * License, Version 2.0 (the "License"); you may not use this file | ||||||
16 | * except in compliance with the License. You may obtain a copy of | ||||||
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . | ||||||
18 | */ | ||||||
19 | |||||||
20 | #ifndef INCLUDED_RTL_REF_HXX | ||||||
21 | #define INCLUDED_RTL_REF_HXX | ||||||
22 | |||||||
23 | #include "sal/config.h" | ||||||
24 | |||||||
25 | #include <cassert> | ||||||
26 | #include <cstddef> | ||||||
27 | #include <functional> | ||||||
28 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||
29 | #include <type_traits> | ||||||
30 | #endif | ||||||
31 | |||||||
32 | #include "sal/types.h" | ||||||
33 | |||||||
34 | namespace rtl | ||||||
35 | { | ||||||
36 | |||||||
37 | /** Template reference class for reference type. | ||||||
38 | */ | ||||||
39 | template <class reference_type> | ||||||
40 | class Reference | ||||||
41 | { | ||||||
42 | /** The <b>reference_type</b> body pointer. | ||||||
43 | */ | ||||||
44 | reference_type * m_pBody; | ||||||
45 | |||||||
46 | |||||||
47 | public: | ||||||
48 | /** Constructor... | ||||||
49 | */ | ||||||
50 | Reference() | ||||||
51 | : m_pBody (NULL__null) | ||||||
52 | {} | ||||||
53 | |||||||
54 | |||||||
55 | /** Constructor... | ||||||
56 | */ | ||||||
57 | Reference (reference_type * pBody, __sal_NoAcquire) | ||||||
58 | : m_pBody (pBody) | ||||||
59 | { | ||||||
60 | } | ||||||
61 | |||||||
62 | /** Constructor... | ||||||
63 | */ | ||||||
64 | Reference (reference_type * pBody) | ||||||
65 | : m_pBody (pBody) | ||||||
66 | { | ||||||
67 | if (m_pBody) | ||||||
68 | m_pBody->acquire(); | ||||||
69 | } | ||||||
70 | |||||||
71 | /** Copy constructor... | ||||||
72 | */ | ||||||
73 | Reference (const Reference<reference_type> & handle) | ||||||
74 | : m_pBody (handle.m_pBody) | ||||||
75 | { | ||||||
76 | if (m_pBody) | ||||||
77 | m_pBody->acquire(); | ||||||
78 | } | ||||||
79 | |||||||
80 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||
81 | /** Move constructor... | ||||||
82 | */ | ||||||
83 | Reference (Reference<reference_type> && handle) noexcept | ||||||
84 | : m_pBody (handle.m_pBody) | ||||||
85 | { | ||||||
86 | handle.m_pBody = nullptr; | ||||||
87 | } | ||||||
88 | #endif | ||||||
89 | |||||||
90 | #if defined LIBO_INTERNAL_ONLY1 | ||||||
91 | /** Up-casting conversion constructor: Copies interface reference. | ||||||
92 | |||||||
93 | Does not work for up-casts to ambiguous bases. | ||||||
94 | |||||||
95 | @param rRef another reference | ||||||
96 | */ | ||||||
97 | template< class derived_type > | ||||||
98 | inline Reference( | ||||||
99 | const Reference< derived_type > & rRef, | ||||||
100 | std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 ) | ||||||
101 | : m_pBody (rRef.get()) | ||||||
102 | { | ||||||
103 | if (m_pBody) | ||||||
104 | m_pBody->acquire(); | ||||||
105 | } | ||||||
106 | #endif | ||||||
107 | |||||||
108 | /** Destructor... | ||||||
109 | */ | ||||||
110 | ~Reference() COVERITY_NOEXCEPT_FALSE | ||||||
111 | { | ||||||
112 | if (m_pBody
| ||||||
113 | m_pBody->release(); | ||||||
114 | } | ||||||
115 | |||||||
116 | /** Set... | ||||||
117 | Similar to assignment. | ||||||
118 | */ | ||||||
119 | Reference<reference_type> & | ||||||
120 | SAL_CALL set (reference_type * pBody) | ||||||
121 | { | ||||||
122 | if (pBody) | ||||||
123 | pBody->acquire(); | ||||||
124 | reference_type * const pOld = m_pBody; | ||||||
125 | m_pBody = pBody; | ||||||
126 | if (pOld) | ||||||
127 | pOld->release(); | ||||||
128 | return *this; | ||||||
129 | } | ||||||
130 | |||||||
131 | /** Assignment. | ||||||
132 | Unbinds this instance from its body (if bound) and | ||||||
133 | bind it to the body represented by the handle. | ||||||
134 | */ | ||||||
135 | Reference<reference_type> & | ||||||
136 | SAL_CALL operator= (const Reference<reference_type> & handle) | ||||||
137 | { | ||||||
138 | return set( handle.m_pBody ); | ||||||
139 | } | ||||||
140 | |||||||
141 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||
142 | /** Assignment. | ||||||
143 | * Unbinds this instance from its body (if bound), | ||||||
144 | * bind it to the body represented by the handle, and | ||||||
145 | * set the body represented by the handle to nullptr. | ||||||
146 | */ | ||||||
147 | Reference<reference_type> & | ||||||
148 | operator= (Reference<reference_type> && handle) | ||||||
149 | { | ||||||
150 | // self-movement guts ourself | ||||||
151 | if (m_pBody) | ||||||
152 | m_pBody->release(); | ||||||
153 | m_pBody = handle.m_pBody; | ||||||
154 | handle.m_pBody = nullptr; | ||||||
155 | return *this; | ||||||
156 | } | ||||||
157 | #endif | ||||||
158 | |||||||
159 | /** Assignment... | ||||||
160 | */ | ||||||
161 | Reference<reference_type> & | ||||||
162 | SAL_CALL operator= (reference_type * pBody) | ||||||
163 | { | ||||||
164 | return set( pBody ); | ||||||
165 | } | ||||||
166 | |||||||
167 | /** Unbind the body from this handle. | ||||||
168 | Note that for a handle representing a large body, | ||||||
169 | "handle.clear().set(new body());" _might_ | ||||||
170 | perform a little bit better than "handle.set(new body());", | ||||||
171 | since in the second case two large objects exist in memory | ||||||
172 | (the old body and the new body). | ||||||
173 | */ | ||||||
174 | Reference<reference_type> & SAL_CALL clear() | ||||||
175 | { | ||||||
176 | if (m_pBody) | ||||||
177 | { | ||||||
178 | reference_type * const pOld = m_pBody; | ||||||
179 | m_pBody = NULL__null; | ||||||
180 | pOld->release(); | ||||||
181 | } | ||||||
182 | return *this; | ||||||
183 | } | ||||||
184 | |||||||
185 | |||||||
186 | /** Get the body. Can be used instead of operator->(). | ||||||
187 | I.e. handle->someBodyOp() and handle.get()->someBodyOp() | ||||||
188 | are the same. | ||||||
189 | */ | ||||||
190 | reference_type * SAL_CALL get() const | ||||||
191 | { | ||||||
192 | return m_pBody; | ||||||
193 | } | ||||||
194 | |||||||
195 | |||||||
196 | /** Probably most common used: handle->someBodyOp(). | ||||||
197 | */ | ||||||
198 | reference_type * SAL_CALL operator->() const | ||||||
199 | { | ||||||
200 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 200, __extension__ __PRETTY_FUNCTION__)); | ||||||
201 | return m_pBody; | ||||||
202 | } | ||||||
203 | |||||||
204 | |||||||
205 | /** Allows (*handle).someBodyOp(). | ||||||
206 | */ | ||||||
207 | reference_type & SAL_CALL operator*() const | ||||||
208 | { | ||||||
209 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 209, __extension__ __PRETTY_FUNCTION__)); | ||||||
210 | return *m_pBody; | ||||||
211 | } | ||||||
212 | |||||||
213 | |||||||
214 | /** Returns True if the handle does point to a valid body. | ||||||
215 | */ | ||||||
216 | bool SAL_CALL is() const | ||||||
217 | { | ||||||
218 | return (m_pBody != NULL__null); | ||||||
219 | } | ||||||
220 | |||||||
221 | #if defined LIBO_INTERNAL_ONLY1 | ||||||
222 | /** Returns True if the handle does point to a valid body. | ||||||
223 | */ | ||||||
224 | explicit operator bool() const | ||||||
225 | { | ||||||
226 | return is(); | ||||||
227 | } | ||||||
228 | #endif | ||||||
229 | |||||||
230 | /** Returns True if this points to pBody. | ||||||
231 | */ | ||||||
232 | bool SAL_CALL operator== (const reference_type * pBody) const | ||||||
233 | { | ||||||
234 | return (m_pBody == pBody); | ||||||
235 | } | ||||||
236 | |||||||
237 | |||||||
238 | /** Returns True if handle points to the same body. | ||||||
239 | */ | ||||||
240 | bool | ||||||
241 | SAL_CALL operator== (const Reference<reference_type> & handle) const | ||||||
242 | { | ||||||
243 | return (m_pBody == handle.m_pBody); | ||||||
244 | } | ||||||
245 | |||||||
246 | |||||||
247 | /** Needed to place References into STL collection. | ||||||
248 | */ | ||||||
249 | bool | ||||||
250 | SAL_CALL operator!= (const Reference<reference_type> & handle) const | ||||||
251 | { | ||||||
252 | return (m_pBody != handle.m_pBody); | ||||||
253 | } | ||||||
254 | |||||||
255 | |||||||
256 | /** Needed to place References into STL collection. | ||||||
257 | */ | ||||||
258 | bool | ||||||
259 | SAL_CALL operator< (const Reference<reference_type> & handle) const | ||||||
260 | { | ||||||
261 | return (m_pBody < handle.m_pBody); | ||||||
262 | } | ||||||
263 | |||||||
264 | |||||||
265 | /** Needed to place References into STL collection. | ||||||
266 | */ | ||||||
267 | bool | ||||||
268 | SAL_CALL operator> (const Reference<reference_type> & handle) const | ||||||
269 | { | ||||||
270 | return (m_pBody > handle.m_pBody); | ||||||
271 | } | ||||||
272 | }; | ||||||
273 | |||||||
274 | } // namespace rtl | ||||||
275 | |||||||
276 | #if defined LIBO_INTERNAL_ONLY1 | ||||||
277 | namespace std | ||||||
278 | { | ||||||
279 | |||||||
280 | /// @cond INTERNAL | ||||||
281 | /** | ||||||
282 | Make rtl::Reference hashable by default for use in STL containers. | ||||||
283 | |||||||
284 | @since LibreOffice 6.3 | ||||||
285 | */ | ||||||
286 | template<typename T> | ||||||
287 | struct hash<::rtl::Reference<T>> | ||||||
288 | { | ||||||
289 | std::size_t operator()(::rtl::Reference<T> const & s) const | ||||||
290 | { return std::size_t(s.get()); } | ||||||
291 | }; | ||||||
292 | /// @endcond | ||||||
293 | |||||||
294 | } | ||||||
295 | |||||||
296 | #endif | ||||||
297 | |||||||
298 | #endif /* ! INCLUDED_RTL_REF_HXX */ | ||||||
299 | |||||||
300 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | /* |
3 | * This file is part of the LibreOffice project. |
4 | * |
5 | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | * |
9 | * This file incorporates work covered by the following license notice: |
10 | * |
11 | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | * contributor license agreements. See the NOTICE file distributed |
13 | * with this work for additional information regarding copyright |
14 | * ownership. The ASF licenses this file to you under the Apache |
15 | * License, Version 2.0 (the "License"); you may not use this file |
16 | * except in compliance with the License. You may obtain a copy of |
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | */ |
19 | #ifndef INCLUDED_VCL_Reference_HXX |
20 | #define INCLUDED_VCL_Reference_HXX |
21 | |
22 | #include <vcl/dllapi.h> |
23 | #include <osl/interlck.h> |
24 | |
25 | class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase |
26 | { |
27 | mutable oslInterlockedCount mnRefCnt; |
28 | |
29 | template<typename T> friend class VclPtr; |
30 | |
31 | public: |
32 | void acquire() const |
33 | { |
34 | osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1); |
35 | } |
36 | |
37 | void release() const |
38 | { |
39 | if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0) |
40 | delete this; |
41 | } |
42 | #ifdef DBG_UTIL |
43 | #ifndef _WIN32 |
44 | sal_Int32 getRefCount() const { return mnRefCnt; } |
45 | #endif |
46 | #endif |
47 | |
48 | |
49 | private: |
50 | VclReferenceBase(const VclReferenceBase&) = delete; |
51 | VclReferenceBase& operator=(const VclReferenceBase&) = delete; |
52 | |
53 | bool mbDisposed : 1; |
54 | |
55 | protected: |
56 | VclReferenceBase(); |
57 | protected: |
58 | virtual ~VclReferenceBase(); |
59 | |
60 | protected: |
61 | virtual void dispose(); |
62 | |
63 | public: |
64 | void disposeOnce(); |
65 | bool isDisposed() const { return mbDisposed; } |
66 | |
67 | }; |
68 | #endif |