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 .
22 #include <o3tl/safeint.hxx>
23 #include <sal/config.h>
24 #include <sal/log.hxx>
26 #include <vcl/accel.hxx>
27 #include <vcl/layout.hxx>
28 #include <vcl/settings.hxx>
29 #include <vcl/svapp.hxx>
30 #include <vcl/menu.hxx>
31 #include <vcl/event.hxx>
32 #include <vcl/syswin.hxx>
33 #include <vcl/taskpanelist.hxx>
34 #include <vcl/tabctrl.hxx>
35 #include <vcl/tabpage.hxx>
36 #include <vcl/virdev.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
)
72 , mbIsCalculatingInitialLayoutSize(false)
73 , mbPaintComplete(false)
74 , mnMenuBarMode(MenuBarMode::Normal
)
76 , mpImplData(new ImplData
)
77 , mbIsDeferredInit(false)
79 mpWindowImpl
->mbSysWin
= true;
80 mpWindowImpl
->mnActivateMode
= ActivateModeFlags::GrabFocus
;
82 //To-Do, reuse maResizeTimer
83 maLayoutIdle
.SetPriority(TaskPriority::RESIZE
);
84 maLayoutIdle
.SetInvokeHandler( LINK( this, SystemWindow
, ImplHandleLayoutTimerHdl
) );
85 maLayoutIdle
.SetDebugName( "vcl::SystemWindow maLayoutIdle" );
88 void SystemWindow::loadUI(vcl::Window
* pParent
, const OString
& rID
, const OUString
& rUIXMLDescription
,
89 const css::uno::Reference
<css::frame::XFrame
> &rFrame
)
91 mbIsDeferredInit
= true;
92 mpDialogParent
= pParent
; //should be unset in doDeferredInit
93 m_pUIBuilder
.reset( new VclBuilder(this, AllSettings::GetUIRootDir(), rUIXMLDescription
, rID
, rFrame
) );
96 SystemWindow::~SystemWindow()
101 void SystemWindow::dispose()
106 // Hack to make sure code called from base ~Window does not interpret this
107 // as a SystemWindow (which it no longer is by then):
108 mpWindowImpl
->mbSysWin
= false;
110 mpDialogParent
.clear();
115 static void ImplHandleControlAccelerator( const vcl::Window
* pWindow
, bool bShow
)
117 Control
*pControl
= dynamic_cast<Control
*>(pWindow
->ImplGetWindow());
118 if (pControl
&& pControl
->GetText().indexOf('~') != -1)
120 pControl
->SetShowAccelerator( bShow
);
121 pControl
->Invalidate(InvalidateFlags::Update
);
127 void processChildren(const vcl::Window
*pParent
, bool bShowAccel
)
129 // go through its children
130 vcl::Window
* pChild
= firstLogicalChildOfParent(pParent
);
133 if (pChild
->GetType() == WindowType::TABCONTROL
)
135 // find currently shown tab page
136 TabControl
* pTabControl
= static_cast<TabControl
*>(pChild
);
137 TabPage
* pTabPage
= pTabControl
->GetTabPage( pTabControl
->GetCurPageId() );
138 processChildren(pTabPage
, bShowAccel
);
140 else if (pChild
->GetType() == WindowType::TABPAGE
)
142 // bare tabpage without tabcontrol parent (options dialog)
143 processChildren(pChild
, bShowAccel
);
145 else if ((pChild
->GetStyle() & (WB_DIALOGCONTROL
| WB_NODIALOGCONTROL
)) == WB_DIALOGCONTROL
)
147 // special controls that manage their children outside of widget layout
148 processChildren(pChild
, bShowAccel
);
152 ImplHandleControlAccelerator(pChild
, bShowAccel
);
154 pChild
= nextLogicalChildOfParent(pParent
, pChild
);
159 bool Accelerator::ToggleMnemonicsOnHierarchy(const CommandEvent
& rCEvent
, const vcl::Window
*pWindow
)
161 if (rCEvent
.GetCommand() == CommandEventId::ModKeyChange
&& ImplGetSVData()->maNWFData
.mbAutoAccel
)
163 const CommandModKeyData
*pCData
= rCEvent
.GetModKeyData();
164 const bool bShowAccel
= pCData
&& pCData
->IsMod2() && pCData
->IsDown();
165 processChildren(pWindow
, bShowAccel
);
171 bool SystemWindow::EventNotify( NotifyEvent
& rNEvt
)
173 if (rNEvt
.GetType() == MouseNotifyEvent::COMMAND
)
174 Accelerator::ToggleMnemonicsOnHierarchy(*rNEvt
.GetCommandEvent(), this);
176 // capture KeyEvents for menu handling
177 if (rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
||
178 rNEvt
.GetType() == MouseNotifyEvent::COMMAND
)
180 MenuBar
* pMBar
= mpMenuBar
;
181 if ( !pMBar
&& ( GetType() == WindowType::FLOATINGWINDOW
) )
183 vcl::Window
* pWin
= ImplGetFrameWindow()->ImplGetWindow();
184 if( pWin
&& pWin
->IsSystemWindow() )
185 pMBar
= static_cast<SystemWindow
*>(pWin
)->GetMenuBar();
190 if (rNEvt
.GetType() == MouseNotifyEvent::COMMAND
)
191 bDone
= pMBar
->ImplHandleCmdEvent(*rNEvt
.GetCommandEvent());
193 bDone
= pMBar
->ImplHandleKeyEvent(*rNEvt
.GetKeyEvent());
199 return Window::EventNotify( rNEvt
);
202 bool SystemWindow::PreNotify( NotifyEvent
& rNEvt
)
204 // capture KeyEvents for taskpane cycling
205 if ( rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
)
207 if( rNEvt
.GetKeyEvent()->GetKeyCode().GetCode() == KEY_F6
&&
208 rNEvt
.GetKeyEvent()->GetKeyCode().IsMod1() &&
209 !rNEvt
.GetKeyEvent()->GetKeyCode().IsShift() )
211 // Ctrl-F6 goes directly to the document
212 GrabFocusToDocument();
217 TaskPaneList
*pTList
= mpImplData
->mpTaskPaneList
.get();
218 if( !pTList
&& ( GetType() == WindowType::FLOATINGWINDOW
) )
220 vcl::Window
* pWin
= ImplGetFrameWindow()->ImplGetWindow();
221 if( pWin
&& pWin
->IsSystemWindow() )
222 pTList
= static_cast<SystemWindow
*>(pWin
)->mpImplData
->mpTaskPaneList
.get();
226 // search topmost system window which is the one to handle dialog/toolbar cycling
227 SystemWindow
*pSysWin
= this;
228 vcl::Window
*pWin
= this;
231 pWin
= pWin
->GetParent();
232 if( pWin
&& pWin
->IsSystemWindow() )
233 pSysWin
= static_cast<SystemWindow
*>(pWin
);
235 pTList
= pSysWin
->mpImplData
->mpTaskPaneList
.get();
237 if( pTList
&& pTList
->HandleKeyEvent( *rNEvt
.GetKeyEvent() ) )
241 return Window::PreNotify( rNEvt
);
244 TaskPaneList
* SystemWindow::GetTaskPaneList()
248 if( mpImplData
->mpTaskPaneList
)
249 return mpImplData
->mpTaskPaneList
.get();
252 mpImplData
->mpTaskPaneList
.reset( new TaskPaneList
);
253 MenuBar
* pMBar
= mpMenuBar
;
254 if ( !pMBar
&& ( GetType() == WindowType::FLOATINGWINDOW
) )
256 vcl::Window
* pWin
= ImplGetFrameWindow()->ImplGetWindow();
257 if ( pWin
&& pWin
->IsSystemWindow() )
258 pMBar
= static_cast<SystemWindow
*>(pWin
)->GetMenuBar();
261 mpImplData
->mpTaskPaneList
->AddWindow( pMBar
->ImplGetWindow() );
262 return mpImplData
->mpTaskPaneList
.get();
266 bool SystemWindow::Close()
268 VclPtr
<vcl::Window
> xWindow
= this;
269 CallEventListeners( VclEventId::WindowClose
);
270 if ( xWindow
->IsDisposed() )
273 if ( mpWindowImpl
->mxWindowPeer
.is() && IsCreatedWithToolkit() )
276 // Is Window not closeable, ignore close
277 vcl::Window
* pBorderWin
= ImplGetBorderWindow();
280 nStyle
= pBorderWin
->GetStyle();
283 if ( !(nStyle
& WB_CLOSEABLE
) )
291 void SystemWindow::TitleButtonClick( TitleButton
)
295 void SystemWindow::Resizing( Size
& )
299 void SystemWindow::SetRepresentedURL( const OUString
& i_rURL
)
301 bool bChanged
= (i_rURL
!= mpImplData
->maRepresentedURL
);
302 mpImplData
->maRepresentedURL
= i_rURL
;
303 if ( !mbSysChild
&& bChanged
)
305 const vcl::Window
* pWindow
= this;
306 while ( pWindow
->mpWindowImpl
->mpBorderWindow
)
307 pWindow
= pWindow
->mpWindowImpl
->mpBorderWindow
;
309 if ( pWindow
->mpWindowImpl
->mbFrame
)
310 pWindow
->mpWindowImpl
->mpFrame
->SetRepresentedURL( i_rURL
);
314 void SystemWindow::SetIcon( sal_uInt16 nIcon
)
316 if ( mnIcon
== nIcon
)
323 const vcl::Window
* pWindow
= this;
324 while ( pWindow
->mpWindowImpl
->mpBorderWindow
)
325 pWindow
= pWindow
->mpWindowImpl
->mpBorderWindow
;
327 if ( pWindow
->mpWindowImpl
->mbFrame
)
328 pWindow
->mpWindowImpl
->mpFrame
->SetIcon( nIcon
);
332 void SystemWindow::ShowTitleButton( TitleButton nButton
, bool bVisible
)
334 if ( nButton
== TitleButton::Docking
)
336 if ( mbDockBtn
!= bVisible
)
338 mbDockBtn
= bVisible
;
339 if ( mpWindowImpl
->mpBorderWindow
)
340 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetDockButton( bVisible
);
343 else if ( nButton
== TitleButton::Hide
)
345 if ( mbHideBtn
!= bVisible
)
347 mbHideBtn
= bVisible
;
348 if ( mpWindowImpl
->mpBorderWindow
)
349 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetHideButton( bVisible
);
352 else if ( nButton
== TitleButton::Menu
)
354 if ( mpWindowImpl
->mpBorderWindow
)
355 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMenuButton( bVisible
);
361 bool SystemWindow::IsTitleButtonVisible( TitleButton nButton
) const
363 if ( nButton
== TitleButton::Docking
)
365 else /* if ( nButton == TitleButton::Hide ) */
369 void SystemWindow::RollUp()
373 maOrgSize
= GetOutputSizePixel();
374 Size aSize
= maRollUpOutSize
;
375 if ( !aSize
.Width() )
376 aSize
.setWidth( GetOutputSizePixel().Width() );
378 if ( mpWindowImpl
->mpBorderWindow
)
379 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetRollUp( true, aSize
);
381 SetOutputSizePixel( aSize
);
385 void SystemWindow::RollDown()
390 if ( mpWindowImpl
->mpBorderWindow
)
391 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetRollUp( false, maOrgSize
);
393 SetOutputSizePixel( maOrgSize
);
397 void SystemWindow::SetMinOutputSizePixel( const Size
& rSize
)
399 maMinOutSize
= rSize
;
400 if ( mpWindowImpl
->mpBorderWindow
)
402 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMinOutputSize( rSize
.Width(), rSize
.Height() );
403 if ( mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbFrame
)
404 mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mpFrame
->SetMinClientSize( rSize
.Width(), rSize
.Height() );
406 else if ( mpWindowImpl
->mbFrame
)
407 mpWindowImpl
->mpFrame
->SetMinClientSize( rSize
.Width(), rSize
.Height() );
410 void SystemWindow::SetMaxOutputSizePixel( const Size
& rSize
)
413 if( aSize
.Width() > SHRT_MAX
|| aSize
.Width() <= 0 )
414 aSize
.setWidth( SHRT_MAX
);
415 if( aSize
.Height() > SHRT_MAX
|| aSize
.Height() <= 0 )
416 aSize
.setHeight( SHRT_MAX
);
418 mpImplData
->maMaxOutSize
= aSize
;
419 if ( mpWindowImpl
->mpBorderWindow
)
421 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMaxOutputSize( aSize
.Width(), aSize
.Height() );
422 if ( mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mbFrame
)
423 mpWindowImpl
->mpBorderWindow
->mpWindowImpl
->mpFrame
->SetMaxClientSize( aSize
.Width(), aSize
.Height() );
425 else if ( mpWindowImpl
->mbFrame
)
426 mpWindowImpl
->mpFrame
->SetMaxClientSize( aSize
.Width(), aSize
.Height() );
429 const Size
& SystemWindow::GetMaxOutputSizePixel() const
431 return mpImplData
->maMaxOutSize
;
434 void ImplWindowStateFromStr(WindowStateData
& rData
,
437 WindowStateMask nValidMask
= WindowStateMask::NONE
;
438 sal_Int32 nIndex
= 0;
440 OString aTokenStr
= rStr
.getToken(0, ',', nIndex
);
441 if (!aTokenStr
.isEmpty())
443 rData
.SetX(aTokenStr
.toInt32());
444 if( rData
.GetX() > -16384 && rData
.GetX() < 16384 )
445 nValidMask
|= WindowStateMask::X
;
451 aTokenStr
= rStr
.getToken(0, ',', nIndex
);
452 if (!aTokenStr
.isEmpty())
454 rData
.SetY(aTokenStr
.toInt32());
455 if( rData
.GetY() > -16384 && rData
.GetY() < 16384 )
456 nValidMask
|= WindowStateMask::Y
;
462 aTokenStr
= rStr
.getToken(0, ',', nIndex
);
463 if (!aTokenStr
.isEmpty())
465 rData
.SetWidth(aTokenStr
.toInt32());
466 if( rData
.GetWidth() > 0 && rData
.GetWidth() < 16384 )
467 nValidMask
|= WindowStateMask::Width
;
473 aTokenStr
= rStr
.getToken(0, ';', nIndex
);
474 if (!aTokenStr
.isEmpty())
476 rData
.SetHeight(aTokenStr
.toInt32());
477 if( rData
.GetHeight() > 0 && rData
.GetHeight() < 16384 )
478 nValidMask
|= WindowStateMask::Height
;
480 rData
.SetHeight( 0 );
483 rData
.SetHeight( 0 );
484 aTokenStr
= rStr
.getToken(0, ';', nIndex
);
485 if (!aTokenStr
.isEmpty())
487 // #94144# allow Minimize again, should be masked out when read from configuration
488 // 91625 - ignore Minimize
489 WindowStateState nState
= static_cast<WindowStateState
>(aTokenStr
.toInt32());
490 //nState &= ~(WindowStateState::Minimized);
491 rData
.SetState( nState
);
492 nValidMask
|= WindowStateMask::State
;
495 rData
.SetState( WindowStateState::NONE
);
497 // read maximized pos/size
498 aTokenStr
= rStr
.getToken(0, ',', nIndex
);
499 if (!aTokenStr
.isEmpty())
501 rData
.SetMaximizedX(aTokenStr
.toInt32());
502 if( rData
.GetMaximizedX() > -16384 && rData
.GetMaximizedX() < 16384 )
503 nValidMask
|= WindowStateMask::MaximizedX
;
505 rData
.SetMaximizedX( 0 );
508 rData
.SetMaximizedX( 0 );
509 aTokenStr
= rStr
.getToken(0, ',', nIndex
);
510 if (!aTokenStr
.isEmpty())
512 rData
.SetMaximizedY(aTokenStr
.toInt32());
513 if( rData
.GetMaximizedY() > -16384 && rData
.GetMaximizedY() < 16384 )
514 nValidMask
|= WindowStateMask::MaximizedY
;
516 rData
.SetMaximizedY( 0 );
519 rData
.SetMaximizedY( 0 );
520 aTokenStr
= rStr
.getToken(0, ',', nIndex
);
521 if (!aTokenStr
.isEmpty())
523 rData
.SetMaximizedWidth(aTokenStr
.toInt32());
524 if( rData
.GetMaximizedWidth() > 0 && rData
.GetMaximizedWidth() < 16384 )
525 nValidMask
|= WindowStateMask::MaximizedWidth
;
527 rData
.SetMaximizedWidth( 0 );
530 rData
.SetMaximizedWidth( 0 );
531 aTokenStr
= rStr
.getToken(0, ';', nIndex
);
532 if (!aTokenStr
.isEmpty())
534 rData
.SetMaximizedHeight(aTokenStr
.toInt32());
535 if( rData
.GetMaximizedHeight() > 0 && rData
.GetMaximizedHeight() < 16384 )
536 nValidMask
|= WindowStateMask::MaximizedHeight
;
538 rData
.SetMaximizedHeight( 0 );
541 rData
.SetMaximizedHeight( 0 );
544 rData
.SetMask( nValidMask
);
547 OString
WindowStateData::ToStr() const
549 const WindowStateMask nValidMask
= GetMask();
550 if ( nValidMask
== WindowStateMask::NONE
)
553 OStringBuffer
rStrBuf(64);
555 if ( nValidMask
& WindowStateMask::X
)
556 rStrBuf
.append(static_cast<sal_Int32
>(GetX()));
558 if ( nValidMask
& WindowStateMask::Y
)
559 rStrBuf
.append(static_cast<sal_Int32
>(GetY()));
561 if ( nValidMask
& WindowStateMask::Width
)
562 rStrBuf
.append(static_cast<sal_Int32
>(GetWidth()));
564 if ( nValidMask
& WindowStateMask::Height
)
565 rStrBuf
.append(static_cast<sal_Int32
>(GetHeight()));
566 rStrBuf
.append( ';' );
567 if ( nValidMask
& WindowStateMask::State
)
569 // #94144# allow Minimize again, should be masked out when read from configuration
570 // 91625 - ignore Minimize
571 WindowStateState nState
= GetState();
572 rStrBuf
.append(static_cast<sal_Int32
>(nState
));
575 if ( nValidMask
& WindowStateMask::MaximizedX
)
576 rStrBuf
.append(static_cast<sal_Int32
>(GetMaximizedX()));
578 if ( nValidMask
& WindowStateMask::MaximizedY
)
579 rStrBuf
.append(static_cast<sal_Int32
>(GetMaximizedY()));
580 rStrBuf
.append( ',' );
581 if ( nValidMask
& WindowStateMask::MaximizedWidth
)
582 rStrBuf
.append(static_cast<sal_Int32
>(GetMaximizedWidth()));
584 if ( nValidMask
& WindowStateMask::MaximizedHeight
)
585 rStrBuf
.append(static_cast<sal_Int32
>(GetMaximizedHeight()));
588 return rStrBuf
.makeStringAndClear();
591 void SystemWindow::ImplMoveToScreen( tools::Long
& io_rX
, tools::Long
& io_rY
, tools::Long i_nWidth
, tools::Long i_nHeight
, vcl::Window
const * i_pConfigureWin
)
593 tools::Rectangle aScreenRect
;
594 if( !Application::IsUnifiedDisplay() )
595 aScreenRect
= Application::GetScreenPosSizePixel( GetScreenNumber() );
598 aScreenRect
= Application::GetScreenPosSizePixel( 0 );
599 for( unsigned int i
= 1; i
< Application::GetScreenCount(); i
++ )
600 aScreenRect
.Union( Application::GetScreenPosSizePixel( i
) );
602 // unfortunately most of the time width and height are not really known
610 if( io_rX
+ i_nWidth
< aScreenRect
.Left() )
613 io_rX
= aScreenRect
.Left();
615 // check right border
616 if( io_rX
> aScreenRect
.Right() - i_nWidth
)
619 io_rX
= aScreenRect
.Right() - i_nWidth
;
622 if( io_rY
+ i_nHeight
< aScreenRect
.Top() )
625 io_rY
= aScreenRect
.Top();
627 // check bottom border
628 if( io_rY
> aScreenRect
.Bottom() - i_nHeight
)
631 io_rY
= aScreenRect
.Bottom() - i_nHeight
;
633 vcl::Window
* pParent
= i_pConfigureWin
->GetParent();
634 if( bMove
&& pParent
)
636 // calculate absolute screen pos here, since that is what is contained in WindowState
637 Point
aParentAbsPos( pParent
->OutputToAbsoluteScreenPixel( Point(0,0) ) );
638 Size
aParentSizePixel( pParent
->GetOutputSizePixel() );
639 Point
aPos( (aParentSizePixel
.Width() - i_nWidth
) / 2,
640 (aParentSizePixel
.Height() - i_nHeight
) / 2 );
641 io_rX
= aParentAbsPos
.X() + aPos
.X();
642 io_rY
= aParentAbsPos
.Y() + aPos
.Y();
646 void SystemWindow::SetWindowStateData( const WindowStateData
& rData
)
648 const WindowStateMask nValidMask
= rData
.GetMask();
649 if ( nValidMask
== WindowStateMask::NONE
)
655 vcl::Window
* pWindow
= this;
656 while ( pWindow
->mpWindowImpl
->mpBorderWindow
)
657 pWindow
= pWindow
->mpWindowImpl
->mpBorderWindow
;
659 if ( pWindow
->mpWindowImpl
->mbFrame
)
661 const WindowStateState nState
= rData
.GetState();
662 SalFrameState aState
;
663 aState
.mnMask
= rData
.GetMask();
664 aState
.mnX
= rData
.GetX();
665 aState
.mnY
= rData
.GetY();
666 aState
.mnWidth
= rData
.GetWidth();
667 aState
.mnHeight
= rData
.GetHeight();
669 if( rData
.GetMask() & (WindowStateMask::Width
|WindowStateMask::Height
) )
671 // #i43799# adjust window state sizes if a minimal output size was set
672 // otherwise the frame and the client might get different sizes
673 if( maMinOutSize
.Width() > aState
.mnWidth
)
674 aState
.mnWidth
= maMinOutSize
.Width();
675 if( maMinOutSize
.Height() > aState
.mnHeight
)
676 aState
.mnHeight
= maMinOutSize
.Height();
679 aState
.mnMaximizedX
= rData
.GetMaximizedX();
680 aState
.mnMaximizedY
= rData
.GetMaximizedY();
681 aState
.mnMaximizedWidth
= rData
.GetMaximizedWidth();
682 aState
.mnMaximizedHeight
= rData
.GetMaximizedHeight();
683 // #94144# allow Minimize again, should be masked out when read from configuration
684 // 91625 - ignore Minimize
685 //nState &= ~(WindowStateState::Minimized);
686 aState
.mnState
= nState
& WindowStateState::SystemMask
;
688 // normalize window positions onto screen
689 ImplMoveToScreen( aState
.mnX
, aState
.mnY
, aState
.mnWidth
, aState
.mnHeight
, pWindow
);
690 ImplMoveToScreen( aState
.mnMaximizedX
, aState
.mnMaximizedY
, aState
.mnMaximizedWidth
, aState
.mnMaximizedHeight
, pWindow
);
692 // #96568# avoid having multiple frames at the same screen location
693 // do the check only if not maximized
694 if( !((rData
.GetMask() & WindowStateMask::State
) && (nState
& WindowStateState::Maximized
)) )
695 if( rData
.GetMask() & (WindowStateMask::Pos
|WindowStateMask::Width
|WindowStateMask::Height
) )
697 tools::Rectangle aDesktop
= GetDesktopRectPixel();
698 ImplSVData
*pSVData
= ImplGetSVData();
699 vcl::Window
*pWin
= pSVData
->maFrameData
.mpFirstFrame
;
700 bool bWrapped
= false;
703 if( !pWin
->ImplIsRealParentPath( this ) && ( pWin
!= this ) &&
704 pWin
->ImplGetWindow()->IsTopWindow() && pWin
->mpWindowImpl
->mbReallyVisible
)
706 SalFrameGeometry g
= pWin
->mpWindowImpl
->mpFrame
->GetGeometry();
707 if( std::abs(g
.nX
-aState
.mnX
) < 2 && std::abs(g
.nY
-aState
.mnY
) < 5 )
709 tools::Long displacement
= g
.nTopDecoration
? g
.nTopDecoration
: 20;
710 if( static_cast<tools::Long
>(aState
.mnX
+ displacement
+ aState
.mnWidth
+ g
.nRightDecoration
) > aDesktop
.Right() ||
711 static_cast<tools::Long
>(aState
.mnY
+ displacement
+ aState
.mnHeight
+ g
.nBottomDecoration
) > aDesktop
.Bottom() )
713 // displacing would leave screen
714 aState
.mnX
= g
.nLeftDecoration
? g
.nLeftDecoration
: 10; // should result in (0,0)
715 aState
.mnY
= displacement
;
717 static_cast<tools::Long
>(aState
.mnX
+ displacement
+ aState
.mnWidth
+ g
.nRightDecoration
) > aDesktop
.Right() ||
718 static_cast<tools::Long
>(aState
.mnY
+ displacement
+ aState
.mnHeight
+ g
.nBottomDecoration
) > aDesktop
.Bottom() )
719 break; // further displacement not possible -> break
720 // avoid endless testing
726 aState
.mnX
+= displacement
;
727 aState
.mnY
+= displacement
;
729 pWin
= pSVData
->maFrameData
.mpFirstFrame
; // check new pos again
732 pWin
= pWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
736 mpWindowImpl
->mpFrame
->SetWindowState( &aState
);
738 // do a synchronous resize for layout reasons
739 // but use rData only when the window is not to be maximized (#i38089#)
740 // otherwise we have no useful size information
741 if( (rData
.GetMask() & WindowStateMask::State
) && (nState
& WindowStateState::Maximized
) )
743 // query maximized size from frame
744 SalFrameGeometry aGeometry
= mpWindowImpl
->mpFrame
->GetGeometry();
746 // but use it only if it is different from the restore size (rData)
747 // as currently only on windows the exact size of a maximized window
748 // can be computed without actually showing the window
749 if( aGeometry
.nWidth
!= rData
.GetWidth() || aGeometry
.nHeight
!= rData
.GetHeight() )
750 ImplHandleResize( pWindow
, aGeometry
.nWidth
, aGeometry
.nHeight
);
753 if( rData
.GetMask() & (WindowStateMask::Width
|WindowStateMask::Height
) )
754 ImplHandleResize( pWindow
, aState
.mnWidth
, aState
.mnHeight
); // #i43799# use aState and not rData, see above
758 PosSizeFlags nPosSize
= PosSizeFlags::NONE
;
759 if ( nValidMask
& WindowStateMask::X
)
760 nPosSize
|= PosSizeFlags::X
;
761 if ( nValidMask
& WindowStateMask::Y
)
762 nPosSize
|= PosSizeFlags::Y
;
763 if ( nValidMask
& WindowStateMask::Width
)
764 nPosSize
|= PosSizeFlags::Width
;
765 if ( nValidMask
& WindowStateMask::Height
)
766 nPosSize
|= PosSizeFlags::Height
;
771 tools::Long nX
= rData
.GetX();
772 tools::Long nY
= rData
.GetY();
773 tools::Long nWidth
= rData
.GetWidth();
774 tools::Long nHeight
= rData
.GetHeight();
775 const SalFrameGeometry
& rGeom
= pWindow
->mpWindowImpl
->mpFrame
->GetGeometry();
778 if( nX
+ nWidth
> static_cast<tools::Long
>(rGeom
.nWidth
) )
779 nX
= rGeom
.nWidth
- nWidth
;
782 if( nY
+ nHeight
> static_cast<tools::Long
>(rGeom
.nHeight
) )
783 nY
= rGeom
.nHeight
- nHeight
;
784 setPosSizePixel( nX
, nY
, nWidth
, nHeight
, nPosSize
);
785 maOrgSize
= Size( nWidth
, nHeight
);
787 // 91625 - ignore Minimize
788 if ( nValidMask
& WindowStateMask::State
)
790 const WindowStateState nState
= rData
.GetState();
791 if ( nState
& WindowStateState::Rollup
)
799 void SystemWindow::GetWindowStateData( WindowStateData
& rData
) const
801 WindowStateMask nValidMask
= rData
.GetMask();
802 if ( nValidMask
== WindowStateMask::NONE
)
808 const vcl::Window
* pWindow
= this;
809 while ( pWindow
->mpWindowImpl
->mpBorderWindow
)
810 pWindow
= pWindow
->mpWindowImpl
->mpBorderWindow
;
812 if ( pWindow
->mpWindowImpl
->mbFrame
)
814 SalFrameState aState
;
815 aState
.mnMask
= WindowStateMask::All
;
816 if ( mpWindowImpl
->mpFrame
->GetWindowState( &aState
) )
818 if ( nValidMask
& WindowStateMask::X
)
819 rData
.SetX( aState
.mnX
);
820 if ( nValidMask
& WindowStateMask::Y
)
821 rData
.SetY( aState
.mnY
);
822 if ( nValidMask
& WindowStateMask::Width
)
823 rData
.SetWidth( aState
.mnWidth
);
824 if ( nValidMask
& WindowStateMask::Height
)
825 rData
.SetHeight( aState
.mnHeight
);
826 if ( aState
.mnMask
& WindowStateMask::MaximizedX
)
828 rData
.SetMaximizedX( aState
.mnMaximizedX
);
829 nValidMask
|= WindowStateMask::MaximizedX
;
831 if ( aState
.mnMask
& WindowStateMask::MaximizedY
)
833 rData
.SetMaximizedY( aState
.mnMaximizedY
);
834 nValidMask
|= WindowStateMask::MaximizedY
;
836 if ( aState
.mnMask
& WindowStateMask::MaximizedWidth
)
838 rData
.SetMaximizedWidth( aState
.mnMaximizedWidth
);
839 nValidMask
|= WindowStateMask::MaximizedWidth
;
841 if ( aState
.mnMask
& WindowStateMask::MaximizedHeight
)
843 rData
.SetMaximizedHeight( aState
.mnMaximizedHeight
);
844 nValidMask
|= WindowStateMask::MaximizedHeight
;
846 if ( nValidMask
& WindowStateMask::State
)
848 // #94144# allow Minimize again, should be masked out when read from configuration
849 // 91625 - ignore Minimize
850 if ( !(nValidMask
&WindowStateMask::Minimized
) )
851 aState
.mnState
&= ~WindowStateState::Minimized
;
852 rData
.SetState( aState
.mnState
);
854 rData
.SetMask( nValidMask
);
857 rData
.SetMask( WindowStateMask::NONE
);
861 Point aPos
= GetPosPixel();
862 Size aSize
= GetSizePixel();
863 WindowStateState nState
= WindowStateState::NONE
;
867 aSize
.AdjustHeight(maOrgSize
.Height() );
868 nState
= WindowStateState::Rollup
;
871 if ( nValidMask
& WindowStateMask::X
)
872 rData
.SetX( aPos
.X() );
873 if ( nValidMask
& WindowStateMask::Y
)
874 rData
.SetY( aPos
.Y() );
875 if ( nValidMask
& WindowStateMask::Width
)
876 rData
.SetWidth( aSize
.Width() );
877 if ( nValidMask
& WindowStateMask::Height
)
878 rData
.SetHeight( aSize
.Height() );
879 if ( nValidMask
& WindowStateMask::State
)
880 rData
.SetState( nState
);
884 void SystemWindow::SetWindowState(const OString
& rStr
)
889 WindowStateData aData
;
890 ImplWindowStateFromStr( aData
, rStr
);
891 SetWindowStateData( aData
);
894 OString
SystemWindow::GetWindowState( WindowStateMask nMask
) const
896 WindowStateData aData
;
897 aData
.SetMask( nMask
);
898 GetWindowStateData( aData
);
900 return aData
.ToStr();
903 void SystemWindow::SetMenuBar(MenuBar
* pMenuBar
)
905 if ( mpMenuBar
== pMenuBar
)
908 MenuBar
* pOldMenuBar
= mpMenuBar
;
909 vcl::Window
* pOldWindow
= nullptr;
910 VclPtr
<vcl::Window
> pNewWindow
;
911 mpMenuBar
= pMenuBar
;
913 if ( mpWindowImpl
->mpBorderWindow
&& (mpWindowImpl
->mpBorderWindow
->GetType() == WindowType::BORDERWINDOW
) )
916 pOldWindow
= pOldMenuBar
->ImplGetWindow();
918 pOldWindow
= nullptr;
921 CallEventListeners( VclEventId::WindowMenubarRemoved
, static_cast<void*>(pOldMenuBar
) );
922 pOldWindow
->SetAccessible( css::uno::Reference
< css::accessibility::XAccessible
>() );
926 SAL_WARN_IF( pMenuBar
->pWindow
, "vcl", "SystemWindow::SetMenuBar() - MenuBars can only set in one SystemWindow at time" );
928 pNewWindow
= MenuBar::ImplCreate(mpWindowImpl
->mpBorderWindow
, pOldWindow
, pMenuBar
);
929 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMenuBarWindow(pNewWindow
);
931 CallEventListeners( VclEventId::WindowMenubarAdded
, static_cast<void*>(pMenuBar
) );
934 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMenuBarWindow( nullptr );
938 bool bDelete
= (pMenuBar
== nullptr);
939 if( bDelete
&& pOldWindow
)
941 if( mpImplData
->mpTaskPaneList
)
942 mpImplData
->mpTaskPaneList
->RemoveWindow( pOldWindow
);
944 MenuBar::ImplDestroy( pOldMenuBar
, bDelete
);
946 pOldWindow
= nullptr; // will be deleted in MenuBar::ImplDestroy,
953 pNewWindow
= pMenuBar
->ImplGetWindow();
955 pOldWindow
= pOldMenuBar
->ImplGetWindow();
958 // update taskpane list to make menubar accessible
959 if( mpImplData
->mpTaskPaneList
)
962 mpImplData
->mpTaskPaneList
->RemoveWindow( pOldWindow
);
964 mpImplData
->mpTaskPaneList
->AddWindow( pNewWindow
);
968 void SystemWindow::SetNotebookBar(const OUString
& rUIXMLDescription
,
969 const css::uno::Reference
<css::frame::XFrame
>& rFrame
,
970 const NotebookBarAddonsItem
& aNotebookBarAddonsItem
,
971 bool bReloadNotebookbar
)
973 if (rUIXMLDescription
!= maNotebookBarUIFile
|| bReloadNotebookbar
)
975 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())
976 ->SetNotebookBar(rUIXMLDescription
, rFrame
, aNotebookBarAddonsItem
);
977 maNotebookBarUIFile
= rUIXMLDescription
;
979 GetNotebookBar()->SetSystemWindow(this);
983 void SystemWindow::CloseNotebookBar()
985 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->CloseNotebookBar();
986 maNotebookBarUIFile
.clear();
989 VclPtr
<NotebookBar
> const & SystemWindow::GetNotebookBar() const
991 return static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->GetNotebookBar();
994 void SystemWindow::SetMenuBarMode( MenuBarMode nMode
)
996 if ( mnMenuBarMode
!= nMode
)
998 mnMenuBarMode
= nMode
;
999 if ( mpWindowImpl
->mpBorderWindow
&& (mpWindowImpl
->mpBorderWindow
->GetType() == WindowType::BORDERWINDOW
) )
1001 if ( nMode
== MenuBarMode::Hide
)
1002 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMenuBarMode( true );
1004 static_cast<ImplBorderWindow
*>(mpWindowImpl
->mpBorderWindow
.get())->SetMenuBarMode( false );
1009 bool SystemWindow::ImplIsInTaskPaneList( vcl::Window
* pWin
)
1011 if( mpImplData
&& mpImplData
->mpTaskPaneList
)
1012 return mpImplData
->mpTaskPaneList
->IsInList( pWin
);
1016 unsigned int SystemWindow::GetScreenNumber() const
1018 return mpWindowImpl
->mpFrame
->maGeometry
.nDisplayScreenNumber
;
1021 void SystemWindow::SetScreenNumber(unsigned int nDisplayScreen
)
1023 mpWindowImpl
->mpFrame
->SetScreenNumber( nDisplayScreen
);
1026 void SystemWindow::SetApplicationID(const OUString
&rApplicationID
)
1028 mpWindowImpl
->mpFrame
->SetApplicationID( rApplicationID
);
1031 void SystemWindow::SetCloseHdl(const Link
<SystemWindow
&,void>& rLink
)
1033 mpImplData
->maCloseHdl
= rLink
;
1036 const Link
<SystemWindow
&,void>& SystemWindow::GetCloseHdl() const
1038 return mpImplData
->maCloseHdl
;
1041 void SystemWindow::queue_resize(StateChangedType
/*eReason*/)
1043 if (!isLayoutEnabled())
1045 if (isCalculatingInitialLayoutSize())
1047 InvalidateSizeCache();
1048 if (hasPendingLayout())
1050 maLayoutIdle
.Start();
1053 void SystemWindow::Resize()
1058 bool SystemWindow::isLayoutEnabled() const
1060 //pre dtor called, and single child is a container => we're layout enabled
1061 return mpImplData
&& ::isLayoutEnabled(this);
1064 Size
SystemWindow::GetOptimalSize() const
1066 if (!isLayoutEnabled())
1067 return Window::GetOptimalSize();
1069 Window
*pBox
= GetWindow(GetWindowType::FirstChild
);
1070 // tdf#141318 Do the same as SystemWindow::setOptimalLayoutSize in case we're called before initial layout
1071 const_cast<SystemWindow
*>(this)->settingOptimalLayoutSize(pBox
);
1072 Size aSize
= VclContainer::getLayoutRequisition(*pBox
);
1074 sal_Int32 nBorderWidth
= get_border_width();
1076 aSize
.AdjustHeight(2 * nBorderWidth
);
1077 aSize
.AdjustWidth(2 * nBorderWidth
);
1079 return Window::CalcWindowSize(aSize
);
1082 void SystemWindow::setPosSizeOnContainee(Size aSize
, Window
&rBox
)
1084 sal_Int32 nBorderWidth
= get_border_width();
1086 aSize
.AdjustWidth( -(2 * nBorderWidth
) );
1087 aSize
.AdjustHeight( -(2 * nBorderWidth
) );
1089 Point
aPos(nBorderWidth
, nBorderWidth
);
1090 VclContainer::setLayoutAllocation(rBox
, aPos
, CalcOutputSize(aSize
));
1093 IMPL_LINK_NOARG( SystemWindow
, ImplHandleLayoutTimerHdl
, Timer
*, void )
1095 if (!isLayoutEnabled())
1097 SAL_WARN("vcl.layout", "SystemWindow has become non-layout because extra children have been added directly to it.");
1101 Window
*pBox
= GetWindow(GetWindowType::FirstChild
);
1103 setPosSizeOnContainee(GetSizePixel(), *pBox
);
1106 void SystemWindow::SetText(const OUString
& rStr
)
1108 setDeferredProperties();
1109 Window::SetText(rStr
);
1112 OUString
SystemWindow::GetText() const
1114 const_cast<SystemWindow
*>(this)->setDeferredProperties();
1115 return Window::GetText();
1118 void SystemWindow::settingOptimalLayoutSize(Window
* /*pBox*/)
1122 void SystemWindow::setOptimalLayoutSize()
1124 maLayoutIdle
.Stop();
1126 //resize SystemWindow to fit requisition on initial show
1127 Window
*pBox
= GetWindow(GetWindowType::FirstChild
);
1129 settingOptimalLayoutSize(pBox
);
1131 Size aSize
= get_preferred_size();
1133 Size
aMax(bestmaxFrameSizeForScreenSize(GetDesktopRectPixel().GetSize()));
1135 aSize
.setWidth( std::min(aMax
.Width(), aSize
.Width()) );
1136 aSize
.setHeight( std::min(aMax
.Height(), aSize
.Height()) );
1138 SetMinOutputSizePixel(aSize
);
1139 SetSizePixel(aSize
);
1140 setPosSizeOnContainee(aSize
, *pBox
);
1143 void SystemWindow::DoInitialLayout()
1145 if (GetSettings().GetStyleSettings().GetAutoMnemonic())
1146 Accelerator::GenerateAutoMnemonicsOnHierarchy(this);
1148 if (isLayoutEnabled())
1150 mbIsCalculatingInitialLayoutSize
= true;
1151 setDeferredProperties();
1152 setOptimalLayoutSize();
1153 mbIsCalculatingInitialLayoutSize
= false;
1157 void SystemWindow::doDeferredInit(WinBits
/*nBits*/)
1159 SAL_WARN("vcl.layout", "SystemWindow in layout without doDeferredInit impl");
1162 VclPtr
<VirtualDevice
> SystemWindow::createScreenshot()
1164 // same prerequisites as in Execute()
1165 setDeferredProperties();
1166 ImplAdjustNWFSizes();
1171 Size
aSize(GetOutputSizePixel());
1173 VclPtr
<VirtualDevice
> xOutput(VclPtr
<VirtualDevice
>::Create(DeviceFormat::DEFAULT
));
1174 xOutput
->SetOutputSizePixel(aSize
);
1177 xOutput
->DrawOutDev(aPos
, aSize
, aPos
, aSize
, *this);
1182 void SystemWindow::PrePaint(vcl::RenderContext
& rRenderContext
)
1184 Window::PrePaint(rRenderContext
);
1185 mbPaintComplete
= false;
1188 void SystemWindow::PostPaint(vcl::RenderContext
& rRenderContext
)
1190 Window::PostPaint(rRenderContext
);
1191 mbPaintComplete
= true;
1194 void SystemWindow::ensureRepaint()
1198 mbPaintComplete
= false;
1200 while (!mbPaintComplete
)
1202 Application::Yield();
1206 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */