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 <sal/config.h>
22 #include <rtl/strbuf.hxx>
23 #include <sal/log.hxx>
25 #include <sal/types.h>
26 #include <tools/diagnose_ex.h>
27 #include <vcl/salgtype.hxx>
28 #include <vcl/event.hxx>
29 #include <vcl/help.hxx>
30 #include <vcl/cursor.hxx>
31 #include <vcl/svapp.hxx>
32 #include <vcl/transfer.hxx>
33 #include <vcl/vclevent.hxx>
34 #include <vcl/window.hxx>
35 #include <vcl/syswin.hxx>
36 #include <vcl/dockwin.hxx>
37 #include <vcl/wall.hxx>
38 #include <vcl/toolkit/fixed.hxx>
39 #include <vcl/taskpanelist.hxx>
40 #include <vcl/toolkit/unowrap.hxx>
41 #include <vcl/lazydelete.hxx>
42 #include <vcl/virdev.hxx>
43 #include <vcl/settings.hxx>
44 #include <vcl/sysdata.hxx>
45 #include <vcl/ptrstyle.hxx>
46 #include <vcl/IDialogRenderable.hxx>
48 #include <vcl/uitest/uiobject.hxx>
50 #include <ImplOutDevData.hxx>
51 #include <impfontcache.hxx>
52 #include <salframe.hxx>
54 #include <salinst.hxx>
60 #include <helpwin.hxx>
62 #include <com/sun/star/accessibility/AccessibleRelation.hpp>
63 #include <com/sun/star/accessibility/XAccessible.hpp>
64 #include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
65 #include <com/sun/star/awt/XWindowPeer.hpp>
66 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
67 #include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
68 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
69 #include <com/sun/star/rendering/CanvasFactory.hpp>
70 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
71 #include <comphelper/lok.hxx>
72 #include <comphelper/processfactory.hxx>
73 #include <unotools/configmgr.hxx>
74 #include <osl/diagnose.h>
75 #include <tools/debug.hxx>
76 #include <tools/json_writer.hxx>
77 #include <boost/property_tree/ptree.hpp>
82 #ifdef _WIN32 // see #140456#
83 #include <win/salframe.h>
86 #include "impldockingwrapper.hxx"
88 using namespace ::com::sun::star::uno
;
89 using namespace ::com::sun::star::lang
;
90 using namespace ::com::sun::star::datatransfer::clipboard
;
91 using namespace ::com::sun::star::datatransfer::dnd
;
95 Window::Window( WindowType nType
)
96 : mpWindowImpl(new WindowImpl( *this, nType
))
98 // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
99 mpWindowImpl
->mxOutDev
->mbEnableRTL
= AllSettings::GetLayoutRTL();
102 Window::Window( vcl::Window
* pParent
, WinBits nStyle
)
103 : mpWindowImpl(new WindowImpl( *this, WindowType::WINDOW
))
105 // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
106 mpWindowImpl
->mxOutDev
->mbEnableRTL
= AllSettings::GetLayoutRTL();
108 ImplInit( pParent
, nStyle
, nullptr );
111 #if OSL_DEBUG_LEVEL > 0
114 OString
lcl_createWindowInfo(const vcl::Window
* pWindow
)
116 // skip border windows, they do not carry information that
117 // would help with diagnosing the problem
118 const vcl::Window
* pTempWin( pWindow
);
119 while ( pTempWin
&& pTempWin
->GetType() == WindowType::BORDERWINDOW
) {
120 pTempWin
= pTempWin
->GetWindow( GetWindowType::FirstChild
);
122 // check if pTempWin is not null, otherwise use the
128 return OString::Concat(" ") +
129 typeid( *pWindow
).name() +
133 RTL_TEXTENCODING_UTF8
140 void Window::dispose()
142 assert( mpWindowImpl
);
143 assert( !mpWindowImpl
->mbInDispose
); // should only be called from disposeOnce()
144 assert( (!mpWindowImpl
->mpParent
||
145 mpWindowImpl
->mpParent
->mpWindowImpl
) &&
146 "vcl::Window child should have its parent disposed first" );
148 // remove Key and Mouse events issued by Application::PostKey/MouseEvent
149 Application::RemoveMouseAndKeyEvents( this );
151 // Dispose of the canvas implementation (which, currently, has an
152 // own wrapper window as a child to this one.
153 GetOutDev()->ImplDisposeCanvas();
155 mpWindowImpl
->mbInDispose
= true;
157 CallEventListeners( VclEventId::ObjectDying
);
159 // do not send child events for frames that were registered as native frames
160 if( !ImplIsAccessibleNativeFrame() && mpWindowImpl
->mbReallyVisible
)
161 if ( ImplIsAccessibleCandidate() && GetAccessibleParentWindow() )
162 GetAccessibleParentWindow()->CallEventListeners( VclEventId::WindowChildDestroyed
, this );
164 // remove associated data structures from dockingmanager
165 ImplGetDockingManager()->RemoveWindow( this );
167 // remove ownerdraw decorated windows from list in the top-most frame window
168 if( (GetStyle() & WB_OWNERDRAWDECORATION
) && mpWindowImpl
->mbFrame
)
170 ::std::vector
< VclPtr
<vcl::Window
> >& rList
= ImplGetOwnerDrawList();
171 auto p
= ::std::find( rList
.begin(), rList
.end(), VclPtr
<vcl::Window
>(this) );
172 if( p
!= rList
.end() )
176 // shutdown drag and drop
177 Reference
< XComponent
> xDnDComponent( mpWindowImpl
->mxDNDListenerContainer
, UNO_QUERY
);
179 if( xDnDComponent
.is() )
180 xDnDComponent
->dispose();
182 if( mpWindowImpl
->mbFrame
&& mpWindowImpl
->mpFrameData
)
186 // deregister drop target listener
187 if( mpWindowImpl
->mpFrameData
->mxDropTargetListener
.is() )
189 Reference
< XDragGestureRecognizer
> xDragGestureRecognizer(mpWindowImpl
->mpFrameData
->mxDragSource
, UNO_QUERY
);
190 if( xDragGestureRecognizer
.is() )
192 xDragGestureRecognizer
->removeDragGestureListener(
193 Reference
< XDragGestureListener
> (mpWindowImpl
->mpFrameData
->mxDropTargetListener
, UNO_QUERY
));
196 mpWindowImpl
->mpFrameData
->mxDropTarget
->removeDropTargetListener( mpWindowImpl
->mpFrameData
->mxDropTargetListener
);
197 mpWindowImpl
->mpFrameData
->mxDropTargetListener
.clear();
200 // shutdown drag and drop for this frame window
201 Reference
< XComponent
> xComponent( mpWindowImpl
->mpFrameData
->mxDropTarget
, UNO_QUERY
);
203 // DNDEventDispatcher does not hold a reference of the DropTarget,
204 // so it's ok if it does not support XComponent
205 if( xComponent
.is() )
206 xComponent
->dispose();
208 catch (const Exception
&)
210 // can be safely ignored here.
214 UnoWrapperBase
* pWrapper
= UnoWrapperBase::GetUnoWrapper( false );
216 pWrapper
->WindowDestroyed( this );
218 // MT: Must be called after WindowDestroyed!
219 // Otherwise, if the accessible is a VCLXWindow, it will try to destroy this window again!
220 // But accessibility implementations from applications need this dispose.
221 if ( mpWindowImpl
->mxAccessible
.is() )
223 Reference
< XComponent
> xC( mpWindowImpl
->mxAccessible
, UNO_QUERY
);
228 ImplSVData
* pSVData
= ImplGetSVData();
230 if ( ImplGetSVHelpData().mpHelpWin
&& (ImplGetSVHelpData().mpHelpWin
->GetParent() == this) )
231 ImplDestroyHelpWindow( true );
233 SAL_WARN_IF(pSVData
->mpWinData
->mpTrackWin
.get() == this, "vcl.window",
234 "Window::~Window(): Window is in TrackingMode");
235 SAL_WARN_IF(IsMouseCaptured(), "vcl.window",
236 "Window::~Window(): Window has the mouse captured");
238 // due to old compatibility
239 if (pSVData
->mpWinData
->mpTrackWin
== this)
241 if (IsMouseCaptured())
244 #if OSL_DEBUG_LEVEL > 0
245 // always perform these tests in debug builds
247 OStringBuffer aErrorStr
;
249 vcl::Window
* pTempWin
;
251 if ( mpWindowImpl
->mpFirstChild
)
253 OStringBuffer aTempStr
= "Window (" +
254 lcl_createWindowInfo(this) +
255 ") with live children destroyed: ";
256 pTempWin
= mpWindowImpl
->mpFirstChild
;
259 aTempStr
.append(lcl_createWindowInfo(pTempWin
));
260 pTempWin
= pTempWin
->mpWindowImpl
->mpNext
;
262 OSL_FAIL( aTempStr
.getStr() );
263 Application::Abort(OStringToOUString(aTempStr
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
)); // abort in debug builds, this must be fixed!
266 if (mpWindowImpl
->mpFrameData
!= nullptr)
268 pTempWin
= mpWindowImpl
->mpFrameData
->mpFirstOverlap
;
271 if ( ImplIsRealParentPath( pTempWin
) )
274 aErrorStr
.append(lcl_createWindowInfo(pTempWin
));
276 pTempWin
= pTempWin
->mpWindowImpl
->mpNextOverlap
;
282 lcl_createWindowInfo(this) +
283 ") with live SystemWindows destroyed: " +
285 OSL_FAIL(aTempStr
.getStr());
286 // abort in debug builds, must be fixed!
287 Application::Abort(OStringToOUString(aTempStr
, RTL_TEXTENCODING_UTF8
));
292 pTempWin
= pSVData
->maFrameData
.mpFirstFrame
;
295 if ( ImplIsRealParentPath( pTempWin
) )
298 aErrorStr
.append(lcl_createWindowInfo(pTempWin
));
300 pTempWin
= pTempWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
304 OString aTempStr
= "Window (" +
305 lcl_createWindowInfo(this) +
306 ") with live SystemWindows destroyed: " +
308 OSL_FAIL( aTempStr
.getStr() );
309 Application::Abort(OStringToOUString(aTempStr
, RTL_TEXTENCODING_UTF8
)); // abort in debug builds, this must be fixed!
312 if ( mpWindowImpl
->mpFirstOverlap
)
314 OStringBuffer aTempStr
= "Window (" +
315 lcl_createWindowInfo(this) +
316 ") with live SystemWindows destroyed: ";
317 pTempWin
= mpWindowImpl
->mpFirstOverlap
;
320 aTempStr
.append(lcl_createWindowInfo(pTempWin
));
321 pTempWin
= pTempWin
->mpWindowImpl
->mpNext
;
323 OSL_FAIL( aTempStr
.getStr() );
324 Application::Abort(OStringToOUString(aTempStr
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
)); // abort in debug builds, this must be fixed!
327 vcl::Window
* pMyParent
= GetParent();
328 SystemWindow
* pMySysWin
= nullptr;
332 if ( pMyParent
->IsSystemWindow() )
334 pMySysWin
= dynamic_cast<SystemWindow
*>(pMyParent
);
336 pMyParent
= pMyParent
->GetParent();
338 if ( pMySysWin
&& pMySysWin
->ImplIsInTaskPaneList( this ) )
340 OString aTempStr
= "Window (" +
341 lcl_createWindowInfo(this) +
342 ") still in TaskPanelList!";
343 OSL_FAIL( aTempStr
.getStr() );
344 Application::Abort(OStringToOUString(aTempStr
, RTL_TEXTENCODING_UTF8
)); // abort in debug builds, this must be fixed!
349 if( mpWindowImpl
->mbIsInTaskPaneList
)
351 vcl::Window
* pMyParent
= GetParent();
352 SystemWindow
* pMySysWin
= nullptr;
356 if ( pMyParent
->IsSystemWindow() )
358 pMySysWin
= dynamic_cast<SystemWindow
*>(pMyParent
);
360 pMyParent
= pMyParent
->GetParent();
362 if ( pMySysWin
&& pMySysWin
->ImplIsInTaskPaneList( this ) )
364 pMySysWin
->GetTaskPaneList()->RemoveWindow( this );
368 SAL_WARN( "vcl", "Window (" << GetText() << ") not found in TaskPanelList");
372 // remove from size-group if necessary
373 remove_from_all_size_groups();
375 // clear mnemonic labels
376 std::vector
<VclPtr
<FixedText
> > aMnemonicLabels(list_mnemonic_labels());
377 for (auto const& mnemonicLabel
: aMnemonicLabels
)
379 remove_mnemonic_label(mnemonicLabel
);
382 // hide window in order to trigger the Paint-Handling
385 // EndExtTextInputMode
386 if (pSVData
->mpWinData
->mpExtTextInputWin
== this)
389 if (pSVData
->mpWinData
->mpExtTextInputWin
== this)
390 pSVData
->mpWinData
->mpExtTextInputWin
= nullptr;
393 // check if the focus window is our child
394 bool bHasFocusedChild
= false;
395 if (pSVData
->mpWinData
->mpFocusWin
&& ImplIsRealParentPath(pSVData
->mpWinData
->mpFocusWin
))
397 // #122232#, this must not happen and is an application bug ! but we try some cleanup to hopefully avoid crashes, see below
398 bHasFocusedChild
= true;
399 #if OSL_DEBUG_LEVEL > 0
400 OUString aTempStr
= "Window (" + GetText() +
401 ") with focused child window destroyed ! THIS WILL LEAD TO CRASHES AND MUST BE FIXED !";
402 SAL_WARN( "vcl", aTempStr
);
403 Application::Abort(aTempStr
); // abort in debug build version, this must be fixed!
407 // if we get focus pass focus to another window
408 vcl::Window
* pOverlapWindow
= ImplGetFirstOverlapWindow();
409 if (pSVData
->mpWinData
->mpFocusWin
== this
410 || bHasFocusedChild
) // #122232#, see above, try some cleanup
412 if ( mpWindowImpl
->mbFrame
)
414 pSVData
->mpWinData
->mpFocusWin
= nullptr;
415 pOverlapWindow
->mpWindowImpl
->mpLastFocusWindow
= nullptr;
419 vcl::Window
* pParent
= GetParent();
420 vcl::Window
* pBorderWindow
= mpWindowImpl
->mpBorderWindow
;
421 // when windows overlap, give focus to the parent
422 // of the next FrameWindow
425 if ( pBorderWindow
->ImplIsOverlapWindow() )
426 pParent
= pBorderWindow
->mpWindowImpl
->mpOverlapWindow
;
428 else if ( ImplIsOverlapWindow() )
429 pParent
= mpWindowImpl
->mpOverlapWindow
;
431 if ( pParent
&& pParent
->IsEnabled() && pParent
->IsInputEnabled() && ! pParent
->IsInModalMode() )
432 pParent
->GrabFocus();
434 mpWindowImpl
->mpFrameWindow
->GrabFocus();
436 // If the focus was set back to 'this' set it to nothing
437 if (pSVData
->mpWinData
->mpFocusWin
== this)
439 pSVData
->mpWinData
->mpFocusWin
= nullptr;
440 pOverlapWindow
->mpWindowImpl
->mpLastFocusWindow
= nullptr;
445 if ( pOverlapWindow
!= nullptr &&
446 pOverlapWindow
->mpWindowImpl
->mpLastFocusWindow
== this )
447 pOverlapWindow
->mpWindowImpl
->mpLastFocusWindow
= nullptr;
449 // reset hint for DefModalDialogParent
450 if( pSVData
->maFrameData
.mpActiveApplicationFrame
== this )
451 pSVData
->maFrameData
.mpActiveApplicationFrame
= nullptr;
453 // reset hint of what was the last wheeled window
454 if (pSVData
->mpWinData
->mpLastWheelWindow
== this)
455 pSVData
->mpWinData
->mpLastWheelWindow
= nullptr;
457 // reset marked windows
458 if ( mpWindowImpl
->mpFrameData
!= nullptr )
460 if ( mpWindowImpl
->mpFrameData
->mpFocusWin
== this )
461 mpWindowImpl
->mpFrameData
->mpFocusWin
= nullptr;
462 if ( mpWindowImpl
->mpFrameData
->mpMouseMoveWin
== this )
463 mpWindowImpl
->mpFrameData
->mpMouseMoveWin
= nullptr;
464 if ( mpWindowImpl
->mpFrameData
->mpMouseDownWin
== this )
465 mpWindowImpl
->mpFrameData
->mpMouseDownWin
= nullptr;
468 // reset Deactivate-Window
469 if (pSVData
->mpWinData
->mpLastDeacWin
== this)
470 pSVData
->mpWinData
->mpLastDeacWin
= nullptr;
472 if ( mpWindowImpl
->mbFrame
&& mpWindowImpl
->mpFrameData
)
474 if ( mpWindowImpl
->mpFrameData
->mnFocusId
)
475 Application::RemoveUserEvent( mpWindowImpl
->mpFrameData
->mnFocusId
);
476 mpWindowImpl
->mpFrameData
->mnFocusId
= nullptr;
477 if ( mpWindowImpl
->mpFrameData
->mnMouseMoveId
)
478 Application::RemoveUserEvent( mpWindowImpl
->mpFrameData
->mnMouseMoveId
);
479 mpWindowImpl
->mpFrameData
->mnMouseMoveId
= nullptr;
482 // release SalGraphics
483 VclPtr
<OutputDevice
> pOutDev
= GetOutDev();
484 pOutDev
->ReleaseGraphics();
486 // remove window from the lists
487 ImplRemoveWindow( true );
489 // de-register as "top window child" at our parent, if necessary
490 if ( mpWindowImpl
->mbFrame
)
493 = mpWindowImpl
->mpWinData
&& (mpWindowImpl
->mpWinData
->mnIsTopWindow
== 1);
494 if ( mpWindowImpl
->mpRealParent
&& bIsTopWindow
)
496 ImplWinData
* pParentWinData
= mpWindowImpl
->mpRealParent
->ImplGetWinData();
498 auto myPos
= ::std::find( pParentWinData
->maTopWindowChildren
.begin(),
499 pParentWinData
->maTopWindowChildren
.end(), VclPtr
<vcl::Window
>(this) );
500 SAL_WARN_IF( myPos
== pParentWinData
->maTopWindowChildren
.end(), "vcl.window", "Window::~Window: inconsistency in top window chain!" );
501 if ( myPos
!= pParentWinData
->maTopWindowChildren
.end() )
502 pParentWinData
->maTopWindowChildren
.erase( myPos
);
506 mpWindowImpl
->mpWinData
.reset();
508 // remove BorderWindow or Frame window data
509 mpWindowImpl
->mpBorderWindow
.disposeAndClear();
510 if ( mpWindowImpl
->mbFrame
)
512 if ( pSVData
->maFrameData
.mpFirstFrame
== this )
513 pSVData
->maFrameData
.mpFirstFrame
= mpWindowImpl
->mpFrameData
->mpNextFrame
;
516 sal_Int32 nWindows
= 0;
517 vcl::Window
* pSysWin
= pSVData
->maFrameData
.mpFirstFrame
;
518 while ( pSysWin
&& pSysWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
.get() != this )
520 pSysWin
= pSysWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
526 assert (mpWindowImpl
->mpFrameData
->mpNextFrame
.get() != pSysWin
);
527 pSysWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
= mpWindowImpl
->mpFrameData
->mpNextFrame
;
529 else // if it is not in the list, we can't remove it.
530 SAL_WARN("vcl.window", "Window " << this << " marked as frame window, "
531 "is missing from list of " << nWindows
<< " frames");
533 if (mpWindowImpl
->mpFrame
) // otherwise exception during init
535 mpWindowImpl
->mpFrame
->SetCallback( nullptr, nullptr );
536 pSVData
->mpDefInst
->DestroyFrame( mpWindowImpl
->mpFrame
);
538 assert (mpWindowImpl
->mpFrameData
->mnFocusId
== nullptr);
539 assert (mpWindowImpl
->mpFrameData
->mnMouseMoveId
== nullptr);
541 mpWindowImpl
->mpFrameData
->mpBuffer
.disposeAndClear();
542 delete mpWindowImpl
->mpFrameData
;
543 mpWindowImpl
->mpFrameData
= nullptr;
546 if (mpWindowImpl
->mxWindowPeer
)
547 mpWindowImpl
->mxWindowPeer
->dispose();
549 // should be the last statements
550 mpWindowImpl
.reset();
552 pOutDev
.disposeAndClear();
553 // just to make loplugin:vclwidgets happy
554 VclReferenceBase::dispose();
562 // We will eventually being removing the inheritance of OutputDevice
563 // from Window. It will be replaced with a transient relationship such
564 // that the OutputDevice is only live for the scope of the Paint method.
565 // In the meantime this can help move us towards a Window use an
566 // OutputDevice, not being one.
568 ::OutputDevice
const* Window::GetOutDev() const
570 return mpWindowImpl
->mxOutDev
.get();
573 ::OutputDevice
* Window::GetOutDev()
575 return mpWindowImpl
->mxOutDev
.get();
578 Color
WindowOutputDevice::GetBackgroundColor() const
580 return mxOwnerWindow
->GetDisplayBackground().GetColor();
583 bool WindowOutputDevice::CanEnableNativeWidget() const
585 return mxOwnerWindow
->IsNativeWidgetEnabled();
588 } /* namespace vcl */
590 WindowImpl::WindowImpl( vcl::Window
& rWindow
, WindowType nType
)
592 mxOutDev
= VclPtr
<vcl::WindowOutputDevice
>::Create(rWindow
);
593 maZoom
= Fraction( 1, 1 );
594 maWinRegion
= vcl::Region(true);
595 maWinClipRegion
= vcl::Region(true);
596 mpWinData
= nullptr; // Extra Window Data, that we don't need for all windows
597 mpFrameData
= nullptr; // Frame Data
598 mpFrame
= nullptr; // Pointer to frame window
600 mpFrameWindow
= nullptr; // window to top level parent (same as frame window)
601 mpOverlapWindow
= nullptr; // first overlap parent
602 mpBorderWindow
= nullptr; // Border-Window
603 mpClientWindow
= nullptr; // Client-Window of a FrameWindow
604 mpParent
= nullptr; // parent (incl. BorderWindow)
605 mpRealParent
= nullptr; // real parent (excl. BorderWindow)
606 mpFirstChild
= nullptr; // first child window
607 mpLastChild
= nullptr; // last child window
608 mpFirstOverlap
= nullptr; // first overlap window (only set in overlap windows)
609 mpLastOverlap
= nullptr; // last overlap window (only set in overlap windows)
610 mpPrev
= nullptr; // prev window
611 mpNext
= nullptr; // next window
612 mpNextOverlap
= nullptr; // next overlap window of frame
613 mpLastFocusWindow
= nullptr; // window for focus restore
614 mpDlgCtrlDownWindow
= nullptr; // window for dialog control
615 mnEventListenersIteratingCount
= 0;
616 mnChildEventListenersIteratingCount
= 0;
617 mpCursor
= nullptr; // cursor
618 maPointer
= PointerStyle::Arrow
;
619 mpVCLXWindow
= nullptr;
620 mpAccessibleInfos
= nullptr;
621 maControlForeground
= COL_TRANSPARENT
; // no foreground set
622 maControlBackground
= COL_TRANSPARENT
; // no background set
623 mnLeftBorder
= 0; // left border
624 mnTopBorder
= 0; // top border
625 mnRightBorder
= 0; // right border
626 mnBottomBorder
= 0; // bottom border
627 mnWidthRequest
= -1; // width request
628 mnHeightRequest
= -1; // height request
629 mnOptimalWidthCache
= -1; // optimal width cache
630 mnOptimalHeightCache
= -1; // optimal height cache
631 mnX
= 0; // X-Position to Parent
632 mnY
= 0; // Y-Position to Parent
633 mnAbsScreenX
= 0; // absolute X-position on screen, used for RTL window positioning
634 mpChildClipRegion
= nullptr; // Child-Clip-Region when ClipChildren
635 mpPaintRegion
= nullptr; // Paint-ClipRegion
636 mnStyle
= 0; // style (init in ImplInitWindow)
637 mnPrevStyle
= 0; // prevstyle (set in SetStyle)
638 mnExtendedStyle
= WindowExtendedStyle::NONE
; // extended style (init in ImplInitWindow)
639 mnType
= nType
; // type
640 mnGetFocusFlags
= GetFocusFlags::NONE
; // Flags for GetFocus()-Call
641 mnWaitCount
= 0; // Wait-Count (>1 == "wait" mouse pointer)
642 mnPaintFlags
= ImplPaintFlags::NONE
; // Flags for ImplCallPaint
643 mnParentClipMode
= ParentClipMode::NONE
; // Flags for Parent-ClipChildren-Mode
644 mnActivateMode
= ActivateModeFlags::NONE
; // Will be converted in System/Overlap-Windows
645 mnDlgCtrlFlags
= DialogControlFlags::NONE
; // DialogControl-Flags
646 meAlwaysInputMode
= AlwaysInputNone
; // AlwaysEnableInput not called
647 meHalign
= VclAlign::Fill
;
648 meValign
= VclAlign::Fill
;
649 mePackType
= VclPackType::Start
;
652 mnGridLeftAttach
= -1;
653 mnGridTopAttach
= -1;
660 mbFrame
= false; // true: Window is a frame window
661 mbBorderWin
= false; // true: Window is a border window
662 mbOverlapWin
= false; // true: Window is an overlap window
663 mbSysWin
= false; // true: SystemWindow is the base class
664 mbDialog
= false; // true: Dialog is the base class
665 mbDockWin
= false; // true: DockingWindow is the base class
666 mbFloatWin
= false; // true: FloatingWindow is the base class
667 mbPushButton
= false; // true: PushButton is the base class
668 mbToolBox
= false; // true: ToolBox is the base class
669 mbMenuFloatingWindow
= false; // true: MenuFloatingWindow is the base class
670 mbToolbarFloatingWindow
= false; // true: ImplPopupFloatWin is the base class, used for subtoolbars
671 mbSplitter
= false; // true: Splitter is the base class
672 mbVisible
= false; // true: Show( true ) called
673 mbOverlapVisible
= false; // true: Hide called for visible window from ImplHideAllOverlapWindow()
674 mbDisabled
= false; // true: Enable( false ) called
675 mbInputDisabled
= false; // true: EnableInput( false ) called
676 mbNoUpdate
= false; // true: SetUpdateMode( false ) called
677 mbNoParentUpdate
= false; // true: SetParentUpdateMode( false ) called
678 mbActive
= false; // true: Window Active
679 mbReallyVisible
= false; // true: this and all parents to an overlapped window are visible
680 mbReallyShown
= false; // true: this and all parents to an overlapped window are shown
681 mbInInitShow
= false; // true: we are in InitShow
682 mbChildPtrOverwrite
= false; // true: PointerStyle overwrites Child-Pointer
683 mbNoPtrVisible
= false; // true: ShowPointer( false ) called
684 mbPaintFrame
= false; // true: Paint is visible, but not painted
685 mbInPaint
= false; // true: Inside PaintHdl
686 mbMouseButtonDown
= false; // true: BaseMouseButtonDown called
687 mbMouseButtonUp
= false; // true: BaseMouseButtonUp called
688 mbKeyInput
= false; // true: BaseKeyInput called
689 mbKeyUp
= false; // true: BaseKeyUp called
690 mbCommand
= false; // true: BaseCommand called
691 mbDefPos
= true; // true: Position is not Set
692 mbDefSize
= true; // true: Size is not Set
693 mbCallMove
= true; // true: Move must be called by Show
694 mbCallResize
= true; // true: Resize must be called by Show
695 mbWaitSystemResize
= true; // true: Wait for System-Resize
696 mbInitWinClipRegion
= true; // true: Calc Window Clip Region
697 mbInitChildRegion
= false; // true: InitChildClipRegion
698 mbWinRegion
= false; // true: Window Region
699 mbClipChildren
= false; // true: Child-window should be clipped
700 mbClipSiblings
= false; // true: Adjacent Child-window should be clipped
701 mbChildTransparent
= false; // true: Child-windows are allowed to switch to transparent (incl. Parent-CLIPCHILDREN)
702 mbPaintTransparent
= false; // true: Paints should be executed on the Parent
703 mbMouseTransparent
= false; // true: Window is transparent for Mouse
704 mbDlgCtrlStart
= false; // true: From here on own Dialog-Control
705 mbFocusVisible
= false; // true: Focus Visible
706 mbUseNativeFocus
= false;
707 mbNativeFocusVisible
= false; // true: native Focus Visible
708 mbInShowFocus
= false; // prevent recursion
709 mbInHideFocus
= false; // prevent recursion
710 mbTrackVisible
= false; // true: Tracking Visible
711 mbControlForeground
= false; // true: Foreground-Property set
712 mbControlBackground
= false; // true: Background-Property set
713 mbAlwaysOnTop
= false; // true: always visible for all others windows
714 mbCompoundControl
= false; // true: Composite Control => Listener...
715 mbCompoundControlHasFocus
= false; // true: Composite Control has focus somewhere
716 mbPaintDisabled
= false; // true: Paint should not be executed
717 mbAllResize
= false; // true: Also sent ResizeEvents with 0,0
718 mbInDispose
= false; // true: We're still in Window::dispose()
719 mbExtTextInput
= false; // true: ExtTextInput-Mode is active
720 mbInFocusHdl
= false; // true: Within GetFocus-Handler
721 mbCreatedWithToolkit
= false;
722 mbSuppressAccessibilityEvents
= false; // true: do not send any accessibility events
723 mbDrawSelectionBackground
= false; // true: draws transparent window background to indicate (toolbox) selection
724 mbIsInTaskPaneList
= false; // true: window was added to the taskpanelist in the topmost system window
725 mnNativeBackground
= ControlPart::NONE
; // initialize later, depends on type
726 mbHelpTextDynamic
= false; // true: append help id in HELP_DEBUG case
727 mbFakeFocusSet
= false; // true: pretend as if the window has focus.
733 mbNonHomogeneous
= false;
734 static bool bDoubleBuffer
= getenv("VCL_DOUBLEBUFFERING_FORCE_ENABLE");
735 mbDoubleBufferingRequested
= bDoubleBuffer
; // when we are not sure, assume it cannot do double-buffering via RenderContext
736 mpLOKNotifier
= nullptr;
738 mbLOKParentNotifier
= false;
741 WindowImpl::~WindowImpl()
743 mpChildClipRegion
.reset();
744 mpAccessibleInfos
.reset();
747 ImplWinData::ImplWinData() :
750 mnCompositionCharRects(0),
751 mnTrackFlags(ShowTrackFlags::NONE
),
752 mnIsTopWindow(sal_uInt16(~0)), // not initialized yet, 0/1 will indicate TopWindow (see IsTopWindow())
754 mbEnableNativeWidget(false)
758 ImplWinData::~ImplWinData()
760 mpCompositionCharRects
.reset();
763 ImplFrameData::ImplFrameData( vcl::Window
*pWindow
)
764 : maPaintIdle( "vcl::Window maPaintIdle" ),
765 maResizeIdle( "vcl::Window maResizeIdle" )
767 ImplSVData
* pSVData
= ImplGetSVData();
768 assert (pSVData
->maFrameData
.mpFirstFrame
.get() != pWindow
);
769 mpNextFrame
= pSVData
->maFrameData
.mpFirstFrame
;
770 pSVData
->maFrameData
.mpFirstFrame
= pWindow
;
771 mpFirstOverlap
= nullptr;
772 mpFocusWin
= nullptr;
773 mpMouseMoveWin
= nullptr;
774 mpMouseDownWin
= nullptr;
775 mxFontCollection
= pSVData
->maGDIData
.mxScreenFontList
;
776 mxFontCache
= pSVData
->maGDIData
.mxScreenFontCache
;
778 mnMouseMoveId
= nullptr;
781 mnBeforeLastMouseX
= -1;
782 mnBeforeLastMouseY
= -1;
785 mnLastMouseWinX
= -1;
786 mnLastMouseWinY
= -1;
790 mnFirstMouseCode
= 0;
792 mnMouseMode
= MouseEventModifiers::NONE
;
794 mbInMouseMove
= false;
796 mbStartDragCalled
= false;
797 mbNeedSysWindow
= false;
799 mbStartFocusState
= false;
800 mbInSysObjFocusHdl
= false;
801 mbInSysObjToTopHdl
= false;
802 mbSysObjFocus
= false;
803 maPaintIdle
.SetPriority( TaskPriority::REPAINT
);
804 maPaintIdle
.SetInvokeHandler( LINK( pWindow
, vcl::Window
, ImplHandlePaintHdl
) );
805 maResizeIdle
.SetPriority( TaskPriority::RESIZE
);
806 maResizeIdle
.SetInvokeHandler( LINK( pWindow
, vcl::Window
, ImplHandleResizeTimerHdl
) );
807 mbInternalDragGestureRecognizer
= false;
808 mbInBufferedPaint
= false;
811 mnTouchPanPosition
= -1;
816 bool WindowOutputDevice::AcquireGraphics() const
818 DBG_TESTSOLARMUTEX();
826 mbInitLineColor
= true;
827 mbInitFillColor
= true;
829 mbInitTextColor
= true;
830 mbInitClipRegion
= true;
832 ImplSVData
* pSVData
= ImplGetSVData();
834 mpGraphics
= mxOwnerWindow
->mpWindowImpl
->mpFrame
->AcquireGraphics();
835 // try harder if no wingraphics was available directly
838 // find another output device in the same frame
839 vcl::WindowOutputDevice
* pReleaseOutDev
= pSVData
->maGDIData
.mpLastWinGraphics
.get();
840 while ( pReleaseOutDev
)
842 if ( pReleaseOutDev
->mxOwnerWindow
&& pReleaseOutDev
->mxOwnerWindow
->mpWindowImpl
->mpFrame
== mxOwnerWindow
->mpWindowImpl
->mpFrame
)
844 pReleaseOutDev
= static_cast<vcl::WindowOutputDevice
*>(pReleaseOutDev
->mpPrevGraphics
.get());
847 if ( pReleaseOutDev
)
849 // steal the wingraphics from the other outdev
850 mpGraphics
= pReleaseOutDev
->mpGraphics
;
851 pReleaseOutDev
->ReleaseGraphics( false );
855 // if needed retry after releasing least recently used wingraphics
856 while ( !mpGraphics
)
858 if ( !pSVData
->maGDIData
.mpLastWinGraphics
)
860 pSVData
->maGDIData
.mpLastWinGraphics
->ReleaseGraphics();
861 mpGraphics
= mxOwnerWindow
->mpWindowImpl
->mpFrame
->AcquireGraphics();
868 // update global LRU list of wingraphics
869 mpNextGraphics
= pSVData
->maGDIData
.mpFirstWinGraphics
.get();
870 pSVData
->maGDIData
.mpFirstWinGraphics
= const_cast<vcl::WindowOutputDevice
*>(this);
871 if ( mpNextGraphics
)
872 mpNextGraphics
->mpPrevGraphics
= const_cast<vcl::WindowOutputDevice
*>(this);
873 if ( !pSVData
->maGDIData
.mpLastWinGraphics
)
874 pSVData
->maGDIData
.mpLastWinGraphics
= const_cast<vcl::WindowOutputDevice
*>(this);
876 mpGraphics
->SetXORMode( (RasterOp::Invert
== meRasterOp
) || (RasterOp::Xor
== meRasterOp
), RasterOp::Invert
== meRasterOp
);
877 mpGraphics
->setAntiAlias(bool(mnAntialiasing
& AntialiasingFlags::Enable
));
880 return mpGraphics
!= nullptr;
883 void WindowOutputDevice::ReleaseGraphics( bool bRelease
)
885 DBG_TESTSOLARMUTEX();
890 // release the fonts of the physically released graphics device
894 ImplSVData
* pSVData
= ImplGetSVData();
896 vcl::Window
* pWindow
= mxOwnerWindow
.get();
901 pWindow
->mpWindowImpl
->mpFrame
->ReleaseGraphics( mpGraphics
);
902 // remove from global LRU list of window graphics
903 if ( mpPrevGraphics
)
904 mpPrevGraphics
->mpNextGraphics
= mpNextGraphics
;
906 pSVData
->maGDIData
.mpFirstWinGraphics
= static_cast<vcl::WindowOutputDevice
*>(mpNextGraphics
.get());
907 if ( mpNextGraphics
)
908 mpNextGraphics
->mpPrevGraphics
= mpPrevGraphics
;
910 pSVData
->maGDIData
.mpLastWinGraphics
= static_cast<vcl::WindowOutputDevice
*>(mpPrevGraphics
.get());
912 mpGraphics
= nullptr;
913 mpPrevGraphics
= nullptr;
914 mpNextGraphics
= nullptr;
917 static sal_Int32
CountDPIScaleFactor(sal_Int32 nDPI
)
920 // Setting of HiDPI is unfortunately all only a heuristic; and to add
921 // insult to an injury, the system is constantly lying to us about
922 // the DPI and whatnot
923 // eg. fdo#77059 - set the value from which we do consider the
924 // screen HiDPI to greater than 168
925 if (nDPI
> 216) // 96 * 2 + 96 / 4
927 else if (nDPI
> 168) // 96 * 2 - 96 / 4
929 else if (nDPI
> 120) // 96 * 1.5 - 96 / 4
938 void Window::ImplInit( vcl::Window
* pParent
, WinBits nStyle
, SystemParentData
* pSystemParentData
)
940 SAL_WARN_IF( !mpWindowImpl
->mbFrame
&& !pParent
&& GetType() != WindowType::FIXEDIMAGE
, "vcl.window",
941 "Window::Window(): pParent == NULL" );
943 ImplSVData
* pSVData
= ImplGetSVData();
944 vcl::Window
* pRealParent
= pParent
;
947 if ( !mpWindowImpl
->mbOverlapWin
&& pParent
&& (pParent
->GetStyle() & WB_3DLOOK
) )
950 // create border window if necessary
951 if ( !mpWindowImpl
->mbFrame
&& !mpWindowImpl
->mbBorderWin
&& !mpWindowImpl
->mpBorderWindow
952 && (nStyle
& (WB_BORDER
| WB_SYSTEMCHILDWINDOW
) ) )
954 BorderWindowStyle nBorderTypeStyle
= BorderWindowStyle::NONE
;
955 if( nStyle
& WB_SYSTEMCHILDWINDOW
)
957 // handle WB_SYSTEMCHILDWINDOW
958 // these should be analogous to a top level frame; meaning they
959 // should have a border window with style BorderWindowStyle::Frame
960 // which controls their size
961 nBorderTypeStyle
|= BorderWindowStyle::Frame
;
964 VclPtrInstance
<ImplBorderWindow
> pBorderWin( pParent
, nStyle
& (WB_BORDER
| WB_DIALOGCONTROL
| WB_NODIALOGCONTROL
), nBorderTypeStyle
);
965 static_cast<vcl::Window
*>(pBorderWin
)->mpWindowImpl
->mpClientWindow
= this;
966 pBorderWin
->GetBorder( mpWindowImpl
->mnLeftBorder
, mpWindowImpl
->mnTopBorder
, mpWindowImpl
->mnRightBorder
, mpWindowImpl
->mnBottomBorder
);
967 mpWindowImpl
->mpBorderWindow
= pBorderWin
;
968 pParent
= mpWindowImpl
->mpBorderWindow
;
970 else if( !mpWindowImpl
->mbFrame
&& ! pParent
)
972 mpWindowImpl
->mbOverlapWin
= true;
973 mpWindowImpl
->mbFrame
= true;
976 // insert window in list
977 ImplInsertWindow( pParent
);
978 mpWindowImpl
->mnStyle
= nStyle
;
980 if( pParent
&& ! mpWindowImpl
->mbFrame
)
981 mpWindowImpl
->mxOutDev
->mbEnableRTL
= AllSettings::GetLayoutRTL();
983 // test for frame creation
984 if ( mpWindowImpl
->mbFrame
)
987 SalFrameStyleFlags nFrameStyle
= SalFrameStyleFlags::NONE
;
989 if ( nStyle
& WB_MOVEABLE
)
990 nFrameStyle
|= SalFrameStyleFlags::MOVEABLE
;
991 if ( nStyle
& WB_SIZEABLE
)
992 nFrameStyle
|= SalFrameStyleFlags::SIZEABLE
;
993 if ( nStyle
& WB_CLOSEABLE
)
994 nFrameStyle
|= SalFrameStyleFlags::CLOSEABLE
;
995 if ( nStyle
& WB_APP
)
996 nFrameStyle
|= SalFrameStyleFlags::DEFAULT
;
997 // check for undecorated floating window
998 if( // 1. floating windows that are not moveable/sizeable (only closeable allowed)
999 ( !(nFrameStyle
& ~SalFrameStyleFlags::CLOSEABLE
) &&
1000 ( mpWindowImpl
->mbFloatWin
|| ((GetType() == WindowType::BORDERWINDOW
) && static_cast<ImplBorderWindow
*>(this)->mbFloatWindow
) || (nStyle
& WB_SYSTEMFLOATWIN
) ) ) ||
1001 // 2. borderwindows of floaters with ownerdraw decoration
1002 ((GetType() == WindowType::BORDERWINDOW
) && static_cast<ImplBorderWindow
*>(this)->mbFloatWindow
&& (nStyle
& WB_OWNERDRAWDECORATION
) ) )
1004 nFrameStyle
= SalFrameStyleFlags::FLOAT
;
1005 if( nStyle
& WB_OWNERDRAWDECORATION
)
1006 nFrameStyle
|= SalFrameStyleFlags::OWNERDRAWDECORATION
| SalFrameStyleFlags::NOSHADOW
;
1008 else if( mpWindowImpl
->mbFloatWin
)
1009 nFrameStyle
|= SalFrameStyleFlags::TOOLWINDOW
;
1011 if( nStyle
& WB_INTROWIN
)
1012 nFrameStyle
|= SalFrameStyleFlags::INTRO
;
1013 if( nStyle
& WB_TOOLTIPWIN
)
1014 nFrameStyle
|= SalFrameStyleFlags::TOOLTIP
;
1016 if( nStyle
& WB_NOSHADOW
)
1017 nFrameStyle
|= SalFrameStyleFlags::NOSHADOW
;
1019 if( nStyle
& WB_SYSTEMCHILDWINDOW
)
1020 nFrameStyle
|= SalFrameStyleFlags::SYSTEMCHILD
;
1022 switch (mpWindowImpl
->mnType
)
1024 case WindowType::DIALOG
:
1025 case WindowType::TABDIALOG
:
1026 case WindowType::MODELESSDIALOG
:
1027 case WindowType::MESSBOX
:
1028 case WindowType::INFOBOX
:
1029 case WindowType::WARNINGBOX
:
1030 case WindowType::ERRORBOX
:
1031 case WindowType::QUERYBOX
:
1032 nFrameStyle
|= SalFrameStyleFlags::DIALOG
;
1038 // tdf#144624 for the DefaultWindow, which is never visible, don't
1039 // create an icon for it so construction of a DefaultWindow cannot
1040 // trigger creation of a VirtualDevice which itself requires a
1041 // DefaultWindow to exist
1042 if( nStyle
& WB_DEFAULTWIN
)
1043 nFrameStyle
|= SalFrameStyleFlags::NOICON
;
1045 SalFrame
* pParentFrame
= nullptr;
1047 pParentFrame
= pParent
->mpWindowImpl
->mpFrame
;
1049 if ( pSystemParentData
)
1050 pFrame
= pSVData
->mpDefInst
->CreateChildFrame( pSystemParentData
, nFrameStyle
| SalFrameStyleFlags::PLUG
);
1052 pFrame
= pSVData
->mpDefInst
->CreateFrame( pParentFrame
, nFrameStyle
);
1055 // do not abort but throw an exception, may be the current thread terminates anyway (plugin-scenario)
1056 throw RuntimeException(
1057 "Could not create system window!",
1058 Reference
< XInterface
>() );
1061 pFrame
->SetCallback( this, ImplWindowFrameProc
);
1063 // set window frame data
1064 mpWindowImpl
->mpFrameData
= new ImplFrameData( this );
1065 mpWindowImpl
->mpFrame
= pFrame
;
1066 mpWindowImpl
->mpFrameWindow
= this;
1067 mpWindowImpl
->mpOverlapWindow
= this;
1069 if (!(nStyle
& WB_DEFAULTWIN
) && mpWindowImpl
->mbDoubleBufferingRequested
)
1070 RequestDoubleBuffering(true);
1072 if ( pRealParent
&& IsTopWindow() )
1074 ImplWinData
* pParentWinData
= pRealParent
->ImplGetWinData();
1075 pParentWinData
->maTopWindowChildren
.emplace_back(this );
1080 mpWindowImpl
->mpRealParent
= pRealParent
;
1082 // #99318: make sure fontcache and list is available before call to SetSettings
1083 mpWindowImpl
->mxOutDev
->mxFontCollection
= mpWindowImpl
->mpFrameData
->mxFontCollection
;
1084 mpWindowImpl
->mxOutDev
->mxFontCache
= mpWindowImpl
->mpFrameData
->mxFontCache
;
1086 if ( mpWindowImpl
->mbFrame
)
1090 mpWindowImpl
->mpFrameData
->mnDPIX
= pParent
->mpWindowImpl
->mpFrameData
->mnDPIX
;
1091 mpWindowImpl
->mpFrameData
->mnDPIY
= pParent
->mpWindowImpl
->mpFrameData
->mnDPIY
;
1095 OutputDevice
*pOutDev
= GetOutDev();
1096 if ( pOutDev
->AcquireGraphics() )
1098 mpWindowImpl
->mxOutDev
->mpGraphics
->GetResolution( mpWindowImpl
->mpFrameData
->mnDPIX
, mpWindowImpl
->mpFrameData
->mnDPIY
);
1102 // add ownerdraw decorated frame windows to list in the top-most frame window
1103 // so they can be hidden on lose focus
1104 if( nStyle
& WB_OWNERDRAWDECORATION
)
1105 ImplGetOwnerDrawList().emplace_back(this );
1107 // delay settings initialization until first "real" frame
1108 // this relies on the IntroWindow not needing any system settings
1109 if ( !pSVData
->maAppData
.mbSettingsInit
&&
1110 ! (nStyle
& (WB_INTROWIN
|WB_DEFAULTWIN
))
1113 // side effect: ImplUpdateGlobalSettings does an ImplGetFrame()->UpdateSettings
1114 ImplUpdateGlobalSettings( *pSVData
->maAppData
.mxSettings
);
1115 mpWindowImpl
->mxOutDev
->SetSettings( *pSVData
->maAppData
.mxSettings
);
1116 pSVData
->maAppData
.mbSettingsInit
= true;
1119 // If we create a Window with default size, query this
1120 // size directly, because we want resize all Controls to
1121 // the correct size before we display the window
1122 if ( nStyle
& (WB_MOVEABLE
| WB_SIZEABLE
| WB_APP
) )
1123 mpWindowImpl
->mpFrame
->GetClientSize( mpWindowImpl
->mxOutDev
->mnOutWidth
, mpWindowImpl
->mxOutDev
->mnOutHeight
);
1129 if ( !ImplIsOverlapWindow() )
1131 mpWindowImpl
->mbDisabled
= pParent
->mpWindowImpl
->mbDisabled
;
1132 mpWindowImpl
->mbInputDisabled
= pParent
->mpWindowImpl
->mbInputDisabled
;
1133 mpWindowImpl
->meAlwaysInputMode
= pParent
->mpWindowImpl
->meAlwaysInputMode
;
1136 if (!utl::ConfigManager::IsFuzzing())
1138 // we don't want to call the WindowOutputDevice override of this because
1139 // it calls back into us.
1140 mpWindowImpl
->mxOutDev
->OutputDevice::SetSettings( pParent
->GetSettings() );
1146 // setup the scale factor for HiDPI displays
1147 mpWindowImpl
->mxOutDev
->mnDPIScalePercentage
= CountDPIScaleFactor(mpWindowImpl
->mpFrameData
->mnDPIY
);
1148 mpWindowImpl
->mxOutDev
->mnDPIX
= mpWindowImpl
->mpFrameData
->mnDPIX
;
1149 mpWindowImpl
->mxOutDev
->mnDPIY
= mpWindowImpl
->mpFrameData
->mnDPIY
;
1151 if (!utl::ConfigManager::IsFuzzing())
1153 const StyleSettings
& rStyleSettings
= mpWindowImpl
->mxOutDev
->mxSettings
->GetStyleSettings();
1154 mpWindowImpl
->mxOutDev
->maFont
= rStyleSettings
.GetAppFont();
1156 if ( nStyle
& WB_3DLOOK
)
1158 SetTextColor( rStyleSettings
.GetButtonTextColor() );
1159 SetBackground( Wallpaper( rStyleSettings
.GetFaceColor() ) );
1163 SetTextColor( rStyleSettings
.GetWindowTextColor() );
1164 SetBackground( Wallpaper( rStyleSettings
.GetWindowColor() ) );
1169 mpWindowImpl
->mxOutDev
->maFont
= OutputDevice::GetDefaultFont( DefaultFontType::FIXED
, LANGUAGE_ENGLISH_US
, GetDefaultFontFlags::NONE
);
1172 ImplPointToLogic(*GetOutDev(), mpWindowImpl
->mxOutDev
->maFont
);
1174 (void)ImplUpdatePos();
1176 // calculate app font res (except for the Intro Window or the default window)
1177 if ( mpWindowImpl
->mbFrame
&& !pSVData
->maGDIData
.mnAppFontX
&& ! (nStyle
& (WB_INTROWIN
|WB_DEFAULTWIN
)) )
1178 ImplInitAppFontData( this );
1181 void Window::ImplInitAppFontData( vcl::Window
const * pWindow
)
1183 ImplSVData
* pSVData
= ImplGetSVData();
1184 tools::Long nTextHeight
= pWindow
->GetTextHeight();
1185 tools::Long nTextWidth
= pWindow
->approximate_char_width() * 8;
1186 tools::Long nSymHeight
= nTextHeight
*4;
1187 // Make the basis wider if the font is too narrow
1188 // such that the dialog looks symmetrical and does not become too narrow.
1189 // Add some extra space when the dialog has the same width,
1190 // as a little more space is better.
1191 if ( nSymHeight
> nTextWidth
)
1192 nTextWidth
= nSymHeight
;
1193 else if ( nSymHeight
+5 > nTextWidth
)
1194 nTextWidth
= nSymHeight
+5;
1195 pSVData
->maGDIData
.mnAppFontX
= nTextWidth
* 10 / 8;
1196 pSVData
->maGDIData
.mnAppFontY
= nTextHeight
* 10;
1199 // FIXME: this is currently only on macOS, check with other
1201 if( pSVData
->maNWFData
.mbNoFocusRects
)
1203 // try to find out whether there is a large correction
1204 // of control sizes, if yes, make app font scalings larger
1205 // so dialog positioning is not completely off
1206 ImplControlValue aControlValue
;
1207 tools::Rectangle
aCtrlRegion( Point(), Size( nTextWidth
< 10 ? 10 : nTextWidth
, nTextHeight
< 10 ? 10 : nTextHeight
) );
1208 tools::Rectangle
aBoundingRgn( aCtrlRegion
);
1209 tools::Rectangle
aContentRgn( aCtrlRegion
);
1210 if( pWindow
->GetNativeControlRegion( ControlType::Editbox
, ControlPart::Entire
, aCtrlRegion
,
1211 ControlState::ENABLED
, aControlValue
,
1212 aBoundingRgn
, aContentRgn
) )
1214 // comment: the magical +6 is for the extra border in bordered
1215 // (which is the standard) edit fields
1216 if( aContentRgn
.GetHeight() - nTextHeight
> (nTextHeight
+4)/4 )
1217 pSVData
->maGDIData
.mnAppFontY
= (aContentRgn
.GetHeight()-4) * 10;
1223 ImplWinData
* Window::ImplGetWinData() const
1225 if (!mpWindowImpl
->mpWinData
)
1227 static const char* pNoNWF
= getenv( "SAL_NO_NWF" );
1229 const_cast<vcl::Window
*>(this)->mpWindowImpl
->mpWinData
.reset(new ImplWinData
);
1230 mpWindowImpl
->mpWinData
->mbEnableNativeWidget
= !(pNoNWF
&& *pNoNWF
); // true: try to draw this control with native theme API
1233 return mpWindowImpl
->mpWinData
.get();
1237 void WindowOutputDevice::CopyDeviceArea( SalTwoRect
& aPosAry
, bool bWindowInvalidate
)
1239 if (aPosAry
.mnSrcWidth
== 0 || aPosAry
.mnSrcHeight
== 0 || aPosAry
.mnDestWidth
== 0 || aPosAry
.mnDestHeight
== 0)
1242 if (bWindowInvalidate
)
1244 const tools::Rectangle
aSrcRect(Point(aPosAry
.mnSrcX
, aPosAry
.mnSrcY
),
1245 Size(aPosAry
.mnSrcWidth
, aPosAry
.mnSrcHeight
));
1247 mxOwnerWindow
->ImplMoveAllInvalidateRegions(aSrcRect
,
1248 aPosAry
.mnDestX
-aPosAry
.mnSrcX
,
1249 aPosAry
.mnDestY
-aPosAry
.mnSrcY
,
1252 mpGraphics
->CopyArea(aPosAry
.mnDestX
, aPosAry
.mnDestY
,
1253 aPosAry
.mnSrcX
, aPosAry
.mnSrcY
,
1254 aPosAry
.mnSrcWidth
, aPosAry
.mnSrcHeight
,
1260 OutputDevice::CopyDeviceArea(aPosAry
, bWindowInvalidate
);
1263 const OutputDevice
* WindowOutputDevice::DrawOutDevDirectCheck(const OutputDevice
& rSrcDev
) const
1265 const OutputDevice
* pSrcDevChecked
;
1266 if ( this == &rSrcDev
)
1267 pSrcDevChecked
= nullptr;
1268 else if (GetOutDevType() != rSrcDev
.GetOutDevType())
1269 pSrcDevChecked
= &rSrcDev
;
1270 else if (mxOwnerWindow
->mpWindowImpl
->mpFrameWindow
== static_cast<const vcl::WindowOutputDevice
&>(rSrcDev
).mxOwnerWindow
->mpWindowImpl
->mpFrameWindow
)
1271 pSrcDevChecked
= nullptr;
1273 pSrcDevChecked
= &rSrcDev
;
1275 return pSrcDevChecked
;
1278 void WindowOutputDevice::DrawOutDevDirectProcess( const OutputDevice
& rSrcDev
, SalTwoRect
& rPosAry
, SalGraphics
* pSrcGraphics
)
1281 mpGraphics
->CopyBits(rPosAry
, *pSrcGraphics
, *this, rSrcDev
);
1283 mpGraphics
->CopyBits(rPosAry
, *this);
1286 SalGraphics
* Window::ImplGetFrameGraphics() const
1288 if ( mpWindowImpl
->mpFrameWindow
->GetOutDev()->mpGraphics
)
1290 mpWindowImpl
->mpFrameWindow
->GetOutDev()->mbInitClipRegion
= true;
1294 OutputDevice
* pFrameWinOutDev
= mpWindowImpl
->mpFrameWindow
->GetOutDev();
1295 if ( ! pFrameWinOutDev
->AcquireGraphics() )
1300 mpWindowImpl
->mpFrameWindow
->GetOutDev()->mpGraphics
->ResetClipRegion();
1301 return mpWindowImpl
->mpFrameWindow
->GetOutDev()->mpGraphics
;
1304 void Window::ImplSetReallyVisible()
1306 // #i43594# it is possible that INITSHOW was never send, because the visibility state changed between
1307 // ImplCallInitShow() and ImplSetReallyVisible() when called from Show()
1308 // mbReallyShown is a useful indicator
1309 if( !mpWindowImpl
->mbReallyShown
)
1312 bool bBecameReallyVisible
= !mpWindowImpl
->mbReallyVisible
;
1314 GetOutDev()->mbDevOutput
= true;
1315 mpWindowImpl
->mbReallyVisible
= true;
1316 mpWindowImpl
->mbReallyShown
= true;
1318 // the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge.
1319 // For this, the data member of the event must not be NULL.
1320 // Previously, we did this in Window::Show, but there some events got lost in certain situations. Now
1321 // we're doing it when the visibility really changes
1322 if( bBecameReallyVisible
&& ImplIsAccessibleCandidate() )
1323 CallEventListeners( VclEventId::WindowShow
, this );
1324 // TODO. It's kind of a hack that we're re-using the VclEventId::WindowShow. Normally, we should
1325 // introduce another event which explicitly triggers the Accessibility implementations.
1327 vcl::Window
* pWindow
= mpWindowImpl
->mpFirstOverlap
;
1330 if ( pWindow
->mpWindowImpl
->mbVisible
)
1331 pWindow
->ImplSetReallyVisible();
1332 pWindow
= pWindow
->mpWindowImpl
->mpNext
;
1335 pWindow
= mpWindowImpl
->mpFirstChild
;
1338 if ( pWindow
->mpWindowImpl
->mbVisible
)
1339 pWindow
->ImplSetReallyVisible();
1340 pWindow
= pWindow
->mpWindowImpl
->mpNext
;
1344 void Window::ImplInitResolutionSettings()
1346 // recalculate AppFont-resolution and DPI-resolution
1347 if (mpWindowImpl
->mbFrame
)
1349 GetOutDev()->mnDPIX
= mpWindowImpl
->mpFrameData
->mnDPIX
;
1350 GetOutDev()->mnDPIY
= mpWindowImpl
->mpFrameData
->mnDPIY
;
1352 // setup the scale factor for HiDPI displays
1353 GetOutDev()->mnDPIScalePercentage
= CountDPIScaleFactor(mpWindowImpl
->mpFrameData
->mnDPIY
);
1354 const StyleSettings
& rStyleSettings
= GetOutDev()->mxSettings
->GetStyleSettings();
1355 SetPointFont(*GetOutDev(), rStyleSettings
.GetAppFont());
1357 else if ( mpWindowImpl
->mpParent
)
1359 GetOutDev()->mnDPIX
= mpWindowImpl
->mpParent
->GetOutDev()->mnDPIX
;
1360 GetOutDev()->mnDPIY
= mpWindowImpl
->mpParent
->GetOutDev()->mnDPIY
;
1361 GetOutDev()->mnDPIScalePercentage
= mpWindowImpl
->mpParent
->GetOutDev()->mnDPIScalePercentage
;
1364 // update the recalculated values for logical units
1365 // and also tools belonging to the values
1366 if (IsMapModeEnabled())
1368 MapMode aMapMode
= GetMapMode();
1370 SetMapMode( aMapMode
);
1374 void Window::ImplPointToLogic(vcl::RenderContext
const & rRenderContext
, vcl::Font
& rFont
) const
1376 Size aSize
= rFont
.GetFontSize();
1380 aSize
.setWidth( aSize
.Width() * ( mpWindowImpl
->mpFrameData
->mnDPIX
) );
1381 aSize
.AdjustWidth(72 / 2 );
1382 aSize
.setWidth( aSize
.Width() / 72 );
1384 aSize
.setHeight( aSize
.Height() * ( mpWindowImpl
->mpFrameData
->mnDPIY
) );
1385 aSize
.AdjustHeight(72/2 );
1386 aSize
.setHeight( aSize
.Height() / 72 );
1388 if (rRenderContext
.IsMapModeEnabled())
1389 aSize
= rRenderContext
.PixelToLogic(aSize
);
1391 rFont
.SetFontSize(aSize
);
1394 void Window::ImplLogicToPoint(vcl::RenderContext
const & rRenderContext
, vcl::Font
& rFont
) const
1396 Size aSize
= rFont
.GetFontSize();
1398 if (rRenderContext
.IsMapModeEnabled())
1399 aSize
= rRenderContext
.LogicToPixel(aSize
);
1403 aSize
.setWidth( aSize
.Width() * 72 );
1404 aSize
.AdjustWidth(mpWindowImpl
->mpFrameData
->mnDPIX
/ 2 );
1405 aSize
.setWidth( aSize
.Width() / ( mpWindowImpl
->mpFrameData
->mnDPIX
) );
1407 aSize
.setHeight( aSize
.Height() * 72 );
1408 aSize
.AdjustHeight(mpWindowImpl
->mpFrameData
->mnDPIY
/ 2 );
1409 aSize
.setHeight( aSize
.Height() / ( mpWindowImpl
->mpFrameData
->mnDPIY
) );
1411 rFont
.SetFontSize(aSize
);
1414 bool Window::ImplUpdatePos()
1416 bool bSysChild
= false;
1418 if ( ImplIsOverlapWindow() )
1420 GetOutDev()->mnOutOffX
= mpWindowImpl
->mnX
;
1421 GetOutDev()->mnOutOffY
= mpWindowImpl
->mnY
;
1425 vcl::Window
* pParent
= ImplGetParent();
1427 GetOutDev()->mnOutOffX
= mpWindowImpl
->mnX
+ pParent
->GetOutDev()->mnOutOffX
;
1428 GetOutDev()->mnOutOffY
= mpWindowImpl
->mnY
+ pParent
->GetOutDev()->mnOutOffY
;
1431 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
1434 if ( pChild
->ImplUpdatePos() )
1436 pChild
= pChild
->mpWindowImpl
->mpNext
;
1439 if ( mpWindowImpl
->mpSysObj
)
1445 void Window::ImplUpdateSysObjPos()
1447 if ( mpWindowImpl
->mpSysObj
)
1448 mpWindowImpl
->mpSysObj
->SetPosSize( GetOutDev()->mnOutOffX
, GetOutDev()->mnOutOffY
, GetOutDev()->mnOutWidth
, GetOutDev()->mnOutHeight
);
1450 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
1453 pChild
->ImplUpdateSysObjPos();
1454 pChild
= pChild
->mpWindowImpl
->mpNext
;
1458 void Window::ImplPosSizeWindow( tools::Long nX
, tools::Long nY
,
1459 tools::Long nWidth
, tools::Long nHeight
, PosSizeFlags nFlags
)
1461 bool bNewPos
= false;
1462 bool bNewSize
= false;
1463 bool bCopyBits
= false;
1464 tools::Long nOldOutOffX
= GetOutDev()->mnOutOffX
;
1465 tools::Long nOldOutOffY
= GetOutDev()->mnOutOffY
;
1466 tools::Long nOldOutWidth
= GetOutDev()->mnOutWidth
;
1467 tools::Long nOldOutHeight
= GetOutDev()->mnOutHeight
;
1468 std::unique_ptr
<vcl::Region
> pOverlapRegion
;
1469 std::unique_ptr
<vcl::Region
> pOldRegion
;
1471 if ( IsReallyVisible() )
1473 tools::Rectangle
aOldWinRect( Point( nOldOutOffX
, nOldOutOffY
),
1474 Size( nOldOutWidth
, nOldOutHeight
) );
1475 pOldRegion
.reset( new vcl::Region( aOldWinRect
) );
1476 if ( mpWindowImpl
->mbWinRegion
)
1477 pOldRegion
->Intersect( GetOutDev()->ImplPixelToDevicePixel( mpWindowImpl
->maWinRegion
) );
1479 if ( GetOutDev()->mnOutWidth
&& GetOutDev()->mnOutHeight
&& !mpWindowImpl
->mbPaintTransparent
&&
1480 !mpWindowImpl
->mbInitWinClipRegion
&& !mpWindowImpl
->maWinClipRegion
.IsEmpty() &&
1485 bool bnXRecycled
= false; // avoid duplicate mirroring in RTL case
1486 if ( nFlags
& PosSizeFlags::Width
)
1488 if(!( nFlags
& PosSizeFlags::X
))
1490 nX
= mpWindowImpl
->mnX
;
1491 nFlags
|= PosSizeFlags::X
;
1492 bnXRecycled
= true; // we're using a mnX which was already mirrored in RTL case
1497 if ( nWidth
!= GetOutDev()->mnOutWidth
)
1499 GetOutDev()->mnOutWidth
= nWidth
;
1504 if ( nFlags
& PosSizeFlags::Height
)
1508 if ( nHeight
!= GetOutDev()->mnOutHeight
)
1510 GetOutDev()->mnOutHeight
= nHeight
;
1516 if ( nFlags
& PosSizeFlags::X
)
1518 tools::Long nOrgX
= nX
;
1519 Point
aPtDev( Point( nX
+GetOutDev()->mnOutOffX
, 0 ) );
1520 OutputDevice
*pOutDev
= GetOutDev();
1521 if( pOutDev
->HasMirroredGraphics() )
1523 aPtDev
.setX( GetOutDev()->mpGraphics
->mirror2( aPtDev
.X(), *GetOutDev() ) );
1525 // #106948# always mirror our pos if our parent is not mirroring, even
1526 // if we are also not mirroring
1527 // RTL: check if parent is in different coordinates
1528 if( !bnXRecycled
&& mpWindowImpl
->mpParent
&& !mpWindowImpl
->mpParent
->mpWindowImpl
->mbFrame
&& mpWindowImpl
->mpParent
->GetOutDev()->ImplIsAntiparallel() )
1530 nX
= mpWindowImpl
->mpParent
->GetOutDev()->mnOutWidth
- GetOutDev()->mnOutWidth
- nX
;
1532 /* #i99166# An LTR window in RTL UI that gets sized only would be
1533 expected to not moved its upper left point
1537 if( GetOutDev()->ImplIsAntiparallel() )
1539 aPtDev
.setX( mpWindowImpl
->mnAbsScreenX
);
1540 nOrgX
= mpWindowImpl
->maPos
.X();
1544 else if( !bnXRecycled
&& mpWindowImpl
->mpParent
&& !mpWindowImpl
->mpParent
->mpWindowImpl
->mbFrame
&& mpWindowImpl
->mpParent
->GetOutDev()->ImplIsAntiparallel() )
1546 // mirrored window in LTR UI
1547 nX
= mpWindowImpl
->mpParent
->GetOutDev()->mnOutWidth
- GetOutDev()->mnOutWidth
- nX
;
1550 // check maPos as well, as it could have been changed for client windows (ImplCallMove())
1551 if ( mpWindowImpl
->mnAbsScreenX
!= aPtDev
.X() || nX
!= mpWindowImpl
->mnX
|| nOrgX
!= mpWindowImpl
->maPos
.X() )
1553 if ( bCopyBits
&& !pOverlapRegion
)
1555 pOverlapRegion
.reset( new vcl::Region() );
1556 ImplCalcOverlapRegion( GetOutputRectPixel(),
1557 *pOverlapRegion
, false, true );
1559 mpWindowImpl
->mnX
= nX
;
1560 mpWindowImpl
->maPos
.setX( nOrgX
);
1561 mpWindowImpl
->mnAbsScreenX
= aPtDev
.X();
1565 if ( nFlags
& PosSizeFlags::Y
)
1567 // check maPos as well, as it could have been changed for client windows (ImplCallMove())
1568 if ( nY
!= mpWindowImpl
->mnY
|| nY
!= mpWindowImpl
->maPos
.Y() )
1570 if ( bCopyBits
&& !pOverlapRegion
)
1572 pOverlapRegion
.reset( new vcl::Region() );
1573 ImplCalcOverlapRegion( GetOutputRectPixel(),
1574 *pOverlapRegion
, false, true );
1576 mpWindowImpl
->mnY
= nY
;
1577 mpWindowImpl
->maPos
.setY( nY
);
1582 if ( !(bNewPos
|| bNewSize
) )
1585 bool bUpdateSysObjPos
= false;
1587 bUpdateSysObjPos
= ImplUpdatePos();
1589 // the borderwindow always specifies the position for its client window
1590 if ( mpWindowImpl
->mpBorderWindow
)
1591 mpWindowImpl
->maPos
= mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->maPos
;
1593 if ( mpWindowImpl
->mpClientWindow
)
1595 mpWindowImpl
->mpClientWindow
->ImplPosSizeWindow( mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnLeftBorder
,
1596 mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnTopBorder
,
1597 GetOutDev()->mnOutWidth
- mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnLeftBorder
-mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnRightBorder
,
1598 GetOutDev()->mnOutHeight
- mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnTopBorder
-mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnBottomBorder
,
1599 PosSizeFlags::X
| PosSizeFlags::Y
|
1600 PosSizeFlags::Width
| PosSizeFlags::Height
);
1601 // If we have a client window, then this is the position
1602 // of the Application's floating windows
1603 mpWindowImpl
->mpClientWindow
->mpWindowImpl
->maPos
= mpWindowImpl
->maPos
;
1606 if ( mpWindowImpl
->mpClientWindow
->IsVisible() )
1608 mpWindowImpl
->mpClientWindow
->ImplCallMove();
1612 mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mbCallMove
= true;
1617 // Move()/Resize() will be called only for Show(), such that
1618 // at least one is called before Show()
1633 mpWindowImpl
->mbCallMove
= true;
1635 mpWindowImpl
->mbCallResize
= true;
1638 bool bUpdateSysObjClip
= false;
1639 if ( IsReallyVisible() )
1641 if ( bNewPos
|| bNewSize
)
1644 bUpdateSysObjClip
= !ImplSetClipFlag( true );
1647 // invalidate window content ?
1648 if ( bNewPos
|| (GetOutDev()->mnOutWidth
> nOldOutWidth
) || (GetOutDev()->mnOutHeight
> nOldOutHeight
) )
1652 bool bInvalidate
= false;
1653 bool bParentPaint
= true;
1654 if ( !ImplIsOverlapWindow() )
1655 bParentPaint
= mpWindowImpl
->mpParent
->IsPaintEnabled();
1656 if ( bCopyBits
&& bParentPaint
&& !HasPaintEvent() )
1658 vcl::Region
aRegion( GetOutputRectPixel() );
1659 if ( mpWindowImpl
->mbWinRegion
)
1660 aRegion
.Intersect( GetOutDev()->ImplPixelToDevicePixel( mpWindowImpl
->maWinRegion
) );
1661 ImplClipBoundaries( aRegion
, false, true );
1662 if ( !pOverlapRegion
->IsEmpty() )
1664 pOverlapRegion
->Move( GetOutDev()->mnOutOffX
- nOldOutOffX
, GetOutDev()->mnOutOffY
- nOldOutOffY
);
1665 aRegion
.Exclude( *pOverlapRegion
);
1667 if ( !aRegion
.IsEmpty() )
1669 // adapt Paint areas
1670 ImplMoveAllInvalidateRegions( tools::Rectangle( Point( nOldOutOffX
, nOldOutOffY
),
1671 Size( nOldOutWidth
, nOldOutHeight
) ),
1672 GetOutDev()->mnOutOffX
- nOldOutOffX
, GetOutDev()->mnOutOffY
- nOldOutOffY
,
1674 SalGraphics
* pGraphics
= ImplGetFrameGraphics();
1678 OutputDevice
*pOutDev
= GetOutDev();
1679 const bool bSelectClipRegion
= pOutDev
->SelectClipRegion( aRegion
, pGraphics
);
1680 if ( bSelectClipRegion
)
1682 pGraphics
->CopyArea( GetOutDev()->mnOutOffX
, GetOutDev()->mnOutOffY
,
1683 nOldOutOffX
, nOldOutOffY
,
1684 nOldOutWidth
, nOldOutHeight
,
1694 if ( !pOverlapRegion
->IsEmpty() )
1695 ImplInvalidateFrameRegion( pOverlapRegion
.get(), InvalidateFlags::Children
);
1704 ImplInvalidateFrameRegion( nullptr, InvalidateFlags::Children
);
1708 vcl::Region
aRegion( GetOutputRectPixel() );
1709 aRegion
.Exclude( *pOldRegion
);
1710 if ( mpWindowImpl
->mbWinRegion
)
1711 aRegion
.Intersect( GetOutDev()->ImplPixelToDevicePixel( mpWindowImpl
->maWinRegion
) );
1712 ImplClipBoundaries( aRegion
, false, true );
1713 if ( !aRegion
.IsEmpty() )
1714 ImplInvalidateFrameRegion( &aRegion
, InvalidateFlags::Children
);
1718 // invalidate Parent or Overlaps
1720 (GetOutDev()->mnOutWidth
< nOldOutWidth
) || (GetOutDev()->mnOutHeight
< nOldOutHeight
) )
1722 vcl::Region
aRegion( *pOldRegion
);
1723 if ( !mpWindowImpl
->mbPaintTransparent
)
1724 ImplExcludeWindowRegion( aRegion
);
1725 ImplClipBoundaries( aRegion
, false, true );
1726 if ( !aRegion
.IsEmpty() && !mpWindowImpl
->mpBorderWindow
)
1727 ImplInvalidateParentFrameRegion( aRegion
);
1731 // adapt system objects
1732 if ( bUpdateSysObjClip
)
1733 ImplUpdateSysObjClip();
1734 if ( bUpdateSysObjPos
)
1735 ImplUpdateSysObjPos();
1736 if ( bNewSize
&& mpWindowImpl
->mpSysObj
)
1737 mpWindowImpl
->mpSysObj
->SetPosSize( GetOutDev()->mnOutOffX
, GetOutDev()->mnOutOffY
, GetOutDev()->mnOutWidth
, GetOutDev()->mnOutHeight
);
1740 void Window::ImplNewInputContext()
1742 ImplSVData
* pSVData
= ImplGetSVData();
1743 vcl::Window
* pFocusWin
= pSVData
->mpWinData
->mpFocusWin
;
1744 if ( !pFocusWin
|| !pFocusWin
->mpWindowImpl
|| pFocusWin
->isDisposed() )
1747 // Is InputContext changed?
1748 const InputContext
& rInputContext
= pFocusWin
->GetInputContext();
1749 if ( rInputContext
== pFocusWin
->mpWindowImpl
->mpFrameData
->maOldInputContext
)
1752 pFocusWin
->mpWindowImpl
->mpFrameData
->maOldInputContext
= rInputContext
;
1754 SalInputContext aNewContext
;
1755 const vcl::Font
& rFont
= rInputContext
.GetFont();
1756 const OUString
& rFontName
= rFont
.GetFamilyName();
1757 rtl::Reference
<LogicalFontInstance
> pFontInstance
;
1758 aNewContext
.mpFont
= nullptr;
1759 if (!rFontName
.isEmpty())
1761 OutputDevice
*pFocusWinOutDev
= pFocusWin
->GetOutDev();
1762 Size aSize
= pFocusWinOutDev
->ImplLogicToDevicePixel( rFont
.GetFontSize() );
1763 if ( !aSize
.Height() )
1765 // only set default sizes if the font height in logical
1766 // coordinates equals 0
1767 if ( rFont
.GetFontSize().Height() )
1768 aSize
.setHeight( 1 );
1770 aSize
.setHeight( (12*pFocusWin
->GetOutDev()->mnDPIY
)/72 );
1772 pFontInstance
= pFocusWin
->GetOutDev()->mxFontCache
->GetFontInstance(
1773 pFocusWin
->GetOutDev()->mxFontCollection
.get(),
1774 rFont
, aSize
, static_cast<float>(aSize
.Height()) );
1775 if ( pFontInstance
)
1776 aNewContext
.mpFont
= pFontInstance
;
1778 aNewContext
.mnOptions
= rInputContext
.GetOptions();
1779 pFocusWin
->ImplGetFrame()->SetInputContext( &aNewContext
);
1782 void Window::SetDumpAsPropertyTreeHdl(const Link
<tools::JsonWriter
&, void>& rLink
)
1784 if (mpWindowImpl
) // may be called after dispose
1786 mpWindowImpl
->maDumpAsPropertyTreeHdl
= rLink
;
1790 void Window::SetModalHierarchyHdl(const Link
<bool, void>& rLink
)
1792 ImplGetFrame()->SetModalHierarchyHdl(rLink
);
1795 KeyIndicatorState
Window::GetIndicatorState() const
1797 return mpWindowImpl
->mpFrame
->GetIndicatorState();
1800 void Window::SimulateKeyPress( sal_uInt16 nKeyCode
) const
1802 mpWindowImpl
->mpFrame
->SimulateKeyPress(nKeyCode
);
1805 void Window::KeyInput( const KeyEvent
& rKEvt
)
1807 KeyCode cod
= rKEvt
.GetKeyCode ();
1808 bool autoacc
= ImplGetSVData()->maNWFData
.mbAutoAccel
;
1810 // do not respond to accelerators unless Alt or Ctrl is held
1811 if (cod
.GetCode () >= 0x200 && cod
.GetCode () <= 0x219)
1813 if (autoacc
&& cod
.GetModifier () != KEY_MOD2
&& !(cod
.GetModifier() & KEY_MOD1
))
1817 NotifyEvent
aNEvt( MouseNotifyEvent::KEYINPUT
, this, &rKEvt
);
1818 if ( !CompatNotify( aNEvt
) )
1819 mpWindowImpl
->mbKeyInput
= true;
1822 void Window::KeyUp( const KeyEvent
& rKEvt
)
1824 NotifyEvent
aNEvt( MouseNotifyEvent::KEYUP
, this, &rKEvt
);
1825 if ( !CompatNotify( aNEvt
) )
1826 mpWindowImpl
->mbKeyUp
= true;
1829 void Window::Draw( OutputDevice
*, const Point
&, SystemTextColorFlags
)
1833 void Window::Move() {}
1835 void Window::Resize() {}
1837 void Window::Activate() {}
1839 void Window::Deactivate() {}
1841 void Window::GetFocus()
1843 if ( HasFocus() && mpWindowImpl
->mpLastFocusWindow
&& !(mpWindowImpl
->mnDlgCtrlFlags
& DialogControlFlags::WantFocus
) )
1845 VclPtr
<vcl::Window
> xWindow(this);
1846 mpWindowImpl
->mpLastFocusWindow
->GrabFocus();
1847 if( xWindow
->isDisposed() )
1851 NotifyEvent
aNEvt( MouseNotifyEvent::GETFOCUS
, this );
1852 CompatNotify( aNEvt
);
1855 void Window::LoseFocus()
1857 NotifyEvent
aNEvt( MouseNotifyEvent::LOSEFOCUS
, this );
1858 CompatNotify( aNEvt
);
1861 void Window::SetHelpHdl(const Link
<vcl::Window
&, bool>& rLink
)
1863 if (mpWindowImpl
) // may be called after dispose
1865 mpWindowImpl
->maHelpRequestHdl
= rLink
;
1869 void Window::RequestHelp( const HelpEvent
& rHEvt
)
1871 // if Balloon-Help is requested, show the balloon
1872 // with help text set
1873 if ( rHEvt
.GetMode() & HelpEventMode::BALLOON
)
1875 OUString rStr
= GetHelpText();
1876 if ( rStr
.isEmpty() )
1877 rStr
= GetQuickHelpText();
1878 if ( rStr
.isEmpty() && ImplGetParent() && !ImplIsOverlapWindow() )
1879 ImplGetParent()->RequestHelp( rHEvt
);
1882 Point aPos
= GetPosPixel();
1883 if ( ImplGetParent() && !ImplIsOverlapWindow() )
1884 aPos
= OutputToScreenPixel(Point(0, 0));
1885 tools::Rectangle
aRect( aPos
, GetSizePixel() );
1887 Help::ShowBalloon( this, rHEvt
.GetMousePosPixel(), aRect
, rStr
);
1890 else if ( rHEvt
.GetMode() & HelpEventMode::QUICK
)
1892 const OUString
& rStr
= GetQuickHelpText();
1893 if ( rStr
.isEmpty() && ImplGetParent() && !ImplIsOverlapWindow() )
1894 ImplGetParent()->RequestHelp( rHEvt
);
1897 Point aPos
= GetPosPixel();
1898 if ( ImplGetParent() && !ImplIsOverlapWindow() )
1899 aPos
= OutputToScreenPixel(Point(0, 0));
1900 tools::Rectangle
aRect( aPos
, GetSizePixel() );
1901 Help::ShowQuickHelp( this, aRect
, rStr
, QuickHelpFlags::CtrlText
);
1904 else if (!mpWindowImpl
->maHelpRequestHdl
.IsSet() || mpWindowImpl
->maHelpRequestHdl
.Call(*this))
1906 OUString
aStrHelpId( OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8
) );
1907 if ( aStrHelpId
.isEmpty() && ImplGetParent() )
1908 ImplGetParent()->RequestHelp( rHEvt
);
1911 Help
* pHelp
= Application::GetHelp();
1914 if( !aStrHelpId
.isEmpty() )
1915 pHelp
->Start( aStrHelpId
, this );
1917 pHelp
->Start( OOO_HELP_INDEX
, this );
1923 void Window::Command( const CommandEvent
& rCEvt
)
1925 CallEventListeners( VclEventId::WindowCommand
, const_cast<CommandEvent
*>(&rCEvt
) );
1927 NotifyEvent
aNEvt( MouseNotifyEvent::COMMAND
, this, &rCEvt
);
1928 if ( !CompatNotify( aNEvt
) )
1929 mpWindowImpl
->mbCommand
= true;
1932 void Window::Tracking( const TrackingEvent
& rTEvt
)
1935 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( this );
1937 pWrapper
->Tracking( rTEvt
);
1940 void Window::StateChanged(StateChangedType eType
)
1944 //stuff that doesn't invalidate the layout
1945 case StateChangedType::ControlForeground
:
1946 case StateChangedType::ControlBackground
:
1947 case StateChangedType::UpdateMode
:
1948 case StateChangedType::ReadOnly
:
1949 case StateChangedType::Enable
:
1950 case StateChangedType::State
:
1951 case StateChangedType::Data
:
1952 case StateChangedType::InitShow
:
1953 case StateChangedType::ControlFocus
:
1955 //stuff that does invalidate the layout
1957 queue_resize(eType
);
1962 void Window::SetStyle( WinBits nStyle
)
1964 if ( mpWindowImpl
&& mpWindowImpl
->mnStyle
!= nStyle
)
1966 mpWindowImpl
->mnPrevStyle
= mpWindowImpl
->mnStyle
;
1967 mpWindowImpl
->mnStyle
= nStyle
;
1968 CompatStateChanged( StateChangedType::Style
);
1972 void Window::SetExtendedStyle( WindowExtendedStyle nExtendedStyle
)
1975 if ( mpWindowImpl
->mnExtendedStyle
== nExtendedStyle
)
1978 vcl::Window
* pWindow
= ImplGetBorderWindow();
1981 if( pWindow
->mpWindowImpl
->mbFrame
)
1983 SalExtStyle nExt
= 0;
1984 if( nExtendedStyle
& WindowExtendedStyle::Document
)
1985 nExt
|= SAL_FRAME_EXT_STYLE_DOCUMENT
;
1986 if( nExtendedStyle
& WindowExtendedStyle::DocModified
)
1987 nExt
|= SAL_FRAME_EXT_STYLE_DOCMODIFIED
;
1989 pWindow
->ImplGetFrame()->SetExtendedFrameStyle( nExt
);
1991 mpWindowImpl
->mnExtendedStyle
= nExtendedStyle
;
1994 void Window::SetBorderStyle( WindowBorderStyle nBorderStyle
)
1997 if ( !mpWindowImpl
->mpBorderWindow
)
2000 if( nBorderStyle
== WindowBorderStyle::REMOVEBORDER
&&
2001 ! mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbFrame
&&
2002 mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mpParent
2005 // this is a little awkward: some controls (e.g. svtools ProgressBar)
2006 // cannot avoid getting constructed with WB_BORDER but want to disable
2007 // borders in case of NWF drawing. So they need a method to remove their border window
2008 VclPtr
<vcl::Window
> pBorderWin
= mpWindowImpl
->mpBorderWindow
;
2009 // remove us as border window's client
2010 pBorderWin
->mpWindowImpl
->mpClientWindow
= nullptr;
2011 mpWindowImpl
->mpBorderWindow
= nullptr;
2012 mpWindowImpl
->mpRealParent
= pBorderWin
->mpWindowImpl
->mpParent
;
2013 // reparent us above the border window
2014 SetParent( pBorderWin
->mpWindowImpl
->mpParent
);
2015 // set us to the position and size of our previous border
2016 Point
aBorderPos( pBorderWin
->GetPosPixel() );
2017 Size
aBorderSize( pBorderWin
->GetSizePixel() );
2018 setPosSizePixel( aBorderPos
.X(), aBorderPos
.Y(), aBorderSize
.Width(), aBorderSize
.Height() );
2019 // release border window
2020 pBorderWin
.disposeAndClear();
2022 // set new style bits
2023 SetStyle( GetStyle() & (~WB_BORDER
) );
2027 if ( mpWindowImpl
->mpBorderWindow
->GetType() == WindowType::BORDERWINDOW
)
2028 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetBorderStyle( nBorderStyle
);
2030 mpWindowImpl
->mpBorderWindow
->SetBorderStyle( nBorderStyle
);
2034 WindowBorderStyle
Window::GetBorderStyle() const
2037 if ( mpWindowImpl
->mpBorderWindow
)
2039 if ( mpWindowImpl
->mpBorderWindow
->GetType() == WindowType::BORDERWINDOW
)
2040 return static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->GetBorderStyle();
2042 return mpWindowImpl
->mpBorderWindow
->GetBorderStyle();
2045 return WindowBorderStyle::NONE
;
2048 tools::Long
Window::CalcTitleWidth() const
2051 if ( mpWindowImpl
->mpBorderWindow
)
2053 if ( mpWindowImpl
->mpBorderWindow
->GetType() == WindowType::BORDERWINDOW
)
2054 return static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->CalcTitleWidth();
2056 return mpWindowImpl
->mpBorderWindow
->CalcTitleWidth();
2058 else if ( mpWindowImpl
->mbFrame
&& (mpWindowImpl
->mnStyle
& WB_MOVEABLE
) )
2060 // we guess the width for frame windows as we do not know the
2061 // border of external dialogs
2062 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
2063 vcl::Font aFont
= GetFont();
2064 const_cast<vcl::Window
*>(this)->SetPointFont(const_cast<::OutputDevice
&>(*GetOutDev()), rStyleSettings
.GetTitleFont());
2065 tools::Long nTitleWidth
= GetTextWidth( GetText() );
2066 const_cast<vcl::Window
*>(this)->SetFont( aFont
);
2067 nTitleWidth
+= rStyleSettings
.GetTitleHeight() * 3;
2068 nTitleWidth
+= StyleSettings::GetBorderSize() * 2;
2076 void Window::SetInputContext( const InputContext
& rInputContext
)
2079 mpWindowImpl
->maInputContext
= rInputContext
;
2080 if ( !mpWindowImpl
->mbInFocusHdl
&& HasFocus() )
2081 ImplNewInputContext();
2084 void Window::PostExtTextInputEvent(VclEventId nType
, const OUString
& rText
)
2088 case VclEventId::ExtTextInput
:
2090 std::unique_ptr
<ExtTextInputAttr
[]> pAttr(new ExtTextInputAttr
[rText
.getLength()]);
2091 for (int i
= 0; i
< rText
.getLength(); ++i
) {
2092 pAttr
[i
] = ExtTextInputAttr::Underline
;
2094 SalExtTextInputEvent aEvent
{ rText
, pAttr
.get(), rText
.getLength(), EXTTEXTINPUT_CURSOR_OVERWRITE
};
2095 ImplWindowFrameProc(this, SalEvent::ExtTextInput
, &aEvent
);
2098 case VclEventId::EndExtTextInput
:
2099 ImplWindowFrameProc(this, SalEvent::EndExtTextInput
, nullptr);
2106 void Window::EndExtTextInput()
2108 if ( mpWindowImpl
->mbExtTextInput
)
2109 ImplGetFrame()->EndExtTextInput( EndExtTextInputFlags::Complete
);
2112 void Window::SetCursorRect( const tools::Rectangle
* pRect
, tools::Long nExtTextInputWidth
)
2115 ImplWinData
* pWinData
= ImplGetWinData();
2116 if ( pWinData
->mpCursorRect
)
2119 pWinData
->mpCursorRect
= *pRect
;
2121 pWinData
->mpCursorRect
.reset();
2126 pWinData
->mpCursorRect
= *pRect
;
2129 pWinData
->mnCursorExtWidth
= nExtTextInputWidth
;
2133 const tools::Rectangle
* Window::GetCursorRect() const
2136 ImplWinData
* pWinData
= ImplGetWinData();
2137 return pWinData
->mpCursorRect
? &*pWinData
->mpCursorRect
: nullptr;
2140 tools::Long
Window::GetCursorExtTextInputWidth() const
2143 ImplWinData
* pWinData
= ImplGetWinData();
2144 return pWinData
->mnCursorExtWidth
;
2147 void Window::SetCompositionCharRect( const tools::Rectangle
* pRect
, tools::Long nCompositionLength
, bool bVertical
) {
2149 ImplWinData
* pWinData
= ImplGetWinData();
2150 pWinData
->mpCompositionCharRects
.reset();
2151 pWinData
->mbVertical
= bVertical
;
2152 pWinData
->mnCompositionCharRects
= nCompositionLength
;
2153 if ( pRect
&& (nCompositionLength
> 0) )
2155 pWinData
->mpCompositionCharRects
.reset( new tools::Rectangle
[nCompositionLength
] );
2156 for (tools::Long i
= 0; i
< nCompositionLength
; ++i
)
2157 pWinData
->mpCompositionCharRects
[i
] = pRect
[i
];
2161 void Window::CollectChildren(::std::vector
<vcl::Window
*>& rAllChildren
)
2163 rAllChildren
.push_back( this );
2165 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2168 pChild
->CollectChildren( rAllChildren
);
2169 pChild
= pChild
->mpWindowImpl
->mpNext
;
2173 void Window::SetPointFont(vcl::RenderContext
& rRenderContext
, const vcl::Font
& rFont
)
2175 vcl::Font aFont
= rFont
;
2176 ImplPointToLogic(rRenderContext
, aFont
);
2177 rRenderContext
.SetFont(aFont
);
2180 vcl::Font
Window::GetPointFont(vcl::RenderContext
const & rRenderContext
) const
2182 vcl::Font aFont
= rRenderContext
.GetFont();
2183 ImplLogicToPoint(rRenderContext
, aFont
);
2187 void Window::Show(bool bVisible
, ShowFlags nFlags
)
2189 if ( !mpWindowImpl
|| mpWindowImpl
->mbVisible
== bVisible
)
2192 VclPtr
<vcl::Window
> xWindow(this);
2194 bool bRealVisibilityChanged
= false;
2195 mpWindowImpl
->mbVisible
= bVisible
;
2199 ImplHideAllOverlaps();
2200 if( !xWindow
->mpWindowImpl
)
2203 if ( mpWindowImpl
->mpBorderWindow
)
2205 bool bOldUpdate
= mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbNoParentUpdate
;
2206 if ( mpWindowImpl
->mbNoParentUpdate
)
2207 mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbNoParentUpdate
= true;
2208 mpWindowImpl
->mpBorderWindow
->Show( false, nFlags
);
2209 mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbNoParentUpdate
= bOldUpdate
;
2211 else if ( mpWindowImpl
->mbFrame
)
2213 mpWindowImpl
->mbSuppressAccessibilityEvents
= true;
2214 mpWindowImpl
->mpFrame
->Show( false );
2217 CompatStateChanged( StateChangedType::Visible
);
2219 if ( mpWindowImpl
->mbReallyVisible
)
2221 if ( mpWindowImpl
->mbInitWinClipRegion
)
2222 ImplInitWinClipRegion();
2224 vcl::Region aInvRegion
= mpWindowImpl
->maWinClipRegion
;
2226 if( !xWindow
->mpWindowImpl
)
2229 bRealVisibilityChanged
= mpWindowImpl
->mbReallyVisible
;
2230 ImplResetReallyVisible();
2233 if ( ImplIsOverlapWindow() && !mpWindowImpl
->mbFrame
)
2236 if ( !(nFlags
& ShowFlags::NoFocusChange
) && HasChildPathFocus() )
2238 if ( mpWindowImpl
->mpOverlapWindow
->IsEnabled() &&
2239 mpWindowImpl
->mpOverlapWindow
->IsInputEnabled() &&
2240 ! mpWindowImpl
->mpOverlapWindow
->IsInModalMode()
2242 mpWindowImpl
->mpOverlapWindow
->GrabFocus();
2246 if ( !mpWindowImpl
->mbFrame
)
2248 if (mpWindowImpl
->mpWinData
&& mpWindowImpl
->mpWinData
->mbEnableNativeWidget
)
2251 * #i48371# native theming: some themes draw outside the control
2252 * area we tell them to (bad thing, but we cannot do much about it ).
2253 * On hiding these controls they get invalidated with their window rectangle
2254 * which leads to the parts outside the control area being left and not
2255 * invalidated. Workaround: invalidate an area on the parent, too
2257 const int workaround_border
= 5;
2258 tools::Rectangle
aBounds( aInvRegion
.GetBoundRect() );
2259 aBounds
.AdjustLeft( -workaround_border
);
2260 aBounds
.AdjustTop( -workaround_border
);
2261 aBounds
.AdjustRight(workaround_border
);
2262 aBounds
.AdjustBottom(workaround_border
);
2263 aInvRegion
= aBounds
;
2265 if ( !mpWindowImpl
->mbNoParentUpdate
)
2267 if ( !aInvRegion
.IsEmpty() )
2268 ImplInvalidateParentFrameRegion( aInvRegion
);
2270 ImplGenerateMouseMove();
2276 // inherit native widget flag for form controls
2277 // required here, because frames never show up in the child hierarchy - which should be fixed...
2278 // eg, the drop down of a combobox which is a system floating window
2279 if( mpWindowImpl
->mbFrame
&& GetParent() && !GetParent()->isDisposed() &&
2280 GetParent()->IsCompoundControl() &&
2281 GetParent()->IsNativeWidgetEnabled() != IsNativeWidgetEnabled() &&
2282 !(GetStyle() & WB_TOOLTIPWIN
) )
2284 EnableNativeWidget( GetParent()->IsNativeWidgetEnabled() );
2287 if ( mpWindowImpl
->mbCallMove
)
2291 if ( mpWindowImpl
->mbCallResize
)
2296 CompatStateChanged( StateChangedType::Visible
);
2298 vcl::Window
* pTestParent
;
2299 if ( ImplIsOverlapWindow() )
2300 pTestParent
= mpWindowImpl
->mpOverlapWindow
;
2302 pTestParent
= ImplGetParent();
2303 if ( mpWindowImpl
->mbFrame
|| pTestParent
->mpWindowImpl
->mbReallyVisible
)
2305 // if a window becomes visible, send all child windows a StateChange,
2306 // such that these can initialise themselves
2309 // If it is a SystemWindow it automatically pops up on top of
2310 // all other windows if needed.
2311 if ( ImplIsOverlapWindow() && !(nFlags
& ShowFlags::NoActivate
) )
2313 ImplStartToTop(( nFlags
& ShowFlags::ForegroundTask
) ? ToTopFlags::ForegroundTask
: ToTopFlags::NONE
);
2314 ImplFocusToTop( ToTopFlags::NONE
, false );
2317 // adjust mpWindowImpl->mbReallyVisible
2318 bRealVisibilityChanged
= !mpWindowImpl
->mbReallyVisible
;
2319 ImplSetReallyVisible();
2321 // assure clip rectangles will be recalculated
2324 if ( !mpWindowImpl
->mbFrame
)
2326 InvalidateFlags nInvalidateFlags
= InvalidateFlags::Children
;
2327 if( ! IsPaintTransparent() )
2328 nInvalidateFlags
|= InvalidateFlags::NoTransparent
;
2329 ImplInvalidate( nullptr, nInvalidateFlags
);
2330 ImplGenerateMouseMove();
2334 if ( mpWindowImpl
->mpBorderWindow
)
2335 mpWindowImpl
->mpBorderWindow
->Show( true, nFlags
);
2336 else if ( mpWindowImpl
->mbFrame
)
2338 // #106431#, hide SplashScreen
2339 ImplSVData
* pSVData
= ImplGetSVData();
2340 if ( !pSVData
->mpIntroWindow
)
2342 // The right way would be just to call this (not even in the 'if')
2343 auto pApp
= GetpApp();
2345 pApp
->InitFinished();
2347 else if ( !ImplIsWindowOrChild( pSVData
->mpIntroWindow
) )
2349 // ... but the VCL splash is broken, and it needs this
2350 // (for ./soffice .uno:NewDoc)
2351 pSVData
->mpIntroWindow
->Hide();
2354 //SAL_WARN_IF( mpWindowImpl->mbSuppressAccessibilityEvents, "vcl", "Window::Show() - Frame reactivated");
2355 mpWindowImpl
->mbSuppressAccessibilityEvents
= false;
2357 mpWindowImpl
->mbPaintFrame
= true;
2358 if (!Application::IsHeadlessModeEnabled())
2360 bool bNoActivate(nFlags
& (ShowFlags::NoActivate
|ShowFlags::NoFocusChange
));
2361 mpWindowImpl
->mpFrame
->Show( true, bNoActivate
);
2363 if( !xWindow
->mpWindowImpl
)
2366 // Query the correct size of the window, if we are waiting for
2368 if ( mpWindowImpl
->mbWaitSystemResize
)
2370 tools::Long nOutWidth
;
2371 tools::Long nOutHeight
;
2372 mpWindowImpl
->mpFrame
->GetClientSize( nOutWidth
, nOutHeight
);
2373 ImplHandleResize( this, nOutWidth
, nOutHeight
);
2376 if (mpWindowImpl
->mpFrameData
->mpBuffer
&& mpWindowImpl
->mpFrameData
->mpBuffer
->GetOutputSizePixel() != GetOutputSizePixel())
2377 // Make sure that the buffer size matches the window size, even if no resize was needed.
2378 mpWindowImpl
->mpFrameData
->mpBuffer
->SetOutputSizePixel(GetOutputSizePixel());
2381 if( !xWindow
->mpWindowImpl
)
2384 ImplShowAllOverlaps();
2387 if( !xWindow
->mpWindowImpl
)
2390 // the SHOW/HIDE events also serve as indicators to send child creation/destroy events to the access bridge
2391 // However, the access bridge only uses this event if the data member is not NULL (it's kind of a hack that
2392 // we re-use the SHOW/HIDE events this way, with this particular semantics).
2393 // Since #104887#, the notifications for the access bridge are done in Impl(Set|Reset)ReallyVisible. Here, we
2394 // now only notify with a NULL data pointer, for all other clients except the access bridge.
2395 if ( !bRealVisibilityChanged
)
2396 CallEventListeners( mpWindowImpl
->mbVisible
? VclEventId::WindowShow
: VclEventId::WindowHide
);
2397 if( xWindow
->isDisposed() )
2402 Size
Window::GetSizePixel() const
2406 SAL_WARN("vcl.layout", "WTF no windowimpl");
2410 // #i43257# trigger pending resize handler to assure correct window sizes
2411 if( mpWindowImpl
->mpFrameData
->maResizeIdle
.IsActive() )
2413 VclPtr
<vcl::Window
> xWindow( const_cast<Window
*>(this) );
2414 mpWindowImpl
->mpFrameData
->maResizeIdle
.Stop();
2415 mpWindowImpl
->mpFrameData
->maResizeIdle
.Invoke( nullptr );
2416 if( xWindow
->isDisposed() )
2420 return Size( GetOutDev()->mnOutWidth
+ mpWindowImpl
->mnLeftBorder
+mpWindowImpl
->mnRightBorder
,
2421 GetOutDev()->mnOutHeight
+ mpWindowImpl
->mnTopBorder
+mpWindowImpl
->mnBottomBorder
);
2424 void Window::GetBorder( sal_Int32
& rLeftBorder
, sal_Int32
& rTopBorder
,
2425 sal_Int32
& rRightBorder
, sal_Int32
& rBottomBorder
) const
2427 rLeftBorder
= mpWindowImpl
->mnLeftBorder
;
2428 rTopBorder
= mpWindowImpl
->mnTopBorder
;
2429 rRightBorder
= mpWindowImpl
->mnRightBorder
;
2430 rBottomBorder
= mpWindowImpl
->mnBottomBorder
;
2433 void Window::Enable( bool bEnable
, bool bChild
)
2440 // the tracking mode will be stopped or the capture will be stolen
2441 // when a window is disabled,
2443 EndTracking( TrackingEventFlags::Cancel
);
2444 if ( IsMouseCaptured() )
2446 // try to pass focus to the next control
2447 // if the window has focus and is contained in the dialog control
2448 // mpWindowImpl->mbDisabled should only be set after a call of ImplDlgCtrlNextWindow().
2449 // Otherwise ImplDlgCtrlNextWindow() should be used
2451 ImplDlgCtrlNextWindow();
2454 if ( mpWindowImpl
->mpBorderWindow
)
2456 mpWindowImpl
->mpBorderWindow
->Enable( bEnable
, false );
2457 if ( (mpWindowImpl
->mpBorderWindow
->GetType() == WindowType::BORDERWINDOW
) &&
2458 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->mpMenuBarWindow
)
2459 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->mpMenuBarWindow
->Enable( bEnable
);
2462 // #i56102# restore app focus win in case the
2463 // window was disabled when the frame focus changed
2464 ImplSVData
* pSVData
= ImplGetSVData();
2465 if (bEnable
&& pSVData
->mpWinData
->mpFocusWin
== nullptr
2466 && mpWindowImpl
->mpFrameData
->mbHasFocus
&& mpWindowImpl
->mpFrameData
->mpFocusWin
== this)
2467 pSVData
->mpWinData
->mpFocusWin
= this;
2469 if ( mpWindowImpl
->mbDisabled
!= !bEnable
)
2471 mpWindowImpl
->mbDisabled
= !bEnable
;
2472 if ( mpWindowImpl
->mpSysObj
)
2473 mpWindowImpl
->mpSysObj
->Enable( bEnable
&& !mpWindowImpl
->mbInputDisabled
);
2474 CompatStateChanged( StateChangedType::Enable
);
2476 CallEventListeners( bEnable
? VclEventId::WindowEnabled
: VclEventId::WindowDisabled
);
2481 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2484 pChild
->Enable( bEnable
, bChild
);
2485 pChild
= pChild
->mpWindowImpl
->mpNext
;
2489 if ( IsReallyVisible() )
2490 ImplGenerateMouseMove();
2493 void Window::EnableInput( bool bEnable
, bool bChild
)
2498 if ( mpWindowImpl
->mpBorderWindow
)
2500 mpWindowImpl
->mpBorderWindow
->EnableInput( bEnable
, false );
2501 if ( (mpWindowImpl
->mpBorderWindow
->GetType() == WindowType::BORDERWINDOW
) &&
2502 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->mpMenuBarWindow
)
2503 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->mpMenuBarWindow
->EnableInput( bEnable
);
2506 if ( (!bEnable
&& mpWindowImpl
->meAlwaysInputMode
!= AlwaysInputEnabled
) || bEnable
)
2508 // automatically stop the tracking mode or steal capture
2509 // if the window is disabled
2513 EndTracking( TrackingEventFlags::Cancel
);
2514 if ( IsMouseCaptured() )
2518 if ( mpWindowImpl
->mbInputDisabled
!= !bEnable
)
2520 mpWindowImpl
->mbInputDisabled
= !bEnable
;
2521 if ( mpWindowImpl
->mpSysObj
)
2522 mpWindowImpl
->mpSysObj
->Enable( !mpWindowImpl
->mbDisabled
&& bEnable
);
2526 // #i56102# restore app focus win in case the
2527 // window was disabled when the frame focus changed
2528 ImplSVData
* pSVData
= ImplGetSVData();
2529 if (bEnable
&& pSVData
->mpWinData
->mpFocusWin
== nullptr
2530 && mpWindowImpl
->mpFrameData
->mbHasFocus
&& mpWindowImpl
->mpFrameData
->mpFocusWin
== this)
2531 pSVData
->mpWinData
->mpFocusWin
= this;
2535 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2538 pChild
->EnableInput( bEnable
, bChild
);
2539 pChild
= pChild
->mpWindowImpl
->mpNext
;
2543 if ( IsReallyVisible() )
2544 ImplGenerateMouseMove();
2547 void Window::EnableInput( bool bEnable
, const vcl::Window
* pExcludeWindow
)
2552 EnableInput( bEnable
);
2554 // pExecuteWindow is the first Overlap-Frame --> if this
2555 // shouldn't be the case, then this must be changed in dialog.cxx
2556 if( pExcludeWindow
)
2557 pExcludeWindow
= pExcludeWindow
->ImplGetFirstOverlapWindow();
2558 vcl::Window
* pSysWin
= mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpFrameData
->mpFirstOverlap
;
2561 // Is Window in the path from this window
2562 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pSysWin
, true ) )
2564 // Is Window not in the exclude window path or not the
2565 // exclude window, then change the status
2566 if ( !pExcludeWindow
|| !pExcludeWindow
->ImplIsWindowOrChild( pSysWin
, true ) )
2567 pSysWin
->EnableInput( bEnable
);
2569 pSysWin
= pSysWin
->mpWindowImpl
->mpNextOverlap
;
2572 // enable/disable floating system windows as well
2573 vcl::Window
* pFrameWin
= ImplGetSVData()->maFrameData
.mpFirstFrame
;
2576 if( pFrameWin
->ImplIsFloatingWindow() )
2578 // Is Window in the path from this window
2579 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pFrameWin
, true ) )
2581 // Is Window not in the exclude window path or not the
2582 // exclude window, then change the status
2583 if ( !pExcludeWindow
|| !pExcludeWindow
->ImplIsWindowOrChild( pFrameWin
, true ) )
2584 pFrameWin
->EnableInput( bEnable
);
2587 pFrameWin
= pFrameWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
2590 // the same for ownerdraw floating windows
2591 if( !mpWindowImpl
->mbFrame
)
2594 ::std::vector
< VclPtr
<vcl::Window
> >& rList
= mpWindowImpl
->mpFrameData
->maOwnerDrawList
;
2595 for (auto const& elem
: rList
)
2597 // Is Window in the path from this window
2598 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( elem
, true ) )
2600 // Is Window not in the exclude window path or not the
2601 // exclude window, then change the status
2602 if ( !pExcludeWindow
|| !pExcludeWindow
->ImplIsWindowOrChild( elem
, true ) )
2603 elem
->EnableInput( bEnable
);
2608 void Window::AlwaysEnableInput( bool bAlways
, bool bChild
)
2611 if ( mpWindowImpl
->mpBorderWindow
)
2612 mpWindowImpl
->mpBorderWindow
->AlwaysEnableInput( bAlways
, false );
2614 if( bAlways
&& mpWindowImpl
->meAlwaysInputMode
!= AlwaysInputEnabled
)
2616 mpWindowImpl
->meAlwaysInputMode
= AlwaysInputEnabled
;
2617 EnableInput(true, false);
2619 else if( ! bAlways
&& mpWindowImpl
->meAlwaysInputMode
== AlwaysInputEnabled
)
2621 mpWindowImpl
->meAlwaysInputMode
= AlwaysInputNone
;
2626 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2629 pChild
->AlwaysEnableInput( bAlways
, bChild
);
2630 pChild
= pChild
->mpWindowImpl
->mpNext
;
2635 void Window::SetActivateMode( ActivateModeFlags nMode
)
2638 if ( mpWindowImpl
->mpBorderWindow
)
2639 mpWindowImpl
->mpBorderWindow
->SetActivateMode( nMode
);
2641 if ( mpWindowImpl
->mnActivateMode
== nMode
)
2644 mpWindowImpl
->mnActivateMode
= nMode
;
2646 // possibly trigger Deactivate/Activate
2647 if ( mpWindowImpl
->mnActivateMode
!= ActivateModeFlags::NONE
)
2649 if ( (mpWindowImpl
->mbActive
|| (GetType() == WindowType::BORDERWINDOW
)) &&
2650 !HasChildPathFocus( true ) )
2652 mpWindowImpl
->mbActive
= false;
2658 if ( !mpWindowImpl
->mbActive
|| (GetType() == WindowType::BORDERWINDOW
) )
2660 mpWindowImpl
->mbActive
= true;
2666 void Window::setPosSizePixel( tools::Long nX
, tools::Long nY
,
2667 tools::Long nWidth
, tools::Long nHeight
, PosSizeFlags nFlags
)
2669 bool bHasValidSize
= !mpWindowImpl
->mbDefSize
;
2671 if ( nFlags
& PosSizeFlags::Pos
)
2672 mpWindowImpl
->mbDefPos
= false;
2673 if ( nFlags
& PosSizeFlags::Size
)
2674 mpWindowImpl
->mbDefSize
= false;
2676 // The top BorderWindow is the window which is to be positioned
2677 VclPtr
<vcl::Window
> pWindow
= this;
2678 while ( pWindow
->mpWindowImpl
->mpBorderWindow
)
2679 pWindow
= pWindow
->mpWindowImpl
->mpBorderWindow
;
2681 if ( pWindow
->mpWindowImpl
->mbFrame
)
2683 // Note: if we're positioning a frame, the coordinates are interpreted
2684 // as being the top-left corner of the window's client area and NOT
2685 // as the position of the border ! (due to limitations of several UNIX window managers)
2686 tools::Long nOldWidth
= pWindow
->GetOutDev()->mnOutWidth
;
2688 if ( !(nFlags
& PosSizeFlags::Width
) )
2689 nWidth
= pWindow
->GetOutDev()->mnOutWidth
;
2690 if ( !(nFlags
& PosSizeFlags::Height
) )
2691 nHeight
= pWindow
->GetOutDev()->mnOutHeight
;
2693 sal_uInt16 nSysFlags
=0;
2694 VclPtr
<vcl::Window
> pParent
= GetParent();
2695 VclPtr
<vcl::Window
> pWinParent
= pWindow
->GetParent();
2697 if( nFlags
& PosSizeFlags::Width
)
2698 nSysFlags
|= SAL_FRAME_POSSIZE_WIDTH
;
2699 if( nFlags
& PosSizeFlags::Height
)
2700 nSysFlags
|= SAL_FRAME_POSSIZE_HEIGHT
;
2701 if( nFlags
& PosSizeFlags::X
)
2703 nSysFlags
|= SAL_FRAME_POSSIZE_X
;
2704 if( pWinParent
&& (pWindow
->GetStyle() & WB_SYSTEMCHILDWINDOW
) )
2706 nX
+= pWinParent
->GetOutDev()->mnOutOffX
;
2708 if( pParent
&& pParent
->GetOutDev()->ImplIsAntiparallel() )
2710 tools::Rectangle
aRect( Point ( nX
, nY
), Size( nWidth
, nHeight
) );
2711 const OutputDevice
*pParentOutDev
= pParent
->GetOutDev();
2712 pParentOutDev
->ReMirror( aRect
);
2716 if( !(nFlags
& PosSizeFlags::X
) && bHasValidSize
&& pWindow
->mpWindowImpl
->mpFrame
->maGeometry
.nWidth
)
2718 // RTL: make sure the old right aligned position is not changed
2719 // system windows will always grow to the right
2722 OutputDevice
*pParentOutDev
= pWinParent
->GetOutDev();
2723 if( pParentOutDev
->HasMirroredGraphics() )
2725 const SalFrameGeometry
& aSysGeometry
= mpWindowImpl
->mpFrame
->GetUnmirroredGeometry();
2726 const SalFrameGeometry
& aParentSysGeometry
=
2727 pWinParent
->mpWindowImpl
->mpFrame
->GetUnmirroredGeometry();
2728 tools::Long myWidth
= nOldWidth
;
2730 myWidth
= aSysGeometry
.nWidth
;
2733 nFlags
|= PosSizeFlags::X
;
2734 nSysFlags
|= SAL_FRAME_POSSIZE_X
;
2735 nX
= aParentSysGeometry
.nX
- aSysGeometry
.nLeftDecoration
+ aParentSysGeometry
.nWidth
2736 - myWidth
- 1 - aSysGeometry
.nX
;
2740 if( nFlags
& PosSizeFlags::Y
)
2742 nSysFlags
|= SAL_FRAME_POSSIZE_Y
;
2743 if( pWinParent
&& (pWindow
->GetStyle() & WB_SYSTEMCHILDWINDOW
) )
2745 nY
+= pWinParent
->GetOutDev()->mnOutOffY
;
2749 if( nSysFlags
& (SAL_FRAME_POSSIZE_WIDTH
|SAL_FRAME_POSSIZE_HEIGHT
) )
2751 // check for min/max client size and adjust size accordingly
2752 // otherwise it may happen that the resize event is ignored, i.e. the old size remains
2753 // unchanged but ImplHandleResize() is called with the wrong size
2754 SystemWindow
*pSystemWindow
= dynamic_cast< SystemWindow
* >( pWindow
.get() );
2757 Size aMinSize
= pSystemWindow
->GetMinOutputSizePixel();
2758 Size aMaxSize
= pSystemWindow
->GetMaxOutputSizePixel();
2759 if( nWidth
< aMinSize
.Width() )
2760 nWidth
= aMinSize
.Width();
2761 if( nHeight
< aMinSize
.Height() )
2762 nHeight
= aMinSize
.Height();
2764 if( nWidth
> aMaxSize
.Width() )
2765 nWidth
= aMaxSize
.Width();
2766 if( nHeight
> aMaxSize
.Height() )
2767 nHeight
= aMaxSize
.Height();
2771 pWindow
->mpWindowImpl
->mpFrame
->SetPosSize( nX
, nY
, nWidth
, nHeight
, nSysFlags
);
2773 // Adjust resize with the hack of different client size and frame geometries to fix
2774 // native menu bars. Eventually this should be replaced by proper mnTopBorder usage.
2775 pWindow
->mpWindowImpl
->mpFrame
->GetClientSize(nWidth
, nHeight
);
2777 // Resize should be called directly. If we haven't
2778 // set the correct size, we get a second resize from
2779 // the system with the correct size. This can be happened
2780 // if the size is too small or too large.
2781 ImplHandleResize( pWindow
, nWidth
, nHeight
);
2785 pWindow
->ImplPosSizeWindow( nX
, nY
, nWidth
, nHeight
, nFlags
);
2786 if ( IsReallyVisible() )
2787 ImplGenerateMouseMove();
2791 Point
Window::GetPosPixel() const
2793 return mpWindowImpl
->maPos
;
2796 tools::Rectangle
Window::GetDesktopRectPixel() const
2798 tools::Rectangle rRect
;
2799 mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpFrame
->GetWorkArea( rRect
);
2803 Point
Window::OutputToScreenPixel( const Point
& rPos
) const
2805 // relative to top level parent
2806 return Point( rPos
.X() + GetOutDev()->mnOutOffX
, rPos
.Y() + GetOutDev()->mnOutOffY
);
2809 Point
Window::ScreenToOutputPixel( const Point
& rPos
) const
2811 // relative to top level parent
2812 return Point( rPos
.X() - GetOutDev()->mnOutOffX
, rPos
.Y() - GetOutDev()->mnOutOffY
);
2815 tools::Long
Window::ImplGetUnmirroredOutOffX()
2817 // revert mnOutOffX changes that were potentially made in ImplPosSizeWindow
2818 tools::Long offx
= GetOutDev()->mnOutOffX
;
2819 OutputDevice
*pOutDev
= GetOutDev();
2820 if( pOutDev
->HasMirroredGraphics() )
2822 if( mpWindowImpl
->mpParent
&& !mpWindowImpl
->mpParent
->mpWindowImpl
->mbFrame
&& mpWindowImpl
->mpParent
->GetOutDev()->ImplIsAntiparallel() )
2824 if ( !ImplIsOverlapWindow() )
2825 offx
-= mpWindowImpl
->mpParent
->GetOutDev()->mnOutOffX
;
2827 offx
= mpWindowImpl
->mpParent
->GetOutDev()->mnOutWidth
- GetOutDev()->mnOutWidth
- offx
;
2829 if ( !ImplIsOverlapWindow() )
2830 offx
+= mpWindowImpl
->mpParent
->GetOutDev()->mnOutOffX
;
2837 // normalized screen pixel are independent of mirroring
2838 Point
Window::OutputToNormalizedScreenPixel( const Point
& rPos
) const
2840 // relative to top level parent
2841 tools::Long offx
= const_cast<vcl::Window
*>(this)->ImplGetUnmirroredOutOffX();
2842 return Point( rPos
.X()+offx
, rPos
.Y() + GetOutDev()->mnOutOffY
);
2845 Point
Window::NormalizedScreenToOutputPixel( const Point
& rPos
) const
2847 // relative to top level parent
2848 tools::Long offx
= const_cast<vcl::Window
*>(this)->ImplGetUnmirroredOutOffX();
2849 return Point( rPos
.X()-offx
, rPos
.Y() - GetOutDev()->mnOutOffY
);
2852 Point
Window::OutputToAbsoluteScreenPixel( const Point
& rPos
) const
2854 // relative to the screen
2855 Point p
= OutputToScreenPixel( rPos
);
2856 SalFrameGeometry g
= mpWindowImpl
->mpFrame
->GetGeometry();
2862 Point
Window::AbsoluteScreenToOutputPixel( const Point
& rPos
) const
2864 // relative to the screen
2865 Point p
= ScreenToOutputPixel( rPos
);
2866 SalFrameGeometry g
= mpWindowImpl
->mpFrame
->GetGeometry();
2867 p
.AdjustX( -(g
.nX
) );
2868 p
.AdjustY( -(g
.nY
) );
2872 tools::Rectangle
Window::ImplOutputToUnmirroredAbsoluteScreenPixel( const tools::Rectangle
&rRect
) const
2874 // this method creates unmirrored screen coordinates to be compared with the desktop
2875 // and is used for positioning of RTL popup windows correctly on the screen
2876 SalFrameGeometry g
= mpWindowImpl
->mpFrame
->GetUnmirroredGeometry();
2878 Point p1
= rRect
.TopRight();
2879 p1
= OutputToScreenPixel(p1
);
2880 p1
.setX( g
.nX
+g
.nWidth
-p1
.X() );
2883 Point p2
= rRect
.BottomLeft();
2884 p2
= OutputToScreenPixel(p2
);
2885 p2
.setX( g
.nX
+g
.nWidth
-p2
.X() );
2888 return tools::Rectangle( p1
, p2
);
2891 tools::Rectangle
Window::ImplUnmirroredAbsoluteScreenToOutputPixel( const tools::Rectangle
&rRect
) const
2893 // undo ImplOutputToUnmirroredAbsoluteScreenPixel
2894 SalFrameGeometry g
= mpWindowImpl
->mpFrame
->GetUnmirroredGeometry();
2896 Point p1
= rRect
.TopRight();
2898 p1
.setX( g
.nX
+g
.nWidth
-p1
.X() );
2899 p1
= ScreenToOutputPixel(p1
);
2901 Point p2
= rRect
.BottomLeft();
2903 p2
.setX( g
.nX
+g
.nWidth
-p2
.X() );
2904 p2
= ScreenToOutputPixel(p2
);
2906 return tools::Rectangle( p1
, p2
);
2910 tools::Rectangle
Window::GetWindowExtentsRelative(const vcl::Window
*pRelativeWindow
) const
2913 return ImplGetWindowExtentsRelative( pRelativeWindow
);
2916 tools::Rectangle
Window::ImplGetWindowExtentsRelative(const vcl::Window
*pRelativeWindow
) const
2918 SalFrameGeometry g
= mpWindowImpl
->mpFrame
->GetGeometry();
2919 // make sure we use the extent of our border window,
2920 // otherwise we miss a few pixels
2921 const vcl::Window
*pWin
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
: this;
2923 Point
aPos( pWin
->OutputToScreenPixel( Point(0,0) ) );
2924 aPos
.AdjustX(g
.nX
);
2925 aPos
.AdjustY(g
.nY
);
2926 Size
aSize ( pWin
->GetSizePixel() );
2927 // #104088# do not add decoration to the workwindow to be compatible to java accessibility api
2928 if( mpWindowImpl
->mbFrame
|| (mpWindowImpl
->mpBorderWindow
&& mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbFrame
&& GetType() != WindowType::WORKWINDOW
) )
2930 aPos
.AdjustX( -sal_Int32(g
.nLeftDecoration
) );
2931 aPos
.AdjustY( -sal_Int32(g
.nTopDecoration
) );
2932 aSize
.AdjustWidth(g
.nLeftDecoration
+ g
.nRightDecoration
);
2933 aSize
.AdjustHeight(g
.nTopDecoration
+ g
.nBottomDecoration
);
2935 if( pRelativeWindow
)
2937 // #106399# express coordinates relative to borderwindow
2938 const vcl::Window
*pRelWin
= pRelativeWindow
->mpWindowImpl
->mpBorderWindow
? pRelativeWindow
->mpWindowImpl
->mpBorderWindow
.get() : pRelativeWindow
;
2939 aPos
= pRelWin
->AbsoluteScreenToOutputPixel( aPos
);
2941 return tools::Rectangle( aPos
, aSize
);
2944 void Window::Scroll( tools::Long nHorzScroll
, tools::Long nVertScroll
, ScrollFlags nFlags
)
2947 ImplScroll( GetOutputRectPixel(),
2948 nHorzScroll
, nVertScroll
, nFlags
& ~ScrollFlags::Clip
);
2951 void Window::Scroll( tools::Long nHorzScroll
, tools::Long nVertScroll
,
2952 const tools::Rectangle
& rRect
, ScrollFlags nFlags
)
2954 OutputDevice
*pOutDev
= GetOutDev();
2955 tools::Rectangle aRect
= pOutDev
->ImplLogicToDevicePixel( rRect
);
2956 aRect
.Intersection( GetOutputRectPixel() );
2957 if ( !aRect
.IsEmpty() )
2958 ImplScroll( aRect
, nHorzScroll
, nVertScroll
, nFlags
);
2961 void WindowOutputDevice::Flush()
2963 if (mxOwnerWindow
->mpWindowImpl
)
2964 mxOwnerWindow
->mpWindowImpl
->mpFrame
->Flush( GetOutputRectPixel() );
2967 void Window::SetUpdateMode( bool bUpdate
)
2971 mpWindowImpl
->mbNoUpdate
= !bUpdate
;
2972 CompatStateChanged( StateChangedType::UpdateMode
);
2976 void Window::GrabFocus()
2978 ImplGrabFocus( GetFocusFlags::NONE
);
2981 bool Window::HasFocus() const
2983 return (this == ImplGetSVData()->mpWinData
->mpFocusWin
);
2986 void Window::GrabFocusToDocument()
2988 ImplGrabFocusToDocument(GetFocusFlags::NONE
);
2991 VclPtr
<vcl::Window
> Window::GetFocusedWindow() const
2993 if (mpWindowImpl
&& mpWindowImpl
->mpFrameData
)
2994 return mpWindowImpl
->mpFrameData
->mpFocusWin
;
2996 return VclPtr
<vcl::Window
>();
2999 void Window::SetFakeFocus( bool bFocus
)
3001 ImplGetWindowImpl()->mbFakeFocusSet
= bFocus
;
3004 bool Window::HasChildPathFocus( bool bSystemWindow
) const
3007 vcl::Window
* pFocusWin
= ImplGetSVData()->mpWinData
->mpFocusWin
;
3009 return ImplIsWindowOrChild( pFocusWin
, bSystemWindow
);
3013 void Window::SetCursor( vcl::Cursor
* pCursor
)
3016 if ( mpWindowImpl
->mpCursor
!= pCursor
)
3018 if ( mpWindowImpl
->mpCursor
)
3019 mpWindowImpl
->mpCursor
->ImplHide();
3020 mpWindowImpl
->mpCursor
= pCursor
;
3022 pCursor
->ImplShow();
3026 void Window::SetText( const OUString
& rStr
)
3028 if (!mpWindowImpl
|| rStr
== mpWindowImpl
->maText
)
3031 OUString
oldTitle( mpWindowImpl
->maText
);
3032 mpWindowImpl
->maText
= rStr
;
3034 if ( mpWindowImpl
->mpBorderWindow
)
3035 mpWindowImpl
->mpBorderWindow
->SetText( rStr
);
3036 else if ( mpWindowImpl
->mbFrame
)
3037 mpWindowImpl
->mpFrame
->SetTitle( rStr
);
3039 CallEventListeners( VclEventId::WindowFrameTitleChanged
, &oldTitle
);
3041 // #107247# needed for accessibility
3042 // The VclEventId::WindowFrameTitleChanged is (mis)used to notify accessible name changes.
3043 // Therefore a window, which is labeled by this window, must also notify an accessible
3045 if ( IsReallyVisible() )
3047 vcl::Window
* pWindow
= GetAccessibleRelationLabelFor();
3048 if ( pWindow
&& pWindow
!= this )
3049 pWindow
->CallEventListeners( VclEventId::WindowFrameTitleChanged
, &oldTitle
);
3052 CompatStateChanged( StateChangedType::Text
);
3055 OUString
Window::GetText() const
3058 return mpWindowImpl
->maText
;
3061 OUString
Window::GetDisplayText() const
3067 const Wallpaper
& Window::GetDisplayBackground() const
3069 // FIXME: fix issue 52349, need to fix this really in
3070 // all NWF enabled controls
3071 const ToolBox
* pTB
= dynamic_cast<const ToolBox
*>(this);
3072 if( pTB
&& IsNativeWidgetEnabled() )
3073 return pTB
->ImplGetToolBoxPrivateData()->maDisplayBackground
;
3075 if( !IsBackground() )
3077 if( mpWindowImpl
->mpParent
)
3078 return mpWindowImpl
->mpParent
->GetDisplayBackground();
3081 const Wallpaper
& rBack
= GetBackground();
3082 if( ! rBack
.IsBitmap() &&
3083 ! rBack
.IsGradient() &&
3084 rBack
.GetColor()== COL_TRANSPARENT
&&
3085 mpWindowImpl
->mpParent
)
3086 return mpWindowImpl
->mpParent
->GetDisplayBackground();
3090 const OUString
& Window::GetHelpText() const
3092 OUString
aStrHelpId( OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8
) );
3093 bool bStrHelpId
= !aStrHelpId
.isEmpty();
3095 if ( !mpWindowImpl
->maHelpText
.getLength() && bStrHelpId
)
3097 if ( !IsDialog() && (mpWindowImpl
->mnType
!= WindowType::TABPAGE
) && (mpWindowImpl
->mnType
!= WindowType::FLOATINGWINDOW
) )
3099 Help
* pHelp
= Application::GetHelp();
3102 mpWindowImpl
->maHelpText
= pHelp
->GetHelpText(aStrHelpId
, this);
3103 mpWindowImpl
->mbHelpTextDynamic
= false;
3107 else if( mpWindowImpl
->mbHelpTextDynamic
&& bStrHelpId
)
3109 static const char* pEnv
= getenv( "HELP_DEBUG" );
3112 OUString aTxt
= mpWindowImpl
->maHelpText
+ "\n------------------\n" + aStrHelpId
;
3113 mpWindowImpl
->maHelpText
= aTxt
;
3115 mpWindowImpl
->mbHelpTextDynamic
= false;
3118 //Fallback to Window::GetAccessibleDescription without reentry to GetHelpText()
3119 if (mpWindowImpl
->maHelpText
.isEmpty() && mpWindowImpl
->mpAccessibleInfos
&& mpWindowImpl
->mpAccessibleInfos
->pAccessibleDescription
)
3120 return *mpWindowImpl
->mpAccessibleInfos
->pAccessibleDescription
;
3121 return mpWindowImpl
->maHelpText
;
3124 void Window::SetWindowPeer( Reference
< css::awt::XWindowPeer
> const & xPeer
, VCLXWindow
* pVCLXWindow
)
3126 if (!mpWindowImpl
|| mpWindowImpl
->mbInDispose
)
3129 // be safe against re-entrance: first clear the old ref, then assign the new one
3130 if (mpWindowImpl
->mxWindowPeer
)
3132 // first, disconnect the peer from ourself, otherwise disposing it, will dispose us
3133 UnoWrapperBase
* pWrapper
= UnoWrapperBase::GetUnoWrapper();
3134 SAL_WARN_IF( !pWrapper
, "vcl.window", "SetComponentInterface: No Wrapper!" );
3136 pWrapper
->SetWindowInterface( nullptr, mpWindowImpl
->mxWindowPeer
);
3137 mpWindowImpl
->mxWindowPeer
->dispose();
3138 mpWindowImpl
->mxWindowPeer
.clear();
3140 mpWindowImpl
->mxWindowPeer
= xPeer
;
3142 mpWindowImpl
->mpVCLXWindow
= pVCLXWindow
;
3145 Reference
< css::awt::XWindowPeer
> Window::GetComponentInterface( bool bCreate
)
3147 if ( !mpWindowImpl
->mxWindowPeer
.is() && bCreate
)
3149 UnoWrapperBase
* pWrapper
= UnoWrapperBase::GetUnoWrapper();
3151 mpWindowImpl
->mxWindowPeer
= pWrapper
->GetWindowInterface( this );
3153 return mpWindowImpl
->mxWindowPeer
;
3156 void Window::SetComponentInterface( Reference
< css::awt::XWindowPeer
> const & xIFace
)
3158 UnoWrapperBase
* pWrapper
= UnoWrapperBase::GetUnoWrapper();
3159 SAL_WARN_IF( !pWrapper
, "vcl.window", "SetComponentInterface: No Wrapper!" );
3161 pWrapper
->SetWindowInterface( this, xIFace
);
3164 typedef std::map
<vcl::LOKWindowId
, VclPtr
<vcl::Window
>> LOKWindowsMap
;
3168 LOKWindowsMap
& GetLOKWindowsMap()
3170 // Map to remember the LOKWindowId <-> Window binding.
3171 static LOKWindowsMap s_aLOKWindowsMap
;
3173 return s_aLOKWindowsMap
;
3178 void Window::SetLOKNotifier(const vcl::ILibreOfficeKitNotifier
* pNotifier
, bool bParent
)
3180 // don't allow setting this twice
3181 assert(mpWindowImpl
->mpLOKNotifier
== nullptr);
3183 // never use this in the desktop case
3184 assert(comphelper::LibreOfficeKit::isActive());
3188 // Counter to be able to have unique id's for each window.
3189 static vcl::LOKWindowId sLastLOKWindowId
= 1;
3191 // assign the LOK window id
3192 assert(mpWindowImpl
->mnLOKWindowId
== 0);
3193 mpWindowImpl
->mnLOKWindowId
= sLastLOKWindowId
++;
3194 GetLOKWindowsMap().emplace(mpWindowImpl
->mnLOKWindowId
, this);
3197 mpWindowImpl
->mbLOKParentNotifier
= true;
3199 mpWindowImpl
->mpLOKNotifier
= pNotifier
;
3202 VclPtr
<Window
> Window::FindLOKWindow(vcl::LOKWindowId nWindowId
)
3204 const auto it
= GetLOKWindowsMap().find(nWindowId
);
3205 if (it
!= GetLOKWindowsMap().end())
3208 return VclPtr
<Window
>();
3211 bool Window::IsLOKWindowsEmpty()
3213 return GetLOKWindowsMap().empty();
3216 void Window::ReleaseLOKNotifier()
3218 // unregister the LOK window binding
3219 if (mpWindowImpl
->mnLOKWindowId
> 0)
3220 GetLOKWindowsMap().erase(mpWindowImpl
->mnLOKWindowId
);
3222 mpWindowImpl
->mpLOKNotifier
= nullptr;
3223 mpWindowImpl
->mnLOKWindowId
= 0;
3226 ILibreOfficeKitNotifier::~ILibreOfficeKitNotifier()
3228 if (!comphelper::LibreOfficeKit::isActive())
3233 for (auto it
= GetLOKWindowsMap().begin(); it
!= GetLOKWindowsMap().end();)
3235 WindowImpl
* pWindowImpl
= it
->second
->ImplGetWindowImpl();
3236 if (pWindowImpl
&& pWindowImpl
->mpLOKNotifier
== this)
3238 pWindowImpl
->mpLOKNotifier
= nullptr;
3239 pWindowImpl
->mnLOKWindowId
= 0;
3240 it
= GetLOKWindowsMap().erase(it
);
3248 const vcl::ILibreOfficeKitNotifier
* Window::GetLOKNotifier() const
3250 return mpWindowImpl
? mpWindowImpl
->mpLOKNotifier
: nullptr;
3253 vcl::LOKWindowId
Window::GetLOKWindowId() const
3255 return mpWindowImpl
? mpWindowImpl
->mnLOKWindowId
: 0;
3258 VclPtr
<vcl::Window
> Window::GetParentWithLOKNotifier()
3260 VclPtr
<vcl::Window
> pWindow(this);
3262 while (pWindow
&& !pWindow
->GetLOKNotifier())
3263 pWindow
= pWindow
->GetParent();
3271 const char* windowTypeName(WindowType nWindowType
)
3273 switch (nWindowType
)
3275 case WindowType::NONE
: return "none";
3276 case WindowType::MESSBOX
: return "messagebox";
3277 case WindowType::INFOBOX
: return "infobox";
3278 case WindowType::WARNINGBOX
: return "warningbox";
3279 case WindowType::ERRORBOX
: return "errorbox";
3280 case WindowType::QUERYBOX
: return "querybox";
3281 case WindowType::WINDOW
: return "window";
3282 case WindowType::WORKWINDOW
: return "workwindow";
3283 case WindowType::CONTAINER
: return "container";
3284 case WindowType::FLOATINGWINDOW
: return "floatingwindow";
3285 case WindowType::DIALOG
: return "dialog";
3286 case WindowType::MODELESSDIALOG
: return "modelessdialog";
3287 case WindowType::CONTROL
: return "control";
3288 case WindowType::PUSHBUTTON
: return "pushbutton";
3289 case WindowType::OKBUTTON
: return "okbutton";
3290 case WindowType::CANCELBUTTON
: return "cancelbutton";
3291 case WindowType::HELPBUTTON
: return "helpbutton";
3292 case WindowType::IMAGEBUTTON
: return "imagebutton";
3293 case WindowType::MENUBUTTON
: return "menubutton";
3294 case WindowType::MOREBUTTON
: return "morebutton";
3295 case WindowType::SPINBUTTON
: return "spinbutton";
3296 case WindowType::RADIOBUTTON
: return "radiobutton";
3297 case WindowType::CHECKBOX
: return "checkbox";
3298 case WindowType::TRISTATEBOX
: return "tristatebox";
3299 case WindowType::EDIT
: return "edit";
3300 case WindowType::MULTILINEEDIT
: return "multilineedit";
3301 case WindowType::COMBOBOX
: return "combobox";
3302 case WindowType::LISTBOX
: return "listbox";
3303 case WindowType::MULTILISTBOX
: return "multilistbox";
3304 case WindowType::FIXEDTEXT
: return "fixedtext";
3305 case WindowType::FIXEDLINE
: return "fixedline";
3306 case WindowType::FIXEDBITMAP
: return "fixedbitmap";
3307 case WindowType::FIXEDIMAGE
: return "fixedimage";
3308 case WindowType::GROUPBOX
: return "groupbox";
3309 case WindowType::SCROLLBAR
: return "scrollbar";
3310 case WindowType::SCROLLBARBOX
: return "scrollbarbox";
3311 case WindowType::SPLITTER
: return "splitter";
3312 case WindowType::SPLITWINDOW
: return "splitwindow";
3313 case WindowType::SPINFIELD
: return "spinfield";
3314 case WindowType::PATTERNFIELD
: return "patternfield";
3315 case WindowType::METRICFIELD
: return "metricfield";
3316 case WindowType::FORMATTEDFIELD
: return "formattedfield";
3317 case WindowType::CURRENCYFIELD
: return "currencyfield";
3318 case WindowType::DATEFIELD
: return "datefield";
3319 case WindowType::TIMEFIELD
: return "timefield";
3320 case WindowType::PATTERNBOX
: return "patternbox";
3321 case WindowType::NUMERICBOX
: return "numericbox";
3322 case WindowType::METRICBOX
: return "metricbox";
3323 case WindowType::CURRENCYBOX
: return "currencybox";
3324 case WindowType::DATEBOX
: return "datebox";
3325 case WindowType::TIMEBOX
: return "timebox";
3326 case WindowType::LONGCURRENCYBOX
: return "longcurrencybox";
3327 case WindowType::SCROLLWINDOW
: return "scrollwindow";
3328 case WindowType::TOOLBOX
: return "toolbox";
3329 case WindowType::DOCKINGWINDOW
: return "dockingwindow";
3330 case WindowType::STATUSBAR
: return "statusbar";
3331 case WindowType::TABPAGE
: return "tabpage";
3332 case WindowType::TABCONTROL
: return "tabcontrol";
3333 case WindowType::TABDIALOG
: return "tabdialog";
3334 case WindowType::BORDERWINDOW
: return "borderwindow";
3335 case WindowType::BUTTONDIALOG
: return "buttondialog";
3336 case WindowType::SYSTEMCHILDWINDOW
: return "systemchildwindow";
3337 case WindowType::SLIDER
: return "slider";
3338 case WindowType::MENUBARWINDOW
: return "menubarwindow";
3339 case WindowType::TREELISTBOX
: return "treelistbox";
3340 case WindowType::HELPTEXTWINDOW
: return "helptextwindow";
3341 case WindowType::INTROWINDOW
: return "introwindow";
3342 case WindowType::LISTBOXWINDOW
: return "listboxwindow";
3343 case WindowType::DOCKINGAREA
: return "dockingarea";
3344 case WindowType::RULER
: return "ruler";
3345 case WindowType::HEADERBAR
: return "headerbar";
3346 case WindowType::VERTICALTABCONTROL
: return "verticaltabcontrol";
3348 // nothing to do here, but for completeness
3349 case WindowType::TOOLKIT_FRAMEWINDOW
: return "toolkit_framewindow";
3350 case WindowType::TOOLKIT_SYSTEMCHILDWINDOW
: return "toolkit_systemchildwindow";
3358 void Window::DumpAsPropertyTree(tools::JsonWriter
& rJsonWriter
)
3363 rJsonWriter
.put("id", get_id()); // TODO could be missing - sort out
3364 rJsonWriter
.put("type", windowTypeName(GetType()));
3365 rJsonWriter
.put("text", GetText());
3366 rJsonWriter
.put("enabled", IsEnabled());
3368 rJsonWriter
.put("visible", false);
3370 if (vcl::Window
* pChild
= mpWindowImpl
->mpFirstChild
)
3372 auto childrenNode
= rJsonWriter
.startArray("children");
3376 auto childNode
= rJsonWriter
.startStruct();
3377 pChild
->DumpAsPropertyTree(rJsonWriter
);
3378 sal_Int32 nLeft
= pChild
->get_grid_left_attach();
3379 sal_Int32 nTop
= pChild
->get_grid_top_attach();
3380 if (nLeft
!= -1 && nTop
!= -1)
3382 rJsonWriter
.put("left", nLeft
);
3383 rJsonWriter
.put("top", nTop
);
3386 sal_Int32 nWidth
= pChild
->get_grid_width();
3388 rJsonWriter
.put("width", nWidth
);
3390 pChild
= pChild
->mpWindowImpl
->mpNext
;
3394 mpWindowImpl
->maDumpAsPropertyTreeHdl
.Call(rJsonWriter
);
3397 void Window::ImplCallDeactivateListeners( vcl::Window
*pNew
)
3399 // no deactivation if the newly activated window is my child
3400 if ( !pNew
|| !ImplIsChild( pNew
) )
3402 VclPtr
<vcl::Window
> xWindow(this);
3403 CallEventListeners( VclEventId::WindowDeactivate
, pNew
);
3404 if( !xWindow
->mpWindowImpl
)
3407 // #100759#, avoid walking the wrong frame's hierarchy
3408 // eg, undocked docking windows (ImplDockFloatWin)
3409 if ( ImplGetParent() && ImplGetParent()->mpWindowImpl
&&
3410 mpWindowImpl
->mpFrameWindow
== ImplGetParent()->mpWindowImpl
->mpFrameWindow
)
3411 ImplGetParent()->ImplCallDeactivateListeners( pNew
);
3415 void Window::ImplCallActivateListeners( vcl::Window
*pOld
)
3417 // no activation if the old active window is my child
3418 if ( pOld
&& ImplIsChild( pOld
))
3421 VclPtr
<vcl::Window
> xWindow(this);
3422 CallEventListeners( VclEventId::WindowActivate
, pOld
);
3423 if( !xWindow
->mpWindowImpl
)
3426 if ( ImplGetParent() )
3427 ImplGetParent()->ImplCallActivateListeners( pOld
);
3428 else if( (mpWindowImpl
->mnStyle
& WB_INTROWIN
) == 0 )
3430 // top level frame reached: store hint for DefModalDialogParent
3431 ImplGetSVData()->maFrameData
.mpActiveApplicationFrame
= mpWindowImpl
->mpFrameWindow
;
3435 void Window::SetClipboard(Reference
<XClipboard
> const & xClipboard
)
3437 if (mpWindowImpl
->mpFrameData
)
3438 mpWindowImpl
->mpFrameData
->mxClipboard
= xClipboard
;
3441 Reference
< XClipboard
> Window::GetClipboard()
3443 if (!mpWindowImpl
->mpFrameData
)
3444 return static_cast<XClipboard
*>(nullptr);
3445 if (!mpWindowImpl
->mpFrameData
->mxClipboard
.is())
3446 mpWindowImpl
->mpFrameData
->mxClipboard
= GetSystemClipboard();
3447 return mpWindowImpl
->mpFrameData
->mxClipboard
;
3450 void Window::RecordLayoutData( vcl::ControlLayoutData
* pLayout
, const tools::Rectangle
& rRect
)
3452 assert(GetOutDev()->mpOutDevData
);
3453 GetOutDev()->mpOutDevData
->mpRecordLayout
= pLayout
;
3454 GetOutDev()->mpOutDevData
->maRecordRect
= rRect
;
3455 Paint(*GetOutDev(), rRect
);
3456 GetOutDev()->mpOutDevData
->mpRecordLayout
= nullptr;
3459 void Window::DrawSelectionBackground( const tools::Rectangle
& rRect
,
3460 sal_uInt16 highlight
,
3465 if( rRect
.IsEmpty() )
3468 const StyleSettings
& rStyles
= GetSettings().GetStyleSettings();
3470 // colors used for item highlighting
3471 Color
aSelectionBorderCol( rStyles
.GetHighlightColor() );
3472 Color
aSelectionFillCol( aSelectionBorderCol
);
3474 bool bDark
= rStyles
.GetFaceColor().IsDark();
3475 bool bBright
= ( rStyles
.GetFaceColor() == COL_WHITE
);
3477 int c1
= aSelectionBorderCol
.GetLuminance();
3478 int c2
= GetBackgroundColor().GetLuminance();
3480 if( !bDark
&& !bBright
&& abs( c2
-c1
) < 75 )
3484 aSelectionFillCol
.RGBtoHSB( h
, s
, b
);
3485 if( b
> 50 ) b
-= 40;
3487 aSelectionFillCol
= Color::HSBtoRGB( h
, s
, b
);
3488 aSelectionBorderCol
= aSelectionFillCol
;
3491 tools::Rectangle
aRect( rRect
);
3492 Color oldFillCol
= GetOutDev()->GetFillColor();
3493 Color oldLineCol
= GetOutDev()->GetLineColor();
3496 GetOutDev()->SetLineColor( bDark
? COL_WHITE
: ( bBright
? COL_BLACK
: aSelectionBorderCol
) );
3498 GetOutDev()->SetLineColor();
3500 sal_uInt16 nPercent
= 0;
3504 aSelectionFillCol
= COL_BLACK
;
3506 nPercent
= 80; // just checked (light)
3510 if( bChecked
&& highlight
== 2 )
3513 aSelectionFillCol
= COL_LIGHTGRAY
;
3516 aSelectionFillCol
= COL_BLACK
;
3517 GetOutDev()->SetLineColor( COL_BLACK
);
3521 nPercent
= 20; // selected, pressed or checked ( very dark )
3523 else if( bChecked
|| highlight
== 1 )
3526 aSelectionFillCol
= COL_GRAY
;
3529 aSelectionFillCol
= COL_BLACK
;
3530 GetOutDev()->SetLineColor( COL_BLACK
);
3534 nPercent
= 35; // selected, pressed or checked ( very dark )
3539 aSelectionFillCol
= COL_LIGHTGRAY
;
3542 aSelectionFillCol
= COL_BLACK
;
3543 GetOutDev()->SetLineColor( COL_BLACK
);
3544 if( highlight
== 3 )
3550 nPercent
= 70; // selected ( dark )
3554 GetOutDev()->SetFillColor( aSelectionFillCol
);
3558 GetOutDev()->DrawRect( aRect
);
3562 tools::Polygon
aPoly( aRect
);
3563 tools::PolyPolygon
aPolyPoly( aPoly
);
3564 GetOutDev()->DrawTransparent( aPolyPoly
, nPercent
);
3567 GetOutDev()->SetFillColor( oldFillCol
);
3568 GetOutDev()->SetLineColor( oldLineCol
);
3571 bool Window::IsScrollable() const
3573 // check for scrollbars
3574 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
3577 if( pChild
->GetType() == WindowType::SCROLLBAR
)
3580 pChild
= pChild
->mpWindowImpl
->mpNext
;
3585 void Window::ImplMirrorFramePos( Point
&pt
) const
3587 pt
.setX( mpWindowImpl
->mpFrame
->maGeometry
.nWidth
-1-pt
.X() );
3590 // frame based modal counter (dialogs are not modal to the whole application anymore)
3591 bool Window::IsInModalMode() const
3593 return (mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpFrameData
->mnModalMode
!= 0);
3596 void Window::IncModalCount()
3598 vcl::Window
* pFrameWindow
= mpWindowImpl
->mpFrameWindow
;
3599 vcl::Window
* pParent
= pFrameWindow
;
3600 while( pFrameWindow
)
3602 pFrameWindow
->mpWindowImpl
->mpFrameData
->mnModalMode
++;
3603 while( pParent
&& pParent
->mpWindowImpl
->mpFrameWindow
== pFrameWindow
)
3605 pParent
= pParent
->GetParent();
3607 pFrameWindow
= pParent
? pParent
->mpWindowImpl
->mpFrameWindow
.get() : nullptr;
3610 void Window::DecModalCount()
3612 vcl::Window
* pFrameWindow
= mpWindowImpl
->mpFrameWindow
;
3613 vcl::Window
* pParent
= pFrameWindow
;
3614 while( pFrameWindow
)
3616 pFrameWindow
->mpWindowImpl
->mpFrameData
->mnModalMode
--;
3617 while( pParent
&& pParent
->mpWindowImpl
->mpFrameWindow
== pFrameWindow
)
3619 pParent
= pParent
->GetParent();
3621 pFrameWindow
= pParent
? pParent
->mpWindowImpl
->mpFrameWindow
.get() : nullptr;
3625 void Window::ImplIsInTaskPaneList( bool mbIsInTaskList
)
3627 mpWindowImpl
->mbIsInTaskPaneList
= mbIsInTaskList
;
3630 void Window::ImplNotifyIconifiedState( bool bIconified
)
3632 mpWindowImpl
->mpFrameWindow
->CallEventListeners( bIconified
? VclEventId::WindowMinimize
: VclEventId::WindowNormalize
);
3633 // #109206# notify client window as well to have toolkit topwindow listeners notified
3634 if( mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpClientWindow
&& mpWindowImpl
->mpFrameWindow
!= mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpClientWindow
)
3635 mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpClientWindow
->CallEventListeners( bIconified
? VclEventId::WindowMinimize
: VclEventId::WindowNormalize
);
3638 bool Window::HasActiveChildFrame() const
3641 vcl::Window
*pFrameWin
= ImplGetSVData()->maFrameData
.mpFirstFrame
;
3644 if( pFrameWin
!= mpWindowImpl
->mpFrameWindow
)
3646 bool bDecorated
= false;
3647 VclPtr
< vcl::Window
> pChildFrame
= pFrameWin
->ImplGetWindow();
3648 // #i15285# unfortunately WB_MOVEABLE is the same as WB_TABSTOP which can
3649 // be removed for ToolBoxes to influence the keyboard accessibility
3650 // thus WB_MOVEABLE is no indicator for decoration anymore
3651 // but FloatingWindows carry this information in their TitleType...
3652 // TODO: avoid duplicate WinBits !!!
3653 if( pChildFrame
&& pChildFrame
->ImplIsFloatingWindow() )
3654 bDecorated
= static_cast<FloatingWindow
*>(pChildFrame
.get())->GetTitleType() != FloatWinTitleType::NONE
;
3655 if( bDecorated
|| (pFrameWin
->mpWindowImpl
->mnStyle
& (WB_MOVEABLE
| WB_SIZEABLE
) ) )
3656 if( pChildFrame
&& pChildFrame
->IsVisible() && pChildFrame
->IsActive() )
3658 if( ImplIsChild( pChildFrame
, true ) )
3665 pFrameWin
= pFrameWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
3670 LanguageType
Window::GetInputLanguage() const
3672 return mpWindowImpl
->mpFrame
->GetInputLanguage();
3675 void Window::EnableNativeWidget( bool bEnable
)
3677 static const char* pNoNWF
= getenv( "SAL_NO_NWF" );
3678 if( pNoNWF
&& *pNoNWF
)
3681 if( bEnable
!= ImplGetWinData()->mbEnableNativeWidget
)
3683 ImplGetWinData()->mbEnableNativeWidget
= bEnable
;
3685 // send datachanged event to allow for internal changes required for NWF
3686 // like clipmode, transparency, etc.
3687 DataChangedEvent
aDCEvt( DataChangedEventType::SETTINGS
, GetOutDev()->mxSettings
.get(), AllSettingsFlags::STYLE
);
3688 CompatDataChanged( aDCEvt
);
3690 // sometimes the borderwindow is queried, so keep it in sync
3691 if( mpWindowImpl
->mpBorderWindow
)
3692 mpWindowImpl
->mpBorderWindow
->ImplGetWinData()->mbEnableNativeWidget
= bEnable
;
3695 // push down, useful for compound controls
3696 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
3699 pChild
->EnableNativeWidget( bEnable
);
3700 pChild
= pChild
->mpWindowImpl
->mpNext
;
3704 bool Window::IsNativeWidgetEnabled() const
3706 return mpWindowImpl
&& ImplGetWinData()->mbEnableNativeWidget
;
3709 Reference
< css::rendering::XCanvas
> WindowOutputDevice::ImplGetCanvas( bool bSpriteCanvas
) const
3711 // Feed any with operating system's window handle
3713 // common: first any is VCL pointer to window (for VCL canvas)
3714 Sequence
< Any
> aArg
{
3715 Any(reinterpret_cast<sal_Int64
>(this)),
3716 Any(css::awt::Rectangle( mnOutOffX
, mnOutOffY
, mnOutWidth
, mnOutHeight
)),
3717 Any(mxOwnerWindow
->mpWindowImpl
->mbAlwaysOnTop
),
3718 Any(Reference
< css::awt::XWindow
>(
3719 mxOwnerWindow
->GetComponentInterface(),
3721 GetSystemGfxDataAny()
3724 Reference
< XComponentContext
> xContext
= comphelper::getProcessComponentContext();
3726 // Create canvas instance with window handle
3728 static vcl::DeleteUnoReferenceOnDeinit
<XMultiComponentFactory
> xStaticCanvasFactory(
3729 css::rendering::CanvasFactory::create( xContext
) );
3730 Reference
<XMultiComponentFactory
> xCanvasFactory(xStaticCanvasFactory
.get());
3731 Reference
< css::rendering::XCanvas
> xCanvas
;
3733 if(xCanvasFactory
.is())
3736 // see #140456# - if we're running on a multiscreen setup,
3737 // request special, multi-screen safe sprite canvas
3738 // implementation (not DX5 canvas, as it cannot cope with
3739 // surfaces spanning multiple displays). Note: canvas
3740 // (without sprite) stays the same)
3741 const sal_uInt32 nDisplay
= static_cast< WinSalFrame
* >( mxOwnerWindow
->mpWindowImpl
->mpFrame
)->mnDisplay
;
3742 if( nDisplay
>= Application::GetScreenCount() )
3744 xCanvas
.set( xCanvasFactory
->createInstanceWithArgumentsAndContext(
3746 OUString( "com.sun.star.rendering.SpriteCanvas.MultiScreen" ) :
3747 OUString( "com.sun.star.rendering.Canvas.MultiScreen" ),
3756 xCanvas
.set( xCanvasFactory
->createInstanceWithArgumentsAndContext(
3758 OUString( "com.sun.star.rendering.SpriteCanvas" ) :
3759 OUString( "com.sun.star.rendering.Canvas" ),
3767 // no factory??? Empty reference, then.
3771 OUString
Window::GetSurroundingText() const
3776 Selection
Window::GetSurroundingTextSelection() const
3778 return Selection( 0, 0 );
3783 using namespace com::sun::star
;
3785 uno::Reference
<accessibility::XAccessibleEditableText
> lcl_GetxText(vcl::Window
*pFocusWin
)
3787 uno::Reference
<accessibility::XAccessibleEditableText
> xText
;
3790 uno::Reference
< accessibility::XAccessible
> xAccessible( pFocusWin
->GetAccessible() );
3791 if (xAccessible
.is())
3792 xText
= FindFocusedEditableText(xAccessible
->getAccessibleContext());
3794 catch(const uno::Exception
&)
3796 TOOLS_WARN_EXCEPTION( "vcl.gtk3", "Exception in getting input method surrounding text");
3802 // this is a rubbish implementation using a11y, ideally all subclasses implementing
3803 // GetSurroundingText/GetSurroundingTextSelection should implement this and then this
3804 // should be removed in favor of a stub that returns false
3805 bool Window::DeleteSurroundingText(const Selection
& rSelection
)
3807 uno::Reference
<accessibility::XAccessibleEditableText
> xText
= lcl_GetxText(this);
3810 sal_Int32 nPosition
= xText
->getCaretPosition();
3811 // #i111768# range checking
3812 sal_Int32 nDeletePos
= rSelection
.Min();
3813 sal_Int32 nDeleteEnd
= rSelection
.Max();
3818 if (nDeleteEnd
> xText
->getCharacterCount())
3819 nDeleteEnd
= xText
->getCharacterCount();
3821 xText
->deleteText(nDeletePos
, nDeleteEnd
);
3822 //tdf91641 adjust cursor if deleted chars shift it forward (normal case)
3823 if (nDeletePos
< nPosition
)
3825 if (nDeleteEnd
<= nPosition
)
3826 nPosition
= nPosition
- (nDeleteEnd
- nDeletePos
);
3828 nPosition
= nDeletePos
;
3830 if (xText
->getCharacterCount() >= nPosition
)
3831 xText
->setCaretPosition( nPosition
);
3839 bool WindowOutputDevice::UsePolyPolygonForComplexGradient()
3841 return meRasterOp
!= RasterOp::OverPaint
;
3844 void Window::ApplySettings(vcl::RenderContext
& /*rRenderContext*/)
3848 const SystemEnvData
* Window::GetSystemData() const
3851 return mpWindowImpl
->mpFrame
? mpWindowImpl
->mpFrame
->GetSystemData() : nullptr;
3854 bool Window::SupportsDoubleBuffering() const
3856 return mpWindowImpl
->mpFrameData
->mpBuffer
;
3859 void Window::RequestDoubleBuffering(bool bRequest
)
3863 mpWindowImpl
->mpFrameData
->mpBuffer
= VclPtrInstance
<VirtualDevice
>();
3864 // Make sure that the buffer size matches the frame size.
3865 mpWindowImpl
->mpFrameData
->mpBuffer
->SetOutputSizePixel(mpWindowImpl
->mpFrameWindow
->GetOutputSizePixel());
3868 mpWindowImpl
->mpFrameData
->mpBuffer
.reset();
3872 * The rationale here is that we moved destructors to
3873 * dispose and this altered a lot of code paths, that
3874 * are better left unchanged for now.
3876 void Window::CompatGetFocus()
3878 if (!mpWindowImpl
|| mpWindowImpl
->mbInDispose
)
3884 void Window::CompatLoseFocus()
3886 if (!mpWindowImpl
|| mpWindowImpl
->mbInDispose
)
3887 Window::LoseFocus();
3892 void Window::CompatStateChanged( StateChangedType nStateChange
)
3894 if (!mpWindowImpl
|| mpWindowImpl
->mbInDispose
)
3895 Window::StateChanged(nStateChange
);
3897 StateChanged(nStateChange
);
3900 void Window::CompatDataChanged( const DataChangedEvent
& rDCEvt
)
3902 if (!mpWindowImpl
|| mpWindowImpl
->mbInDispose
)
3903 Window::DataChanged(rDCEvt
);
3905 DataChanged(rDCEvt
);
3908 bool Window::CompatPreNotify( NotifyEvent
& rNEvt
)
3910 if (!mpWindowImpl
|| mpWindowImpl
->mbInDispose
)
3911 return Window::PreNotify( rNEvt
);
3913 return PreNotify( rNEvt
);
3916 bool Window::CompatNotify( NotifyEvent
& rNEvt
)
3918 if (!mpWindowImpl
|| mpWindowImpl
->mbInDispose
)
3919 return Window::EventNotify( rNEvt
);
3921 return EventNotify( rNEvt
);
3924 void Window::set_id(const OUString
& rID
)
3926 mpWindowImpl
->maID
= rID
;
3929 const OUString
& Window::get_id() const
3931 static OUString empty
;
3932 return mpWindowImpl
? mpWindowImpl
->maID
: empty
;
3935 FactoryFunction
Window::GetUITestFactory() const
3937 return WindowUIObject::create
;
3940 WindowOutputDevice::WindowOutputDevice(vcl::Window
& rOwnerWindow
) :
3941 ::OutputDevice(OUTDEV_WINDOW
),
3942 mxOwnerWindow(&rOwnerWindow
)
3944 assert(mxOwnerWindow
);
3947 WindowOutputDevice::~WindowOutputDevice()
3952 void WindowOutputDevice::dispose()
3954 assert((!mxOwnerWindow
|| mxOwnerWindow
->isDisposed()) && "This belongs to the associated window and must be disposed after it");
3955 ::OutputDevice::dispose();
3956 // need to do this after OutputDevice::dispose so that the call to WindowOutputDevice::ReleaseGraphics
3957 // can release the graphics properly
3958 mxOwnerWindow
.clear();
3961 css::awt::DeviceInfo
WindowOutputDevice::GetDeviceInfo() const
3963 css::awt::DeviceInfo aInfo
= GetCommonDeviceInfo(mxOwnerWindow
->GetSizePixel());
3964 mxOwnerWindow
->GetBorder(aInfo
.LeftInset
, aInfo
.TopInset
, aInfo
.RightInset
, aInfo
.BottomInset
);
3969 } /* namespace vcl */
3971 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */