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