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 .
23 #include "rtl/ustrbuf.hxx"
27 #include "vcl/svapp.hxx"
28 #include "vcl/window.hxx"
29 #include "vcl/syswin.hxx"
31 #include "aqua/saldata.hxx"
32 #include "aqua/salgdi.h"
33 #include "aqua/salframe.h"
34 #include "aqua/salmenu.h"
35 #include "aqua/salinst.h"
36 #include "aqua/salframeview.h"
37 #include "aqua/aqua11yfactory.h"
38 #include "quartz/utils.h"
40 #include "salwtype.hxx"
43 #include <objc/objc-runtime.h>
45 // FIXME: move theming code to salnativewidgets.cxx
46 #include <Carbon/Carbon.h>
51 // =======================================================================
53 AquaSalFrame
* AquaSalFrame::s_pCaptureFrame
= NULL
;
55 // =======================================================================
57 AquaSalFrame::AquaSalFrame( SalFrame
* pParent
, sal_uLong salFrameStyle
) :
68 mbFullScreen( false ),
73 mbPresentation( false ),
74 mnStyle( salFrameStyle
),
77 mnLastModifierFlags( 0 ),
80 mePointerStyle( POINTER_ARROW
),
81 mnTrackingRectTag( 0 ),
85 maSysData
.nSize
= sizeof( SystemEnvData
);
87 mpParent
= dynamic_cast<AquaSalFrame
*>(pParent
);
91 SalData
* pSalData
= GetSalData();
92 pSalData
->maFrames
.push_front( this );
93 pSalData
->maFrameCheck
.insert( this );
96 // -----------------------------------------------------------------------
98 AquaSalFrame::~AquaSalFrame()
100 // if the frame is destroyed and has the current menubar
101 // set the default menubar
102 if( mpMenu
&& mpMenu
->mbMenuBar
&& AquaSalMenu::pCurrentMenuBar
== mpMenu
)
103 AquaSalMenu::setDefaultMenu();
105 // cleanup clipping stuff
108 [SalFrameView unsetMouseFrame
: this];
110 SalData
* pSalData
= GetSalData();
111 pSalData
->maFrames
.remove( this );
112 pSalData
->maFrameCheck
.erase( this );
113 pSalData
->maPresentationFrames
.remove( this );
115 DBG_ASSERT( this != s_pCaptureFrame
, "capture frame destroyed" );
116 if( this == s_pCaptureFrame
)
117 s_pCaptureFrame
= NULL
;
121 if( mpDockMenuEntry
)
122 // life cycle comment: the menu has ownership of the item, so no release
123 [AquaSalInstance::GetDynamicDockMenu() removeItem
: mpDockMenuEntry
];
125 [AquaA11yFactory revokeView
: mpView
];
132 // -----------------------------------------------------------------------
134 void AquaSalFrame::initWindowAndView()
136 // initialize mirroring parameters
137 // FIXME: screens changing
138 NSScreen
* pScreen
= [mpWindow screen
];
140 pScreen
= [NSScreen mainScreen
];
141 maScreenRect
= [pScreen frame
];
143 // calculate some default geometry
144 NSRect aVisibleRect
= [pScreen visibleFrame
];
145 CocoaToVCL( aVisibleRect
);
147 maGeometry
.nX
= static_cast<int>(aVisibleRect
.origin
.x
+ aVisibleRect
.size
.width
/ 10);
148 maGeometry
.nY
= static_cast<int>(aVisibleRect
.origin
.y
+ aVisibleRect
.size
.height
/ 10);
149 maGeometry
.nWidth
= static_cast<unsigned int>(aVisibleRect
.size
.width
* 0.8);
150 maGeometry
.nHeight
= static_cast<unsigned int>(aVisibleRect
.size
.height
* 0.8);
152 // calculate style mask
153 if( (mnStyle
& SAL_FRAME_STYLE_FLOAT
) ||
154 (mnStyle
& SAL_FRAME_STYLE_OWNERDRAWDECORATION
) )
155 mnStyleMask
= NSBorderlessWindowMask
;
156 else if( mnStyle
& SAL_FRAME_STYLE_DEFAULT
)
158 mnStyleMask
= NSTitledWindowMask
|
159 NSMiniaturizableWindowMask
|
160 NSResizableWindowMask
|
161 NSClosableWindowMask
;
162 // make default window "maximized"
163 maGeometry
.nX
= static_cast<int>(aVisibleRect
.origin
.x
);
164 maGeometry
.nY
= static_cast<int>(aVisibleRect
.origin
.y
);
165 maGeometry
.nWidth
= static_cast<int>(aVisibleRect
.size
.width
);
166 maGeometry
.nHeight
= static_cast<int>(aVisibleRect
.size
.height
);
167 mbPositioned
= mbSized
= true;
171 if( (mnStyle
& SAL_FRAME_STYLE_MOVEABLE
) )
173 mnStyleMask
|= NSTitledWindowMask
;
174 if( mpParent
== NULL
)
175 mnStyleMask
|= NSMiniaturizableWindowMask
;
177 if( (mnStyle
& SAL_FRAME_STYLE_SIZEABLE
) )
178 mnStyleMask
|= NSResizableWindowMask
;
179 if( (mnStyle
& SAL_FRAME_STYLE_CLOSEABLE
) )
180 mnStyleMask
|= NSClosableWindowMask
;
181 // documentation says anything other than NSBorderlessWindowMask (=0)
182 // should also include NSTitledWindowMask;
183 if( mnStyleMask
!= 0 )
184 mnStyleMask
|= NSTitledWindowMask
;
187 // #i91990# support GUI-less (daemon) execution
190 mpWindow
= [[SalFrameWindow alloc
] initWithSalFrame
: this];
191 mpView
= [[SalFrameView alloc
] initWithSalFrame
: this];
193 @
catch ( id exception
)
198 if( (mnStyle
& SAL_FRAME_STYLE_TOOLTIP
) )
199 [mpWindow setIgnoresMouseEvents
: YES
];
201 [mpWindow setAcceptsMouseMovedEvents
: YES
];
202 [mpWindow setHasShadow
: YES
];
204 // WTF? With the 10.6 SDK and gcc 4.2.1, we get: class 'NSWindow'
205 // does not implement the 'NSWindowDelegate' protocol. Anyway,
206 // having the window object be its own delegate object is
207 // apparently what the code does on purpose, see discussion in
208 // https://issues.apache.org/ooo/show_bug.cgi?id=91990
210 // So to silence the warning when compiling with -Werror, instead of:
211 // [mpWindow setDelegate: mpWindow];
213 objc_msgSend(mpWindow
, @
selector(setDelegate
:), mpWindow
);
215 if( [mpWindow respondsToSelector
: @
selector(setRestorable
:)])
217 objc_msgSend(mpWindow
, @
selector(setRestorable
:), NO
);
219 NSRect aRect
= { { 0,0 }, { static_cast<CGFloat
>(maGeometry
.nWidth
), static_cast<CGFloat
>(maGeometry
.nHeight
) } };
220 mnTrackingRectTag
= [mpView addTrackingRect
: aRect owner
: mpView userData
: nil assumeInside
: NO
];
222 maSysData
.pView
= mpView
;
224 UpdateFrameGeometry();
226 [mpWindow setContentView
: mpView
];
229 // -----------------------------------------------------------------------
231 void AquaSalFrame::CocoaToVCL( NSRect
& io_rRect
, bool bRelativeToScreen
)
233 if( bRelativeToScreen
)
234 io_rRect
.origin
.y
= maScreenRect
.size
.height
- (io_rRect
.origin
.y
+io_rRect
.size
.height
);
236 io_rRect
.origin
.y
= maGeometry
.nHeight
- (io_rRect
.origin
.y
+io_rRect
.size
.height
);
239 void AquaSalFrame::VCLToCocoa( NSRect
& io_rRect
, bool bRelativeToScreen
)
241 if( bRelativeToScreen
)
242 io_rRect
.origin
.y
= maScreenRect
.size
.height
- (io_rRect
.origin
.y
+io_rRect
.size
.height
);
244 io_rRect
.origin
.y
= maGeometry
.nHeight
- (io_rRect
.origin
.y
+io_rRect
.size
.height
);
247 void AquaSalFrame::CocoaToVCL( NSPoint
& io_rPoint
, bool bRelativeToScreen
)
249 if( bRelativeToScreen
)
250 io_rPoint
.y
= maScreenRect
.size
.height
- io_rPoint
.y
;
252 io_rPoint
.y
= maGeometry
.nHeight
- io_rPoint
.y
;
255 void AquaSalFrame::VCLToCocoa( NSPoint
& io_rPoint
, bool bRelativeToScreen
)
257 if( bRelativeToScreen
)
258 io_rPoint
.y
= maScreenRect
.size
.height
- io_rPoint
.y
;
260 io_rPoint
.y
= maGeometry
.nHeight
- io_rPoint
.y
;
263 // -----------------------------------------------------------------------
265 void AquaSalFrame::screenParametersChanged()
267 UpdateFrameGeometry();
270 mpGraphics
->updateResolution();
271 CallCallback( SALEVENT_DISPLAYCHANGED
, 0 );
274 // -----------------------------------------------------------------------
276 SalGraphics
* AquaSalFrame::GetGraphics()
283 mpGraphics
= new AquaSalGraphics
;
284 mpGraphics
->SetWindowGraphics( this );
291 // -----------------------------------------------------------------------
293 void AquaSalFrame::ReleaseGraphics( SalGraphics
*pGraphics
)
296 DBG_ASSERT( pGraphics
== mpGraphics
, "graphics released on wrong frame" );
300 // -----------------------------------------------------------------------
302 sal_Bool
AquaSalFrame::PostEvent( void *pData
)
304 GetSalData()->mpFirstInstance
->PostUserEvent( this, SALEVENT_USEREVENT
, pData
);
308 // -----------------------------------------------------------------------
309 void AquaSalFrame::SetTitle(const OUString
& rTitle
)
314 // #i113170# may not be the main thread if called from UNO API
315 SalData::ensureThreadAutoreleasePool();
317 NSString
* pTitle
= CreateNSString( rTitle
);
318 [mpWindow setTitle
: pTitle
];
320 // create an entry in the dock menu
321 const sal_uLong nAppWindowStyle
= (SAL_FRAME_STYLE_CLOSEABLE
| SAL_FRAME_STYLE_MOVEABLE
);
322 if( mpParent
== NULL
&&
323 (mnStyle
& nAppWindowStyle
) == nAppWindowStyle
)
325 if( mpDockMenuEntry
== NULL
)
327 NSMenu
* pDock
= AquaSalInstance::GetDynamicDockMenu();
328 mpDockMenuEntry
= [pDock insertItemWithTitle
: pTitle
329 action
: @
selector(dockMenuItemTriggered
:)
332 [mpDockMenuEntry setTarget
: mpWindow
];
334 // TODO: image (either the generic window image or an icon
335 // check mark (for "main" window ?)
338 [mpDockMenuEntry setTitle
: pTitle
];
345 // -----------------------------------------------------------------------
347 void AquaSalFrame::SetIcon( sal_uInt16
)
351 // -----------------------------------------------------------------------
353 void AquaSalFrame::SetRepresentedURL( const OUString
& i_rDocURL
)
355 // #i113170# may not be the main thread if called from UNO API
356 SalData::ensureThreadAutoreleasePool();
358 if( i_rDocURL
.startsWith( "file:" ) )
361 osl_getSystemPathFromFileURL( i_rDocURL
.pData
, &aSysPath
.pData
);
362 NSString
* pStr
= CreateNSString( aSysPath
);
366 [mpWindow setRepresentedFilename
: pStr
];
371 // -----------------------------------------------------------------------
373 void AquaSalFrame::initShow()
376 if( ! mbPositioned
&& ! mbFullScreen
)
378 Rectangle aScreenRect
;
379 GetWorkArea( aScreenRect
);
380 if( mpParent
) // center relative to parent
383 long nNewX
= mpParent
->maGeometry
.nX
+ ((long)mpParent
->maGeometry
.nWidth
- (long)maGeometry
.nWidth
)/2;
384 if( nNewX
< aScreenRect
.Left() )
385 nNewX
= aScreenRect
.Left();
386 if( long(nNewX
+ maGeometry
.nWidth
) > aScreenRect
.Right() )
387 nNewX
= aScreenRect
.Right() - maGeometry
.nWidth
-1;
388 long nNewY
= mpParent
->maGeometry
.nY
+ ((long)mpParent
->maGeometry
.nHeight
- (long)maGeometry
.nHeight
)/2;
389 if( nNewY
< aScreenRect
.Top() )
390 nNewY
= aScreenRect
.Top();
391 if( nNewY
> aScreenRect
.Bottom() )
392 nNewY
= aScreenRect
.Bottom() - maGeometry
.nHeight
-1;
393 SetPosSize( nNewX
- mpParent
->maGeometry
.nX
,
394 nNewY
- mpParent
->maGeometry
.nY
,
395 0, 0, SAL_FRAME_POSSIZE_X
| SAL_FRAME_POSSIZE_Y
);
397 else if( ! (mnStyle
& SAL_FRAME_STYLE_SIZEABLE
) )
400 long nNewX
= (aScreenRect
.GetWidth() - maGeometry
.nWidth
)/2;
401 long nNewY
= (aScreenRect
.GetHeight() - maGeometry
.nHeight
)/2;
402 SetPosSize( nNewX
, nNewY
, 0, 0, SAL_FRAME_POSSIZE_X
| SAL_FRAME_POSSIZE_Y
);
406 // make sure the view is present in the wrapper list before any children receive focus
407 [AquaA11yFactory registerView
: mpView
];
410 void AquaSalFrame::SendPaintEvent( const Rectangle
* pRect
)
412 SalPaintEvent
aPaintEvt( 0, 0, maGeometry
.nWidth
, maGeometry
.nHeight
, true );
415 aPaintEvt
.mnBoundX
= pRect
->Left();
416 aPaintEvt
.mnBoundY
= pRect
->Top();
417 aPaintEvt
.mnBoundWidth
= pRect
->GetWidth();
418 aPaintEvt
.mnBoundHeight
= pRect
->GetHeight();
421 CallCallback(SALEVENT_PAINT
, &aPaintEvt
);
424 // -----------------------------------------------------------------------
426 void AquaSalFrame::Show(sal_Bool bVisible
, sal_Bool bNoActivate
)
431 // #i113170# may not be the main thread if called from UNO API
432 SalData::ensureThreadAutoreleasePool();
440 CallCallback(SALEVENT_RESIZE
, 0);
441 // trigger filling our backbuffer
444 if( bNoActivate
|| [mpWindow canBecomeKeyWindow
] == NO
)
445 [mpWindow orderFront
: NSApp
];
447 [mpWindow makeKeyAndOrderFront
: NSApp
];
451 /* #i92674# #i96433# we do not want an invisible parent to show up (which adding a visible
452 child implicitly does). However we also do not want a parentless toolbar.
454 HACK: try to decide when we should not insert a child to its parent
455 floaters and ownerdraw windows have not yet shown up in cases where
456 we don't want the parent to become visible
458 if( mpParent
->mbShown
|| (mnStyle
& (SAL_FRAME_STYLE_OWNERDRAWDECORATION
| SAL_FRAME_STYLE_FLOAT
) ) )
460 [mpParent
->mpWindow addChildWindow
: mpWindow ordered
: NSWindowAbove
];
465 [mpWindow makeMainWindow
];
469 // if the frame holding the current menubar gets hidden
470 // show the default menubar
471 if( mpMenu
&& mpMenu
->mbMenuBar
&& AquaSalMenu::pCurrentMenuBar
== mpMenu
)
472 AquaSalMenu::setDefaultMenu();
474 // #i90440# #i94443# work around the focus going back to some other window
475 // if a child gets hidden for a parent window
476 if( mpParent
&& mpParent
->mbShown
&& [mpWindow isKeyWindow
] )
477 [mpParent
->mpWindow makeKeyAndOrderFront
: NSApp
];
479 [SalFrameView unsetMouseFrame
: this];
480 if( mpParent
&& [mpWindow parentWindow
] == mpParent
->mpWindow
)
481 [mpParent
->mpWindow removeChildWindow
: mpWindow
];
483 [mpWindow orderOut
: NSApp
];
487 // -----------------------------------------------------------------------
489 void AquaSalFrame::Enable( sal_Bool
)
493 // -----------------------------------------------------------------------
495 void AquaSalFrame::SetMinClientSize( long nWidth
, long nHeight
)
497 // #i113170# may not be the main thread if called from UNO API
498 SalData::ensureThreadAutoreleasePool();
501 mnMinHeight
= nHeight
;
505 // Always add the decoration as the dimension concerns only
506 // the content rectangle
507 nWidth
+= maGeometry
.nLeftDecoration
+ maGeometry
.nRightDecoration
;
508 nHeight
+= maGeometry
.nTopDecoration
+ maGeometry
.nBottomDecoration
;
510 NSSize aSize
= { static_cast<CGFloat
>(nWidth
), static_cast<CGFloat
>(nHeight
) };
512 // Size of full window (content+structure) although we only
513 // have the client size in arguments
514 [mpWindow setMinSize
: aSize
];
518 // -----------------------------------------------------------------------
520 void AquaSalFrame::SetMaxClientSize( long nWidth
, long nHeight
)
522 // #i113170# may not be the main thread if called from UNO API
523 SalData::ensureThreadAutoreleasePool();
526 mnMaxHeight
= nHeight
;
530 // Always add the decoration as the dimension concerns only
531 // the content rectangle
532 nWidth
+= maGeometry
.nLeftDecoration
+ maGeometry
.nRightDecoration
;
533 nHeight
+= maGeometry
.nTopDecoration
+ maGeometry
.nBottomDecoration
;
535 // Carbon windows can't have a size greater than 32767x32767
536 if (nWidth
>32767) nWidth
=32767;
537 if (nHeight
>32767) nHeight
=32767;
539 NSSize aSize
= { static_cast<CGFloat
>(nWidth
), static_cast<CGFloat
>(nHeight
) };
541 // Size of full window (content+structure) although we only
542 // have the client size in arguments
543 [mpWindow setMaxSize
: aSize
];
547 // -----------------------------------------------------------------------
549 void AquaSalFrame::SetClientSize( long nWidth
, long nHeight
)
551 // #i113170# may not be the main thread if called from UNO API
552 SalData::ensureThreadAutoreleasePool();
556 NSSize aSize
= { static_cast<CGFloat
>(nWidth
), static_cast<CGFloat
>(nHeight
) };
558 [mpWindow setContentSize
: aSize
];
559 UpdateFrameGeometry();
561 // trigger filling our backbuffer
566 // -----------------------------------------------------------------------
568 void AquaSalFrame::GetClientSize( long& rWidth
, long& rHeight
)
570 if( mbShown
|| mbInitShow
)
572 rWidth
= maGeometry
.nWidth
;
573 rHeight
= maGeometry
.nHeight
;
582 // -----------------------------------------------------------------------
584 void AquaSalFrame::SetWindowState( const SalFrameState
* pState
)
586 // #i113170# may not be the main thread if called from UNO API
587 SalData::ensureThreadAutoreleasePool();
592 NSRect aStateRect
= [mpWindow frame
];
593 aStateRect
= [NSWindow contentRectForFrameRect
: aStateRect styleMask
: mnStyleMask
];
594 CocoaToVCL( aStateRect
);
595 if( pState
->mnMask
& WINDOWSTATE_MASK_X
)
596 aStateRect
.origin
.x
= float(pState
->mnX
);
597 if( pState
->mnMask
& WINDOWSTATE_MASK_Y
)
598 aStateRect
.origin
.y
= float(pState
->mnY
);
599 if( pState
->mnMask
& WINDOWSTATE_MASK_WIDTH
)
600 aStateRect
.size
.width
= float(pState
->mnWidth
);
601 if( pState
->mnMask
& WINDOWSTATE_MASK_HEIGHT
)
602 aStateRect
.size
.height
= float(pState
->mnHeight
);
603 VCLToCocoa( aStateRect
);
604 aStateRect
= [NSWindow frameRectForContentRect
: aStateRect styleMask
: mnStyleMask
];
606 [mpWindow setFrame
: aStateRect display
: NO
];
607 if( pState
->mnState
== WINDOWSTATE_STATE_MINIMIZED
)
608 [mpWindow miniaturize
: NSApp
];
609 else if( [mpWindow isMiniaturized
] )
610 [mpWindow deminiaturize
: NSApp
];
613 /* ZOOMED is not really maximized (actually it toggles between a user set size and
614 the program specified one), but comes closest since the default behavior is
615 "maximized" if the user did not intervene
617 if( pState
->mnState
== WINDOWSTATE_STATE_MAXIMIZED
)
619 if(! [mpWindow isZoomed
])
620 [mpWindow zoom
: NSApp
];
624 if( [mpWindow isZoomed
] )
625 [mpWindow zoom
: NSApp
];
630 UpdateFrameGeometry();
632 sal_uInt16 nEvent
= 0;
633 if( pState
->mnMask
& (WINDOWSTATE_MASK_X
| WINDOWSTATE_MASK_Y
) )
636 nEvent
= SALEVENT_MOVE
;
639 if( pState
->mnMask
& (WINDOWSTATE_MASK_WIDTH
| WINDOWSTATE_MASK_HEIGHT
) )
642 nEvent
= (nEvent
== SALEVENT_MOVE
) ? SALEVENT_MOVERESIZE
: SALEVENT_RESIZE
;
644 // send event that we were moved/sized
646 CallCallback( nEvent
, NULL
);
648 if( mbShown
&& mpWindow
)
650 // trigger filling our backbuffer
653 // tell the system the views need to be updated
658 // -----------------------------------------------------------------------
660 sal_Bool
AquaSalFrame::GetWindowState( SalFrameState
* pState
)
665 // #i113170# may not be the main thread if called from UNO API
666 SalData::ensureThreadAutoreleasePool();
668 pState
->mnMask
= WINDOWSTATE_MASK_X
|
670 WINDOWSTATE_MASK_WIDTH
|
671 WINDOWSTATE_MASK_HEIGHT
|
672 WINDOWSTATE_MASK_STATE
;
674 NSRect aStateRect
= [mpWindow frame
];
675 aStateRect
= [NSWindow contentRectForFrameRect
: aStateRect styleMask
: mnStyleMask
];
676 CocoaToVCL( aStateRect
);
677 pState
->mnX
= long(aStateRect
.origin
.x
);
678 pState
->mnY
= long(aStateRect
.origin
.y
);
679 pState
->mnWidth
= long(aStateRect
.size
.width
);
680 pState
->mnHeight
= long(aStateRect
.size
.height
);
682 if( [mpWindow isMiniaturized
] )
683 pState
->mnState
= WINDOWSTATE_STATE_MINIMIZED
;
684 else if( ! [mpWindow isZoomed
] )
685 pState
->mnState
= WINDOWSTATE_STATE_NORMAL
;
687 pState
->mnState
= WINDOWSTATE_STATE_MAXIMIZED
;
692 // -----------------------------------------------------------------------
694 void AquaSalFrame::SetScreenNumber(unsigned int nScreen
)
699 // #i113170# may not be the main thread if called from UNO API
700 SalData::ensureThreadAutoreleasePool();
702 NSArray
* pScreens
= [NSScreen screens
];
704 NSScreen
* pScreen
= nil
;
705 if( pScreens
&& nScreen
< [pScreens count
] )
707 // get new screen frame
708 pScreen
= [pScreens objectAtIndex
: nScreen
];
709 NSRect aNewScreen
= [pScreen frame
];
711 // get current screen frame
712 pScreen
= [mpWindow screen
];
715 NSRect aCurScreen
= [pScreen frame
];
716 if( aCurScreen
.origin
.x
!= aNewScreen
.origin
.x
||
717 aCurScreen
.origin
.y
!= aNewScreen
.origin
.y
)
719 NSRect aFrameRect
= [mpWindow frame
];
720 aFrameRect
.origin
.x
+= aNewScreen
.origin
.x
- aCurScreen
.origin
.x
;
721 aFrameRect
.origin
.y
+= aNewScreen
.origin
.y
- aCurScreen
.origin
.y
;
722 [mpWindow setFrame
: aFrameRect display
: NO
];
723 UpdateFrameGeometry();
729 void AquaSalFrame::SetApplicationID( const OUString
&/*rApplicationID*/ )
733 // -----------------------------------------------------------------------
735 void AquaSalFrame::ShowFullScreen( sal_Bool bFullScreen
, sal_Int32 nDisplay
)
740 // #i113170# may not be the main thread if called from UNO API
741 SalData::ensureThreadAutoreleasePool();
743 SAL_INFO("vcl.macosx", OSL_THIS_FUNC
<< ": mbFullScreen=" << mbFullScreen
<< ", bFullScreen=" << bFullScreen
);
745 if( mbFullScreen
== bFullScreen
)
748 mbFullScreen
= bFullScreen
;
752 // hide the dock and the menubar if we are on the menu screen
753 // which is always on index 0 according to documentation
754 bool bHideMenu
= (nDisplay
== 0);
756 NSRect aNewContentRect
= { { 0, 0 }, { 0, 0 } };
757 // get correct screen
758 NSScreen
* pScreen
= nil
;
759 NSArray
* pScreens
= [NSScreen screens
];
762 if( nDisplay
>= 0 && (unsigned int)nDisplay
< [pScreens count
] )
763 pScreen
= [pScreens objectAtIndex
: nDisplay
];
766 // this means span all screens
768 NSEnumerator
* pEnum
= [pScreens objectEnumerator
];
769 while( (pScreen
= [pEnum nextObject
]) != nil
)
771 NSRect aScreenRect
= [pScreen frame
];
772 if( aScreenRect
.origin
.x
< aNewContentRect
.origin
.x
)
774 aNewContentRect
.size
.width
+= aNewContentRect
.origin
.x
- aScreenRect
.origin
.x
;
775 aNewContentRect
.origin
.x
= aScreenRect
.origin
.x
;
777 if( aScreenRect
.origin
.y
< aNewContentRect
.origin
.y
)
779 aNewContentRect
.size
.height
+= aNewContentRect
.origin
.y
- aScreenRect
.origin
.y
;
780 aNewContentRect
.origin
.y
= aScreenRect
.origin
.y
;
782 if( aScreenRect
.origin
.x
+ aScreenRect
.size
.width
> aNewContentRect
.origin
.x
+ aNewContentRect
.size
.width
)
783 aNewContentRect
.size
.width
= aScreenRect
.origin
.x
+ aScreenRect
.size
.width
- aNewContentRect
.origin
.x
;
784 if( aScreenRect
.origin
.y
+ aScreenRect
.size
.height
> aNewContentRect
.origin
.y
+ aNewContentRect
.size
.height
)
785 aNewContentRect
.size
.height
= aScreenRect
.origin
.y
+ aScreenRect
.size
.height
- aNewContentRect
.origin
.y
;
789 if( aNewContentRect
.size
.width
== 0 && aNewContentRect
.size
.height
== 0 )
792 pScreen
= [mpWindow screen
];
794 pScreen
= [NSScreen mainScreen
];
796 aNewContentRect
= [pScreen frame
];
800 [NSMenu setMenuBarVisible
:NO
];
802 maFullScreenRect
= [mpWindow frame
];
804 [mpWindow setFrame
: [NSWindow frameRectForContentRect
: aNewContentRect styleMask
: mnStyleMask
] display
: mbShown
? YES
: NO
];
807 UpdateFrameGeometry();
810 CallCallback( SALEVENT_MOVERESIZE
, NULL
);
815 [mpWindow setFrame
: maFullScreenRect display
: mbShown
? YES
: NO
];
817 UpdateFrameGeometry();
820 CallCallback( SALEVENT_MOVERESIZE
, NULL
);
822 // show the dock and the menubar
823 [NSMenu setMenuBarVisible
:YES
];
826 // trigger filling our backbuffer
830 // -----------------------------------------------------------------------
832 void AquaSalFrame::StartPresentation( sal_Bool bStart
)
837 // #i113170# may not be the main thread if called from UNO API
838 SalData::ensureThreadAutoreleasePool();
842 GetSalData()->maPresentationFrames
.push_back( this );
843 IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep
,
844 kIOPMAssertionLevelOn
,
845 CFSTR("LibreOffice presentation running"),
847 [mpWindow setLevel
: NSPopUpMenuWindowLevel
];
849 [mpWindow makeMainWindow
];
853 GetSalData()->maPresentationFrames
.remove( this );
854 IOPMAssertionRelease(mnAssertionID
);
855 [mpWindow setLevel
: NSNormalWindowLevel
];
859 // -----------------------------------------------------------------------
861 void AquaSalFrame::SetAlwaysOnTop( sal_Bool
)
865 // -----------------------------------------------------------------------
867 void AquaSalFrame::ToTop(sal_uInt16 nFlags
)
872 // #i113170# may not be the main thread if called from UNO API
873 SalData::ensureThreadAutoreleasePool();
875 if( ! (nFlags
& SAL_FRAME_TOTOP_RESTOREWHENMIN
) )
877 if( ! [mpWindow isVisible
] || [mpWindow isMiniaturized
] )
880 if( nFlags
& SAL_FRAME_TOTOP_GRABFOCUS
)
881 [mpWindow makeKeyAndOrderFront
: NSApp
];
883 [mpWindow orderFront
: NSApp
];
886 // -----------------------------------------------------------------------
888 NSCursor
* AquaSalFrame::getCurrentCursor() const
890 NSCursor
* pCursor
= nil
;
891 switch( mePointerStyle
)
893 case POINTER_TEXT
: pCursor
= [NSCursor IBeamCursor
]; break;
894 case POINTER_CROSS
: pCursor
= [NSCursor crosshairCursor
]; break;
896 case POINTER_MOVE
: pCursor
= [NSCursor openHandCursor
]; break;
897 case POINTER_NSIZE
: pCursor
= [NSCursor resizeUpCursor
]; break;
898 case POINTER_SSIZE
: pCursor
= [NSCursor resizeDownCursor
]; break;
899 case POINTER_ESIZE
: pCursor
= [NSCursor resizeRightCursor
]; break;
900 case POINTER_WSIZE
: pCursor
= [NSCursor resizeLeftCursor
]; break;
901 case POINTER_ARROW
: pCursor
= [NSCursor arrowCursor
]; break;
903 case POINTER_VSIZEBAR
:
904 case POINTER_WINDOW_NSIZE
:
905 case POINTER_WINDOW_SSIZE
:
906 pCursor
= [NSCursor resizeUpDownCursor
]; break;
908 case POINTER_HSIZEBAR
:
909 case POINTER_WINDOW_ESIZE
:
910 case POINTER_WINDOW_WSIZE
:
911 pCursor
= [NSCursor resizeLeftRightCursor
]; break;
912 case POINTER_REFHAND
: pCursor
= [NSCursor pointingHandCursor
]; break;
913 case POINTER_NULL
: [NSCursor hide
]; break;
916 pCursor
= GetSalData()->getCursor( mePointerStyle
);
919 OSL_FAIL( "unmapped cursor" );
920 pCursor
= [NSCursor arrowCursor
];
927 void AquaSalFrame::SetPointer( PointerStyle ePointerStyle
)
932 // #i113170# may not be the main thread if called from UNO API
933 SalData::ensureThreadAutoreleasePool();
935 if( ePointerStyle
>= POINTER_COUNT
|| ePointerStyle
== mePointerStyle
)
937 mePointerStyle
= ePointerStyle
;
939 [mpWindow invalidateCursorRectsForView
: mpView
];
942 // -----------------------------------------------------------------------
944 void AquaSalFrame::SetPointerPos( long nX
, long nY
)
946 // FIXME: use Cocoa functions
948 // FIXME: multiscreen support
949 CGPoint aPoint
= { static_cast<CGFloat
>(nX
+ maGeometry
.nX
), static_cast<CGFloat
>(nY
+ maGeometry
.nY
) };
950 CGDirectDisplayID mainDisplayID
= CGMainDisplayID();
951 CGDisplayMoveCursorToPoint( mainDisplayID
, aPoint
);
954 // -----------------------------------------------------------------------
956 void AquaSalFrame::Flush( void )
958 if( !(mbGraphics
&& mpGraphics
&& mpView
&& mbShown
) )
961 // #i113170# may not be the main thread if called from UNO API
962 SalData::ensureThreadAutoreleasePool();
965 [mpView setNeedsDisplay
: YES
];
967 // outside of the application's event loop (e.g. IntroWindow)
968 // nothing would trigger paint event handling
969 // => fall back to synchronous painting
970 if( ImplGetSVData()->maAppData
.mnDispatchLevel
<= 0 )
976 // -----------------------------------------------------------------------
978 void AquaSalFrame::Flush( const Rectangle
& rRect
)
980 if( !(mbGraphics
&& mpGraphics
&& mpView
&& mbShown
) )
983 // #i113170# may not be the main thread if called from UNO API
984 SalData::ensureThreadAutoreleasePool();
986 NSRect aNSRect
= { { static_cast<CGFloat
>(rRect
.Left()), static_cast<CGFloat
>(rRect
.Top()) }, { static_cast<CGFloat
>(rRect
.GetWidth()), static_cast<CGFloat
>(rRect
.GetHeight()) } };
987 VCLToCocoa( aNSRect
, false );
988 [mpView setNeedsDisplayInRect
: aNSRect
];
990 // outside of the application's event loop (e.g. IntroWindow)
991 // nothing would trigger paint event handling
992 // => fall back to synchronous painting
993 if( ImplGetSVData()->maAppData
.mnDispatchLevel
<= 0 )
999 // -----------------------------------------------------------------------
1001 void AquaSalFrame::Sync()
1003 if( mbGraphics
&& mpGraphics
&& mpView
&& mbShown
)
1005 // #i113170# may not be the main thread if called from UNO API
1006 SalData::ensureThreadAutoreleasePool();
1008 [mpView setNeedsDisplay
: YES
];
1013 // -----------------------------------------------------------------------
1015 void AquaSalFrame::SetInputContext( SalInputContext
* pContext
)
1023 mnICOptions
= pContext
->mnOptions
;
1025 if(!(pContext
->mnOptions
& SAL_INPUTCONTEXT_TEXT
))
1029 // -----------------------------------------------------------------------
1031 void AquaSalFrame::EndExtTextInput( sal_uInt16
)
1035 // -----------------------------------------------------------------------
1037 OUString
AquaSalFrame::GetKeyName( sal_uInt16 nKeyCode
)
1039 static std::map
< sal_uInt16
, OUString
> aKeyMap
;
1040 if( aKeyMap
.empty() )
1043 for( i
= KEY_A
; i
<= KEY_Z
; i
++ )
1044 aKeyMap
[ i
] = OUString( sal_Unicode( 'A' + (i
- KEY_A
) ) );
1045 for( i
= KEY_0
; i
<= KEY_9
; i
++ )
1046 aKeyMap
[ i
] = OUString( sal_Unicode( '0' + (i
- KEY_0
) ) );
1047 for( i
= KEY_F1
; i
<= KEY_F26
; i
++ )
1049 OUStringBuffer
aKey( 3 );
1051 aKey
.append( sal_Int32( i
- KEY_F1
+ 1 ) );
1052 aKeyMap
[ i
] = aKey
.makeStringAndClear();
1055 aKeyMap
[ KEY_DOWN
] = OUString( sal_Unicode( 0x21e3 ) );
1056 aKeyMap
[ KEY_UP
] = OUString( sal_Unicode( 0x21e1 ) );
1057 aKeyMap
[ KEY_LEFT
] = OUString( sal_Unicode( 0x21e0 ) );
1058 aKeyMap
[ KEY_RIGHT
] = OUString( sal_Unicode( 0x21e2 ) );
1059 aKeyMap
[ KEY_HOME
] = OUString( sal_Unicode( 0x2196 ) );
1060 aKeyMap
[ KEY_END
] = OUString( sal_Unicode( 0x2198 ) );
1061 aKeyMap
[ KEY_PAGEUP
] = OUString( sal_Unicode( 0x21de ) );
1062 aKeyMap
[ KEY_PAGEDOWN
] = OUString( sal_Unicode( 0x21df ) );
1063 aKeyMap
[ KEY_RETURN
] = OUString( sal_Unicode( 0x21a9 ) );
1064 aKeyMap
[ KEY_ESCAPE
] = OUString( "esc" );
1065 aKeyMap
[ KEY_TAB
] = OUString( sal_Unicode( 0x21e5 ) );
1066 aKeyMap
[ KEY_BACKSPACE
]= OUString( sal_Unicode( 0x232b ) );
1067 aKeyMap
[ KEY_SPACE
] = OUString( sal_Unicode( 0x2423 ) );
1068 aKeyMap
[ KEY_DELETE
] = OUString( sal_Unicode( 0x2326 ) );
1069 aKeyMap
[ KEY_ADD
] = OUString( '+' );
1070 aKeyMap
[ KEY_SUBTRACT
] = OUString( '-' );
1071 aKeyMap
[ KEY_DIVIDE
] = OUString( '/' );
1072 aKeyMap
[ KEY_MULTIPLY
] = OUString( '*' );
1073 aKeyMap
[ KEY_POINT
] = OUString( '.' );
1074 aKeyMap
[ KEY_COMMA
] = OUString( ',' );
1075 aKeyMap
[ KEY_LESS
] = OUString( '<' );
1076 aKeyMap
[ KEY_GREATER
] = OUString( '>' );
1077 aKeyMap
[ KEY_EQUAL
] = OUString( '=' );
1078 aKeyMap
[ KEY_OPEN
] = OUString( sal_Unicode( 0x23cf ) );
1080 /* yet unmapped KEYCODES:
1081 aKeyMap[ KEY_INSERT ] = OUString( sal_Unicode( ) );
1082 aKeyMap[ KEY_CUT ] = OUString( sal_Unicode( ) );
1083 aKeyMap[ KEY_COPY ] = OUString( sal_Unicode( ) );
1084 aKeyMap[ KEY_PASTE ] = OUString( sal_Unicode( ) );
1085 aKeyMap[ KEY_UNDO ] = OUString( sal_Unicode( ) );
1086 aKeyMap[ KEY_REPEAT ] = OUString( sal_Unicode( ) );
1087 aKeyMap[ KEY_FIND ] = OUString( sal_Unicode( ) );
1088 aKeyMap[ KEY_PROPERTIES ] = OUString( sal_Unicode( ) );
1089 aKeyMap[ KEY_FRONT ] = OUString( sal_Unicode( ) );
1090 aKeyMap[ KEY_CONTEXTMENU ] = OUString( sal_Unicode( ) );
1091 aKeyMap[ KEY_MENU ] = OUString( sal_Unicode( ) );
1092 aKeyMap[ KEY_HELP ] = OUString( sal_Unicode( ) );
1093 aKeyMap[ KEY_HANGUL_HANJA ] = OUString( sal_Unicode( ) );
1094 aKeyMap[ KEY_DECIMAL ] = OUString( sal_Unicode( ) );
1095 aKeyMap[ KEY_TILDE ] = OUString( sal_Unicode( ) );
1096 aKeyMap[ KEY_QUOTELEFT ]= OUString( sal_Unicode( ) );
1101 OUStringBuffer
aResult( 16 );
1103 sal_uInt16 nUnmodifiedCode
= (nKeyCode
& KEY_CODE
);
1104 std::map
< sal_uInt16
, OUString
>::const_iterator it
= aKeyMap
.find( nUnmodifiedCode
);
1105 if( it
!= aKeyMap
.end() )
1107 if( (nKeyCode
& KEY_SHIFT
) != 0 )
1108 aResult
.append( sal_Unicode( 0x21e7 ) );
1109 if( (nKeyCode
& KEY_MOD1
) != 0 )
1110 aResult
.append( sal_Unicode( 0x2318 ) );
1111 // we do not really handle Alt (see below)
1112 // we map it to MOD3, whichis actually Command
1113 if( (nKeyCode
& (KEY_MOD2
|KEY_MOD3
)) != 0 )
1114 aResult
.append( sal_Unicode( 0x2303 ) );
1116 aResult
.append( it
->second
);
1119 return aResult
.makeStringAndClear();
1122 // -----------------------------------------------------------------------
1124 static void getAppleScrollBarVariant(StyleSettings
&rSettings
)
1126 bool bIsScrollbarDoubleMax
= true; // default is DoubleMax
1128 CFStringRef AppleScrollBarType
= CFSTR("AppleScrollBarVariant");
1129 if( AppleScrollBarType
)
1131 CFStringRef ScrollBarVariant
= ((CFStringRef
)CFPreferencesCopyAppValue( AppleScrollBarType
, kCFPreferencesCurrentApplication
));
1132 if( ScrollBarVariant
)
1134 if( CFGetTypeID( ScrollBarVariant
) == CFStringGetTypeID() )
1136 // TODO: check for the less important variants "DoubleMin" and "DoubleBoth" too
1137 CFStringRef DoubleMax
= CFSTR("DoubleMax");
1140 if ( !CFStringCompare(ScrollBarVariant
, DoubleMax
, kCFCompareCaseInsensitive
) )
1141 bIsScrollbarDoubleMax
= true;
1143 bIsScrollbarDoubleMax
= false;
1144 CFRelease(DoubleMax
);
1147 CFRelease( ScrollBarVariant
);
1149 CFRelease(AppleScrollBarType
);
1152 GetSalData()->mbIsScrollbarDoubleMax
= bIsScrollbarDoubleMax
;
1154 CFStringRef jumpScroll
= CFSTR("AppleScrollerPagingBehavior");
1157 CFBooleanRef jumpStr
= ((CFBooleanRef
)CFPreferencesCopyAppValue( jumpScroll
, kCFPreferencesCurrentApplication
));
1160 if( CFGetTypeID( jumpStr
) == CFBooleanGetTypeID() )
1161 rSettings
.SetPrimaryButtonWarpsSlider(jumpStr
== kCFBooleanTrue
);
1162 CFRelease( jumpStr
);
1164 CFRelease( jumpScroll
);
1168 static Color
getColor( NSColor
* pSysColor
, const Color
& rDefault
, NSWindow
* pWin
)
1170 Color
aRet( rDefault
);
1174 NSColor
* pRBGColor
= [pSysColor colorUsingColorSpaceName
: NSDeviceRGBColorSpace device
: [pWin deviceDescription
]];
1177 CGFloat r
= 0, g
= 0, b
= 0, a
= 0;
1178 [pRBGColor getRed
: &r green
: &g blue
: &b alpha
: &a
];
1179 aRet
= Color( int(r
*255.999), int(g
*255.999), int(b
*255.999) );
1181 do not release here; leads to duplicate free in yield
1182 it seems the converted color comes out autoreleased, although this
1184 [pRBGColor release];
1191 static Font
getFont( NSFont
* pFont
, long nDPIY
, const Font
& rDefault
)
1193 Font
aResult( rDefault
);
1196 aResult
.SetName( GetOUString( [pFont familyName
] ) );
1197 aResult
.SetHeight( static_cast<int>(([pFont pointSize
] * 72.0 / (float)nDPIY
)+0.5) );
1198 aResult
.SetItalic( ([pFont italicAngle
] != 0.0) ? ITALIC_NORMAL
: ITALIC_NONE
);
1205 void AquaSalFrame::getResolution( sal_Int32
& o_rDPIX
, sal_Int32
& o_rDPIY
)
1210 ReleaseGraphics( mpGraphics
);
1212 mpGraphics
->GetResolution( o_rDPIX
, o_rDPIY
);
1215 // on OSX-Aqua the style settings are independent of the frame, so it does
1216 // not really belong here. Since the connection to the Appearance_Manager
1217 // is currently done in salnativewidgets.cxx this would be a good place.
1218 // On the other hand VCL's platform independent code currently only asks
1219 // SalFrames for system settings anyway, so moving the code somewhere else
1220 // doesn't make the anything cleaner for now
1221 void AquaSalFrame::UpdateSettings( AllSettings
& rSettings
)
1226 // #i113170# may not be the main thread if called from UNO API
1227 SalData::ensureThreadAutoreleasePool();
1231 StyleSettings aStyleSettings
= rSettings
.GetStyleSettings();
1234 Color aBackgroundColor
= Color( 0xEC, 0xEC, 0xEC );
1235 aStyleSettings
.Set3DColors( aBackgroundColor
);
1236 aStyleSettings
.SetFaceColor( aBackgroundColor
);
1237 Color
aInactiveTabColor( aBackgroundColor
);
1238 aInactiveTabColor
.DecreaseLuminance( 32 );
1239 aStyleSettings
.SetInactiveTabColor( aInactiveTabColor
);
1241 aStyleSettings
.SetDialogColor( aBackgroundColor
);
1242 aStyleSettings
.SetLightBorderColor( aBackgroundColor
);
1243 Color
aShadowColor( aStyleSettings
.GetShadowColor() );
1244 aShadowColor
.IncreaseLuminance( 32 );
1245 aStyleSettings
.SetShadowColor( aShadowColor
);
1247 // get the system font settings
1248 Font aAppFont
= aStyleSettings
.GetAppFont();
1249 sal_Int32 nDPIX
= 72, nDPIY
= 72;
1250 getResolution( nDPIX
, nDPIY
);
1251 aAppFont
= getFont( [NSFont systemFontOfSize
: 0], nDPIY
, aAppFont
);
1253 aStyleSettings
.SetToolbarIconSize( STYLE_TOOLBAR_ICONSIZE_LARGE
);
1255 // TODO: better mapping of aqua<->ooo font settings
1256 aStyleSettings
.SetAppFont( aAppFont
);
1257 aStyleSettings
.SetHelpFont( aAppFont
);
1258 aStyleSettings
.SetPushButtonFont( aAppFont
);
1260 Font
aTitleFont( getFont( [NSFont titleBarFontOfSize
: 0], nDPIY
, aAppFont
) );
1261 aStyleSettings
.SetTitleFont( aTitleFont
);
1262 aStyleSettings
.SetFloatTitleFont( aTitleFont
);
1264 Font
aMenuFont( getFont( [NSFont menuFontOfSize
: 0], nDPIY
, aAppFont
) );
1265 aStyleSettings
.SetMenuFont( aMenuFont
);
1267 aStyleSettings
.SetToolFont( aAppFont
);
1269 Font
aLabelFont( getFont( [NSFont labelFontOfSize
: 0], nDPIY
, aAppFont
) );
1270 aStyleSettings
.SetLabelFont( aLabelFont
);
1271 aStyleSettings
.SetInfoFont( aLabelFont
);
1272 aStyleSettings
.SetRadioCheckFont( aLabelFont
);
1273 aStyleSettings
.SetFieldFont( aLabelFont
);
1274 aStyleSettings
.SetGroupFont( aLabelFont
);
1275 aStyleSettings
.SetIconFont( aLabelFont
);
1277 Color
aHighlightColor( getColor( [NSColor selectedTextBackgroundColor
],
1278 aStyleSettings
.GetHighlightColor(), mpWindow
) );
1279 aStyleSettings
.SetHighlightColor( aHighlightColor
);
1280 Color
aHighlightTextColor( getColor( [NSColor selectedTextColor
],
1281 aStyleSettings
.GetHighlightTextColor(), mpWindow
) );
1282 aStyleSettings
.SetHighlightTextColor( aHighlightTextColor
);
1284 Color
aMenuHighlightColor( getColor( [NSColor selectedMenuItemColor
],
1285 aStyleSettings
.GetMenuHighlightColor(), mpWindow
) );
1286 aStyleSettings
.SetMenuHighlightColor( aMenuHighlightColor
);
1287 Color
aMenuHighlightTextColor( getColor( [NSColor selectedMenuItemTextColor
],
1288 aStyleSettings
.GetMenuHighlightTextColor(), mpWindow
) );
1289 aStyleSettings
.SetMenuHighlightTextColor( aMenuHighlightTextColor
);
1291 aStyleSettings
.SetMenuColor( aBackgroundColor
);
1292 Color
aMenuTextColor( getColor( [NSColor textColor
],
1293 aStyleSettings
.GetMenuTextColor(), mpWindow
) );
1294 aStyleSettings
.SetMenuTextColor( aMenuTextColor
);
1295 aStyleSettings
.SetMenuBarTextColor( aMenuTextColor
);
1296 aStyleSettings
.SetMenuBarRolloverTextColor( aMenuTextColor
);
1298 aStyleSettings
.SetCursorBlinkTime( 500 );
1300 // no mnemonics on aqua
1301 aStyleSettings
.SetOptions( aStyleSettings
.GetOptions() | STYLE_OPTION_NOMNEMONICS
);
1303 getAppleScrollBarVariant(aStyleSettings
);
1305 // set scrollbar size
1306 aStyleSettings
.SetScrollBarSize( static_cast<long int>([NSScroller scrollerWidth
]) );
1308 // images in menus false for MacOSX
1309 aStyleSettings
.SetPreferredUseImagesInMenus( false );
1310 aStyleSettings
.SetHideDisabledMenuItems( sal_True
);
1311 aStyleSettings
.SetAcceleratorsInContextMenus( sal_False
);
1313 rSettings
.SetStyleSettings( aStyleSettings
);
1315 [mpView unlockFocus
];
1318 // -----------------------------------------------------------------------
1320 const SystemEnvData
* AquaSalFrame::GetSystemData() const
1325 // -----------------------------------------------------------------------
1327 void AquaSalFrame::Beep()
1332 // -----------------------------------------------------------------------
1334 void AquaSalFrame::SetPosSize(long nX
, long nY
, long nWidth
, long nHeight
, sal_uInt16 nFlags
)
1339 // #i113170# may not be the main thread if called from UNO API
1340 SalData::ensureThreadAutoreleasePool();
1342 sal_uInt16 nEvent
= 0;
1344 if( [mpWindow isMiniaturized
] )
1345 [mpWindow deminiaturize
: NSApp
]; // expand the window
1347 if (nFlags
& (SAL_FRAME_POSSIZE_X
| SAL_FRAME_POSSIZE_Y
))
1349 mbPositioned
= true;
1350 nEvent
= SALEVENT_MOVE
;
1353 if (nFlags
& (SAL_FRAME_POSSIZE_WIDTH
| SAL_FRAME_POSSIZE_HEIGHT
))
1356 nEvent
= (nEvent
== SALEVENT_MOVE
) ? SALEVENT_MOVERESIZE
: SALEVENT_RESIZE
;
1359 NSRect aFrameRect
= [mpWindow frame
];
1360 NSRect aContentRect
= [NSWindow contentRectForFrameRect
: aFrameRect styleMask
: mnStyleMask
];
1362 // position is always relative to parent frame
1363 NSRect aParentContentRect
;
1367 if( Application::GetSettings().GetLayoutRTL() )
1369 if( (nFlags
& SAL_FRAME_POSSIZE_WIDTH
) != 0 )
1370 nX
= mpParent
->maGeometry
.nWidth
- nWidth
-1 - nX
;
1372 nX
= mpParent
->maGeometry
.nWidth
- static_cast<long int>( aContentRect
.size
.width
-1) - nX
;
1374 NSRect aParentFrameRect
= [mpParent
->mpWindow frame
];
1375 aParentContentRect
= [NSWindow contentRectForFrameRect
: aParentFrameRect styleMask
: mpParent
->mnStyleMask
];
1378 aParentContentRect
= maScreenRect
; // use screen if no parent
1380 CocoaToVCL( aContentRect
);
1381 CocoaToVCL( aParentContentRect
);
1383 bool bPaint
= false;
1384 if( (nFlags
& (SAL_FRAME_POSSIZE_WIDTH
| SAL_FRAME_POSSIZE_HEIGHT
)) != 0 )
1386 if( nWidth
!= aContentRect
.size
.width
|| nHeight
!= aContentRect
.size
.height
)
1390 // use old window pos if no new pos requested
1391 if( (nFlags
& SAL_FRAME_POSSIZE_X
) != 0 )
1392 aContentRect
.origin
.x
= nX
+ aParentContentRect
.origin
.x
;
1393 if( (nFlags
& SAL_FRAME_POSSIZE_Y
) != 0)
1394 aContentRect
.origin
.y
= nY
+ aParentContentRect
.origin
.y
;
1396 // use old size if no new size requested
1397 if( (nFlags
& SAL_FRAME_POSSIZE_WIDTH
) != 0 )
1398 aContentRect
.size
.width
= nWidth
;
1399 if( (nFlags
& SAL_FRAME_POSSIZE_HEIGHT
) != 0)
1400 aContentRect
.size
.height
= nHeight
;
1402 VCLToCocoa( aContentRect
);
1404 // do not display yet, we need to update our backbuffer
1406 [mpWindow setFrame
: [NSWindow frameRectForContentRect
: aContentRect styleMask
: mnStyleMask
] display
: NO
];
1409 UpdateFrameGeometry();
1412 CallCallback(nEvent
, NULL
);
1414 if( mbShown
&& bPaint
)
1416 // trigger filling our backbuffer
1419 // now inform the system that the views need to be drawn
1424 void AquaSalFrame::GetWorkArea( Rectangle
& rRect
)
1429 // #i113170# may not be the main thread if called from UNO API
1430 SalData::ensureThreadAutoreleasePool();
1432 NSScreen
* pScreen
= [mpWindow screen
];
1433 if( pScreen
== nil
)
1434 pScreen
= [NSScreen mainScreen
];
1435 NSRect aRect
= [pScreen visibleFrame
];
1436 CocoaToVCL( aRect
);
1437 rRect
.Left() = static_cast<long>(aRect
.origin
.x
);
1438 rRect
.Top() = static_cast<long>(aRect
.origin
.y
);
1439 rRect
.Right() = static_cast<long>(aRect
.origin
.x
+ aRect
.size
.width
- 1);
1440 rRect
.Bottom() = static_cast<long>(aRect
.origin
.y
+ aRect
.size
.height
- 1);
1443 SalPointerState
AquaSalFrame::GetPointerState()
1445 // #i113170# may not be the main thread if called from UNO API
1446 SalData::ensureThreadAutoreleasePool();
1448 SalPointerState state
;
1452 NSPoint aPt
= [mpWindow mouseLocationOutsideOfEventStream
];
1453 CocoaToVCL( aPt
, false );
1454 state
.maPos
= Point(static_cast<long>(aPt
.x
), static_cast<long>(aPt
.y
));
1456 NSEvent
* pCur
= [NSApp currentEvent
];
1457 bool bMouseEvent
= false;
1461 switch( [pCur type
] )
1463 case NSLeftMouseDown
: state
.mnState
|= MOUSE_LEFT
; break;
1464 case NSLeftMouseUp
: break;
1465 case NSRightMouseDown
: state
.mnState
|= MOUSE_RIGHT
; break;
1466 case NSRightMouseUp
: break;
1467 case NSOtherMouseDown
: state
.mnState
|= ([pCur buttonNumber
] == 2) ? MOUSE_MIDDLE
: 0; break;
1468 case NSOtherMouseUp
: break;
1469 case NSMouseMoved
: break;
1470 case NSLeftMouseDragged
: state
.mnState
|= MOUSE_LEFT
; break;
1471 case NSRightMouseDragged
: state
.mnState
|= MOUSE_RIGHT
; break;
1472 case NSOtherMouseDragged
: state
.mnState
|= ([pCur buttonNumber
] == 2) ? MOUSE_MIDDLE
: 0; break;
1475 bMouseEvent
= false;
1481 unsigned int nMask
= (unsigned int)[pCur modifierFlags
];
1482 if( (nMask
& NSShiftKeyMask
) != 0 )
1483 state
.mnState
|= KEY_SHIFT
;
1484 if( (nMask
& NSControlKeyMask
) != 0 )
1485 state
.mnState
|= KEY_MOD3
;
1486 if( (nMask
& NSAlternateKeyMask
) != 0 )
1487 state
.mnState
|= KEY_MOD2
;
1488 if( (nMask
& NSCommandKeyMask
) != 0 )
1489 state
.mnState
|= KEY_MOD1
;
1494 // FIXME: replace Carbon by Cocoa
1495 // Cocoa does not have an equivalent for GetCurrentEventButtonState
1496 // and GetCurrentEventKeyModifiers.
1497 // we could try to get away with tracking all events for modifierKeys
1498 // and all mouse events for button state in VCL_NSApllication::sendEvent,
1499 // but it is unclear whether this will get us the same result.
1500 // leave in GetCurrentEventButtonState and GetCurrentEventKeyModifiers for now
1502 // fill in button state
1503 UInt32 nState
= GetCurrentEventButtonState();
1506 state
.mnState
|= MOUSE_LEFT
; // primary button
1508 state
.mnState
|= MOUSE_RIGHT
; // secondary button
1510 state
.mnState
|= MOUSE_MIDDLE
; // tertiary button
1512 // fill in modifier state
1513 nState
= GetCurrentEventKeyModifiers();
1514 if( nState
& shiftKey
)
1515 state
.mnState
|= KEY_SHIFT
;
1516 if( nState
& controlKey
)
1517 state
.mnState
|= KEY_MOD3
;
1518 if( nState
& optionKey
)
1519 state
.mnState
|= KEY_MOD2
;
1520 if( nState
& cmdKey
)
1521 state
.mnState
|= KEY_MOD1
;
1528 SalFrame::SalIndicatorState
AquaSalFrame::GetIndicatorState()
1530 SalIndicatorState aState
;
1535 void AquaSalFrame::SimulateKeyPress( sal_uInt16
/*nKeyCode*/ )
1539 bool AquaSalFrame::SetPluginParent( SystemParentData
* )
1541 // plugin parent may be killed unexpectedly by
1542 // plugging process;
1548 sal_Bool
AquaSalFrame::MapUnicodeToKeyCode( sal_Unicode
, LanguageType
, KeyCode
& )
1550 // not supported yet
1554 LanguageType
AquaSalFrame::GetInputLanguage()
1557 return LANGUAGE_DONTKNOW
;
1560 void AquaSalFrame::DrawMenuBar()
1564 void AquaSalFrame::SetMenu( SalMenu
* pSalMenu
)
1566 // #i113170# may not be the main thread if called from UNO API
1567 SalData::ensureThreadAutoreleasePool();
1569 AquaSalMenu
* pMenu
= static_cast<AquaSalMenu
*>(pSalMenu
);
1570 DBG_ASSERT( ! pMenu
|| pMenu
->mbMenuBar
, "setting non menubar on frame" );
1573 mpMenu
->setMainMenu();
1576 void AquaSalFrame::SetExtendedFrameStyle( SalExtStyle nStyle
)
1580 // #i113170# may not be the main thread if called from UNO API
1581 SalData::ensureThreadAutoreleasePool();
1583 if( (mnExtStyle
& SAL_FRAME_EXT_STYLE_DOCMODIFIED
) != (nStyle
& SAL_FRAME_EXT_STYLE_DOCMODIFIED
) )
1584 [mpWindow setDocumentEdited
: (nStyle
& SAL_FRAME_EXT_STYLE_DOCMODIFIED
) ? YES
: NO
];
1587 mnExtStyle
= nStyle
;
1590 SalFrame
* AquaSalFrame::GetParent() const
1595 void AquaSalFrame::SetParent( SalFrame
* pNewParent
)
1597 bool bShown
= mbShown
;
1598 // remove from child list
1600 mpParent
= (AquaSalFrame
*)pNewParent
;
1601 // insert to correct parent and paint
1605 void AquaSalFrame::UpdateFrameGeometry()
1612 // keep in mind that view and window coordinates are lower left
1613 // whereas vcl's are upper left
1615 // update screen rect
1616 NSScreen
* pScreen
= [mpWindow screen
];
1619 maScreenRect
= [pScreen frame
];
1620 NSArray
* pScreens
= [NSScreen screens
];
1622 maGeometry
.nDisplayScreenNumber
= [pScreens indexOfObject
: pScreen
];
1625 NSRect aFrameRect
= [mpWindow frame
];
1626 NSRect aContentRect
= [NSWindow contentRectForFrameRect
: aFrameRect styleMask
: mnStyleMask
];
1628 // release old track rect
1629 [mpView removeTrackingRect
: mnTrackingRectTag
];
1630 // install the new track rect
1631 NSRect aTrackRect
= { { 0, 0 }, aContentRect
.size
};
1632 mnTrackingRectTag
= [mpView addTrackingRect
: aTrackRect owner
: mpView userData
: nil assumeInside
: NO
];
1634 // convert to vcl convention
1635 CocoaToVCL( aFrameRect
);
1636 CocoaToVCL( aContentRect
);
1638 maGeometry
.nX
= static_cast<int>(aContentRect
.origin
.x
);
1639 maGeometry
.nY
= static_cast<int>(aContentRect
.origin
.y
);
1641 maGeometry
.nLeftDecoration
= static_cast<unsigned int>(aContentRect
.origin
.x
- aFrameRect
.origin
.x
);
1642 maGeometry
.nRightDecoration
= static_cast<unsigned int>((aFrameRect
.origin
.x
+ aFrameRect
.size
.width
) -
1643 (aContentRect
.origin
.x
+ aContentRect
.size
.width
));
1645 maGeometry
.nTopDecoration
= static_cast<unsigned int>(aContentRect
.origin
.y
- aFrameRect
.origin
.y
);
1646 maGeometry
.nBottomDecoration
= static_cast<unsigned int>((aFrameRect
.origin
.y
+ aFrameRect
.size
.height
) -
1647 (aContentRect
.origin
.y
+ aContentRect
.size
.height
));
1649 maGeometry
.nWidth
= static_cast<unsigned int>(aContentRect
.size
.width
);
1650 maGeometry
.nHeight
= static_cast<unsigned int>(aContentRect
.size
.height
);
1653 // -----------------------------------------------------------------------
1655 void AquaSalFrame::CaptureMouse( sal_Bool bCapture
)
1658 we'll try to use a pidgin version of capture mouse
1659 on MacOSX (neither carbon nor cocoa) there is a
1660 CaptureMouse equivalent (in Carbon there is TrackMouseLocation
1661 but this is useless to use since it is blocking)
1663 However on cocoa the active frame seems to get mouse events
1664 also outside the window, so we'll try to forward mouse events
1665 to the capture frame in the hope that one of our frames
1668 This will break as soon as the user activates another app, but
1669 a mouse click will normally lead to a release of the mouse anyway.
1671 Let's see how far we get this way. Alternatively we could use one
1672 large overlay window like we did for the carbon implementation,
1673 however that is resource intensive.
1677 s_pCaptureFrame
= this;
1678 else if( ! bCapture
&& s_pCaptureFrame
== this )
1679 s_pCaptureFrame
= NULL
;
1682 void AquaSalFrame::ResetClipRegion()
1689 // #i113170# may not be the main thread if called from UNO API
1690 SalData::ensureThreadAutoreleasePool();
1692 // release old path and indicate no clipping
1693 CGPathRelease( mrClippingPath
);
1694 mrClippingPath
= NULL
;
1696 if( mpView
&& mbShown
)
1697 [mpView setNeedsDisplay
: YES
];
1700 [mpWindow setOpaque
: YES
];
1701 [mpWindow invalidateShadow
];
1705 void AquaSalFrame::BeginSetClipRegion( sal_uLong nRects
)
1712 // #i113170# may not be the main thread if called from UNO API
1713 SalData::ensureThreadAutoreleasePool();
1716 if( mrClippingPath
)
1718 CGPathRelease( mrClippingPath
);
1719 mrClippingPath
= NULL
;
1722 if( maClippingRects
.size() > SAL_CLIPRECT_COUNT
&& nRects
< maClippingRects
.size() )
1724 std::vector
<CGRect
> aEmptyVec
;
1725 maClippingRects
.swap( aEmptyVec
);
1727 maClippingRects
.clear();
1728 maClippingRects
.reserve( nRects
);
1731 void AquaSalFrame::UnionClipRegion( long nX
, long nY
, long nWidth
, long nHeight
)
1733 // #i113170# may not be the main thread if called from UNO API
1734 SalData::ensureThreadAutoreleasePool();
1736 if( nWidth
&& nHeight
)
1738 NSRect aRect
= { { static_cast<CGFloat
>(nX
), static_cast<CGFloat
>(nY
) }, { static_cast<CGFloat
>(nWidth
), static_cast<CGFloat
>(nHeight
) } };
1739 VCLToCocoa( aRect
, false );
1740 maClippingRects
.push_back( CGRectMake(aRect
.origin
.x
, aRect
.origin
.y
, aRect
.size
.width
, aRect
.size
.height
) );
1744 void AquaSalFrame::EndSetClipRegion()
1751 // #i113170# may not be the main thread if called from UNO API
1752 SalData::ensureThreadAutoreleasePool();
1754 if( ! maClippingRects
.empty() )
1756 mrClippingPath
= CGPathCreateMutable();
1757 CGPathAddRects( mrClippingPath
, NULL
, &maClippingRects
[0], maClippingRects
.size() );
1759 if( mpView
&& mbShown
)
1760 [mpView setNeedsDisplay
: YES
];
1763 [mpWindow setOpaque
: (mrClippingPath
!= NULL
) ? NO
: YES
];
1764 [mpWindow setBackgroundColor
: [NSColor clearColor
]];
1765 // shadow is invalidated when view gets drawn again
1769 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */