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