1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
24 #include <tools/debug.hxx>
26 #include <vcl/layout.hxx>
27 #include <vcl/settings.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/menu.hxx>
30 #include <vcl/event.hxx>
31 #include <vcl/syswin.hxx>
32 #include <vcl/taskpanelist.hxx>
33 #include <vcl/unowrap.hxx>
34 #include <vcl/tabctrl.hxx>
35 #include <vcl/tabpage.hxx>
36 #include <vcl/mnemonic.hxx>
38 #include <rtl/strbuf.hxx>
40 #include <salframe.hxx>
45 using namespace ::com::sun::star::uno
;
46 using namespace ::com::sun::star::lang
;
48 class SystemWindow::ImplData
53 std::unique_ptr
<TaskPaneList
>
56 OUString maRepresentedURL
;
57 Link
<SystemWindow
&,void> maCloseHdl
;
60 SystemWindow::ImplData::ImplData()
62 mpTaskPaneList
= nullptr;
63 maMaxOutSize
= Size( SHRT_MAX
, SHRT_MAX
);
66 SystemWindow::SystemWindow(WindowType nType
)
74 , mbIsCalculatingInitialLayoutSize(false)
75 , mnMenuBarMode(MenuBarMode::Normal
)
77 , mpImplData(new ImplData
)
78 , mbIsDefferedInit(false)
80 mpWindowImpl
->mbSysWin
= true;
81 mpWindowImpl
->mnActivateMode
= ActivateModeFlags::GrabFocus
;
83 //To-Do, reuse maResizeTimer
84 maLayoutIdle
.SetPriority(SchedulerPriority::RESIZE
);
85 maLayoutIdle
.SetIdleHdl( LINK( this, SystemWindow
, ImplHandleLayoutTimerHdl
) );
86 maLayoutIdle
.SetDebugName( "vcl::SystemWindow maLayoutIdle" );
89 void SystemWindow::loadUI(vcl::Window
* pParent
, const OString
& rID
, const OUString
& rUIXMLDescription
,
90 const css::uno::Reference
<css::frame::XFrame
> &rFrame
)
92 mbIsDefferedInit
= true;
93 mpDialogParent
= pParent
; //should be unset in doDeferredInit
94 m_pUIBuilder
.reset( new VclBuilder(this, getUIRootDir(), rUIXMLDescription
, rID
, rFrame
) );
97 SystemWindow::~SystemWindow()
102 void SystemWindow::dispose()
106 mpImplData
= nullptr;
108 // Hack to make sure code called from base ~Window does not interpret this
109 // as a SystemWindow (which it no longer is by then):
110 mpWindowImpl
->mbSysWin
= false;
112 mpDialogParent
.clear();
117 void ImplHandleControlAccelerator( vcl::Window
* pWindow
, bool bShow
)
119 Control
*pControl
= dynamic_cast<Control
*>(pWindow
->ImplGetWindow());
120 if (pControl
&& pControl
->GetText().indexOf('~') != -1)
122 pControl
->SetShowAccelerator( bShow
);
123 pControl
->Invalidate(InvalidateFlags::Update
);
129 void processChildren(vcl::Window
*pParent
, bool bShowAccel
)
131 // go through its children
132 vcl::Window
* pChild
= firstLogicalChildOfParent(pParent
);
135 if (pChild
->GetType() == WINDOW_TABCONTROL
)
137 // find currently shown tab page
138 TabControl
* pTabControl
= static_cast<TabControl
*>(pChild
);
139 TabPage
* pTabPage
= pTabControl
->GetTabPage( pTabControl
->GetCurPageId() );
140 processChildren(pTabPage
, bShowAccel
);
142 else if (pChild
->GetType() == WINDOW_TABPAGE
)
144 // bare tabpage without tabcontrol parent (options dialog)
145 processChildren(pChild
, bShowAccel
);
147 else if ((pChild
->GetStyle() & (WB_DIALOGCONTROL
| WB_NODIALOGCONTROL
)) == WB_DIALOGCONTROL
)
149 // special controls that manage their children outside of widget layout
150 processChildren(pChild
, bShowAccel
);
154 ImplHandleControlAccelerator(pChild
, bShowAccel
);
156 pChild
= nextLogicalChildOfParent(pParent
, pChild
);
161 bool Accelerator::ToggleMnemonicsOnHierarchy(const CommandEvent
& rCEvent
, vcl::Window
*pWindow
)
163 if (rCEvent
.GetCommand() == CommandEventId::ModKeyChange
&& ImplGetSVData()->maNWFData
.mbAutoAccel
)
165 const CommandModKeyData
*pCData
= rCEvent
.GetModKeyData();
166 const bool bShowAccel
= pCData
&& pCData
->IsMod2() && pCData
->IsDown();
167 processChildren(pWindow
, bShowAccel
);
173 bool SystemWindow::EventNotify( NotifyEvent
& rNEvt
)
175 if (rNEvt
.GetType() == MouseNotifyEvent::COMMAND
)
176 Accelerator::ToggleMnemonicsOnHierarchy(*rNEvt
.GetCommandEvent(), this);
178 // capture KeyEvents for menu handling
179 if (rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
||
180 rNEvt
.GetType() == MouseNotifyEvent::COMMAND
)
182 MenuBar
* pMBar
= mpMenuBar
;
183 if ( !pMBar
&& ( GetType() == WINDOW_FLOATINGWINDOW
) )
185 vcl::Window
* pWin
= ImplGetFrameWindow()->ImplGetWindow();
186 if( pWin
&& pWin
->IsSystemWindow() )
187 pMBar
= static_cast<SystemWindow
*>(pWin
)->GetMenuBar();
192 if (rNEvt
.GetType() == MouseNotifyEvent::COMMAND
)
193 bDone
= pMBar
->ImplHandleCmdEvent(*rNEvt
.GetCommandEvent());
195 bDone
= pMBar
->ImplHandleKeyEvent(*rNEvt
.GetKeyEvent());
201 return Window::EventNotify( rNEvt
);
204 bool SystemWindow::PreNotify( NotifyEvent
& rNEvt
)
206 // capture KeyEvents for taskpane cycling
207 if ( rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
)
209 if( rNEvt
.GetKeyEvent()->GetKeyCode().GetCode() == KEY_F6
&&
210 rNEvt
.GetKeyEvent()->GetKeyCode().IsMod1() &&
211 !rNEvt
.GetKeyEvent()->GetKeyCode().IsShift() )
213 // Ctrl-F6 goes directly to the document
214 GrabFocusToDocument();
219 TaskPaneList
*pTList
= mpImplData
->mpTaskPaneList
.get();
220 if( !pTList
&& ( GetType() == WINDOW_FLOATINGWINDOW
) )
222 vcl::Window
* pWin
= ImplGetFrameWindow()->ImplGetWindow();
223 if( pWin
&& pWin
->IsSystemWindow() )
224 pTList
= static_cast<SystemWindow
*>(pWin
)->mpImplData
->mpTaskPaneList
.get();
228 // search topmost system window which is the one to handle dialog/toolbar cycling
229 SystemWindow
*pSysWin
= this;
230 vcl::Window
*pWin
= this;
233 pWin
= pWin
->GetParent();
234 if( pWin
&& pWin
->IsSystemWindow() )
235 pSysWin
= static_cast<SystemWindow
*>(pWin
);
237 pTList
= pSysWin
->mpImplData
->mpTaskPaneList
.get();
239 if( pTList
&& pTList
->HandleKeyEvent( *rNEvt
.GetKeyEvent() ) )
243 return Window::PreNotify( rNEvt
);
246 TaskPaneList
* SystemWindow::GetTaskPaneList()
250 if( mpImplData
->mpTaskPaneList
)
251 return mpImplData
->mpTaskPaneList
.get();
254 mpImplData
->mpTaskPaneList
.reset( new TaskPaneList
);
255 MenuBar
* pMBar
= mpMenuBar
;
256 if ( !pMBar
&& ( GetType() == WINDOW_FLOATINGWINDOW
) )
258 vcl::Window
* pWin
= ImplGetFrameWindow()->ImplGetWindow();
259 if ( pWin
&& pWin
->IsSystemWindow() )
260 pMBar
= static_cast<SystemWindow
*>(pWin
)->GetMenuBar();
263 mpImplData
->mpTaskPaneList
->AddWindow( pMBar
->ImplGetWindow() );
264 return mpImplData
->mpTaskPaneList
.get();
268 bool SystemWindow::Close()
270 VclPtr
<vcl::Window
> xWindow
= this;
271 CallEventListeners( VCLEVENT_WINDOW_CLOSE
);
272 if ( xWindow
->IsDisposed() )
275 if ( mpWindowImpl
->mxWindowPeer
.is() && IsCreatedWithToolkit() )
278 // Is Window not closeable, ignore close
279 vcl::Window
* pBorderWin
= ImplGetBorderWindow();
282 nStyle
= pBorderWin
->GetStyle();
285 if ( !(nStyle
& WB_CLOSEABLE
) )
293 void SystemWindow::TitleButtonClick( TitleButton
)
297 void SystemWindow::Resizing( Size
& )
301 void SystemWindow::SetRepresentedURL( const OUString
& i_rURL
)
303 bool bChanged
= (i_rURL
!= mpImplData
->maRepresentedURL
);
304 mpImplData
->maRepresentedURL
= i_rURL
;
305 if ( !mbSysChild
&& bChanged
)
307 const vcl::Window
* pWindow
= this;
308 while ( pWindow
->mpWindowImpl
->mpBorderWindow
)
309 pWindow
= pWindow
->mpWindowImpl
->mpBorderWindow
;
311 if ( pWindow
->mpWindowImpl
->mbFrame
)
312 pWindow
->mpWindowImpl
->mpFrame
->SetRepresentedURL( i_rURL
);
316 void SystemWindow::SetIcon( sal_uInt16 nIcon
)
318 if ( mnIcon
== nIcon
)
325 const vcl::Window
* pWindow
= this;
326 while ( pWindow
->mpWindowImpl
->mpBorderWindow
)
327 pWindow
= pWindow
->mpWindowImpl
->mpBorderWindow
;
329 if ( pWindow
->mpWindowImpl
->mbFrame
)
330 pWindow
->mpWindowImpl
->mpFrame
->SetIcon( nIcon
);
334 void SystemWindow::ShowTitleButton( TitleButton nButton
, bool bVisible
)
336 if ( nButton
== TitleButton::Docking
)
338 if ( mbDockBtn
!= bVisible
)
340 mbDockBtn
= bVisible
;
341 if ( mpWindowImpl
->mpBorderWindow
)
342 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetDockButton( bVisible
);
345 else if ( nButton
== TitleButton::Hide
)
347 if ( mbHideBtn
!= bVisible
)
349 mbHideBtn
= bVisible
;
350 if ( mpWindowImpl
->mpBorderWindow
)
351 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetHideButton( bVisible
);
354 else if ( nButton
== TitleButton::Menu
)
356 if ( mpWindowImpl
->mpBorderWindow
)
357 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMenuButton( bVisible
);
363 bool SystemWindow::IsTitleButtonVisible( TitleButton nButton
) const
365 if ( nButton
== TitleButton::Docking
)
367 else /* if ( nButton == TitleButton::Hide ) */
371 void SystemWindow::SetPin( bool bPin
)
373 if ( bPin
!= mbPinned
)
376 if ( mpWindowImpl
->mpBorderWindow
)
377 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetPin( bPin
);
381 void SystemWindow::RollUp()
385 maOrgSize
= GetOutputSizePixel();
387 Size aSize
= maRollUpOutSize
;
388 if ( !aSize
.Width() )
389 aSize
.Width() = GetOutputSizePixel().Width();
391 if ( mpWindowImpl
->mpBorderWindow
)
392 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetRollUp( true, aSize
);
394 SetOutputSizePixel( aSize
);
399 void SystemWindow::RollDown()
404 if ( mpWindowImpl
->mpBorderWindow
)
405 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetRollUp( false, maOrgSize
);
407 SetOutputSizePixel( maOrgSize
);
411 void SystemWindow::SetMinOutputSizePixel( const Size
& rSize
)
413 maMinOutSize
= rSize
;
414 if ( mpWindowImpl
->mpBorderWindow
)
416 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMinOutputSize( rSize
.Width(), rSize
.Height() );
417 if ( mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbFrame
)
418 mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mpFrame
->SetMinClientSize( rSize
.Width(), rSize
.Height() );
420 else if ( mpWindowImpl
->mbFrame
)
421 mpWindowImpl
->mpFrame
->SetMinClientSize( rSize
.Width(), rSize
.Height() );
424 void SystemWindow::SetMaxOutputSizePixel( const Size
& rSize
)
427 if( aSize
.Width() > SHRT_MAX
|| aSize
.Width() <= 0 )
428 aSize
.Width() = SHRT_MAX
;
429 if( aSize
.Height() > SHRT_MAX
|| aSize
.Height() <= 0 )
430 aSize
.Height() = SHRT_MAX
;
432 mpImplData
->maMaxOutSize
= aSize
;
433 if ( mpWindowImpl
->mpBorderWindow
)
435 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMaxOutputSize( aSize
.Width(), aSize
.Height() );
436 if ( mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbFrame
)
437 mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mpFrame
->SetMaxClientSize( aSize
.Width(), aSize
.Height() );
439 else if ( mpWindowImpl
->mbFrame
)
440 mpWindowImpl
->mpFrame
->SetMaxClientSize( aSize
.Width(), aSize
.Height() );
443 const Size
& SystemWindow::GetMaxOutputSizePixel() const
445 return mpImplData
->maMaxOutSize
;
448 static void ImplWindowStateFromStr(WindowStateData
& rData
,
451 WindowStateMask nValidMask
= WindowStateMask::NONE
;
452 sal_Int32 nIndex
= 0;
455 aTokenStr
= rStr
.getToken(0, ',', nIndex
);
456 if (!aTokenStr
.isEmpty())
458 rData
.SetX(aTokenStr
.toInt32());
459 if( rData
.GetX() > -16384 && rData
.GetX() < 16384 )
460 nValidMask
|= WindowStateMask::X
;
466 aTokenStr
= rStr
.getToken(0, ',', nIndex
);
467 if (!aTokenStr
.isEmpty())
469 rData
.SetY(aTokenStr
.toInt32());
470 if( rData
.GetY() > -16384 && rData
.GetY() < 16384 )
471 nValidMask
|= WindowStateMask::Y
;
477 aTokenStr
= rStr
.getToken(0, ',', nIndex
);
478 if (!aTokenStr
.isEmpty())
480 rData
.SetWidth(aTokenStr
.toInt32());
481 if( rData
.GetWidth() > 0 && rData
.GetWidth() < 16384 )
482 nValidMask
|= WindowStateMask::Width
;
488 aTokenStr
= rStr
.getToken(0, ';', nIndex
);
489 if (!aTokenStr
.isEmpty())
491 rData
.SetHeight(aTokenStr
.toInt32());
492 if( rData
.GetHeight() > 0 && rData
.GetHeight() < 16384 )
493 nValidMask
|= WindowStateMask::Height
;
495 rData
.SetHeight( 0 );
498 rData
.SetHeight( 0 );
499 aTokenStr
= rStr
.getToken(0, ';', nIndex
);
500 if (!aTokenStr
.isEmpty())
502 // #94144# allow Minimize again, should be masked out when read from configuration
503 // 91625 - ignore Minimize
504 WindowStateState nState
= (WindowStateState
)aTokenStr
.toInt32();
505 //nState &= ~(WindowStateState::Minimized);
506 rData
.SetState( nState
);
507 nValidMask
|= WindowStateMask::State
;
510 rData
.SetState( WindowStateState::NONE
);
512 // read maximized pos/size
513 aTokenStr
= rStr
.getToken(0, ',', nIndex
);
514 if (!aTokenStr
.isEmpty())
516 rData
.SetMaximizedX(aTokenStr
.toInt32());
517 if( rData
.GetMaximizedX() > -16384 && rData
.GetMaximizedX() < 16384 )
518 nValidMask
|= WindowStateMask::MaximizedX
;
520 rData
.SetMaximizedX( 0 );
523 rData
.SetMaximizedX( 0 );
524 aTokenStr
= rStr
.getToken(0, ',', nIndex
);
525 if (!aTokenStr
.isEmpty())
527 rData
.SetMaximizedY(aTokenStr
.toInt32());
528 if( rData
.GetMaximizedY() > -16384 && rData
.GetMaximizedY() < 16384 )
529 nValidMask
|= WindowStateMask::MaximizedY
;
531 rData
.SetMaximizedY( 0 );
534 rData
.SetMaximizedY( 0 );
535 aTokenStr
= rStr
.getToken(0, ',', nIndex
);
536 if (!aTokenStr
.isEmpty())
538 rData
.SetMaximizedWidth(aTokenStr
.toInt32());
539 if( rData
.GetMaximizedWidth() > 0 && rData
.GetMaximizedWidth() < 16384 )
540 nValidMask
|= WindowStateMask::MaximizedWidth
;
542 rData
.SetMaximizedWidth( 0 );
545 rData
.SetMaximizedWidth( 0 );
546 aTokenStr
= rStr
.getToken(0, ';', nIndex
);
547 if (!aTokenStr
.isEmpty())
549 rData
.SetMaximizedHeight(aTokenStr
.toInt32());
550 if( rData
.GetMaximizedHeight() > 0 && rData
.GetMaximizedHeight() < 16384 )
551 nValidMask
|= WindowStateMask::MaximizedHeight
;
553 rData
.SetMaximizedHeight( 0 );
556 rData
.SetMaximizedHeight( 0 );
559 rData
.SetMask( nValidMask
);
562 static OString
ImplWindowStateToStr(const WindowStateData
& rData
)
564 const WindowStateMask nValidMask
= rData
.GetMask();
565 if ( nValidMask
== WindowStateMask::NONE
)
568 OStringBuffer rStrBuf
;
570 if ( nValidMask
& WindowStateMask::X
)
571 rStrBuf
.append(static_cast<sal_Int32
>(rData
.GetX()));
573 if ( nValidMask
& WindowStateMask::Y
)
574 rStrBuf
.append(static_cast<sal_Int32
>(rData
.GetY()));
576 if ( nValidMask
& WindowStateMask::Width
)
577 rStrBuf
.append(static_cast<sal_Int32
>(rData
.GetWidth()));
579 if ( nValidMask
& WindowStateMask::Height
)
580 rStrBuf
.append(static_cast<sal_Int32
>(rData
.GetHeight()));
581 rStrBuf
.append( ';' );
582 if ( nValidMask
& WindowStateMask::State
)
584 // #94144# allow Minimize again, should be masked out when read from configuration
585 // 91625 - ignore Minimize
586 WindowStateState nState
= rData
.GetState();
587 rStrBuf
.append(static_cast<sal_Int32
>(nState
));
590 if ( nValidMask
& WindowStateMask::MaximizedX
)
591 rStrBuf
.append(static_cast<sal_Int32
>(rData
.GetMaximizedX()));
593 if ( nValidMask
& WindowStateMask::MaximizedY
)
594 rStrBuf
.append(static_cast<sal_Int32
>(rData
.GetMaximizedY()));
595 rStrBuf
.append( ',' );
596 if ( nValidMask
& WindowStateMask::MaximizedWidth
)
597 rStrBuf
.append(static_cast<sal_Int32
>(rData
.GetMaximizedWidth()));
599 if ( nValidMask
& WindowStateMask::MaximizedHeight
)
600 rStrBuf
.append(static_cast<sal_Int32
>(rData
.GetMaximizedHeight()));
603 return rStrBuf
.makeStringAndClear();
606 void SystemWindow::ImplMoveToScreen( long& io_rX
, long& io_rY
, long i_nWidth
, long i_nHeight
, vcl::Window
* i_pConfigureWin
)
608 Rectangle aScreenRect
;
609 if( !Application::IsUnifiedDisplay() )
610 aScreenRect
= Application::GetScreenPosSizePixel( GetScreenNumber() );
613 aScreenRect
= Application::GetScreenPosSizePixel( 0 );
614 for( unsigned int i
= 1; i
< Application::GetScreenCount(); i
++ )
615 aScreenRect
.Union( Application::GetScreenPosSizePixel( i
) );
617 // unfortunately most of the time width and height are not really known
625 if( io_rX
+ i_nWidth
< aScreenRect
.Left() )
628 io_rX
= aScreenRect
.Left();
630 // check right border
631 if( io_rX
> aScreenRect
.Right() - i_nWidth
)
634 io_rX
= aScreenRect
.Right() - i_nWidth
;
637 if( io_rY
+ i_nHeight
< aScreenRect
.Top() )
640 io_rY
= aScreenRect
.Top();
642 // check bottom border
643 if( io_rY
> aScreenRect
.Bottom() - i_nHeight
)
646 io_rY
= aScreenRect
.Bottom() - i_nHeight
;
648 vcl::Window
* pParent
= i_pConfigureWin
->GetParent();
649 if( bMove
&& pParent
)
651 // calculate absolute screen pos here, since that is what is contained in WindowState
652 Point
aParentAbsPos( pParent
->OutputToAbsoluteScreenPixel( Point(0,0) ) );
653 Size
aParentSizePixel( pParent
->GetOutputSizePixel() );
654 Point
aPos( (aParentSizePixel
.Width() - i_nWidth
) / 2,
655 (aParentSizePixel
.Height() - i_nHeight
) / 2 );
656 io_rX
= aParentAbsPos
.X() + aPos
.X();
657 io_rY
= aParentAbsPos
.Y() + aPos
.Y();
661 void SystemWindow::SetWindowStateData( const WindowStateData
& rData
)
663 const WindowStateMask nValidMask
= rData
.GetMask();
664 if ( nValidMask
== WindowStateMask::NONE
)
670 vcl::Window
* pWindow
= this;
671 while ( pWindow
->mpWindowImpl
->mpBorderWindow
)
672 pWindow
= pWindow
->mpWindowImpl
->mpBorderWindow
;
674 if ( pWindow
->mpWindowImpl
->mbFrame
)
676 const WindowStateState nState
= rData
.GetState();
677 SalFrameState aState
;
678 aState
.mnMask
= rData
.GetMask();
679 aState
.mnX
= rData
.GetX();
680 aState
.mnY
= rData
.GetY();
681 aState
.mnWidth
= rData
.GetWidth();
682 aState
.mnHeight
= rData
.GetHeight();
684 if( rData
.GetMask() & (WindowStateMask::Width
|WindowStateMask::Height
) )
686 // #i43799# adjust window state sizes if a minimal output size was set
687 // otherwise the frame and the client might get different sizes
688 if( maMinOutSize
.Width() > aState
.mnWidth
)
689 aState
.mnWidth
= maMinOutSize
.Width();
690 if( maMinOutSize
.Height() > aState
.mnHeight
)
691 aState
.mnHeight
= maMinOutSize
.Height();
694 aState
.mnMaximizedX
= rData
.GetMaximizedX();
695 aState
.mnMaximizedY
= rData
.GetMaximizedY();
696 aState
.mnMaximizedWidth
= rData
.GetMaximizedWidth();
697 aState
.mnMaximizedHeight
= rData
.GetMaximizedHeight();
698 // #94144# allow Minimize again, should be masked out when read from configuration
699 // 91625 - ignore Minimize
700 //nState &= ~(WindowStateState::Minimized);
701 aState
.mnState
= nState
& WindowStateState::SystemMask
;
703 // normalize window positions onto screen
704 ImplMoveToScreen( aState
.mnX
, aState
.mnY
, aState
.mnWidth
, aState
.mnHeight
, pWindow
);
705 ImplMoveToScreen( aState
.mnMaximizedX
, aState
.mnMaximizedY
, aState
.mnMaximizedWidth
, aState
.mnMaximizedHeight
, pWindow
);
707 // #96568# avoid having multiple frames at the same screen location
708 // do the check only if not maximized
709 if( !((rData
.GetMask() & WindowStateMask::State
) && (nState
& WindowStateState::Maximized
)) )
710 if( rData
.GetMask() & (WindowStateMask::Pos
|WindowStateMask::Width
|WindowStateMask::Height
) )
712 Rectangle aDesktop
= GetDesktopRectPixel();
713 ImplSVData
*pSVData
= ImplGetSVData();
714 vcl::Window
*pWin
= pSVData
->maWinData
.mpFirstFrame
;
715 bool bWrapped
= false;
718 if( !pWin
->ImplIsRealParentPath( this ) && ( pWin
!= this ) &&
719 pWin
->ImplGetWindow()->IsTopWindow() && pWin
->mpWindowImpl
->mbReallyVisible
)
721 SalFrameGeometry g
= pWin
->mpWindowImpl
->mpFrame
->GetGeometry();
722 if( std::abs(g
.nX
-aState
.mnX
) < 2 && std::abs(g
.nY
-aState
.mnY
) < 5 )
724 long displacement
= g
.nTopDecoration
? g
.nTopDecoration
: 20;
725 if( (unsigned long) (aState
.mnX
+ displacement
+ aState
.mnWidth
+ g
.nRightDecoration
) > (unsigned long) aDesktop
.Right() ||
726 (unsigned long) (aState
.mnY
+ displacement
+ aState
.mnHeight
+ g
.nBottomDecoration
) > (unsigned long) aDesktop
.Bottom() )
728 // displacing would leave screen
729 aState
.mnX
= g
.nLeftDecoration
? g
.nLeftDecoration
: 10; // should result in (0,0)
730 aState
.mnY
= displacement
;
732 (unsigned long) (aState
.mnX
+ displacement
+ aState
.mnWidth
+ g
.nRightDecoration
) > (unsigned long) aDesktop
.Right() ||
733 (unsigned long) (aState
.mnY
+ displacement
+ aState
.mnHeight
+ g
.nBottomDecoration
) > (unsigned long) aDesktop
.Bottom() )
734 break; // further displacement not possible -> break
735 // avoid endless testing
741 aState
.mnX
+= displacement
;
742 aState
.mnY
+= displacement
;
744 pWin
= pSVData
->maWinData
.mpFirstFrame
; // check new pos again
747 pWin
= pWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
751 mpWindowImpl
->mpFrame
->SetWindowState( &aState
);
753 // do a synchronous resize for layout reasons
754 // but use rData only when the window is not to be maximized (#i38089#)
755 // otherwise we have no useful size information
756 if( (rData
.GetMask() & WindowStateMask::State
) && (nState
& WindowStateState::Maximized
) )
758 // query maximized size from frame
759 SalFrameGeometry aGeometry
= mpWindowImpl
->mpFrame
->GetGeometry();
761 // but use it only if it is different from the restore size (rData)
762 // as currently only on windows the exact size of a maximized window
763 // can be computed without actually showing the window
764 if( aGeometry
.nWidth
!= rData
.GetWidth() || aGeometry
.nHeight
!= rData
.GetHeight() )
765 ImplHandleResize( pWindow
, aGeometry
.nWidth
, aGeometry
.nHeight
);
768 if( rData
.GetMask() & (WindowStateMask::Width
|WindowStateMask::Height
) )
769 ImplHandleResize( pWindow
, aState
.mnWidth
, aState
.mnHeight
); // #i43799# use aState and not rData, see above
773 PosSizeFlags nPosSize
= PosSizeFlags::NONE
;
774 if ( nValidMask
& WindowStateMask::X
)
775 nPosSize
|= PosSizeFlags::X
;
776 if ( nValidMask
& WindowStateMask::Y
)
777 nPosSize
|= PosSizeFlags::Y
;
778 if ( nValidMask
& WindowStateMask::Width
)
779 nPosSize
|= PosSizeFlags::Width
;
780 if ( nValidMask
& WindowStateMask::Height
)
781 nPosSize
|= PosSizeFlags::Height
;
786 long nX
= rData
.GetX();
787 long nY
= rData
.GetY();
788 long nWidth
= rData
.GetWidth();
789 long nHeight
= rData
.GetHeight();
790 const SalFrameGeometry
& rGeom
= pWindow
->mpWindowImpl
->mpFrame
->GetGeometry();
793 if( nX
+ nWidth
> (long) rGeom
.nWidth
)
794 nX
= rGeom
.nWidth
- nWidth
;
797 if( nY
+ nHeight
> (long) rGeom
.nHeight
)
798 nY
= rGeom
.nHeight
- nHeight
;
799 setPosSizePixel( nX
, nY
, nWidth
, nHeight
, nPosSize
);
800 maOrgSize
= Size( nWidth
, nHeight
);
802 // 91625 - ignore Minimize
803 if ( nValidMask
& WindowStateMask::State
)
805 const WindowStateState nState
= rData
.GetState();
806 if ( nState
& WindowStateState::Rollup
)
814 void SystemWindow::GetWindowStateData( WindowStateData
& rData
) const
816 WindowStateMask nValidMask
= rData
.GetMask();
817 if ( nValidMask
== WindowStateMask::NONE
)
823 const vcl::Window
* pWindow
= this;
824 while ( pWindow
->mpWindowImpl
->mpBorderWindow
)
825 pWindow
= pWindow
->mpWindowImpl
->mpBorderWindow
;
827 if ( pWindow
->mpWindowImpl
->mbFrame
)
829 SalFrameState aState
;
830 aState
.mnMask
= WindowStateMask::All
;
831 if ( mpWindowImpl
->mpFrame
->GetWindowState( &aState
) )
833 if ( nValidMask
& WindowStateMask::X
)
834 rData
.SetX( aState
.mnX
);
835 if ( nValidMask
& WindowStateMask::Y
)
836 rData
.SetY( aState
.mnY
);
837 if ( nValidMask
& WindowStateMask::Width
)
838 rData
.SetWidth( aState
.mnWidth
);
839 if ( nValidMask
& WindowStateMask::Height
)
840 rData
.SetHeight( aState
.mnHeight
);
841 if ( aState
.mnMask
& WindowStateMask::MaximizedX
)
843 rData
.SetMaximizedX( aState
.mnMaximizedX
);
844 nValidMask
|= WindowStateMask::MaximizedX
;
846 if ( aState
.mnMask
& WindowStateMask::MaximizedY
)
848 rData
.SetMaximizedY( aState
.mnMaximizedY
);
849 nValidMask
|= WindowStateMask::MaximizedY
;
851 if ( aState
.mnMask
& WindowStateMask::MaximizedWidth
)
853 rData
.SetMaximizedWidth( aState
.mnMaximizedWidth
);
854 nValidMask
|= WindowStateMask::MaximizedWidth
;
856 if ( aState
.mnMask
& WindowStateMask::MaximizedHeight
)
858 rData
.SetMaximizedHeight( aState
.mnMaximizedHeight
);
859 nValidMask
|= WindowStateMask::MaximizedHeight
;
861 if ( nValidMask
& WindowStateMask::State
)
863 // #94144# allow Minimize again, should be masked out when read from configuration
864 // 91625 - ignore Minimize
865 if ( !(nValidMask
&WindowStateMask::Minimized
) )
866 aState
.mnState
&= ~(WindowStateState::Minimized
);
867 rData
.SetState( aState
.mnState
);
869 rData
.SetMask( nValidMask
);
872 rData
.SetMask( WindowStateMask::NONE
);
876 Point aPos
= GetPosPixel();
877 Size aSize
= GetSizePixel();
878 WindowStateState nState
= WindowStateState::NONE
;
882 aSize
.Height() += maOrgSize
.Height();
883 nState
= WindowStateState::Rollup
;
886 if ( nValidMask
& WindowStateMask::X
)
887 rData
.SetX( aPos
.X() );
888 if ( nValidMask
& WindowStateMask::Y
)
889 rData
.SetY( aPos
.Y() );
890 if ( nValidMask
& WindowStateMask::Width
)
891 rData
.SetWidth( aSize
.Width() );
892 if ( nValidMask
& WindowStateMask::Height
)
893 rData
.SetHeight( aSize
.Height() );
894 if ( nValidMask
& WindowStateMask::State
)
895 rData
.SetState( nState
);
899 void SystemWindow::SetWindowState(const OString
& rStr
)
904 WindowStateData aData
;
905 ImplWindowStateFromStr( aData
, rStr
);
906 SetWindowStateData( aData
);
909 OString
SystemWindow::GetWindowState( WindowStateMask nMask
) const
911 WindowStateData aData
;
912 aData
.SetMask( nMask
);
913 GetWindowStateData( aData
);
915 return ImplWindowStateToStr(aData
);
918 void SystemWindow::SetMenuBar(MenuBar
* pMenuBar
)
920 if ( mpMenuBar
!= pMenuBar
)
922 MenuBar
* pOldMenuBar
= mpMenuBar
;
923 vcl::Window
* pOldWindow
= nullptr;
924 VclPtr
<vcl::Window
> pNewWindow
;
925 mpMenuBar
= pMenuBar
;
927 if ( mpWindowImpl
->mpBorderWindow
&& (mpWindowImpl
->mpBorderWindow
->GetType() == WINDOW_BORDERWINDOW
) )
930 pOldWindow
= pOldMenuBar
->ImplGetWindow();
932 pOldWindow
= nullptr;
935 CallEventListeners( VCLEVENT_WINDOW_MENUBARREMOVED
, static_cast<void*>(pOldMenuBar
) );
936 pOldWindow
->SetAccessible( css::uno::Reference
< css::accessibility::XAccessible
>() );
940 SAL_WARN_IF( pMenuBar
->pWindow
, "vcl", "SystemWindow::SetMenuBar() - MenuBars can only set in one SystemWindow at time" );
942 pNewWindow
= MenuBar::ImplCreate(mpWindowImpl
->mpBorderWindow
, pOldWindow
, pMenuBar
);
943 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMenuBarWindow(pNewWindow
);
945 CallEventListeners( VCLEVENT_WINDOW_MENUBARADDED
, static_cast<void*>(pMenuBar
) );
948 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMenuBarWindow( nullptr );
952 bool bDelete
= (pMenuBar
== nullptr);
953 if( bDelete
&& pOldWindow
)
955 if( mpImplData
->mpTaskPaneList
)
956 mpImplData
->mpTaskPaneList
->RemoveWindow( pOldWindow
);
958 MenuBar::ImplDestroy( pOldMenuBar
, bDelete
);
960 pOldWindow
= nullptr; // will be deleted in MenuBar::ImplDestroy,
967 pNewWindow
= pMenuBar
->ImplGetWindow();
969 pOldWindow
= pOldMenuBar
->ImplGetWindow();
972 // update taskpane list to make menubar accessible
973 if( mpImplData
->mpTaskPaneList
)
976 mpImplData
->mpTaskPaneList
->RemoveWindow( pOldWindow
);
978 mpImplData
->mpTaskPaneList
->AddWindow( pNewWindow
);
983 void SystemWindow::SetNotebookBar(const OUString
& rUIXMLDescription
, const css::uno::Reference
<css::frame::XFrame
>& rFrame
)
985 if (rUIXMLDescription
!= maNotebookBarUIFile
)
987 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetNotebookBar(rUIXMLDescription
, rFrame
);
988 maNotebookBarUIFile
= rUIXMLDescription
;
992 void SystemWindow::CloseNotebookBar()
994 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->CloseNotebookBar();
995 maNotebookBarUIFile
.clear();
998 VclPtr
<NotebookBar
> SystemWindow::GetNotebookBar() const
1000 return static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->GetNotebookBar();
1003 void SystemWindow::SetMenuBarMode( MenuBarMode nMode
)
1005 if ( mnMenuBarMode
!= nMode
)
1007 mnMenuBarMode
= nMode
;
1008 if ( mpWindowImpl
->mpBorderWindow
&& (mpWindowImpl
->mpBorderWindow
->GetType() == WINDOW_BORDERWINDOW
) )
1010 if ( nMode
== MenuBarMode::Hide
)
1011 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMenuBarMode( true );
1013 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMenuBarMode( false );
1018 bool SystemWindow::ImplIsInTaskPaneList( vcl::Window
* pWin
)
1020 if( mpImplData
&& mpImplData
->mpTaskPaneList
)
1021 return mpImplData
->mpTaskPaneList
->IsInList( pWin
);
1025 unsigned int SystemWindow::GetScreenNumber() const
1027 return mpWindowImpl
->mpFrame
->maGeometry
.nDisplayScreenNumber
;
1030 void SystemWindow::SetScreenNumber(unsigned int nDisplayScreen
)
1032 mpWindowImpl
->mpFrame
->SetScreenNumber( nDisplayScreen
);
1035 void SystemWindow::SetApplicationID(const OUString
&rApplicationID
)
1037 mpWindowImpl
->mpFrame
->SetApplicationID( rApplicationID
);
1040 void SystemWindow::SetCloseHdl(const Link
<SystemWindow
&,void>& rLink
)
1042 mpImplData
->maCloseHdl
= rLink
;
1045 const Link
<SystemWindow
&,void>& SystemWindow::GetCloseHdl() const
1047 return mpImplData
->maCloseHdl
;
1050 void SystemWindow::queue_resize(StateChangedType
/*eReason*/)
1052 if (!isLayoutEnabled())
1054 if (isCalculatingInitialLayoutSize())
1056 InvalidateSizeCache();
1057 if (hasPendingLayout())
1059 maLayoutIdle
.Start();
1062 void SystemWindow::Resize()
1067 bool SystemWindow::isLayoutEnabled() const
1069 //pre dtor called, and single child is a container => we're layout enabled
1070 return mpImplData
&& ::isLayoutEnabled(this);
1073 Size
SystemWindow::GetOptimalSize() const
1075 if (!isLayoutEnabled())
1076 return Window::GetOptimalSize();
1078 Size aSize
= VclContainer::getLayoutRequisition(*GetWindow(GetWindowType::FirstChild
));
1080 sal_Int32 nBorderWidth
= get_border_width();
1082 aSize
.Height() += 2 * nBorderWidth
;
1083 aSize
.Width() += 2 * nBorderWidth
;
1085 return Window::CalcWindowSize(aSize
);
1088 void SystemWindow::setPosSizeOnContainee(Size aSize
, Window
&rBox
)
1090 sal_Int32 nBorderWidth
= get_border_width();
1092 aSize
.Width() -= 2 * nBorderWidth
;
1093 aSize
.Height() -= 2 * nBorderWidth
;
1095 Point
aPos(nBorderWidth
, nBorderWidth
);
1096 VclContainer::setLayoutAllocation(rBox
, aPos
, CalcOutputSize(aSize
));
1099 IMPL_LINK_NOARG( SystemWindow
, ImplHandleLayoutTimerHdl
, Idle
*, void )
1101 if (!isLayoutEnabled())
1103 SAL_WARN("vcl.layout", "SystemWindow has become non-layout because extra children have been added directly to it.");
1107 Window
*pBox
= GetWindow(GetWindowType::FirstChild
);
1109 setPosSizeOnContainee(GetSizePixel(), *pBox
);
1112 void SystemWindow::SetText(const OUString
& rStr
)
1114 setDeferredProperties();
1115 Window::SetText(rStr
);
1118 OUString
SystemWindow::GetText() const
1120 const_cast<SystemWindow
*>(this)->setDeferredProperties();
1121 return Window::GetText();
1124 void SystemWindow::settingOptimalLayoutSize(Window
* /*pBox*/)
1128 void SystemWindow::setOptimalLayoutSize()
1130 maLayoutIdle
.Stop();
1132 //resize SystemWindow to fit requisition on initial show
1133 Window
*pBox
= GetWindow(GetWindowType::FirstChild
);
1135 settingOptimalLayoutSize(pBox
);
1137 Size aSize
= get_preferred_size();
1139 Size
aMax(bestmaxFrameSizeForScreenSize(GetDesktopRectPixel().GetSize()));
1141 aSize
.Width() = std::min(aMax
.Width(), aSize
.Width());
1142 aSize
.Height() = std::min(aMax
.Height(), aSize
.Height());
1144 SetMinOutputSizePixel(aSize
);
1145 SetSizePixel(aSize
);
1146 setPosSizeOnContainee(aSize
, *pBox
);
1149 void SystemWindow::DoInitialLayout()
1151 if (GetSettings().GetStyleSettings().GetAutoMnemonic())
1152 Accelerator::GenerateAutoMnemonicsOnHierarchy(this);
1154 if (isLayoutEnabled())
1156 mbIsCalculatingInitialLayoutSize
= true;
1157 setDeferredProperties();
1158 setOptimalLayoutSize();
1159 mbIsCalculatingInitialLayoutSize
= false;
1163 void SystemWindow::doDeferredInit(WinBits
/*nBits*/)
1165 SAL_WARN("vcl.layout", "SystemWindow in layout without doDeferredInit impl");
1168 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */