1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <tools/debug.hxx>
21 #include <tools/time.hxx>
23 #include <unotools/localedatawrapper.hxx>
25 #include <comphelper/lok.hxx>
26 #include <vcl/i18nhelp.hxx>
27 #include <vcl/unohelp.hxx>
28 #include <vcl/timer.hxx>
29 #include <vcl/event.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/lazydelete.hxx>
41 #include <touch/touch.h>
44 #include <salwtype.hxx>
45 #include <salframe.hxx>
49 #include <helpwin.hxx>
52 #include "dndlistenercontainer.hxx"
54 #include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
55 #include <com/sun/star/awt/MouseEvent.hpp>
57 #define IMPL_MIN_NEEDSYSWIN 49
59 bool ImplCallPreNotify( NotifyEvent
& rEvt
)
61 return Application::CallEventHooks( rEvt
)
62 || rEvt
.GetWindow()->CompatPreNotify( rEvt
);
65 static bool ImplHandleMouseFloatMode( vcl::Window
* pChild
, const Point
& rMousePos
,
66 sal_uInt16 nCode
, MouseNotifyEvent nSVEvent
,
69 ImplSVData
* pSVData
= ImplGetSVData();
71 if ( pSVData
->maWinData
.mpFirstFloat
&& !pSVData
->maWinData
.mpCaptureWin
&&
72 !pSVData
->maWinData
.mpFirstFloat
->ImplIsFloatPopupModeWindow( pChild
) )
75 * #93895# since floats are system windows, coordinates have
76 * to be converted to float relative for the hittest
78 HitTest nHitTest
= HITTEST_OUTSIDE
;
79 FloatingWindow
* pFloat
= pSVData
->maWinData
.mpFirstFloat
->ImplFloatHitTest( pChild
, rMousePos
, nHitTest
);
80 FloatingWindow
* pLastLevelFloat
;
81 FloatWinPopupFlags nPopupFlags
;
82 if ( nSVEvent
== MouseNotifyEvent::MOUSEMOVE
)
87 if ( !pFloat
|| (nHitTest
== HITTEST_RECT
) )
89 if ( pSVData
->maHelpData
.mpHelpWin
&& !pSVData
->maHelpData
.mbKeyboardHelp
)
90 ImplDestroyHelpWindow( true );
91 pChild
->ImplGetFrame()->SetPointer( PointerStyle::Arrow
);
97 if ( nCode
& MOUSE_LEFT
)
99 if ( nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
)
103 pLastLevelFloat
= pSVData
->maWinData
.mpFirstFloat
->ImplFindLastLevelFloat();
104 pLastLevelFloat
->EndPopupMode( FloatWinPopupEndFlags::Cancel
| FloatWinPopupEndFlags::CloseAll
);
107 else if ( nHitTest
== HITTEST_RECT
)
109 pFloat
->ImplSetMouseDown();
117 if ( nHitTest
== HITTEST_RECT
)
119 if ( pFloat
->ImplIsMouseDown() )
120 pFloat
->EndPopupMode( FloatWinPopupEndFlags::Cancel
);
126 pLastLevelFloat
= pSVData
->maWinData
.mpFirstFloat
->ImplFindLastLevelFloat();
127 nPopupFlags
= pLastLevelFloat
->GetPopupModeFlags();
128 if ( !(nPopupFlags
& FloatWinPopupFlags::NoMouseUpClose
) )
130 pLastLevelFloat
->EndPopupMode( FloatWinPopupEndFlags::Cancel
| FloatWinPopupEndFlags::CloseAll
);
140 pLastLevelFloat
= pSVData
->maWinData
.mpFirstFloat
->ImplFindLastLevelFloat();
141 nPopupFlags
= pLastLevelFloat
->GetPopupModeFlags();
142 if ( nPopupFlags
& FloatWinPopupFlags::AllMouseButtonClose
)
144 if ( (nPopupFlags
& FloatWinPopupFlags::NoMouseUpClose
) &&
145 (nSVEvent
== MouseNotifyEvent::MOUSEBUTTONUP
) )
147 pLastLevelFloat
->EndPopupMode( FloatWinPopupEndFlags::Cancel
| FloatWinPopupEndFlags::CloseAll
);
160 static void ImplHandleMouseHelpRequest( vcl::Window
* pChild
, const Point
& rMousePos
)
162 if (comphelper::LibreOfficeKit::isActive())
165 ImplSVData
* pSVData
= ImplGetSVData();
166 if ( !pSVData
->maHelpData
.mpHelpWin
||
167 !( pSVData
->maHelpData
.mpHelpWin
->IsWindowOrChild( pChild
) ||
168 pChild
->IsWindowOrChild( pSVData
->maHelpData
.mpHelpWin
) ) )
170 HelpEventMode nHelpMode
= HelpEventMode::NONE
;
171 if ( pSVData
->maHelpData
.mbQuickHelp
)
172 nHelpMode
= HelpEventMode::QUICK
;
173 if ( pSVData
->maHelpData
.mbBalloonHelp
)
174 nHelpMode
|= HelpEventMode::BALLOON
;
175 if ( bool(nHelpMode
) )
177 if ( pChild
->IsInputEnabled() && !pChild
->IsInModalMode() )
179 HelpEvent
aHelpEvent( rMousePos
, nHelpMode
);
180 pSVData
->maHelpData
.mbRequestingHelp
= true;
181 pChild
->RequestHelp( aHelpEvent
);
182 pSVData
->maHelpData
.mbRequestingHelp
= false;
184 // #104172# do not kill keyboard activated tooltips
185 else if ( pSVData
->maHelpData
.mpHelpWin
&& !pSVData
->maHelpData
.mbKeyboardHelp
)
187 ImplDestroyHelpWindow( true );
193 static void ImplSetMousePointer( vcl::Window
* pChild
)
195 ImplSVData
* pSVData
= ImplGetSVData();
196 if ( pSVData
->maHelpData
.mbExtHelpMode
)
197 pChild
->ImplGetFrame()->SetPointer( PointerStyle::Help
);
199 pChild
->ImplGetFrame()->SetPointer( pChild
->ImplGetMousePointer() );
202 static bool ImplCallCommand( const VclPtr
<vcl::Window
>& pChild
, CommandEventId nEvt
, void* pData
= nullptr,
203 bool bMouse
= false, Point
* pPos
= nullptr )
211 aPos
= pChild
->GetPointerPosPixel();
214 // simulate mouseposition at center of window
215 Size
aSize( pChild
->GetOutputSizePixel() );
216 aPos
= Point( aSize
.getWidth()/2, aSize
.getHeight()/2 );
220 CommandEvent
aCEvt( aPos
, nEvt
, bMouse
, pData
);
221 NotifyEvent
aNCmdEvt( MouseNotifyEvent::COMMAND
, pChild
, &aCEvt
);
222 bool bPreNotify
= ImplCallPreNotify( aNCmdEvt
);
223 if ( pChild
->IsDisposed() )
227 pChild
->ImplGetWindowImpl()->mbCommand
= false;
228 pChild
->Command( aCEvt
);
230 if( pChild
->IsDisposed() )
232 pChild
->ImplNotifyKeyMouseCommandEventListeners( aNCmdEvt
);
233 if ( pChild
->IsDisposed() )
235 if ( pChild
->ImplGetWindowImpl()->mbCommand
)
242 /* #i34277# delayed context menu activation;
243 * necessary if there already was a popup menu running.
246 struct ContextMenuEvent
248 VclPtr
<vcl::Window
> pWindow
;
252 static void ContextMenuEventLink( void* pCEvent
, void* )
254 ContextMenuEvent
* pEv
= static_cast<ContextMenuEvent
*>(pCEvent
);
256 if( ! pEv
->pWindow
->IsDisposed() )
258 ImplCallCommand( pEv
->pWindow
, CommandEventId::ContextMenu
, nullptr, true, &pEv
->aChildPos
);
263 bool ImplHandleMouseEvent( const VclPtr
<vcl::Window
>& xWindow
, MouseNotifyEvent nSVEvent
, bool bMouseLeave
,
264 long nX
, long nY
, sal_uInt64 nMsgTime
,
265 sal_uInt16 nCode
, MouseEventModifiers nMode
)
267 ImplSVData
* pSVData
= ImplGetSVData();
268 Point
aMousePos( nX
, nY
);
269 VclPtr
<vcl::Window
> pChild
;
271 sal_uInt16
nClicks(0);
272 ImplFrameData
* pWinFrameData
= xWindow
->ImplGetFrameData();
273 sal_uInt16 nOldCode
= pWinFrameData
->mnMouseCode
;
275 // we need a mousemove event, before we get a mousebuttondown or a
276 // mousebuttonup event
277 if ( (nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
) || (nSVEvent
== MouseNotifyEvent::MOUSEBUTTONUP
) )
279 if ( (nSVEvent
== MouseNotifyEvent::MOUSEBUTTONUP
) && pSVData
->maHelpData
.mbExtHelpMode
)
281 if ( pSVData
->maHelpData
.mpHelpWin
)
283 if( xWindow
->ImplGetWindow() == pSVData
->maHelpData
.mpHelpWin
)
285 ImplDestroyHelpWindow( false );
286 return true; // xWindow is dead now - avoid crash!
289 ImplDestroyHelpWindow( true );
292 if ( (pWinFrameData
->mnLastMouseX
!= nX
) ||
293 (pWinFrameData
->mnLastMouseY
!= nY
) )
295 sal_uInt16 nMoveCode
= nCode
& ~(MOUSE_LEFT
| MOUSE_RIGHT
| MOUSE_MIDDLE
);
296 ImplHandleMouseEvent(xWindow
, MouseNotifyEvent::MOUSEMOVE
, false, nX
, nY
, nMsgTime
, nMoveCode
, nMode
);
301 pWinFrameData
->mnBeforeLastMouseX
= pWinFrameData
->mnLastMouseX
;
302 pWinFrameData
->mnBeforeLastMouseY
= pWinFrameData
->mnLastMouseY
;
303 pWinFrameData
->mnLastMouseX
= nX
;
304 pWinFrameData
->mnLastMouseY
= nY
;
305 pWinFrameData
->mnMouseCode
= nCode
;
306 MouseEventModifiers nTmpMask
= MouseEventModifiers::SYNTHETIC
| MouseEventModifiers::MODIFIERCHANGED
;
307 pWinFrameData
->mnMouseMode
= nMode
& ~nTmpMask
;
310 pWinFrameData
->mbMouseIn
= false;
311 if ( pSVData
->maHelpData
.mpHelpWin
&& !pSVData
->maHelpData
.mbKeyboardHelp
)
313 ImplDestroyHelpWindow( true );
315 if ( xWindow
->IsDisposed() )
316 return true; // xWindow is dead now - avoid crash! (#122045#)
320 pWinFrameData
->mbMouseIn
= true;
322 DBG_ASSERT( !pSVData
->maWinData
.mpTrackWin
||
323 (pSVData
->maWinData
.mpTrackWin
== pSVData
->maWinData
.mpCaptureWin
),
324 "ImplHandleMouseEvent: TrackWin != CaptureWin" );
327 if ( pSVData
->maWinData
.mpAutoScrollWin
&& (nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
) )
329 pSVData
->maWinData
.mpAutoScrollWin
->EndAutoScroll();
334 if ( pSVData
->maWinData
.mpCaptureWin
)
336 pChild
= pSVData
->maWinData
.mpCaptureWin
;
338 SAL_WARN_IF( xWindow
!= pChild
->ImplGetFrameWindow(), "vcl",
339 "ImplHandleMouseEvent: mouse event is not sent to capture window" );
341 // java client cannot capture mouse correctly
342 if ( xWindow
!= pChild
->ImplGetFrameWindow() )
353 pChild
= xWindow
->ImplFindWindow( aMousePos
);
356 // test this because mouse events are buffered in the remote version
357 // and size may not be in sync
358 if ( !pChild
&& !bMouseLeave
)
361 // execute a few tests and catch the message or implement the status
364 if( pChild
->ImplIsAntiparallel() )
366 // - RTL - re-mirror frame pos at pChild
367 const OutputDevice
*pChildWinOutDev
= pChild
->GetOutDev();
368 pChildWinOutDev
->ReMirror( aMousePos
);
371 // no mouse messages to disabled windows
372 // #106845# if the window was disabled during capturing we have to pass the mouse events to release capturing
373 if ( pSVData
->maWinData
.mpCaptureWin
.get() != pChild
&& (!pChild
->IsEnabled() || !pChild
->IsInputEnabled() || pChild
->IsInModalMode() ) )
375 ImplHandleMouseFloatMode( pChild
, aMousePos
, nCode
, nSVEvent
, bMouseLeave
);
376 if ( nSVEvent
== MouseNotifyEvent::MOUSEMOVE
)
378 ImplHandleMouseHelpRequest( pChild
, aMousePos
);
379 if( pWinFrameData
->mpMouseMoveWin
.get() != pChild
)
380 nMode
|= MouseEventModifiers::ENTERWINDOW
;
383 // Call the hook also, if Window is disabled
384 Point aChildPos
= pChild
->ImplFrameToOutput( aMousePos
);
385 MouseEvent
aMEvt( aChildPos
, pWinFrameData
->mnClickCount
, nMode
, nCode
, nCode
);
386 NotifyEvent
aNEvt( nSVEvent
, pChild
, &aMEvt
);
387 Application::CallEventHooks( aNEvt
);
389 if( pChild
->IsCallHandlersOnInputDisabled() )
391 pWinFrameData
->mpMouseMoveWin
= pChild
;
392 pChild
->ImplNotifyKeyMouseCommandEventListeners( aNEvt
);
395 if ( nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
)
399 // Set normal MousePointer for disabled windows
400 if ( nSVEvent
== MouseNotifyEvent::MOUSEMOVE
)
401 ImplSetMousePointer( pChild
);
407 // End ExtTextInput-Mode, if the user click in the same TopLevel Window
408 if ( pSVData
->maWinData
.mpExtTextInputWin
&&
409 ((nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
) ||
410 (nSVEvent
== MouseNotifyEvent::MOUSEBUTTONUP
)) )
411 pSVData
->maWinData
.mpExtTextInputWin
->EndExtTextInput();
414 // determine mouse event data
415 if ( nSVEvent
== MouseNotifyEvent::MOUSEMOVE
)
417 // check if MouseMove belongs to same window and if the
418 // status did not change
421 Point aChildMousePos
= pChild
->ImplFrameToOutput( aMousePos
);
423 (pChild
== pWinFrameData
->mpMouseMoveWin
) &&
424 (aChildMousePos
.X() == pWinFrameData
->mnLastMouseWinX
) &&
425 (aChildMousePos
.Y() == pWinFrameData
->mnLastMouseWinY
) &&
426 (nOldCode
== pWinFrameData
->mnMouseCode
) )
428 // set mouse pointer anew, as it could have changed
429 // due to the mode switch
430 ImplSetMousePointer( pChild
);
434 pWinFrameData
->mnLastMouseWinX
= aChildMousePos
.X();
435 pWinFrameData
->mnLastMouseWinY
= aChildMousePos
.Y();
439 nClicks
= pWinFrameData
->mnClickCount
;
441 // call Start-Drag handler if required
442 // Warning: should be called before Move, as otherwise during
443 // fast mouse movements the applications move to the selection state
444 vcl::Window
* pMouseDownWin
= pWinFrameData
->mpMouseDownWin
;
447 // check for matching StartDrag mode. We only compare
448 // the status of the mouse buttons, such that e. g. Mod1 can
449 // change immediately to the copy mode
450 const MouseSettings
& rMSettings
= pMouseDownWin
->GetSettings().GetMouseSettings();
451 if ( (nCode
& (MOUSE_LEFT
| MOUSE_RIGHT
| MOUSE_MIDDLE
)) ==
452 (rMSettings
.GetStartDragCode() & (MOUSE_LEFT
| MOUSE_RIGHT
| MOUSE_MIDDLE
)) )
454 if ( !pMouseDownWin
->ImplGetFrameData()->mbStartDragCalled
)
456 long nDragW
= rMSettings
.GetStartDragWidth();
457 long nDragH
= rMSettings
.GetStartDragHeight();
460 long nMouseX
= aMousePos
.X(); // #106074# use the possibly re-mirrored coordinates (RTL) ! nX,nY are unmodified !
461 long nMouseY
= aMousePos
.Y();
462 if ( !(((nMouseX
-nDragW
) <= pMouseDownWin
->ImplGetFrameData()->mnFirstMouseX
) &&
463 ((nMouseX
+nDragW
) >= pMouseDownWin
->ImplGetFrameData()->mnFirstMouseX
)) ||
464 !(((nMouseY
-nDragH
) <= pMouseDownWin
->ImplGetFrameData()->mnFirstMouseY
) &&
465 ((nMouseY
+nDragH
) >= pMouseDownWin
->ImplGetFrameData()->mnFirstMouseY
)) )
467 pMouseDownWin
->ImplGetFrameData()->mbStartDragCalled
= true;
469 // Check if drag source provides it's own recognizer
470 if( pMouseDownWin
->ImplGetFrameData()->mbInternalDragGestureRecognizer
)
472 // query DropTarget from child window
473 css::uno::Reference
< css::datatransfer::dnd::XDragGestureRecognizer
> xDragGestureRecognizer
=
474 css::uno::Reference
< css::datatransfer::dnd::XDragGestureRecognizer
> ( pMouseDownWin
->ImplGetWindowImpl()->mxDNDListenerContainer
,
475 css::uno::UNO_QUERY
);
477 if( xDragGestureRecognizer
.is() )
479 // retrieve mouse position relative to mouse down window
480 Point relLoc
= pMouseDownWin
->ImplFrameToOutput( Point(
481 pMouseDownWin
->ImplGetFrameData()->mnFirstMouseX
,
482 pMouseDownWin
->ImplGetFrameData()->mnFirstMouseY
) );
484 // create a uno mouse event out of the available data
485 css::awt::MouseEvent
aMouseEvent( static_cast < css::uno::XInterface
* > ( nullptr ),
487 nCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
| KEY_MOD3
),
489 nCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
),
491 nCode
& (MOUSE_LEFT
| MOUSE_RIGHT
| MOUSE_MIDDLE
),
497 SolarMutexReleaser aReleaser
;
499 // FIXME: where do I get Action from ?
500 css::uno::Reference
< css::datatransfer::dnd::XDragSource
> xDragSource
= pMouseDownWin
->GetDragSource();
502 if( xDragSource
.is() )
504 static_cast < DNDListenerContainer
* > ( xDragGestureRecognizer
.get() )->fireDragGestureEvent( 0,
505 relLoc
.X(), relLoc
.Y(), xDragSource
, css::uno::makeAny( aMouseEvent
) );
513 pMouseDownWin
->ImplGetFrameData()->mbStartDragCalled
= true;
516 // test for mouseleave and mouseenter
517 VclPtr
<vcl::Window
> pMouseMoveWin
= pWinFrameData
->mpMouseMoveWin
;
518 if ( pChild
!= pMouseMoveWin
)
522 Point aLeaveMousePos
= pMouseMoveWin
->ImplFrameToOutput( aMousePos
);
523 MouseEvent
aMLeaveEvt( aLeaveMousePos
, nClicks
, nMode
| MouseEventModifiers::LEAVEWINDOW
, nCode
, nCode
);
524 NotifyEvent
aNLeaveEvt( MouseNotifyEvent::MOUSEMOVE
, pMouseMoveWin
, &aMLeaveEvt
);
525 pWinFrameData
->mbInMouseMove
= true;
526 pMouseMoveWin
->ImplGetWinData()->mbMouseOver
= false;
528 // A MouseLeave can destroy this window
529 if ( !ImplCallPreNotify( aNLeaveEvt
) )
531 pMouseMoveWin
->MouseMove( aMLeaveEvt
);
532 if( !pMouseMoveWin
->IsDisposed() )
533 aNLeaveEvt
.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNLeaveEvt
);
536 pWinFrameData
->mpMouseMoveWin
= nullptr;
537 pWinFrameData
->mbInMouseMove
= false;
541 if ( pChild
->IsDisposed() )
544 if ( pMouseMoveWin
->IsDisposed() )
548 nMode
|= MouseEventModifiers::ENTERWINDOW
;
550 pWinFrameData
->mpMouseMoveWin
= pChild
;
552 pChild
->ImplGetWinData()->mbMouseOver
= true;
563 if ( nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
)
565 const MouseSettings
& rMSettings
= pChild
->GetSettings().GetMouseSettings();
566 sal_uInt64 nDblClkTime
= rMSettings
.GetDoubleClickTime();
567 long nDblClkW
= rMSettings
.GetDoubleClickWidth();
568 long nDblClkH
= rMSettings
.GetDoubleClickHeight();
571 long nMouseX
= aMousePos
.X(); // #106074# use the possibly re-mirrored coordinates (RTL) ! nX,nY are unmodified !
572 long nMouseY
= aMousePos
.Y();
574 if ( (pChild
== pChild
->ImplGetFrameData()->mpMouseDownWin
) &&
575 (nCode
== pChild
->ImplGetFrameData()->mnFirstMouseCode
) &&
576 ((nMsgTime
-pChild
->ImplGetFrameData()->mnMouseDownTime
) < nDblClkTime
) &&
577 ((nMouseX
-nDblClkW
) <= pChild
->ImplGetFrameData()->mnFirstMouseX
) &&
578 ((nMouseX
+nDblClkW
) >= pChild
->ImplGetFrameData()->mnFirstMouseX
) &&
579 ((nMouseY
-nDblClkH
) <= pChild
->ImplGetFrameData()->mnFirstMouseY
) &&
580 ((nMouseY
+nDblClkH
) >= pChild
->ImplGetFrameData()->mnFirstMouseY
) )
582 pChild
->ImplGetFrameData()->mnClickCount
++;
583 pChild
->ImplGetFrameData()->mbStartDragCalled
= true;
587 pChild
->ImplGetFrameData()->mpMouseDownWin
= pChild
;
588 pChild
->ImplGetFrameData()->mnClickCount
= 1;
589 pChild
->ImplGetFrameData()->mnFirstMouseX
= nMouseX
;
590 pChild
->ImplGetFrameData()->mnFirstMouseY
= nMouseY
;
591 pChild
->ImplGetFrameData()->mnFirstMouseCode
= nCode
;
592 pChild
->ImplGetFrameData()->mbStartDragCalled
= !((nCode
& (MOUSE_LEFT
| MOUSE_RIGHT
| MOUSE_MIDDLE
)) ==
593 (rMSettings
.GetStartDragCode() & (MOUSE_LEFT
| MOUSE_RIGHT
| MOUSE_MIDDLE
)));
595 pChild
->ImplGetFrameData()->mnMouseDownTime
= nMsgTime
;
597 nClicks
= pChild
->ImplGetFrameData()->mnClickCount
;
600 pSVData
->maAppData
.mnLastInputTime
= tools::Time::GetSystemTicks();
603 SAL_WARN_IF( !pChild
, "vcl", "ImplHandleMouseEvent: pChild == NULL" );
608 // create mouse event
609 Point aChildPos
= pChild
->ImplFrameToOutput( aMousePos
);
610 MouseEvent
aMEvt( aChildPos
, nClicks
, nMode
, nCode
, nCode
);
613 // tracking window gets the mouse events
614 if ( pSVData
->maWinData
.mpTrackWin
)
615 pChild
= pSVData
->maWinData
.mpTrackWin
;
617 // handle FloatingMode
618 if ( !pSVData
->maWinData
.mpTrackWin
&& pSVData
->maWinData
.mpFirstFloat
)
620 if ( ImplHandleMouseFloatMode( pChild
, aMousePos
, nCode
, nSVEvent
, bMouseLeave
) )
622 if ( !pChild
->IsDisposed() )
624 pChild
->ImplGetFrameData()->mbStartDragCalled
= true;
632 bool bCallHelpRequest
= true;
633 SAL_WARN_IF( !pChild
, "vcl", "ImplHandleMouseEvent: pChild is NULL" );
638 NotifyEvent
aNEvt( nSVEvent
, pChild
, &aMEvt
);
639 if ( nSVEvent
== MouseNotifyEvent::MOUSEMOVE
)
640 pChild
->ImplGetFrameData()->mbInMouseMove
= true;
642 // bring window into foreground on mouseclick
643 if ( nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
)
645 if( !pSVData
->maWinData
.mpFirstFloat
&& // totop for floating windows in popup would change the focus and would close them immediately
646 !(pChild
->ImplGetFrameWindow()->GetStyle() & WB_OWNERDRAWDECORATION
) ) // ownerdrawdecorated windows must never grab focus
648 if ( pChild
->IsDisposed() )
652 if ( ImplCallPreNotify( aNEvt
) || pChild
->IsDisposed() )
657 if ( nSVEvent
== MouseNotifyEvent::MOUSEMOVE
)
659 if ( pSVData
->maWinData
.mpTrackWin
)
661 TrackingEvent
aTEvt( aMEvt
);
662 pChild
->Tracking( aTEvt
);
663 if ( !pChild
->IsDisposed() )
665 // When ScrollRepeat, we restart the timer
666 if ( pSVData
->maWinData
.mpTrackTimer
&&
667 (pSVData
->maWinData
.mnTrackFlags
& StartTrackingFlags::ScrollRepeat
) )
668 pSVData
->maWinData
.mpTrackTimer
->Start();
670 bCallHelpRequest
= false;
676 if ( !pSVData
->maWinData
.mpCaptureWin
&&
677 (pChild
->GetSettings().GetMouseSettings().GetOptions() & MouseSettingsOptions::AutoFocus
) )
678 pChild
->ToTop( ToTopFlags::NoGrabFocus
);
680 if( pChild
->IsDisposed() )
681 bCallHelpRequest
= false;
684 // if the MouseMove handler changes the help window's visibility
685 // the HelpRequest handler should not be called anymore
686 vcl::Window
* pOldHelpTextWin
= pSVData
->maHelpData
.mpHelpWin
;
687 pChild
->ImplGetWindowImpl()->mbMouseMove
= false;
688 pChild
->MouseMove( aMEvt
);
689 if ( pOldHelpTextWin
!= pSVData
->maHelpData
.mpHelpWin
)
690 bCallHelpRequest
= false;
694 else if ( nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
)
696 if ( pSVData
->maWinData
.mpTrackWin
&&
697 !(pSVData
->maWinData
.mnTrackFlags
& StartTrackingFlags::MouseButtonDown
) )
701 pChild
->ImplGetWindowImpl()->mbMouseButtonDown
= false;
702 pChild
->MouseButtonDown( aMEvt
);
707 if ( pSVData
->maWinData
.mpTrackWin
)
709 pChild
->EndTracking();
714 pChild
->ImplGetWindowImpl()->mbMouseButtonUp
= false;
715 pChild
->MouseButtonUp( aMEvt
);
719 assert(aNEvt
.GetWindow() == pChild
);
721 if (!pChild
->IsDisposed())
722 pChild
->ImplNotifyKeyMouseCommandEventListeners( aNEvt
);
725 if (pChild
->IsDisposed())
728 if ( nSVEvent
== MouseNotifyEvent::MOUSEMOVE
)
729 pChild
->ImplGetWindowImpl()->mpFrameData
->mbInMouseMove
= false;
731 if ( nSVEvent
== MouseNotifyEvent::MOUSEMOVE
)
733 if ( bCallHelpRequest
&& !pSVData
->maHelpData
.mbKeyboardHelp
)
734 ImplHandleMouseHelpRequest( pChild
, pChild
->OutputToScreenPixel( aMEvt
.GetPosPixel() ) );
739 if ( nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
)
741 if ( !pChild
->ImplGetWindowImpl()->mbMouseButtonDown
)
746 if ( !pChild
->ImplGetWindowImpl()->mbMouseButtonUp
)
751 if ( nSVEvent
== MouseNotifyEvent::MOUSEMOVE
)
753 // set new mouse pointer
755 ImplSetMousePointer( pChild
);
757 else if ( (nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
) || (nSVEvent
== MouseNotifyEvent::MOUSEBUTTONUP
) )
762 if ( /*!bRet &&*/ (nClicks
== 1) && (nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
) &&
763 (nCode
== MOUSE_MIDDLE
) )
765 MouseMiddleButtonAction nMiddleAction
= pChild
->GetSettings().GetMouseSettings().GetMiddleButtonAction();
766 if ( nMiddleAction
== MouseMiddleButtonAction::AutoScroll
)
767 bRet
= !ImplCallCommand( pChild
, CommandEventId::StartAutoScroll
, nullptr, true, &aChildPos
);
768 else if ( nMiddleAction
== MouseMiddleButtonAction::PasteSelection
)
769 bRet
= !ImplCallCommand( pChild
, CommandEventId::PasteSelection
, nullptr, true, &aChildPos
);
774 const MouseSettings
& rMSettings
= pChild
->GetSettings().GetMouseSettings();
775 if ( (nCode
== rMSettings
.GetContextMenuCode()) &&
776 (nClicks
== rMSettings
.GetContextMenuClicks()) )
778 bool bContextMenu
= (nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
);
781 if( pSVData
->maAppData
.mpActivePopupMenu
)
783 /* #i34277# there already is a context menu open
784 * that was probably just closed with EndPopupMode.
785 * We need to give the eventual corresponding
786 * PopupMenu::Execute a chance to end properly.
787 * Therefore delay context menu command and
788 * issue only after popping one frame of the
791 ContextMenuEvent
* pEv
= new ContextMenuEvent
;
792 pEv
->pWindow
= pChild
;
793 pEv
->aChildPos
= aChildPos
;
794 Application::PostUserEvent( Link
<void*,void>( pEv
, ContextMenuEventLink
) );
797 bRet
= ! ImplCallCommand( pChild
, CommandEventId::ContextMenu
, nullptr, true, &aChildPos
);
807 static vcl::Window
* ImplGetKeyInputWindow( vcl::Window
* pWindow
)
809 ImplSVData
* pSVData
= ImplGetSVData();
811 // determine last input time
812 pSVData
->maAppData
.mnLastInputTime
= tools::Time::GetSystemTicks();
814 // #127104# workaround for destroyed windows
815 if( pWindow
->ImplGetWindowImpl() == nullptr )
818 // find window - is every time the window which has currently the
819 // focus or the last time the focus.
821 // the first floating window always has the focus, try it, or any parent floating windows, first
822 vcl::Window
* pChild
= pSVData
->maWinData
.mpFirstFloat
;
825 if (pChild
->ImplGetWindowImpl()->mbFloatWin
)
827 if (static_cast<FloatingWindow
*>(pChild
)->GrabsFocus())
830 pChild
= pChild
->GetParent();
836 pChild
= pChild
->ImplGetWindowImpl()->mpFrameData
->mpFocusWin
;
838 // no child - than no input
842 // We call also KeyInput if we haven't the focus, because on Unix
843 // system this is often the case when a Lookup Choice Window has
844 // the focus - because this windows send the KeyInput directly to
845 // the window without resetting the focus
846 SAL_WARN_IF( pChild
!= pSVData
->maWinData
.mpFocusWin
, "vcl",
847 "ImplHandleKey: Keyboard-Input is sent to a frame without focus" );
849 // no keyinput to disabled windows
850 if ( !pChild
->IsEnabled() || !pChild
->IsInputEnabled() || pChild
->IsInModalMode() )
856 static bool ImplHandleKey( vcl::Window
* pWindow
, MouseNotifyEvent nSVEvent
,
857 sal_uInt16 nKeyCode
, sal_uInt16 nCharCode
, sal_uInt16 nRepeat
, bool bForward
)
859 ImplSVData
* pSVData
= ImplGetSVData();
860 vcl::KeyCode
aKeyCode( nKeyCode
, nKeyCode
);
861 sal_uInt16 nEvCode
= aKeyCode
.GetCode();
863 // allow application key listeners to remove the key event
864 // but make sure we're not forwarding external KeyEvents, (ie where bForward is false)
865 // because those are coming back from the listener itself and MUST be processed
866 KeyEvent
aKeyEvent( (sal_Unicode
)nCharCode
, aKeyCode
, nRepeat
);
869 sal_uInt16 nVCLEvent
;
872 case MouseNotifyEvent::KEYINPUT
:
873 nVCLEvent
= VCLEVENT_WINDOW_KEYINPUT
;
875 case MouseNotifyEvent::KEYUP
:
876 nVCLEvent
= VCLEVENT_WINDOW_KEYUP
;
882 if( nVCLEvent
&& Application::HandleKey( nVCLEvent
, pWindow
, &aKeyEvent
) )
886 // #i1820# use locale specific decimal separator
887 if( nEvCode
== KEY_DECIMAL
)
889 if( Application::GetSettings().GetMiscSettings().GetEnableLocalizedDecimalSep() )
891 OUString
aSep( pWindow
->GetSettings().GetLocaleDataWrapper().getNumDecimalSep() );
892 nCharCode
= (sal_uInt16
) aSep
[0];
896 bool bCtrlF6
= (aKeyCode
.GetCode() == KEY_F6
) && aKeyCode
.IsMod1();
898 // determine last input time
899 pSVData
->maAppData
.mnLastInputTime
= tools::Time::GetSystemTicks();
901 // handle tracking window
902 if ( nSVEvent
== MouseNotifyEvent::KEYINPUT
)
904 if ( pSVData
->maHelpData
.mbExtHelpMode
)
907 if ( nEvCode
== KEY_ESCAPE
)
910 if ( pSVData
->maHelpData
.mpHelpWin
)
911 ImplDestroyHelpWindow( false );
914 if ( pSVData
->maWinData
.mpAutoScrollWin
)
916 pSVData
->maWinData
.mpAutoScrollWin
->EndAutoScroll();
917 if ( nEvCode
== KEY_ESCAPE
)
921 if ( pSVData
->maWinData
.mpTrackWin
)
923 sal_uInt16 nOrigCode
= aKeyCode
.GetCode();
925 if ( (nOrigCode
== KEY_ESCAPE
) && !(pSVData
->maWinData
.mnTrackFlags
& StartTrackingFlags::NoKeyCancel
) )
927 pSVData
->maWinData
.mpTrackWin
->EndTracking( TrackingEventFlags::Cancel
| TrackingEventFlags::Key
);
928 if ( pSVData
->maWinData
.mpFirstFloat
)
930 FloatingWindow
* pLastLevelFloat
= pSVData
->maWinData
.mpFirstFloat
->ImplFindLastLevelFloat();
931 if ( !(pLastLevelFloat
->GetPopupModeFlags() & FloatWinPopupFlags::NoKeyClose
) )
933 sal_uInt16 nEscCode
= aKeyCode
.GetCode();
935 if ( nEscCode
== KEY_ESCAPE
)
936 pLastLevelFloat
->EndPopupMode( FloatWinPopupEndFlags::Cancel
| FloatWinPopupEndFlags::CloseAll
);
941 else if ( nOrigCode
== KEY_RETURN
)
943 pSVData
->maWinData
.mpTrackWin
->EndTracking( TrackingEventFlags::Key
);
946 else if ( !(pSVData
->maWinData
.mnTrackFlags
& StartTrackingFlags::KeyInput
) )
950 // handle FloatingMode
951 if ( pSVData
->maWinData
.mpFirstFloat
)
953 FloatingWindow
* pLastLevelFloat
= pSVData
->maWinData
.mpFirstFloat
->ImplFindLastLevelFloat();
954 if ( !(pLastLevelFloat
->GetPopupModeFlags() & FloatWinPopupFlags::NoKeyClose
) )
956 sal_uInt16 nCode
= aKeyCode
.GetCode();
958 if ( (nCode
== KEY_ESCAPE
) || bCtrlF6
)
960 pLastLevelFloat
->EndPopupMode( FloatWinPopupEndFlags::Cancel
| FloatWinPopupEndFlags::CloseAll
);
968 if ( pSVData
->maAppData
.mpAccelMgr
)
970 if ( pSVData
->maAppData
.mpAccelMgr
->IsAccelKey( aKeyCode
, nRepeat
) )
976 VclPtr
<vcl::Window
> pChild
= ImplGetKeyInputWindow( pWindow
);
980 // --- RTL --- mirror cursor keys
981 const OutputDevice
*pChildOutDev
= pChild
->GetOutDev();
982 if( (aKeyCode
.GetCode() == KEY_LEFT
|| aKeyCode
.GetCode() == KEY_RIGHT
) &&
983 pChildOutDev
->HasMirroredGraphics() && pChild
->IsRTLEnabled() )
984 aKeyCode
= vcl::KeyCode( aKeyCode
.GetCode() == KEY_LEFT
? KEY_RIGHT
: KEY_LEFT
, aKeyCode
.GetModifier() );
986 KeyEvent
aKeyEvt( (sal_Unicode
)nCharCode
, aKeyCode
, nRepeat
);
987 NotifyEvent
aNotifyEvt( nSVEvent
, pChild
, &aKeyEvt
);
988 bool bKeyPreNotify
= ImplCallPreNotify( aNotifyEvt
);
991 if ( !bKeyPreNotify
&& !pChild
->IsDisposed() )
993 if ( nSVEvent
== MouseNotifyEvent::KEYINPUT
)
995 pChild
->ImplGetWindowImpl()->mbKeyInput
= false;
996 pChild
->KeyInput( aKeyEvt
);
1000 pChild
->ImplGetWindowImpl()->mbKeyUp
= false;
1001 pChild
->KeyUp( aKeyEvt
);
1003 if( !pChild
->IsDisposed() )
1004 aNotifyEvt
.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNotifyEvt
);
1007 if ( pChild
->IsDisposed() )
1010 if ( nSVEvent
== MouseNotifyEvent::KEYINPUT
)
1012 if ( !bKeyPreNotify
&& pChild
->ImplGetWindowImpl()->mbKeyInput
)
1014 sal_uInt16 nCode
= aKeyCode
.GetCode();
1016 // #101999# is focus in or below toolbox
1017 bool bToolboxFocus
=false;
1018 if( (nCode
== KEY_F1
) && aKeyCode
.IsShift() )
1020 vcl::Window
*pWin
= pWindow
->ImplGetWindowImpl()->mpFrameData
->mpFocusWin
;
1023 if( pWin
->ImplGetWindowImpl()->mbToolBox
)
1025 bToolboxFocus
= true;
1029 pWin
= pWin
->GetParent();
1034 if ( (nCode
== KEY_CONTEXTMENU
) || ((nCode
== KEY_F10
) && aKeyCode
.IsShift() && !aKeyCode
.IsMod1() && !aKeyCode
.IsMod2() ) )
1035 bRet
= !ImplCallCommand( pChild
, CommandEventId::ContextMenu
);
1036 else if ( ( (nCode
== KEY_F2
) && aKeyCode
.IsShift() ) || ( (nCode
== KEY_F1
) && aKeyCode
.IsMod1() ) ||
1037 // #101999# no active help when focus in toolbox, simulate BallonHelp instead
1038 ( (nCode
== KEY_F1
) && aKeyCode
.IsShift() && bToolboxFocus
) )
1040 // TipHelp via Keyboard (Shift-F2 or Ctrl-F1)
1041 // simulate mouseposition at center of window
1043 Size aSize
= pChild
->GetOutputSize();
1044 Point aPos
= Point( aSize
.getWidth()/2, aSize
.getHeight()/2 );
1045 aPos
= pChild
->OutputToScreenPixel( aPos
);
1047 HelpEvent
aHelpEvent( aPos
, HelpEventMode::BALLOON
);
1048 aHelpEvent
.SetKeyboardActivated( true );
1049 pSVData
->maHelpData
.mbSetKeyboardHelp
= true;
1050 pChild
->RequestHelp( aHelpEvent
);
1051 pSVData
->maHelpData
.mbSetKeyboardHelp
= false;
1053 else if ( (nCode
== KEY_F1
) || (nCode
== KEY_HELP
) )
1055 if ( !aKeyCode
.GetModifier() )
1057 if ( pSVData
->maHelpData
.mbContextHelp
)
1059 Point aMousePos
= pChild
->OutputToScreenPixel( pChild
->GetPointerPosPixel() );
1060 HelpEvent
aHelpEvent( aMousePos
, HelpEventMode::CONTEXT
);
1061 pChild
->RequestHelp( aHelpEvent
);
1066 else if ( aKeyCode
.IsShift() )
1068 if ( pSVData
->maHelpData
.mbExtHelp
)
1069 Help::StartExtHelp();
1076 if ( ImplCallHotKey( aKeyCode
) )
1085 if ( !bKeyPreNotify
&& pChild
->ImplGetWindowImpl()->mbKeyUp
)
1089 // #105591# send keyinput to parent if we are a floating window and the key was not processed yet
1090 if( !bRet
&& pWindow
->ImplGetWindowImpl()->mbFloatWin
&& pWindow
->GetParent() && (pWindow
->ImplGetWindowImpl()->mpFrame
!= pWindow
->GetParent()->ImplGetWindowImpl()->mpFrame
) )
1092 pChild
= pWindow
->GetParent();
1095 KeyEvent
aKEvt( (sal_Unicode
)nCharCode
, aKeyCode
, nRepeat
);
1096 NotifyEvent
aNEvt( nSVEvent
, pChild
, &aKEvt
);
1097 bool bPreNotify
= ImplCallPreNotify( aNEvt
);
1098 if ( pChild
->IsDisposed() )
1103 if ( nSVEvent
== MouseNotifyEvent::KEYINPUT
)
1105 pChild
->ImplGetWindowImpl()->mbKeyInput
= false;
1106 pChild
->KeyInput( aKEvt
);
1110 pChild
->ImplGetWindowImpl()->mbKeyUp
= false;
1111 pChild
->KeyUp( aKEvt
);
1114 if( !pChild
->IsDisposed() )
1115 aNEvt
.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNEvt
);
1116 if ( pChild
->IsDisposed() )
1120 if( bPreNotify
|| !pChild
->ImplGetWindowImpl()->mbKeyInput
)
1127 static bool ImplHandleExtTextInput( vcl::Window
* pWindow
,
1128 const OUString
& rText
,
1129 const ExtTextInputAttr
* pTextAttr
,
1130 sal_Int32 nCursorPos
, sal_uInt16 nCursorFlags
)
1132 ImplSVData
* pSVData
= ImplGetSVData();
1133 vcl::Window
* pChild
= nullptr;
1138 pChild
= pSVData
->maWinData
.mpExtTextInputWin
;
1141 pChild
= ImplGetKeyInputWindow( pWindow
);
1145 if( !pChild
->ImplGetWindowImpl()->mpFrameData
->mnFocusId
)
1147 Application::Yield();
1150 // If it is the first ExtTextInput call, we inform the information
1151 // and allocate the data, which we must store in this mode
1152 ImplWinData
* pWinData
= pChild
->ImplGetWinData();
1153 if ( !pChild
->ImplGetWindowImpl()->mbExtTextInput
)
1155 pChild
->ImplGetWindowImpl()->mbExtTextInput
= true;
1156 pWinData
->mpExtOldText
= new OUString
;
1157 if ( pWinData
->mpExtOldAttrAry
)
1159 delete [] pWinData
->mpExtOldAttrAry
;
1160 pWinData
->mpExtOldAttrAry
= nullptr;
1162 pSVData
->maWinData
.mpExtTextInputWin
= pChild
;
1163 ImplCallCommand( pChild
, CommandEventId::StartExtTextInput
);
1166 // be aware of being recursively called in StartExtTextInput
1167 if ( !pChild
->ImplGetWindowImpl()->mbExtTextInput
)
1171 bool bOnlyCursor
= false;
1172 sal_Int32 nMinLen
= std::min( pWinData
->mpExtOldText
->getLength(), rText
.getLength() );
1173 sal_Int32 nDeltaStart
= 0;
1174 while ( nDeltaStart
< nMinLen
)
1176 if ( (*pWinData
->mpExtOldText
)[nDeltaStart
] != rText
[nDeltaStart
] )
1180 if ( pWinData
->mpExtOldAttrAry
|| pTextAttr
)
1182 if ( !pWinData
->mpExtOldAttrAry
|| !pTextAttr
)
1187 while ( i
< nDeltaStart
)
1189 if ( pWinData
->mpExtOldAttrAry
[i
] != pTextAttr
[i
] )
1198 if ( (nDeltaStart
>= nMinLen
) &&
1199 (pWinData
->mpExtOldText
->getLength() == rText
.getLength()) )
1202 // Call Event and store the information
1203 CommandExtTextInputData
aData( rText
, pTextAttr
,
1204 nCursorPos
, nCursorFlags
,
1206 *pWinData
->mpExtOldText
= rText
;
1207 if ( pWinData
->mpExtOldAttrAry
)
1209 delete [] pWinData
->mpExtOldAttrAry
;
1210 pWinData
->mpExtOldAttrAry
= nullptr;
1214 pWinData
->mpExtOldAttrAry
= new ExtTextInputAttr
[rText
.getLength()];
1215 memcpy( pWinData
->mpExtOldAttrAry
, pTextAttr
, rText
.getLength()*sizeof( ExtTextInputAttr
) );
1217 return !ImplCallCommand( pChild
, CommandEventId::ExtTextInput
, &aData
);
1220 static bool ImplHandleEndExtTextInput( vcl::Window
* /* pWindow */ )
1222 ImplSVData
* pSVData
= ImplGetSVData();
1223 vcl::Window
* pChild
= pSVData
->maWinData
.mpExtTextInputWin
;
1228 pChild
->ImplGetWindowImpl()->mbExtTextInput
= false;
1229 pSVData
->maWinData
.mpExtTextInputWin
= nullptr;
1230 ImplWinData
* pWinData
= pChild
->ImplGetWinData();
1231 if ( pWinData
->mpExtOldText
)
1233 delete pWinData
->mpExtOldText
;
1234 pWinData
->mpExtOldText
= nullptr;
1236 if ( pWinData
->mpExtOldAttrAry
)
1238 delete [] pWinData
->mpExtOldAttrAry
;
1239 pWinData
->mpExtOldAttrAry
= nullptr;
1241 bRet
= !ImplCallCommand( pChild
, CommandEventId::EndExtTextInput
);
1247 static void ImplHandleExtTextInputPos( vcl::Window
* pWindow
,
1248 Rectangle
& rRect
, long& rInputWidth
,
1251 ImplSVData
* pSVData
= ImplGetSVData();
1252 vcl::Window
* pChild
= pSVData
->maWinData
.mpExtTextInputWin
;
1255 pChild
= ImplGetKeyInputWindow( pWindow
);
1258 // Test, if the Window is related to the frame
1259 if ( !pWindow
->ImplIsWindowOrChild( pChild
) )
1260 pChild
= ImplGetKeyInputWindow( pWindow
);
1265 const OutputDevice
*pChildOutDev
= pChild
->GetOutDev();
1266 ImplCallCommand( pChild
, CommandEventId::CursorPos
);
1267 const Rectangle
* pRect
= pChild
->GetCursorRect();
1269 rRect
= pChildOutDev
->ImplLogicToDevicePixel( *pRect
);
1272 vcl::Cursor
* pCursor
= pChild
->GetCursor();
1275 Point aPos
= pChildOutDev
->ImplLogicToDevicePixel( pCursor
->GetPos() );
1276 Size aSize
= pChild
->LogicToPixel( pCursor
->GetSize() );
1277 if ( !aSize
.Width() )
1278 aSize
.Width() = pChild
->GetSettings().GetStyleSettings().GetCursorSize();
1279 rRect
= Rectangle( aPos
, aSize
);
1282 rRect
= Rectangle( Point( pChild
->GetOutOffXPixel(), pChild
->GetOutOffYPixel() ), Size() );
1284 rInputWidth
= pChild
->ImplLogicWidthToDevicePixel( pChild
->GetCursorExtTextInputWidth() );
1286 rInputWidth
= rRect
.GetWidth();
1288 if (pVertical
!= nullptr)
1290 = pChild
!= nullptr && pChild
->GetInputContext().GetFont().IsVertical();
1293 static bool ImplHandleInputContextChange( vcl::Window
* pWindow
, LanguageType eNewLang
)
1295 vcl::Window
* pChild
= ImplGetKeyInputWindow( pWindow
);
1296 CommandInputContextData
aData( eNewLang
);
1297 return !ImplCallCommand( pChild
, CommandEventId::InputContextChange
, &aData
);
1300 static bool ImplCallWheelCommand( const VclPtr
<vcl::Window
>& pWindow
, const Point
& rPos
,
1301 const CommandWheelData
* pWheelData
)
1303 Point aCmdMousePos
= pWindow
->ImplFrameToOutput( rPos
);
1304 CommandEvent
aCEvt( aCmdMousePos
, CommandEventId::Wheel
, true, pWheelData
);
1305 NotifyEvent
aNCmdEvt( MouseNotifyEvent::COMMAND
, pWindow
, &aCEvt
);
1306 bool bPreNotify
= ImplCallPreNotify( aNCmdEvt
);
1307 if ( pWindow
->IsDisposed() )
1311 pWindow
->ImplGetWindowImpl()->mbCommand
= false;
1312 pWindow
->Command( aCEvt
);
1313 if ( pWindow
->IsDisposed() )
1315 if ( pWindow
->ImplGetWindowImpl()->mbCommand
)
1321 static bool acceptableWheelScrollTarget(const vcl::Window
*pMouseWindow
)
1323 return (pMouseWindow
&& !pMouseWindow
->isDisposed() && pMouseWindow
->IsInputEnabled() && !pMouseWindow
->IsInModalMode());
1326 //If the last event at the same absolute screen position was handled by a
1327 //different window then reuse that window if the event occurs within 1/2 a
1328 //second, i.e. so scrolling down something like the calc sidebar that contains
1329 //widgets that respond to wheel events will continue to send the event to the
1330 //scrolling widget in favour of the widget that happens to end up under the
1332 static bool shouldReusePreviousMouseWindow(const SalWheelMouseEvent
& rPrevEvt
, const SalWheelMouseEvent
& rEvt
)
1334 return (rEvt
.mnX
== rPrevEvt
.mnX
&& rEvt
.mnY
== rPrevEvt
.mnY
&& rEvt
.mnTime
-rPrevEvt
.mnTime
< 500/*ms*/);
1337 class HandleGestureEventBase
1340 ImplSVData
* m_pSVData
;
1341 VclPtr
<vcl::Window
> m_pWindow
;
1345 HandleGestureEventBase(vcl::Window
*pWindow
, const Point
&rMousePos
)
1346 : m_pSVData(ImplGetSVData())
1347 , m_pWindow(pWindow
)
1348 , m_aMousePos(rMousePos
)
1352 vcl::Window
* FindTarget();
1353 vcl::Window
* Dispatch(vcl::Window
* pTarget
);
1354 virtual bool CallCommand(vcl::Window
*pWindow
, const Point
&rMousePos
) = 0;
1355 virtual ~HandleGestureEventBase() {}
1358 bool HandleGestureEventBase::Setup()
1361 if (m_pSVData
->maWinData
.mpAutoScrollWin
)
1362 m_pSVData
->maWinData
.mpAutoScrollWin
->EndAutoScroll();
1363 if (m_pSVData
->maHelpData
.mpHelpWin
)
1364 ImplDestroyHelpWindow( true );
1365 if (m_pWindow
->IsDisposed())
1370 vcl::Window
* HandleGestureEventBase::FindTarget()
1372 // first check any floating window ( eg. drop down listboxes)
1373 vcl::Window
*pMouseWindow
= nullptr;
1375 if (m_pSVData
->maWinData
.mpFirstFloat
&& !m_pSVData
->maWinData
.mpCaptureWin
&&
1376 !m_pSVData
->maWinData
.mpFirstFloat
->ImplIsFloatPopupModeWindow( m_pWindow
) )
1378 HitTest nHitTest
= HITTEST_OUTSIDE
;
1379 pMouseWindow
= m_pSVData
->maWinData
.mpFirstFloat
->ImplFloatHitTest( m_pWindow
, m_aMousePos
, nHitTest
);
1381 pMouseWindow
= m_pSVData
->maWinData
.mpFirstFloat
;
1383 // then try the window directly beneath the mouse
1386 pMouseWindow
= m_pWindow
->ImplFindWindow( m_aMousePos
);
1390 // transform coordinates to float window frame coordinates
1391 pMouseWindow
= pMouseWindow
->ImplFindWindow(
1392 pMouseWindow
->OutputToScreenPixel(
1393 pMouseWindow
->AbsoluteScreenToOutputPixel(
1394 m_pWindow
->OutputToAbsoluteScreenPixel(
1395 m_pWindow
->ScreenToOutputPixel( m_aMousePos
) ) ) ) );
1398 while (acceptableWheelScrollTarget(pMouseWindow
))
1400 if (pMouseWindow
->IsEnabled())
1402 //try the parent if this one is disabled
1403 pMouseWindow
= pMouseWindow
->GetParent();
1406 return pMouseWindow
;
1409 vcl::Window
*HandleGestureEventBase::Dispatch(vcl::Window
* pMouseWindow
)
1411 vcl::Window
*pDispatchedTo
= nullptr;
1413 if (acceptableWheelScrollTarget(pMouseWindow
) && pMouseWindow
->IsEnabled())
1415 // transform coordinates to float window frame coordinates
1416 Point
aRelMousePos( pMouseWindow
->OutputToScreenPixel(
1417 pMouseWindow
->AbsoluteScreenToOutputPixel(
1418 m_pWindow
->OutputToAbsoluteScreenPixel(
1419 m_pWindow
->ScreenToOutputPixel( m_aMousePos
) ) ) ) );
1420 bool bPropogate
= CallCommand(pMouseWindow
, aRelMousePos
);
1422 pDispatchedTo
= pMouseWindow
;
1425 // if the command was not handled try the focus window
1428 vcl::Window
* pFocusWindow
= m_pWindow
->ImplGetWindowImpl()->mpFrameData
->mpFocusWin
;
1429 if ( pFocusWindow
&& (pFocusWindow
!= pMouseWindow
) &&
1430 (pFocusWindow
== m_pSVData
->maWinData
.mpFocusWin
) )
1432 // no wheel-messages to disabled windows
1433 if ( pFocusWindow
->IsEnabled() && pFocusWindow
->IsInputEnabled() && ! pFocusWindow
->IsInModalMode() )
1435 // transform coordinates to focus window frame coordinates
1436 Point
aRelMousePos( pFocusWindow
->OutputToScreenPixel(
1437 pFocusWindow
->AbsoluteScreenToOutputPixel(
1438 m_pWindow
->OutputToAbsoluteScreenPixel(
1439 m_pWindow
->ScreenToOutputPixel( m_aMousePos
) ) ) ) );
1440 bool bPropogate
= CallCommand(pFocusWindow
, aRelMousePos
);
1442 pDispatchedTo
= pMouseWindow
;
1446 return pDispatchedTo
;
1449 class HandleWheelEvent
: public HandleGestureEventBase
1452 CommandWheelData m_aWheelData
;
1454 HandleWheelEvent(vcl::Window
*pWindow
, const SalWheelMouseEvent
& rEvt
, bool bScaleDirectly
)
1455 : HandleGestureEventBase(pWindow
, Point(rEvt
.mnX
, rEvt
.mnY
))
1457 CommandWheelMode nMode
;
1458 sal_uInt16 nCode
= rEvt
.mnCode
;
1459 bool bHorz
= rEvt
.mbHorz
;
1460 bool bPixel
= rEvt
.mbDeltaIsPixel
;
1462 nMode
= CommandWheelMode::ZOOM_SCALE
;
1463 else if ( nCode
& KEY_MOD1
)
1464 nMode
= CommandWheelMode::ZOOM
;
1465 else if ( nCode
& KEY_MOD2
)
1466 nMode
= CommandWheelMode::DATAZOOM
;
1469 nMode
= CommandWheelMode::SCROLL
;
1470 // #i85450# interpret shift-wheel as horizontal wheel action
1471 if( (nCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
| KEY_MOD3
)) == KEY_SHIFT
)
1475 m_aWheelData
= CommandWheelData(rEvt
.mnDelta
, rEvt
.mnNotchDelta
, rEvt
.mnScrollLines
, nMode
, nCode
, bHorz
, bPixel
);
1478 virtual bool CallCommand(vcl::Window
*pWindow
, const Point
&rMousePos
) override
1480 return ImplCallWheelCommand(pWindow
, rMousePos
, &m_aWheelData
);
1482 bool HandleEvent(const SalWheelMouseEvent
& rEvt
);
1485 bool HandleWheelEvent::HandleEvent(const SalWheelMouseEvent
& rEvt
)
1490 VclPtr
<vcl::Window
> xMouseWindow
= FindTarget();
1492 ImplSVData
* pSVData
= ImplGetSVData();
1494 // avoid the problem that scrolling via wheel to this point brings a widget
1495 // under the mouse that also accepts wheel commands, so stick with the old
1496 // widget if the time gap is very small
1497 if (shouldReusePreviousMouseWindow(pSVData
->maWinData
.maLastWheelEvent
, rEvt
) &&
1498 acceptableWheelScrollTarget(pSVData
->maWinData
.mpLastWheelWindow
))
1500 xMouseWindow
= pSVData
->maWinData
.mpLastWheelWindow
;
1503 pSVData
->maWinData
.maLastWheelEvent
= rEvt
;
1505 pSVData
->maWinData
.mpLastWheelWindow
= Dispatch(xMouseWindow
);
1507 return pSVData
->maWinData
.mpLastWheelWindow
.get();
1510 class HandleGestureEvent
: public HandleGestureEventBase
1513 HandleGestureEvent(vcl::Window
*pWindow
, const Point
&rMousePos
)
1514 : HandleGestureEventBase(pWindow
, rMousePos
)
1520 bool HandleGestureEvent::HandleEvent()
1525 vcl::Window
*pTarget
= FindTarget();
1527 bool bHandled
= Dispatch(pTarget
) != nullptr;
1531 static bool ImplHandleWheelEvent( vcl::Window
* pWindow
, const SalWheelMouseEvent
& rEvt
, bool scaleDirectly
= false )
1533 HandleWheelEvent
aHandler(pWindow
, rEvt
, scaleDirectly
);
1534 return aHandler
.HandleEvent(rEvt
);
1537 class HandleSwipeEvent
: public HandleGestureEvent
1540 CommandSwipeData m_aSwipeData
;
1542 HandleSwipeEvent(vcl::Window
*pWindow
, const SalSwipeEvent
& rEvt
)
1543 : HandleGestureEvent(pWindow
, Point(rEvt
.mnX
, rEvt
.mnY
))
1545 m_aSwipeData
= CommandSwipeData(rEvt
.mnVelocityX
);
1547 virtual bool CallCommand(vcl::Window
*pWindow
, const Point
&/*rMousePos*/) override
1549 return ImplCallCommand(pWindow
, CommandEventId::Swipe
, &m_aSwipeData
);
1553 static bool ImplHandleSwipe(vcl::Window
*pWindow
, const SalSwipeEvent
& rEvt
)
1555 HandleSwipeEvent
aHandler(pWindow
, rEvt
);
1556 return aHandler
.HandleEvent();
1559 class HandleLongPressEvent
: public HandleGestureEvent
1562 CommandLongPressData m_aLongPressData
;
1564 HandleLongPressEvent(vcl::Window
*pWindow
, const SalLongPressEvent
& rEvt
)
1565 : HandleGestureEvent(pWindow
, Point(rEvt
.mnX
, rEvt
.mnY
))
1567 m_aLongPressData
= CommandLongPressData(rEvt
.mnX
, rEvt
.mnY
);
1569 virtual bool CallCommand(vcl::Window
*pWindow
, const Point
&/*rMousePos*/) override
1571 return ImplCallCommand(pWindow
, CommandEventId::LongPress
, &m_aLongPressData
);
1575 static bool ImplHandleLongPress(vcl::Window
*pWindow
, const SalLongPressEvent
& rEvt
)
1577 HandleLongPressEvent
aHandler(pWindow
, rEvt
);
1578 return aHandler
.HandleEvent();
1581 #define IMPL_PAINT_CHECKRTL ((sal_uInt16)0x0020)
1583 static void ImplHandlePaint( vcl::Window
* pWindow
, const Rectangle
& rBoundRect
, bool bImmediateUpdate
)
1585 // system paint events must be checked for re-mirroring
1586 pWindow
->ImplGetWindowImpl()->mnPaintFlags
|= IMPL_PAINT_CHECKRTL
;
1588 // trigger paint for all windows that live in the new paint region
1589 vcl::Region
aRegion( rBoundRect
);
1590 pWindow
->ImplInvalidateOverlapFrameRegion( aRegion
);
1591 if( bImmediateUpdate
)
1593 // #i87663# trigger possible pending resize notifications
1594 // (GetSizePixel does that for us)
1595 pWindow
->GetSizePixel();
1596 // force drawing immediately
1601 static void KillOwnPopups( vcl::Window
* pWindow
)
1603 ImplSVData
* pSVData
= ImplGetSVData();
1604 vcl::Window
*pParent
= pWindow
->ImplGetWindowImpl()->mpFrameWindow
;
1605 vcl::Window
*pChild
= pSVData
->maWinData
.mpFirstFloat
;
1606 if ( pChild
&& pParent
->ImplIsWindowOrChild( pChild
, true ) )
1608 if ( !(pSVData
->maWinData
.mpFirstFloat
->GetPopupModeFlags() & FloatWinPopupFlags::NoAppFocusClose
) )
1609 pSVData
->maWinData
.mpFirstFloat
->EndPopupMode( FloatWinPopupEndFlags::Cancel
| FloatWinPopupEndFlags::CloseAll
);
1613 void ImplHandleResize( vcl::Window
* pWindow
, long nNewWidth
, long nNewHeight
)
1615 if( pWindow
->GetStyle() & (WB_MOVEABLE
|WB_SIZEABLE
) )
1617 KillOwnPopups( pWindow
);
1618 if( pWindow
->ImplGetWindow() != ImplGetSVData()->maHelpData
.mpHelpWin
)
1619 ImplDestroyHelpWindow( true );
1623 (nNewWidth
> 0 && nNewHeight
> 0) ||
1624 pWindow
->ImplGetWindow()->ImplGetWindowImpl()->mbAllResize
1627 if ( (nNewWidth
!= pWindow
->GetOutputWidthPixel()) || (nNewHeight
!= pWindow
->GetOutputHeightPixel()) )
1629 pWindow
->mnOutWidth
= nNewWidth
;
1630 pWindow
->mnOutHeight
= nNewHeight
;
1631 pWindow
->ImplGetWindowImpl()->mbWaitSystemResize
= false;
1632 if ( pWindow
->IsReallyVisible() )
1633 pWindow
->ImplSetClipFlag();
1634 if ( pWindow
->IsVisible() || pWindow
->ImplGetWindow()->ImplGetWindowImpl()->mbAllResize
||
1635 ( pWindow
->ImplGetWindowImpl()->mbFrame
&& pWindow
->ImplGetWindowImpl()->mpClientWindow
) ) // propagate resize for system border windows
1637 bool bStartTimer
= true;
1638 // use resize buffering for user resizes
1639 // ownerdraw decorated windows and floating windows can be resized immediately (i.e. synchronously)
1640 if( pWindow
->ImplGetWindowImpl()->mbFrame
&& (pWindow
->GetStyle() & WB_SIZEABLE
)
1641 && !(pWindow
->GetStyle() & WB_OWNERDRAWDECORATION
) // synchronous resize for ownerdraw decorated windows (toolbars)
1642 && !pWindow
->ImplGetWindowImpl()->mbFloatWin
) // synchronous resize for floating windows, #i43799#
1644 if( pWindow
->ImplGetWindowImpl()->mpClientWindow
)
1646 // #i42750# presentation wants to be informed about resize
1647 // as early as possible
1648 WorkWindow
* pWorkWindow
= dynamic_cast<WorkWindow
*>(pWindow
->ImplGetWindowImpl()->mpClientWindow
.get());
1649 if( ! pWorkWindow
|| pWorkWindow
->IsPresentationMode() )
1650 bStartTimer
= false;
1654 WorkWindow
* pWorkWindow
= dynamic_cast<WorkWindow
*>(pWindow
);
1655 if( ! pWorkWindow
|| pWorkWindow
->IsPresentationMode() )
1656 bStartTimer
= false;
1660 bStartTimer
= false;
1663 pWindow
->ImplGetWindowImpl()->mpFrameData
->maResizeIdle
.Start();
1665 pWindow
->ImplCallResize(); // otherwise menus cannot be positioned
1668 pWindow
->ImplGetWindowImpl()->mbCallResize
= true;
1670 if (pWindow
->SupportsDoubleBuffering() && pWindow
->ImplGetWindowImpl()->mbFrame
)
1672 // Propagate resize for the frame's buffer.
1673 pWindow
->ImplGetWindowImpl()->mpFrameData
->mpBuffer
->SetOutputSizePixel(pWindow
->GetOutputSizePixel());
1678 pWindow
->ImplGetWindowImpl()->mpFrameData
->mbNeedSysWindow
= (nNewWidth
< IMPL_MIN_NEEDSYSWIN
) ||
1679 (nNewHeight
< IMPL_MIN_NEEDSYSWIN
);
1680 bool bMinimized
= (nNewWidth
<= 0) || (nNewHeight
<= 0);
1681 if( bMinimized
!= pWindow
->ImplGetWindowImpl()->mpFrameData
->mbMinimized
)
1682 pWindow
->ImplGetWindowImpl()->mpFrameWindow
->ImplNotifyIconifiedState( bMinimized
);
1683 pWindow
->ImplGetWindowImpl()->mpFrameData
->mbMinimized
= bMinimized
;
1686 static void ImplHandleMove( vcl::Window
* pWindow
)
1688 if( pWindow
->ImplGetWindowImpl()->mbFrame
&& pWindow
->ImplIsFloatingWindow() && pWindow
->IsReallyVisible() )
1690 static_cast<FloatingWindow
*>(pWindow
)->EndPopupMode( FloatWinPopupEndFlags::TearOff
);
1691 pWindow
->ImplCallMove();
1694 if( pWindow
->GetStyle() & (WB_MOVEABLE
|WB_SIZEABLE
) )
1696 KillOwnPopups( pWindow
);
1697 if( pWindow
->ImplGetWindow() != ImplGetSVData()->maHelpData
.mpHelpWin
)
1698 ImplDestroyHelpWindow( true );
1701 if ( pWindow
->IsVisible() )
1702 pWindow
->ImplCallMove();
1704 pWindow
->ImplGetWindowImpl()->mbCallMove
= true; // make sure the framepos will be updated on the next Show()
1706 if ( pWindow
->ImplGetWindowImpl()->mbFrame
&& pWindow
->ImplGetWindowImpl()->mpClientWindow
)
1707 pWindow
->ImplGetWindowImpl()->mpClientWindow
->ImplCallMove(); // notify client to update geometry
1711 static void ImplHandleMoveResize( vcl::Window
* pWindow
, long nNewWidth
, long nNewHeight
)
1713 ImplHandleMove( pWindow
);
1714 ImplHandleResize( pWindow
, nNewWidth
, nNewHeight
);
1717 static void ImplActivateFloatingWindows( vcl::Window
* pWindow
, bool bActive
)
1719 // First check all overlapping windows
1720 vcl::Window
* pTempWindow
= pWindow
->ImplGetWindowImpl()->mpFirstOverlap
;
1721 while ( pTempWindow
)
1723 if ( pTempWindow
->GetActivateMode() == ActivateModeFlags::NONE
)
1725 if ( (pTempWindow
->GetType() == WINDOW_BORDERWINDOW
) &&
1726 (pTempWindow
->ImplGetWindow()->GetType() == WINDOW_FLOATINGWINDOW
) )
1727 static_cast<ImplBorderWindow
*>(pTempWindow
)->SetDisplayActive( bActive
);
1730 ImplActivateFloatingWindows( pTempWindow
, bActive
);
1731 pTempWindow
= pTempWindow
->ImplGetWindowImpl()->mpNext
;
1735 IMPL_LINK_NOARG(vcl::Window
, ImplAsyncFocusHdl
, void*, void)
1737 ImplGetWindowImpl()->mpFrameData
->mnFocusId
= nullptr;
1739 // If the status has been preserved, because we got back the focus
1740 // in the meantime, we do nothing
1741 bool bHasFocus
= ImplGetWindowImpl()->mpFrameData
->mbHasFocus
|| ImplGetWindowImpl()->mpFrameData
->mbSysObjFocus
;
1743 // next execute the delayed functions
1746 // redraw all floating windows inactive
1747 if ( ImplGetWindowImpl()->mpFrameData
->mbStartFocusState
!= bHasFocus
)
1748 ImplActivateFloatingWindows( this, bHasFocus
);
1750 if ( ImplGetWindowImpl()->mpFrameData
->mpFocusWin
)
1752 bool bHandled
= false;
1753 if ( ImplGetWindowImpl()->mpFrameData
->mpFocusWin
->IsInputEnabled() &&
1754 ! ImplGetWindowImpl()->mpFrameData
->mpFocusWin
->IsInModalMode() )
1756 if ( ImplGetWindowImpl()->mpFrameData
->mpFocusWin
->IsEnabled() )
1758 ImplGetWindowImpl()->mpFrameData
->mpFocusWin
->GrabFocus();
1761 else if( ImplGetWindowImpl()->mpFrameData
->mpFocusWin
->ImplHasDlgCtrl() )
1763 // #109094# if the focus is restored to a disabled dialog control (was disabled meanwhile)
1764 // try to move it to the next control
1765 ImplGetWindowImpl()->mpFrameData
->mpFocusWin
->ImplDlgCtrlNextWindow();
1771 ImplSVData
* pSVData
= ImplGetSVData();
1772 vcl::Window
* pTopLevelWindow
= ImplGetWindowImpl()->mpFrameData
->mpFocusWin
->ImplGetFirstOverlapWindow();
1773 if ( ( ! pTopLevelWindow
->IsInputEnabled() || pTopLevelWindow
->IsInModalMode() )
1774 && pSVData
->maWinData
.mpLastExecuteDlg
)
1775 pSVData
->maWinData
.mpLastExecuteDlg
->ToTop( ToTopFlags::RestoreWhenMin
| ToTopFlags::GrabFocusOnly
);
1777 pTopLevelWindow
->GrabFocus();
1785 vcl::Window
* pFocusWin
= ImplGetWindowImpl()->mpFrameData
->mpFocusWin
;
1788 ImplSVData
* pSVData
= ImplGetSVData();
1790 if ( pSVData
->maWinData
.mpFocusWin
== pFocusWin
)
1792 // transfer the FocusWindow
1793 vcl::Window
* pOverlapWindow
= pFocusWin
->ImplGetFirstOverlapWindow();
1794 pOverlapWindow
->ImplGetWindowImpl()->mpLastFocusWindow
= pFocusWin
;
1795 pSVData
->maWinData
.mpFocusWin
= nullptr;
1797 if ( pFocusWin
->ImplGetWindowImpl()->mpCursor
)
1798 pFocusWin
->ImplGetWindowImpl()->mpCursor
->ImplHide();
1800 // call the Deactivate
1801 vcl::Window
* pOldFocusWindow
= pFocusWin
;
1802 if ( pOldFocusWindow
)
1804 vcl::Window
* pOldOverlapWindow
= pOldFocusWindow
->ImplGetFirstOverlapWindow();
1805 vcl::Window
* pOldRealWindow
= pOldOverlapWindow
->ImplGetWindow();
1807 pOldOverlapWindow
->ImplGetWindowImpl()->mbActive
= false;
1808 pOldOverlapWindow
->Deactivate();
1809 if ( pOldRealWindow
!= pOldOverlapWindow
)
1811 pOldRealWindow
->ImplGetWindowImpl()->mbActive
= false;
1812 pOldRealWindow
->Deactivate();
1816 // TrackingMode is ended in ImplHandleLoseFocus
1818 // To avoid problems with the Unix IME
1819 pFocusWin
->EndExtTextInput();
1822 NotifyEvent
aNEvt(MouseNotifyEvent::LOSEFOCUS
, pFocusWin
);
1823 if (!ImplCallPreNotify(aNEvt
))
1824 pFocusWin
->CompatLoseFocus();
1825 pFocusWin
->ImplCallDeactivateListeners(nullptr);
1829 // Redraw all floating window inactive
1830 if ( ImplGetWindowImpl()->mpFrameData
->mbStartFocusState
!= bHasFocus
)
1831 ImplActivateFloatingWindows( this, bHasFocus
);
1835 static void ImplHandleGetFocus( vcl::Window
* pWindow
)
1837 pWindow
->ImplGetWindowImpl()->mpFrameData
->mbHasFocus
= true;
1839 // execute Focus-Events after a delay, such that SystemChildWindows
1840 // do not blink when they receive focus
1841 if ( !pWindow
->ImplGetWindowImpl()->mpFrameData
->mnFocusId
)
1843 pWindow
->ImplGetWindowImpl()->mpFrameData
->mbStartFocusState
= !pWindow
->ImplGetWindowImpl()->mpFrameData
->mbHasFocus
;
1844 pWindow
->ImplGetWindowImpl()->mpFrameData
->mnFocusId
= Application::PostUserEvent( LINK( pWindow
, vcl::Window
, ImplAsyncFocusHdl
), nullptr, true);
1845 vcl::Window
* pFocusWin
= pWindow
->ImplGetWindowImpl()->mpFrameData
->mpFocusWin
;
1846 if ( pFocusWin
&& pFocusWin
->ImplGetWindowImpl()->mpCursor
)
1847 pFocusWin
->ImplGetWindowImpl()->mpCursor
->ImplShow();
1851 static void ImplHandleLoseFocus( vcl::Window
* pWindow
)
1853 ImplSVData
* pSVData
= ImplGetSVData();
1855 // Abort the autoscroll if the frame loses focus
1856 if ( pSVData
->maWinData
.mpAutoScrollWin
)
1857 pSVData
->maWinData
.mpAutoScrollWin
->EndAutoScroll();
1859 // Abort tracking if the frame loses focus
1860 if ( pSVData
->maWinData
.mpTrackWin
)
1862 if ( pSVData
->maWinData
.mpTrackWin
->ImplGetWindowImpl()->mpFrameWindow
== pWindow
)
1863 pSVData
->maWinData
.mpTrackWin
->EndTracking( TrackingEventFlags::Cancel
);
1866 pWindow
->ImplGetWindowImpl()->mpFrameData
->mbHasFocus
= false;
1868 // execute Focus-Events after a delay, such that SystemChildWindows
1869 // do not flicker when they receive focus
1870 if ( !pWindow
->ImplGetWindowImpl()->mpFrameData
->mnFocusId
)
1872 pWindow
->ImplGetWindowImpl()->mpFrameData
->mbStartFocusState
= !pWindow
->ImplGetWindowImpl()->mpFrameData
->mbHasFocus
;
1873 pWindow
->ImplGetWindowImpl()->mpFrameData
->mnFocusId
= Application::PostUserEvent( LINK( pWindow
, vcl::Window
, ImplAsyncFocusHdl
), nullptr, true );
1876 vcl::Window
* pFocusWin
= pWindow
->ImplGetWindowImpl()->mpFrameData
->mpFocusWin
;
1877 if ( pFocusWin
&& pFocusWin
->ImplGetWindowImpl()->mpCursor
)
1878 pFocusWin
->ImplGetWindowImpl()->mpCursor
->ImplHide();
1881 struct DelayedCloseEvent
1883 VclPtr
<vcl::Window
> pWindow
;
1886 static void DelayedCloseEventLink( void* pCEvent
, void* )
1888 DelayedCloseEvent
* pEv
= static_cast<DelayedCloseEvent
*>(pCEvent
);
1890 if( ! pEv
->pWindow
->IsDisposed() )
1892 // dispatch to correct window type
1893 if( pEv
->pWindow
->IsSystemWindow() )
1894 static_cast<SystemWindow
*>(pEv
->pWindow
.get())->Close();
1895 else if( pEv
->pWindow
->IsDockingWindow() )
1896 static_cast<DockingWindow
*>(pEv
->pWindow
.get())->Close();
1901 void ImplHandleClose( vcl::Window
* pWindow
)
1903 ImplSVData
* pSVData
= ImplGetSVData();
1905 bool bWasPopup
= false;
1906 if( pWindow
->ImplIsFloatingWindow() &&
1907 static_cast<FloatingWindow
*>(pWindow
)->ImplIsInPrivatePopupMode() )
1912 // on Close stop all floating modes and end popups
1913 if ( pSVData
->maWinData
.mpFirstFloat
)
1915 FloatingWindow
* pLastLevelFloat
;
1916 pLastLevelFloat
= pSVData
->maWinData
.mpFirstFloat
->ImplFindLastLevelFloat();
1917 pLastLevelFloat
->EndPopupMode( FloatWinPopupEndFlags::Cancel
| FloatWinPopupEndFlags::CloseAll
);
1919 if ( pSVData
->maHelpData
.mbExtHelpMode
)
1921 if ( pSVData
->maHelpData
.mpHelpWin
)
1922 ImplDestroyHelpWindow( false );
1924 if ( pSVData
->maWinData
.mpAutoScrollWin
)
1925 pSVData
->maWinData
.mpAutoScrollWin
->EndAutoScroll();
1927 if ( pSVData
->maWinData
.mpTrackWin
)
1928 pSVData
->maWinData
.mpTrackWin
->EndTracking( TrackingEventFlags::Cancel
| TrackingEventFlags::Key
);
1933 vcl::Window
*pWin
= pWindow
->ImplGetWindow();
1934 SystemWindow
* pSysWin
= dynamic_cast<SystemWindow
*>(pWin
);
1937 // See if the custom close handler is set.
1938 const Link
<SystemWindow
&,void>& rLink
= pSysWin
->GetCloseHdl();
1941 rLink
.Call(*pSysWin
);
1946 // check whether close is allowed
1947 if ( pWin
->IsEnabled() && pWin
->IsInputEnabled() && !pWin
->IsInModalMode() )
1949 DelayedCloseEvent
* pEv
= new DelayedCloseEvent
;
1950 pEv
->pWindow
= pWin
;
1951 Application::PostUserEvent( Link
<void*,void>( pEv
, DelayedCloseEventLink
) );
1955 static void ImplHandleUserEvent( ImplSVEvent
* pSVEvent
)
1959 if ( pSVEvent
->mbCall
)
1961 pSVEvent
->maLink
.Call( pSVEvent
->mpData
);
1968 static MouseEventModifiers
ImplGetMouseMoveMode( SalMouseEvent
* pEvent
)
1970 MouseEventModifiers nMode
= MouseEventModifiers::NONE
;
1971 if ( !pEvent
->mnCode
)
1972 nMode
|= MouseEventModifiers::SIMPLEMOVE
;
1973 if ( (pEvent
->mnCode
& MOUSE_LEFT
) && !(pEvent
->mnCode
& KEY_MOD1
) )
1974 nMode
|= MouseEventModifiers::DRAGMOVE
;
1975 if ( (pEvent
->mnCode
& MOUSE_LEFT
) && (pEvent
->mnCode
& KEY_MOD1
) )
1976 nMode
|= MouseEventModifiers::DRAGCOPY
;
1980 static MouseEventModifiers
ImplGetMouseButtonMode( SalMouseEvent
* pEvent
)
1982 MouseEventModifiers nMode
= MouseEventModifiers::NONE
;
1983 if ( pEvent
->mnButton
== MOUSE_LEFT
)
1984 nMode
|= MouseEventModifiers::SIMPLECLICK
;
1985 if ( (pEvent
->mnButton
== MOUSE_LEFT
) && !(pEvent
->mnCode
& (MOUSE_MIDDLE
| MOUSE_RIGHT
)) )
1986 nMode
|= MouseEventModifiers::SELECT
;
1987 if ( (pEvent
->mnButton
== MOUSE_LEFT
) && (pEvent
->mnCode
& KEY_MOD1
) &&
1988 !(pEvent
->mnCode
& (MOUSE_MIDDLE
| MOUSE_RIGHT
| KEY_SHIFT
)) )
1989 nMode
|= MouseEventModifiers::MULTISELECT
;
1990 if ( (pEvent
->mnButton
== MOUSE_LEFT
) && (pEvent
->mnCode
& KEY_SHIFT
) &&
1991 !(pEvent
->mnCode
& (MOUSE_MIDDLE
| MOUSE_RIGHT
| KEY_MOD1
)) )
1992 nMode
|= MouseEventModifiers::RANGESELECT
;
1996 inline bool ImplHandleSalMouseLeave( vcl::Window
* pWindow
, SalMouseEvent
* pEvent
)
1998 return ImplHandleMouseEvent( pWindow
, MouseNotifyEvent::MOUSEMOVE
, true,
1999 pEvent
->mnX
, pEvent
->mnY
,
2000 pEvent
->mnTime
, pEvent
->mnCode
,
2001 ImplGetMouseMoveMode( pEvent
) );
2004 inline bool ImplHandleSalMouseMove( vcl::Window
* pWindow
, SalMouseEvent
* pEvent
)
2006 return ImplHandleMouseEvent( pWindow
, MouseNotifyEvent::MOUSEMOVE
, false,
2007 pEvent
->mnX
, pEvent
->mnY
,
2008 pEvent
->mnTime
, pEvent
->mnCode
,
2009 ImplGetMouseMoveMode( pEvent
) );
2012 inline bool ImplHandleSalMouseButtonDown( vcl::Window
* pWindow
, SalMouseEvent
* pEvent
)
2014 return ImplHandleMouseEvent( pWindow
, MouseNotifyEvent::MOUSEBUTTONDOWN
, false,
2015 pEvent
->mnX
, pEvent
->mnY
,
2018 pEvent
->mnButton
| (pEvent
->mnCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
| KEY_MOD3
)),
2020 pEvent
->mnButton
| (pEvent
->mnCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
)),
2022 ImplGetMouseButtonMode( pEvent
) );
2025 inline bool ImplHandleSalMouseButtonUp( vcl::Window
* pWindow
, SalMouseEvent
* pEvent
)
2027 return ImplHandleMouseEvent( pWindow
, MouseNotifyEvent::MOUSEBUTTONUP
, false,
2028 pEvent
->mnX
, pEvent
->mnY
,
2031 pEvent
->mnButton
| (pEvent
->mnCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
| KEY_MOD3
)),
2033 pEvent
->mnButton
| (pEvent
->mnCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
)),
2035 ImplGetMouseButtonMode( pEvent
) );
2038 static bool ImplHandleMenuEvent( vcl::Window
* pWindow
, SalMenuEvent
* pEvent
, SalEvent nEvent
)
2040 // Find SystemWindow and its Menubar and let it dispatch the command
2042 vcl::Window
*pWin
= pWindow
->ImplGetWindowImpl()->mpFirstChild
;
2045 if ( pWin
->ImplGetWindowImpl()->mbSysWin
)
2047 pWin
= pWin
->ImplGetWindowImpl()->mpNext
;
2051 MenuBar
*pMenuBar
= static_cast<SystemWindow
*>(pWin
)->GetMenuBar();
2056 case SalEvent::MenuActivate
:
2057 bRet
= pMenuBar
->HandleMenuActivateEvent( static_cast<Menu
*>(pEvent
->mpMenu
) );
2059 case SalEvent::MenuDeactivate
:
2060 bRet
= pMenuBar
->HandleMenuDeActivateEvent( static_cast<Menu
*>(pEvent
->mpMenu
) );
2062 case SalEvent::MenuHighlight
:
2063 bRet
= pMenuBar
->HandleMenuHighlightEvent( static_cast<Menu
*>(pEvent
->mpMenu
), pEvent
->mnId
);
2065 case SalEvent::MenuButtonCommand
:
2066 bRet
= pMenuBar
->HandleMenuButtonEvent( static_cast<Menu
*>(pEvent
->mpMenu
), pEvent
->mnId
);
2068 case SalEvent::MenuCommand
:
2069 bRet
= pMenuBar
->HandleMenuCommandEvent( static_cast<Menu
*>(pEvent
->mpMenu
), pEvent
->mnId
);
2079 static void ImplHandleSalKeyMod( vcl::Window
* pWindow
, SalKeyModEvent
* pEvent
)
2081 ImplSVData
* pSVData
= ImplGetSVData();
2082 vcl::Window
* pTrackWin
= pSVData
->maWinData
.mpTrackWin
;
2084 pWindow
= pTrackWin
;
2086 sal_uInt16 nOldCode
= pWindow
->ImplGetWindowImpl()->mpFrameData
->mnMouseCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
| KEY_MOD3
);
2088 sal_uInt16 nOldCode
= pWindow
->ImplGetWindowImpl()->mpFrameData
->mnMouseCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
);
2090 sal_uInt16 nNewCode
= pEvent
->mnCode
;
2091 if ( nOldCode
!= nNewCode
)
2094 nNewCode
|= pWindow
->ImplGetWindowImpl()->mpFrameData
->mnMouseCode
& ~(KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
| KEY_MOD3
);
2096 nNewCode
|= pWindow
->ImplGetWindowImpl()->mpFrameData
->mnMouseCode
& ~(KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
);
2098 pWindow
->ImplGetWindowImpl()->mpFrameWindow
->ImplCallMouseMove( nNewCode
, true );
2101 // #105224# send commandevent to allow special treatment of Ctrl-LeftShift/Ctrl-RightShift etc.
2102 // + auto-accelerator feature, tdf#92630
2105 vcl::Window
* pChild
= ImplGetKeyInputWindow( pWindow
);
2109 CommandModKeyData
data( pEvent
->mnModKeyCode
, pEvent
->mbDown
);
2110 ImplCallCommand( pChild
, CommandEventId::ModKeyChange
, &data
);
2113 static void ImplHandleInputLanguageChange( vcl::Window
* pWindow
)
2116 vcl::Window
* pChild
= ImplGetKeyInputWindow( pWindow
);
2120 ImplCallCommand( pChild
, CommandEventId::InputLanguageChange
);
2123 static void ImplHandleSalSettings( SalEvent nEvent
)
2125 Application
* pApp
= GetpApp();
2129 if ( nEvent
== SalEvent::SettingsChanged
)
2131 AllSettings aSettings
= Application::GetSettings();
2132 Application::MergeSystemSettings( aSettings
);
2133 pApp
->OverrideSystemSettings( aSettings
);
2134 Application::SetSettings( aSettings
);
2138 DataChangedEventType nType
;
2141 case SalEvent::PrinterChanged
:
2142 ImplDeletePrnQueueList();
2143 nType
= DataChangedEventType::PRINTER
;
2145 case SalEvent::DisplayChanged
:
2146 nType
= DataChangedEventType::DISPLAY
;
2148 case SalEvent::FontChanged
:
2149 OutputDevice::ImplUpdateAllFontData( true );
2150 nType
= DataChangedEventType::FONTS
;
2153 nType
= DataChangedEventType::NONE
;
2157 if ( nType
!= DataChangedEventType::NONE
)
2159 DataChangedEvent
aDCEvt( nType
);
2160 Application::NotifyAllWindows( aDCEvt
);
2165 static void ImplHandleSalExtTextInputPos( vcl::Window
* pWindow
, SalExtTextInputPosEvent
* pEvt
)
2167 Rectangle aCursorRect
;
2168 ImplHandleExtTextInputPos( pWindow
, aCursorRect
, pEvt
->mnExtWidth
, &pEvt
->mbVertical
);
2169 if ( aCursorRect
.IsEmpty() )
2174 pEvt
->mnHeight
= -1;
2178 pEvt
->mnX
= aCursorRect
.Left();
2179 pEvt
->mnY
= aCursorRect
.Top();
2180 pEvt
->mnWidth
= aCursorRect
.GetWidth();
2181 pEvt
->mnHeight
= aCursorRect
.GetHeight();
2185 static bool ImplHandleShowDialog( vcl::Window
* pWindow
, ShowDialogId nDialogId
)
2190 if( pWindow
->GetType() == WINDOW_BORDERWINDOW
)
2192 vcl::Window
* pWrkWin
= pWindow
->GetWindow( GetWindowType::Client
);
2196 CommandDialogData
aCmdData( nDialogId
);
2197 return ImplCallCommand( pWindow
, CommandEventId::ShowDialog
, &aCmdData
);
2200 static void ImplHandleSurroundingTextRequest( vcl::Window
*pWindow
,
2202 Selection
&rSelRange
)
2204 vcl::Window
* pChild
= ImplGetKeyInputWindow( pWindow
);
2209 rSelRange
.setMin( 0 );
2210 rSelRange
.setMax( 0 );
2214 rText
= pChild
->GetSurroundingText();
2215 Selection aSel
= pChild
->GetSurroundingTextSelection();
2216 rSelRange
.setMin( aSel
.Min() );
2217 rSelRange
.setMax( aSel
.Max() );
2221 static void ImplHandleSalSurroundingTextRequest( vcl::Window
*pWindow
,
2222 SalSurroundingTextRequestEvent
*pEvt
)
2224 Selection aSelRange
;
2225 ImplHandleSurroundingTextRequest( pWindow
, pEvt
->maText
, aSelRange
);
2227 aSelRange
.Justify();
2229 if( aSelRange
.Min() < 0 )
2231 else if( aSelRange
.Min() > pEvt
->maText
.getLength() )
2232 pEvt
->mnStart
= pEvt
->maText
.getLength();
2234 pEvt
->mnStart
= aSelRange
.Min();
2236 if( aSelRange
.Max() < 0 )
2238 else if( aSelRange
.Max() > pEvt
->maText
.getLength() )
2239 pEvt
->mnEnd
= pEvt
->maText
.getLength();
2241 pEvt
->mnEnd
= aSelRange
.Max();
2244 static void ImplHandleSurroundingTextSelectionChange( vcl::Window
*pWindow
,
2248 vcl::Window
* pChild
= ImplGetKeyInputWindow( pWindow
);
2251 CommandSelectionChangeData
data( nStart
, nEnd
);
2252 ImplCallCommand( pChild
, CommandEventId::SelectionChange
, &data
);
2256 static void ImplHandleStartReconversion( vcl::Window
*pWindow
)
2258 vcl::Window
* pChild
= ImplGetKeyInputWindow( pWindow
);
2260 ImplCallCommand( pChild
, CommandEventId::PrepareReconversion
);
2263 static void ImplHandleSalQueryCharPosition( vcl::Window
*pWindow
,
2264 SalQueryCharPositionEvent
*pEvt
)
2266 pEvt
->mbValid
= false;
2267 pEvt
->mbVertical
= false;
2268 pEvt
->mnCursorBoundX
= 0;
2269 pEvt
->mnCursorBoundY
= 0;
2270 pEvt
->mnCursorBoundWidth
= 0;
2271 pEvt
->mnCursorBoundHeight
= 0;
2273 ImplSVData
* pSVData
= ImplGetSVData();
2274 vcl::Window
* pChild
= pSVData
->maWinData
.mpExtTextInputWin
;
2277 pChild
= ImplGetKeyInputWindow( pWindow
);
2280 // Test, if the Window is related to the frame
2281 if ( !pWindow
->ImplIsWindowOrChild( pChild
) )
2282 pChild
= ImplGetKeyInputWindow( pWindow
);
2287 ImplCallCommand( pChild
, CommandEventId::QueryCharPosition
);
2289 ImplWinData
* pWinData
= pChild
->ImplGetWinData();
2290 if ( pWinData
->mpCompositionCharRects
&& pEvt
->mnCharPos
< static_cast<sal_uLong
>( pWinData
->mnCompositionCharRects
) )
2292 const OutputDevice
*pChildOutDev
= pChild
->GetOutDev();
2293 const Rectangle
& aRect
= pWinData
->mpCompositionCharRects
[ pEvt
->mnCharPos
];
2294 Rectangle aDeviceRect
= pChildOutDev
->ImplLogicToDevicePixel( aRect
);
2295 Point aAbsScreenPos
= pChild
->OutputToAbsoluteScreenPixel( pChild
->ScreenToOutputPixel(aDeviceRect
.TopLeft()) );
2296 pEvt
->mnCursorBoundX
= aAbsScreenPos
.X();
2297 pEvt
->mnCursorBoundY
= aAbsScreenPos
.Y();
2298 pEvt
->mnCursorBoundWidth
= aDeviceRect
.GetWidth();
2299 pEvt
->mnCursorBoundHeight
= aDeviceRect
.GetHeight();
2300 pEvt
->mbVertical
= pWinData
->mbVertical
;
2301 pEvt
->mbValid
= true;
2306 bool ImplWindowFrameProc( vcl::Window
* _pWindow
, SalEvent nEvent
, const void* pEvent
)
2308 DBG_TESTSOLARMUTEX();
2310 // Ensure the window survives during this method.
2311 VclPtr
<vcl::Window
> pWindow( _pWindow
);
2315 // #119709# for some unknown reason it is possible to receive events (in this case key events)
2316 // although the corresponding VCL window must have been destroyed already
2317 // at least ImplGetWindowImpl() was NULL in these cases, so check this here
2318 if( pWindow
->ImplGetWindowImpl() == nullptr )
2323 case SalEvent::MouseMove
:
2324 bRet
= ImplHandleSalMouseMove( pWindow
, const_cast<SalMouseEvent
*>(static_cast<SalMouseEvent
const *>(pEvent
)) );
2326 case SalEvent::ExternalMouseMove
:
2328 MouseEvent
const * pMouseEvt
= static_cast<MouseEvent
const *>(pEvent
);
2329 SalMouseEvent aSalMouseEvent
;
2331 aSalMouseEvent
.mnTime
= tools::Time::GetSystemTicks();
2332 aSalMouseEvent
.mnX
= pMouseEvt
->GetPosPixel().X();
2333 aSalMouseEvent
.mnY
= pMouseEvt
->GetPosPixel().Y();
2334 aSalMouseEvent
.mnButton
= 0;
2335 aSalMouseEvent
.mnCode
= pMouseEvt
->GetButtons() | pMouseEvt
->GetModifier();
2337 bRet
= ImplHandleSalMouseMove( pWindow
, &aSalMouseEvent
);
2340 case SalEvent::MouseLeave
:
2341 bRet
= ImplHandleSalMouseLeave( pWindow
, const_cast<SalMouseEvent
*>(static_cast<SalMouseEvent
const *>(pEvent
)) );
2343 case SalEvent::MouseButtonDown
:
2344 bRet
= ImplHandleSalMouseButtonDown( pWindow
, const_cast<SalMouseEvent
*>(static_cast<SalMouseEvent
const *>(pEvent
)) );
2346 case SalEvent::ExternalMouseButtonDown
:
2348 MouseEvent
const * pMouseEvt
= static_cast<MouseEvent
const *>(pEvent
);
2349 SalMouseEvent aSalMouseEvent
;
2351 aSalMouseEvent
.mnTime
= tools::Time::GetSystemTicks();
2352 aSalMouseEvent
.mnX
= pMouseEvt
->GetPosPixel().X();
2353 aSalMouseEvent
.mnY
= pMouseEvt
->GetPosPixel().Y();
2354 aSalMouseEvent
.mnButton
= pMouseEvt
->GetButtons();
2355 aSalMouseEvent
.mnCode
= pMouseEvt
->GetButtons() | pMouseEvt
->GetModifier();
2357 bRet
= ImplHandleSalMouseButtonDown( pWindow
, &aSalMouseEvent
);
2360 case SalEvent::MouseButtonUp
:
2361 bRet
= ImplHandleSalMouseButtonUp( pWindow
, const_cast<SalMouseEvent
*>(static_cast<SalMouseEvent
const *>(pEvent
)) );
2363 case SalEvent::ExternalMouseButtonUp
:
2365 MouseEvent
const * pMouseEvt
= static_cast<MouseEvent
const *>(pEvent
);
2366 SalMouseEvent aSalMouseEvent
;
2368 aSalMouseEvent
.mnTime
= tools::Time::GetSystemTicks();
2369 aSalMouseEvent
.mnX
= pMouseEvt
->GetPosPixel().X();
2370 aSalMouseEvent
.mnY
= pMouseEvt
->GetPosPixel().Y();
2371 aSalMouseEvent
.mnButton
= pMouseEvt
->GetButtons();
2372 aSalMouseEvent
.mnCode
= pMouseEvt
->GetButtons() | pMouseEvt
->GetModifier();
2374 bRet
= ImplHandleSalMouseButtonUp( pWindow
, &aSalMouseEvent
);
2377 case SalEvent::MouseActivate
:
2380 case SalEvent::KeyInput
:
2382 SalKeyEvent
const * pKeyEvt
= static_cast<SalKeyEvent
const *>(pEvent
);
2383 bRet
= ImplHandleKey( pWindow
, MouseNotifyEvent::KEYINPUT
,
2384 pKeyEvt
->mnCode
, pKeyEvt
->mnCharCode
, pKeyEvt
->mnRepeat
, true );
2387 case SalEvent::ExternalKeyInput
:
2389 KeyEvent
const * pKeyEvt
= static_cast<KeyEvent
const *>(pEvent
);
2390 bRet
= ImplHandleKey( pWindow
, MouseNotifyEvent::KEYINPUT
,
2391 pKeyEvt
->GetKeyCode().GetFullCode(), pKeyEvt
->GetCharCode(), pKeyEvt
->GetRepeat(), false );
2394 case SalEvent::KeyUp
:
2396 SalKeyEvent
const * pKeyEvt
= static_cast<SalKeyEvent
const *>(pEvent
);
2397 bRet
= ImplHandleKey( pWindow
, MouseNotifyEvent::KEYUP
,
2398 pKeyEvt
->mnCode
, pKeyEvt
->mnCharCode
, pKeyEvt
->mnRepeat
, true );
2401 case SalEvent::ExternalKeyUp
:
2403 KeyEvent
const * pKeyEvt
= static_cast<KeyEvent
const *>(pEvent
);
2404 bRet
= ImplHandleKey( pWindow
, MouseNotifyEvent::KEYUP
,
2405 pKeyEvt
->GetKeyCode().GetFullCode(), pKeyEvt
->GetCharCode(), pKeyEvt
->GetRepeat(), false );
2408 case SalEvent::KeyModChange
:
2409 ImplHandleSalKeyMod( pWindow
, const_cast<SalKeyModEvent
*>(static_cast<SalKeyModEvent
const *>(pEvent
)) );
2412 case SalEvent::InputLanguageChange
:
2413 ImplHandleInputLanguageChange( pWindow
);
2416 case SalEvent::MenuActivate
:
2417 case SalEvent::MenuDeactivate
:
2418 case SalEvent::MenuHighlight
:
2419 case SalEvent::MenuCommand
:
2420 case SalEvent::MenuButtonCommand
:
2421 bRet
= ImplHandleMenuEvent( pWindow
, const_cast<SalMenuEvent
*>(static_cast<SalMenuEvent
const *>(pEvent
)), nEvent
);
2424 case SalEvent::WheelMouse
:
2425 bRet
= ImplHandleWheelEvent( pWindow
, *static_cast<const SalWheelMouseEvent
*>(pEvent
));
2428 case SalEvent::Paint
:
2430 SalPaintEvent
const * pPaintEvt
= static_cast<SalPaintEvent
const *>(pEvent
);
2432 if( AllSettings::GetLayoutRTL() )
2434 // --- RTL --- (mirror paint rect)
2435 SalFrame
* pSalFrame
= pWindow
->ImplGetWindowImpl()->mpFrame
;
2436 const_cast<SalPaintEvent
*>(pPaintEvt
)->mnBoundX
= pSalFrame
->maGeometry
.nWidth
-pPaintEvt
->mnBoundWidth
-pPaintEvt
->mnBoundX
;
2439 Rectangle
aBoundRect( Point( pPaintEvt
->mnBoundX
, pPaintEvt
->mnBoundY
),
2440 Size( pPaintEvt
->mnBoundWidth
, pPaintEvt
->mnBoundHeight
) );
2441 ImplHandlePaint( pWindow
, aBoundRect
, pPaintEvt
->mbImmediateUpdate
);
2445 case SalEvent::Move
:
2446 ImplHandleMove( pWindow
);
2449 case SalEvent::Resize
:
2453 pWindow
->ImplGetWindowImpl()->mpFrame
->GetClientSize( nNewWidth
, nNewHeight
);
2454 ImplHandleResize( pWindow
, nNewWidth
, nNewHeight
);
2458 case SalEvent::MoveResize
:
2460 SalFrameGeometry g
= pWindow
->ImplGetWindowImpl()->mpFrame
->GetGeometry();
2461 ImplHandleMoveResize( pWindow
, g
.nWidth
, g
.nHeight
);
2465 case SalEvent::ClosePopups
:
2467 KillOwnPopups( pWindow
);
2471 case SalEvent::GetFocus
:
2472 ImplHandleGetFocus( pWindow
);
2474 case SalEvent::LoseFocus
:
2475 ImplHandleLoseFocus( pWindow
);
2478 case SalEvent::Close
:
2479 ImplHandleClose( pWindow
);
2482 case SalEvent::Shutdown
:
2484 static bool bInQueryExit
= false;
2487 bInQueryExit
= true;
2488 if ( GetpApp()->QueryExit() )
2490 // end the message loop
2491 Application::Quit();
2496 bInQueryExit
= false;
2503 case SalEvent::SettingsChanged
:
2504 case SalEvent::PrinterChanged
:
2505 case SalEvent::DisplayChanged
:
2506 case SalEvent::FontChanged
:
2507 ImplHandleSalSettings( nEvent
);
2510 case SalEvent::UserEvent
:
2511 ImplHandleUserEvent( const_cast<ImplSVEvent
*>(static_cast<ImplSVEvent
const *>(pEvent
)) );
2514 case SalEvent::ExtTextInput
:
2516 SalExtTextInputEvent
const * pEvt
= static_cast<SalExtTextInputEvent
const *>(pEvent
);
2517 bRet
= ImplHandleExtTextInput( pWindow
,
2518 pEvt
->maText
, pEvt
->mpTextAttr
,
2519 pEvt
->mnCursorPos
, pEvt
->mnCursorFlags
);
2522 case SalEvent::EndExtTextInput
:
2523 bRet
= ImplHandleEndExtTextInput( pWindow
);
2525 case SalEvent::ExtTextInputPos
:
2526 ImplHandleSalExtTextInputPos( pWindow
, const_cast<SalExtTextInputPosEvent
*>(static_cast<SalExtTextInputPosEvent
const *>(pEvent
)) );
2528 case SalEvent::InputContextChange
:
2529 bRet
= ImplHandleInputContextChange( pWindow
, static_cast<SalInputContextChangeEvent
const *>(pEvent
)->meLanguage
);
2531 case SalEvent::ShowDialog
:
2533 ShowDialogId nLOKWindowId
= static_cast<ShowDialogId
>(reinterpret_cast<sal_IntPtr
>(pEvent
));
2534 bRet
= ImplHandleShowDialog( pWindow
, nLOKWindowId
);
2537 case SalEvent::SurroundingTextRequest
:
2538 ImplHandleSalSurroundingTextRequest( pWindow
, const_cast<SalSurroundingTextRequestEvent
*>(static_cast<SalSurroundingTextRequestEvent
const *>(pEvent
)) );
2540 case SalEvent::SurroundingTextSelectionChange
:
2542 SalSurroundingTextSelectionChangeEvent
const * pEvt
2543 = static_cast<SalSurroundingTextSelectionChangeEvent
const *>(pEvent
);
2544 ImplHandleSurroundingTextSelectionChange( pWindow
,
2547 SAL_FALLTHROUGH
; // TODO: Fallthrough really intended?
2549 case SalEvent::StartReconversion
:
2550 ImplHandleStartReconversion( pWindow
);
2552 case SalEvent::ExternalZoom
:
2554 SalWheelMouseEvent aSalWheelMouseEvent
;
2555 aSalWheelMouseEvent
.mnTime
= tools::Time::GetSystemTicks();
2556 aSalWheelMouseEvent
.mnX
= 0;
2557 aSalWheelMouseEvent
.mnY
= 0;
2558 // Pass on the scale as a percentage * 100 of current zoom factor
2559 // so to assure zoom granularity
2560 aSalWheelMouseEvent
.mnDelta
= long(MOBILE_ZOOM_SCALE_MULTIPLIER
);
2561 // Other SalWheelMouseEvent fields ignored when the
2562 // scaleDirectly parameter to ImplHandleWheelEvent() is
2564 bRet
= ImplHandleWheelEvent( pWindow
, aSalWheelMouseEvent
, true );
2567 case SalEvent::ExternalScroll
:
2569 SalWheelMouseEvent aSalWheelMouseEvent
;
2570 aSalWheelMouseEvent
.mnTime
= tools::Time::GetSystemTicks();
2571 aSalWheelMouseEvent
.mbDeltaIsPixel
= true;
2572 // event location holds delta values instead
2573 aSalWheelMouseEvent
.mnX
= 0;
2574 aSalWheelMouseEvent
.mnY
= 0;
2575 aSalWheelMouseEvent
.mnScrollLines
= 0;
2576 if (aSalWheelMouseEvent
.mnX
!= 0 || aSalWheelMouseEvent
.mnY
!= 0)
2578 bRet
= ImplHandleWheelEvent( pWindow
, aSalWheelMouseEvent
);
2582 case SalEvent::QueryCharPosition
:
2583 ImplHandleSalQueryCharPosition( pWindow
, const_cast<SalQueryCharPositionEvent
*>(static_cast<SalQueryCharPositionEvent
const *>(pEvent
)) );
2586 case SalEvent::Swipe
:
2587 bRet
= ImplHandleSwipe(pWindow
, *static_cast<const SalSwipeEvent
*>(pEvent
));
2590 case SalEvent::LongPress
:
2591 bRet
= ImplHandleLongPress(pWindow
, *static_cast<const SalLongPressEvent
*>(pEvent
));
2596 SAL_WARN( "vcl.layout", "ImplWindowFrameProc(): unknown event (" << (int)nEvent
<< ")" );
2603 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */