1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <memory>
21 #include <sal/config.h>
22 #include <sal/log.hxx>
23 
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>
35 
36 #include <rtl/strbuf.hxx>
37 
38 #include <salframe.hxx>
39 #include <svdata.hxx>
40 #include <brdwin.hxx>
41 #include <window.h>
42 
43 using namespace ::com::sun::star::uno;
44 using namespace ::com::sun::star::lang;
45 
46 class SystemWindow::ImplData
47 {
48 public:
49     ImplData();
50 
51     std::unique_ptr<TaskPaneList>
52                     mpTaskPaneList;
53     Size            maMaxOutSize;
54     OUString        maRepresentedURL;
55     Link<SystemWindow&,void> maCloseHdl;
56 };
57 
ImplData()58 SystemWindow::ImplData::ImplData()
59 {
60     mpTaskPaneList = nullptr;
61     maMaxOutSize = Size( SHRT_MAX, SHRT_MAX );
62 }
63 
SystemWindow(WindowType nType)64 SystemWindow::SystemWindow(WindowType nType)
65     : Window(nType)
66     , mbRollUp(false)
67     , mbDockBtn(false)
68     , mbHideBtn(false)
69     , mbSysChild(false)
70     , mbIsCalculatingInitialLayoutSize(false)
71     , mbPaintComplete(false)
72     , mnMenuBarMode(MenuBarMode::Normal)
73     , mnIcon(0)
74     , mpImplData(new ImplData)
75     , mbIsDeferredInit(false)
76 {
77     mpWindowImpl->mbSysWin            = true;
78     mpWindowImpl->mnActivateMode      = ActivateModeFlags::GrabFocus;
79 
80     //To-Do, reuse maResizeTimer
81     maLayoutIdle.SetPriority(TaskPriority::RESIZE);
82     maLayoutIdle.SetInvokeHandler( LINK( this, SystemWindow, ImplHandleLayoutTimerHdl ) );
83     maLayoutIdle.SetDebugName( "vcl::SystemWindow maLayoutIdle" );
84 }
85 
loadUI(vcl::Window * pParent,const OString & rID,const OUString & rUIXMLDescription,const css::uno::Reference<css::frame::XFrame> & rFrame)86 void SystemWindow::loadUI(vcl::Window* pParent, const OString& rID, const OUString& rUIXMLDescription,
87     const css::uno::Reference<css::frame::XFrame> &rFrame)
88 {
89     mbIsDeferredInit = true;
90     mpDialogParent = pParent; //should be unset in doDeferredInit
91     m_pUIBuilder.reset( new VclBuilder(this, getUIRootDir(), rUIXMLDescription, rID, rFrame) );
92 }
93 
~SystemWindow()94 SystemWindow::~SystemWindow()
95 {
96     disposeOnce();
97 }
98 
dispose()99 void SystemWindow::dispose()
100 {
101     maLayoutIdle.Stop();
102     mpImplData.reset();
103 
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;
107     disposeBuilder();
108     mpDialogParent.clear();
109     mpMenuBar.clear();
110     Window::dispose();
111 }
112 
ImplHandleControlAccelerator(const vcl::Window * pWindow,bool bShow)113 static void ImplHandleControlAccelerator( const vcl::Window* pWindow, bool bShow )
114 {
115     Control *pControl = dynamic_cast<Control*>(pWindow->ImplGetWindow());
116     if (pControl && pControl->GetText().indexOf('~') != -1)
117     {
118         pControl->SetShowAccelerator( bShow );
119         pControl->Invalidate(InvalidateFlags::Update);
120     }
121 }
122 
123 namespace
124 {
processChildren(const vcl::Window * pParent,bool bShowAccel)125     void processChildren(const vcl::Window *pParent, bool bShowAccel)
126     {
127         // go through its children
128         vcl::Window* pChild = firstLogicalChildOfParent(pParent);
129         while (pChild)
130         {
131             if (pChild->GetType() == WindowType::TABCONTROL)
132             {
133                 // find currently shown tab page
134                 TabControl* pTabControl = static_cast<TabControl*>(pChild);
135                 TabPage* pTabPage = pTabControl->GetTabPage( pTabControl->GetCurPageId() );
136                 processChildren(pTabPage, bShowAccel);
137             }
138             else if (pChild->GetType() == WindowType::TABPAGE)
139             {
140                 // bare tabpage without tabcontrol parent (options dialog)
141                 processChildren(pChild, bShowAccel);
142             }
143             else if ((pChild->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) == WB_DIALOGCONTROL)
144             {
145                 // special controls that manage their children outside of widget layout
146                 processChildren(pChild, bShowAccel);
147             }
148             else
149             {
150                 ImplHandleControlAccelerator(pChild, bShowAccel);
151             }
152             pChild = nextLogicalChildOfParent(pParent, pChild);
153         }
154     }
155 }
156 
ToggleMnemonicsOnHierarchy(const CommandEvent & rCEvent,const vcl::Window * pWindow)157 bool Accelerator::ToggleMnemonicsOnHierarchy(const CommandEvent& rCEvent, const vcl::Window *pWindow)
158 {
159     if (rCEvent.GetCommand() == CommandEventId::ModKeyChange && ImplGetSVData()->maNWFData.mbAutoAccel)
160     {
161         const CommandModKeyData *pCData = rCEvent.GetModKeyData();
162         const bool bShowAccel = pCData && pCData->IsMod2() && pCData->IsDown();
163         processChildren(pWindow, bShowAccel);
164         return true;
165     }
166     return false;
167 }
168 
EventNotify(NotifyEvent & rNEvt)169 bool SystemWindow::EventNotify( NotifyEvent& rNEvt )
170 {
171     if (rNEvt.GetType() == MouseNotifyEvent::COMMAND)
172         Accelerator::ToggleMnemonicsOnHierarchy(*rNEvt.GetCommandEvent(), this);
173 
174     // capture KeyEvents for menu handling
175     if (rNEvt.GetType() == MouseNotifyEvent::KEYINPUT ||
176         rNEvt.GetType() == MouseNotifyEvent::COMMAND)
177     {
178         MenuBar* pMBar = mpMenuBar;
179         if ( !pMBar && ( GetType() == WindowType::FLOATINGWINDOW ) )
180         {
181             vcl::Window* pWin = ImplGetFrameWindow()->ImplGetWindow();
182             if( pWin && pWin->IsSystemWindow() )
183                 pMBar = static_cast<SystemWindow*>(pWin)->GetMenuBar();
184         }
185         bool bDone(false);
186         if (pMBar)
187         {
188             if (rNEvt.GetType() == MouseNotifyEvent::COMMAND)
189                 bDone = pMBar->ImplHandleCmdEvent(*rNEvt.GetCommandEvent());
190             else
191                 bDone = pMBar->ImplHandleKeyEvent(*rNEvt.GetKeyEvent());
192         }
193         if (bDone)
194             return true;
195     }
196 
197     return Window::EventNotify( rNEvt );
198 }
199 
PreNotify(NotifyEvent & rNEvt)200 bool SystemWindow::PreNotify( NotifyEvent& rNEvt )
201 {
202     // capture KeyEvents for taskpane cycling
203     if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
204     {
205         if( rNEvt.GetKeyEvent()->GetKeyCode().GetCode() == KEY_F6 &&
206             rNEvt.GetKeyEvent()->GetKeyCode().IsMod1() &&
207            !rNEvt.GetKeyEvent()->GetKeyCode().IsShift() )
208         {
209             // Ctrl-F6 goes directly to the document
210             GrabFocusToDocument();
211             return true;
212         }
213         else
214         {
215             TaskPaneList *pTList = mpImplData->mpTaskPaneList.get();
216             if( !pTList && ( GetType() == WindowType::FLOATINGWINDOW ) )
217             {
218                 vcl::Window* pWin = ImplGetFrameWindow()->ImplGetWindow();
219                 if( pWin && pWin->IsSystemWindow() )
220                     pTList = static_cast<SystemWindow*>(pWin)->mpImplData->mpTaskPaneList.get();
221             }
222             if( !pTList )
223             {
224                 // search topmost system window which is the one to handle dialog/toolbar cycling
225                 SystemWindow *pSysWin = this;
226                 vcl::Window *pWin = this;
227                 while( pWin )
228                 {
229                     pWin = pWin->GetParent();
230                     if( pWin && pWin->IsSystemWindow() )
231                         pSysWin = static_cast<SystemWindow*>(pWin);
232                 }
233                 pTList = pSysWin->mpImplData->mpTaskPaneList.get();
234             }
235             if( pTList && pTList->HandleKeyEvent( *rNEvt.GetKeyEvent() ) )
236                 return true;
237         }
238     }
239     return Window::PreNotify( rNEvt );
240 }
241 
GetTaskPaneList()242 TaskPaneList* SystemWindow::GetTaskPaneList()
243 {
244     if( !mpImplData )
245         return nullptr;
246     if( mpImplData->mpTaskPaneList )
247         return mpImplData->mpTaskPaneList.get();
248     else
249     {
250         mpImplData->mpTaskPaneList.reset( new TaskPaneList );
251         MenuBar* pMBar = mpMenuBar;
252         if ( !pMBar && ( GetType() == WindowType::FLOATINGWINDOW ) )
253         {
254             vcl::Window* pWin = ImplGetFrameWindow()->ImplGetWindow();
255             if ( pWin && pWin->IsSystemWindow() )
256                 pMBar = static_cast<SystemWindow*>(pWin)->GetMenuBar();
257         }
258         if( pMBar )
259             mpImplData->mpTaskPaneList->AddWindow( pMBar->ImplGetWindow() );
260         return mpImplData->mpTaskPaneList.get();
261     }
262 }
263 
Close()264 bool SystemWindow::Close()
265 {
266     VclPtr<vcl::Window> xWindow = this;
267     CallEventListeners( VclEventId::WindowClose );
268     if ( xWindow->IsDisposed() )
269         return false;
270 
271     if ( mpWindowImpl->mxWindowPeer.is() && IsCreatedWithToolkit() )
272         return false;
273 
274     // Is Window not closeable, ignore close
275     vcl::Window*     pBorderWin = ImplGetBorderWindow();
276     WinBits     nStyle;
277     if ( pBorderWin )
278         nStyle = pBorderWin->GetStyle();
279     else
280         nStyle = GetStyle();
281     if ( !(nStyle & WB_CLOSEABLE) )
282         return false;
283 
284     Hide();
285 
286     return true;
287 }
288 
TitleButtonClick(TitleButton)289 void SystemWindow::TitleButtonClick( TitleButton )
290 {
291 }
292 
Resizing(Size &)293 void SystemWindow::Resizing( Size& )
294 {
295 }
296 
SetRepresentedURL(const OUString & i_rURL)297 void SystemWindow::SetRepresentedURL( const OUString& i_rURL )
298 {
299     bool bChanged = (i_rURL != mpImplData->maRepresentedURL);
300     mpImplData->maRepresentedURL = i_rURL;
301     if ( !mbSysChild && bChanged )
302     {
303         const vcl::Window* pWindow = this;
304         while ( pWindow->mpWindowImpl->mpBorderWindow )
305             pWindow = pWindow->mpWindowImpl->mpBorderWindow;
306 
307         if ( pWindow->mpWindowImpl->mbFrame )
308             pWindow->mpWindowImpl->mpFrame->SetRepresentedURL( i_rURL );
309     }
310 }
311 
SetIcon(sal_uInt16 nIcon)312 void SystemWindow::SetIcon( sal_uInt16 nIcon )
313 {
314     if ( mnIcon == nIcon )
315         return;
316 
317     mnIcon = nIcon;
318 
319     if ( !mbSysChild )
320     {
321         const vcl::Window* pWindow = this;
322         while ( pWindow->mpWindowImpl->mpBorderWindow )
323             pWindow = pWindow->mpWindowImpl->mpBorderWindow;
324 
325         if ( pWindow->mpWindowImpl->mbFrame )
326             pWindow->mpWindowImpl->mpFrame->SetIcon( nIcon );
327     }
328 }
329 
ShowTitleButton(TitleButton nButton,bool bVisible)330 void SystemWindow::ShowTitleButton( TitleButton nButton, bool bVisible )
331 {
332     if ( nButton == TitleButton::Docking )
333     {
334         if ( mbDockBtn != bVisible )
335         {
336             mbDockBtn = bVisible;
337             if ( mpWindowImpl->mpBorderWindow )
338                 static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->SetDockButton( bVisible );
339         }
340     }
341     else if ( nButton == TitleButton::Hide )
342     {
343         if ( mbHideBtn != bVisible )
344         {
345             mbHideBtn = bVisible;
346             if ( mpWindowImpl->mpBorderWindow )
347                 static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->SetHideButton( bVisible );
348         }
349     }
350     else if ( nButton == TitleButton::Menu )
351     {
352         if ( mpWindowImpl->mpBorderWindow )
353             static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->SetMenuButton( bVisible );
354     }
355     else
356         return;
357 }
358 
IsTitleButtonVisible(TitleButton nButton) const359 bool SystemWindow::IsTitleButtonVisible( TitleButton nButton ) const
360 {
361     if ( nButton == TitleButton::Docking )
362         return mbDockBtn;
363     else /* if ( nButton == TitleButton::Hide ) */
364         return mbHideBtn;
365 }
366 
RollUp()367 void SystemWindow::RollUp()
368 {
369     if ( !mbRollUp )
370     {
371         maOrgSize = GetOutputSizePixel();
372         Size aSize = maRollUpOutSize;
373         if ( !aSize.Width() )
374             aSize.setWidth( GetOutputSizePixel().Width() );
375         mbRollUp = true;
376         if ( mpWindowImpl->mpBorderWindow )
377             static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->SetRollUp( true, aSize );
378         else
379             SetOutputSizePixel( aSize );
380     }
381 }
382 
RollDown()383 void SystemWindow::RollDown()
384 {
385     if ( mbRollUp )
386     {
387         mbRollUp = false;
388         if ( mpWindowImpl->mpBorderWindow )
389             static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->SetRollUp( false, maOrgSize );
390         else
391             SetOutputSizePixel( maOrgSize );
392     }
393 }
394 
SetMinOutputSizePixel(const Size & rSize)395 void SystemWindow::SetMinOutputSizePixel( const Size& rSize )
396 {
397     maMinOutSize = rSize;
398     if ( mpWindowImpl->mpBorderWindow )
399     {
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() );
403     }
404     else if ( mpWindowImpl->mbFrame )
405         mpWindowImpl->mpFrame->SetMinClientSize( rSize.Width(), rSize.Height() );
406 }
407 
SetMaxOutputSizePixel(const Size & rSize)408 void SystemWindow::SetMaxOutputSizePixel( const Size& rSize )
409 {
410     Size aSize( 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 );
415 
416     mpImplData->maMaxOutSize = aSize;
417     if ( mpWindowImpl->mpBorderWindow )
418     {
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() );
422     }
423     else if ( mpWindowImpl->mbFrame )
424         mpWindowImpl->mpFrame->SetMaxClientSize( aSize.Width(), aSize.Height() );
425 }
426 
GetMaxOutputSizePixel() const427 const Size& SystemWindow::GetMaxOutputSizePixel() const
428 {
429     return mpImplData->maMaxOutSize;
430 }
431 
ImplWindowStateFromStr(WindowStateData & rData,const OString & rStr)432 void ImplWindowStateFromStr(WindowStateData& rData,
433     const OString& rStr)
434 {
435     WindowStateMask nValidMask = WindowStateMask::NONE;
436     sal_Int32 nIndex      = 0;
437 
438     OString aTokenStr = rStr.getToken(0, ',', nIndex);
439     if (!aTokenStr.isEmpty())
440     {
441         rData.SetX(aTokenStr.toInt32());
442         if( rData.GetX() > -16384 && rData.GetX() < 16384 )
443             nValidMask |= WindowStateMask::X;
444         else
445             rData.SetX( 0 );
446     }
447     else
448         rData.SetX( 0 );
449     aTokenStr = rStr.getToken(0, ',', nIndex);
450     if (!aTokenStr.isEmpty())
451     {
452         rData.SetY(aTokenStr.toInt32());
453         if( rData.GetY() > -16384 && rData.GetY() < 16384 )
454             nValidMask |= WindowStateMask::Y;
455         else
456             rData.SetY( 0 );
457     }
458     else
459         rData.SetY( 0 );
460     aTokenStr = rStr.getToken(0, ',', nIndex);
461     if (!aTokenStr.isEmpty())
462     {
463         rData.SetWidth(aTokenStr.toInt32());
464         if( rData.GetWidth() > 0 && rData.GetWidth() < 16384 )
465             nValidMask |= WindowStateMask::Width;
466         else
467             rData.SetWidth( 0 );
468     }
469     else
470         rData.SetWidth( 0 );
471     aTokenStr = rStr.getToken(0, ';', nIndex);
472     if (!aTokenStr.isEmpty())
473     {
474         rData.SetHeight(aTokenStr.toInt32());
475         if( rData.GetHeight() > 0 && rData.GetHeight() < 16384 )
476             nValidMask |= WindowStateMask::Height;
477         else
478             rData.SetHeight( 0 );
479     }
480     else
481         rData.SetHeight( 0 );
482     aTokenStr = rStr.getToken(0, ';', nIndex);
483     if (!aTokenStr.isEmpty())
484     {
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;
491     }
492     else
493         rData.SetState( WindowStateState::NONE );
494 
495     // read maximized pos/size
496     aTokenStr = rStr.getToken(0, ',', nIndex);
497     if (!aTokenStr.isEmpty())
498     {
499         rData.SetMaximizedX(aTokenStr.toInt32());
500         if( rData.GetMaximizedX() > -16384 && rData.GetMaximizedX() < 16384 )
501             nValidMask |= WindowStateMask::MaximizedX;
502         else
503             rData.SetMaximizedX( 0 );
504     }
505     else
506         rData.SetMaximizedX( 0 );
507     aTokenStr = rStr.getToken(0, ',', nIndex);
508     if (!aTokenStr.isEmpty())
509     {
510         rData.SetMaximizedY(aTokenStr.toInt32());
511         if( rData.GetMaximizedY() > -16384 && rData.GetMaximizedY() < 16384 )
512             nValidMask |= WindowStateMask::MaximizedY;
513         else
514             rData.SetMaximizedY( 0 );
515     }
516     else
517         rData.SetMaximizedY( 0 );
518     aTokenStr = rStr.getToken(0, ',', nIndex);
519     if (!aTokenStr.isEmpty())
520     {
521         rData.SetMaximizedWidth(aTokenStr.toInt32());
522         if( rData.GetMaximizedWidth() > 0 && rData.GetMaximizedWidth() < 16384 )
523             nValidMask |= WindowStateMask::MaximizedWidth;
524         else
525             rData.SetMaximizedWidth( 0 );
526     }
527     else
528         rData.SetMaximizedWidth( 0 );
529     aTokenStr = rStr.getToken(0, ';', nIndex);
530     if (!aTokenStr.isEmpty())
531     {
532         rData.SetMaximizedHeight(aTokenStr.toInt32());
533         if( rData.GetMaximizedHeight() > 0 && rData.GetMaximizedHeight() < 16384 )
534             nValidMask |= WindowStateMask::MaximizedHeight;
535         else
536             rData.SetMaximizedHeight( 0 );
537     }
538     else
539         rData.SetMaximizedHeight( 0 );
540 
541     // mark valid fields
542     rData.SetMask( nValidMask );
543 }
544 
ToStr() const545 OString WindowStateData::ToStr() const
546 {
547     const WindowStateMask nValidMask = GetMask();
548     if ( nValidMask == WindowStateMask::NONE )
549         return OString();
550 
551     OStringBuffer rStrBuf(64);
552 
553     if ( nValidMask & WindowStateMask::X )
554         rStrBuf.append(static_cast<sal_Int32>(GetX()));
555     rStrBuf.append(',');
556     if ( nValidMask & WindowStateMask::Y )
557         rStrBuf.append(static_cast<sal_Int32>(GetY()));
558     rStrBuf.append(',');
559     if ( nValidMask & WindowStateMask::Width )
560         rStrBuf.append(static_cast<sal_Int32>(GetWidth()));
561     rStrBuf.append(',');
562     if ( nValidMask & WindowStateMask::Height )
563         rStrBuf.append(static_cast<sal_Int32>(GetHeight()));
564     rStrBuf.append( ';' );
565     if ( nValidMask & WindowStateMask::State )
566     {
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));
571     }
572     rStrBuf.append(';');
573     if ( nValidMask & WindowStateMask::MaximizedX )
574         rStrBuf.append(static_cast<sal_Int32>(GetMaximizedX()));
575     rStrBuf.append(',');
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()));
581     rStrBuf.append(',');
582     if ( nValidMask & WindowStateMask::MaximizedHeight )
583         rStrBuf.append(static_cast<sal_Int32>(GetMaximizedHeight()));
584     rStrBuf.append(';');
585 
586     return rStrBuf.makeStringAndClear();
587 }
588 
ImplMoveToScreen(long & io_rX,long & io_rY,long i_nWidth,long i_nHeight,vcl::Window const * i_pConfigureWin)589 void SystemWindow::ImplMoveToScreen( long& io_rX, long& io_rY, long i_nWidth, long i_nHeight, vcl::Window const * i_pConfigureWin )
590 {
591     tools::Rectangle aScreenRect;
592     if( !Application::IsUnifiedDisplay() )
593         aScreenRect = Application::GetScreenPosSizePixel( GetScreenNumber() );
594     else
595     {
596         aScreenRect = Application::GetScreenPosSizePixel( 0 );
597         for( unsigned int i = 1; i < Application::GetScreenCount(); i++ )
598             aScreenRect.Union( Application::GetScreenPosSizePixel( i ) );
599     }
600     // unfortunately most of the time width and height are not really known
601     if( i_nWidth < 1 )
602         i_nWidth = 50;
603     if( i_nHeight < 1 )
604         i_nHeight = 50;
605 
606     // check left border
607     bool bMove = false;
608     if( io_rX + i_nWidth < aScreenRect.Left() )
609     {
610         bMove = true;
611         io_rX = aScreenRect.Left();
612     }
613     // check right border
614     if( io_rX > aScreenRect.Right() - i_nWidth )
615     {
616         bMove = true;
617         io_rX = aScreenRect.Right() - i_nWidth;
618     }
619     // check top border
620     if( io_rY + i_nHeight < aScreenRect.Top() )
621     {
622         bMove = true;
623         io_rY = aScreenRect.Top();
624     }
625     // check bottom border
626     if( io_rY > aScreenRect.Bottom() - i_nHeight )
627     {
628         bMove = true;
629         io_rY = aScreenRect.Bottom() - i_nHeight;
630     }
631     vcl::Window* pParent = i_pConfigureWin->GetParent();
632     if( bMove && pParent )
633     {
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();
641     }
642 }
643 
SetWindowStateData(const WindowStateData & rData)644 void SystemWindow::SetWindowStateData( const WindowStateData& rData )
645 {
646     const WindowStateMask nValidMask = rData.GetMask();
647     if ( nValidMask == WindowStateMask::NONE )
648         return;
649 
650     if ( mbSysChild )
651         return;
652 
653     vcl::Window* pWindow = this;
654     while ( pWindow->mpWindowImpl->mpBorderWindow )
655         pWindow = pWindow->mpWindowImpl->mpBorderWindow;
656 
657     if ( pWindow->mpWindowImpl->mbFrame )
658     {
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();
666 
667         if( rData.GetMask() & (WindowStateMask::Width|WindowStateMask::Height) )
668         {
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();
675         }
676 
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;
685 
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 );
689 
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) )
694             {
695                 tools::Rectangle aDesktop = GetDesktopRectPixel();
696                 ImplSVData *pSVData = ImplGetSVData();
697                 vcl::Window *pWin = pSVData->maWinData.mpFirstFrame;
698                 bool bWrapped = false;
699                 while( pWin )
700                 {
701                     if( !pWin->ImplIsRealParentPath( this ) && ( pWin != this ) &&
702                         pWin->ImplGetWindow()->IsTopWindow() && pWin->mpWindowImpl->mbReallyVisible )
703                     {
704                         SalFrameGeometry g = pWin->mpWindowImpl->mpFrame->GetGeometry();
705                         if( std::abs(g.nX-aState.mnX) < 2 && std::abs(g.nY-aState.mnY) < 5 )
706                         {
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()) )
710                             {
711                                 // displacing would leave screen
712                                 aState.mnX = g.nLeftDecoration ? g.nLeftDecoration : 10; // should result in (0,0)
713                                 aState.mnY = displacement;
714                                 if( bWrapped ||
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
719                                 bWrapped = true;
720                             }
721                             else
722                             {
723                                 // displace
724                                 aState.mnX += displacement;
725                                 aState.mnY += displacement;
726                             }
727                             pWin = pSVData->maWinData.mpFirstFrame; // check new pos again
728                         }
729                     }
730                     pWin = pWin->mpWindowImpl->mpFrameData->mpNextFrame;
731                 }
732             }
733 
734         mpWindowImpl->mpFrame->SetWindowState( &aState );
735 
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) )
740         {
741             // query maximized size from frame
742             SalFrameGeometry aGeometry = mpWindowImpl->mpFrame->GetGeometry();
743 
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 );
749         }
750         else
751             if( rData.GetMask() & (WindowStateMask::Width|WindowStateMask::Height) )
752                 ImplHandleResize( pWindow, aState.mnWidth, aState.mnHeight );   // #i43799# use aState and not rData, see above
753     }
754     else
755     {
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;
765 
766         if( IsRollUp() )
767             RollDown();
768 
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();
774         if( nX < 0 )
775             nX = 0;
776         if( nX + nWidth > static_cast<long>(rGeom.nWidth) )
777             nX = rGeom.nWidth - nWidth;
778         if( nY < 0 )
779             nY = 0;
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 );
784 
785         // 91625 - ignore Minimize
786         if ( nValidMask & WindowStateMask::State )
787         {
788             const WindowStateState nState = rData.GetState();
789             if ( nState & WindowStateState::Rollup )
790                 RollUp();
791             else
792                 RollDown();
793         }
794     }
795 }
796 
GetWindowStateData(WindowStateData & rData) const797 void SystemWindow::GetWindowStateData( WindowStateData& rData ) const
798 {
799     WindowStateMask nValidMask = rData.GetMask();
800     if ( nValidMask == WindowStateMask::NONE )
801         return;
802 
803     if ( mbSysChild )
804         return;
805 
806     const vcl::Window* pWindow = this;
807     while ( pWindow->mpWindowImpl->mpBorderWindow )
808         pWindow = pWindow->mpWindowImpl->mpBorderWindow;
809 
810     if ( pWindow->mpWindowImpl->mbFrame )
811     {
812         SalFrameState aState;
813         aState.mnMask = WindowStateMask::All;
814         if ( mpWindowImpl->mpFrame->GetWindowState( &aState ) )
815         {
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 )
825             {
826                 rData.SetMaximizedX( aState.mnMaximizedX );
827                 nValidMask |= WindowStateMask::MaximizedX;
828             }
829             if ( aState.mnMask & WindowStateMask::MaximizedY )
830             {
831                 rData.SetMaximizedY( aState.mnMaximizedY );
832                 nValidMask |= WindowStateMask::MaximizedY;
833             }
834             if ( aState.mnMask & WindowStateMask::MaximizedWidth )
835             {
836                 rData.SetMaximizedWidth( aState.mnMaximizedWidth );
837                 nValidMask |= WindowStateMask::MaximizedWidth;
838             }
839             if ( aState.mnMask & WindowStateMask::MaximizedHeight )
840             {
841                 rData.SetMaximizedHeight( aState.mnMaximizedHeight );
842                 nValidMask |= WindowStateMask::MaximizedHeight;
843             }
844             if ( nValidMask & WindowStateMask::State )
845             {
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 );
851             }
852             rData.SetMask( nValidMask );
853         }
854         else
855             rData.SetMask( WindowStateMask::NONE );
856     }
857     else
858     {
859         Point   aPos = GetPosPixel();
860         Size    aSize = GetSizePixel();
861         WindowStateState nState = WindowStateState::NONE;
862 
863         if ( IsRollUp() )
864         {
865             aSize.AdjustHeight(maOrgSize.Height() );
866             nState = WindowStateState::Rollup;
867         }
868 
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 );
879     }
880 }
881 
SetWindowState(const OString & rStr)882 void SystemWindow::SetWindowState(const OString& rStr)
883 {
884     if (rStr.isEmpty())
885         return;
886 
887     WindowStateData aData;
888     ImplWindowStateFromStr( aData, rStr );
889     SetWindowStateData( aData );
890 }
891 
GetWindowState(WindowStateMask nMask) const892 OString SystemWindow::GetWindowState( WindowStateMask nMask ) const
893 {
894     WindowStateData aData;
895     aData.SetMask( nMask );
896     GetWindowStateData( aData );
897 
898     return aData.ToStr();
899 }
900 
SetMenuBar(MenuBar * pMenuBar)901 void SystemWindow::SetMenuBar(MenuBar* pMenuBar)
902 {
903     if ( mpMenuBar != pMenuBar )
904     {
905         MenuBar* pOldMenuBar = mpMenuBar;
906         vcl::Window*  pOldWindow = nullptr;
907         VclPtr<vcl::Window> pNewWindow;
908         mpMenuBar = pMenuBar;
909 
910         if ( mpWindowImpl->mpBorderWindow && (mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW) )
911         {
912             if ( pOldMenuBar )
913                 pOldWindow = pOldMenuBar->ImplGetWindow();
914             else
915                 pOldWindow = nullptr;
916             if ( pOldWindow )
917             {
918                 CallEventListeners( VclEventId::WindowMenubarRemoved, static_cast<void*>(pOldMenuBar) );
919                 pOldWindow->SetAccessible( css::uno::Reference< css::accessibility::XAccessible >() );
920             }
921             if ( pMenuBar )
922             {
923                 SAL_WARN_IF( pMenuBar->pWindow, "vcl", "SystemWindow::SetMenuBar() - MenuBars can only set in one SystemWindow at time" );
924 
925                 pNewWindow = MenuBar::ImplCreate(mpWindowImpl->mpBorderWindow, pOldWindow, pMenuBar);
926                 static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->SetMenuBarWindow(pNewWindow);
927 
928                 CallEventListeners( VclEventId::WindowMenubarAdded, static_cast<void*>(pMenuBar) );
929             }
930             else
931                 static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->SetMenuBarWindow( nullptr );
932             ImplToBottomChild();
933             if ( pOldMenuBar )
934             {
935                 bool bDelete = (pMenuBar == nullptr);
936                 if( bDelete && pOldWindow )
937                 {
938                     if( mpImplData->mpTaskPaneList )
939                         mpImplData->mpTaskPaneList->RemoveWindow( pOldWindow );
940                 }
941                 MenuBar::ImplDestroy( pOldMenuBar, bDelete );
942                 if( bDelete )
943                     pOldWindow = nullptr;  // will be deleted in MenuBar::ImplDestroy,
944             }
945 
946         }
947         else
948         {
949             if( pMenuBar )
950                 pNewWindow = pMenuBar->ImplGetWindow();
951             if( pOldMenuBar )
952                 pOldWindow = pOldMenuBar->ImplGetWindow();
953         }
954 
955         // update taskpane list to make menubar accessible
956         if( mpImplData->mpTaskPaneList )
957         {
958             if( pOldWindow )
959                 mpImplData->mpTaskPaneList->RemoveWindow( pOldWindow );
960             if( pNewWindow )
961                 mpImplData->mpTaskPaneList->AddWindow( pNewWindow );
962         }
963     }
964 }
965 
SetNotebookBar(const OUString & rUIXMLDescription,const css::uno::Reference<css::frame::XFrame> & rFrame,const NotebookBarAddonsItem & aNotebookBarAddonsItem,bool bReloadNotebookbar)966 void SystemWindow::SetNotebookBar(const OUString& rUIXMLDescription,
967                                   const css::uno::Reference<css::frame::XFrame>& rFrame,
968                                   const NotebookBarAddonsItem& aNotebookBarAddonsItem,
969                                   bool bReloadNotebookbar)
970 {
971     if (rUIXMLDescription != maNotebookBarUIFile || bReloadNotebookbar)
972     {
973         static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())
974             ->SetNotebookBar(rUIXMLDescription, rFrame, aNotebookBarAddonsItem);
975         maNotebookBarUIFile = rUIXMLDescription;
976         if(GetNotebookBar())
977             GetNotebookBar()->SetSystemWindow(this);
978     }
979 }
980 
CloseNotebookBar()981 void SystemWindow::CloseNotebookBar()
982 {
983     static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->CloseNotebookBar();
984     maNotebookBarUIFile.clear();
985 }
986 
GetNotebookBar() const987 VclPtr<NotebookBar> const & SystemWindow::GetNotebookBar() const
988 {
989     return static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->GetNotebookBar();
990 }
991 
SetMenuBarMode(MenuBarMode nMode)992 void SystemWindow::SetMenuBarMode( MenuBarMode nMode )
993 {
994     if ( mnMenuBarMode != nMode )
995     {
996         mnMenuBarMode = nMode;
997         if ( mpWindowImpl->mpBorderWindow && (mpWindowImpl->mpBorderWindow->GetType() == WindowType::BORDERWINDOW) )
998         {
999             if ( nMode == MenuBarMode::Hide )
1000                 static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->SetMenuBarMode( true );
1001             else
1002                 static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->SetMenuBarMode( false );
1003         }
1004     }
1005 }
1006 
ImplIsInTaskPaneList(vcl::Window * pWin)1007 bool SystemWindow::ImplIsInTaskPaneList( vcl::Window* pWin )
1008 {
1009     if( mpImplData && mpImplData->mpTaskPaneList )
1010         return mpImplData->mpTaskPaneList->IsInList( pWin );
1011     return false;
1012 }
1013 
GetScreenNumber() const1014 unsigned int SystemWindow::GetScreenNumber() const
1015 {
1016     return mpWindowImpl->mpFrame->maGeometry.nDisplayScreenNumber;
1017 }
1018 
SetScreenNumber(unsigned int nDisplayScreen)1019 void SystemWindow::SetScreenNumber(unsigned int nDisplayScreen)
1020 {
1021     mpWindowImpl->mpFrame->SetScreenNumber( nDisplayScreen );
1022 }
1023 
SetApplicationID(const OUString & rApplicationID)1024 void SystemWindow::SetApplicationID(const OUString &rApplicationID)
1025 {
1026     mpWindowImpl->mpFrame->SetApplicationID( rApplicationID );
1027 }
1028 
SetCloseHdl(const Link<SystemWindow &,void> & rLink)1029 void SystemWindow::SetCloseHdl(const Link<SystemWindow&,void>& rLink)
1030 {
1031     mpImplData->maCloseHdl = rLink;
1032 }
1033 
GetCloseHdl() const1034 const Link<SystemWindow&,void>& SystemWindow::GetCloseHdl() const
1035 {
1036     return mpImplData->maCloseHdl;
1037 }
1038 
queue_resize(StateChangedType)1039 void SystemWindow::queue_resize(StateChangedType /*eReason*/)
1040 {
1041     if (!isLayoutEnabled())
1042         return;
1043     if (isCalculatingInitialLayoutSize())
1044         return;
1045     InvalidateSizeCache();
1046     if (hasPendingLayout())
1047         return;
1048     maLayoutIdle.Start();
1049 }
1050 
Resize()1051 void SystemWindow::Resize()
1052 {
1053     queue_resize();
1054 }
1055 
isLayoutEnabled() const1056 bool SystemWindow::isLayoutEnabled() const
1057 {
1058     //pre dtor called, and single child is a container => we're layout enabled
1059     return mpImplData && ::isLayoutEnabled(this);
1060 }
1061 
GetOptimalSize() const1062 Size SystemWindow::GetOptimalSize() const
1063 {
1064     if (!isLayoutEnabled())
1065         return Window::GetOptimalSize();
1066 
1067     Size aSize = VclContainer::getLayoutRequisition(*GetWindow(GetWindowType::FirstChild));
1068 
1069     sal_Int32 nBorderWidth = get_border_width();
1070 
1071     aSize.AdjustHeight(2 * nBorderWidth );
1072     aSize.AdjustWidth(2 * nBorderWidth );
1073 
1074     return Window::CalcWindowSize(aSize);
1075 }
1076 
setPosSizeOnContainee(Size aSize,Window & rBox)1077 void SystemWindow::setPosSizeOnContainee(Size aSize, Window &rBox)
1078 {
1079     sal_Int32 nBorderWidth = get_border_width();
1080 
1081     aSize.AdjustWidth( -(2 * nBorderWidth) );
1082     aSize.AdjustHeight( -(2 * nBorderWidth) );
1083 
1084     Point aPos(nBorderWidth, nBorderWidth);
1085     VclContainer::setLayoutAllocation(rBox, aPos, CalcOutputSize(aSize));
1086 }
1087 
IMPL_LINK_NOARG(SystemWindow,ImplHandleLayoutTimerHdl,Timer *,void)1088 IMPL_LINK_NOARG( SystemWindow, ImplHandleLayoutTimerHdl, Timer*, void )
1089 {
1090     if (!isLayoutEnabled())
1091     {
1092         SAL_WARN("vcl.layout", "SystemWindow has become non-layout because extra children have been added directly to it.");
1093         return;
1094     }
1095 
1096     Window *pBox = GetWindow(GetWindowType::FirstChild);
1097     assert(pBox);
1098     setPosSizeOnContainee(GetSizePixel(), *pBox);
1099 }
1100 
SetText(const OUString & rStr)1101 void SystemWindow::SetText(const OUString& rStr)
1102 {
1103     setDeferredProperties();
1104     Window::SetText(rStr);
1105 }
1106 
GetText() const1107 OUString SystemWindow::GetText() const
1108 {
1109     const_cast<SystemWindow*>(this)->setDeferredProperties();
1110     return Window::GetText();
1111 }
1112 
settingOptimalLayoutSize(Window *)1113 void SystemWindow::settingOptimalLayoutSize(Window* /*pBox*/)
1114 {
1115 }
1116 
setOptimalLayoutSize()1117 void SystemWindow::setOptimalLayoutSize()
1118 {
1119     maLayoutIdle.Stop();
1120 
1121     //resize SystemWindow to fit requisition on initial show
1122     Window *pBox = GetWindow(GetWindowType::FirstChild);
1123 
1124     settingOptimalLayoutSize(pBox);
1125 
1126     Size aSize = get_preferred_size();
1127 
1128     Size aMax(bestmaxFrameSizeForScreenSize(GetDesktopRectPixel().GetSize()));
1129 
1130     aSize.setWidth( std::min(aMax.Width(), aSize.Width()) );
1131     aSize.setHeight( std::min(aMax.Height(), aSize.Height()) );
1132 
1133     SetMinOutputSizePixel(aSize);
1134     SetSizePixel(aSize);
1135     setPosSizeOnContainee(aSize, *pBox);
1136 }
1137 
DoInitialLayout()1138 void SystemWindow::DoInitialLayout()
1139 {
1140     if (GetSettings().GetStyleSettings().GetAutoMnemonic())
1141        Accelerator::GenerateAutoMnemonicsOnHierarchy(this);
1142 
1143     if (isLayoutEnabled())
1144     {
1145         mbIsCalculatingInitialLayoutSize = true;
1146         setDeferredProperties();
1147         setOptimalLayoutSize();
1148         mbIsCalculatingInitialLayoutSize = false;
1149     }
1150 }
1151 
doDeferredInit(WinBits)1152 void SystemWindow::doDeferredInit(WinBits /*nBits*/)
1153 {
1154     SAL_WARN("vcl.layout", "SystemWindow in layout without doDeferredInit impl");
1155 }
1156 
createScreenshot(VirtualDevice & rOutput)1157 void SystemWindow::createScreenshot(VirtualDevice& rOutput)
1158 {
1159     // same prerequisites as in Execute()
1160     setDeferredProperties();
1161     ImplAdjustNWFSizes();
1162     Show();
1163     ToTop();
1164     ensureRepaint();
1165 
1166     Point aPos;
1167     Size aSize(GetOutputSizePixel());
1168 
1169     rOutput.SetOutputSizePixel(aSize);
1170     rOutput.DrawOutDev(aPos, aSize, aPos, aSize, *this);
1171 }
1172 
PrePaint(vcl::RenderContext & rRenderContext)1173 void SystemWindow::PrePaint(vcl::RenderContext& rRenderContext)
1174 {
1175     Window::PrePaint(rRenderContext);
1176     mbPaintComplete = false;
1177 }
1178 
PostPaint(vcl::RenderContext & rRenderContext)1179 void SystemWindow::PostPaint(vcl::RenderContext& rRenderContext)
1180 {
1181     Window::PostPaint(rRenderContext);
1182     mbPaintComplete = true;
1183 }
1184 
ensureRepaint()1185 void SystemWindow::ensureRepaint()
1186 {
1187     // ensure repaint
1188     Invalidate();
1189     mbPaintComplete = false;
1190 
1191     while (!mbPaintComplete)
1192     {
1193         Application::Yield();
1194     }
1195 }
1196 
1197 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1198