1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <config_features.h>
22 #include <config_feature_desktop.h>
24 #include <tools/time.hxx>
26 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
28 #include <vcl/ITiledRenderable.hxx>
29 #include <vcl/svapp.hxx>
30 #include <vcl/window.hxx>
31 #include <vcl/cursor.hxx>
32 #include <vcl/sysdata.hxx>
33 #include <vcl/event.hxx>
35 #include <sal/types.h>
41 #include <salframe.hxx>
43 #include <dndlistenercontainer.hxx>
44 #include <dndeventdispatcher.hxx>
46 #include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
47 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
48 #include <com/sun/star/uno/XComponentContext.hpp>
50 #include <comphelper/processfactory.hxx>
52 using namespace ::com::sun::star::uno
;
56 WindowHitTest
Window::ImplHitTest( const Point
& rFramePos
)
58 Point
aFramePos( rFramePos
);
59 if( ImplIsAntiparallel() )
61 const OutputDevice
*pOutDev
= GetOutDev();
62 pOutDev
->ReMirror( aFramePos
);
64 tools::Rectangle
aRect( Point( mnOutOffX
, mnOutOffY
), Size( mnOutWidth
, mnOutHeight
) );
65 if ( !aRect
.IsInside( aFramePos
) )
66 return WindowHitTest::NONE
;
67 if ( mpWindowImpl
->mbWinRegion
)
69 Point aTempPos
= aFramePos
;
70 aTempPos
.AdjustX( -mnOutOffX
);
71 aTempPos
.AdjustY( -mnOutOffY
);
72 if ( !mpWindowImpl
->maWinRegion
.IsInside( aTempPos
) )
73 return WindowHitTest::NONE
;
76 WindowHitTest nHitTest
= WindowHitTest::Inside
;
77 if ( mpWindowImpl
->mbMouseTransparent
)
78 nHitTest
|= WindowHitTest::Transparent
;
82 bool Window::ImplTestMousePointerSet()
84 // as soon as mouse is captured, switch mouse-pointer
85 if ( IsMouseCaptured() )
88 // if the mouse is over the window, switch it
89 tools::Rectangle
aClientRect( Point( 0, 0 ), GetOutputSizePixel() );
90 return aClientRect
.IsInside( GetPointerPosPixel() );
93 PointerStyle
Window::ImplGetMousePointer() const
95 PointerStyle ePointerStyle
;
98 if ( IsEnabled() && IsInputEnabled() && ! IsInModalMode() )
99 ePointerStyle
= GetPointer();
101 ePointerStyle
= PointerStyle::Arrow
;
103 const vcl::Window
* pWindow
= this;
106 // when the pointer is not visible stop the search, as
107 // this status should not be overwritten
108 if ( pWindow
->mpWindowImpl
->mbNoPtrVisible
)
109 return PointerStyle::Null
;
113 if ( pWindow
->mpWindowImpl
->mnWaitCount
)
115 ePointerStyle
= PointerStyle::Wait
;
120 if ( pWindow
->mpWindowImpl
->mbChildPtrOverwrite
)
121 ePointerStyle
= pWindow
->GetPointer();
125 if ( pWindow
->ImplIsOverlapWindow() )
128 pWindow
= pWindow
->ImplGetParent();
132 return ePointerStyle
;
135 void Window::ImplCallMouseMove( sal_uInt16 nMouseCode
, bool bModChanged
)
137 if ( mpWindowImpl
->mpFrameData
->mbMouseIn
&& mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mbReallyVisible
)
139 sal_uInt64 nTime
= tools::Time::GetSystemTicks();
140 long nX
= mpWindowImpl
->mpFrameData
->mnLastMouseX
;
141 long nY
= mpWindowImpl
->mpFrameData
->mnLastMouseY
;
142 sal_uInt16 nCode
= nMouseCode
;
143 MouseEventModifiers nMode
= mpWindowImpl
->mpFrameData
->mnMouseMode
;
145 // check for MouseLeave
146 bLeave
= ((nX
< 0) || (nY
< 0) ||
147 (nX
>= mpWindowImpl
->mpFrameWindow
->mnOutWidth
) ||
148 (nY
>= mpWindowImpl
->mpFrameWindow
->mnOutHeight
)) &&
149 !ImplGetSVData()->maWinData
.mpCaptureWin
;
150 nMode
|= MouseEventModifiers::SYNTHETIC
;
152 nMode
|= MouseEventModifiers::MODIFIERCHANGED
;
153 ImplHandleMouseEvent( mpWindowImpl
->mpFrameWindow
, MouseNotifyEvent::MOUSEMOVE
, bLeave
, nX
, nY
, nTime
, nCode
, nMode
);
157 void Window::ImplGenerateMouseMove()
159 if ( mpWindowImpl
&& mpWindowImpl
->mpFrameData
&&
160 !mpWindowImpl
->mpFrameData
->mnMouseMoveId
)
161 mpWindowImpl
->mpFrameData
->mnMouseMoveId
= Application::PostUserEvent( LINK( mpWindowImpl
->mpFrameWindow
, Window
, ImplGenerateMouseMoveHdl
), nullptr, true );
164 IMPL_LINK_NOARG(Window
, ImplGenerateMouseMoveHdl
, void*, void)
166 mpWindowImpl
->mpFrameData
->mnMouseMoveId
= nullptr;
167 vcl::Window
* pCaptureWin
= ImplGetSVData()->maWinData
.mpCaptureWin
;
169 (pCaptureWin
->mpWindowImpl
&& pCaptureWin
->mpWindowImpl
->mpFrame
== mpWindowImpl
->mpFrame
)
172 ImplCallMouseMove( mpWindowImpl
->mpFrameData
->mnMouseCode
);
176 void Window::ImplInvertFocus( const tools::Rectangle
& rRect
)
178 InvertTracking( rRect
, ShowTrackFlags::Small
| ShowTrackFlags::TrackWindow
);
181 static bool IsWindowFocused(const WindowImpl
& rWinImpl
)
183 if (rWinImpl
.mpSysObj
)
186 if (rWinImpl
.mpFrameData
->mbHasFocus
)
189 if (rWinImpl
.mbFakeFocusSet
)
195 void Window::ImplGrabFocus( GetFocusFlags nFlags
)
197 // #143570# no focus for destructing windows
198 if( !mpWindowImpl
|| mpWindowImpl
->mbInDispose
)
201 // some event listeners do really bad stuff
202 // => prepare for the worst
203 VclPtr
<vcl::Window
> xWindow( this );
205 // Currently the client window should always get the focus
206 // Should the border window at some point be focusable
207 // we need to change all GrabFocus() instances in VCL,
210 if ( mpWindowImpl
->mpClientWindow
)
212 // For a lack of design we need a little hack here to
213 // ensure that dialogs on close pass the focus back to
214 // the correct window
215 if ( mpWindowImpl
->mpLastFocusWindow
&& (mpWindowImpl
->mpLastFocusWindow
.get() != this) &&
216 !(mpWindowImpl
->mnDlgCtrlFlags
& DialogControlFlags::WantFocus
) &&
217 mpWindowImpl
->mpLastFocusWindow
->IsEnabled() &&
218 mpWindowImpl
->mpLastFocusWindow
->IsInputEnabled() &&
219 ! mpWindowImpl
->mpLastFocusWindow
->IsInModalMode()
221 mpWindowImpl
->mpLastFocusWindow
->GrabFocus();
223 mpWindowImpl
->mpClientWindow
->GrabFocus();
226 else if ( mpWindowImpl
->mbFrame
)
228 // For a lack of design we need a little hack here to
229 // ensure that dialogs on close pass the focus back to
230 // the correct window
231 if ( mpWindowImpl
->mpLastFocusWindow
&& (mpWindowImpl
->mpLastFocusWindow
.get() != this) &&
232 !(mpWindowImpl
->mnDlgCtrlFlags
& DialogControlFlags::WantFocus
) &&
233 mpWindowImpl
->mpLastFocusWindow
->IsEnabled() &&
234 mpWindowImpl
->mpLastFocusWindow
->IsInputEnabled() &&
235 ! mpWindowImpl
->mpLastFocusWindow
->IsInModalMode()
238 mpWindowImpl
->mpLastFocusWindow
->GrabFocus();
243 // If the Window is disabled, then we don't change the focus
244 if ( !IsEnabled() || !IsInputEnabled() || IsInModalMode() )
247 // we only need to set the focus if it is not already set
248 // note: if some other frame is waiting for an asynchronous focus event
249 // we also have to post an asynchronous focus event for this frame
250 // which is done using ToTop
251 ImplSVData
* pSVData
= ImplGetSVData();
253 bool bAsyncFocusWaiting
= false;
254 vcl::Window
*pFrame
= pSVData
->maWinData
.mpFirstFrame
;
257 if( pFrame
!= mpWindowImpl
->mpFrameWindow
.get() && pFrame
->mpWindowImpl
->mpFrameData
->mnFocusId
)
259 bAsyncFocusWaiting
= true;
262 pFrame
= pFrame
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
265 bool bHasFocus
= IsWindowFocused(*mpWindowImpl
);
267 bool bMustNotGrabFocus
= false;
268 // #100242#, check parent hierarchy if some floater prohibits grab focus
270 vcl::Window
*pParent
= this;
273 if ((pParent
->GetStyle() & WB_SYSTEMFLOATWIN
) && !(pParent
->GetStyle() & WB_MOVEABLE
))
275 bMustNotGrabFocus
= true;
278 pParent
= pParent
->mpWindowImpl
->mpParent
;
281 if ( !(( pSVData
->maWinData
.mpFocusWin
.get() != this &&
282 !mpWindowImpl
->mbInDispose
) ||
283 ( bAsyncFocusWaiting
&& !bHasFocus
&& !bMustNotGrabFocus
)) )
286 // EndExtTextInput if it is not the same window
287 if ( pSVData
->maWinData
.mpExtTextInputWin
&&
288 (pSVData
->maWinData
.mpExtTextInputWin
.get() != this) )
289 pSVData
->maWinData
.mpExtTextInputWin
->EndExtTextInput();
291 // mark this windows as the last FocusWindow
292 vcl::Window
* pOverlapWindow
= ImplGetFirstOverlapWindow();
293 pOverlapWindow
->mpWindowImpl
->mpLastFocusWindow
= this;
294 mpWindowImpl
->mpFrameData
->mpFocusWin
= this;
298 // menu windows never get the system focus
299 // the application will keep the focus
300 if( bMustNotGrabFocus
)
304 // here we already switch focus as ToTop()
305 // should not give focus to another window
306 mpWindowImpl
->mpFrame
->ToTop( SalFrameToTop::GrabFocus
| SalFrameToTop::GrabFocusOnly
);
311 VclPtr
<vcl::Window
> pOldFocusWindow
= pSVData
->maWinData
.mpFocusWin
;
313 pSVData
->maWinData
.mpFocusWin
= this;
315 if ( pOldFocusWindow
)
318 if ( pOldFocusWindow
->mpWindowImpl
->mpCursor
)
319 pOldFocusWindow
->mpWindowImpl
->mpCursor
->ImplHide();
322 // !!!!! due to old SV-Office Activate/Deactivate handling
323 // !!!!! first as before
324 if ( pOldFocusWindow
)
327 vcl::Window
* pOldOverlapWindow
= pOldFocusWindow
->ImplGetFirstOverlapWindow();
328 vcl::Window
* pNewOverlapWindow
= ImplGetFirstOverlapWindow();
329 if ( pOldOverlapWindow
!= pNewOverlapWindow
)
330 ImplCallFocusChangeActivate( pNewOverlapWindow
, pOldOverlapWindow
);
334 vcl::Window
* pNewOverlapWindow
= ImplGetFirstOverlapWindow();
335 vcl::Window
* pNewRealWindow
= pNewOverlapWindow
->ImplGetWindow();
336 pNewOverlapWindow
->mpWindowImpl
->mbActive
= true;
337 pNewOverlapWindow
->Activate();
338 if ( pNewRealWindow
!= pNewOverlapWindow
)
340 pNewRealWindow
->mpWindowImpl
->mbActive
= true;
341 pNewRealWindow
->Activate();
345 // call Get- and LoseFocus
346 if ( pOldFocusWindow
&& ! pOldFocusWindow
->IsDisposed() )
348 NotifyEvent
aNEvt( MouseNotifyEvent::LOSEFOCUS
, pOldFocusWindow
);
349 if ( !ImplCallPreNotify( aNEvt
) )
350 pOldFocusWindow
->CompatLoseFocus();
351 pOldFocusWindow
->ImplCallDeactivateListeners( this );
354 if ( pSVData
->maWinData
.mpFocusWin
.get() == this )
356 if ( mpWindowImpl
->mpSysObj
)
358 mpWindowImpl
->mpFrameData
->mpFocusWin
= this;
359 if ( !mpWindowImpl
->mpFrameData
->mbInSysObjFocusHdl
)
360 mpWindowImpl
->mpSysObj
->GrabFocus();
363 if ( pSVData
->maWinData
.mpFocusWin
.get() == this )
365 if ( mpWindowImpl
->mpCursor
)
366 mpWindowImpl
->mpCursor
->ImplShow();
367 mpWindowImpl
->mbInFocusHdl
= true;
368 mpWindowImpl
->mnGetFocusFlags
= nFlags
;
369 // if we're changing focus due to closing a popup floating window
370 // notify the new focus window so it can restore the inner focus
371 // eg, toolboxes can select their recent active item
372 if( pOldFocusWindow
&&
373 ! pOldFocusWindow
->IsDisposed() &&
374 ( pOldFocusWindow
->GetDialogControlFlags() & DialogControlFlags::FloatWinPopupModeEndCancel
) )
375 mpWindowImpl
->mnGetFocusFlags
|= GetFocusFlags::FloatWinPopupModeEndCancel
;
376 NotifyEvent
aNEvt( MouseNotifyEvent::GETFOCUS
, this );
377 if ( !ImplCallPreNotify( aNEvt
) && !xWindow
->IsDisposed() )
379 if( !xWindow
->IsDisposed() )
380 ImplCallActivateListeners( (pOldFocusWindow
&& ! pOldFocusWindow
->IsDisposed()) ? pOldFocusWindow
: nullptr );
381 if( !xWindow
->IsDisposed() )
383 mpWindowImpl
->mnGetFocusFlags
= GetFocusFlags::NONE
;
384 mpWindowImpl
->mbInFocusHdl
= false;
389 ImplNewInputContext();
393 void Window::ImplGrabFocusToDocument( GetFocusFlags nFlags
)
395 vcl::Window
*pWin
= this;
398 if( !pWin
->GetParent() )
400 pWin
->ImplGetFrameWindow()->GetWindow( GetWindowType::Client
)->ImplGrabFocus(nFlags
);
403 pWin
= pWin
->GetParent();
407 void Window::MouseMove( const MouseEvent
& rMEvt
)
409 NotifyEvent
aNEvt( MouseNotifyEvent::MOUSEMOVE
, this, &rMEvt
);
413 void Window::MouseButtonDown( const MouseEvent
& rMEvt
)
415 NotifyEvent
aNEvt( MouseNotifyEvent::MOUSEBUTTONDOWN
, this, &rMEvt
);
416 if (!EventNotify(aNEvt
))
417 mpWindowImpl
->mbMouseButtonDown
= true;
420 void Window::MouseButtonUp( const MouseEvent
& rMEvt
)
422 NotifyEvent
aNEvt( MouseNotifyEvent::MOUSEBUTTONUP
, this, &rMEvt
);
423 if (!EventNotify(aNEvt
))
424 mpWindowImpl
->mbMouseButtonUp
= true;
427 void Window::SetMouseTransparent( bool bTransparent
)
430 if ( mpWindowImpl
->mpBorderWindow
)
431 mpWindowImpl
->mpBorderWindow
->SetMouseTransparent( bTransparent
);
433 if( mpWindowImpl
->mpSysObj
)
434 mpWindowImpl
->mpSysObj
->SetMouseTransparent( bTransparent
);
436 mpWindowImpl
->mbMouseTransparent
= bTransparent
;
439 void Window::CaptureMouse()
442 ImplSVData
* pSVData
= ImplGetSVData();
444 // possibly stop tracking
445 if ( pSVData
->maWinData
.mpTrackWin
.get() != this )
447 if ( pSVData
->maWinData
.mpTrackWin
)
448 pSVData
->maWinData
.mpTrackWin
->EndTracking( TrackingEventFlags::Cancel
);
451 if ( pSVData
->maWinData
.mpCaptureWin
.get() != this )
453 pSVData
->maWinData
.mpCaptureWin
= this;
454 mpWindowImpl
->mpFrame
->CaptureMouse( true );
458 void Window::ReleaseMouse()
460 if (IsMouseCaptured())
462 ImplSVData
* pSVData
= ImplGetSVData();
463 pSVData
->maWinData
.mpCaptureWin
= nullptr;
464 mpWindowImpl
->mpFrame
->CaptureMouse( false );
465 ImplGenerateMouseMove();
469 bool Window::IsMouseCaptured() const
471 return (this == ImplGetSVData()->maWinData
.mpCaptureWin
);
474 void Window::SetPointer( PointerStyle nPointer
)
476 if ( mpWindowImpl
->maPointer
== nPointer
)
479 mpWindowImpl
->maPointer
= nPointer
;
481 // possibly immediately move pointer
482 if ( !mpWindowImpl
->mpFrameData
->mbInMouseMove
&& ImplTestMousePointerSet() )
483 mpWindowImpl
->mpFrame
->SetPointer( ImplGetMousePointer() );
485 if (VclPtr
<vcl::Window
> pWin
= GetParentWithLOKNotifier())
487 PointerStyle aPointer
= GetPointer();
488 // We don't map all possible pointers hence we need a default
489 OString aPointerString
= "default";
490 auto aIt
= vcl::gaLOKPointerMap
.find(aPointer
);
491 if (aIt
!= vcl::gaLOKPointerMap
.end())
493 aPointerString
= aIt
->second
;
496 // issue mouse pointer events only for document windows
497 // Doc windows' immediate parent SfxFrameViewWindow_Impl is the one with
498 // parent notifier set during initialization
499 if (GetParent()->ImplGetWindowImpl()->mbLOKParentNotifier
&&
500 GetParent()->ImplGetWindowImpl()->mnLOKWindowId
== 0)
502 pWin
->GetLOKNotifier()->libreOfficeKitViewCallback(LOK_CALLBACK_MOUSE_POINTER
, aPointerString
.getStr());
507 void Window::EnableChildPointerOverwrite( bool bOverwrite
)
510 if ( mpWindowImpl
->mbChildPtrOverwrite
== bOverwrite
)
513 mpWindowImpl
->mbChildPtrOverwrite
= bOverwrite
;
515 // possibly immediately move pointer
516 if ( !mpWindowImpl
->mpFrameData
->mbInMouseMove
&& ImplTestMousePointerSet() )
517 mpWindowImpl
->mpFrame
->SetPointer( ImplGetMousePointer() );
520 void Window::SetPointerPosPixel( const Point
& rPos
)
522 Point aPos
= ImplOutputToFrame( rPos
);
523 const OutputDevice
*pOutDev
= GetOutDev();
524 if( pOutDev
->HasMirroredGraphics() )
526 if( !IsRTLEnabled() )
528 pOutDev
->ReMirror( aPos
);
530 // mirroring is required here, SetPointerPos bypasses SalGraphics
531 aPos
.setX( mpGraphics
->mirror2( aPos
.X(), this ) );
533 else if( ImplIsAntiparallel() )
535 pOutDev
->ReMirror( aPos
);
537 mpWindowImpl
->mpFrame
->SetPointerPos( aPos
.X(), aPos
.Y() );
540 void Window::SetLastMousePos(const Point
& rPos
)
542 // Do this conversion, so when GetPointerPosPixel() calls
543 // ImplFrameToOutput(), we get back the original position.
544 Point aPos
= ImplOutputToFrame(rPos
);
545 mpWindowImpl
->mpFrameData
->mnLastMouseX
= aPos
.X();
546 mpWindowImpl
->mpFrameData
->mnLastMouseY
= aPos
.Y();
549 Point
Window::GetPointerPosPixel()
552 Point
aPos( mpWindowImpl
->mpFrameData
->mnLastMouseX
, mpWindowImpl
->mpFrameData
->mnLastMouseY
);
553 if( ImplIsAntiparallel() )
555 const OutputDevice
*pOutDev
= GetOutDev();
556 pOutDev
->ReMirror( aPos
);
558 return ImplFrameToOutput( aPos
);
561 Point
Window::GetLastPointerPosPixel()
564 Point
aPos( mpWindowImpl
->mpFrameData
->mnBeforeLastMouseX
, mpWindowImpl
->mpFrameData
->mnBeforeLastMouseY
);
565 if( ImplIsAntiparallel() )
567 const OutputDevice
*pOutDev
= GetOutDev();
568 pOutDev
->ReMirror( aPos
);
570 return ImplFrameToOutput( aPos
);
573 void Window::ShowPointer( bool bVisible
)
576 if ( mpWindowImpl
->mbNoPtrVisible
!= !bVisible
)
578 mpWindowImpl
->mbNoPtrVisible
= !bVisible
;
580 // possibly immediately move pointer
581 if ( !mpWindowImpl
->mpFrameData
->mbInMouseMove
&& ImplTestMousePointerSet() )
582 mpWindowImpl
->mpFrame
->SetPointer( ImplGetMousePointer() );
586 Window::PointerState
Window::GetPointerState()
591 if (mpWindowImpl
->mpFrame
)
593 SalFrame::SalPointerState aSalPointerState
= mpWindowImpl
->mpFrame
->GetPointerState();
594 if( ImplIsAntiparallel() )
596 const OutputDevice
*pOutDev
= GetOutDev();
597 pOutDev
->ReMirror( aSalPointerState
.maPos
);
599 aState
.maPos
= ImplFrameToOutput( aSalPointerState
.maPos
);
600 aState
.mnState
= aSalPointerState
.mnState
;
605 bool Window::IsMouseOver() const
607 return ImplGetWinData()->mbMouseOver
;
610 void Window::EnterWait()
613 mpWindowImpl
->mnWaitCount
++;
615 if ( mpWindowImpl
->mnWaitCount
== 1 )
617 // possibly immediately move pointer
618 if ( !mpWindowImpl
->mpFrameData
->mbInMouseMove
&& ImplTestMousePointerSet() )
619 mpWindowImpl
->mpFrame
->SetPointer( ImplGetMousePointer() );
623 void Window::LeaveWait()
626 if ( mpWindowImpl
->mnWaitCount
)
628 mpWindowImpl
->mnWaitCount
--;
630 if ( !mpWindowImpl
->mnWaitCount
)
632 // possibly immediately move pointer
633 if ( !mpWindowImpl
->mpFrameData
->mbInMouseMove
&& ImplTestMousePointerSet() )
634 mpWindowImpl
->mpFrame
->SetPointer( ImplGetMousePointer() );
639 bool Window::ImplStopDnd()
642 if( mpWindowImpl
->mpFrameData
&& mpWindowImpl
->mpFrameData
->mxDropTargetListener
.is() )
645 mpWindowImpl
->mpFrameData
->mxDropTarget
.clear();
646 mpWindowImpl
->mpFrameData
->mxDragSource
.clear();
647 mpWindowImpl
->mpFrameData
->mxDropTargetListener
.clear();
653 void Window::ImplStartDnd()
658 Reference
< css::datatransfer::dnd::XDropTarget
> Window::GetDropTarget()
661 return Reference
< css::datatransfer::dnd::XDropTarget
>();
663 if( ! mpWindowImpl
->mxDNDListenerContainer
.is() )
665 sal_Int8 nDefaultActions
= 0;
667 if( mpWindowImpl
->mpFrameData
)
669 if( ! mpWindowImpl
->mpFrameData
->mxDropTarget
.is() )
671 // initialization is done in GetDragSource
675 if( mpWindowImpl
->mpFrameData
->mxDropTarget
.is() )
677 nDefaultActions
= mpWindowImpl
->mpFrameData
->mxDropTarget
->getDefaultActions();
679 if( ! mpWindowImpl
->mpFrameData
->mxDropTargetListener
.is() )
681 mpWindowImpl
->mpFrameData
->mxDropTargetListener
= new DNDEventDispatcher( mpWindowImpl
->mpFrameWindow
);
685 mpWindowImpl
->mpFrameData
->mxDropTarget
->addDropTargetListener( mpWindowImpl
->mpFrameData
->mxDropTargetListener
);
687 // register also as drag gesture listener if directly supported by drag source
688 Reference
< css::datatransfer::dnd::XDragGestureRecognizer
> xDragGestureRecognizer(
689 mpWindowImpl
->mpFrameData
->mxDragSource
, UNO_QUERY
);
691 if( xDragGestureRecognizer
.is() )
693 xDragGestureRecognizer
->addDragGestureListener(
694 Reference
< css::datatransfer::dnd::XDragGestureListener
> (mpWindowImpl
->mpFrameData
->mxDropTargetListener
, UNO_QUERY
));
697 mpWindowImpl
->mpFrameData
->mbInternalDragGestureRecognizer
= true;
700 catch (const RuntimeException
&)
702 // release all instances
703 mpWindowImpl
->mpFrameData
->mxDropTarget
.clear();
704 mpWindowImpl
->mpFrameData
->mxDragSource
.clear();
711 mpWindowImpl
->mxDNDListenerContainer
= static_cast < css::datatransfer::dnd::XDropTarget
* > ( new DNDListenerContainer( nDefaultActions
) );
714 // this object is located in the same process, so there will be no runtime exception
715 return Reference
< css::datatransfer::dnd::XDropTarget
> ( mpWindowImpl
->mxDNDListenerContainer
, UNO_QUERY
);
718 Reference
< css::datatransfer::dnd::XDragSource
> Window::GetDragSource()
721 #if HAVE_FEATURE_DESKTOP
723 if( mpWindowImpl
->mpFrameData
)
725 if( ! mpWindowImpl
->mpFrameData
->mxDragSource
.is() )
729 Reference
< XComponentContext
> xContext( comphelper::getProcessComponentContext() );
730 const SystemEnvData
* pEnvData
= GetSystemData();
734 Sequence
< Any
> aDragSourceAL( 2 ), aDropTargetAL( 2 );
735 OUString aDragSourceSN
, aDropTargetSN
;
737 aDragSourceSN
= "com.sun.star.datatransfer.dnd.OleDragSource";
738 aDropTargetSN
= "com.sun.star.datatransfer.dnd.OleDropTarget";
739 aDragSourceAL
[ 1 ] <<= static_cast<sal_uInt64
>( reinterpret_cast<sal_IntPtr
>(pEnvData
->hWnd
) );
740 aDropTargetAL
[ 0 ] <<= static_cast<sal_uInt64
>( reinterpret_cast<sal_IntPtr
>(pEnvData
->hWnd
) );
742 /* FIXME: macOS specific dnd interface does not exist! *
743 * Using Windows based dnd as a temporary solution */
744 aDragSourceSN
= "com.sun.star.datatransfer.dnd.OleDragSource";
745 aDropTargetSN
= "com.sun.star.datatransfer.dnd.OleDropTarget";
746 aDragSourceAL
[ 1 ] <<= static_cast<sal_uInt64
>( reinterpret_cast<sal_IntPtr
>(pEnvData
->mpNSView
) );
747 aDropTargetAL
[ 0 ] <<= static_cast<sal_uInt64
>( reinterpret_cast<sal_IntPtr
>(pEnvData
->mpNSView
) );
748 #elif HAVE_FEATURE_X11
749 aDragSourceSN
= "com.sun.star.datatransfer.dnd.X11DragSource";
750 aDropTargetSN
= "com.sun.star.datatransfer.dnd.X11DropTarget";
752 aDragSourceAL
[ 0 ] <<= Application::GetDisplayConnection();
753 aDragSourceAL
[ 1 ] <<= pEnvData
->aShellWindow
;
754 aDropTargetAL
[ 0 ] <<= Application::GetDisplayConnection();
755 aDropTargetAL
[ 1 ] <<= pEnvData
->aShellWindow
;
757 if( !aDragSourceSN
.isEmpty() )
758 mpWindowImpl
->mpFrameData
->mxDragSource
.set(
759 xContext
->getServiceManager()->createInstanceWithArgumentsAndContext( aDragSourceSN
, aDragSourceAL
, xContext
),
762 if( !aDropTargetSN
.isEmpty() )
763 mpWindowImpl
->mpFrameData
->mxDropTarget
.set(
764 xContext
->getServiceManager()->createInstanceWithArgumentsAndContext( aDropTargetSN
, aDropTargetAL
, xContext
),
769 // createInstance can throw any exception
770 catch (const Exception
&)
772 // release all instances
773 mpWindowImpl
->mpFrameData
->mxDropTarget
.clear();
774 mpWindowImpl
->mpFrameData
->mxDragSource
.clear();
778 return mpWindowImpl
->mpFrameData
->mxDragSource
;
781 return Reference
< css::datatransfer::dnd::XDragSource
> ();
784 Reference
< css::datatransfer::dnd::XDragGestureRecognizer
> Window::GetDragGestureRecognizer()
786 return Reference
< css::datatransfer::dnd::XDragGestureRecognizer
> ( GetDropTarget(), UNO_QUERY
);
789 } /* namespace vcl */
791 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */