File: | home/maarten/src/libreoffice/core/vcl/source/window/winproc.cxx |
Warning: | line 1976, column 10 Called C++ object pointer is null |
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: */ |