bump product version to 4.1.6.2
[LibreOffice.git] / vcl / source / window / winproc.cxx
blob73e5a7a6e8007d2c7873f80a818eb95d4d2d10d5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <vcl/i18nhelp.hxx>
26 #include <vcl/unohelp.hxx>
27 #include <vcl/timer.hxx>
28 #include <vcl/event.hxx>
29 #include <vcl/settings.hxx>
30 #include <vcl/svapp.hxx>
31 #include <vcl/cursor.hxx>
32 #include <vcl/wrkwin.hxx>
33 #include <vcl/floatwin.hxx>
34 #include <vcl/dialog.hxx>
35 #include <vcl/help.hxx>
36 #include <vcl/dockwin.hxx>
37 #include <vcl/menu.hxx>
39 #include <svdata.hxx>
40 #include <dbggui.hxx>
41 #include <salwtype.hxx>
42 #include <salframe.hxx>
43 #include <accmgr.hxx>
44 #include <print.h>
45 #include <window.h>
46 #include <helpwin.hxx>
47 #include <brdwin.hxx>
48 #include <salgdi.hxx>
49 #include <dndlcon.hxx>
51 #include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
52 #include <com/sun/star/awt/MouseEvent.hpp>
54 #if OSL_DEBUG_LEVEL > 1
55 char dbgbuffer[1024];
56 #ifndef WNT
57 #include <stdio.h>
58 #define MyOutputDebugString(s) (fprintf(stderr, s ))
59 #else
60 extern void MyOutputDebugString( char *s);
61 #endif
62 #endif
65 // =======================================================================
67 #define IMPL_MIN_NEEDSYSWIN 49
69 // =======================================================================
71 long ImplCallPreNotify( NotifyEvent& rEvt )
73 long nRet = Application::CallEventHooks( rEvt );
74 if ( !nRet )
75 nRet = rEvt.GetWindow()->PreNotify( rEvt );
76 return nRet;
79 // =======================================================================
81 long ImplCallEvent( NotifyEvent& rEvt )
83 long nRet = ImplCallPreNotify( rEvt );
84 if ( !nRet )
86 Window* pWindow = rEvt.GetWindow();
87 switch ( rEvt.GetType() )
89 case EVENT_MOUSEBUTTONDOWN:
90 pWindow->MouseButtonDown( *rEvt.GetMouseEvent() );
91 break;
92 case EVENT_MOUSEBUTTONUP:
93 pWindow->MouseButtonUp( *rEvt.GetMouseEvent() );
94 break;
95 case EVENT_MOUSEMOVE:
96 pWindow->MouseMove( *rEvt.GetMouseEvent() );
97 break;
98 case EVENT_KEYINPUT:
99 pWindow->KeyInput( *rEvt.GetKeyEvent() );
100 break;
101 case EVENT_KEYUP:
102 pWindow->KeyUp( *rEvt.GetKeyEvent() );
103 break;
104 case EVENT_GETFOCUS:
105 pWindow->GetFocus();
106 break;
107 case EVENT_LOSEFOCUS:
108 pWindow->LoseFocus();
109 break;
110 case EVENT_COMMAND:
111 pWindow->Command( *rEvt.GetCommandEvent() );
112 break;
116 return nRet;
119 // =======================================================================
121 static sal_Bool ImplHandleMouseFloatMode( Window* pChild, const Point& rMousePos,
122 sal_uInt16 nCode, sal_uInt16 nSVEvent,
123 sal_Bool bMouseLeave )
125 ImplSVData* pSVData = ImplGetSVData();
127 if ( pSVData->maWinData.mpFirstFloat && !pSVData->maWinData.mpCaptureWin &&
128 !pSVData->maWinData.mpFirstFloat->ImplIsFloatPopupModeWindow( pChild ) )
131 * #93895# since floats are system windows, coordinates have
132 * to be converted to float relative for the hittest
134 sal_uInt16 nHitTest = IMPL_FLOATWIN_HITTEST_OUTSIDE;
135 FloatingWindow* pFloat = pSVData->maWinData.mpFirstFloat->ImplFloatHitTest( pChild, rMousePos, nHitTest );
136 FloatingWindow* pLastLevelFloat;
137 sal_uLong nPopupFlags;
138 if ( nSVEvent == EVENT_MOUSEMOVE )
140 if ( bMouseLeave )
141 return sal_True;
143 if ( !pFloat || (nHitTest & IMPL_FLOATWIN_HITTEST_RECT) )
145 if ( pSVData->maHelpData.mpHelpWin && !pSVData->maHelpData.mbKeyboardHelp )
146 ImplDestroyHelpWindow( true );
147 pChild->ImplGetFrame()->SetPointer( POINTER_ARROW );
148 return sal_True;
151 else
153 if ( nCode & MOUSE_LEFT )
155 if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
157 if ( !pFloat )
159 pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
160 nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
161 pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
162 // Erstmal ausgebaut als Hack fuer Bug 53378
163 // if ( nPopupFlags & FLOATWIN_POPUPMODE_PATHMOUSECANCELCLICK )
164 // return sal_False;
165 // else
166 return sal_True;
168 else if ( nHitTest & IMPL_FLOATWIN_HITTEST_RECT )
170 if ( !(pFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOMOUSERECTCLOSE) )
171 pFloat->ImplSetMouseDown();
172 return sal_True;
175 else
177 if ( pFloat )
179 if ( nHitTest & IMPL_FLOATWIN_HITTEST_RECT )
181 if ( pFloat->ImplIsMouseDown() )
182 pFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL );
183 return sal_True;
186 else
188 pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
189 nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
190 if ( !(nPopupFlags & FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE) )
192 pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
193 return sal_True;
198 else
200 if ( !pFloat )
202 pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
203 nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
204 if ( nPopupFlags & FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE )
206 if ( (nPopupFlags & FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE) &&
207 (nSVEvent == EVENT_MOUSEBUTTONUP) )
208 return sal_True;
209 pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
210 if ( nPopupFlags & FLOATWIN_POPUPMODE_PATHMOUSECANCELCLICK )
211 return sal_False;
212 else
213 return sal_True;
215 else
216 return sal_True;
222 return sal_False;
225 // -----------------------------------------------------------------------
227 static void ImplHandleMouseHelpRequest( Window* pChild, const Point& rMousePos )
229 ImplSVData* pSVData = ImplGetSVData();
230 if ( !pSVData->maHelpData.mpHelpWin ||
231 !( pSVData->maHelpData.mpHelpWin->IsWindowOrChild( pChild ) ||
232 pChild->IsWindowOrChild( pSVData->maHelpData.mpHelpWin ) ) )
234 sal_uInt16 nHelpMode = 0;
235 if ( pSVData->maHelpData.mbQuickHelp )
236 nHelpMode = HELPMODE_QUICK;
237 if ( pSVData->maHelpData.mbBalloonHelp )
238 nHelpMode |= HELPMODE_BALLOON;
239 if ( nHelpMode )
241 if ( pChild->IsInputEnabled() && !pChild->IsInModalNonRefMode() )
243 HelpEvent aHelpEvent( rMousePos, nHelpMode );
244 pSVData->maHelpData.mbRequestingHelp = sal_True;
245 pChild->RequestHelp( aHelpEvent );
246 pSVData->maHelpData.mbRequestingHelp = sal_False;
248 // #104172# do not kill keyboard activated tooltips
249 else if ( pSVData->maHelpData.mpHelpWin && !pSVData->maHelpData.mbKeyboardHelp)
251 ImplDestroyHelpWindow( true );
257 // -----------------------------------------------------------------------
259 static void ImplSetMousePointer( Window* pChild )
261 ImplSVData* pSVData = ImplGetSVData();
262 if ( pSVData->maHelpData.mbExtHelpMode )
263 pChild->ImplGetFrame()->SetPointer( POINTER_HELP );
264 else
265 pChild->ImplGetFrame()->SetPointer( pChild->ImplGetMousePointer() );
268 // -----------------------------------------------------------------------
270 static sal_Bool ImplCallCommand( Window* pChild, sal_uInt16 nEvt, void* pData = NULL,
271 sal_Bool bMouse = sal_False, Point* pPos = NULL )
273 Point aPos;
274 if ( pPos )
275 aPos = *pPos;
276 else
278 if( bMouse )
279 aPos = pChild->GetPointerPosPixel();
280 else
282 // simulate mouseposition at center of window
283 Size aSize( pChild->GetOutputSizePixel() );
284 aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
288 CommandEvent aCEvt( aPos, nEvt, bMouse, pData );
289 NotifyEvent aNCmdEvt( EVENT_COMMAND, pChild, &aCEvt );
290 ImplDelData aDelData( pChild );
291 sal_Bool bPreNotify = (ImplCallPreNotify( aNCmdEvt ) != 0);
292 if ( aDelData.IsDead() )
293 return sal_False;
294 if ( !bPreNotify )
296 pChild->ImplGetWindowImpl()->mbCommand = sal_False;
297 pChild->Command( aCEvt );
299 if( aDelData.IsDead() )
300 return sal_False;
301 pChild->ImplNotifyKeyMouseCommandEventListeners( aNCmdEvt );
302 if ( aDelData.IsDead() )
303 return sal_False;
304 if ( pChild->ImplGetWindowImpl()->mbCommand )
305 return sal_True;
308 return sal_False;
311 // -----------------------------------------------------------------------
313 /* #i34277# delayed context menu activation;
314 * necessary if there already was a popup menu running.
317 struct ContextMenuEvent
319 Window* pWindow;
320 ImplDelData aDelData;
321 Point aChildPos;
324 static long ContextMenuEventLink( void* pCEvent, void* )
326 ContextMenuEvent* pEv = (ContextMenuEvent*)pCEvent;
328 if( ! pEv->aDelData.IsDead() )
330 pEv->pWindow->ImplRemoveDel( &pEv->aDelData );
331 ImplCallCommand( pEv->pWindow, COMMAND_CONTEXTMENU, NULL, sal_True, &pEv->aChildPos );
333 delete pEv;
335 return 0;
338 long ImplHandleMouseEvent( Window* pWindow, sal_uInt16 nSVEvent, sal_Bool bMouseLeave,
339 long nX, long nY, sal_uLong nMsgTime,
340 sal_uInt16 nCode, sal_uInt16 nMode )
342 ImplSVData* pSVData = ImplGetSVData();
343 Point aMousePos( nX, nY );
344 Window* pChild;
345 long nRet;
346 sal_uInt16 nClicks;
347 ImplFrameData* pWinFrameData = pWindow->ImplGetFrameData();
348 sal_uInt16 nOldCode = pWinFrameData->mnMouseCode;
350 // we need a mousemove event, befor we get a mousebuttondown or a
351 // mousebuttonup event
352 if ( (nSVEvent == EVENT_MOUSEBUTTONDOWN) ||
353 (nSVEvent == EVENT_MOUSEBUTTONUP) )
355 if ( (nSVEvent == EVENT_MOUSEBUTTONUP) && pSVData->maHelpData.mbExtHelpMode )
356 Help::EndExtHelp();
357 if ( pSVData->maHelpData.mpHelpWin )
359 if( pWindow->ImplGetWindow() == pSVData->maHelpData.mpHelpWin )
361 ImplDestroyHelpWindow( false );
362 return 1; // pWindow is dead now - avoid crash!
364 else
365 ImplDestroyHelpWindow( true );
368 if ( (pWinFrameData->mnLastMouseX != nX) ||
369 (pWinFrameData->mnLastMouseY != nY) )
371 ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, sal_False, nX, nY, nMsgTime, nCode, nMode );
375 // update frame data
376 pWinFrameData->mnBeforeLastMouseX = pWinFrameData->mnLastMouseX;
377 pWinFrameData->mnBeforeLastMouseY = pWinFrameData->mnLastMouseY;
378 pWinFrameData->mnLastMouseX = nX;
379 pWinFrameData->mnLastMouseY = nY;
380 pWinFrameData->mnMouseCode = nCode;
381 pWinFrameData->mnMouseMode = nMode & ~(MOUSE_SYNTHETIC | MOUSE_MODIFIERCHANGED);
382 if ( bMouseLeave )
384 pWinFrameData->mbMouseIn = sal_False;
385 if ( pSVData->maHelpData.mpHelpWin && !pSVData->maHelpData.mbKeyboardHelp )
387 ImplDelData aDelData( pWindow );
389 ImplDestroyHelpWindow( true );
391 if ( aDelData.IsDead() )
392 return 1; // pWindow is dead now - avoid crash! (#122045#)
395 else
396 pWinFrameData->mbMouseIn = sal_True;
398 DBG_ASSERT( !pSVData->maWinData.mpTrackWin ||
399 (pSVData->maWinData.mpTrackWin == pSVData->maWinData.mpCaptureWin),
400 "ImplHandleMouseEvent: TrackWin != CaptureWin" );
402 // AutoScrollMode
403 if ( pSVData->maWinData.mpAutoScrollWin && (nSVEvent == EVENT_MOUSEBUTTONDOWN) )
405 pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
406 return 1;
409 // find mouse window
410 if ( pSVData->maWinData.mpCaptureWin )
412 pChild = pSVData->maWinData.mpCaptureWin;
414 DBG_ASSERT( pWindow == pChild->ImplGetFrameWindow(),
415 "ImplHandleMouseEvent: mouse event is not sent to capture window" );
417 // java client cannot capture mouse correctly
418 if ( pWindow != pChild->ImplGetFrameWindow() )
419 return 0;
421 if ( bMouseLeave )
422 return 0;
424 else
426 if ( bMouseLeave )
427 pChild = NULL;
428 else
429 pChild = pWindow->ImplFindWindow( aMousePos );
432 // test this because mouse events are buffered in the remote version
433 // and size may not be in sync
434 if ( !pChild && !bMouseLeave )
435 return 0;
437 // execute a few tests and catch the message or implement the status
438 if ( pChild )
440 if( pChild->ImplIsAntiparallel() )
442 // - RTL - re-mirror frame pos at pChild
443 pChild->ImplReMirror( aMousePos );
445 // no mouse messages to system object windows ?
446 // !!!KA: Is it OK to comment this out? !!!
447 // if ( pChild->ImplGetWindowImpl()->mpSysObj )
448 // return 0;
450 // no mouse messages to disabled windows
451 // #106845# if the window was disabed during capturing we have to pass the mouse events to release capturing
452 if ( pSVData->maWinData.mpCaptureWin != pChild && (!pChild->IsEnabled() || !pChild->IsInputEnabled() || pChild->IsInModalNonRefMode() ) )
454 ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave );
455 if ( nSVEvent == EVENT_MOUSEMOVE )
457 ImplHandleMouseHelpRequest( pChild, aMousePos );
458 if( pWinFrameData->mpMouseMoveWin != pChild )
459 nMode |= MOUSE_ENTERWINDOW;
462 // Call the hook also, if Window is disabled
463 Point aChildPos = pChild->ImplFrameToOutput( aMousePos );
464 MouseEvent aMEvt( aChildPos, pWinFrameData->mnClickCount, nMode, nCode, nCode );
465 NotifyEvent aNEvt( nSVEvent, pChild, &aMEvt );
466 Application::CallEventHooks( aNEvt );
468 if( pChild->IsCallHandlersOnInputDisabled() )
470 pWinFrameData->mpMouseMoveWin = pChild;
471 pChild->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
474 if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
475 return 1;
476 else
478 // Set normal MousePointer for disabled windows
479 if ( nSVEvent == EVENT_MOUSEMOVE )
480 ImplSetMousePointer( pChild );
482 return 0;
486 // End ExtTextInput-Mode, if the user click in the same TopLevel Window
487 if ( pSVData->maWinData.mpExtTextInputWin &&
488 ((nSVEvent == EVENT_MOUSEBUTTONDOWN) ||
489 (nSVEvent == EVENT_MOUSEBUTTONUP)) )
490 pSVData->maWinData.mpExtTextInputWin->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
493 // determine mouse event data
494 if ( nSVEvent == EVENT_MOUSEMOVE )
496 // check if MouseMove belongs to same window and if the
497 // status did not change
498 if ( pChild )
500 Point aChildMousePos = pChild->ImplFrameToOutput( aMousePos );
501 if ( !bMouseLeave &&
502 (pChild == pWinFrameData->mpMouseMoveWin) &&
503 (aChildMousePos.X() == pWinFrameData->mnLastMouseWinX) &&
504 (aChildMousePos.Y() == pWinFrameData->mnLastMouseWinY) &&
505 (nOldCode == pWinFrameData->mnMouseCode) )
507 // set mouse pointer anew, as it could have changed
508 // due to the mode switch
509 ImplSetMousePointer( pChild );
510 return 0;
513 pWinFrameData->mnLastMouseWinX = aChildMousePos.X();
514 pWinFrameData->mnLastMouseWinY = aChildMousePos.Y();
517 // mouse click
518 nClicks = pWinFrameData->mnClickCount;
520 // call Start-Drag handler if required
521 // Warning: should be called before Move, as otherwise during
522 // fast mouse movements the applications move to the selection state
523 Window* pMouseDownWin = pWinFrameData->mpMouseDownWin;
524 if ( pMouseDownWin )
526 // check for matching StartDrag mode. We only compare
527 // the status of the mouse buttons, such that e. g. Mod1 can
528 // change immediately to the copy mode
529 const MouseSettings& rMSettings = pMouseDownWin->GetSettings().GetMouseSettings();
530 if ( (nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) ==
531 (rMSettings.GetStartDragCode() & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) )
533 if ( !pMouseDownWin->ImplGetFrameData()->mbStartDragCalled )
535 long nDragW = rMSettings.GetStartDragWidth();
536 long nDragH = rMSettings.GetStartDragWidth();
537 //long nMouseX = nX;
538 //long nMouseY = nY;
539 long nMouseX = aMousePos.X(); // #106074# use the possibly re-mirrored coordinates (RTL) ! nX,nY are unmodified !
540 long nMouseY = aMousePos.Y();
541 if ( !(((nMouseX-nDragW) <= pMouseDownWin->ImplGetFrameData()->mnFirstMouseX) &&
542 ((nMouseX+nDragW) >= pMouseDownWin->ImplGetFrameData()->mnFirstMouseX)) ||
543 !(((nMouseY-nDragH) <= pMouseDownWin->ImplGetFrameData()->mnFirstMouseY) &&
544 ((nMouseY+nDragH) >= pMouseDownWin->ImplGetFrameData()->mnFirstMouseY)) )
546 pMouseDownWin->ImplGetFrameData()->mbStartDragCalled = sal_True;
548 // Check if drag source provides it's own recognizer
549 if( pMouseDownWin->ImplGetFrameData()->mbInternalDragGestureRecognizer )
551 // query DropTarget from child window
552 ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureRecognizer > xDragGestureRecognizer =
553 ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureRecognizer > ( pMouseDownWin->ImplGetWindowImpl()->mxDNDListenerContainer,
554 ::com::sun::star::uno::UNO_QUERY );
556 if( xDragGestureRecognizer.is() )
558 // retrieve mouse position relative to mouse down window
559 Point relLoc = pMouseDownWin->ImplFrameToOutput( Point(
560 pMouseDownWin->ImplGetFrameData()->mnFirstMouseX,
561 pMouseDownWin->ImplGetFrameData()->mnFirstMouseY ) );
563 // create a uno mouse event out of the available data
564 ::com::sun::star::awt::MouseEvent aMouseEvent(
565 static_cast < ::com::sun::star::uno::XInterface * > ( 0 ),
566 #ifdef MACOSX
567 nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3),
568 #else
569 nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2),
570 #endif
571 nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE),
572 nMouseX,
573 nMouseY,
574 nClicks,
575 sal_False );
577 sal_uLong nCount = Application::ReleaseSolarMutex();
579 // FIXME: where do I get Action from ?
580 ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragSource > xDragSource = pMouseDownWin->GetDragSource();
582 if( xDragSource.is() )
584 static_cast < DNDListenerContainer * > ( xDragGestureRecognizer.get() )->fireDragGestureEvent( 0,
585 relLoc.X(), relLoc.Y(), xDragSource, ::com::sun::star::uno::makeAny( aMouseEvent ) );
588 Application::AcquireSolarMutex( nCount );
594 else
595 pMouseDownWin->ImplGetFrameData()->mbStartDragCalled = sal_True;
598 // test for mouseleave and mouseenter
599 Window* pMouseMoveWin = pWinFrameData->mpMouseMoveWin;
600 if ( pChild != pMouseMoveWin )
602 if ( pMouseMoveWin )
604 Point aLeaveMousePos = pMouseMoveWin->ImplFrameToOutput( aMousePos );
605 MouseEvent aMLeaveEvt( aLeaveMousePos, nClicks, nMode | MOUSE_LEAVEWINDOW, nCode, nCode );
606 NotifyEvent aNLeaveEvt( EVENT_MOUSEMOVE, pMouseMoveWin, &aMLeaveEvt );
607 ImplDelData aDelData;
608 ImplDelData aDelData2;
609 pWinFrameData->mbInMouseMove = sal_True;
610 pMouseMoveWin->ImplGetWinData()->mbMouseOver = sal_False;
611 pMouseMoveWin->ImplAddDel( &aDelData );
613 // A MouseLeave can destroy this window
614 if ( pChild )
615 pChild->ImplAddDel( &aDelData2 );
616 if ( !ImplCallPreNotify( aNLeaveEvt ) )
618 pMouseMoveWin->MouseMove( aMLeaveEvt );
619 // #82968#
620 if( !aDelData.IsDead() )
621 aNLeaveEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNLeaveEvt );
624 pWinFrameData->mpMouseMoveWin = NULL;
625 pWinFrameData->mbInMouseMove = sal_False;
627 if ( pChild )
629 if ( aDelData2.IsDead() )
630 pChild = NULL;
631 else
632 pChild->ImplRemoveDel( &aDelData2 );
634 if ( aDelData.IsDead() )
635 return 1;
636 pMouseMoveWin->ImplRemoveDel( &aDelData );
639 nMode |= MOUSE_ENTERWINDOW;
641 pWinFrameData->mpMouseMoveWin = pChild;
642 if( pChild )
643 pChild->ImplGetWinData()->mbMouseOver = sal_True;
645 // MouseLeave
646 if ( !pChild )
647 return 0;
649 else
651 // mouse click
652 if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
654 const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
655 sal_uLong nDblClkTime = rMSettings.GetDoubleClickTime();
656 long nDblClkW = rMSettings.GetDoubleClickWidth();
657 long nDblClkH = rMSettings.GetDoubleClickHeight();
658 //long nMouseX = nX;
659 //long nMouseY = nY;
660 long nMouseX = aMousePos.X(); // #106074# use the possibly re-mirrored coordinates (RTL) ! nX,nY are unmodified !
661 long nMouseY = aMousePos.Y();
663 if ( (pChild == pChild->ImplGetFrameData()->mpMouseDownWin) &&
664 (nCode == pChild->ImplGetFrameData()->mnFirstMouseCode) &&
665 ((nMsgTime-pChild->ImplGetFrameData()->mnMouseDownTime) < nDblClkTime) &&
666 ((nMouseX-nDblClkW) <= pChild->ImplGetFrameData()->mnFirstMouseX) &&
667 ((nMouseX+nDblClkW) >= pChild->ImplGetFrameData()->mnFirstMouseX) &&
668 ((nMouseY-nDblClkH) <= pChild->ImplGetFrameData()->mnFirstMouseY) &&
669 ((nMouseY+nDblClkH) >= pChild->ImplGetFrameData()->mnFirstMouseY) )
671 pChild->ImplGetFrameData()->mnClickCount++;
672 pChild->ImplGetFrameData()->mbStartDragCalled = sal_True;
674 else
676 pChild->ImplGetFrameData()->mpMouseDownWin = pChild;
677 pChild->ImplGetFrameData()->mnClickCount = 1;
678 pChild->ImplGetFrameData()->mnFirstMouseX = nMouseX;
679 pChild->ImplGetFrameData()->mnFirstMouseY = nMouseY;
680 pChild->ImplGetFrameData()->mnFirstMouseCode = nCode;
681 pChild->ImplGetFrameData()->mbStartDragCalled = !((nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) ==
682 (rMSettings.GetStartDragCode() & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)));
684 pChild->ImplGetFrameData()->mnMouseDownTime = nMsgTime;
686 nClicks = pChild->ImplGetFrameData()->mnClickCount;
688 pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
691 DBG_ASSERT( pChild, "ImplHandleMouseEvent: pChild == NULL" );
693 // create mouse event
694 Point aChildPos = pChild->ImplFrameToOutput( aMousePos );
695 MouseEvent aMEvt( aChildPos, nClicks, nMode, nCode, nCode );
697 // tracking window gets the mouse events
698 if ( pSVData->maWinData.mpTrackWin )
699 pChild = pSVData->maWinData.mpTrackWin;
701 // handle FloatingMode
702 if ( !pSVData->maWinData.mpTrackWin && pSVData->maWinData.mpFirstFloat )
704 ImplDelData aDelData;
705 pChild->ImplAddDel( &aDelData );
706 if ( ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave ) )
708 if ( !aDelData.IsDead() )
710 pChild->ImplRemoveDel( &aDelData );
711 pChild->ImplGetFrameData()->mbStartDragCalled = sal_True;
713 return 1;
715 else
716 pChild->ImplRemoveDel( &aDelData );
719 // call handler
720 sal_Bool bDrag = sal_False;
721 sal_Bool bCallHelpRequest = sal_True;
722 DBG_ASSERT( pChild, "ImplHandleMouseEvent: pChild is NULL" );
724 ImplDelData aDelData;
725 NotifyEvent aNEvt( nSVEvent, pChild, &aMEvt );
726 pChild->ImplAddDel( &aDelData );
727 if ( nSVEvent == EVENT_MOUSEMOVE )
728 pChild->ImplGetFrameData()->mbInMouseMove = sal_True;
730 // bring window into foreground on mouseclick
731 if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
733 if( !pSVData->maWinData.mpFirstFloat && // totop for floating windows in popup would change the focus and would close them immediately
734 !(pChild->ImplGetFrameWindow()->GetStyle() & WB_OWNERDRAWDECORATION) ) // ownerdrawdecorated windows must never grab focus
735 pChild->ToTop();
736 if ( aDelData.IsDead() )
737 return 1;
740 if ( ImplCallPreNotify( aNEvt ) || aDelData.IsDead() )
741 nRet = 1;
742 else
744 nRet = 0;
745 if ( nSVEvent == EVENT_MOUSEMOVE )
747 if ( pSVData->maWinData.mpTrackWin )
749 TrackingEvent aTEvt( aMEvt );
750 pChild->Tracking( aTEvt );
751 if ( !aDelData.IsDead() )
753 // When ScrollRepeat, we restart the timer
754 if ( pSVData->maWinData.mpTrackTimer &&
755 (pSVData->maWinData.mnTrackFlags & STARTTRACK_SCROLLREPEAT) )
756 pSVData->maWinData.mpTrackTimer->Start();
758 bCallHelpRequest = sal_False;
759 nRet = 1;
761 else
763 // Auto-ToTop
764 if ( !pSVData->maWinData.mpCaptureWin &&
765 (pChild->GetSettings().GetMouseSettings().GetOptions() & MOUSE_OPTION_AUTOFOCUS) )
766 pChild->ToTop( TOTOP_NOGRABFOCUS );
768 if( aDelData.IsDead() )
769 bCallHelpRequest = sal_False;
770 else
772 // if the MouseMove handler changes the help window's visibility
773 // the HelpRequest handler should not be called anymore
774 Window* pOldHelpTextWin = pSVData->maHelpData.mpHelpWin;
775 pChild->ImplGetWindowImpl()->mbMouseMove = sal_False;
776 pChild->MouseMove( aMEvt );
777 if ( pOldHelpTextWin != pSVData->maHelpData.mpHelpWin )
778 bCallHelpRequest = sal_False;
782 else if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
784 if ( pSVData->maWinData.mpTrackWin &&
785 !(pSVData->maWinData.mnTrackFlags & STARTTRACK_MOUSEBUTTONDOWN) )
786 nRet = 1;
787 else
789 pChild->ImplGetWindowImpl()->mbMouseButtonDown = sal_False;
790 pChild->MouseButtonDown( aMEvt );
793 else
795 if ( pSVData->maWinData.mpTrackWin )
797 pChild->EndTracking();
798 nRet = 1;
800 else
802 pChild->ImplGetWindowImpl()->mbMouseButtonUp = sal_False;
803 pChild->MouseButtonUp( aMEvt );
807 // #82968#
808 if ( !aDelData.IsDead() )
809 aNEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
812 if ( aDelData.IsDead() )
813 return 1;
816 if ( nSVEvent == EVENT_MOUSEMOVE )
817 pChild->ImplGetWindowImpl()->mpFrameData->mbInMouseMove = sal_False;
819 if ( nSVEvent == EVENT_MOUSEMOVE )
821 if ( bCallHelpRequest && !pSVData->maHelpData.mbKeyboardHelp )
822 ImplHandleMouseHelpRequest( pChild, pChild->OutputToScreenPixel( aMEvt.GetPosPixel() ) );
823 nRet = 1;
825 else if ( !nRet )
827 if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
829 if ( !pChild->ImplGetWindowImpl()->mbMouseButtonDown )
830 nRet = 1;
832 else
834 if ( !pChild->ImplGetWindowImpl()->mbMouseButtonUp )
835 nRet = 1;
839 pChild->ImplRemoveDel( &aDelData );
841 if ( nSVEvent == EVENT_MOUSEMOVE )
843 // set new mouse pointer
844 if ( !bMouseLeave )
845 ImplSetMousePointer( pChild );
847 else if ( (nSVEvent == EVENT_MOUSEBUTTONDOWN) || (nSVEvent == EVENT_MOUSEBUTTONUP) )
849 if ( !bDrag )
851 // Command-Events
852 if ( /*(nRet == 0) &&*/ (nClicks == 1) && (nSVEvent == EVENT_MOUSEBUTTONDOWN) &&
853 (nCode == MOUSE_MIDDLE) )
855 sal_uInt16 nMiddleAction = pChild->GetSettings().GetMouseSettings().GetMiddleButtonAction();
856 if ( nMiddleAction == MOUSE_MIDDLE_AUTOSCROLL )
857 nRet = !ImplCallCommand( pChild, COMMAND_STARTAUTOSCROLL, NULL, sal_True, &aChildPos );
858 else if ( nMiddleAction == MOUSE_MIDDLE_PASTESELECTION )
859 nRet = !ImplCallCommand( pChild, COMMAND_PASTESELECTION, NULL, sal_True, &aChildPos );
861 else
863 // ContextMenu
864 const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
865 if ( (nCode == rMSettings.GetContextMenuCode()) &&
866 (nClicks == rMSettings.GetContextMenuClicks()) )
868 sal_Bool bContextMenu;
869 if ( rMSettings.GetContextMenuDown() )
870 bContextMenu = (nSVEvent == EVENT_MOUSEBUTTONDOWN);
871 else
872 bContextMenu = (nSVEvent == EVENT_MOUSEBUTTONUP);
873 if ( bContextMenu )
875 if( pSVData->maAppData.mpActivePopupMenu )
877 /* #i34277# there already is a context menu open
878 * that was probably just closed with EndPopupMode.
879 * We need to give the eventual corresponding
880 * PopupMenu::Execute a chance to end properly.
881 * Therefore delay context menu command and
882 * issue only after popping one frame of the
883 * Yield stack.
885 ContextMenuEvent* pEv = new ContextMenuEvent;
886 pEv->pWindow = pChild;
887 pEv->aChildPos = aChildPos;
888 pChild->ImplAddDel( &pEv->aDelData );
889 Application::PostUserEvent( Link( pEv, ContextMenuEventLink ) );
891 else
892 nRet = ! ImplCallCommand( pChild, COMMAND_CONTEXTMENU, NULL, sal_True, &aChildPos );
899 return nRet;
902 // -----------------------------------------------------------------------
904 static Window* ImplGetKeyInputWindow( Window* pWindow )
906 ImplSVData* pSVData = ImplGetSVData();
908 // determine last input time
909 pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
911 // #127104# workaround for destroyed windows
912 if( pWindow->ImplGetWindowImpl() == NULL )
913 return 0;
915 // find window - is every time the window which has currently the
916 // focus or the last time the focus.
917 // the first floating window always has the focus
918 Window* pChild = pSVData->maWinData.mpFirstFloat;
919 if( !pChild || ( pChild->ImplGetWindowImpl()->mbFloatWin && !((FloatingWindow *)pChild)->GrabsFocus() ) )
920 pChild = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
921 else
923 // allow floaters to forward keyinput to some member
924 pChild = pChild->GetPreferredKeyInputWindow();
927 // no child - than no input
928 if ( !pChild )
929 return 0;
931 // We call also KeyInput if we haven't the focus, because on Unix
932 // system this is often the case when a Lookup Choise Window has
933 // the focus - because this windows send the KeyInput directly to
934 // the window without resetting the focus
935 DBG_ASSERTWARNING( pChild == pSVData->maWinData.mpFocusWin,
936 "ImplHandleKey: Keyboard-Input is sent to a frame without focus" );
938 // no keyinput to disabled windows
939 if ( !pChild->IsEnabled() || !pChild->IsInputEnabled() || pChild->IsInModalMode() )
940 return 0;
942 return pChild;
945 // -----------------------------------------------------------------------
947 static long ImplHandleKey( Window* pWindow, sal_uInt16 nSVEvent,
948 sal_uInt16 nKeyCode, sal_uInt16 nCharCode, sal_uInt16 nRepeat, sal_Bool bForward )
950 ImplSVData* pSVData = ImplGetSVData();
951 KeyCode aKeyCode( nKeyCode, nKeyCode );
952 sal_uInt16 nEvCode = aKeyCode.GetCode();
954 // allow application key listeners to remove the key event
955 // but make sure we're not forwarding external KeyEvents, (ie where bForward is sal_False)
956 // because those are coming back from the listener itself and MUST be processed
957 KeyEvent aKeyEvent( (sal_Unicode)nCharCode, aKeyCode, nRepeat );
958 if( bForward )
960 sal_uInt16 nVCLEvent;
961 switch( nSVEvent )
963 case EVENT_KEYINPUT:
964 nVCLEvent = VCLEVENT_WINDOW_KEYINPUT;
965 break;
966 case EVENT_KEYUP:
967 nVCLEvent = VCLEVENT_WINDOW_KEYUP;
968 break;
969 default:
970 nVCLEvent = 0;
971 break;
973 if( nVCLEvent && pSVData->mpApp->HandleKey( nVCLEvent, pWindow, &aKeyEvent ) )
974 return 1;
977 // #i1820# use locale specific decimal separator
978 if( nEvCode == KEY_DECIMAL )
980 if( Application::GetSettings().GetMiscSettings().GetEnableLocalizedDecimalSep() )
982 String aSep( pWindow->GetSettings().GetLocaleDataWrapper().getNumDecimalSep() );
983 nCharCode = (sal_uInt16) aSep.GetChar(0);
987 sal_Bool bCtrlF6 = (aKeyCode.GetCode() == KEY_F6) && aKeyCode.IsMod1();
989 // determine last input time
990 pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
992 // handle tracking window
993 if ( nSVEvent == EVENT_KEYINPUT )
995 #ifdef DBG_UTIL
996 // #105224# use Ctrl-Alt-Shift-D, Ctrl-Shift-D must be useable by app
997 if ( aKeyCode.IsShift() && aKeyCode.IsMod1() && (aKeyCode.IsMod2() || aKeyCode.IsMod3()) && (aKeyCode.GetCode() == KEY_D) )
999 DBGGUI_START();
1000 return 1;
1002 #endif
1004 if ( pSVData->maHelpData.mbExtHelpMode )
1006 Help::EndExtHelp();
1007 if ( nEvCode == KEY_ESCAPE )
1008 return 1;
1010 if ( pSVData->maHelpData.mpHelpWin )
1011 ImplDestroyHelpWindow( false );
1013 // AutoScrollMode
1014 if ( pSVData->maWinData.mpAutoScrollWin )
1016 pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
1017 if ( nEvCode == KEY_ESCAPE )
1018 return 1;
1021 if ( pSVData->maWinData.mpTrackWin )
1023 sal_uInt16 nOrigCode = aKeyCode.GetCode();
1025 if ( (nOrigCode == KEY_ESCAPE) && !(pSVData->maWinData.mnTrackFlags & STARTTRACK_NOKEYCANCEL) )
1027 pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL | ENDTRACK_KEY );
1028 if ( pSVData->maWinData.mpFirstFloat )
1030 FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
1031 if ( !(pLastLevelFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOKEYCLOSE) )
1033 sal_uInt16 nEscCode = aKeyCode.GetCode();
1035 if ( nEscCode == KEY_ESCAPE )
1036 pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
1039 return 1;
1041 else if ( nOrigCode == KEY_RETURN )
1043 pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_KEY );
1044 return 1;
1046 else if ( !(pSVData->maWinData.mnTrackFlags & STARTTRACK_KEYINPUT) )
1047 return 1;
1050 // handle FloatingMode
1051 if ( pSVData->maWinData.mpFirstFloat )
1053 FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
1054 if ( !(pLastLevelFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOKEYCLOSE) )
1056 sal_uInt16 nCode = aKeyCode.GetCode();
1058 if ( (nCode == KEY_ESCAPE) || bCtrlF6)
1060 pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
1061 if( !bCtrlF6 )
1062 return 1;
1067 // test for accel
1068 if ( pSVData->maAppData.mpAccelMgr )
1070 if ( pSVData->maAppData.mpAccelMgr->IsAccelKey( aKeyCode, nRepeat ) )
1071 return 1;
1075 // find window
1076 Window* pChild = ImplGetKeyInputWindow( pWindow );
1077 if ( !pChild )
1078 return 0;
1080 // --- RTL --- mirror cursor keys
1081 if( (aKeyCode.GetCode() == KEY_LEFT || aKeyCode.GetCode() == KEY_RIGHT) &&
1082 pChild->ImplHasMirroredGraphics() && pChild->IsRTLEnabled() )
1083 aKeyCode = KeyCode( aKeyCode.GetCode() == KEY_LEFT ? KEY_RIGHT : KEY_LEFT, aKeyCode.GetModifier() );
1085 // call handler
1086 ImplDelData aDelData;
1087 pChild->ImplAddDel( &aDelData );
1089 KeyEvent aKeyEvt( (sal_Unicode)nCharCode, aKeyCode, nRepeat );
1090 NotifyEvent aNotifyEvt( nSVEvent, pChild, &aKeyEvt );
1091 sal_Bool bKeyPreNotify = (ImplCallPreNotify( aNotifyEvt ) != 0);
1092 long nRet = 1;
1094 if ( !bKeyPreNotify && !aDelData.IsDead() )
1096 if ( nSVEvent == EVENT_KEYINPUT )
1098 pChild->ImplGetWindowImpl()->mbKeyInput = sal_False;
1099 pChild->KeyInput( aKeyEvt );
1101 else
1103 pChild->ImplGetWindowImpl()->mbKeyUp = sal_False;
1104 pChild->KeyUp( aKeyEvt );
1106 // #82968#
1107 if( !aDelData.IsDead() )
1108 aNotifyEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNotifyEvt );
1111 if ( aDelData.IsDead() )
1112 return 1;
1114 pChild->ImplRemoveDel( &aDelData );
1116 if ( nSVEvent == EVENT_KEYINPUT )
1118 if ( !bKeyPreNotify && pChild->ImplGetWindowImpl()->mbKeyInput )
1120 sal_uInt16 nCode = aKeyCode.GetCode();
1122 // #101999# is focus in or below toolbox
1123 sal_Bool bToolboxFocus=sal_False;
1124 if( (nCode == KEY_F1) && aKeyCode.IsShift() )
1126 Window *pWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1127 while( pWin )
1129 if( pWin->ImplGetWindowImpl()->mbToolBox )
1131 bToolboxFocus = sal_True;
1132 break;
1134 else
1135 pWin = pWin->GetParent();
1139 // ContextMenu
1140 if ( (nCode == KEY_CONTEXTMENU) || ((nCode == KEY_F10) && aKeyCode.IsShift() && !aKeyCode.IsMod1() && !aKeyCode.IsMod2() ) )
1141 nRet = !ImplCallCommand( pChild, COMMAND_CONTEXTMENU, NULL, sal_False );
1142 else if ( ( (nCode == KEY_F2) && aKeyCode.IsShift() ) || ( (nCode == KEY_F1) && aKeyCode.IsMod1() ) ||
1143 // #101999# no active help when focus in toolbox, simulate BallonHelp instead
1144 ( (nCode == KEY_F1) && aKeyCode.IsShift() && bToolboxFocus ) )
1146 // TipHelp via Keyboard (Shift-F2 or Ctrl-F1)
1147 // simulate mouseposition at center of window
1149 Size aSize = pChild->GetOutputSize();
1150 Point aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
1151 aPos = pChild->OutputToScreenPixel( aPos );
1153 HelpEvent aHelpEvent( aPos, HELPMODE_BALLOON );
1154 aHelpEvent.SetKeyboardActivated( sal_True );
1155 pSVData->maHelpData.mbSetKeyboardHelp = sal_True;
1156 pChild->RequestHelp( aHelpEvent );
1157 pSVData->maHelpData.mbSetKeyboardHelp = sal_False;
1159 else if ( (nCode == KEY_F1) || (nCode == KEY_HELP) )
1161 if ( !aKeyCode.GetModifier() )
1163 if ( pSVData->maHelpData.mbContextHelp )
1165 Point aMousePos = pChild->OutputToScreenPixel( pChild->GetPointerPosPixel() );
1166 HelpEvent aHelpEvent( aMousePos, HELPMODE_CONTEXT );
1167 pChild->RequestHelp( aHelpEvent );
1169 else
1170 nRet = 0;
1172 else if ( aKeyCode.IsShift() )
1174 if ( pSVData->maHelpData.mbExtHelp )
1175 Help::StartExtHelp();
1176 else
1177 nRet = 0;
1180 else
1182 if ( ImplCallHotKey( aKeyCode ) )
1183 nRet = 1;
1184 else
1185 nRet = 0;
1189 else
1191 if ( !bKeyPreNotify && pChild->ImplGetWindowImpl()->mbKeyUp )
1192 nRet = 0;
1195 // #105591# send keyinput to parent if we are a floating window and the key was not pocessed yet
1196 if( !nRet && pWindow->ImplGetWindowImpl()->mbFloatWin && pWindow->GetParent() && (pWindow->ImplGetWindowImpl()->mpFrame != pWindow->GetParent()->ImplGetWindowImpl()->mpFrame) )
1198 pChild = pWindow->GetParent();
1200 // call handler
1201 ImplDelData aChildDelData( pChild );
1202 KeyEvent aKEvt( (sal_Unicode)nCharCode, aKeyCode, nRepeat );
1203 NotifyEvent aNEvt( nSVEvent, pChild, &aKEvt );
1204 sal_Bool bPreNotify = (ImplCallPreNotify( aNEvt ) != 0);
1205 if ( aChildDelData.IsDead() )
1206 return 1;
1208 if ( !bPreNotify )
1210 if ( nSVEvent == EVENT_KEYINPUT )
1212 pChild->ImplGetWindowImpl()->mbKeyInput = sal_False;
1213 pChild->KeyInput( aKEvt );
1215 else
1217 pChild->ImplGetWindowImpl()->mbKeyUp = sal_False;
1218 pChild->KeyUp( aKEvt );
1220 // #82968#
1221 if( !aChildDelData.IsDead() )
1222 aNEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
1223 if ( aChildDelData.IsDead() )
1224 return 1;
1227 if( bPreNotify || !pChild->ImplGetWindowImpl()->mbKeyInput )
1228 nRet = 1;
1231 return nRet;
1234 // -----------------------------------------------------------------------
1236 static long ImplHandleExtTextInput( Window* pWindow,
1237 const XubString& rText,
1238 const sal_uInt16* pTextAttr,
1239 sal_uLong nCursorPos, sal_uInt16 nCursorFlags )
1241 ImplSVData* pSVData = ImplGetSVData();
1242 Window* pChild = NULL;
1244 int nTries = 200;
1245 while( nTries-- )
1247 pChild = pSVData->maWinData.mpExtTextInputWin;
1248 if ( !pChild )
1250 pChild = ImplGetKeyInputWindow( pWindow );
1251 if ( !pChild )
1252 return 0;
1254 if( !pChild->ImplGetWindowImpl()->mpFrameData->mnFocusId )
1255 break;
1256 Application::Yield();
1259 // If it is the first ExtTextInput call, we inform the information
1260 // and allocate the data, which we must store in this mode
1261 ImplWinData* pWinData = pChild->ImplGetWinData();
1262 if ( !pChild->ImplGetWindowImpl()->mbExtTextInput )
1264 pChild->ImplGetWindowImpl()->mbExtTextInput = sal_True;
1265 pWinData->mpExtOldText = new OUString;
1266 if ( pWinData->mpExtOldAttrAry )
1268 delete [] pWinData->mpExtOldAttrAry;
1269 pWinData->mpExtOldAttrAry = NULL;
1271 pSVData->maWinData.mpExtTextInputWin = pChild;
1272 ImplCallCommand( pChild, COMMAND_STARTEXTTEXTINPUT );
1275 // be aware of being recursively called in StartExtTextInput
1276 if ( !pChild->ImplGetWindowImpl()->mbExtTextInput )
1277 return 0;
1279 // Test for changes
1280 sal_Bool bOnlyCursor = sal_False;
1281 xub_StrLen nMinLen = std::min( pWinData->mpExtOldText->getLength(), sal_Int32(rText.Len()) );
1282 xub_StrLen nDeltaStart = 0;
1283 while ( nDeltaStart < nMinLen )
1285 if ( (*pWinData->mpExtOldText)[nDeltaStart] != rText.GetChar( nDeltaStart ) )
1286 break;
1287 nDeltaStart++;
1289 if ( pWinData->mpExtOldAttrAry || pTextAttr )
1291 if ( !pWinData->mpExtOldAttrAry || !pTextAttr )
1292 nDeltaStart = 0;
1293 else
1295 xub_StrLen i = 0;
1296 while ( i < nDeltaStart )
1298 if ( pWinData->mpExtOldAttrAry[i] != pTextAttr[i] )
1300 nDeltaStart = i;
1301 break;
1303 i++;
1307 if ( (nDeltaStart >= nMinLen) &&
1308 (pWinData->mpExtOldText->getLength() == rText.Len()) )
1309 bOnlyCursor = sal_True;
1311 // Call Event and store the information
1312 CommandExtTextInputData aData( rText, pTextAttr,
1313 (xub_StrLen)nCursorPos, nCursorFlags,
1314 nDeltaStart, pWinData->mpExtOldText->getLength(),
1315 bOnlyCursor );
1316 *pWinData->mpExtOldText = rText;
1317 if ( pWinData->mpExtOldAttrAry )
1319 delete [] pWinData->mpExtOldAttrAry;
1320 pWinData->mpExtOldAttrAry = NULL;
1322 if ( pTextAttr )
1324 pWinData->mpExtOldAttrAry = new sal_uInt16[rText.Len()];
1325 memcpy( pWinData->mpExtOldAttrAry, pTextAttr, rText.Len()*sizeof( sal_uInt16 ) );
1327 return !ImplCallCommand( pChild, COMMAND_EXTTEXTINPUT, &aData );
1330 // -----------------------------------------------------------------------
1332 static long ImplHandleEndExtTextInput( Window* /* pWindow */ )
1334 ImplSVData* pSVData = ImplGetSVData();
1335 Window* pChild = pSVData->maWinData.mpExtTextInputWin;
1336 long nRet = 0;
1338 if ( pChild )
1340 pChild->ImplGetWindowImpl()->mbExtTextInput = sal_False;
1341 pSVData->maWinData.mpExtTextInputWin = NULL;
1342 ImplWinData* pWinData = pChild->ImplGetWinData();
1343 if ( pWinData->mpExtOldText )
1345 delete pWinData->mpExtOldText;
1346 pWinData->mpExtOldText = NULL;
1348 if ( pWinData->mpExtOldAttrAry )
1350 delete [] pWinData->mpExtOldAttrAry;
1351 pWinData->mpExtOldAttrAry = NULL;
1353 nRet = !ImplCallCommand( pChild, COMMAND_ENDEXTTEXTINPUT );
1356 return nRet;
1359 // -----------------------------------------------------------------------
1361 static void ImplHandleExtTextInputPos( Window* pWindow,
1362 Rectangle& rRect, long& rInputWidth,
1363 bool * pVertical )
1365 ImplSVData* pSVData = ImplGetSVData();
1366 Window* pChild = pSVData->maWinData.mpExtTextInputWin;
1368 if ( !pChild )
1369 pChild = ImplGetKeyInputWindow( pWindow );
1370 else
1372 // Test, if the Window is related to the frame
1373 if ( !pWindow->ImplIsWindowOrChild( pChild ) )
1374 pChild = ImplGetKeyInputWindow( pWindow );
1377 if ( pChild )
1379 ImplCallCommand( pChild, COMMAND_CURSORPOS );
1380 const Rectangle* pRect = pChild->GetCursorRect();
1381 if ( pRect )
1382 rRect = pChild->ImplLogicToDevicePixel( *pRect );
1383 else
1385 Cursor* pCursor = pChild->GetCursor();
1386 if ( pCursor )
1388 Point aPos = pChild->ImplLogicToDevicePixel( pCursor->GetPos() );
1389 Size aSize = pChild->LogicToPixel( pCursor->GetSize() );
1390 if ( !aSize.Width() )
1391 aSize.Width() = pChild->GetSettings().GetStyleSettings().GetCursorSize();
1392 rRect = Rectangle( aPos, aSize );
1394 else
1395 rRect = Rectangle( Point( pChild->GetOutOffXPixel(), pChild->GetOutOffYPixel() ), Size() );
1397 rInputWidth = pChild->ImplLogicWidthToDevicePixel( pChild->GetCursorExtTextInputWidth() );
1398 if ( !rInputWidth )
1399 rInputWidth = rRect.GetWidth();
1401 if (pVertical != 0)
1402 *pVertical
1403 = pChild != 0 && pChild->GetInputContext().GetFont().IsVertical();
1406 // -----------------------------------------------------------------------
1408 static long ImplHandleInputContextChange( Window* pWindow, LanguageType eNewLang )
1410 Window* pChild = ImplGetKeyInputWindow( pWindow );
1411 CommandInputContextData aData( eNewLang );
1412 return !ImplCallCommand( pChild, COMMAND_INPUTCONTEXTCHANGE, &aData );
1415 // -----------------------------------------------------------------------
1417 static sal_Bool ImplCallWheelCommand( Window* pWindow, const Point& rPos,
1418 const CommandWheelData* pWheelData )
1420 Point aCmdMousePos = pWindow->ImplFrameToOutput( rPos );
1421 CommandEvent aCEvt( aCmdMousePos, COMMAND_WHEEL, sal_True, pWheelData );
1422 NotifyEvent aNCmdEvt( EVENT_COMMAND, pWindow, &aCEvt );
1423 ImplDelData aDelData( pWindow );
1424 sal_Bool bPreNotify = (ImplCallPreNotify( aNCmdEvt ) != 0);
1425 if ( aDelData.IsDead() )
1426 return sal_False;
1427 if ( !bPreNotify )
1429 pWindow->ImplGetWindowImpl()->mbCommand = sal_False;
1430 pWindow->Command( aCEvt );
1431 if ( aDelData.IsDead() )
1432 return sal_False;
1433 if ( pWindow->ImplGetWindowImpl()->mbCommand )
1434 return sal_True;
1436 return sal_False;
1439 // -----------------------------------------------------------------------
1441 static long ImplHandleWheelEvent( Window* pWindow, const SalWheelMouseEvent& rEvt, bool scaleDirectly = false )
1443 ImplDelData aDogTag( pWindow );
1445 ImplSVData* pSVData = ImplGetSVData();
1446 if ( pSVData->maWinData.mpAutoScrollWin )
1447 pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
1448 if ( pSVData->maHelpData.mpHelpWin )
1449 ImplDestroyHelpWindow( true );
1450 if( aDogTag.IsDead() )
1451 return 0;
1453 sal_uInt16 nMode;
1454 sal_uInt16 nCode = rEvt.mnCode;
1455 bool bHorz = rEvt.mbHorz;
1456 bool bPixel = rEvt.mbDeltaIsPixel;
1457 if ( scaleDirectly )
1458 nMode = COMMAND_WHEEL_ZOOM_SCALE;
1459 else if ( nCode & KEY_MOD1 )
1460 nMode = COMMAND_WHEEL_ZOOM;
1461 else if ( nCode & KEY_MOD2 )
1462 nMode = COMMAND_WHEEL_DATAZOOM;
1463 else
1465 nMode = COMMAND_WHEEL_SCROLL;
1466 // #i85450# interpret shift-wheel as horizontal wheel action
1467 if( (nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)) == KEY_SHIFT )
1468 bHorz = true;
1471 CommandWheelData aWheelData( rEvt.mnDelta, rEvt.mnNotchDelta, rEvt.mnScrollLines, nMode, nCode, bHorz, bPixel );
1472 Point aMousePos( rEvt.mnX, rEvt.mnY );
1473 sal_Bool bRet = sal_True;
1475 // first check any floating window ( eg. drop down listboxes)
1476 bool bIsFloat = false;
1477 Window *pMouseWindow = NULL;
1478 if ( pSVData->maWinData.mpFirstFloat && !pSVData->maWinData.mpCaptureWin &&
1479 !pSVData->maWinData.mpFirstFloat->ImplIsFloatPopupModeWindow( pWindow ) )
1481 sal_uInt16 nHitTest = IMPL_FLOATWIN_HITTEST_OUTSIDE;
1482 pMouseWindow = pSVData->maWinData.mpFirstFloat->ImplFloatHitTest( pWindow, aMousePos, nHitTest );
1484 // then try the window directly beneath the mouse
1485 if( !pMouseWindow )
1486 pMouseWindow = pWindow->ImplFindWindow( aMousePos );
1487 else
1489 // transform coordinates to float window frame coordinates
1490 pMouseWindow = pMouseWindow->ImplFindWindow(
1491 pMouseWindow->OutputToScreenPixel(
1492 pMouseWindow->AbsoluteScreenToOutputPixel(
1493 pWindow->OutputToAbsoluteScreenPixel(
1494 pWindow->ScreenToOutputPixel( aMousePos ) ) ) ) );
1495 bIsFloat = true;
1498 if ( pMouseWindow &&
1499 pMouseWindow->IsEnabled() && pMouseWindow->IsInputEnabled() && ! pMouseWindow->IsInModalMode() )
1501 // transform coordinates to float window frame coordinates
1502 Point aRelMousePos( pMouseWindow->OutputToScreenPixel(
1503 pMouseWindow->AbsoluteScreenToOutputPixel(
1504 pWindow->OutputToAbsoluteScreenPixel(
1505 pWindow->ScreenToOutputPixel( aMousePos ) ) ) ) );
1506 bRet = ImplCallWheelCommand( pMouseWindow, aRelMousePos, &aWheelData );
1509 // if the commad was not handled try the focus window
1510 if ( bRet )
1512 Window* pFocusWindow = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1513 if ( pFocusWindow && (pFocusWindow != pMouseWindow) &&
1514 (pFocusWindow == pSVData->maWinData.mpFocusWin) )
1516 // no wheel-messages to disabled windows
1517 if ( pFocusWindow->IsEnabled() && pFocusWindow->IsInputEnabled() && ! pFocusWindow->IsInModalMode() )
1519 // transform coordinates to focus window frame coordinates
1520 Point aRelMousePos( pFocusWindow->OutputToScreenPixel(
1521 pFocusWindow->AbsoluteScreenToOutputPixel(
1522 pWindow->OutputToAbsoluteScreenPixel(
1523 pWindow->ScreenToOutputPixel( aMousePos ) ) ) ) );
1524 bRet = ImplCallWheelCommand( pFocusWindow, aRelMousePos, &aWheelData );
1529 // close floaters
1530 if( ! bIsFloat && pSVData->maWinData.mpFirstFloat )
1532 FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
1533 if( pLastLevelFloat )
1535 sal_uLong nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
1536 if ( nPopupFlags & FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE )
1538 pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
1543 return !bRet;
1546 // -----------------------------------------------------------------------
1547 #define IMPL_PAINT_CHECKRTL ((sal_uInt16)0x0020)
1549 static void ImplHandlePaint( Window* pWindow, const Rectangle& rBoundRect, bool bImmediateUpdate )
1551 // give up background save when sytem paints arrive
1552 Window* pSaveBackWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFirstBackWin;
1553 while ( pSaveBackWin )
1555 Window* pNext = pSaveBackWin->ImplGetWindowImpl()->mpOverlapData->mpNextBackWin;
1556 Rectangle aRect( Point( pSaveBackWin->GetOutOffXPixel(), pSaveBackWin->GetOutOffYPixel() ),
1557 Size( pSaveBackWin->GetOutputWidthPixel(), pSaveBackWin->GetOutputHeightPixel() ) );
1558 if ( aRect.IsOver( rBoundRect ) )
1559 pSaveBackWin->ImplDeleteOverlapBackground();
1560 pSaveBackWin = pNext;
1563 // system paint events must be checked for re-mirroring
1564 pWindow->ImplGetWindowImpl()->mnPaintFlags |= IMPL_PAINT_CHECKRTL;
1566 // trigger paint for all windows that live in the new paint region
1567 Region aRegion( rBoundRect );
1568 pWindow->ImplInvalidateOverlapFrameRegion( aRegion );
1569 if( bImmediateUpdate )
1571 // #i87663# trigger possible pending resize notifications
1572 // (GetSizePixel does that for us)
1573 pWindow->GetSizePixel();
1574 // force drawing inmmediately
1575 pWindow->Update();
1579 // -----------------------------------------------------------------------
1581 static void KillOwnPopups( Window* pWindow )
1583 ImplSVData* pSVData = ImplGetSVData();
1584 Window *pParent = pWindow->ImplGetWindowImpl()->mpFrameWindow;
1585 Window *pChild = pSVData->maWinData.mpFirstFloat;
1586 if ( pChild && pParent->ImplIsWindowOrChild( pChild, sal_True ) )
1588 if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE) )
1589 pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
1593 // -----------------------------------------------------------------------
1595 void ImplHandleResize( Window* pWindow, long nNewWidth, long nNewHeight )
1597 if( pWindow->GetStyle() & (WB_MOVEABLE|WB_SIZEABLE) )
1599 KillOwnPopups( pWindow );
1600 if( pWindow->ImplGetWindow() != ImplGetSVData()->maHelpData.mpHelpWin )
1601 ImplDestroyHelpWindow( true );
1604 if (
1605 (nNewWidth > 0 && nNewHeight > 0) ||
1606 pWindow->ImplGetWindow()->ImplGetWindowImpl()->mbAllResize
1609 if ( (nNewWidth != pWindow->GetOutputWidthPixel()) || (nNewHeight != pWindow->GetOutputHeightPixel()) )
1611 pWindow->mnOutWidth = nNewWidth;
1612 pWindow->mnOutHeight = nNewHeight;
1613 pWindow->ImplGetWindowImpl()->mbWaitSystemResize = sal_False;
1614 if ( pWindow->IsReallyVisible() )
1615 pWindow->ImplSetClipFlag();
1616 if ( pWindow->IsVisible() || pWindow->ImplGetWindow()->ImplGetWindowImpl()->mbAllResize ||
1617 ( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplGetWindowImpl()->mpClientWindow ) ) // propagate resize for system border windows
1619 bool bStartTimer = true;
1620 // use resize buffering for user resizes
1621 // ownerdraw decorated windows and floating windows can be resized immediately (i.e. synchronously)
1622 if( pWindow->ImplGetWindowImpl()->mbFrame && (pWindow->GetStyle() & WB_SIZEABLE)
1623 && !(pWindow->GetStyle() & WB_OWNERDRAWDECORATION) // synchronous resize for ownerdraw decorated windows (toolbars)
1624 && !pWindow->ImplGetWindowImpl()->mbFloatWin ) // synchronous resize for floating windows, #i43799#
1626 if( pWindow->ImplGetWindowImpl()->mpClientWindow )
1628 // #i42750# presentation wants to be informed about resize
1629 // as early as possible
1630 WorkWindow* pWorkWindow = dynamic_cast<WorkWindow*>(pWindow->ImplGetWindowImpl()->mpClientWindow);
1631 if( ! pWorkWindow || pWorkWindow->IsPresentationMode() )
1632 bStartTimer = false;
1634 else
1636 WorkWindow* pWorkWindow = dynamic_cast<WorkWindow*>(pWindow);
1637 if( ! pWorkWindow || pWorkWindow->IsPresentationMode() )
1638 bStartTimer = false;
1641 else
1642 bStartTimer = false;
1644 if( bStartTimer )
1645 pWindow->ImplGetWindowImpl()->mpFrameData->maResizeTimer.Start();
1646 else
1647 pWindow->ImplCallResize(); // otherwise menus cannot be positioned
1649 else
1650 pWindow->ImplGetWindowImpl()->mbCallResize = sal_True;
1654 pWindow->ImplGetWindowImpl()->mpFrameData->mbNeedSysWindow = (nNewWidth < IMPL_MIN_NEEDSYSWIN) ||
1655 (nNewHeight < IMPL_MIN_NEEDSYSWIN);
1656 sal_Bool bMinimized = (nNewWidth <= 0) || (nNewHeight <= 0);
1657 if( bMinimized != pWindow->ImplGetWindowImpl()->mpFrameData->mbMinimized )
1658 pWindow->ImplGetWindowImpl()->mpFrameWindow->ImplNotifyIconifiedState( bMinimized );
1659 pWindow->ImplGetWindowImpl()->mpFrameData->mbMinimized = bMinimized;
1662 // -----------------------------------------------------------------------
1664 static void ImplHandleMove( Window* pWindow )
1666 if( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplIsFloatingWindow() && pWindow->IsReallyVisible() )
1668 static_cast<FloatingWindow*>(pWindow)->EndPopupMode( FLOATWIN_POPUPMODEEND_TEAROFF );
1669 pWindow->ImplCallMove();
1672 if( pWindow->GetStyle() & (WB_MOVEABLE|WB_SIZEABLE) )
1674 KillOwnPopups( pWindow );
1675 if( pWindow->ImplGetWindow() != ImplGetSVData()->maHelpData.mpHelpWin )
1676 ImplDestroyHelpWindow( true );
1679 if ( pWindow->IsVisible() )
1680 pWindow->ImplCallMove();
1681 else
1682 pWindow->ImplGetWindowImpl()->mbCallMove = sal_True; // make sure the framepos will be updated on the next Show()
1684 if ( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplGetWindowImpl()->mpClientWindow )
1685 pWindow->ImplGetWindowImpl()->mpClientWindow->ImplCallMove(); // notify client to update geometry
1689 // -----------------------------------------------------------------------
1691 static void ImplHandleMoveResize( Window* pWindow, long nNewWidth, long nNewHeight )
1693 ImplHandleMove( pWindow );
1694 ImplHandleResize( pWindow, nNewWidth, nNewHeight );
1697 // -----------------------------------------------------------------------
1699 static void ImplActivateFloatingWindows( Window* pWindow, sal_Bool bActive )
1701 // First check all overlapping windows
1702 Window* pTempWindow = pWindow->ImplGetWindowImpl()->mpFirstOverlap;
1703 while ( pTempWindow )
1705 if ( !pTempWindow->GetActivateMode() )
1707 if ( (pTempWindow->GetType() == WINDOW_BORDERWINDOW) &&
1708 (pTempWindow->ImplGetWindow()->GetType() == WINDOW_FLOATINGWINDOW) )
1709 ((ImplBorderWindow*)pTempWindow)->SetDisplayActive( bActive );
1712 ImplActivateFloatingWindows( pTempWindow, bActive );
1713 pTempWindow = pTempWindow->ImplGetWindowImpl()->mpNext;
1718 // -----------------------------------------------------------------------
1720 IMPL_LINK_NOARG(Window, ImplAsyncFocusHdl)
1722 ImplGetWindowImpl()->mpFrameData->mnFocusId = 0;
1724 // If the status has been preserved, because we got back the focus
1725 // in the meantime, we do nothing
1726 sal_Bool bHasFocus = ImplGetWindowImpl()->mpFrameData->mbHasFocus || ImplGetWindowImpl()->mpFrameData->mbSysObjFocus;
1728 // next execute the delayed functions
1729 if ( bHasFocus )
1731 // redraw all floating windows inactive
1732 if ( ImplGetWindowImpl()->mpFrameData->mbStartFocusState != bHasFocus )
1733 ImplActivateFloatingWindows( this, bHasFocus );
1735 if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin )
1737 sal_Bool bHandled = sal_False;
1738 if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsInputEnabled() &&
1739 ! ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsInModalMode() )
1741 if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsEnabled() )
1743 ImplGetWindowImpl()->mpFrameData->mpFocusWin->GrabFocus();
1744 bHandled = sal_True;
1746 else if( ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplHasDlgCtrl() )
1748 // #109094# if the focus is restored to a disabled dialog control (was disabled meanwhile)
1749 // try to move it to the next control
1750 ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplDlgCtrlNextWindow();
1751 bHandled = sal_True;
1754 if ( !bHandled )
1756 ImplSVData* pSVData = ImplGetSVData();
1757 Window* pTopLevelWindow = ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplGetFirstOverlapWindow();
1758 if ( ( ! pTopLevelWindow->IsInputEnabled() || pTopLevelWindow->IsInModalMode() )
1759 && pSVData->maWinData.mpLastExecuteDlg )
1760 pSVData->maWinData.mpLastExecuteDlg->ToTop( TOTOP_RESTOREWHENMIN | TOTOP_GRABFOCUSONLY);
1761 else
1762 pTopLevelWindow->GrabFocus();
1765 else
1766 GrabFocus();
1768 else
1770 Window* pFocusWin = ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1771 if ( pFocusWin )
1773 ImplSVData* pSVData = ImplGetSVData();
1775 if ( pSVData->maWinData.mpFocusWin == pFocusWin )
1777 // FocusWindow umsetzen
1778 Window* pOverlapWindow = pFocusWin->ImplGetFirstOverlapWindow();
1779 pOverlapWindow->ImplGetWindowImpl()->mpLastFocusWindow = pFocusWin;
1780 pSVData->maWinData.mpFocusWin = NULL;
1782 if ( pFocusWin->ImplGetWindowImpl()->mpCursor )
1783 pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide( true );
1785 // Deaktivate rufen
1786 Window* pOldFocusWindow = pFocusWin;
1787 if ( pOldFocusWindow )
1789 Window* pOldOverlapWindow = pOldFocusWindow->ImplGetFirstOverlapWindow();
1790 Window* pOldRealWindow = pOldOverlapWindow->ImplGetWindow();
1792 pOldOverlapWindow->ImplGetWindowImpl()->mbActive = sal_False;
1793 pOldOverlapWindow->Deactivate();
1794 if ( pOldRealWindow != pOldOverlapWindow )
1796 pOldRealWindow->ImplGetWindowImpl()->mbActive = sal_False;
1797 pOldRealWindow->Deactivate();
1801 // TrackingMode is ended in ImplHandleLoseFocus
1802 // To avoid problems with the Unix IME
1803 // pFocusWin->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
1805 // XXX #102010# hack for accessibility: do not close the menu,
1806 // even after focus lost
1807 static const char* pEnv = getenv("SAL_FLOATWIN_NOAPPFOCUSCLOSE");
1808 if( !(pEnv && *pEnv) )
1810 NotifyEvent aNEvt( EVENT_LOSEFOCUS, pFocusWin );
1811 if ( !ImplCallPreNotify( aNEvt ) )
1812 pFocusWin->LoseFocus();
1813 pFocusWin->ImplCallDeactivateListeners( NULL );
1814 GetpApp()->FocusChanged();
1816 // XXX
1820 // Redraw all floating window inactive
1821 if ( ImplGetWindowImpl()->mpFrameData->mbStartFocusState != bHasFocus )
1822 ImplActivateFloatingWindows( this, bHasFocus );
1825 return 0;
1828 // -----------------------------------------------------------------------
1830 static void ImplHandleGetFocus( Window* pWindow )
1832 pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus = sal_True;
1835 // execute Focus-Events after a delay, such that SystemChildWindows
1836 // do not blink when they receive focus
1837 if ( !pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId )
1839 pWindow->ImplGetWindowImpl()->mpFrameData->mbStartFocusState = !pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus;
1840 Application::PostUserEvent( pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId, LINK( pWindow, Window, ImplAsyncFocusHdl ) );
1841 Window* pFocusWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1842 if ( pFocusWin && pFocusWin->ImplGetWindowImpl()->mpCursor )
1843 pFocusWin->ImplGetWindowImpl()->mpCursor->ImplShow();
1847 // -----------------------------------------------------------------------
1849 static void ImplHandleLoseFocus( Window* pWindow )
1851 ImplSVData* pSVData = ImplGetSVData();
1853 // Abort the autoscroll if the frame loses focus
1854 if ( pSVData->maWinData.mpAutoScrollWin )
1855 pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
1857 // Abort tracking if the frame loses focus
1858 if ( pSVData->maWinData.mpTrackWin )
1860 if ( pSVData->maWinData.mpTrackWin->ImplGetWindowImpl()->mpFrameWindow == pWindow )
1861 pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL );
1864 // here we always terminate the popupmode, also when NOFOCUSCLOSE
1865 // is set, such that we do not show windows during the switch
1866 if ( pSVData->maWinData.mpFirstFloat )
1868 if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE) )
1869 pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
1872 pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus = sal_False;
1874 // execute Focus-Events after a delay, such that SystemChildWindows
1875 // do not flicker when they receive focus
1876 if ( !pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId )
1878 pWindow->ImplGetWindowImpl()->mpFrameData->mbStartFocusState = !pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus;
1879 Application::PostUserEvent( pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId, LINK( pWindow, Window, ImplAsyncFocusHdl ) );
1882 Window* pFocusWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1883 if ( pFocusWin && pFocusWin->ImplGetWindowImpl()->mpCursor )
1884 pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide( true );
1887 // -----------------------------------------------------------------------
1888 struct DelayedCloseEvent
1890 Window* pWindow;
1891 ImplDelData aDelData;
1894 static long DelayedCloseEventLink( void* pCEvent, void* )
1896 DelayedCloseEvent* pEv = (DelayedCloseEvent*)pCEvent;
1898 if( ! pEv->aDelData.IsDead() )
1900 pEv->pWindow->ImplRemoveDel( &pEv->aDelData );
1901 // dispatch to correct window type
1902 if( pEv->pWindow->IsSystemWindow() )
1903 ((SystemWindow*)pEv->pWindow)->Close();
1904 else if( pEv->pWindow->ImplIsDockingWindow() )
1905 ((DockingWindow*)pEv->pWindow)->Close();
1907 delete pEv;
1909 return 0;
1912 void ImplHandleClose( Window* pWindow )
1914 ImplSVData* pSVData = ImplGetSVData();
1916 bool bWasPopup = false;
1917 if( pWindow->ImplIsFloatingWindow() &&
1918 static_cast<FloatingWindow*>(pWindow)->ImplIsInPrivatePopupMode() )
1920 bWasPopup = true;
1923 // on Close stop all floating modes and end popups
1924 if ( pSVData->maWinData.mpFirstFloat )
1926 FloatingWindow* pLastLevelFloat;
1927 pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
1928 pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
1930 if ( pSVData->maHelpData.mbExtHelpMode )
1931 Help::EndExtHelp();
1932 if ( pSVData->maHelpData.mpHelpWin )
1933 ImplDestroyHelpWindow( false );
1934 // AutoScrollMode
1935 if ( pSVData->maWinData.mpAutoScrollWin )
1936 pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
1938 if ( pSVData->maWinData.mpTrackWin )
1939 pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL | ENDTRACK_KEY );
1941 if (bWasPopup)
1942 return;
1944 Window *pWin = pWindow->ImplGetWindow();
1945 SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(pWin);
1946 if (pSysWin)
1948 // See if the custom close handler is set.
1949 const Link& rLink = pSysWin->GetCloseHdl();
1950 if (rLink.IsSet())
1952 rLink.Call(pSysWin);
1953 return;
1957 // check whether close is allowed
1958 if ( pWin->IsEnabled() && pWin->IsInputEnabled() && !pWin->IsInModalMode() )
1960 DelayedCloseEvent* pEv = new DelayedCloseEvent;
1961 pEv->pWindow = pWin;
1962 pWin->ImplAddDel( &pEv->aDelData );
1963 Application::PostUserEvent( Link( pEv, DelayedCloseEventLink ) );
1967 // -----------------------------------------------------------------------
1969 static void ImplHandleUserEvent( ImplSVEvent* pSVEvent )
1971 if ( pSVEvent )
1973 if ( pSVEvent->mbCall && !pSVEvent->maDelData.IsDead() )
1975 if ( pSVEvent->mpWindow )
1977 pSVEvent->mpWindow->ImplRemoveDel( &(pSVEvent->maDelData) );
1978 if ( pSVEvent->mpLink )
1979 pSVEvent->mpLink->Call( pSVEvent->mpData );
1980 else
1981 pSVEvent->mpWindow->UserEvent( pSVEvent->mnEvent, pSVEvent->mpData );
1983 else
1985 if ( pSVEvent->mpLink )
1986 pSVEvent->mpLink->Call( pSVEvent->mpData );
1987 else
1988 GetpApp()->UserEvent( pSVEvent->mnEvent, pSVEvent->mpData );
1992 delete pSVEvent->mpLink;
1993 delete pSVEvent;
1997 // =======================================================================
1999 static sal_uInt16 ImplGetMouseMoveMode( SalMouseEvent* pEvent )
2001 sal_uInt16 nMode = 0;
2002 if ( !pEvent->mnCode )
2003 nMode |= MOUSE_SIMPLEMOVE;
2004 if ( (pEvent->mnCode & MOUSE_LEFT) && !(pEvent->mnCode & KEY_MOD1) )
2005 nMode |= MOUSE_DRAGMOVE;
2006 if ( (pEvent->mnCode & MOUSE_LEFT) && (pEvent->mnCode & KEY_MOD1) )
2007 nMode |= MOUSE_DRAGCOPY;
2008 return nMode;
2011 // -----------------------------------------------------------------------
2013 static sal_uInt16 ImplGetMouseButtonMode( SalMouseEvent* pEvent )
2015 sal_uInt16 nMode = 0;
2016 if ( pEvent->mnButton == MOUSE_LEFT )
2017 nMode |= MOUSE_SIMPLECLICK;
2018 if ( (pEvent->mnButton == MOUSE_LEFT) && !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT)) )
2019 nMode |= MOUSE_SELECT;
2020 if ( (pEvent->mnButton == MOUSE_LEFT) && (pEvent->mnCode & KEY_MOD1) &&
2021 !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT | KEY_SHIFT)) )
2022 nMode |= MOUSE_MULTISELECT;
2023 if ( (pEvent->mnButton == MOUSE_LEFT) && (pEvent->mnCode & KEY_SHIFT) &&
2024 !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT | KEY_MOD1)) )
2025 nMode |= MOUSE_RANGESELECT;
2026 return nMode;
2029 // -----------------------------------------------------------------------
2031 inline long ImplHandleSalMouseLeave( Window* pWindow, SalMouseEvent* pEvent )
2033 return ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, sal_True,
2034 pEvent->mnX, pEvent->mnY,
2035 pEvent->mnTime, pEvent->mnCode,
2036 ImplGetMouseMoveMode( pEvent ) );
2039 // -----------------------------------------------------------------------
2041 inline long ImplHandleSalMouseMove( Window* pWindow, SalMouseEvent* pEvent )
2043 return ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, sal_False,
2044 pEvent->mnX, pEvent->mnY,
2045 pEvent->mnTime, pEvent->mnCode,
2046 ImplGetMouseMoveMode( pEvent ) );
2049 // -----------------------------------------------------------------------
2051 inline long ImplHandleSalMouseButtonDown( Window* pWindow, SalMouseEvent* pEvent )
2053 return ImplHandleMouseEvent( pWindow, EVENT_MOUSEBUTTONDOWN, sal_False,
2054 pEvent->mnX, pEvent->mnY,
2055 pEvent->mnTime,
2056 #ifdef MACOSX
2057 pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)),
2058 #else
2059 pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
2060 #endif
2061 ImplGetMouseButtonMode( pEvent ) );
2064 // -----------------------------------------------------------------------
2066 inline long ImplHandleSalMouseButtonUp( Window* pWindow, SalMouseEvent* pEvent )
2068 return ImplHandleMouseEvent( pWindow, EVENT_MOUSEBUTTONUP, sal_False,
2069 pEvent->mnX, pEvent->mnY,
2070 pEvent->mnTime,
2071 #ifdef MACOSX
2072 pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)),
2073 #else
2074 pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
2075 #endif
2076 ImplGetMouseButtonMode( pEvent ) );
2079 // -----------------------------------------------------------------------
2081 static long ImplHandleSalMouseActivate( Window* /*pWindow*/, SalMouseActivateEvent* /*pEvent*/ )
2083 return sal_False;
2086 // -----------------------------------------------------------------------
2088 static long ImplHandleMenuEvent( Window* pWindow, SalMenuEvent* pEvent, sal_uInt16 nEvent )
2090 // Find SystemWindow and its Menubar and let it dispatch the command
2091 long nRet = 0;
2092 Window *pWin = pWindow->ImplGetWindowImpl()->mpFirstChild;
2093 while ( pWin )
2095 if ( pWin->ImplGetWindowImpl()->mbSysWin )
2096 break;
2097 pWin = pWin->ImplGetWindowImpl()->mpNext;
2099 if( pWin )
2101 MenuBar *pMenuBar = ((SystemWindow*) pWin)->GetMenuBar();
2102 if( pMenuBar )
2104 switch( nEvent )
2106 case SALEVENT_MENUACTIVATE:
2107 nRet = pMenuBar->HandleMenuActivateEvent( (Menu*) pEvent->mpMenu ) ? 1 : 0;
2108 break;
2109 case SALEVENT_MENUDEACTIVATE:
2110 nRet = pMenuBar->HandleMenuDeActivateEvent( (Menu*) pEvent->mpMenu ) ? 1 : 0;
2111 break;
2112 case SALEVENT_MENUHIGHLIGHT:
2113 nRet = pMenuBar->HandleMenuHighlightEvent( (Menu*) pEvent->mpMenu, pEvent->mnId ) ? 1 : 0;
2114 break;
2115 case SALEVENT_MENUBUTTONCOMMAND:
2116 nRet = pMenuBar->HandleMenuButtonEvent( (Menu*) pEvent->mpMenu, pEvent->mnId ) ? 1 : 0;
2117 break;
2118 case SALEVENT_MENUCOMMAND:
2119 nRet = pMenuBar->HandleMenuCommandEvent( (Menu*) pEvent->mpMenu, pEvent->mnId ) ? 1 : 0;
2120 break;
2121 default:
2122 break;
2126 return nRet;
2129 // -----------------------------------------------------------------------
2131 static void ImplHandleSalKeyMod( Window* pWindow, SalKeyModEvent* pEvent )
2133 ImplSVData* pSVData = ImplGetSVData();
2134 Window* pTrackWin = pSVData->maWinData.mpTrackWin;
2135 if ( pTrackWin )
2136 pWindow = pTrackWin;
2137 #ifdef MACOSX
2138 sal_uInt16 nOldCode = pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3);
2139 #else
2140 sal_uInt16 nOldCode = pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
2141 #endif
2142 sal_uInt16 nNewCode = pEvent->mnCode;
2143 if ( nOldCode != nNewCode )
2145 #ifdef MACOSX
2146 nNewCode |= pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & ~(KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3);
2147 #else
2148 nNewCode |= pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & ~(KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
2149 #endif
2150 pWindow->ImplGetWindowImpl()->mpFrameWindow->ImplCallMouseMove( nNewCode, sal_True );
2153 // #105224# send commandevent to allow special treatment of Ctrl-LeftShift/Ctrl-RightShift etc.
2155 // find window
2156 Window* pChild = ImplGetKeyInputWindow( pWindow );
2157 if ( !pChild )
2158 return;
2160 // send modkey events only if useful data is available
2161 if( pEvent->mnModKeyCode != 0 )
2163 CommandModKeyData data( pEvent->mnModKeyCode );
2164 ImplCallCommand( pChild, COMMAND_MODKEYCHANGE, &data );
2168 // -----------------------------------------------------------------------
2170 static void ImplHandleInputLanguageChange( Window* pWindow )
2172 // find window
2173 Window* pChild = ImplGetKeyInputWindow( pWindow );
2174 if ( !pChild )
2175 return;
2177 ImplCallCommand( pChild, COMMAND_INPUTLANGUAGECHANGE );
2180 // -----------------------------------------------------------------------
2182 static void ImplHandleSalSettings( Window* pWindow, sal_uInt16 nEvent )
2184 // Application Notification werden nur fuer das erste Window ausgeloest
2185 ImplSVData* pSVData = ImplGetSVData();
2186 if ( pWindow != pSVData->maWinData.mpFirstFrame )
2187 return;
2189 Application* pApp = GetpApp();
2190 if ( !pApp )
2191 return;
2193 if ( nEvent == SALEVENT_SETTINGSCHANGED )
2195 AllSettings aSettings = pApp->GetSettings();
2196 pApp->MergeSystemSettings( aSettings );
2197 pApp->SystemSettingsChanging( aSettings, pWindow );
2198 pApp->SetSettings( aSettings );
2200 else
2202 sal_uInt16 nType;
2203 switch ( nEvent )
2205 case SALEVENT_VOLUMECHANGED:
2206 nType = 0;
2207 break;
2208 case SALEVENT_PRINTERCHANGED:
2209 ImplDeletePrnQueueList();
2210 nType = DATACHANGED_PRINTER;
2211 break;
2212 case SALEVENT_DISPLAYCHANGED:
2213 nType = DATACHANGED_DISPLAY;
2214 break;
2215 case SALEVENT_FONTCHANGED:
2216 OutputDevice::ImplUpdateAllFontData( sal_True );
2217 nType = DATACHANGED_FONTS;
2218 break;
2219 case SALEVENT_DATETIMECHANGED:
2220 nType = DATACHANGED_DATETIME;
2221 break;
2222 case SALEVENT_KEYBOARDCHANGED:
2223 nType = 0;
2224 break;
2225 default:
2226 nType = 0;
2227 break;
2230 if ( nType )
2232 DataChangedEvent aDCEvt( nType );
2233 pApp->DataChanged( aDCEvt );
2234 pApp->NotifyAllWindows( aDCEvt );
2239 // -----------------------------------------------------------------------
2241 static void ImplHandleSalExtTextInputPos( Window* pWindow, SalExtTextInputPosEvent* pEvt )
2243 Rectangle aCursorRect;
2244 ImplHandleExtTextInputPos( pWindow, aCursorRect, pEvt->mnExtWidth, &pEvt->mbVertical );
2245 if ( aCursorRect.IsEmpty() )
2247 pEvt->mnX = -1;
2248 pEvt->mnY = -1;
2249 pEvt->mnWidth = -1;
2250 pEvt->mnHeight = -1;
2252 else
2254 pEvt->mnX = aCursorRect.Left();
2255 pEvt->mnY = aCursorRect.Top();
2256 pEvt->mnWidth = aCursorRect.GetWidth();
2257 pEvt->mnHeight = aCursorRect.GetHeight();
2261 // -----------------------------------------------------------------------
2263 static long ImplHandleShowDialog( Window* pWindow, int nDialogId )
2265 if( ! pWindow )
2266 return sal_False;
2268 if( pWindow->GetType() == WINDOW_BORDERWINDOW )
2270 Window* pWrkWin = pWindow->GetWindow( WINDOW_CLIENT );
2271 if( pWrkWin )
2272 pWindow = pWrkWin;
2274 CommandDialogData aCmdData( nDialogId );
2275 return ImplCallCommand( pWindow, COMMAND_SHOWDIALOG, &aCmdData );
2278 // -----------------------------------------------------------------------
2280 static void ImplHandleSurroundingTextRequest( Window *pWindow,
2281 OUString& rText,
2282 Selection &rSelRange )
2284 Window* pChild = ImplGetKeyInputWindow( pWindow );
2286 if ( !pChild )
2288 rText = OUString();
2289 rSelRange.setMin( 0 );
2290 rSelRange.setMax( 0 );
2292 else
2294 rText = pChild->GetSurroundingText();
2295 Selection aSel = pChild->GetSurroundingTextSelection();
2296 rSelRange.setMin( aSel.Min() );
2297 rSelRange.setMax( aSel.Max() );
2301 // -----------------------------------------------------------------------
2303 static void ImplHandleSalSurroundingTextRequest( Window *pWindow,
2304 SalSurroundingTextRequestEvent *pEvt )
2306 Selection aSelRange;
2307 ImplHandleSurroundingTextRequest( pWindow, pEvt->maText, aSelRange );
2309 aSelRange.Justify();
2311 if( aSelRange.Min() < 0 )
2312 pEvt->mnStart = 0;
2313 else if( aSelRange.Min() > pEvt->maText.getLength() )
2314 pEvt->mnStart = pEvt->maText.getLength();
2315 else
2316 pEvt->mnStart = aSelRange.Min();
2318 if( aSelRange.Max() < 0 )
2319 pEvt->mnStart = 0;
2320 else if( aSelRange.Max() > pEvt->maText.getLength() )
2321 pEvt->mnEnd = pEvt->maText.getLength();
2322 else
2323 pEvt->mnEnd = aSelRange.Max();
2326 // -----------------------------------------------------------------------
2328 static void ImplHandleSurroundingTextSelectionChange( Window *pWindow,
2329 sal_uLong nStart,
2330 sal_uLong nEnd )
2332 Window* pChild = ImplGetKeyInputWindow( pWindow );
2333 if( pChild )
2335 CommandSelectionChangeData data( nStart, nEnd );
2336 ImplCallCommand( pChild, COMMAND_SELECTIONCHANGE, &data );
2340 // -----------------------------------------------------------------------
2342 static void ImplHandleStartReconversion( Window *pWindow )
2344 Window* pChild = ImplGetKeyInputWindow( pWindow );
2345 if( pChild )
2346 ImplCallCommand( pChild, COMMAND_PREPARERECONVERSION );
2349 // -----------------------------------------------------------------------
2351 static void ImplHandleSalQueryCharPosition( Window *pWindow,
2352 SalQueryCharPositionEvent *pEvt )
2354 pEvt->mbValid = false;
2355 pEvt->mbVertical = false;
2356 pEvt->mnCursorBoundX = 0;
2357 pEvt->mnCursorBoundY = 0;
2358 pEvt->mnCursorBoundWidth = 0;
2359 pEvt->mnCursorBoundHeight = 0;
2361 ImplSVData* pSVData = ImplGetSVData();
2362 Window* pChild = pSVData->maWinData.mpExtTextInputWin;
2364 if ( !pChild )
2365 pChild = ImplGetKeyInputWindow( pWindow );
2366 else
2368 // Test, if the Window is related to the frame
2369 if ( !pWindow->ImplIsWindowOrChild( pChild ) )
2370 pChild = ImplGetKeyInputWindow( pWindow );
2373 if( pChild )
2375 ImplCallCommand( pChild, COMMAND_QUERYCHARPOSITION );
2377 ImplWinData* pWinData = pChild->ImplGetWinData();
2378 if ( pWinData->mpCompositionCharRects && pEvt->mnCharPos < static_cast<sal_uLong>( pWinData->mnCompositionCharRects ) )
2380 const Rectangle& aRect = pWinData->mpCompositionCharRects[ pEvt->mnCharPos ];
2381 Rectangle aDeviceRect = pChild->ImplLogicToDevicePixel( aRect );
2382 Point aAbsScreenPos = pChild->OutputToAbsoluteScreenPixel( pChild->ScreenToOutputPixel(aDeviceRect.TopLeft()) );
2383 pEvt->mnCursorBoundX = aAbsScreenPos.X();
2384 pEvt->mnCursorBoundY = aAbsScreenPos.Y();
2385 pEvt->mnCursorBoundWidth = aDeviceRect.GetWidth();
2386 pEvt->mnCursorBoundHeight = aDeviceRect.GetHeight();
2387 pEvt->mbVertical = (pWinData->mbVertical != sal_False);
2388 pEvt->mbValid = true;
2393 // -----------------------------------------------------------------------
2395 long ImplWindowFrameProc( Window* pWindow, SalFrame* /*pFrame*/,
2396 sal_uInt16 nEvent, const void* pEvent )
2398 DBG_TESTSOLARMUTEX();
2400 long nRet = 0;
2402 // #119709# for some unknown reason it is possible to receive events (in this case key events)
2403 // although the corresponding VCL window must have been destroyed already
2404 // at least ImplGetWindowImpl() was NULL in these cases, so check this here
2405 if( pWindow->ImplGetWindowImpl() == NULL )
2406 return 0;
2408 switch ( nEvent )
2410 case SALEVENT_MOUSEMOVE:
2411 nRet = ImplHandleSalMouseMove( pWindow, (SalMouseEvent*)pEvent );
2412 break;
2413 case SALEVENT_EXTERNALMOUSEMOVE:
2415 MouseEvent* pMouseEvt = (MouseEvent*) pEvent;
2416 SalMouseEvent aSalMouseEvent;
2418 aSalMouseEvent.mnTime = Time::GetSystemTicks();
2419 aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
2420 aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
2421 aSalMouseEvent.mnButton = 0;
2422 aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
2424 nRet = ImplHandleSalMouseMove( pWindow, &aSalMouseEvent );
2426 break;
2427 case SALEVENT_MOUSELEAVE:
2428 nRet = ImplHandleSalMouseLeave( pWindow, (SalMouseEvent*)pEvent );
2429 break;
2430 case SALEVENT_MOUSEBUTTONDOWN:
2431 nRet = ImplHandleSalMouseButtonDown( pWindow, (SalMouseEvent*)pEvent );
2432 break;
2433 case SALEVENT_EXTERNALMOUSEBUTTONDOWN:
2435 MouseEvent* pMouseEvt = (MouseEvent*) pEvent;
2436 SalMouseEvent aSalMouseEvent;
2438 aSalMouseEvent.mnTime = Time::GetSystemTicks();
2439 aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
2440 aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
2441 aSalMouseEvent.mnButton = pMouseEvt->GetButtons();
2442 aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
2444 nRet = ImplHandleSalMouseButtonDown( pWindow, &aSalMouseEvent );
2446 break;
2447 case SALEVENT_MOUSEBUTTONUP:
2448 nRet = ImplHandleSalMouseButtonUp( pWindow, (SalMouseEvent*)pEvent );
2449 break;
2450 case SALEVENT_EXTERNALMOUSEBUTTONUP:
2452 MouseEvent* pMouseEvt = (MouseEvent*) pEvent;
2453 SalMouseEvent aSalMouseEvent;
2455 aSalMouseEvent.mnTime = Time::GetSystemTicks();
2456 aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
2457 aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
2458 aSalMouseEvent.mnButton = pMouseEvt->GetButtons();
2459 aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
2461 nRet = ImplHandleSalMouseButtonUp( pWindow, &aSalMouseEvent );
2463 break;
2464 case SALEVENT_MOUSEACTIVATE:
2465 nRet = ImplHandleSalMouseActivate( pWindow, (SalMouseActivateEvent*)pEvent );
2466 break;
2467 case SALEVENT_KEYINPUT:
2469 SalKeyEvent* pKeyEvt = (SalKeyEvent*)pEvent;
2470 nRet = ImplHandleKey( pWindow, EVENT_KEYINPUT,
2471 pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat, sal_True );
2473 break;
2474 case SALEVENT_EXTERNALKEYINPUT:
2476 KeyEvent* pKeyEvt = (KeyEvent*) pEvent;
2477 nRet = ImplHandleKey( pWindow, EVENT_KEYINPUT,
2478 pKeyEvt->GetKeyCode().GetFullCode(), pKeyEvt->GetCharCode(), pKeyEvt->GetRepeat(), sal_False );
2480 break;
2481 case SALEVENT_KEYUP:
2483 SalKeyEvent* pKeyEvt = (SalKeyEvent*)pEvent;
2484 nRet = ImplHandleKey( pWindow, EVENT_KEYUP,
2485 pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat, sal_True );
2487 break;
2488 case SALEVENT_EXTERNALKEYUP:
2490 KeyEvent* pKeyEvt = (KeyEvent*) pEvent;
2491 nRet = ImplHandleKey( pWindow, EVENT_KEYUP,
2492 pKeyEvt->GetKeyCode().GetFullCode(), pKeyEvt->GetCharCode(), pKeyEvt->GetRepeat(), sal_False );
2494 break;
2495 case SALEVENT_KEYMODCHANGE:
2496 ImplHandleSalKeyMod( pWindow, (SalKeyModEvent*)pEvent );
2497 break;
2499 case SALEVENT_INPUTLANGUAGECHANGE:
2500 ImplHandleInputLanguageChange( pWindow );
2501 break;
2503 case SALEVENT_MENUACTIVATE:
2504 case SALEVENT_MENUDEACTIVATE:
2505 case SALEVENT_MENUHIGHLIGHT:
2506 case SALEVENT_MENUCOMMAND:
2507 case SALEVENT_MENUBUTTONCOMMAND:
2508 nRet = ImplHandleMenuEvent( pWindow, (SalMenuEvent*)pEvent, nEvent );
2509 break;
2511 case SALEVENT_WHEELMOUSE:
2512 nRet = ImplHandleWheelEvent( pWindow, *(const SalWheelMouseEvent*)pEvent);
2513 break;
2515 case SALEVENT_PAINT:
2517 SalPaintEvent* pPaintEvt = (SalPaintEvent*)pEvent;
2519 if( Application::GetSettings().GetLayoutRTL() )
2521 // --- RTL --- (mirror paint rect)
2522 SalFrame* pSalFrame = pWindow->ImplGetWindowImpl()->mpFrame;
2523 pPaintEvt->mnBoundX = pSalFrame->maGeometry.nWidth-pPaintEvt->mnBoundWidth-pPaintEvt->mnBoundX;
2526 Rectangle aBoundRect( Point( pPaintEvt->mnBoundX, pPaintEvt->mnBoundY ),
2527 Size( pPaintEvt->mnBoundWidth, pPaintEvt->mnBoundHeight ) );
2528 ImplHandlePaint( pWindow, aBoundRect, pPaintEvt->mbImmediateUpdate );
2530 break;
2532 case SALEVENT_MOVE:
2533 ImplHandleMove( pWindow );
2534 break;
2536 case SALEVENT_RESIZE:
2538 long nNewWidth;
2539 long nNewHeight;
2540 pWindow->ImplGetWindowImpl()->mpFrame->GetClientSize( nNewWidth, nNewHeight );
2541 ImplHandleResize( pWindow, nNewWidth, nNewHeight );
2543 break;
2545 case SALEVENT_MOVERESIZE:
2547 SalFrameGeometry g = pWindow->ImplGetWindowImpl()->mpFrame->GetGeometry();
2548 ImplHandleMoveResize( pWindow, g.nWidth, g.nHeight );
2550 break;
2552 case SALEVENT_CLOSEPOPUPS:
2554 KillOwnPopups( pWindow );
2556 break;
2558 case SALEVENT_GETFOCUS:
2559 ImplHandleGetFocus( pWindow );
2560 break;
2561 case SALEVENT_LOSEFOCUS:
2562 ImplHandleLoseFocus( pWindow );
2563 break;
2565 case SALEVENT_CLOSE:
2566 ImplHandleClose( pWindow );
2567 break;
2569 case SALEVENT_SHUTDOWN:
2571 static bool bInQueryExit = false;
2572 if( !bInQueryExit )
2574 bInQueryExit = true;
2575 if ( GetpApp()->QueryExit() )
2577 // Message-Schleife beenden
2578 Application::Quit();
2579 return sal_False;
2581 else
2583 bInQueryExit = false;
2584 return sal_True;
2587 return sal_False;
2590 case SALEVENT_SETTINGSCHANGED:
2591 case SALEVENT_VOLUMECHANGED:
2592 case SALEVENT_PRINTERCHANGED:
2593 case SALEVENT_DISPLAYCHANGED:
2594 case SALEVENT_FONTCHANGED:
2595 case SALEVENT_DATETIMECHANGED:
2596 case SALEVENT_KEYBOARDCHANGED:
2597 ImplHandleSalSettings( pWindow, nEvent );
2598 break;
2600 case SALEVENT_USEREVENT:
2601 ImplHandleUserEvent( (ImplSVEvent*)pEvent );
2602 break;
2604 case SALEVENT_EXTTEXTINPUT:
2606 SalExtTextInputEvent* pEvt = (SalExtTextInputEvent*)pEvent;
2607 nRet = ImplHandleExtTextInput( pWindow,
2608 pEvt->maText, pEvt->mpTextAttr,
2609 pEvt->mnCursorPos, pEvt->mnCursorFlags );
2611 break;
2612 case SALEVENT_ENDEXTTEXTINPUT:
2613 nRet = ImplHandleEndExtTextInput( pWindow );
2614 break;
2615 case SALEVENT_EXTTEXTINPUTPOS:
2616 ImplHandleSalExtTextInputPos( pWindow, (SalExtTextInputPosEvent*)pEvent );
2617 break;
2618 case SALEVENT_INPUTCONTEXTCHANGE:
2619 nRet = ImplHandleInputContextChange( pWindow, ((SalInputContextChangeEvent*)pEvent)->meLanguage );
2620 break;
2621 case SALEVENT_SHOWDIALOG:
2623 int nDialogID = static_cast<int>(reinterpret_cast<sal_IntPtr>(pEvent));
2624 nRet = ImplHandleShowDialog( pWindow, nDialogID );
2626 break;
2627 case SALEVENT_SURROUNDINGTEXTREQUEST:
2628 ImplHandleSalSurroundingTextRequest( pWindow, (SalSurroundingTextRequestEvent*)pEvent );
2629 break;
2630 case SALEVENT_SURROUNDINGTEXTSELECTIONCHANGE:
2632 SalSurroundingTextSelectionChangeEvent* pEvt
2633 = (SalSurroundingTextSelectionChangeEvent*)pEvent;
2634 ImplHandleSurroundingTextSelectionChange( pWindow,
2635 pEvt->mnStart,
2636 pEvt->mnEnd );
2638 case SALEVENT_STARTRECONVERSION:
2639 ImplHandleStartReconversion( pWindow );
2640 break;
2641 case SALEVENT_EXTERNALZOOM:
2643 ZoomEvent* pZoomEvent = (ZoomEvent*) pEvent;
2644 SalWheelMouseEvent aSalWheelMouseEvent;
2646 aSalWheelMouseEvent.mnTime = Time::GetSystemTicks();
2647 aSalWheelMouseEvent.mnX = pZoomEvent->GetCenter().getX();
2648 aSalWheelMouseEvent.mnY = pZoomEvent->GetCenter().getY();
2650 // Pass on the scale as a percentage of current zoom factor
2651 aSalWheelMouseEvent.mnDelta = (long) (pZoomEvent->GetScale() * 100);
2653 // Other SalWheelMouseEvent fields ignored when the
2654 // scaleDirectly parameter to ImplHandleWheelEvent() is
2655 // true.
2656 nRet = ImplHandleWheelEvent( pWindow, aSalWheelMouseEvent, true );
2658 break;
2659 case SALEVENT_EXTERNALSCROLL:
2661 ScrollEvent* pScrollEvent = (ScrollEvent*) pEvent;
2662 SalWheelMouseEvent aSalWheelMouseEvent;
2664 aSalWheelMouseEvent.mnTime = Time::GetSystemTicks();
2665 aSalWheelMouseEvent.mnX = 0; // ???
2666 aSalWheelMouseEvent.mnY = 0;
2668 // Note that it seems that the delta-is-pixels thing is
2669 // not actually implemented. The field is just passed on
2670 // but its value never tested and has no effect?
2671 aSalWheelMouseEvent.mbDeltaIsPixel = sal_True;
2673 // First scroll vertically, then horizontally
2674 aSalWheelMouseEvent.mnDelta = (long) pScrollEvent->GetYOffset();
2676 // No way to figure out correct amount of "lines" to
2677 // scroll, and for touch devices (for which this
2678 // SALEVENBT_EXTERNALSCROLL was introduced) we don't even
2679 // display the scroll bars. This means that the scroll
2680 // bars (which still exist as objects, all the scrolling
2681 // action goes through them) apparently use some dummy
2682 // default values for range, line size and page size
2683 // anyway, not related to actual contents of scrolled
2684 // window. This all is very broken. I really wish the
2685 // delta-is-pixels feature (which would be exactly what
2686 // one wants for touch devices) would work.
2687 aSalWheelMouseEvent.mnScrollLines = aSalWheelMouseEvent.mnDelta;
2689 if (aSalWheelMouseEvent.mnDelta != 0)
2691 aSalWheelMouseEvent.mnNotchDelta = (aSalWheelMouseEvent.mnDelta < 0) ? -1 : 1;
2692 aSalWheelMouseEvent.mnCode = 0;
2693 aSalWheelMouseEvent.mbHorz = sal_False;
2694 nRet = ImplHandleWheelEvent( pWindow, aSalWheelMouseEvent );
2696 aSalWheelMouseEvent.mnDelta = (long) pScrollEvent->GetXOffset();
2697 if (aSalWheelMouseEvent.mnDelta != 0)
2699 aSalWheelMouseEvent.mnNotchDelta = (aSalWheelMouseEvent.mnDelta < 0) ? -1 : 1;
2700 aSalWheelMouseEvent.mnCode = 0;
2701 aSalWheelMouseEvent.mbHorz = sal_True;
2702 nRet = ImplHandleWheelEvent( pWindow, aSalWheelMouseEvent );
2705 break;
2706 case SALEVENT_QUERYCHARPOSITION:
2707 ImplHandleSalQueryCharPosition( pWindow, (SalQueryCharPositionEvent*)pEvent );
2708 break;
2709 #ifdef DBG_UTIL
2710 default:
2711 SAL_WARN( "vcl.layout", "ImplWindowFrameProc(): unknown event (" << nEvent << ")" );
2712 break;
2713 #endif
2716 return nRet;
2719 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */