LibreOffice Module vcl (master)  1
mouse.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 
21 #include <config_feature_desktop.h>
22 #include <config_vclplug.h>
23 
24 #include <tools/time.hxx>
25 
26 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
27 
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>
34 
35 #include <sal/types.h>
36 
37 #include <window.h>
38 #include <svdata.hxx>
39 #include <salobj.hxx>
40 #include <salgdi.hxx>
41 #include <salframe.hxx>
42 
43 #include <dndlistenercontainer.hxx>
44 #include <dndeventdispatcher.hxx>
45 
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>
49 
51 
52 using namespace ::com::sun::star::uno;
53 
54 namespace vcl {
55 
56 WindowHitTest Window::ImplHitTest( const Point& rFramePos )
57 {
58  Point aFramePos( rFramePos );
59  if( GetOutDev()->ImplIsAntiparallel() )
60  {
61  const OutputDevice *pOutDev = GetOutDev();
62  pOutDev->ReMirror( aFramePos );
63  }
64  if ( !GetOutputRectPixel().IsInside( aFramePos ) )
65  return WindowHitTest::NONE;
66  if ( mpWindowImpl->mbWinRegion )
67  {
68  Point aTempPos = aFramePos;
69  aTempPos.AdjustX( -GetOutDev()->mnOutOffX );
70  aTempPos.AdjustY( -GetOutDev()->mnOutOffY );
71  if ( !mpWindowImpl->maWinRegion.IsInside( aTempPos ) )
72  return WindowHitTest::NONE;
73  }
74 
76  if ( mpWindowImpl->mbMouseTransparent )
77  nHitTest |= WindowHitTest::Transparent;
78  return nHitTest;
79 }
80 
82 {
83  // as soon as mouse is captured, switch mouse-pointer
84  if ( IsMouseCaptured() )
85  return true;
86 
87  // if the mouse is over the window, switch it
88  tools::Rectangle aClientRect( Point( 0, 0 ), GetOutputSizePixel() );
89  return aClientRect.IsInside( GetPointerPosPixel() );
90 }
91 
93 {
94  PointerStyle ePointerStyle;
95  bool bWait = false;
96 
97  if ( IsEnabled() && IsInputEnabled() && ! IsInModalMode() )
98  ePointerStyle = GetPointer();
99  else
100  ePointerStyle = PointerStyle::Arrow;
101 
102  const vcl::Window* pWindow = this;
103  do
104  {
105  // when the pointer is not visible stop the search, as
106  // this status should not be overwritten
107  if ( pWindow->mpWindowImpl->mbNoPtrVisible )
108  return PointerStyle::Null;
109 
110  if ( !bWait )
111  {
112  if ( pWindow->mpWindowImpl->mnWaitCount )
113  {
114  ePointerStyle = PointerStyle::Wait;
115  bWait = true;
116  }
117  else
118  {
119  if ( pWindow->mpWindowImpl->mbChildPtrOverwrite )
120  ePointerStyle = pWindow->GetPointer();
121  }
122  }
123 
124  if ( pWindow->ImplIsOverlapWindow() )
125  break;
126 
127  pWindow = pWindow->ImplGetParent();
128  }
129  while ( pWindow );
130 
131  return ePointerStyle;
132 }
133 
134 void Window::ImplCallMouseMove( sal_uInt16 nMouseCode, bool bModChanged )
135 {
136  if ( !(mpWindowImpl->mpFrameData->mbMouseIn && mpWindowImpl->mpFrameWindow->mpWindowImpl->mbReallyVisible) )
137  return;
138 
139  sal_uInt64 nTime = tools::Time::GetSystemTicks();
140  tools::Long nX = mpWindowImpl->mpFrameData->mnLastMouseX;
141  tools::Long nY = mpWindowImpl->mpFrameData->mnLastMouseY;
142  sal_uInt16 nCode = nMouseCode;
143  MouseEventModifiers nMode = mpWindowImpl->mpFrameData->mnMouseMode;
144  bool bLeave;
145  // check for MouseLeave
146  bLeave = ((nX < 0) || (nY < 0) ||
147  (nX >= mpWindowImpl->mpFrameWindow->GetOutDev()->mnOutWidth) ||
148  (nY >= mpWindowImpl->mpFrameWindow->GetOutDev()->mnOutHeight)) &&
151  if ( bModChanged )
153  ImplHandleMouseEvent( mpWindowImpl->mpFrameWindow, MouseNotifyEvent::MOUSEMOVE, bLeave, nX, nY, nTime, nCode, nMode );
154 }
155 
157 {
158  if ( mpWindowImpl && mpWindowImpl->mpFrameData &&
159  !mpWindowImpl->mpFrameData->mnMouseMoveId )
160  mpWindowImpl->mpFrameData->mnMouseMoveId = Application::PostUserEvent( LINK( mpWindowImpl->mpFrameWindow, Window, ImplGenerateMouseMoveHdl ), nullptr, true );
161 }
162 
163 IMPL_LINK_NOARG(Window, ImplGenerateMouseMoveHdl, void*, void)
164 {
165  mpWindowImpl->mpFrameData->mnMouseMoveId = nullptr;
166  vcl::Window* pCaptureWin = ImplGetSVData()->mpWinData->mpCaptureWin;
167  if( ! pCaptureWin ||
168  (pCaptureWin->mpWindowImpl && pCaptureWin->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame)
169  )
170  {
171  ImplCallMouseMove( mpWindowImpl->mpFrameData->mnMouseCode );
172  }
173 }
174 
176 {
178 }
179 
180 static bool IsWindowFocused(const WindowImpl& rWinImpl)
181 {
182  if (rWinImpl.mpSysObj)
183  return true;
184 
185  if (rWinImpl.mpFrameData->mbHasFocus)
186  return true;
187 
188  if (rWinImpl.mbFakeFocusSet)
189  return true;
190 
191  return false;
192 }
193 
195 {
196  // #143570# no focus for destructing windows
197  if( !mpWindowImpl || mpWindowImpl->mbInDispose )
198  return;
199 
200  // some event listeners do really bad stuff
201  // => prepare for the worst
202  VclPtr<vcl::Window> xWindow( this );
203 
204  // Currently the client window should always get the focus
205  // Should the border window at some point be focusable
206  // we need to change all GrabFocus() instances in VCL,
207  // e.g. in ToTop()
208 
209  if ( mpWindowImpl->mpClientWindow )
210  {
211  // For a lack of design we need a little hack here to
212  // ensure that dialogs on close pass the focus back to
213  // the correct window
214  if ( mpWindowImpl->mpLastFocusWindow && (mpWindowImpl->mpLastFocusWindow.get() != this) &&
215  !(mpWindowImpl->mnDlgCtrlFlags & DialogControlFlags::WantFocus) &&
216  mpWindowImpl->mpLastFocusWindow->IsEnabled() &&
217  mpWindowImpl->mpLastFocusWindow->IsInputEnabled() &&
218  ! mpWindowImpl->mpLastFocusWindow->IsInModalMode()
219  )
220  mpWindowImpl->mpLastFocusWindow->GrabFocus();
221  else
222  mpWindowImpl->mpClientWindow->GrabFocus();
223  return;
224  }
225  else if ( mpWindowImpl->mbFrame )
226  {
227  // For a lack of design we need a little hack here to
228  // ensure that dialogs on close pass the focus back to
229  // the correct window
230  if ( mpWindowImpl->mpLastFocusWindow && (mpWindowImpl->mpLastFocusWindow.get() != this) &&
231  !(mpWindowImpl->mnDlgCtrlFlags & DialogControlFlags::WantFocus) &&
232  mpWindowImpl->mpLastFocusWindow->IsEnabled() &&
233  mpWindowImpl->mpLastFocusWindow->IsInputEnabled() &&
234  ! mpWindowImpl->mpLastFocusWindow->IsInModalMode()
235  )
236  {
237  mpWindowImpl->mpLastFocusWindow->GrabFocus();
238  return;
239  }
240  }
241 
242  // If the Window is disabled, then we don't change the focus
243  if ( !IsEnabled() || !IsInputEnabled() || IsInModalMode() )
244  return;
245 
246  // we only need to set the focus if it is not already set
247  // note: if some other frame is waiting for an asynchronous focus event
248  // we also have to post an asynchronous focus event for this frame
249  // which is done using ToTop
250  ImplSVData* pSVData = ImplGetSVData();
251 
252  bool bAsyncFocusWaiting = false;
253  vcl::Window *pFrame = pSVData->maFrameData.mpFirstFrame;
254  while( pFrame && pFrame->mpWindowImpl && pFrame->mpWindowImpl->mpFrameData )
255  {
256  if( pFrame != mpWindowImpl->mpFrameWindow.get() && pFrame->mpWindowImpl->mpFrameData->mnFocusId )
257  {
258  bAsyncFocusWaiting = true;
259  break;
260  }
261  pFrame = pFrame->mpWindowImpl->mpFrameData->mpNextFrame;
262  }
263 
264  bool bHasFocus = IsWindowFocused(*mpWindowImpl);
265 
266  bool bMustNotGrabFocus = false;
267  // #100242#, check parent hierarchy if some floater prohibits grab focus
268 
269  vcl::Window *pParent = this;
270  while( pParent )
271  {
272  if ((pParent->GetStyle() & WB_SYSTEMFLOATWIN) && !(pParent->GetStyle() & WB_MOVEABLE))
273  {
274  bMustNotGrabFocus = true;
275  break;
276  }
277  if (!pParent->mpWindowImpl)
278  break;
279  pParent = pParent->mpWindowImpl->mpParent;
280  }
281 
282  if ( !(( pSVData->mpWinData->mpFocusWin.get() != this &&
283  !mpWindowImpl->mbInDispose ) ||
284  ( bAsyncFocusWaiting && !bHasFocus && !bMustNotGrabFocus )) )
285  return;
286 
287  // EndExtTextInput if it is not the same window
288  if (pSVData->mpWinData->mpExtTextInputWin
289  && (pSVData->mpWinData->mpExtTextInputWin.get() != this))
291 
292  // mark this windows as the last FocusWindow
293  vcl::Window* pOverlapWindow = ImplGetFirstOverlapWindow();
294  if (pOverlapWindow->mpWindowImpl)
295  pOverlapWindow->mpWindowImpl->mpLastFocusWindow = this;
296  mpWindowImpl->mpFrameData->mpFocusWin = this;
297 
298  if( !bHasFocus )
299  {
300  // menu windows never get the system focus
301  // the application will keep the focus
302  if( bMustNotGrabFocus )
303  return;
304  else
305  {
306  // here we already switch focus as ToTop()
307  // should not give focus to another window
309  return;
310  }
311  }
312 
313  VclPtr<vcl::Window> pOldFocusWindow = pSVData->mpWinData->mpFocusWin;
314 
315  pSVData->mpWinData->mpFocusWin = this;
316 
317  if ( pOldFocusWindow && pOldFocusWindow->mpWindowImpl )
318  {
319  // Cursor hidden
320  if ( pOldFocusWindow->mpWindowImpl->mpCursor )
321  pOldFocusWindow->mpWindowImpl->mpCursor->ImplHide();
322  }
323 
324  // !!!!! due to old SV-Office Activate/Deactivate handling
325  // !!!!! first as before
326  if ( pOldFocusWindow )
327  {
328  // remember Focus
329  vcl::Window* pOldOverlapWindow = pOldFocusWindow->ImplGetFirstOverlapWindow();
330  vcl::Window* pNewOverlapWindow = ImplGetFirstOverlapWindow();
331  if ( pOldOverlapWindow != pNewOverlapWindow )
332  ImplCallFocusChangeActivate( pNewOverlapWindow, pOldOverlapWindow );
333  }
334  else
335  {
336  vcl::Window* pNewOverlapWindow = ImplGetFirstOverlapWindow();
337  if ( pNewOverlapWindow && pNewOverlapWindow->mpWindowImpl )
338  {
339  vcl::Window* pNewRealWindow = pNewOverlapWindow->ImplGetWindow();
340  pNewOverlapWindow->mpWindowImpl->mbActive = true;
341  pNewOverlapWindow->Activate();
342  if ( pNewRealWindow != pNewOverlapWindow && pNewRealWindow && pNewRealWindow->mpWindowImpl )
343  {
344  pNewRealWindow->mpWindowImpl->mbActive = true;
345  pNewRealWindow->Activate();
346  }
347  }
348  }
349 
350  // call Get- and LoseFocus
351  if ( pOldFocusWindow && ! pOldFocusWindow->isDisposed() )
352  {
353  NotifyEvent aNEvt( MouseNotifyEvent::LOSEFOCUS, pOldFocusWindow );
354  if ( !ImplCallPreNotify( aNEvt ) )
355  pOldFocusWindow->CompatLoseFocus();
356  pOldFocusWindow->ImplCallDeactivateListeners( this );
357  }
358 
359  if (pSVData->mpWinData->mpFocusWin.get() == this)
360  {
361  if ( mpWindowImpl->mpSysObj )
362  {
363  mpWindowImpl->mpFrameData->mpFocusWin = this;
364  if ( !mpWindowImpl->mpFrameData->mbInSysObjFocusHdl )
365  mpWindowImpl->mpSysObj->GrabFocus();
366  }
367 
368  if (pSVData->mpWinData->mpFocusWin.get() == this)
369  {
370  if ( mpWindowImpl->mpCursor )
371  mpWindowImpl->mpCursor->ImplShow();
372  mpWindowImpl->mbInFocusHdl = true;
373  mpWindowImpl->mnGetFocusFlags = nFlags;
374  // if we're changing focus due to closing a popup floating window
375  // notify the new focus window so it can restore the inner focus
376  // eg, toolboxes can select their recent active item
377  if( pOldFocusWindow &&
378  ! pOldFocusWindow->isDisposed() &&
382  if ( !ImplCallPreNotify( aNEvt ) && !xWindow->isDisposed() )
383  CompatGetFocus();
384  if( !xWindow->isDisposed() )
385  ImplCallActivateListeners( (pOldFocusWindow && ! pOldFocusWindow->isDisposed()) ? pOldFocusWindow : nullptr );
386  if( !xWindow->isDisposed() )
387  {
388  mpWindowImpl->mnGetFocusFlags = GetFocusFlags::NONE;
389  mpWindowImpl->mbInFocusHdl = false;
390  }
391  }
392  }
393 
395 
396 }
397 
399 {
400  vcl::Window *pWin = this;
401  while( pWin )
402  {
403  if( !pWin->GetParent() )
404  {
405  pWin->mpWindowImpl->mpFrame->GrabFocus();
407  return;
408  }
409  pWin = pWin->GetParent();
410  }
411 }
412 
413 void Window::MouseMove( const MouseEvent& rMEvt )
414 {
415  NotifyEvent aNEvt( MouseNotifyEvent::MOUSEMOVE, this, &rMEvt );
416  EventNotify(aNEvt);
417 }
418 
420 {
421  NotifyEvent aNEvt( MouseNotifyEvent::MOUSEBUTTONDOWN, this, &rMEvt );
422  if (!EventNotify(aNEvt))
423  mpWindowImpl->mbMouseButtonDown = true;
424 }
425 
426 void Window::MouseButtonUp( const MouseEvent& rMEvt )
427 {
428  NotifyEvent aNEvt( MouseNotifyEvent::MOUSEBUTTONUP, this, &rMEvt );
429  if (!EventNotify(aNEvt))
430  mpWindowImpl->mbMouseButtonUp = true;
431 }
432 
433 void Window::SetMouseTransparent( bool bTransparent )
434 {
435 
436  if ( mpWindowImpl->mpBorderWindow )
437  mpWindowImpl->mpBorderWindow->SetMouseTransparent( bTransparent );
438 
439  if( mpWindowImpl->mpSysObj )
440  mpWindowImpl->mpSysObj->SetMouseTransparent( bTransparent );
441 
442  mpWindowImpl->mbMouseTransparent = bTransparent;
443 }
444 
446 {
447  ImplSVData* pSVData = ImplGetSVData();
448 
449  // possibly stop tracking
450  if (pSVData->mpWinData->mpTrackWin.get() != this)
451  {
452  if (pSVData->mpWinData->mpTrackWin)
454  }
455 
456  if (pSVData->mpWinData->mpCaptureWin.get() != this)
457  {
458  pSVData->mpWinData->mpCaptureWin = this;
459  mpWindowImpl->mpFrame->CaptureMouse( true );
460  }
461 }
462 
464 {
465  if (IsMouseCaptured())
466  {
467  ImplSVData* pSVData = ImplGetSVData();
468  pSVData->mpWinData->mpCaptureWin = nullptr;
469  if (mpWindowImpl && mpWindowImpl->mpFrame)
470  mpWindowImpl->mpFrame->CaptureMouse( false );
472  }
473 }
474 
476 {
477  return (this == ImplGetSVData()->mpWinData->mpCaptureWin);
478 }
479 
481 {
482  if ( mpWindowImpl->maPointer == nPointer )
483  return;
484 
485  mpWindowImpl->maPointer = nPointer;
486 
487  // possibly immediately move pointer
488  if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
489  mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
490 
492  if (!pWin)
493  return;
494 
495  PointerStyle aPointer = GetPointer();
496  // We don't map all possible pointers hence we need a default
497  OString aPointerString = "default";
498  auto aIt = vcl::gaLOKPointerMap.find(aPointer);
499  if (aIt != vcl::gaLOKPointerMap.end())
500  {
501  aPointerString = aIt->second;
502  }
503 
504  // issue mouse pointer events only for document windows
505  // Doc windows' immediate parent SfxFrameViewWindow_Impl is the one with
506  // parent notifier set during initialization
507  if (GetParent()->ImplGetWindowImpl()->mbLOKParentNotifier &&
508  GetParent()->ImplGetWindowImpl()->mnLOKWindowId == 0)
509  {
510  pWin->GetLOKNotifier()->libreOfficeKitViewCallback(LOK_CALLBACK_MOUSE_POINTER, aPointerString.getStr());
511  }
512 }
513 
514 void Window::EnableChildPointerOverwrite( bool bOverwrite )
515 {
516 
517  if ( mpWindowImpl->mbChildPtrOverwrite == bOverwrite )
518  return;
519 
520  mpWindowImpl->mbChildPtrOverwrite = bOverwrite;
521 
522  // possibly immediately move pointer
523  if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
524  mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
525 }
526 
527 void Window::SetPointerPosPixel( const Point& rPos )
528 {
529  Point aPos = ImplOutputToFrame( rPos );
530  const OutputDevice *pOutDev = GetOutDev();
531  if( pOutDev->HasMirroredGraphics() )
532  {
533  if( !IsRTLEnabled() )
534  {
535  pOutDev->ReMirror( aPos );
536  }
537  // mirroring is required here, SetPointerPos bypasses SalGraphics
538  aPos.setX( GetOutDev()->mpGraphics->mirror2( aPos.X(), *GetOutDev() ) );
539  }
540  else if( GetOutDev()->ImplIsAntiparallel() )
541  {
542  pOutDev->ReMirror( aPos );
543  }
544  mpWindowImpl->mpFrame->SetPointerPos( aPos.X(), aPos.Y() );
545 }
546 
547 void Window::SetLastMousePos(const Point& rPos)
548 {
549  // Do this conversion, so when GetPointerPosPixel() calls
550  // ImplFrameToOutput(), we get back the original position.
551  Point aPos = ImplOutputToFrame(rPos);
552  mpWindowImpl->mpFrameData->mnLastMouseX = aPos.X();
553  mpWindowImpl->mpFrameData->mnLastMouseY = aPos.Y();
554 }
555 
557 {
558 
559  Point aPos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
560  if( GetOutDev()->ImplIsAntiparallel() )
561  {
562  const OutputDevice *pOutDev = GetOutDev();
563  pOutDev->ReMirror( aPos );
564  }
565  return ImplFrameToOutput( aPos );
566 }
567 
569 {
570 
571  Point aPos( mpWindowImpl->mpFrameData->mnBeforeLastMouseX, mpWindowImpl->mpFrameData->mnBeforeLastMouseY );
572  if( GetOutDev()->ImplIsAntiparallel() )
573  {
574  const OutputDevice *pOutDev = GetOutDev();
575  pOutDev->ReMirror( aPos );
576  }
577  return ImplFrameToOutput( aPos );
578 }
579 
580 void Window::ShowPointer( bool bVisible )
581 {
582 
583  if ( mpWindowImpl->mbNoPtrVisible != !bVisible )
584  {
585  mpWindowImpl->mbNoPtrVisible = !bVisible;
586 
587  // possibly immediately move pointer
588  if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
589  mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
590  }
591 }
592 
594 {
595  PointerState aState;
596  aState.mnState = 0;
597 
598  if (mpWindowImpl->mpFrame)
599  {
600  SalFrame::SalPointerState aSalPointerState = mpWindowImpl->mpFrame->GetPointerState();
601  if( GetOutDev()->ImplIsAntiparallel() )
602  {
603  const OutputDevice *pOutDev = GetOutDev();
604  pOutDev->ReMirror( aSalPointerState.maPos );
605  }
606  aState.maPos = ImplFrameToOutput( aSalPointerState.maPos );
607  aState.mnState = aSalPointerState.mnState;
608  }
609  return aState;
610 }
611 
613 {
614  return ImplGetWinData()->mbMouseOver;
615 }
616 
618 {
619 
620  mpWindowImpl->mnWaitCount++;
621 
622  if ( mpWindowImpl->mnWaitCount == 1 )
623  {
624  // possibly immediately move pointer
625  if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
626  mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
627  }
628 }
629 
631 {
632 
633  if ( mpWindowImpl->mnWaitCount )
634  {
635  mpWindowImpl->mnWaitCount--;
636 
637  if ( !mpWindowImpl->mnWaitCount )
638  {
639  // possibly immediately move pointer
640  if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
641  mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
642  }
643  }
644 }
645 
647 {
648  bool bRet = false;
649  if( mpWindowImpl->mpFrameData && mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
650  {
651  bRet = true;
652  mpWindowImpl->mpFrameData->mxDropTarget.clear();
653  mpWindowImpl->mpFrameData->mxDragSource.clear();
654  mpWindowImpl->mpFrameData->mxDropTargetListener.clear();
655  }
656 
657  return bRet;
658 }
659 
661 {
662  GetDropTarget();
663 }
664 
665 Reference< css::datatransfer::dnd::XDropTarget > Window::GetDropTarget()
666 {
667  if( !mpWindowImpl )
668  return Reference< css::datatransfer::dnd::XDropTarget >();
669 
670  if( ! mpWindowImpl->mxDNDListenerContainer.is() )
671  {
672  sal_Int8 nDefaultActions = 0;
673 
674  if( mpWindowImpl->mpFrameData )
675  {
676  if( ! mpWindowImpl->mpFrameData->mxDropTarget.is() )
677  {
678  // initialization is done in GetDragSource
679  GetDragSource();
680  }
681 
682  if( mpWindowImpl->mpFrameData->mxDropTarget.is() )
683  {
684  nDefaultActions = mpWindowImpl->mpFrameData->mxDropTarget->getDefaultActions();
685 
686  if( ! mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
687  {
688  mpWindowImpl->mpFrameData->mxDropTargetListener = new DNDEventDispatcher( mpWindowImpl->mpFrameWindow );
689 
690  try
691  {
692  mpWindowImpl->mpFrameData->mxDropTarget->addDropTargetListener( mpWindowImpl->mpFrameData->mxDropTargetListener );
693 
694  // register also as drag gesture listener if directly supported by drag source
695  Reference< css::datatransfer::dnd::XDragGestureRecognizer > xDragGestureRecognizer(
696  mpWindowImpl->mpFrameData->mxDragSource, UNO_QUERY);
697 
698  if( xDragGestureRecognizer.is() )
699  {
700  xDragGestureRecognizer->addDragGestureListener(
701  Reference< css::datatransfer::dnd::XDragGestureListener > (mpWindowImpl->mpFrameData->mxDropTargetListener, UNO_QUERY));
702  }
703  else
704  mpWindowImpl->mpFrameData->mbInternalDragGestureRecognizer = true;
705 
706  }
707  catch (const RuntimeException&)
708  {
709  // release all instances
710  mpWindowImpl->mpFrameData->mxDropTarget.clear();
711  mpWindowImpl->mpFrameData->mxDragSource.clear();
712  }
713  }
714  }
715 
716  }
717 
718  mpWindowImpl->mxDNDListenerContainer = static_cast < css::datatransfer::dnd::XDropTarget * > ( new DNDListenerContainer( nDefaultActions ) );
719  }
720 
721  // this object is located in the same process, so there will be no runtime exception
722  return Reference< css::datatransfer::dnd::XDropTarget > ( mpWindowImpl->mxDNDListenerContainer, UNO_QUERY );
723 }
724 
725 Reference< css::datatransfer::dnd::XDragSource > Window::GetDragSource()
726 {
727 
728 #if HAVE_FEATURE_DESKTOP
729 
730  if( mpWindowImpl->mpFrameData )
731  {
732  if( ! mpWindowImpl->mpFrameData->mxDragSource.is() )
733  {
734  try
735  {
737  const SystemEnvData * pEnvData = GetSystemData();
738 
739  if( pEnvData )
740  {
741  Sequence< Any > aDragSourceAL( 2 ), aDropTargetAL( 2 );
742  OUString aDragSourceSN, aDropTargetSN;
743 #if defined(_WIN32)
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->hWnd) );
747  aDropTargetAL[ 0 ] <<= static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->hWnd) );
748 #elif defined MACOSX
749  /* FIXME: macOS specific dnd interface does not exist! *
750  * Using Windows based dnd as a temporary solution */
751  aDragSourceSN = "com.sun.star.datatransfer.dnd.OleDragSource";
752  aDropTargetSN = "com.sun.star.datatransfer.dnd.OleDropTarget";
753  aDragSourceAL[ 1 ] <<= static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->mpNSView) );
754  aDropTargetAL[ 0 ] <<= static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->mpNSView) );
755 #elif USING_X11
756  aDragSourceSN = "com.sun.star.datatransfer.dnd.X11DragSource";
757  aDropTargetSN = "com.sun.star.datatransfer.dnd.X11DropTarget";
758 
759  aDragSourceAL[ 0 ] <<= Application::GetDisplayConnection();
760  aDragSourceAL[ 1 ] <<= pEnvData->aShellWindow;
761  aDropTargetAL[ 0 ] <<= Application::GetDisplayConnection();
762  aDropTargetAL[ 1 ] <<= pEnvData->aShellWindow;
763 #endif
764  if( !aDragSourceSN.isEmpty() )
765  mpWindowImpl->mpFrameData->mxDragSource.set(
766  xContext->getServiceManager()->createInstanceWithArgumentsAndContext( aDragSourceSN, aDragSourceAL, xContext ),
767  UNO_QUERY );
768 
769  if( !aDropTargetSN.isEmpty() )
770  mpWindowImpl->mpFrameData->mxDropTarget.set(
771  xContext->getServiceManager()->createInstanceWithArgumentsAndContext( aDropTargetSN, aDropTargetAL, xContext ),
772  UNO_QUERY );
773  }
774  }
775 
776  // createInstance can throw any exception
777  catch (const Exception&)
778  {
779  // release all instances
780  mpWindowImpl->mpFrameData->mxDropTarget.clear();
781  mpWindowImpl->mpFrameData->mxDragSource.clear();
782  }
783  }
784 
785  return mpWindowImpl->mpFrameData->mxDragSource;
786  }
787 #endif
788  return Reference< css::datatransfer::dnd::XDragSource > ();
789 }
790 
791 Reference< css::datatransfer::dnd::XDragGestureRecognizer > Window::GetDragGestureRecognizer()
792 {
793  return Reference< css::datatransfer::dnd::XDragGestureRecognizer > ( GetDropTarget(), UNO_QUERY );
794 }
795 
796 } /* namespace vcl */
797 
798 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void EndExtTextInput()
Definition: window.cxx:2096
bool IsInputEnabled() const
Definition: window2.cxx:1121
vcl::Window * ImplGetWindow() const
if this is a proxy return the client, otherwise itself
Definition: window2.cxx:824
css::uno::Reference< css::datatransfer::dnd::XDragSource > GetDragSource()
Definition: mouse.cxx:725
void CaptureMouse()
Definition: mouse.cxx:445
Point GetPointerPosPixel()
Definition: mouse.cxx:556
void EnableChildPointerOverwrite(bool bOverwrite)
Definition: mouse.cxx:514
VclPtr< vcl::Window > mpFocusWin
Definition: svdata.hxx:250
WindowHitTest
Definition: window.hxx:402
bool ImplCallPreNotify(NotifyEvent &rEvt)
Definition: winproc.cxx:63
virtual void MouseButtonDown(const MouseEvent &rMEvt)
Definition: mouse.cxx:419
SAL_DLLPRIVATE void CompatLoseFocus()
Definition: window.cxx:3873
signed char sal_Int8
virtual WindowHitTest ImplHitTest(const Point &rFramePos)
Definition: mouse.cxx:56
void InvertTracking(const tools::Rectangle &rRect, ShowTrackFlags nFlags)
Definition: window2.cxx:160
SAL_DLLPRIVATE void ImplCallMouseMove(sal_uInt16 nMouseCode, bool bModChanged=false)
Definition: mouse.cxx:134
SAL_DLLPRIVATE Point ImplOutputToFrame(const Point &rPos)
Definition: window2.cxx:931
long Long
void EnterWait()
Definition: mouse.cxx:617
SAL_DLLPRIVATE void ImplGrabFocus(GetFocusFlags nFlags)
Definition: mouse.cxx:194
SAL_DLLPRIVATE vcl::Window * ImplGetFrameWindow() const
Definition: window2.cxx:895
SAL_DLLPRIVATE WindowImpl * ImplGetWindowImpl() const
Definition: window.hxx:527
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
Post a user event to the default window.
Definition: svapp.cxx:1025
bool mbHasFocus
Definition: window.h:156
virtual void MouseButtonUp(const MouseEvent &rMEvt)
Definition: mouse.cxx:426
bool IsRTLEnabled() const
Definition: window3.cxx:127
MouseEventModifiers
Definition: event.hxx:79
static css::uno::Reference< css::awt::XDisplayConnection > GetDisplayConnection()
Definition: svapp.cxx:1523
DialogControlFlags GetDialogControlFlags() const
Definition: window2.cxx:1051
SAL_DLLPRIVATE bool ImplIsOverlapWindow() const
Definition: window2.cxx:920
SAL_DLLPRIVATE ImplWinData * ImplGetWinData() const
Definition: window.cxx:1213
const std::map< PointerStyle, OString > gaLOKPointerMap
SAL_DLLPRIVATE void ReMirror(Point &rPoint) const
Definition: outdev.cxx:667
VclPtr< vcl::Window > GetParentWithLOKNotifier()
Find the nearest parent with LOK Notifier; can be itself if this Window has LOK notifier set...
Definition: window.cxx:3248
SAL_DLLPRIVATE void ImplStartDnd()
Definition: mouse.cxx:660
SAL_DLLPRIVATE void CompatGetFocus()
Definition: window.cxx:3865
void EndTracking(TrackingEventFlags nFlags=TrackingEventFlags::NONE)
Definition: window2.cxx:272
SAL_DLLPRIVATE void ImplGrabFocusToDocument(GetFocusFlags nFlags)
Definition: mouse.cxx:398
void ShowPointer(bool bVisible)
Definition: mouse.cxx:580
WinBits const WB_SYSTEMFLOATWIN
css::uno::Reference< css::datatransfer::dnd::XDragGestureRecognizer > GetDragGestureRecognizer()
Definition: mouse.cxx:791
static bool IsWindowFocused(const WindowImpl &rWinImpl)
Definition: mouse.cxx:180
sal_uInt16 nCode
void SetPointerPosPixel(const Point &rPos)
Definition: mouse.cxx:527
SAL_DLLPRIVATE PointerStyle ImplGetMousePointer() const
Definition: mouse.cxx:92
GetFocusFlags
Definition: window.hxx:311
PointerStyle GetPointer() const
Definition: window2.cxx:1241
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:75
GraphicsSharedPtr mpGraphics
void SetLastMousePos(const Point &rPos)
Similar to SetPointerPosPixel(), but sets the frame data's last mouse position instead.
Definition: mouse.cxx:547
VclPtr< vcl::Window > mpCaptureWin
Definition: svdata.hxx:251
virtual bool EventNotify(NotifyEvent &rNEvt)
Definition: event.cxx:104
SAL_DLLPRIVATE bool ImplIsAntiparallel() const
Definition: outdev.cxx:651
css::uno::Reference< css::datatransfer::dnd::XDropTarget > GetDropTarget()
Definition: mouse.cxx:665
virtual bool HasMirroredGraphics() const
Definition: outdev.cxx:699
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:168
SAL_DLLPRIVATE void ImplGenerateMouseMove()
Definition: mouse.cxx:156
std::unique_ptr< WindowImpl > mpWindowImpl
Definition: window.hxx:483
bool IsInModalMode() const
A window is in modal mode if one of its children or subchildren is a running modal window (a modal di...
Definition: window.cxx:3580
SAL_DLLPRIVATE vcl::Window * ImplGetParent() const
Definition: window2.cxx:854
SAL_DLLPRIVATE bool ImplTestMousePointerSet()
Definition: mouse.cxx:81
bool IsInside(const Point &rPOINT) const
SalObject * mpSysObj
Definition: window.h:225
bool IsMouseCaptured() const
Definition: mouse.cxx:475
bool mbMouseOver
Definition: window.h:116
static SAL_DLLPRIVATE void ImplCallFocusChangeActivate(vcl::Window *pNewOverlapWindow, vcl::Window *pOldOverlapWindow)
Definition: event.cxx:569
tools::Rectangle GetOutputRectPixel() const
Definition: window3.cxx:91
vcl::Window * GetParent() const
Definition: window2.cxx:1091
VclPtr< vcl::Window > mpTrackWin
Definition: svdata.hxx:256
enumrange< T >::Iterator end(enumrange< T >)
SAL_DLLPRIVATE void ImplCallDeactivateListeners(vcl::Window *)
Definition: window.cxx:3387
vcl::Window * GetWindow(GetWindowType nType) const
Definition: stacking.cxx:1035
virtual const SystemEnvData * GetSystemData() const
Definition: window.cxx:3837
bool ImplHandleMouseEvent(const VclPtr< vcl::Window > &xWindow, MouseNotifyEvent nSVEvent, bool bMouseLeave, tools::Long nX, tools::Long nY, sal_uInt64 nMsgTime, sal_uInt16 nCode, MouseEventModifiers nMode)
Definition: winproc.cxx:264
void ReleaseMouse()
Definition: mouse.cxx:463
SAL_DLLPRIVATE vcl::Window * ImplGetFirstOverlapWindow()
Definition: window2.cxx:869
void SetPointer(PointerStyle)
Definition: mouse.cxx:480
VclPtr< vcl::Window > mpExtTextInputWin
Definition: svdata.hxx:255
bool IsMouseOver() const
Definition: mouse.cxx:612
void SetMouseTransparent(bool bTransparent)
Definition: mouse.cxx:433
SAL_DLLPRIVATE bool ImplStopDnd()
Definition: mouse.cxx:646
ImplSVFrameData maFrameData
Definition: svdata.hxx:395
::OutputDevice const * GetOutDev() const
Definition: window.cxx:565
SAL_DLLPRIVATE Point ImplFrameToOutput(const Point &rPos)
Definition: window2.cxx:936
Reference< XComponentContext > getProcessComponentContext()
static sal_uInt64 GetSystemTicks()
PointerStyle
Definition: ptrstyle.hxx:25
virtual void Activate()
Definition: window.cxx:1827
Size GetOutputSizePixel() const
Definition: window3.cxx:89
SAL_DLLPRIVATE void ImplInvertFocus(const tools::Rectangle &rRect)
Definition: mouse.cxx:175
sal_IntPtr aShellWindow
Definition: sysdata.hxx:74
reference_type * get() const
Get the body.
Definition: vclptr.hxx:143
bool IsEnabled() const
Definition: window2.cxx:1116
virtual void MouseMove(const MouseEvent &rMEvt)
Definition: mouse.cxx:413
const vcl::ILibreOfficeKitNotifier * GetLOKNotifier() const
Definition: window.cxx:3238
VclPtr< vcl::Window > mpFirstFrame
Definition: svdata.hxx:240
WinBits GetStyle() const
Definition: window2.cxx:947
Point GetLastPointerPosPixel()
Definition: mouse.cxx:568
WinBits const WB_MOVEABLE
void LeaveWait()
Definition: mouse.cxx:630
SAL_DLLPRIVATE void ImplCallActivateListeners(vcl::Window *)
Definition: window.cxx:3404
IMPL_LINK_NOARG(QuickSelectionEngine_Data, SearchStringTimeout, Timer *, void)
PointerState GetPointerState()
Definition: mouse.cxx:593
ImplFrameData * mpFrameData
Definition: window.h:223
bool isDisposed() const
static SAL_DLLPRIVATE void ImplNewInputContext()
Definition: window.cxx:1730
ImplSVWinData * mpWinData
Definition: svdata.hxx:396
bool mbFakeFocusSet
Definition: window.h:312