6a7a0ac6aa
This reverts commit 59887868da
.
Change-Id: I0f3f6a7680c78103a559a0f881badc8211b97ace
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/90544
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2644 lines
98 KiB
C++
2644 lines
98 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <sal/config.h>
|
|
|
|
#include <o3tl/safeint.hxx>
|
|
#include <tools/debug.hxx>
|
|
#include <tools/time.hxx>
|
|
#include <sal/log.hxx>
|
|
|
|
#include <unotools/localedatawrapper.hxx>
|
|
|
|
#include <comphelper/lok.hxx>
|
|
#include <vcl/timer.hxx>
|
|
#include <vcl/event.hxx>
|
|
#include <vcl/GestureEvent.hxx>
|
|
#include <vcl/settings.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
#include <vcl/cursor.hxx>
|
|
#include <vcl/wrkwin.hxx>
|
|
#include <vcl/floatwin.hxx>
|
|
#include <vcl/toolkit/dialog.hxx>
|
|
#include <vcl/help.hxx>
|
|
#include <vcl/dockwin.hxx>
|
|
#include <vcl/menu.hxx>
|
|
#include <vcl/virdev.hxx>
|
|
#include <vcl/uitest/logger.hxx>
|
|
#include <vcl/ptrstyle.hxx>
|
|
|
|
#include <svdata.hxx>
|
|
#include <salwtype.hxx>
|
|
#include <salframe.hxx>
|
|
#include <accmgr.hxx>
|
|
#include <print.h>
|
|
#include <window.h>
|
|
#include <helpwin.hxx>
|
|
#include <brdwin.hxx>
|
|
#include <dndlistenercontainer.hxx>
|
|
|
|
#include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
|
|
#include <com/sun/star/awt/MouseEvent.hpp>
|
|
|
|
#define IMPL_MIN_NEEDSYSWIN 49
|
|
|
|
bool ImplCallPreNotify( NotifyEvent& rEvt )
|
|
{
|
|
return rEvt.GetWindow()->CompatPreNotify( rEvt );
|
|
}
|
|
|
|
static bool ImplHandleMouseFloatMode( vcl::Window* pChild, const Point& rMousePos,
|
|
sal_uInt16 nCode, MouseNotifyEvent nSVEvent,
|
|
bool bMouseLeave )
|
|
{
|
|
ImplSVData* pSVData = ImplGetSVData();
|
|
|
|
if (pSVData->mpWinData->mpFirstFloat && !pSVData->mpWinData->mpCaptureWin
|
|
&& !pSVData->mpWinData->mpFirstFloat->ImplIsFloatPopupModeWindow(pChild))
|
|
{
|
|
/*
|
|
* #93895# since floats are system windows, coordinates have
|
|
* to be converted to float relative for the hittest
|
|
*/
|
|
bool bHitTestInsideRect = false;
|
|
FloatingWindow* pFloat = pSVData->mpWinData->mpFirstFloat->ImplFloatHitTest( pChild, rMousePos, bHitTestInsideRect );
|
|
FloatingWindow* pLastLevelFloat;
|
|
FloatWinPopupFlags nPopupFlags;
|
|
if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
|
|
{
|
|
if ( bMouseLeave )
|
|
return true;
|
|
|
|
if ( !pFloat || bHitTestInsideRect )
|
|
{
|
|
if ( ImplGetSVHelpData().mpHelpWin && !ImplGetSVHelpData().mbKeyboardHelp )
|
|
ImplDestroyHelpWindow( true );
|
|
pChild->ImplGetFrame()->SetPointer( PointerStyle::Arrow );
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( nCode & MOUSE_LEFT )
|
|
{
|
|
if ( nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN )
|
|
{
|
|
if ( !pFloat )
|
|
{
|
|
pLastLevelFloat = pSVData->mpWinData->mpFirstFloat->ImplFindLastLevelFloat();
|
|
pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
|
|
return true;
|
|
}
|
|
else if ( bHitTestInsideRect )
|
|
{
|
|
pFloat->ImplSetMouseDown();
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( pFloat )
|
|
{
|
|
if ( bHitTestInsideRect )
|
|
{
|
|
if ( pFloat->ImplIsMouseDown() )
|
|
pFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel );
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pLastLevelFloat = pSVData->mpWinData->mpFirstFloat->ImplFindLastLevelFloat();
|
|
nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
|
|
if ( !(nPopupFlags & FloatWinPopupFlags::NoMouseUpClose) )
|
|
{
|
|
pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( !pFloat )
|
|
{
|
|
pLastLevelFloat = pSVData->mpWinData->mpFirstFloat->ImplFindLastLevelFloat();
|
|
nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
|
|
if ( nPopupFlags & FloatWinPopupFlags::AllMouseButtonClose )
|
|
{
|
|
if ( (nPopupFlags & FloatWinPopupFlags::NoMouseUpClose) &&
|
|
(nSVEvent == MouseNotifyEvent::MOUSEBUTTONUP) )
|
|
return true;
|
|
pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
|
|
return true;
|
|
}
|
|
else
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
static void ImplHandleMouseHelpRequest( vcl::Window* pChild, const Point& rMousePos )
|
|
{
|
|
if (comphelper::LibreOfficeKit::isActive())
|
|
{
|
|
// Ignore tooltips in popup color palettes
|
|
// (e.g. Character Properties dialog -> Font Effects -> Font Color)
|
|
if(pChild->GetType() == WindowType::CONTROL &&
|
|
pChild->GetParent() && pChild->GetParent()->GetParent() &&
|
|
pChild->GetParent()->GetParent()->GetType() == WindowType::DOCKINGWINDOW)
|
|
return;
|
|
}
|
|
|
|
ImplSVHelpData& aHelpData = ImplGetSVHelpData();
|
|
if ( !aHelpData.mpHelpWin ||
|
|
!( aHelpData.mpHelpWin->IsWindowOrChild( pChild ) ||
|
|
pChild->IsWindowOrChild( aHelpData.mpHelpWin ) ) )
|
|
{
|
|
HelpEventMode nHelpMode = HelpEventMode::NONE;
|
|
if ( aHelpData.mbQuickHelp )
|
|
nHelpMode = HelpEventMode::QUICK;
|
|
if ( aHelpData.mbBalloonHelp )
|
|
nHelpMode |= HelpEventMode::BALLOON;
|
|
if ( bool(nHelpMode) )
|
|
{
|
|
if ( pChild->IsInputEnabled() && !pChild->IsInModalMode() )
|
|
{
|
|
HelpEvent aHelpEvent( rMousePos, nHelpMode );
|
|
aHelpData.mbRequestingHelp = true;
|
|
pChild->RequestHelp( aHelpEvent );
|
|
aHelpData.mbRequestingHelp = false;
|
|
}
|
|
// #104172# do not kill keyboard activated tooltips
|
|
else if ( aHelpData.mpHelpWin && !aHelpData.mbKeyboardHelp)
|
|
{
|
|
ImplDestroyHelpWindow( true );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void ImplSetMousePointer( vcl::Window const * pChild )
|
|
{
|
|
if ( ImplGetSVHelpData().mbExtHelpMode )
|
|
pChild->ImplGetFrame()->SetPointer( PointerStyle::Help );
|
|
else
|
|
pChild->ImplGetFrame()->SetPointer( pChild->ImplGetMousePointer() );
|
|
}
|
|
|
|
static bool ImplCallCommand( const VclPtr<vcl::Window>& pChild, CommandEventId nEvt, void const * pData = nullptr,
|
|
bool bMouse = false, Point const * pPos = nullptr )
|
|
{
|
|
Point aPos;
|
|
if ( pPos )
|
|
aPos = *pPos;
|
|
else
|
|
{
|
|
if( bMouse )
|
|
aPos = pChild->GetPointerPosPixel();
|
|
else
|
|
{
|
|
// simulate mouseposition at center of window
|
|
Size aSize( pChild->GetOutputSizePixel() );
|
|
aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
|
|
}
|
|
}
|
|
|
|
CommandEvent aCEvt( aPos, nEvt, bMouse, pData );
|
|
NotifyEvent aNCmdEvt( MouseNotifyEvent::COMMAND, pChild, &aCEvt );
|
|
bool bPreNotify = ImplCallPreNotify( aNCmdEvt );
|
|
if ( pChild->IsDisposed() )
|
|
return false;
|
|
if ( !bPreNotify )
|
|
{
|
|
pChild->ImplGetWindowImpl()->mbCommand = false;
|
|
pChild->Command( aCEvt );
|
|
|
|
if( pChild->IsDisposed() )
|
|
return false;
|
|
pChild->ImplNotifyKeyMouseCommandEventListeners( aNCmdEvt );
|
|
if ( pChild->IsDisposed() )
|
|
return false;
|
|
if ( pChild->ImplGetWindowImpl()->mbCommand )
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/* #i34277# delayed context menu activation;
|
|
* necessary if there already was a popup menu running.
|
|
*/
|
|
|
|
namespace {
|
|
|
|
struct ContextMenuEvent
|
|
{
|
|
VclPtr<vcl::Window> pWindow;
|
|
Point aChildPos;
|
|
};
|
|
|
|
}
|
|
|
|
static void ContextMenuEventLink( void* pCEvent, void* )
|
|
{
|
|
ContextMenuEvent* pEv = static_cast<ContextMenuEvent*>(pCEvent);
|
|
|
|
if( ! pEv->pWindow->IsDisposed() )
|
|
{
|
|
ImplCallCommand( pEv->pWindow, CommandEventId::ContextMenu, nullptr, true, &pEv->aChildPos );
|
|
}
|
|
delete pEv;
|
|
}
|
|
|
|
bool ImplHandleMouseEvent( const VclPtr<vcl::Window>& xWindow, MouseNotifyEvent nSVEvent, bool bMouseLeave,
|
|
long nX, long nY, sal_uInt64 nMsgTime,
|
|
sal_uInt16 nCode, MouseEventModifiers nMode )
|
|
{
|
|
ImplSVHelpData& aHelpData = ImplGetSVHelpData();
|
|
ImplSVData* pSVData = ImplGetSVData();
|
|
Point aMousePos( nX, nY );
|
|
VclPtr<vcl::Window> pChild;
|
|
bool bRet(false);
|
|
sal_uInt16 nClicks(0);
|
|
ImplFrameData* pWinFrameData = xWindow->ImplGetFrameData();
|
|
sal_uInt16 nOldCode = pWinFrameData->mnMouseCode;
|
|
|
|
// we need a mousemove event, before we get a mousebuttondown or a
|
|
// mousebuttonup event
|
|
if ( (nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN) || (nSVEvent == MouseNotifyEvent::MOUSEBUTTONUP) )
|
|
{
|
|
if ( (nSVEvent == MouseNotifyEvent::MOUSEBUTTONUP) && aHelpData.mbExtHelpMode )
|
|
Help::EndExtHelp();
|
|
if ( aHelpData.mpHelpWin )
|
|
{
|
|
if( xWindow->ImplGetWindow() == aHelpData.mpHelpWin )
|
|
{
|
|
ImplDestroyHelpWindow( false );
|
|
return true; // xWindow is dead now - avoid crash!
|
|
}
|
|
else
|
|
ImplDestroyHelpWindow( true );
|
|
}
|
|
|
|
if ( (pWinFrameData->mnLastMouseX != nX) ||
|
|
(pWinFrameData->mnLastMouseY != nY) )
|
|
{
|
|
sal_uInt16 nMoveCode = nCode & ~(MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE);
|
|
ImplHandleMouseEvent(xWindow, MouseNotifyEvent::MOUSEMOVE, false, nX, nY, nMsgTime, nMoveCode, nMode);
|
|
}
|
|
}
|
|
|
|
// update frame data
|
|
pWinFrameData->mnBeforeLastMouseX = pWinFrameData->mnLastMouseX;
|
|
pWinFrameData->mnBeforeLastMouseY = pWinFrameData->mnLastMouseY;
|
|
pWinFrameData->mnLastMouseX = nX;
|
|
pWinFrameData->mnLastMouseY = nY;
|
|
pWinFrameData->mnMouseCode = nCode;
|
|
MouseEventModifiers const nTmpMask = MouseEventModifiers::SYNTHETIC | MouseEventModifiers::MODIFIERCHANGED;
|
|
pWinFrameData->mnMouseMode = nMode & ~nTmpMask;
|
|
if ( bMouseLeave )
|
|
{
|
|
pWinFrameData->mbMouseIn = false;
|
|
if ( ImplGetSVHelpData().mpHelpWin && !ImplGetSVHelpData().mbKeyboardHelp )
|
|
{
|
|
ImplDestroyHelpWindow( true );
|
|
|
|
if ( xWindow->IsDisposed() )
|
|
return true; // xWindow is dead now - avoid crash! (#122045#)
|
|
}
|
|
}
|
|
else
|
|
pWinFrameData->mbMouseIn = true;
|
|
|
|
DBG_ASSERT(!pSVData->mpWinData->mpTrackWin
|
|
|| (pSVData->mpWinData->mpTrackWin == pSVData->mpWinData->mpCaptureWin),
|
|
"ImplHandleMouseEvent: TrackWin != CaptureWin");
|
|
|
|
// AutoScrollMode
|
|
if (pSVData->mpWinData->mpAutoScrollWin && (nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN))
|
|
{
|
|
pSVData->mpWinData->mpAutoScrollWin->EndAutoScroll();
|
|
return true;
|
|
}
|
|
|
|
// find mouse window
|
|
if (pSVData->mpWinData->mpCaptureWin)
|
|
{
|
|
pChild = pSVData->mpWinData->mpCaptureWin;
|
|
|
|
SAL_WARN_IF( xWindow != pChild->ImplGetFrameWindow(), "vcl",
|
|
"ImplHandleMouseEvent: mouse event is not sent to capture window" );
|
|
|
|
// java client cannot capture mouse correctly
|
|
if ( xWindow != pChild->ImplGetFrameWindow() )
|
|
return false;
|
|
|
|
if ( bMouseLeave )
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
if ( bMouseLeave )
|
|
pChild = nullptr;
|
|
else
|
|
pChild = xWindow->ImplFindWindow( aMousePos );
|
|
}
|
|
|
|
// test this because mouse events are buffered in the remote version
|
|
// and size may not be in sync
|
|
if ( !pChild && !bMouseLeave )
|
|
return false;
|
|
|
|
// execute a few tests and catch the message or implement the status
|
|
if ( pChild )
|
|
{
|
|
if( pChild->ImplIsAntiparallel() )
|
|
{
|
|
// re-mirror frame pos at pChild
|
|
const OutputDevice *pChildWinOutDev = pChild->GetOutDev();
|
|
pChildWinOutDev->ReMirror( aMousePos );
|
|
}
|
|
|
|
// no mouse messages to disabled windows
|
|
// #106845# if the window was disabled during capturing we have to pass the mouse events to release capturing
|
|
if (pSVData->mpWinData->mpCaptureWin.get() != pChild
|
|
&& (!pChild->IsEnabled() || !pChild->IsInputEnabled() || pChild->IsInModalMode()))
|
|
{
|
|
ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave );
|
|
if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
|
|
{
|
|
ImplHandleMouseHelpRequest( pChild, aMousePos );
|
|
if( pWinFrameData->mpMouseMoveWin.get() != pChild )
|
|
nMode |= MouseEventModifiers::ENTERWINDOW;
|
|
}
|
|
|
|
// Call the hook also, if Window is disabled
|
|
Point aChildPos = pChild->ImplFrameToOutput( aMousePos );
|
|
MouseEvent aMEvt( aChildPos, pWinFrameData->mnClickCount, nMode, nCode, nCode );
|
|
NotifyEvent aNEvt( nSVEvent, pChild, &aMEvt );
|
|
|
|
if( pChild->IsCallHandlersOnInputDisabled() )
|
|
{
|
|
pWinFrameData->mpMouseMoveWin = pChild;
|
|
pChild->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
|
|
}
|
|
|
|
if ( nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN )
|
|
return true;
|
|
else
|
|
{
|
|
// Set normal MousePointer for disabled windows
|
|
if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
|
|
ImplSetMousePointer( pChild );
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// End ExtTextInput-Mode, if the user click in the same TopLevel Window
|
|
if (pSVData->mpWinData->mpExtTextInputWin
|
|
&& ((nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN)
|
|
|| (nSVEvent == MouseNotifyEvent::MOUSEBUTTONUP)))
|
|
pSVData->mpWinData->mpExtTextInputWin->EndExtTextInput();
|
|
}
|
|
|
|
// determine mouse event data
|
|
if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
|
|
{
|
|
// check if MouseMove belongs to same window and if the
|
|
// status did not change
|
|
if ( pChild )
|
|
{
|
|
Point aChildMousePos = pChild->ImplFrameToOutput( aMousePos );
|
|
if ( !bMouseLeave &&
|
|
(pChild == pWinFrameData->mpMouseMoveWin) &&
|
|
(aChildMousePos.X() == pWinFrameData->mnLastMouseWinX) &&
|
|
(aChildMousePos.Y() == pWinFrameData->mnLastMouseWinY) &&
|
|
(nOldCode == pWinFrameData->mnMouseCode) )
|
|
{
|
|
// set mouse pointer anew, as it could have changed
|
|
// due to the mode switch
|
|
ImplSetMousePointer( pChild );
|
|
return false;
|
|
}
|
|
|
|
pWinFrameData->mnLastMouseWinX = aChildMousePos.X();
|
|
pWinFrameData->mnLastMouseWinY = aChildMousePos.Y();
|
|
}
|
|
|
|
// mouse click
|
|
nClicks = pWinFrameData->mnClickCount;
|
|
|
|
// call Start-Drag handler if required
|
|
// Warning: should be called before Move, as otherwise during
|
|
// fast mouse movements the applications move to the selection state
|
|
vcl::Window* pMouseDownWin = pWinFrameData->mpMouseDownWin;
|
|
if ( pMouseDownWin )
|
|
{
|
|
// check for matching StartDrag mode. We only compare
|
|
// the status of the mouse buttons, such that e. g. Mod1 can
|
|
// change immediately to the copy mode
|
|
const MouseSettings& rMSettings = pMouseDownWin->GetSettings().GetMouseSettings();
|
|
if ( (nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) ==
|
|
(MouseSettings::GetStartDragCode() & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) )
|
|
{
|
|
if ( !pMouseDownWin->ImplGetFrameData()->mbStartDragCalled )
|
|
{
|
|
long nDragW = rMSettings.GetStartDragWidth();
|
|
long nDragH = rMSettings.GetStartDragHeight();
|
|
//long nMouseX = nX;
|
|
//long nMouseY = nY;
|
|
long nMouseX = aMousePos.X(); // #106074# use the possibly re-mirrored coordinates (RTL) ! nX,nY are unmodified !
|
|
long nMouseY = aMousePos.Y();
|
|
if ( !(((nMouseX-nDragW) <= pMouseDownWin->ImplGetFrameData()->mnFirstMouseX) &&
|
|
((nMouseX+nDragW) >= pMouseDownWin->ImplGetFrameData()->mnFirstMouseX)) ||
|
|
!(((nMouseY-nDragH) <= pMouseDownWin->ImplGetFrameData()->mnFirstMouseY) &&
|
|
((nMouseY+nDragH) >= pMouseDownWin->ImplGetFrameData()->mnFirstMouseY)) )
|
|
{
|
|
pMouseDownWin->ImplGetFrameData()->mbStartDragCalled = true;
|
|
|
|
// Check if drag source provides its own recognizer
|
|
if( pMouseDownWin->ImplGetFrameData()->mbInternalDragGestureRecognizer )
|
|
{
|
|
// query DropTarget from child window
|
|
css::uno::Reference< css::datatransfer::dnd::XDragGestureRecognizer > xDragGestureRecognizer(
|
|
pMouseDownWin->ImplGetWindowImpl()->mxDNDListenerContainer,
|
|
css::uno::UNO_QUERY );
|
|
|
|
if( xDragGestureRecognizer.is() )
|
|
{
|
|
// retrieve mouse position relative to mouse down window
|
|
Point relLoc = pMouseDownWin->ImplFrameToOutput( Point(
|
|
pMouseDownWin->ImplGetFrameData()->mnFirstMouseX,
|
|
pMouseDownWin->ImplGetFrameData()->mnFirstMouseY ) );
|
|
|
|
// create a UNO mouse event out of the available data
|
|
css::awt::MouseEvent aMouseEvent( static_cast < css::uno::XInterface * > ( nullptr ),
|
|
#ifdef MACOSX
|
|
nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3),
|
|
#else
|
|
nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2),
|
|
#endif
|
|
nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE),
|
|
nMouseX,
|
|
nMouseY,
|
|
nClicks,
|
|
false );
|
|
|
|
SolarMutexReleaser aReleaser;
|
|
|
|
// FIXME: where do I get Action from ?
|
|
css::uno::Reference< css::datatransfer::dnd::XDragSource > xDragSource = pMouseDownWin->GetDragSource();
|
|
|
|
if( xDragSource.is() )
|
|
{
|
|
static_cast < DNDListenerContainer * > ( xDragGestureRecognizer.get() )->fireDragGestureEvent( 0,
|
|
relLoc.X(), relLoc.Y(), xDragSource, css::uno::makeAny( aMouseEvent ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
pMouseDownWin->ImplGetFrameData()->mbStartDragCalled = true;
|
|
}
|
|
|
|
// test for mouseleave and mouseenter
|
|
VclPtr<vcl::Window> pMouseMoveWin = pWinFrameData->mpMouseMoveWin;
|
|
if ( pChild != pMouseMoveWin )
|
|
{
|
|
if ( pMouseMoveWin )
|
|
{
|
|
Point aLeaveMousePos = pMouseMoveWin->ImplFrameToOutput( aMousePos );
|
|
MouseEvent aMLeaveEvt( aLeaveMousePos, nClicks, nMode | MouseEventModifiers::LEAVEWINDOW, nCode, nCode );
|
|
NotifyEvent aNLeaveEvt( MouseNotifyEvent::MOUSEMOVE, pMouseMoveWin, &aMLeaveEvt );
|
|
pWinFrameData->mbInMouseMove = true;
|
|
pMouseMoveWin->ImplGetWinData()->mbMouseOver = false;
|
|
|
|
// A MouseLeave can destroy this window
|
|
if ( !ImplCallPreNotify( aNLeaveEvt ) )
|
|
{
|
|
pMouseMoveWin->MouseMove( aMLeaveEvt );
|
|
if( !pMouseMoveWin->IsDisposed() )
|
|
aNLeaveEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNLeaveEvt );
|
|
}
|
|
|
|
pWinFrameData->mpMouseMoveWin = nullptr;
|
|
pWinFrameData->mbInMouseMove = false;
|
|
|
|
if ( pChild && pChild->IsDisposed() )
|
|
pChild = nullptr;
|
|
if ( pMouseMoveWin->IsDisposed() )
|
|
return true;
|
|
}
|
|
|
|
nMode |= MouseEventModifiers::ENTERWINDOW;
|
|
}
|
|
pWinFrameData->mpMouseMoveWin = pChild;
|
|
if( pChild )
|
|
pChild->ImplGetWinData()->mbMouseOver = true;
|
|
|
|
// MouseLeave
|
|
if ( !pChild )
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
if (pChild)
|
|
{
|
|
// mouse click
|
|
if ( nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN )
|
|
{
|
|
const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
|
|
sal_uInt64 nDblClkTime = rMSettings.GetDoubleClickTime();
|
|
long nDblClkW = rMSettings.GetDoubleClickWidth();
|
|
long nDblClkH = rMSettings.GetDoubleClickHeight();
|
|
//long nMouseX = nX;
|
|
//long nMouseY = nY;
|
|
long nMouseX = aMousePos.X(); // #106074# use the possibly re-mirrored coordinates (RTL) ! nX,nY are unmodified !
|
|
long nMouseY = aMousePos.Y();
|
|
|
|
if ( (pChild == pChild->ImplGetFrameData()->mpMouseDownWin) &&
|
|
(nCode == pChild->ImplGetFrameData()->mnFirstMouseCode) &&
|
|
((nMsgTime-pChild->ImplGetFrameData()->mnMouseDownTime) < nDblClkTime) &&
|
|
((nMouseX-nDblClkW) <= pChild->ImplGetFrameData()->mnFirstMouseX) &&
|
|
((nMouseX+nDblClkW) >= pChild->ImplGetFrameData()->mnFirstMouseX) &&
|
|
((nMouseY-nDblClkH) <= pChild->ImplGetFrameData()->mnFirstMouseY) &&
|
|
((nMouseY+nDblClkH) >= pChild->ImplGetFrameData()->mnFirstMouseY) )
|
|
{
|
|
pChild->ImplGetFrameData()->mnClickCount++;
|
|
pChild->ImplGetFrameData()->mbStartDragCalled = true;
|
|
}
|
|
else
|
|
{
|
|
pChild->ImplGetFrameData()->mpMouseDownWin = pChild;
|
|
pChild->ImplGetFrameData()->mnClickCount = 1;
|
|
pChild->ImplGetFrameData()->mnFirstMouseX = nMouseX;
|
|
pChild->ImplGetFrameData()->mnFirstMouseY = nMouseY;
|
|
pChild->ImplGetFrameData()->mnFirstMouseCode = nCode;
|
|
pChild->ImplGetFrameData()->mbStartDragCalled = (nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) !=
|
|
(MouseSettings::GetStartDragCode() & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE));
|
|
}
|
|
pChild->ImplGetFrameData()->mnMouseDownTime = nMsgTime;
|
|
}
|
|
nClicks = pChild->ImplGetFrameData()->mnClickCount;
|
|
}
|
|
|
|
pSVData->maAppData.mnLastInputTime = tools::Time::GetSystemTicks();
|
|
}
|
|
|
|
SAL_WARN_IF( !pChild, "vcl", "ImplHandleMouseEvent: pChild == NULL" );
|
|
|
|
if (!pChild)
|
|
return false;
|
|
|
|
// create mouse event
|
|
Point aChildPos = pChild->ImplFrameToOutput( aMousePos );
|
|
MouseEvent aMEvt( aChildPos, nClicks, nMode, nCode, nCode );
|
|
|
|
|
|
// tracking window gets the mouse events
|
|
if (pSVData->mpWinData->mpTrackWin)
|
|
pChild = pSVData->mpWinData->mpTrackWin;
|
|
|
|
// handle FloatingMode
|
|
if (!pSVData->mpWinData->mpTrackWin && pSVData->mpWinData->mpFirstFloat)
|
|
{
|
|
if ( ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave ) )
|
|
{
|
|
if ( !pChild->IsDisposed() )
|
|
{
|
|
pChild->ImplGetFrameData()->mbStartDragCalled = true;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// call handler
|
|
bool bCallHelpRequest = true;
|
|
SAL_WARN_IF( !pChild, "vcl", "ImplHandleMouseEvent: pChild is NULL" );
|
|
|
|
if (!pChild)
|
|
return false;
|
|
|
|
NotifyEvent aNEvt( nSVEvent, pChild, &aMEvt );
|
|
if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
|
|
pChild->ImplGetFrameData()->mbInMouseMove = true;
|
|
|
|
// bring window into foreground on mouseclick
|
|
if ( nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN )
|
|
{
|
|
if (!pSVData->mpWinData->mpFirstFloat
|
|
&& // totop for floating windows in popup would change the focus and would close them immediately
|
|
!(pChild->ImplGetFrameWindow()->GetStyle()
|
|
& WB_OWNERDRAWDECORATION)) // ownerdrawdecorated windows must never grab focus
|
|
pChild->ToTop();
|
|
if ( pChild->IsDisposed() )
|
|
return true;
|
|
}
|
|
|
|
if ( ImplCallPreNotify( aNEvt ) || pChild->IsDisposed() )
|
|
bRet = true;
|
|
else
|
|
{
|
|
bRet = false;
|
|
if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
|
|
{
|
|
if (pSVData->mpWinData->mpTrackWin)
|
|
{
|
|
TrackingEvent aTEvt( aMEvt );
|
|
pChild->Tracking( aTEvt );
|
|
if ( !pChild->IsDisposed() )
|
|
{
|
|
// When ScrollRepeat, we restart the timer
|
|
if (pSVData->mpWinData->mpTrackTimer
|
|
&& (pSVData->mpWinData->mnTrackFlags & StartTrackingFlags::ScrollRepeat))
|
|
pSVData->mpWinData->mpTrackTimer->Start();
|
|
}
|
|
bCallHelpRequest = false;
|
|
bRet = true;
|
|
}
|
|
else
|
|
{
|
|
// Auto-ToTop
|
|
if (!pSVData->mpWinData->mpCaptureWin
|
|
&& (pChild->GetSettings().GetMouseSettings().GetOptions()
|
|
& MouseSettingsOptions::AutoFocus))
|
|
pChild->ToTop( ToTopFlags::NoGrabFocus );
|
|
|
|
if( pChild->IsDisposed() )
|
|
bCallHelpRequest = false;
|
|
else
|
|
{
|
|
// if the MouseMove handler changes the help window's visibility
|
|
// the HelpRequest handler should not be called anymore
|
|
vcl::Window* pOldHelpTextWin = ImplGetSVHelpData().mpHelpWin;
|
|
pChild->MouseMove( aMEvt );
|
|
if ( pOldHelpTextWin != ImplGetSVHelpData().mpHelpWin )
|
|
bCallHelpRequest = false;
|
|
}
|
|
}
|
|
}
|
|
else if ( nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN )
|
|
{
|
|
if ( pSVData->mpWinData->mpTrackWin )
|
|
bRet = true;
|
|
else
|
|
{
|
|
pChild->ImplGetWindowImpl()->mbMouseButtonDown = false;
|
|
pChild->MouseButtonDown( aMEvt );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pSVData->mpWinData->mpTrackWin)
|
|
{
|
|
pChild->EndTracking();
|
|
bRet = true;
|
|
}
|
|
else
|
|
{
|
|
pChild->ImplGetWindowImpl()->mbMouseButtonUp = false;
|
|
pChild->MouseButtonUp( aMEvt );
|
|
}
|
|
}
|
|
|
|
assert(aNEvt.GetWindow() == pChild);
|
|
|
|
if (!pChild->IsDisposed())
|
|
pChild->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
|
|
}
|
|
|
|
if (pChild->IsDisposed())
|
|
return true;
|
|
|
|
if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
|
|
pChild->ImplGetWindowImpl()->mpFrameData->mbInMouseMove = false;
|
|
|
|
if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
|
|
{
|
|
if ( bCallHelpRequest && !ImplGetSVHelpData().mbKeyboardHelp )
|
|
ImplHandleMouseHelpRequest( pChild, pChild->OutputToScreenPixel( aMEvt.GetPosPixel() ) );
|
|
bRet = true;
|
|
}
|
|
else if ( !bRet )
|
|
{
|
|
if ( nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN )
|
|
{
|
|
if ( !pChild->ImplGetWindowImpl()->mbMouseButtonDown )
|
|
bRet = true;
|
|
}
|
|
else
|
|
{
|
|
if ( !pChild->ImplGetWindowImpl()->mbMouseButtonUp )
|
|
bRet = true;
|
|
}
|
|
}
|
|
|
|
if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
|
|
{
|
|
// set new mouse pointer
|
|
if ( !bMouseLeave )
|
|
ImplSetMousePointer( pChild );
|
|
}
|
|
else if ( (nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN) || (nSVEvent == MouseNotifyEvent::MOUSEBUTTONUP) )
|
|
{
|
|
// Command-Events
|
|
if ( /*!bRet &&*/ (nClicks == 1) && (nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN) &&
|
|
(nCode == MOUSE_MIDDLE) )
|
|
{
|
|
MouseMiddleButtonAction nMiddleAction = pChild->GetSettings().GetMouseSettings().GetMiddleButtonAction();
|
|
if ( nMiddleAction == MouseMiddleButtonAction::AutoScroll )
|
|
bRet = !ImplCallCommand( pChild, CommandEventId::StartAutoScroll, nullptr, true, &aChildPos );
|
|
else if ( nMiddleAction == MouseMiddleButtonAction::PasteSelection )
|
|
bRet = !ImplCallCommand( pChild, CommandEventId::PasteSelection, nullptr, true, &aChildPos );
|
|
}
|
|
else
|
|
{
|
|
// ContextMenu
|
|
if ( (nCode == MouseSettings::GetContextMenuCode()) &&
|
|
(nClicks == MouseSettings::GetContextMenuClicks()) )
|
|
{
|
|
bool bContextMenu = (nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN);
|
|
if ( bContextMenu )
|
|
{
|
|
if( pSVData->maAppData.mpActivePopupMenu )
|
|
{
|
|
/* #i34277# there already is a context menu open
|
|
* that was probably just closed with EndPopupMode.
|
|
* We need to give the eventual corresponding
|
|
* PopupMenu::Execute a chance to end properly.
|
|
* Therefore delay context menu command and
|
|
* issue only after popping one frame of the
|
|
* Yield stack.
|
|
*/
|
|
ContextMenuEvent* pEv = new ContextMenuEvent;
|
|
pEv->pWindow = pChild;
|
|
pEv->aChildPos = aChildPos;
|
|
Application::PostUserEvent( Link<void*,void>( pEv, ContextMenuEventLink ) );
|
|
}
|
|
else
|
|
bRet = ! ImplCallCommand( pChild, CommandEventId::ContextMenu, nullptr, true, &aChildPos );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
static vcl::Window* ImplGetKeyInputWindow( vcl::Window* pWindow )
|
|
{
|
|
ImplSVData* pSVData = ImplGetSVData();
|
|
|
|
// determine last input time
|
|
pSVData->maAppData.mnLastInputTime = tools::Time::GetSystemTicks();
|
|
|
|
// #127104# workaround for destroyed windows
|
|
if( pWindow->ImplGetWindowImpl() == nullptr )
|
|
return nullptr;
|
|
|
|
// find window - is every time the window which has currently the
|
|
// focus or the last time the focus.
|
|
|
|
// the first floating window always has the focus, try it, or any parent floating windows, first
|
|
vcl::Window* pChild = pSVData->mpWinData->mpFirstFloat;
|
|
while (pChild)
|
|
{
|
|
if (pChild->ImplGetWindowImpl()->mbFloatWin)
|
|
{
|
|
if (static_cast<FloatingWindow *>(pChild)->GrabsFocus())
|
|
break;
|
|
}
|
|
else if (pChild->ImplGetWindowImpl()->mbDockWin)
|
|
{
|
|
vcl::Window* pParent = pChild->GetWindow(GetWindowType::RealParent);
|
|
if (pParent && pParent->ImplGetWindowImpl()->mbFloatWin &&
|
|
static_cast<FloatingWindow *>(pParent)->GrabsFocus())
|
|
break;
|
|
}
|
|
pChild = pChild->GetParent();
|
|
}
|
|
|
|
if (!pChild)
|
|
pChild = pWindow;
|
|
|
|
pChild = pChild->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
|
|
|
|
// no child - then no input
|
|
if ( !pChild )
|
|
return nullptr;
|
|
|
|
// We call also KeyInput if we haven't the focus, because on Unix
|
|
// system this is often the case when a Lookup Choice Window has
|
|
// the focus - because this windows send the KeyInput directly to
|
|
// the window without resetting the focus
|
|
SAL_WARN_IF(pChild != pSVData->mpWinData->mpFocusWin, "vcl",
|
|
"ImplHandleKey: Keyboard-Input is sent to a frame without focus");
|
|
|
|
// no keyinput to disabled windows
|
|
if ( !pChild->IsEnabled() || !pChild->IsInputEnabled() || pChild->IsInModalMode() )
|
|
return nullptr;
|
|
|
|
return pChild;
|
|
}
|
|
|
|
static bool ImplHandleKey( vcl::Window* pWindow, MouseNotifyEvent nSVEvent,
|
|
sal_uInt16 nKeyCode, sal_uInt16 nCharCode, sal_uInt16 nRepeat, bool bForward )
|
|
{
|
|
ImplSVData* pSVData = ImplGetSVData();
|
|
vcl::KeyCode aKeyCode( nKeyCode, nKeyCode );
|
|
sal_uInt16 nEvCode = aKeyCode.GetCode();
|
|
|
|
// allow application key listeners to remove the key event
|
|
// but make sure we're not forwarding external KeyEvents, (ie where bForward is false)
|
|
// because those are coming back from the listener itself and MUST be processed
|
|
if( bForward )
|
|
{
|
|
VclEventId nVCLEvent;
|
|
switch( nSVEvent )
|
|
{
|
|
case MouseNotifyEvent::KEYINPUT:
|
|
nVCLEvent = VclEventId::WindowKeyInput;
|
|
break;
|
|
case MouseNotifyEvent::KEYUP:
|
|
nVCLEvent = VclEventId::WindowKeyUp;
|
|
break;
|
|
default:
|
|
nVCLEvent = VclEventId::NONE;
|
|
break;
|
|
}
|
|
KeyEvent aKeyEvent(static_cast<sal_Unicode>(nCharCode), aKeyCode, nRepeat);
|
|
if (nVCLEvent != VclEventId::NONE && Application::HandleKey(nVCLEvent, pWindow, &aKeyEvent))
|
|
return true;
|
|
}
|
|
|
|
// #i1820# use locale specific decimal separator
|
|
if( nEvCode == KEY_DECIMAL )
|
|
{
|
|
if( Application::GetSettings().GetMiscSettings().GetEnableLocalizedDecimalSep() )
|
|
{
|
|
OUString aSep( pWindow->GetSettings().GetLocaleDataWrapper().getNumDecimalSep() );
|
|
nCharCode = static_cast<sal_uInt16>(aSep[0]);
|
|
}
|
|
}
|
|
|
|
bool bCtrlF6 = (aKeyCode.GetCode() == KEY_F6) && aKeyCode.IsMod1();
|
|
|
|
// determine last input time
|
|
pSVData->maAppData.mnLastInputTime = tools::Time::GetSystemTicks();
|
|
|
|
// handle tracking window
|
|
if ( nSVEvent == MouseNotifyEvent::KEYINPUT )
|
|
{
|
|
if ( ImplGetSVHelpData().mbExtHelpMode )
|
|
{
|
|
Help::EndExtHelp();
|
|
if ( nEvCode == KEY_ESCAPE )
|
|
return true;
|
|
}
|
|
if ( ImplGetSVHelpData().mpHelpWin )
|
|
ImplDestroyHelpWindow( false );
|
|
|
|
// AutoScrollMode
|
|
if (pSVData->mpWinData->mpAutoScrollWin)
|
|
{
|
|
pSVData->mpWinData->mpAutoScrollWin->EndAutoScroll();
|
|
if ( nEvCode == KEY_ESCAPE )
|
|
return true;
|
|
}
|
|
|
|
if (pSVData->mpWinData->mpTrackWin)
|
|
{
|
|
sal_uInt16 nOrigCode = aKeyCode.GetCode();
|
|
|
|
if ( nOrigCode == KEY_ESCAPE )
|
|
{
|
|
pSVData->mpWinData->mpTrackWin->EndTracking( TrackingEventFlags::Cancel | TrackingEventFlags::Key );
|
|
if (pSVData->mpWinData->mpFirstFloat)
|
|
{
|
|
FloatingWindow* pLastLevelFloat = pSVData->mpWinData->mpFirstFloat->ImplFindLastLevelFloat();
|
|
if ( !(pLastLevelFloat->GetPopupModeFlags() & FloatWinPopupFlags::NoKeyClose) )
|
|
{
|
|
sal_uInt16 nEscCode = aKeyCode.GetCode();
|
|
|
|
if ( nEscCode == KEY_ESCAPE )
|
|
pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
else if ( nOrigCode == KEY_RETURN )
|
|
{
|
|
pSVData->mpWinData->mpTrackWin->EndTracking( TrackingEventFlags::Key );
|
|
return true;
|
|
}
|
|
else
|
|
return true;
|
|
}
|
|
|
|
// handle FloatingMode
|
|
if (pSVData->mpWinData->mpFirstFloat)
|
|
{
|
|
FloatingWindow* pLastLevelFloat = pSVData->mpWinData->mpFirstFloat->ImplFindLastLevelFloat();
|
|
if ( !(pLastLevelFloat->GetPopupModeFlags() & FloatWinPopupFlags::NoKeyClose) )
|
|
{
|
|
sal_uInt16 nCode = aKeyCode.GetCode();
|
|
|
|
if ( (nCode == KEY_ESCAPE) || bCtrlF6)
|
|
{
|
|
pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
|
|
if( !bCtrlF6 )
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// test for accel
|
|
if ( pSVData->maAppData.mpAccelMgr )
|
|
{
|
|
if ( pSVData->maAppData.mpAccelMgr->IsAccelKey( aKeyCode ) )
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// find window
|
|
VclPtr<vcl::Window> pChild = ImplGetKeyInputWindow( pWindow );
|
|
if ( !pChild )
|
|
return false;
|
|
|
|
// RTL: mirror cursor keys
|
|
const OutputDevice *pChildOutDev = pChild->GetOutDev();
|
|
if( (aKeyCode.GetCode() == KEY_LEFT || aKeyCode.GetCode() == KEY_RIGHT) &&
|
|
pChildOutDev->HasMirroredGraphics() && pChild->IsRTLEnabled() )
|
|
aKeyCode = vcl::KeyCode( aKeyCode.GetCode() == KEY_LEFT ? KEY_RIGHT : KEY_LEFT, aKeyCode.GetModifier() );
|
|
|
|
KeyEvent aKeyEvt( static_cast<sal_Unicode>(nCharCode), aKeyCode, nRepeat );
|
|
NotifyEvent aNotifyEvt( nSVEvent, pChild, &aKeyEvt );
|
|
bool bKeyPreNotify = ImplCallPreNotify( aNotifyEvt );
|
|
bool bRet = true;
|
|
|
|
if ( !bKeyPreNotify && !pChild->IsDisposed() )
|
|
{
|
|
if ( nSVEvent == MouseNotifyEvent::KEYINPUT )
|
|
{
|
|
UITestLogger::getInstance().logKeyInput(pChild, aKeyEvt);
|
|
pChild->ImplGetWindowImpl()->mbKeyInput = false;
|
|
pChild->KeyInput( aKeyEvt );
|
|
}
|
|
else
|
|
{
|
|
pChild->ImplGetWindowImpl()->mbKeyUp = false;
|
|
pChild->KeyUp( aKeyEvt );
|
|
}
|
|
if( !pChild->IsDisposed() )
|
|
aNotifyEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNotifyEvt );
|
|
}
|
|
|
|
if ( pChild->IsDisposed() )
|
|
return true;
|
|
|
|
if ( nSVEvent == MouseNotifyEvent::KEYINPUT )
|
|
{
|
|
if ( !bKeyPreNotify && pChild->ImplGetWindowImpl()->mbKeyInput )
|
|
{
|
|
sal_uInt16 nCode = aKeyCode.GetCode();
|
|
|
|
// #101999# is focus in or below toolbox
|
|
bool bToolboxFocus=false;
|
|
if( (nCode == KEY_F1) && aKeyCode.IsShift() )
|
|
{
|
|
vcl::Window *pWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
|
|
while( pWin )
|
|
{
|
|
if( pWin->ImplGetWindowImpl()->mbToolBox )
|
|
{
|
|
bToolboxFocus = true;
|
|
break;
|
|
}
|
|
else
|
|
pWin = pWin->GetParent();
|
|
}
|
|
}
|
|
|
|
// ContextMenu
|
|
if ( (nCode == KEY_CONTEXTMENU) || ((nCode == KEY_F10) && aKeyCode.IsShift() && !aKeyCode.IsMod1() && !aKeyCode.IsMod2() ) )
|
|
bRet = !ImplCallCommand( pChild, CommandEventId::ContextMenu );
|
|
else if ( ( (nCode == KEY_F2) && aKeyCode.IsShift() ) || ( (nCode == KEY_F1) && aKeyCode.IsMod1() ) ||
|
|
// #101999# no active help when focus in toolbox, simulate BalloonHelp instead
|
|
( (nCode == KEY_F1) && aKeyCode.IsShift() && bToolboxFocus ) )
|
|
{
|
|
// TipHelp via Keyboard (Shift-F2 or Ctrl-F1)
|
|
// simulate mouseposition at center of window
|
|
|
|
Size aSize = pChild->GetOutputSize();
|
|
Point aPos( aSize.getWidth()/2, aSize.getHeight()/2 );
|
|
aPos = pChild->OutputToScreenPixel( aPos );
|
|
|
|
HelpEvent aHelpEvent( aPos, HelpEventMode::BALLOON );
|
|
aHelpEvent.SetKeyboardActivated( true );
|
|
ImplGetSVHelpData().mbSetKeyboardHelp = true;
|
|
pChild->RequestHelp( aHelpEvent );
|
|
ImplGetSVHelpData().mbSetKeyboardHelp = false;
|
|
}
|
|
else if ( (nCode == KEY_F1) || (nCode == KEY_HELP) )
|
|
{
|
|
if ( !aKeyCode.GetModifier() )
|
|
{
|
|
if ( ImplGetSVHelpData().mbContextHelp )
|
|
{
|
|
Point aMousePos = pChild->OutputToScreenPixel( pChild->GetPointerPosPixel() );
|
|
HelpEvent aHelpEvent( aMousePos, HelpEventMode::CONTEXT );
|
|
pChild->RequestHelp( aHelpEvent );
|
|
}
|
|
else
|
|
bRet = false;
|
|
}
|
|
else if ( aKeyCode.IsShift() )
|
|
{
|
|
if ( ImplGetSVHelpData().mbExtHelp )
|
|
Help::StartExtHelp();
|
|
else
|
|
bRet = false;
|
|
}
|
|
}
|
|
else
|
|
bRet = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( !bKeyPreNotify && pChild->ImplGetWindowImpl()->mbKeyUp )
|
|
bRet = false;
|
|
}
|
|
|
|
// #105591# send keyinput to parent if we are a floating window and the key was not processed yet
|
|
if( !bRet && pWindow->ImplGetWindowImpl() && pWindow->ImplGetWindowImpl()->mbFloatWin && pWindow->GetParent() && (pWindow->ImplGetWindowImpl()->mpFrame != pWindow->GetParent()->ImplGetWindowImpl()->mpFrame) )
|
|
{
|
|
pChild = pWindow->GetParent();
|
|
|
|
// call handler
|
|
NotifyEvent aNEvt( nSVEvent, pChild, &aKeyEvt );
|
|
bool bPreNotify = ImplCallPreNotify( aNEvt );
|
|
if ( pChild->IsDisposed() )
|
|
return true;
|
|
|
|
if ( !bPreNotify )
|
|
{
|
|
if ( nSVEvent == MouseNotifyEvent::KEYINPUT )
|
|
{
|
|
pChild->ImplGetWindowImpl()->mbKeyInput = false;
|
|
pChild->KeyInput( aKeyEvt );
|
|
}
|
|
else
|
|
{
|
|
pChild->ImplGetWindowImpl()->mbKeyUp = false;
|
|
pChild->KeyUp( aKeyEvt );
|
|
}
|
|
|
|
if( !pChild->IsDisposed() )
|
|
aNEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
|
|
if ( pChild->IsDisposed() )
|
|
return true;
|
|
}
|
|
|
|
if( bPreNotify || !pChild->ImplGetWindowImpl()->mbKeyInput )
|
|
bRet = true;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
static bool ImplHandleExtTextInput( vcl::Window* pWindow,
|
|
const OUString& rText,
|
|
const ExtTextInputAttr* pTextAttr,
|
|
sal_Int32 nCursorPos, sal_uInt16 nCursorFlags )
|
|
{
|
|
ImplSVData* pSVData = ImplGetSVData();
|
|
vcl::Window* pChild = nullptr;
|
|
|
|
int nTries = 200;
|
|
while( nTries-- )
|
|
{
|
|
pChild = pSVData->mpWinData->mpExtTextInputWin;
|
|
if ( !pChild )
|
|
{
|
|
pChild = ImplGetKeyInputWindow( pWindow );
|
|
if ( !pChild )
|
|
return false;
|
|
}
|
|
if( !pChild->ImplGetWindowImpl()->mpFrameData->mnFocusId )
|
|
break;
|
|
|
|
if (comphelper::LibreOfficeKit::isActive())
|
|
{
|
|
SAL_WARN("vcl", "Failed to get ext text input context");
|
|
break;
|
|
}
|
|
Application::Yield();
|
|
}
|
|
|
|
// If it is the first ExtTextInput call, we inform the information
|
|
// and allocate the data, which we must store in this mode
|
|
ImplWinData* pWinData = pChild->ImplGetWinData();
|
|
if ( !pChild->ImplGetWindowImpl()->mbExtTextInput )
|
|
{
|
|
pChild->ImplGetWindowImpl()->mbExtTextInput = true;
|
|
pWinData->mpExtOldText = OUString();
|
|
pWinData->mpExtOldAttrAry.reset();
|
|
pSVData->mpWinData->mpExtTextInputWin = pChild;
|
|
ImplCallCommand( pChild, CommandEventId::StartExtTextInput );
|
|
}
|
|
|
|
// be aware of being recursively called in StartExtTextInput
|
|
if ( !pChild->ImplGetWindowImpl()->mbExtTextInput )
|
|
return false;
|
|
|
|
// Test for changes
|
|
bool bOnlyCursor = false;
|
|
sal_Int32 nMinLen = std::min( pWinData->mpExtOldText->getLength(), rText.getLength() );
|
|
sal_Int32 nDeltaStart = 0;
|
|
while ( nDeltaStart < nMinLen )
|
|
{
|
|
if ( (*pWinData->mpExtOldText)[nDeltaStart] != rText[nDeltaStart] )
|
|
break;
|
|
nDeltaStart++;
|
|
}
|
|
if ( pWinData->mpExtOldAttrAry || pTextAttr )
|
|
{
|
|
if ( !pWinData->mpExtOldAttrAry || !pTextAttr )
|
|
nDeltaStart = 0;
|
|
else
|
|
{
|
|
sal_Int32 i = 0;
|
|
while ( i < nDeltaStart )
|
|
{
|
|
if ( pWinData->mpExtOldAttrAry[i] != pTextAttr[i] )
|
|
{
|
|
nDeltaStart = i;
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
if ( (nDeltaStart >= nMinLen) &&
|
|
(pWinData->mpExtOldText->getLength() == rText.getLength()) )
|
|
bOnlyCursor = true;
|
|
|
|
// Call Event and store the information
|
|
CommandExtTextInputData aData( rText, pTextAttr,
|
|
nCursorPos, nCursorFlags,
|
|
bOnlyCursor );
|
|
*pWinData->mpExtOldText = rText;
|
|
pWinData->mpExtOldAttrAry.reset();
|
|
if ( pTextAttr )
|
|
{
|
|
pWinData->mpExtOldAttrAry.reset( new ExtTextInputAttr[rText.getLength()] );
|
|
memcpy( pWinData->mpExtOldAttrAry.get(), pTextAttr, rText.getLength()*sizeof( ExtTextInputAttr ) );
|
|
}
|
|
return !ImplCallCommand( pChild, CommandEventId::ExtTextInput, &aData );
|
|
}
|
|
|
|
static bool ImplHandleEndExtTextInput()
|
|
{
|
|
ImplSVData* pSVData = ImplGetSVData();
|
|
vcl::Window* pChild = pSVData->mpWinData->mpExtTextInputWin;
|
|
bool bRet = false;
|
|
|
|
if ( pChild )
|
|
{
|
|
pChild->ImplGetWindowImpl()->mbExtTextInput = false;
|
|
pSVData->mpWinData->mpExtTextInputWin = nullptr;
|
|
ImplWinData* pWinData = pChild->ImplGetWinData();
|
|
pWinData->mpExtOldText.reset();
|
|
pWinData->mpExtOldAttrAry.reset();
|
|
bRet = !ImplCallCommand( pChild, CommandEventId::EndExtTextInput );
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
static void ImplHandleExtTextInputPos( vcl::Window* pWindow,
|
|
tools::Rectangle& rRect, long& rInputWidth,
|
|
bool * pVertical )
|
|
{
|
|
ImplSVData* pSVData = ImplGetSVData();
|
|
vcl::Window* pChild = pSVData->mpWinData->mpExtTextInputWin;
|
|
|
|
if ( !pChild )
|
|
pChild = ImplGetKeyInputWindow( pWindow );
|
|
else
|
|
{
|
|
// Test, if the Window is related to the frame
|
|
if ( !pWindow->ImplIsWindowOrChild( pChild ) )
|
|
pChild = ImplGetKeyInputWindow( pWindow );
|
|
}
|
|
|
|
if ( pChild )
|
|
{
|
|
const OutputDevice *pChildOutDev = pChild->GetOutDev();
|
|
ImplCallCommand( pChild, CommandEventId::CursorPos );
|
|
const tools::Rectangle* pRect = pChild->GetCursorRect();
|
|
if ( pRect )
|
|
rRect = pChildOutDev->ImplLogicToDevicePixel( *pRect );
|
|
else
|
|
{
|
|
vcl::Cursor* pCursor = pChild->GetCursor();
|
|
if ( pCursor )
|
|
{
|
|
Point aPos = pChildOutDev->ImplLogicToDevicePixel( pCursor->GetPos() );
|
|
Size aSize = pChild->LogicToPixel( pCursor->GetSize() );
|
|
if ( !aSize.Width() )
|
|
aSize.setWidth( pChild->GetSettings().GetStyleSettings().GetCursorSize() );
|
|
rRect = tools::Rectangle( aPos, aSize );
|
|
}
|
|
else
|
|
rRect = tools::Rectangle( Point( pChild->GetOutOffXPixel(), pChild->GetOutOffYPixel() ), Size() );
|
|
}
|
|
rInputWidth = pChild->ImplLogicWidthToDevicePixel( pChild->GetCursorExtTextInputWidth() );
|
|
if ( !rInputWidth )
|
|
rInputWidth = rRect.GetWidth();
|
|
}
|
|
if (pVertical != nullptr)
|
|
*pVertical
|
|
= pChild != nullptr && pChild->GetInputContext().GetFont().IsVertical();
|
|
}
|
|
|
|
static bool ImplHandleInputContextChange( vcl::Window* pWindow )
|
|
{
|
|
vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
|
|
CommandInputContextData aData;
|
|
return !ImplCallCommand( pChild, CommandEventId::InputContextChange, &aData );
|
|
}
|
|
|
|
static bool ImplCallWheelCommand( const VclPtr<vcl::Window>& pWindow, const Point& rPos,
|
|
const CommandWheelData* pWheelData )
|
|
{
|
|
Point aCmdMousePos = pWindow->ImplFrameToOutput( rPos );
|
|
CommandEvent aCEvt( aCmdMousePos, CommandEventId::Wheel, true, pWheelData );
|
|
NotifyEvent aNCmdEvt( MouseNotifyEvent::COMMAND, pWindow, &aCEvt );
|
|
bool bPreNotify = ImplCallPreNotify( aNCmdEvt );
|
|
if ( pWindow->IsDisposed() )
|
|
return false;
|
|
if ( !bPreNotify )
|
|
{
|
|
pWindow->ImplGetWindowImpl()->mbCommand = false;
|
|
pWindow->Command( aCEvt );
|
|
if ( pWindow->IsDisposed() )
|
|
return false;
|
|
if ( pWindow->ImplGetWindowImpl()->mbCommand )
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static bool acceptableWheelScrollTarget(const vcl::Window *pMouseWindow)
|
|
{
|
|
return (pMouseWindow && !pMouseWindow->isDisposed() && pMouseWindow->IsInputEnabled() && !pMouseWindow->IsInModalMode());
|
|
}
|
|
|
|
//If the last event at the same absolute screen position was handled by a
|
|
//different window then reuse that window if the event occurs within 1/2 a
|
|
//second, i.e. so scrolling down something like the calc sidebar that contains
|
|
//widgets that respond to wheel events will continue to send the event to the
|
|
//scrolling widget in favour of the widget that happens to end up under the
|
|
//mouse.
|
|
static bool shouldReusePreviousMouseWindow(const SalWheelMouseEvent& rPrevEvt, const SalWheelMouseEvent& rEvt)
|
|
{
|
|
return (rEvt.mnX == rPrevEvt.mnX && rEvt.mnY == rPrevEvt.mnY && rEvt.mnTime-rPrevEvt.mnTime < 500/*ms*/);
|
|
}
|
|
|
|
namespace {
|
|
|
|
class HandleGestureEventBase
|
|
{
|
|
protected:
|
|
ImplSVData* m_pSVData;
|
|
VclPtr<vcl::Window> m_pWindow;
|
|
Point m_aMousePos;
|
|
|
|
public:
|
|
HandleGestureEventBase(vcl::Window *pWindow, const Point &rMousePos)
|
|
: m_pSVData(ImplGetSVData())
|
|
, m_pWindow(pWindow)
|
|
, m_aMousePos(rMousePos)
|
|
{
|
|
}
|
|
bool Setup();
|
|
vcl::Window* FindTarget();
|
|
vcl::Window* Dispatch(vcl::Window* pTarget);
|
|
virtual bool CallCommand(vcl::Window *pWindow, const Point &rMousePos) = 0;
|
|
virtual ~HandleGestureEventBase() {}
|
|
};
|
|
|
|
}
|
|
|
|
bool HandleGestureEventBase::Setup()
|
|
{
|
|
|
|
if (m_pSVData->mpWinData->mpAutoScrollWin)
|
|
m_pSVData->mpWinData->mpAutoScrollWin->EndAutoScroll();
|
|
if (ImplGetSVHelpData().mpHelpWin)
|
|
ImplDestroyHelpWindow( true );
|
|
return !m_pWindow->IsDisposed();
|
|
}
|
|
|
|
vcl::Window* HandleGestureEventBase::FindTarget()
|
|
{
|
|
// first check any floating window ( eg. drop down listboxes)
|
|
vcl::Window *pMouseWindow = nullptr;
|
|
|
|
if (m_pSVData->mpWinData->mpFirstFloat && !m_pSVData->mpWinData->mpCaptureWin &&
|
|
!m_pSVData->mpWinData->mpFirstFloat->ImplIsFloatPopupModeWindow( m_pWindow ) )
|
|
{
|
|
bool bHitTestInsideRect = false;
|
|
pMouseWindow = m_pSVData->mpWinData->mpFirstFloat->ImplFloatHitTest( m_pWindow, m_aMousePos, bHitTestInsideRect );
|
|
if (!pMouseWindow)
|
|
pMouseWindow = m_pSVData->mpWinData->mpFirstFloat;
|
|
}
|
|
// then try the window directly beneath the mouse
|
|
if( !pMouseWindow )
|
|
{
|
|
pMouseWindow = m_pWindow->ImplFindWindow( m_aMousePos );
|
|
}
|
|
else
|
|
{
|
|
// transform coordinates to float window frame coordinates
|
|
pMouseWindow = pMouseWindow->ImplFindWindow(
|
|
pMouseWindow->OutputToScreenPixel(
|
|
pMouseWindow->AbsoluteScreenToOutputPixel(
|
|
m_pWindow->OutputToAbsoluteScreenPixel(
|
|
m_pWindow->ScreenToOutputPixel( m_aMousePos ) ) ) ) );
|
|
}
|
|
|
|
while (acceptableWheelScrollTarget(pMouseWindow))
|
|
{
|
|
if (pMouseWindow->IsEnabled())
|
|
break;
|
|
//try the parent if this one is disabled
|
|
pMouseWindow = pMouseWindow->GetParent();
|
|
}
|
|
|
|
return pMouseWindow;
|
|
}
|
|
|
|
vcl::Window *HandleGestureEventBase::Dispatch(vcl::Window* pMouseWindow)
|
|
{
|
|
vcl::Window *pDispatchedTo = nullptr;
|
|
|
|
if (acceptableWheelScrollTarget(pMouseWindow) && pMouseWindow->IsEnabled())
|
|
{
|
|
// transform coordinates to float window frame coordinates
|
|
Point aRelMousePos( pMouseWindow->OutputToScreenPixel(
|
|
pMouseWindow->AbsoluteScreenToOutputPixel(
|
|
m_pWindow->OutputToAbsoluteScreenPixel(
|
|
m_pWindow->ScreenToOutputPixel( m_aMousePos ) ) ) ) );
|
|
bool bPropogate = CallCommand(pMouseWindow, aRelMousePos);
|
|
if (!bPropogate)
|
|
pDispatchedTo = pMouseWindow;
|
|
}
|
|
|
|
// if the command was not handled try the focus window
|
|
if (!pDispatchedTo)
|
|
{
|
|
vcl::Window* pFocusWindow = m_pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
|
|
if ( pFocusWindow && (pFocusWindow != pMouseWindow) &&
|
|
(pFocusWindow == m_pSVData->mpWinData->mpFocusWin) )
|
|
{
|
|
// no wheel-messages to disabled windows
|
|
if ( pFocusWindow->IsEnabled() && pFocusWindow->IsInputEnabled() && ! pFocusWindow->IsInModalMode() )
|
|
{
|
|
// transform coordinates to focus window frame coordinates
|
|
Point aRelMousePos( pFocusWindow->OutputToScreenPixel(
|
|
pFocusWindow->AbsoluteScreenToOutputPixel(
|
|
m_pWindow->OutputToAbsoluteScreenPixel(
|
|
m_pWindow->ScreenToOutputPixel( m_aMousePos ) ) ) ) );
|
|
bool bPropogate = CallCommand(pFocusWindow, aRelMousePos);
|
|
if (!bPropogate)
|
|
pDispatchedTo = pMouseWindow;
|
|
}
|
|
}
|
|
}
|
|
return pDispatchedTo;
|
|
}
|
|
|
|
namespace {
|
|
|
|
class HandleWheelEvent : public HandleGestureEventBase
|
|
{
|
|
private:
|
|
CommandWheelData m_aWheelData;
|
|
public:
|
|
HandleWheelEvent(vcl::Window *pWindow, const SalWheelMouseEvent& rEvt)
|
|
: HandleGestureEventBase(pWindow, Point(rEvt.mnX, rEvt.mnY))
|
|
{
|
|
CommandWheelMode nMode;
|
|
sal_uInt16 nCode = rEvt.mnCode;
|
|
bool bHorz = rEvt.mbHorz;
|
|
bool bPixel = rEvt.mbDeltaIsPixel;
|
|
if ( nCode & KEY_MOD1 )
|
|
nMode = CommandWheelMode::ZOOM;
|
|
else if ( nCode & KEY_MOD2 )
|
|
nMode = CommandWheelMode::DATAZOOM;
|
|
else
|
|
{
|
|
nMode = CommandWheelMode::SCROLL;
|
|
// #i85450# interpret shift-wheel as horizontal wheel action
|
|
if( (nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)) == KEY_SHIFT )
|
|
bHorz = true;
|
|
}
|
|
|
|
m_aWheelData = CommandWheelData(rEvt.mnDelta, rEvt.mnNotchDelta, rEvt.mnScrollLines, nMode, nCode, bHorz, bPixel);
|
|
|
|
}
|
|
virtual bool CallCommand(vcl::Window *pWindow, const Point &rMousePos) override
|
|
{
|
|
return ImplCallWheelCommand(pWindow, rMousePos, &m_aWheelData);
|
|
}
|
|
bool HandleEvent(const SalWheelMouseEvent& rEvt);
|
|
};
|
|
|
|
}
|
|
|
|
bool HandleWheelEvent::HandleEvent(const SalWheelMouseEvent& rEvt)
|
|
{
|
|
if (!Setup())
|
|
return false;
|
|
|
|
VclPtr<vcl::Window> xMouseWindow = FindTarget();
|
|
|
|
ImplSVData* pSVData = ImplGetSVData();
|
|
|
|
// avoid the problem that scrolling via wheel to this point brings a widget
|
|
// under the mouse that also accepts wheel commands, so stick with the old
|
|
// widget if the time gap is very small
|
|
if (shouldReusePreviousMouseWindow(pSVData->mpWinData->maLastWheelEvent, rEvt) &&
|
|
acceptableWheelScrollTarget(pSVData->mpWinData->mpLastWheelWindow))
|
|
{
|
|
xMouseWindow = pSVData->mpWinData->mpLastWheelWindow;
|
|
}
|
|
|
|
pSVData->mpWinData->maLastWheelEvent = rEvt;
|
|
|
|
pSVData->mpWinData->mpLastWheelWindow = Dispatch(xMouseWindow);
|
|
|
|
return pSVData->mpWinData->mpLastWheelWindow.get();
|
|
}
|
|
|
|
namespace {
|
|
|
|
class HandleGestureEvent : public HandleGestureEventBase
|
|
{
|
|
public:
|
|
HandleGestureEvent(vcl::Window *pWindow, const Point &rMousePos)
|
|
: HandleGestureEventBase(pWindow, rMousePos)
|
|
{
|
|
}
|
|
bool HandleEvent();
|
|
};
|
|
|
|
}
|
|
|
|
bool HandleGestureEvent::HandleEvent()
|
|
{
|
|
if (!Setup())
|
|
return false;
|
|
|
|
vcl::Window *pTarget = FindTarget();
|
|
|
|
bool bHandled = Dispatch(pTarget) != nullptr;
|
|
return bHandled;
|
|
}
|
|
|
|
static bool ImplHandleWheelEvent(vcl::Window* pWindow, const SalWheelMouseEvent& rEvt)
|
|
{
|
|
HandleWheelEvent aHandler(pWindow, rEvt);
|
|
return aHandler.HandleEvent(rEvt);
|
|
}
|
|
|
|
namespace {
|
|
|
|
class HandleSwipeEvent : public HandleGestureEvent
|
|
{
|
|
private:
|
|
CommandSwipeData m_aSwipeData;
|
|
public:
|
|
HandleSwipeEvent(vcl::Window *pWindow, const SalSwipeEvent& rEvt)
|
|
: HandleGestureEvent(pWindow, Point(rEvt.mnX, rEvt.mnY)),
|
|
m_aSwipeData(rEvt.mnVelocityX)
|
|
{
|
|
}
|
|
virtual bool CallCommand(vcl::Window *pWindow, const Point &/*rMousePos*/) override
|
|
{
|
|
return ImplCallCommand(pWindow, CommandEventId::Swipe, &m_aSwipeData);
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
static bool ImplHandleSwipe(vcl::Window *pWindow, const SalSwipeEvent& rEvt)
|
|
{
|
|
HandleSwipeEvent aHandler(pWindow, rEvt);
|
|
return aHandler.HandleEvent();
|
|
}
|
|
|
|
namespace {
|
|
|
|
class HandleLongPressEvent : public HandleGestureEvent
|
|
{
|
|
private:
|
|
CommandLongPressData m_aLongPressData;
|
|
public:
|
|
HandleLongPressEvent(vcl::Window *pWindow, const SalLongPressEvent& rEvt)
|
|
: HandleGestureEvent(pWindow, Point(rEvt.mnX, rEvt.mnY)),
|
|
m_aLongPressData(rEvt.mnX, rEvt.mnY)
|
|
{
|
|
}
|
|
virtual bool CallCommand(vcl::Window *pWindow, const Point &/*rMousePos*/) override
|
|
{
|
|
return ImplCallCommand(pWindow, CommandEventId::LongPress, &m_aLongPressData);
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
static bool ImplHandleLongPress(vcl::Window *pWindow, const SalLongPressEvent& rEvt)
|
|
{
|
|
HandleLongPressEvent aHandler(pWindow, rEvt);
|
|
return aHandler.HandleEvent();
|
|
}
|
|
|
|
namespace {
|
|
|
|
class HandleGeneralGestureEvent : public HandleGestureEvent
|
|
{
|
|
private:
|
|
CommandGestureData m_aGestureData;
|
|
|
|
public:
|
|
HandleGeneralGestureEvent(vcl::Window* pWindow, const SalGestureEvent& rEvent)
|
|
: HandleGestureEvent(pWindow, Point(rEvent.mnX, rEvent.mnY))
|
|
, m_aGestureData(rEvent.mnX, rEvent.mnY, rEvent.meEventType, rEvent.mfOffset, rEvent.meOrientation)
|
|
{
|
|
}
|
|
|
|
virtual bool CallCommand(vcl::Window* pWindow, const Point& /*rMousePos*/) override
|
|
{
|
|
return ImplCallCommand(pWindow, CommandEventId::Gesture, &m_aGestureData);
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
static bool ImplHandleGestureEvent(vcl::Window* pWindow, const SalGestureEvent& rEvent)
|
|
{
|
|
HandleGeneralGestureEvent aHandler(pWindow, rEvent);
|
|
return aHandler.HandleEvent();
|
|
}
|
|
|
|
static void ImplHandlePaint( vcl::Window* pWindow, const tools::Rectangle& rBoundRect, bool bImmediateUpdate )
|
|
{
|
|
// system paint events must be checked for re-mirroring
|
|
pWindow->ImplGetWindowImpl()->mnPaintFlags |= ImplPaintFlags::CheckRtl;
|
|
|
|
// trigger paint for all windows that live in the new paint region
|
|
vcl::Region aRegion( rBoundRect );
|
|
pWindow->ImplInvalidateOverlapFrameRegion( aRegion );
|
|
if( bImmediateUpdate )
|
|
{
|
|
// #i87663# trigger possible pending resize notifications
|
|
// (GetSizePixel does that for us)
|
|
pWindow->GetSizePixel();
|
|
// force drawing immediately
|
|
pWindow->Update();
|
|
}
|
|
}
|
|
|
|
static void KillOwnPopups( vcl::Window const * pWindow )
|
|
{
|
|
ImplSVData* pSVData = ImplGetSVData();
|
|
vcl::Window *pParent = pWindow->ImplGetWindowImpl()->mpFrameWindow;
|
|
vcl::Window *pChild = pSVData->mpWinData->mpFirstFloat;
|
|
if ( pChild && pParent->ImplIsWindowOrChild( pChild, true ) )
|
|
{
|
|
if (!(pSVData->mpWinData->mpFirstFloat->GetPopupModeFlags()
|
|
& FloatWinPopupFlags::NoAppFocusClose))
|
|
pSVData->mpWinData->mpFirstFloat->EndPopupMode(FloatWinPopupEndFlags::Cancel
|
|
| FloatWinPopupEndFlags::CloseAll);
|
|
}
|
|
}
|
|
|
|
void ImplHandleResize( vcl::Window* pWindow, long nNewWidth, long nNewHeight )
|
|
{
|
|
const bool bChanged = (nNewWidth != pWindow->GetOutputWidthPixel()) || (nNewHeight != pWindow->GetOutputHeightPixel());
|
|
if (bChanged && pWindow->GetStyle() & (WB_MOVEABLE|WB_SIZEABLE))
|
|
{
|
|
KillOwnPopups( pWindow );
|
|
if( pWindow->ImplGetWindow() != ImplGetSVHelpData().mpHelpWin )
|
|
ImplDestroyHelpWindow( true );
|
|
}
|
|
|
|
if (
|
|
(nNewWidth > 0 && nNewHeight > 0) ||
|
|
pWindow->ImplGetWindow()->ImplGetWindowImpl()->mbAllResize
|
|
)
|
|
{
|
|
if (bChanged)
|
|
{
|
|
pWindow->mnOutWidth = nNewWidth;
|
|
pWindow->mnOutHeight = nNewHeight;
|
|
pWindow->ImplGetWindowImpl()->mbWaitSystemResize = false;
|
|
if ( pWindow->IsReallyVisible() )
|
|
pWindow->ImplSetClipFlag();
|
|
if ( pWindow->IsVisible() || pWindow->ImplGetWindow()->ImplGetWindowImpl()->mbAllResize ||
|
|
( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplGetWindowImpl()->mpClientWindow ) ) // propagate resize for system border windows
|
|
{
|
|
bool bStartTimer = true;
|
|
// use resize buffering for user resizes
|
|
// ownerdraw decorated windows and floating windows can be resized immediately (i.e. synchronously)
|
|
if( pWindow->ImplGetWindowImpl()->mbFrame && (pWindow->GetStyle() & WB_SIZEABLE)
|
|
&& !(pWindow->GetStyle() & WB_OWNERDRAWDECORATION) // synchronous resize for ownerdraw decorated windows (toolbars)
|
|
&& !pWindow->ImplGetWindowImpl()->mbFloatWin ) // synchronous resize for floating windows, #i43799#
|
|
{
|
|
if( pWindow->ImplGetWindowImpl()->mpClientWindow )
|
|
{
|
|
// #i42750# presentation wants to be informed about resize
|
|
// as early as possible
|
|
WorkWindow* pWorkWindow = dynamic_cast<WorkWindow*>(pWindow->ImplGetWindowImpl()->mpClientWindow.get());
|
|
if( ! pWorkWindow || pWorkWindow->IsPresentationMode() )
|
|
bStartTimer = false;
|
|
}
|
|
else
|
|
{
|
|
WorkWindow* pWorkWindow = dynamic_cast<WorkWindow*>(pWindow);
|
|
if( ! pWorkWindow || pWorkWindow->IsPresentationMode() )
|
|
bStartTimer = false;
|
|
}
|
|
}
|
|
else
|
|
bStartTimer = false;
|
|
|
|
if( bStartTimer )
|
|
pWindow->ImplGetWindowImpl()->mpFrameData->maResizeIdle.Start();
|
|
else
|
|
pWindow->ImplCallResize(); // otherwise menus cannot be positioned
|
|
}
|
|
else
|
|
pWindow->ImplGetWindowImpl()->mbCallResize = true;
|
|
|
|
if (pWindow->SupportsDoubleBuffering() && pWindow->ImplGetWindowImpl()->mbFrame)
|
|
{
|
|
// Propagate resize for the frame's buffer.
|
|
pWindow->ImplGetWindowImpl()->mpFrameData->mpBuffer->SetOutputSizePixel(pWindow->GetOutputSizePixel());
|
|
}
|
|
}
|
|
}
|
|
|
|
pWindow->ImplGetWindowImpl()->mpFrameData->mbNeedSysWindow = (nNewWidth < IMPL_MIN_NEEDSYSWIN) ||
|
|
(nNewHeight < IMPL_MIN_NEEDSYSWIN);
|
|
bool bMinimized = (nNewWidth <= 0) || (nNewHeight <= 0);
|
|
if( bMinimized != pWindow->ImplGetWindowImpl()->mpFrameData->mbMinimized )
|
|
pWindow->ImplGetWindowImpl()->mpFrameWindow->ImplNotifyIconifiedState( bMinimized );
|
|
pWindow->ImplGetWindowImpl()->mpFrameData->mbMinimized = bMinimized;
|
|
}
|
|
|
|
static void ImplHandleMove( vcl::Window* pWindow )
|
|
{
|
|
if( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplIsFloatingWindow() && pWindow->IsReallyVisible() )
|
|
{
|
|
static_cast<FloatingWindow*>(pWindow)->EndPopupMode( FloatWinPopupEndFlags::TearOff );
|
|
pWindow->ImplCallMove();
|
|
}
|
|
|
|
if( pWindow->GetStyle() & (WB_MOVEABLE|WB_SIZEABLE) )
|
|
{
|
|
KillOwnPopups( pWindow );
|
|
if( pWindow->ImplGetWindow() != ImplGetSVHelpData().mpHelpWin )
|
|
ImplDestroyHelpWindow( true );
|
|
}
|
|
|
|
if ( pWindow->IsVisible() )
|
|
pWindow->ImplCallMove();
|
|
else
|
|
pWindow->ImplGetWindowImpl()->mbCallMove = true; // make sure the framepos will be updated on the next Show()
|
|
|
|
if ( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplGetWindowImpl()->mpClientWindow )
|
|
pWindow->ImplGetWindowImpl()->mpClientWindow->ImplCallMove(); // notify client to update geometry
|
|
|
|
}
|
|
|
|
static void ImplHandleMoveResize( vcl::Window* pWindow, long nNewWidth, long nNewHeight )
|
|
{
|
|
ImplHandleMove( pWindow );
|
|
ImplHandleResize( pWindow, nNewWidth, nNewHeight );
|
|
}
|
|
|
|
static void ImplActivateFloatingWindows( vcl::Window const * pWindow, bool bActive )
|
|
{
|
|
// First check all overlapping windows
|
|
vcl::Window* pTempWindow = pWindow->ImplGetWindowImpl()->mpFirstOverlap;
|
|
while ( pTempWindow )
|
|
{
|
|
if ( pTempWindow->GetActivateMode() == ActivateModeFlags::NONE )
|
|
{
|
|
if ( (pTempWindow->GetType() == WindowType::BORDERWINDOW) &&
|
|
(pTempWindow->ImplGetWindow()->GetType() == WindowType::FLOATINGWINDOW) )
|
|
static_cast<ImplBorderWindow*>(pTempWindow)->SetDisplayActive( bActive );
|
|
}
|
|
|
|
ImplActivateFloatingWindows( pTempWindow, bActive );
|
|
pTempWindow = pTempWindow->ImplGetWindowImpl()->mpNext;
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG(vcl::Window, ImplAsyncFocusHdl, void*, void)
|
|
{
|
|
ImplGetWindowImpl()->mpFrameData->mnFocusId = nullptr;
|
|
|
|
// If the status has been preserved, because we got back the focus
|
|
// in the meantime, we do nothing
|
|
bool bHasFocus = ImplGetWindowImpl()->mpFrameData->mbHasFocus || ImplGetWindowImpl()->mpFrameData->mbSysObjFocus;
|
|
|
|
// next execute the delayed functions
|
|
if ( bHasFocus )
|
|
{
|
|
// redraw all floating windows inactive
|
|
if ( ImplGetWindowImpl()->mpFrameData->mbStartFocusState != bHasFocus )
|
|
ImplActivateFloatingWindows( this, bHasFocus );
|
|
|
|
if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin )
|
|
{
|
|
bool bHandled = false;
|
|
if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsInputEnabled() &&
|
|
! ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsInModalMode() )
|
|
{
|
|
if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsEnabled() )
|
|
{
|
|
ImplGetWindowImpl()->mpFrameData->mpFocusWin->GrabFocus();
|
|
bHandled = true;
|
|
}
|
|
else if( ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplHasDlgCtrl() )
|
|
{
|
|
// #109094# if the focus is restored to a disabled dialog control (was disabled meanwhile)
|
|
// try to move it to the next control
|
|
ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplDlgCtrlNextWindow();
|
|
bHandled = true;
|
|
}
|
|
}
|
|
if ( !bHandled )
|
|
{
|
|
ImplSVData* pSVData = ImplGetSVData();
|
|
vcl::Window* pTopLevelWindow = ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplGetFirstOverlapWindow();
|
|
|
|
if ((!pTopLevelWindow->IsInputEnabled() || pTopLevelWindow->IsInModalMode())
|
|
&& !pSVData->mpWinData->mpExecuteDialogs.empty())
|
|
pSVData->mpWinData->mpExecuteDialogs.back()->ToTop(ToTopFlags::RestoreWhenMin | ToTopFlags::GrabFocusOnly);
|
|
else
|
|
pTopLevelWindow->GrabFocus();
|
|
}
|
|
}
|
|
else
|
|
GrabFocus();
|
|
}
|
|
else
|
|
{
|
|
vcl::Window* pFocusWin = ImplGetWindowImpl()->mpFrameData->mpFocusWin;
|
|
if ( pFocusWin )
|
|
{
|
|
ImplSVData* pSVData = ImplGetSVData();
|
|
|
|
if (pSVData->mpWinData->mpFocusWin == pFocusWin)
|
|
{
|
|
// transfer the FocusWindow
|
|
vcl::Window* pOverlapWindow = pFocusWin->ImplGetFirstOverlapWindow();
|
|
pOverlapWindow->ImplGetWindowImpl()->mpLastFocusWindow = pFocusWin;
|
|
pSVData->mpWinData->mpFocusWin = nullptr;
|
|
|
|
if ( pFocusWin->ImplGetWindowImpl()->mpCursor )
|
|
pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide();
|
|
|
|
// call the Deactivate
|
|
vcl::Window* pOldOverlapWindow = pFocusWin->ImplGetFirstOverlapWindow();
|
|
vcl::Window* pOldRealWindow = pOldOverlapWindow->ImplGetWindow();
|
|
|
|
pOldOverlapWindow->ImplGetWindowImpl()->mbActive = false;
|
|
pOldOverlapWindow->Deactivate();
|
|
if ( pOldRealWindow != pOldOverlapWindow )
|
|
{
|
|
pOldRealWindow->ImplGetWindowImpl()->mbActive = false;
|
|
pOldRealWindow->Deactivate();
|
|
}
|
|
|
|
// TrackingMode is ended in ImplHandleLoseFocus
|
|
#ifdef _WIN32
|
|
// To avoid problems with the Unix IME
|
|
pFocusWin->EndExtTextInput();
|
|
#endif
|
|
|
|
NotifyEvent aNEvt(MouseNotifyEvent::LOSEFOCUS, pFocusWin);
|
|
if (!ImplCallPreNotify(aNEvt))
|
|
pFocusWin->CompatLoseFocus();
|
|
pFocusWin->ImplCallDeactivateListeners(nullptr);
|
|
}
|
|
}
|
|
|
|
// Redraw all floating window inactive
|
|
if ( ImplGetWindowImpl()->mpFrameData->mbStartFocusState != bHasFocus )
|
|
ImplActivateFloatingWindows( this, bHasFocus );
|
|
}
|
|
}
|
|
|
|
static void ImplHandleGetFocus( vcl::Window* pWindow )
|
|
{
|
|
pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus = true;
|
|
|
|
// execute Focus-Events after a delay, such that SystemChildWindows
|
|
// do not blink when they receive focus
|
|
if ( !pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId )
|
|
{
|
|
pWindow->ImplGetWindowImpl()->mpFrameData->mbStartFocusState = !pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus;
|
|
pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId = Application::PostUserEvent( LINK( pWindow, vcl::Window, ImplAsyncFocusHdl ), nullptr, true);
|
|
vcl::Window* pFocusWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
|
|
if ( pFocusWin && pFocusWin->ImplGetWindowImpl()->mpCursor )
|
|
pFocusWin->ImplGetWindowImpl()->mpCursor->ImplShow();
|
|
}
|
|
}
|
|
|
|
static void ImplHandleLoseFocus( vcl::Window* pWindow )
|
|
{
|
|
ImplSVData* pSVData = ImplGetSVData();
|
|
|
|
// Abort the autoscroll if the frame loses focus
|
|
if (pSVData->mpWinData->mpAutoScrollWin)
|
|
pSVData->mpWinData->mpAutoScrollWin->EndAutoScroll();
|
|
|
|
// Abort tracking if the frame loses focus
|
|
if (pSVData->mpWinData->mpTrackWin)
|
|
{
|
|
if (pSVData->mpWinData->mpTrackWin->ImplGetWindowImpl()->mpFrameWindow == pWindow)
|
|
pSVData->mpWinData->mpTrackWin->EndTracking(TrackingEventFlags::Cancel);
|
|
}
|
|
|
|
pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus = false;
|
|
|
|
// execute Focus-Events after a delay, such that SystemChildWindows
|
|
// do not flicker when they receive focus
|
|
if ( !pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId )
|
|
{
|
|
pWindow->ImplGetWindowImpl()->mpFrameData->mbStartFocusState = !pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus;
|
|
pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId = Application::PostUserEvent( LINK( pWindow, vcl::Window, ImplAsyncFocusHdl ), nullptr, true );
|
|
}
|
|
|
|
vcl::Window* pFocusWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
|
|
if ( pFocusWin && pFocusWin->ImplGetWindowImpl()->mpCursor )
|
|
pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide();
|
|
|
|
// Make sure that no menu is visible when a toplevel window loses focus.
|
|
VclPtr<FloatingWindow> pFirstFloat = pSVData->mpWinData->mpFirstFloat;
|
|
if (pFirstFloat && !pWindow->GetParent())
|
|
pFirstFloat->EndPopupMode(FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll);
|
|
}
|
|
|
|
namespace {
|
|
|
|
struct DelayedCloseEvent
|
|
{
|
|
VclPtr<vcl::Window> pWindow;
|
|
};
|
|
|
|
}
|
|
|
|
static void DelayedCloseEventLink( void* pCEvent, void* )
|
|
{
|
|
DelayedCloseEvent* pEv = static_cast<DelayedCloseEvent*>(pCEvent);
|
|
|
|
if( ! pEv->pWindow->IsDisposed() )
|
|
{
|
|
// dispatch to correct window type
|
|
if( pEv->pWindow->IsSystemWindow() )
|
|
static_cast<SystemWindow*>(pEv->pWindow.get())->Close();
|
|
else if( pEv->pWindow->IsDockingWindow() )
|
|
static_cast<DockingWindow*>(pEv->pWindow.get())->Close();
|
|
}
|
|
delete pEv;
|
|
}
|
|
|
|
static void ImplHandleClose( const vcl::Window* pWindow )
|
|
{
|
|
ImplSVData* pSVData = ImplGetSVData();
|
|
|
|
bool bWasPopup = false;
|
|
if( pWindow->ImplIsFloatingWindow() &&
|
|
static_cast<const FloatingWindow*>(pWindow)->ImplIsInPrivatePopupMode() )
|
|
{
|
|
bWasPopup = true;
|
|
}
|
|
|
|
// on Close stop all floating modes and end popups
|
|
if (pSVData->mpWinData->mpFirstFloat)
|
|
{
|
|
FloatingWindow* pLastLevelFloat;
|
|
pLastLevelFloat = pSVData->mpWinData->mpFirstFloat->ImplFindLastLevelFloat();
|
|
pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
|
|
}
|
|
if ( ImplGetSVHelpData().mbExtHelpMode )
|
|
Help::EndExtHelp();
|
|
if ( ImplGetSVHelpData().mpHelpWin )
|
|
ImplDestroyHelpWindow( false );
|
|
// AutoScrollMode
|
|
if (pSVData->mpWinData->mpAutoScrollWin)
|
|
pSVData->mpWinData->mpAutoScrollWin->EndAutoScroll();
|
|
|
|
if (pSVData->mpWinData->mpTrackWin)
|
|
pSVData->mpWinData->mpTrackWin->EndTracking( TrackingEventFlags::Cancel | TrackingEventFlags::Key );
|
|
|
|
if (bWasPopup)
|
|
return;
|
|
|
|
vcl::Window *pWin = pWindow->ImplGetWindow();
|
|
SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(pWin);
|
|
if (pSysWin)
|
|
{
|
|
// See if the custom close handler is set.
|
|
const Link<SystemWindow&,void>& rLink = pSysWin->GetCloseHdl();
|
|
if (rLink.IsSet())
|
|
{
|
|
rLink.Call(*pSysWin);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// check whether close is allowed
|
|
if ( pWin->IsEnabled() && pWin->IsInputEnabled() && !pWin->IsInModalMode() )
|
|
{
|
|
DelayedCloseEvent* pEv = new DelayedCloseEvent;
|
|
pEv->pWindow = pWin;
|
|
Application::PostUserEvent( Link<void*,void>( pEv, DelayedCloseEventLink ) );
|
|
}
|
|
}
|
|
|
|
static void ImplHandleUserEvent( ImplSVEvent* pSVEvent )
|
|
{
|
|
if ( pSVEvent )
|
|
{
|
|
if ( pSVEvent->mbCall )
|
|
{
|
|
pSVEvent->maLink.Call( pSVEvent->mpData );
|
|
}
|
|
|
|
delete pSVEvent;
|
|
}
|
|
}
|
|
|
|
static MouseEventModifiers ImplGetMouseMoveMode( SalMouseEvent const * pEvent )
|
|
{
|
|
MouseEventModifiers nMode = MouseEventModifiers::NONE;
|
|
if ( !pEvent->mnCode )
|
|
nMode |= MouseEventModifiers::SIMPLEMOVE;
|
|
if ( (pEvent->mnCode & MOUSE_LEFT) && !(pEvent->mnCode & KEY_MOD1) )
|
|
nMode |= MouseEventModifiers::DRAGMOVE;
|
|
if ( (pEvent->mnCode & MOUSE_LEFT) && (pEvent->mnCode & KEY_MOD1) )
|
|
nMode |= MouseEventModifiers::DRAGCOPY;
|
|
return nMode;
|
|
}
|
|
|
|
static MouseEventModifiers ImplGetMouseButtonMode( SalMouseEvent const * pEvent )
|
|
{
|
|
MouseEventModifiers nMode = MouseEventModifiers::NONE;
|
|
if ( pEvent->mnButton == MOUSE_LEFT )
|
|
nMode |= MouseEventModifiers::SIMPLECLICK;
|
|
if ( (pEvent->mnButton == MOUSE_LEFT) && !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT)) )
|
|
nMode |= MouseEventModifiers::SELECT;
|
|
if ( (pEvent->mnButton == MOUSE_LEFT) && (pEvent->mnCode & KEY_MOD1) &&
|
|
!(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT | KEY_SHIFT)) )
|
|
nMode |= MouseEventModifiers::MULTISELECT;
|
|
if ( (pEvent->mnButton == MOUSE_LEFT) && (pEvent->mnCode & KEY_SHIFT) &&
|
|
!(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT | KEY_MOD1)) )
|
|
nMode |= MouseEventModifiers::RANGESELECT;
|
|
return nMode;
|
|
}
|
|
|
|
static bool ImplHandleSalMouseLeave( vcl::Window* pWindow, SalMouseEvent const * pEvent )
|
|
{
|
|
return ImplHandleMouseEvent( pWindow, MouseNotifyEvent::MOUSEMOVE, true,
|
|
pEvent->mnX, pEvent->mnY,
|
|
pEvent->mnTime, pEvent->mnCode,
|
|
ImplGetMouseMoveMode( pEvent ) );
|
|
}
|
|
|
|
static bool ImplHandleSalMouseMove( vcl::Window* pWindow, SalMouseEvent const * pEvent )
|
|
{
|
|
return ImplHandleMouseEvent( pWindow, MouseNotifyEvent::MOUSEMOVE, false,
|
|
pEvent->mnX, pEvent->mnY,
|
|
pEvent->mnTime, pEvent->mnCode,
|
|
ImplGetMouseMoveMode( pEvent ) );
|
|
}
|
|
|
|
static bool ImplHandleSalMouseButtonDown( vcl::Window* pWindow, SalMouseEvent const * pEvent )
|
|
{
|
|
return ImplHandleMouseEvent( pWindow, MouseNotifyEvent::MOUSEBUTTONDOWN, false,
|
|
pEvent->mnX, pEvent->mnY,
|
|
pEvent->mnTime,
|
|
#ifdef MACOSX
|
|
pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)),
|
|
#else
|
|
pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
|
|
#endif
|
|
ImplGetMouseButtonMode( pEvent ) );
|
|
}
|
|
|
|
static bool ImplHandleSalMouseButtonUp( vcl::Window* pWindow, SalMouseEvent const * pEvent )
|
|
{
|
|
return ImplHandleMouseEvent( pWindow, MouseNotifyEvent::MOUSEBUTTONUP, false,
|
|
pEvent->mnX, pEvent->mnY,
|
|
pEvent->mnTime,
|
|
#ifdef MACOSX
|
|
pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)),
|
|
#else
|
|
pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
|
|
#endif
|
|
ImplGetMouseButtonMode( pEvent ) );
|
|
}
|
|
|
|
static bool ImplHandleMenuEvent( vcl::Window const * pWindow, SalMenuEvent* pEvent, SalEvent nEvent )
|
|
{
|
|
// Find SystemWindow and its Menubar and let it dispatch the command
|
|
bool bRet = false;
|
|
vcl::Window *pWin = pWindow->ImplGetWindowImpl()->mpFirstChild;
|
|
while ( pWin )
|
|
{
|
|
if ( pWin->ImplGetWindowImpl()->mbSysWin )
|
|
break;
|
|
pWin = pWin->ImplGetWindowImpl()->mpNext;
|
|
}
|
|
if( pWin )
|
|
{
|
|
MenuBar *pMenuBar = static_cast<SystemWindow*>(pWin)->GetMenuBar();
|
|
if( pMenuBar )
|
|
{
|
|
switch( nEvent )
|
|
{
|
|
case SalEvent::MenuActivate:
|
|
pMenuBar->HandleMenuActivateEvent( static_cast<Menu*>(pEvent->mpMenu) );
|
|
bRet = true;
|
|
break;
|
|
case SalEvent::MenuDeactivate:
|
|
pMenuBar->HandleMenuDeActivateEvent( static_cast<Menu*>(pEvent->mpMenu) );
|
|
bRet = true;
|
|
break;
|
|
case SalEvent::MenuHighlight:
|
|
bRet = pMenuBar->HandleMenuHighlightEvent( static_cast<Menu*>(pEvent->mpMenu), pEvent->mnId );
|
|
break;
|
|
case SalEvent::MenuButtonCommand:
|
|
bRet = pMenuBar->HandleMenuButtonEvent( pEvent->mnId );
|
|
break;
|
|
case SalEvent::MenuCommand:
|
|
bRet = pMenuBar->HandleMenuCommandEvent( static_cast<Menu*>(pEvent->mpMenu), pEvent->mnId );
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
static void ImplHandleSalKeyMod( vcl::Window* pWindow, SalKeyModEvent const * pEvent )
|
|
{
|
|
ImplSVData* pSVData = ImplGetSVData();
|
|
vcl::Window* pTrackWin = pSVData->mpWinData->mpTrackWin;
|
|
if ( pTrackWin )
|
|
pWindow = pTrackWin;
|
|
#ifdef MACOSX
|
|
sal_uInt16 nOldCode = pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3);
|
|
#else
|
|
sal_uInt16 nOldCode = pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
|
|
#endif
|
|
sal_uInt16 nNewCode = pEvent->mnCode;
|
|
if ( nOldCode != nNewCode )
|
|
{
|
|
#ifdef MACOSX
|
|
nNewCode |= pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & ~(KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3);
|
|
#else
|
|
nNewCode |= pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & ~(KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
|
|
#endif
|
|
pWindow->ImplGetWindowImpl()->mpFrameWindow->ImplCallMouseMove( nNewCode, true );
|
|
}
|
|
|
|
// #105224# send commandevent to allow special treatment of Ctrl-LeftShift/Ctrl-RightShift etc.
|
|
// + auto-accelerator feature, tdf#92630
|
|
|
|
// try to find a key input window...
|
|
vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
|
|
//...otherwise fail safe...
|
|
if (!pChild)
|
|
pChild = pWindow;
|
|
|
|
CommandModKeyData data( pEvent->mnModKeyCode, pEvent->mbDown );
|
|
ImplCallCommand( pChild, CommandEventId::ModKeyChange, &data );
|
|
}
|
|
|
|
static void ImplHandleInputLanguageChange( vcl::Window* pWindow )
|
|
{
|
|
// find window
|
|
vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
|
|
if ( !pChild )
|
|
return;
|
|
|
|
ImplCallCommand( pChild, CommandEventId::InputLanguageChange );
|
|
}
|
|
|
|
static void ImplHandleSalSettings( SalEvent nEvent )
|
|
{
|
|
Application* pApp = GetpApp();
|
|
if ( !pApp )
|
|
return;
|
|
|
|
if ( nEvent == SalEvent::SettingsChanged )
|
|
{
|
|
AllSettings aSettings = Application::GetSettings();
|
|
Application::MergeSystemSettings( aSettings );
|
|
pApp->OverrideSystemSettings( aSettings );
|
|
Application::SetSettings( aSettings );
|
|
}
|
|
else
|
|
{
|
|
DataChangedEventType nType;
|
|
switch ( nEvent )
|
|
{
|
|
case SalEvent::PrinterChanged:
|
|
ImplDeletePrnQueueList();
|
|
nType = DataChangedEventType::PRINTER;
|
|
break;
|
|
case SalEvent::DisplayChanged:
|
|
nType = DataChangedEventType::DISPLAY;
|
|
break;
|
|
case SalEvent::FontChanged:
|
|
OutputDevice::ImplUpdateAllFontData( true );
|
|
nType = DataChangedEventType::FONTS;
|
|
break;
|
|
default:
|
|
nType = DataChangedEventType::NONE;
|
|
break;
|
|
}
|
|
|
|
if ( nType != DataChangedEventType::NONE )
|
|
{
|
|
DataChangedEvent aDCEvt( nType );
|
|
Application::ImplCallEventListenersApplicationDataChanged(&aDCEvt);
|
|
Application::NotifyAllWindows( aDCEvt );
|
|
}
|
|
}
|
|
}
|
|
|
|
static void ImplHandleSalExtTextInputPos( vcl::Window* pWindow, SalExtTextInputPosEvent* pEvt )
|
|
{
|
|
tools::Rectangle aCursorRect;
|
|
ImplHandleExtTextInputPos( pWindow, aCursorRect, pEvt->mnExtWidth, &pEvt->mbVertical );
|
|
if ( aCursorRect.IsEmpty() )
|
|
{
|
|
pEvt->mnX = -1;
|
|
pEvt->mnY = -1;
|
|
pEvt->mnWidth = -1;
|
|
pEvt->mnHeight = -1;
|
|
}
|
|
else
|
|
{
|
|
pEvt->mnX = aCursorRect.Left();
|
|
pEvt->mnY = aCursorRect.Top();
|
|
pEvt->mnWidth = aCursorRect.GetWidth();
|
|
pEvt->mnHeight = aCursorRect.GetHeight();
|
|
}
|
|
}
|
|
|
|
static bool ImplHandleShowDialog( vcl::Window* pWindow, ShowDialogId nDialogId )
|
|
{
|
|
if( ! pWindow )
|
|
return false;
|
|
|
|
if( pWindow->GetType() == WindowType::BORDERWINDOW )
|
|
{
|
|
vcl::Window* pWrkWin = pWindow->GetWindow( GetWindowType::Client );
|
|
if( pWrkWin )
|
|
pWindow = pWrkWin;
|
|
}
|
|
CommandDialogData aCmdData( nDialogId );
|
|
return ImplCallCommand( pWindow, CommandEventId::ShowDialog, &aCmdData );
|
|
}
|
|
|
|
static void ImplHandleSurroundingTextRequest( vcl::Window *pWindow,
|
|
OUString& rText,
|
|
Selection &rSelRange )
|
|
{
|
|
vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
|
|
|
|
if ( !pChild )
|
|
{
|
|
rText.clear();
|
|
rSelRange.setMin( 0 );
|
|
rSelRange.setMax( 0 );
|
|
}
|
|
else
|
|
{
|
|
rText = pChild->GetSurroundingText();
|
|
Selection aSel = pChild->GetSurroundingTextSelection();
|
|
rSelRange.setMin( aSel.Min() );
|
|
rSelRange.setMax( aSel.Max() );
|
|
}
|
|
}
|
|
|
|
static void ImplHandleSalSurroundingTextRequest( vcl::Window *pWindow,
|
|
SalSurroundingTextRequestEvent *pEvt )
|
|
{
|
|
Selection aSelRange;
|
|
ImplHandleSurroundingTextRequest( pWindow, pEvt->maText, aSelRange );
|
|
|
|
aSelRange.Justify();
|
|
|
|
if( aSelRange.Min() < 0 )
|
|
pEvt->mnStart = 0;
|
|
else if( aSelRange.Min() > pEvt->maText.getLength() )
|
|
pEvt->mnStart = pEvt->maText.getLength();
|
|
else
|
|
pEvt->mnStart = aSelRange.Min();
|
|
|
|
if( aSelRange.Max() < 0 )
|
|
pEvt->mnStart = 0;
|
|
else if( aSelRange.Max() > pEvt->maText.getLength() )
|
|
pEvt->mnEnd = pEvt->maText.getLength();
|
|
else
|
|
pEvt->mnEnd = aSelRange.Max();
|
|
}
|
|
|
|
static void ImplHandleSurroundingTextSelectionChange( vcl::Window *pWindow,
|
|
sal_uLong nStart,
|
|
sal_uLong nEnd )
|
|
{
|
|
vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
|
|
if( pChild )
|
|
{
|
|
CommandSelectionChangeData data( nStart, nEnd );
|
|
ImplCallCommand( pChild, CommandEventId::SelectionChange, &data );
|
|
}
|
|
}
|
|
|
|
static void ImplHandleStartReconversion( vcl::Window *pWindow )
|
|
{
|
|
vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
|
|
if( pChild )
|
|
ImplCallCommand( pChild, CommandEventId::PrepareReconversion );
|
|
}
|
|
|
|
static void ImplHandleSalQueryCharPosition( vcl::Window *pWindow,
|
|
SalQueryCharPositionEvent *pEvt )
|
|
{
|
|
pEvt->mbValid = false;
|
|
pEvt->mbVertical = false;
|
|
pEvt->mnCursorBoundX = 0;
|
|
pEvt->mnCursorBoundY = 0;
|
|
pEvt->mnCursorBoundWidth = 0;
|
|
pEvt->mnCursorBoundHeight = 0;
|
|
|
|
ImplSVData* pSVData = ImplGetSVData();
|
|
vcl::Window* pChild = pSVData->mpWinData->mpExtTextInputWin;
|
|
|
|
if ( !pChild )
|
|
pChild = ImplGetKeyInputWindow( pWindow );
|
|
else
|
|
{
|
|
// Test, if the Window is related to the frame
|
|
if ( !pWindow->ImplIsWindowOrChild( pChild ) )
|
|
pChild = ImplGetKeyInputWindow( pWindow );
|
|
}
|
|
|
|
if( pChild )
|
|
{
|
|
ImplCallCommand( pChild, CommandEventId::QueryCharPosition );
|
|
|
|
ImplWinData* pWinData = pChild->ImplGetWinData();
|
|
if ( pWinData->mpCompositionCharRects && pEvt->mnCharPos < o3tl::make_unsigned( pWinData->mnCompositionCharRects ) )
|
|
{
|
|
const OutputDevice *pChildOutDev = pChild->GetOutDev();
|
|
const tools::Rectangle& aRect = pWinData->mpCompositionCharRects[ pEvt->mnCharPos ];
|
|
tools::Rectangle aDeviceRect = pChildOutDev->ImplLogicToDevicePixel( aRect );
|
|
Point aAbsScreenPos = pChild->OutputToAbsoluteScreenPixel( pChild->ScreenToOutputPixel(aDeviceRect.TopLeft()) );
|
|
pEvt->mnCursorBoundX = aAbsScreenPos.X();
|
|
pEvt->mnCursorBoundY = aAbsScreenPos.Y();
|
|
pEvt->mnCursorBoundWidth = aDeviceRect.GetWidth();
|
|
pEvt->mnCursorBoundHeight = aDeviceRect.GetHeight();
|
|
pEvt->mbVertical = pWinData->mbVertical;
|
|
pEvt->mbValid = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool ImplWindowFrameProc( vcl::Window* _pWindow, SalEvent nEvent, const void* pEvent )
|
|
{
|
|
DBG_TESTSOLARMUTEX();
|
|
|
|
// Ensure the window survives during this method.
|
|
VclPtr<vcl::Window> pWindow( _pWindow );
|
|
|
|
bool bRet = false;
|
|
|
|
// #119709# for some unknown reason it is possible to receive events (in this case key events)
|
|
// although the corresponding VCL window must have been destroyed already
|
|
// at least ImplGetWindowImpl() was NULL in these cases, so check this here
|
|
if( pWindow->ImplGetWindowImpl() == nullptr )
|
|
return false;
|
|
|
|
switch ( nEvent )
|
|
{
|
|
case SalEvent::MouseMove:
|
|
bRet = ImplHandleSalMouseMove( pWindow, static_cast<SalMouseEvent const *>(pEvent) );
|
|
break;
|
|
case SalEvent::ExternalMouseMove:
|
|
{
|
|
MouseEvent const * pMouseEvt = static_cast<MouseEvent const *>(pEvent);
|
|
SalMouseEvent aSalMouseEvent;
|
|
|
|
aSalMouseEvent.mnTime = tools::Time::GetSystemTicks();
|
|
aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
|
|
aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
|
|
aSalMouseEvent.mnButton = 0;
|
|
aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
|
|
|
|
bRet = ImplHandleSalMouseMove( pWindow, &aSalMouseEvent );
|
|
}
|
|
break;
|
|
case SalEvent::MouseLeave:
|
|
bRet = ImplHandleSalMouseLeave( pWindow, static_cast<SalMouseEvent const *>(pEvent) );
|
|
break;
|
|
case SalEvent::MouseButtonDown:
|
|
bRet = ImplHandleSalMouseButtonDown( pWindow, static_cast<SalMouseEvent const *>(pEvent) );
|
|
break;
|
|
case SalEvent::ExternalMouseButtonDown:
|
|
{
|
|
MouseEvent const * pMouseEvt = static_cast<MouseEvent const *>(pEvent);
|
|
SalMouseEvent aSalMouseEvent;
|
|
|
|
aSalMouseEvent.mnTime = tools::Time::GetSystemTicks();
|
|
aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
|
|
aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
|
|
aSalMouseEvent.mnButton = pMouseEvt->GetButtons();
|
|
aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
|
|
|
|
bRet = ImplHandleSalMouseButtonDown( pWindow, &aSalMouseEvent );
|
|
}
|
|
break;
|
|
case SalEvent::MouseButtonUp:
|
|
bRet = ImplHandleSalMouseButtonUp( pWindow, static_cast<SalMouseEvent const *>(pEvent) );
|
|
break;
|
|
case SalEvent::ExternalMouseButtonUp:
|
|
{
|
|
MouseEvent const * pMouseEvt = static_cast<MouseEvent const *>(pEvent);
|
|
SalMouseEvent aSalMouseEvent;
|
|
|
|
aSalMouseEvent.mnTime = tools::Time::GetSystemTicks();
|
|
aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
|
|
aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
|
|
aSalMouseEvent.mnButton = pMouseEvt->GetButtons();
|
|
aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
|
|
|
|
bRet = ImplHandleSalMouseButtonUp( pWindow, &aSalMouseEvent );
|
|
}
|
|
break;
|
|
case SalEvent::MouseActivate:
|
|
bRet = false;
|
|
break;
|
|
case SalEvent::KeyInput:
|
|
{
|
|
SalKeyEvent const * pKeyEvt = static_cast<SalKeyEvent const *>(pEvent);
|
|
bRet = ImplHandleKey( pWindow, MouseNotifyEvent::KEYINPUT,
|
|
pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat, true );
|
|
}
|
|
break;
|
|
case SalEvent::ExternalKeyInput:
|
|
{
|
|
KeyEvent const * pKeyEvt = static_cast<KeyEvent const *>(pEvent);
|
|
bRet = ImplHandleKey( pWindow, MouseNotifyEvent::KEYINPUT,
|
|
pKeyEvt->GetKeyCode().GetFullCode(), pKeyEvt->GetCharCode(), pKeyEvt->GetRepeat(), false );
|
|
}
|
|
break;
|
|
case SalEvent::KeyUp:
|
|
{
|
|
SalKeyEvent const * pKeyEvt = static_cast<SalKeyEvent const *>(pEvent);
|
|
bRet = ImplHandleKey( pWindow, MouseNotifyEvent::KEYUP,
|
|
pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat, true );
|
|
}
|
|
break;
|
|
case SalEvent::ExternalKeyUp:
|
|
{
|
|
KeyEvent const * pKeyEvt = static_cast<KeyEvent const *>(pEvent);
|
|
bRet = ImplHandleKey( pWindow, MouseNotifyEvent::KEYUP,
|
|
pKeyEvt->GetKeyCode().GetFullCode(), pKeyEvt->GetCharCode(), pKeyEvt->GetRepeat(), false );
|
|
}
|
|
break;
|
|
case SalEvent::KeyModChange:
|
|
ImplHandleSalKeyMod( pWindow, static_cast<SalKeyModEvent const *>(pEvent) );
|
|
break;
|
|
|
|
case SalEvent::InputLanguageChange:
|
|
ImplHandleInputLanguageChange( pWindow );
|
|
break;
|
|
|
|
case SalEvent::MenuActivate:
|
|
case SalEvent::MenuDeactivate:
|
|
case SalEvent::MenuHighlight:
|
|
case SalEvent::MenuCommand:
|
|
case SalEvent::MenuButtonCommand:
|
|
bRet = ImplHandleMenuEvent( pWindow, const_cast<SalMenuEvent *>(static_cast<SalMenuEvent const *>(pEvent)), nEvent );
|
|
break;
|
|
|
|
case SalEvent::WheelMouse:
|
|
bRet = ImplHandleWheelEvent( pWindow, *static_cast<const SalWheelMouseEvent*>(pEvent));
|
|
break;
|
|
|
|
case SalEvent::Paint:
|
|
{
|
|
SalPaintEvent const * pPaintEvt = static_cast<SalPaintEvent const *>(pEvent);
|
|
|
|
if( AllSettings::GetLayoutRTL() )
|
|
{
|
|
SalFrame* pSalFrame = pWindow->ImplGetWindowImpl()->mpFrame;
|
|
const_cast<SalPaintEvent *>(pPaintEvt)->mnBoundX = pSalFrame->maGeometry.nWidth-pPaintEvt->mnBoundWidth-pPaintEvt->mnBoundX;
|
|
}
|
|
|
|
tools::Rectangle aBoundRect( Point( pPaintEvt->mnBoundX, pPaintEvt->mnBoundY ),
|
|
Size( pPaintEvt->mnBoundWidth, pPaintEvt->mnBoundHeight ) );
|
|
ImplHandlePaint( pWindow, aBoundRect, pPaintEvt->mbImmediateUpdate );
|
|
}
|
|
break;
|
|
|
|
case SalEvent::Move:
|
|
ImplHandleMove( pWindow );
|
|
break;
|
|
|
|
case SalEvent::Resize:
|
|
{
|
|
long nNewWidth;
|
|
long nNewHeight;
|
|
pWindow->ImplGetWindowImpl()->mpFrame->GetClientSize( nNewWidth, nNewHeight );
|
|
ImplHandleResize( pWindow, nNewWidth, nNewHeight );
|
|
}
|
|
break;
|
|
|
|
case SalEvent::MoveResize:
|
|
{
|
|
SalFrameGeometry g = pWindow->ImplGetWindowImpl()->mpFrame->GetGeometry();
|
|
ImplHandleMoveResize( pWindow, g.nWidth, g.nHeight );
|
|
}
|
|
break;
|
|
|
|
case SalEvent::ClosePopups:
|
|
{
|
|
KillOwnPopups( pWindow );
|
|
}
|
|
break;
|
|
|
|
case SalEvent::GetFocus:
|
|
ImplHandleGetFocus( pWindow );
|
|
break;
|
|
case SalEvent::LoseFocus:
|
|
ImplHandleLoseFocus( pWindow );
|
|
break;
|
|
|
|
case SalEvent::Close:
|
|
ImplHandleClose( pWindow );
|
|
break;
|
|
|
|
case SalEvent::Shutdown:
|
|
{
|
|
static bool bInQueryExit = false;
|
|
if( !bInQueryExit )
|
|
{
|
|
bInQueryExit = true;
|
|
if ( GetpApp()->QueryExit() )
|
|
{
|
|
// end the message loop
|
|
Application::Quit();
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
bInQueryExit = false;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
case SalEvent::SettingsChanged:
|
|
case SalEvent::PrinterChanged:
|
|
case SalEvent::DisplayChanged:
|
|
case SalEvent::FontChanged:
|
|
ImplHandleSalSettings( nEvent );
|
|
break;
|
|
|
|
case SalEvent::UserEvent:
|
|
ImplHandleUserEvent( const_cast<ImplSVEvent *>(static_cast<ImplSVEvent const *>(pEvent)) );
|
|
break;
|
|
|
|
case SalEvent::ExtTextInput:
|
|
{
|
|
SalExtTextInputEvent const * pEvt = static_cast<SalExtTextInputEvent const *>(pEvent);
|
|
bRet = ImplHandleExtTextInput( pWindow,
|
|
pEvt->maText, pEvt->mpTextAttr,
|
|
pEvt->mnCursorPos, pEvt->mnCursorFlags );
|
|
}
|
|
break;
|
|
case SalEvent::EndExtTextInput:
|
|
bRet = ImplHandleEndExtTextInput();
|
|
break;
|
|
case SalEvent::ExtTextInputPos:
|
|
ImplHandleSalExtTextInputPos( pWindow, const_cast<SalExtTextInputPosEvent *>(static_cast<SalExtTextInputPosEvent const *>(pEvent)) );
|
|
break;
|
|
case SalEvent::InputContextChange:
|
|
bRet = ImplHandleInputContextChange( pWindow );
|
|
break;
|
|
case SalEvent::ShowDialog:
|
|
{
|
|
ShowDialogId nLOKWindowId = static_cast<ShowDialogId>(reinterpret_cast<sal_IntPtr>(pEvent));
|
|
bRet = ImplHandleShowDialog( pWindow, nLOKWindowId );
|
|
}
|
|
break;
|
|
case SalEvent::SurroundingTextRequest:
|
|
ImplHandleSalSurroundingTextRequest( pWindow, const_cast<SalSurroundingTextRequestEvent *>(static_cast<SalSurroundingTextRequestEvent const *>(pEvent)) );
|
|
break;
|
|
case SalEvent::SurroundingTextSelectionChange:
|
|
{
|
|
SalSurroundingTextSelectionChangeEvent const * pEvt
|
|
= static_cast<SalSurroundingTextSelectionChangeEvent const *>(pEvent);
|
|
ImplHandleSurroundingTextSelectionChange( pWindow,
|
|
pEvt->mnStart,
|
|
pEvt->mnEnd );
|
|
[[fallthrough]]; // TODO: Fallthrough really intended?
|
|
}
|
|
case SalEvent::StartReconversion:
|
|
ImplHandleStartReconversion( pWindow );
|
|
break;
|
|
|
|
case SalEvent::QueryCharPosition:
|
|
ImplHandleSalQueryCharPosition( pWindow, const_cast<SalQueryCharPositionEvent *>(static_cast<SalQueryCharPositionEvent const *>(pEvent)) );
|
|
break;
|
|
|
|
case SalEvent::Swipe:
|
|
bRet = ImplHandleSwipe(pWindow, *static_cast<const SalSwipeEvent*>(pEvent));
|
|
break;
|
|
|
|
case SalEvent::LongPress:
|
|
bRet = ImplHandleLongPress(pWindow, *static_cast<const SalLongPressEvent*>(pEvent));
|
|
break;
|
|
|
|
case SalEvent::ExternalGesture:
|
|
{
|
|
auto const * pGestureEvent = static_cast<GestureEvent const *>(pEvent);
|
|
|
|
SalGestureEvent aSalGestureEvent;
|
|
aSalGestureEvent.mfOffset = pGestureEvent->mnOffset;
|
|
aSalGestureEvent.mnX = pGestureEvent->mnX;
|
|
aSalGestureEvent.mnY = pGestureEvent->mnY;
|
|
aSalGestureEvent.meEventType = pGestureEvent->meEventType;
|
|
aSalGestureEvent.meOrientation = pGestureEvent->meOrientation;
|
|
|
|
bRet = ImplHandleGestureEvent(pWindow, aSalGestureEvent);
|
|
}
|
|
break;
|
|
case SalEvent::Gesture:
|
|
{
|
|
auto const * aSalGestureEvent = static_cast<SalGestureEvent const *>(pEvent);
|
|
bRet = ImplHandleGestureEvent(pWindow, *aSalGestureEvent);
|
|
}
|
|
break;
|
|
default:
|
|
SAL_WARN( "vcl.layout", "ImplWindowFrameProc(): unknown event (" << static_cast<int>(nEvent) << ")" );
|
|
break;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|