1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_features.h>
21 #include <rtl/strbuf.hxx>
24 #include <sal/types.h>
25 #include <vcl/salgtype.hxx>
26 #include <vcl/event.hxx>
27 #include <vcl/help.hxx>
28 #include <vcl/cursor.hxx>
29 #include <vcl/svapp.hxx>
30 #include <vcl/vclevent.hxx>
31 #include <vcl/window.hxx>
32 #include <vcl/syswin.hxx>
33 #include <vcl/syschild.hxx>
34 #include <vcl/dockwin.hxx>
35 #include <vcl/wall.hxx>
36 #include <vcl/fixed.hxx>
37 #include <vcl/gradient.hxx>
38 #include <vcl/button.hxx>
39 #include <vcl/taskpanelist.hxx>
40 #include <vcl/dialog.hxx>
41 #include <vcl/unowrap.hxx>
42 #include <vcl/gdimtf.hxx>
43 #include <vcl/lazydelete.hxx>
44 #include <vcl/virdev.hxx>
45 #include <vcl/settings.hxx>
46 #include <vcl/sysdata.hxx>
47 #include <vcl/IDialogRenderable.hxx>
49 #include <vcl/uitest/uiobject.hxx>
50 #include <vcl/uitest/uitest.hxx>
52 #include <salframe.hxx>
54 #include <salinst.hxx>
61 #include <helpwin.hxx>
62 #include "dndlistenercontainer.hxx"
64 #include <com/sun/star/awt/XDisplayConnection.hpp>
65 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
66 #include <com/sun/star/datatransfer/clipboard/SystemClipboard.hpp>
67 #include <com/sun/star/rendering/CanvasFactory.hpp>
68 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
69 #include <comphelper/lok.hxx>
70 #include <comphelper/processfactory.hxx>
71 #include <unotools/configmgr.hxx>
77 #ifdef _WIN32 // see #140456#
78 #include <win/salframe.h>
82 using namespace ::com::sun::star::uno
;
83 using namespace ::com::sun::star::lang
;
84 using namespace ::com::sun::star::datatransfer::clipboard
;
85 using namespace ::com::sun::star::datatransfer::dnd
;
89 Window::Window( WindowType nType
) :
90 mpWindowImpl(new WindowImpl( nType
))
92 meOutDevType
= OUTDEV_WINDOW
;
94 // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
95 mbEnableRTL
= AllSettings::GetLayoutRTL();
98 Window::Window( vcl::Window
* pParent
, WinBits nStyle
) :
99 mpWindowImpl(new WindowImpl( WINDOW_WINDOW
))
101 meOutDevType
= OUTDEV_WINDOW
;
103 // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
104 mbEnableRTL
= AllSettings::GetLayoutRTL();
106 ImplInit( pParent
, nStyle
, nullptr );
109 #if OSL_DEBUG_LEVEL > 0
112 OString
lcl_createWindowInfo(const vcl::Window
* pWindow
)
114 // skip border windows, they do not carry information that
115 // would help with diagnosing the problem
116 const vcl::Window
* pTempWin( pWindow
);
117 while ( pTempWin
&& pTempWin
->GetType() == WINDOW_BORDERWINDOW
) {
118 pTempWin
= pTempWin
->GetWindow( GetWindowType::FirstChild
);
120 // check if pTempWin is not null, otherwise use the
126 OStringBuffer aErrorString
;
127 aErrorString
.append(' ');
128 aErrorString
.append(typeid( *pWindow
).name());
129 aErrorString
.append("(");
133 RTL_TEXTENCODING_UTF8
136 aErrorString
.append(")");
137 return aErrorString
.makeStringAndClear();
142 bool Window::IsDisposed() const
144 return !mpWindowImpl
;
147 void Window::dispose()
149 assert( mpWindowImpl
);
150 assert( !mpWindowImpl
->mbInDispose
); // should only be called from disposeOnce()
151 assert( (!mpWindowImpl
->mpParent
||
152 !mpWindowImpl
->mpParent
->IsDisposed()) &&
153 "vcl::Window child should have its parent disposed first" );
155 // remove Key and Mouse events issued by Application::PostKey/MouseEvent
156 Application::RemoveMouseAndKeyEvents( this );
158 // Dispose of the canvas implementation (which, currently, has an
159 // own wrapper window as a child to this one.
160 Reference
< css::rendering::XCanvas
> xCanvas( mpWindowImpl
->mxCanvas
);
163 Reference
< XComponent
> xCanvasComponent( xCanvas
, UNO_QUERY
);
164 if( xCanvasComponent
.is() )
165 xCanvasComponent
->dispose();
168 mpWindowImpl
->mbInDispose
= true;
170 CallEventListeners( VCLEVENT_OBJECT_DYING
);
172 // do not send child events for frames that were registered as native frames
173 if( !ImplIsAccessibleNativeFrame() && mpWindowImpl
->mbReallyVisible
)
174 if ( ImplIsAccessibleCandidate() && GetAccessibleParentWindow() )
175 GetAccessibleParentWindow()->CallEventListeners( VCLEVENT_WINDOW_CHILDDESTROYED
, this );
177 // remove associated data structures from dockingmanager
178 ImplGetDockingManager()->RemoveWindow( this );
180 // remove ownerdraw decorated windows from list in the top-most frame window
181 if( (GetStyle() & WB_OWNERDRAWDECORATION
) && mpWindowImpl
->mbFrame
)
183 ::std::vector
< VclPtr
<vcl::Window
> >& rList
= ImplGetOwnerDrawList();
184 auto p
= ::std::find( rList
.begin(), rList
.end(), VclPtr
<vcl::Window
>(this) );
185 if( p
!= rList
.end() )
189 // shutdown drag and drop
190 Reference
< XComponent
> xDnDComponent( mpWindowImpl
->mxDNDListenerContainer
, UNO_QUERY
);
192 if( xDnDComponent
.is() )
193 xDnDComponent
->dispose();
195 if( mpWindowImpl
->mbFrame
&& mpWindowImpl
->mpFrameData
)
199 // deregister drop target listener
200 if( mpWindowImpl
->mpFrameData
->mxDropTargetListener
.is() )
202 Reference
< XDragGestureRecognizer
> xDragGestureRecognizer
=
203 Reference
< XDragGestureRecognizer
> (mpWindowImpl
->mpFrameData
->mxDragSource
, UNO_QUERY
);
204 if( xDragGestureRecognizer
.is() )
206 xDragGestureRecognizer
->removeDragGestureListener(
207 Reference
< XDragGestureListener
> (mpWindowImpl
->mpFrameData
->mxDropTargetListener
, UNO_QUERY
));
210 mpWindowImpl
->mpFrameData
->mxDropTarget
->removeDropTargetListener( mpWindowImpl
->mpFrameData
->mxDropTargetListener
);
211 mpWindowImpl
->mpFrameData
->mxDropTargetListener
.clear();
214 // shutdown drag and drop for this frame window
215 Reference
< XComponent
> xComponent( mpWindowImpl
->mpFrameData
->mxDropTarget
, UNO_QUERY
);
217 // DNDEventDispatcher does not hold a reference of the DropTarget,
218 // so it's ok if it does not support XComponent
219 if( xComponent
.is() )
220 xComponent
->dispose();
222 catch (const Exception
&)
224 // can be safely ignored here.
228 UnoWrapperBase
* pWrapper
= Application::GetUnoWrapper( false );
230 pWrapper
->WindowDestroyed( this );
232 // MT: Must be called after WindowDestroyed!
233 // Otherwise, if the accessible is a VCLXWindow, it will try to destroy this window again!
234 // But accessibility implementations from applications need this dispose.
235 if ( mpWindowImpl
->mxAccessible
.is() )
237 Reference
< XComponent
> xC( mpWindowImpl
->mxAccessible
, UNO_QUERY
);
242 ImplSVData
* pSVData
= ImplGetSVData();
244 if ( pSVData
->maHelpData
.mpHelpWin
&& (pSVData
->maHelpData
.mpHelpWin
->GetParent() == this) )
245 ImplDestroyHelpWindow( true );
247 SAL_WARN_IF( pSVData
->maWinData
.mpTrackWin
.get() == this, "vcl",
248 "Window::~Window(): Window is in TrackingMode" );
249 SAL_WARN_IF(IsMouseCaptured(), "vcl",
250 "Window::~Window(): Window has the mouse captured");
252 // due to old compatibility
253 if ( pSVData
->maWinData
.mpTrackWin
== this )
255 if (IsMouseCaptured())
258 #if OSL_DEBUG_LEVEL > 0
259 if ( true ) // always perform these tests in debug builds
261 OStringBuffer aErrorStr
;
263 vcl::Window
* pTempWin
;
265 if ( mpWindowImpl
->mpFirstChild
)
267 OStringBuffer
aTempStr("Window (");
268 aTempStr
.append(lcl_createWindowInfo(this));
269 aTempStr
.append(") with live children destroyed: ");
270 pTempWin
= mpWindowImpl
->mpFirstChild
;
273 aTempStr
.append(lcl_createWindowInfo(pTempWin
));
274 pTempWin
= pTempWin
->mpWindowImpl
->mpNext
;
276 OSL_FAIL( aTempStr
.getStr() );
277 Application::Abort(OStringToOUString(aTempStr
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
)); // abort in debug builds, this must be fixed!
280 if (mpWindowImpl
->mpFrameData
!= nullptr)
282 pTempWin
= mpWindowImpl
->mpFrameData
->mpFirstOverlap
;
285 if ( ImplIsRealParentPath( pTempWin
) )
288 aErrorStr
.append(lcl_createWindowInfo(pTempWin
));
290 pTempWin
= pTempWin
->mpWindowImpl
->mpNextOverlap
;
294 OStringBuffer aTempStr
;
295 aTempStr
.append("Window (");
296 aTempStr
.append(lcl_createWindowInfo(this));
297 aTempStr
.append(") with live SystemWindows destroyed: ");
298 aTempStr
.append(aErrorStr
.toString());
299 OSL_FAIL(aTempStr
.getStr());
300 // abort in debug builds, must be fixed!
301 Application::Abort(OStringToOUString(
302 aTempStr
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
));
307 pTempWin
= pSVData
->maWinData
.mpFirstFrame
;
310 if ( ImplIsRealParentPath( pTempWin
) )
313 aErrorStr
.append(lcl_createWindowInfo(pTempWin
));
315 pTempWin
= pTempWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
319 OStringBuffer
aTempStr( "Window (" );
320 aTempStr
.append(lcl_createWindowInfo(this));
321 aTempStr
.append(") with live SystemWindows destroyed: ");
322 aTempStr
.append(aErrorStr
.toString());
323 OSL_FAIL( aTempStr
.getStr() );
324 Application::Abort(OStringToOUString(aTempStr
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
)); // abort in debug builds, this must be fixed!
327 if ( mpWindowImpl
->mpFirstOverlap
)
329 OStringBuffer
aTempStr("Window (");
330 aTempStr
.append(lcl_createWindowInfo(this));
331 aTempStr
.append(") with live SystemWindows destroyed: ");
332 pTempWin
= mpWindowImpl
->mpFirstOverlap
;
335 aTempStr
.append(lcl_createWindowInfo(pTempWin
));
336 pTempWin
= pTempWin
->mpWindowImpl
->mpNext
;
338 OSL_FAIL( aTempStr
.getStr() );
339 Application::Abort(OStringToOUString(aTempStr
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
)); // abort in debug builds, this must be fixed!
342 vcl::Window
* pMyParent
= GetParent();
343 SystemWindow
* pMySysWin
= nullptr;
347 if ( pMyParent
->IsSystemWindow() )
349 pMySysWin
= dynamic_cast<SystemWindow
*>(pMyParent
);
351 pMyParent
= pMyParent
->GetParent();
353 if ( pMySysWin
&& pMySysWin
->ImplIsInTaskPaneList( this ) )
355 OStringBuffer
aTempStr("Window (");
356 aTempStr
.append(lcl_createWindowInfo(this));
357 aTempStr
.append(") still in TaskPanelList!");
358 OSL_FAIL( aTempStr
.getStr() );
359 Application::Abort(OStringToOUString(aTempStr
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
)); // abort in debug builds, this must be fixed!
364 if( mpWindowImpl
->mbIsInTaskPaneList
)
366 vcl::Window
* pMyParent
= GetParent();
367 SystemWindow
* pMySysWin
= nullptr;
371 if ( pMyParent
->IsSystemWindow() )
373 pMySysWin
= dynamic_cast<SystemWindow
*>(pMyParent
);
375 pMyParent
= pMyParent
->GetParent();
377 if ( pMySysWin
&& pMySysWin
->ImplIsInTaskPaneList( this ) )
379 pMySysWin
->GetTaskPaneList()->RemoveWindow( this );
383 OStringBuffer
aTempStr("Window (");
384 aTempStr
.append(OUStringToOString(GetText(), RTL_TEXTENCODING_UTF8
));
385 aTempStr
.append(") not found in TaskPanelList!");
386 OSL_FAIL( aTempStr
.getStr() );
390 // remove from size-group if necessary
391 remove_from_all_size_groups();
393 // clear mnemonic labels
394 std::vector
<VclPtr
<FixedText
> > aMnemonicLabels(list_mnemonic_labels());
395 for (auto aI
= aMnemonicLabels
.begin(); aI
!= aMnemonicLabels
.end(); ++aI
)
397 remove_mnemonic_label(*aI
);
400 // hide window in order to trigger the Paint-Handling
403 // announce the window is to be destroyed
405 NotifyEvent
aNEvt( MouseNotifyEvent::DESTROY
, this );
406 CompatNotify( aNEvt
);
409 // EndExtTextInputMode
410 if ( pSVData
->maWinData
.mpExtTextInputWin
== this )
413 if ( pSVData
->maWinData
.mpExtTextInputWin
== this )
414 pSVData
->maWinData
.mpExtTextInputWin
= nullptr;
417 // check if the focus window is our child
418 bool bHasFocussedChild
= false;
419 if( pSVData
->maWinData
.mpFocusWin
&& ImplIsRealParentPath( pSVData
->maWinData
.mpFocusWin
) )
421 // #122232#, this must not happen and is an application bug ! but we try some cleanup to hopefully avoid crashes, see below
422 bHasFocussedChild
= true;
423 #if OSL_DEBUG_LEVEL > 0
424 OStringBuffer
aTempStr("Window (");
425 aTempStr
.append(OUStringToOString(GetText(),
426 RTL_TEXTENCODING_UTF8
)).
427 append(") with focussed child window destroyed ! THIS WILL LEAD TO CRASHES AND MUST BE FIXED !");
428 OSL_FAIL( aTempStr
.getStr() );
429 Application::Abort(OStringToOUString(aTempStr
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
)); // abort in debug build version, this must be fixed!
433 // if we get focus pass focus to another window
434 vcl::Window
* pOverlapWindow
= ImplGetFirstOverlapWindow();
435 if ( pSVData
->maWinData
.mpFocusWin
== this
436 || bHasFocussedChild
) // #122232#, see above, try some cleanup
438 if ( mpWindowImpl
->mbFrame
)
440 pSVData
->maWinData
.mpFocusWin
= nullptr;
441 pOverlapWindow
->mpWindowImpl
->mpLastFocusWindow
= nullptr;
445 vcl::Window
* pParent
= GetParent();
446 vcl::Window
* pBorderWindow
= mpWindowImpl
->mpBorderWindow
;
447 // when windows overlap, give focus to the parent
448 // of the next FrameWindow
451 if ( pBorderWindow
->ImplIsOverlapWindow() )
452 pParent
= pBorderWindow
->mpWindowImpl
->mpOverlapWindow
;
454 else if ( ImplIsOverlapWindow() )
455 pParent
= mpWindowImpl
->mpOverlapWindow
;
457 if ( pParent
&& pParent
->IsEnabled() && pParent
->IsInputEnabled() && ! pParent
->IsInModalMode() )
458 pParent
->GrabFocus();
460 mpWindowImpl
->mpFrameWindow
->GrabFocus();
462 // If the focus was set back to 'this' set it to nothing
463 if ( pSVData
->maWinData
.mpFocusWin
== this )
465 pSVData
->maWinData
.mpFocusWin
= nullptr;
466 pOverlapWindow
->mpWindowImpl
->mpLastFocusWindow
= nullptr;
471 if ( pOverlapWindow
!= nullptr &&
472 pOverlapWindow
->mpWindowImpl
->mpLastFocusWindow
== this )
473 pOverlapWindow
->mpWindowImpl
->mpLastFocusWindow
= nullptr;
475 // reset hint for DefModalDialogParent
476 if( pSVData
->maWinData
.mpActiveApplicationFrame
== this )
477 pSVData
->maWinData
.mpActiveApplicationFrame
= nullptr;
479 // reset hint of what was the last wheeled window
480 if( pSVData
->maWinData
.mpLastWheelWindow
== this )
481 pSVData
->maWinData
.mpLastWheelWindow
= nullptr;
483 // reset marked windows
484 if ( mpWindowImpl
->mpFrameData
!= nullptr )
486 if ( mpWindowImpl
->mpFrameData
->mpFocusWin
== this )
487 mpWindowImpl
->mpFrameData
->mpFocusWin
= nullptr;
488 if ( mpWindowImpl
->mpFrameData
->mpMouseMoveWin
== this )
489 mpWindowImpl
->mpFrameData
->mpMouseMoveWin
= nullptr;
490 if ( mpWindowImpl
->mpFrameData
->mpMouseDownWin
== this )
491 mpWindowImpl
->mpFrameData
->mpMouseDownWin
= nullptr;
494 // reset Deactivate-Window
495 if ( pSVData
->maWinData
.mpLastDeacWin
== this )
496 pSVData
->maWinData
.mpLastDeacWin
= nullptr;
498 if ( mpWindowImpl
->mpFrameData
)
500 if ( mpWindowImpl
->mpFrameData
->mnFocusId
)
501 Application::RemoveUserEvent( mpWindowImpl
->mpFrameData
->mnFocusId
);
502 mpWindowImpl
->mpFrameData
->mnFocusId
= nullptr;
503 if ( mpWindowImpl
->mpFrameData
->mnMouseMoveId
)
504 Application::RemoveUserEvent( mpWindowImpl
->mpFrameData
->mnMouseMoveId
);
505 mpWindowImpl
->mpFrameData
->mnMouseMoveId
= nullptr;
508 // release SalGraphics
509 OutputDevice
*pOutDev
= GetOutDev();
510 pOutDev
->ReleaseGraphics();
512 // remove window from the lists
513 ImplRemoveWindow( true );
515 // de-register as "top window child" at our parent, if necessary
516 if ( mpWindowImpl
->mbFrame
)
518 bool bIsTopWindow
= mpWindowImpl
->mpWinData
&& ( mpWindowImpl
->mpWinData
->mnIsTopWindow
== 1 );
519 if ( mpWindowImpl
->mpRealParent
&& bIsTopWindow
)
521 ImplWinData
* pParentWinData
= mpWindowImpl
->mpRealParent
->ImplGetWinData();
523 auto myPos
= ::std::find( pParentWinData
->maTopWindowChildren
.begin(),
524 pParentWinData
->maTopWindowChildren
.end(), VclPtr
<vcl::Window
>(this) );
525 SAL_WARN_IF( myPos
== pParentWinData
->maTopWindowChildren
.end(), "vcl", "Window::~Window: inconsistency in top window chain!" );
526 if ( myPos
!= pParentWinData
->maTopWindowChildren
.end() )
527 pParentWinData
->maTopWindowChildren
.erase( myPos
);
531 delete mpWindowImpl
->mpWinData
;
532 mpWindowImpl
->mpWinData
= nullptr;
534 // remove BorderWindow or Frame window data
535 mpWindowImpl
->mpBorderWindow
.disposeAndClear();
536 if ( mpWindowImpl
->mbFrame
)
538 if ( pSVData
->maWinData
.mpFirstFrame
== this )
539 pSVData
->maWinData
.mpFirstFrame
= mpWindowImpl
->mpFrameData
->mpNextFrame
;
542 sal_Int32 nWindows
= 0;
543 vcl::Window
* pSysWin
= pSVData
->maWinData
.mpFirstFrame
;
544 while ( pSysWin
&& pSysWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
.get() != this )
546 pSysWin
= pSysWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
552 assert (mpWindowImpl
->mpFrameData
->mpNextFrame
.get() != pSysWin
);
553 pSysWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
= mpWindowImpl
->mpFrameData
->mpNextFrame
;
555 else // if it is not in the list, we can't remove it.
556 SAL_WARN("vcl", "Window " << this << " marked as frame window, "
557 "is missing from list of " << nWindows
<< " frames");
559 if (mpWindowImpl
->mpFrame
) // otherwise exception during init
561 mpWindowImpl
->mpFrame
->SetCallback( nullptr, nullptr );
562 pSVData
->mpDefInst
->DestroyFrame( mpWindowImpl
->mpFrame
);
564 assert (mpWindowImpl
->mpFrameData
->mnFocusId
== nullptr);
565 assert (mpWindowImpl
->mpFrameData
->mnMouseMoveId
== nullptr);
567 delete mpWindowImpl
->mpFrameData
;
568 mpWindowImpl
->mpFrameData
= nullptr;
571 // should be the last statements
572 mpWindowImpl
.reset();
574 OutputDevice::dispose();
579 // FIXME: we should kill all LazyDeletor usage.
580 vcl::LazyDeletor::Undelete( this );
584 // We will eventually being removing the inheritance of OutputDevice
585 // from Window. It will be replaced with a transient relationship such
586 // that the OutputDevice is only live for the scope of the Paint method.
587 // In the meantime this can help move us towards a Window use an
588 // OutputDevice, not being one.
590 ::OutputDevice
const* Window::GetOutDev() const
595 ::OutputDevice
* Window::GetOutDev()
600 } /* namespace vcl */
602 WindowImpl::WindowImpl( WindowType nType
)
604 maZoom
= Fraction( 1, 1 );
605 maWinRegion
= vcl::Region(true);
606 maWinClipRegion
= vcl::Region(true);
607 mpWinData
= nullptr; // Extra Window Data, that we don't need for all windows
608 mpFrameData
= nullptr; // Frame Data
609 mpFrame
= nullptr; // Pointer to frame window
611 mpFrameWindow
= nullptr; // window to top level parent (same as frame window)
612 mpOverlapWindow
= nullptr; // first overlap parent
613 mpBorderWindow
= nullptr; // Border-Window
614 mpClientWindow
= nullptr; // Client-Window of a FrameWindow
615 mpParent
= nullptr; // parent (incl. BorderWindow)
616 mpRealParent
= nullptr; // real parent (excl. BorderWindow)
617 mpFirstChild
= nullptr; // first child window
618 mpLastChild
= nullptr; // last child window
619 mpFirstOverlap
= nullptr; // first overlap window (only set in overlap windows)
620 mpLastOverlap
= nullptr; // last overlap window (only set in overlap windows)
621 mpPrev
= nullptr; // prev window
622 mpNext
= nullptr; // next window
623 mpNextOverlap
= nullptr; // next overlap window of frame
624 mpLastFocusWindow
= nullptr; // window for focus restore
625 mpDlgCtrlDownWindow
= nullptr; // window for dialog control
626 mnEventListenersIteratingCount
= 0;
627 mnChildEventListenersIteratingCount
= 0;
628 mpCursor
= nullptr; // cursor
629 mpControlFont
= nullptr; // font properties
630 mpVCLXWindow
= nullptr;
631 mpAccessibleInfos
= nullptr;
632 maControlForeground
= Color( COL_TRANSPARENT
); // no foreground set
633 maControlBackground
= Color( COL_TRANSPARENT
); // no background set
634 mnLeftBorder
= 0; // left border
635 mnTopBorder
= 0; // top border
636 mnRightBorder
= 0; // right border
637 mnBottomBorder
= 0; // bottom border
638 mnWidthRequest
= -1; // width request
639 mnHeightRequest
= -1; // height request
640 mnOptimalWidthCache
= -1; // optimal width cache
641 mnOptimalHeightCache
= -1; // optimal height cache
642 mnX
= 0; // X-Position to Parent
643 mnY
= 0; // Y-Position to Parent
644 mnAbsScreenX
= 0; // absolute X-position on screen, used for RTL window positioning
645 mpChildClipRegion
= nullptr; // Child-Clip-Region when ClipChildren
646 mpPaintRegion
= nullptr; // Paint-ClipRegion
647 mnStyle
= 0; // style (init in ImplInitWindow)
648 mnPrevStyle
= 0; // prevstyle (set in SetStyle)
649 mnExtendedStyle
= 0; // extended style (init in ImplInitWindow)
650 mnPrevExtendedStyle
= 0; // prevstyle (set in SetExtendedStyle)
651 mnType
= nType
; // type
652 mnGetFocusFlags
= GetFocusFlags::NONE
; // Flags fuer GetFocus()-Aufruf
653 mnWaitCount
= 0; // Wait-Count (>1 == Warte-MousePointer)
654 mnPaintFlags
= 0; // Flags for ImplCallPaint
655 mnParentClipMode
= ParentClipMode::NONE
; // Flags for Parent-ClipChildren-Mode
656 mnActivateMode
= ActivateModeFlags::NONE
; // Will be converted in System/Overlap-Windows
657 mnDlgCtrlFlags
= DialogControlFlags::NONE
; // DialogControl-Flags
658 mnLockCount
= 0; // LockCount
659 meAlwaysInputMode
= AlwaysInputNone
; // neither AlwaysEnableInput nor AlwaysDisableInput called
660 meHalign
= VclAlign::Fill
;
661 meValign
= VclAlign::Fill
;
662 mePackType
= VclPackType::Start
;
665 mnGridLeftAttach
= -1;
666 mnGridTopAttach
= -1;
673 mbFrame
= false; // true: Window is a frame window
674 mbBorderWin
= false; // true: Window is a border window
675 mbOverlapWin
= false; // true: Window is a overlap window
676 mbSysWin
= false; // true: SystemWindow is the base class
677 mbDialog
= false; // true: Dialog is the base class
678 mbDockWin
= false; // true: DockingWindow is the base class
679 mbFloatWin
= false; // true: FloatingWindow is the base class
680 mbPushButton
= false; // true: PushButton is the base class
681 mbToolBox
= false; // true: ToolBox is the base class
682 mbMenuFloatingWindow
= false; // true: MenuFloatingWindow is the base class
683 mbToolbarFloatingWindow
= false; // true: ImplPopupFloatWin is the base class, used for subtoolbars
684 mbSplitter
= false; // true: Splitter is the base class
685 mbVisible
= false; // true: Show( true ) called
686 mbOverlapVisible
= false; // true: Hide called for visible window from ImplHideAllOverlapWindow()
687 mbDisabled
= false; // true: Enable( false ) called
688 mbInputDisabled
= false; // true: EnableInput( false ) called
689 mbNoUpdate
= false; // true: SetUpdateMode( false ) called
690 mbNoParentUpdate
= false; // true: SetParentUpdateMode( false ) called
691 mbActive
= false; // true: Window Active
692 mbReallyVisible
= false; // true: this and all parents to an overlapped window are visible
693 mbReallyShown
= false; // true: this and all parents to an overlapped window are shown
694 mbInInitShow
= false; // true: we are in InitShow
695 mbChildPtrOverwrite
= false; // true: PointerStyle overwrites Child-Pointer
696 mbNoPtrVisible
= false; // true: ShowPointer( false ) called
697 mbMouseMove
= false; // true: BaseMouseMove called
698 mbPaintFrame
= false; // true: Paint is visible, but not painted
699 mbInPaint
= false; // true: Inside PaintHdl
700 mbMouseButtonDown
= false; // true: BaseMouseButtonDown called
701 mbMouseButtonUp
= false; // true: BaseMouseButtonUp called
702 mbKeyInput
= false; // true: BaseKeyInput called
703 mbKeyUp
= false; // true: BaseKeyUp called
704 mbCommand
= false; // true: BaseCommand called
705 mbDefPos
= true; // true: Position is not Set
706 mbDefSize
= true; // true: Size is not Set
707 mbCallMove
= true; // true: Move must be called by Show
708 mbCallResize
= true; // true: Resize must be called by Show
709 mbWaitSystemResize
= true; // true: Wait for System-Resize
710 mbInitWinClipRegion
= true; // true: Calc Window Clip Region
711 mbInitChildRegion
= false; // true: InitChildClipRegion
712 mbWinRegion
= false; // true: Window Region
713 mbClipChildren
= false; // true: Child-window should be clipped
714 mbClipSiblings
= false; // true: Adjacent Child-window should be clipped
715 mbChildTransparent
= false; // true: Child-windows are allowed to switch to transparent (incl. Parent-CLIPCHILDREN)
716 mbPaintTransparent
= false; // true: Paints should be executed on the Parent
717 mbMouseTransparent
= false; // true: Window is transparent for Mouse
718 mbDlgCtrlStart
= false; // true: From here on own Dialog-Control
719 mbFocusVisible
= false; // true: Focus Visible
720 mbUseNativeFocus
= false;
721 mbNativeFocusVisible
= false; // true: native Focus Visible
722 mbInShowFocus
= false; // prevent recursion
723 mbInHideFocus
= false; // prevent recursion
724 mbTrackVisible
= false; // true: Tracking Visible
725 mbControlForeground
= false; // true: Foreground-Property set
726 mbControlBackground
= false; // true: Background-Property set
727 mbAlwaysOnTop
= false; // true: always visible for all others windows
728 mbCompoundControl
= false; // true: Composite Control => Listener...
729 mbCompoundControlHasFocus
= false; // true: Composite Control has focus somewhere
730 mbPaintDisabled
= false; // true: Paint should not be executed
731 mbAllResize
= false; // true: Also sent ResizeEvents with 0,0
732 mbInDispose
= false; // true: We're still in Window::dispose()
733 mbExtTextInput
= false; // true: ExtTextInput-Mode is active
734 mbInFocusHdl
= false; // true: Within GetFocus-Handler
735 mbCreatedWithToolkit
= false;
736 mbSuppressAccessibilityEvents
= false; // true: do not send any accessibility events
737 mbDrawSelectionBackground
= false; // true: draws transparent window background to indicate (toolbox) selection
738 mbIsInTaskPaneList
= false; // true: window was added to the taskpanelist in the topmost system window
739 mnNativeBackground
= ControlPart::NONE
; // initialize later, depends on type
740 mbCallHandlersDuringInputDisabled
= false; // true: call event handlers even if input is disabled
741 mbHelpTextDynamic
= false; // true: append help id in HELP_DEBUG case
742 mbFakeFocusSet
= false; // true: pretend as if the window has focus.
748 mbNonHomogeneous
= false;
749 static bool bDoubleBuffer
= getenv("VCL_DOUBLEBUFFERING_FORCE_ENABLE");
750 mbDoubleBufferingRequested
= bDoubleBuffer
; // when we are not sure, assume it cannot do double-buffering via RenderContext
751 mpLOKNotifier
= nullptr;
753 mbLOKParentNotifier
= false;
756 WindowImpl::~WindowImpl()
758 delete mpChildClipRegion
;
759 delete mpAccessibleInfos
;
760 delete mpControlFont
;
763 ImplWinData::ImplWinData() :
764 mpExtOldText(nullptr),
765 mpExtOldAttrAry(nullptr),
766 mpCursorRect(nullptr),
769 mpCompositionCharRects(nullptr),
770 mnCompositionCharRects(0),
771 mpFocusRect(nullptr),
772 mpTrackRect(nullptr),
773 mnTrackFlags(ShowTrackFlags::NONE
),
774 mnIsTopWindow((sal_uInt16
) ~0), // not initialized yet, 0/1 will indicate TopWindow (see IsTopWindow())
776 mbEnableNativeWidget(false)
780 ImplWinData::~ImplWinData()
783 delete mpExtOldAttrAry
;
785 delete[] mpCompositionCharRects
;
793 bool Window::AcquireGraphics() const
795 DBG_TESTSOLARMUTEX();
800 mbInitLineColor
= true;
801 mbInitFillColor
= true;
803 mbInitTextColor
= true;
804 mbInitClipRegion
= true;
806 ImplSVData
* pSVData
= ImplGetSVData();
808 mpGraphics
= mpWindowImpl
->mpFrame
->AcquireGraphics();
809 // try harder if no wingraphics was available directly
812 // find another output device in the same frame
813 OutputDevice
* pReleaseOutDev
= pSVData
->maGDIData
.mpLastWinGraphics
;
814 while ( pReleaseOutDev
)
816 if ( static_cast<vcl::Window
*>(pReleaseOutDev
)->mpWindowImpl
->mpFrame
== mpWindowImpl
->mpFrame
)
818 pReleaseOutDev
= pReleaseOutDev
->mpPrevGraphics
;
821 if ( pReleaseOutDev
)
823 // steal the wingraphics from the other outdev
824 mpGraphics
= pReleaseOutDev
->mpGraphics
;
825 pReleaseOutDev
->ReleaseGraphics( false );
829 // if needed retry after releasing least recently used wingraphics
830 while ( !mpGraphics
)
832 if ( !pSVData
->maGDIData
.mpLastWinGraphics
)
834 pSVData
->maGDIData
.mpLastWinGraphics
->ReleaseGraphics();
835 mpGraphics
= mpWindowImpl
->mpFrame
->AcquireGraphics();
840 // update global LRU list of wingraphics
843 mpNextGraphics
= pSVData
->maGDIData
.mpFirstWinGraphics
;
844 pSVData
->maGDIData
.mpFirstWinGraphics
= const_cast<vcl::Window
*>(this);
845 if ( mpNextGraphics
)
846 mpNextGraphics
->mpPrevGraphics
= const_cast<vcl::Window
*>(this);
847 if ( !pSVData
->maGDIData
.mpLastWinGraphics
)
848 pSVData
->maGDIData
.mpLastWinGraphics
= const_cast<vcl::Window
*>(this);
853 mpGraphics
->SetXORMode( (RasterOp::Invert
== meRasterOp
) || (RasterOp::Xor
== meRasterOp
) );
854 mpGraphics
->setAntiAliasB2DDraw(bool(mnAntialiasing
& AntialiasingFlags::EnableB2dDraw
));
857 return mpGraphics
!= nullptr;
860 void Window::ReleaseGraphics( bool bRelease
)
862 DBG_TESTSOLARMUTEX();
867 // release the fonts of the physically released graphics device
871 ImplSVData
* pSVData
= ImplGetSVData();
873 vcl::Window
* pWindow
= this;
876 pWindow
->mpWindowImpl
->mpFrame
->ReleaseGraphics( mpGraphics
);
877 // remove from global LRU list of window graphics
878 if ( mpPrevGraphics
)
879 mpPrevGraphics
->mpNextGraphics
= mpNextGraphics
;
881 pSVData
->maGDIData
.mpFirstWinGraphics
= mpNextGraphics
;
882 if ( mpNextGraphics
)
883 mpNextGraphics
->mpPrevGraphics
= mpPrevGraphics
;
885 pSVData
->maGDIData
.mpLastWinGraphics
= mpPrevGraphics
;
887 mpGraphics
= nullptr;
888 mpPrevGraphics
= nullptr;
889 mpNextGraphics
= nullptr;
892 static sal_Int32
CountDPIScaleFactor(sal_Int32 nDPI
)
894 sal_Int32 nResult
= 100;
897 // Setting of HiDPI is unfortunately all only a heuristic; and to add
898 // insult to an injury, the system is constantly lying to us about
899 // the DPI and whatnot
900 // eg. fdo#77059 - set the value from which we do consider the
901 // screen hi-dpi to greater than 168
902 if (nDPI
> 216) // 96 * 2 + 96 / 4
904 else if (nDPI
> 168) // 96 * 2 - 96 / 4
906 else if (nDPI
> 120) // 96 * 1.5 - 96 / 4
915 void Window::ImplInit( vcl::Window
* pParent
, WinBits nStyle
, SystemParentData
* pSystemParentData
)
917 SAL_WARN_IF( !mpWindowImpl
->mbFrame
&& !pParent
&& GetType() != WINDOW_FIXEDIMAGE
, "vcl",
918 "Window::Window(): pParent == NULL" );
920 ImplSVData
* pSVData
= ImplGetSVData();
921 vcl::Window
* pRealParent
= pParent
;
924 if ( !mpWindowImpl
->mbOverlapWin
&& pParent
&& (pParent
->GetStyle() & WB_3DLOOK
) )
927 // create border window if necessary
928 if ( !mpWindowImpl
->mbFrame
&& !mpWindowImpl
->mbBorderWin
&& !mpWindowImpl
->mpBorderWindow
929 && (nStyle
& (WB_BORDER
| WB_SYSTEMCHILDWINDOW
) ) )
931 BorderWindowStyle nBorderTypeStyle
= BorderWindowStyle::NONE
;
932 if( (nStyle
& WB_SYSTEMCHILDWINDOW
) )
934 // handle WB_SYSTEMCHILDWINDOW
935 // these should be analogous to a top level frame; meaning they
936 // should have a border window with style BorderWindowStyle::Frame
937 // which controls their size
938 nBorderTypeStyle
|= BorderWindowStyle::Frame
;
941 VclPtrInstance
<ImplBorderWindow
> pBorderWin( pParent
, nStyle
& (WB_BORDER
| WB_DIALOGCONTROL
| WB_NODIALOGCONTROL
), nBorderTypeStyle
);
942 static_cast<vcl::Window
*>(pBorderWin
)->mpWindowImpl
->mpClientWindow
= this;
943 pBorderWin
->GetBorder( mpWindowImpl
->mnLeftBorder
, mpWindowImpl
->mnTopBorder
, mpWindowImpl
->mnRightBorder
, mpWindowImpl
->mnBottomBorder
);
944 mpWindowImpl
->mpBorderWindow
= pBorderWin
;
945 pParent
= mpWindowImpl
->mpBorderWindow
;
947 else if( !mpWindowImpl
->mbFrame
&& ! pParent
)
949 mpWindowImpl
->mbOverlapWin
= true;
950 mpWindowImpl
->mbFrame
= true;
953 // insert window in list
954 ImplInsertWindow( pParent
);
955 mpWindowImpl
->mnStyle
= nStyle
;
957 if( pParent
&& ! mpWindowImpl
->mbFrame
)
958 mbEnableRTL
= AllSettings::GetLayoutRTL();
960 // test for frame creation
961 if ( mpWindowImpl
->mbFrame
)
964 SalFrameStyleFlags nFrameStyle
= SalFrameStyleFlags::NONE
;
966 if ( nStyle
& WB_MOVEABLE
)
967 nFrameStyle
|= SalFrameStyleFlags::MOVEABLE
;
968 if ( nStyle
& WB_SIZEABLE
)
969 nFrameStyle
|= SalFrameStyleFlags::SIZEABLE
;
970 if ( nStyle
& WB_CLOSEABLE
)
971 nFrameStyle
|= SalFrameStyleFlags::CLOSEABLE
;
972 if ( nStyle
& WB_APP
)
973 nFrameStyle
|= SalFrameStyleFlags::DEFAULT
;
974 // check for undecorated floating window
975 if( // 1. floating windows that are not moveable/sizeable (only closeable allowed)
976 ( !(nFrameStyle
& ~SalFrameStyleFlags::CLOSEABLE
) &&
977 ( mpWindowImpl
->mbFloatWin
|| ((GetType() == WINDOW_BORDERWINDOW
) && static_cast<ImplBorderWindow
*>(this)->mbFloatWindow
) || (nStyle
& WB_SYSTEMFLOATWIN
) ) ) ||
978 // 2. borderwindows of floaters with ownerdraw decoration
979 ( ((GetType() == WINDOW_BORDERWINDOW
) && static_cast<ImplBorderWindow
*>(this)->mbFloatWindow
&& (nStyle
& WB_OWNERDRAWDECORATION
) ) ) )
981 nFrameStyle
= SalFrameStyleFlags::FLOAT
;
982 if( nStyle
& WB_OWNERDRAWDECORATION
)
983 nFrameStyle
|= (SalFrameStyleFlags::OWNERDRAWDECORATION
| SalFrameStyleFlags::NOSHADOW
);
985 else if( mpWindowImpl
->mbFloatWin
)
986 nFrameStyle
|= SalFrameStyleFlags::TOOLWINDOW
;
988 if( nStyle
& WB_INTROWIN
)
989 nFrameStyle
|= SalFrameStyleFlags::INTRO
;
990 if( nStyle
& WB_TOOLTIPWIN
)
991 nFrameStyle
|= SalFrameStyleFlags::TOOLTIP
;
993 if( nStyle
& WB_NOSHADOW
)
994 nFrameStyle
|= SalFrameStyleFlags::NOSHADOW
;
996 if( nStyle
& WB_SYSTEMCHILDWINDOW
)
997 nFrameStyle
|= SalFrameStyleFlags::SYSTEMCHILD
;
999 switch (mpWindowImpl
->mnType
)
1002 case WINDOW_TABDIALOG
:
1003 case WINDOW_MODALDIALOG
:
1004 case WINDOW_MODELESSDIALOG
:
1005 case WINDOW_MESSBOX
:
1006 case WINDOW_INFOBOX
:
1007 case WINDOW_WARNINGBOX
:
1008 case WINDOW_ERRORBOX
:
1009 case WINDOW_QUERYBOX
:
1010 nFrameStyle
|= SalFrameStyleFlags::DIALOG
;
1016 SalFrame
* pParentFrame
= nullptr;
1018 pParentFrame
= pParent
->mpWindowImpl
->mpFrame
;
1020 if ( pSystemParentData
)
1021 pFrame
= pSVData
->mpDefInst
->CreateChildFrame( pSystemParentData
, nFrameStyle
| SalFrameStyleFlags::PLUG
);
1023 pFrame
= pSVData
->mpDefInst
->CreateFrame( pParentFrame
, nFrameStyle
);
1026 // do not abort but throw an exception, may be the current thread terminates anyway (plugin-scenario)
1027 throw RuntimeException(
1028 "Could not create system window!",
1029 Reference
< XInterface
>() );
1032 pFrame
->SetCallback( this, ImplWindowFrameProc
);
1034 // set window frame data
1035 mpWindowImpl
->mpFrameData
= new ImplFrameData
;
1036 mpWindowImpl
->mpFrame
= pFrame
;
1037 mpWindowImpl
->mpFrameWindow
= this;
1038 mpWindowImpl
->mpOverlapWindow
= this;
1041 assert (pSVData
->maWinData
.mpFirstFrame
.get() != this);
1042 mpWindowImpl
->mpFrameData
->mpNextFrame
= pSVData
->maWinData
.mpFirstFrame
;
1043 pSVData
->maWinData
.mpFirstFrame
= this;
1044 mpWindowImpl
->mpFrameData
->mpFirstOverlap
= nullptr;
1045 mpWindowImpl
->mpFrameData
->mpFocusWin
= nullptr;
1046 mpWindowImpl
->mpFrameData
->mpMouseMoveWin
= nullptr;
1047 mpWindowImpl
->mpFrameData
->mpMouseDownWin
= nullptr;
1048 mpWindowImpl
->mpFrameData
->mpFontCollection
= pSVData
->maGDIData
.mpScreenFontList
;
1049 mpWindowImpl
->mpFrameData
->mpFontCache
= pSVData
->maGDIData
.mpScreenFontCache
;
1050 mpWindowImpl
->mpFrameData
->mnFocusId
= nullptr;
1051 mpWindowImpl
->mpFrameData
->mnMouseMoveId
= nullptr;
1052 mpWindowImpl
->mpFrameData
->mnLastMouseX
= -1;
1053 mpWindowImpl
->mpFrameData
->mnLastMouseY
= -1;
1054 mpWindowImpl
->mpFrameData
->mnBeforeLastMouseX
= -1;
1055 mpWindowImpl
->mpFrameData
->mnBeforeLastMouseY
= -1;
1056 mpWindowImpl
->mpFrameData
->mnFirstMouseX
= -1;
1057 mpWindowImpl
->mpFrameData
->mnFirstMouseY
= -1;
1058 mpWindowImpl
->mpFrameData
->mnLastMouseWinX
= -1;
1059 mpWindowImpl
->mpFrameData
->mnLastMouseWinY
= -1;
1060 mpWindowImpl
->mpFrameData
->mnModalMode
= 0;
1061 mpWindowImpl
->mpFrameData
->mnMouseDownTime
= 0;
1062 mpWindowImpl
->mpFrameData
->mnClickCount
= 0;
1063 mpWindowImpl
->mpFrameData
->mnFirstMouseCode
= 0;
1064 mpWindowImpl
->mpFrameData
->mnMouseCode
= 0;
1065 mpWindowImpl
->mpFrameData
->mnMouseMode
= MouseEventModifiers::NONE
;
1066 mpWindowImpl
->mpFrameData
->meMapUnit
= MapUnit::MapPixel
;
1067 mpWindowImpl
->mpFrameData
->mbHasFocus
= false;
1068 mpWindowImpl
->mpFrameData
->mbInMouseMove
= false;
1069 mpWindowImpl
->mpFrameData
->mbMouseIn
= false;
1070 mpWindowImpl
->mpFrameData
->mbStartDragCalled
= false;
1071 mpWindowImpl
->mpFrameData
->mbNeedSysWindow
= false;
1072 mpWindowImpl
->mpFrameData
->mbMinimized
= false;
1073 mpWindowImpl
->mpFrameData
->mbStartFocusState
= false;
1074 mpWindowImpl
->mpFrameData
->mbInSysObjFocusHdl
= false;
1075 mpWindowImpl
->mpFrameData
->mbInSysObjToTopHdl
= false;
1076 mpWindowImpl
->mpFrameData
->mbSysObjFocus
= false;
1077 mpWindowImpl
->mpFrameData
->maPaintIdle
.SetPriority( SchedulerPriority::REPAINT
);
1078 mpWindowImpl
->mpFrameData
->maPaintIdle
.SetIdleHdl( LINK( this, Window
, ImplHandlePaintHdl
) );
1079 mpWindowImpl
->mpFrameData
->maPaintIdle
.SetDebugName( "vcl::Window maPaintIdle" );
1080 mpWindowImpl
->mpFrameData
->maResizeIdle
.SetPriority( SchedulerPriority::RESIZE
);
1081 mpWindowImpl
->mpFrameData
->maResizeIdle
.SetIdleHdl( LINK( this, Window
, ImplHandleResizeTimerHdl
) );
1082 mpWindowImpl
->mpFrameData
->maResizeIdle
.SetDebugName( "vcl::Window maResizeIdle" );
1083 mpWindowImpl
->mpFrameData
->mbInternalDragGestureRecognizer
= false;
1084 if (!(nStyle
& WB_DEFAULTWIN
) && mpWindowImpl
->mbDoubleBufferingRequested
)
1085 RequestDoubleBuffering(true);
1086 mpWindowImpl
->mpFrameData
->mbInBufferedPaint
= false;
1088 if ( pRealParent
&& IsTopWindow() )
1090 ImplWinData
* pParentWinData
= pRealParent
->ImplGetWinData();
1091 pParentWinData
->maTopWindowChildren
.push_back( this );
1096 mpWindowImpl
->mpRealParent
= pRealParent
;
1098 // #99318: make sure fontcache and list is available before call to SetSettings
1099 mpFontCollection
= mpWindowImpl
->mpFrameData
->mpFontCollection
;
1100 mpFontCache
= mpWindowImpl
->mpFrameData
->mpFontCache
;
1102 if ( mpWindowImpl
->mbFrame
)
1106 mpWindowImpl
->mpFrameData
->mnDPIX
= pParent
->mpWindowImpl
->mpFrameData
->mnDPIX
;
1107 mpWindowImpl
->mpFrameData
->mnDPIY
= pParent
->mpWindowImpl
->mpFrameData
->mnDPIY
;
1111 OutputDevice
*pOutDev
= GetOutDev();
1112 if ( pOutDev
->AcquireGraphics() )
1114 mpGraphics
->GetResolution( mpWindowImpl
->mpFrameData
->mnDPIX
, mpWindowImpl
->mpFrameData
->mnDPIY
);
1118 // add ownerdraw decorated frame windows to list in the top-most frame window
1119 // so they can be hidden on lose focus
1120 if( nStyle
& WB_OWNERDRAWDECORATION
)
1121 ImplGetOwnerDrawList().push_back( this );
1123 // delay settings initialization until first "real" frame
1124 // this relies on the IntroWindow not needing any system settings
1125 if ( !pSVData
->maAppData
.mbSettingsInit
&&
1126 ! (nStyle
& (WB_INTROWIN
|WB_DEFAULTWIN
))
1129 // side effect: ImplUpdateGlobalSettings does an ImplGetFrame()->UpdateSettings
1130 ImplUpdateGlobalSettings( *pSVData
->maAppData
.mpSettings
);
1131 OutputDevice::SetSettings( *pSVData
->maAppData
.mpSettings
);
1132 pSVData
->maAppData
.mbSettingsInit
= true;
1135 // If we create a Window with default size, query this
1136 // size directly, because we want resize all Controls to
1137 // the correct size before we display the window
1138 if ( nStyle
& (WB_MOVEABLE
| WB_SIZEABLE
| WB_APP
) )
1139 mpWindowImpl
->mpFrame
->GetClientSize( mnOutWidth
, mnOutHeight
);
1145 if ( !ImplIsOverlapWindow() )
1147 mpWindowImpl
->mbDisabled
= pParent
->mpWindowImpl
->mbDisabled
;
1148 mpWindowImpl
->mbInputDisabled
= pParent
->mpWindowImpl
->mbInputDisabled
;
1149 mpWindowImpl
->meAlwaysInputMode
= pParent
->mpWindowImpl
->meAlwaysInputMode
;
1152 if (!utl::ConfigManager::IsAvoidConfig())
1153 OutputDevice::SetSettings( pParent
->GetSettings() );
1158 // setup the scale factor for Hi-DPI displays
1159 mnDPIScalePercentage
= CountDPIScaleFactor(mpWindowImpl
->mpFrameData
->mnDPIY
);
1160 mnDPIX
= mpWindowImpl
->mpFrameData
->mnDPIX
;
1161 mnDPIY
= mpWindowImpl
->mpFrameData
->mnDPIY
;
1163 if (!utl::ConfigManager::IsAvoidConfig())
1165 const StyleSettings
& rStyleSettings
= mxSettings
->GetStyleSettings();
1166 maFont
= rStyleSettings
.GetAppFont();
1168 if ( nStyle
& WB_3DLOOK
)
1170 SetTextColor( rStyleSettings
.GetButtonTextColor() );
1171 SetBackground( Wallpaper( rStyleSettings
.GetFaceColor() ) );
1175 SetTextColor( rStyleSettings
.GetWindowTextColor() );
1176 SetBackground( Wallpaper( rStyleSettings
.GetWindowColor() ) );
1181 maFont
= GetDefaultFont( DefaultFontType::FIXED
, LANGUAGE_ENGLISH_US
, GetDefaultFontFlags::NONE
);
1184 ImplPointToLogic(*this, maFont
);
1186 (void)ImplUpdatePos();
1188 // calculate app font res (except for the Intro Window or the default window)
1189 if ( mpWindowImpl
->mbFrame
&& !pSVData
->maGDIData
.mnAppFontX
&& ! (nStyle
& (WB_INTROWIN
|WB_DEFAULTWIN
)) )
1190 ImplInitAppFontData( this );
1192 if ( GetAccessibleParentWindow() && GetParent() != Application::GetDefDialogParent() )
1193 GetAccessibleParentWindow()->CallEventListeners( VCLEVENT_WINDOW_CHILDCREATED
, this );
1196 void Window::ImplInitAppFontData( vcl::Window
* pWindow
)
1198 ImplSVData
* pSVData
= ImplGetSVData();
1199 long nTextHeight
= pWindow
->GetTextHeight();
1200 long nTextWidth
= pWindow
->approximate_char_width() * 8;
1201 long nSymHeight
= nTextHeight
*4;
1202 // Make the basis wider if the font is too narrow
1203 // such that the dialog looks symmetrical and does not become too narrow.
1204 // Add some extra space when the dialog has the same width,
1205 // as a little more space is better.
1206 if ( nSymHeight
> nTextWidth
)
1207 nTextWidth
= nSymHeight
;
1208 else if ( nSymHeight
+5 > nTextWidth
)
1209 nTextWidth
= nSymHeight
+5;
1210 pSVData
->maGDIData
.mnAppFontX
= nTextWidth
* 10 / 8;
1211 pSVData
->maGDIData
.mnAppFontY
= nTextHeight
* 10;
1214 // FIXME: this is currently only on OS X, check with other
1216 if( pSVData
->maNWFData
.mbNoFocusRects
)
1218 // try to find out whether there is a large correction
1219 // of control sizes, if yes, make app font scalings larger
1220 // so dialog positioning is not completely off
1221 ImplControlValue aControlValue
;
1222 Rectangle
aCtrlRegion( Point(), Size( nTextWidth
< 10 ? 10 : nTextWidth
, nTextHeight
< 10 ? 10 : nTextHeight
) );
1223 Rectangle
aBoundingRgn( aCtrlRegion
);
1224 Rectangle
aContentRgn( aCtrlRegion
);
1225 if( pWindow
->GetNativeControlRegion( ControlType::Editbox
, ControlPart::Entire
, aCtrlRegion
,
1226 ControlState::ENABLED
, aControlValue
, OUString(),
1227 aBoundingRgn
, aContentRgn
) )
1229 // comment: the magical +6 is for the extra border in bordered
1230 // (which is the standard) edit fields
1231 if( aContentRgn
.GetHeight() - nTextHeight
> (nTextHeight
+4)/4 )
1232 pSVData
->maGDIData
.mnAppFontY
= (aContentRgn
.GetHeight()-4) * 10;
1238 ImplWinData
* Window::ImplGetWinData() const
1240 if ( !mpWindowImpl
->mpWinData
)
1242 static const char* pNoNWF
= getenv( "SAL_NO_NWF" );
1244 const_cast<vcl::Window
*>(this)->mpWindowImpl
->mpWinData
= new ImplWinData
;
1245 mpWindowImpl
->mpWinData
->mbEnableNativeWidget
= !(pNoNWF
&& *pNoNWF
); // true: try to draw this control with native theme API
1248 return mpWindowImpl
->mpWinData
;
1252 void Window::CopyDeviceArea( SalTwoRect
& aPosAry
, bool bWindowInvalidate
)
1254 if (aPosAry
.mnSrcWidth
== 0 || aPosAry
.mnSrcHeight
== 0 || aPosAry
.mnDestWidth
== 0 || aPosAry
.mnDestHeight
== 0)
1257 if (bWindowInvalidate
)
1259 const Rectangle
aSrcRect(Point(aPosAry
.mnSrcX
, aPosAry
.mnSrcY
),
1260 Size(aPosAry
.mnSrcWidth
, aPosAry
.mnSrcHeight
));
1262 ImplMoveAllInvalidateRegions(aSrcRect
,
1263 aPosAry
.mnDestX
-aPosAry
.mnSrcX
,
1264 aPosAry
.mnDestY
-aPosAry
.mnSrcY
,
1267 mpGraphics
->CopyArea(aPosAry
.mnDestX
, aPosAry
.mnDestY
,
1268 aPosAry
.mnSrcX
, aPosAry
.mnSrcY
,
1269 aPosAry
.mnSrcWidth
, aPosAry
.mnSrcHeight
,
1275 OutputDevice::CopyDeviceArea(aPosAry
, bWindowInvalidate
);
1278 SalGraphics
* Window::ImplGetFrameGraphics() const
1280 if ( mpWindowImpl
->mpFrameWindow
->mpGraphics
)
1282 mpWindowImpl
->mpFrameWindow
->mbInitClipRegion
= true;
1286 OutputDevice
* pFrameWinOutDev
= mpWindowImpl
->mpFrameWindow
;
1287 if ( ! pFrameWinOutDev
->AcquireGraphics() )
1292 mpWindowImpl
->mpFrameWindow
->mpGraphics
->ResetClipRegion();
1293 return mpWindowImpl
->mpFrameWindow
->mpGraphics
;
1296 void Window::ImplSetReallyVisible()
1298 // #i43594# it is possible that INITSHOW was never send, because the visibility state changed between
1299 // ImplCallInitShow() and ImplSetReallyVisible() when called from Show()
1300 // mbReallyShown is a useful indicator
1301 if( !mpWindowImpl
->mbReallyShown
)
1304 bool bBecameReallyVisible
= !mpWindowImpl
->mbReallyVisible
;
1307 mpWindowImpl
->mbReallyVisible
= true;
1308 mpWindowImpl
->mbReallyShown
= true;
1310 // the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge.
1311 // For this, the data member of the event must not be NULL.
1312 // Previously, we did this in Window::Show, but there some events got lost in certain situations. Now
1313 // we're doing it when the visibility really changes
1314 if( bBecameReallyVisible
&& ImplIsAccessibleCandidate() )
1315 CallEventListeners( VCLEVENT_WINDOW_SHOW
, this );
1316 // TODO. It's kind of a hack that we're re-using the VCLEVENT_WINDOW_SHOW. Normally, we should
1317 // introduce another event which explicitly triggers the Accessibility implementations.
1319 vcl::Window
* pWindow
= mpWindowImpl
->mpFirstOverlap
;
1322 if ( pWindow
->mpWindowImpl
->mbVisible
)
1323 pWindow
->ImplSetReallyVisible();
1324 pWindow
= pWindow
->mpWindowImpl
->mpNext
;
1327 pWindow
= mpWindowImpl
->mpFirstChild
;
1330 if ( pWindow
->mpWindowImpl
->mbVisible
)
1331 pWindow
->ImplSetReallyVisible();
1332 pWindow
= pWindow
->mpWindowImpl
->mpNext
;
1336 void Window::ImplInitResolutionSettings()
1338 // recalculate AppFont-resolution and DPI-resolution
1339 if (mpWindowImpl
->mbFrame
)
1341 mnDPIX
= mpWindowImpl
->mpFrameData
->mnDPIX
;
1342 mnDPIY
= mpWindowImpl
->mpFrameData
->mnDPIY
;
1344 // setup the scale factor for Hi-DPI displays
1345 mnDPIScalePercentage
= CountDPIScaleFactor(mpWindowImpl
->mpFrameData
->mnDPIY
);
1346 const StyleSettings
& rStyleSettings
= mxSettings
->GetStyleSettings();
1347 SetPointFont(*this, rStyleSettings
.GetAppFont());
1349 else if ( mpWindowImpl
->mpParent
)
1351 mnDPIX
= mpWindowImpl
->mpParent
->mnDPIX
;
1352 mnDPIY
= mpWindowImpl
->mpParent
->mnDPIY
;
1353 mnDPIScalePercentage
= mpWindowImpl
->mpParent
->mnDPIScalePercentage
;
1356 // update the recalculated values for logical units
1357 // and also tools belonging to the values
1358 if (IsMapModeEnabled())
1360 MapMode aMapMode
= GetMapMode();
1362 SetMapMode( aMapMode
);
1366 void Window::ImplPointToLogic(vcl::RenderContext
& rRenderContext
, vcl::Font
& rFont
) const
1368 Size aSize
= rFont
.GetFontSize();
1372 aSize
.Width() *= mpWindowImpl
->mpFrameData
->mnDPIX
;
1373 aSize
.Width() += 72 / 2;
1374 aSize
.Width() /= 72;
1376 aSize
.Height() *= mpWindowImpl
->mpFrameData
->mnDPIY
;
1377 aSize
.Height() += 72/2;
1378 aSize
.Height() /= 72;
1380 if (rRenderContext
.IsMapModeEnabled())
1381 aSize
= rRenderContext
.PixelToLogic(aSize
);
1383 rFont
.SetFontSize(aSize
);
1386 void Window::ImplLogicToPoint(vcl::RenderContext
& rRenderContext
, vcl::Font
& rFont
) const
1388 Size aSize
= rFont
.GetFontSize();
1390 if (rRenderContext
.IsMapModeEnabled())
1391 aSize
= rRenderContext
.LogicToPixel(aSize
);
1395 aSize
.Width() *= 72;
1396 aSize
.Width() += mpWindowImpl
->mpFrameData
->mnDPIX
/ 2;
1397 aSize
.Width() /= mpWindowImpl
->mpFrameData
->mnDPIX
;
1399 aSize
.Height() *= 72;
1400 aSize
.Height() += mpWindowImpl
->mpFrameData
->mnDPIY
/ 2;
1401 aSize
.Height() /= mpWindowImpl
->mpFrameData
->mnDPIY
;
1403 rFont
.SetFontSize(aSize
);
1406 bool Window::ImplUpdatePos()
1408 bool bSysChild
= false;
1410 if ( ImplIsOverlapWindow() )
1412 mnOutOffX
= mpWindowImpl
->mnX
;
1413 mnOutOffY
= mpWindowImpl
->mnY
;
1417 vcl::Window
* pParent
= ImplGetParent();
1419 mnOutOffX
= mpWindowImpl
->mnX
+ pParent
->mnOutOffX
;
1420 mnOutOffY
= mpWindowImpl
->mnY
+ pParent
->mnOutOffY
;
1423 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
1426 if ( pChild
->ImplUpdatePos() )
1428 pChild
= pChild
->mpWindowImpl
->mpNext
;
1431 if ( mpWindowImpl
->mpSysObj
)
1437 void Window::ImplUpdateSysObjPos()
1439 if ( mpWindowImpl
->mpSysObj
)
1440 mpWindowImpl
->mpSysObj
->SetPosSize( mnOutOffX
, mnOutOffY
, mnOutWidth
, mnOutHeight
);
1442 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
1445 pChild
->ImplUpdateSysObjPos();
1446 pChild
= pChild
->mpWindowImpl
->mpNext
;
1450 void Window::ImplPosSizeWindow( long nX
, long nY
,
1451 long nWidth
, long nHeight
, PosSizeFlags nFlags
)
1453 bool bNewPos
= false;
1454 bool bNewSize
= false;
1455 bool bCopyBits
= false;
1456 long nOldOutOffX
= mnOutOffX
;
1457 long nOldOutOffY
= mnOutOffY
;
1458 long nOldOutWidth
= mnOutWidth
;
1459 long nOldOutHeight
= mnOutHeight
;
1460 vcl::Region
* pOverlapRegion
= nullptr;
1461 vcl::Region
* pOldRegion
= nullptr;
1463 if ( IsReallyVisible() )
1465 Rectangle
aOldWinRect( Point( nOldOutOffX
, nOldOutOffY
),
1466 Size( nOldOutWidth
, nOldOutHeight
) );
1467 pOldRegion
= new vcl::Region( aOldWinRect
);
1468 if ( mpWindowImpl
->mbWinRegion
)
1469 pOldRegion
->Intersect( ImplPixelToDevicePixel( mpWindowImpl
->maWinRegion
) );
1471 if ( mnOutWidth
&& mnOutHeight
&& !mpWindowImpl
->mbPaintTransparent
&&
1472 !mpWindowImpl
->mbInitWinClipRegion
&& !mpWindowImpl
->maWinClipRegion
.IsEmpty() &&
1477 bool bnXRecycled
= false; // avoid duplicate mirroring in RTL case
1478 if ( nFlags
& PosSizeFlags::Width
)
1480 if(!( nFlags
& PosSizeFlags::X
))
1482 nX
= mpWindowImpl
->mnX
;
1483 nFlags
|= PosSizeFlags::X
;
1484 bnXRecycled
= true; // we're using a mnX which was already mirrored in RTL case
1489 if ( nWidth
!= mnOutWidth
)
1491 mnOutWidth
= nWidth
;
1496 if ( nFlags
& PosSizeFlags::Height
)
1500 if ( nHeight
!= mnOutHeight
)
1502 mnOutHeight
= nHeight
;
1508 if ( nFlags
& PosSizeFlags::X
)
1511 // --- RTL --- (compare the screen coordinates)
1512 Point
aPtDev( Point( nX
+mnOutOffX
, 0 ) );
1513 OutputDevice
*pOutDev
= GetOutDev();
1514 if( pOutDev
->HasMirroredGraphics() )
1516 mpGraphics
->mirror( aPtDev
.X(), this );
1518 // #106948# always mirror our pos if our parent is not mirroring, even
1519 // if we are also not mirroring
1520 // --- RTL --- check if parent is in different coordinates
1521 if( !bnXRecycled
&& mpWindowImpl
->mpParent
&& !mpWindowImpl
->mpParent
->mpWindowImpl
->mbFrame
&& mpWindowImpl
->mpParent
->ImplIsAntiparallel() )
1523 // --- RTL --- (re-mirror at parent window)
1524 nX
= mpWindowImpl
->mpParent
->mnOutWidth
- mnOutWidth
- nX
;
1526 /* #i99166# An LTR window in RTL UI that gets sized only would be
1527 expected to not moved its upper left point
1531 if( ImplIsAntiparallel() )
1533 aPtDev
.X() = mpWindowImpl
->mnAbsScreenX
;
1534 nOrgX
= mpWindowImpl
->maPos
.X();
1538 else if( !bnXRecycled
&& mpWindowImpl
->mpParent
&& !mpWindowImpl
->mpParent
->mpWindowImpl
->mbFrame
&& mpWindowImpl
->mpParent
->ImplIsAntiparallel() )
1540 // mirrored window in LTR UI
1542 // --- RTL --- (re-mirror at parent window)
1543 nX
= mpWindowImpl
->mpParent
->mnOutWidth
- mnOutWidth
- nX
;
1547 // check maPos as well, as it could have been changed for client windows (ImplCallMove())
1548 if ( mpWindowImpl
->mnAbsScreenX
!= aPtDev
.X() || nX
!= mpWindowImpl
->mnX
|| nOrgX
!= mpWindowImpl
->maPos
.X() )
1550 if ( bCopyBits
&& !pOverlapRegion
)
1552 pOverlapRegion
= new vcl::Region();
1553 ImplCalcOverlapRegion( Rectangle( Point( mnOutOffX
, mnOutOffY
),
1554 Size( mnOutWidth
, mnOutHeight
) ),
1555 *pOverlapRegion
, false, true );
1557 mpWindowImpl
->mnX
= nX
;
1558 mpWindowImpl
->maPos
.X() = nOrgX
;
1559 mpWindowImpl
->mnAbsScreenX
= aPtDev
.X(); // --- RTL --- (store real screen pos)
1563 if ( nFlags
& PosSizeFlags::Y
)
1565 // check maPos as well, as it could have been changed for client windows (ImplCallMove())
1566 if ( nY
!= mpWindowImpl
->mnY
|| nY
!= mpWindowImpl
->maPos
.Y() )
1568 if ( bCopyBits
&& !pOverlapRegion
)
1570 pOverlapRegion
= new vcl::Region();
1571 ImplCalcOverlapRegion( Rectangle( Point( mnOutOffX
, mnOutOffY
),
1572 Size( mnOutWidth
, mnOutHeight
) ),
1573 *pOverlapRegion
, false, true );
1575 mpWindowImpl
->mnY
= nY
;
1576 mpWindowImpl
->maPos
.Y() = nY
;
1581 if ( bNewPos
|| bNewSize
)
1583 bool bUpdateSysObjPos
= false;
1585 bUpdateSysObjPos
= ImplUpdatePos();
1587 // the borderwindow always specifies the position for its client window
1588 if ( mpWindowImpl
->mpBorderWindow
)
1589 mpWindowImpl
->maPos
= mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->maPos
;
1591 if ( mpWindowImpl
->mpClientWindow
)
1593 mpWindowImpl
->mpClientWindow
->ImplPosSizeWindow( mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnLeftBorder
,
1594 mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnTopBorder
,
1595 mnOutWidth
-mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnLeftBorder
-mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnRightBorder
,
1596 mnOutHeight
-mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnTopBorder
-mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnBottomBorder
,
1597 PosSizeFlags::X
| PosSizeFlags::Y
|
1598 PosSizeFlags::Width
| PosSizeFlags::Height
);
1599 // If we have a client window, then this is the position
1600 // of the Application's floating windows
1601 mpWindowImpl
->mpClientWindow
->mpWindowImpl
->maPos
= mpWindowImpl
->maPos
;
1604 if ( mpWindowImpl
->mpClientWindow
->IsVisible() )
1606 mpWindowImpl
->mpClientWindow
->ImplCallMove();
1610 mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mbCallMove
= true;
1615 // Move()/Resize() will be called only for Show(), such that
1616 // at least one is called before Show()
1631 mpWindowImpl
->mbCallMove
= true;
1633 mpWindowImpl
->mbCallResize
= true;
1636 bool bUpdateSysObjClip
= false;
1637 if ( IsReallyVisible() )
1639 if ( bNewPos
|| bNewSize
)
1642 bUpdateSysObjClip
= !ImplSetClipFlag( true );
1645 // invalidate window content ?
1646 if ( bNewPos
|| (mnOutWidth
> nOldOutWidth
) || (mnOutHeight
> nOldOutHeight
) )
1650 bool bInvalidate
= false;
1651 bool bParentPaint
= true;
1652 if ( !ImplIsOverlapWindow() )
1653 bParentPaint
= mpWindowImpl
->mpParent
->IsPaintEnabled();
1654 if ( bCopyBits
&& bParentPaint
&& !HasPaintEvent() )
1656 Point
aPoint( mnOutOffX
, mnOutOffY
);
1657 vcl::Region
aRegion( Rectangle( aPoint
,
1658 Size( mnOutWidth
, mnOutHeight
) ) );
1659 if ( mpWindowImpl
->mbWinRegion
)
1660 aRegion
.Intersect( ImplPixelToDevicePixel( mpWindowImpl
->maWinRegion
) );
1661 ImplClipBoundaries( aRegion
, false, true );
1662 if ( !pOverlapRegion
->IsEmpty() )
1664 pOverlapRegion
->Move( mnOutOffX
-nOldOutOffX
, mnOutOffY
-nOldOutOffY
);
1665 aRegion
.Exclude( *pOverlapRegion
);
1667 if ( !aRegion
.IsEmpty() )
1669 // adapt Paint areas
1670 ImplMoveAllInvalidateRegions( Rectangle( Point( nOldOutOffX
, nOldOutOffY
),
1671 Size( nOldOutWidth
, nOldOutHeight
) ),
1672 mnOutOffX
-nOldOutOffX
, mnOutOffY
-nOldOutOffY
,
1674 SalGraphics
* pGraphics
= ImplGetFrameGraphics();
1678 OutputDevice
*pOutDev
= GetOutDev();
1679 const bool bSelectClipRegion
= pOutDev
->SelectClipRegion( aRegion
, pGraphics
);
1680 if ( bSelectClipRegion
)
1682 pGraphics
->CopyArea( mnOutOffX
, mnOutOffY
,
1683 nOldOutOffX
, nOldOutOffY
,
1684 nOldOutWidth
, nOldOutHeight
,
1694 if ( !pOverlapRegion
->IsEmpty() )
1695 ImplInvalidateFrameRegion( pOverlapRegion
, InvalidateFlags::Children
);
1704 ImplInvalidateFrameRegion( nullptr, InvalidateFlags::Children
);
1708 Point
aPoint( mnOutOffX
, mnOutOffY
);
1709 vcl::Region
aRegion( Rectangle( aPoint
,
1710 Size( mnOutWidth
, mnOutHeight
) ) );
1711 aRegion
.Exclude( *pOldRegion
);
1712 if ( mpWindowImpl
->mbWinRegion
)
1713 aRegion
.Intersect( ImplPixelToDevicePixel( mpWindowImpl
->maWinRegion
) );
1714 ImplClipBoundaries( aRegion
, false, true );
1715 if ( !aRegion
.IsEmpty() )
1716 ImplInvalidateFrameRegion( &aRegion
, InvalidateFlags::Children
);
1720 // invalidate Parent or Overlaps
1722 (mnOutWidth
< nOldOutWidth
) || (mnOutHeight
< nOldOutHeight
) )
1724 vcl::Region
aRegion( *pOldRegion
);
1725 if ( !mpWindowImpl
->mbPaintTransparent
)
1726 ImplExcludeWindowRegion( aRegion
);
1727 ImplClipBoundaries( aRegion
, false, true );
1728 if ( !aRegion
.IsEmpty() && !mpWindowImpl
->mpBorderWindow
)
1729 ImplInvalidateParentFrameRegion( aRegion
);
1733 // adapt system objects
1734 if ( bUpdateSysObjClip
)
1735 ImplUpdateSysObjClip();
1736 if ( bUpdateSysObjPos
)
1737 ImplUpdateSysObjPos();
1738 if ( bNewSize
&& mpWindowImpl
->mpSysObj
)
1739 mpWindowImpl
->mpSysObj
->SetPosSize( mnOutOffX
, mnOutOffY
, mnOutWidth
, mnOutHeight
);
1742 delete pOverlapRegion
;
1746 void Window::ImplNewInputContext()
1748 ImplSVData
* pSVData
= ImplGetSVData();
1749 vcl::Window
* pFocusWin
= pSVData
->maWinData
.mpFocusWin
;
1753 // Is InputContext changed?
1754 const InputContext
& rInputContext
= pFocusWin
->GetInputContext();
1755 if ( rInputContext
== pFocusWin
->mpWindowImpl
->mpFrameData
->maOldInputContext
)
1758 pFocusWin
->mpWindowImpl
->mpFrameData
->maOldInputContext
= rInputContext
;
1760 SalInputContext aNewContext
;
1761 const vcl::Font
& rFont
= rInputContext
.GetFont();
1762 const OUString
& rFontName
= rFont
.GetFamilyName();
1763 LogicalFontInstance
* pFontInstance
= nullptr;
1764 aNewContext
.mpFont
= nullptr;
1765 if (!rFontName
.isEmpty())
1767 OutputDevice
*pFocusWinOutDev
= pFocusWin
->GetOutDev();
1768 Size aSize
= pFocusWinOutDev
->ImplLogicToDevicePixel( rFont
.GetFontSize() );
1769 if ( !aSize
.Height() )
1771 // only set default sizes if the font height in logical
1772 // coordinates equals 0
1773 if ( rFont
.GetFontSize().Height() )
1776 aSize
.Height() = (12*pFocusWin
->mnDPIY
)/72;
1778 pFontInstance
= pFocusWin
->mpFontCache
->GetFontInstance( pFocusWin
->mpFontCollection
,
1779 rFont
, aSize
, static_cast<float>(aSize
.Height()) );
1780 if ( pFontInstance
)
1781 aNewContext
.mpFont
= &pFontInstance
->maFontSelData
;
1783 aNewContext
.meLanguage
= rFont
.GetLanguage();
1784 aNewContext
.mnOptions
= rInputContext
.GetOptions();
1785 pFocusWin
->ImplGetFrame()->SetInputContext( &aNewContext
);
1787 if ( pFontInstance
)
1788 pFocusWin
->mpFontCache
->Release( pFontInstance
);
1791 void Window::doLazyDelete()
1793 SystemWindow
* pSysWin
= dynamic_cast<SystemWindow
*>(this);
1794 DockingWindow
* pDockWin
= dynamic_cast<DockingWindow
*>(this);
1795 if( pSysWin
|| ( pDockWin
&& pDockWin
->IsFloatingMode() ) )
1798 SetParent( ImplGetDefaultWindow() );
1800 vcl::LazyDeletor::Delete( this );
1803 KeyIndicatorState
Window::GetIndicatorState() const
1805 return mpWindowImpl
->mpFrame
->GetIndicatorState();
1808 void Window::SimulateKeyPress( sal_uInt16 nKeyCode
) const
1810 mpWindowImpl
->mpFrame
->SimulateKeyPress(nKeyCode
);
1813 void Window::KeyInput( const KeyEvent
& rKEvt
)
1815 KeyCode cod
= rKEvt
.GetKeyCode ();
1816 bool accel
= ImplGetSVData()->maNWFData
.mbEnableAccel
;
1817 bool autoacc
= ImplGetSVData()->maNWFData
.mbAutoAccel
;
1819 // do not respond to accelerators unless Alt is held */
1820 if (cod
.GetCode () >= 0x200 && cod
.GetCode () <= 0x219)
1823 if (autoacc
&& cod
.GetModifier () != KEY_MOD2
) return;
1826 NotifyEvent
aNEvt( MouseNotifyEvent::KEYINPUT
, this, &rKEvt
);
1827 if ( !CompatNotify( aNEvt
) )
1828 mpWindowImpl
->mbKeyInput
= true;
1831 void Window::KeyUp( const KeyEvent
& rKEvt
)
1833 NotifyEvent
aNEvt( MouseNotifyEvent::KEYUP
, this, &rKEvt
);
1834 if ( !CompatNotify( aNEvt
) )
1835 mpWindowImpl
->mbKeyUp
= true;
1838 void Window::Draw( OutputDevice
*, const Point
&, const Size
&, DrawFlags
)
1842 void Window::Move() {}
1844 void Window::Resize() {}
1846 void Window::Activate() {}
1848 void Window::Deactivate() {}
1850 void Window::GetFocus()
1852 if ( HasFocus() && mpWindowImpl
->mpLastFocusWindow
&& !(mpWindowImpl
->mnDlgCtrlFlags
& DialogControlFlags::WantFocus
) )
1854 VclPtr
<vcl::Window
> xWindow(this);
1855 mpWindowImpl
->mpLastFocusWindow
->GrabFocus();
1856 if( xWindow
->IsDisposed() )
1860 NotifyEvent
aNEvt( MouseNotifyEvent::GETFOCUS
, this );
1861 CompatNotify( aNEvt
);
1864 void Window::LoseFocus()
1866 NotifyEvent
aNEvt( MouseNotifyEvent::LOSEFOCUS
, this );
1867 CompatNotify( aNEvt
);
1870 void Window::RequestHelp( const HelpEvent
& rHEvt
)
1872 // if Balloon-Help is requested, show the balloon
1873 // with help text set
1874 if ( rHEvt
.GetMode() & HelpEventMode::BALLOON
)
1876 OUString rStr
= GetHelpText();
1877 if ( rStr
.isEmpty() )
1878 rStr
= GetQuickHelpText();
1879 if ( rStr
.isEmpty() && ImplGetParent() && !ImplIsOverlapWindow() )
1880 ImplGetParent()->RequestHelp( rHEvt
);
1883 Point aPos
= GetPosPixel();
1884 if ( ImplGetParent() && !ImplIsOverlapWindow() )
1885 aPos
= ImplGetParent()->OutputToScreenPixel( aPos
);
1886 Rectangle
aRect( aPos
, GetSizePixel() );
1888 Help::ShowBalloon( this, rHEvt
.GetMousePosPixel(), aRect
, rStr
);
1891 else if ( rHEvt
.GetMode() & HelpEventMode::QUICK
)
1893 const OUString
& rStr
= GetQuickHelpText();
1894 if ( rStr
.isEmpty() && ImplGetParent() && !ImplIsOverlapWindow() )
1895 ImplGetParent()->RequestHelp( rHEvt
);
1898 Point aPos
= GetPosPixel();
1899 if ( ImplGetParent() && !ImplIsOverlapWindow() )
1900 aPos
= ImplGetParent()->OutputToScreenPixel( aPos
);
1901 Rectangle
aRect( aPos
, GetSizePixel() );
1903 if ( !rStr
.isEmpty() )
1904 aHelpText
= GetHelpText();
1905 Help::ShowQuickHelp( this, aRect
, rStr
, aHelpText
, QuickHelpFlags::CtrlText
);
1910 OUString
aStrHelpId( OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8
) );
1911 if ( aStrHelpId
.isEmpty() && ImplGetParent() )
1912 ImplGetParent()->RequestHelp( rHEvt
);
1915 Help
* pHelp
= Application::GetHelp();
1918 if( !aStrHelpId
.isEmpty() )
1919 pHelp
->Start( aStrHelpId
, this );
1921 pHelp
->Start( OOO_HELP_INDEX
, this );
1927 void Window::Command( const CommandEvent
& rCEvt
)
1929 CallEventListeners( VCLEVENT_WINDOW_COMMAND
, const_cast<CommandEvent
*>(&rCEvt
) );
1931 NotifyEvent
aNEvt( MouseNotifyEvent::COMMAND
, this, &rCEvt
);
1932 if ( !CompatNotify( aNEvt
) )
1933 mpWindowImpl
->mbCommand
= true;
1936 void Window::Tracking( const TrackingEvent
& rTEvt
)
1939 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( this );
1941 pWrapper
->Tracking( rTEvt
);
1944 void Window::StateChanged(StateChangedType eType
)
1948 //stuff that doesn't invalidate the layout
1949 case StateChangedType::ControlForeground
:
1950 case StateChangedType::ControlBackground
:
1951 case StateChangedType::Transparent
:
1952 case StateChangedType::UpdateMode
:
1953 case StateChangedType::ReadOnly
:
1954 case StateChangedType::Enable
:
1955 case StateChangedType::State
:
1956 case StateChangedType::Data
:
1957 case StateChangedType::InitShow
:
1958 case StateChangedType::ControlFocus
:
1960 //stuff that does invalidate the layout
1962 queue_resize(eType
);
1967 bool Window::IsLocked() const
1969 if ( mpWindowImpl
->mnLockCount
!= 0 )
1972 VclPtr
<vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
1975 if ( pChild
->IsLocked() )
1977 pChild
= pChild
->mpWindowImpl
->mpNext
;
1983 void Window::SetStyle( WinBits nStyle
)
1985 if ( mpWindowImpl
&& mpWindowImpl
->mnStyle
!= nStyle
)
1987 mpWindowImpl
->mnPrevStyle
= mpWindowImpl
->mnStyle
;
1988 mpWindowImpl
->mnStyle
= nStyle
;
1989 CompatStateChanged( StateChangedType::Style
);
1993 void Window::SetExtendedStyle( WinBits nExtendedStyle
)
1996 if ( mpWindowImpl
->mnExtendedStyle
!= nExtendedStyle
)
1998 vcl::Window
* pWindow
= ImplGetBorderWindow();
2001 if( pWindow
->mpWindowImpl
->mbFrame
)
2003 SalExtStyle nExt
= 0;
2004 if( (nExtendedStyle
& WB_EXT_DOCUMENT
) )
2005 nExt
|= SAL_FRAME_EXT_STYLE_DOCUMENT
;
2006 if( (nExtendedStyle
& WB_EXT_DOCMODIFIED
) )
2007 nExt
|= SAL_FRAME_EXT_STYLE_DOCMODIFIED
;
2009 pWindow
->ImplGetFrame()->SetExtendedFrameStyle( nExt
);
2011 mpWindowImpl
->mnPrevExtendedStyle
= mpWindowImpl
->mnExtendedStyle
;
2012 mpWindowImpl
->mnExtendedStyle
= nExtendedStyle
;
2013 CompatStateChanged( StateChangedType::ExtendedStyle
);
2017 void Window::SetBorderStyle( WindowBorderStyle nBorderStyle
)
2020 if ( mpWindowImpl
->mpBorderWindow
)
2022 if( nBorderStyle
== WindowBorderStyle::REMOVEBORDER
&&
2023 ! mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbFrame
&&
2024 mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mpParent
2027 // this is a little awkward: some controls (e.g. svtools ProgressBar)
2028 // cannot avoid getting constructed with WB_BORDER but want to disable
2029 // borders in case of NWF drawing. So they need a method to remove their border window
2030 VclPtr
<vcl::Window
> pBorderWin
= mpWindowImpl
->mpBorderWindow
;
2031 // remove us as border window's client
2032 pBorderWin
->mpWindowImpl
->mpClientWindow
= nullptr;
2033 mpWindowImpl
->mpBorderWindow
= nullptr;
2034 mpWindowImpl
->mpRealParent
= pBorderWin
->mpWindowImpl
->mpParent
;
2035 // reparent us above the border window
2036 SetParent( pBorderWin
->mpWindowImpl
->mpParent
);
2037 // set us to the position and size of our previous border
2038 Point
aBorderPos( pBorderWin
->GetPosPixel() );
2039 Size
aBorderSize( pBorderWin
->GetSizePixel() );
2040 setPosSizePixel( aBorderPos
.X(), aBorderPos
.Y(), aBorderSize
.Width(), aBorderSize
.Height() );
2041 // release border window
2042 pBorderWin
.disposeAndClear();
2044 // set new style bits
2045 SetStyle( GetStyle() & (~WB_BORDER
) );
2049 if ( mpWindowImpl
->mpBorderWindow
->GetType() == WINDOW_BORDERWINDOW
)
2050 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetBorderStyle( nBorderStyle
);
2052 mpWindowImpl
->mpBorderWindow
->SetBorderStyle( nBorderStyle
);
2057 WindowBorderStyle
Window::GetBorderStyle() const
2060 if ( mpWindowImpl
->mpBorderWindow
)
2062 if ( mpWindowImpl
->mpBorderWindow
->GetType() == WINDOW_BORDERWINDOW
)
2063 return static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->GetBorderStyle();
2065 return mpWindowImpl
->mpBorderWindow
->GetBorderStyle();
2068 return WindowBorderStyle::NONE
;
2071 long Window::CalcTitleWidth() const
2074 if ( mpWindowImpl
->mpBorderWindow
)
2076 if ( mpWindowImpl
->mpBorderWindow
->GetType() == WINDOW_BORDERWINDOW
)
2077 return static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->CalcTitleWidth();
2079 return mpWindowImpl
->mpBorderWindow
->CalcTitleWidth();
2081 else if ( mpWindowImpl
->mbFrame
&& (mpWindowImpl
->mnStyle
& WB_MOVEABLE
) )
2083 // we guess the width for frame windows as we do not know the
2084 // border of external dialogs
2085 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
2086 vcl::Font aFont
= GetFont();
2087 const_cast<vcl::Window
*>(this)->SetPointFont(*const_cast<Window
*>(this), rStyleSettings
.GetTitleFont());
2088 long nTitleWidth
= GetTextWidth( GetText() );
2089 const_cast<vcl::Window
*>(this)->SetFont( aFont
);
2090 nTitleWidth
+= rStyleSettings
.GetTitleHeight() * 3;
2091 nTitleWidth
+= rStyleSettings
.GetBorderSize() * 2;
2099 void Window::SetInputContext( const InputContext
& rInputContext
)
2102 mpWindowImpl
->maInputContext
= rInputContext
;
2103 if ( !mpWindowImpl
->mbInFocusHdl
&& HasFocus() )
2104 ImplNewInputContext();
2107 void Window::PostExtTextInputEvent(int nType
, const OUString
& rText
)
2111 case VCLEVENT_WINDOW_EXTTEXTINPUT
:
2113 std::unique_ptr
<ExtTextInputAttr
[]> pAttr(new ExtTextInputAttr
[rText
.getLength()]);
2114 for (int i
= 0; i
< rText
.getLength(); ++i
) {
2115 pAttr
[i
] = ExtTextInputAttr::Underline
;
2117 SalExtTextInputEvent aEvent
{ rText
, pAttr
.get(), rText
.getLength(), EXTTEXTINPUT_CURSOR_OVERWRITE
};
2118 ImplWindowFrameProc(this, SalEvent::ExtTextInput
, &aEvent
);
2119 SalExtTextInputPosEvent evt
;
2120 ImplWindowFrameProc(this, SalEvent::ExtTextInputPos
, &evt
);
2123 case VCLEVENT_WINDOW_ENDEXTTEXTINPUT
:
2124 ImplWindowFrameProc(this, SalEvent::EndExtTextInput
, nullptr);
2131 void Window::EndExtTextInput()
2133 if ( mpWindowImpl
->mbExtTextInput
)
2134 ImplGetFrame()->EndExtTextInput( EndExtTextInputFlags::Complete
);
2137 void Window::SetCursorRect( const Rectangle
* pRect
, long nExtTextInputWidth
)
2140 ImplWinData
* pWinData
= ImplGetWinData();
2141 if ( pWinData
->mpCursorRect
)
2144 *pWinData
->mpCursorRect
= *pRect
;
2147 delete pWinData
->mpCursorRect
;
2148 pWinData
->mpCursorRect
= nullptr;
2154 pWinData
->mpCursorRect
= new Rectangle( *pRect
);
2157 pWinData
->mnCursorExtWidth
= nExtTextInputWidth
;
2161 const Rectangle
* Window::GetCursorRect() const
2164 ImplWinData
* pWinData
= ImplGetWinData();
2165 return pWinData
->mpCursorRect
;
2168 long Window::GetCursorExtTextInputWidth() const
2171 ImplWinData
* pWinData
= ImplGetWinData();
2172 return pWinData
->mnCursorExtWidth
;
2175 void Window::SetCompositionCharRect( const Rectangle
* pRect
, long nCompositionLength
, bool bVertical
) {
2177 ImplWinData
* pWinData
= ImplGetWinData();
2178 delete[] pWinData
->mpCompositionCharRects
;
2179 pWinData
->mbVertical
= bVertical
;
2180 pWinData
->mpCompositionCharRects
= nullptr;
2181 pWinData
->mnCompositionCharRects
= nCompositionLength
;
2182 if ( pRect
&& (nCompositionLength
> 0) )
2184 pWinData
->mpCompositionCharRects
= new Rectangle
[nCompositionLength
];
2185 for (long i
= 0; i
< nCompositionLength
; ++i
)
2186 pWinData
->mpCompositionCharRects
[i
] = pRect
[i
];
2190 void Window::CollectChildren(::std::vector
<vcl::Window
*>& rAllChildren
)
2192 rAllChildren
.push_back( this );
2194 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2197 pChild
->CollectChildren( rAllChildren
);
2198 pChild
= pChild
->mpWindowImpl
->mpNext
;
2202 void Window::SetPointFont(vcl::RenderContext
& rRenderContext
, const vcl::Font
& rFont
)
2204 vcl::Font aFont
= rFont
;
2205 ImplPointToLogic(rRenderContext
, aFont
);
2206 rRenderContext
.SetFont(aFont
);
2209 vcl::Font
Window::GetPointFont(vcl::RenderContext
& rRenderContext
) const
2211 vcl::Font aFont
= rRenderContext
.GetFont();
2212 ImplLogicToPoint(rRenderContext
, aFont
);
2216 void Window::Show(bool bVisible
, ShowFlags nFlags
)
2218 if ( IsDisposed() || mpWindowImpl
->mbVisible
== bVisible
)
2221 VclPtr
<vcl::Window
> xWindow(this);
2223 bool bRealVisibilityChanged
= false;
2224 mpWindowImpl
->mbVisible
= bVisible
;
2228 ImplHideAllOverlaps();
2229 if( xWindow
->IsDisposed() )
2232 if ( mpWindowImpl
->mpBorderWindow
)
2234 bool bOldUpdate
= mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbNoParentUpdate
;
2235 if ( mpWindowImpl
->mbNoParentUpdate
)
2236 mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbNoParentUpdate
= true;
2237 mpWindowImpl
->mpBorderWindow
->Show( false, nFlags
);
2238 mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbNoParentUpdate
= bOldUpdate
;
2240 else if ( mpWindowImpl
->mbFrame
)
2242 mpWindowImpl
->mbSuppressAccessibilityEvents
= true;
2243 mpWindowImpl
->mpFrame
->Show( false );
2246 CompatStateChanged( StateChangedType::Visible
);
2248 if ( mpWindowImpl
->mbReallyVisible
)
2250 if ( mpWindowImpl
->mbInitWinClipRegion
)
2251 ImplInitWinClipRegion();
2253 vcl::Region aInvRegion
= mpWindowImpl
->maWinClipRegion
;
2255 if( xWindow
->IsDisposed() )
2258 bRealVisibilityChanged
= mpWindowImpl
->mbReallyVisible
;
2259 ImplResetReallyVisible();
2262 if ( ImplIsOverlapWindow() && !mpWindowImpl
->mbFrame
)
2265 if ( !(nFlags
& ShowFlags::NoFocusChange
) && HasChildPathFocus() )
2267 if ( mpWindowImpl
->mpOverlapWindow
->IsEnabled() &&
2268 mpWindowImpl
->mpOverlapWindow
->IsInputEnabled() &&
2269 ! mpWindowImpl
->mpOverlapWindow
->IsInModalMode()
2271 mpWindowImpl
->mpOverlapWindow
->GrabFocus();
2275 if ( !mpWindowImpl
->mbFrame
)
2277 if( mpWindowImpl
->mpWinData
&& mpWindowImpl
->mpWinData
->mbEnableNativeWidget
)
2280 * #i48371# native theming: some themes draw outside the control
2281 * area we tell them to (bad thing, but we cannot do much about it ).
2282 * On hiding these controls they get invalidated with their window rectangle
2283 * which leads to the parts outside the control area being left and not
2284 * invalidated. Workaround: invalidate an area on the parent, too
2286 const int workaround_border
= 5;
2287 Rectangle
aBounds( aInvRegion
.GetBoundRect() );
2288 aBounds
.Left() -= workaround_border
;
2289 aBounds
.Top() -= workaround_border
;
2290 aBounds
.Right() += workaround_border
;
2291 aBounds
.Bottom() += workaround_border
;
2292 aInvRegion
= aBounds
;
2294 if ( !mpWindowImpl
->mbNoParentUpdate
&& !(nFlags
& ShowFlags::NoParentUpdate
) )
2296 if ( !aInvRegion
.IsEmpty() )
2297 ImplInvalidateParentFrameRegion( aInvRegion
);
2299 ImplGenerateMouseMove();
2305 // inherit native widget flag for form controls
2306 // required here, because frames never show up in the child hierarchy - which should be fixed....
2307 // eg, the drop down of a combobox which is a system floating window
2308 if( mpWindowImpl
->mbFrame
&& GetParent() && GetParent()->IsCompoundControl() &&
2309 GetParent()->IsNativeWidgetEnabled() != IsNativeWidgetEnabled() )
2311 EnableNativeWidget( GetParent()->IsNativeWidgetEnabled() );
2314 if ( mpWindowImpl
->mbCallMove
)
2318 if ( mpWindowImpl
->mbCallResize
)
2323 CompatStateChanged( StateChangedType::Visible
);
2325 vcl::Window
* pTestParent
;
2326 if ( ImplIsOverlapWindow() )
2327 pTestParent
= mpWindowImpl
->mpOverlapWindow
;
2329 pTestParent
= ImplGetParent();
2330 if ( mpWindowImpl
->mbFrame
|| pTestParent
->mpWindowImpl
->mbReallyVisible
)
2332 // if a window becomes visible, send all child windows a StateChange,
2333 // such that these can initialise themselves
2336 // If it is a SystemWindow it automatically pops up on top of
2337 // all other windows if needed.
2338 if ( ImplIsOverlapWindow() && !(nFlags
& ShowFlags::NoActivate
) )
2340 ImplStartToTop(( nFlags
& ShowFlags::ForegroundTask
) ? ToTopFlags::ForegroundTask
: ToTopFlags::NONE
);
2341 ImplFocusToTop( ToTopFlags::NONE
, false );
2344 // adjust mpWindowImpl->mbReallyVisible
2345 bRealVisibilityChanged
= !mpWindowImpl
->mbReallyVisible
;
2346 ImplSetReallyVisible();
2348 // assure clip rectangles will be recalculated
2351 if ( !mpWindowImpl
->mbFrame
)
2353 InvalidateFlags nInvalidateFlags
= InvalidateFlags::Children
;
2354 if( ! IsPaintTransparent() )
2355 nInvalidateFlags
|= InvalidateFlags::NoTransparent
;
2356 ImplInvalidate( nullptr, nInvalidateFlags
);
2357 ImplGenerateMouseMove();
2361 if ( mpWindowImpl
->mpBorderWindow
)
2362 mpWindowImpl
->mpBorderWindow
->Show( true, nFlags
);
2363 else if ( mpWindowImpl
->mbFrame
)
2365 // #106431#, hide SplashScreen
2366 ImplSVData
* pSVData
= ImplGetSVData();
2367 if ( !pSVData
->mpIntroWindow
)
2369 // The right way would be just to call this (not even in the 'if')
2370 GetpApp()->InitFinished();
2372 else if ( !ImplIsWindowOrChild( pSVData
->mpIntroWindow
) )
2374 // ... but the VCL splash is broken, and it needs this
2375 // (for ./soffice .uno:NewDoc)
2376 pSVData
->mpIntroWindow
->Hide();
2379 //SAL_WARN_IF( mpWindowImpl->mbSuppressAccessibilityEvents, "vcl", "Window::Show() - Frame reactivated");
2380 mpWindowImpl
->mbSuppressAccessibilityEvents
= false;
2382 mpWindowImpl
->mbPaintFrame
= true;
2383 if (!Application::GetSettings().GetMiscSettings().GetPseudoHeadless())
2385 bool bNoActivate(nFlags
& (ShowFlags::NoActivate
|ShowFlags::NoFocusChange
));
2386 mpWindowImpl
->mpFrame
->Show( true, bNoActivate
);
2388 if( xWindow
->IsDisposed() )
2391 // Query the correct size of the window, if we are waiting for
2393 if ( mpWindowImpl
->mbWaitSystemResize
)
2397 mpWindowImpl
->mpFrame
->GetClientSize( nOutWidth
, nOutHeight
);
2398 ImplHandleResize( this, nOutWidth
, nOutHeight
);
2401 if (mpWindowImpl
->mpFrameData
->mpBuffer
&& mpWindowImpl
->mpFrameData
->mpBuffer
->GetOutputSizePixel() != GetOutputSizePixel())
2402 // Make sure that the buffer size matches the window size, even if no resize was needed.
2403 mpWindowImpl
->mpFrameData
->mpBuffer
->SetOutputSizePixel(GetOutputSizePixel());
2406 if( xWindow
->IsDisposed() )
2409 ImplShowAllOverlaps();
2412 if( xWindow
->IsDisposed() )
2415 // the SHOW/HIDE events also serve as indicators to send child creation/destroy events to the access bridge
2416 // However, the access bridge only uses this event if the data member is not NULL (it's kind of a hack that
2417 // we re-use the SHOW/HIDE events this way, with this particular semantics).
2418 // Since #104887#, the notifications for the access bridge are done in Impl(Set|Reset)ReallyVisible. Here, we
2419 // now only notify with a NULL data pointer, for all other clients except the access bridge.
2420 if ( !bRealVisibilityChanged
)
2421 CallEventListeners( mpWindowImpl
->mbVisible
? VCLEVENT_WINDOW_SHOW
: VCLEVENT_WINDOW_HIDE
);
2422 if( xWindow
->IsDisposed() )
2427 Size
Window::GetSizePixel() const
2431 SAL_WARN("vcl.layout", "WTF no windowimpl");
2435 // #i43257# trigger pending resize handler to assure correct window sizes
2436 if( mpWindowImpl
->mpFrameData
->maResizeIdle
.IsActive() )
2438 VclPtr
<vcl::Window
> xWindow( const_cast<Window
*>(this) );
2439 mpWindowImpl
->mpFrameData
->maResizeIdle
.Stop();
2440 mpWindowImpl
->mpFrameData
->maResizeIdle
.GetIdleHdl().Call( nullptr );
2441 if( xWindow
->IsDisposed() )
2445 return Size( mnOutWidth
+mpWindowImpl
->mnLeftBorder
+mpWindowImpl
->mnRightBorder
,
2446 mnOutHeight
+mpWindowImpl
->mnTopBorder
+mpWindowImpl
->mnBottomBorder
);
2449 void Window::GetBorder( sal_Int32
& rLeftBorder
, sal_Int32
& rTopBorder
,
2450 sal_Int32
& rRightBorder
, sal_Int32
& rBottomBorder
) const
2452 rLeftBorder
= mpWindowImpl
->mnLeftBorder
;
2453 rTopBorder
= mpWindowImpl
->mnTopBorder
;
2454 rRightBorder
= mpWindowImpl
->mnRightBorder
;
2455 rBottomBorder
= mpWindowImpl
->mnBottomBorder
;
2458 void Window::Enable( bool bEnable
, bool bChild
)
2465 // the tracking mode will be stopped or the capture will be stolen
2466 // when a window is disabled,
2468 EndTracking( TrackingEventFlags::Cancel
);
2469 if ( IsMouseCaptured() )
2471 // try to pass focus to the next control
2472 // if the window has focus and is contained in the dialog control
2473 // mpWindowImpl->mbDisabled should only be set after a call of ImplDlgCtrlNextWindow().
2474 // Otherwise ImplDlgCtrlNextWindow() should be used
2476 ImplDlgCtrlNextWindow();
2479 if ( mpWindowImpl
->mpBorderWindow
)
2481 mpWindowImpl
->mpBorderWindow
->Enable( bEnable
, false );
2482 if ( (mpWindowImpl
->mpBorderWindow
->GetType() == WINDOW_BORDERWINDOW
) &&
2483 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->mpMenuBarWindow
)
2484 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->mpMenuBarWindow
->Enable( bEnable
);
2487 // #i56102# restore app focus win in case the
2488 // window was disabled when the frame focus changed
2489 ImplSVData
* pSVData
= ImplGetSVData();
2491 pSVData
->maWinData
.mpFocusWin
== nullptr &&
2492 mpWindowImpl
->mpFrameData
->mbHasFocus
&&
2493 mpWindowImpl
->mpFrameData
->mpFocusWin
== this )
2494 pSVData
->maWinData
.mpFocusWin
= this;
2496 if ( mpWindowImpl
->mbDisabled
!= !bEnable
)
2498 mpWindowImpl
->mbDisabled
= !bEnable
;
2499 if ( mpWindowImpl
->mpSysObj
)
2500 mpWindowImpl
->mpSysObj
->Enable( bEnable
&& !mpWindowImpl
->mbInputDisabled
);
2501 CompatStateChanged( StateChangedType::Enable
);
2503 CallEventListeners( bEnable
? VCLEVENT_WINDOW_ENABLED
: VCLEVENT_WINDOW_DISABLED
);
2508 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2511 pChild
->Enable( bEnable
, bChild
);
2512 pChild
= pChild
->mpWindowImpl
->mpNext
;
2516 if ( IsReallyVisible() )
2517 ImplGenerateMouseMove();
2520 void Window::SetCallHandlersOnInputDisabled( bool bCall
)
2522 mpWindowImpl
->mbCallHandlersDuringInputDisabled
= bCall
;
2524 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2527 pChild
->SetCallHandlersOnInputDisabled( bCall
);
2528 pChild
= pChild
->mpWindowImpl
->mpNext
;
2532 bool Window::IsCallHandlersOnInputDisabled() const
2534 return mpWindowImpl
->mbCallHandlersDuringInputDisabled
;
2537 void Window::EnableInput( bool bEnable
, bool bChild
)
2542 bool bNotify
= (bEnable
!= mpWindowImpl
->mbInputDisabled
);
2543 if ( mpWindowImpl
->mpBorderWindow
)
2545 mpWindowImpl
->mpBorderWindow
->EnableInput( bEnable
, false );
2546 if ( (mpWindowImpl
->mpBorderWindow
->GetType() == WINDOW_BORDERWINDOW
) &&
2547 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->mpMenuBarWindow
)
2548 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->mpMenuBarWindow
->EnableInput( bEnable
);
2551 if ( (! bEnable
&& mpWindowImpl
->meAlwaysInputMode
!= AlwaysInputEnabled
) ||
2552 ( bEnable
&& mpWindowImpl
->meAlwaysInputMode
!= AlwaysInputDisabled
) )
2554 // automatically stop the tracking mode or steal capture
2555 // if the window is disabled
2559 EndTracking( TrackingEventFlags::Cancel
);
2560 if ( IsMouseCaptured() )
2564 if ( mpWindowImpl
->mbInputDisabled
!= !bEnable
)
2566 mpWindowImpl
->mbInputDisabled
= !bEnable
;
2567 if ( mpWindowImpl
->mpSysObj
)
2568 mpWindowImpl
->mpSysObj
->Enable( !mpWindowImpl
->mbDisabled
&& bEnable
);
2572 // #i56102# restore app focus win in case the
2573 // window was disabled when the frame focus changed
2574 ImplSVData
* pSVData
= ImplGetSVData();
2576 pSVData
->maWinData
.mpFocusWin
== nullptr &&
2577 mpWindowImpl
->mpFrameData
->mbHasFocus
&&
2578 mpWindowImpl
->mpFrameData
->mpFocusWin
== this )
2579 pSVData
->maWinData
.mpFocusWin
= this;
2583 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2586 pChild
->EnableInput( bEnable
, bChild
);
2587 pChild
= pChild
->mpWindowImpl
->mpNext
;
2591 if ( IsReallyVisible() )
2592 ImplGenerateMouseMove();
2594 // #104827# notify parent
2597 NotifyEvent
aNEvt( bEnable
? MouseNotifyEvent::INPUTENABLE
: MouseNotifyEvent::INPUTDISABLE
, this );
2598 CompatNotify( aNEvt
);
2602 void Window::EnableInput( bool bEnable
, const vcl::Window
* pExcludeWindow
)
2607 EnableInput( bEnable
);
2609 // pExecuteWindow is the first Overlap-Frame --> if this
2610 // shouldn't be the case, than this must be changed in dialog.cxx
2611 if( pExcludeWindow
)
2612 pExcludeWindow
= pExcludeWindow
->ImplGetFirstOverlapWindow();
2613 vcl::Window
* pSysWin
= mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpFrameData
->mpFirstOverlap
;
2616 // Is Window in the path from this window
2617 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pSysWin
, true ) )
2619 // Is Window not in the exclude window path or not the
2620 // exclude window, than change the status
2621 if ( !pExcludeWindow
|| !pExcludeWindow
->ImplIsWindowOrChild( pSysWin
, true ) )
2622 pSysWin
->EnableInput( bEnable
);
2624 pSysWin
= pSysWin
->mpWindowImpl
->mpNextOverlap
;
2627 // enable/disable floating system windows as well
2628 vcl::Window
* pFrameWin
= ImplGetSVData()->maWinData
.mpFirstFrame
;
2631 if( pFrameWin
->ImplIsFloatingWindow() )
2633 // Is Window in the path from this window
2634 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pFrameWin
, true ) )
2636 // Is Window not in the exclude window path or not the
2637 // exclude window, than change the status
2638 if ( !pExcludeWindow
|| !pExcludeWindow
->ImplIsWindowOrChild( pFrameWin
, true ) )
2639 pFrameWin
->EnableInput( bEnable
);
2642 pFrameWin
= pFrameWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
2645 // the same for ownerdraw floating windows
2646 if( mpWindowImpl
->mbFrame
)
2648 ::std::vector
< VclPtr
<vcl::Window
> >& rList
= mpWindowImpl
->mpFrameData
->maOwnerDrawList
;
2649 auto p
= rList
.begin();
2650 while( p
!= rList
.end() )
2652 // Is Window in the path from this window
2653 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( (*p
), true ) )
2655 // Is Window not in the exclude window path or not the
2656 // exclude window, than change the status
2657 if ( !pExcludeWindow
|| !pExcludeWindow
->ImplIsWindowOrChild( (*p
), true ) )
2658 (*p
)->EnableInput( bEnable
);
2665 void Window::AlwaysEnableInput( bool bAlways
, bool bChild
)
2668 if ( mpWindowImpl
->mpBorderWindow
)
2669 mpWindowImpl
->mpBorderWindow
->AlwaysEnableInput( bAlways
, false );
2671 if( bAlways
&& mpWindowImpl
->meAlwaysInputMode
!= AlwaysInputEnabled
)
2673 mpWindowImpl
->meAlwaysInputMode
= AlwaysInputEnabled
;
2676 EnableInput( true, false );
2678 else if( ! bAlways
&& mpWindowImpl
->meAlwaysInputMode
== AlwaysInputEnabled
)
2680 mpWindowImpl
->meAlwaysInputMode
= AlwaysInputNone
;
2685 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2688 pChild
->AlwaysEnableInput( bAlways
, bChild
);
2689 pChild
= pChild
->mpWindowImpl
->mpNext
;
2694 void Window::AlwaysDisableInput( bool bAlways
, bool bChild
)
2697 if ( mpWindowImpl
->mpBorderWindow
)
2698 mpWindowImpl
->mpBorderWindow
->AlwaysDisableInput( bAlways
, false );
2700 if( bAlways
&& mpWindowImpl
->meAlwaysInputMode
!= AlwaysInputDisabled
)
2702 mpWindowImpl
->meAlwaysInputMode
= AlwaysInputDisabled
;
2705 EnableInput( false, false );
2707 else if( ! bAlways
&& mpWindowImpl
->meAlwaysInputMode
== AlwaysInputDisabled
)
2709 mpWindowImpl
->meAlwaysInputMode
= AlwaysInputNone
;
2714 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2717 pChild
->AlwaysDisableInput( bAlways
, bChild
);
2718 pChild
= pChild
->mpWindowImpl
->mpNext
;
2723 void Window::SetActivateMode( ActivateModeFlags nMode
)
2726 if ( mpWindowImpl
->mpBorderWindow
)
2727 mpWindowImpl
->mpBorderWindow
->SetActivateMode( nMode
);
2729 if ( mpWindowImpl
->mnActivateMode
!= nMode
)
2731 mpWindowImpl
->mnActivateMode
= nMode
;
2733 // possibly trigger Decativate/Activate
2734 if ( mpWindowImpl
->mnActivateMode
!= ActivateModeFlags::NONE
)
2736 if ( (mpWindowImpl
->mbActive
|| (GetType() == WINDOW_BORDERWINDOW
)) &&
2737 !HasChildPathFocus( true ) )
2739 mpWindowImpl
->mbActive
= false;
2745 if ( !mpWindowImpl
->mbActive
|| (GetType() == WINDOW_BORDERWINDOW
) )
2747 mpWindowImpl
->mbActive
= true;
2754 void Window::setPosSizePixel( long nX
, long nY
,
2755 long nWidth
, long nHeight
, PosSizeFlags nFlags
)
2757 bool bHasValidSize
= !mpWindowImpl
->mbDefSize
;
2759 if ( nFlags
& PosSizeFlags::Pos
)
2760 mpWindowImpl
->mbDefPos
= false;
2761 if ( nFlags
& PosSizeFlags::Size
)
2762 mpWindowImpl
->mbDefSize
= false;
2764 // The top BorderWindow is the window which is to be positioned
2765 VclPtr
<vcl::Window
> pWindow
= this;
2766 while ( pWindow
->mpWindowImpl
->mpBorderWindow
)
2767 pWindow
= pWindow
->mpWindowImpl
->mpBorderWindow
;
2769 if ( pWindow
->mpWindowImpl
->mbFrame
)
2771 // Note: if we're positioning a frame, the coordinates are interpreted
2772 // as being the top-left corner of the window's client area and NOT
2773 // as the position of the border ! (due to limitations of several UNIX window managers)
2774 long nOldWidth
= pWindow
->mnOutWidth
;
2776 if ( !(nFlags
& PosSizeFlags::Width
) )
2777 nWidth
= pWindow
->mnOutWidth
;
2778 if ( !(nFlags
& PosSizeFlags::Height
) )
2779 nHeight
= pWindow
->mnOutHeight
;
2781 sal_uInt16 nSysFlags
=0;
2782 VclPtr
<vcl::Window
> pParent
= GetParent();
2783 VclPtr
<vcl::Window
> pWinParent
= pWindow
->GetParent();
2785 if( nFlags
& PosSizeFlags::Width
)
2786 nSysFlags
|= SAL_FRAME_POSSIZE_WIDTH
;
2787 if( nFlags
& PosSizeFlags::Height
)
2788 nSysFlags
|= SAL_FRAME_POSSIZE_HEIGHT
;
2789 if( nFlags
& PosSizeFlags::X
)
2791 nSysFlags
|= SAL_FRAME_POSSIZE_X
;
2792 if( pWinParent
&& (pWindow
->GetStyle() & WB_SYSTEMCHILDWINDOW
) )
2794 nX
+= pWinParent
->mnOutOffX
;
2796 if( pParent
&& pParent
->ImplIsAntiparallel() )
2798 // --- RTL --- (re-mirror at parent window)
2799 Rectangle
aRect( Point ( nX
, nY
), Size( nWidth
, nHeight
) );
2800 const OutputDevice
*pParentOutDev
= pParent
->GetOutDev();
2801 pParentOutDev
->ReMirror( aRect
);
2805 if( !(nFlags
& PosSizeFlags::X
) && bHasValidSize
&& pWindow
->mpWindowImpl
->mpFrame
->maGeometry
.nWidth
)
2807 // --- RTL --- make sure the old right aligned position is not changed
2808 // system windows will always grow to the right
2811 OutputDevice
*pParentOutDev
= pWinParent
->GetOutDev();
2812 if( pParentOutDev
->HasMirroredGraphics() )
2814 long myWidth
= nOldWidth
;
2816 myWidth
= mpWindowImpl
->mpFrame
->GetUnmirroredGeometry().nWidth
;
2819 nFlags
|= PosSizeFlags::X
;
2820 nSysFlags
|= SAL_FRAME_POSSIZE_X
;
2821 nX
= pWinParent
->mpWindowImpl
->mpFrame
->GetUnmirroredGeometry().nX
- mpWindowImpl
->mpFrame
->GetUnmirroredGeometry().nLeftDecoration
+
2822 pWinParent
->mpWindowImpl
->mpFrame
->GetUnmirroredGeometry().nWidth
- myWidth
- 1 - mpWindowImpl
->mpFrame
->GetUnmirroredGeometry().nX
;
2823 if(!(nFlags
& PosSizeFlags::Y
))
2825 nFlags
|= PosSizeFlags::Y
;
2826 nSysFlags
|= SAL_FRAME_POSSIZE_Y
;
2827 nY
= mpWindowImpl
->mpFrame
->GetUnmirroredGeometry().nY
- pWinParent
->mpWindowImpl
->mpFrame
->GetUnmirroredGeometry().nY
-
2828 mpWindowImpl
->mpFrame
->GetUnmirroredGeometry().nTopDecoration
;
2833 if( nFlags
& PosSizeFlags::Y
)
2835 nSysFlags
|= SAL_FRAME_POSSIZE_Y
;
2836 if( pWinParent
&& (pWindow
->GetStyle() & WB_SYSTEMCHILDWINDOW
) )
2838 nY
+= pWinParent
->mnOutOffY
;
2842 if( nSysFlags
& (SAL_FRAME_POSSIZE_WIDTH
|SAL_FRAME_POSSIZE_HEIGHT
) )
2844 // check for min/max client size and adjust size accordingly
2845 // otherwise it may happen that the resize event is ignored, i.e. the old size remains
2846 // unchanged but ImplHandleResize() is called with the wrong size
2847 SystemWindow
*pSystemWindow
= dynamic_cast< SystemWindow
* >( pWindow
.get() );
2850 Size aMinSize
= pSystemWindow
->GetMinOutputSizePixel();
2851 Size aMaxSize
= pSystemWindow
->GetMaxOutputSizePixel();
2852 if( nWidth
< aMinSize
.Width() )
2853 nWidth
= aMinSize
.Width();
2854 if( nHeight
< aMinSize
.Height() )
2855 nHeight
= aMinSize
.Height();
2857 if( nWidth
> aMaxSize
.Width() )
2858 nWidth
= aMaxSize
.Width();
2859 if( nHeight
> aMaxSize
.Height() )
2860 nHeight
= aMaxSize
.Height();
2864 pWindow
->mpWindowImpl
->mpFrame
->SetPosSize( nX
, nY
, nWidth
, nHeight
, nSysFlags
);
2866 // Resize should be called directly. If we haven't
2867 // set the correct size, we get a second resize from
2868 // the system with the correct size. This can be happened
2869 // if the size is to small or to large.
2870 ImplHandleResize( pWindow
, nWidth
, nHeight
);
2874 pWindow
->ImplPosSizeWindow( nX
, nY
, nWidth
, nHeight
, nFlags
);
2875 if ( IsReallyVisible() )
2876 ImplGenerateMouseMove();
2880 Point
Window::GetPosPixel() const
2882 return mpWindowImpl
->maPos
;
2885 Rectangle
Window::GetDesktopRectPixel() const
2888 mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpFrame
->GetWorkArea( rRect
);
2892 Point
Window::OutputToScreenPixel( const Point
& rPos
) const
2894 // relative to top level parent
2895 return Point( rPos
.X()+mnOutOffX
, rPos
.Y()+mnOutOffY
);
2898 Point
Window::ScreenToOutputPixel( const Point
& rPos
) const
2900 // relative to top level parent
2901 return Point( rPos
.X()-mnOutOffX
, rPos
.Y()-mnOutOffY
);
2904 long Window::ImplGetUnmirroredOutOffX()
2906 // revert mnOutOffX changes that were potentially made in ImplPosSizeWindow
2907 long offx
= mnOutOffX
;
2908 OutputDevice
*pOutDev
= GetOutDev();
2909 if( pOutDev
->HasMirroredGraphics() )
2911 if( mpWindowImpl
->mpParent
&& !mpWindowImpl
->mpParent
->mpWindowImpl
->mbFrame
&& mpWindowImpl
->mpParent
->ImplIsAntiparallel() )
2913 if ( !ImplIsOverlapWindow() )
2914 offx
-= mpWindowImpl
->mpParent
->mnOutOffX
;
2916 offx
= mpWindowImpl
->mpParent
->mnOutWidth
- mnOutWidth
- offx
;
2918 if ( !ImplIsOverlapWindow() )
2919 offx
+= mpWindowImpl
->mpParent
->mnOutOffX
;
2926 // normalized screen pixel are independent of mirroring
2927 Point
Window::OutputToNormalizedScreenPixel( const Point
& rPos
) const
2929 // relative to top level parent
2930 long offx
= const_cast<vcl::Window
*>(this)->ImplGetUnmirroredOutOffX();
2931 return Point( rPos
.X()+offx
, rPos
.Y()+mnOutOffY
);
2934 Point
Window::NormalizedScreenToOutputPixel( const Point
& rPos
) const
2936 // relative to top level parent
2937 long offx
= const_cast<vcl::Window
*>(this)->ImplGetUnmirroredOutOffX();
2938 return Point( rPos
.X()-offx
, rPos
.Y()-mnOutOffY
);
2941 Point
Window::OutputToAbsoluteScreenPixel( const Point
& rPos
) const
2943 // relative to the screen
2944 Point p
= OutputToScreenPixel( rPos
);
2945 SalFrameGeometry g
= mpWindowImpl
->mpFrame
->GetGeometry();
2951 Point
Window::AbsoluteScreenToOutputPixel( const Point
& rPos
) const
2953 // relative to the screen
2954 Point p
= ScreenToOutputPixel( rPos
);
2955 SalFrameGeometry g
= mpWindowImpl
->mpFrame
->GetGeometry();
2961 Rectangle
Window::ImplOutputToUnmirroredAbsoluteScreenPixel( const Rectangle
&rRect
) const
2963 // this method creates unmirrored screen coordinates to be compared with the desktop
2964 // and is used for positioning of RTL popup windows correctly on the screen
2965 SalFrameGeometry g
= mpWindowImpl
->mpFrame
->GetUnmirroredGeometry();
2967 Point p1
= OutputToScreenPixel( rRect
.TopRight() );
2968 p1
.X() = g
.nX
+g
.nWidth
-p1
.X();
2971 Point p2
= OutputToScreenPixel( rRect
.BottomLeft() );
2972 p2
.X() = g
.nX
+g
.nWidth
-p2
.X();
2975 return Rectangle( p1
, p2
);
2978 Rectangle
Window::GetWindowExtentsRelative( vcl::Window
*pRelativeWindow
) const
2981 return ImplGetWindowExtentsRelative( pRelativeWindow
, false );
2984 Rectangle
Window::GetClientWindowExtentsRelative() const
2986 // without decoration
2987 return ImplGetWindowExtentsRelative( nullptr, true );
2990 Rectangle
Window::ImplGetWindowExtentsRelative( vcl::Window
*pRelativeWindow
, bool bClientOnly
) const
2992 SalFrameGeometry g
= mpWindowImpl
->mpFrame
->GetGeometry();
2993 // make sure we use the extent of our border window,
2994 // otherwise we miss a few pixels
2995 const vcl::Window
*pWin
= (!bClientOnly
&& mpWindowImpl
->mpBorderWindow
) ? mpWindowImpl
->mpBorderWindow
: this;
2997 Point
aPos( pWin
->OutputToScreenPixel( Point(0,0) ) );
3000 Size
aSize ( pWin
->GetSizePixel() );
3001 // #104088# do not add decoration to the workwindow to be compatible to java accessibility api
3002 if( !bClientOnly
&& (mpWindowImpl
->mbFrame
|| (mpWindowImpl
->mpBorderWindow
&& mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbFrame
&& GetType() != WINDOW_WORKWINDOW
)) )
3004 aPos
.X() -= g
.nLeftDecoration
;
3005 aPos
.Y() -= g
.nTopDecoration
;
3006 aSize
.Width() += g
.nLeftDecoration
+ g
.nRightDecoration
;
3007 aSize
.Height() += g
.nTopDecoration
+ g
.nBottomDecoration
;
3009 if( pRelativeWindow
)
3011 // #106399# express coordinates relative to borderwindow
3012 vcl::Window
*pRelWin
= (!bClientOnly
&& pRelativeWindow
->mpWindowImpl
->mpBorderWindow
) ? pRelativeWindow
->mpWindowImpl
->mpBorderWindow
.get() : pRelativeWindow
;
3013 aPos
= pRelWin
->AbsoluteScreenToOutputPixel( aPos
);
3015 return Rectangle( aPos
, aSize
);
3018 void Window::Scroll( long nHorzScroll
, long nVertScroll
, ScrollFlags nFlags
)
3021 ImplScroll( Rectangle( Point( mnOutOffX
, mnOutOffY
),
3022 Size( mnOutWidth
, mnOutHeight
) ),
3023 nHorzScroll
, nVertScroll
, nFlags
& ~ScrollFlags::Clip
);
3026 void Window::Scroll( long nHorzScroll
, long nVertScroll
,
3027 const Rectangle
& rRect
, ScrollFlags nFlags
)
3029 OutputDevice
*pOutDev
= GetOutDev();
3030 Rectangle aRect
= pOutDev
->ImplLogicToDevicePixel( rRect
);
3031 aRect
.Intersection( Rectangle( Point( mnOutOffX
, mnOutOffY
), Size( mnOutWidth
, mnOutHeight
) ) );
3032 if ( !aRect
.IsEmpty() )
3033 ImplScroll( aRect
, nHorzScroll
, nVertScroll
, nFlags
);
3036 void Window::Flush()
3039 const Rectangle
aWinRect( Point( mnOutOffX
, mnOutOffY
), Size( mnOutWidth
, mnOutHeight
) );
3040 mpWindowImpl
->mpFrame
->Flush( aWinRect
);
3043 void Window::SetUpdateMode( bool bUpdate
)
3045 mpWindowImpl
->mbNoUpdate
= !bUpdate
;
3046 CompatStateChanged( StateChangedType::UpdateMode
);
3049 void Window::GrabFocus()
3051 ImplGrabFocus( GetFocusFlags::NONE
);
3054 bool Window::HasFocus() const
3056 return (this == ImplGetSVData()->maWinData
.mpFocusWin
);
3059 void Window::GrabFocusToDocument()
3061 ImplGrabFocusToDocument(GetFocusFlags::NONE
);
3064 void Window::SetFakeFocus( bool bFocus
)
3066 ImplGetWindowImpl()->mbFakeFocusSet
= bFocus
;
3069 bool Window::HasChildPathFocus( bool bSystemWindow
) const
3072 vcl::Window
* pFocusWin
= ImplGetSVData()->maWinData
.mpFocusWin
;
3074 return ImplIsWindowOrChild( pFocusWin
, bSystemWindow
);
3078 void Window::SetCursor( vcl::Cursor
* pCursor
)
3081 if ( mpWindowImpl
->mpCursor
!= pCursor
)
3083 if ( mpWindowImpl
->mpCursor
)
3084 mpWindowImpl
->mpCursor
->ImplHide();
3085 mpWindowImpl
->mpCursor
= pCursor
;
3087 pCursor
->ImplShow();
3091 void Window::SetText( const OUString
& rStr
)
3093 if (!mpWindowImpl
|| rStr
== mpWindowImpl
->maText
)
3096 OUString
oldTitle( mpWindowImpl
->maText
);
3097 mpWindowImpl
->maText
= rStr
;
3099 if ( mpWindowImpl
->mpBorderWindow
)
3100 mpWindowImpl
->mpBorderWindow
->SetText( rStr
);
3101 else if ( mpWindowImpl
->mbFrame
)
3102 mpWindowImpl
->mpFrame
->SetTitle( rStr
);
3104 CallEventListeners( VCLEVENT_WINDOW_FRAMETITLECHANGED
, &oldTitle
);
3106 // #107247# needed for accessibility
3107 // The VCLEVENT_WINDOW_FRAMETITLECHANGED is (mis)used to notify accessible name changes.
3108 // Therefore a window, which is labeled by this window, must also notify an accessible
3110 if ( IsReallyVisible() )
3112 vcl::Window
* pWindow
= GetAccessibleRelationLabelFor();
3113 if ( pWindow
&& pWindow
!= this )
3114 pWindow
->CallEventListeners( VCLEVENT_WINDOW_FRAMETITLECHANGED
, &oldTitle
);
3117 CompatStateChanged( StateChangedType::Text
);
3120 OUString
Window::GetText() const
3123 return mpWindowImpl
->maText
;
3126 OUString
Window::GetDisplayText() const
3132 const Wallpaper
& Window::GetDisplayBackground() const
3134 // FIXME: fix issue 52349, need to fix this really in
3135 // all NWF enabled controls
3136 const ToolBox
* pTB
= dynamic_cast<const ToolBox
*>(this);
3139 if( IsNativeWidgetEnabled() )
3140 return pTB
->ImplGetToolBoxPrivateData()->maDisplayBackground
;
3143 if( !IsBackground() )
3145 if( mpWindowImpl
->mpParent
)
3146 return mpWindowImpl
->mpParent
->GetDisplayBackground();
3149 const Wallpaper
& rBack
= GetBackground();
3150 if( ! rBack
.IsBitmap() &&
3151 ! rBack
.IsGradient() &&
3152 rBack
.GetColor().GetColor() == COL_TRANSPARENT
&&
3153 mpWindowImpl
->mpParent
)
3154 return mpWindowImpl
->mpParent
->GetDisplayBackground();
3158 const OUString
& Window::GetHelpText() const
3160 OUString
aStrHelpId( OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8
) );
3161 bool bStrHelpId
= !aStrHelpId
.isEmpty();
3163 if ( !mpWindowImpl
->maHelpText
.getLength() && bStrHelpId
)
3165 if ( !IsDialog() && (mpWindowImpl
->mnType
!= WINDOW_TABPAGE
) && (mpWindowImpl
->mnType
!= WINDOW_FLOATINGWINDOW
) )
3167 Help
* pHelp
= Application::GetHelp();
3170 mpWindowImpl
->maHelpText
= pHelp
->GetHelpText(aStrHelpId
, this);
3171 mpWindowImpl
->mbHelpTextDynamic
= false;
3175 else if( mpWindowImpl
->mbHelpTextDynamic
&& bStrHelpId
)
3177 static const char* pEnv
= getenv( "HELP_DEBUG" );
3180 OUStringBuffer
aTxt( 64+mpWindowImpl
->maHelpText
.getLength() );
3181 aTxt
.append( mpWindowImpl
->maHelpText
);
3182 aTxt
.append( "\n------------------\n" );
3183 aTxt
.append( OUString( aStrHelpId
) );
3184 mpWindowImpl
->maHelpText
= aTxt
.makeStringAndClear();
3186 mpWindowImpl
->mbHelpTextDynamic
= false;
3189 return mpWindowImpl
->maHelpText
;
3192 void Window::SetWindowPeer( Reference
< css::awt::XWindowPeer
> const & xPeer
, VCLXWindow
* pVCLXWindow
)
3194 assert(mpWindowImpl
);
3196 // be safe against re-entrance: first clear the old ref, then assign the new one
3197 mpWindowImpl
->mxWindowPeer
.clear();
3198 mpWindowImpl
->mxWindowPeer
= xPeer
;
3200 mpWindowImpl
->mpVCLXWindow
= pVCLXWindow
;
3203 Reference
< css::awt::XWindowPeer
> Window::GetComponentInterface( bool bCreate
)
3205 if ( !mpWindowImpl
->mxWindowPeer
.is() && bCreate
)
3207 UnoWrapperBase
* pWrapper
= Application::GetUnoWrapper();
3209 mpWindowImpl
->mxWindowPeer
= pWrapper
->GetWindowInterface( this );
3211 return mpWindowImpl
->mxWindowPeer
;
3214 void Window::SetComponentInterface( Reference
< css::awt::XWindowPeer
> const & xIFace
)
3216 UnoWrapperBase
* pWrapper
= Application::GetUnoWrapper();
3217 SAL_WARN_IF( !pWrapper
, "vcl", "SetComponentInterface: No Wrapper!" );
3219 pWrapper
->SetWindowInterface( this, xIFace
);
3222 typedef std::map
<vcl::LOKWindowId
, VclPtr
<vcl::Window
>> LOKWindowsMap
;
3226 LOKWindowsMap
& GetLOKWindowsMap()
3228 // never use this in the desktop case
3229 assert(comphelper::LibreOfficeKit::isActive());
3231 // Map to remember the LOKWindowId <-> Window binding.
3232 static std::unique_ptr
<LOKWindowsMap
> s_pLOKWindowsMap
;
3234 if (!s_pLOKWindowsMap
)
3235 s_pLOKWindowsMap
.reset(new LOKWindowsMap
);
3237 return *s_pLOKWindowsMap
.get();
3242 void Window::SetLOKNotifier(const vcl::ILibreOfficeKitNotifier
* pNotifier
, bool bParent
)
3244 // don't allow setting this twice
3245 assert(mpWindowImpl
->mpLOKNotifier
== nullptr);
3250 // Counter to be able to have unique id's for each window.
3251 static vcl::LOKWindowId sLastLOKWindowId
= 1;
3253 // assign the LOK window id
3254 assert(mpWindowImpl
->mnLOKWindowId
== 0);
3255 mpWindowImpl
->mnLOKWindowId
= sLastLOKWindowId
++;
3256 GetLOKWindowsMap().insert(std::map
<vcl::LOKWindowId
, VclPtr
<vcl::Window
>>::value_type(mpWindowImpl
->mnLOKWindowId
, this));
3259 mpWindowImpl
->mbLOKParentNotifier
= true;
3261 mpWindowImpl
->mpLOKNotifier
= pNotifier
;
3264 VclPtr
<Window
> Window::FindLOKWindow(vcl::LOKWindowId nWindowId
)
3266 const auto it
= GetLOKWindowsMap().find(nWindowId
);
3267 if (it
!= GetLOKWindowsMap().end())
3270 return VclPtr
<Window
>();
3273 void Window::ReleaseLOKNotifier()
3275 // unregister the LOK window binding
3276 if (mpWindowImpl
->mnLOKWindowId
> 0)
3277 GetLOKWindowsMap().erase(mpWindowImpl
->mnLOKWindowId
);
3279 mpWindowImpl
->mpLOKNotifier
= nullptr;
3280 mpWindowImpl
->mnLOKWindowId
= 0;
3283 const vcl::ILibreOfficeKitNotifier
* Window::GetLOKNotifier() const
3285 return mpWindowImpl
->mpLOKNotifier
;
3288 vcl::LOKWindowId
Window::GetLOKWindowId() const
3290 return mpWindowImpl
->mnLOKWindowId
;
3293 VclPtr
<vcl::Window
> Window::GetParentWithLOKNotifier()
3295 VclPtr
<vcl::Window
> pWindow(this);
3297 while (pWindow
&& !pWindow
->GetLOKNotifier())
3298 pWindow
= pWindow
->GetParent();
3303 void Window::ImplCallDeactivateListeners( vcl::Window
*pNew
)
3305 // no deactivation if the newly activated window is my child
3306 if ( !pNew
|| !ImplIsChild( pNew
) )
3308 VclPtr
<vcl::Window
> xWindow(this);
3309 CallEventListeners( VCLEVENT_WINDOW_DEACTIVATE
);
3310 if( xWindow
->IsDisposed() )
3313 // #100759#, avoid walking the wrong frame's hierarchy
3314 // eg, undocked docking windows (ImplDockFloatWin)
3315 if ( ImplGetParent() && mpWindowImpl
->mpFrameWindow
== ImplGetParent()->mpWindowImpl
->mpFrameWindow
)
3316 ImplGetParent()->ImplCallDeactivateListeners( pNew
);
3320 void Window::ImplCallActivateListeners( vcl::Window
*pOld
)
3322 // no activation if the old active window is my child
3323 if ( !pOld
|| !ImplIsChild( pOld
) )
3325 VclPtr
<vcl::Window
> xWindow(this);
3326 CallEventListeners( VCLEVENT_WINDOW_ACTIVATE
, pOld
);
3327 if( xWindow
->IsDisposed() )
3330 if ( ImplGetParent() )
3331 ImplGetParent()->ImplCallActivateListeners( pOld
);
3332 else if( (mpWindowImpl
->mnStyle
& WB_INTROWIN
) == 0 )
3334 // top level frame reached: store hint for DefModalDialogParent
3335 ImplGetSVData()->maWinData
.mpActiveApplicationFrame
= mpWindowImpl
->mpFrameWindow
;
3340 void Window::SetClipboard(Reference
<XClipboard
> const & xClipboard
)
3342 if (mpWindowImpl
->mpFrameData
)
3343 mpWindowImpl
->mpFrameData
->mxClipboard
= xClipboard
;
3346 Reference
< XClipboard
> Window::GetClipboard()
3349 if( mpWindowImpl
->mpFrameData
)
3351 if( ! mpWindowImpl
->mpFrameData
->mxClipboard
.is() )
3355 mpWindowImpl
->mpFrameData
->mxClipboard
3356 = css::datatransfer::clipboard::SystemClipboard::create(
3357 comphelper::getProcessComponentContext());
3359 catch (DeploymentException
& e
)
3363 "ignoring DeploymentException \"" << e
.Message
<< "\"");
3367 return mpWindowImpl
->mpFrameData
->mxClipboard
;
3370 return static_cast < XClipboard
* > (nullptr);
3373 Reference
< XClipboard
> Window::GetPrimarySelection()
3376 if( mpWindowImpl
->mpFrameData
)
3378 if( ! mpWindowImpl
->mpFrameData
->mxSelection
.is() )
3382 Reference
< XComponentContext
> xContext( comphelper::getProcessComponentContext() );
3384 #if HAVE_FEATURE_X11
3385 // A hack, making the primary selection available as an instance
3386 // of the SystemClipboard service on X11:
3387 Sequence
< Any
> args(1);
3388 args
[0] <<= OUString("PRIMARY");
3389 mpWindowImpl
->mpFrameData
->mxSelection
.set(
3390 (xContext
->getServiceManager()->
3391 createInstanceWithArgumentsAndContext(
3392 "com.sun.star.datatransfer.clipboard.SystemClipboard",
3396 static Reference
< XClipboard
> s_xSelection(
3397 xContext
->getServiceManager()->createInstanceWithContext( "com.sun.star.datatransfer.clipboard.GenericClipboard", xContext
), UNO_QUERY
);
3399 mpWindowImpl
->mpFrameData
->mxSelection
= s_xSelection
;
3402 catch (RuntimeException
& e
)
3406 "ignoring RuntimeException \"" << e
.Message
<< "\"");
3410 return mpWindowImpl
->mpFrameData
->mxSelection
;
3413 return static_cast < XClipboard
* > (nullptr);
3416 void Window::RecordLayoutData( vcl::ControlLayoutData
* pLayout
, const Rectangle
& rRect
)
3418 assert(mpOutDevData
);
3419 mpOutDevData
->mpRecordLayout
= pLayout
;
3420 mpOutDevData
->maRecordRect
= rRect
;
3421 Paint(*this, rRect
);
3422 mpOutDevData
->mpRecordLayout
= nullptr;
3425 void Window::DrawSelectionBackground( const Rectangle
& rRect
,
3426 sal_uInt16 highlight
,
3431 if( rRect
.IsEmpty() )
3434 const StyleSettings
& rStyles
= GetSettings().GetStyleSettings();
3436 // colors used for item highlighting
3437 Color
aSelectionBorderCol( rStyles
.GetHighlightColor() );
3438 Color
aSelectionFillCol( aSelectionBorderCol
);
3440 bool bDark
= rStyles
.GetFaceColor().IsDark();
3441 bool bBright
= ( rStyles
.GetFaceColor() == Color( COL_WHITE
) );
3443 int c1
= aSelectionBorderCol
.GetLuminance();
3444 int c2
= GetDisplayBackground().GetColor().GetLuminance();
3446 if( !bDark
&& !bBright
&& abs( c2
-c1
) < 75 )
3448 // constrast too low
3450 aSelectionFillCol
.RGBtoHSB( h
, s
, b
);
3451 if( b
> 50 ) b
-= 40;
3453 aSelectionFillCol
.SetColor( Color::HSBtoRGB( h
, s
, b
) );
3454 aSelectionBorderCol
= aSelectionFillCol
;
3457 Rectangle
aRect( rRect
);
3458 Color oldFillCol
= GetFillColor();
3459 Color oldLineCol
= GetLineColor();
3462 SetLineColor( bDark
? Color(COL_WHITE
) : ( bBright
? Color(COL_BLACK
) : aSelectionBorderCol
) );
3466 sal_uInt16 nPercent
= 0;
3470 aSelectionFillCol
= COL_BLACK
;
3472 nPercent
= 80; // just checked (light)
3476 if( bChecked
&& highlight
== 2 )
3479 aSelectionFillCol
= COL_LIGHTGRAY
;
3482 aSelectionFillCol
= COL_BLACK
;
3483 SetLineColor( COL_BLACK
);
3487 nPercent
= 20; // selected, pressed or checked ( very dark )
3489 else if( bChecked
|| highlight
== 1 )
3492 aSelectionFillCol
= COL_GRAY
;
3495 aSelectionFillCol
= COL_BLACK
;
3496 SetLineColor( COL_BLACK
);
3500 nPercent
= 35; // selected, pressed or checked ( very dark )
3505 aSelectionFillCol
= COL_LIGHTGRAY
;
3508 aSelectionFillCol
= COL_BLACK
;
3509 SetLineColor( COL_BLACK
);
3510 if( highlight
== 3 )
3516 nPercent
= 70; // selected ( dark )
3520 SetFillColor( aSelectionFillCol
);
3528 tools::Polygon
aPoly( aRect
);
3529 tools::PolyPolygon
aPolyPoly( aPoly
);
3530 DrawTransparent( aPolyPoly
, nPercent
);
3533 SetFillColor( oldFillCol
);
3534 SetLineColor( oldLineCol
);
3537 bool Window::IsScrollable() const
3539 // check for scrollbars
3540 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
3543 if( pChild
->GetType() == WINDOW_SCROLLBAR
)
3546 pChild
= pChild
->mpWindowImpl
->mpNext
;
3551 void Window::ImplMirrorFramePos( Point
&pt
) const
3553 pt
.X() = mpWindowImpl
->mpFrame
->maGeometry
.nWidth
-1-pt
.X();
3556 // frame based modal counter (dialogs are not modal to the whole application anymore)
3557 bool Window::IsInModalMode() const
3559 return (mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpFrameData
->mnModalMode
!= 0);
3562 void Window::ImplIncModalCount()
3564 vcl::Window
* pFrameWindow
= mpWindowImpl
->mpFrameWindow
;
3565 vcl::Window
* pParent
= pFrameWindow
;
3566 while( pFrameWindow
)
3568 pFrameWindow
->mpWindowImpl
->mpFrameData
->mnModalMode
++;
3569 while( pParent
&& pParent
->mpWindowImpl
->mpFrameWindow
== pFrameWindow
)
3571 pParent
= pParent
->GetParent();
3573 pFrameWindow
= pParent
? pParent
->mpWindowImpl
->mpFrameWindow
.get() : nullptr;
3576 void Window::ImplDecModalCount()
3578 vcl::Window
* pFrameWindow
= mpWindowImpl
->mpFrameWindow
;
3579 vcl::Window
* pParent
= pFrameWindow
;
3580 while( pFrameWindow
)
3582 pFrameWindow
->mpWindowImpl
->mpFrameData
->mnModalMode
--;
3583 while( pParent
&& pParent
->mpWindowImpl
->mpFrameWindow
== pFrameWindow
)
3585 pParent
= pParent
->GetParent();
3587 pFrameWindow
= pParent
? pParent
->mpWindowImpl
->mpFrameWindow
.get() : nullptr;
3591 void Window::ImplIsInTaskPaneList( bool mbIsInTaskList
)
3593 mpWindowImpl
->mbIsInTaskPaneList
= mbIsInTaskList
;
3596 void Window::ImplNotifyIconifiedState( bool bIconified
)
3598 mpWindowImpl
->mpFrameWindow
->CallEventListeners( bIconified
? VCLEVENT_WINDOW_MINIMIZE
: VCLEVENT_WINDOW_NORMALIZE
);
3599 // #109206# notify client window as well to have toolkit topwindow listeners notified
3600 if( mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpClientWindow
&& mpWindowImpl
->mpFrameWindow
!= mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpClientWindow
)
3601 mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpClientWindow
->CallEventListeners( bIconified
? VCLEVENT_WINDOW_MINIMIZE
: VCLEVENT_WINDOW_NORMALIZE
);
3604 bool Window::HasActiveChildFrame()
3607 vcl::Window
*pFrameWin
= ImplGetSVData()->maWinData
.mpFirstFrame
;
3610 if( pFrameWin
!= mpWindowImpl
->mpFrameWindow
)
3612 bool bDecorated
= false;
3613 VclPtr
< vcl::Window
> pChildFrame
= pFrameWin
->ImplGetWindow();
3614 // #i15285# unfortunately WB_MOVEABLE is the same as WB_TABSTOP which can
3615 // be removed for ToolBoxes to influence the keyboard accessibility
3616 // thus WB_MOVEABLE is no indicator for decoration anymore
3617 // but FloatingWindows carry this information in their TitleType...
3618 // TODO: avoid duplicate WinBits !!!
3619 if( pChildFrame
&& pChildFrame
->ImplIsFloatingWindow() )
3620 bDecorated
= static_cast<FloatingWindow
*>(pChildFrame
.get())->GetTitleType() != FloatWinTitleType::NONE
;
3621 if( bDecorated
|| (pFrameWin
->mpWindowImpl
->mnStyle
& (WB_MOVEABLE
| WB_SIZEABLE
) ) )
3622 if( pChildFrame
&& pChildFrame
->IsVisible() && pChildFrame
->IsActive() )
3624 if( ImplIsChild( pChildFrame
, true ) )
3631 pFrameWin
= pFrameWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
3636 LanguageType
Window::GetInputLanguage() const
3638 return mpWindowImpl
->mpFrame
->GetInputLanguage();
3641 void Window::EnableNativeWidget( bool bEnable
)
3643 static const char* pNoNWF
= getenv( "SAL_NO_NWF" );
3644 if( pNoNWF
&& *pNoNWF
)
3647 if( bEnable
!= ImplGetWinData()->mbEnableNativeWidget
)
3649 ImplGetWinData()->mbEnableNativeWidget
= bEnable
;
3651 // send datachanged event to allow for internal changes required for NWF
3652 // like clipmode, transparency, etc.
3653 DataChangedEvent
aDCEvt( DataChangedEventType::SETTINGS
, mxSettings
.get(), AllSettingsFlags::STYLE
);
3654 CompatDataChanged( aDCEvt
);
3656 // sometimes the borderwindow is queried, so keep it in sync
3657 if( mpWindowImpl
->mpBorderWindow
)
3658 mpWindowImpl
->mpBorderWindow
->ImplGetWinData()->mbEnableNativeWidget
= bEnable
;
3661 // push down, useful for compound controls
3662 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
3665 pChild
->EnableNativeWidget( bEnable
);
3666 pChild
= pChild
->mpWindowImpl
->mpNext
;
3670 bool Window::IsNativeWidgetEnabled() const
3672 return ImplGetWinData()->mbEnableNativeWidget
;
3675 Reference
< css::rendering::XCanvas
> Window::ImplGetCanvas( bool bSpriteCanvas
) const
3677 // try to retrieve hard reference from weak member
3678 Reference
< css::rendering::XCanvas
> xCanvas( mpWindowImpl
->mxCanvas
);
3680 // canvas still valid? Then we're done.
3684 Sequence
< Any
> aArg(6);
3686 // Feed any with operating system's window handle
3688 // common: first any is VCL pointer to window (for VCL canvas)
3689 aArg
[ 0 ] = makeAny( reinterpret_cast<sal_Int64
>(this) );
3690 aArg
[ 1 ] = GetSystemDataAny();
3691 aArg
[ 2 ] = makeAny( css::awt::Rectangle( mnOutOffX
, mnOutOffY
, mnOutWidth
, mnOutHeight
) );
3692 aArg
[ 3 ] = makeAny( mpWindowImpl
->mbAlwaysOnTop
);
3693 aArg
[ 4 ] = makeAny( Reference
< css::awt::XWindow
>(
3694 const_cast<vcl::Window
*>(this)->GetComponentInterface(),
3696 aArg
[ 5 ] = GetSystemGfxDataAny();
3698 Reference
< XComponentContext
> xContext
= comphelper::getProcessComponentContext();
3700 // Create canvas instance with window handle
3702 static vcl::DeleteUnoReferenceOnDeinit
<XMultiComponentFactory
> xStaticCanvasFactory(
3703 css::rendering::CanvasFactory::create( xContext
) );
3704 Reference
<XMultiComponentFactory
> xCanvasFactory(xStaticCanvasFactory
.get());
3706 if(xCanvasFactory
.is())
3709 // see #140456# - if we're running on a multiscreen setup,
3710 // request special, multi-screen safe sprite canvas
3711 // implementation (not DX5 canvas, as it cannot cope with
3712 // surfaces spanning multiple displays). Note: canvas
3713 // (without sprite) stays the same)
3714 const sal_uInt32 nDisplay
= static_cast< WinSalFrame
* >( mpWindowImpl
->mpFrame
)->mnDisplay
;
3715 if( (nDisplay
>= Application::GetScreenCount()) )
3717 xCanvas
.set( xCanvasFactory
->createInstanceWithArgumentsAndContext(
3719 OUString( "com.sun.star.rendering.SpriteCanvas.MultiScreen" ) :
3720 OUString( "com.sun.star.rendering.Canvas.MultiScreen" ),
3729 xCanvas
.set( xCanvasFactory
->createInstanceWithArgumentsAndContext(
3731 OUString( "com.sun.star.rendering.SpriteCanvas" ) :
3732 OUString( "com.sun.star.rendering.Canvas" ),
3740 mpWindowImpl
->mxCanvas
= xCanvas
;
3743 // no factory??? Empty reference, then.
3747 Reference
< css::rendering::XCanvas
> Window::GetCanvas() const
3749 return ImplGetCanvas( false );
3752 Reference
< css::rendering::XSpriteCanvas
> Window::GetSpriteCanvas() const
3754 Reference
< css::rendering::XSpriteCanvas
> xSpriteCanvas(
3755 ImplGetCanvas( true ), UNO_QUERY
);
3756 return xSpriteCanvas
;
3759 OUString
Window::GetSurroundingText() const
3764 Selection
Window::GetSurroundingTextSelection() const
3766 return Selection( 0, 0 );
3769 bool Window::UsePolyPolygonForComplexGradient()
3771 if ( meRasterOp
!= RasterOp::OverPaint
)
3777 void Window::ApplySettings(vcl::RenderContext
& /*rRenderContext*/)
3781 const SystemEnvData
* Window::GetSystemData() const
3784 return mpWindowImpl
->mpFrame
? mpWindowImpl
->mpFrame
->GetSystemData() : nullptr;
3787 Any
Window::GetSystemDataAny() const
3790 const SystemEnvData
* pSysData
= GetSystemData();
3793 Sequence
< sal_Int8
> aSeq( reinterpret_cast<sal_Int8
const *>(pSysData
), pSysData
->nSize
);
3799 bool Window::SupportsDoubleBuffering() const
3801 return mpWindowImpl
->mpFrameData
->mpBuffer
;
3804 void Window::RequestDoubleBuffering(bool bRequest
)
3808 mpWindowImpl
->mpFrameData
->mpBuffer
= VclPtrInstance
<VirtualDevice
>();
3809 // Make sure that the buffer size matches the frame size.
3810 mpWindowImpl
->mpFrameData
->mpBuffer
->SetOutputSizePixel(mpWindowImpl
->mpFrameWindow
->GetOutputSizePixel());
3813 mpWindowImpl
->mpFrameData
->mpBuffer
.reset();
3817 * The rational here is that we moved destructors to
3818 * dispose and this altered a lot of code paths, that
3819 * are better left unchanged for now.
3821 #define COMPAT_BODY(method,args) \
3822 if (!mpWindowImpl || mpWindowImpl->mbInDispose) \
3823 Window::method args; \
3827 void Window::CompatGetFocus()
3829 COMPAT_BODY(GetFocus
,())
3832 void Window::CompatLoseFocus()
3834 COMPAT_BODY(LoseFocus
,())
3837 void Window::CompatStateChanged( StateChangedType nStateChange
)
3839 COMPAT_BODY(StateChanged
,(nStateChange
))
3842 void Window::CompatDataChanged( const DataChangedEvent
& rDCEvt
)
3844 COMPAT_BODY(DataChanged
,(rDCEvt
))
3847 bool Window::CompatPreNotify( NotifyEvent
& rNEvt
)
3849 if (!mpWindowImpl
|| mpWindowImpl
->mbInDispose
)
3850 return Window::PreNotify( rNEvt
);
3852 return PreNotify( rNEvt
);
3855 bool Window::CompatNotify( NotifyEvent
& rNEvt
)
3857 if (!mpWindowImpl
|| mpWindowImpl
->mbInDispose
)
3858 return Window::EventNotify( rNEvt
);
3860 return EventNotify( rNEvt
);
3863 void Window::set_id(const OUString
& rID
)
3865 mpWindowImpl
->maID
= rID
;
3868 const OUString
& Window::get_id() const
3870 return mpWindowImpl
->maID
;
3873 FactoryFunction
Window::GetUITestFactory() const
3875 return WindowUIObject::create
;
3878 } /* namespace vcl */
3880 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */