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 <vcl/salgtype.hxx>
25 #include <vcl/event.hxx>
26 #include <vcl/help.hxx>
27 #include <vcl/cursor.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/vclevent.hxx>
30 #include <vcl/window.hxx>
31 #include <vcl/syswin.hxx>
32 #include <vcl/dockwin.hxx>
33 #include <vcl/wall.hxx>
34 #include <vcl/fixed.hxx>
35 #include <vcl/taskpanelist.hxx>
36 #include <vcl/toolkit/unowrap.hxx>
37 #include <vcl/lazydelete.hxx>
38 #include <vcl/virdev.hxx>
39 #include <vcl/settings.hxx>
40 #include <vcl/sysdata.hxx>
41 #include <vcl/ptrstyle.hxx>
42 #include <vcl/IDialogRenderable.hxx>
44 #include <vcl/uitest/uiobject.hxx>
46 #include <salframe.hxx>
48 #include <salinst.hxx>
55 #include <helpwin.hxx>
57 #include <com/sun/star/accessibility/AccessibleRelation.hpp>
58 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
59 #include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
60 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
61 #include <com/sun/star/rendering/CanvasFactory.hpp>
62 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
63 #include <comphelper/lok.hxx>
64 #include <comphelper/processfactory.hxx>
65 #include <unotools/configmgr.hxx>
66 #include <osl/diagnose.h>
67 #include <tools/debug.hxx>
68 #include <boost/property_tree/ptree.hpp>
73 #ifdef _WIN32 // see #140456#
74 #include <win/salframe.h>
78 using namespace ::com::sun::star::uno
;
79 using namespace ::com::sun::star::lang
;
80 using namespace ::com::sun::star::datatransfer::clipboard
;
81 using namespace ::com::sun::star::datatransfer::dnd
;
85 Window::Window( WindowType nType
)
86 : OutputDevice(OUTDEV_WINDOW
)
87 , mpWindowImpl(new WindowImpl( nType
))
89 // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
90 mbEnableRTL
= AllSettings::GetLayoutRTL();
93 Window::Window( vcl::Window
* pParent
, WinBits nStyle
)
94 : OutputDevice(OUTDEV_WINDOW
)
95 , mpWindowImpl(new WindowImpl( WindowType::WINDOW
))
97 // true: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
98 mbEnableRTL
= AllSettings::GetLayoutRTL();
100 ImplInit( pParent
, nStyle
, nullptr );
103 #if OSL_DEBUG_LEVEL > 0
106 OString
lcl_createWindowInfo(const vcl::Window
* pWindow
)
108 // skip border windows, they do not carry information that
109 // would help with diagnosing the problem
110 const vcl::Window
* pTempWin( pWindow
);
111 while ( pTempWin
&& pTempWin
->GetType() == WindowType::BORDERWINDOW
) {
112 pTempWin
= pTempWin
->GetWindow( GetWindowType::FirstChild
);
114 // check if pTempWin is not null, otherwise use the
120 OStringBuffer aErrorString
;
121 aErrorString
.append(' ');
122 aErrorString
.append(typeid( *pWindow
).name());
123 aErrorString
.append("(");
127 RTL_TEXTENCODING_UTF8
130 aErrorString
.append(")");
131 return aErrorString
.makeStringAndClear();
136 bool Window::IsDisposed() const
138 return !mpWindowImpl
;
141 void Window::dispose()
143 assert( mpWindowImpl
);
144 assert( !mpWindowImpl
->mbInDispose
); // should only be called from disposeOnce()
145 assert( (!mpWindowImpl
->mpParent
||
146 !mpWindowImpl
->mpParent
->IsDisposed()) &&
147 "vcl::Window child should have its parent disposed first" );
149 // remove Key and Mouse events issued by Application::PostKey/MouseEvent
150 Application::RemoveMouseAndKeyEvents( this );
152 // Dispose of the canvas implementation (which, currently, has an
153 // own wrapper window as a child to this one.
154 Reference
< css::rendering::XCanvas
> xCanvas( mpWindowImpl
->mxCanvas
);
157 Reference
< XComponent
> xCanvasComponent( xCanvas
, UNO_QUERY
);
158 if( xCanvasComponent
.is() )
159 xCanvasComponent
->dispose();
162 mpWindowImpl
->mbInDispose
= true;
164 CallEventListeners( VclEventId::ObjectDying
);
166 // do not send child events for frames that were registered as native frames
167 if( !ImplIsAccessibleNativeFrame() && mpWindowImpl
->mbReallyVisible
)
168 if ( ImplIsAccessibleCandidate() && GetAccessibleParentWindow() )
169 GetAccessibleParentWindow()->CallEventListeners( VclEventId::WindowChildDestroyed
, this );
171 // remove associated data structures from dockingmanager
172 ImplGetDockingManager()->RemoveWindow( this );
174 // remove ownerdraw decorated windows from list in the top-most frame window
175 if( (GetStyle() & WB_OWNERDRAWDECORATION
) && mpWindowImpl
->mbFrame
)
177 ::std::vector
< VclPtr
<vcl::Window
> >& rList
= ImplGetOwnerDrawList();
178 auto p
= ::std::find( rList
.begin(), rList
.end(), VclPtr
<vcl::Window
>(this) );
179 if( p
!= rList
.end() )
183 // shutdown drag and drop
184 Reference
< XComponent
> xDnDComponent( mpWindowImpl
->mxDNDListenerContainer
, UNO_QUERY
);
186 if( xDnDComponent
.is() )
187 xDnDComponent
->dispose();
189 if( mpWindowImpl
->mbFrame
&& mpWindowImpl
->mpFrameData
)
193 // deregister drop target listener
194 if( mpWindowImpl
->mpFrameData
->mxDropTargetListener
.is() )
196 Reference
< XDragGestureRecognizer
> xDragGestureRecognizer(mpWindowImpl
->mpFrameData
->mxDragSource
, UNO_QUERY
);
197 if( xDragGestureRecognizer
.is() )
199 xDragGestureRecognizer
->removeDragGestureListener(
200 Reference
< XDragGestureListener
> (mpWindowImpl
->mpFrameData
->mxDropTargetListener
, UNO_QUERY
));
203 mpWindowImpl
->mpFrameData
->mxDropTarget
->removeDropTargetListener( mpWindowImpl
->mpFrameData
->mxDropTargetListener
);
204 mpWindowImpl
->mpFrameData
->mxDropTargetListener
.clear();
207 // shutdown drag and drop for this frame window
208 Reference
< XComponent
> xComponent( mpWindowImpl
->mpFrameData
->mxDropTarget
, UNO_QUERY
);
210 // DNDEventDispatcher does not hold a reference of the DropTarget,
211 // so it's ok if it does not support XComponent
212 if( xComponent
.is() )
213 xComponent
->dispose();
215 catch (const Exception
&)
217 // can be safely ignored here.
221 UnoWrapperBase
* pWrapper
= UnoWrapperBase::GetUnoWrapper( false );
223 pWrapper
->WindowDestroyed( this );
225 // MT: Must be called after WindowDestroyed!
226 // Otherwise, if the accessible is a VCLXWindow, it will try to destroy this window again!
227 // But accessibility implementations from applications need this dispose.
228 if ( mpWindowImpl
->mxAccessible
.is() )
230 Reference
< XComponent
> xC( mpWindowImpl
->mxAccessible
, UNO_QUERY
);
235 ImplSVData
* pSVData
= ImplGetSVData();
237 if ( pSVData
->maHelpData
.mpHelpWin
&& (pSVData
->maHelpData
.mpHelpWin
->GetParent() == this) )
238 ImplDestroyHelpWindow( true );
240 SAL_WARN_IF( pSVData
->maWinData
.mpTrackWin
.get() == this, "vcl.window",
241 "Window::~Window(): Window is in TrackingMode" );
242 SAL_WARN_IF(IsMouseCaptured(), "vcl.window",
243 "Window::~Window(): Window has the mouse captured");
245 // due to old compatibility
246 if ( pSVData
->maWinData
.mpTrackWin
== this )
248 if (IsMouseCaptured())
251 #if OSL_DEBUG_LEVEL > 0
252 if ( true ) // always perform these tests in debug builds
254 OStringBuffer aErrorStr
;
256 vcl::Window
* pTempWin
;
258 if ( mpWindowImpl
->mpFirstChild
)
260 OStringBuffer
aTempStr("Window (");
261 aTempStr
.append(lcl_createWindowInfo(this));
262 aTempStr
.append(") with live children destroyed: ");
263 pTempWin
= mpWindowImpl
->mpFirstChild
;
266 aTempStr
.append(lcl_createWindowInfo(pTempWin
));
267 pTempWin
= pTempWin
->mpWindowImpl
->mpNext
;
269 OSL_FAIL( aTempStr
.getStr() );
270 Application::Abort(OStringToOUString(aTempStr
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
)); // abort in debug builds, this must be fixed!
273 if (mpWindowImpl
->mpFrameData
!= nullptr)
275 pTempWin
= mpWindowImpl
->mpFrameData
->mpFirstOverlap
;
278 if ( ImplIsRealParentPath( pTempWin
) )
281 aErrorStr
.append(lcl_createWindowInfo(pTempWin
));
283 pTempWin
= pTempWin
->mpWindowImpl
->mpNextOverlap
;
287 OStringBuffer aTempStr
;
288 aTempStr
.append("Window (");
289 aTempStr
.append(lcl_createWindowInfo(this));
290 aTempStr
.append(") with live SystemWindows destroyed: ");
291 aTempStr
.append(aErrorStr
.toString());
292 OSL_FAIL(aTempStr
.getStr());
293 // abort in debug builds, must be fixed!
294 Application::Abort(OStringToOUString(
295 aTempStr
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
));
300 pTempWin
= pSVData
->maWinData
.mpFirstFrame
;
303 if ( ImplIsRealParentPath( pTempWin
) )
306 aErrorStr
.append(lcl_createWindowInfo(pTempWin
));
308 pTempWin
= pTempWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
312 OStringBuffer
aTempStr( "Window (" );
313 aTempStr
.append(lcl_createWindowInfo(this));
314 aTempStr
.append(") with live SystemWindows destroyed: ");
315 aTempStr
.append(aErrorStr
.toString());
316 OSL_FAIL( aTempStr
.getStr() );
317 Application::Abort(OStringToOUString(aTempStr
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
)); // abort in debug builds, this must be fixed!
320 if ( mpWindowImpl
->mpFirstOverlap
)
322 OStringBuffer
aTempStr("Window (");
323 aTempStr
.append(lcl_createWindowInfo(this));
324 aTempStr
.append(") with live SystemWindows destroyed: ");
325 pTempWin
= mpWindowImpl
->mpFirstOverlap
;
328 aTempStr
.append(lcl_createWindowInfo(pTempWin
));
329 pTempWin
= pTempWin
->mpWindowImpl
->mpNext
;
331 OSL_FAIL( aTempStr
.getStr() );
332 Application::Abort(OStringToOUString(aTempStr
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
)); // abort in debug builds, this must be fixed!
335 vcl::Window
* pMyParent
= GetParent();
336 SystemWindow
* pMySysWin
= nullptr;
340 if ( pMyParent
->IsSystemWindow() )
342 pMySysWin
= dynamic_cast<SystemWindow
*>(pMyParent
);
344 pMyParent
= pMyParent
->GetParent();
346 if ( pMySysWin
&& pMySysWin
->ImplIsInTaskPaneList( this ) )
348 OStringBuffer
aTempStr("Window (");
349 aTempStr
.append(lcl_createWindowInfo(this));
350 aTempStr
.append(") still in TaskPanelList!");
351 OSL_FAIL( aTempStr
.getStr() );
352 Application::Abort(OStringToOUString(aTempStr
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
)); // abort in debug builds, this must be fixed!
357 if( mpWindowImpl
->mbIsInTaskPaneList
)
359 vcl::Window
* pMyParent
= GetParent();
360 SystemWindow
* pMySysWin
= nullptr;
364 if ( pMyParent
->IsSystemWindow() )
366 pMySysWin
= dynamic_cast<SystemWindow
*>(pMyParent
);
368 pMyParent
= pMyParent
->GetParent();
370 if ( pMySysWin
&& pMySysWin
->ImplIsInTaskPaneList( this ) )
372 pMySysWin
->GetTaskPaneList()->RemoveWindow( this );
376 SAL_WARN( "vcl", "Window (" << GetText() << ") not found in TaskPanelList");
380 // remove from size-group if necessary
381 remove_from_all_size_groups();
383 // clear mnemonic labels
384 std::vector
<VclPtr
<FixedText
> > aMnemonicLabels(list_mnemonic_labels());
385 for (auto const& mnemonicLabel
: aMnemonicLabels
)
387 remove_mnemonic_label(mnemonicLabel
);
390 // hide window in order to trigger the Paint-Handling
393 // EndExtTextInputMode
394 if ( pSVData
->maWinData
.mpExtTextInputWin
== this )
397 if ( pSVData
->maWinData
.mpExtTextInputWin
== this )
398 pSVData
->maWinData
.mpExtTextInputWin
= nullptr;
401 // check if the focus window is our child
402 bool bHasFocussedChild
= false;
403 if( pSVData
->maWinData
.mpFocusWin
&& ImplIsRealParentPath( pSVData
->maWinData
.mpFocusWin
) )
405 // #122232#, this must not happen and is an application bug ! but we try some cleanup to hopefully avoid crashes, see below
406 bHasFocussedChild
= true;
407 #if OSL_DEBUG_LEVEL > 0
408 OUString aTempStr
= "Window (" + GetText() +
409 ") with focused child window destroyed ! THIS WILL LEAD TO CRASHES AND MUST BE FIXED !";
410 SAL_WARN( "vcl", aTempStr
);
411 Application::Abort(aTempStr
); // abort in debug build version, this must be fixed!
415 // if we get focus pass focus to another window
416 vcl::Window
* pOverlapWindow
= ImplGetFirstOverlapWindow();
417 if ( pSVData
->maWinData
.mpFocusWin
== this
418 || bHasFocussedChild
) // #122232#, see above, try some cleanup
420 if ( mpWindowImpl
->mbFrame
)
422 pSVData
->maWinData
.mpFocusWin
= nullptr;
423 pOverlapWindow
->mpWindowImpl
->mpLastFocusWindow
= nullptr;
427 vcl::Window
* pParent
= GetParent();
428 vcl::Window
* pBorderWindow
= mpWindowImpl
->mpBorderWindow
;
429 // when windows overlap, give focus to the parent
430 // of the next FrameWindow
433 if ( pBorderWindow
->ImplIsOverlapWindow() )
434 pParent
= pBorderWindow
->mpWindowImpl
->mpOverlapWindow
;
436 else if ( ImplIsOverlapWindow() )
437 pParent
= mpWindowImpl
->mpOverlapWindow
;
439 if ( pParent
&& pParent
->IsEnabled() && pParent
->IsInputEnabled() && ! pParent
->IsInModalMode() )
440 pParent
->GrabFocus();
442 mpWindowImpl
->mpFrameWindow
->GrabFocus();
444 // If the focus was set back to 'this' set it to nothing
445 if ( pSVData
->maWinData
.mpFocusWin
== this )
447 pSVData
->maWinData
.mpFocusWin
= nullptr;
448 pOverlapWindow
->mpWindowImpl
->mpLastFocusWindow
= nullptr;
453 if ( pOverlapWindow
!= nullptr &&
454 pOverlapWindow
->mpWindowImpl
->mpLastFocusWindow
== this )
455 pOverlapWindow
->mpWindowImpl
->mpLastFocusWindow
= nullptr;
457 // reset hint for DefModalDialogParent
458 if( pSVData
->maWinData
.mpActiveApplicationFrame
== this )
459 pSVData
->maWinData
.mpActiveApplicationFrame
= nullptr;
461 // reset hint of what was the last wheeled window
462 if( pSVData
->maWinData
.mpLastWheelWindow
== this )
463 pSVData
->maWinData
.mpLastWheelWindow
= nullptr;
465 // reset marked windows
466 if ( mpWindowImpl
->mpFrameData
!= nullptr )
468 if ( mpWindowImpl
->mpFrameData
->mpFocusWin
== this )
469 mpWindowImpl
->mpFrameData
->mpFocusWin
= nullptr;
470 if ( mpWindowImpl
->mpFrameData
->mpMouseMoveWin
== this )
471 mpWindowImpl
->mpFrameData
->mpMouseMoveWin
= nullptr;
472 if ( mpWindowImpl
->mpFrameData
->mpMouseDownWin
== this )
473 mpWindowImpl
->mpFrameData
->mpMouseDownWin
= nullptr;
476 // reset Deactivate-Window
477 if ( pSVData
->maWinData
.mpLastDeacWin
== this )
478 pSVData
->maWinData
.mpLastDeacWin
= nullptr;
480 if ( mpWindowImpl
->mbFrame
&& mpWindowImpl
->mpFrameData
)
482 if ( mpWindowImpl
->mpFrameData
->mnFocusId
)
483 Application::RemoveUserEvent( mpWindowImpl
->mpFrameData
->mnFocusId
);
484 mpWindowImpl
->mpFrameData
->mnFocusId
= nullptr;
485 if ( mpWindowImpl
->mpFrameData
->mnMouseMoveId
)
486 Application::RemoveUserEvent( mpWindowImpl
->mpFrameData
->mnMouseMoveId
);
487 mpWindowImpl
->mpFrameData
->mnMouseMoveId
= nullptr;
490 // release SalGraphics
491 OutputDevice
*pOutDev
= GetOutDev();
492 pOutDev
->ReleaseGraphics();
494 // remove window from the lists
495 ImplRemoveWindow( true );
497 // de-register as "top window child" at our parent, if necessary
498 if ( mpWindowImpl
->mbFrame
)
500 bool bIsTopWindow
= mpWindowImpl
->mpWinData
&& ( mpWindowImpl
->mpWinData
->mnIsTopWindow
== 1 );
501 if ( mpWindowImpl
->mpRealParent
&& bIsTopWindow
)
503 ImplWinData
* pParentWinData
= mpWindowImpl
->mpRealParent
->ImplGetWinData();
505 auto myPos
= ::std::find( pParentWinData
->maTopWindowChildren
.begin(),
506 pParentWinData
->maTopWindowChildren
.end(), VclPtr
<vcl::Window
>(this) );
507 SAL_WARN_IF( myPos
== pParentWinData
->maTopWindowChildren
.end(), "vcl.window", "Window::~Window: inconsistency in top window chain!" );
508 if ( myPos
!= pParentWinData
->maTopWindowChildren
.end() )
509 pParentWinData
->maTopWindowChildren
.erase( myPos
);
513 delete mpWindowImpl
->mpWinData
;
514 mpWindowImpl
->mpWinData
= nullptr;
516 // remove BorderWindow or Frame window data
517 mpWindowImpl
->mpBorderWindow
.disposeAndClear();
518 if ( mpWindowImpl
->mbFrame
)
520 if ( pSVData
->maWinData
.mpFirstFrame
== this )
521 pSVData
->maWinData
.mpFirstFrame
= mpWindowImpl
->mpFrameData
->mpNextFrame
;
524 sal_Int32 nWindows
= 0;
525 vcl::Window
* pSysWin
= pSVData
->maWinData
.mpFirstFrame
;
526 while ( pSysWin
&& pSysWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
.get() != this )
528 pSysWin
= pSysWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
534 assert (mpWindowImpl
->mpFrameData
->mpNextFrame
.get() != pSysWin
);
535 pSysWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
= mpWindowImpl
->mpFrameData
->mpNextFrame
;
537 else // if it is not in the list, we can't remove it.
538 SAL_WARN("vcl.window", "Window " << this << " marked as frame window, "
539 "is missing from list of " << nWindows
<< " frames");
541 if (mpWindowImpl
->mpFrame
) // otherwise exception during init
543 mpWindowImpl
->mpFrame
->SetCallback( nullptr, nullptr );
544 pSVData
->mpDefInst
->DestroyFrame( mpWindowImpl
->mpFrame
);
546 assert (mpWindowImpl
->mpFrameData
->mnFocusId
== nullptr);
547 assert (mpWindowImpl
->mpFrameData
->mnMouseMoveId
== nullptr);
549 mpWindowImpl
->mpFrameData
->mpBuffer
.disposeAndClear();
550 delete mpWindowImpl
->mpFrameData
;
551 mpWindowImpl
->mpFrameData
= nullptr;
554 // should be the last statements
555 mpWindowImpl
.reset();
557 OutputDevice::dispose();
565 // We will eventually being removing the inheritance of OutputDevice
566 // from Window. It will be replaced with a transient relationship such
567 // that the OutputDevice is only live for the scope of the Paint method.
568 // In the meantime this can help move us towards a Window use an
569 // OutputDevice, not being one.
571 ::OutputDevice
const* Window::GetOutDev() const
576 ::OutputDevice
* Window::GetOutDev()
581 Color
Window::GetBackgroundColor() const
583 return GetDisplayBackground().GetColor();
586 } /* namespace vcl */
588 WindowImpl::WindowImpl( WindowType nType
)
590 maZoom
= Fraction( 1, 1 );
591 maWinRegion
= vcl::Region(true);
592 maWinClipRegion
= vcl::Region(true);
593 mpWinData
= nullptr; // Extra Window Data, that we don't need for all windows
594 mpFrameData
= nullptr; // Frame Data
595 mpFrame
= nullptr; // Pointer to frame window
597 mpFrameWindow
= nullptr; // window to top level parent (same as frame window)
598 mpOverlapWindow
= nullptr; // first overlap parent
599 mpBorderWindow
= nullptr; // Border-Window
600 mpClientWindow
= nullptr; // Client-Window of a FrameWindow
601 mpParent
= nullptr; // parent (incl. BorderWindow)
602 mpRealParent
= nullptr; // real parent (excl. BorderWindow)
603 mpFirstChild
= nullptr; // first child window
604 mpLastChild
= nullptr; // last child window
605 mpFirstOverlap
= nullptr; // first overlap window (only set in overlap windows)
606 mpLastOverlap
= nullptr; // last overlap window (only set in overlap windows)
607 mpPrev
= nullptr; // prev window
608 mpNext
= nullptr; // next window
609 mpNextOverlap
= nullptr; // next overlap window of frame
610 mpLastFocusWindow
= nullptr; // window for focus restore
611 mpDlgCtrlDownWindow
= nullptr; // window for dialog control
612 mnEventListenersIteratingCount
= 0;
613 mnChildEventListenersIteratingCount
= 0;
614 mpCursor
= nullptr; // cursor
615 maPointer
= PointerStyle::Arrow
;
616 mpVCLXWindow
= nullptr;
617 mpAccessibleInfos
= nullptr;
618 maControlForeground
= COL_TRANSPARENT
; // no foreground set
619 maControlBackground
= COL_TRANSPARENT
; // no background set
620 mnLeftBorder
= 0; // left border
621 mnTopBorder
= 0; // top border
622 mnRightBorder
= 0; // right border
623 mnBottomBorder
= 0; // bottom border
624 mnWidthRequest
= -1; // width request
625 mnHeightRequest
= -1; // height request
626 mnOptimalWidthCache
= -1; // optimal width cache
627 mnOptimalHeightCache
= -1; // optimal height cache
628 mnX
= 0; // X-Position to Parent
629 mnY
= 0; // Y-Position to Parent
630 mnAbsScreenX
= 0; // absolute X-position on screen, used for RTL window positioning
631 mpChildClipRegion
= nullptr; // Child-Clip-Region when ClipChildren
632 mpPaintRegion
= nullptr; // Paint-ClipRegion
633 mnStyle
= 0; // style (init in ImplInitWindow)
634 mnPrevStyle
= 0; // prevstyle (set in SetStyle)
635 mnExtendedStyle
= WindowExtendedStyle::NONE
; // extended style (init in ImplInitWindow)
636 mnType
= nType
; // type
637 mnGetFocusFlags
= GetFocusFlags::NONE
; // Flags for GetFocus()-Call
638 mnWaitCount
= 0; // Wait-Count (>1 == "wait" mouse pointer)
639 mnPaintFlags
= ImplPaintFlags::NONE
; // Flags for ImplCallPaint
640 mnParentClipMode
= ParentClipMode::NONE
; // Flags for Parent-ClipChildren-Mode
641 mnActivateMode
= ActivateModeFlags::NONE
; // Will be converted in System/Overlap-Windows
642 mnDlgCtrlFlags
= DialogControlFlags::NONE
; // DialogControl-Flags
643 meAlwaysInputMode
= AlwaysInputNone
; // neither AlwaysEnableInput nor AlwaysDisableInput called
644 meHalign
= VclAlign::Fill
;
645 meValign
= VclAlign::Fill
;
646 mePackType
= VclPackType::Start
;
649 mnGridLeftAttach
= -1;
650 mnGridTopAttach
= -1;
657 mbFrame
= false; // true: Window is a frame window
658 mbBorderWin
= false; // true: Window is a border window
659 mbOverlapWin
= false; // true: Window is an overlap window
660 mbSysWin
= false; // true: SystemWindow is the base class
661 mbDialog
= false; // true: Dialog is the base class
662 mbDockWin
= false; // true: DockingWindow is the base class
663 mbFloatWin
= false; // true: FloatingWindow is the base class
664 mbPushButton
= false; // true: PushButton is the base class
665 mbToolBox
= false; // true: ToolBox is the base class
666 mbMenuFloatingWindow
= false; // true: MenuFloatingWindow is the base class
667 mbToolbarFloatingWindow
= false; // true: ImplPopupFloatWin is the base class, used for subtoolbars
668 mbSplitter
= false; // true: Splitter is the base class
669 mbVisible
= false; // true: Show( true ) called
670 mbOverlapVisible
= false; // true: Hide called for visible window from ImplHideAllOverlapWindow()
671 mbDisabled
= false; // true: Enable( false ) called
672 mbInputDisabled
= false; // true: EnableInput( false ) called
673 mbNoUpdate
= false; // true: SetUpdateMode( false ) called
674 mbNoParentUpdate
= false; // true: SetParentUpdateMode( false ) called
675 mbActive
= false; // true: Window Active
676 mbReallyVisible
= false; // true: this and all parents to an overlapped window are visible
677 mbReallyShown
= false; // true: this and all parents to an overlapped window are shown
678 mbInInitShow
= false; // true: we are in InitShow
679 mbChildPtrOverwrite
= false; // true: PointerStyle overwrites Child-Pointer
680 mbNoPtrVisible
= false; // true: ShowPointer( false ) called
681 mbPaintFrame
= false; // true: Paint is visible, but not painted
682 mbInPaint
= false; // true: Inside PaintHdl
683 mbMouseButtonDown
= false; // true: BaseMouseButtonDown called
684 mbMouseButtonUp
= false; // true: BaseMouseButtonUp called
685 mbKeyInput
= false; // true: BaseKeyInput called
686 mbKeyUp
= false; // true: BaseKeyUp called
687 mbCommand
= false; // true: BaseCommand called
688 mbDefPos
= true; // true: Position is not Set
689 mbDefSize
= true; // true: Size is not Set
690 mbCallMove
= true; // true: Move must be called by Show
691 mbCallResize
= true; // true: Resize must be called by Show
692 mbWaitSystemResize
= true; // true: Wait for System-Resize
693 mbInitWinClipRegion
= true; // true: Calc Window Clip Region
694 mbInitChildRegion
= false; // true: InitChildClipRegion
695 mbWinRegion
= false; // true: Window Region
696 mbClipChildren
= false; // true: Child-window should be clipped
697 mbClipSiblings
= false; // true: Adjacent Child-window should be clipped
698 mbChildTransparent
= false; // true: Child-windows are allowed to switch to transparent (incl. Parent-CLIPCHILDREN)
699 mbPaintTransparent
= false; // true: Paints should be executed on the Parent
700 mbMouseTransparent
= false; // true: Window is transparent for Mouse
701 mbDlgCtrlStart
= false; // true: From here on own Dialog-Control
702 mbFocusVisible
= false; // true: Focus Visible
703 mbUseNativeFocus
= false;
704 mbNativeFocusVisible
= false; // true: native Focus Visible
705 mbInShowFocus
= false; // prevent recursion
706 mbInHideFocus
= false; // prevent recursion
707 mbTrackVisible
= false; // true: Tracking Visible
708 mbControlForeground
= false; // true: Foreground-Property set
709 mbControlBackground
= false; // true: Background-Property set
710 mbAlwaysOnTop
= false; // true: always visible for all others windows
711 mbCompoundControl
= false; // true: Composite Control => Listener...
712 mbCompoundControlHasFocus
= false; // true: Composite Control has focus somewhere
713 mbPaintDisabled
= false; // true: Paint should not be executed
714 mbAllResize
= false; // true: Also sent ResizeEvents with 0,0
715 mbInDispose
= false; // true: We're still in Window::dispose()
716 mbExtTextInput
= false; // true: ExtTextInput-Mode is active
717 mbInFocusHdl
= false; // true: Within GetFocus-Handler
718 mbCreatedWithToolkit
= false;
719 mbSuppressAccessibilityEvents
= false; // true: do not send any accessibility events
720 mbDrawSelectionBackground
= false; // true: draws transparent window background to indicate (toolbox) selection
721 mbIsInTaskPaneList
= false; // true: window was added to the taskpanelist in the topmost system window
722 mnNativeBackground
= ControlPart::NONE
; // initialize later, depends on type
723 mbCallHandlersDuringInputDisabled
= false; // true: call event handlers even if input is disabled
724 mbHelpTextDynamic
= false; // true: append help id in HELP_DEBUG case
725 mbFakeFocusSet
= false; // true: pretend as if the window has focus.
731 mbNonHomogeneous
= false;
732 static bool bDoubleBuffer
= getenv("VCL_DOUBLEBUFFERING_FORCE_ENABLE");
733 mbDoubleBufferingRequested
= bDoubleBuffer
; // when we are not sure, assume it cannot do double-buffering via RenderContext
734 mpLOKNotifier
= nullptr;
736 mbLOKParentNotifier
= false;
739 WindowImpl::~WindowImpl()
741 mpChildClipRegion
.reset();
742 mpAccessibleInfos
.reset();
745 ImplWinData::ImplWinData() :
748 mnCompositionCharRects(0),
749 mnTrackFlags(ShowTrackFlags::NONE
),
750 mnIsTopWindow(sal_uInt16(~0)), // not initialized yet, 0/1 will indicate TopWindow (see IsTopWindow())
752 mbEnableNativeWidget(false)
756 ImplWinData::~ImplWinData()
758 mpCompositionCharRects
.reset();
761 ImplFrameData::ImplFrameData( vcl::Window
*pWindow
)
763 ImplSVData
* pSVData
= ImplGetSVData();
764 assert (pSVData
->maWinData
.mpFirstFrame
.get() != pWindow
);
765 mpNextFrame
= pSVData
->maWinData
.mpFirstFrame
;
766 pSVData
->maWinData
.mpFirstFrame
= pWindow
;
767 mpFirstOverlap
= nullptr;
768 mpFocusWin
= nullptr;
769 mpMouseMoveWin
= nullptr;
770 mpMouseDownWin
= nullptr;
771 mxFontCollection
= pSVData
->maGDIData
.mxScreenFontList
;
772 mxFontCache
= pSVData
->maGDIData
.mxScreenFontCache
;
774 mnMouseMoveId
= nullptr;
777 mnBeforeLastMouseX
= -1;
778 mnBeforeLastMouseY
= -1;
781 mnLastMouseWinX
= -1;
782 mnLastMouseWinY
= -1;
786 mnFirstMouseCode
= 0;
788 mnMouseMode
= MouseEventModifiers::NONE
;
790 mbInMouseMove
= false;
792 mbStartDragCalled
= false;
793 mbNeedSysWindow
= false;
795 mbStartFocusState
= false;
796 mbInSysObjFocusHdl
= false;
797 mbInSysObjToTopHdl
= false;
798 mbSysObjFocus
= false;
799 maPaintIdle
.SetPriority( TaskPriority::REPAINT
);
800 maPaintIdle
.SetInvokeHandler( LINK( pWindow
, vcl::Window
, ImplHandlePaintHdl
) );
801 maPaintIdle
.SetDebugName( "vcl::Window maPaintIdle" );
802 maResizeIdle
.SetPriority( TaskPriority::RESIZE
);
803 maResizeIdle
.SetInvokeHandler( LINK( pWindow
, vcl::Window
, ImplHandleResizeTimerHdl
) );
804 maResizeIdle
.SetDebugName( "vcl::Window maResizeIdle" );
805 mbInternalDragGestureRecognizer
= false;
806 mbInBufferedPaint
= false;
809 mnTouchPanPosition
= -1;
814 bool Window::AcquireGraphics() const
816 DBG_TESTSOLARMUTEX();
821 mbInitLineColor
= true;
822 mbInitFillColor
= true;
824 mbInitTextColor
= true;
825 mbInitClipRegion
= true;
827 ImplSVData
* pSVData
= ImplGetSVData();
829 mpGraphics
= mpWindowImpl
->mpFrame
->AcquireGraphics();
830 // try harder if no wingraphics was available directly
833 // find another output device in the same frame
834 OutputDevice
* pReleaseOutDev
= pSVData
->maGDIData
.mpLastWinGraphics
;
835 while ( pReleaseOutDev
)
837 if ( static_cast<vcl::Window
*>(pReleaseOutDev
)->mpWindowImpl
->mpFrame
== mpWindowImpl
->mpFrame
)
839 pReleaseOutDev
= pReleaseOutDev
->mpPrevGraphics
;
842 if ( pReleaseOutDev
)
844 // steal the wingraphics from the other outdev
845 mpGraphics
= pReleaseOutDev
->mpGraphics
;
846 pReleaseOutDev
->ReleaseGraphics( false );
850 // if needed retry after releasing least recently used wingraphics
851 while ( !mpGraphics
)
853 if ( !pSVData
->maGDIData
.mpLastWinGraphics
)
855 pSVData
->maGDIData
.mpLastWinGraphics
->ReleaseGraphics();
856 mpGraphics
= mpWindowImpl
->mpFrame
->AcquireGraphics();
863 // update global LRU list of wingraphics
864 mpNextGraphics
= pSVData
->maGDIData
.mpFirstWinGraphics
;
865 pSVData
->maGDIData
.mpFirstWinGraphics
= const_cast<vcl::Window
*>(this);
866 if ( mpNextGraphics
)
867 mpNextGraphics
->mpPrevGraphics
= const_cast<vcl::Window
*>(this);
868 if ( !pSVData
->maGDIData
.mpLastWinGraphics
)
869 pSVData
->maGDIData
.mpLastWinGraphics
= const_cast<vcl::Window
*>(this);
871 mpGraphics
->SetXORMode( (RasterOp::Invert
== meRasterOp
) || (RasterOp::Xor
== meRasterOp
), RasterOp::Invert
== meRasterOp
);
872 mpGraphics
->setAntiAliasB2DDraw(bool(mnAntialiasing
& AntialiasingFlags::EnableB2dDraw
));
875 return mpGraphics
!= nullptr;
878 void Window::ReleaseGraphics( bool bRelease
)
880 DBG_TESTSOLARMUTEX();
885 // release the fonts of the physically released graphics device
889 ImplSVData
* pSVData
= ImplGetSVData();
891 vcl::Window
* pWindow
= this;
894 pWindow
->mpWindowImpl
->mpFrame
->ReleaseGraphics( mpGraphics
);
895 // remove from global LRU list of window graphics
896 if ( mpPrevGraphics
)
897 mpPrevGraphics
->mpNextGraphics
= mpNextGraphics
;
899 pSVData
->maGDIData
.mpFirstWinGraphics
= mpNextGraphics
;
900 if ( mpNextGraphics
)
901 mpNextGraphics
->mpPrevGraphics
= mpPrevGraphics
;
903 pSVData
->maGDIData
.mpLastWinGraphics
= mpPrevGraphics
;
905 mpGraphics
= nullptr;
906 mpPrevGraphics
= nullptr;
907 mpNextGraphics
= nullptr;
910 static sal_Int32
CountDPIScaleFactor(sal_Int32 nDPI
)
913 // Setting of HiDPI is unfortunately all only a heuristic; and to add
914 // insult to an injury, the system is constantly lying to us about
915 // the DPI and whatnot
916 // eg. fdo#77059 - set the value from which we do consider the
917 // screen HiDPI to greater than 168
918 if (nDPI
> 216) // 96 * 2 + 96 / 4
920 else if (nDPI
> 168) // 96 * 2 - 96 / 4
922 else if (nDPI
> 120) // 96 * 1.5 - 96 / 4
931 void Window::ImplInit( vcl::Window
* pParent
, WinBits nStyle
, SystemParentData
* pSystemParentData
)
933 SAL_WARN_IF( !mpWindowImpl
->mbFrame
&& !pParent
&& GetType() != WindowType::FIXEDIMAGE
, "vcl.window",
934 "Window::Window(): pParent == NULL" );
936 ImplSVData
* pSVData
= ImplGetSVData();
937 vcl::Window
* pRealParent
= pParent
;
940 if ( !mpWindowImpl
->mbOverlapWin
&& pParent
&& (pParent
->GetStyle() & WB_3DLOOK
) )
943 // create border window if necessary
944 if ( !mpWindowImpl
->mbFrame
&& !mpWindowImpl
->mbBorderWin
&& !mpWindowImpl
->mpBorderWindow
945 && (nStyle
& (WB_BORDER
| WB_SYSTEMCHILDWINDOW
) ) )
947 BorderWindowStyle nBorderTypeStyle
= BorderWindowStyle::NONE
;
948 if( nStyle
& WB_SYSTEMCHILDWINDOW
)
950 // handle WB_SYSTEMCHILDWINDOW
951 // these should be analogous to a top level frame; meaning they
952 // should have a border window with style BorderWindowStyle::Frame
953 // which controls their size
954 nBorderTypeStyle
|= BorderWindowStyle::Frame
;
957 VclPtrInstance
<ImplBorderWindow
> pBorderWin( pParent
, nStyle
& (WB_BORDER
| WB_DIALOGCONTROL
| WB_NODIALOGCONTROL
), nBorderTypeStyle
);
958 static_cast<vcl::Window
*>(pBorderWin
)->mpWindowImpl
->mpClientWindow
= this;
959 pBorderWin
->GetBorder( mpWindowImpl
->mnLeftBorder
, mpWindowImpl
->mnTopBorder
, mpWindowImpl
->mnRightBorder
, mpWindowImpl
->mnBottomBorder
);
960 mpWindowImpl
->mpBorderWindow
= pBorderWin
;
961 pParent
= mpWindowImpl
->mpBorderWindow
;
963 else if( !mpWindowImpl
->mbFrame
&& ! pParent
)
965 mpWindowImpl
->mbOverlapWin
= true;
966 mpWindowImpl
->mbFrame
= true;
969 // insert window in list
970 ImplInsertWindow( pParent
);
971 mpWindowImpl
->mnStyle
= nStyle
;
973 if( pParent
&& ! mpWindowImpl
->mbFrame
)
974 mbEnableRTL
= AllSettings::GetLayoutRTL();
976 // test for frame creation
977 if ( mpWindowImpl
->mbFrame
)
980 SalFrameStyleFlags nFrameStyle
= SalFrameStyleFlags::NONE
;
982 if ( nStyle
& WB_MOVEABLE
)
983 nFrameStyle
|= SalFrameStyleFlags::MOVEABLE
;
984 if ( nStyle
& WB_SIZEABLE
)
985 nFrameStyle
|= SalFrameStyleFlags::SIZEABLE
;
986 if ( nStyle
& WB_CLOSEABLE
)
987 nFrameStyle
|= SalFrameStyleFlags::CLOSEABLE
;
988 if ( nStyle
& WB_APP
)
989 nFrameStyle
|= SalFrameStyleFlags::DEFAULT
;
990 // check for undecorated floating window
991 if( // 1. floating windows that are not moveable/sizeable (only closeable allowed)
992 ( !(nFrameStyle
& ~SalFrameStyleFlags::CLOSEABLE
) &&
993 ( mpWindowImpl
->mbFloatWin
|| ((GetType() == WindowType::BORDERWINDOW
) && static_cast<ImplBorderWindow
*>(this)->mbFloatWindow
) || (nStyle
& WB_SYSTEMFLOATWIN
) ) ) ||
994 // 2. borderwindows of floaters with ownerdraw decoration
995 ((GetType() == WindowType::BORDERWINDOW
) && static_cast<ImplBorderWindow
*>(this)->mbFloatWindow
&& (nStyle
& WB_OWNERDRAWDECORATION
) ) )
997 nFrameStyle
= SalFrameStyleFlags::FLOAT
;
998 if( nStyle
& WB_OWNERDRAWDECORATION
)
999 nFrameStyle
|= SalFrameStyleFlags::OWNERDRAWDECORATION
| SalFrameStyleFlags::NOSHADOW
;
1001 else if( mpWindowImpl
->mbFloatWin
)
1002 nFrameStyle
|= SalFrameStyleFlags::TOOLWINDOW
;
1004 if( nStyle
& WB_INTROWIN
)
1005 nFrameStyle
|= SalFrameStyleFlags::INTRO
;
1006 if( nStyle
& WB_TOOLTIPWIN
)
1007 nFrameStyle
|= SalFrameStyleFlags::TOOLTIP
;
1009 if( nStyle
& WB_NOSHADOW
)
1010 nFrameStyle
|= SalFrameStyleFlags::NOSHADOW
;
1012 if( nStyle
& WB_SYSTEMCHILDWINDOW
)
1013 nFrameStyle
|= SalFrameStyleFlags::SYSTEMCHILD
;
1015 switch (mpWindowImpl
->mnType
)
1017 case WindowType::DIALOG
:
1018 case WindowType::TABDIALOG
:
1019 case WindowType::MODALDIALOG
:
1020 case WindowType::MODELESSDIALOG
:
1021 case WindowType::MESSBOX
:
1022 case WindowType::INFOBOX
:
1023 case WindowType::WARNINGBOX
:
1024 case WindowType::ERRORBOX
:
1025 case WindowType::QUERYBOX
:
1026 nFrameStyle
|= SalFrameStyleFlags::DIALOG
;
1032 SalFrame
* pParentFrame
= nullptr;
1034 pParentFrame
= pParent
->mpWindowImpl
->mpFrame
;
1036 if ( pSystemParentData
)
1037 pFrame
= pSVData
->mpDefInst
->CreateChildFrame( pSystemParentData
, nFrameStyle
| SalFrameStyleFlags::PLUG
);
1039 pFrame
= pSVData
->mpDefInst
->CreateFrame( pParentFrame
, nFrameStyle
);
1042 // do not abort but throw an exception, may be the current thread terminates anyway (plugin-scenario)
1043 throw RuntimeException(
1044 "Could not create system window!",
1045 Reference
< XInterface
>() );
1048 pFrame
->SetCallback( this, ImplWindowFrameProc
);
1050 // set window frame data
1051 mpWindowImpl
->mpFrameData
= new ImplFrameData( this );
1052 mpWindowImpl
->mpFrame
= pFrame
;
1053 mpWindowImpl
->mpFrameWindow
= this;
1054 mpWindowImpl
->mpOverlapWindow
= this;
1056 if (!(nStyle
& WB_DEFAULTWIN
) && mpWindowImpl
->mbDoubleBufferingRequested
)
1057 RequestDoubleBuffering(true);
1059 if ( pRealParent
&& IsTopWindow() )
1061 ImplWinData
* pParentWinData
= pRealParent
->ImplGetWinData();
1062 pParentWinData
->maTopWindowChildren
.emplace_back(this );
1067 mpWindowImpl
->mpRealParent
= pRealParent
;
1069 // #99318: make sure fontcache and list is available before call to SetSettings
1070 mxFontCollection
= mpWindowImpl
->mpFrameData
->mxFontCollection
;
1071 mxFontCache
= mpWindowImpl
->mpFrameData
->mxFontCache
;
1073 if ( mpWindowImpl
->mbFrame
)
1077 mpWindowImpl
->mpFrameData
->mnDPIX
= pParent
->mpWindowImpl
->mpFrameData
->mnDPIX
;
1078 mpWindowImpl
->mpFrameData
->mnDPIY
= pParent
->mpWindowImpl
->mpFrameData
->mnDPIY
;
1082 OutputDevice
*pOutDev
= GetOutDev();
1083 if ( pOutDev
->AcquireGraphics() )
1085 mpGraphics
->GetResolution( mpWindowImpl
->mpFrameData
->mnDPIX
, mpWindowImpl
->mpFrameData
->mnDPIY
);
1089 // add ownerdraw decorated frame windows to list in the top-most frame window
1090 // so they can be hidden on lose focus
1091 if( nStyle
& WB_OWNERDRAWDECORATION
)
1092 ImplGetOwnerDrawList().emplace_back(this );
1094 // delay settings initialization until first "real" frame
1095 // this relies on the IntroWindow not needing any system settings
1096 if ( !pSVData
->maAppData
.mbSettingsInit
&&
1097 ! (nStyle
& (WB_INTROWIN
|WB_DEFAULTWIN
))
1100 // side effect: ImplUpdateGlobalSettings does an ImplGetFrame()->UpdateSettings
1101 ImplUpdateGlobalSettings( *pSVData
->maAppData
.mpSettings
);
1102 OutputDevice::SetSettings( *pSVData
->maAppData
.mpSettings
);
1103 pSVData
->maAppData
.mbSettingsInit
= true;
1106 // If we create a Window with default size, query this
1107 // size directly, because we want resize all Controls to
1108 // the correct size before we display the window
1109 if ( nStyle
& (WB_MOVEABLE
| WB_SIZEABLE
| WB_APP
) )
1110 mpWindowImpl
->mpFrame
->GetClientSize( mnOutWidth
, mnOutHeight
);
1116 if ( !ImplIsOverlapWindow() )
1118 mpWindowImpl
->mbDisabled
= pParent
->mpWindowImpl
->mbDisabled
;
1119 mpWindowImpl
->mbInputDisabled
= pParent
->mpWindowImpl
->mbInputDisabled
;
1120 mpWindowImpl
->meAlwaysInputMode
= pParent
->mpWindowImpl
->meAlwaysInputMode
;
1123 if (!utl::ConfigManager::IsFuzzing())
1124 OutputDevice::SetSettings( pParent
->GetSettings() );
1129 // setup the scale factor for HiDPI displays
1130 mnDPIScalePercentage
= CountDPIScaleFactor(mpWindowImpl
->mpFrameData
->mnDPIY
);
1131 mnDPIX
= mpWindowImpl
->mpFrameData
->mnDPIX
;
1132 mnDPIY
= mpWindowImpl
->mpFrameData
->mnDPIY
;
1134 if (!utl::ConfigManager::IsFuzzing())
1136 const StyleSettings
& rStyleSettings
= mxSettings
->GetStyleSettings();
1137 maFont
= rStyleSettings
.GetAppFont();
1139 if ( nStyle
& WB_3DLOOK
)
1141 SetTextColor( rStyleSettings
.GetButtonTextColor() );
1142 SetBackground( Wallpaper( rStyleSettings
.GetFaceColor() ) );
1146 SetTextColor( rStyleSettings
.GetWindowTextColor() );
1147 SetBackground( Wallpaper( rStyleSettings
.GetWindowColor() ) );
1152 maFont
= GetDefaultFont( DefaultFontType::FIXED
, LANGUAGE_ENGLISH_US
, GetDefaultFontFlags::NONE
);
1155 ImplPointToLogic(*this, maFont
);
1157 (void)ImplUpdatePos();
1159 // calculate app font res (except for the Intro Window or the default window)
1160 if ( mpWindowImpl
->mbFrame
&& !pSVData
->maGDIData
.mnAppFontX
&& ! (nStyle
& (WB_INTROWIN
|WB_DEFAULTWIN
)) )
1161 ImplInitAppFontData( this );
1164 void Window::ImplInitAppFontData( vcl::Window
const * pWindow
)
1166 ImplSVData
* pSVData
= ImplGetSVData();
1167 long nTextHeight
= pWindow
->GetTextHeight();
1168 long nTextWidth
= pWindow
->approximate_char_width() * 8;
1169 long nSymHeight
= nTextHeight
*4;
1170 // Make the basis wider if the font is too narrow
1171 // such that the dialog looks symmetrical and does not become too narrow.
1172 // Add some extra space when the dialog has the same width,
1173 // as a little more space is better.
1174 if ( nSymHeight
> nTextWidth
)
1175 nTextWidth
= nSymHeight
;
1176 else if ( nSymHeight
+5 > nTextWidth
)
1177 nTextWidth
= nSymHeight
+5;
1178 pSVData
->maGDIData
.mnAppFontX
= nTextWidth
* 10 / 8;
1179 pSVData
->maGDIData
.mnAppFontY
= nTextHeight
* 10;
1182 // FIXME: this is currently only on macOS, check with other
1184 if( pSVData
->maNWFData
.mbNoFocusRects
)
1186 // try to find out whether there is a large correction
1187 // of control sizes, if yes, make app font scalings larger
1188 // so dialog positioning is not completely off
1189 ImplControlValue aControlValue
;
1190 tools::Rectangle
aCtrlRegion( Point(), Size( nTextWidth
< 10 ? 10 : nTextWidth
, nTextHeight
< 10 ? 10 : nTextHeight
) );
1191 tools::Rectangle
aBoundingRgn( aCtrlRegion
);
1192 tools::Rectangle
aContentRgn( aCtrlRegion
);
1193 if( pWindow
->GetNativeControlRegion( ControlType::Editbox
, ControlPart::Entire
, aCtrlRegion
,
1194 ControlState::ENABLED
, aControlValue
,
1195 aBoundingRgn
, aContentRgn
) )
1197 // comment: the magical +6 is for the extra border in bordered
1198 // (which is the standard) edit fields
1199 if( aContentRgn
.GetHeight() - nTextHeight
> (nTextHeight
+4)/4 )
1200 pSVData
->maGDIData
.mnAppFontY
= (aContentRgn
.GetHeight()-4) * 10;
1206 ImplWinData
* Window::ImplGetWinData() const
1208 if ( !mpWindowImpl
->mpWinData
)
1210 static const char* pNoNWF
= getenv( "SAL_NO_NWF" );
1212 const_cast<vcl::Window
*>(this)->mpWindowImpl
->mpWinData
= new ImplWinData
;
1213 mpWindowImpl
->mpWinData
->mbEnableNativeWidget
= !(pNoNWF
&& *pNoNWF
); // true: try to draw this control with native theme API
1216 return mpWindowImpl
->mpWinData
;
1220 void Window::CopyDeviceArea( SalTwoRect
& aPosAry
, bool bWindowInvalidate
)
1222 if (aPosAry
.mnSrcWidth
== 0 || aPosAry
.mnSrcHeight
== 0 || aPosAry
.mnDestWidth
== 0 || aPosAry
.mnDestHeight
== 0)
1225 if (bWindowInvalidate
)
1227 const tools::Rectangle
aSrcRect(Point(aPosAry
.mnSrcX
, aPosAry
.mnSrcY
),
1228 Size(aPosAry
.mnSrcWidth
, aPosAry
.mnSrcHeight
));
1230 ImplMoveAllInvalidateRegions(aSrcRect
,
1231 aPosAry
.mnDestX
-aPosAry
.mnSrcX
,
1232 aPosAry
.mnDestY
-aPosAry
.mnSrcY
,
1235 mpGraphics
->CopyArea(aPosAry
.mnDestX
, aPosAry
.mnDestY
,
1236 aPosAry
.mnSrcX
, aPosAry
.mnSrcY
,
1237 aPosAry
.mnSrcWidth
, aPosAry
.mnSrcHeight
,
1243 OutputDevice::CopyDeviceArea(aPosAry
, bWindowInvalidate
);
1246 SalGraphics
* Window::ImplGetFrameGraphics() const
1248 if ( mpWindowImpl
->mpFrameWindow
->mpGraphics
)
1250 mpWindowImpl
->mpFrameWindow
->mbInitClipRegion
= true;
1254 OutputDevice
* pFrameWinOutDev
= mpWindowImpl
->mpFrameWindow
;
1255 if ( ! pFrameWinOutDev
->AcquireGraphics() )
1260 mpWindowImpl
->mpFrameWindow
->mpGraphics
->ResetClipRegion();
1261 return mpWindowImpl
->mpFrameWindow
->mpGraphics
;
1264 void Window::ImplSetReallyVisible()
1266 // #i43594# it is possible that INITSHOW was never send, because the visibility state changed between
1267 // ImplCallInitShow() and ImplSetReallyVisible() when called from Show()
1268 // mbReallyShown is a useful indicator
1269 if( !mpWindowImpl
->mbReallyShown
)
1272 bool bBecameReallyVisible
= !mpWindowImpl
->mbReallyVisible
;
1275 mpWindowImpl
->mbReallyVisible
= true;
1276 mpWindowImpl
->mbReallyShown
= true;
1278 // the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge.
1279 // For this, the data member of the event must not be NULL.
1280 // Previously, we did this in Window::Show, but there some events got lost in certain situations. Now
1281 // we're doing it when the visibility really changes
1282 if( bBecameReallyVisible
&& ImplIsAccessibleCandidate() )
1283 CallEventListeners( VclEventId::WindowShow
, this );
1284 // TODO. It's kind of a hack that we're re-using the VclEventId::WindowShow. Normally, we should
1285 // introduce another event which explicitly triggers the Accessibility implementations.
1287 vcl::Window
* pWindow
= mpWindowImpl
->mpFirstOverlap
;
1290 if ( pWindow
->mpWindowImpl
->mbVisible
)
1291 pWindow
->ImplSetReallyVisible();
1292 pWindow
= pWindow
->mpWindowImpl
->mpNext
;
1295 pWindow
= mpWindowImpl
->mpFirstChild
;
1298 if ( pWindow
->mpWindowImpl
->mbVisible
)
1299 pWindow
->ImplSetReallyVisible();
1300 pWindow
= pWindow
->mpWindowImpl
->mpNext
;
1304 void Window::ImplInitResolutionSettings()
1306 // recalculate AppFont-resolution and DPI-resolution
1307 if (mpWindowImpl
->mbFrame
)
1309 mnDPIX
= mpWindowImpl
->mpFrameData
->mnDPIX
;
1310 mnDPIY
= mpWindowImpl
->mpFrameData
->mnDPIY
;
1312 // setup the scale factor for HiDPI displays
1313 mnDPIScalePercentage
= CountDPIScaleFactor(mpWindowImpl
->mpFrameData
->mnDPIY
);
1314 const StyleSettings
& rStyleSettings
= mxSettings
->GetStyleSettings();
1315 SetPointFont(*this, rStyleSettings
.GetAppFont());
1317 else if ( mpWindowImpl
->mpParent
)
1319 mnDPIX
= mpWindowImpl
->mpParent
->mnDPIX
;
1320 mnDPIY
= mpWindowImpl
->mpParent
->mnDPIY
;
1321 mnDPIScalePercentage
= mpWindowImpl
->mpParent
->mnDPIScalePercentage
;
1324 // update the recalculated values for logical units
1325 // and also tools belonging to the values
1326 if (IsMapModeEnabled())
1328 MapMode aMapMode
= GetMapMode();
1330 SetMapMode( aMapMode
);
1334 void Window::ImplPointToLogic(vcl::RenderContext
const & rRenderContext
, vcl::Font
& rFont
) const
1336 Size aSize
= rFont
.GetFontSize();
1340 aSize
.setWidth( aSize
.Width() * ( mpWindowImpl
->mpFrameData
->mnDPIX
) );
1341 aSize
.AdjustWidth(72 / 2 );
1342 aSize
.setWidth( aSize
.Width() / 72 );
1344 aSize
.setHeight( aSize
.Height() * ( mpWindowImpl
->mpFrameData
->mnDPIY
) );
1345 aSize
.AdjustHeight(72/2 );
1346 aSize
.setHeight( aSize
.Height() / 72 );
1348 if (rRenderContext
.IsMapModeEnabled())
1349 aSize
= rRenderContext
.PixelToLogic(aSize
);
1351 rFont
.SetFontSize(aSize
);
1354 void Window::ImplLogicToPoint(vcl::RenderContext
const & rRenderContext
, vcl::Font
& rFont
) const
1356 Size aSize
= rFont
.GetFontSize();
1358 if (rRenderContext
.IsMapModeEnabled())
1359 aSize
= rRenderContext
.LogicToPixel(aSize
);
1363 aSize
.setWidth( aSize
.Width() * 72 );
1364 aSize
.AdjustWidth(mpWindowImpl
->mpFrameData
->mnDPIX
/ 2 );
1365 aSize
.setWidth( aSize
.Width() / ( mpWindowImpl
->mpFrameData
->mnDPIX
) );
1367 aSize
.setHeight( aSize
.Height() * 72 );
1368 aSize
.AdjustHeight(mpWindowImpl
->mpFrameData
->mnDPIY
/ 2 );
1369 aSize
.setHeight( aSize
.Height() / ( mpWindowImpl
->mpFrameData
->mnDPIY
) );
1371 rFont
.SetFontSize(aSize
);
1374 bool Window::ImplUpdatePos()
1376 bool bSysChild
= false;
1378 if ( ImplIsOverlapWindow() )
1380 mnOutOffX
= mpWindowImpl
->mnX
;
1381 mnOutOffY
= mpWindowImpl
->mnY
;
1385 vcl::Window
* pParent
= ImplGetParent();
1387 mnOutOffX
= mpWindowImpl
->mnX
+ pParent
->mnOutOffX
;
1388 mnOutOffY
= mpWindowImpl
->mnY
+ pParent
->mnOutOffY
;
1391 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
1394 if ( pChild
->ImplUpdatePos() )
1396 pChild
= pChild
->mpWindowImpl
->mpNext
;
1399 if ( mpWindowImpl
->mpSysObj
)
1405 void Window::ImplUpdateSysObjPos()
1407 if ( mpWindowImpl
->mpSysObj
)
1408 mpWindowImpl
->mpSysObj
->SetPosSize( mnOutOffX
, mnOutOffY
, mnOutWidth
, mnOutHeight
);
1410 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
1413 pChild
->ImplUpdateSysObjPos();
1414 pChild
= pChild
->mpWindowImpl
->mpNext
;
1418 void Window::ImplPosSizeWindow( long nX
, long nY
,
1419 long nWidth
, long nHeight
, PosSizeFlags nFlags
)
1421 bool bNewPos
= false;
1422 bool bNewSize
= false;
1423 bool bCopyBits
= false;
1424 long nOldOutOffX
= mnOutOffX
;
1425 long nOldOutOffY
= mnOutOffY
;
1426 long nOldOutWidth
= mnOutWidth
;
1427 long nOldOutHeight
= mnOutHeight
;
1428 std::unique_ptr
<vcl::Region
> pOverlapRegion
;
1429 std::unique_ptr
<vcl::Region
> pOldRegion
;
1431 if ( IsReallyVisible() )
1433 tools::Rectangle
aOldWinRect( Point( nOldOutOffX
, nOldOutOffY
),
1434 Size( nOldOutWidth
, nOldOutHeight
) );
1435 pOldRegion
.reset( new vcl::Region( aOldWinRect
) );
1436 if ( mpWindowImpl
->mbWinRegion
)
1437 pOldRegion
->Intersect( ImplPixelToDevicePixel( mpWindowImpl
->maWinRegion
) );
1439 if ( mnOutWidth
&& mnOutHeight
&& !mpWindowImpl
->mbPaintTransparent
&&
1440 !mpWindowImpl
->mbInitWinClipRegion
&& !mpWindowImpl
->maWinClipRegion
.IsEmpty() &&
1445 bool bnXRecycled
= false; // avoid duplicate mirroring in RTL case
1446 if ( nFlags
& PosSizeFlags::Width
)
1448 if(!( nFlags
& PosSizeFlags::X
))
1450 nX
= mpWindowImpl
->mnX
;
1451 nFlags
|= PosSizeFlags::X
;
1452 bnXRecycled
= true; // we're using a mnX which was already mirrored in RTL case
1457 if ( nWidth
!= mnOutWidth
)
1459 mnOutWidth
= nWidth
;
1464 if ( nFlags
& PosSizeFlags::Height
)
1468 if ( nHeight
!= mnOutHeight
)
1470 mnOutHeight
= nHeight
;
1476 if ( nFlags
& PosSizeFlags::X
)
1479 Point
aPtDev( Point( nX
+mnOutOffX
, 0 ) );
1480 OutputDevice
*pOutDev
= GetOutDev();
1481 if( pOutDev
->HasMirroredGraphics() )
1483 aPtDev
.setX( mpGraphics
->mirror2( aPtDev
.X(), this ) );
1485 // #106948# always mirror our pos if our parent is not mirroring, even
1486 // if we are also not mirroring
1487 // RTL: check if parent is in different coordinates
1488 if( !bnXRecycled
&& mpWindowImpl
->mpParent
&& !mpWindowImpl
->mpParent
->mpWindowImpl
->mbFrame
&& mpWindowImpl
->mpParent
->ImplIsAntiparallel() )
1490 nX
= mpWindowImpl
->mpParent
->mnOutWidth
- mnOutWidth
- nX
;
1492 /* #i99166# An LTR window in RTL UI that gets sized only would be
1493 expected to not moved its upper left point
1497 if( ImplIsAntiparallel() )
1499 aPtDev
.setX( mpWindowImpl
->mnAbsScreenX
);
1500 nOrgX
= mpWindowImpl
->maPos
.X();
1504 else if( !bnXRecycled
&& mpWindowImpl
->mpParent
&& !mpWindowImpl
->mpParent
->mpWindowImpl
->mbFrame
&& mpWindowImpl
->mpParent
->ImplIsAntiparallel() )
1506 // mirrored window in LTR UI
1507 nX
= mpWindowImpl
->mpParent
->mnOutWidth
- mnOutWidth
- nX
;
1510 // check maPos as well, as it could have been changed for client windows (ImplCallMove())
1511 if ( mpWindowImpl
->mnAbsScreenX
!= aPtDev
.X() || nX
!= mpWindowImpl
->mnX
|| nOrgX
!= mpWindowImpl
->maPos
.X() )
1513 if ( bCopyBits
&& !pOverlapRegion
)
1515 pOverlapRegion
.reset( new vcl::Region() );
1516 ImplCalcOverlapRegion( tools::Rectangle( Point( mnOutOffX
, mnOutOffY
),
1517 Size( mnOutWidth
, mnOutHeight
) ),
1518 *pOverlapRegion
, false, true );
1520 mpWindowImpl
->mnX
= nX
;
1521 mpWindowImpl
->maPos
.setX( nOrgX
);
1522 mpWindowImpl
->mnAbsScreenX
= aPtDev
.X();
1526 if ( nFlags
& PosSizeFlags::Y
)
1528 // check maPos as well, as it could have been changed for client windows (ImplCallMove())
1529 if ( nY
!= mpWindowImpl
->mnY
|| nY
!= mpWindowImpl
->maPos
.Y() )
1531 if ( bCopyBits
&& !pOverlapRegion
)
1533 pOverlapRegion
.reset( new vcl::Region() );
1534 ImplCalcOverlapRegion( tools::Rectangle( Point( mnOutOffX
, mnOutOffY
),
1535 Size( mnOutWidth
, mnOutHeight
) ),
1536 *pOverlapRegion
, false, true );
1538 mpWindowImpl
->mnY
= nY
;
1539 mpWindowImpl
->maPos
.setY( nY
);
1544 if ( bNewPos
|| bNewSize
)
1546 bool bUpdateSysObjPos
= false;
1548 bUpdateSysObjPos
= ImplUpdatePos();
1550 // the borderwindow always specifies the position for its client window
1551 if ( mpWindowImpl
->mpBorderWindow
)
1552 mpWindowImpl
->maPos
= mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->maPos
;
1554 if ( mpWindowImpl
->mpClientWindow
)
1556 mpWindowImpl
->mpClientWindow
->ImplPosSizeWindow( mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnLeftBorder
,
1557 mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnTopBorder
,
1558 mnOutWidth
-mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnLeftBorder
-mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnRightBorder
,
1559 mnOutHeight
-mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnTopBorder
-mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mnBottomBorder
,
1560 PosSizeFlags::X
| PosSizeFlags::Y
|
1561 PosSizeFlags::Width
| PosSizeFlags::Height
);
1562 // If we have a client window, then this is the position
1563 // of the Application's floating windows
1564 mpWindowImpl
->mpClientWindow
->mpWindowImpl
->maPos
= mpWindowImpl
->maPos
;
1567 if ( mpWindowImpl
->mpClientWindow
->IsVisible() )
1569 mpWindowImpl
->mpClientWindow
->ImplCallMove();
1573 mpWindowImpl
->mpClientWindow
->mpWindowImpl
->mbCallMove
= true;
1578 // Move()/Resize() will be called only for Show(), such that
1579 // at least one is called before Show()
1594 mpWindowImpl
->mbCallMove
= true;
1596 mpWindowImpl
->mbCallResize
= true;
1599 bool bUpdateSysObjClip
= false;
1600 if ( IsReallyVisible() )
1602 if ( bNewPos
|| bNewSize
)
1605 bUpdateSysObjClip
= !ImplSetClipFlag( true );
1608 // invalidate window content ?
1609 if ( bNewPos
|| (mnOutWidth
> nOldOutWidth
) || (mnOutHeight
> nOldOutHeight
) )
1613 bool bInvalidate
= false;
1614 bool bParentPaint
= true;
1615 if ( !ImplIsOverlapWindow() )
1616 bParentPaint
= mpWindowImpl
->mpParent
->IsPaintEnabled();
1617 if ( bCopyBits
&& bParentPaint
&& !HasPaintEvent() )
1619 Point
aPoint( mnOutOffX
, mnOutOffY
);
1620 vcl::Region
aRegion( tools::Rectangle( aPoint
,
1621 Size( mnOutWidth
, mnOutHeight
) ) );
1622 if ( mpWindowImpl
->mbWinRegion
)
1623 aRegion
.Intersect( ImplPixelToDevicePixel( mpWindowImpl
->maWinRegion
) );
1624 ImplClipBoundaries( aRegion
, false, true );
1625 if ( !pOverlapRegion
->IsEmpty() )
1627 pOverlapRegion
->Move( mnOutOffX
-nOldOutOffX
, mnOutOffY
-nOldOutOffY
);
1628 aRegion
.Exclude( *pOverlapRegion
);
1630 if ( !aRegion
.IsEmpty() )
1632 // adapt Paint areas
1633 ImplMoveAllInvalidateRegions( tools::Rectangle( Point( nOldOutOffX
, nOldOutOffY
),
1634 Size( nOldOutWidth
, nOldOutHeight
) ),
1635 mnOutOffX
-nOldOutOffX
, mnOutOffY
-nOldOutOffY
,
1637 SalGraphics
* pGraphics
= ImplGetFrameGraphics();
1641 OutputDevice
*pOutDev
= GetOutDev();
1642 const bool bSelectClipRegion
= pOutDev
->SelectClipRegion( aRegion
, pGraphics
);
1643 if ( bSelectClipRegion
)
1645 pGraphics
->CopyArea( mnOutOffX
, mnOutOffY
,
1646 nOldOutOffX
, nOldOutOffY
,
1647 nOldOutWidth
, nOldOutHeight
,
1657 if ( !pOverlapRegion
->IsEmpty() )
1658 ImplInvalidateFrameRegion( pOverlapRegion
.get(), InvalidateFlags::Children
);
1667 ImplInvalidateFrameRegion( nullptr, InvalidateFlags::Children
);
1671 Point
aPoint( mnOutOffX
, mnOutOffY
);
1672 vcl::Region
aRegion( tools::Rectangle( aPoint
,
1673 Size( mnOutWidth
, mnOutHeight
) ) );
1674 aRegion
.Exclude( *pOldRegion
);
1675 if ( mpWindowImpl
->mbWinRegion
)
1676 aRegion
.Intersect( ImplPixelToDevicePixel( mpWindowImpl
->maWinRegion
) );
1677 ImplClipBoundaries( aRegion
, false, true );
1678 if ( !aRegion
.IsEmpty() )
1679 ImplInvalidateFrameRegion( &aRegion
, InvalidateFlags::Children
);
1683 // invalidate Parent or Overlaps
1685 (mnOutWidth
< nOldOutWidth
) || (mnOutHeight
< nOldOutHeight
) )
1687 vcl::Region
aRegion( *pOldRegion
);
1688 if ( !mpWindowImpl
->mbPaintTransparent
)
1689 ImplExcludeWindowRegion( aRegion
);
1690 ImplClipBoundaries( aRegion
, false, true );
1691 if ( !aRegion
.IsEmpty() && !mpWindowImpl
->mpBorderWindow
)
1692 ImplInvalidateParentFrameRegion( aRegion
);
1696 // adapt system objects
1697 if ( bUpdateSysObjClip
)
1698 ImplUpdateSysObjClip();
1699 if ( bUpdateSysObjPos
)
1700 ImplUpdateSysObjPos();
1701 if ( bNewSize
&& mpWindowImpl
->mpSysObj
)
1702 mpWindowImpl
->mpSysObj
->SetPosSize( mnOutOffX
, mnOutOffY
, mnOutWidth
, mnOutHeight
);
1706 void Window::ImplNewInputContext()
1708 ImplSVData
* pSVData
= ImplGetSVData();
1709 vcl::Window
* pFocusWin
= pSVData
->maWinData
.mpFocusWin
;
1713 // Is InputContext changed?
1714 const InputContext
& rInputContext
= pFocusWin
->GetInputContext();
1715 if ( rInputContext
== pFocusWin
->mpWindowImpl
->mpFrameData
->maOldInputContext
)
1718 pFocusWin
->mpWindowImpl
->mpFrameData
->maOldInputContext
= rInputContext
;
1720 SalInputContext aNewContext
;
1721 const vcl::Font
& rFont
= rInputContext
.GetFont();
1722 const OUString
& rFontName
= rFont
.GetFamilyName();
1723 rtl::Reference
<LogicalFontInstance
> pFontInstance
;
1724 aNewContext
.mpFont
= nullptr;
1725 if (!rFontName
.isEmpty())
1727 OutputDevice
*pFocusWinOutDev
= pFocusWin
->GetOutDev();
1728 Size aSize
= pFocusWinOutDev
->ImplLogicToDevicePixel( rFont
.GetFontSize() );
1729 if ( !aSize
.Height() )
1731 // only set default sizes if the font height in logical
1732 // coordinates equals 0
1733 if ( rFont
.GetFontSize().Height() )
1734 aSize
.setHeight( 1 );
1736 aSize
.setHeight( (12*pFocusWin
->mnDPIY
)/72 );
1738 pFontInstance
= pFocusWin
->mxFontCache
->GetFontInstance( pFocusWin
->mxFontCollection
.get(),
1739 rFont
, aSize
, static_cast<float>(aSize
.Height()) );
1740 if ( pFontInstance
)
1741 aNewContext
.mpFont
= pFontInstance
;
1743 aNewContext
.mnOptions
= rInputContext
.GetOptions();
1744 pFocusWin
->ImplGetFrame()->SetInputContext( &aNewContext
);
1747 void Window::SetModalHierarchyHdl(const Link
<bool, void>& rLink
)
1749 ImplGetFrame()->SetModalHierarchyHdl(rLink
);
1752 void Window::SetParentToDefaultWindow()
1755 SetParent(ImplGetDefaultWindow());
1758 KeyIndicatorState
Window::GetIndicatorState() const
1760 return mpWindowImpl
->mpFrame
->GetIndicatorState();
1763 void Window::SimulateKeyPress( sal_uInt16 nKeyCode
) const
1765 mpWindowImpl
->mpFrame
->SimulateKeyPress(nKeyCode
);
1768 void Window::KeyInput( const KeyEvent
& rKEvt
)
1770 KeyCode cod
= rKEvt
.GetKeyCode ();
1771 bool autoacc
= ImplGetSVData()->maNWFData
.mbAutoAccel
;
1773 // do not respond to accelerators unless Alt is held */
1774 if (cod
.GetCode () >= 0x200 && cod
.GetCode () <= 0x219)
1776 if (autoacc
&& cod
.GetModifier () != KEY_MOD2
)
1780 NotifyEvent
aNEvt( MouseNotifyEvent::KEYINPUT
, this, &rKEvt
);
1781 if ( !CompatNotify( aNEvt
) )
1782 mpWindowImpl
->mbKeyInput
= true;
1785 void Window::KeyUp( const KeyEvent
& rKEvt
)
1787 NotifyEvent
aNEvt( MouseNotifyEvent::KEYUP
, this, &rKEvt
);
1788 if ( !CompatNotify( aNEvt
) )
1789 mpWindowImpl
->mbKeyUp
= true;
1792 void Window::Draw( OutputDevice
*, const Point
&, const Size
&, DrawFlags
)
1796 void Window::Move() {}
1798 void Window::Resize() {}
1800 void Window::Activate() {}
1802 void Window::Deactivate() {}
1804 void Window::GetFocus()
1806 if ( HasFocus() && mpWindowImpl
->mpLastFocusWindow
&& !(mpWindowImpl
->mnDlgCtrlFlags
& DialogControlFlags::WantFocus
) )
1808 VclPtr
<vcl::Window
> xWindow(this);
1809 mpWindowImpl
->mpLastFocusWindow
->GrabFocus();
1810 if( xWindow
->IsDisposed() )
1814 NotifyEvent
aNEvt( MouseNotifyEvent::GETFOCUS
, this );
1815 CompatNotify( aNEvt
);
1818 void Window::LoseFocus()
1820 NotifyEvent
aNEvt( MouseNotifyEvent::LOSEFOCUS
, this );
1821 CompatNotify( aNEvt
);
1824 void Window::SetHelpHdl(const Link
<vcl::Window
&, bool>& rLink
)
1826 if (mpWindowImpl
) // may be called after dispose
1828 mpWindowImpl
->maHelpRequestHdl
= rLink
;
1832 void Window::RequestHelp( const HelpEvent
& rHEvt
)
1834 // if Balloon-Help is requested, show the balloon
1835 // with help text set
1836 if ( rHEvt
.GetMode() & HelpEventMode::BALLOON
)
1838 OUString rStr
= GetHelpText();
1839 if ( rStr
.isEmpty() )
1840 rStr
= GetQuickHelpText();
1841 if ( rStr
.isEmpty() && ImplGetParent() && !ImplIsOverlapWindow() )
1842 ImplGetParent()->RequestHelp( rHEvt
);
1845 Point aPos
= GetPosPixel();
1846 if ( ImplGetParent() && !ImplIsOverlapWindow() )
1847 aPos
= OutputToScreenPixel(Point(0, 0));
1848 tools::Rectangle
aRect( aPos
, GetSizePixel() );
1850 Help::ShowBalloon( this, rHEvt
.GetMousePosPixel(), aRect
, rStr
);
1853 else if ( rHEvt
.GetMode() & HelpEventMode::QUICK
)
1855 const OUString
& rStr
= GetQuickHelpText();
1856 if ( rStr
.isEmpty() && ImplGetParent() && !ImplIsOverlapWindow() )
1857 ImplGetParent()->RequestHelp( rHEvt
);
1860 Point aPos
= GetPosPixel();
1861 if ( ImplGetParent() && !ImplIsOverlapWindow() )
1862 aPos
= OutputToScreenPixel(Point(0, 0));
1863 tools::Rectangle
aRect( aPos
, GetSizePixel() );
1864 Help::ShowQuickHelp( this, aRect
, rStr
, QuickHelpFlags::CtrlText
);
1867 else if (!mpWindowImpl
->maHelpRequestHdl
.IsSet() || mpWindowImpl
->maHelpRequestHdl
.Call(*this))
1869 OUString
aStrHelpId( OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8
) );
1870 if ( aStrHelpId
.isEmpty() && ImplGetParent() )
1871 ImplGetParent()->RequestHelp( rHEvt
);
1874 Help
* pHelp
= Application::GetHelp();
1877 if( !aStrHelpId
.isEmpty() )
1878 pHelp
->Start( aStrHelpId
, this );
1880 pHelp
->Start( OOO_HELP_INDEX
, this );
1886 void Window::Command( const CommandEvent
& rCEvt
)
1888 CallEventListeners( VclEventId::WindowCommand
, const_cast<CommandEvent
*>(&rCEvt
) );
1890 NotifyEvent
aNEvt( MouseNotifyEvent::COMMAND
, this, &rCEvt
);
1891 if ( !CompatNotify( aNEvt
) )
1892 mpWindowImpl
->mbCommand
= true;
1895 void Window::Tracking( const TrackingEvent
& rTEvt
)
1898 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( this );
1900 pWrapper
->Tracking( rTEvt
);
1903 void Window::StateChanged(StateChangedType eType
)
1907 //stuff that doesn't invalidate the layout
1908 case StateChangedType::ControlForeground
:
1909 case StateChangedType::ControlBackground
:
1910 case StateChangedType::UpdateMode
:
1911 case StateChangedType::ReadOnly
:
1912 case StateChangedType::Enable
:
1913 case StateChangedType::State
:
1914 case StateChangedType::Data
:
1915 case StateChangedType::InitShow
:
1916 case StateChangedType::ControlFocus
:
1918 //stuff that does invalidate the layout
1920 queue_resize(eType
);
1925 void Window::SetStyle( WinBits nStyle
)
1927 if ( mpWindowImpl
&& mpWindowImpl
->mnStyle
!= nStyle
)
1929 mpWindowImpl
->mnPrevStyle
= mpWindowImpl
->mnStyle
;
1930 mpWindowImpl
->mnStyle
= nStyle
;
1931 CompatStateChanged( StateChangedType::Style
);
1935 void Window::SetExtendedStyle( WindowExtendedStyle nExtendedStyle
)
1938 if ( mpWindowImpl
->mnExtendedStyle
!= nExtendedStyle
)
1940 vcl::Window
* pWindow
= ImplGetBorderWindow();
1943 if( pWindow
->mpWindowImpl
->mbFrame
)
1945 SalExtStyle nExt
= 0;
1946 if( nExtendedStyle
& WindowExtendedStyle::Document
)
1947 nExt
|= SAL_FRAME_EXT_STYLE_DOCUMENT
;
1948 if( nExtendedStyle
& WindowExtendedStyle::DocModified
)
1949 nExt
|= SAL_FRAME_EXT_STYLE_DOCMODIFIED
;
1951 pWindow
->ImplGetFrame()->SetExtendedFrameStyle( nExt
);
1953 mpWindowImpl
->mnExtendedStyle
= nExtendedStyle
;
1957 void Window::SetBorderStyle( WindowBorderStyle nBorderStyle
)
1960 if ( mpWindowImpl
->mpBorderWindow
)
1962 if( nBorderStyle
== WindowBorderStyle::REMOVEBORDER
&&
1963 ! mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbFrame
&&
1964 mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mpParent
1967 // this is a little awkward: some controls (e.g. svtools ProgressBar)
1968 // cannot avoid getting constructed with WB_BORDER but want to disable
1969 // borders in case of NWF drawing. So they need a method to remove their border window
1970 VclPtr
<vcl::Window
> pBorderWin
= mpWindowImpl
->mpBorderWindow
;
1971 // remove us as border window's client
1972 pBorderWin
->mpWindowImpl
->mpClientWindow
= nullptr;
1973 mpWindowImpl
->mpBorderWindow
= nullptr;
1974 mpWindowImpl
->mpRealParent
= pBorderWin
->mpWindowImpl
->mpParent
;
1975 // reparent us above the border window
1976 SetParent( pBorderWin
->mpWindowImpl
->mpParent
);
1977 // set us to the position and size of our previous border
1978 Point
aBorderPos( pBorderWin
->GetPosPixel() );
1979 Size
aBorderSize( pBorderWin
->GetSizePixel() );
1980 setPosSizePixel( aBorderPos
.X(), aBorderPos
.Y(), aBorderSize
.Width(), aBorderSize
.Height() );
1981 // release border window
1982 pBorderWin
.disposeAndClear();
1984 // set new style bits
1985 SetStyle( GetStyle() & (~WB_BORDER
) );
1989 if ( mpWindowImpl
->mpBorderWindow
->GetType() == WindowType::BORDERWINDOW
)
1990 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetBorderStyle( nBorderStyle
);
1992 mpWindowImpl
->mpBorderWindow
->SetBorderStyle( nBorderStyle
);
1997 WindowBorderStyle
Window::GetBorderStyle() const
2000 if ( mpWindowImpl
->mpBorderWindow
)
2002 if ( mpWindowImpl
->mpBorderWindow
->GetType() == WindowType::BORDERWINDOW
)
2003 return static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->GetBorderStyle();
2005 return mpWindowImpl
->mpBorderWindow
->GetBorderStyle();
2008 return WindowBorderStyle::NONE
;
2011 long Window::CalcTitleWidth() const
2014 if ( mpWindowImpl
->mpBorderWindow
)
2016 if ( mpWindowImpl
->mpBorderWindow
->GetType() == WindowType::BORDERWINDOW
)
2017 return static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->CalcTitleWidth();
2019 return mpWindowImpl
->mpBorderWindow
->CalcTitleWidth();
2021 else if ( mpWindowImpl
->mbFrame
&& (mpWindowImpl
->mnStyle
& WB_MOVEABLE
) )
2023 // we guess the width for frame windows as we do not know the
2024 // border of external dialogs
2025 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
2026 vcl::Font aFont
= GetFont();
2027 const_cast<vcl::Window
*>(this)->SetPointFont(*const_cast<Window
*>(this), rStyleSettings
.GetTitleFont());
2028 long nTitleWidth
= GetTextWidth( GetText() );
2029 const_cast<vcl::Window
*>(this)->SetFont( aFont
);
2030 nTitleWidth
+= rStyleSettings
.GetTitleHeight() * 3;
2031 nTitleWidth
+= StyleSettings::GetBorderSize() * 2;
2039 void Window::SetInputContext( const InputContext
& rInputContext
)
2042 mpWindowImpl
->maInputContext
= rInputContext
;
2043 if ( !mpWindowImpl
->mbInFocusHdl
&& HasFocus() )
2044 ImplNewInputContext();
2047 void Window::PostExtTextInputEvent(VclEventId nType
, const OUString
& rText
)
2051 case VclEventId::ExtTextInput
:
2053 std::unique_ptr
<ExtTextInputAttr
[]> pAttr(new ExtTextInputAttr
[rText
.getLength()]);
2054 for (int i
= 0; i
< rText
.getLength(); ++i
) {
2055 pAttr
[i
] = ExtTextInputAttr::Underline
;
2057 SalExtTextInputEvent aEvent
{ rText
, pAttr
.get(), rText
.getLength(), EXTTEXTINPUT_CURSOR_OVERWRITE
};
2058 ImplWindowFrameProc(this, SalEvent::ExtTextInput
, &aEvent
);
2061 case VclEventId::EndExtTextInput
:
2062 ImplWindowFrameProc(this, SalEvent::EndExtTextInput
, nullptr);
2069 void Window::EndExtTextInput()
2071 if ( mpWindowImpl
->mbExtTextInput
)
2072 ImplGetFrame()->EndExtTextInput( EndExtTextInputFlags::Complete
);
2075 void Window::SetCursorRect( const tools::Rectangle
* pRect
, long nExtTextInputWidth
)
2078 ImplWinData
* pWinData
= ImplGetWinData();
2079 if ( pWinData
->mpCursorRect
)
2082 pWinData
->mpCursorRect
= *pRect
;
2084 pWinData
->mpCursorRect
.reset();
2089 pWinData
->mpCursorRect
= *pRect
;
2092 pWinData
->mnCursorExtWidth
= nExtTextInputWidth
;
2096 const tools::Rectangle
* Window::GetCursorRect() const
2099 ImplWinData
* pWinData
= ImplGetWinData();
2100 return pWinData
->mpCursorRect
? &*pWinData
->mpCursorRect
: nullptr;
2103 long Window::GetCursorExtTextInputWidth() const
2106 ImplWinData
* pWinData
= ImplGetWinData();
2107 return pWinData
->mnCursorExtWidth
;
2110 void Window::SetCompositionCharRect( const tools::Rectangle
* pRect
, long nCompositionLength
, bool bVertical
) {
2112 ImplWinData
* pWinData
= ImplGetWinData();
2113 pWinData
->mpCompositionCharRects
.reset();
2114 pWinData
->mbVertical
= bVertical
;
2115 pWinData
->mnCompositionCharRects
= nCompositionLength
;
2116 if ( pRect
&& (nCompositionLength
> 0) )
2118 pWinData
->mpCompositionCharRects
.reset( new tools::Rectangle
[nCompositionLength
] );
2119 for (long i
= 0; i
< nCompositionLength
; ++i
)
2120 pWinData
->mpCompositionCharRects
[i
] = pRect
[i
];
2124 void Window::CollectChildren(::std::vector
<vcl::Window
*>& rAllChildren
)
2126 rAllChildren
.push_back( this );
2128 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2131 pChild
->CollectChildren( rAllChildren
);
2132 pChild
= pChild
->mpWindowImpl
->mpNext
;
2136 void Window::SetPointFont(vcl::RenderContext
& rRenderContext
, const vcl::Font
& rFont
)
2138 vcl::Font aFont
= rFont
;
2139 ImplPointToLogic(rRenderContext
, aFont
);
2140 rRenderContext
.SetFont(aFont
);
2143 vcl::Font
Window::GetPointFont(vcl::RenderContext
const & rRenderContext
) const
2145 vcl::Font aFont
= rRenderContext
.GetFont();
2146 ImplLogicToPoint(rRenderContext
, aFont
);
2150 void Window::Show(bool bVisible
, ShowFlags nFlags
)
2152 if ( IsDisposed() || mpWindowImpl
->mbVisible
== bVisible
)
2155 VclPtr
<vcl::Window
> xWindow(this);
2157 bool bRealVisibilityChanged
= false;
2158 mpWindowImpl
->mbVisible
= bVisible
;
2162 ImplHideAllOverlaps();
2163 if( xWindow
->IsDisposed() )
2166 if ( mpWindowImpl
->mpBorderWindow
)
2168 bool bOldUpdate
= mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbNoParentUpdate
;
2169 if ( mpWindowImpl
->mbNoParentUpdate
)
2170 mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbNoParentUpdate
= true;
2171 mpWindowImpl
->mpBorderWindow
->Show( false, nFlags
);
2172 mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbNoParentUpdate
= bOldUpdate
;
2174 else if ( mpWindowImpl
->mbFrame
)
2176 mpWindowImpl
->mbSuppressAccessibilityEvents
= true;
2177 mpWindowImpl
->mpFrame
->Show( false );
2180 CompatStateChanged( StateChangedType::Visible
);
2182 if ( mpWindowImpl
->mbReallyVisible
)
2184 if ( mpWindowImpl
->mbInitWinClipRegion
)
2185 ImplInitWinClipRegion();
2187 vcl::Region aInvRegion
= mpWindowImpl
->maWinClipRegion
;
2189 if( xWindow
->IsDisposed() )
2192 bRealVisibilityChanged
= mpWindowImpl
->mbReallyVisible
;
2193 ImplResetReallyVisible();
2196 if ( ImplIsOverlapWindow() && !mpWindowImpl
->mbFrame
)
2199 if ( !(nFlags
& ShowFlags::NoFocusChange
) && HasChildPathFocus() )
2201 if ( mpWindowImpl
->mpOverlapWindow
->IsEnabled() &&
2202 mpWindowImpl
->mpOverlapWindow
->IsInputEnabled() &&
2203 ! mpWindowImpl
->mpOverlapWindow
->IsInModalMode()
2205 mpWindowImpl
->mpOverlapWindow
->GrabFocus();
2209 if ( !mpWindowImpl
->mbFrame
)
2211 if( mpWindowImpl
->mpWinData
&& mpWindowImpl
->mpWinData
->mbEnableNativeWidget
)
2214 * #i48371# native theming: some themes draw outside the control
2215 * area we tell them to (bad thing, but we cannot do much about it ).
2216 * On hiding these controls they get invalidated with their window rectangle
2217 * which leads to the parts outside the control area being left and not
2218 * invalidated. Workaround: invalidate an area on the parent, too
2220 const int workaround_border
= 5;
2221 tools::Rectangle
aBounds( aInvRegion
.GetBoundRect() );
2222 aBounds
.AdjustLeft( -workaround_border
);
2223 aBounds
.AdjustTop( -workaround_border
);
2224 aBounds
.AdjustRight(workaround_border
);
2225 aBounds
.AdjustBottom(workaround_border
);
2226 aInvRegion
= aBounds
;
2228 if ( !mpWindowImpl
->mbNoParentUpdate
)
2230 if ( !aInvRegion
.IsEmpty() )
2231 ImplInvalidateParentFrameRegion( aInvRegion
);
2233 ImplGenerateMouseMove();
2239 // inherit native widget flag for form controls
2240 // required here, because frames never show up in the child hierarchy - which should be fixed...
2241 // eg, the drop down of a combobox which is a system floating window
2242 if( mpWindowImpl
->mbFrame
&& GetParent() && GetParent()->IsCompoundControl() &&
2243 GetParent()->IsNativeWidgetEnabled() != IsNativeWidgetEnabled() &&
2244 !(GetStyle() & WB_TOOLTIPWIN
) )
2246 EnableNativeWidget( GetParent()->IsNativeWidgetEnabled() );
2249 if ( mpWindowImpl
->mbCallMove
)
2253 if ( mpWindowImpl
->mbCallResize
)
2258 CompatStateChanged( StateChangedType::Visible
);
2260 vcl::Window
* pTestParent
;
2261 if ( ImplIsOverlapWindow() )
2262 pTestParent
= mpWindowImpl
->mpOverlapWindow
;
2264 pTestParent
= ImplGetParent();
2265 if ( mpWindowImpl
->mbFrame
|| pTestParent
->mpWindowImpl
->mbReallyVisible
)
2267 // if a window becomes visible, send all child windows a StateChange,
2268 // such that these can initialise themselves
2271 // If it is a SystemWindow it automatically pops up on top of
2272 // all other windows if needed.
2273 if ( ImplIsOverlapWindow() && !(nFlags
& ShowFlags::NoActivate
) )
2275 ImplStartToTop(( nFlags
& ShowFlags::ForegroundTask
) ? ToTopFlags::ForegroundTask
: ToTopFlags::NONE
);
2276 ImplFocusToTop( ToTopFlags::NONE
, false );
2279 // adjust mpWindowImpl->mbReallyVisible
2280 bRealVisibilityChanged
= !mpWindowImpl
->mbReallyVisible
;
2281 ImplSetReallyVisible();
2283 // assure clip rectangles will be recalculated
2286 if ( !mpWindowImpl
->mbFrame
)
2288 InvalidateFlags nInvalidateFlags
= InvalidateFlags::Children
;
2289 if( ! IsPaintTransparent() )
2290 nInvalidateFlags
|= InvalidateFlags::NoTransparent
;
2291 ImplInvalidate( nullptr, nInvalidateFlags
);
2292 ImplGenerateMouseMove();
2296 if ( mpWindowImpl
->mpBorderWindow
)
2297 mpWindowImpl
->mpBorderWindow
->Show( true, nFlags
);
2298 else if ( mpWindowImpl
->mbFrame
)
2300 // #106431#, hide SplashScreen
2301 ImplSVData
* pSVData
= ImplGetSVData();
2302 if ( !pSVData
->mpIntroWindow
)
2304 // The right way would be just to call this (not even in the 'if')
2305 auto pApp
= GetpApp();
2307 pApp
->InitFinished();
2309 else if ( !ImplIsWindowOrChild( pSVData
->mpIntroWindow
) )
2311 // ... but the VCL splash is broken, and it needs this
2312 // (for ./soffice .uno:NewDoc)
2313 pSVData
->mpIntroWindow
->Hide();
2316 //SAL_WARN_IF( mpWindowImpl->mbSuppressAccessibilityEvents, "vcl", "Window::Show() - Frame reactivated");
2317 mpWindowImpl
->mbSuppressAccessibilityEvents
= false;
2319 mpWindowImpl
->mbPaintFrame
= true;
2320 if (!Application::IsHeadlessModeEnabled())
2322 bool bNoActivate(nFlags
& (ShowFlags::NoActivate
|ShowFlags::NoFocusChange
));
2323 mpWindowImpl
->mpFrame
->Show( true, bNoActivate
);
2325 if( xWindow
->IsDisposed() )
2328 // Query the correct size of the window, if we are waiting for
2330 if ( mpWindowImpl
->mbWaitSystemResize
)
2334 mpWindowImpl
->mpFrame
->GetClientSize( nOutWidth
, nOutHeight
);
2335 ImplHandleResize( this, nOutWidth
, nOutHeight
);
2338 if (mpWindowImpl
->mpFrameData
->mpBuffer
&& mpWindowImpl
->mpFrameData
->mpBuffer
->GetOutputSizePixel() != GetOutputSizePixel())
2339 // Make sure that the buffer size matches the window size, even if no resize was needed.
2340 mpWindowImpl
->mpFrameData
->mpBuffer
->SetOutputSizePixel(GetOutputSizePixel());
2343 if( xWindow
->IsDisposed() )
2346 ImplShowAllOverlaps();
2349 if( xWindow
->IsDisposed() )
2352 // the SHOW/HIDE events also serve as indicators to send child creation/destroy events to the access bridge
2353 // However, the access bridge only uses this event if the data member is not NULL (it's kind of a hack that
2354 // we re-use the SHOW/HIDE events this way, with this particular semantics).
2355 // Since #104887#, the notifications for the access bridge are done in Impl(Set|Reset)ReallyVisible. Here, we
2356 // now only notify with a NULL data pointer, for all other clients except the access bridge.
2357 if ( !bRealVisibilityChanged
)
2358 CallEventListeners( mpWindowImpl
->mbVisible
? VclEventId::WindowShow
: VclEventId::WindowHide
);
2359 if( xWindow
->IsDisposed() )
2364 Size
Window::GetSizePixel() const
2368 SAL_WARN("vcl.layout", "WTF no windowimpl");
2372 // #i43257# trigger pending resize handler to assure correct window sizes
2373 if( mpWindowImpl
->mpFrameData
->maResizeIdle
.IsActive() )
2375 VclPtr
<vcl::Window
> xWindow( const_cast<Window
*>(this) );
2376 mpWindowImpl
->mpFrameData
->maResizeIdle
.Stop();
2377 mpWindowImpl
->mpFrameData
->maResizeIdle
.Invoke( nullptr );
2378 if( xWindow
->IsDisposed() )
2382 return Size( mnOutWidth
+mpWindowImpl
->mnLeftBorder
+mpWindowImpl
->mnRightBorder
,
2383 mnOutHeight
+mpWindowImpl
->mnTopBorder
+mpWindowImpl
->mnBottomBorder
);
2386 void Window::GetBorder( sal_Int32
& rLeftBorder
, sal_Int32
& rTopBorder
,
2387 sal_Int32
& rRightBorder
, sal_Int32
& rBottomBorder
) const
2389 rLeftBorder
= mpWindowImpl
->mnLeftBorder
;
2390 rTopBorder
= mpWindowImpl
->mnTopBorder
;
2391 rRightBorder
= mpWindowImpl
->mnRightBorder
;
2392 rBottomBorder
= mpWindowImpl
->mnBottomBorder
;
2395 void Window::Enable( bool bEnable
, bool bChild
)
2402 // the tracking mode will be stopped or the capture will be stolen
2403 // when a window is disabled,
2405 EndTracking( TrackingEventFlags::Cancel
);
2406 if ( IsMouseCaptured() )
2408 // try to pass focus to the next control
2409 // if the window has focus and is contained in the dialog control
2410 // mpWindowImpl->mbDisabled should only be set after a call of ImplDlgCtrlNextWindow().
2411 // Otherwise ImplDlgCtrlNextWindow() should be used
2413 ImplDlgCtrlNextWindow();
2416 if ( mpWindowImpl
->mpBorderWindow
)
2418 mpWindowImpl
->mpBorderWindow
->Enable( bEnable
, false );
2419 if ( (mpWindowImpl
->mpBorderWindow
->GetType() == WindowType::BORDERWINDOW
) &&
2420 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->mpMenuBarWindow
)
2421 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->mpMenuBarWindow
->Enable( bEnable
);
2424 // #i56102# restore app focus win in case the
2425 // window was disabled when the frame focus changed
2426 ImplSVData
* pSVData
= ImplGetSVData();
2428 pSVData
->maWinData
.mpFocusWin
== nullptr &&
2429 mpWindowImpl
->mpFrameData
->mbHasFocus
&&
2430 mpWindowImpl
->mpFrameData
->mpFocusWin
== this )
2431 pSVData
->maWinData
.mpFocusWin
= this;
2433 if ( mpWindowImpl
->mbDisabled
!= !bEnable
)
2435 mpWindowImpl
->mbDisabled
= !bEnable
;
2436 if ( mpWindowImpl
->mpSysObj
)
2437 mpWindowImpl
->mpSysObj
->Enable( bEnable
&& !mpWindowImpl
->mbInputDisabled
);
2438 CompatStateChanged( StateChangedType::Enable
);
2440 CallEventListeners( bEnable
? VclEventId::WindowEnabled
: VclEventId::WindowDisabled
);
2445 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2448 pChild
->Enable( bEnable
, bChild
);
2449 pChild
= pChild
->mpWindowImpl
->mpNext
;
2453 if ( IsReallyVisible() )
2454 ImplGenerateMouseMove();
2457 void Window::SetCallHandlersOnInputDisabled( bool bCall
)
2459 mpWindowImpl
->mbCallHandlersDuringInputDisabled
= bCall
;
2461 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2464 pChild
->SetCallHandlersOnInputDisabled( bCall
);
2465 pChild
= pChild
->mpWindowImpl
->mpNext
;
2469 bool Window::IsCallHandlersOnInputDisabled() const
2471 return mpWindowImpl
->mbCallHandlersDuringInputDisabled
;
2474 void Window::EnableInput( bool bEnable
, bool bChild
)
2479 bool bNotify
= (bEnable
!= mpWindowImpl
->mbInputDisabled
);
2480 if ( mpWindowImpl
->mpBorderWindow
)
2482 mpWindowImpl
->mpBorderWindow
->EnableInput( bEnable
, false );
2483 if ( (mpWindowImpl
->mpBorderWindow
->GetType() == WindowType::BORDERWINDOW
) &&
2484 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->mpMenuBarWindow
)
2485 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->mpMenuBarWindow
->EnableInput( bEnable
);
2488 if ( (! bEnable
&& mpWindowImpl
->meAlwaysInputMode
!= AlwaysInputEnabled
) ||
2489 ( bEnable
&& mpWindowImpl
->meAlwaysInputMode
!= AlwaysInputDisabled
) )
2491 // automatically stop the tracking mode or steal capture
2492 // if the window is disabled
2496 EndTracking( TrackingEventFlags::Cancel
);
2497 if ( IsMouseCaptured() )
2501 if ( mpWindowImpl
->mbInputDisabled
!= !bEnable
)
2503 mpWindowImpl
->mbInputDisabled
= !bEnable
;
2504 if ( mpWindowImpl
->mpSysObj
)
2505 mpWindowImpl
->mpSysObj
->Enable( !mpWindowImpl
->mbDisabled
&& bEnable
);
2509 // #i56102# restore app focus win in case the
2510 // window was disabled when the frame focus changed
2511 ImplSVData
* pSVData
= ImplGetSVData();
2513 pSVData
->maWinData
.mpFocusWin
== nullptr &&
2514 mpWindowImpl
->mpFrameData
->mbHasFocus
&&
2515 mpWindowImpl
->mpFrameData
->mpFocusWin
== this )
2516 pSVData
->maWinData
.mpFocusWin
= this;
2520 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2523 pChild
->EnableInput( bEnable
, bChild
);
2524 pChild
= pChild
->mpWindowImpl
->mpNext
;
2528 if ( IsReallyVisible() )
2529 ImplGenerateMouseMove();
2531 // #104827# notify parent
2532 if ( bNotify
&& bEnable
)
2534 NotifyEvent
aNEvt( MouseNotifyEvent::INPUTENABLE
, this );
2535 CompatNotify( aNEvt
);
2539 void Window::EnableInput( bool bEnable
, const vcl::Window
* pExcludeWindow
)
2544 EnableInput( bEnable
);
2546 // pExecuteWindow is the first Overlap-Frame --> if this
2547 // shouldn't be the case, then this must be changed in dialog.cxx
2548 if( pExcludeWindow
)
2549 pExcludeWindow
= pExcludeWindow
->ImplGetFirstOverlapWindow();
2550 vcl::Window
* pSysWin
= mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpFrameData
->mpFirstOverlap
;
2553 // Is Window in the path from this window
2554 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pSysWin
, true ) )
2556 // Is Window not in the exclude window path or not the
2557 // exclude window, then change the status
2558 if ( !pExcludeWindow
|| !pExcludeWindow
->ImplIsWindowOrChild( pSysWin
, true ) )
2559 pSysWin
->EnableInput( bEnable
);
2561 pSysWin
= pSysWin
->mpWindowImpl
->mpNextOverlap
;
2564 // enable/disable floating system windows as well
2565 vcl::Window
* pFrameWin
= ImplGetSVData()->maWinData
.mpFirstFrame
;
2568 if( pFrameWin
->ImplIsFloatingWindow() )
2570 // Is Window in the path from this window
2571 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pFrameWin
, true ) )
2573 // Is Window not in the exclude window path or not the
2574 // exclude window, then change the status
2575 if ( !pExcludeWindow
|| !pExcludeWindow
->ImplIsWindowOrChild( pFrameWin
, true ) )
2576 pFrameWin
->EnableInput( bEnable
);
2579 pFrameWin
= pFrameWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
2582 // the same for ownerdraw floating windows
2583 if( mpWindowImpl
->mbFrame
)
2585 ::std::vector
< VclPtr
<vcl::Window
> >& rList
= mpWindowImpl
->mpFrameData
->maOwnerDrawList
;
2586 for (auto const& elem
: rList
)
2588 // Is Window in the path from this window
2589 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( elem
, true ) )
2591 // Is Window not in the exclude window path or not the
2592 // exclude window, then change the status
2593 if ( !pExcludeWindow
|| !pExcludeWindow
->ImplIsWindowOrChild( elem
, true ) )
2594 elem
->EnableInput( bEnable
);
2600 void Window::AlwaysEnableInput( bool bAlways
, bool bChild
)
2603 if ( mpWindowImpl
->mpBorderWindow
)
2604 mpWindowImpl
->mpBorderWindow
->AlwaysEnableInput( bAlways
, false );
2606 if( bAlways
&& mpWindowImpl
->meAlwaysInputMode
!= AlwaysInputEnabled
)
2608 mpWindowImpl
->meAlwaysInputMode
= AlwaysInputEnabled
;
2609 EnableInput(true, false);
2611 else if( ! bAlways
&& mpWindowImpl
->meAlwaysInputMode
== AlwaysInputEnabled
)
2613 mpWindowImpl
->meAlwaysInputMode
= AlwaysInputNone
;
2618 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2621 pChild
->AlwaysEnableInput( bAlways
, bChild
);
2622 pChild
= pChild
->mpWindowImpl
->mpNext
;
2627 void Window::AlwaysDisableInput( bool bAlways
, bool bChild
)
2630 if ( mpWindowImpl
->mpBorderWindow
)
2631 mpWindowImpl
->mpBorderWindow
->AlwaysDisableInput( bAlways
, false );
2633 if( bAlways
&& mpWindowImpl
->meAlwaysInputMode
!= AlwaysInputDisabled
)
2635 mpWindowImpl
->meAlwaysInputMode
= AlwaysInputDisabled
;
2636 EnableInput(false, false);
2638 else if( ! bAlways
&& mpWindowImpl
->meAlwaysInputMode
== AlwaysInputDisabled
)
2640 mpWindowImpl
->meAlwaysInputMode
= AlwaysInputNone
;
2645 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
2648 pChild
->AlwaysDisableInput( bAlways
, bChild
);
2649 pChild
= pChild
->mpWindowImpl
->mpNext
;
2654 void Window::SetActivateMode( ActivateModeFlags nMode
)
2657 if ( mpWindowImpl
->mpBorderWindow
)
2658 mpWindowImpl
->mpBorderWindow
->SetActivateMode( nMode
);
2660 if ( mpWindowImpl
->mnActivateMode
!= nMode
)
2662 mpWindowImpl
->mnActivateMode
= nMode
;
2664 // possibly trigger Deactivate/Activate
2665 if ( mpWindowImpl
->mnActivateMode
!= ActivateModeFlags::NONE
)
2667 if ( (mpWindowImpl
->mbActive
|| (GetType() == WindowType::BORDERWINDOW
)) &&
2668 !HasChildPathFocus( true ) )
2670 mpWindowImpl
->mbActive
= false;
2676 if ( !mpWindowImpl
->mbActive
|| (GetType() == WindowType::BORDERWINDOW
) )
2678 mpWindowImpl
->mbActive
= true;
2685 void Window::setPosSizePixel( long nX
, long nY
,
2686 long nWidth
, long nHeight
, PosSizeFlags nFlags
)
2688 bool bHasValidSize
= !mpWindowImpl
->mbDefSize
;
2690 if ( nFlags
& PosSizeFlags::Pos
)
2691 mpWindowImpl
->mbDefPos
= false;
2692 if ( nFlags
& PosSizeFlags::Size
)
2693 mpWindowImpl
->mbDefSize
= false;
2695 // The top BorderWindow is the window which is to be positioned
2696 VclPtr
<vcl::Window
> pWindow
= this;
2697 while ( pWindow
->mpWindowImpl
->mpBorderWindow
)
2698 pWindow
= pWindow
->mpWindowImpl
->mpBorderWindow
;
2700 if ( pWindow
->mpWindowImpl
->mbFrame
)
2702 // Note: if we're positioning a frame, the coordinates are interpreted
2703 // as being the top-left corner of the window's client area and NOT
2704 // as the position of the border ! (due to limitations of several UNIX window managers)
2705 long nOldWidth
= pWindow
->mnOutWidth
;
2707 if ( !(nFlags
& PosSizeFlags::Width
) )
2708 nWidth
= pWindow
->mnOutWidth
;
2709 if ( !(nFlags
& PosSizeFlags::Height
) )
2710 nHeight
= pWindow
->mnOutHeight
;
2712 sal_uInt16 nSysFlags
=0;
2713 VclPtr
<vcl::Window
> pParent
= GetParent();
2714 VclPtr
<vcl::Window
> pWinParent
= pWindow
->GetParent();
2716 if( nFlags
& PosSizeFlags::Width
)
2717 nSysFlags
|= SAL_FRAME_POSSIZE_WIDTH
;
2718 if( nFlags
& PosSizeFlags::Height
)
2719 nSysFlags
|= SAL_FRAME_POSSIZE_HEIGHT
;
2720 if( nFlags
& PosSizeFlags::X
)
2722 nSysFlags
|= SAL_FRAME_POSSIZE_X
;
2723 if( pWinParent
&& (pWindow
->GetStyle() & WB_SYSTEMCHILDWINDOW
) )
2725 nX
+= pWinParent
->mnOutOffX
;
2727 if( pParent
&& pParent
->ImplIsAntiparallel() )
2729 tools::Rectangle
aRect( Point ( nX
, nY
), Size( nWidth
, nHeight
) );
2730 const OutputDevice
*pParentOutDev
= pParent
->GetOutDev();
2731 pParentOutDev
->ReMirror( aRect
);
2735 if( !(nFlags
& PosSizeFlags::X
) && bHasValidSize
&& pWindow
->mpWindowImpl
->mpFrame
->maGeometry
.nWidth
)
2737 // RTL: make sure the old right aligned position is not changed
2738 // system windows will always grow to the right
2741 OutputDevice
*pParentOutDev
= pWinParent
->GetOutDev();
2742 if( pParentOutDev
->HasMirroredGraphics() )
2744 const SalFrameGeometry
& aSysGeometry
= mpWindowImpl
->mpFrame
->GetUnmirroredGeometry();
2745 const SalFrameGeometry
& aParentSysGeometry
=
2746 pWinParent
->mpWindowImpl
->mpFrame
->GetUnmirroredGeometry();
2747 long myWidth
= nOldWidth
;
2749 myWidth
= aSysGeometry
.nWidth
;
2752 nFlags
|= PosSizeFlags::X
;
2753 nSysFlags
|= SAL_FRAME_POSSIZE_X
;
2754 nX
= aParentSysGeometry
.nX
- aSysGeometry
.nLeftDecoration
+ aParentSysGeometry
.nWidth
2755 - myWidth
- 1 - aSysGeometry
.nX
;
2759 if( nFlags
& PosSizeFlags::Y
)
2761 nSysFlags
|= SAL_FRAME_POSSIZE_Y
;
2762 if( pWinParent
&& (pWindow
->GetStyle() & WB_SYSTEMCHILDWINDOW
) )
2764 nY
+= pWinParent
->mnOutOffY
;
2768 if( nSysFlags
& (SAL_FRAME_POSSIZE_WIDTH
|SAL_FRAME_POSSIZE_HEIGHT
) )
2770 // check for min/max client size and adjust size accordingly
2771 // otherwise it may happen that the resize event is ignored, i.e. the old size remains
2772 // unchanged but ImplHandleResize() is called with the wrong size
2773 SystemWindow
*pSystemWindow
= dynamic_cast< SystemWindow
* >( pWindow
.get() );
2776 Size aMinSize
= pSystemWindow
->GetMinOutputSizePixel();
2777 Size aMaxSize
= pSystemWindow
->GetMaxOutputSizePixel();
2778 if( nWidth
< aMinSize
.Width() )
2779 nWidth
= aMinSize
.Width();
2780 if( nHeight
< aMinSize
.Height() )
2781 nHeight
= aMinSize
.Height();
2783 if( nWidth
> aMaxSize
.Width() )
2784 nWidth
= aMaxSize
.Width();
2785 if( nHeight
> aMaxSize
.Height() )
2786 nHeight
= aMaxSize
.Height();
2790 pWindow
->mpWindowImpl
->mpFrame
->SetPosSize( nX
, nY
, nWidth
, nHeight
, nSysFlags
);
2792 // Resize should be called directly. If we haven't
2793 // set the correct size, we get a second resize from
2794 // the system with the correct size. This can be happened
2795 // if the size is too small or too large.
2796 ImplHandleResize( pWindow
, nWidth
, nHeight
);
2800 pWindow
->ImplPosSizeWindow( nX
, nY
, nWidth
, nHeight
, nFlags
);
2801 if ( IsReallyVisible() )
2802 ImplGenerateMouseMove();
2806 Point
Window::GetPosPixel() const
2808 return mpWindowImpl
->maPos
;
2811 tools::Rectangle
Window::GetDesktopRectPixel() const
2813 tools::Rectangle rRect
;
2814 mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpFrame
->GetWorkArea( rRect
);
2818 Point
Window::OutputToScreenPixel( const Point
& rPos
) const
2820 // relative to top level parent
2821 return Point( rPos
.X()+mnOutOffX
, rPos
.Y()+mnOutOffY
);
2824 Point
Window::ScreenToOutputPixel( const Point
& rPos
) const
2826 // relative to top level parent
2827 return Point( rPos
.X()-mnOutOffX
, rPos
.Y()-mnOutOffY
);
2830 long Window::ImplGetUnmirroredOutOffX()
2832 // revert mnOutOffX changes that were potentially made in ImplPosSizeWindow
2833 long offx
= mnOutOffX
;
2834 OutputDevice
*pOutDev
= GetOutDev();
2835 if( pOutDev
->HasMirroredGraphics() )
2837 if( mpWindowImpl
->mpParent
&& !mpWindowImpl
->mpParent
->mpWindowImpl
->mbFrame
&& mpWindowImpl
->mpParent
->ImplIsAntiparallel() )
2839 if ( !ImplIsOverlapWindow() )
2840 offx
-= mpWindowImpl
->mpParent
->mnOutOffX
;
2842 offx
= mpWindowImpl
->mpParent
->mnOutWidth
- mnOutWidth
- offx
;
2844 if ( !ImplIsOverlapWindow() )
2845 offx
+= mpWindowImpl
->mpParent
->mnOutOffX
;
2852 // normalized screen pixel are independent of mirroring
2853 Point
Window::OutputToNormalizedScreenPixel( const Point
& rPos
) const
2855 // relative to top level parent
2856 long offx
= const_cast<vcl::Window
*>(this)->ImplGetUnmirroredOutOffX();
2857 return Point( rPos
.X()+offx
, rPos
.Y()+mnOutOffY
);
2860 Point
Window::NormalizedScreenToOutputPixel( const Point
& rPos
) const
2862 // relative to top level parent
2863 long offx
= const_cast<vcl::Window
*>(this)->ImplGetUnmirroredOutOffX();
2864 return Point( rPos
.X()-offx
, rPos
.Y()-mnOutOffY
);
2867 Point
Window::OutputToAbsoluteScreenPixel( const Point
& rPos
) const
2869 // relative to the screen
2870 Point p
= OutputToScreenPixel( rPos
);
2871 SalFrameGeometry g
= mpWindowImpl
->mpFrame
->GetGeometry();
2877 Point
Window::AbsoluteScreenToOutputPixel( const Point
& rPos
) const
2879 // relative to the screen
2880 Point p
= ScreenToOutputPixel( rPos
);
2881 SalFrameGeometry g
= mpWindowImpl
->mpFrame
->GetGeometry();
2882 p
.AdjustX( -(g
.nX
) );
2883 p
.AdjustY( -(g
.nY
) );
2887 tools::Rectangle
Window::ImplOutputToUnmirroredAbsoluteScreenPixel( const tools::Rectangle
&rRect
) const
2889 // this method creates unmirrored screen coordinates to be compared with the desktop
2890 // and is used for positioning of RTL popup windows correctly on the screen
2891 SalFrameGeometry g
= mpWindowImpl
->mpFrame
->GetUnmirroredGeometry();
2893 Point p1
= OutputToScreenPixel( rRect
.TopRight() );
2894 p1
.setX( g
.nX
+g
.nWidth
-p1
.X() );
2897 Point p2
= OutputToScreenPixel( rRect
.BottomLeft() );
2898 p2
.setX( g
.nX
+g
.nWidth
-p2
.X() );
2901 return tools::Rectangle( p1
, p2
);
2904 tools::Rectangle
Window::GetWindowExtentsRelative( vcl::Window
*pRelativeWindow
) const
2907 return ImplGetWindowExtentsRelative( pRelativeWindow
, false );
2910 tools::Rectangle
Window::GetClientWindowExtentsRelative() const
2912 // without decoration
2913 return ImplGetWindowExtentsRelative( nullptr, true );
2916 tools::Rectangle
Window::ImplGetWindowExtentsRelative( vcl::Window
*pRelativeWindow
, bool bClientOnly
) const
2918 SalFrameGeometry g
= mpWindowImpl
->mpFrame
->GetGeometry();
2919 // make sure we use the extent of our border window,
2920 // otherwise we miss a few pixels
2921 const vcl::Window
*pWin
= (!bClientOnly
&& mpWindowImpl
->mpBorderWindow
) ? mpWindowImpl
->mpBorderWindow
: this;
2923 Point
aPos( pWin
->OutputToScreenPixel( Point(0,0) ) );
2924 aPos
.AdjustX(g
.nX
);
2925 aPos
.AdjustY(g
.nY
);
2926 Size
aSize ( pWin
->GetSizePixel() );
2927 // #104088# do not add decoration to the workwindow to be compatible to java accessibility api
2928 if( !bClientOnly
&& (mpWindowImpl
->mbFrame
|| (mpWindowImpl
->mpBorderWindow
&& mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbFrame
&& GetType() != WindowType::WORKWINDOW
)) )
2930 aPos
.AdjustX( -sal_Int32(g
.nLeftDecoration
) );
2931 aPos
.AdjustY( -sal_Int32(g
.nTopDecoration
) );
2932 aSize
.AdjustWidth(g
.nLeftDecoration
+ g
.nRightDecoration
);
2933 aSize
.AdjustHeight(g
.nTopDecoration
+ g
.nBottomDecoration
);
2935 if( pRelativeWindow
)
2937 // #106399# express coordinates relative to borderwindow
2938 vcl::Window
*pRelWin
= (!bClientOnly
&& pRelativeWindow
->mpWindowImpl
->mpBorderWindow
) ? pRelativeWindow
->mpWindowImpl
->mpBorderWindow
.get() : pRelativeWindow
;
2939 aPos
= pRelWin
->AbsoluteScreenToOutputPixel( aPos
);
2941 return tools::Rectangle( aPos
, aSize
);
2944 void Window::Scroll( long nHorzScroll
, long nVertScroll
, ScrollFlags nFlags
)
2947 ImplScroll( tools::Rectangle( Point( mnOutOffX
, mnOutOffY
),
2948 Size( mnOutWidth
, mnOutHeight
) ),
2949 nHorzScroll
, nVertScroll
, nFlags
& ~ScrollFlags::Clip
);
2952 void Window::Scroll( long nHorzScroll
, long nVertScroll
,
2953 const tools::Rectangle
& rRect
, ScrollFlags nFlags
)
2955 OutputDevice
*pOutDev
= GetOutDev();
2956 tools::Rectangle aRect
= pOutDev
->ImplLogicToDevicePixel( rRect
);
2957 aRect
.Intersection( tools::Rectangle( Point( mnOutOffX
, mnOutOffY
), Size( mnOutWidth
, mnOutHeight
) ) );
2958 if ( !aRect
.IsEmpty() )
2959 ImplScroll( aRect
, nHorzScroll
, nVertScroll
, nFlags
);
2962 void Window::Flush()
2966 const tools::Rectangle
aWinRect( Point( mnOutOffX
, mnOutOffY
), Size( mnOutWidth
, mnOutHeight
) );
2967 mpWindowImpl
->mpFrame
->Flush( aWinRect
);
2971 void Window::SetUpdateMode( bool bUpdate
)
2975 mpWindowImpl
->mbNoUpdate
= !bUpdate
;
2976 CompatStateChanged( StateChangedType::UpdateMode
);
2980 void Window::GrabFocus()
2982 ImplGrabFocus( GetFocusFlags::NONE
);
2985 bool Window::HasFocus() const
2987 return (this == ImplGetSVData()->maWinData
.mpFocusWin
);
2990 void Window::GrabFocusToDocument()
2992 ImplGrabFocusToDocument(GetFocusFlags::NONE
);
2995 VclPtr
<vcl::Window
> Window::GetFocusedWindow() const
2997 if (mpWindowImpl
&& mpWindowImpl
->mpFrameData
)
2998 return mpWindowImpl
->mpFrameData
->mpFocusWin
;
3000 return VclPtr
<vcl::Window
>();
3003 void Window::SetFakeFocus( bool bFocus
)
3005 ImplGetWindowImpl()->mbFakeFocusSet
= bFocus
;
3008 bool Window::HasChildPathFocus( bool bSystemWindow
) const
3011 vcl::Window
* pFocusWin
= ImplGetSVData()->maWinData
.mpFocusWin
;
3013 return ImplIsWindowOrChild( pFocusWin
, bSystemWindow
);
3017 void Window::SetCursor( vcl::Cursor
* pCursor
)
3020 if ( mpWindowImpl
->mpCursor
!= pCursor
)
3022 if ( mpWindowImpl
->mpCursor
)
3023 mpWindowImpl
->mpCursor
->ImplHide();
3024 mpWindowImpl
->mpCursor
= pCursor
;
3026 pCursor
->ImplShow();
3030 void Window::SetText( const OUString
& rStr
)
3032 if (!mpWindowImpl
|| rStr
== mpWindowImpl
->maText
)
3035 OUString
oldTitle( mpWindowImpl
->maText
);
3036 mpWindowImpl
->maText
= rStr
;
3038 if ( mpWindowImpl
->mpBorderWindow
)
3039 mpWindowImpl
->mpBorderWindow
->SetText( rStr
);
3040 else if ( mpWindowImpl
->mbFrame
)
3041 mpWindowImpl
->mpFrame
->SetTitle( rStr
);
3043 CallEventListeners( VclEventId::WindowFrameTitleChanged
, &oldTitle
);
3045 // #107247# needed for accessibility
3046 // The VclEventId::WindowFrameTitleChanged is (mis)used to notify accessible name changes.
3047 // Therefore a window, which is labeled by this window, must also notify an accessible
3049 if ( IsReallyVisible() )
3051 vcl::Window
* pWindow
= GetAccessibleRelationLabelFor();
3052 if ( pWindow
&& pWindow
!= this )
3053 pWindow
->CallEventListeners( VclEventId::WindowFrameTitleChanged
, &oldTitle
);
3056 CompatStateChanged( StateChangedType::Text
);
3059 OUString
Window::GetText() const
3062 return mpWindowImpl
->maText
;
3065 OUString
Window::GetDisplayText() const
3071 const Wallpaper
& Window::GetDisplayBackground() const
3073 // FIXME: fix issue 52349, need to fix this really in
3074 // all NWF enabled controls
3075 const ToolBox
* pTB
= dynamic_cast<const ToolBox
*>(this);
3076 if( pTB
&& IsNativeWidgetEnabled() )
3077 return pTB
->ImplGetToolBoxPrivateData()->maDisplayBackground
;
3079 if( !IsBackground() )
3081 if( mpWindowImpl
->mpParent
)
3082 return mpWindowImpl
->mpParent
->GetDisplayBackground();
3085 const Wallpaper
& rBack
= GetBackground();
3086 if( ! rBack
.IsBitmap() &&
3087 ! rBack
.IsGradient() &&
3088 rBack
.GetColor()== COL_TRANSPARENT
&&
3089 mpWindowImpl
->mpParent
)
3090 return mpWindowImpl
->mpParent
->GetDisplayBackground();
3094 const OUString
& Window::GetHelpText() const
3096 OUString
aStrHelpId( OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8
) );
3097 bool bStrHelpId
= !aStrHelpId
.isEmpty();
3099 if ( !mpWindowImpl
->maHelpText
.getLength() && bStrHelpId
)
3101 if ( !IsDialog() && (mpWindowImpl
->mnType
!= WindowType::TABPAGE
) && (mpWindowImpl
->mnType
!= WindowType::FLOATINGWINDOW
) )
3103 Help
* pHelp
= Application::GetHelp();
3106 mpWindowImpl
->maHelpText
= pHelp
->GetHelpText(aStrHelpId
, this);
3107 mpWindowImpl
->mbHelpTextDynamic
= false;
3111 else if( mpWindowImpl
->mbHelpTextDynamic
&& bStrHelpId
)
3113 static const char* pEnv
= getenv( "HELP_DEBUG" );
3116 OUString aTxt
= mpWindowImpl
->maHelpText
+ "\n------------------\n" + aStrHelpId
;
3117 mpWindowImpl
->maHelpText
= aTxt
;
3119 mpWindowImpl
->mbHelpTextDynamic
= false;
3122 //Fallback to Window::GetAccessibleDescription without reentry to GetHelpText()
3123 if (mpWindowImpl
->maHelpText
.isEmpty() && mpWindowImpl
->mpAccessibleInfos
&& mpWindowImpl
->mpAccessibleInfos
->pAccessibleDescription
)
3124 return *mpWindowImpl
->mpAccessibleInfos
->pAccessibleDescription
;
3125 return mpWindowImpl
->maHelpText
;
3128 void Window::SetWindowPeer( Reference
< css::awt::XWindowPeer
> const & xPeer
, VCLXWindow
* pVCLXWindow
)
3133 // be safe against re-entrance: first clear the old ref, then assign the new one
3134 mpWindowImpl
->mxWindowPeer
.clear();
3135 mpWindowImpl
->mxWindowPeer
= xPeer
;
3137 mpWindowImpl
->mpVCLXWindow
= pVCLXWindow
;
3140 Reference
< css::awt::XWindowPeer
> Window::GetComponentInterface( bool bCreate
)
3142 if ( !mpWindowImpl
->mxWindowPeer
.is() && bCreate
)
3144 UnoWrapperBase
* pWrapper
= UnoWrapperBase::GetUnoWrapper();
3146 mpWindowImpl
->mxWindowPeer
= pWrapper
->GetWindowInterface( this );
3148 return mpWindowImpl
->mxWindowPeer
;
3151 void Window::SetComponentInterface( Reference
< css::awt::XWindowPeer
> const & xIFace
)
3153 UnoWrapperBase
* pWrapper
= UnoWrapperBase::GetUnoWrapper();
3154 SAL_WARN_IF( !pWrapper
, "vcl.window", "SetComponentInterface: No Wrapper!" );
3156 pWrapper
->SetWindowInterface( this, xIFace
);
3159 typedef std::map
<vcl::LOKWindowId
, VclPtr
<vcl::Window
>> LOKWindowsMap
;
3163 LOKWindowsMap
& GetLOKWindowsMap()
3165 // never use this in the desktop case
3166 assert(comphelper::LibreOfficeKit::isActive());
3168 // Map to remember the LOKWindowId <-> Window binding.
3169 static LOKWindowsMap s_aLOKWindowsMap
;
3171 return s_aLOKWindowsMap
;
3176 void Window::SetLOKNotifier(const vcl::ILibreOfficeKitNotifier
* pNotifier
, bool bParent
)
3178 // don't allow setting this twice
3179 assert(mpWindowImpl
->mpLOKNotifier
== nullptr);
3181 // never use this in the desktop case
3182 assert(comphelper::LibreOfficeKit::isActive());
3186 // Counter to be able to have unique id's for each window.
3187 static vcl::LOKWindowId sLastLOKWindowId
= 1;
3189 // assign the LOK window id
3190 assert(mpWindowImpl
->mnLOKWindowId
== 0);
3191 mpWindowImpl
->mnLOKWindowId
= sLastLOKWindowId
++;
3192 GetLOKWindowsMap().insert(std::map
<vcl::LOKWindowId
, VclPtr
<vcl::Window
>>::value_type(mpWindowImpl
->mnLOKWindowId
, this));
3195 mpWindowImpl
->mbLOKParentNotifier
= true;
3197 mpWindowImpl
->mpLOKNotifier
= pNotifier
;
3200 VclPtr
<Window
> Window::FindLOKWindow(vcl::LOKWindowId nWindowId
)
3202 const auto it
= GetLOKWindowsMap().find(nWindowId
);
3203 if (it
!= GetLOKWindowsMap().end())
3206 return VclPtr
<Window
>();
3209 void Window::ReleaseLOKNotifier()
3211 // unregister the LOK window binding
3212 if (mpWindowImpl
->mnLOKWindowId
> 0)
3213 GetLOKWindowsMap().erase(mpWindowImpl
->mnLOKWindowId
);
3215 mpWindowImpl
->mpLOKNotifier
= nullptr;
3216 mpWindowImpl
->mnLOKWindowId
= 0;
3219 ILibreOfficeKitNotifier::~ILibreOfficeKitNotifier()
3221 if (!comphelper::LibreOfficeKit::isActive())
3226 for (auto it
= GetLOKWindowsMap().begin(); it
!= GetLOKWindowsMap().end();)
3228 WindowImpl
* pWindowImpl
= it
->second
->ImplGetWindowImpl();
3229 if (pWindowImpl
&& pWindowImpl
->mpLOKNotifier
== this)
3231 pWindowImpl
->mpLOKNotifier
= nullptr;
3232 pWindowImpl
->mnLOKWindowId
= 0;
3233 it
= GetLOKWindowsMap().erase(it
);
3241 const vcl::ILibreOfficeKitNotifier
* Window::GetLOKNotifier() const
3243 return mpWindowImpl
->mpLOKNotifier
;
3246 vcl::LOKWindowId
Window::GetLOKWindowId() const
3248 return mpWindowImpl
->mnLOKWindowId
;
3251 VclPtr
<vcl::Window
> Window::GetParentWithLOKNotifier()
3253 VclPtr
<vcl::Window
> pWindow(this);
3255 while (pWindow
&& !pWindow
->GetLOKNotifier())
3256 pWindow
= pWindow
->GetParent();
3264 const char* windowTypeName(WindowType nWindowType
)
3266 switch (nWindowType
)
3268 case WindowType::NONE
: return "none";
3269 case WindowType::MESSBOX
: return "messagebox";
3270 case WindowType::INFOBOX
: return "infobox";
3271 case WindowType::WARNINGBOX
: return "warningbox";
3272 case WindowType::ERRORBOX
: return "errorbox";
3273 case WindowType::QUERYBOX
: return "querybox";
3274 case WindowType::WINDOW
: return "window";
3275 case WindowType::WORKWINDOW
: return "workwindow";
3276 case WindowType::CONTAINER
: return "container";
3277 case WindowType::FLOATINGWINDOW
: return "floatingwindow";
3278 case WindowType::DIALOG
: return "dialog";
3279 case WindowType::MODELESSDIALOG
: return "modelessdialog";
3280 case WindowType::MODALDIALOG
: return "modaldialog";
3281 case WindowType::CONTROL
: return "control";
3282 case WindowType::PUSHBUTTON
: return "pushbutton";
3283 case WindowType::OKBUTTON
: return "okbutton";
3284 case WindowType::CANCELBUTTON
: return "cancelbutton";
3285 case WindowType::HELPBUTTON
: return "helpbutton";
3286 case WindowType::IMAGEBUTTON
: return "imagebutton";
3287 case WindowType::MENUBUTTON
: return "menubutton";
3288 case WindowType::MOREBUTTON
: return "morebutton";
3289 case WindowType::SPINBUTTON
: return "spinbutton";
3290 case WindowType::RADIOBUTTON
: return "radiobutton";
3291 case WindowType::CHECKBOX
: return "checkbox";
3292 case WindowType::TRISTATEBOX
: return "tristatebox";
3293 case WindowType::EDIT
: return "edit";
3294 case WindowType::MULTILINEEDIT
: return "multilineedit";
3295 case WindowType::COMBOBOX
: return "combobox";
3296 case WindowType::LISTBOX
: return "listbox";
3297 case WindowType::MULTILISTBOX
: return "multilistbox";
3298 case WindowType::FIXEDTEXT
: return "fixedtext";
3299 case WindowType::FIXEDLINE
: return "fixedline";
3300 case WindowType::FIXEDBITMAP
: return "fixedbitmap";
3301 case WindowType::FIXEDIMAGE
: return "fixedimage";
3302 case WindowType::GROUPBOX
: return "groupbox";
3303 case WindowType::SCROLLBAR
: return "scrollbar";
3304 case WindowType::SCROLLBARBOX
: return "scrollbarbox";
3305 case WindowType::SPLITTER
: return "splitter";
3306 case WindowType::SPLITWINDOW
: return "splitwindow";
3307 case WindowType::SPINFIELD
: return "spinfield";
3308 case WindowType::PATTERNFIELD
: return "patternfield";
3309 case WindowType::NUMERICFIELD
: return "numericfield";
3310 case WindowType::METRICFIELD
: return "metricfield";
3311 case WindowType::CURRENCYFIELD
: return "currencyfield";
3312 case WindowType::DATEFIELD
: return "datefield";
3313 case WindowType::TIMEFIELD
: return "timefield";
3314 case WindowType::PATTERNBOX
: return "patternbox";
3315 case WindowType::NUMERICBOX
: return "numericbox";
3316 case WindowType::METRICBOX
: return "metricbox";
3317 case WindowType::CURRENCYBOX
: return "currencybox";
3318 case WindowType::DATEBOX
: return "datebox";
3319 case WindowType::TIMEBOX
: return "timebox";
3320 case WindowType::LONGCURRENCYFIELD
: return "longcurrencyfield";
3321 case WindowType::LONGCURRENCYBOX
: return "longcurrencybox";
3322 case WindowType::SCROLLWINDOW
: return "scrollwindow";
3323 case WindowType::TOOLBOX
: return "toolbox";
3324 case WindowType::DOCKINGWINDOW
: return "dockingwindow";
3325 case WindowType::STATUSBAR
: return "statusbar";
3326 case WindowType::TABPAGE
: return "tabpage";
3327 case WindowType::TABCONTROL
: return "tabcontrol";
3328 case WindowType::TABDIALOG
: return "tabdialog";
3329 case WindowType::BORDERWINDOW
: return "borderwindow";
3330 case WindowType::BUTTONDIALOG
: return "buttondialog";
3331 case WindowType::SYSTEMCHILDWINDOW
: return "systemchildwindow";
3332 case WindowType::SLIDER
: return "slider";
3333 case WindowType::MENUBARWINDOW
: return "menubarwindow";
3334 case WindowType::TREELISTBOX
: return "treelistbox";
3335 case WindowType::HELPTEXTWINDOW
: return "helptextwindow";
3336 case WindowType::INTROWINDOW
: return "introwindow";
3337 case WindowType::LISTBOXWINDOW
: return "listboxwindow";
3338 case WindowType::DOCKINGAREA
: return "dockingarea";
3339 case WindowType::RULER
: return "ruler";
3340 case WindowType::CALCINPUTLINE
: return "calcinputline";
3341 case WindowType::HEADERBAR
: return "headerbar";
3342 case WindowType::VERTICALTABCONTROL
: return "verticaltabcontrol";
3344 // nothing to do here, but for completeness
3345 case WindowType::TOOLKIT_FRAMEWINDOW
: return "toolkit_framewindow";
3346 case WindowType::TOOLKIT_SYSTEMCHILDWINDOW
: return "toolkit_systemchildwindow";
3354 boost::property_tree::ptree
Window::DumpAsPropertyTree()
3356 boost::property_tree::ptree aTree
;
3357 aTree
.put("id", get_id()); // TODO could be missing - sort out
3358 aTree
.put("type", windowTypeName(GetType()));
3359 aTree
.put("text", GetText());
3360 aTree
.put("enabled", IsEnabled());
3362 boost::property_tree::ptree aChildren
;
3363 if (vcl::Window
* pChild
= mpWindowImpl
->mpFirstChild
)
3367 if (pChild
->IsVisible()) {
3368 boost::property_tree::ptree aSubTree
= pChild
->DumpAsPropertyTree();
3369 int nLeft
= pChild
->get_grid_left_attach();
3370 int nTop
= pChild
->get_grid_top_attach();
3371 if (nLeft
!= -1 && nTop
!= -1)
3373 OUString sLeft
= OUString::number(nLeft
);
3374 OUString sTop
= OUString::number(nTop
);
3375 aSubTree
.put("left", sLeft
);
3376 aSubTree
.put("top", sTop
);
3378 aChildren
.push_back(std::make_pair("", aSubTree
));
3380 pChild
= pChild
->mpWindowImpl
->mpNext
;
3382 aTree
.add_child("children", aChildren
);
3388 void Window::ImplCallDeactivateListeners( vcl::Window
*pNew
)
3390 // no deactivation if the newly activated window is my child
3391 if ( !pNew
|| !ImplIsChild( pNew
) )
3393 VclPtr
<vcl::Window
> xWindow(this);
3394 CallEventListeners( VclEventId::WindowDeactivate
, pNew
);
3395 if( xWindow
->IsDisposed() )
3398 // #100759#, avoid walking the wrong frame's hierarchy
3399 // eg, undocked docking windows (ImplDockFloatWin)
3400 if ( ImplGetParent() && mpWindowImpl
->mpFrameWindow
== ImplGetParent()->mpWindowImpl
->mpFrameWindow
)
3401 ImplGetParent()->ImplCallDeactivateListeners( pNew
);
3405 void Window::ImplCallActivateListeners( vcl::Window
*pOld
)
3407 // no activation if the old active window is my child
3408 if ( !pOld
|| !ImplIsChild( pOld
) )
3410 VclPtr
<vcl::Window
> xWindow(this);
3411 CallEventListeners( VclEventId::WindowActivate
, pOld
);
3412 if( xWindow
->IsDisposed() )
3415 if ( ImplGetParent() )
3416 ImplGetParent()->ImplCallActivateListeners( pOld
);
3417 else if( (mpWindowImpl
->mnStyle
& WB_INTROWIN
) == 0 )
3419 // top level frame reached: store hint for DefModalDialogParent
3420 ImplGetSVData()->maWinData
.mpActiveApplicationFrame
= mpWindowImpl
->mpFrameWindow
;
3425 void Window::SetClipboard(Reference
<XClipboard
> const & xClipboard
)
3427 if (mpWindowImpl
->mpFrameData
)
3428 mpWindowImpl
->mpFrameData
->mxClipboard
= xClipboard
;
3431 Reference
< XClipboard
> Window::GetClipboard()
3433 if (!mpWindowImpl
->mpFrameData
)
3434 return static_cast<XClipboard
*>(nullptr);
3435 if (!mpWindowImpl
->mpFrameData
->mxClipboard
.is())
3436 mpWindowImpl
->mpFrameData
->mxClipboard
= GetSystemClipboard();
3437 return mpWindowImpl
->mpFrameData
->mxClipboard
;
3440 Reference
< XClipboard
> Window::GetPrimarySelection()
3442 if (!mpWindowImpl
->mpFrameData
)
3443 return static_cast<XClipboard
*>(nullptr);
3444 if (!mpWindowImpl
->mpFrameData
->mxSelection
.is())
3445 mpWindowImpl
->mpFrameData
->mxSelection
= GetSystemPrimarySelection();
3446 return mpWindowImpl
->mpFrameData
->mxSelection
;
3449 void Window::RecordLayoutData( vcl::ControlLayoutData
* pLayout
, const tools::Rectangle
& rRect
)
3451 assert(mpOutDevData
);
3452 mpOutDevData
->mpRecordLayout
= pLayout
;
3453 mpOutDevData
->maRecordRect
= rRect
;
3454 Paint(*this, rRect
);
3455 mpOutDevData
->mpRecordLayout
= nullptr;
3458 void Window::DrawSelectionBackground( const tools::Rectangle
& rRect
,
3459 sal_uInt16 highlight
,
3464 if( rRect
.IsEmpty() )
3467 const StyleSettings
& rStyles
= GetSettings().GetStyleSettings();
3469 // colors used for item highlighting
3470 Color
aSelectionBorderCol( rStyles
.GetHighlightColor() );
3471 Color
aSelectionFillCol( aSelectionBorderCol
);
3473 bool bDark
= rStyles
.GetFaceColor().IsDark();
3474 bool bBright
= ( rStyles
.GetFaceColor() == COL_WHITE
);
3476 int c1
= aSelectionBorderCol
.GetLuminance();
3477 int c2
= GetBackgroundColor().GetLuminance();
3479 if( !bDark
&& !bBright
&& abs( c2
-c1
) < 75 )
3483 aSelectionFillCol
.RGBtoHSB( h
, s
, b
);
3484 if( b
> 50 ) b
-= 40;
3486 aSelectionFillCol
= Color::HSBtoRGB( h
, s
, b
);
3487 aSelectionBorderCol
= aSelectionFillCol
;
3490 tools::Rectangle
aRect( rRect
);
3491 Color oldFillCol
= GetFillColor();
3492 Color oldLineCol
= GetLineColor();
3495 SetLineColor( bDark
? COL_WHITE
: ( bBright
? COL_BLACK
: aSelectionBorderCol
) );
3499 sal_uInt16 nPercent
= 0;
3503 aSelectionFillCol
= COL_BLACK
;
3505 nPercent
= 80; // just checked (light)
3509 if( bChecked
&& highlight
== 2 )
3512 aSelectionFillCol
= COL_LIGHTGRAY
;
3515 aSelectionFillCol
= COL_BLACK
;
3516 SetLineColor( COL_BLACK
);
3520 nPercent
= 20; // selected, pressed or checked ( very dark )
3522 else if( bChecked
|| highlight
== 1 )
3525 aSelectionFillCol
= COL_GRAY
;
3528 aSelectionFillCol
= COL_BLACK
;
3529 SetLineColor( COL_BLACK
);
3533 nPercent
= 35; // selected, pressed or checked ( very dark )
3538 aSelectionFillCol
= COL_LIGHTGRAY
;
3541 aSelectionFillCol
= COL_BLACK
;
3542 SetLineColor( COL_BLACK
);
3543 if( highlight
== 3 )
3549 nPercent
= 70; // selected ( dark )
3553 SetFillColor( aSelectionFillCol
);
3561 tools::Polygon
aPoly( aRect
);
3562 tools::PolyPolygon
aPolyPoly( aPoly
);
3563 DrawTransparent( aPolyPoly
, nPercent
);
3566 SetFillColor( oldFillCol
);
3567 SetLineColor( oldLineCol
);
3570 bool Window::IsScrollable() const
3572 // check for scrollbars
3573 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
3576 if( pChild
->GetType() == WindowType::SCROLLBAR
)
3579 pChild
= pChild
->mpWindowImpl
->mpNext
;
3584 void Window::ImplMirrorFramePos( Point
&pt
) const
3586 pt
.setX( mpWindowImpl
->mpFrame
->maGeometry
.nWidth
-1-pt
.X() );
3589 // frame based modal counter (dialogs are not modal to the whole application anymore)
3590 bool Window::IsInModalMode() const
3592 return (mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpFrameData
->mnModalMode
!= 0);
3595 void Window::IncModalCount()
3597 vcl::Window
* pFrameWindow
= mpWindowImpl
->mpFrameWindow
;
3598 vcl::Window
* pParent
= pFrameWindow
;
3599 while( pFrameWindow
)
3601 pFrameWindow
->mpWindowImpl
->mpFrameData
->mnModalMode
++;
3602 while( pParent
&& pParent
->mpWindowImpl
->mpFrameWindow
== pFrameWindow
)
3604 pParent
= pParent
->GetParent();
3606 pFrameWindow
= pParent
? pParent
->mpWindowImpl
->mpFrameWindow
.get() : nullptr;
3609 void Window::DecModalCount()
3611 vcl::Window
* pFrameWindow
= mpWindowImpl
->mpFrameWindow
;
3612 vcl::Window
* pParent
= pFrameWindow
;
3613 while( pFrameWindow
)
3615 pFrameWindow
->mpWindowImpl
->mpFrameData
->mnModalMode
--;
3616 while( pParent
&& pParent
->mpWindowImpl
->mpFrameWindow
== pFrameWindow
)
3618 pParent
= pParent
->GetParent();
3620 pFrameWindow
= pParent
? pParent
->mpWindowImpl
->mpFrameWindow
.get() : nullptr;
3624 void Window::ImplIsInTaskPaneList( bool mbIsInTaskList
)
3626 mpWindowImpl
->mbIsInTaskPaneList
= mbIsInTaskList
;
3629 void Window::ImplNotifyIconifiedState( bool bIconified
)
3631 mpWindowImpl
->mpFrameWindow
->CallEventListeners( bIconified
? VclEventId::WindowMinimize
: VclEventId::WindowNormalize
);
3632 // #109206# notify client window as well to have toolkit topwindow listeners notified
3633 if( mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpClientWindow
&& mpWindowImpl
->mpFrameWindow
!= mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpClientWindow
)
3634 mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mpClientWindow
->CallEventListeners( bIconified
? VclEventId::WindowMinimize
: VclEventId::WindowNormalize
);
3637 bool Window::HasActiveChildFrame() const
3640 vcl::Window
*pFrameWin
= ImplGetSVData()->maWinData
.mpFirstFrame
;
3643 if( pFrameWin
!= mpWindowImpl
->mpFrameWindow
)
3645 bool bDecorated
= false;
3646 VclPtr
< vcl::Window
> pChildFrame
= pFrameWin
->ImplGetWindow();
3647 // #i15285# unfortunately WB_MOVEABLE is the same as WB_TABSTOP which can
3648 // be removed for ToolBoxes to influence the keyboard accessibility
3649 // thus WB_MOVEABLE is no indicator for decoration anymore
3650 // but FloatingWindows carry this information in their TitleType...
3651 // TODO: avoid duplicate WinBits !!!
3652 if( pChildFrame
&& pChildFrame
->ImplIsFloatingWindow() )
3653 bDecorated
= static_cast<FloatingWindow
*>(pChildFrame
.get())->GetTitleType() != FloatWinTitleType::NONE
;
3654 if( bDecorated
|| (pFrameWin
->mpWindowImpl
->mnStyle
& (WB_MOVEABLE
| WB_SIZEABLE
) ) )
3655 if( pChildFrame
&& pChildFrame
->IsVisible() && pChildFrame
->IsActive() )
3657 if( ImplIsChild( pChildFrame
, true ) )
3664 pFrameWin
= pFrameWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
3669 LanguageType
Window::GetInputLanguage() const
3671 return mpWindowImpl
->mpFrame
->GetInputLanguage();
3674 void Window::EnableNativeWidget( bool bEnable
)
3676 static const char* pNoNWF
= getenv( "SAL_NO_NWF" );
3677 if( pNoNWF
&& *pNoNWF
)
3680 if( bEnable
!= ImplGetWinData()->mbEnableNativeWidget
)
3682 ImplGetWinData()->mbEnableNativeWidget
= bEnable
;
3684 // send datachanged event to allow for internal changes required for NWF
3685 // like clipmode, transparency, etc.
3686 DataChangedEvent
aDCEvt( DataChangedEventType::SETTINGS
, mxSettings
.get(), AllSettingsFlags::STYLE
);
3687 CompatDataChanged( aDCEvt
);
3689 // sometimes the borderwindow is queried, so keep it in sync
3690 if( mpWindowImpl
->mpBorderWindow
)
3691 mpWindowImpl
->mpBorderWindow
->ImplGetWinData()->mbEnableNativeWidget
= bEnable
;
3694 // push down, useful for compound controls
3695 VclPtr
< vcl::Window
> pChild
= mpWindowImpl
->mpFirstChild
;
3698 pChild
->EnableNativeWidget( bEnable
);
3699 pChild
= pChild
->mpWindowImpl
->mpNext
;
3703 bool Window::IsNativeWidgetEnabled() const
3705 return ImplGetWinData()->mbEnableNativeWidget
;
3708 Reference
< css::rendering::XCanvas
> Window::ImplGetCanvas( bool bSpriteCanvas
) const
3710 // try to retrieve hard reference from weak member
3711 Reference
< css::rendering::XCanvas
> xCanvas( mpWindowImpl
->mxCanvas
);
3713 // canvas still valid? Then we're done.
3717 Sequence
< Any
> aArg(5);
3719 // Feed any with operating system's window handle
3721 // common: first any is VCL pointer to window (for VCL canvas)
3722 aArg
[ 0 ] <<= reinterpret_cast<sal_Int64
>(this);
3723 aArg
[ 1 ] <<= css::awt::Rectangle( mnOutOffX
, mnOutOffY
, mnOutWidth
, mnOutHeight
);
3724 aArg
[ 2 ] <<= mpWindowImpl
->mbAlwaysOnTop
;
3725 aArg
[ 3 ] <<= Reference
< css::awt::XWindow
>(
3726 const_cast<vcl::Window
*>(this)->GetComponentInterface(),
3728 aArg
[ 4 ] = GetSystemGfxDataAny();
3730 Reference
< XComponentContext
> xContext
= comphelper::getProcessComponentContext();
3732 // Create canvas instance with window handle
3734 static vcl::DeleteUnoReferenceOnDeinit
<XMultiComponentFactory
> xStaticCanvasFactory(
3735 css::rendering::CanvasFactory::create( xContext
) );
3736 Reference
<XMultiComponentFactory
> xCanvasFactory(xStaticCanvasFactory
.get());
3738 if(xCanvasFactory
.is())
3741 // see #140456# - if we're running on a multiscreen setup,
3742 // request special, multi-screen safe sprite canvas
3743 // implementation (not DX5 canvas, as it cannot cope with
3744 // surfaces spanning multiple displays). Note: canvas
3745 // (without sprite) stays the same)
3746 const sal_uInt32 nDisplay
= static_cast< WinSalFrame
* >( mpWindowImpl
->mpFrame
)->mnDisplay
;
3747 if( nDisplay
>= Application::GetScreenCount() )
3749 xCanvas
.set( xCanvasFactory
->createInstanceWithArgumentsAndContext(
3751 OUString( "com.sun.star.rendering.SpriteCanvas.MultiScreen" ) :
3752 OUString( "com.sun.star.rendering.Canvas.MultiScreen" ),
3761 xCanvas
.set( xCanvasFactory
->createInstanceWithArgumentsAndContext(
3763 OUString( "com.sun.star.rendering.SpriteCanvas" ) :
3764 OUString( "com.sun.star.rendering.Canvas" ),
3770 mpWindowImpl
->mxCanvas
= xCanvas
;
3773 // no factory??? Empty reference, then.
3777 Reference
< css::rendering::XCanvas
> Window::GetCanvas() const
3779 return ImplGetCanvas( false );
3782 Reference
< css::rendering::XSpriteCanvas
> Window::GetSpriteCanvas() const
3784 Reference
< css::rendering::XSpriteCanvas
> xSpriteCanvas(
3785 ImplGetCanvas( true ), UNO_QUERY
);
3786 return xSpriteCanvas
;
3789 OUString
Window::GetSurroundingText() const
3794 Selection
Window::GetSurroundingTextSelection() const
3796 return Selection( 0, 0 );
3799 bool Window::UsePolyPolygonForComplexGradient()
3801 return meRasterOp
!= RasterOp::OverPaint
;
3804 void Window::ApplySettings(vcl::RenderContext
& /*rRenderContext*/)
3808 const SystemEnvData
* Window::GetSystemData() const
3811 return mpWindowImpl
->mpFrame
? mpWindowImpl
->mpFrame
->GetSystemData() : nullptr;
3814 bool Window::SupportsDoubleBuffering() const
3816 return mpWindowImpl
->mpFrameData
->mpBuffer
;
3819 void Window::RequestDoubleBuffering(bool bRequest
)
3823 mpWindowImpl
->mpFrameData
->mpBuffer
= VclPtrInstance
<VirtualDevice
>();
3824 // Make sure that the buffer size matches the frame size.
3825 mpWindowImpl
->mpFrameData
->mpBuffer
->SetOutputSizePixel(mpWindowImpl
->mpFrameWindow
->GetOutputSizePixel());
3828 mpWindowImpl
->mpFrameData
->mpBuffer
.reset();
3832 * The rational here is that we moved destructors to
3833 * dispose and this altered a lot of code paths, that
3834 * are better left unchanged for now.
3836 #define COMPAT_BODY(method,args) \
3837 if (!mpWindowImpl || mpWindowImpl->mbInDispose) \
3838 Window::method args; \
3842 void Window::CompatGetFocus()
3844 COMPAT_BODY(GetFocus
,())
3847 void Window::CompatLoseFocus()
3849 COMPAT_BODY(LoseFocus
,())
3852 void Window::CompatStateChanged( StateChangedType nStateChange
)
3854 COMPAT_BODY(StateChanged
,(nStateChange
))
3857 void Window::CompatDataChanged( const DataChangedEvent
& rDCEvt
)
3859 COMPAT_BODY(DataChanged
,(rDCEvt
))
3862 bool Window::CompatPreNotify( NotifyEvent
& rNEvt
)
3864 if (!mpWindowImpl
|| mpWindowImpl
->mbInDispose
)
3865 return Window::PreNotify( rNEvt
);
3867 return PreNotify( rNEvt
);
3870 bool Window::CompatNotify( NotifyEvent
& rNEvt
)
3872 if (!mpWindowImpl
|| mpWindowImpl
->mbInDispose
)
3873 return Window::EventNotify( rNEvt
);
3875 return EventNotify( rNEvt
);
3878 void Window::set_id(const OUString
& rID
)
3880 mpWindowImpl
->maID
= rID
;
3883 const OUString
& Window::get_id() const
3885 return mpWindowImpl
->maID
;
3888 FactoryFunction
Window::GetUITestFactory() const
3890 return WindowUIObject::create
;
3893 } /* namespace vcl */
3895 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */