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>
22 #include <sal/log.hxx>
24 #include <unotools/localedatawrapper.hxx>
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>
44 #include <salwtype.hxx>
45 #include <salframe.hxx>
49 #include <helpwin.hxx>
51 #include <dndlistenercontainer.hxx>
53 #include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
54 #include <com/sun/star/awt/MouseEvent.hpp>
56 #define IMPL_MIN_NEEDSYSWIN 49
58 bool ImplCallPreNotify( NotifyEvent
& rEvt
)
60 return rEvt
.GetWindow()->CompatPreNotify( rEvt
);
63 static bool ImplHandleMouseFloatMode( vcl::Window
* pChild
, const Point
& rMousePos
,
64 sal_uInt16 nCode
, MouseNotifyEvent nSVEvent
,
67 ImplSVData
* pSVData
= ImplGetSVData();
69 if ( pSVData
->maWinData
.mpFirstFloat
&& !pSVData
->maWinData
.mpCaptureWin
&&
70 !pSVData
->maWinData
.mpFirstFloat
->ImplIsFloatPopupModeWindow( pChild
) )
73 * #93895# since floats are system windows, coordinates have
74 * to be converted to float relative for the hittest
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
)
85 if ( !pFloat
|| bHitTestInsideRect
)
87 if ( pSVData
->maHelpData
.mpHelpWin
&& !pSVData
->maHelpData
.mbKeyboardHelp
)
88 ImplDestroyHelpWindow( true );
89 pChild
->ImplGetFrame()->SetPointer( PointerStyle::Arrow
);
95 if ( nCode
& MOUSE_LEFT
)
97 if ( nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
)
101 pLastLevelFloat
= pSVData
->maWinData
.mpFirstFloat
->ImplFindLastLevelFloat();
102 pLastLevelFloat
->EndPopupMode( FloatWinPopupEndFlags::Cancel
| FloatWinPopupEndFlags::CloseAll
);
105 else if ( bHitTestInsideRect
)
107 pFloat
->ImplSetMouseDown();
115 if ( bHitTestInsideRect
)
117 if ( pFloat
->ImplIsMouseDown() )
118 pFloat
->EndPopupMode( FloatWinPopupEndFlags::Cancel
);
124 pLastLevelFloat
= pSVData
->maWinData
.mpFirstFloat
->ImplFindLastLevelFloat();
125 nPopupFlags
= pLastLevelFloat
->GetPopupModeFlags();
126 if ( !(nPopupFlags
& FloatWinPopupFlags::NoMouseUpClose
) )
128 pLastLevelFloat
->EndPopupMode( FloatWinPopupEndFlags::Cancel
| FloatWinPopupEndFlags::CloseAll
);
138 pLastLevelFloat
= pSVData
->maWinData
.mpFirstFloat
->ImplFindLastLevelFloat();
139 nPopupFlags
= pLastLevelFloat
->GetPopupModeFlags();
140 if ( nPopupFlags
& FloatWinPopupFlags::AllMouseButtonClose
)
142 if ( (nPopupFlags
& FloatWinPopupFlags::NoMouseUpClose
) &&
143 (nSVEvent
== MouseNotifyEvent::MOUSEBUTTONUP
) )
145 pLastLevelFloat
->EndPopupMode( FloatWinPopupEndFlags::Cancel
| FloatWinPopupEndFlags::CloseAll
);
158 static void ImplHandleMouseHelpRequest( vcl::Window
* pChild
, const Point
& rMousePos
)
160 if (comphelper::LibreOfficeKit::isActive())
163 ImplSVData
* pSVData
= ImplGetSVData();
164 if ( !pSVData
->maHelpData
.mpHelpWin
||
165 !( pSVData
->maHelpData
.mpHelpWin
->IsWindowOrChild( pChild
) ||
166 pChild
->IsWindowOrChild( pSVData
->maHelpData
.mpHelpWin
) ) )
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
) )
175 if ( pChild
->IsInputEnabled() && !pChild
->IsInModalMode() )
177 HelpEvent
aHelpEvent( rMousePos
, nHelpMode
);
178 pSVData
->maHelpData
.mbRequestingHelp
= true;
179 pChild
->RequestHelp( aHelpEvent
);
180 pSVData
->maHelpData
.mbRequestingHelp
= false;
182 // #104172# do not kill keyboard activated tooltips
183 else if ( pSVData
->maHelpData
.mpHelpWin
&& !pSVData
->maHelpData
.mbKeyboardHelp
)
185 ImplDestroyHelpWindow( true );
191 static void ImplSetMousePointer( vcl::Window
const * pChild
)
193 ImplSVData
* pSVData
= ImplGetSVData();
194 if ( pSVData
->maHelpData
.mbExtHelpMode
)
195 pChild
->ImplGetFrame()->SetPointer( PointerStyle::Help
);
197 pChild
->ImplGetFrame()->SetPointer( pChild
->ImplGetMousePointer() );
200 static bool ImplCallCommand( const VclPtr
<vcl::Window
>& pChild
, CommandEventId nEvt
, void const * pData
= nullptr,
201 bool bMouse
= false, Point
const * pPos
= nullptr )
209 aPos
= pChild
->GetPointerPosPixel();
212 // simulate mouseposition at center of window
213 Size
aSize( pChild
->GetOutputSizePixel() );
214 aPos
= Point( aSize
.getWidth()/2, aSize
.getHeight()/2 );
218 CommandEvent
aCEvt( aPos
, nEvt
, bMouse
, pData
);
219 NotifyEvent
aNCmdEvt( MouseNotifyEvent::COMMAND
, pChild
, &aCEvt
);
220 bool bPreNotify
= ImplCallPreNotify( aNCmdEvt
);
221 if ( pChild
->IsDisposed() )
225 pChild
->ImplGetWindowImpl()->mbCommand
= false;
226 pChild
->Command( aCEvt
);
228 if( pChild
->IsDisposed() )
230 pChild
->ImplNotifyKeyMouseCommandEventListeners( aNCmdEvt
);
231 if ( pChild
->IsDisposed() )
233 if ( pChild
->ImplGetWindowImpl()->mbCommand
)
240 /* #i34277# delayed context menu activation;
241 * necessary if there already was a popup menu running.
244 struct ContextMenuEvent
246 VclPtr
<vcl::Window
> pWindow
;
250 static void ContextMenuEventLink( void* pCEvent
, void* )
252 ContextMenuEvent
* pEv
= static_cast<ContextMenuEvent
*>(pCEvent
);
254 if( ! pEv
->pWindow
->IsDisposed() )
256 ImplCallCommand( pEv
->pWindow
, CommandEventId::ContextMenu
, nullptr, true, &pEv
->aChildPos
);
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
)
265 ImplSVData
* pSVData
= ImplGetSVData();
266 Point
aMousePos( nX
, nY
);
267 VclPtr
<vcl::Window
> pChild
;
269 sal_uInt16
nClicks(0);
270 ImplFrameData
* pWinFrameData
= xWindow
->ImplGetFrameData();
271 sal_uInt16 nOldCode
= pWinFrameData
->mnMouseCode
;
273 // we need a mousemove event, before we get a mousebuttondown or a
274 // mousebuttonup event
275 if ( (nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
) || (nSVEvent
== MouseNotifyEvent::MOUSEBUTTONUP
) )
277 if ( (nSVEvent
== MouseNotifyEvent::MOUSEBUTTONUP
) && pSVData
->maHelpData
.mbExtHelpMode
)
279 if ( pSVData
->maHelpData
.mpHelpWin
)
281 if( xWindow
->ImplGetWindow() == pSVData
->maHelpData
.mpHelpWin
)
283 ImplDestroyHelpWindow( false );
284 return true; // xWindow is dead now - avoid crash!
287 ImplDestroyHelpWindow( true );
290 if ( (pWinFrameData
->mnLastMouseX
!= nX
) ||
291 (pWinFrameData
->mnLastMouseY
!= nY
) )
293 sal_uInt16 nMoveCode
= nCode
& ~(MOUSE_LEFT
| MOUSE_RIGHT
| MOUSE_MIDDLE
);
294 ImplHandleMouseEvent(xWindow
, MouseNotifyEvent::MOUSEMOVE
, false, nX
, nY
, nMsgTime
, nMoveCode
, nMode
);
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
;
308 pWinFrameData
->mbMouseIn
= false;
309 if ( pSVData
->maHelpData
.mpHelpWin
&& !pSVData
->maHelpData
.mbKeyboardHelp
)
311 ImplDestroyHelpWindow( true );
313 if ( xWindow
->IsDisposed() )
314 return true; // xWindow is dead now - avoid crash! (#122045#)
318 pWinFrameData
->mbMouseIn
= true;
320 DBG_ASSERT( !pSVData
->maWinData
.mpTrackWin
||
321 (pSVData
->maWinData
.mpTrackWin
== pSVData
->maWinData
.mpCaptureWin
),
322 "ImplHandleMouseEvent: TrackWin != CaptureWin" );
325 if ( pSVData
->maWinData
.mpAutoScrollWin
&& (nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
) )
327 pSVData
->maWinData
.mpAutoScrollWin
->EndAutoScroll();
332 if ( pSVData
->maWinData
.mpCaptureWin
)
334 pChild
= pSVData
->maWinData
.mpCaptureWin
;
336 SAL_WARN_IF( xWindow
!= pChild
->ImplGetFrameWindow(), "vcl",
337 "ImplHandleMouseEvent: mouse event is not sent to capture window" );
339 // java client cannot capture mouse correctly
340 if ( xWindow
!= pChild
->ImplGetFrameWindow() )
351 pChild
= xWindow
->ImplFindWindow( aMousePos
);
354 // test this because mouse events are buffered in the remote version
355 // and size may not be in sync
356 if ( !pChild
&& !bMouseLeave
)
359 // execute a few tests and catch the message or implement the status
362 if( pChild
->ImplIsAntiparallel() )
364 // re-mirror frame pos at pChild
365 const OutputDevice
*pChildWinOutDev
= pChild
->GetOutDev();
366 pChildWinOutDev
->ReMirror( aMousePos
);
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() ) )
373 ImplHandleMouseFloatMode( pChild
, aMousePos
, nCode
, nSVEvent
, bMouseLeave
);
374 if ( nSVEvent
== MouseNotifyEvent::MOUSEMOVE
)
376 ImplHandleMouseHelpRequest( pChild
, aMousePos
);
377 if( pWinFrameData
->mpMouseMoveWin
.get() != pChild
)
378 nMode
|= MouseEventModifiers::ENTERWINDOW
;
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
);
386 if( pChild
->IsCallHandlersOnInputDisabled() )
388 pWinFrameData
->mpMouseMoveWin
= pChild
;
389 pChild
->ImplNotifyKeyMouseCommandEventListeners( aNEvt
);
392 if ( nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
)
396 // Set normal MousePointer for disabled windows
397 if ( nSVEvent
== MouseNotifyEvent::MOUSEMOVE
)
398 ImplSetMousePointer( pChild
);
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();
411 // determine mouse event data
412 if ( nSVEvent
== MouseNotifyEvent::MOUSEMOVE
)
414 // check if MouseMove belongs to same window and if the
415 // status did not change
418 Point aChildMousePos
= pChild
->ImplFrameToOutput( aMousePos
);
420 (pChild
== pWinFrameData
->mpMouseMoveWin
) &&
421 (aChildMousePos
.X() == pWinFrameData
->mnLastMouseWinX
) &&
422 (aChildMousePos
.Y() == pWinFrameData
->mnLastMouseWinY
) &&
423 (nOldCode
== pWinFrameData
->mnMouseCode
) )
425 // set mouse pointer anew, as it could have changed
426 // due to the mode switch
427 ImplSetMousePointer( pChild
);
431 pWinFrameData
->mnLastMouseWinX
= aChildMousePos
.X();
432 pWinFrameData
->mnLastMouseWinY
= aChildMousePos
.Y();
436 nClicks
= pWinFrameData
->mnClickCount
;
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
;
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
)) )
451 if ( !pMouseDownWin
->ImplGetFrameData()->mbStartDragCalled
)
453 long nDragW
= rMSettings
.GetStartDragWidth();
454 long nDragH
= rMSettings
.GetStartDragHeight();
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
)) )
464 pMouseDownWin
->ImplGetFrameData()->mbStartDragCalled
= true;
466 // Check if drag source provides its own recognizer
467 if( pMouseDownWin
->ImplGetFrameData()->mbInternalDragGestureRecognizer
)
469 // query DropTarget from child window
470 css::uno::Reference
< css::datatransfer::dnd::XDragGestureRecognizer
> xDragGestureRecognizer(
471 pMouseDownWin
->ImplGetWindowImpl()->mxDNDListenerContainer
,
472 css::uno::UNO_QUERY
);
474 if( xDragGestureRecognizer
.is() )
476 // retrieve mouse position relative to mouse down window
477 Point relLoc
= pMouseDownWin
->ImplFrameToOutput( Point(
478 pMouseDownWin
->ImplGetFrameData()->mnFirstMouseX
,
479 pMouseDownWin
->ImplGetFrameData()->mnFirstMouseY
) );
481 // create a UNO mouse event out of the available data
482 css::awt::MouseEvent
aMouseEvent( static_cast < css::uno::XInterface
* > ( nullptr ),
484 nCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
| KEY_MOD3
),
486 nCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
),
488 nCode
& (MOUSE_LEFT
| MOUSE_RIGHT
| MOUSE_MIDDLE
),
494 SolarMutexReleaser aReleaser
;
496 // FIXME: where do I get Action from ?
497 css::uno::Reference
< css::datatransfer::dnd::XDragSource
> xDragSource
= pMouseDownWin
->GetDragSource();
499 if( xDragSource
.is() )
501 static_cast < DNDListenerContainer
* > ( xDragGestureRecognizer
.get() )->fireDragGestureEvent( 0,
502 relLoc
.X(), relLoc
.Y(), xDragSource
, css::uno::makeAny( aMouseEvent
) );
510 pMouseDownWin
->ImplGetFrameData()->mbStartDragCalled
= true;
513 // test for mouseleave and mouseenter
514 VclPtr
<vcl::Window
> pMouseMoveWin
= pWinFrameData
->mpMouseMoveWin
;
515 if ( pChild
!= pMouseMoveWin
)
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;
525 // A MouseLeave can destroy this window
526 if ( !ImplCallPreNotify( aNLeaveEvt
) )
528 pMouseMoveWin
->MouseMove( aMLeaveEvt
);
529 if( !pMouseMoveWin
->IsDisposed() )
530 aNLeaveEvt
.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNLeaveEvt
);
533 pWinFrameData
->mpMouseMoveWin
= nullptr;
534 pWinFrameData
->mbInMouseMove
= false;
536 if ( pChild
&& pChild
->IsDisposed() )
538 if ( pMouseMoveWin
->IsDisposed() )
542 nMode
|= MouseEventModifiers::ENTERWINDOW
;
544 pWinFrameData
->mpMouseMoveWin
= pChild
;
546 pChild
->ImplGetWinData()->mbMouseOver
= true;
557 if ( nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
)
559 const MouseSettings
& rMSettings
= pChild
->GetSettings().GetMouseSettings();
560 sal_uInt64 nDblClkTime
= rMSettings
.GetDoubleClickTime();
561 long nDblClkW
= rMSettings
.GetDoubleClickWidth();
562 long nDblClkH
= rMSettings
.GetDoubleClickHeight();
565 long nMouseX
= aMousePos
.X(); // #106074# use the possibly re-mirrored coordinates (RTL) ! nX,nY are unmodified !
566 long nMouseY
= aMousePos
.Y();
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
) )
576 pChild
->ImplGetFrameData()->mnClickCount
++;
577 pChild
->ImplGetFrameData()->mbStartDragCalled
= true;
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
));
589 pChild
->ImplGetFrameData()->mnMouseDownTime
= nMsgTime
;
591 nClicks
= pChild
->ImplGetFrameData()->mnClickCount
;
594 pSVData
->maAppData
.mnLastInputTime
= tools::Time::GetSystemTicks();
597 SAL_WARN_IF( !pChild
, "vcl", "ImplHandleMouseEvent: pChild == NULL" );
602 // create mouse event
603 Point aChildPos
= pChild
->ImplFrameToOutput( aMousePos
);
604 MouseEvent
aMEvt( aChildPos
, nClicks
, nMode
, nCode
, nCode
);
607 // tracking window gets the mouse events
608 if ( pSVData
->maWinData
.mpTrackWin
)
609 pChild
= pSVData
->maWinData
.mpTrackWin
;
611 // handle FloatingMode
612 if ( !pSVData
->maWinData
.mpTrackWin
&& pSVData
->maWinData
.mpFirstFloat
)
614 if ( ImplHandleMouseFloatMode( pChild
, aMousePos
, nCode
, nSVEvent
, bMouseLeave
) )
616 if ( !pChild
->IsDisposed() )
618 pChild
->ImplGetFrameData()->mbStartDragCalled
= true;
625 bool bCallHelpRequest
= true;
626 SAL_WARN_IF( !pChild
, "vcl", "ImplHandleMouseEvent: pChild is NULL" );
631 NotifyEvent
aNEvt( nSVEvent
, pChild
, &aMEvt
);
632 if ( nSVEvent
== MouseNotifyEvent::MOUSEMOVE
)
633 pChild
->ImplGetFrameData()->mbInMouseMove
= true;
635 // bring window into foreground on mouseclick
636 if ( nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
)
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
641 if ( pChild
->IsDisposed() )
645 if ( ImplCallPreNotify( aNEvt
) || pChild
->IsDisposed() )
650 if ( nSVEvent
== MouseNotifyEvent::MOUSEMOVE
)
652 if ( pSVData
->maWinData
.mpTrackWin
)
654 TrackingEvent
aTEvt( aMEvt
);
655 pChild
->Tracking( aTEvt
);
656 if ( !pChild
->IsDisposed() )
658 // When ScrollRepeat, we restart the timer
659 if ( pSVData
->maWinData
.mpTrackTimer
&&
660 (pSVData
->maWinData
.mnTrackFlags
& StartTrackingFlags::ScrollRepeat
) )
661 pSVData
->maWinData
.mpTrackTimer
->Start();
663 bCallHelpRequest
= false;
669 if ( !pSVData
->maWinData
.mpCaptureWin
&&
670 (pChild
->GetSettings().GetMouseSettings().GetOptions() & MouseSettingsOptions::AutoFocus
) )
671 pChild
->ToTop( ToTopFlags::NoGrabFocus
);
673 if( pChild
->IsDisposed() )
674 bCallHelpRequest
= false;
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;
686 else if ( nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
)
688 if ( pSVData
->maWinData
.mpTrackWin
)
692 pChild
->ImplGetWindowImpl()->mbMouseButtonDown
= false;
693 pChild
->MouseButtonDown( aMEvt
);
698 if ( pSVData
->maWinData
.mpTrackWin
)
700 pChild
->EndTracking();
705 pChild
->ImplGetWindowImpl()->mbMouseButtonUp
= false;
706 pChild
->MouseButtonUp( aMEvt
);
710 assert(aNEvt
.GetWindow() == pChild
);
712 if (!pChild
->IsDisposed())
713 pChild
->ImplNotifyKeyMouseCommandEventListeners( aNEvt
);
716 if (pChild
->IsDisposed())
719 if ( nSVEvent
== MouseNotifyEvent::MOUSEMOVE
)
720 pChild
->ImplGetWindowImpl()->mpFrameData
->mbInMouseMove
= false;
722 if ( nSVEvent
== MouseNotifyEvent::MOUSEMOVE
)
724 if ( bCallHelpRequest
&& !pSVData
->maHelpData
.mbKeyboardHelp
)
725 ImplHandleMouseHelpRequest( pChild
, pChild
->OutputToScreenPixel( aMEvt
.GetPosPixel() ) );
730 if ( nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
)
732 if ( !pChild
->ImplGetWindowImpl()->mbMouseButtonDown
)
737 if ( !pChild
->ImplGetWindowImpl()->mbMouseButtonUp
)
742 if ( nSVEvent
== MouseNotifyEvent::MOUSEMOVE
)
744 // set new mouse pointer
746 ImplSetMousePointer( pChild
);
748 else if ( (nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
) || (nSVEvent
== MouseNotifyEvent::MOUSEBUTTONUP
) )
751 if ( /*!bRet &&*/ (nClicks
== 1) && (nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
) &&
752 (nCode
== MOUSE_MIDDLE
) )
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
);
763 if ( (nCode
== MouseSettings::GetContextMenuCode()) &&
764 (nClicks
== MouseSettings::GetContextMenuClicks()) )
766 bool bContextMenu
= (nSVEvent
== MouseNotifyEvent::MOUSEBUTTONDOWN
);
769 if( pSVData
->maAppData
.mpActivePopupMenu
)
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
779 ContextMenuEvent
* pEv
= new ContextMenuEvent
;
780 pEv
->pWindow
= pChild
;
781 pEv
->aChildPos
= aChildPos
;
782 Application::PostUserEvent( Link
<void*,void>( pEv
, ContextMenuEventLink
) );
785 bRet
= ! ImplCallCommand( pChild
, CommandEventId::ContextMenu
, nullptr, true, &aChildPos
);
794 static vcl::Window
* ImplGetKeyInputWindow( vcl::Window
* pWindow
)
796 ImplSVData
* pSVData
= ImplGetSVData();
798 // determine last input time
799 pSVData
->maAppData
.mnLastInputTime
= tools::Time::GetSystemTicks();
801 // #127104# workaround for destroyed windows
802 if( pWindow
->ImplGetWindowImpl() == nullptr )
805 // find window - is every time the window which has currently the
806 // focus or the last time the focus.
808 // the first floating window always has the focus, try it, or any parent floating windows, first
809 vcl::Window
* pChild
= pSVData
->maWinData
.mpFirstFloat
;
812 if (pChild
->ImplGetWindowImpl()->mbFloatWin
)
814 if (static_cast<FloatingWindow
*>(pChild
)->GrabsFocus())
817 else if (pChild
->ImplGetWindowImpl()->mbDockWin
)
819 vcl::Window
* pParent
= pChild
->GetWindow(GetWindowType::RealParent
);
820 if (pParent
&& pParent
->ImplGetWindowImpl()->mbFloatWin
&&
821 static_cast<FloatingWindow
*>(pParent
)->GrabsFocus())
824 pChild
= pChild
->GetParent();
830 pChild
= pChild
->ImplGetWindowImpl()->mpFrameData
->mpFocusWin
;
832 // no child - then no input
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" );
843 // no keyinput to disabled windows
844 if ( !pChild
->IsEnabled() || !pChild
->IsInputEnabled() || pChild
->IsInModalMode() )
850 static bool ImplHandleKey( vcl::Window
* pWindow
, MouseNotifyEvent nSVEvent
,
851 sal_uInt16 nKeyCode
, sal_uInt16 nCharCode
, sal_uInt16 nRepeat
, bool bForward
)
853 ImplSVData
* pSVData
= ImplGetSVData();
854 vcl::KeyCode
aKeyCode( nKeyCode
, nKeyCode
);
855 sal_uInt16 nEvCode
= aKeyCode
.GetCode();
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
862 VclEventId nVCLEvent
;
865 case MouseNotifyEvent::KEYINPUT
:
866 nVCLEvent
= VclEventId::WindowKeyInput
;
868 case MouseNotifyEvent::KEYUP
:
869 nVCLEvent
= VclEventId::WindowKeyUp
;
872 nVCLEvent
= VclEventId::NONE
;
875 KeyEvent
aKeyEvent(static_cast<sal_Unicode
>(nCharCode
), aKeyCode
, nRepeat
);
876 if (nVCLEvent
!= VclEventId::NONE
&& Application::HandleKey(nVCLEvent
, pWindow
, &aKeyEvent
))
880 // #i1820# use locale specific decimal separator
881 if( nEvCode
== KEY_DECIMAL
)
883 if( Application::GetSettings().GetMiscSettings().GetEnableLocalizedDecimalSep() )
885 OUString
aSep( pWindow
->GetSettings().GetLocaleDataWrapper().getNumDecimalSep() );
886 nCharCode
= static_cast<sal_uInt16
>(aSep
[0]);
890 bool bCtrlF6
= (aKeyCode
.GetCode() == KEY_F6
) && aKeyCode
.IsMod1();
892 // determine last input time
893 pSVData
->maAppData
.mnLastInputTime
= tools::Time::GetSystemTicks();
895 // handle tracking window
896 if ( nSVEvent
== MouseNotifyEvent::KEYINPUT
)
898 if ( pSVData
->maHelpData
.mbExtHelpMode
)
901 if ( nEvCode
== KEY_ESCAPE
)
904 if ( pSVData
->maHelpData
.mpHelpWin
)
905 ImplDestroyHelpWindow( false );
908 if ( pSVData
->maWinData
.mpAutoScrollWin
)
910 pSVData
->maWinData
.mpAutoScrollWin
->EndAutoScroll();
911 if ( nEvCode
== KEY_ESCAPE
)
915 if ( pSVData
->maWinData
.mpTrackWin
)
917 sal_uInt16 nOrigCode
= aKeyCode
.GetCode();
919 if ( nOrigCode
== KEY_ESCAPE
)
921 pSVData
->maWinData
.mpTrackWin
->EndTracking( TrackingEventFlags::Cancel
| TrackingEventFlags::Key
);
922 if ( pSVData
->maWinData
.mpFirstFloat
)
924 FloatingWindow
* pLastLevelFloat
= pSVData
->maWinData
.mpFirstFloat
->ImplFindLastLevelFloat();
925 if ( !(pLastLevelFloat
->GetPopupModeFlags() & FloatWinPopupFlags::NoKeyClose
) )
927 sal_uInt16 nEscCode
= aKeyCode
.GetCode();
929 if ( nEscCode
== KEY_ESCAPE
)
930 pLastLevelFloat
->EndPopupMode( FloatWinPopupEndFlags::Cancel
| FloatWinPopupEndFlags::CloseAll
);
935 else if ( nOrigCode
== KEY_RETURN
)
937 pSVData
->maWinData
.mpTrackWin
->EndTracking( TrackingEventFlags::Key
);
944 // handle FloatingMode
945 if ( pSVData
->maWinData
.mpFirstFloat
)
947 FloatingWindow
* pLastLevelFloat
= pSVData
->maWinData
.mpFirstFloat
->ImplFindLastLevelFloat();
948 if ( !(pLastLevelFloat
->GetPopupModeFlags() & FloatWinPopupFlags::NoKeyClose
) )
950 sal_uInt16 nCode
= aKeyCode
.GetCode();
952 if ( (nCode
== KEY_ESCAPE
) || bCtrlF6
)
954 pLastLevelFloat
->EndPopupMode( FloatWinPopupEndFlags::Cancel
| FloatWinPopupEndFlags::CloseAll
);
962 if ( pSVData
->maAppData
.mpAccelMgr
)
964 if ( pSVData
->maAppData
.mpAccelMgr
->IsAccelKey( aKeyCode
) )
970 VclPtr
<vcl::Window
> pChild
= ImplGetKeyInputWindow( pWindow
);
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() );
980 KeyEvent
aKeyEvt( static_cast<sal_Unicode
>(nCharCode
), aKeyCode
, nRepeat
);
981 NotifyEvent
aNotifyEvt( nSVEvent
, pChild
, &aKeyEvt
);
982 bool bKeyPreNotify
= ImplCallPreNotify( aNotifyEvt
);
985 if ( !bKeyPreNotify
&& !pChild
->IsDisposed() )
987 if ( nSVEvent
== MouseNotifyEvent::KEYINPUT
)
989 UITestLogger::getInstance().logKeyInput(pChild
, aKeyEvt
);
990 pChild
->ImplGetWindowImpl()->mbKeyInput
= false;
991 pChild
->KeyInput( aKeyEvt
);
995 pChild
->ImplGetWindowImpl()->mbKeyUp
= false;
996 pChild
->KeyUp( aKeyEvt
);
998 if( !pChild
->IsDisposed() )
999 aNotifyEvt
.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNotifyEvt
);
1002 if ( pChild
->IsDisposed() )
1005 if ( nSVEvent
== MouseNotifyEvent::KEYINPUT
)
1007 if ( !bKeyPreNotify
&& pChild
->ImplGetWindowImpl()->mbKeyInput
)
1009 sal_uInt16 nCode
= aKeyCode
.GetCode();
1011 // #101999# is focus in or below toolbox
1012 bool bToolboxFocus
=false;
1013 if( (nCode
== KEY_F1
) && aKeyCode
.IsShift() )
1015 vcl::Window
*pWin
= pWindow
->ImplGetWindowImpl()->mpFrameData
->mpFocusWin
;
1018 if( pWin
->ImplGetWindowImpl()->mbToolBox
)
1020 bToolboxFocus
= true;
1024 pWin
= pWin
->GetParent();
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
) )
1035 // TipHelp via Keyboard (Shift-F2 or Ctrl-F1)
1036 // simulate mouseposition at center of window
1038 Size aSize
= pChild
->GetOutputSize();
1039 Point
aPos( aSize
.getWidth()/2, aSize
.getHeight()/2 );
1040 aPos
= pChild
->OutputToScreenPixel( aPos
);
1042 HelpEvent
aHelpEvent( aPos
, HelpEventMode::BALLOON
);
1043 aHelpEvent
.SetKeyboardActivated( true );
1044 pSVData
->maHelpData
.mbSetKeyboardHelp
= true;
1045 pChild
->RequestHelp( aHelpEvent
);
1046 pSVData
->maHelpData
.mbSetKeyboardHelp
= false;
1048 else if ( (nCode
== KEY_F1
) || (nCode
== KEY_HELP
) )
1050 if ( !aKeyCode
.GetModifier() )
1052 if ( pSVData
->maHelpData
.mbContextHelp
)
1054 Point aMousePos
= pChild
->OutputToScreenPixel( pChild
->GetPointerPosPixel() );
1055 HelpEvent
aHelpEvent( aMousePos
, HelpEventMode::CONTEXT
);
1056 pChild
->RequestHelp( aHelpEvent
);
1061 else if ( aKeyCode
.IsShift() )
1063 if ( pSVData
->maHelpData
.mbExtHelp
)
1064 Help::StartExtHelp();
1075 if ( !bKeyPreNotify
&& pChild
->ImplGetWindowImpl()->mbKeyUp
)
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
) )
1082 pChild
= pWindow
->GetParent();
1085 NotifyEvent
aNEvt( nSVEvent
, pChild
, &aKeyEvt
);
1086 bool bPreNotify
= ImplCallPreNotify( aNEvt
);
1087 if ( pChild
->IsDisposed() )
1092 if ( nSVEvent
== MouseNotifyEvent::KEYINPUT
)
1094 pChild
->ImplGetWindowImpl()->mbKeyInput
= false;
1095 pChild
->KeyInput( aKeyEvt
);
1099 pChild
->ImplGetWindowImpl()->mbKeyUp
= false;
1100 pChild
->KeyUp( aKeyEvt
);
1103 if( !pChild
->IsDisposed() )
1104 aNEvt
.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNEvt
);
1105 if ( pChild
->IsDisposed() )
1109 if( bPreNotify
|| !pChild
->ImplGetWindowImpl()->mbKeyInput
)
1116 static bool ImplHandleExtTextInput( vcl::Window
* pWindow
,
1117 const OUString
& rText
,
1118 const ExtTextInputAttr
* pTextAttr
,
1119 sal_Int32 nCursorPos
, sal_uInt16 nCursorFlags
)
1121 ImplSVData
* pSVData
= ImplGetSVData();
1122 vcl::Window
* pChild
= nullptr;
1127 pChild
= pSVData
->maWinData
.mpExtTextInputWin
;
1130 pChild
= ImplGetKeyInputWindow( pWindow
);
1134 if( !pChild
->ImplGetWindowImpl()->mpFrameData
->mnFocusId
)
1137 if (comphelper::LibreOfficeKit::isActive())
1139 SAL_WARN("vcl", "Failed to get ext text input context");
1142 Application::Yield();
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
)
1150 pChild
->ImplGetWindowImpl()->mbExtTextInput
= true;
1151 pWinData
->mpExtOldText
= OUString();
1152 pWinData
->mpExtOldAttrAry
.reset();
1153 pSVData
->maWinData
.mpExtTextInputWin
= pChild
;
1154 ImplCallCommand( pChild
, CommandEventId::StartExtTextInput
);
1157 // be aware of being recursively called in StartExtTextInput
1158 if ( !pChild
->ImplGetWindowImpl()->mbExtTextInput
)
1162 bool bOnlyCursor
= false;
1163 sal_Int32 nMinLen
= std::min( pWinData
->mpExtOldText
->getLength(), rText
.getLength() );
1164 sal_Int32 nDeltaStart
= 0;
1165 while ( nDeltaStart
< nMinLen
)
1167 if ( (*pWinData
->mpExtOldText
)[nDeltaStart
] != rText
[nDeltaStart
] )
1171 if ( pWinData
->mpExtOldAttrAry
|| pTextAttr
)
1173 if ( !pWinData
->mpExtOldAttrAry
|| !pTextAttr
)
1178 while ( i
< nDeltaStart
)
1180 if ( pWinData
->mpExtOldAttrAry
[i
] != pTextAttr
[i
] )
1189 if ( (nDeltaStart
>= nMinLen
) &&
1190 (pWinData
->mpExtOldText
->getLength() == rText
.getLength()) )
1193 // Call Event and store the information
1194 CommandExtTextInputData
aData( rText
, pTextAttr
,
1195 nCursorPos
, nCursorFlags
,
1197 *pWinData
->mpExtOldText
= rText
;
1198 pWinData
->mpExtOldAttrAry
.reset();
1201 pWinData
->mpExtOldAttrAry
.reset( new ExtTextInputAttr
[rText
.getLength()] );
1202 memcpy( pWinData
->mpExtOldAttrAry
.get(), pTextAttr
, rText
.getLength()*sizeof( ExtTextInputAttr
) );
1204 return !ImplCallCommand( pChild
, CommandEventId::ExtTextInput
, &aData
);
1207 static bool ImplHandleEndExtTextInput()
1209 ImplSVData
* pSVData
= ImplGetSVData();
1210 vcl::Window
* pChild
= pSVData
->maWinData
.mpExtTextInputWin
;
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
);
1226 static void ImplHandleExtTextInputPos( vcl::Window
* pWindow
,
1227 tools::Rectangle
& rRect
, long& rInputWidth
,
1230 ImplSVData
* pSVData
= ImplGetSVData();
1231 vcl::Window
* pChild
= pSVData
->maWinData
.mpExtTextInputWin
;
1234 pChild
= ImplGetKeyInputWindow( pWindow
);
1237 // Test, if the Window is related to the frame
1238 if ( !pWindow
->ImplIsWindowOrChild( pChild
) )
1239 pChild
= ImplGetKeyInputWindow( pWindow
);
1244 const OutputDevice
*pChildOutDev
= pChild
->GetOutDev();
1245 ImplCallCommand( pChild
, CommandEventId::CursorPos
);
1246 const tools::Rectangle
* pRect
= pChild
->GetCursorRect();
1248 rRect
= pChildOutDev
->ImplLogicToDevicePixel( *pRect
);
1251 vcl::Cursor
* pCursor
= pChild
->GetCursor();
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
);
1261 rRect
= tools::Rectangle( Point( pChild
->GetOutOffXPixel(), pChild
->GetOutOffYPixel() ), Size() );
1263 rInputWidth
= pChild
->ImplLogicWidthToDevicePixel( pChild
->GetCursorExtTextInputWidth() );
1265 rInputWidth
= rRect
.GetWidth();
1267 if (pVertical
!= nullptr)
1269 = pChild
!= nullptr && pChild
->GetInputContext().GetFont().IsVertical();
1272 static bool ImplHandleInputContextChange( vcl::Window
* pWindow
)
1274 vcl::Window
* pChild
= ImplGetKeyInputWindow( pWindow
);
1275 CommandInputContextData aData
;
1276 return !ImplCallCommand( pChild
, CommandEventId::InputContextChange
, &aData
);
1279 static bool ImplCallWheelCommand( const VclPtr
<vcl::Window
>& pWindow
, const Point
& rPos
,
1280 const CommandWheelData
* pWheelData
)
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() )
1290 pWindow
->ImplGetWindowImpl()->mbCommand
= false;
1291 pWindow
->Command( aCEvt
);
1292 if ( pWindow
->IsDisposed() )
1294 if ( pWindow
->ImplGetWindowImpl()->mbCommand
)
1300 static bool acceptableWheelScrollTarget(const vcl::Window
*pMouseWindow
)
1302 return (pMouseWindow
&& !pMouseWindow
->isDisposed() && pMouseWindow
->IsInputEnabled() && !pMouseWindow
->IsInModalMode());
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
1311 static bool shouldReusePreviousMouseWindow(const SalWheelMouseEvent
& rPrevEvt
, const SalWheelMouseEvent
& rEvt
)
1313 return (rEvt
.mnX
== rPrevEvt
.mnX
&& rEvt
.mnY
== rPrevEvt
.mnY
&& rEvt
.mnTime
-rPrevEvt
.mnTime
< 500/*ms*/);
1316 class HandleGestureEventBase
1319 ImplSVData
* m_pSVData
;
1320 VclPtr
<vcl::Window
> m_pWindow
;
1321 Point
const m_aMousePos
;
1324 HandleGestureEventBase(vcl::Window
*pWindow
, const Point
&rMousePos
)
1325 : m_pSVData(ImplGetSVData())
1326 , m_pWindow(pWindow
)
1327 , m_aMousePos(rMousePos
)
1331 vcl::Window
* FindTarget();
1332 vcl::Window
* Dispatch(vcl::Window
* pTarget
);
1333 virtual bool CallCommand(vcl::Window
*pWindow
, const Point
&rMousePos
) = 0;
1334 virtual ~HandleGestureEventBase() {}
1337 bool HandleGestureEventBase::Setup()
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();
1347 vcl::Window
* HandleGestureEventBase::FindTarget()
1349 // first check any floating window ( eg. drop down listboxes)
1350 vcl::Window
*pMouseWindow
= nullptr;
1352 if (m_pSVData
->maWinData
.mpFirstFloat
&& !m_pSVData
->maWinData
.mpCaptureWin
&&
1353 !m_pSVData
->maWinData
.mpFirstFloat
->ImplIsFloatPopupModeWindow( m_pWindow
) )
1355 bool bHitTestInsideRect
= false;
1356 pMouseWindow
= m_pSVData
->maWinData
.mpFirstFloat
->ImplFloatHitTest( m_pWindow
, m_aMousePos
, bHitTestInsideRect
);
1358 pMouseWindow
= m_pSVData
->maWinData
.mpFirstFloat
;
1360 // then try the window directly beneath the mouse
1363 pMouseWindow
= m_pWindow
->ImplFindWindow( m_aMousePos
);
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
) ) ) ) );
1375 while (acceptableWheelScrollTarget(pMouseWindow
))
1377 if (pMouseWindow
->IsEnabled())
1379 //try the parent if this one is disabled
1380 pMouseWindow
= pMouseWindow
->GetParent();
1383 return pMouseWindow
;
1386 vcl::Window
*HandleGestureEventBase::Dispatch(vcl::Window
* pMouseWindow
)
1388 vcl::Window
*pDispatchedTo
= nullptr;
1390 if (acceptableWheelScrollTarget(pMouseWindow
) && pMouseWindow
->IsEnabled())
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
);
1399 pDispatchedTo
= pMouseWindow
;
1402 // if the command was not handled try the focus window
1405 vcl::Window
* pFocusWindow
= m_pWindow
->ImplGetWindowImpl()->mpFrameData
->mpFocusWin
;
1406 if ( pFocusWindow
&& (pFocusWindow
!= pMouseWindow
) &&
1407 (pFocusWindow
== m_pSVData
->maWinData
.mpFocusWin
) )
1409 // no wheel-messages to disabled windows
1410 if ( pFocusWindow
->IsEnabled() && pFocusWindow
->IsInputEnabled() && ! pFocusWindow
->IsInModalMode() )
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
);
1419 pDispatchedTo
= pMouseWindow
;
1423 return pDispatchedTo
;
1426 class HandleWheelEvent
: public HandleGestureEventBase
1429 CommandWheelData m_aWheelData
;
1431 HandleWheelEvent(vcl::Window
*pWindow
, const SalWheelMouseEvent
& rEvt
)
1432 : HandleGestureEventBase(pWindow
, Point(rEvt
.mnX
, rEvt
.mnY
))
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
;
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
)
1450 m_aWheelData
= CommandWheelData(rEvt
.mnDelta
, rEvt
.mnNotchDelta
, rEvt
.mnScrollLines
, nMode
, nCode
, bHorz
, bPixel
);
1453 virtual bool CallCommand(vcl::Window
*pWindow
, const Point
&rMousePos
) override
1455 return ImplCallWheelCommand(pWindow
, rMousePos
, &m_aWheelData
);
1457 bool HandleEvent(const SalWheelMouseEvent
& rEvt
);
1460 bool HandleWheelEvent::HandleEvent(const SalWheelMouseEvent
& rEvt
)
1465 VclPtr
<vcl::Window
> xMouseWindow
= FindTarget();
1467 ImplSVData
* pSVData
= ImplGetSVData();
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
))
1475 xMouseWindow
= pSVData
->maWinData
.mpLastWheelWindow
;
1478 pSVData
->maWinData
.maLastWheelEvent
= rEvt
;
1480 pSVData
->maWinData
.mpLastWheelWindow
= Dispatch(xMouseWindow
);
1482 return pSVData
->maWinData
.mpLastWheelWindow
.get();
1485 class HandleGestureEvent
: public HandleGestureEventBase
1488 HandleGestureEvent(vcl::Window
*pWindow
, const Point
&rMousePos
)
1489 : HandleGestureEventBase(pWindow
, rMousePos
)
1495 bool HandleGestureEvent::HandleEvent()
1500 vcl::Window
*pTarget
= FindTarget();
1502 bool bHandled
= Dispatch(pTarget
) != nullptr;
1506 static bool ImplHandleWheelEvent(vcl::Window
* pWindow
, const SalWheelMouseEvent
& rEvt
)
1508 HandleWheelEvent
aHandler(pWindow
, rEvt
);
1509 return aHandler
.HandleEvent(rEvt
);
1512 class HandleSwipeEvent
: public HandleGestureEvent
1515 CommandSwipeData m_aSwipeData
;
1517 HandleSwipeEvent(vcl::Window
*pWindow
, const SalSwipeEvent
& rEvt
)
1518 : HandleGestureEvent(pWindow
, Point(rEvt
.mnX
, rEvt
.mnY
)),
1519 m_aSwipeData(rEvt
.mnVelocityX
)
1522 virtual bool CallCommand(vcl::Window
*pWindow
, const Point
&/*rMousePos*/) override
1524 return ImplCallCommand(pWindow
, CommandEventId::Swipe
, &m_aSwipeData
);
1528 static bool ImplHandleSwipe(vcl::Window
*pWindow
, const SalSwipeEvent
& rEvt
)
1530 HandleSwipeEvent
aHandler(pWindow
, rEvt
);
1531 return aHandler
.HandleEvent();
1534 class HandleLongPressEvent
: public HandleGestureEvent
1537 CommandLongPressData m_aLongPressData
;
1539 HandleLongPressEvent(vcl::Window
*pWindow
, const SalLongPressEvent
& rEvt
)
1540 : HandleGestureEvent(pWindow
, Point(rEvt
.mnX
, rEvt
.mnY
)),
1541 m_aLongPressData(rEvt
.mnX
, rEvt
.mnY
)
1544 virtual bool CallCommand(vcl::Window
*pWindow
, const Point
&/*rMousePos*/) override
1546 return ImplCallCommand(pWindow
, CommandEventId::LongPress
, &m_aLongPressData
);
1550 static bool ImplHandleLongPress(vcl::Window
*pWindow
, const SalLongPressEvent
& rEvt
)
1552 HandleLongPressEvent
aHandler(pWindow
, rEvt
);
1553 return aHandler
.HandleEvent();
1556 class HandleGeneralGestureEvent
: public HandleGestureEvent
1559 CommandGestureData m_aGestureData
;
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
)
1568 virtual bool CallCommand(vcl::Window
* pWindow
, const Point
& /*rMousePos*/) override
1570 return ImplCallCommand(pWindow
, CommandEventId::Gesture
, &m_aGestureData
);
1574 static bool ImplHandleGestureEvent(vcl::Window
* pWindow
, const SalGestureEvent
& rEvent
)
1576 HandleGeneralGestureEvent
aHandler(pWindow
, rEvent
);
1577 return aHandler
.HandleEvent();
1580 static void ImplHandlePaint( vcl::Window
* pWindow
, const tools::Rectangle
& rBoundRect
, bool bImmediateUpdate
)
1582 // system paint events must be checked for re-mirroring
1583 pWindow
->ImplGetWindowImpl()->mnPaintFlags
|= ImplPaintFlags::CheckRtl
;
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
)
1590 // #i87663# trigger possible pending resize notifications
1591 // (GetSizePixel does that for us)
1592 pWindow
->GetSizePixel();
1593 // force drawing immediately
1598 static void KillOwnPopups( vcl::Window
const * pWindow
)
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 ) )
1605 if ( !(pSVData
->maWinData
.mpFirstFloat
->GetPopupModeFlags() & FloatWinPopupFlags::NoAppFocusClose
) )
1606 pSVData
->maWinData
.mpFirstFloat
->EndPopupMode( FloatWinPopupEndFlags::Cancel
| FloatWinPopupEndFlags::CloseAll
);
1610 void ImplHandleResize( vcl::Window
* pWindow
, long nNewWidth
, long nNewHeight
)
1612 const bool bChanged
= (nNewWidth
!= pWindow
->GetOutputWidthPixel()) || (nNewHeight
!= pWindow
->GetOutputHeightPixel());
1613 if (bChanged
&& pWindow
->GetStyle() & (WB_MOVEABLE
|WB_SIZEABLE
))
1615 KillOwnPopups( pWindow
);
1616 if( pWindow
->ImplGetWindow() != ImplGetSVData()->maHelpData
.mpHelpWin
)
1617 ImplDestroyHelpWindow( true );
1621 (nNewWidth
> 0 && nNewHeight
> 0) ||
1622 pWindow
->ImplGetWindow()->ImplGetWindowImpl()->mbAllResize
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
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#
1642 if( pWindow
->ImplGetWindowImpl()->mpClientWindow
)
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;
1652 WorkWindow
* pWorkWindow
= dynamic_cast<WorkWindow
*>(pWindow
);
1653 if( ! pWorkWindow
|| pWorkWindow
->IsPresentationMode() )
1654 bStartTimer
= false;
1658 bStartTimer
= false;
1661 pWindow
->ImplGetWindowImpl()->mpFrameData
->maResizeIdle
.Start();
1663 pWindow
->ImplCallResize(); // otherwise menus cannot be positioned
1666 pWindow
->ImplGetWindowImpl()->mbCallResize
= true;
1668 if (pWindow
->SupportsDoubleBuffering() && pWindow
->ImplGetWindowImpl()->mbFrame
)
1670 // Propagate resize for the frame's buffer.
1671 pWindow
->ImplGetWindowImpl()->mpFrameData
->mpBuffer
->SetOutputSizePixel(pWindow
->GetOutputSizePixel());
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
;
1684 static void ImplHandleMove( vcl::Window
* pWindow
)
1686 if( pWindow
->ImplGetWindowImpl()->mbFrame
&& pWindow
->ImplIsFloatingWindow() && pWindow
->IsReallyVisible() )
1688 static_cast<FloatingWindow
*>(pWindow
)->EndPopupMode( FloatWinPopupEndFlags::TearOff
);
1689 pWindow
->ImplCallMove();
1692 if( pWindow
->GetStyle() & (WB_MOVEABLE
|WB_SIZEABLE
) )
1694 KillOwnPopups( pWindow
);
1695 if( pWindow
->ImplGetWindow() != ImplGetSVData()->maHelpData
.mpHelpWin
)
1696 ImplDestroyHelpWindow( true );
1699 if ( pWindow
->IsVisible() )
1700 pWindow
->ImplCallMove();
1702 pWindow
->ImplGetWindowImpl()->mbCallMove
= true; // make sure the framepos will be updated on the next Show()
1704 if ( pWindow
->ImplGetWindowImpl()->mbFrame
&& pWindow
->ImplGetWindowImpl()->mpClientWindow
)
1705 pWindow
->ImplGetWindowImpl()->mpClientWindow
->ImplCallMove(); // notify client to update geometry
1709 static void ImplHandleMoveResize( vcl::Window
* pWindow
, long nNewWidth
, long nNewHeight
)
1711 ImplHandleMove( pWindow
);
1712 ImplHandleResize( pWindow
, nNewWidth
, nNewHeight
);
1715 static void ImplActivateFloatingWindows( vcl::Window
const * pWindow
, bool bActive
)
1717 // First check all overlapping windows
1718 vcl::Window
* pTempWindow
= pWindow
->ImplGetWindowImpl()->mpFirstOverlap
;
1719 while ( pTempWindow
)
1721 if ( pTempWindow
->GetActivateMode() == ActivateModeFlags::NONE
)
1723 if ( (pTempWindow
->GetType() == WindowType::BORDERWINDOW
) &&
1724 (pTempWindow
->ImplGetWindow()->GetType() == WindowType::FLOATINGWINDOW
) )
1725 static_cast<ImplBorderWindow
*>(pTempWindow
)->SetDisplayActive( bActive
);
1728 ImplActivateFloatingWindows( pTempWindow
, bActive
);
1729 pTempWindow
= pTempWindow
->ImplGetWindowImpl()->mpNext
;
1733 IMPL_LINK_NOARG(vcl::Window
, ImplAsyncFocusHdl
, void*, void)
1735 ImplGetWindowImpl()->mpFrameData
->mnFocusId
= nullptr;
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
;
1741 // next execute the delayed functions
1744 // redraw all floating windows inactive
1745 if ( ImplGetWindowImpl()->mpFrameData
->mbStartFocusState
!= bHasFocus
)
1746 ImplActivateFloatingWindows( this, bHasFocus
);
1748 if ( ImplGetWindowImpl()->mpFrameData
->mpFocusWin
)
1750 bool bHandled
= false;
1751 if ( ImplGetWindowImpl()->mpFrameData
->mpFocusWin
->IsInputEnabled() &&
1752 ! ImplGetWindowImpl()->mpFrameData
->mpFocusWin
->IsInModalMode() )
1754 if ( ImplGetWindowImpl()->mpFrameData
->mpFocusWin
->IsEnabled() )
1756 ImplGetWindowImpl()->mpFrameData
->mpFocusWin
->GrabFocus();
1759 else if( ImplGetWindowImpl()->mpFrameData
->mpFocusWin
->ImplHasDlgCtrl() )
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();
1769 ImplSVData
* pSVData
= ImplGetSVData();
1770 vcl::Window
* pTopLevelWindow
= ImplGetWindowImpl()->mpFrameData
->mpFocusWin
->ImplGetFirstOverlapWindow();
1772 if ((!pTopLevelWindow
->IsInputEnabled() || pTopLevelWindow
->IsInModalMode()) && !pSVData
->maWinData
.mpExecuteDialogs
.empty())
1773 pSVData
->maWinData
.mpExecuteDialogs
.back()->ToTop(ToTopFlags::RestoreWhenMin
| ToTopFlags::GrabFocusOnly
);
1775 pTopLevelWindow
->GrabFocus();
1783 vcl::Window
* pFocusWin
= ImplGetWindowImpl()->mpFrameData
->mpFocusWin
;
1786 ImplSVData
* pSVData
= ImplGetSVData();
1788 if ( pSVData
->maWinData
.mpFocusWin
== pFocusWin
)
1790 // transfer the FocusWindow
1791 vcl::Window
* pOverlapWindow
= pFocusWin
->ImplGetFirstOverlapWindow();
1792 pOverlapWindow
->ImplGetWindowImpl()->mpLastFocusWindow
= pFocusWin
;
1793 pSVData
->maWinData
.mpFocusWin
= nullptr;
1795 if ( pFocusWin
->ImplGetWindowImpl()->mpCursor
)
1796 pFocusWin
->ImplGetWindowImpl()->mpCursor
->ImplHide();
1798 // call the Deactivate
1799 vcl::Window
* pOldOverlapWindow
= pFocusWin
->ImplGetFirstOverlapWindow();
1800 vcl::Window
* pOldRealWindow
= pOldOverlapWindow
->ImplGetWindow();
1802 pOldOverlapWindow
->ImplGetWindowImpl()->mbActive
= false;
1803 pOldOverlapWindow
->Deactivate();
1804 if ( pOldRealWindow
!= pOldOverlapWindow
)
1806 pOldRealWindow
->ImplGetWindowImpl()->mbActive
= false;
1807 pOldRealWindow
->Deactivate();
1810 // TrackingMode is ended in ImplHandleLoseFocus
1812 // To avoid problems with the Unix IME
1813 pFocusWin
->EndExtTextInput();
1816 NotifyEvent
aNEvt(MouseNotifyEvent::LOSEFOCUS
, pFocusWin
);
1817 if (!ImplCallPreNotify(aNEvt
))
1818 pFocusWin
->CompatLoseFocus();
1819 pFocusWin
->ImplCallDeactivateListeners(nullptr);
1823 // Redraw all floating window inactive
1824 if ( ImplGetWindowImpl()->mpFrameData
->mbStartFocusState
!= bHasFocus
)
1825 ImplActivateFloatingWindows( this, bHasFocus
);
1829 static void ImplHandleGetFocus( vcl::Window
* pWindow
)
1831 pWindow
->ImplGetWindowImpl()->mpFrameData
->mbHasFocus
= true;
1833 // execute Focus-Events after a delay, such that SystemChildWindows
1834 // do not blink when they receive focus
1835 if ( !pWindow
->ImplGetWindowImpl()->mpFrameData
->mnFocusId
)
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();
1845 static void ImplHandleLoseFocus( vcl::Window
* pWindow
)
1847 ImplSVData
* pSVData
= ImplGetSVData();
1849 // Abort the autoscroll if the frame loses focus
1850 if ( pSVData
->maWinData
.mpAutoScrollWin
)
1851 pSVData
->maWinData
.mpAutoScrollWin
->EndAutoScroll();
1853 // Abort tracking if the frame loses focus
1854 if ( pSVData
->maWinData
.mpTrackWin
)
1856 if ( pSVData
->maWinData
.mpTrackWin
->ImplGetWindowImpl()->mpFrameWindow
== pWindow
)
1857 pSVData
->maWinData
.mpTrackWin
->EndTracking( TrackingEventFlags::Cancel
);
1860 pWindow
->ImplGetWindowImpl()->mpFrameData
->mbHasFocus
= false;
1862 // execute Focus-Events after a delay, such that SystemChildWindows
1863 // do not flicker when they receive focus
1864 if ( !pWindow
->ImplGetWindowImpl()->mpFrameData
->mnFocusId
)
1866 pWindow
->ImplGetWindowImpl()->mpFrameData
->mbStartFocusState
= !pWindow
->ImplGetWindowImpl()->mpFrameData
->mbHasFocus
;
1867 pWindow
->ImplGetWindowImpl()->mpFrameData
->mnFocusId
= Application::PostUserEvent( LINK( pWindow
, vcl::Window
, ImplAsyncFocusHdl
), nullptr, true );
1870 vcl::Window
* pFocusWin
= pWindow
->ImplGetWindowImpl()->mpFrameData
->mpFocusWin
;
1871 if ( pFocusWin
&& pFocusWin
->ImplGetWindowImpl()->mpCursor
)
1872 pFocusWin
->ImplGetWindowImpl()->mpCursor
->ImplHide();
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
);
1880 struct DelayedCloseEvent
1882 VclPtr
<vcl::Window
> pWindow
;
1885 static void DelayedCloseEventLink( void* pCEvent
, void* )
1887 DelayedCloseEvent
* pEv
= static_cast<DelayedCloseEvent
*>(pCEvent
);
1889 if( ! pEv
->pWindow
->IsDisposed() )
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();
1900 static void ImplHandleClose( const vcl::Window
* pWindow
)
1902 ImplSVData
* pSVData
= ImplGetSVData();
1904 bool bWasPopup
= false;
1905 if( pWindow
->ImplIsFloatingWindow() &&
1906 static_cast<const FloatingWindow
*>(pWindow
)->ImplIsInPrivatePopupMode() )
1911 // on Close stop all floating modes and end popups
1912 if ( pSVData
->maWinData
.mpFirstFloat
)
1914 FloatingWindow
* pLastLevelFloat
;
1915 pLastLevelFloat
= pSVData
->maWinData
.mpFirstFloat
->ImplFindLastLevelFloat();
1916 pLastLevelFloat
->EndPopupMode( FloatWinPopupEndFlags::Cancel
| FloatWinPopupEndFlags::CloseAll
);
1918 if ( pSVData
->maHelpData
.mbExtHelpMode
)
1920 if ( pSVData
->maHelpData
.mpHelpWin
)
1921 ImplDestroyHelpWindow( false );
1923 if ( pSVData
->maWinData
.mpAutoScrollWin
)
1924 pSVData
->maWinData
.mpAutoScrollWin
->EndAutoScroll();
1926 if ( pSVData
->maWinData
.mpTrackWin
)
1927 pSVData
->maWinData
.mpTrackWin
->EndTracking( TrackingEventFlags::Cancel
| TrackingEventFlags::Key
);
1932 vcl::Window
*pWin
= pWindow
->ImplGetWindow();
1933 SystemWindow
* pSysWin
= dynamic_cast<SystemWindow
*>(pWin
);
1936 // See if the custom close handler is set.
1937 const Link
<SystemWindow
&,void>& rLink
= pSysWin
->GetCloseHdl();
1940 rLink
.Call(*pSysWin
);
1945 // check whether close is allowed
1946 if ( pWin
->IsEnabled() && pWin
->IsInputEnabled() && !pWin
->IsInModalMode() )
1948 DelayedCloseEvent
* pEv
= new DelayedCloseEvent
;
1949 pEv
->pWindow
= pWin
;
1950 Application::PostUserEvent( Link
<void*,void>( pEv
, DelayedCloseEventLink
) );
1954 static void ImplHandleUserEvent( ImplSVEvent
* pSVEvent
)
1958 if ( pSVEvent
->mbCall
)
1960 pSVEvent
->maLink
.Call( pSVEvent
->mpData
);
1967 static MouseEventModifiers
ImplGetMouseMoveMode( SalMouseEvent
const * pEvent
)
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
;
1979 static MouseEventModifiers
ImplGetMouseButtonMode( SalMouseEvent
const * pEvent
)
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
;
1995 static bool ImplHandleSalMouseLeave( vcl::Window
* pWindow
, SalMouseEvent
const * pEvent
)
1997 return ImplHandleMouseEvent( pWindow
, MouseNotifyEvent::MOUSEMOVE
, true,
1998 pEvent
->mnX
, pEvent
->mnY
,
1999 pEvent
->mnTime
, pEvent
->mnCode
,
2000 ImplGetMouseMoveMode( pEvent
) );
2003 static bool ImplHandleSalMouseMove( vcl::Window
* pWindow
, SalMouseEvent
const * pEvent
)
2005 return ImplHandleMouseEvent( pWindow
, MouseNotifyEvent::MOUSEMOVE
, false,
2006 pEvent
->mnX
, pEvent
->mnY
,
2007 pEvent
->mnTime
, pEvent
->mnCode
,
2008 ImplGetMouseMoveMode( pEvent
) );
2011 static bool ImplHandleSalMouseButtonDown( vcl::Window
* pWindow
, SalMouseEvent
const * pEvent
)
2013 return ImplHandleMouseEvent( pWindow
, MouseNotifyEvent::MOUSEBUTTONDOWN
, false,
2014 pEvent
->mnX
, pEvent
->mnY
,
2017 pEvent
->mnButton
| (pEvent
->mnCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
| KEY_MOD3
)),
2019 pEvent
->mnButton
| (pEvent
->mnCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
)),
2021 ImplGetMouseButtonMode( pEvent
) );
2024 static bool ImplHandleSalMouseButtonUp( vcl::Window
* pWindow
, SalMouseEvent
const * pEvent
)
2026 return ImplHandleMouseEvent( pWindow
, MouseNotifyEvent::MOUSEBUTTONUP
, false,
2027 pEvent
->mnX
, pEvent
->mnY
,
2030 pEvent
->mnButton
| (pEvent
->mnCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
| KEY_MOD3
)),
2032 pEvent
->mnButton
| (pEvent
->mnCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
)),
2034 ImplGetMouseButtonMode( pEvent
) );
2037 static bool ImplHandleMenuEvent( vcl::Window
const * pWindow
, SalMenuEvent
* pEvent
, SalEvent nEvent
)
2039 // Find SystemWindow and its Menubar and let it dispatch the command
2041 vcl::Window
*pWin
= pWindow
->ImplGetWindowImpl()->mpFirstChild
;
2044 if ( pWin
->ImplGetWindowImpl()->mbSysWin
)
2046 pWin
= pWin
->ImplGetWindowImpl()->mpNext
;
2050 MenuBar
*pMenuBar
= static_cast<SystemWindow
*>(pWin
)->GetMenuBar();
2055 case SalEvent::MenuActivate
:
2056 pMenuBar
->HandleMenuActivateEvent( static_cast<Menu
*>(pEvent
->mpMenu
) );
2059 case SalEvent::MenuDeactivate
:
2060 pMenuBar
->HandleMenuDeActivateEvent( static_cast<Menu
*>(pEvent
->mpMenu
) );
2063 case SalEvent::MenuHighlight
:
2064 bRet
= pMenuBar
->HandleMenuHighlightEvent( static_cast<Menu
*>(pEvent
->mpMenu
), pEvent
->mnId
);
2066 case SalEvent::MenuButtonCommand
:
2067 bRet
= pMenuBar
->HandleMenuButtonEvent( pEvent
->mnId
);
2069 case SalEvent::MenuCommand
:
2070 bRet
= pMenuBar
->HandleMenuCommandEvent( static_cast<Menu
*>(pEvent
->mpMenu
), pEvent
->mnId
);
2080 static void ImplHandleSalKeyMod( vcl::Window
* pWindow
, SalKeyModEvent
const * pEvent
)
2082 ImplSVData
* pSVData
= ImplGetSVData();
2083 vcl::Window
* pTrackWin
= pSVData
->maWinData
.mpTrackWin
;
2085 pWindow
= pTrackWin
;
2087 sal_uInt16 nOldCode
= pWindow
->ImplGetWindowImpl()->mpFrameData
->mnMouseCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
| KEY_MOD3
);
2089 sal_uInt16 nOldCode
= pWindow
->ImplGetWindowImpl()->mpFrameData
->mnMouseCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
);
2091 sal_uInt16 nNewCode
= pEvent
->mnCode
;
2092 if ( nOldCode
!= nNewCode
)
2095 nNewCode
|= pWindow
->ImplGetWindowImpl()->mpFrameData
->mnMouseCode
& ~(KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
| KEY_MOD3
);
2097 nNewCode
|= pWindow
->ImplGetWindowImpl()->mpFrameData
->mnMouseCode
& ~(KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
);
2099 pWindow
->ImplGetWindowImpl()->mpFrameWindow
->ImplCallMouseMove( nNewCode
, true );
2102 // #105224# send commandevent to allow special treatment of Ctrl-LeftShift/Ctrl-RightShift etc.
2103 // + auto-accelerator feature, tdf#92630
2105 // try to find a key input window...
2106 vcl::Window
* pChild
= ImplGetKeyInputWindow( pWindow
);
2107 //...otherwise fail safe...
2111 CommandModKeyData
data( pEvent
->mnModKeyCode
, pEvent
->mbDown
);
2112 ImplCallCommand( pChild
, CommandEventId::ModKeyChange
, &data
);
2115 static void ImplHandleInputLanguageChange( vcl::Window
* pWindow
)
2118 vcl::Window
* pChild
= ImplGetKeyInputWindow( pWindow
);
2122 ImplCallCommand( pChild
, CommandEventId::InputLanguageChange
);
2125 static void ImplHandleSalSettings( SalEvent nEvent
)
2127 Application
* pApp
= GetpApp();
2131 if ( nEvent
== SalEvent::SettingsChanged
)
2133 AllSettings aSettings
= Application::GetSettings();
2134 Application::MergeSystemSettings( aSettings
);
2135 pApp
->OverrideSystemSettings( aSettings
);
2136 Application::SetSettings( aSettings
);
2140 DataChangedEventType nType
;
2143 case SalEvent::PrinterChanged
:
2144 ImplDeletePrnQueueList();
2145 nType
= DataChangedEventType::PRINTER
;
2147 case SalEvent::DisplayChanged
:
2148 nType
= DataChangedEventType::DISPLAY
;
2150 case SalEvent::FontChanged
:
2151 OutputDevice::ImplUpdateAllFontData( true );
2152 nType
= DataChangedEventType::FONTS
;
2155 nType
= DataChangedEventType::NONE
;
2159 if ( nType
!= DataChangedEventType::NONE
)
2161 DataChangedEvent
aDCEvt( nType
);
2162 Application::ImplCallEventListenersApplicationDataChanged(&aDCEvt
);
2163 Application::NotifyAllWindows( aDCEvt
);
2168 static void ImplHandleSalExtTextInputPos( vcl::Window
* pWindow
, SalExtTextInputPosEvent
* pEvt
)
2170 tools::Rectangle aCursorRect
;
2171 ImplHandleExtTextInputPos( pWindow
, aCursorRect
, pEvt
->mnExtWidth
, &pEvt
->mbVertical
);
2172 if ( aCursorRect
.IsEmpty() )
2177 pEvt
->mnHeight
= -1;
2181 pEvt
->mnX
= aCursorRect
.Left();
2182 pEvt
->mnY
= aCursorRect
.Top();
2183 pEvt
->mnWidth
= aCursorRect
.GetWidth();
2184 pEvt
->mnHeight
= aCursorRect
.GetHeight();
2188 static bool ImplHandleShowDialog( vcl::Window
* pWindow
, ShowDialogId nDialogId
)
2193 if( pWindow
->GetType() == WindowType::BORDERWINDOW
)
2195 vcl::Window
* pWrkWin
= pWindow
->GetWindow( GetWindowType::Client
);
2199 CommandDialogData
aCmdData( nDialogId
);
2200 return ImplCallCommand( pWindow
, CommandEventId::ShowDialog
, &aCmdData
);
2203 static void ImplHandleSurroundingTextRequest( vcl::Window
*pWindow
,
2205 Selection
&rSelRange
)
2207 vcl::Window
* pChild
= ImplGetKeyInputWindow( pWindow
);
2212 rSelRange
.setMin( 0 );
2213 rSelRange
.setMax( 0 );
2217 rText
= pChild
->GetSurroundingText();
2218 Selection aSel
= pChild
->GetSurroundingTextSelection();
2219 rSelRange
.setMin( aSel
.Min() );
2220 rSelRange
.setMax( aSel
.Max() );
2224 static void ImplHandleSalSurroundingTextRequest( vcl::Window
*pWindow
,
2225 SalSurroundingTextRequestEvent
*pEvt
)
2227 Selection aSelRange
;
2228 ImplHandleSurroundingTextRequest( pWindow
, pEvt
->maText
, aSelRange
);
2230 aSelRange
.Justify();
2232 if( aSelRange
.Min() < 0 )
2234 else if( aSelRange
.Min() > pEvt
->maText
.getLength() )
2235 pEvt
->mnStart
= pEvt
->maText
.getLength();
2237 pEvt
->mnStart
= aSelRange
.Min();
2239 if( aSelRange
.Max() < 0 )
2241 else if( aSelRange
.Max() > pEvt
->maText
.getLength() )
2242 pEvt
->mnEnd
= pEvt
->maText
.getLength();
2244 pEvt
->mnEnd
= aSelRange
.Max();
2247 static void ImplHandleSurroundingTextSelectionChange( vcl::Window
*pWindow
,
2251 vcl::Window
* pChild
= ImplGetKeyInputWindow( pWindow
);
2254 CommandSelectionChangeData
data( nStart
, nEnd
);
2255 ImplCallCommand( pChild
, CommandEventId::SelectionChange
, &data
);
2259 static void ImplHandleStartReconversion( vcl::Window
*pWindow
)
2261 vcl::Window
* pChild
= ImplGetKeyInputWindow( pWindow
);
2263 ImplCallCommand( pChild
, CommandEventId::PrepareReconversion
);
2266 static void ImplHandleSalQueryCharPosition( vcl::Window
*pWindow
,
2267 SalQueryCharPositionEvent
*pEvt
)
2269 pEvt
->mbValid
= false;
2270 pEvt
->mbVertical
= false;
2271 pEvt
->mnCursorBoundX
= 0;
2272 pEvt
->mnCursorBoundY
= 0;
2273 pEvt
->mnCursorBoundWidth
= 0;
2274 pEvt
->mnCursorBoundHeight
= 0;
2276 ImplSVData
* pSVData
= ImplGetSVData();
2277 vcl::Window
* pChild
= pSVData
->maWinData
.mpExtTextInputWin
;
2280 pChild
= ImplGetKeyInputWindow( pWindow
);
2283 // Test, if the Window is related to the frame
2284 if ( !pWindow
->ImplIsWindowOrChild( pChild
) )
2285 pChild
= ImplGetKeyInputWindow( pWindow
);
2290 ImplCallCommand( pChild
, CommandEventId::QueryCharPosition
);
2292 ImplWinData
* pWinData
= pChild
->ImplGetWinData();
2293 if ( pWinData
->mpCompositionCharRects
&& pEvt
->mnCharPos
< static_cast<sal_uLong
>( pWinData
->mnCompositionCharRects
) )
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;
2309 bool ImplWindowFrameProc( vcl::Window
* _pWindow
, SalEvent nEvent
, const void* pEvent
)
2311 DBG_TESTSOLARMUTEX();
2313 // Ensure the window survives during this method.
2314 VclPtr
<vcl::Window
> pWindow( _pWindow
);
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 )
2326 case SalEvent::MouseMove
:
2327 bRet
= ImplHandleSalMouseMove( pWindow
, static_cast<SalMouseEvent
const *>(pEvent
) );
2329 case SalEvent::ExternalMouseMove
:
2331 MouseEvent
const * pMouseEvt
= static_cast<MouseEvent
const *>(pEvent
);
2332 SalMouseEvent aSalMouseEvent
;
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();
2340 bRet
= ImplHandleSalMouseMove( pWindow
, &aSalMouseEvent
);
2343 case SalEvent::MouseLeave
:
2344 bRet
= ImplHandleSalMouseLeave( pWindow
, static_cast<SalMouseEvent
const *>(pEvent
) );
2346 case SalEvent::MouseButtonDown
:
2347 bRet
= ImplHandleSalMouseButtonDown( pWindow
, static_cast<SalMouseEvent
const *>(pEvent
) );
2349 case SalEvent::ExternalMouseButtonDown
:
2351 MouseEvent
const * pMouseEvt
= static_cast<MouseEvent
const *>(pEvent
);
2352 SalMouseEvent aSalMouseEvent
;
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();
2360 bRet
= ImplHandleSalMouseButtonDown( pWindow
, &aSalMouseEvent
);
2363 case SalEvent::MouseButtonUp
:
2364 bRet
= ImplHandleSalMouseButtonUp( pWindow
, static_cast<SalMouseEvent
const *>(pEvent
) );
2366 case SalEvent::ExternalMouseButtonUp
:
2368 MouseEvent
const * pMouseEvt
= static_cast<MouseEvent
const *>(pEvent
);
2369 SalMouseEvent aSalMouseEvent
;
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();
2377 bRet
= ImplHandleSalMouseButtonUp( pWindow
, &aSalMouseEvent
);
2380 case SalEvent::MouseActivate
:
2383 case SalEvent::KeyInput
:
2385 SalKeyEvent
const * pKeyEvt
= static_cast<SalKeyEvent
const *>(pEvent
);
2386 bRet
= ImplHandleKey( pWindow
, MouseNotifyEvent::KEYINPUT
,
2387 pKeyEvt
->mnCode
, pKeyEvt
->mnCharCode
, pKeyEvt
->mnRepeat
, true );
2390 case SalEvent::ExternalKeyInput
:
2392 KeyEvent
const * pKeyEvt
= static_cast<KeyEvent
const *>(pEvent
);
2393 bRet
= ImplHandleKey( pWindow
, MouseNotifyEvent::KEYINPUT
,
2394 pKeyEvt
->GetKeyCode().GetFullCode(), pKeyEvt
->GetCharCode(), pKeyEvt
->GetRepeat(), false );
2397 case SalEvent::KeyUp
:
2399 SalKeyEvent
const * pKeyEvt
= static_cast<SalKeyEvent
const *>(pEvent
);
2400 bRet
= ImplHandleKey( pWindow
, MouseNotifyEvent::KEYUP
,
2401 pKeyEvt
->mnCode
, pKeyEvt
->mnCharCode
, pKeyEvt
->mnRepeat
, true );
2404 case SalEvent::ExternalKeyUp
:
2406 KeyEvent
const * pKeyEvt
= static_cast<KeyEvent
const *>(pEvent
);
2407 bRet
= ImplHandleKey( pWindow
, MouseNotifyEvent::KEYUP
,
2408 pKeyEvt
->GetKeyCode().GetFullCode(), pKeyEvt
->GetCharCode(), pKeyEvt
->GetRepeat(), false );
2411 case SalEvent::KeyModChange
:
2412 ImplHandleSalKeyMod( pWindow
, static_cast<SalKeyModEvent
const *>(pEvent
) );
2415 case SalEvent::InputLanguageChange
:
2416 ImplHandleInputLanguageChange( pWindow
);
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
);
2427 case SalEvent::WheelMouse
:
2428 bRet
= ImplHandleWheelEvent( pWindow
, *static_cast<const SalWheelMouseEvent
*>(pEvent
));
2431 case SalEvent::Paint
:
2433 SalPaintEvent
const * pPaintEvt
= static_cast<SalPaintEvent
const *>(pEvent
);
2435 if( AllSettings::GetLayoutRTL() )
2437 SalFrame
* pSalFrame
= pWindow
->ImplGetWindowImpl()->mpFrame
;
2438 const_cast<SalPaintEvent
*>(pPaintEvt
)->mnBoundX
= pSalFrame
->maGeometry
.nWidth
-pPaintEvt
->mnBoundWidth
-pPaintEvt
->mnBoundX
;
2441 tools::Rectangle
aBoundRect( Point( pPaintEvt
->mnBoundX
, pPaintEvt
->mnBoundY
),
2442 Size( pPaintEvt
->mnBoundWidth
, pPaintEvt
->mnBoundHeight
) );
2443 ImplHandlePaint( pWindow
, aBoundRect
, pPaintEvt
->mbImmediateUpdate
);
2447 case SalEvent::Move
:
2448 ImplHandleMove( pWindow
);
2451 case SalEvent::Resize
:
2455 pWindow
->ImplGetWindowImpl()->mpFrame
->GetClientSize( nNewWidth
, nNewHeight
);
2456 ImplHandleResize( pWindow
, nNewWidth
, nNewHeight
);
2460 case SalEvent::MoveResize
:
2462 SalFrameGeometry g
= pWindow
->ImplGetWindowImpl()->mpFrame
->GetGeometry();
2463 ImplHandleMoveResize( pWindow
, g
.nWidth
, g
.nHeight
);
2467 case SalEvent::ClosePopups
:
2469 KillOwnPopups( pWindow
);
2473 case SalEvent::GetFocus
:
2474 ImplHandleGetFocus( pWindow
);
2476 case SalEvent::LoseFocus
:
2477 ImplHandleLoseFocus( pWindow
);
2480 case SalEvent::Close
:
2481 ImplHandleClose( pWindow
);
2484 case SalEvent::Shutdown
:
2486 static bool bInQueryExit
= false;
2489 bInQueryExit
= true;
2490 if ( GetpApp()->QueryExit() )
2492 // end the message loop
2493 Application::Quit();
2498 bInQueryExit
= false;
2505 case SalEvent::SettingsChanged
:
2506 case SalEvent::PrinterChanged
:
2507 case SalEvent::DisplayChanged
:
2508 case SalEvent::FontChanged
:
2509 ImplHandleSalSettings( nEvent
);
2512 case SalEvent::UserEvent
:
2513 ImplHandleUserEvent( const_cast<ImplSVEvent
*>(static_cast<ImplSVEvent
const *>(pEvent
)) );
2516 case SalEvent::ExtTextInput
:
2518 SalExtTextInputEvent
const * pEvt
= static_cast<SalExtTextInputEvent
const *>(pEvent
);
2519 bRet
= ImplHandleExtTextInput( pWindow
,
2520 pEvt
->maText
, pEvt
->mpTextAttr
,
2521 pEvt
->mnCursorPos
, pEvt
->mnCursorFlags
);
2524 case SalEvent::EndExtTextInput
:
2525 bRet
= ImplHandleEndExtTextInput();
2527 case SalEvent::ExtTextInputPos
:
2528 ImplHandleSalExtTextInputPos( pWindow
, const_cast<SalExtTextInputPosEvent
*>(static_cast<SalExtTextInputPosEvent
const *>(pEvent
)) );
2530 case SalEvent::InputContextChange
:
2531 bRet
= ImplHandleInputContextChange( pWindow
);
2533 case SalEvent::ShowDialog
:
2535 ShowDialogId nLOKWindowId
= static_cast<ShowDialogId
>(reinterpret_cast<sal_IntPtr
>(pEvent
));
2536 bRet
= ImplHandleShowDialog( pWindow
, nLOKWindowId
);
2539 case SalEvent::SurroundingTextRequest
:
2540 ImplHandleSalSurroundingTextRequest( pWindow
, const_cast<SalSurroundingTextRequestEvent
*>(static_cast<SalSurroundingTextRequestEvent
const *>(pEvent
)) );
2542 case SalEvent::SurroundingTextSelectionChange
:
2544 SalSurroundingTextSelectionChangeEvent
const * pEvt
2545 = static_cast<SalSurroundingTextSelectionChangeEvent
const *>(pEvent
);
2546 ImplHandleSurroundingTextSelectionChange( pWindow
,
2549 [[fallthrough
]]; // TODO: Fallthrough really intended?
2551 case SalEvent::StartReconversion
:
2552 ImplHandleStartReconversion( pWindow
);
2555 case SalEvent::QueryCharPosition
:
2556 ImplHandleSalQueryCharPosition( pWindow
, const_cast<SalQueryCharPositionEvent
*>(static_cast<SalQueryCharPositionEvent
const *>(pEvent
)) );
2559 case SalEvent::Swipe
:
2560 bRet
= ImplHandleSwipe(pWindow
, *static_cast<const SalSwipeEvent
*>(pEvent
));
2563 case SalEvent::LongPress
:
2564 bRet
= ImplHandleLongPress(pWindow
, *static_cast<const SalLongPressEvent
*>(pEvent
));
2567 case SalEvent::ExternalGesture
:
2569 auto const * pGestureEvent
= static_cast<GestureEvent
const *>(pEvent
);
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
;
2578 bRet
= ImplHandleGestureEvent(pWindow
, aSalGestureEvent
);
2581 case SalEvent::Gesture
:
2583 auto const * aSalGestureEvent
= static_cast<SalGestureEvent
const *>(pEvent
);
2584 bRet
= ImplHandleGestureEvent(pWindow
, *aSalGestureEvent
);
2588 SAL_WARN( "vcl.layout", "ImplWindowFrameProc(): unknown event (" << static_cast<int>(nEvent
) << ")" );
2595 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */