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 <comphelper/fileurl.hxx>
23 #include "rtl/ustrbuf.hxx"
27 #include <vcl/svapp.hxx>
28 #include <vcl/window.hxx>
29 #include <vcl/syswin.hxx>
30 #include <vcl/settings.hxx>
32 #include "osx/saldata.hxx"
33 #include "quartz/salgdi.h"
34 #include "osx/salframe.h"
35 #include "osx/salmenu.h"
36 #include "osx/salinst.h"
37 #include "osx/salframeview.h"
38 #include "osx/a11yfactory.h"
39 #include "quartz/utils.h"
41 #include "salwtype.hxx"
44 #include <objc/objc-runtime.h>
46 // FIXME: move theming code to salnativewidgets.cxx
47 #include <Carbon/Carbon.h>
52 AquaSalFrame
* AquaSalFrame::s_pCaptureFrame
= nullptr;
54 AquaSalFrame::AquaSalFrame( SalFrame
* pParent
, SalFrameStyleFlags salFrameStyle
) :
65 mbFullScreen( false ),
70 mbPresentation( false ),
71 mnStyle( salFrameStyle
),
74 mnLastModifierFlags( 0 ),
77 mePointerStyle( PointerStyle::Arrow
),
78 mnTrackingRectTag( 0 ),
79 mrClippingPath( nullptr ),
80 mnICOptions( InputContextFlags::NONE
)
82 maSysData
.nSize
= sizeof( SystemEnvData
);
84 mpParent
= dynamic_cast<AquaSalFrame
*>(pParent
);
88 SalData
* pSalData
= GetSalData();
89 pSalData
->maFrames
.push_front( this );
90 pSalData
->maFrameCheck
.insert( this );
93 AquaSalFrame::~AquaSalFrame()
95 // if the frame is destroyed and has the current menubar
96 // set the default menubar
97 if( mpMenu
&& mpMenu
->mbMenuBar
&& AquaSalMenu::pCurrentMenuBar
== mpMenu
)
98 AquaSalMenu::setDefaultMenu();
100 // cleanup clipping stuff
103 [SalFrameView unsetMouseFrame
: this];
105 SalData
* pSalData
= GetSalData();
106 pSalData
->maFrames
.remove( this );
107 pSalData
->maFrameCheck
.erase( this );
108 pSalData
->maPresentationFrames
.remove( this );
110 SAL_WARN_IF( this == s_pCaptureFrame
, "vcl", "capture frame destroyed" );
111 if( this == s_pCaptureFrame
)
112 s_pCaptureFrame
= nullptr;
116 if( mpDockMenuEntry
)
118 NSMenu
* pDock
= AquaSalInstance::GetDynamicDockMenu();
119 // life cycle comment: the menu has ownership of the item, so no release
120 [pDock removeItem
: mpDockMenuEntry
];
121 if ([pDock numberOfItems
] != 0
122 && [[pDock itemAtIndex
: 0] isSeparatorItem
])
124 [pDock removeItemAtIndex
: 0];
128 [AquaA11yFactory revokeView
: mpNSView
];
132 [mpNSWindow release
];
135 void AquaSalFrame::initWindowAndView()
137 // initialize mirroring parameters
138 // FIXME: screens changing
139 NSScreen
* pNSScreen
= [mpNSWindow screen
];
140 if( pNSScreen
== nil
)
141 pNSScreen
= [NSScreen mainScreen
];
142 maScreenRect
= [pNSScreen frame
];
144 // calculate some default geometry
145 NSRect aVisibleRect
= [pNSScreen visibleFrame
];
146 CocoaToVCL( aVisibleRect
);
148 maGeometry
.nX
= static_cast<int>(aVisibleRect
.origin
.x
+ aVisibleRect
.size
.width
/ 10);
149 maGeometry
.nY
= static_cast<int>(aVisibleRect
.origin
.y
+ aVisibleRect
.size
.height
/ 10);
150 maGeometry
.nWidth
= static_cast<unsigned int>(aVisibleRect
.size
.width
* 0.8);
151 maGeometry
.nHeight
= static_cast<unsigned int>(aVisibleRect
.size
.height
* 0.8);
153 // calculate style mask
154 SAL_WNODEPRECATED_DECLARATIONS_PUSH
155 // 'NSBorderlessWindowMask' is deprecated: first deprecated in macOS 10.12
156 // 'NSClosableWindowMask' is deprecated: first deprecated in macOS 10.12
157 // 'NSMiniaturizableWindowMask' is deprecated: first deprecated in macOS 10.12
158 // 'NSResizableWindowMask' is deprecated: first deprecated in macOS 10.12
159 // 'NSTitledWindowMask' is deprecated: first deprecated in macOS 10.12
160 if( (mnStyle
& SalFrameStyleFlags::FLOAT
) ||
161 (mnStyle
& SalFrameStyleFlags::OWNERDRAWDECORATION
) )
162 mnStyleMask
= NSBorderlessWindowMask
;
163 else if( mnStyle
& SalFrameStyleFlags::DEFAULT
)
165 mnStyleMask
= NSTitledWindowMask
|
166 NSMiniaturizableWindowMask
|
167 NSResizableWindowMask
|
168 NSClosableWindowMask
;
169 // make default window "maximized"
170 maGeometry
.nX
= static_cast<int>(aVisibleRect
.origin
.x
);
171 maGeometry
.nY
= static_cast<int>(aVisibleRect
.origin
.y
);
172 maGeometry
.nWidth
= static_cast<int>(aVisibleRect
.size
.width
);
173 maGeometry
.nHeight
= static_cast<int>(aVisibleRect
.size
.height
);
174 mbPositioned
= mbSized
= true;
178 if( (mnStyle
& SalFrameStyleFlags::MOVEABLE
) )
180 mnStyleMask
|= NSTitledWindowMask
;
181 if( mpParent
== nullptr )
182 mnStyleMask
|= NSMiniaturizableWindowMask
;
184 if( (mnStyle
& SalFrameStyleFlags::SIZEABLE
) )
185 mnStyleMask
|= NSResizableWindowMask
;
186 if( (mnStyle
& SalFrameStyleFlags::CLOSEABLE
) )
187 mnStyleMask
|= NSClosableWindowMask
;
188 // documentation says anything other than NSBorderlessWindowMask (=0)
189 // should also include NSTitledWindowMask;
190 if( mnStyleMask
!= 0 )
191 mnStyleMask
|= NSTitledWindowMask
;
193 SAL_WNODEPRECATED_DECLARATIONS_POP
195 // #i91990# support GUI-less (daemon) execution
198 mpNSWindow
= [[SalFrameWindow alloc
] initWithSalFrame
: this];
199 mpNSView
= [[SalFrameView alloc
] initWithSalFrame
: this];
201 @
catch ( id exception
)
206 if( (mnStyle
& SalFrameStyleFlags::TOOLTIP
) )
207 [mpNSWindow setIgnoresMouseEvents
: YES
];
209 [mpNSWindow setAcceptsMouseMovedEvents
: YES
];
210 [mpNSWindow setHasShadow
: YES
];
212 [mpNSWindow setDelegate
: static_cast<id
<NSWindowDelegate
> >(mpNSWindow
)];
214 if( [mpNSWindow respondsToSelector
: @
selector(setRestorable
:)])
216 objc_msgSend(mpNSWindow
, @
selector(setRestorable
:), NO
);
218 const NSRect aRect
= { NSZeroPoint
, NSMakeSize( maGeometry
.nWidth
, maGeometry
.nHeight
)};
219 mnTrackingRectTag
= [mpNSView addTrackingRect
: aRect owner
: mpNSView userData
: nil assumeInside
: NO
];
221 maSysData
.mpNSView
= mpNSView
;
223 UpdateFrameGeometry();
225 [mpNSWindow setContentView
: mpNSView
];
228 void AquaSalFrame::CocoaToVCL( NSRect
& io_rRect
, bool bRelativeToScreen
)
230 if( bRelativeToScreen
)
231 io_rRect
.origin
.y
= maScreenRect
.size
.height
- (io_rRect
.origin
.y
+io_rRect
.size
.height
);
233 io_rRect
.origin
.y
= maGeometry
.nHeight
- (io_rRect
.origin
.y
+io_rRect
.size
.height
);
236 void AquaSalFrame::VCLToCocoa( NSRect
& io_rRect
, bool bRelativeToScreen
)
238 if( bRelativeToScreen
)
239 io_rRect
.origin
.y
= maScreenRect
.size
.height
- (io_rRect
.origin
.y
+io_rRect
.size
.height
);
241 io_rRect
.origin
.y
= maGeometry
.nHeight
- (io_rRect
.origin
.y
+io_rRect
.size
.height
);
244 void AquaSalFrame::CocoaToVCL( NSPoint
& io_rPoint
, bool bRelativeToScreen
)
246 if( bRelativeToScreen
)
247 io_rPoint
.y
= maScreenRect
.size
.height
- io_rPoint
.y
;
249 io_rPoint
.y
= maGeometry
.nHeight
- io_rPoint
.y
;
252 void AquaSalFrame::VCLToCocoa( NSPoint
& io_rPoint
, bool bRelativeToScreen
)
254 if( bRelativeToScreen
)
255 io_rPoint
.y
= maScreenRect
.size
.height
- io_rPoint
.y
;
257 io_rPoint
.y
= maGeometry
.nHeight
- io_rPoint
.y
;
260 void AquaSalFrame::screenParametersChanged()
262 UpdateFrameGeometry();
265 mpGraphics
->updateResolution();
266 CallCallback( SalEvent::DisplayChanged
, nullptr );
269 SalGraphics
* AquaSalFrame::AcquireGraphics()
276 mpGraphics
= new AquaSalGraphics
;
277 mpGraphics
->SetWindowGraphics( this );
284 void AquaSalFrame::ReleaseGraphics( SalGraphics
*pGraphics
)
287 SAL_WARN_IF( pGraphics
!= mpGraphics
, "vcl", "graphics released on wrong frame" );
291 bool AquaSalFrame::PostEvent(ImplSVEvent
* pData
)
293 GetSalData()->mpFirstInstance
->PostUserEvent( this, SalEvent::UserEvent
, pData
);
297 void AquaSalFrame::SetTitle(const OUString
& rTitle
)
302 // #i113170# may not be the main thread if called from UNO API
303 SalData::ensureThreadAutoreleasePool();
305 NSString
* pTitle
= CreateNSString( rTitle
);
306 [mpNSWindow setTitle
: pTitle
];
308 // create an entry in the dock menu
309 const SalFrameStyleFlags nAppWindowStyle
= (SalFrameStyleFlags::CLOSEABLE
| SalFrameStyleFlags::MOVEABLE
);
310 if( mpParent
== nullptr &&
311 (mnStyle
& nAppWindowStyle
) == nAppWindowStyle
)
313 if( mpDockMenuEntry
== nullptr )
315 NSMenu
* pDock
= AquaSalInstance::GetDynamicDockMenu();
317 if ([pDock numberOfItems
] != 0) {
318 NSMenuItem
* pTopItem
= [pDock itemAtIndex
: 0];
319 if ( [pTopItem hasSubmenu
] )
320 [pDock insertItem
: [NSMenuItem separatorItem
] atIndex
: 0];
323 mpDockMenuEntry
= [pDock insertItemWithTitle
: pTitle
324 action
: @
selector(dockMenuItemTriggered
:)
327 [mpDockMenuEntry setTarget
: mpNSWindow
];
329 // TODO: image (either the generic window image or an icon
330 // check mark (for "main" window ?)
333 [mpDockMenuEntry setTitle
: pTitle
];
340 void AquaSalFrame::SetIcon( sal_uInt16
)
344 void AquaSalFrame::SetRepresentedURL( const OUString
& i_rDocURL
)
346 // #i113170# may not be the main thread if called from UNO API
347 SalData::ensureThreadAutoreleasePool();
349 if( comphelper::isFileUrl(i_rDocURL
) )
352 osl_getSystemPathFromFileURL( i_rDocURL
.pData
, &aSysPath
.pData
);
353 NSString
* pStr
= CreateNSString( aSysPath
);
357 [mpNSWindow setRepresentedFilename
: pStr
];
362 void AquaSalFrame::initShow()
365 if( ! mbPositioned
&& ! mbFullScreen
)
367 tools::Rectangle aScreenRect
;
368 GetWorkArea( aScreenRect
);
369 if( mpParent
) // center relative to parent
372 long nNewX
= mpParent
->maGeometry
.nX
+ ((long)mpParent
->maGeometry
.nWidth
- (long)maGeometry
.nWidth
)/2;
373 if( nNewX
< aScreenRect
.Left() )
374 nNewX
= aScreenRect
.Left();
375 if( long(nNewX
+ maGeometry
.nWidth
) > aScreenRect
.Right() )
376 nNewX
= aScreenRect
.Right() - maGeometry
.nWidth
-1;
377 long nNewY
= mpParent
->maGeometry
.nY
+ ((long)mpParent
->maGeometry
.nHeight
- (long)maGeometry
.nHeight
)/2;
378 if( nNewY
< aScreenRect
.Top() )
379 nNewY
= aScreenRect
.Top();
380 if( nNewY
> aScreenRect
.Bottom() )
381 nNewY
= aScreenRect
.Bottom() - maGeometry
.nHeight
-1;
382 SetPosSize( nNewX
- mpParent
->maGeometry
.nX
,
383 nNewY
- mpParent
->maGeometry
.nY
,
384 0, 0, SAL_FRAME_POSSIZE_X
| SAL_FRAME_POSSIZE_Y
);
386 else if( ! (mnStyle
& SalFrameStyleFlags::SIZEABLE
) )
389 long nNewX
= (aScreenRect
.GetWidth() - maGeometry
.nWidth
)/2;
390 long nNewY
= (aScreenRect
.GetHeight() - maGeometry
.nHeight
)/2;
391 SetPosSize( nNewX
, nNewY
, 0, 0, SAL_FRAME_POSSIZE_X
| SAL_FRAME_POSSIZE_Y
);
395 // make sure the view is present in the wrapper list before any children receive focus
396 [AquaA11yFactory registerView
: mpNSView
];
399 void AquaSalFrame::SendPaintEvent( const tools::Rectangle
* pRect
)
401 SalPaintEvent
aPaintEvt( 0, 0, maGeometry
.nWidth
, maGeometry
.nHeight
, true );
404 aPaintEvt
.mnBoundX
= pRect
->Left();
405 aPaintEvt
.mnBoundY
= pRect
->Top();
406 aPaintEvt
.mnBoundWidth
= pRect
->GetWidth();
407 aPaintEvt
.mnBoundHeight
= pRect
->GetHeight();
410 CallCallback(SalEvent::Paint
, &aPaintEvt
);
413 void AquaSalFrame::Show(bool bVisible
, bool bNoActivate
)
418 // #i113170# may not be the main thread if called from UNO API
419 SalData::ensureThreadAutoreleasePool();
427 CallCallback(SalEvent::Resize
, nullptr);
428 // trigger filling our backbuffer
431 if( bNoActivate
|| [mpNSWindow canBecomeKeyWindow
] == NO
)
432 [mpNSWindow orderFront
: NSApp
];
434 [mpNSWindow makeKeyAndOrderFront
: NSApp
];
438 /* #i92674# #i96433# we do not want an invisible parent to show up (which adding a visible
439 child implicitly does). However we also do not want a parentless toolbar.
441 HACK: try to decide when we should not insert a child to its parent
442 floaters and ownerdraw windows have not yet shown up in cases where
443 we don't want the parent to become visible
445 if( mpParent
->mbShown
|| (mnStyle
& (SalFrameStyleFlags::OWNERDRAWDECORATION
| SalFrameStyleFlags::FLOAT
) ) )
447 [mpParent
->mpNSWindow addChildWindow
: mpNSWindow ordered
: NSWindowAbove
];
452 [mpNSWindow makeMainWindow
];
456 // if the frame holding the current menubar gets hidden
457 // show the default menubar
458 if( mpMenu
&& mpMenu
->mbMenuBar
&& AquaSalMenu::pCurrentMenuBar
== mpMenu
)
459 AquaSalMenu::setDefaultMenu();
461 // #i90440# #i94443# work around the focus going back to some other window
462 // if a child gets hidden for a parent window
463 if( mpParent
&& mpParent
->mbShown
&& [mpNSWindow isKeyWindow
] )
464 [mpParent
->mpNSWindow makeKeyAndOrderFront
: NSApp
];
466 [SalFrameView unsetMouseFrame
: this];
467 if( mpParent
&& [mpNSWindow parentWindow
] == mpParent
->mpNSWindow
)
468 [mpParent
->mpNSWindow removeChildWindow
: mpNSWindow
];
470 [mpNSWindow orderOut
: NSApp
];
474 void AquaSalFrame::SetMinClientSize( long nWidth
, long nHeight
)
476 // #i113170# may not be the main thread if called from UNO API
477 SalData::ensureThreadAutoreleasePool();
480 mnMinHeight
= nHeight
;
484 // Always add the decoration as the dimension concerns only
485 // the content rectangle
486 nWidth
+= maGeometry
.nLeftDecoration
+ maGeometry
.nRightDecoration
;
487 nHeight
+= maGeometry
.nTopDecoration
+ maGeometry
.nBottomDecoration
;
489 NSSize aSize
= { static_cast<CGFloat
>(nWidth
), static_cast<CGFloat
>(nHeight
) };
491 // Size of full window (content+structure) although we only
492 // have the client size in arguments
493 [mpNSWindow setMinSize
: aSize
];
497 void AquaSalFrame::SetMaxClientSize( long nWidth
, long nHeight
)
499 // #i113170# may not be the main thread if called from UNO API
500 SalData::ensureThreadAutoreleasePool();
503 mnMaxHeight
= nHeight
;
507 // Always add the decoration as the dimension concerns only
508 // the content rectangle
509 nWidth
+= maGeometry
.nLeftDecoration
+ maGeometry
.nRightDecoration
;
510 nHeight
+= maGeometry
.nTopDecoration
+ maGeometry
.nBottomDecoration
;
512 // Carbon windows can't have a size greater than 32767x32767
513 if (nWidth
>32767) nWidth
=32767;
514 if (nHeight
>32767) nHeight
=32767;
516 NSSize aSize
= { static_cast<CGFloat
>(nWidth
), static_cast<CGFloat
>(nHeight
) };
518 // Size of full window (content+structure) although we only
519 // have the client size in arguments
520 [mpNSWindow setMaxSize
: aSize
];
524 void AquaSalFrame::GetClientSize( long& rWidth
, long& rHeight
)
526 if( mbShown
|| mbInitShow
)
528 rWidth
= maGeometry
.nWidth
;
529 rHeight
= maGeometry
.nHeight
;
538 void AquaSalFrame::SetWindowState( const SalFrameState
* pState
)
540 // #i113170# may not be the main thread if called from UNO API
541 SalData::ensureThreadAutoreleasePool();
546 NSRect aStateRect
= [mpNSWindow frame
];
547 aStateRect
= [NSWindow contentRectForFrameRect
: aStateRect styleMask
: mnStyleMask
];
548 CocoaToVCL( aStateRect
);
549 if( pState
->mnMask
& WindowStateMask::X
)
550 aStateRect
.origin
.x
= float(pState
->mnX
);
551 if( pState
->mnMask
& WindowStateMask::Y
)
552 aStateRect
.origin
.y
= float(pState
->mnY
);
553 if( pState
->mnMask
& WindowStateMask::Width
)
554 aStateRect
.size
.width
= float(pState
->mnWidth
);
555 if( pState
->mnMask
& WindowStateMask::Height
)
556 aStateRect
.size
.height
= float(pState
->mnHeight
);
557 VCLToCocoa( aStateRect
);
558 aStateRect
= [NSWindow frameRectForContentRect
: aStateRect styleMask
: mnStyleMask
];
560 [mpNSWindow setFrame
: aStateRect display
: NO
];
561 if( pState
->mnState
== WindowStateState::Minimized
)
562 [mpNSWindow miniaturize
: NSApp
];
563 else if( [mpNSWindow isMiniaturized
] )
564 [mpNSWindow deminiaturize
: NSApp
];
566 /* ZOOMED is not really maximized (actually it toggles between a user set size and
567 the program specified one), but comes closest since the default behavior is
568 "maximized" if the user did not intervene
570 if( pState
->mnState
== WindowStateState::Maximized
)
572 if(! [mpNSWindow isZoomed
])
573 [mpNSWindow zoom
: NSApp
];
577 if( [mpNSWindow isZoomed
] )
578 [mpNSWindow zoom
: NSApp
];
583 UpdateFrameGeometry();
585 SalEvent nEvent
= SalEvent::NONE
;
586 if( pState
->mnMask
& (WindowStateMask::X
| WindowStateMask::Y
) )
589 nEvent
= SalEvent::Move
;
592 if( pState
->mnMask
& (WindowStateMask::Width
| WindowStateMask::Height
) )
595 nEvent
= (nEvent
== SalEvent::Move
) ? SalEvent::MoveResize
: SalEvent::Resize
;
597 // send event that we were moved/sized
598 if( nEvent
!= SalEvent::NONE
)
599 CallCallback( nEvent
, nullptr );
601 if( mbShown
&& mpNSWindow
)
603 // trigger filling our backbuffer
606 // tell the system the views need to be updated
607 [mpNSWindow display
];
611 bool AquaSalFrame::GetWindowState( SalFrameState
* pState
)
616 // #i113170# may not be the main thread if called from UNO API
617 SalData::ensureThreadAutoreleasePool();
619 pState
->mnMask
= WindowStateMask::X
|
621 WindowStateMask::Width
|
622 WindowStateMask::Height
|
623 WindowStateMask::State
;
625 NSRect aStateRect
= [mpNSWindow frame
];
626 aStateRect
= [NSWindow contentRectForFrameRect
: aStateRect styleMask
: mnStyleMask
];
627 CocoaToVCL( aStateRect
);
628 pState
->mnX
= long(aStateRect
.origin
.x
);
629 pState
->mnY
= long(aStateRect
.origin
.y
);
630 pState
->mnWidth
= long(aStateRect
.size
.width
);
631 pState
->mnHeight
= long(aStateRect
.size
.height
);
633 if( [mpNSWindow isMiniaturized
] )
634 pState
->mnState
= WindowStateState::Minimized
;
635 else if( ! [mpNSWindow isZoomed
] )
636 pState
->mnState
= WindowStateState::Normal
;
638 pState
->mnState
= WindowStateState::Maximized
;
643 void AquaSalFrame::SetScreenNumber(unsigned int nScreen
)
648 // #i113170# may not be the main thread if called from UNO API
649 SalData::ensureThreadAutoreleasePool();
651 NSArray
* pScreens
= [NSScreen screens
];
652 NSScreen
* pScreen
= nil
;
653 if( pScreens
&& nScreen
< [pScreens count
] )
655 // get new screen frame
656 pScreen
= [pScreens objectAtIndex
: nScreen
];
657 NSRect aNewScreen
= [pScreen frame
];
659 // get current screen frame
660 pScreen
= [mpNSWindow screen
];
663 NSRect aCurScreen
= [pScreen frame
];
664 if( aCurScreen
.origin
.x
!= aNewScreen
.origin
.x
||
665 aCurScreen
.origin
.y
!= aNewScreen
.origin
.y
)
667 NSRect aFrameRect
= [mpNSWindow frame
];
668 aFrameRect
.origin
.x
+= aNewScreen
.origin
.x
- aCurScreen
.origin
.x
;
669 aFrameRect
.origin
.y
+= aNewScreen
.origin
.y
- aCurScreen
.origin
.y
;
670 [mpNSWindow setFrame
: aFrameRect display
: NO
];
671 UpdateFrameGeometry();
677 void AquaSalFrame::SetApplicationID( const OUString
&/*rApplicationID*/ )
681 void AquaSalFrame::ShowFullScreen( bool bFullScreen
, sal_Int32 nDisplay
)
686 // #i113170# may not be the main thread if called from UNO API
687 SalData::ensureThreadAutoreleasePool();
689 SAL_INFO("vcl.osx", OSL_THIS_FUNC
<< ": mbFullScreen=" << mbFullScreen
<< ", bFullScreen=" << bFullScreen
);
691 if( mbFullScreen
== bFullScreen
)
694 mbFullScreen
= bFullScreen
;
698 // hide the dock and the menubar if we are on the menu screen
699 // which is always on index 0 according to documentation
700 bool bHideMenu
= (nDisplay
== 0);
702 NSRect aNewContentRect
= NSZeroRect
;
703 // get correct screen
704 NSScreen
* pScreen
= nil
;
705 NSArray
* pScreens
= [NSScreen screens
];
708 if( nDisplay
>= 0 && (unsigned int)nDisplay
< [pScreens count
] )
709 pScreen
= [pScreens objectAtIndex
: nDisplay
];
712 // this means span all screens
714 NSEnumerator
* pEnum
= [pScreens objectEnumerator
];
715 while( (pScreen
= [pEnum nextObject
]) != nil
)
717 NSRect aScreenRect
= [pScreen frame
];
718 if( aScreenRect
.origin
.x
< aNewContentRect
.origin
.x
)
720 aNewContentRect
.size
.width
+= aNewContentRect
.origin
.x
- aScreenRect
.origin
.x
;
721 aNewContentRect
.origin
.x
= aScreenRect
.origin
.x
;
723 if( aScreenRect
.origin
.y
< aNewContentRect
.origin
.y
)
725 aNewContentRect
.size
.height
+= aNewContentRect
.origin
.y
- aScreenRect
.origin
.y
;
726 aNewContentRect
.origin
.y
= aScreenRect
.origin
.y
;
728 if( aScreenRect
.origin
.x
+ aScreenRect
.size
.width
> aNewContentRect
.origin
.x
+ aNewContentRect
.size
.width
)
729 aNewContentRect
.size
.width
= aScreenRect
.origin
.x
+ aScreenRect
.size
.width
- aNewContentRect
.origin
.x
;
730 if( aScreenRect
.origin
.y
+ aScreenRect
.size
.height
> aNewContentRect
.origin
.y
+ aNewContentRect
.size
.height
)
731 aNewContentRect
.size
.height
= aScreenRect
.origin
.y
+ aScreenRect
.size
.height
- aNewContentRect
.origin
.y
;
735 if( aNewContentRect
.size
.width
== 0 && aNewContentRect
.size
.height
== 0 )
738 pScreen
= [mpNSWindow screen
];
740 pScreen
= [NSScreen mainScreen
];
742 aNewContentRect
= [pScreen frame
];
746 [NSMenu setMenuBarVisible
:NO
];
748 maFullScreenRect
= [mpNSWindow frame
];
750 [mpNSWindow setFrame
: [NSWindow frameRectForContentRect
: aNewContentRect styleMask
: mnStyleMask
] display
: mbShown
? YES
: NO
];
753 UpdateFrameGeometry();
756 CallCallback( SalEvent::MoveResize
, nullptr );
761 [mpNSWindow setFrame
: maFullScreenRect display
: mbShown
? YES
: NO
];
763 UpdateFrameGeometry();
766 CallCallback( SalEvent::MoveResize
, nullptr );
768 // show the dock and the menubar
769 [NSMenu setMenuBarVisible
:YES
];
772 // trigger filling our backbuffer
776 void AquaSalFrame::StartPresentation( bool bStart
)
781 // #i113170# may not be the main thread if called from UNO API
782 SalData::ensureThreadAutoreleasePool();
786 GetSalData()->maPresentationFrames
.push_back( this );
787 IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep
,
788 kIOPMAssertionLevelOn
,
789 CFSTR("LibreOffice presentation running"),
791 [mpNSWindow setLevel
: NSPopUpMenuWindowLevel
];
793 [mpNSWindow makeMainWindow
];
797 GetSalData()->maPresentationFrames
.remove( this );
798 IOPMAssertionRelease(mnAssertionID
);
799 [mpNSWindow setLevel
: NSNormalWindowLevel
];
803 void AquaSalFrame::SetAlwaysOnTop( bool )
807 void AquaSalFrame::ToTop(SalFrameToTop nFlags
)
812 // #i113170# may not be the main thread if called from UNO API
813 SalData::ensureThreadAutoreleasePool();
815 if( ! (nFlags
& SalFrameToTop::RestoreWhenMin
) )
817 if( ! [mpNSWindow isVisible
] || [mpNSWindow isMiniaturized
] )
820 if( nFlags
& SalFrameToTop::GrabFocus
)
821 [mpNSWindow makeKeyAndOrderFront
: NSApp
];
823 [mpNSWindow orderFront
: NSApp
];
826 NSCursor
* AquaSalFrame::getCurrentCursor() const
828 NSCursor
* pCursor
= nil
;
829 switch( mePointerStyle
)
831 case PointerStyle::Text
: pCursor
= [NSCursor IBeamCursor
]; break;
832 case PointerStyle::Cross
: pCursor
= [NSCursor crosshairCursor
]; break;
833 case PointerStyle::Hand
:
834 case PointerStyle::Move
: pCursor
= [NSCursor openHandCursor
]; break;
835 case PointerStyle::NSize
: pCursor
= [NSCursor resizeUpCursor
]; break;
836 case PointerStyle::SSize
: pCursor
= [NSCursor resizeDownCursor
]; break;
837 case PointerStyle::ESize
: pCursor
= [NSCursor resizeRightCursor
]; break;
838 case PointerStyle::WSize
: pCursor
= [NSCursor resizeLeftCursor
]; break;
839 case PointerStyle::Arrow
: pCursor
= [NSCursor arrowCursor
]; break;
840 case PointerStyle::VSplit
:
841 case PointerStyle::VSizeBar
:
842 case PointerStyle::WindowNSize
:
843 case PointerStyle::WindowSSize
:
844 pCursor
= [NSCursor resizeUpDownCursor
]; break;
845 case PointerStyle::HSplit
:
846 case PointerStyle::HSizeBar
:
847 case PointerStyle::WindowESize
:
848 case PointerStyle::WindowWSize
:
849 pCursor
= [NSCursor resizeLeftRightCursor
]; break;
850 case PointerStyle::RefHand
: pCursor
= [NSCursor pointingHandCursor
]; break;
853 pCursor
= GetSalData()->getCursor( mePointerStyle
);
856 OSL_FAIL( "unmapped cursor" );
857 pCursor
= [NSCursor arrowCursor
];
864 void AquaSalFrame::SetPointer( PointerStyle ePointerStyle
)
869 // #i113170# may not be the main thread if called from UNO API
870 SalData::ensureThreadAutoreleasePool();
872 if( ePointerStyle
== mePointerStyle
)
874 mePointerStyle
= ePointerStyle
;
876 [mpNSWindow invalidateCursorRectsForView
: mpNSView
];
879 void AquaSalFrame::SetPointerPos( long nX
, long nY
)
881 // FIXME: use Cocoa functions
883 // FIXME: multiscreen support
884 CGPoint aPoint
= { static_cast<CGFloat
>(nX
+ maGeometry
.nX
), static_cast<CGFloat
>(nY
+ maGeometry
.nY
) };
885 CGDirectDisplayID mainDisplayID
= CGMainDisplayID();
886 CGDisplayMoveCursorToPoint( mainDisplayID
, aPoint
);
889 void AquaSalFrame::Flush()
891 if( !(mbGraphics
&& mpGraphics
&& mpNSView
&& mbShown
) )
894 // #i113170# may not be the main thread if called from UNO API
895 SalData::ensureThreadAutoreleasePool();
897 [mpNSView setNeedsDisplay
: YES
];
899 // outside of the application's event loop (e.g. IntroWindow)
900 // nothing would trigger paint event handling
901 // => fall back to synchronous painting
902 if( ImplGetSVData()->maAppData
.mnDispatchLevel
<= 0 )
908 void AquaSalFrame::Flush( const tools::Rectangle
& rRect
)
910 if( !(mbGraphics
&& mpGraphics
&& mpNSView
&& mbShown
) )
913 // #i113170# may not be the main thread if called from UNO API
914 SalData::ensureThreadAutoreleasePool();
916 NSRect aNSRect
= { { static_cast<CGFloat
>(rRect
.Left()), static_cast<CGFloat
>(rRect
.Top()) }, { static_cast<CGFloat
>(rRect
.GetWidth()), static_cast<CGFloat
>(rRect
.GetHeight()) } };
917 VCLToCocoa( aNSRect
, false );
918 [mpNSView setNeedsDisplayInRect
: aNSRect
];
920 // outside of the application's event loop (e.g. IntroWindow)
921 // nothing would trigger paint event handling
922 // => fall back to synchronous painting
923 if( ImplGetSVData()->maAppData
.mnDispatchLevel
<= 0 )
929 void AquaSalFrame::SetInputContext( SalInputContext
* pContext
)
933 mnICOptions
= InputContextFlags::NONE
;
937 mnICOptions
= pContext
->mnOptions
;
939 if(!(pContext
->mnOptions
& InputContextFlags::Text
))
943 void AquaSalFrame::EndExtTextInput( EndExtTextInputFlags
)
947 OUString
AquaSalFrame::GetKeyName( sal_uInt16 nKeyCode
)
949 static std::map
< sal_uInt16
, OUString
> aKeyMap
;
950 if( aKeyMap
.empty() )
953 for( i
= KEY_A
; i
<= KEY_Z
; i
++ )
954 aKeyMap
[ i
] = OUString( sal_Unicode( 'A' + (i
- KEY_A
) ) );
955 for( i
= KEY_0
; i
<= KEY_9
; i
++ )
956 aKeyMap
[ i
] = OUString( sal_Unicode( '0' + (i
- KEY_0
) ) );
957 for( i
= KEY_F1
; i
<= KEY_F26
; i
++ )
959 OUStringBuffer
aKey( 3 );
961 aKey
.append( sal_Int32( i
- KEY_F1
+ 1 ) );
962 aKeyMap
[ i
] = aKey
.makeStringAndClear();
965 aKeyMap
[ KEY_DOWN
] = OUString( u
'\x21e3' );
966 aKeyMap
[ KEY_UP
] = OUString( u
'\x21e1' );
967 aKeyMap
[ KEY_LEFT
] = OUString( u
'\x21e0' );
968 aKeyMap
[ KEY_RIGHT
] = OUString( u
'\x21e2' );
969 aKeyMap
[ KEY_HOME
] = OUString( u
'\x2196' );
970 aKeyMap
[ KEY_END
] = OUString( u
'\x2198' );
971 aKeyMap
[ KEY_PAGEUP
] = OUString( u
'\x21de' );
972 aKeyMap
[ KEY_PAGEDOWN
] = OUString( u
'\x21df' );
973 aKeyMap
[ KEY_RETURN
] = OUString( u
'\x21a9' );
974 aKeyMap
[ KEY_ESCAPE
] = "esc";
975 aKeyMap
[ KEY_TAB
] = OUString( u
'\x21e5' );
976 aKeyMap
[ KEY_BACKSPACE
]= OUString( u
'\x232b' );
977 aKeyMap
[ KEY_SPACE
] = OUString( u
'\x2423' );
978 aKeyMap
[ KEY_DELETE
] = OUString( u
'\x2326' );
979 aKeyMap
[ KEY_ADD
] = "+";
980 aKeyMap
[ KEY_SUBTRACT
] = "-";
981 aKeyMap
[ KEY_DIVIDE
] = "/";
982 aKeyMap
[ KEY_MULTIPLY
] = "*";
983 aKeyMap
[ KEY_POINT
] = ".";
984 aKeyMap
[ KEY_COMMA
] = ",";
985 aKeyMap
[ KEY_LESS
] = "<";
986 aKeyMap
[ KEY_GREATER
] = ">";
987 aKeyMap
[ KEY_EQUAL
] = "=";
988 aKeyMap
[ KEY_OPEN
] = OUString( u
'\x23cf' );
989 aKeyMap
[ KEY_TILDE
] = "~";
990 aKeyMap
[ KEY_BRACKETLEFT
] = "[";
991 aKeyMap
[ KEY_BRACKETRIGHT
] = "]";
992 aKeyMap
[ KEY_SEMICOLON
] = ";";
993 aKeyMap
[ KEY_QUOTERIGHT
] = "'";
995 /* yet unmapped KEYCODES:
996 aKeyMap[ KEY_INSERT ] = OUString( sal_Unicode( ) );
997 aKeyMap[ KEY_CUT ] = OUString( sal_Unicode( ) );
998 aKeyMap[ KEY_COPY ] = OUString( sal_Unicode( ) );
999 aKeyMap[ KEY_PASTE ] = OUString( sal_Unicode( ) );
1000 aKeyMap[ KEY_UNDO ] = OUString( sal_Unicode( ) );
1001 aKeyMap[ KEY_REPEAT ] = OUString( sal_Unicode( ) );
1002 aKeyMap[ KEY_FIND ] = OUString( sal_Unicode( ) );
1003 aKeyMap[ KEY_PROPERTIES ] = OUString( sal_Unicode( ) );
1004 aKeyMap[ KEY_FRONT ] = OUString( sal_Unicode( ) );
1005 aKeyMap[ KEY_CONTEXTMENU ] = OUString( sal_Unicode( ) );
1006 aKeyMap[ KEY_MENU ] = OUString( sal_Unicode( ) );
1007 aKeyMap[ KEY_HELP ] = OUString( sal_Unicode( ) );
1008 aKeyMap[ KEY_HANGUL_HANJA ] = OUString( sal_Unicode( ) );
1009 aKeyMap[ KEY_DECIMAL ] = OUString( sal_Unicode( ) );
1010 aKeyMap[ KEY_QUOTELEFT ]= OUString( sal_Unicode( ) );
1011 aKeyMap[ KEY_CAPSLOCK ]= OUString( sal_Unicode( ) );
1012 aKeyMap[ KEY_NUMLOCK ]= OUString( sal_Unicode( ) );
1013 aKeyMap[ KEY_SCROLLLOCK ]= OUString( sal_Unicode( ) );
1018 OUStringBuffer
aResult( 16 );
1020 sal_uInt16 nUnmodifiedCode
= (nKeyCode
& KEY_CODE_MASK
);
1021 std::map
< sal_uInt16
, OUString
>::const_iterator it
= aKeyMap
.find( nUnmodifiedCode
);
1022 if( it
!= aKeyMap
.end() )
1024 if( (nKeyCode
& KEY_SHIFT
) != 0 )
1025 aResult
.append( u
'\x21e7' );
1026 if( (nKeyCode
& KEY_MOD1
) != 0 )
1027 aResult
.append( u
'\x2318' );
1028 // we do not really handle Alt (see below)
1029 // we map it to MOD3, which is actually Command
1030 if( (nKeyCode
& (KEY_MOD2
|KEY_MOD3
)) != 0 )
1031 aResult
.append( u
'\x2325' );
1033 aResult
.append( it
->second
);
1036 return aResult
.makeStringAndClear();
1039 static void getAppleScrollBarVariant(StyleSettings
&rSettings
)
1041 bool bIsScrollbarDoubleMax
= true; // default is DoubleMax
1043 CFStringRef AppleScrollBarType
= CFSTR("AppleScrollBarVariant");
1044 if( AppleScrollBarType
)
1046 CFStringRef ScrollBarVariant
= static_cast<CFStringRef
>(CFPreferencesCopyAppValue( AppleScrollBarType
, kCFPreferencesCurrentApplication
));
1047 if( ScrollBarVariant
)
1049 if( CFGetTypeID( ScrollBarVariant
) == CFStringGetTypeID() )
1051 // TODO: check for the less important variants "DoubleMin" and "DoubleBoth" too
1052 CFStringRef DoubleMax
= CFSTR("DoubleMax");
1055 if ( !CFStringCompare(ScrollBarVariant
, DoubleMax
, kCFCompareCaseInsensitive
) )
1056 bIsScrollbarDoubleMax
= true;
1058 bIsScrollbarDoubleMax
= false;
1059 CFRelease(DoubleMax
);
1062 CFRelease( ScrollBarVariant
);
1064 CFRelease(AppleScrollBarType
);
1067 GetSalData()->mbIsScrollbarDoubleMax
= bIsScrollbarDoubleMax
;
1069 CFStringRef jumpScroll
= CFSTR("AppleScrollerPagingBehavior");
1072 CFBooleanRef jumpStr
= static_cast<CFBooleanRef
>(CFPreferencesCopyAppValue( jumpScroll
, kCFPreferencesCurrentApplication
));
1075 if( CFGetTypeID( jumpStr
) == CFBooleanGetTypeID() )
1076 rSettings
.SetPrimaryButtonWarpsSlider(jumpStr
== kCFBooleanTrue
);
1077 CFRelease( jumpStr
);
1079 CFRelease( jumpScroll
);
1083 static Color
getColor( NSColor
* pSysColor
, const Color
& rDefault
, NSWindow
* pWin
)
1085 Color
aRet( rDefault
);
1089 NSColor
* pRBGColor
= [pSysColor colorUsingColorSpaceName
: NSDeviceRGBColorSpace device
: [pWin deviceDescription
]];
1092 CGFloat r
= 0, g
= 0, b
= 0, a
= 0;
1093 [pRBGColor getRed
: &r green
: &g blue
: &b alpha
: &a
];
1094 aRet
= Color( int(r
*255.999), int(g
*255.999), int(b
*255.999) );
1096 do not release here; leads to duplicate free in yield
1097 it seems the converted color comes out autoreleased, although this
1099 [pRBGColor release];
1106 static vcl::Font
getFont( NSFont
* pFont
, long nDPIY
, const vcl::Font
& rDefault
)
1108 vcl::Font
aResult( rDefault
);
1111 aResult
.SetFamilyName( GetOUString( [pFont familyName
] ) );
1112 aResult
.SetFontHeight( static_cast<int>(([pFont pointSize
] * 72.0 / (float)nDPIY
)+0.5) );
1113 aResult
.SetItalic( ([pFont italicAngle
] != 0.0) ? ITALIC_NORMAL
: ITALIC_NONE
);
1120 void AquaSalFrame::getResolution( sal_Int32
& o_rDPIX
, sal_Int32
& o_rDPIY
)
1125 ReleaseGraphics( mpGraphics
);
1127 mpGraphics
->GetResolution( o_rDPIX
, o_rDPIY
);
1130 // on OSX-Aqua the style settings are independent of the frame, so it does
1131 // not really belong here. Since the connection to the Appearance_Manager
1132 // is currently done in salnativewidgets.cxx this would be a good place.
1133 // On the other hand VCL's platform independent code currently only asks
1134 // SalFrames for system settings anyway, so moving the code somewhere else
1135 // doesn't make the anything cleaner for now
1136 void AquaSalFrame::UpdateSettings( AllSettings
& rSettings
)
1141 // #i113170# may not be the main thread if called from UNO API
1142 SalData::ensureThreadAutoreleasePool();
1144 [mpNSView lockFocus
];
1146 StyleSettings aStyleSettings
= rSettings
.GetStyleSettings();
1149 Color
aBackgroundColor( 0xEC, 0xEC, 0xEC );
1150 aStyleSettings
.Set3DColors( aBackgroundColor
);
1151 aStyleSettings
.SetFaceColor( aBackgroundColor
);
1152 Color
aInactiveTabColor( aBackgroundColor
);
1153 aInactiveTabColor
.DecreaseLuminance( 32 );
1154 aStyleSettings
.SetInactiveTabColor( aInactiveTabColor
);
1156 aStyleSettings
.SetDialogColor( aBackgroundColor
);
1157 aStyleSettings
.SetLightBorderColor( aBackgroundColor
);
1158 Color
aShadowColor( aStyleSettings
.GetShadowColor() );
1159 aShadowColor
.IncreaseLuminance( 32 );
1160 aStyleSettings
.SetShadowColor( aShadowColor
);
1162 // get the system font settings
1163 vcl::Font aAppFont
= aStyleSettings
.GetAppFont();
1164 sal_Int32 nDPIX
= 72, nDPIY
= 72;
1165 getResolution( nDPIX
, nDPIY
);
1166 aAppFont
= getFont( [NSFont systemFontOfSize
: 0], nDPIY
, aAppFont
);
1168 aStyleSettings
.SetToolbarIconSize( ToolbarIconSize::Large
);
1170 // TODO: better mapping of OS X<->LibreOffice font settings
1171 aStyleSettings
.SetAppFont( aAppFont
);
1172 aStyleSettings
.SetHelpFont( aAppFont
);
1173 aStyleSettings
.SetPushButtonFont( aAppFont
);
1175 vcl::Font
aTitleFont( getFont( [NSFont titleBarFontOfSize
: 0], nDPIY
, aAppFont
) );
1176 aStyleSettings
.SetTitleFont( aTitleFont
);
1177 aStyleSettings
.SetFloatTitleFont( aTitleFont
);
1179 vcl::Font
aMenuFont( getFont( [NSFont menuFontOfSize
: 0], nDPIY
, aAppFont
) );
1180 aStyleSettings
.SetMenuFont( aMenuFont
);
1182 aStyleSettings
.SetToolFont( aAppFont
);
1184 vcl::Font
aLabelFont( getFont( [NSFont labelFontOfSize
: 0], nDPIY
, aAppFont
) );
1185 aStyleSettings
.SetLabelFont( aLabelFont
);
1186 aStyleSettings
.SetRadioCheckFont( aLabelFont
);
1187 aStyleSettings
.SetFieldFont( aLabelFont
);
1188 aStyleSettings
.SetGroupFont( aLabelFont
);
1189 aStyleSettings
.SetTabFont( aLabelFont
);
1190 aStyleSettings
.SetIconFont( aLabelFont
);
1192 Color
aHighlightColor( getColor( [NSColor selectedTextBackgroundColor
],
1193 aStyleSettings
.GetHighlightColor(), mpNSWindow
) );
1194 aStyleSettings
.SetHighlightColor( aHighlightColor
);
1195 Color
aHighlightTextColor( getColor( [NSColor selectedTextColor
],
1196 aStyleSettings
.GetHighlightTextColor(), mpNSWindow
) );
1197 aStyleSettings
.SetHighlightTextColor( aHighlightTextColor
);
1199 Color
aMenuHighlightColor( getColor( [NSColor selectedMenuItemColor
],
1200 aStyleSettings
.GetMenuHighlightColor(), mpNSWindow
) );
1201 aStyleSettings
.SetMenuHighlightColor( aMenuHighlightColor
);
1202 Color
aMenuHighlightTextColor( getColor( [NSColor selectedMenuItemTextColor
],
1203 aStyleSettings
.GetMenuHighlightTextColor(), mpNSWindow
) );
1204 aStyleSettings
.SetMenuHighlightTextColor( aMenuHighlightTextColor
);
1206 aStyleSettings
.SetMenuColor( aBackgroundColor
);
1207 Color
aMenuTextColor( getColor( [NSColor textColor
],
1208 aStyleSettings
.GetMenuTextColor(), mpNSWindow
) );
1209 aStyleSettings
.SetMenuTextColor( aMenuTextColor
);
1210 aStyleSettings
.SetMenuBarTextColor( aMenuTextColor
);
1211 aStyleSettings
.SetMenuBarRolloverTextColor( aMenuTextColor
);
1212 aStyleSettings
.SetMenuBarHighlightTextColor(aStyleSettings
.GetMenuHighlightTextColor());
1214 aStyleSettings
.SetCursorBlinkTime( 500 );
1216 // no mnemonics on OS X
1217 aStyleSettings
.SetOptions( aStyleSettings
.GetOptions() | StyleSettingsOptions::NoMnemonics
);
1219 getAppleScrollBarVariant(aStyleSettings
);
1221 // set scrollbar size
1222 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1223 // 'NSRegularControlSize' is deprecated: first deprecated in macOS 10.12
1224 aStyleSettings
.SetScrollBarSize( static_cast<long int>([NSScroller scrollerWidthForControlSize
:NSRegularControlSize scrollerStyle
:NSScrollerStyleLegacy
]) );
1225 SAL_WNODEPRECATED_DECLARATIONS_POP
1226 // images in menus false for MacOSX
1227 aStyleSettings
.SetPreferredUseImagesInMenus( false );
1228 aStyleSettings
.SetHideDisabledMenuItems( true );
1229 aStyleSettings
.SetPreferredContextMenuShortcuts( false );
1231 rSettings
.SetStyleSettings( aStyleSettings
);
1233 // don't draw frame around each and every toolbar
1234 ImplGetSVData()->maNWFData
.mbDockingAreaAvoidTBFrames
= true;
1236 [mpNSView unlockFocus
];
1239 const SystemEnvData
* AquaSalFrame::GetSystemData() const
1244 void AquaSalFrame::Beep()
1249 void AquaSalFrame::SetPosSize(long nX
, long nY
, long nWidth
, long nHeight
, sal_uInt16 nFlags
)
1254 // #i113170# may not be the main thread if called from UNO API
1255 SalData::ensureThreadAutoreleasePool();
1257 SalEvent nEvent
= SalEvent::NONE
;
1259 if( [mpNSWindow isMiniaturized
] )
1260 [mpNSWindow deminiaturize
: NSApp
]; // expand the window
1262 if (nFlags
& (SAL_FRAME_POSSIZE_X
| SAL_FRAME_POSSIZE_Y
))
1264 mbPositioned
= true;
1265 nEvent
= SalEvent::Move
;
1268 if (nFlags
& (SAL_FRAME_POSSIZE_WIDTH
| SAL_FRAME_POSSIZE_HEIGHT
))
1271 nEvent
= (nEvent
== SalEvent::Move
) ? SalEvent::MoveResize
: SalEvent::Resize
;
1274 NSRect aFrameRect
= [mpNSWindow frame
];
1275 NSRect aContentRect
= [NSWindow contentRectForFrameRect
: aFrameRect styleMask
: mnStyleMask
];
1277 // position is always relative to parent frame
1278 NSRect aParentContentRect
;
1282 if( AllSettings::GetLayoutRTL() )
1284 if( (nFlags
& SAL_FRAME_POSSIZE_WIDTH
) != 0 )
1285 nX
= mpParent
->maGeometry
.nWidth
- nWidth
-1 - nX
;
1287 nX
= mpParent
->maGeometry
.nWidth
- static_cast<long int>( aContentRect
.size
.width
-1) - nX
;
1289 NSRect aParentFrameRect
= [mpParent
->mpNSWindow frame
];
1290 aParentContentRect
= [NSWindow contentRectForFrameRect
: aParentFrameRect styleMask
: mpParent
->mnStyleMask
];
1293 aParentContentRect
= maScreenRect
; // use screen if no parent
1295 CocoaToVCL( aContentRect
);
1296 CocoaToVCL( aParentContentRect
);
1298 bool bPaint
= false;
1299 if( (nFlags
& (SAL_FRAME_POSSIZE_WIDTH
| SAL_FRAME_POSSIZE_HEIGHT
)) != 0 )
1301 if( nWidth
!= aContentRect
.size
.width
|| nHeight
!= aContentRect
.size
.height
)
1305 // use old window pos if no new pos requested
1306 if( (nFlags
& SAL_FRAME_POSSIZE_X
) != 0 )
1307 aContentRect
.origin
.x
= nX
+ aParentContentRect
.origin
.x
;
1308 if( (nFlags
& SAL_FRAME_POSSIZE_Y
) != 0)
1309 aContentRect
.origin
.y
= nY
+ aParentContentRect
.origin
.y
;
1311 // use old size if no new size requested
1312 if( (nFlags
& SAL_FRAME_POSSIZE_WIDTH
) != 0 )
1313 aContentRect
.size
.width
= nWidth
;
1314 if( (nFlags
& SAL_FRAME_POSSIZE_HEIGHT
) != 0)
1315 aContentRect
.size
.height
= nHeight
;
1317 VCLToCocoa( aContentRect
);
1319 // do not display yet, we need to update our backbuffer
1321 [mpNSWindow setFrame
: [NSWindow frameRectForContentRect
: aContentRect styleMask
: mnStyleMask
] display
: NO
];
1324 UpdateFrameGeometry();
1326 if (nEvent
!= SalEvent::NONE
)
1327 CallCallback(nEvent
, nullptr);
1329 if( mbShown
&& bPaint
)
1331 // trigger filling our backbuffer
1334 // now inform the system that the views need to be drawn
1335 [mpNSWindow display
];
1339 void AquaSalFrame::GetWorkArea( tools::Rectangle
& rRect
)
1344 // #i113170# may not be the main thread if called from UNO API
1345 SalData::ensureThreadAutoreleasePool();
1347 NSScreen
* pScreen
= [mpNSWindow screen
];
1348 if( pScreen
== nil
)
1349 pScreen
= [NSScreen mainScreen
];
1350 NSRect aRect
= [pScreen visibleFrame
];
1351 CocoaToVCL( aRect
);
1352 rRect
.Left() = static_cast<long>(aRect
.origin
.x
);
1353 rRect
.Top() = static_cast<long>(aRect
.origin
.y
);
1354 rRect
.Right() = static_cast<long>(aRect
.origin
.x
+ aRect
.size
.width
- 1);
1355 rRect
.Bottom() = static_cast<long>(aRect
.origin
.y
+ aRect
.size
.height
- 1);
1358 SalPointerState
AquaSalFrame::GetPointerState()
1360 // #i113170# may not be the main thread if called from UNO API
1361 SalData::ensureThreadAutoreleasePool();
1363 SalPointerState state
;
1367 NSPoint aPt
= [mpNSWindow mouseLocationOutsideOfEventStream
];
1368 CocoaToVCL( aPt
, false );
1369 state
.maPos
= Point(static_cast<long>(aPt
.x
), static_cast<long>(aPt
.y
));
1371 NSEvent
* pCur
= [NSApp currentEvent
];
1372 bool bMouseEvent
= false;
1376 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1377 // 'NSLeftMouseDown' is deprecated: first deprecated in macOS 10.12
1378 // 'NSLeftMouseDragged' is deprecated: first deprecated in macOS 10.12
1379 // 'NSLeftMouseUp' is deprecated: first deprecated in macOS 10.12
1380 // 'NSMouseMoved' is deprecated: first deprecated in macOS 10.12
1381 // 'NSOtherMouseDown' is deprecated: first deprecated in macOS 10.12
1382 // 'NSOtherMouseDragged' is deprecated: first deprecated in macOS 10.12
1383 // 'NSOtherMouseUp' is deprecated: first deprecated in macOS 10.12
1384 // 'NSRightMouseDown' is deprecated: first deprecated in macOS 10.12
1385 // 'NSRightMouseDragged' is deprecated: first deprecated in macOS 10.12
1386 // 'NSRightMouseUp' is deprecated: first deprecated in macOS 10.12
1387 switch( [pCur type
] )
1389 case NSLeftMouseDown
: state
.mnState
|= MOUSE_LEFT
; break;
1390 case NSLeftMouseUp
: break;
1391 case NSRightMouseDown
: state
.mnState
|= MOUSE_RIGHT
; break;
1392 case NSRightMouseUp
: break;
1393 case NSOtherMouseDown
: state
.mnState
|= ([pCur buttonNumber
] == 2) ? MOUSE_MIDDLE
: 0; break;
1394 case NSOtherMouseUp
: break;
1395 case NSMouseMoved
: break;
1396 case NSLeftMouseDragged
: state
.mnState
|= MOUSE_LEFT
; break;
1397 case NSRightMouseDragged
: state
.mnState
|= MOUSE_RIGHT
; break;
1398 case NSOtherMouseDragged
: state
.mnState
|= ([pCur buttonNumber
] == 2) ? MOUSE_MIDDLE
: 0; break;
1401 bMouseEvent
= false;
1404 SAL_WNODEPRECATED_DECLARATIONS_POP
1408 unsigned int nMask
= (unsigned int)[pCur modifierFlags
];
1409 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1410 // 'NSAlternateKeyMask' is deprecated: first deprecated in macOS 10.12
1411 // 'NSCommandKeyMask' is deprecated: first deprecated in macOS 10.12
1412 // 'NSControlKeyMask' is deprecated: first deprecated in macOS 10.12
1413 // 'NSShiftKeyMask' is deprecated: first deprecated in macOS 10.12
1414 if( (nMask
& NSShiftKeyMask
) != 0 )
1415 state
.mnState
|= KEY_SHIFT
;
1416 if( (nMask
& NSControlKeyMask
) != 0 )
1417 state
.mnState
|= KEY_MOD3
;
1418 if( (nMask
& NSAlternateKeyMask
) != 0 )
1419 state
.mnState
|= KEY_MOD2
;
1420 if( (nMask
& NSCommandKeyMask
) != 0 )
1421 state
.mnState
|= KEY_MOD1
;
1422 SAL_WNODEPRECATED_DECLARATIONS_POP
1427 // FIXME: replace Carbon by Cocoa
1428 // Cocoa does not have an equivalent for GetCurrentEventButtonState
1429 // and GetCurrentEventKeyModifiers.
1430 // we could try to get away with tracking all events for modifierKeys
1431 // and all mouse events for button state in VCL_NSApllication::sendEvent,
1432 // but it is unclear whether this will get us the same result.
1433 // leave in GetCurrentEventButtonState and GetCurrentEventKeyModifiers for now
1435 // fill in button state
1436 UInt32 nState
= GetCurrentEventButtonState();
1439 state
.mnState
|= MOUSE_LEFT
; // primary button
1441 state
.mnState
|= MOUSE_RIGHT
; // secondary button
1443 state
.mnState
|= MOUSE_MIDDLE
; // tertiary button
1445 // fill in modifier state
1446 nState
= GetCurrentEventKeyModifiers();
1447 if( nState
& shiftKey
)
1448 state
.mnState
|= KEY_SHIFT
;
1449 if( nState
& controlKey
)
1450 state
.mnState
|= KEY_MOD3
;
1451 if( nState
& optionKey
)
1452 state
.mnState
|= KEY_MOD2
;
1453 if( nState
& cmdKey
)
1454 state
.mnState
|= KEY_MOD1
;
1460 KeyIndicatorState
AquaSalFrame::GetIndicatorState()
1462 return KeyIndicatorState::NONE
;
1465 void AquaSalFrame::SimulateKeyPress( sal_uInt16
/*nKeyCode*/ )
1469 bool AquaSalFrame::SetPluginParent( SystemParentData
* )
1471 // plugin parent may be killed unexpectedly by
1472 // plugging process;
1478 bool AquaSalFrame::MapUnicodeToKeyCode( sal_Unicode
, LanguageType
, vcl::KeyCode
& )
1480 // not supported yet
1484 LanguageType
AquaSalFrame::GetInputLanguage()
1487 return LANGUAGE_DONTKNOW
;
1490 void AquaSalFrame::DrawMenuBar()
1494 void AquaSalFrame::SetMenu( SalMenu
* pSalMenu
)
1496 // #i113170# may not be the main thread if called from UNO API
1497 SalData::ensureThreadAutoreleasePool();
1499 AquaSalMenu
* pMenu
= static_cast<AquaSalMenu
*>(pSalMenu
);
1500 SAL_WARN_IF( pMenu
&& !pMenu
->mbMenuBar
, "vcl", "setting non menubar on frame" );
1503 mpMenu
->setMainMenu();
1506 void AquaSalFrame::SetExtendedFrameStyle( SalExtStyle nStyle
)
1510 // #i113170# may not be the main thread if called from UNO API
1511 SalData::ensureThreadAutoreleasePool();
1513 if( (mnExtStyle
& SAL_FRAME_EXT_STYLE_DOCMODIFIED
) != (nStyle
& SAL_FRAME_EXT_STYLE_DOCMODIFIED
) )
1514 [mpNSWindow setDocumentEdited
: (nStyle
& SAL_FRAME_EXT_STYLE_DOCMODIFIED
) ? YES
: NO
];
1517 mnExtStyle
= nStyle
;
1520 SalFrame
* AquaSalFrame::GetParent() const
1525 void AquaSalFrame::SetParent( SalFrame
* pNewParent
)
1527 bool bShown
= mbShown
;
1528 // remove from child list
1530 mpParent
= static_cast<AquaSalFrame
*>(pNewParent
);
1531 // insert to correct parent and paint
1535 void AquaSalFrame::UpdateFrameGeometry()
1542 // keep in mind that view and window coordinates are lower left
1543 // whereas vcl's are upper left
1545 // update screen rect
1546 NSScreen
* pScreen
= [mpNSWindow screen
];
1549 maScreenRect
= [pScreen frame
];
1550 NSArray
* pScreens
= [NSScreen screens
];
1552 maGeometry
.nDisplayScreenNumber
= [pScreens indexOfObject
: pScreen
];
1555 NSRect aFrameRect
= [mpNSWindow frame
];
1556 NSRect aContentRect
= [NSWindow contentRectForFrameRect
: aFrameRect styleMask
: mnStyleMask
];
1558 // release old track rect
1559 [mpNSView removeTrackingRect
: mnTrackingRectTag
];
1560 // install the new track rect
1561 NSRect aTrackRect
= { NSZeroPoint
, aContentRect
.size
};
1562 mnTrackingRectTag
= [mpNSView addTrackingRect
: aTrackRect owner
: mpNSView userData
: nil assumeInside
: NO
];
1564 // convert to vcl convention
1565 CocoaToVCL( aFrameRect
);
1566 CocoaToVCL( aContentRect
);
1568 maGeometry
.nX
= static_cast<int>(aContentRect
.origin
.x
);
1569 maGeometry
.nY
= static_cast<int>(aContentRect
.origin
.y
);
1571 maGeometry
.nLeftDecoration
= static_cast<unsigned int>(aContentRect
.origin
.x
- aFrameRect
.origin
.x
);
1572 maGeometry
.nRightDecoration
= static_cast<unsigned int>((aFrameRect
.origin
.x
+ aFrameRect
.size
.width
) -
1573 (aContentRect
.origin
.x
+ aContentRect
.size
.width
));
1575 maGeometry
.nTopDecoration
= static_cast<unsigned int>(aContentRect
.origin
.y
- aFrameRect
.origin
.y
);
1576 maGeometry
.nBottomDecoration
= static_cast<unsigned int>((aFrameRect
.origin
.y
+ aFrameRect
.size
.height
) -
1577 (aContentRect
.origin
.y
+ aContentRect
.size
.height
));
1579 maGeometry
.nWidth
= static_cast<unsigned int>(aContentRect
.size
.width
);
1580 maGeometry
.nHeight
= static_cast<unsigned int>(aContentRect
.size
.height
);
1583 void AquaSalFrame::CaptureMouse( bool bCapture
)
1586 we'll try to use a pidgin version of capture mouse
1587 on MacOSX (neither carbon nor cocoa) there is a
1588 CaptureMouse equivalent (in Carbon there is TrackMouseLocation
1589 but this is useless to use since it is blocking)
1591 However on cocoa the active frame seems to get mouse events
1592 also outside the window, so we'll try to forward mouse events
1593 to the capture frame in the hope that one of our frames
1596 This will break as soon as the user activates another app, but
1597 a mouse click will normally lead to a release of the mouse anyway.
1599 Let's see how far we get this way. Alternatively we could use one
1600 large overlay window like we did for the carbon implementation,
1601 however that is resource intensive.
1605 s_pCaptureFrame
= this;
1606 else if( ! bCapture
&& s_pCaptureFrame
== this )
1607 s_pCaptureFrame
= nullptr;
1610 void AquaSalFrame::ResetClipRegion()
1617 // #i113170# may not be the main thread if called from UNO API
1618 SalData::ensureThreadAutoreleasePool();
1620 // release old path and indicate no clipping
1621 CGPathRelease( mrClippingPath
);
1622 mrClippingPath
= nullptr;
1624 if( mpNSView
&& mbShown
)
1625 [mpNSView setNeedsDisplay
: YES
];
1628 [mpNSWindow setOpaque
: YES
];
1629 [mpNSWindow invalidateShadow
];
1633 void AquaSalFrame::BeginSetClipRegion( sal_uLong nRects
)
1640 // #i113170# may not be the main thread if called from UNO API
1641 SalData::ensureThreadAutoreleasePool();
1644 if( mrClippingPath
)
1646 CGPathRelease( mrClippingPath
);
1647 mrClippingPath
= nullptr;
1650 if( maClippingRects
.size() > SAL_CLIPRECT_COUNT
&& nRects
< maClippingRects
.size() )
1652 std::vector
<CGRect
> aEmptyVec
;
1653 maClippingRects
.swap( aEmptyVec
);
1655 maClippingRects
.clear();
1656 maClippingRects
.reserve( nRects
);
1659 void AquaSalFrame::UnionClipRegion( long nX
, long nY
, long nWidth
, long nHeight
)
1661 // #i113170# may not be the main thread if called from UNO API
1662 SalData::ensureThreadAutoreleasePool();
1664 if( nWidth
&& nHeight
)
1666 NSRect aRect
= { { static_cast<CGFloat
>(nX
), static_cast<CGFloat
>(nY
) }, { static_cast<CGFloat
>(nWidth
), static_cast<CGFloat
>(nHeight
) } };
1667 VCLToCocoa( aRect
, false );
1668 maClippingRects
.push_back( CGRectMake(aRect
.origin
.x
, aRect
.origin
.y
, aRect
.size
.width
, aRect
.size
.height
) );
1672 void AquaSalFrame::EndSetClipRegion()
1679 // #i113170# may not be the main thread if called from UNO API
1680 SalData::ensureThreadAutoreleasePool();
1682 if( ! maClippingRects
.empty() )
1684 mrClippingPath
= CGPathCreateMutable();
1685 CGPathAddRects( mrClippingPath
, nullptr, &maClippingRects
[0], maClippingRects
.size() );
1687 if( mpNSView
&& mbShown
)
1688 [mpNSView setNeedsDisplay
: YES
];
1691 [mpNSWindow setOpaque
: (mrClippingPath
!= nullptr) ? NO
: YES
];
1692 [mpNSWindow setBackgroundColor
: [NSColor clearColor
]];
1693 // shadow is invalidated when view gets drawn again
1697 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */