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 <rtl/strbuf.hxx>
21 #include <sal/log.hxx>
23 #include <sal/types.h>
24 #include <tools/diagnose_ex.h>
25 #include <vcl/salgtype.hxx>
26 #include <vcl/event.hxx>
27 #include <vcl/help.hxx>
28 #include <vcl/cursor.hxx>
29 #include <vcl/svapp.hxx>
30 #include <vcl/transfer.hxx>
31 #include <vcl/vclevent.hxx>
32 #include <vcl/window.hxx>
33 #include <vcl/syswin.hxx>
34 #include <vcl/dockwin.hxx>
35 #include <vcl/wall.hxx>
36 #include <vcl/toolkit/fixed.hxx>
37 #include <vcl/taskpanelist.hxx>
38 #include <vcl/toolkit/unowrap.hxx>
39 #include <vcl/lazydelete.hxx>
40 #include <vcl/virdev.hxx>
41 #include <vcl/settings.hxx>
42 #include <vcl/sysdata.hxx>
43 #include <vcl/ptrstyle.hxx>
44 #include <vcl/IDialogRenderable.hxx>
46 #include <vcl/uitest/uiobject.hxx>
48 #include <salframe.hxx>
50 #include <salinst.hxx>
57 #include <helpwin.hxx>
59 #include <com/sun/star/accessibility/AccessibleRelation.hpp>
60 #include <com/sun/star/accessibility/XAccessible.hpp>
61 #include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
62 #include <com/sun/star/awt/XWindowPeer.hpp>
63 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
64 #include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
65 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
66 #include <com/sun/star/rendering/CanvasFactory.hpp>
67 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
68 #include <comphelper/lok.hxx>
69 #include <comphelper/processfactory.hxx>
70 #include <unotools/configmgr.hxx>
71 #include <osl/diagnose.h>
72 #include <tools/debug.hxx>
73 #include <tools/json_writer.hxx>
74 #include <boost/property_tree/ptree.hpp>
79 #ifdef _WIN32 // see #140456#
80 #include <win/salframe.h>
84 using namespace ::com::sun::star::uno
;
85 using namespace ::com::sun::star::lang
;
86 using namespace ::com::sun::star::datatransfer::clipboard
;
87 using namespace ::com::sun::star::datatransfer::dnd
;
91 Window::Window( WindowType nType
)
92 : OutputDevice(OUTDEV_WINDOW
)
93 , mpWindowImpl(new WindowImpl( nType
))
95 // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
96 mbEnableRTL
= AllSettings::GetLayoutRTL();
99 Window::Window( vcl::Window
* pParent
, WinBits nStyle
)
100 : OutputDevice(OUTDEV_WINDOW
)
101 , mpWindowImpl(new WindowImpl( WindowType::WINDOW
))
103 // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
104 mbEnableRTL
= AllSettings::GetLayoutRTL();
106 ImplInit( pParent
, nStyle
, nullptr );
109 #if OSL_DEBUG_LEVEL > 0
112 OString
lcl_createWindowInfo(const vcl::Window
* pWindow
)
114 // skip border windows, they do not carry information that
115 // would help with diagnosing the problem
116 const vcl::Window
* pTempWin( pWindow
);
117 while ( pTempWin
&& pTempWin
->GetType() == WindowType::BORDERWINDOW
) {
118 pTempWin
= pTempWin
->GetWindow( GetWindowType::FirstChild
);
120 // check if pTempWin is not null, otherwise use the
126 OStringBuffer aErrorString
;
127 aErrorString
.append(' ');
128 aErrorString
.append(typeid( *pWindow
).name());
129 aErrorString
.append("(");
133 RTL_TEXTENCODING_UTF8
136 aErrorString
.append(")");
137 return aErrorString
.makeStringAndClear();
142 bool Window::IsDisposed() const
144 return !mpWindowImpl
;
147 void Window::dispose()
149 assert( mpWindowImpl
);
150 assert( !mpWindowImpl
->mbInDispose
); // should only be called from disposeOnce()
151 assert( (!mpWindowImpl
->mpParent
||
152 !mpWindowImpl
->mpParent
->IsDisposed()) &&
153 "vcl::Window child should have its parent disposed first" );
155 // remove Key and Mouse events issued by Application::PostKey/MouseEvent
156 Application::RemoveMouseAndKeyEvents( this );
158 // Dispose of the canvas implementation (which, currently, has an
159 // own wrapper window as a child to this one.
160 Reference
< css::rendering::XCanvas
> xCanvas( mpWindowImpl
->mxCanvas
);
163 Reference
< XComponent
> xCanvasComponent( xCanvas
, UNO_QUERY
);
164 if( xCanvasComponent
.is() )
165 xCanvasComponent
->dispose();
168 mpWindowImpl
->mbInDispose
= true;
170 CallEventListeners( VclEventId::ObjectDying
);
172 // do not send child events for frames that were registered as native frames
173 if( !ImplIsAccessibleNativeFrame() && mpWindowImpl
->mbReallyVisible
)
174 if ( ImplIsAccessibleCandidate() && GetAccessibleParentWindow() )
175 GetAccessibleParentWindow()->CallEventListeners( VclEventId::WindowChildDestroyed
, this );
177 // remove associated data structures from dockingmanager
178 ImplGetDockingManager()->RemoveWindow( this );
180 // remove ownerdraw decorated windows from list in the top-most frame window
181 if( (GetStyle() & WB_OWNERDRAWDECORATION
) && mpWindowImpl
->mbFrame
)
183 ::std::vector
< VclPtr
<vcl::Window
> >& rList
= ImplGetOwnerDrawList();
184 auto p
= ::std::find( rList
.begin(), rList
.end(), VclPtr
<vcl::Window
>(this) );
185 if( p
!= rList
.end() )
189 // shutdown drag and drop
190 Reference
< XComponent
> xDnDComponent( mpWindowImpl
->mxDNDListenerContainer
, UNO_QUERY
);
192 if( xDnDComponent
.is() )
193 xDnDComponent
->dispose();
195 if( mpWindowImpl
->mbFrame
&& mpWindowImpl
->mpFrameData
)
199 // deregister drop target listener
200 if( mpWindowImpl
->mpFrameData
->mxDropTargetListener
.is() )
202 Reference
< XDragGestureRecognizer
> xDragGestureRecognizer(mpWindowImpl
->mpFrameData
->mxDragSource
, UNO_QUERY
);
203 if( xDragGestureRecognizer
.is() )
205 xDragGestureRecognizer
->removeDragGestureListener(
206 Reference
< XDragGestureListener
> (mpWindowImpl
->mpFrameData
->mxDropTargetListener
, UNO_QUERY
));
209 mpWindowImpl
->mpFrameData
->mxDropTarget
->removeDropTargetListener( mpWindowImpl
->mpFrameData
->mxDropTargetListener
);
210 mpWindowImpl
->mpFrameData
->mxDropTargetListener
.clear();
213 // shutdown drag and drop for this frame window
214 Reference
< XComponent
> xComponent( mpWindowImpl
->mpFrameData
->mxDropTarget
, UNO_QUERY
);
216 // DNDEventDispatcher does not hold a reference of the DropTarget,
217 // so it's ok if it does not support XComponent
218 if( xComponent
.is() )
219 xComponent
->dispose();
221 catch (const Exception
&)
223 // can be safely ignored here.
227 UnoWrapperBase
* pWrapper
= UnoWrapperBase::GetUnoWrapper( false );
229 pWrapper
->WindowDestroyed( this );
231 // MT: Must be called after WindowDestroyed!
232 // Otherwise, if the accessible is a VCLXWindow, it will try to destroy this window again!
233 // But accessibility implementations from applications need this dispose.
234 if ( mpWindowImpl
->mxAccessible
.is() )
236 Reference
< XComponent
> xC( mpWindowImpl
->mxAccessible
, UNO_QUERY
);
241 ImplSVData
* pSVData
= ImplGetSVData();
243 if ( ImplGetSVHelpData().mpHelpWin
&& (ImplGetSVHelpData().mpHelpWin
->GetParent() == this) )
244 ImplDestroyHelpWindow( true );
246 SAL_WARN_IF(pSVData
->mpWinData
->mpTrackWin
.get() == this, "vcl.window",
247 "Window::~Window(): Window is in TrackingMode");
248 SAL_WARN_IF(IsMouseCaptured(), "vcl.window",
249 "Window::~Window(): Window has the mouse captured");
251 // due to old compatibility
252 if (pSVData
->mpWinData
->mpTrackWin
== this)
254 if (IsMouseCaptured())
257 #if OSL_DEBUG_LEVEL > 0
258 // always perform these tests in debug builds
260 OStringBuffer aErrorStr
;
262 vcl::Window
* pTempWin
;
264 if ( mpWindowImpl
->mpFirstChild
)
266 OStringBuffer
aTempStr("Window (");
267 aTempStr
.append(lcl_createWindowInfo(this));
268 aTempStr
.append(") with live children destroyed: ");
269 pTempWin
= mpWindowImpl
->mpFirstChild
;
272 aTempStr
.append(lcl_createWindowInfo(pTempWin
));
273 pTempWin
= pTempWin
->mpWindowImpl
->mpNext
;
275 OSL_FAIL( aTempStr
.getStr() );
276 Application::Abort(OStringToOUString(aTempStr
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
)); // abort in debug builds, this must be fixed!
279 if (mpWindowImpl
->mpFrameData
!= nullptr)
281 pTempWin
= mpWindowImpl
->mpFrameData
->mpFirstOverlap
;
284 if ( ImplIsRealParentPath( pTempWin
) )
287 aErrorStr
.append(lcl_createWindowInfo(pTempWin
));
289 pTempWin
= pTempWin
->mpWindowImpl
->mpNextOverlap
;
293 OStringBuffer aTempStr
;
294 aTempStr
.append("Window (");
295 aTempStr
.append(lcl_createWindowInfo(this));
296 aTempStr
.append(") with live SystemWindows destroyed: ");
297 aTempStr
.append(aErrorStr
.toString());
298 OSL_FAIL(aTempStr
.getStr());
299 // abort in debug builds, must be fixed!
300 Application::Abort(OStringToOUString(
301 aTempStr
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
));
306 pTempWin
= pSVData
->maFrameData
.mpFirstFrame
;
309 if ( ImplIsRealParentPath( pTempWin
) )
312 aErrorStr
.append(lcl_createWindowInfo(pTempWin
));
314 pTempWin
= pTempWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
318 OStringBuffer
aTempStr( "Window (" );
319 aTempStr
.append(lcl_createWindowInfo(this));
320 aTempStr
.append(") with live SystemWindows destroyed: ");
321 aTempStr
.append(aErrorStr
.toString());
322 OSL_FAIL( aTempStr
.getStr() );
323 Application::Abort(OStringToOUString(aTempStr
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
)); // abort in debug builds, this must be fixed!
326 if ( mpWindowImpl
->mpFirstOverlap
)
328 OStringBuffer
aTempStr("Window (");
329 aTempStr
.append(lcl_createWindowInfo(this));
330 aTempStr
.append(") with live SystemWindows destroyed: ");
331 pTempWin
= mpWindowImpl
->mpFirstOverlap
;
334 aTempStr
.append(lcl_createWindowInfo(pTempWin
));
335 pTempWin
= pTempWin
->mpWindowImpl
->mpNext
;
337 OSL_FAIL( aTempStr
.getStr() );
338 Application::Abort(OStringToOUString(aTempStr
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
)); // abort in debug builds, this must be fixed!
341 vcl::Window
* pMyParent
= GetParent();
342 SystemWindow
* pMySysWin
= nullptr;
346 if ( pMyParent
->IsSystemWindow() )
348 pMySysWin
= dynamic_cast<SystemWindow
*>(pMyParent
);
350 pMyParent
= pMyParent
->GetParent();
352 if ( pMySysWin
&& pMySysWin
->ImplIsInTaskPaneList( this ) )
354 OStringBuffer
aTempStr("Window (");
355 aTempStr
.append(lcl_createWindowInfo(this));
356 aTempStr
.append(") still in TaskPanelList!");
357 OSL_FAIL( aTempStr
.getStr() );
358 Application::Abort(OStringToOUString(aTempStr
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
)); // abort in debug builds, this must be fixed!
363 if( mpWindowImpl
->mbIsInTaskPaneList
)
365 vcl::Window
* pMyParent
= GetParent();
366 SystemWindow
* pMySysWin
= nullptr;
370 if ( pMyParent
->IsSystemWindow() )
372 pMySysWin
= dynamic_cast<SystemWindow
*>(pMyParent
);
374 pMyParent
= pMyParent
->GetParent();
376 if ( pMySysWin
&& pMySysWin
->ImplIsInTaskPaneList( this ) )
378 pMySysWin
->GetTaskPaneList()->RemoveWindow( this );
382 SAL_WARN( "vcl", "Window (" << GetText() << ") not found in TaskPanelList");
386 // remove from size-group if necessary
387 remove_from_all_size_groups();
389 // clear mnemonic labels
390 std::vector
<VclPtr
<FixedText
> > aMnemonicLabels(list_mnemonic_labels());
391 for (auto const& mnemonicLabel
: aMnemonicLabels
)
393 remove_mnemonic_label(mnemonicLabel
);
396 // hide window in order to trigger the Paint-Handling
399 // EndExtTextInputMode
400 if (pSVData
->mpWinData
->mpExtTextInputWin
== this)
403 if (pSVData
->mpWinData
->mpExtTextInputWin
== this)
404 pSVData
->mpWinData
->mpExtTextInputWin
= nullptr;
407 // check if the focus window is our child
408 bool bHasFocusedChild
= false;
409 if (pSVData
->mpWinData
->mpFocusWin
&& ImplIsRealParentPath(pSVData
->mpWinData
->mpFocusWin
))
411 // #122232#, this must not happen and is an application bug ! but we try some cleanup to hopefully avoid crashes, see below
412 bHasFocusedChild
= true;
413 #if OSL_DEBUG_LEVEL > 0
414 OUString aTempStr
= "Window (" + GetText() +
415 ") with focused child window destroyed ! THIS WILL LEAD TO CRASHES AND MUST BE FIXED !";
416 SAL_WARN( "vcl", aTempStr
);
417 Application::Abort(aTempStr
); // abort in debug build version, this must be fixed!
421 // if we get focus pass focus to another window
422 vcl::Window
* pOverlapWindow
= ImplGetFirstOverlapWindow();
423 if (pSVData
->mpWinData
->mpFocusWin
== this
424 || bHasFocusedChild
) // #122232#, see above, try some cleanup
426 if ( mpWindowImpl
->mbFrame
)
428 pSVData
->mpWinData
->mpFocusWin
= nullptr;
429 pOverlapWindow
->mpWindowImpl
->mpLastFocusWindow
= nullptr;
433 vcl::Window
* pParent
= GetParent();
434 vcl::Window
* pBorderWindow
= mpWindowImpl
->mpBorderWindow
;
435 // when windows overlap, give focus to the parent
436 // of the next FrameWindow
439 if ( pBorderWindow
->ImplIsOverlapWindow() )
440 pParent
= pBorderWindow
->mpWindowImpl
->mpOverlapWindow
;
442 else if ( ImplIsOverlapWindow() )
443 pParent
= mpWindowImpl
->mpOverlapWindow
;
445 if ( pParent
&& pParent
->IsEnabled() && pParent
->IsInputEnabled() && ! pParent
->IsInModalMode() )
446 pParent
->GrabFocus();
448 mpWindowImpl
->mpFrameWindow
->GrabFocus();
450 // If the focus was set back to 'this' set it to nothing
451 if (pSVData
->mpWinData
->mpFocusWin
== this)
453 pSVData
->mpWinData
->mpFocusWin
= nullptr;
454 pOverlapWindow
->mpWindowImpl
->mpLastFocusWindow
= nullptr;
459 if ( pOverlapWindow
!= nullptr &&
460 pOverlapWindow
->mpWindowImpl
->mpLastFocusWindow
== this )
461 pOverlapWindow
->mpWindowImpl
->mpLastFocusWindow
= nullptr;
463 // reset hint for DefModalDialogParent
464 if( pSVData
->maFrameData
.mpActiveApplicationFrame
== this )
465 pSVData
->maFrameData
.mpActiveApplicationFrame
= nullptr;
467 // reset hint of what was the last wheeled window
468 if (pSVData
->mpWinData
->mpLastWheelWindow
== this)
469 pSVData
->mpWinData
->mpLastWheelWindow
= nullptr;
471 // reset marked windows
472 if ( mpWindowImpl
->mpFrameData
!= nullptr )
474 if ( mpWindowImpl
->mpFrameData
->mpFocusWin
== this )
475 mpWindowImpl
->mpFrameData
->mpFocusWin
= nullptr;
476 if ( mpWindowImpl
->mpFrameData
->mpMouseMoveWin
== this )
477 mpWindowImpl
->mpFrameData
->mpMouseMoveWin
= nullptr;
478 if ( mpWindowImpl
->mpFrameData
->mpMouseDownWin
== this )
479 mpWindowImpl
->mpFrameData
->mpMouseDownWin
= nullptr;
482 // reset Deactivate-Window
483 if (pSVData
->mpWinData
->mpLastDeacWin
== this)
484 pSVData
->mpWinData
->mpLastDeacWin
= nullptr;
486 if ( mpWindowImpl
->mbFrame
&& mpWindowImpl
->mpFrameData
)
488 if ( mpWindowImpl
->mpFrameData
->mnFocusId
)
489 Application::RemoveUserEvent( mpWindowImpl
->mpFrameData
->mnFocusId
);
490 mpWindowImpl
->mpFrameData
->mnFocusId
= nullptr;
491 if ( mpWindowImpl
->mpFrameData
->mnMouseMoveId
)
492 Application::RemoveUserEvent( mpWindowImpl
->mpFrameData
->mnMouseMoveId
);
493 mpWindowImpl
->mpFrameData
->mnMouseMoveId
= nullptr;
496 // release SalGraphics
497 OutputDevice
*pOutDev
= GetOutDev();
498 pOutDev
->ReleaseGraphics();
500 // remove window from the lists
501 ImplRemoveWindow( true );
503 // de-register as "top window child" at our parent, if necessary
504 if ( mpWindowImpl
->mbFrame
)
507 = mpWindowImpl
->mpWinData
&& (mpWindowImpl
->mpWinData
->mnIsTopWindow
== 1);
508 if ( mpWindowImpl
->mpRealParent
&& bIsTopWindow
)
510 ImplWinData
* pParentWinData
= mpWindowImpl
->mpRealParent
->ImplGetWinData();
512 auto myPos
= ::std::find( pParentWinData
->maTopWindowChildren
.begin(),
513 pParentWinData
->maTopWindowChildren
.end(), VclPtr
<vcl::Window
>(this) );
514 SAL_WARN_IF( myPos
== pParentWinData
->maTopWindowChildren
.end(), "vcl.window", "Window::~Window: inconsistency in top window chain!" );
515 if ( myPos
!= pParentWinData
->maTopWindowChildren
.end() )
516 pParentWinData
->maTopWindowChildren
.erase( myPos
);
520 delete mpWindowImpl
->mpWinData
;
521 mpWindowImpl
->mpWinData
= nullptr;
523 // remove BorderWindow or Frame window data
524 mpWindowImpl
->mpBorderWindow
.disposeAndClear();
525 if ( mpWindowImpl
->mbFrame
)
527 if ( pSVData
->maFrameData
.mpFirstFrame
== this )
528 pSVData
->maFrameData
.mpFirstFrame
= mpWindowImpl
->mpFrameData
->mpNextFrame
;
531 sal_Int32 nWindows
= 0;
532 vcl::Window
* pSysWin
= pSVData
->maFrameData
.mpFirstFrame
;
533 while ( pSysWin
&& pSysWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
.get() != this )
535 pSysWin
= pSysWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
541 assert (mpWindowImpl
->mpFrameData
->mpNextFrame
.get() != pSysWin
);
542 pSysWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
= mpWindowImpl
->mpFrameData
->mpNextFrame
;
544 else // if it is not in the list, we can't remove it.
545 SAL_WARN("vcl.window", "Window " << this << " marked as frame window, "
546 "is missing from list of " << nWindows
<< " frames");
548 if (mpWindowImpl
->mpFrame
) // otherwise exception during init
550 mpWindowImpl
->mpFrame
->SetCallback( nullptr, nullptr );
551 pSVData
->mpDefInst
->DestroyFrame( mpWindowImpl
->mpFrame
);
553 assert (mpWindowImpl
->mpFrameData
->mnFocusId
== nullptr);
554 assert (mpWindowImpl
->mpFrameData
->mnMouseMoveId
== nullptr);
556 mpWindowImpl
->mpFrameData
->mpBuffer
.disposeAndClear();
557 delete mpWindowImpl
->mpFrameData
;
558 mpWindowImpl
->mpFrameData
= nullptr;
561 // should be the last statements
562 mpWindowImpl
.reset();
564 OutputDevice::dispose();
572 // We will eventually being removing the inheritance of OutputDevice
573 // from Window. It will be replaced with a transient relationship such
574 // that the OutputDevice is only live for the scope of the Paint method.
575 // In the meantime this can help move us towards a Window use an
576 // OutputDevice, not being one.
578 ::OutputDevice
const* Window::GetOutDev() const
583 ::OutputDevice
* Window::GetOutDev()
588 Color
Window::GetBackgroundColor() const
590 return GetDisplayBackground().GetColor();
593 } /* namespace vcl */
595 WindowImpl::WindowImpl( WindowType nType
)
597 maZoom
= Fraction( 1, 1 );
598 maWinRegion
= vcl::Region(true);
599 maWinClipRegion
= vcl::Region(true);
600 mpWinData
= nullptr; // Extra Window Data, that we don't need for all windows
601 mpFrameData
= nullptr; // Frame Data
602 mpFrame
= nullptr; // Pointer to frame window
604 mpFrameWindow
= nullptr; // window to top level parent (same as frame window)
605 mpOverlapWindow
= nullptr; // first overlap parent
606 mpBorderWindow
= nullptr; // Border-Window
607 mpClientWindow
= nullptr; // Client-Window of a FrameWindow
608 mpParent
= nullptr; // parent (incl. BorderWindow)
609 mpRealParent
= nullptr; // real parent (excl. BorderWindow)
610 mpFirstChild
= nullptr; // first child window
611 mpLastChild
= nullptr; // last child window
612 mpFirstOverlap
= nullptr; // first overlap window (only set in overlap windows)
613 mpLastOverlap
= nullptr; // last overlap window (only set in overlap windows)
614 mpPrev
= nullptr; // prev window
615 mpNext
= nullptr; // next window
616 mpNextOverlap
= nullptr; // next overlap window of frame
617 mpLastFocusWindow
= nullptr; // window for focus restore
618 mpDlgCtrlDownWindow
= nullptr; // window for dialog control
619 mnEventListenersIteratingCount
= 0;
620 mnChildEventListenersIteratingCount
= 0;
621 mpCursor
= nullptr; // cursor
622 maPointer
= PointerStyle::Arrow
;
623 mpVCLXWindow
= nullptr;
624 mpAccessibleInfos
= nullptr;
625 maControlForeground
= COL_TRANSPARENT
; // no foreground set
626 maControlBackground
= COL_TRANSPARENT
; // no background set
627 mnLeftBorder
= 0; // left border
628 mnTopBorder
= 0; // top border
629 mnRightBorder
= 0; // right border
630 mnBottomBorder
= 0; // bottom border
631 mnWidthRequest
= -1; // width request
632 mnHeightRequest
= -1; // height request
633 mnOptimalWidthCache
= -1; // optimal width cache
634 mnOptimalHeightCache
= -1; // optimal height cache
635 mnX
= 0; // X-Position to Parent
636 mnY
= 0; // Y-Position to Parent
637 mnAbsScreenX
= 0; // absolute X-position on screen, used for RTL window positioning
638 mpChildClipRegion
= nullptr; // Child-Clip-Region when ClipChildren
639 mpPaintRegion
= nullptr; // Paint-ClipRegion
640 mnStyle
= 0; // style (init in ImplInitWindow)
641 mnPrevStyle
= 0; // prevstyle (set in SetStyle)
642 mnExtendedStyle
= WindowExtendedStyle::NONE
; // extended style (init in ImplInitWindow)
643 mnType
= nType
; // type
644 mnGetFocusFlags
= GetFocusFlags::NONE
; // Flags for GetFocus()-Call
645 mnWaitCount
= 0; // Wait-Count (>1 == "wait" mouse pointer)
646 mnPaintFlags
= ImplPaintFlags::NONE
; // Flags for ImplCallPaint
647 mnParentClipMode
= ParentClipMode::NONE
; // Flags for Parent-ClipChildren-Mode
648 mnActivateMode
= ActivateModeFlags::NONE
; // Will be converted in System/Overlap-Windows
649 mnDlgCtrlFlags
= DialogControlFlags::NONE
; // DialogControl-Flags
650 meAlwaysInputMode
= AlwaysInputNone
; // AlwaysEnableInput not called
651 meHalign
= VclAlign::Fill
;
652 meValign
= VclAlign::Fill
;
653 mePackType
= VclPackType::Start
;
656 mnGridLeftAttach
= -1;
657 mnGridTopAttach
= -1;
664 mbFrame
= false; // true: Window is a frame window
665 mbBorderWin
= false; // true: Window is a border window
666 mbOverlapWin
= false; // true: Window is an overlap window
667 mbSysWin
= false; // true: SystemWindow is the base class
668 mbDialog
= false; // true: Dialog is the base class
669 mbDockWin
= false; // true: DockingWindow is the base class
670 mbFloatWin
= false; // true: FloatingWindow is the base class
671 mbPushButton
= false; // true: PushButton is the base class
672 mbToolBox
= false; // true: ToolBox is the base class
673 mbMenuFloatingWindow
= false; // true: MenuFloatingWindow is the base class
674 mbToolbarFloatingWindow
= false; // true: ImplPopupFloatWin is the base class, used for subtoolbars
675 mbSplitter
= false; // true: Splitter is the base class
676 mbVisible
= false; // true: Show( true ) called
677 mbOverlapVisible
= false; // true: Hide called for visible window from ImplHideAllOverlapWindow()
678 mbDisabled
= false; // true: Enable( false ) called
679 mbInputDisabled
= false; // true: EnableInput( false ) called
680 mbNoUpdate
= false; // true: SetUpdateMode( false ) called
681 mbNoParentUpdate
= false; // true: SetParentUpdateMode( false ) called
682 mbActive
= false; // true: Window Active
683 mbReallyVisible
= false; // true: this and all parents to an overlapped window are visible
684 mbReallyShown
= false; // true: this and all parents to an overlapped window are shown
685 mbInInitShow
= false; // true: we are in InitShow
686 mbChildPtrOverwrite
= false; // true: PointerStyle overwrites Child-Pointer
687 mbNoPtrVisible
= false; // true: ShowPointer( false ) called
688 mbPaintFrame
= false; // true: Paint is visible, but not painted
689 mbInPaint
= false; // true: Inside PaintHdl
690 mbMouseButtonDown
= false; // true: BaseMouseButtonDown called
691 mbMouseButtonUp
= false; // true: BaseMouseButtonUp called
692 mbKeyInput
= false; // true: BaseKeyInput called
693 mbKeyUp
= false; // true: BaseKeyUp called
694 mbCommand
= false; // true: BaseCommand called
695 mbDefPos
= true; // true: Position is not Set
696 mbDefSize
= true; // true: Size is not Set
697 mbCallMove
= true; // true: Move must be called by Show
698 mbCallResize
= true; // true: Resize must be called by Show
699 mbWaitSystemResize
= true; // true: Wait for System-Resize
700 mbInitWinClipRegion
= true; // true: Calc Window Clip Region
701 mbInitChildRegion
= false; // true: InitChildClipRegion
702 mbWinRegion
= false; // true: Window Region
703 mbClipChildren
= false; // true: Child-window should be clipped
704 mbClipSiblings
= false; // true: Adjacent Child-window should be clipped
705 mbChildTransparent
= false; // true: Child-windows are allowed to switch to transparent (incl. Parent-CLIPCHILDREN)
706 mbPaintTransparent
= false; // true: Paints should be executed on the Parent
707 mbMouseTransparent
= false; // true: Window is transparent for Mouse
708 mbDlgCtrlStart
= false; // true: From here on own Dialog-Control
709 mbFocusVisible
= false; // true: Focus Visible
710 mbUseNativeFocus
= false;
711 mbNativeFocusVisible
= false; // true: native Focus Visible
712 mbInShowFocus
= false; // prevent recursion
713 mbInHideFocus
= false; // prevent recursion
714 mbTrackVisible
= false; // true: Tracking Visible
715 mbControlForeground
= false; // true: Foreground-Property set
716 mbControlBackground
= false; // true: Background-Property set
717 mbAlwaysOnTop
= false; // true: always visible for all others windows
718 mbCompoundControl
= false; // true: Composite Control => Listener...
719 mbCompoundControlHasFocus
= false; // true: Composite Control has focus somewhere
720 mbPaintDisabled
= false; // true: Paint should not be executed
721 mbAllResize
= false; // true: Also sent ResizeEvents with 0,0
722 mbInDispose
= false; // true: We're still in Window::dispose()
723 mbExtTextInput
= false; // true: ExtTextInput-Mode is active
724 mbInFocusHdl
= false; // true: Within GetFocus-Handler
725 mbCreatedWithToolkit
= false;
726 mbSuppressAccessibilityEvents
= false; // true: do not send any accessibility events
727 mbDrawSelectionBackground
= false; // true: draws transparent window background to indicate (toolbox) selection
728 mbIsInTaskPaneList
= false; // true: window was added to the taskpanelist in the topmost system window
729 mnNativeBackground
= ControlPart::NONE
; // initialize later, depends on type
730 mbHelpTextDynamic
= false; // true: append help id in HELP_DEBUG case
731 mbFakeFocusSet
= false; // true: pretend as if the window has focus.
737 mbNonHomogeneous
= false;
738 static bool bDoubleBuffer
= getenv("VCL_DOUBLEBUFFERING_FORCE_ENABLE");
739 mbDoubleBufferingRequested
= bDoubleBuffer
; // when we are not sure, assume it cannot do double-buffering via RenderContext
740 mpLOKNotifier
= nullptr;
742 mbLOKParentNotifier
= false;
745 WindowImpl::~WindowImpl()
747 mpChildClipRegion
.reset();
748 mpAccessibleInfos
.reset();
751 ImplWinData::ImplWinData() :
754 mnCompositionCharRects(0),
755 mnTrackFlags(ShowTrackFlags::NONE
),
756 mnIsTopWindow(sal_uInt16(~0)), // not initialized yet, 0/1 will indicate TopWindow (see IsTopWindow())
758 mbEnableNativeWidget(false)
762 ImplWinData::~ImplWinData()
764 mpCompositionCharRects
.reset();
767 ImplFrameData::ImplFrameData( vcl::Window
*pWindow
)
769 ImplSVData
* pSVData
= ImplGetSVData();
770 assert (pSVData
->maFrameData
.mpFirstFrame
.get() != pWindow
);
771 mpNextFrame
= pSVData
->maFrameData
.mpFirstFrame
;
772 pSVData
->maFrameData
.mpFirstFrame
= pWindow
;
773 mpFirstOverlap
= nullptr;
774 mpFocusWin
= nullptr;
775 mpMouseMoveWin
= nullptr;
776 mpMouseDownWin
= nullptr;
777 mxFontCollection
= pSVData
->maGDIData
.mxScreenFontList
;
778 mxFontCache
= pSVData
->maGDIData
.mxScreenFontCache
;
780 mnMouseMoveId
= nullptr;
783 mnBeforeLastMouseX
= -1;
784 mnBeforeLastMouseY
= -1;
787 mnLastMouseWinX
= -1;
788 mnLastMouseWinY
= -1;
792 mnFirstMouseCode
= 0;
794 mnMouseMode
= MouseEventModifiers::NONE
;
796 mbInMouseMove
= false;
798 mbStartDragCalled
= false;
799 mbNeedSysWindow
= false;
801 mbStartFocusState
= false;
802 mbInSysObjFocusHdl
= false;
803 mbInSysObjToTopHdl
= false;
804 mbSysObjFocus
= false;
805 maPaintIdle
.SetPriority( TaskPriority::REPAINT
);
806 maPaintIdle
.SetInvokeHandler( LINK( pWindow
, vcl::Window
, ImplHandlePaintHdl
) );
807 maPaintIdle
.SetDebugName( "vcl::Window maPaintIdle" );
808 maResizeIdle
.SetPriority( TaskPriority::RESIZE
);
809 maResizeIdle
.SetInvokeHandler( LINK( pWindow
, vcl::Window
, ImplHandleResizeTimerHdl
) );
810 maResizeIdle
.SetDebugName( "vcl::Window maResizeIdle" );
811 mbInternalDragGestureRecognizer
= false;
812 mbInBufferedPaint
= false;
815 mnTouchPanPosition
= -1;
820 bool Window::AcquireGraphics() const
822 DBG_TESTSOLARMUTEX();
827 mbInitLineColor
= true;
828 mbInitFillColor
= true;
830 mbInitTextColor
= true;
831 mbInitClipRegion
= true;
833 ImplSVData
* pSVData
= ImplGetSVData();
835 mpGraphics
= mpWindowImpl
->mpFrame
->AcquireGraphics();
836 // try harder if no wingraphics was available directly
839 // find another output device in the same frame
840 OutputDevice
* pReleaseOutDev
= pSVData
->maGDIData
.mpLastWinGraphics
;
841 while ( pReleaseOutDev
)
843 if ( static_cast<vcl::Window
*>(pReleaseOutDev
)->mpWindowImpl
->mpFrame
== mpWindowImpl
->mpFrame
)
845 pReleaseOutDev
= pReleaseOutDev
->mpPrevGraphics
;
848 if ( pReleaseOutDev
)
850 // steal the wingraphics from the other outdev
851 mpGraphics
= pReleaseOutDev
->mpGraphics
;
852 pReleaseOutDev
->ReleaseGraphics( false );
856 // if needed retry after releasing least recently used wingraphics
857 while ( !mpGraphics
)
859 if ( !pSVData
->maGDIData
.mpLastWinGraphics
)
861 pSVData
->maGDIData
.mpLastWinGraphics
->ReleaseGraphics();
862 mpGraphics
= mpWindowImpl
->mpFrame
->AcquireGraphics();
869 // update global LRU list of wingraphics
870 mpNextGraphics
= pSVData
->maGDIData
.mpFirstWinGraphics
;
871 pSVData
->maGDIData
.mpFirstWinGraphics
= const_cast<vcl::Window
*>(this);
872 if ( mpNextGraphics
)
873 mpNextGraphics
->mpPrevGraphics
= const_cast<vcl::Window
*>(this);
874 if ( !pSVData
->maGDIData
.mpLastWinGraphics
)
875 pSVData
->maGDIData
.mpLastWinGraphics
= const_cast<vcl::Window
*>(this);
877 mpGraphics
->SetXORMode( (RasterOp::Invert
== meRasterOp
) || (RasterOp::Xor
== meRasterOp
), RasterOp::Invert
== meRasterOp
);
878 mpGraphics
->setAntiAlias(bool(mnAntialiasing
& AntialiasingFlags::Enable
));
881 return mpGraphics
!= nullptr;
884 void Window::ReleaseGraphics( bool bRelease
)
886 DBG_TESTSOLARMUTEX();
891 // release the fonts of the physically released graphics device
895 ImplSVData
* pSVData
= ImplGetSVData();
897 vcl::Window
* pWindow
= this;
900 pWindow
->mpWindowImpl
->mpFrame
->ReleaseGraphics( mpGraphics
);
901 // remove from global LRU list of window graphics
902 if ( mpPrevGraphics
)
903 mpPrevGraphics
->mpNextGraphics
= mpNextGraphics
;
905 pSVData
->maGDIData
.mpFirstWinGraphics
= mpNextGraphics
;
906 if ( mpNextGraphics
)
907 mpNextGraphics
->mpPrevGraphics
= mpPrevGraphics
;
909 pSVData
->maGDIData
.mpLastWinGraphics
= mpPrevGraphics
;
911 mpGraphics
= nullptr;
912 mpPrevGraphics
= nullptr;
913 mpNextGraphics
= nullptr;
916 static sal_Int32
CountDPIScaleFactor(sal_Int32 nDPI
)
919 // Setting of HiDPI is unfortunately all only a heuristic; and to add
920 // insult to an injury, the system is constantly lying to us about
921 // the DPI and whatnot
922 // eg. fdo#77059 - set the value from which we do consider the
923 // screen HiDPI to greater than 168
924 if (nDPI
> 216) // 96 * 2 + 96 / 4
926 else if (nDPI
> 168) // 96 * 2 - 96 / 4
928 else if (nDPI
> 120) // 96 * 1.5 - 96 / 4
937 void Window::ImplInit( vcl::Window
* pParent
, WinBits nStyle
, SystemParentData
* pSystemParentData
)
939 SAL_WARN_IF( !mpWindowImpl
->mbFrame
&& !pParent
&& GetType() != WindowType::FIXEDIMAGE
, "vcl.window",
940 "Window::Window(): pParent == NULL" );
942 ImplSVData
* pSVData
= ImplGetSVData();
943 vcl::Window
* pRealParent
= pParent
;
946 if ( !mpWindowImpl
->mbOverlapWin
&& pParent
&& (pParent
->GetStyle() & WB_3DLOOK
) )
949 // create border window if necessary
950 if ( !mpWindowImpl
->mbFrame
&& !mpWindowImpl
->mbBorderWin
&& !mpWindowImpl
->mpBorderWindow
951 && (nStyle
& (WB_BORDER
| WB_SYSTEMCHILDWINDOW
) ) )
953 BorderWindowStyle nBorderTypeStyle
= BorderWindowStyle::NONE
;
954 if( nStyle
& WB_SYSTEMCHILDWINDOW
)
956 // handle WB_SYSTEMCHILDWINDOW
957 // these should be analogous to a top level frame; meaning they
958 // should have a border window with style BorderWindowStyle::Frame
959 // which controls their size
960 nBorderTypeStyle
|= BorderWindowStyle::Frame
;
963 VclPtrInstance
<ImplBorderWindow
> pBorderWin( pParent
, nStyle
& (WB_BORDER
| WB_DIALOGCONTROL
| WB_NODIALOGCONTROL
), nBorderTypeStyle
);
964 static_cast<vcl::Window
*>(pBorderWin
)->mpWindowImpl
->mpClientWindow
= this;
965 pBorderWin
->GetBorder( mpWindowImpl
->mnLeftBorder
, mpWindowImpl
->mnTopBorder
, mpWindowImpl
->mnRightBorder
, mpWindowImpl
->mnBottomBorder
);
966 mpWindowImpl
->mpBorderWindow
= pBorderWin
;
967 pParent
= mpWindowImpl
->mpBorderWindow
;
969 else if( !mpWindowImpl
->mbFrame
&& ! pParent
)
971 mpWindowImpl
->mbOverlapWin
= true;
972 mpWindowImpl
->mbFrame
= true;
975 // insert window in list
976 ImplInsertWindow( pParent
);
977 mpWindowImpl
->mnStyle
= nStyle
;
979 if( pParent
&& ! mpWindowImpl
->mbFrame
)
980 mbEnableRTL
= AllSettings::GetLayoutRTL();
982 // test for frame creation
983 if ( mpWindowImpl
->mbFrame
)
986 SalFrameStyleFlags nFrameStyle
= SalFrameStyleFlags::NONE
;
988 if ( nStyle
& WB_MOVEABLE
)
989 nFrameStyle
|= SalFrameStyleFlags::MOVEABLE
;
990 if ( nStyle
& WB_SIZEABLE
)
991 nFrameStyle
|= SalFrameStyleFlags::SIZEABLE
;
992 if ( nStyle
& WB_CLOSEABLE
)
993 nFrameStyle
|= SalFrameStyleFlags::CLOSEABLE
;
994 if ( nStyle
& WB_APP
)
995 nFrameStyle
|= SalFrameStyleFlags::DEFAULT
;
996 // check for undecorated floating window
997 if( // 1. floating windows that are not moveable/sizeable (only closeable allowed)
998 ( !(nFrameStyle
& ~SalFrameStyleFlags::CLOSEABLE
) &&
999 ( mpWindowImpl
->mbFloatWin
|| ((GetType() == WindowType::BORDERWINDOW
) && static_cast<ImplBorderWindow
*>(this)->mbFloatWindow
) || (nStyle
& WB_SYSTEMFLOATWIN
) ) ) ||
1000 // 2. borderwindows of floaters with ownerdraw decoration
1001 ((GetType() == WindowType::BORDERWINDOW
) && static_cast<ImplBorderWindow
*>(this)->mbFloatWindow
&& (nStyle
& WB_OWNERDRAWDECORATION
) ) )
1003 nFrameStyle
= SalFrameStyleFlags::FLOAT
;
1004 if( nStyle
& WB_OWNERDRAWDECORATION
)
1005 nFrameStyle
|= SalFrameStyleFlags::OWNERDRAWDECORATION
| SalFrameStyleFlags::NOSHADOW
;
1007 else if( mpWindowImpl
->mbFloatWin
)
1008 nFrameStyle
|= SalFrameStyleFlags::TOOLWINDOW
;
1010 if( nStyle
& WB_INTROWIN
)
1011 nFrameStyle
|= SalFrameStyleFlags::INTRO
;
1012 if( nStyle
& WB_TOOLTIPWIN
)
1013 nFrameStyle
|= SalFrameStyleFlags::TOOLTIP
;
1015 if( nStyle
& WB_NOSHADOW
)
1016 nFrameStyle
|= SalFrameStyleFlags::NOSHADOW
;
1018 if( nStyle
& WB_SYSTEMCHILDWINDOW
)
1019 nFrameStyle
|= SalFrameStyleFlags::SYSTEMCHILD
;
1021 switch (mpWindowImpl
->mnType
)
1023 case WindowType::DIALOG
:
1024 case WindowType::TABDIALOG
:
1025 case WindowType::MODELESSDIALOG
:
1026 case WindowType::MESSBOX
:
1027 case WindowType::INFOBOX
:
1028 case WindowType::WARNINGBOX
:
1029 case WindowType::ERRORBOX
:
1030 case WindowType::QUERYBOX
:
1031 nFrameStyle
|= SalFrameStyleFlags::DIALOG
;
1037 SalFrame
* pParentFrame
= nullptr;
1039 pParentFrame
= pParent
->mpWindowImpl
->mpFrame
;
1041 if ( pSystemParentData
)
1042 pFrame
= pSVData
->mpDefInst
->CreateChildFrame( pSystemParentData
, nFrameStyle
| SalFrameStyleFlags::PLUG
);
1044 pFrame
= pSVData
->mpDefInst
->CreateFrame( pParentFrame
, nFrameStyle
);
1047 // do not abort but throw an exception, may be the current thread terminates anyway (plugin-scenario)
1048 throw RuntimeException(
1049 "Could not create system window!",
1050 Reference
< XInterface
>() );
1053 pFrame
->SetCallback( this, ImplWindowFrameProc
);
1055 // set window frame data
1056 mpWindowImpl
->mpFrameData
= new ImplFrameData( this );
1057 mpWindowImpl
->mpFrame
= pFrame
;
1058 mpWindowImpl
->mpFrameWindow
= this;
1059 mpWindowImpl
->mpOverlapWindow
= this;
1061 if (!(nStyle
& WB_DEFAULTWIN
) && mpWindowImpl
->mbDoubleBufferingRequested
)
1062 RequestDoubleBuffering(true);
1064 if ( pRealParent
&& IsTopWindow() )
1066 ImplWinData
* pParentWinData
= pRealParent
->ImplGetWinData();
1067 pParentWinData
->maTopWindowChildren
.emplace_back(this );
1072 mpWindowImpl
->mpRealParent
= pRealParent
;
1074 // #99318: make sure fontcache and list is available before call to SetSettings
1075 mxFontCollection
= mpWindowImpl
->mpFrameData
->mxFontCollection
;
1076 mxFontCache
= mpWindowImpl
->mpFrameData
->mxFontCache
;
1078 if ( mpWindowImpl
->mbFrame
)
1082 mpWindowImpl
->mpFrameData
->mnDPIX
= pParent
->mpWindowImpl
->mpFrameData
->mnDPIX
;
1083 mpWindowImpl
->mpFrameData
->mnDPIY
= pParent
->mpWindowImpl
->mpFrameData
->mnDPIY
;
1087 OutputDevice
*pOutDev
= GetOutDev();
1088 if ( pOutDev
->AcquireGraphics() )
1090 mpGraphics
->GetResolution( mpWindowImpl
->mpFrameData
->mnDPIX
, mpWindowImpl
->mpFrameData
->mnDPIY
);
1094 // add ownerdraw decorated frame windows to list in the top-most frame window
1095 // so they can be hidden on lose focus
1096 if( nStyle
& WB_OWNERDRAWDECORATION
)
1097 ImplGetOwnerDrawList().emplace_back(this );
1099 // delay settings initialization until first "real" frame
1100 // this relies on the IntroWindow not needing any system settings
1101 if ( !pSVData
->maAppData
.mbSettingsInit
&&
1102 ! (nStyle
& (WB_INTROWIN
|WB_DEFAULTWIN
))
1105 // side effect: ImplUpdateGlobalSettings does an ImplGetFrame()->UpdateSettings
1106 ImplUpdateGlobalSettings( *pSVData
->maAppData
.mpSettings
);
1107 OutputDevice::SetSettings( *pSVData
->maAppData
.mpSettings
);
1108 pSVData
->maAppData
.mbSettingsInit
= true;
1111 // If we create a Window with default size, query this
1112 // size directly, because we want resize all Controls to
1113 // the correct size before we display the window
1114 if ( nStyle
& (WB_MOVEABLE
| WB_SIZEABLE
| WB_APP
) )
1115 mpWindowImpl
->mpFrame
->GetClientSize( mnOutWidth
, mnOutHeight
);
1121 if ( !ImplIsOverlapWindow() )
1123 mpWindowImpl
->mbDisabled
= pParent
->mpWindowImpl
->mbDisabled
;
1124 mpWindowImpl
->mbInputDisabled
= pParent
->mpWindowImpl
->mbInputDisabled
;
1125 mpWindowImpl
->meAlwaysInputMode
= pParent
->mpWindowImpl
->meAlwaysInputMode
;
1128 if (!utl::ConfigManager::IsFuzzing())
1129 OutputDevice::SetSettings( pParent
->GetSettings() );
1134 // setup the scale factor for HiDPI displays
1135 mnDPIScalePercentage
= CountDPIScaleFactor(mpWindowImpl
->mpFrameData
->mnDPIY
);
1136 mnDPIX
= mpWindowImpl
->mpFrameData
->mnDPIX
;
1137 mnDPIY
= mpWindowImpl
->mpFrameData
->mnDPIY
;
1139 if (!utl::ConfigManager::IsFuzzing())
1141 const StyleSettings
& rStyleSettings
= mxSettings
->GetStyleSettings();
1142 maFont
= rStyleSettings
.GetAppFont();
1144 if ( nStyle
& WB_3DLOOK
)
1146 SetTextColor( rStyleSettings
.GetButtonTextColor() );
1147 SetBackground( Wallpaper( rStyleSettings
.GetFaceColor() ) );
1151 SetTextColor( rStyleSettings
.GetWindowTextColor() );
1152 SetBackground( Wallpaper( rStyleSettings
.GetWindowColor() ) );
1157 maFont
= GetDefaultFont( DefaultFontType::FIXED
, LANGUAGE_ENGLISH_US
, GetDefaultFontFlags::NONE
);
1160 ImplPointToLogic(*this, maFont
);
1162 (void)ImplUpdatePos();
1164 // calculate app font res (except for the Intro Window or the default window)
1165 if ( mpWindowImpl
->mbFrame
&& !pSVData
->maGDIData
.mnAppFontX
&& ! (nStyle
& (WB_INTROWIN
|WB_DEFAULTWIN
)) )
1166 ImplInitAppFontData( this );
1169 void Window::ImplInitAppFontData( vcl::Window
const * pWindow
)
1171 ImplSVData
* pSVData
= ImplGetSVData();
1172 tools::Long nTextHeight
= pWindow
->GetTextHeight();
1173 tools::Long nTextWidth
= pWindow
->approximate_char_width() * 8;
1174 tools::Long nSymHeight
= nTextHeight
*4;
1175 // Make the basis wider if the font is too narrow
1176 // such that the dialog looks symmetrical and does not become too narrow.
1177 // Add some extra space when the dialog has the same width,
1178 // as a little more space is better.
1179 if ( nSymHeight
> nTextWidth
)
1180 nTextWidth
= nSymHeight
;
1181 else if ( nSymHeight
+5 > nTextWidth
)
1182 nTextWidth
= nSymHeight
+5;
1183 pSVData
->maGDIData
.mnAppFontX
= nTextWidth
* 10 / 8;
1184 pSVData
->maGDIData
.mnAppFontY
= nTextHeight
* 10;
1187 // FIXME: this is currently only on macOS, check with other
1189 if( pSVData
->maNWFData
.mbNoFocusRects
)
1191 // try to find out whether there is a large correction
1192 // of control sizes, if yes, make app font scalings larger
1193 // so dialog positioning is not completely off
1194 ImplControlValue aControlValue
;
1195 tools::Rectangle
aCtrlRegion( Point(), Size( nTextWidth
< 10 ? 10 : nTextWidth
, nTextHeight
< 10 ? 10 : nTextHeight
) );
1196 tools::Rectangle
aBoundingRgn( aCtrlRegion
);
1197 tools::Rectangle
aContentRgn( aCtrlRegion
);
1198 if( pWindow
->GetNativeControlRegion( ControlType::Editbox
, ControlPart::Entire
, aCtrlRegion
,
1199 ControlState::ENABLED
, aControlValue
,
1200 aBoundingRgn
, aContentRgn
) )
1202 // comment: the magical +6 is for the extra border in bordered
1203 // (which is the standard) edit fields
1204 if( aContentRgn
.GetHeight() - nTextHeight
> (nTextHeight
+4)/4 )
1205 pSVData
->maGDIData
.mnAppFontY
= (aContentRgn
.GetHeight()-4) * 10;
1211 ImplWinData
* Window::ImplGetWinData() const
1213 if (!mpWindowImpl
->mpWinData
)
1215 static const char* pNoNWF
= getenv( "SAL_NO_NWF" );
1217 const_cast<vcl::Window
*>(this)->mpWindowImpl
->mpWinData
= new ImplWinData
;
1218 mpWindowImpl
->mpWinData
->mbEnableNativeWidget
= !(pNoNWF
&& *pNoNWF
); // true: try to draw this control with native theme API
1221 return mpWindowImpl
->mpWinData
;
1225 void Window::CopyDeviceArea( SalTwoRect
& aPosAry
, bool bWindowInvalidate
)
1227 if (aPosAry
.mnSrcWidth
== 0 || aPosAry
.mnSrcHeight
== 0 || aPosAry
.mnDestWidth
== 0 || aPosAry
.mnDestHeight
== 0)
1230 if (bWindowInvalidate
)
1232 const tools::Rectangle
aSrcRect(Point(aPosAry
.mnSrcX
, aPosAry
.mnSrcY
),
1233 Size(aPosAry
.mnSrcWidth
, aPosAry
.mnSrcHeight
));
1235 ImplMoveAllInvalidateRegions(aSrcRect
,
1236 aPosAry
.mnDestX
-aPosAry
.mnSrcX
,
1237 aPosAry
.mnDestY
-aPosAry
.mnSrcY
,
1240 mpGraphics
->CopyArea(aPosAry
.mnDestX
, aPosAry
.mnDestY
,
1241 aPosAry
.mnSrcX
, aPosAry
.mnSrcY
,
1242 aPosAry
.mnSrcWidth
, aPosAry
.mnSrcHeight
,
1248 OutputDevice::CopyDeviceArea(aPosAry
, bWindowInvalidate
);
1251 const OutputDevice
* Window::DrawOutDevDirectCheck(const OutputDevice
* pSrcDev
) const
1253 const OutputDevice
* pSrcDevChecked
;
1254 if ( this == pSrcDev
)
1255 pSrcDevChecked
= nullptr;
1256 else if (GetOutDevType() != pSrcDev
->GetOutDevType())
1257 pSrcDevChecked
= pSrcDev
;
1258 else if (this->mpWindowImpl
->mpFrameWindow
== static_cast<const vcl::Window
*>(pSrcDev
)->mpWindowImpl
->mpFrameWindow
)
1259 pSrcDevChecked
= nullptr;
1261 pSrcDevChecked
= pSrcDev
;
1263 return pSrcDevChecked
;
1266 void Window::DrawOutDevDirectProcess( const OutputDevice
* pSrcDev
, SalTwoRect
& rPosAry
, SalGraphics
* pSrcGraphics
)
1268 mpGraphics
->CopyBits( rPosAry
, pSrcGraphics
, this, pSrcDev
);
1271 SalGraphics
* Window::ImplGetFrameGraphics() const
1273 if ( mpWindowImpl
->mpFrameWindow
->mpGraphics
)
1275 mpWindowImpl
->mpFrameWindow
->mbInitClipRegion
= true;
1279 OutputDevice
* pFrameWinOutDev
= mpWindowImpl
->mpFrameWindow
;
1280 if ( ! pFrameWinOutDev
->AcquireGraphics() )
1285 mpWindowImpl
->mpFrameWindow
->mpGraphics
->ResetClipRegion();
1286 return mpWindowImpl
->mpFrameWindow
->mpGraphics
;
1289 void Window::ImplSetReallyVisible()
1291 // #i43594# it is possible that INITSHOW was never send, because the visibility state changed between
1292 // ImplCallInitShow() and ImplSetReallyVisible() when called from Show()
1293 // mbReallyShown is a useful indicator
1294 if( !mpWindowImpl
->mbReallyShown
)
1297 bool bBecameReallyVisible
= !mpWindowImpl
->mbReallyVisible
;
1300 mpWindowImpl
->mbReallyVisible
= true;
1301 mpWindowImpl
->mbReallyShown
= true;
1303 // the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge.
1304 // For this, the data member of the event must not be NULL.
1305 // Previously, we did this in Window::Show, but there some events got lost in certain situations. Now
1306 // we're doing it when the visibility really changes
1307 if( bBecameReallyVisible
&& ImplIsAccessibleCandidate() )
1308 CallEventListeners( VclEventId::WindowShow
, this );
1309 // TODO. It's kind of a hack that we're re-using the VclEventId::WindowShow. Normally, we should
1310 // introduce another event which explicitly triggers the Accessibility implementations.
1312 vcl::Window
* pWindow
= mpWindowImpl
->mpFirstOverlap
;
1315 if ( pWindow
->mpWindowImpl
->mbVisible
)
1316 pWindow
->ImplSetReallyVisible();
1317 pWindow
= pWindow
->mpWindowImpl
->mpNext
;
1320 pWindow
= mpWindowImpl
->mpFirstChild
;
1323 if ( pWindow
->mpWindowImpl
->mbVisible
)
1324 pWindow
->ImplSetReallyVisible();
1325 pWindow
= pWindow
->mpWindowImpl
->mpNext
;
1329 void Window::ImplInitResolutionSettings()
1331 // recalculate AppFont-resolution and DPI-resolution
1332 if (mpWindowImpl
->mbFrame
)
1334 mnDPIX
= mpWindowImpl
->mpFrameData
->mnDPIX
;
1335 mnDPIY
= mpWindowImpl
->mpFrameData
->mnDPIY
;
1337 // setup the scale factor for HiDPI displays
1338 mnDPIScalePercentage
= CountDPIScaleFactor(mpWindowImpl
->mpFrameData
->mnDPIY
);
1339 const StyleSettings
& rStyleSettings
= mxSettings
->GetStyleSettings();
1340 SetPointFont(*this, rStyleSettings
.GetAppFont());
1342 else if ( mpWindowImpl
->mpParent
)
1344 mnDPIX
= mpWindowImpl
->mpParent
->mnDPIX
;
1345 mnDPIY
= mpWindowImpl
->mpParent
->mnDPIY
;
1346 mnDPIScalePercentage
= mpWindowImpl
->mpParent
->mnDPIScalePercentage
;
1349 // update the recalculated values for logical units
1350 // and also tools belonging to the values
1351 if (IsMapModeEnabled())
1353 MapMode aMapMode
= GetMapMode();
1355 SetMapMode( aMapMode
);
1359 void Window::ImplPointToLogic(vcl::RenderContext
const & rRenderContext
, vcl::Font
& rFont
) const
1361 Size aSize
= rFont
.GetFontSize();
1365 aSize
.setWidth( aSize
.Width() * ( mpWindowImpl
->mpFrameData
->mnDPIX
) );
1366 aSize
.AdjustWidth(72 / 2 );
1367 aSize
.setWidth( aSize
.Width() / 72 );
1369 aSize
.setHeight( aSize
.Height() * ( mpWindowImpl
->mpFrameData
->mnDPIY
) );
1370 aSize
.AdjustHeight(72/2 );
1371 aSize
.setHeight( aSize
.Height() / 72 );
1373 if (rRenderContext
.IsMapModeEnabled())
1374 aSize
= rRenderContext
.PixelToLogic(aSize
);
1376 rFont
.SetFontSize(aSize
);
1379 void Window::ImplLogicToPoint(vcl::RenderContext
const & rRenderContext
, vcl::Font
& rFont
) const
1381 Size aSize
= rFont
.GetFontSize();
1383 if (rRenderContext
.IsMapModeEnabled())
1384 aSize
= rRenderContext
.LogicToPixel(aSize
);
1388 aSize
.setWidth( aSize
.Width() * 72 );
1389 aSize
.AdjustWidth(mpWindowImpl
->mpFrameData
->mnDPIX
/ 2 );
1390 aSize
.setWidth( aSize
.Width() / ( mpWindowImpl
->mpFrameData
->mnDPIX
) );
1392 aSize
.setHeight( aSize
.Height() * 72 );
1393 aSize
.AdjustHeight(mpWindowImpl
->mpFrameData
->mnDPIY
/ 2 );
1394 aSize
.setHeight( aSize
.Height() / ( mpWindowImpl
->mpFrameData
->mnDPIY
) );
1396 rFont
.SetFontSize(aSize
);
1399 bool Window::ImplUpdatePos()
1401 bool bSysChild
= false;
1403 if ( ImplIsOverlapWindow() )
1405 mnOutOffX
= mpWindowImpl
->mnX
;
1406 mnOutOffY
= mpWindowImpl
->mnY
;
1410 vcl::Window
* pParent
= ImplGetParent();
1412 mnOutOffX
= mpWindowImpl
->mnX
+ pParent
->mnOutOffX
;
1413 mnOutOffY
= mpWindowImpl
->mnY
+ pParent
->mnOutOffY
;
1416 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
1419 if ( pChild
->ImplUpdatePos() )
1421 pChild
= pChild
->mpWindowImpl
->mpNext
;
1424 if ( mpWindowImpl
->mpSysObj
)
1430 void Window::ImplUpdateSysObjPos()
1432 if ( mpWindowImpl
->mpSysObj
)
1433 mpWindowImpl
->mpSysObj
->SetPosSize( mnOutOffX
, mnOutOffY
, mnOutWidth
, mnOutHeight
);
1435 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
1438 pChild
->ImplUpdateSysObjPos();
1439 pChild
= pChild
->mpWindowImpl
->mpNext
;
1443 void Window::ImplPosSizeWindow( tools::Long nX
, tools::Long nY
,
1444 tools::Long nWidth
, tools::Long nHeight
, PosSizeFlags nFlags
)
1446 bool bNewPos
= false;
1447 bool bNewSize
= false;
1448 bool bCopyBits
= false;
1449 tools::Long nOldOutOffX
= mnOutOffX
;
1450 tools::Long nOldOutOffY
= mnOutOffY
;
1451 tools::Long nOldOutWidth
= mnOutWidth
;
1452 tools::Long nOldOutHeight
= mnOutHeight
;
1453 std::unique_ptr
<vcl::Region
> pOverlapRegion
;
1454 std::unique_ptr
<vcl::Region
> pOldRegion
;
1456 if ( IsReallyVisible() )
1458 tools::Rectangle
aOldWinRect( Point( nOldOutOffX
, nOldOutOffY
),
1459 Size( nOldOutWidth
, nOldOutHeight
) );
1460 pOldRegion
.reset( new vcl::Region( aOldWinRect
) );
1461 if ( mpWindowImpl
->mbWinRegion
)
1462 pOldRegion
->Intersect( ImplPixelToDevicePixel( mpWindowImpl
->maWinRegion
) );
1464 if ( mnOutWidth
&& mnOutHeight
&& !mpWindowImpl
->mbPaintTransparent
&&
1465 !mpWindowImpl
->mbInitWinClipRegion
&& !mpWindowImpl
->maWinClipRegion
.IsEmpty() &&
1470 bool bnXRecycled
= false; // avoid duplicate mirroring in RTL case
1471 if ( nFlags
& PosSizeFlags::Width
)
1473 if(!( nFlags
& PosSizeFlags::X
))
1475 nX
= mpWindowImpl
->mnX
;
1476 nFlags
|= PosSizeFlags::X
;
1477 bnXRecycled
= true; // we're using a mnX which was already mirrored in RTL case
1482 if ( nWidth
!= mnOutWidth
)
1484 mnOutWidth
= nWidth
;
1489 if ( nFlags
& PosSizeFlags::Height
)
1493 if ( nHeight
!= mnOutHeight
)
1495 mnOutHeight
= nHeight
;
1501 if ( nFlags
& PosSizeFlags::X
)
1503 tools::Long nOrgX
= nX
;
1504 Point
aPtDev( Point( nX
+mnOutOffX
, 0 ) );
1505 OutputDevice
*pOutDev
= GetOutDev();
1506 if( pOutDev
->HasMirroredGraphics() )
1508 aPtDev
.setX( mpGraphics
->mirror2( aPtDev
.X(), this ) );
1510 // #106948# always mirror our pos if our parent is not mirroring, even
1511 // if we are also not mirroring
1512 // RTL: check if parent is in different coordinates
1513 if( !bnXRecycled
&& mpWindowImpl
->mpParent
&& !mpWindowImpl
->mpParent
->mpWindowImpl
->mbFrame
&& mpWindowImpl
->mpParent
->ImplIsAntiparallel() )
1515 nX
= mpWindowImpl
->mpParent
->mnOutWidth
- mnOutWidth
- nX
;
1517 /* #i99166# An LTR window in RTL UI that gets sized only would be
1518 expected to not moved its upper left point
1522 if( ImplIsAntiparallel() )
1524 aPtDev
.setX( mpWindowImpl
->mnAbsScreenX
);
1525 nOrgX
= mpWindowImpl
->maPos
.X();
1529 else if( !bnXRecycled
&& mpWindowImpl
->mpParent
&& !mpWindowImpl
->mpParent
->mpWindowImpl
->mbFrame
&& mpWindowImpl
->mpParent
->ImplIsAntiparallel() )
1531 // mirrored window in LTR UI
1532 nX
= mpWindowImpl
->mpParent
->mnOutWidth
- mnOutWidth
- nX
;
1535 // check maPos as well, as it could have been changed for client windows (ImplCallMove())
1536 if ( mpWindowImpl
->mnAbsScreenX
!= aPtDev
.X() || nX
!= mpWindowImpl
->mnX
|| nOrgX
!= mpWindowImpl
->maPos
.X() )
1538 if ( bCopyBits
&& !pOverlapRegion
)
1540 pOverlapRegion
.reset( new vcl::Region() );
1541 ImplCalcOverlapRegion( tools::Rectangle( Point( mnOutOffX
, mnOutOffY
),
1542 Size( mnOutWidth
, mnOutHeight
) ),
1543 *pOverlapRegion
, false, true );
1545 mpWindowImpl
->mnX
= nX
;
1546 mpWindowImpl
->maPos
.setX( nOrgX
);
1547 mpWindowImpl
->mnAbsScreenX
= aPtDev
.X();
1551 if ( nFlags
& PosSizeFlags::Y
)
1553 // check maPos as well, as it could have been changed for client windows (ImplCallMove())
1554 if ( nY
!= mpWindowImpl
->mnY
|| nY
!= mpWindowImpl
->maPos
.Y() )
1556 if ( bCopyBits
&& !pOverlapRegion
)
1558 pOverlapRegion
.reset( new vcl::Region() );
1559 ImplCalcOverlapRegion( tools::Rectangle( Point( mnOutOffX
, mnOutOffY
),
1560 Size( mnOutWidth
, mnOutHeight
) ),
1561 *pOverlapRegion
, false, true );
1563 mpWindowImpl
->mnY
= nY
;
1564 mpWindowImpl
->maPos
.setY( nY
);
1569 if ( !(bNewPos
|| bNewSize
) )
1572 bool bUpdateSysObjPos
= false;
1574 bUpdateSysObjPos
= ImplUpdatePos();
1576 // the borderwindow always specifies the position for its client window
1577 if ( mpWindowImpl
->mpBorderWindow
)
1578 mpWindowImpl
->maPos
= mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->maPos
;
1580 if ( mpWindowImpl
->mpClientWindow
)
1582 mpWindowImpl
->mpClientWindow
->ImplPosSizeWindow( mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnLeftBorder
,
1583 mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnTopBorder
,
1584 mnOutWidth
-mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnLeftBorder
-mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnRightBorder
,
1585 mnOutHeight
-mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnTopBorder
-mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnBottomBorder
,
1586 PosSizeFlags::X
| PosSizeFlags::Y
|
1587 PosSizeFlags::Width
| PosSizeFlags::Height
);
1588 // If we have a client window, then this is the position
1589 // of the Application's floating windows
1590 mpWindowImpl
->mpClientWindow
->mpWindowImpl
->maPos
= mpWindowImpl
->maPos
;
1593 if ( mpWindowImpl
->mpClientWindow
->IsVisible() )
1595 mpWindowImpl
->mpClientWindow
->ImplCallMove();
1599 mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mbCallMove
= true;
1604 // Move()/Resize() will be called only for Show(), such that
1605 // at least one is called before Show()
1620 mpWindowImpl
->mbCallMove
= true;
1622 mpWindowImpl
->mbCallResize
= true;
1625 bool bUpdateSysObjClip
= false;
1626 if ( IsReallyVisible() )
1628 if ( bNewPos
|| bNewSize
)
1631 bUpdateSysObjClip
= !ImplSetClipFlag( true );
1634 // invalidate window content ?
1635 if ( bNewPos
|| (mnOutWidth
> nOldOutWidth
) || (mnOutHeight
> nOldOutHeight
) )
1639 bool bInvalidate
= false;
1640 bool bParentPaint
= true;
1641 if ( !ImplIsOverlapWindow() )
1642 bParentPaint
= mpWindowImpl
->mpParent
->IsPaintEnabled();
1643 if ( bCopyBits
&& bParentPaint
&& !HasPaintEvent() )
1645 Point
aPoint( mnOutOffX
, mnOutOffY
);
1646 vcl::Region
aRegion( tools::Rectangle( aPoint
,
1647 Size( mnOutWidth
, mnOutHeight
) ) );
1648 if ( mpWindowImpl
->mbWinRegion
)
1649 aRegion
.Intersect( ImplPixelToDevicePixel( mpWindowImpl
->maWinRegion
) );
1650 ImplClipBoundaries( aRegion
, false, true );
1651 if ( !pOverlapRegion
->IsEmpty() )
1653 pOverlapRegion
->Move( mnOutOffX
-nOldOutOffX
, mnOutOffY
-nOldOutOffY
);
1654 aRegion
.Exclude( *pOverlapRegion
);
1656 if ( !aRegion
.IsEmpty() )
1658 // adapt Paint areas
1659 ImplMoveAllInvalidateRegions( tools::Rectangle( Point( nOldOutOffX
, nOldOutOffY
),
1660 Size( nOldOutWidth
, nOldOutHeight
) ),
1661 mnOutOffX
-nOldOutOffX
, mnOutOffY
-nOldOutOffY
,
1663 SalGraphics
* pGraphics
= ImplGetFrameGraphics();
1667 OutputDevice
*pOutDev
= GetOutDev();
1668 const bool bSelectClipRegion
= pOutDev
->SelectClipRegion( aRegion
, pGraphics
);
1669 if ( bSelectClipRegion
)
1671 pGraphics
->CopyArea( mnOutOffX
, mnOutOffY
,
1672 nOldOutOffX
, nOldOutOffY
,
1673 nOldOutWidth
, nOldOutHeight
,
1683 if ( !pOverlapRegion
->IsEmpty() )
1684 ImplInvalidateFrameRegion( pOverlapRegion
.get(), InvalidateFlags::Children
);
1693 ImplInvalidateFrameRegion( nullptr, InvalidateFlags::Children
);
1697 Point
aPoint( mnOutOffX
, mnOutOffY
);
1698 vcl::Region
aRegion( tools::Rectangle( aPoint
,
1699 Size( mnOutWidth
, mnOutHeight
) ) );
1700 aRegion
.Exclude( *pOldRegion
);
1701 if ( mpWindowImpl
->mbWinRegion
)
1702 aRegion
.Intersect( ImplPixelToDevicePixel( mpWindowImpl
->maWinRegion
) );
1703 ImplClipBoundaries( aRegion
, false, true );
1704 if ( !aRegion
.IsEmpty() )
1705 ImplInvalidateFrameRegion( &aRegion
, InvalidateFlags::Children
);
1709 // invalidate Parent or Overlaps
1711 (mnOutWidth
< nOldOutWidth
) || (mnOutHeight
< nOldOutHeight
) )
1713 vcl::Region
aRegion( *pOldRegion
);
1714 if ( !mpWindowImpl
->mbPaintTransparent
)
1715 ImplExcludeWindowRegion( aRegion
);
1716 ImplClipBoundaries( aRegion
, false, true );
1717 if ( !aRegion
.IsEmpty() && !mpWindowImpl
->mpBorderWindow
)
1718 ImplInvalidateParentFrameRegion( aRegion
);
1722 // adapt system objects
1723 if ( bUpdateSysObjClip
)
1724 ImplUpdateSysObjClip();
1725 if ( bUpdateSysObjPos
)
1726 ImplUpdateSysObjPos();
1727 if ( bNewSize
&& mpWindowImpl
->mpSysObj
)
1728 mpWindowImpl
->mpSysObj
->SetPosSize( mnOutOffX
, mnOutOffY
, mnOutWidth
, mnOutHeight
);
1731 void Window::ImplNewInputContext()
1733 ImplSVData
* pSVData
= ImplGetSVData();
1734 vcl::Window
* pFocusWin
= pSVData
->mpWinData
->mpFocusWin
;
1735 if ( !pFocusWin
|| pFocusWin
->IsDisposed() )
1738 // Is InputContext changed?
1739 const InputContext
& rInputContext
= pFocusWin
->GetInputContext();
1740 if ( rInputContext
== pFocusWin
->mpWindowImpl
->mpFrameData
->maOldInputContext
)
1743 pFocusWin
->mpWindowImpl
->mpFrameData
->maOldInputContext
= rInputContext
;
1745 SalInputContext aNewContext
;
1746 const vcl::Font
& rFont
= rInputContext
.GetFont();
1747 const OUString
& rFontName
= rFont
.GetFamilyName();
1748 rtl::Reference
<LogicalFontInstance
> pFontInstance
;
1749 aNewContext
.mpFont
= nullptr;
1750 if (!rFontName
.isEmpty())
1752 OutputDevice
*pFocusWinOutDev
= pFocusWin
->GetOutDev();
1753 Size aSize
= pFocusWinOutDev
->ImplLogicToDevicePixel( rFont
.GetFontSize() );
1754 if ( !aSize
.Height() )
1756 // only set default sizes if the font height in logical
1757 // coordinates equals 0
1758 if ( rFont
.GetFontSize().Height() )
1759 aSize
.setHeight( 1 );
1761 aSize
.setHeight( (12*pFocusWin
->mnDPIY
)/72 );
1763 pFontInstance
= pFocusWin
->mxFontCache
->GetFontInstance( pFocusWin
->mxFontCollection
.get(),
1764 rFont
, aSize
, static_cast<float>(aSize
.Height()) );
1765 if ( pFontInstance
)
1766 aNewContext
.mpFont
= pFontInstance
;
1768 aNewContext
.mnOptions
= rInputContext
.GetOptions();
1769 pFocusWin
->ImplGetFrame()->SetInputContext( &aNewContext
);
1772 void Window::SetDumpAsPropertyTreeHdl(const Link
<tools::JsonWriter
&, void>& rLink
)
1774 if (mpWindowImpl
) // may be called after dispose
1776 mpWindowImpl
->maDumpAsPropertyTreeHdl
= rLink
;
1780 void Window::SetModalHierarchyHdl(const Link
<bool, void>& rLink
)
1782 ImplGetFrame()->SetModalHierarchyHdl(rLink
);
1785 void Window::SetParentToDefaultWindow()
1788 SetParent(ImplGetDefaultWindow());
1791 KeyIndicatorState
Window::GetIndicatorState() const
1793 return mpWindowImpl
->mpFrame
->GetIndicatorState();
1796 void Window::SimulateKeyPress( sal_uInt16 nKeyCode
) const
1798 mpWindowImpl
->mpFrame
->SimulateKeyPress(nKeyCode
);
1801 void Window::KeyInput( const KeyEvent
& rKEvt
)
1803 KeyCode cod
= rKEvt
.GetKeyCode ();
1804 bool autoacc
= ImplGetSVData()->maNWFData
.mbAutoAccel
;
1806 // do not respond to accelerators unless Alt or Ctrl is held */
1807 if (cod
.GetCode () >= 0x200 && cod
.GetCode () <= 0x219)
1809 if (autoacc
&& cod
.GetModifier () != KEY_MOD2
&& !(cod
.GetModifier() & KEY_MOD1
))
1813 NotifyEvent
aNEvt( MouseNotifyEvent::KEYINPUT
, this, &rKEvt
);
1814 if ( !CompatNotify( aNEvt
) )
1815 mpWindowImpl
->mbKeyInput
= true;
1818 void Window::KeyUp( const KeyEvent
& rKEvt
)
1820 NotifyEvent
aNEvt( MouseNotifyEvent::KEYUP
, this, &rKEvt
);
1821 if ( !CompatNotify( aNEvt
) )
1822 mpWindowImpl
->mbKeyUp
= true;
1825 void Window::Draw( OutputDevice
*, const Point
&, DrawFlags
)
1829 void Window::Move() {}
1831 void Window::Resize() {}
1833 void Window::Activate() {}
1835 void Window::Deactivate() {}
1837 void Window::GetFocus()
1839 if ( HasFocus() && mpWindowImpl
->mpLastFocusWindow
&& !(mpWindowImpl
->mnDlgCtrlFlags
& DialogControlFlags::WantFocus
) )
1841 VclPtr
<vcl::Window
> xWindow(this);
1842 mpWindowImpl
->mpLastFocusWindow
->GrabFocus();
1843 if( xWindow
->IsDisposed() )
1847 NotifyEvent
aNEvt( MouseNotifyEvent::GETFOCUS
, this );
1848 CompatNotify( aNEvt
);
1851 void Window::LoseFocus()
1853 NotifyEvent
aNEvt( MouseNotifyEvent::LOSEFOCUS
, this );
1854 CompatNotify( aNEvt
);
1857 void Window::SetHelpHdl(const Link
<vcl::Window
&, bool>& rLink
)
1859 if (mpWindowImpl
) // may be called after dispose
1861 mpWindowImpl
->maHelpRequestHdl
= rLink
;
1865 void Window::RequestHelp( const HelpEvent
& rHEvt
)
1867 // if Balloon-Help is requested, show the balloon
1868 // with help text set
1869 if ( rHEvt
.GetMode() & HelpEventMode::BALLOON
)
1871 OUString rStr
= GetHelpText();
1872 if ( rStr
.isEmpty() )
1873 rStr
= GetQuickHelpText();
1874 if ( rStr
.isEmpty() && ImplGetParent() && !ImplIsOverlapWindow() )
1875 ImplGetParent()->RequestHelp( rHEvt
);
1878 Point aPos
= GetPosPixel();
1879 if ( ImplGetParent() && !ImplIsOverlapWindow() )
1880 aPos
= OutputToScreenPixel(Point(0, 0));
1881 tools::Rectangle
aRect( aPos
, GetSizePixel() );
1883 Help::ShowBalloon( this, rHEvt
.GetMousePosPixel(), aRect
, rStr
);
1886 else if ( rHEvt
.GetMode() & HelpEventMode::QUICK
)
1888 const OUString
& rStr
= GetQuickHelpText();
1889 if ( rStr
.isEmpty() && ImplGetParent() && !ImplIsOverlapWindow() )
1890 ImplGetParent()->RequestHelp( rHEvt
);
1893 Point aPos
= GetPosPixel();
1894 if ( ImplGetParent() && !ImplIsOverlapWindow() )
1895 aPos
= OutputToScreenPixel(Point(0, 0));
1896 tools::Rectangle
aRect( aPos
, GetSizePixel() );
1897 Help::ShowQuickHelp( this, aRect
, rStr
, QuickHelpFlags::CtrlText
);
1900 else if (!mpWindowImpl
->maHelpRequestHdl
.IsSet() || mpWindowImpl
->maHelpRequestHdl
.Call(*this))
1902 OUString
aStrHelpId( OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8
) );
1903 if ( aStrHelpId
.isEmpty() && ImplGetParent() )
1904 ImplGetParent()->RequestHelp( rHEvt
);
1907 Help
* pHelp
= Application::GetHelp();
1910 if( !aStrHelpId
.isEmpty() )
1911 pHelp
->Start( aStrHelpId
, this );
1913 pHelp
->Start( OOO_HELP_INDEX
, this );
1919 void Window::Command( const CommandEvent
& rCEvt
)
1921 CallEventListeners( VclEventId::WindowCommand
, const_cast<CommandEvent
*>(&rCEvt
) );
1923 NotifyEvent
aNEvt( MouseNotifyEvent::COMMAND
, this, &rCEvt
);
1924 if ( !CompatNotify( aNEvt
) )
1925 mpWindowImpl
->mbCommand
= true;
1928 void Window::Tracking( const TrackingEvent
& rTEvt
)
1931 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( this );
1933 pWrapper
->Tracking( rTEvt
);
1936 void Window::StateChanged(StateChangedType eType
)
1940 //stuff that doesn't invalidate the layout
1941 case StateChangedType::ControlForeground
:
1942 case StateChangedType::ControlBackground
:
1943 case StateChangedType::UpdateMode
:
1944 case StateChangedType::ReadOnly
:
1945 case StateChangedType::Enable
:
1946 case StateChangedType::State
:
1947 case StateChangedType::Data
:
1948 case StateChangedType::InitShow
:
1949 case StateChangedType::ControlFocus
:
1951 //stuff that does invalidate the layout
1953 queue_resize(eType
);
1958 void Window::SetStyle( WinBits nStyle
)
1960 if ( mpWindowImpl
&& mpWindowImpl
->mnStyle
!= nStyle
)
1962 mpWindowImpl
->mnPrevStyle
= mpWindowImpl
->mnStyle
;
1963 mpWindowImpl
->mnStyle
= nStyle
;
1964 CompatStateChanged( StateChangedType::Style
);
1968 void Window::SetExtendedStyle( WindowExtendedStyle nExtendedStyle
)
1971 if ( mpWindowImpl
->mnExtendedStyle
== nExtendedStyle
)
1974 vcl::Window
* pWindow
= ImplGetBorderWindow();
1977 if( pWindow
->mpWindowImpl
->mbFrame
)
1979 SalExtStyle nExt
= 0;
1980 if( nExtendedStyle
& WindowExtendedStyle::Document
)
1981 nExt
|= SAL_FRAME_EXT_STYLE_DOCUMENT
;
1982 if( nExtendedStyle
& WindowExtendedStyle::DocModified
)
1983 nExt
|= SAL_FRAME_EXT_STYLE_DOCMODIFIED
;
1985 pWindow
->ImplGetFrame()->SetExtendedFrameStyle( nExt
);
1987 mpWindowImpl
->mnExtendedStyle
= nExtendedStyle
;
1990 void Window::SetBorderStyle( WindowBorderStyle nBorderStyle
)
1993 if ( !mpWindowImpl
->mpBorderWindow
)
1996 if( nBorderStyle
== WindowBorderStyle::REMOVEBORDER
&&
1997 ! mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbFrame
&&
1998 mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mpParent
2001 // this is a little awkward: some controls (e.g. svtools ProgressBar)
2002 // cannot avoid getting constructed with WB_BORDER but want to disable
2003 // borders in case of NWF drawing. So they need a method to remove their border window
2004 VclPtr
<vcl::Window
> pBorderWin
= mpWindowImpl
->mpBorderWindow
;
2005 // remove us as border window's client
2006 pBorderWin
->mpWindowImpl
->mpClientWindow
= nullptr;
2007 mpWindowImpl
->mpBorderWindow
= nullptr;
2008 mpWindowImpl
->mpRealParent
= pBorderWin
->mpWindowImpl
->mpParent
;
2009 // reparent us above the border window
2010 SetParent( pBorderWin
->mpWindowImpl
->mpParent
);
2011 // set us to the position and size of our previous border
2012 Point
aBorderPos( pBorderWin
->GetPosPixel() );
2013 Size
aBorderSize( pBorderWin
->GetSizePixel() );
2014 setPosSizePixel( aBorderPos
.X(), aBorderPos
.Y(), aBorderSize
.Width(), aBorderSize
.Height() );
2015 // release border window
2016 pBorderWin
.disposeAndClear();
2018 // set new style bits
2019 SetStyle( GetStyle() & (~WB_BORDER
) );
2023 if ( mpWindowImpl
->mpBorderWindow
->GetType() == WindowType::BORDERWINDOW
)
2024 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetBorderStyle( nBorderStyle
);
2026 mpWindowImpl
->mpBorderWindow
->SetBorderStyle( nBorderStyle
);
2030 WindowBorderStyle
Window::GetBorderStyle() const
2033 if ( mpWindowImpl
->mpBorderWindow
)
2035 if ( mpWindowImpl
->mpBorderWindow
->GetType() == WindowType::BORDERWINDOW
)
2036 return static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->GetBorderStyle();
2038 return mpWindowImpl
->mpBorderWindow
->GetBorderStyle();
2041 return WindowBorderStyle::NONE
;
2044 tools::Long
Window::CalcTitleWidth() const
2047 if ( mpWindowImpl
->mpBorderWindow
)
2049 if ( mpWindowImpl
->mpBorderWindow
->GetType() == WindowType::BORDERWINDOW
)
2050 return static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->CalcTitleWidth();
2052 return mpWindowImpl
->mpBorderWindow
->CalcTitleWidth();
2054 else if ( mpWindowImpl
->mbFrame
&& (mpWindowImpl
->mnStyle
& WB_MOVEABLE
) )
2056 // we guess the width for frame windows as we do not know the
2057 // border of external dialogs
2058 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
2059 vcl::Font aFont
= GetFont();
2060 const_cast<vcl::Window
*>(this)->SetPointFont(*const_cast<Window
*>(this), rStyleSettings
.GetTitleFont());
2061 tools::Long nTitleWidth
= GetTextWidth( GetText() );
2062 const_cast<vcl::Window
*>(this)->SetFont( aFont
);
2063 nTitleWidth
+= rStyleSettings
.GetTitleHeight() * 3;
2064 nTitleWidth
+= StyleSettings::GetBorderSize() * 2;
2072 void Window::SetInputContext( const InputContext
& rInputContext
)
2075 mpWindowImpl
->maInputContext
= rInputContext
;
2076 if ( !mpWindowImpl
->mbInFocusHdl
&& HasFocus() )
2077 ImplNewInputContext();
2080 void Window::PostExtTextInputEvent(VclEventId nType
, const OUString
& rText
)
2084 case VclEventId::ExtTextInput
:
2086 std::unique_ptr
<ExtTextInputAttr
[]> pAttr(new ExtTextInputAttr
[rText
.getLength()]);
2087 for (int i
= 0; i
< rText
.getLength(); ++i
) {
2088 pAttr
[i
] = ExtTextInputAttr::Underline
;
2090 SalExtTextInputEvent aEvent
{ rText
, pAttr
.get(), rText
.getLength(), EXTTEXTINPUT_CURSOR_OVERWRITE
};
2091 ImplWindowFrameProc(this, SalEvent::ExtTextInput
, &aEvent
);
2094 case VclEventId::EndExtTextInput
:
2095 ImplWindowFrameProc(this, SalEvent::EndExtTextInput
, nullptr);
2102 void Window::EndExtTextInput()
2104 if ( mpWindowImpl
->mbExtTextInput
)
2105 ImplGetFrame()->EndExtTextInput( EndExtTextInputFlags::Complete
);
2108 void Window::SetCursorRect( const tools::Rectangle
* pRect
, tools::Long nExtTextInputWidth
)
2111 ImplWinData
* pWinData
= ImplGetWinData();
2112 if ( pWinData
->mpCursorRect
)
2115 pWinData
->mpCursorRect
= *pRect
;
2117 pWinData
->mpCursorRect
.reset();
2122 pWinData
->mpCursorRect
= *pRect
;
2125 pWinData
->mnCursorExtWidth
= nExtTextInputWidth
;
2129 const tools::Rectangle
* Window::GetCursorRect() const
2132 ImplWinData
* pWinData
= ImplGetWinData();
2133 return pWinData
->mpCursorRect
? &*pWinData
->mpCursorRect
: nullptr;
2136 tools::Long
Window::GetCursorExtTextInputWidth() const
2139 ImplWinData
* pWinData
= ImplGetWinData();
2140 return pWinData
->mnCursorExtWidth
;
2143 void Window::SetCompositionCharRect( const tools::Rectangle
* pRect
, tools::Long nCompositionLength
, bool bVertical
) {
2145 ImplWinData
* pWinData
= ImplGetWinData();
2146 pWinData
->mpCompositionCharRects
.reset();
2147 pWinData
->mbVertical
= bVertical
;
2148 pWinData
->mnCompositionCharRects
= nCompositionLength
;
2149 if ( pRect
&& (nCompositionLength
> 0) )
2151 pWinData
->mpCompositionCharRects
.reset( new tools::Rectangle
[nCompositionLength
] );
2152 for (tools::Long i
= 0; i
< nCompositionLength
; ++i
)
2153 pWinData
->mpCompositionCharRects
[i
] = pRect
[i
];
2157 void Window::CollectChildren(::std::vector
<vcl::Window
*>& rAllChildren
)
2159 rAllChildren
.push_back( this );
2161 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2164 pChild
->CollectChildren( rAllChildren
);
2165 pChild
= pChild
->mpWindowImpl
->mpNext
;
2169 void Window::SetPointFont(vcl::RenderContext
& rRenderContext
, const vcl::Font
& rFont
)
2171 vcl::Font aFont
= rFont
;
2172 ImplPointToLogic(rRenderContext
, aFont
);
2173 rRenderContext
.SetFont(aFont
);
2176 vcl::Font
Window::GetPointFont(vcl::RenderContext
const & rRenderContext
) const
2178 vcl::Font aFont
= rRenderContext
.GetFont();
2179 ImplLogicToPoint(rRenderContext
, aFont
);
2183 void Window::Show(bool bVisible
, ShowFlags nFlags
)
2185 if ( IsDisposed() || mpWindowImpl
->mbVisible
== bVisible
)
2188 VclPtr
<vcl::Window
> xWindow(this);
2190 bool bRealVisibilityChanged
= false;
2191 mpWindowImpl
->mbVisible
= bVisible
;
2195 ImplHideAllOverlaps();
2196 if( xWindow
->IsDisposed() )
2199 if ( mpWindowImpl
->mpBorderWindow
)
2201 bool bOldUpdate
= mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbNoParentUpdate
;
2202 if ( mpWindowImpl
->mbNoParentUpdate
)
2203 mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbNoParentUpdate
= true;
2204 mpWindowImpl
->mpBorderWindow
->Show( false, nFlags
);
2205 mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbNoParentUpdate
= bOldUpdate
;
2207 else if ( mpWindowImpl
->mbFrame
)
2209 mpWindowImpl
->mbSuppressAccessibilityEvents
= true;
2210 mpWindowImpl
->mpFrame
->Show( false );
2213 CompatStateChanged( StateChangedType::Visible
);
2215 if ( mpWindowImpl
->mbReallyVisible
)
2217 if ( mpWindowImpl
->mbInitWinClipRegion
)
2218 ImplInitWinClipRegion();
2220 vcl::Region aInvRegion
= mpWindowImpl
->maWinClipRegion
;
2222 if( xWindow
->IsDisposed() )
2225 bRealVisibilityChanged
= mpWindowImpl
->mbReallyVisible
;
2226 ImplResetReallyVisible();
2229 if ( ImplIsOverlapWindow() && !mpWindowImpl
->mbFrame
)
2232 if ( !(nFlags
& ShowFlags::NoFocusChange
) && HasChildPathFocus() )
2234 if ( mpWindowImpl
->mpOverlapWindow
->IsEnabled() &&
2235 mpWindowImpl
->mpOverlapWindow
->IsInputEnabled() &&
2236 ! mpWindowImpl
->mpOverlapWindow
->IsInModalMode()
2238 mpWindowImpl
->mpOverlapWindow
->GrabFocus();
2242 if ( !mpWindowImpl
->mbFrame
)
2244 if (mpWindowImpl
->mpWinData
&& mpWindowImpl
->mpWinData
->mbEnableNativeWidget
)
2247 * #i48371# native theming: some themes draw outside the control
2248 * area we tell them to (bad thing, but we cannot do much about it ).
2249 * On hiding these controls they get invalidated with their window rectangle
2250 * which leads to the parts outside the control area being left and not
2251 * invalidated. Workaround: invalidate an area on the parent, too
2253 const int workaround_border
= 5;
2254 tools::Rectangle
aBounds( aInvRegion
.GetBoundRect() );
2255 aBounds
.AdjustLeft( -workaround_border
);
2256 aBounds
.AdjustTop( -workaround_border
);
2257 aBounds
.AdjustRight(workaround_border
);
2258 aBounds
.AdjustBottom(workaround_border
);
2259 aInvRegion
= aBounds
;
2261 if ( !mpWindowImpl
->mbNoParentUpdate
)
2263 if ( !aInvRegion
.IsEmpty() )
2264 ImplInvalidateParentFrameRegion( aInvRegion
);
2266 ImplGenerateMouseMove();
2272 // inherit native widget flag for form controls
2273 // required here, because frames never show up in the child hierarchy - which should be fixed...
2274 // eg, the drop down of a combobox which is a system floating window
2275 if( mpWindowImpl
->mbFrame
&& GetParent() && GetParent()->IsCompoundControl() &&
2276 GetParent()->IsNativeWidgetEnabled() != IsNativeWidgetEnabled() &&
2277 !(GetStyle() & WB_TOOLTIPWIN
) )
2279 EnableNativeWidget( GetParent()->IsNativeWidgetEnabled() );
2282 if ( mpWindowImpl
->mbCallMove
)
2286 if ( mpWindowImpl
->mbCallResize
)
2291 CompatStateChanged( StateChangedType::Visible
);
2293 vcl::Window
* pTestParent
;
2294 if ( ImplIsOverlapWindow() )
2295 pTestParent
= mpWindowImpl
->mpOverlapWindow
;
2297 pTestParent
= ImplGetParent();
2298 if ( mpWindowImpl
->mbFrame
|| pTestParent
->mpWindowImpl
->mbReallyVisible
)
2300 // if a window becomes visible, send all child windows a StateChange,
2301 // such that these can initialise themselves
2304 // If it is a SystemWindow it automatically pops up on top of
2305 // all other windows if needed.
2306 if ( ImplIsOverlapWindow() && !(nFlags
& ShowFlags::NoActivate
) )
2308 ImplStartToTop(( nFlags
& ShowFlags::ForegroundTask
) ? ToTopFlags::ForegroundTask
: ToTopFlags::NONE
);
2309 ImplFocusToTop( ToTopFlags::NONE
, false );
2312 // adjust mpWindowImpl->mbReallyVisible
2313 bRealVisibilityChanged
= !mpWindowImpl
->mbReallyVisible
;
2314 ImplSetReallyVisible();
2316 // assure clip rectangles will be recalculated
2319 if ( !mpWindowImpl
->mbFrame
)
2321 InvalidateFlags nInvalidateFlags
= InvalidateFlags::Children
;
2322 if( ! IsPaintTransparent() )
2323 nInvalidateFlags
|= InvalidateFlags::NoTransparent
;
2324 ImplInvalidate( nullptr, nInvalidateFlags
);
2325 ImplGenerateMouseMove();
2329 if ( mpWindowImpl
->mpBorderWindow
)
2330 mpWindowImpl
->mpBorderWindow
->Show( true, nFlags
);
2331 else if ( mpWindowImpl
->mbFrame
)
2333 // #106431#, hide SplashScreen
2334 ImplSVData
* pSVData
= ImplGetSVData();
2335 if ( !pSVData
->mpIntroWindow
)
2337 // The right way would be just to call this (not even in the 'if')
2338 auto pApp
= GetpApp();
2340 pApp
->InitFinished();
2342 else if ( !ImplIsWindowOrChild( pSVData
->mpIntroWindow
) )
2344 // ... but the VCL splash is broken, and it needs this
2345 // (for ./soffice .uno:NewDoc)
2346 pSVData
->mpIntroWindow
->Hide();
2349 //SAL_WARN_IF( mpWindowImpl->mbSuppressAccessibilityEvents, "vcl", "Window::Show() - Frame reactivated");
2350 mpWindowImpl
->mbSuppressAccessibilityEvents
= false;
2352 mpWindowImpl
->mbPaintFrame
= true;
2353 if (!Application::IsHeadlessModeEnabled())
2355 bool bNoActivate(nFlags
& (ShowFlags::NoActivate
|ShowFlags::NoFocusChange
));
2356 mpWindowImpl
->mpFrame
->Show( true, bNoActivate
);
2358 if( xWindow
->IsDisposed() )
2361 // Query the correct size of the window, if we are waiting for
2363 if ( mpWindowImpl
->mbWaitSystemResize
)
2365 tools::Long nOutWidth
;
2366 tools::Long nOutHeight
;
2367 mpWindowImpl
->mpFrame
->GetClientSize( nOutWidth
, nOutHeight
);
2368 ImplHandleResize( this, nOutWidth
, nOutHeight
);
2371 if (mpWindowImpl
->mpFrameData
->mpBuffer
&& mpWindowImpl
->mpFrameData
->mpBuffer
->GetOutputSizePixel() != GetOutputSizePixel())
2372 // Make sure that the buffer size matches the window size, even if no resize was needed.
2373 mpWindowImpl
->mpFrameData
->mpBuffer
->SetOutputSizePixel(GetOutputSizePixel());
2376 if( xWindow
->IsDisposed() )
2379 ImplShowAllOverlaps();
2382 if( xWindow
->IsDisposed() )
2385 // the SHOW/HIDE events also serve as indicators to send child creation/destroy events to the access bridge
2386 // However, the access bridge only uses this event if the data member is not NULL (it's kind of a hack that
2387 // we re-use the SHOW/HIDE events this way, with this particular semantics).
2388 // Since #104887#, the notifications for the access bridge are done in Impl(Set|Reset)ReallyVisible. Here, we
2389 // now only notify with a NULL data pointer, for all other clients except the access bridge.
2390 if ( !bRealVisibilityChanged
)
2391 CallEventListeners( mpWindowImpl
->mbVisible
? VclEventId::WindowShow
: VclEventId::WindowHide
);
2392 if( xWindow
->IsDisposed() )
2397 Size
Window::GetSizePixel() const
2401 SAL_WARN("vcl.layout", "WTF no windowimpl");
2405 // #i43257# trigger pending resize handler to assure correct window sizes
2406 if( mpWindowImpl
->mpFrameData
->maResizeIdle
.IsActive() )
2408 VclPtr
<vcl::Window
> xWindow( const_cast<Window
*>(this) );
2409 mpWindowImpl
->mpFrameData
->maResizeIdle
.Stop();
2410 mpWindowImpl
->mpFrameData
->maResizeIdle
.Invoke( nullptr );
2411 if( xWindow
->IsDisposed() )
2415 return Size( mnOutWidth
+mpWindowImpl
->mnLeftBorder
+mpWindowImpl
->mnRightBorder
,
2416 mnOutHeight
+mpWindowImpl
->mnTopBorder
+mpWindowImpl
->mnBottomBorder
);
2419 void Window::GetBorder( sal_Int32
& rLeftBorder
, sal_Int32
& rTopBorder
,
2420 sal_Int32
& rRightBorder
, sal_Int32
& rBottomBorder
) const
2422 rLeftBorder
= mpWindowImpl
->mnLeftBorder
;
2423 rTopBorder
= mpWindowImpl
->mnTopBorder
;
2424 rRightBorder
= mpWindowImpl
->mnRightBorder
;
2425 rBottomBorder
= mpWindowImpl
->mnBottomBorder
;
2428 void Window::Enable( bool bEnable
, bool bChild
)
2435 // the tracking mode will be stopped or the capture will be stolen
2436 // when a window is disabled,
2438 EndTracking( TrackingEventFlags::Cancel
);
2439 if ( IsMouseCaptured() )
2441 // try to pass focus to the next control
2442 // if the window has focus and is contained in the dialog control
2443 // mpWindowImpl->mbDisabled should only be set after a call of ImplDlgCtrlNextWindow().
2444 // Otherwise ImplDlgCtrlNextWindow() should be used
2446 ImplDlgCtrlNextWindow();
2449 if ( mpWindowImpl
->mpBorderWindow
)
2451 mpWindowImpl
->mpBorderWindow
->Enable( bEnable
, false );
2452 if ( (mpWindowImpl
->mpBorderWindow
->GetType() == WindowType::BORDERWINDOW
) &&
2453 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->mpMenuBarWindow
)
2454 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->mpMenuBarWindow
->Enable( bEnable
);
2457 // #i56102# restore app focus win in case the
2458 // window was disabled when the frame focus changed
2459 ImplSVData
* pSVData
= ImplGetSVData();
2460 if (bEnable
&& pSVData
->mpWinData
->mpFocusWin
== nullptr
2461 && mpWindowImpl
->mpFrameData
->mbHasFocus
&& mpWindowImpl
->mpFrameData
->mpFocusWin
== this)
2462 pSVData
->mpWinData
->mpFocusWin
= this;
2464 if ( mpWindowImpl
->mbDisabled
!= !bEnable
)
2466 mpWindowImpl
->mbDisabled
= !bEnable
;
2467 if ( mpWindowImpl
->mpSysObj
)
2468 mpWindowImpl
->mpSysObj
->Enable( bEnable
&& !mpWindowImpl
->mbInputDisabled
);
2469 CompatStateChanged( StateChangedType::Enable
);
2471 CallEventListeners( bEnable
? VclEventId::WindowEnabled
: VclEventId::WindowDisabled
);
2476 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2479 pChild
->Enable( bEnable
, bChild
);
2480 pChild
= pChild
->mpWindowImpl
->mpNext
;
2484 if ( IsReallyVisible() )
2485 ImplGenerateMouseMove();
2488 void Window::EnableInput( bool bEnable
, bool bChild
)
2493 if ( mpWindowImpl
->mpBorderWindow
)
2495 mpWindowImpl
->mpBorderWindow
->EnableInput( bEnable
, false );
2496 if ( (mpWindowImpl
->mpBorderWindow
->GetType() == WindowType::BORDERWINDOW
) &&
2497 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->mpMenuBarWindow
)
2498 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->mpMenuBarWindow
->EnableInput( bEnable
);
2501 if ( (!bEnable
&& mpWindowImpl
->meAlwaysInputMode
!= AlwaysInputEnabled
) || bEnable
)
2503 // automatically stop the tracking mode or steal capture
2504 // if the window is disabled
2508 EndTracking( TrackingEventFlags::Cancel
);
2509 if ( IsMouseCaptured() )
2513 if ( mpWindowImpl
->mbInputDisabled
!= !bEnable
)
2515 mpWindowImpl
->mbInputDisabled
= !bEnable
;
2516 if ( mpWindowImpl
->mpSysObj
)
2517 mpWindowImpl
->mpSysObj
->Enable( !mpWindowImpl
->mbDisabled
&& bEnable
);
2521 // #i56102# restore app focus win in case the
2522 // window was disabled when the frame focus changed
2523 ImplSVData
* pSVData
= ImplGetSVData();
2524 if (bEnable
&& pSVData
->mpWinData
->mpFocusWin
== nullptr
2525 && mpWindowImpl
->mpFrameData
->mbHasFocus
&& mpWindowImpl
->mpFrameData
->mpFocusWin
== this)
2526 pSVData
->mpWinData
->mpFocusWin
= this;
2530 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2533 pChild
->EnableInput( bEnable
, bChild
);
2534 pChild
= pChild
->mpWindowImpl
->mpNext
;
2538 if ( IsReallyVisible() )
2539 ImplGenerateMouseMove();
2542 void Window::EnableInput( bool bEnable
, const vcl::Window
* pExcludeWindow
)
2547 EnableInput( bEnable
);
2549 // pExecuteWindow is the first Overlap-Frame --> if this
2550 // shouldn't be the case, then this must be changed in dialog.cxx
2551 if( pExcludeWindow
)
2552 pExcludeWindow
= pExcludeWindow
->ImplGetFirstOverlapWindow();
2553 vcl::Window
* pSysWin
= mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpFrameData
->mpFirstOverlap
;
2556 // Is Window in the path from this window
2557 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pSysWin
, true ) )
2559 // Is Window not in the exclude window path or not the
2560 // exclude window, then change the status
2561 if ( !pExcludeWindow
|| !pExcludeWindow
->ImplIsWindowOrChild( pSysWin
, true ) )
2562 pSysWin
->EnableInput( bEnable
);
2564 pSysWin
= pSysWin
->mpWindowImpl
->mpNextOverlap
;
2567 // enable/disable floating system windows as well
2568 vcl::Window
* pFrameWin
= ImplGetSVData()->maFrameData
.mpFirstFrame
;
2571 if( pFrameWin
->ImplIsFloatingWindow() )
2573 // Is Window in the path from this window
2574 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pFrameWin
, true ) )
2576 // Is Window not in the exclude window path or not the
2577 // exclude window, then change the status
2578 if ( !pExcludeWindow
|| !pExcludeWindow
->ImplIsWindowOrChild( pFrameWin
, true ) )
2579 pFrameWin
->EnableInput( bEnable
);
2582 pFrameWin
= pFrameWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
2585 // the same for ownerdraw floating windows
2586 if( !mpWindowImpl
->mbFrame
)
2589 ::std::vector
< VclPtr
<vcl::Window
> >& rList
= mpWindowImpl
->mpFrameData
->maOwnerDrawList
;
2590 for (auto const& elem
: rList
)
2592 // Is Window in the path from this window
2593 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( elem
, true ) )
2595 // Is Window not in the exclude window path or not the
2596 // exclude window, then change the status
2597 if ( !pExcludeWindow
|| !pExcludeWindow
->ImplIsWindowOrChild( elem
, true ) )
2598 elem
->EnableInput( bEnable
);
2603 void Window::AlwaysEnableInput( bool bAlways
, bool bChild
)
2606 if ( mpWindowImpl
->mpBorderWindow
)
2607 mpWindowImpl
->mpBorderWindow
->AlwaysEnableInput( bAlways
, false );
2609 if( bAlways
&& mpWindowImpl
->meAlwaysInputMode
!= AlwaysInputEnabled
)
2611 mpWindowImpl
->meAlwaysInputMode
= AlwaysInputEnabled
;
2612 EnableInput(true, false);
2614 else if( ! bAlways
&& mpWindowImpl
->meAlwaysInputMode
== AlwaysInputEnabled
)
2616 mpWindowImpl
->meAlwaysInputMode
= AlwaysInputNone
;
2621 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2624 pChild
->AlwaysEnableInput( bAlways
, bChild
);
2625 pChild
= pChild
->mpWindowImpl
->mpNext
;
2630 void Window::SetActivateMode( ActivateModeFlags nMode
)
2633 if ( mpWindowImpl
->mpBorderWindow
)
2634 mpWindowImpl
->mpBorderWindow
->SetActivateMode( nMode
);
2636 if ( mpWindowImpl
->mnActivateMode
== nMode
)
2639 mpWindowImpl
->mnActivateMode
= nMode
;
2641 // possibly trigger Deactivate/Activate
2642 if ( mpWindowImpl
->mnActivateMode
!= ActivateModeFlags::NONE
)
2644 if ( (mpWindowImpl
->mbActive
|| (GetType() == WindowType::BORDERWINDOW
)) &&
2645 !HasChildPathFocus( true ) )
2647 mpWindowImpl
->mbActive
= false;
2653 if ( !mpWindowImpl
->mbActive
|| (GetType() == WindowType::BORDERWINDOW
) )
2655 mpWindowImpl
->mbActive
= true;
2661 void Window::setPosSizePixel( tools::Long nX
, tools::Long nY
,
2662 tools::Long nWidth
, tools::Long nHeight
, PosSizeFlags nFlags
)
2664 bool bHasValidSize
= !mpWindowImpl
->mbDefSize
;
2666 if ( nFlags
& PosSizeFlags::Pos
)
2667 mpWindowImpl
->mbDefPos
= false;
2668 if ( nFlags
& PosSizeFlags::Size
)
2669 mpWindowImpl
->mbDefSize
= false;
2671 // The top BorderWindow is the window which is to be positioned
2672 VclPtr
<vcl::Window
> pWindow
= this;
2673 while ( pWindow
->mpWindowImpl
->mpBorderWindow
)
2674 pWindow
= pWindow
->mpWindowImpl
->mpBorderWindow
;
2676 if ( pWindow
->mpWindowImpl
->mbFrame
)
2678 // Note: if we're positioning a frame, the coordinates are interpreted
2679 // as being the top-left corner of the window's client area and NOT
2680 // as the position of the border ! (due to limitations of several UNIX window managers)
2681 tools::Long nOldWidth
= pWindow
->mnOutWidth
;
2683 if ( !(nFlags
& PosSizeFlags::Width
) )
2684 nWidth
= pWindow
->mnOutWidth
;
2685 if ( !(nFlags
& PosSizeFlags::Height
) )
2686 nHeight
= pWindow
->mnOutHeight
;
2688 sal_uInt16 nSysFlags
=0;
2689 VclPtr
<vcl::Window
> pParent
= GetParent();
2690 VclPtr
<vcl::Window
> pWinParent
= pWindow
->GetParent();
2692 if( nFlags
& PosSizeFlags::Width
)
2693 nSysFlags
|= SAL_FRAME_POSSIZE_WIDTH
;
2694 if( nFlags
& PosSizeFlags::Height
)
2695 nSysFlags
|= SAL_FRAME_POSSIZE_HEIGHT
;
2696 if( nFlags
& PosSizeFlags::X
)
2698 nSysFlags
|= SAL_FRAME_POSSIZE_X
;
2699 if( pWinParent
&& (pWindow
->GetStyle() & WB_SYSTEMCHILDWINDOW
) )
2701 nX
+= pWinParent
->mnOutOffX
;
2703 if( pParent
&& pParent
->ImplIsAntiparallel() )
2705 tools::Rectangle
aRect( Point ( nX
, nY
), Size( nWidth
, nHeight
) );
2706 const OutputDevice
*pParentOutDev
= pParent
->GetOutDev();
2707 pParentOutDev
->ReMirror( aRect
);
2711 if( !(nFlags
& PosSizeFlags::X
) && bHasValidSize
&& pWindow
->mpWindowImpl
->mpFrame
->maGeometry
.nWidth
)
2713 // RTL: make sure the old right aligned position is not changed
2714 // system windows will always grow to the right
2717 OutputDevice
*pParentOutDev
= pWinParent
->GetOutDev();
2718 if( pParentOutDev
->HasMirroredGraphics() )
2720 const SalFrameGeometry
& aSysGeometry
= mpWindowImpl
->mpFrame
->GetUnmirroredGeometry();
2721 const SalFrameGeometry
& aParentSysGeometry
=
2722 pWinParent
->mpWindowImpl
->mpFrame
->GetUnmirroredGeometry();
2723 tools::Long myWidth
= nOldWidth
;
2725 myWidth
= aSysGeometry
.nWidth
;
2728 nFlags
|= PosSizeFlags::X
;
2729 nSysFlags
|= SAL_FRAME_POSSIZE_X
;
2730 nX
= aParentSysGeometry
.nX
- aSysGeometry
.nLeftDecoration
+ aParentSysGeometry
.nWidth
2731 - myWidth
- 1 - aSysGeometry
.nX
;
2735 if( nFlags
& PosSizeFlags::Y
)
2737 nSysFlags
|= SAL_FRAME_POSSIZE_Y
;
2738 if( pWinParent
&& (pWindow
->GetStyle() & WB_SYSTEMCHILDWINDOW
) )
2740 nY
+= pWinParent
->mnOutOffY
;
2744 if( nSysFlags
& (SAL_FRAME_POSSIZE_WIDTH
|SAL_FRAME_POSSIZE_HEIGHT
) )
2746 // check for min/max client size and adjust size accordingly
2747 // otherwise it may happen that the resize event is ignored, i.e. the old size remains
2748 // unchanged but ImplHandleResize() is called with the wrong size
2749 SystemWindow
*pSystemWindow
= dynamic_cast< SystemWindow
* >( pWindow
.get() );
2752 Size aMinSize
= pSystemWindow
->GetMinOutputSizePixel();
2753 Size aMaxSize
= pSystemWindow
->GetMaxOutputSizePixel();
2754 if( nWidth
< aMinSize
.Width() )
2755 nWidth
= aMinSize
.Width();
2756 if( nHeight
< aMinSize
.Height() )
2757 nHeight
= aMinSize
.Height();
2759 if( nWidth
> aMaxSize
.Width() )
2760 nWidth
= aMaxSize
.Width();
2761 if( nHeight
> aMaxSize
.Height() )
2762 nHeight
= aMaxSize
.Height();
2766 pWindow
->mpWindowImpl
->mpFrame
->SetPosSize( nX
, nY
, nWidth
, nHeight
, nSysFlags
);
2768 // Adjust resize with the hack of different client size and frame geometries to fix
2769 // native menu bars. Eventually this should be replaced by proper mnTopBorder usage.
2770 pWindow
->mpWindowImpl
->mpFrame
->GetClientSize(nWidth
, nHeight
);
2772 // Resize should be called directly. If we haven't
2773 // set the correct size, we get a second resize from
2774 // the system with the correct size. This can be happened
2775 // if the size is too small or too large.
2776 ImplHandleResize( pWindow
, nWidth
, nHeight
);
2780 pWindow
->ImplPosSizeWindow( nX
, nY
, nWidth
, nHeight
, nFlags
);
2781 if ( IsReallyVisible() )
2782 ImplGenerateMouseMove();
2786 Point
Window::GetPosPixel() const
2788 return mpWindowImpl
->maPos
;
2791 tools::Rectangle
Window::GetDesktopRectPixel() const
2793 tools::Rectangle rRect
;
2794 mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpFrame
->GetWorkArea( rRect
);
2798 Point
Window::OutputToScreenPixel( const Point
& rPos
) const
2800 // relative to top level parent
2801 return Point( rPos
.X()+mnOutOffX
, rPos
.Y()+mnOutOffY
);
2804 Point
Window::ScreenToOutputPixel( const Point
& rPos
) const
2806 // relative to top level parent
2807 return Point( rPos
.X()-mnOutOffX
, rPos
.Y()-mnOutOffY
);
2810 tools::Long
Window::ImplGetUnmirroredOutOffX()
2812 // revert mnOutOffX changes that were potentially made in ImplPosSizeWindow
2813 tools::Long offx
= mnOutOffX
;
2814 OutputDevice
*pOutDev
= GetOutDev();
2815 if( pOutDev
->HasMirroredGraphics() )
2817 if( mpWindowImpl
->mpParent
&& !mpWindowImpl
->mpParent
->mpWindowImpl
->mbFrame
&& mpWindowImpl
->mpParent
->ImplIsAntiparallel() )
2819 if ( !ImplIsOverlapWindow() )
2820 offx
-= mpWindowImpl
->mpParent
->mnOutOffX
;
2822 offx
= mpWindowImpl
->mpParent
->mnOutWidth
- mnOutWidth
- offx
;
2824 if ( !ImplIsOverlapWindow() )
2825 offx
+= mpWindowImpl
->mpParent
->mnOutOffX
;
2832 // normalized screen pixel are independent of mirroring
2833 Point
Window::OutputToNormalizedScreenPixel( const Point
& rPos
) const
2835 // relative to top level parent
2836 tools::Long offx
= const_cast<vcl::Window
*>(this)->ImplGetUnmirroredOutOffX();
2837 return Point( rPos
.X()+offx
, rPos
.Y()+mnOutOffY
);
2840 Point
Window::NormalizedScreenToOutputPixel( const Point
& rPos
) const
2842 // relative to top level parent
2843 tools::Long offx
= const_cast<vcl::Window
*>(this)->ImplGetUnmirroredOutOffX();
2844 return Point( rPos
.X()-offx
, rPos
.Y()-mnOutOffY
);
2847 Point
Window::OutputToAbsoluteScreenPixel( const Point
& rPos
) const
2849 // relative to the screen
2850 Point p
= OutputToScreenPixel( rPos
);
2851 SalFrameGeometry g
= mpWindowImpl
->mpFrame
->GetGeometry();
2857 Point
Window::AbsoluteScreenToOutputPixel( const Point
& rPos
) const
2859 // relative to the screen
2860 Point p
= ScreenToOutputPixel( rPos
);
2861 SalFrameGeometry g
= mpWindowImpl
->mpFrame
->GetGeometry();
2862 p
.AdjustX( -(g
.nX
) );
2863 p
.AdjustY( -(g
.nY
) );
2867 tools::Rectangle
Window::ImplOutputToUnmirroredAbsoluteScreenPixel( const tools::Rectangle
&rRect
) const
2869 // this method creates unmirrored screen coordinates to be compared with the desktop
2870 // and is used for positioning of RTL popup windows correctly on the screen
2871 SalFrameGeometry g
= mpWindowImpl
->mpFrame
->GetUnmirroredGeometry();
2873 Point p1
= OutputToScreenPixel( rRect
.TopRight() );
2874 p1
.setX( g
.nX
+g
.nWidth
-p1
.X() );
2877 Point p2
= OutputToScreenPixel( rRect
.BottomLeft() );
2878 p2
.setX( g
.nX
+g
.nWidth
-p2
.X() );
2881 return tools::Rectangle( p1
, p2
);
2884 tools::Rectangle
Window::GetWindowExtentsRelative(const vcl::Window
*pRelativeWindow
) const
2887 return ImplGetWindowExtentsRelative( pRelativeWindow
);
2890 tools::Rectangle
Window::ImplGetWindowExtentsRelative(const vcl::Window
*pRelativeWindow
) const
2892 SalFrameGeometry g
= mpWindowImpl
->mpFrame
->GetGeometry();
2893 // make sure we use the extent of our border window,
2894 // otherwise we miss a few pixels
2895 const vcl::Window
*pWin
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
: this;
2897 Point
aPos( pWin
->OutputToScreenPixel( Point(0,0) ) );
2898 aPos
.AdjustX(g
.nX
);
2899 aPos
.AdjustY(g
.nY
);
2900 Size
aSize ( pWin
->GetSizePixel() );
2901 // #104088# do not add decoration to the workwindow to be compatible to java accessibility api
2902 if( mpWindowImpl
->mbFrame
|| (mpWindowImpl
->mpBorderWindow
&& mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbFrame
&& GetType() != WindowType::WORKWINDOW
) )
2904 aPos
.AdjustX( -sal_Int32(g
.nLeftDecoration
) );
2905 aPos
.AdjustY( -sal_Int32(g
.nTopDecoration
) );
2906 aSize
.AdjustWidth(g
.nLeftDecoration
+ g
.nRightDecoration
);
2907 aSize
.AdjustHeight(g
.nTopDecoration
+ g
.nBottomDecoration
);
2909 if( pRelativeWindow
)
2911 // #106399# express coordinates relative to borderwindow
2912 const vcl::Window
*pRelWin
= pRelativeWindow
->mpWindowImpl
->mpBorderWindow
? pRelativeWindow
->mpWindowImpl
->mpBorderWindow
.get() : pRelativeWindow
;
2913 aPos
= pRelWin
->AbsoluteScreenToOutputPixel( aPos
);
2915 return tools::Rectangle( aPos
, aSize
);
2918 void Window::Scroll( tools::Long nHorzScroll
, tools::Long nVertScroll
, ScrollFlags nFlags
)
2921 ImplScroll( tools::Rectangle( Point( mnOutOffX
, mnOutOffY
),
2922 Size( mnOutWidth
, mnOutHeight
) ),
2923 nHorzScroll
, nVertScroll
, nFlags
& ~ScrollFlags::Clip
);
2926 void Window::Scroll( tools::Long nHorzScroll
, tools::Long nVertScroll
,
2927 const tools::Rectangle
& rRect
, ScrollFlags nFlags
)
2929 OutputDevice
*pOutDev
= GetOutDev();
2930 tools::Rectangle aRect
= pOutDev
->ImplLogicToDevicePixel( rRect
);
2931 aRect
.Intersection( tools::Rectangle( Point( mnOutOffX
, mnOutOffY
), Size( mnOutWidth
, mnOutHeight
) ) );
2932 if ( !aRect
.IsEmpty() )
2933 ImplScroll( aRect
, nHorzScroll
, nVertScroll
, nFlags
);
2936 void Window::Flush()
2940 const tools::Rectangle
aWinRect( Point( mnOutOffX
, mnOutOffY
), Size( mnOutWidth
, mnOutHeight
) );
2941 mpWindowImpl
->mpFrame
->Flush( aWinRect
);
2945 void Window::SetUpdateMode( bool bUpdate
)
2949 mpWindowImpl
->mbNoUpdate
= !bUpdate
;
2950 CompatStateChanged( StateChangedType::UpdateMode
);
2954 void Window::GrabFocus()
2956 ImplGrabFocus( GetFocusFlags::NONE
);
2959 bool Window::HasFocus() const
2961 return (this == ImplGetSVData()->mpWinData
->mpFocusWin
);
2964 void Window::GrabFocusToDocument()
2966 ImplGrabFocusToDocument(GetFocusFlags::NONE
);
2969 VclPtr
<vcl::Window
> Window::GetFocusedWindow() const
2971 if (mpWindowImpl
&& mpWindowImpl
->mpFrameData
)
2972 return mpWindowImpl
->mpFrameData
->mpFocusWin
;
2974 return VclPtr
<vcl::Window
>();
2977 void Window::SetFakeFocus( bool bFocus
)
2979 ImplGetWindowImpl()->mbFakeFocusSet
= bFocus
;
2982 bool Window::HasChildPathFocus( bool bSystemWindow
) const
2985 vcl::Window
* pFocusWin
= ImplGetSVData()->mpWinData
->mpFocusWin
;
2987 return ImplIsWindowOrChild( pFocusWin
, bSystemWindow
);
2991 void Window::SetCursor( vcl::Cursor
* pCursor
)
2994 if ( mpWindowImpl
->mpCursor
!= pCursor
)
2996 if ( mpWindowImpl
->mpCursor
)
2997 mpWindowImpl
->mpCursor
->ImplHide();
2998 mpWindowImpl
->mpCursor
= pCursor
;
3000 pCursor
->ImplShow();
3004 void Window::SetText( const OUString
& rStr
)
3006 if (!mpWindowImpl
|| rStr
== mpWindowImpl
->maText
)
3009 OUString
oldTitle( mpWindowImpl
->maText
);
3010 mpWindowImpl
->maText
= rStr
;
3012 if ( mpWindowImpl
->mpBorderWindow
)
3013 mpWindowImpl
->mpBorderWindow
->SetText( rStr
);
3014 else if ( mpWindowImpl
->mbFrame
)
3015 mpWindowImpl
->mpFrame
->SetTitle( rStr
);
3017 CallEventListeners( VclEventId::WindowFrameTitleChanged
, &oldTitle
);
3019 // #107247# needed for accessibility
3020 // The VclEventId::WindowFrameTitleChanged is (mis)used to notify accessible name changes.
3021 // Therefore a window, which is labeled by this window, must also notify an accessible
3023 if ( IsReallyVisible() )
3025 vcl::Window
* pWindow
= GetAccessibleRelationLabelFor();
3026 if ( pWindow
&& pWindow
!= this )
3027 pWindow
->CallEventListeners( VclEventId::WindowFrameTitleChanged
, &oldTitle
);
3030 CompatStateChanged( StateChangedType::Text
);
3033 OUString
Window::GetText() const
3036 return mpWindowImpl
->maText
;
3039 OUString
Window::GetDisplayText() const
3045 const Wallpaper
& Window::GetDisplayBackground() const
3047 // FIXME: fix issue 52349, need to fix this really in
3048 // all NWF enabled controls
3049 const ToolBox
* pTB
= dynamic_cast<const ToolBox
*>(this);
3050 if( pTB
&& IsNativeWidgetEnabled() )
3051 return pTB
->ImplGetToolBoxPrivateData()->maDisplayBackground
;
3053 if( !IsBackground() )
3055 if( mpWindowImpl
->mpParent
)
3056 return mpWindowImpl
->mpParent
->GetDisplayBackground();
3059 const Wallpaper
& rBack
= GetBackground();
3060 if( ! rBack
.IsBitmap() &&
3061 ! rBack
.IsGradient() &&
3062 rBack
.GetColor()== COL_TRANSPARENT
&&
3063 mpWindowImpl
->mpParent
)
3064 return mpWindowImpl
->mpParent
->GetDisplayBackground();
3068 const OUString
& Window::GetHelpText() const
3070 OUString
aStrHelpId( OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8
) );
3071 bool bStrHelpId
= !aStrHelpId
.isEmpty();
3073 if ( !mpWindowImpl
->maHelpText
.getLength() && bStrHelpId
)
3075 if ( !IsDialog() && (mpWindowImpl
->mnType
!= WindowType::TABPAGE
) && (mpWindowImpl
->mnType
!= WindowType::FLOATINGWINDOW
) )
3077 Help
* pHelp
= Application::GetHelp();
3080 mpWindowImpl
->maHelpText
= pHelp
->GetHelpText(aStrHelpId
, this);
3081 mpWindowImpl
->mbHelpTextDynamic
= false;
3085 else if( mpWindowImpl
->mbHelpTextDynamic
&& bStrHelpId
)
3087 static const char* pEnv
= getenv( "HELP_DEBUG" );
3090 OUString aTxt
= mpWindowImpl
->maHelpText
+ "\n------------------\n" + aStrHelpId
;
3091 mpWindowImpl
->maHelpText
= aTxt
;
3093 mpWindowImpl
->mbHelpTextDynamic
= false;
3096 //Fallback to Window::GetAccessibleDescription without reentry to GetHelpText()
3097 if (mpWindowImpl
->maHelpText
.isEmpty() && mpWindowImpl
->mpAccessibleInfos
&& mpWindowImpl
->mpAccessibleInfos
->pAccessibleDescription
)
3098 return *mpWindowImpl
->mpAccessibleInfos
->pAccessibleDescription
;
3099 return mpWindowImpl
->maHelpText
;
3102 void Window::SetWindowPeer( Reference
< css::awt::XWindowPeer
> const & xPeer
, VCLXWindow
* pVCLXWindow
)
3107 // be safe against re-entrance: first clear the old ref, then assign the new one
3108 mpWindowImpl
->mxWindowPeer
.clear();
3109 mpWindowImpl
->mxWindowPeer
= xPeer
;
3111 mpWindowImpl
->mpVCLXWindow
= pVCLXWindow
;
3114 Reference
< css::awt::XWindowPeer
> Window::GetComponentInterface( bool bCreate
)
3116 if ( !mpWindowImpl
->mxWindowPeer
.is() && bCreate
)
3118 UnoWrapperBase
* pWrapper
= UnoWrapperBase::GetUnoWrapper();
3120 mpWindowImpl
->mxWindowPeer
= pWrapper
->GetWindowInterface( this );
3122 return mpWindowImpl
->mxWindowPeer
;
3125 void Window::SetComponentInterface( Reference
< css::awt::XWindowPeer
> const & xIFace
)
3127 UnoWrapperBase
* pWrapper
= UnoWrapperBase::GetUnoWrapper();
3128 SAL_WARN_IF( !pWrapper
, "vcl.window", "SetComponentInterface: No Wrapper!" );
3130 pWrapper
->SetWindowInterface( this, xIFace
);
3133 typedef std::map
<vcl::LOKWindowId
, VclPtr
<vcl::Window
>> LOKWindowsMap
;
3137 LOKWindowsMap
& GetLOKWindowsMap()
3139 // Map to remember the LOKWindowId <-> Window binding.
3140 static LOKWindowsMap s_aLOKWindowsMap
;
3142 return s_aLOKWindowsMap
;
3147 void Window::SetLOKNotifier(const vcl::ILibreOfficeKitNotifier
* pNotifier
, bool bParent
)
3149 // don't allow setting this twice
3150 assert(mpWindowImpl
->mpLOKNotifier
== nullptr);
3152 // never use this in the desktop case
3153 assert(comphelper::LibreOfficeKit::isActive());
3157 // Counter to be able to have unique id's for each window.
3158 static vcl::LOKWindowId sLastLOKWindowId
= 1;
3160 // assign the LOK window id
3161 assert(mpWindowImpl
->mnLOKWindowId
== 0);
3162 mpWindowImpl
->mnLOKWindowId
= sLastLOKWindowId
++;
3163 GetLOKWindowsMap().emplace(mpWindowImpl
->mnLOKWindowId
, this);
3166 mpWindowImpl
->mbLOKParentNotifier
= true;
3168 mpWindowImpl
->mpLOKNotifier
= pNotifier
;
3171 VclPtr
<Window
> Window::FindLOKWindow(vcl::LOKWindowId nWindowId
)
3173 const auto it
= GetLOKWindowsMap().find(nWindowId
);
3174 if (it
!= GetLOKWindowsMap().end())
3177 return VclPtr
<Window
>();
3180 bool Window::IsLOKWindowsEmpty()
3182 return GetLOKWindowsMap().empty();
3185 void Window::ReleaseLOKNotifier()
3187 // unregister the LOK window binding
3188 if (mpWindowImpl
->mnLOKWindowId
> 0)
3189 GetLOKWindowsMap().erase(mpWindowImpl
->mnLOKWindowId
);
3191 mpWindowImpl
->mpLOKNotifier
= nullptr;
3192 mpWindowImpl
->mnLOKWindowId
= 0;
3195 ILibreOfficeKitNotifier::~ILibreOfficeKitNotifier()
3197 if (!comphelper::LibreOfficeKit::isActive())
3202 for (auto it
= GetLOKWindowsMap().begin(); it
!= GetLOKWindowsMap().end();)
3204 WindowImpl
* pWindowImpl
= it
->second
->ImplGetWindowImpl();
3205 if (pWindowImpl
&& pWindowImpl
->mpLOKNotifier
== this)
3207 pWindowImpl
->mpLOKNotifier
= nullptr;
3208 pWindowImpl
->mnLOKWindowId
= 0;
3209 it
= GetLOKWindowsMap().erase(it
);
3217 const vcl::ILibreOfficeKitNotifier
* Window::GetLOKNotifier() const
3219 return mpWindowImpl
->mpLOKNotifier
;
3222 vcl::LOKWindowId
Window::GetLOKWindowId() const
3224 return mpWindowImpl
->mnLOKWindowId
;
3227 VclPtr
<vcl::Window
> Window::GetParentWithLOKNotifier()
3229 VclPtr
<vcl::Window
> pWindow(this);
3231 while (pWindow
&& !pWindow
->GetLOKNotifier())
3232 pWindow
= pWindow
->GetParent();
3240 const char* windowTypeName(WindowType nWindowType
)
3242 switch (nWindowType
)
3244 case WindowType::NONE
: return "none";
3245 case WindowType::MESSBOX
: return "messagebox";
3246 case WindowType::INFOBOX
: return "infobox";
3247 case WindowType::WARNINGBOX
: return "warningbox";
3248 case WindowType::ERRORBOX
: return "errorbox";
3249 case WindowType::QUERYBOX
: return "querybox";
3250 case WindowType::WINDOW
: return "window";
3251 case WindowType::WORKWINDOW
: return "workwindow";
3252 case WindowType::CONTAINER
: return "container";
3253 case WindowType::FLOATINGWINDOW
: return "floatingwindow";
3254 case WindowType::DIALOG
: return "dialog";
3255 case WindowType::MODELESSDIALOG
: return "modelessdialog";
3256 case WindowType::CONTROL
: return "control";
3257 case WindowType::PUSHBUTTON
: return "pushbutton";
3258 case WindowType::OKBUTTON
: return "okbutton";
3259 case WindowType::CANCELBUTTON
: return "cancelbutton";
3260 case WindowType::HELPBUTTON
: return "helpbutton";
3261 case WindowType::IMAGEBUTTON
: return "imagebutton";
3262 case WindowType::MENUBUTTON
: return "menubutton";
3263 case WindowType::MOREBUTTON
: return "morebutton";
3264 case WindowType::SPINBUTTON
: return "spinbutton";
3265 case WindowType::RADIOBUTTON
: return "radiobutton";
3266 case WindowType::CHECKBOX
: return "checkbox";
3267 case WindowType::TRISTATEBOX
: return "tristatebox";
3268 case WindowType::EDIT
: return "edit";
3269 case WindowType::MULTILINEEDIT
: return "multilineedit";
3270 case WindowType::COMBOBOX
: return "combobox";
3271 case WindowType::LISTBOX
: return "listbox";
3272 case WindowType::MULTILISTBOX
: return "multilistbox";
3273 case WindowType::FIXEDTEXT
: return "fixedtext";
3274 case WindowType::FIXEDLINE
: return "fixedline";
3275 case WindowType::FIXEDBITMAP
: return "fixedbitmap";
3276 case WindowType::FIXEDIMAGE
: return "fixedimage";
3277 case WindowType::GROUPBOX
: return "groupbox";
3278 case WindowType::SCROLLBAR
: return "scrollbar";
3279 case WindowType::SCROLLBARBOX
: return "scrollbarbox";
3280 case WindowType::SPLITTER
: return "splitter";
3281 case WindowType::SPLITWINDOW
: return "splitwindow";
3282 case WindowType::SPINFIELD
: return "spinfield";
3283 case WindowType::PATTERNFIELD
: return "patternfield";
3284 case WindowType::METRICFIELD
: return "metricfield";
3285 case WindowType::FORMATTEDFIELD
: return "formattedfield";
3286 case WindowType::CURRENCYFIELD
: return "currencyfield";
3287 case WindowType::DATEFIELD
: return "datefield";
3288 case WindowType::TIMEFIELD
: return "timefield";
3289 case WindowType::PATTERNBOX
: return "patternbox";
3290 case WindowType::NUMERICBOX
: return "numericbox";
3291 case WindowType::METRICBOX
: return "metricbox";
3292 case WindowType::CURRENCYBOX
: return "currencybox";
3293 case WindowType::DATEBOX
: return "datebox";
3294 case WindowType::TIMEBOX
: return "timebox";
3295 case WindowType::LONGCURRENCYBOX
: return "longcurrencybox";
3296 case WindowType::SCROLLWINDOW
: return "scrollwindow";
3297 case WindowType::TOOLBOX
: return "toolbox";
3298 case WindowType::DOCKINGWINDOW
: return "dockingwindow";
3299 case WindowType::STATUSBAR
: return "statusbar";
3300 case WindowType::TABPAGE
: return "tabpage";
3301 case WindowType::TABCONTROL
: return "tabcontrol";
3302 case WindowType::TABDIALOG
: return "tabdialog";
3303 case WindowType::BORDERWINDOW
: return "borderwindow";
3304 case WindowType::BUTTONDIALOG
: return "buttondialog";
3305 case WindowType::SYSTEMCHILDWINDOW
: return "systemchildwindow";
3306 case WindowType::SLIDER
: return "slider";
3307 case WindowType::MENUBARWINDOW
: return "menubarwindow";
3308 case WindowType::TREELISTBOX
: return "treelistbox";
3309 case WindowType::HELPTEXTWINDOW
: return "helptextwindow";
3310 case WindowType::INTROWINDOW
: return "introwindow";
3311 case WindowType::LISTBOXWINDOW
: return "listboxwindow";
3312 case WindowType::DOCKINGAREA
: return "dockingarea";
3313 case WindowType::RULER
: return "ruler";
3314 case WindowType::HEADERBAR
: return "headerbar";
3315 case WindowType::VERTICALTABCONTROL
: return "verticaltabcontrol";
3317 // nothing to do here, but for completeness
3318 case WindowType::TOOLKIT_FRAMEWINDOW
: return "toolkit_framewindow";
3319 case WindowType::TOOLKIT_SYSTEMCHILDWINDOW
: return "toolkit_systemchildwindow";
3327 void Window::DumpAsPropertyTree(tools::JsonWriter
& rJsonWriter
)
3329 rJsonWriter
.put("id", get_id()); // TODO could be missing - sort out
3330 rJsonWriter
.put("type", windowTypeName(GetType()));
3331 rJsonWriter
.put("text", GetText());
3332 rJsonWriter
.put("enabled", IsEnabled());
3334 if (vcl::Window
* pChild
= mpWindowImpl
->mpFirstChild
)
3336 auto childrenNode
= rJsonWriter
.startNode("children");
3339 if (pChild
->IsVisible()) {
3340 auto childNode
= rJsonWriter
.startNode("");
3341 pChild
->DumpAsPropertyTree(rJsonWriter
);
3342 sal_Int32 nLeft
= pChild
->get_grid_left_attach();
3343 sal_Int32 nTop
= pChild
->get_grid_top_attach();
3344 if (nLeft
!= -1 && nTop
!= -1)
3346 rJsonWriter
.put("left", nLeft
);
3347 rJsonWriter
.put("top", nTop
);
3350 pChild
= pChild
->mpWindowImpl
->mpNext
;
3354 mpWindowImpl
->maDumpAsPropertyTreeHdl
.Call(rJsonWriter
);
3357 void Window::ImplCallDeactivateListeners( vcl::Window
*pNew
)
3359 // no deactivation if the newly activated window is my child
3360 if ( !pNew
|| !ImplIsChild( pNew
) )
3362 VclPtr
<vcl::Window
> xWindow(this);
3363 CallEventListeners( VclEventId::WindowDeactivate
, pNew
);
3364 if( xWindow
->IsDisposed() )
3367 // #100759#, avoid walking the wrong frame's hierarchy
3368 // eg, undocked docking windows (ImplDockFloatWin)
3369 if ( ImplGetParent() && mpWindowImpl
->mpFrameWindow
== ImplGetParent()->mpWindowImpl
->mpFrameWindow
)
3370 ImplGetParent()->ImplCallDeactivateListeners( pNew
);
3374 void Window::ImplCallActivateListeners( vcl::Window
*pOld
)
3376 // no activation if the old active window is my child
3377 if ( pOld
&& ImplIsChild( pOld
))
3380 VclPtr
<vcl::Window
> xWindow(this);
3381 CallEventListeners( VclEventId::WindowActivate
, pOld
);
3382 if( xWindow
->IsDisposed() )
3385 if ( ImplGetParent() )
3386 ImplGetParent()->ImplCallActivateListeners( pOld
);
3387 else if( (mpWindowImpl
->mnStyle
& WB_INTROWIN
) == 0 )
3389 // top level frame reached: store hint for DefModalDialogParent
3390 ImplGetSVData()->maFrameData
.mpActiveApplicationFrame
= mpWindowImpl
->mpFrameWindow
;
3394 void Window::SetClipboard(Reference
<XClipboard
> const & xClipboard
)
3396 if (mpWindowImpl
->mpFrameData
)
3397 mpWindowImpl
->mpFrameData
->mxClipboard
= xClipboard
;
3400 Reference
< XClipboard
> Window::GetClipboard()
3402 if (!mpWindowImpl
->mpFrameData
)
3403 return static_cast<XClipboard
*>(nullptr);
3404 if (!mpWindowImpl
->mpFrameData
->mxClipboard
.is())
3405 mpWindowImpl
->mpFrameData
->mxClipboard
= GetSystemClipboard();
3406 return mpWindowImpl
->mpFrameData
->mxClipboard
;
3409 Reference
< XClipboard
> Window::GetPrimarySelection()
3411 if (!mpWindowImpl
->mpFrameData
)
3412 return static_cast<XClipboard
*>(nullptr);
3413 if (!mpWindowImpl
->mpFrameData
->mxSelection
.is())
3414 mpWindowImpl
->mpFrameData
->mxSelection
= GetSystemPrimarySelection();
3415 return mpWindowImpl
->mpFrameData
->mxSelection
;
3418 void Window::RecordLayoutData( vcl::ControlLayoutData
* pLayout
, const tools::Rectangle
& rRect
)
3420 assert(mpOutDevData
);
3421 mpOutDevData
->mpRecordLayout
= pLayout
;
3422 mpOutDevData
->maRecordRect
= rRect
;
3423 Paint(*this, rRect
);
3424 mpOutDevData
->mpRecordLayout
= nullptr;
3427 void Window::DrawSelectionBackground( const tools::Rectangle
& rRect
,
3428 sal_uInt16 highlight
,
3433 if( rRect
.IsEmpty() )
3436 const StyleSettings
& rStyles
= GetSettings().GetStyleSettings();
3438 // colors used for item highlighting
3439 Color
aSelectionBorderCol( rStyles
.GetHighlightColor() );
3440 Color
aSelectionFillCol( aSelectionBorderCol
);
3442 bool bDark
= rStyles
.GetFaceColor().IsDark();
3443 bool bBright
= ( rStyles
.GetFaceColor() == COL_WHITE
);
3445 int c1
= aSelectionBorderCol
.GetLuminance();
3446 int c2
= GetBackgroundColor().GetLuminance();
3448 if( !bDark
&& !bBright
&& abs( c2
-c1
) < 75 )
3452 aSelectionFillCol
.RGBtoHSB( h
, s
, b
);
3453 if( b
> 50 ) b
-= 40;
3455 aSelectionFillCol
= Color::HSBtoRGB( h
, s
, b
);
3456 aSelectionBorderCol
= aSelectionFillCol
;
3459 tools::Rectangle
aRect( rRect
);
3460 Color oldFillCol
= GetFillColor();
3461 Color oldLineCol
= GetLineColor();
3464 SetLineColor( bDark
? COL_WHITE
: ( bBright
? COL_BLACK
: aSelectionBorderCol
) );
3468 sal_uInt16 nPercent
= 0;
3472 aSelectionFillCol
= COL_BLACK
;
3474 nPercent
= 80; // just checked (light)
3478 if( bChecked
&& highlight
== 2 )
3481 aSelectionFillCol
= COL_LIGHTGRAY
;
3484 aSelectionFillCol
= COL_BLACK
;
3485 SetLineColor( COL_BLACK
);
3489 nPercent
= 20; // selected, pressed or checked ( very dark )
3491 else if( bChecked
|| highlight
== 1 )
3494 aSelectionFillCol
= COL_GRAY
;
3497 aSelectionFillCol
= COL_BLACK
;
3498 SetLineColor( COL_BLACK
);
3502 nPercent
= 35; // selected, pressed or checked ( very dark )
3507 aSelectionFillCol
= COL_LIGHTGRAY
;
3510 aSelectionFillCol
= COL_BLACK
;
3511 SetLineColor( COL_BLACK
);
3512 if( highlight
== 3 )
3518 nPercent
= 70; // selected ( dark )
3522 SetFillColor( aSelectionFillCol
);
3530 tools::Polygon
aPoly( aRect
);
3531 tools::PolyPolygon
aPolyPoly( aPoly
);
3532 DrawTransparent( aPolyPoly
, nPercent
);
3535 SetFillColor( oldFillCol
);
3536 SetLineColor( oldLineCol
);
3539 bool Window::IsScrollable() const
3541 // check for scrollbars
3542 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
3545 if( pChild
->GetType() == WindowType::SCROLLBAR
)
3548 pChild
= pChild
->mpWindowImpl
->mpNext
;
3553 void Window::ImplMirrorFramePos( Point
&pt
) const
3555 pt
.setX( mpWindowImpl
->mpFrame
->maGeometry
.nWidth
-1-pt
.X() );
3558 // frame based modal counter (dialogs are not modal to the whole application anymore)
3559 bool Window::IsInModalMode() const
3561 return (mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpFrameData
->mnModalMode
!= 0);
3564 void Window::IncModalCount()
3566 vcl::Window
* pFrameWindow
= mpWindowImpl
->mpFrameWindow
;
3567 vcl::Window
* pParent
= pFrameWindow
;
3568 while( pFrameWindow
)
3570 pFrameWindow
->mpWindowImpl
->mpFrameData
->mnModalMode
++;
3571 while( pParent
&& pParent
->mpWindowImpl
->mpFrameWindow
== pFrameWindow
)
3573 pParent
= pParent
->GetParent();
3575 pFrameWindow
= pParent
? pParent
->mpWindowImpl
->mpFrameWindow
.get() : nullptr;
3578 void Window::DecModalCount()
3580 vcl::Window
* pFrameWindow
= mpWindowImpl
->mpFrameWindow
;
3581 vcl::Window
* pParent
= pFrameWindow
;
3582 while( pFrameWindow
)
3584 pFrameWindow
->mpWindowImpl
->mpFrameData
->mnModalMode
--;
3585 while( pParent
&& pParent
->mpWindowImpl
->mpFrameWindow
== pFrameWindow
)
3587 pParent
= pParent
->GetParent();
3589 pFrameWindow
= pParent
? pParent
->mpWindowImpl
->mpFrameWindow
.get() : nullptr;
3593 void Window::ImplIsInTaskPaneList( bool mbIsInTaskList
)
3595 mpWindowImpl
->mbIsInTaskPaneList
= mbIsInTaskList
;
3598 void Window::ImplNotifyIconifiedState( bool bIconified
)
3600 mpWindowImpl
->mpFrameWindow
->CallEventListeners( bIconified
? VclEventId::WindowMinimize
: VclEventId::WindowNormalize
);
3601 // #109206# notify client window as well to have toolkit topwindow listeners notified
3602 if( mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpClientWindow
&& mpWindowImpl
->mpFrameWindow
!= mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpClientWindow
)
3603 mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpClientWindow
->CallEventListeners( bIconified
? VclEventId::WindowMinimize
: VclEventId::WindowNormalize
);
3606 bool Window::HasActiveChildFrame() const
3609 vcl::Window
*pFrameWin
= ImplGetSVData()->maFrameData
.mpFirstFrame
;
3612 if( pFrameWin
!= mpWindowImpl
->mpFrameWindow
)
3614 bool bDecorated
= false;
3615 VclPtr
< vcl::Window
> pChildFrame
= pFrameWin
->ImplGetWindow();
3616 // #i15285# unfortunately WB_MOVEABLE is the same as WB_TABSTOP which can
3617 // be removed for ToolBoxes to influence the keyboard accessibility
3618 // thus WB_MOVEABLE is no indicator for decoration anymore
3619 // but FloatingWindows carry this information in their TitleType...
3620 // TODO: avoid duplicate WinBits !!!
3621 if( pChildFrame
&& pChildFrame
->ImplIsFloatingWindow() )
3622 bDecorated
= static_cast<FloatingWindow
*>(pChildFrame
.get())->GetTitleType() != FloatWinTitleType::NONE
;
3623 if( bDecorated
|| (pFrameWin
->mpWindowImpl
->mnStyle
& (WB_MOVEABLE
| WB_SIZEABLE
) ) )
3624 if( pChildFrame
&& pChildFrame
->IsVisible() && pChildFrame
->IsActive() )
3626 if( ImplIsChild( pChildFrame
, true ) )
3633 pFrameWin
= pFrameWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
3638 LanguageType
Window::GetInputLanguage() const
3640 return mpWindowImpl
->mpFrame
->GetInputLanguage();
3643 void Window::EnableNativeWidget( bool bEnable
)
3645 static const char* pNoNWF
= getenv( "SAL_NO_NWF" );
3646 if( pNoNWF
&& *pNoNWF
)
3649 if( bEnable
!= ImplGetWinData()->mbEnableNativeWidget
)
3651 ImplGetWinData()->mbEnableNativeWidget
= bEnable
;
3653 // send datachanged event to allow for internal changes required for NWF
3654 // like clipmode, transparency, etc.
3655 DataChangedEvent
aDCEvt( DataChangedEventType::SETTINGS
, mxSettings
.get(), AllSettingsFlags::STYLE
);
3656 CompatDataChanged( aDCEvt
);
3658 // sometimes the borderwindow is queried, so keep it in sync
3659 if( mpWindowImpl
->mpBorderWindow
)
3660 mpWindowImpl
->mpBorderWindow
->ImplGetWinData()->mbEnableNativeWidget
= bEnable
;
3663 // push down, useful for compound controls
3664 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
3667 pChild
->EnableNativeWidget( bEnable
);
3668 pChild
= pChild
->mpWindowImpl
->mpNext
;
3672 bool Window::IsNativeWidgetEnabled() const
3674 return ImplGetWinData()->mbEnableNativeWidget
;
3677 Reference
< css::rendering::XCanvas
> Window::ImplGetCanvas( bool bSpriteCanvas
) const
3679 // try to retrieve hard reference from weak member
3680 Reference
< css::rendering::XCanvas
> xCanvas( mpWindowImpl
->mxCanvas
);
3682 // canvas still valid? Then we're done.
3686 Sequence
< Any
> aArg(5);
3688 // Feed any with operating system's window handle
3690 // common: first any is VCL pointer to window (for VCL canvas)
3691 aArg
[ 0 ] <<= reinterpret_cast<sal_Int64
>(this);
3692 aArg
[ 1 ] <<= css::awt::Rectangle( mnOutOffX
, mnOutOffY
, mnOutWidth
, mnOutHeight
);
3693 aArg
[ 2 ] <<= mpWindowImpl
->mbAlwaysOnTop
;
3694 aArg
[ 3 ] <<= Reference
< css::awt::XWindow
>(
3695 const_cast<vcl::Window
*>(this)->GetComponentInterface(),
3697 aArg
[ 4 ] = GetSystemGfxDataAny();
3699 Reference
< XComponentContext
> xContext
= comphelper::getProcessComponentContext();
3701 // Create canvas instance with window handle
3703 static vcl::DeleteUnoReferenceOnDeinit
<XMultiComponentFactory
> xStaticCanvasFactory(
3704 css::rendering::CanvasFactory::create( xContext
) );
3705 Reference
<XMultiComponentFactory
> xCanvasFactory(xStaticCanvasFactory
.get());
3707 if(xCanvasFactory
.is())
3710 // see #140456# - if we're running on a multiscreen setup,
3711 // request special, multi-screen safe sprite canvas
3712 // implementation (not DX5 canvas, as it cannot cope with
3713 // surfaces spanning multiple displays). Note: canvas
3714 // (without sprite) stays the same)
3715 const sal_uInt32 nDisplay
= static_cast< WinSalFrame
* >( mpWindowImpl
->mpFrame
)->mnDisplay
;
3716 if( nDisplay
>= Application::GetScreenCount() )
3718 xCanvas
.set( xCanvasFactory
->createInstanceWithArgumentsAndContext(
3720 OUString( "com.sun.star.rendering.SpriteCanvas.MultiScreen" ) :
3721 OUString( "com.sun.star.rendering.Canvas.MultiScreen" ),
3730 xCanvas
.set( xCanvasFactory
->createInstanceWithArgumentsAndContext(
3732 OUString( "com.sun.star.rendering.SpriteCanvas" ) :
3733 OUString( "com.sun.star.rendering.Canvas" ),
3739 mpWindowImpl
->mxCanvas
= xCanvas
;
3742 // no factory??? Empty reference, then.
3746 Reference
< css::rendering::XCanvas
> Window::GetCanvas() const
3748 return ImplGetCanvas( false );
3751 Reference
< css::rendering::XSpriteCanvas
> Window::GetSpriteCanvas() const
3753 Reference
< css::rendering::XSpriteCanvas
> xSpriteCanvas(
3754 ImplGetCanvas( true ), UNO_QUERY
);
3755 return xSpriteCanvas
;
3758 OUString
Window::GetSurroundingText() const
3763 Selection
Window::GetSurroundingTextSelection() const
3765 return Selection( 0, 0 );
3770 using namespace com::sun::star
;
3772 uno::Reference
<accessibility::XAccessibleEditableText
> lcl_GetxText(vcl::Window
*pFocusWin
)
3774 uno::Reference
<accessibility::XAccessibleEditableText
> xText
;
3777 uno::Reference
< accessibility::XAccessible
> xAccessible( pFocusWin
->GetAccessible() );
3778 if (xAccessible
.is())
3779 xText
= FindFocusedEditableText(xAccessible
->getAccessibleContext());
3781 catch(const uno::Exception
&)
3783 TOOLS_WARN_EXCEPTION( "vcl.gtk3", "Exception in getting input method surrounding text");
3789 // this is a rubbish implementation using a11y, ideally all subclasses implementing
3790 // GetSurroundingText/GetSurroundingTextSelection should implement this and then this
3791 // should be removed in favor of a stub that returns false
3792 bool Window::DeleteSurroundingText(const Selection
& rSelection
)
3794 uno::Reference
<accessibility::XAccessibleEditableText
> xText
= lcl_GetxText(this);
3797 sal_Int32 nPosition
= xText
->getCaretPosition();
3798 // #i111768# range checking
3799 sal_Int32 nDeletePos
= rSelection
.Min();
3800 sal_Int32 nDeleteEnd
= rSelection
.Max();
3805 if (nDeleteEnd
> xText
->getCharacterCount())
3806 nDeleteEnd
= xText
->getCharacterCount();
3808 xText
->deleteText(nDeletePos
, nDeleteEnd
);
3809 //tdf91641 adjust cursor if deleted chars shift it forward (normal case)
3810 if (nDeletePos
< nPosition
)
3812 if (nDeleteEnd
<= nPosition
)
3813 nPosition
= nPosition
- (nDeleteEnd
- nDeletePos
);
3815 nPosition
= nDeletePos
;
3817 if (xText
->getCharacterCount() >= nPosition
)
3818 xText
->setCaretPosition( nPosition
);
3826 bool Window::UsePolyPolygonForComplexGradient()
3828 return meRasterOp
!= RasterOp::OverPaint
;
3831 void Window::ApplySettings(vcl::RenderContext
& /*rRenderContext*/)
3835 const SystemEnvData
* Window::GetSystemData() const
3838 return mpWindowImpl
->mpFrame
? mpWindowImpl
->mpFrame
->GetSystemData() : nullptr;
3841 bool Window::SupportsDoubleBuffering() const
3843 return mpWindowImpl
->mpFrameData
->mpBuffer
;
3846 void Window::RequestDoubleBuffering(bool bRequest
)
3850 mpWindowImpl
->mpFrameData
->mpBuffer
= VclPtrInstance
<VirtualDevice
>();
3851 // Make sure that the buffer size matches the frame size.
3852 mpWindowImpl
->mpFrameData
->mpBuffer
->SetOutputSizePixel(mpWindowImpl
->mpFrameWindow
->GetOutputSizePixel());
3855 mpWindowImpl
->mpFrameData
->mpBuffer
.reset();
3859 * The rationale here is that we moved destructors to
3860 * dispose and this altered a lot of code paths, that
3861 * are better left unchanged for now.
3863 #define COMPAT_BODY(method,args) \
3864 if (!mpWindowImpl || mpWindowImpl->mbInDispose) \
3865 Window::method args; \
3869 void Window::CompatGetFocus()
3871 COMPAT_BODY(GetFocus
,())
3874 void Window::CompatLoseFocus()
3876 COMPAT_BODY(LoseFocus
,())
3879 void Window::CompatStateChanged( StateChangedType nStateChange
)
3881 COMPAT_BODY(StateChanged
,(nStateChange
))
3884 void Window::CompatDataChanged( const DataChangedEvent
& rDCEvt
)
3886 COMPAT_BODY(DataChanged
,(rDCEvt
))
3889 bool Window::CompatPreNotify( NotifyEvent
& rNEvt
)
3891 if (!mpWindowImpl
|| mpWindowImpl
->mbInDispose
)
3892 return Window::PreNotify( rNEvt
);
3894 return PreNotify( rNEvt
);
3897 bool Window::CompatNotify( NotifyEvent
& rNEvt
)
3899 if (!mpWindowImpl
|| mpWindowImpl
->mbInDispose
)
3900 return Window::EventNotify( rNEvt
);
3902 return EventNotify( rNEvt
);
3905 void Window::set_id(const OUString
& rID
)
3907 mpWindowImpl
->maID
= rID
;
3910 const OUString
& Window::get_id() const
3912 return mpWindowImpl
->maID
;
3915 FactoryFunction
Window::GetUITestFactory() const
3917 return WindowUIObject::create
;
3920 } /* namespace vcl */
3922 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */