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 .
21 #include <sal/config.h>
22 #include <sal/log.hxx>
24 #include <vcl/accel.hxx>
25 #include <vcl/layout.hxx>
26 #include <vcl/settings.hxx>
27 #include <vcl/svapp.hxx>
28 #include <vcl/menu.hxx>
29 #include <vcl/event.hxx>
30 #include <vcl/syswin.hxx>
31 #include <vcl/taskpanelist.hxx>
32 #include <vcl/tabctrl.hxx>
33 #include <vcl/tabpage.hxx>
34 #include <vcl/virdev.hxx>
36 #include <rtl/strbuf.hxx>
38 #include <salframe.hxx>
43 using namespace ::com::sun::star::uno
;
44 using namespace ::com::sun::star::lang
;
46 class SystemWindow::ImplData
51 std::unique_ptr
<TaskPaneList
>
54 OUString maRepresentedURL
;
55 Link
<SystemWindow
&,void> maCloseHdl
;
58 SystemWindow::ImplData::ImplData()
60 mpTaskPaneList
= nullptr;
61 maMaxOutSize
= Size( SHRT_MAX
, SHRT_MAX
);
64 SystemWindow::SystemWindow(WindowType nType
)
70 , mbIsCalculatingInitialLayoutSize(false)
71 , mbPaintComplete(false)
72 , mnMenuBarMode(MenuBarMode::Normal
)
74 , mpImplData(new ImplData
)
75 , mbIsDeferredInit(false)
77 mpWindowImpl
->mbSysWin
= true;
78 mpWindowImpl
->mnActivateMode
= ActivateModeFlags::GrabFocus
;
80 //To-Do, reuse maResizeTimer
81 maLayoutIdle
.SetPriority(TaskPriority::RESIZE
);
82 maLayoutIdle
.SetInvokeHandler( LINK( this, SystemWindow
, ImplHandleLayoutTimerHdl
) );
83 maLayoutIdle
.SetDebugName( "vcl::SystemWindow maLayoutIdle" );
86 void SystemWindow::loadUI(vcl::Window
* pParent
, const OString
& rID
, const OUString
& rUIXMLDescription
,
87 const css::uno::Reference
<css::frame::XFrame
> &rFrame
)
89 mbIsDeferredInit
= true;
90 mpDialogParent
= pParent
; //should be unset in doDeferredInit
91 m_pUIBuilder
.reset( new VclBuilder(this, getUIRootDir(), rUIXMLDescription
, rID
, rFrame
) );
94 SystemWindow::~SystemWindow()
99 void SystemWindow::dispose()
104 // Hack to make sure code called from base ~Window does not interpret this
105 // as a SystemWindow (which it no longer is by then):
106 mpWindowImpl
->mbSysWin
= false;
108 mpDialogParent
.clear();
113 static void ImplHandleControlAccelerator( const vcl::Window
* pWindow
, bool bShow
)
115 Control
*pControl
= dynamic_cast<Control
*>(pWindow
->ImplGetWindow());
116 if (pControl
&& pControl
->GetText().indexOf('~') != -1)
118 pControl
->SetShowAccelerator( bShow
);
119 pControl
->Invalidate(InvalidateFlags::Update
);
125 void processChildren(const vcl::Window
*pParent
, bool bShowAccel
)
127 // go through its children
128 vcl::Window
* pChild
= firstLogicalChildOfParent(pParent
);
131 if (pChild
->GetType() == WindowType::TABCONTROL
)
133 // find currently shown tab page
134 TabControl
* pTabControl
= static_cast<TabControl
*>(pChild
);
135 TabPage
* pTabPage
= pTabControl
->GetTabPage( pTabControl
->GetCurPageId() );
136 processChildren(pTabPage
, bShowAccel
);
138 else if (pChild
->GetType() == WindowType::TABPAGE
)
140 // bare tabpage without tabcontrol parent (options dialog)
141 processChildren(pChild
, bShowAccel
);
143 else if ((pChild
->GetStyle() & (WB_DIALOGCONTROL
| WB_NODIALOGCONTROL
)) == WB_DIALOGCONTROL
)
145 // special controls that manage their children outside of widget layout
146 processChildren(pChild
, bShowAccel
);
150 ImplHandleControlAccelerator(pChild
, bShowAccel
);
152 pChild
= nextLogicalChildOfParent(pParent
, pChild
);
157 bool Accelerator::ToggleMnemonicsOnHierarchy(const CommandEvent
& rCEvent
, const vcl::Window
*pWindow
)
159 if (rCEvent
.GetCommand() == CommandEventId::ModKeyChange
&& ImplGetSVData()->maNWFData
.mbAutoAccel
)
161 const CommandModKeyData
*pCData
= rCEvent
.GetModKeyData();
162 const bool bShowAccel
= pCData
&& pCData
->IsMod2() && pCData
->IsDown();
163 processChildren(pWindow
, bShowAccel
);
169 bool SystemWindow::EventNotify( NotifyEvent
& rNEvt
)
171 if (rNEvt
.GetType() == MouseNotifyEvent::COMMAND
)
172 Accelerator::ToggleMnemonicsOnHierarchy(*rNEvt
.GetCommandEvent(), this);
174 // capture KeyEvents for menu handling
175 if (rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
||
176 rNEvt
.GetType() == MouseNotifyEvent::COMMAND
)
178 MenuBar
* pMBar
= mpMenuBar
;
179 if ( !pMBar
&& ( GetType() == WindowType::FLOATINGWINDOW
) )
181 vcl::Window
* pWin
= ImplGetFrameWindow()->ImplGetWindow();
182 if( pWin
&& pWin
->IsSystemWindow() )
183 pMBar
= static_cast<SystemWindow
*>(pWin
)->GetMenuBar();
188 if (rNEvt
.GetType() == MouseNotifyEvent::COMMAND
)
189 bDone
= pMBar
->ImplHandleCmdEvent(*rNEvt
.GetCommandEvent());
191 bDone
= pMBar
->ImplHandleKeyEvent(*rNEvt
.GetKeyEvent());
197 return Window::EventNotify( rNEvt
);
200 bool SystemWindow::PreNotify( NotifyEvent
& rNEvt
)
202 // capture KeyEvents for taskpane cycling
203 if ( rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
)
205 if( rNEvt
.GetKeyEvent()->GetKeyCode().GetCode() == KEY_F6
&&
206 rNEvt
.GetKeyEvent()->GetKeyCode().IsMod1() &&
207 !rNEvt
.GetKeyEvent()->GetKeyCode().IsShift() )
209 // Ctrl-F6 goes directly to the document
210 GrabFocusToDocument();
215 TaskPaneList
*pTList
= mpImplData
->mpTaskPaneList
.get();
216 if( !pTList
&& ( GetType() == WindowType::FLOATINGWINDOW
) )
218 vcl::Window
* pWin
= ImplGetFrameWindow()->ImplGetWindow();
219 if( pWin
&& pWin
->IsSystemWindow() )
220 pTList
= static_cast<SystemWindow
*>(pWin
)->mpImplData
->mpTaskPaneList
.get();
224 // search topmost system window which is the one to handle dialog/toolbar cycling
225 SystemWindow
*pSysWin
= this;
226 vcl::Window
*pWin
= this;
229 pWin
= pWin
->GetParent();
230 if( pWin
&& pWin
->IsSystemWindow() )
231 pSysWin
= static_cast<SystemWindow
*>(pWin
);
233 pTList
= pSysWin
->mpImplData
->mpTaskPaneList
.get();
235 if( pTList
&& pTList
->HandleKeyEvent( *rNEvt
.GetKeyEvent() ) )
239 return Window::PreNotify( rNEvt
);
242 TaskPaneList
* SystemWindow::GetTaskPaneList()
246 if( mpImplData
->mpTaskPaneList
)
247 return mpImplData
->mpTaskPaneList
.get();
250 mpImplData
->mpTaskPaneList
.reset( new TaskPaneList
);
251 MenuBar
* pMBar
= mpMenuBar
;
252 if ( !pMBar
&& ( GetType() == WindowType::FLOATINGWINDOW
) )
254 vcl::Window
* pWin
= ImplGetFrameWindow()->ImplGetWindow();
255 if ( pWin
&& pWin
->IsSystemWindow() )
256 pMBar
= static_cast<SystemWindow
*>(pWin
)->GetMenuBar();
259 mpImplData
->mpTaskPaneList
->AddWindow( pMBar
->ImplGetWindow() );
260 return mpImplData
->mpTaskPaneList
.get();
264 bool SystemWindow::Close()
266 VclPtr
<vcl::Window
> xWindow
= this;
267 CallEventListeners( VclEventId::WindowClose
);
268 if ( xWindow
->IsDisposed() )
271 if ( mpWindowImpl
->mxWindowPeer
.is() && IsCreatedWithToolkit() )
274 // Is Window not closeable, ignore close
275 vcl::Window
* pBorderWin
= ImplGetBorderWindow();
278 nStyle
= pBorderWin
->GetStyle();
281 if ( !(nStyle
& WB_CLOSEABLE
) )
289 void SystemWindow::TitleButtonClick( TitleButton
)
293 void SystemWindow::Resizing( Size
& )
297 void SystemWindow::SetRepresentedURL( const OUString
& i_rURL
)
299 bool bChanged
= (i_rURL
!= mpImplData
->maRepresentedURL
);
300 mpImplData
->maRepresentedURL
= i_rURL
;
301 if ( !mbSysChild
&& bChanged
)
303 const vcl::Window
* pWindow
= this;
304 while ( pWindow
->mpWindowImpl
->mpBorderWindow
)
305 pWindow
= pWindow
->mpWindowImpl
->mpBorderWindow
;
307 if ( pWindow
->mpWindowImpl
->mbFrame
)
308 pWindow
->mpWindowImpl
->mpFrame
->SetRepresentedURL( i_rURL
);
312 void SystemWindow::SetIcon( sal_uInt16 nIcon
)
314 if ( mnIcon
== nIcon
)
321 const vcl::Window
* pWindow
= this;
322 while ( pWindow
->mpWindowImpl
->mpBorderWindow
)
323 pWindow
= pWindow
->mpWindowImpl
->mpBorderWindow
;
325 if ( pWindow
->mpWindowImpl
->mbFrame
)
326 pWindow
->mpWindowImpl
->mpFrame
->SetIcon( nIcon
);
330 void SystemWindow::ShowTitleButton( TitleButton nButton
, bool bVisible
)
332 if ( nButton
== TitleButton::Docking
)
334 if ( mbDockBtn
!= bVisible
)
336 mbDockBtn
= bVisible
;
337 if ( mpWindowImpl
->mpBorderWindow
)
338 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetDockButton( bVisible
);
341 else if ( nButton
== TitleButton::Hide
)
343 if ( mbHideBtn
!= bVisible
)
345 mbHideBtn
= bVisible
;
346 if ( mpWindowImpl
->mpBorderWindow
)
347 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetHideButton( bVisible
);
350 else if ( nButton
== TitleButton::Menu
)
352 if ( mpWindowImpl
->mpBorderWindow
)
353 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMenuButton( bVisible
);
359 bool SystemWindow::IsTitleButtonVisible( TitleButton nButton
) const
361 if ( nButton
== TitleButton::Docking
)
363 else /* if ( nButton == TitleButton::Hide ) */
367 void SystemWindow::RollUp()
371 maOrgSize
= GetOutputSizePixel();
372 Size aSize
= maRollUpOutSize
;
373 if ( !aSize
.Width() )
374 aSize
.setWidth( GetOutputSizePixel().Width() );
376 if ( mpWindowImpl
->mpBorderWindow
)
377 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetRollUp( true, aSize
);
379 SetOutputSizePixel( aSize
);
383 void SystemWindow::RollDown()
388 if ( mpWindowImpl
->mpBorderWindow
)
389 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetRollUp( false, maOrgSize
);
391 SetOutputSizePixel( maOrgSize
);
395 void SystemWindow::SetMinOutputSizePixel( const Size
& rSize
)
397 maMinOutSize
= rSize
;
398 if ( mpWindowImpl
->mpBorderWindow
)
400 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMinOutputSize( rSize
.Width(), rSize
.Height() );
401 if ( mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbFrame
)
402 mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mpFrame
->SetMinClientSize( rSize
.Width(), rSize
.Height() );
404 else if ( mpWindowImpl
->mbFrame
)
405 mpWindowImpl
->mpFrame
->SetMinClientSize( rSize
.Width(), rSize
.Height() );
408 void SystemWindow::SetMaxOutputSizePixel( const Size
& rSize
)
411 if( aSize
.Width() > SHRT_MAX
|| aSize
.Width() <= 0 )
412 aSize
.setWidth( SHRT_MAX
);
413 if( aSize
.Height() > SHRT_MAX
|| aSize
.Height() <= 0 )
414 aSize
.setHeight( SHRT_MAX
);
416 mpImplData
->maMaxOutSize
= aSize
;
417 if ( mpWindowImpl
->mpBorderWindow
)
419 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMaxOutputSize( aSize
.Width(), aSize
.Height() );
420 if ( mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbFrame
)
421 mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mpFrame
->SetMaxClientSize( aSize
.Width(), aSize
.Height() );
423 else if ( mpWindowImpl
->mbFrame
)
424 mpWindowImpl
->mpFrame
->SetMaxClientSize( aSize
.Width(), aSize
.Height() );
427 const Size
& SystemWindow::GetMaxOutputSizePixel() const
429 return mpImplData
->maMaxOutSize
;
432 void ImplWindowStateFromStr(WindowStateData
& rData
,
435 WindowStateMask nValidMask
= WindowStateMask::NONE
;
436 sal_Int32 nIndex
= 0;
438 OString aTokenStr
= rStr
.getToken(0, ',', nIndex
);
439 if (!aTokenStr
.isEmpty())
441 rData
.SetX(aTokenStr
.toInt32());
442 if( rData
.GetX() > -16384 && rData
.GetX() < 16384 )
443 nValidMask
|= WindowStateMask::X
;
449 aTokenStr
= rStr
.getToken(0, ',', nIndex
);
450 if (!aTokenStr
.isEmpty())
452 rData
.SetY(aTokenStr
.toInt32());
453 if( rData
.GetY() > -16384 && rData
.GetY() < 16384 )
454 nValidMask
|= WindowStateMask::Y
;
460 aTokenStr
= rStr
.getToken(0, ',', nIndex
);
461 if (!aTokenStr
.isEmpty())
463 rData
.SetWidth(aTokenStr
.toInt32());
464 if( rData
.GetWidth() > 0 && rData
.GetWidth() < 16384 )
465 nValidMask
|= WindowStateMask::Width
;
471 aTokenStr
= rStr
.getToken(0, ';', nIndex
);
472 if (!aTokenStr
.isEmpty())
474 rData
.SetHeight(aTokenStr
.toInt32());
475 if( rData
.GetHeight() > 0 && rData
.GetHeight() < 16384 )
476 nValidMask
|= WindowStateMask::Height
;
478 rData
.SetHeight( 0 );
481 rData
.SetHeight( 0 );
482 aTokenStr
= rStr
.getToken(0, ';', nIndex
);
483 if (!aTokenStr
.isEmpty())
485 // #94144# allow Minimize again, should be masked out when read from configuration
486 // 91625 - ignore Minimize
487 WindowStateState nState
= static_cast<WindowStateState
>(aTokenStr
.toInt32());
488 //nState &= ~(WindowStateState::Minimized);
489 rData
.SetState( nState
);
490 nValidMask
|= WindowStateMask::State
;
493 rData
.SetState( WindowStateState::NONE
);
495 // read maximized pos/size
496 aTokenStr
= rStr
.getToken(0, ',', nIndex
);
497 if (!aTokenStr
.isEmpty())
499 rData
.SetMaximizedX(aTokenStr
.toInt32());
500 if( rData
.GetMaximizedX() > -16384 && rData
.GetMaximizedX() < 16384 )
501 nValidMask
|= WindowStateMask::MaximizedX
;
503 rData
.SetMaximizedX( 0 );
506 rData
.SetMaximizedX( 0 );
507 aTokenStr
= rStr
.getToken(0, ',', nIndex
);
508 if (!aTokenStr
.isEmpty())
510 rData
.SetMaximizedY(aTokenStr
.toInt32());
511 if( rData
.GetMaximizedY() > -16384 && rData
.GetMaximizedY() < 16384 )
512 nValidMask
|= WindowStateMask::MaximizedY
;
514 rData
.SetMaximizedY( 0 );
517 rData
.SetMaximizedY( 0 );
518 aTokenStr
= rStr
.getToken(0, ',', nIndex
);
519 if (!aTokenStr
.isEmpty())
521 rData
.SetMaximizedWidth(aTokenStr
.toInt32());
522 if( rData
.GetMaximizedWidth() > 0 && rData
.GetMaximizedWidth() < 16384 )
523 nValidMask
|= WindowStateMask::MaximizedWidth
;
525 rData
.SetMaximizedWidth( 0 );
528 rData
.SetMaximizedWidth( 0 );
529 aTokenStr
= rStr
.getToken(0, ';', nIndex
);
530 if (!aTokenStr
.isEmpty())
532 rData
.SetMaximizedHeight(aTokenStr
.toInt32());
533 if( rData
.GetMaximizedHeight() > 0 && rData
.GetMaximizedHeight() < 16384 )
534 nValidMask
|= WindowStateMask::MaximizedHeight
;
536 rData
.SetMaximizedHeight( 0 );
539 rData
.SetMaximizedHeight( 0 );
542 rData
.SetMask( nValidMask
);
545 OString
WindowStateData::ToStr() const
547 const WindowStateMask nValidMask
= GetMask();
548 if ( nValidMask
== WindowStateMask::NONE
)
551 OStringBuffer
rStrBuf(64);
553 if ( nValidMask
& WindowStateMask::X
)
554 rStrBuf
.append(static_cast<sal_Int32
>(GetX()));
556 if ( nValidMask
& WindowStateMask::Y
)
557 rStrBuf
.append(static_cast<sal_Int32
>(GetY()));
559 if ( nValidMask
& WindowStateMask::Width
)
560 rStrBuf
.append(static_cast<sal_Int32
>(GetWidth()));
562 if ( nValidMask
& WindowStateMask::Height
)
563 rStrBuf
.append(static_cast<sal_Int32
>(GetHeight()));
564 rStrBuf
.append( ';' );
565 if ( nValidMask
& WindowStateMask::State
)
567 // #94144# allow Minimize again, should be masked out when read from configuration
568 // 91625 - ignore Minimize
569 WindowStateState nState
= GetState();
570 rStrBuf
.append(static_cast<sal_Int32
>(nState
));
573 if ( nValidMask
& WindowStateMask::MaximizedX
)
574 rStrBuf
.append(static_cast<sal_Int32
>(GetMaximizedX()));
576 if ( nValidMask
& WindowStateMask::MaximizedY
)
577 rStrBuf
.append(static_cast<sal_Int32
>(GetMaximizedY()));
578 rStrBuf
.append( ',' );
579 if ( nValidMask
& WindowStateMask::MaximizedWidth
)
580 rStrBuf
.append(static_cast<sal_Int32
>(GetMaximizedWidth()));
582 if ( nValidMask
& WindowStateMask::MaximizedHeight
)
583 rStrBuf
.append(static_cast<sal_Int32
>(GetMaximizedHeight()));
586 return rStrBuf
.makeStringAndClear();
589 void SystemWindow::ImplMoveToScreen( long& io_rX
, long& io_rY
, long i_nWidth
, long i_nHeight
, vcl::Window
const * i_pConfigureWin
)
591 tools::Rectangle aScreenRect
;
592 if( !Application::IsUnifiedDisplay() )
593 aScreenRect
= Application::GetScreenPosSizePixel( GetScreenNumber() );
596 aScreenRect
= Application::GetScreenPosSizePixel( 0 );
597 for( unsigned int i
= 1; i
< Application::GetScreenCount(); i
++ )
598 aScreenRect
.Union( Application::GetScreenPosSizePixel( i
) );
600 // unfortunately most of the time width and height are not really known
608 if( io_rX
+ i_nWidth
< aScreenRect
.Left() )
611 io_rX
= aScreenRect
.Left();
613 // check right border
614 if( io_rX
> aScreenRect
.Right() - i_nWidth
)
617 io_rX
= aScreenRect
.Right() - i_nWidth
;
620 if( io_rY
+ i_nHeight
< aScreenRect
.Top() )
623 io_rY
= aScreenRect
.Top();
625 // check bottom border
626 if( io_rY
> aScreenRect
.Bottom() - i_nHeight
)
629 io_rY
= aScreenRect
.Bottom() - i_nHeight
;
631 vcl::Window
* pParent
= i_pConfigureWin
->GetParent();
632 if( bMove
&& pParent
)
634 // calculate absolute screen pos here, since that is what is contained in WindowState
635 Point
aParentAbsPos( pParent
->OutputToAbsoluteScreenPixel( Point(0,0) ) );
636 Size
aParentSizePixel( pParent
->GetOutputSizePixel() );
637 Point
aPos( (aParentSizePixel
.Width() - i_nWidth
) / 2,
638 (aParentSizePixel
.Height() - i_nHeight
) / 2 );
639 io_rX
= aParentAbsPos
.X() + aPos
.X();
640 io_rY
= aParentAbsPos
.Y() + aPos
.Y();
644 void SystemWindow::SetWindowStateData( const WindowStateData
& rData
)
646 const WindowStateMask nValidMask
= rData
.GetMask();
647 if ( nValidMask
== WindowStateMask::NONE
)
653 vcl::Window
* pWindow
= this;
654 while ( pWindow
->mpWindowImpl
->mpBorderWindow
)
655 pWindow
= pWindow
->mpWindowImpl
->mpBorderWindow
;
657 if ( pWindow
->mpWindowImpl
->mbFrame
)
659 const WindowStateState nState
= rData
.GetState();
660 SalFrameState aState
;
661 aState
.mnMask
= rData
.GetMask();
662 aState
.mnX
= rData
.GetX();
663 aState
.mnY
= rData
.GetY();
664 aState
.mnWidth
= rData
.GetWidth();
665 aState
.mnHeight
= rData
.GetHeight();
667 if( rData
.GetMask() & (WindowStateMask::Width
|WindowStateMask::Height
) )
669 // #i43799# adjust window state sizes if a minimal output size was set
670 // otherwise the frame and the client might get different sizes
671 if( maMinOutSize
.Width() > aState
.mnWidth
)
672 aState
.mnWidth
= maMinOutSize
.Width();
673 if( maMinOutSize
.Height() > aState
.mnHeight
)
674 aState
.mnHeight
= maMinOutSize
.Height();
677 aState
.mnMaximizedX
= rData
.GetMaximizedX();
678 aState
.mnMaximizedY
= rData
.GetMaximizedY();
679 aState
.mnMaximizedWidth
= rData
.GetMaximizedWidth();
680 aState
.mnMaximizedHeight
= rData
.GetMaximizedHeight();
681 // #94144# allow Minimize again, should be masked out when read from configuration
682 // 91625 - ignore Minimize
683 //nState &= ~(WindowStateState::Minimized);
684 aState
.mnState
= nState
& WindowStateState::SystemMask
;
686 // normalize window positions onto screen
687 ImplMoveToScreen( aState
.mnX
, aState
.mnY
, aState
.mnWidth
, aState
.mnHeight
, pWindow
);
688 ImplMoveToScreen( aState
.mnMaximizedX
, aState
.mnMaximizedY
, aState
.mnMaximizedWidth
, aState
.mnMaximizedHeight
, pWindow
);
690 // #96568# avoid having multiple frames at the same screen location
691 // do the check only if not maximized
692 if( !((rData
.GetMask() & WindowStateMask::State
) && (nState
& WindowStateState::Maximized
)) )
693 if( rData
.GetMask() & (WindowStateMask::Pos
|WindowStateMask::Width
|WindowStateMask::Height
) )
695 tools::Rectangle aDesktop
= GetDesktopRectPixel();
696 ImplSVData
*pSVData
= ImplGetSVData();
697 vcl::Window
*pWin
= pSVData
->maWinData
.mpFirstFrame
;
698 bool bWrapped
= false;
701 if( !pWin
->ImplIsRealParentPath( this ) && ( pWin
!= this ) &&
702 pWin
->ImplGetWindow()->IsTopWindow() && pWin
->mpWindowImpl
->mbReallyVisible
)
704 SalFrameGeometry g
= pWin
->mpWindowImpl
->mpFrame
->GetGeometry();
705 if( std::abs(g
.nX
-aState
.mnX
) < 2 && std::abs(g
.nY
-aState
.mnY
) < 5 )
707 long displacement
= g
.nTopDecoration
? g
.nTopDecoration
: 20;
708 if( static_cast<unsigned long>(aState
.mnX
+ displacement
+ aState
.mnWidth
+ g
.nRightDecoration
) > static_cast<unsigned long>(aDesktop
.Right()) ||
709 static_cast<unsigned long>(aState
.mnY
+ displacement
+ aState
.mnHeight
+ g
.nBottomDecoration
) > static_cast<unsigned long>(aDesktop
.Bottom()) )
711 // displacing would leave screen
712 aState
.mnX
= g
.nLeftDecoration
? g
.nLeftDecoration
: 10; // should result in (0,0)
713 aState
.mnY
= displacement
;
715 static_cast<unsigned long>(aState
.mnX
+ displacement
+ aState
.mnWidth
+ g
.nRightDecoration
) > static_cast<unsigned long>(aDesktop
.Right()) ||
716 static_cast<unsigned long>(aState
.mnY
+ displacement
+ aState
.mnHeight
+ g
.nBottomDecoration
) > static_cast<unsigned long>(aDesktop
.Bottom()) )
717 break; // further displacement not possible -> break
718 // avoid endless testing
724 aState
.mnX
+= displacement
;
725 aState
.mnY
+= displacement
;
727 pWin
= pSVData
->maWinData
.mpFirstFrame
; // check new pos again
730 pWin
= pWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
734 mpWindowImpl
->mpFrame
->SetWindowState( &aState
);
736 // do a synchronous resize for layout reasons
737 // but use rData only when the window is not to be maximized (#i38089#)
738 // otherwise we have no useful size information
739 if( (rData
.GetMask() & WindowStateMask::State
) && (nState
& WindowStateState::Maximized
) )
741 // query maximized size from frame
742 SalFrameGeometry aGeometry
= mpWindowImpl
->mpFrame
->GetGeometry();
744 // but use it only if it is different from the restore size (rData)
745 // as currently only on windows the exact size of a maximized window
746 // can be computed without actually showing the window
747 if( aGeometry
.nWidth
!= rData
.GetWidth() || aGeometry
.nHeight
!= rData
.GetHeight() )
748 ImplHandleResize( pWindow
, aGeometry
.nWidth
, aGeometry
.nHeight
);
751 if( rData
.GetMask() & (WindowStateMask::Width
|WindowStateMask::Height
) )
752 ImplHandleResize( pWindow
, aState
.mnWidth
, aState
.mnHeight
); // #i43799# use aState and not rData, see above
756 PosSizeFlags nPosSize
= PosSizeFlags::NONE
;
757 if ( nValidMask
& WindowStateMask::X
)
758 nPosSize
|= PosSizeFlags::X
;
759 if ( nValidMask
& WindowStateMask::Y
)
760 nPosSize
|= PosSizeFlags::Y
;
761 if ( nValidMask
& WindowStateMask::Width
)
762 nPosSize
|= PosSizeFlags::Width
;
763 if ( nValidMask
& WindowStateMask::Height
)
764 nPosSize
|= PosSizeFlags::Height
;
769 long nX
= rData
.GetX();
770 long nY
= rData
.GetY();
771 long nWidth
= rData
.GetWidth();
772 long nHeight
= rData
.GetHeight();
773 const SalFrameGeometry
& rGeom
= pWindow
->mpWindowImpl
->mpFrame
->GetGeometry();
776 if( nX
+ nWidth
> static_cast<long>(rGeom
.nWidth
) )
777 nX
= rGeom
.nWidth
- nWidth
;
780 if( nY
+ nHeight
> static_cast<long>(rGeom
.nHeight
) )
781 nY
= rGeom
.nHeight
- nHeight
;
782 setPosSizePixel( nX
, nY
, nWidth
, nHeight
, nPosSize
);
783 maOrgSize
= Size( nWidth
, nHeight
);
785 // 91625 - ignore Minimize
786 if ( nValidMask
& WindowStateMask::State
)
788 const WindowStateState nState
= rData
.GetState();
789 if ( nState
& WindowStateState::Rollup
)
797 void SystemWindow::GetWindowStateData( WindowStateData
& rData
) const
799 WindowStateMask nValidMask
= rData
.GetMask();
800 if ( nValidMask
== WindowStateMask::NONE
)
806 const vcl::Window
* pWindow
= this;
807 while ( pWindow
->mpWindowImpl
->mpBorderWindow
)
808 pWindow
= pWindow
->mpWindowImpl
->mpBorderWindow
;
810 if ( pWindow
->mpWindowImpl
->mbFrame
)
812 SalFrameState aState
;
813 aState
.mnMask
= WindowStateMask::All
;
814 if ( mpWindowImpl
->mpFrame
->GetWindowState( &aState
) )
816 if ( nValidMask
& WindowStateMask::X
)
817 rData
.SetX( aState
.mnX
);
818 if ( nValidMask
& WindowStateMask::Y
)
819 rData
.SetY( aState
.mnY
);
820 if ( nValidMask
& WindowStateMask::Width
)
821 rData
.SetWidth( aState
.mnWidth
);
822 if ( nValidMask
& WindowStateMask::Height
)
823 rData
.SetHeight( aState
.mnHeight
);
824 if ( aState
.mnMask
& WindowStateMask::MaximizedX
)
826 rData
.SetMaximizedX( aState
.mnMaximizedX
);
827 nValidMask
|= WindowStateMask::MaximizedX
;
829 if ( aState
.mnMask
& WindowStateMask::MaximizedY
)
831 rData
.SetMaximizedY( aState
.mnMaximizedY
);
832 nValidMask
|= WindowStateMask::MaximizedY
;
834 if ( aState
.mnMask
& WindowStateMask::MaximizedWidth
)
836 rData
.SetMaximizedWidth( aState
.mnMaximizedWidth
);
837 nValidMask
|= WindowStateMask::MaximizedWidth
;
839 if ( aState
.mnMask
& WindowStateMask::MaximizedHeight
)
841 rData
.SetMaximizedHeight( aState
.mnMaximizedHeight
);
842 nValidMask
|= WindowStateMask::MaximizedHeight
;
844 if ( nValidMask
& WindowStateMask::State
)
846 // #94144# allow Minimize again, should be masked out when read from configuration
847 // 91625 - ignore Minimize
848 if ( !(nValidMask
&WindowStateMask::Minimized
) )
849 aState
.mnState
&= ~WindowStateState::Minimized
;
850 rData
.SetState( aState
.mnState
);
852 rData
.SetMask( nValidMask
);
855 rData
.SetMask( WindowStateMask::NONE
);
859 Point aPos
= GetPosPixel();
860 Size aSize
= GetSizePixel();
861 WindowStateState nState
= WindowStateState::NONE
;
865 aSize
.AdjustHeight(maOrgSize
.Height() );
866 nState
= WindowStateState::Rollup
;
869 if ( nValidMask
& WindowStateMask::X
)
870 rData
.SetX( aPos
.X() );
871 if ( nValidMask
& WindowStateMask::Y
)
872 rData
.SetY( aPos
.Y() );
873 if ( nValidMask
& WindowStateMask::Width
)
874 rData
.SetWidth( aSize
.Width() );
875 if ( nValidMask
& WindowStateMask::Height
)
876 rData
.SetHeight( aSize
.Height() );
877 if ( nValidMask
& WindowStateMask::State
)
878 rData
.SetState( nState
);
882 void SystemWindow::SetWindowState(const OString
& rStr
)
887 WindowStateData aData
;
888 ImplWindowStateFromStr( aData
, rStr
);
889 SetWindowStateData( aData
);
892 OString
SystemWindow::GetWindowState( WindowStateMask nMask
) const
894 WindowStateData aData
;
895 aData
.SetMask( nMask
);
896 GetWindowStateData( aData
);
898 return aData
.ToStr();
901 void SystemWindow::SetMenuBar(MenuBar
* pMenuBar
)
903 if ( mpMenuBar
!= pMenuBar
)
905 MenuBar
* pOldMenuBar
= mpMenuBar
;
906 vcl::Window
* pOldWindow
= nullptr;
907 VclPtr
<vcl::Window
> pNewWindow
;
908 mpMenuBar
= pMenuBar
;
910 if ( mpWindowImpl
->mpBorderWindow
&& (mpWindowImpl
->mpBorderWindow
->GetType() == WindowType::BORDERWINDOW
) )
913 pOldWindow
= pOldMenuBar
->ImplGetWindow();
915 pOldWindow
= nullptr;
918 CallEventListeners( VclEventId::WindowMenubarRemoved
, static_cast<void*>(pOldMenuBar
) );
919 pOldWindow
->SetAccessible( css::uno::Reference
< css::accessibility::XAccessible
>() );
923 SAL_WARN_IF( pMenuBar
->pWindow
, "vcl", "SystemWindow::SetMenuBar() - MenuBars can only set in one SystemWindow at time" );
925 pNewWindow
= MenuBar::ImplCreate(mpWindowImpl
->mpBorderWindow
, pOldWindow
, pMenuBar
);
926 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMenuBarWindow(pNewWindow
);
928 CallEventListeners( VclEventId::WindowMenubarAdded
, static_cast<void*>(pMenuBar
) );
931 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMenuBarWindow( nullptr );
935 bool bDelete
= (pMenuBar
== nullptr);
936 if( bDelete
&& pOldWindow
)
938 if( mpImplData
->mpTaskPaneList
)
939 mpImplData
->mpTaskPaneList
->RemoveWindow( pOldWindow
);
941 MenuBar::ImplDestroy( pOldMenuBar
, bDelete
);
943 pOldWindow
= nullptr; // will be deleted in MenuBar::ImplDestroy,
950 pNewWindow
= pMenuBar
->ImplGetWindow();
952 pOldWindow
= pOldMenuBar
->ImplGetWindow();
955 // update taskpane list to make menubar accessible
956 if( mpImplData
->mpTaskPaneList
)
959 mpImplData
->mpTaskPaneList
->RemoveWindow( pOldWindow
);
961 mpImplData
->mpTaskPaneList
->AddWindow( pNewWindow
);
966 void SystemWindow::SetNotebookBar(const OUString
& rUIXMLDescription
,
967 const css::uno::Reference
<css::frame::XFrame
>& rFrame
,
968 const NotebookBarAddonsItem
& aNotebookBarAddonsItem
,
969 bool bReloadNotebookbar
)
971 if (rUIXMLDescription
!= maNotebookBarUIFile
|| bReloadNotebookbar
)
973 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())
974 ->SetNotebookBar(rUIXMLDescription
, rFrame
, aNotebookBarAddonsItem
);
975 maNotebookBarUIFile
= rUIXMLDescription
;
977 GetNotebookBar()->SetSystemWindow(this);
981 void SystemWindow::CloseNotebookBar()
983 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->CloseNotebookBar();
984 maNotebookBarUIFile
.clear();
987 VclPtr
<NotebookBar
> const & SystemWindow::GetNotebookBar() const
989 return static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->GetNotebookBar();
992 void SystemWindow::SetMenuBarMode( MenuBarMode nMode
)
994 if ( mnMenuBarMode
!= nMode
)
996 mnMenuBarMode
= nMode
;
997 if ( mpWindowImpl
->mpBorderWindow
&& (mpWindowImpl
->mpBorderWindow
->GetType() == WindowType::BORDERWINDOW
) )
999 if ( nMode
== MenuBarMode::Hide
)
1000 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMenuBarMode( true );
1002 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMenuBarMode( false );
1007 bool SystemWindow::ImplIsInTaskPaneList( vcl::Window
* pWin
)
1009 if( mpImplData
&& mpImplData
->mpTaskPaneList
)
1010 return mpImplData
->mpTaskPaneList
->IsInList( pWin
);
1014 unsigned int SystemWindow::GetScreenNumber() const
1016 return mpWindowImpl
->mpFrame
->maGeometry
.nDisplayScreenNumber
;
1019 void SystemWindow::SetScreenNumber(unsigned int nDisplayScreen
)
1021 mpWindowImpl
->mpFrame
->SetScreenNumber( nDisplayScreen
);
1024 void SystemWindow::SetApplicationID(const OUString
&rApplicationID
)
1026 mpWindowImpl
->mpFrame
->SetApplicationID( rApplicationID
);
1029 void SystemWindow::SetCloseHdl(const Link
<SystemWindow
&,void>& rLink
)
1031 mpImplData
->maCloseHdl
= rLink
;
1034 const Link
<SystemWindow
&,void>& SystemWindow::GetCloseHdl() const
1036 return mpImplData
->maCloseHdl
;
1039 void SystemWindow::queue_resize(StateChangedType
/*eReason*/)
1041 if (!isLayoutEnabled())
1043 if (isCalculatingInitialLayoutSize())
1045 InvalidateSizeCache();
1046 if (hasPendingLayout())
1048 maLayoutIdle
.Start();
1051 void SystemWindow::Resize()
1056 bool SystemWindow::isLayoutEnabled() const
1058 //pre dtor called, and single child is a container => we're layout enabled
1059 return mpImplData
&& ::isLayoutEnabled(this);
1062 Size
SystemWindow::GetOptimalSize() const
1064 if (!isLayoutEnabled())
1065 return Window::GetOptimalSize();
1067 Size aSize
= VclContainer::getLayoutRequisition(*GetWindow(GetWindowType::FirstChild
));
1069 sal_Int32 nBorderWidth
= get_border_width();
1071 aSize
.AdjustHeight(2 * nBorderWidth
);
1072 aSize
.AdjustWidth(2 * nBorderWidth
);
1074 return Window::CalcWindowSize(aSize
);
1077 void SystemWindow::setPosSizeOnContainee(Size aSize
, Window
&rBox
)
1079 sal_Int32 nBorderWidth
= get_border_width();
1081 aSize
.AdjustWidth( -(2 * nBorderWidth
) );
1082 aSize
.AdjustHeight( -(2 * nBorderWidth
) );
1084 Point
aPos(nBorderWidth
, nBorderWidth
);
1085 VclContainer::setLayoutAllocation(rBox
, aPos
, CalcOutputSize(aSize
));
1088 IMPL_LINK_NOARG( SystemWindow
, ImplHandleLayoutTimerHdl
, Timer
*, void )
1090 if (!isLayoutEnabled())
1092 SAL_WARN("vcl.layout", "SystemWindow has become non-layout because extra children have been added directly to it.");
1096 Window
*pBox
= GetWindow(GetWindowType::FirstChild
);
1098 setPosSizeOnContainee(GetSizePixel(), *pBox
);
1101 void SystemWindow::SetText(const OUString
& rStr
)
1103 setDeferredProperties();
1104 Window::SetText(rStr
);
1107 OUString
SystemWindow::GetText() const
1109 const_cast<SystemWindow
*>(this)->setDeferredProperties();
1110 return Window::GetText();
1113 void SystemWindow::settingOptimalLayoutSize(Window
* /*pBox*/)
1117 void SystemWindow::setOptimalLayoutSize()
1119 maLayoutIdle
.Stop();
1121 //resize SystemWindow to fit requisition on initial show
1122 Window
*pBox
= GetWindow(GetWindowType::FirstChild
);
1124 settingOptimalLayoutSize(pBox
);
1126 Size aSize
= get_preferred_size();
1128 Size
aMax(bestmaxFrameSizeForScreenSize(GetDesktopRectPixel().GetSize()));
1130 aSize
.setWidth( std::min(aMax
.Width(), aSize
.Width()) );
1131 aSize
.setHeight( std::min(aMax
.Height(), aSize
.Height()) );
1133 SetMinOutputSizePixel(aSize
);
1134 SetSizePixel(aSize
);
1135 setPosSizeOnContainee(aSize
, *pBox
);
1138 void SystemWindow::DoInitialLayout()
1140 if (GetSettings().GetStyleSettings().GetAutoMnemonic())
1141 Accelerator::GenerateAutoMnemonicsOnHierarchy(this);
1143 if (isLayoutEnabled())
1145 mbIsCalculatingInitialLayoutSize
= true;
1146 setDeferredProperties();
1147 setOptimalLayoutSize();
1148 mbIsCalculatingInitialLayoutSize
= false;
1152 void SystemWindow::doDeferredInit(WinBits
/*nBits*/)
1154 SAL_WARN("vcl.layout", "SystemWindow in layout without doDeferredInit impl");
1157 void SystemWindow::createScreenshot(VirtualDevice
& rOutput
)
1159 // same prerequisites as in Execute()
1160 setDeferredProperties();
1161 ImplAdjustNWFSizes();
1167 Size
aSize(GetOutputSizePixel());
1169 rOutput
.SetOutputSizePixel(aSize
);
1170 rOutput
.DrawOutDev(aPos
, aSize
, aPos
, aSize
, *this);
1173 void SystemWindow::PrePaint(vcl::RenderContext
& rRenderContext
)
1175 Window::PrePaint(rRenderContext
);
1176 mbPaintComplete
= false;
1179 void SystemWindow::PostPaint(vcl::RenderContext
& rRenderContext
)
1181 Window::PostPaint(rRenderContext
);
1182 mbPaintComplete
= true;
1185 void SystemWindow::ensureRepaint()
1189 mbPaintComplete
= false;
1191 while (!mbPaintComplete
)
1193 Application::Yield();
1197 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */