1 /************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: salframe.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
36 #include "saldata.hxx"
42 #include "salframeview.h"
43 #include "aqua11yfactory.h"
44 #include "vcl/salwtype.hxx"
45 #include "vcl/window.hxx"
46 #include "vcl/timer.hxx"
50 // FIXME: move theming code to salnativewidgets.cxx
51 #include <Carbon/Carbon.h>
54 #include "boost/assert.hpp"
55 #include "vcl/svapp.hxx"
56 #include "rtl/ustrbuf.hxx"
59 #include <CoreFoundation/CoreFoundation.h>
64 // =======================================================================
66 AquaSalFrame
* AquaSalFrame::s_pCaptureFrame
= NULL
;
68 // =======================================================================
70 AquaSalFrame::AquaSalFrame( SalFrame
* pParent
, ULONG salFrameStyle
) :
81 mbFullScreen( false ),
86 mbPresentation( false ),
87 mnStyle( salFrameStyle
),
90 mnLastModifierFlags( 0 ),
93 mePointerStyle( POINTER_ARROW
),
94 mnTrackingRectTag( 0 ),
98 maSysData
.nSize
= sizeof( SystemEnvData
);
100 mpParent
= dynamic_cast<AquaSalFrame
*>(pParent
);
104 SalData
* pSalData
= GetSalData();
105 pSalData
->maFrames
.push_front( this );
106 pSalData
->maFrameCheck
.insert( this );
109 // -----------------------------------------------------------------------
111 AquaSalFrame::~AquaSalFrame()
113 // if the frame is destroyed and has the current menubar
114 // set the default menubar
115 if( mpMenu
&& mpMenu
->mbMenuBar
&& AquaSalMenu::pCurrentMenuBar
== mpMenu
)
116 AquaSalMenu::setDefaultMenu();
118 // cleanup clipping stuff
121 [SalFrameView unsetMouseFrame
: this];
123 SalData
* pSalData
= GetSalData();
124 pSalData
->maFrames
.remove( this );
125 pSalData
->maFrameCheck
.erase( this );
127 DBG_ASSERT( this != s_pCaptureFrame
, "capture frame destroyed" );
128 if( this == s_pCaptureFrame
)
129 s_pCaptureFrame
= NULL
;
134 if( mpDockMenuEntry
)
135 // life cycle comment: the menu has ownership of the item, so no release
136 [AquaSalInstance::GetDynamicDockMenu() removeItem
: mpDockMenuEntry
];
138 [AquaA11yFactory revokeView
: mpView
];
145 // -----------------------------------------------------------------------
147 void AquaSalFrame::initWindowAndView()
149 // initialize mirroring parameters
150 // FIXME: screens changing
151 NSScreen
* pScreen
= [mpWindow screen
];
153 pScreen
= [NSScreen mainScreen
];
154 maScreenRect
= [pScreen frame
];
156 // calculate some default geometry
157 NSRect aVisibleRect
= [pScreen visibleFrame
];
158 CocoaToVCL( aVisibleRect
);
160 maGeometry
.nX
= static_cast<int>(aVisibleRect
.origin
.x
+ aVisibleRect
.size
.width
/ 10);
161 maGeometry
.nY
= static_cast<int>(aVisibleRect
.origin
.y
+ aVisibleRect
.size
.height
/ 10);
162 maGeometry
.nWidth
= static_cast<unsigned int>(aVisibleRect
.size
.width
* 0.8);
163 maGeometry
.nHeight
= static_cast<unsigned int>(aVisibleRect
.size
.height
* 0.8);
165 // calculate style mask
166 if( (mnStyle
& SAL_FRAME_STYLE_FLOAT
) ||
167 (mnStyle
& SAL_FRAME_STYLE_OWNERDRAWDECORATION
) )
168 mnStyleMask
= NSBorderlessWindowMask
;
169 else if( mnStyle
& SAL_FRAME_STYLE_DEFAULT
)
171 mnStyleMask
= NSTitledWindowMask
|
172 NSMiniaturizableWindowMask
|
173 NSResizableWindowMask
|
174 NSClosableWindowMask
;
175 // make default window "maximized"
176 maGeometry
.nX
= static_cast<int>(aVisibleRect
.origin
.x
);
177 maGeometry
.nY
= static_cast<int>(aVisibleRect
.origin
.y
);
178 maGeometry
.nWidth
= static_cast<int>(aVisibleRect
.size
.width
);
179 maGeometry
.nHeight
= static_cast<int>(aVisibleRect
.size
.height
);
180 mbPositioned
= mbSized
= true;
184 if( (mnStyle
& SAL_FRAME_STYLE_MOVEABLE
) )
186 mnStyleMask
|= NSTitledWindowMask
;
187 if( mpParent
== NULL
)
188 mnStyleMask
|= NSMiniaturizableWindowMask
;
190 if( (mnStyle
& SAL_FRAME_STYLE_SIZEABLE
) )
191 mnStyleMask
|= NSResizableWindowMask
;
192 if( (mnStyle
& SAL_FRAME_STYLE_CLOSEABLE
) )
193 mnStyleMask
|= NSClosableWindowMask
;
194 // documentation says anything other than NSBorderlessWindowMask (=0)
195 // should also include NSTitledWindowMask;
196 if( mnStyleMask
!= 0 )
197 mnStyleMask
|= NSTitledWindowMask
;
200 mpWindow
= [[SalFrameWindow alloc
] initWithSalFrame
: this];
201 mpView
= [[SalFrameView alloc
] initWithSalFrame
: this];
202 if( (mnStyle
& SAL_FRAME_STYLE_TOOLTIP
) )
203 [mpWindow setIgnoresMouseEvents
: YES
];
205 [mpWindow setAcceptsMouseMovedEvents
: YES
];
206 [mpWindow setHasShadow
: YES
];
207 [mpWindow setDelegate
: mpWindow
];
209 NSRect aRect
= { { 0,0 }, { maGeometry
.nWidth
, maGeometry
.nHeight
} };
210 mnTrackingRectTag
= [mpView addTrackingRect
: aRect owner
: mpView userData
: nil assumeInside
: NO
];
212 maSysData
.pView
= mpView
;
214 UpdateFrameGeometry();
216 // setContentView causes a display; in multithreaded use this can deadlock
217 //YieldMutexReleaser aRel;
218 [mpWindow setContentView
: mpView
];
221 // -----------------------------------------------------------------------
223 void AquaSalFrame::CocoaToVCL( NSRect
& io_rRect
, bool bRelativeToScreen
)
225 if( bRelativeToScreen
)
226 io_rRect
.origin
.y
= maScreenRect
.size
.height
- (io_rRect
.origin
.y
+io_rRect
.size
.height
);
228 io_rRect
.origin
.y
= maGeometry
.nHeight
- (io_rRect
.origin
.y
+io_rRect
.size
.height
);
231 void AquaSalFrame::VCLToCocoa( 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::CocoaToVCL( NSPoint
& io_rPoint
, bool bRelativeToScreen
)
241 if( bRelativeToScreen
)
242 io_rPoint
.y
= maScreenRect
.size
.height
- io_rPoint
.y
;
244 io_rPoint
.y
= maGeometry
.nHeight
- io_rPoint
.y
;
247 void AquaSalFrame::VCLToCocoa( 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 // -----------------------------------------------------------------------
257 void AquaSalFrame::screenParametersChanged()
259 UpdateFrameGeometry();
262 mpGraphics
->updateResolution();
263 CallCallback( SALEVENT_DISPLAYCHANGED
, 0 );
266 // -----------------------------------------------------------------------
268 SalGraphics
* AquaSalFrame::GetGraphics()
275 mpGraphics
= new AquaSalGraphics
;
276 mpGraphics
->SetWindowGraphics( this );
283 // -----------------------------------------------------------------------
285 void AquaSalFrame::ReleaseGraphics( SalGraphics
*pGraphics
)
287 DBG_ASSERT( pGraphics
== mpGraphics
, "graphics released on wrong frame" );
291 // -----------------------------------------------------------------------
293 BOOL
AquaSalFrame::PostEvent( void *pData
)
295 GetSalData()->mpFirstInstance
->PostUserEvent( this, SALEVENT_USEREVENT
, pData
);
299 // -----------------------------------------------------------------------
300 void AquaSalFrame::SetTitle(const XubString
& rTitle
)
302 NSString
* pTitle
= CreateNSString( rTitle
);
303 [mpWindow setTitle
: pTitle
];
305 // create an entry in the dock menu
306 const ULONG nAppWindowStyle
= (SAL_FRAME_STYLE_CLOSEABLE
| SAL_FRAME_STYLE_MOVEABLE
);
307 if( mpParent
== NULL
&&
308 (mnStyle
& nAppWindowStyle
) == nAppWindowStyle
)
310 if( mpDockMenuEntry
== NULL
)
312 NSMenu
* pDock
= AquaSalInstance::GetDynamicDockMenu();
313 mpDockMenuEntry
= [pDock insertItemWithTitle
: pTitle
314 action
: @
selector(dockMenuItemTriggered
:)
317 [mpDockMenuEntry setTarget
: mpWindow
];
319 // TODO: image (either the generic window image or an icon
320 // check mark (for "main" window ?)
323 [mpDockMenuEntry setTitle
: pTitle
];
330 // -----------------------------------------------------------------------
332 void AquaSalFrame::SetIcon( USHORT nIcon
)
336 // -----------------------------------------------------------------------
338 void AquaSalFrame::initShow()
341 if( ! mbPositioned
&& ! mbFullScreen
)
343 Rectangle aScreenRect
;
344 GetWorkArea( aScreenRect
);
345 if( mpParent
) // center relative to parent
348 long nNewX
= mpParent
->maGeometry
.nX
+ (mpParent
->maGeometry
.nWidth
- maGeometry
.nWidth
)/2;
349 if( nNewX
< aScreenRect
.Left() )
350 nNewX
= aScreenRect
.Left();
351 if( long(nNewX
+ maGeometry
.nWidth
) > aScreenRect
.Right() )
352 nNewX
= aScreenRect
.Right() - maGeometry
.nWidth
-1;
353 long nNewY
= mpParent
->maGeometry
.nY
+ (mpParent
->maGeometry
.nHeight
- maGeometry
.nHeight
)/2;
354 if( nNewY
< aScreenRect
.Top() )
355 nNewY
= aScreenRect
.Top();
356 if( nNewY
> aScreenRect
.Bottom() )
357 nNewY
= aScreenRect
.Bottom() - maGeometry
.nHeight
-1;
358 SetPosSize( nNewX
- mpParent
->maGeometry
.nX
,
359 nNewY
- mpParent
->maGeometry
.nY
,
360 0, 0, SAL_FRAME_POSSIZE_X
| SAL_FRAME_POSSIZE_Y
);
362 else if( ! (mnStyle
& SAL_FRAME_STYLE_SIZEABLE
) )
365 long nNewX
= (aScreenRect
.GetWidth() - maGeometry
.nWidth
)/2;
366 long nNewY
= (aScreenRect
.GetHeight() - maGeometry
.nHeight
)/2;
367 SetPosSize( nNewX
, nNewY
, 0, 0, SAL_FRAME_POSSIZE_X
| SAL_FRAME_POSSIZE_Y
);
371 // make sure the view is present in the wrapper list before any children receive focus
372 [AquaA11yFactory registerView
: mpView
];
375 void AquaSalFrame::SendPaintEvent( const Rectangle
* pRect
)
377 SalPaintEvent
aPaintEvt( 0, 0, maGeometry
.nWidth
, maGeometry
.nHeight
, true );
380 aPaintEvt
.mnBoundX
= pRect
->Left();
381 aPaintEvt
.mnBoundY
= pRect
->Top();
382 aPaintEvt
.mnBoundWidth
= pRect
->GetWidth();
383 aPaintEvt
.mnBoundHeight
= pRect
->GetHeight();
386 CallCallback(SALEVENT_PAINT
, &aPaintEvt
);
389 // -----------------------------------------------------------------------
391 void AquaSalFrame::Show(BOOL bVisible
, BOOL bNoActivate
)
399 CallCallback(SALEVENT_RESIZE
, 0);
400 // trigger filling our backbuffer
403 //YieldMutexReleaser aRel;
405 if( bNoActivate
|| [mpWindow canBecomeKeyWindow
] == NO
)
406 [mpWindow orderFront
: NSApp
];
408 [mpWindow makeKeyAndOrderFront
: NSApp
];
412 /* #i92674# #i96433# we do not want an invisible parent to show up (which adding a visible
413 child implicitly does). However we also do not want a parentless toolbar.
415 HACK: try to decide when we should not insert a child to its parent
416 floaters and ownerdraw windows have not yet shown up in cases where
417 we don't want the parent to become visible
419 if( mpParent
->mbShown
|| (mnStyle
& (SAL_FRAME_STYLE_OWNERDRAWDECORATION
| SAL_FRAME_STYLE_FLOAT
) ) )
421 [mpParent
->mpWindow addChildWindow
: mpWindow ordered
: NSWindowAbove
];
426 [mpWindow makeMainWindow
];
430 // if the frame holding the current menubar gets hidden
431 // show the default menubar
432 if( mpMenu
&& mpMenu
->mbMenuBar
&& AquaSalMenu::pCurrentMenuBar
== mpMenu
)
433 AquaSalMenu::setDefaultMenu();
435 //YieldMutexReleaser aRel;
437 // #i90440# #i94443# work around the focus going back to some other window
438 // if a child gets hidden for a parent window
439 if( mpParent
&& mpParent
->mbShown
&& [mpWindow isKeyWindow
] )
440 [mpParent
->mpWindow makeKeyAndOrderFront
: NSApp
];
442 [SalFrameView unsetMouseFrame
: this];
443 if( mpParent
&& [mpWindow parentWindow
] == mpParent
->mpWindow
)
444 [mpParent
->mpWindow removeChildWindow
: mpWindow
];
446 [mpWindow orderOut
: NSApp
];
450 // -----------------------------------------------------------------------
452 void AquaSalFrame::Enable( BOOL bEnable
)
456 // -----------------------------------------------------------------------
458 void AquaSalFrame::SetMinClientSize( long nWidth
, long nHeight
)
461 mnMinHeight
= nHeight
;
465 // Always add the decoration as the dimension concerns only
466 // the content rectangle
467 nWidth
+= maGeometry
.nLeftDecoration
+ maGeometry
.nRightDecoration
;
468 nHeight
+= maGeometry
.nTopDecoration
+ maGeometry
.nBottomDecoration
;
470 NSSize aSize
= { nWidth
, nHeight
};
472 // Size of full window (content+structure) although we only
473 // have the client size in arguments
474 [mpWindow setMinSize
: aSize
];
478 // -----------------------------------------------------------------------
480 void AquaSalFrame::SetMaxClientSize( long nWidth
, long nHeight
)
483 mnMaxHeight
= nHeight
;
487 // Always add the decoration as the dimension concerns only
488 // the content rectangle
489 nWidth
+= maGeometry
.nLeftDecoration
+ maGeometry
.nRightDecoration
;
490 nHeight
+= maGeometry
.nTopDecoration
+ maGeometry
.nBottomDecoration
;
492 // Carbon windows can't have a size greater than 32767x32767
493 if (nWidth
>32767) nWidth
=32767;
494 if (nHeight
>32767) nHeight
=32767;
496 NSSize aSize
= { nWidth
, nHeight
};
498 // Size of full window (content+structure) although we only
499 // have the client size in arguments
500 [mpWindow setMaxSize
: aSize
];
504 // -----------------------------------------------------------------------
506 void AquaSalFrame::SetClientSize( long nWidth
, long nHeight
)
510 NSSize aSize
= { nWidth
, nHeight
};
512 [mpWindow setContentSize
: aSize
];
513 UpdateFrameGeometry();
515 // trigger filling our backbuffer
520 // -----------------------------------------------------------------------
522 void AquaSalFrame::GetClientSize( long& rWidth
, long& rHeight
)
524 if( mbShown
|| mbInitShow
)
526 rWidth
= maGeometry
.nWidth
;
527 rHeight
= maGeometry
.nHeight
;
536 // -----------------------------------------------------------------------
538 void AquaSalFrame::SetWindowState( const SalFrameState
* pState
)
541 NSRect aStateRect
= [mpWindow frame
];
542 aStateRect
= [NSWindow contentRectForFrameRect
: aStateRect styleMask
: mnStyleMask
];
543 CocoaToVCL( aStateRect
);
544 if( pState
->mnMask
& SAL_FRAMESTATE_MASK_X
)
545 aStateRect
.origin
.x
= float(pState
->mnX
);
546 if( pState
->mnMask
& SAL_FRAMESTATE_MASK_Y
)
547 aStateRect
.origin
.y
= float(pState
->mnY
);
548 if( pState
->mnMask
& SAL_FRAMESTATE_MASK_WIDTH
)
549 aStateRect
.size
.width
= float(pState
->mnWidth
);
550 if( pState
->mnMask
& SAL_FRAMESTATE_MASK_HEIGHT
)
551 aStateRect
.size
.height
= float(pState
->mnHeight
);
552 VCLToCocoa( aStateRect
);
553 aStateRect
= [NSWindow frameRectForContentRect
: aStateRect styleMask
: mnStyleMask
];
555 // relase and acquire mutex again since this call can block waiting for an internal lock
557 //YieldMutexReleaser aRel;
558 [mpWindow setFrame
: aStateRect display
: NO
];
561 // FIXME: HTH maximized state ?
564 UpdateFrameGeometry();
567 if( pState
->mnMask
& (SAL_FRAMESTATE_MASK_X
| SAL_FRAMESTATE_MASK_X
) )
570 nEvent
= SALEVENT_MOVE
;
573 if( pState
->mnMask
& (SAL_FRAMESTATE_MASK_WIDTH
| SAL_FRAMESTATE_MASK_HEIGHT
) )
576 nEvent
= (nEvent
== SALEVENT_MOVE
) ? SALEVENT_MOVERESIZE
: SALEVENT_RESIZE
;
578 // send event that we were moved/sized
580 CallCallback( nEvent
, NULL
);
584 // trigger filling our backbuffer
587 // tell the system the views need to be updated
588 //YieldMutexReleaser aRel;
594 // -----------------------------------------------------------------------
596 BOOL
AquaSalFrame::GetWindowState( SalFrameState
* pState
)
598 pState
->mnMask
= SAL_FRAMESTATE_MASK_X
|
599 SAL_FRAMESTATE_MASK_Y
|
600 SAL_FRAMESTATE_MASK_WIDTH
|
601 SAL_FRAMESTATE_MASK_HEIGHT
|
603 SAL_FRAMESTATE_MASK_MAXIMIZED_X
|
604 SAL_FRAMESTATE_MASK_MAXIMIZED_Y
|
605 SAL_FRAMESTATE_MASK_MAXIMIZED_WIDTH
|
606 SAL_FRAMESTATE_MASK_MAXIMIZED_HEIGHT
|
608 SAL_FRAMESTATE_MASK_STATE
;
610 NSRect aStateRect
= [mpWindow frame
];
611 aStateRect
= [NSWindow contentRectForFrameRect
: aStateRect styleMask
: mnStyleMask
];
612 CocoaToVCL( aStateRect
);
613 pState
->mnX
= long(aStateRect
.origin
.x
);
614 pState
->mnY
= long(aStateRect
.origin
.y
);
615 pState
->mnWidth
= long(aStateRect
.size
.width
);
616 pState
->mnHeight
= long(aStateRect
.size
.height
);
618 // FIXME: HTH maximized state ?
620 if( [mpWindow isMiniaturized
] )
621 pState
->mnState
= SAL_FRAMESTATE_MINIMIZED
;
622 else if( ! [mpWindow isZoomed
] )
623 pState
->mnState
= SAL_FRAMESTATE_NORMAL
;
625 pState
->mnState
= SAL_FRAMESTATE_MAXIMIZED
;
630 // -----------------------------------------------------------------------
632 void AquaSalFrame::SetScreenNumber(unsigned int nScreen
)
634 NSArray
* pScreens
= [NSScreen screens
];
636 NSScreen
* pScreen
= nil
;
637 if( pScreens
&& nScreen
< [pScreens count
] )
639 // get new screen frame
640 pScreen
= [pScreens objectAtIndex
: nScreen
];
641 NSRect aNewScreen
= [pScreen frame
];
643 // get current screen frame
644 pScreen
= [mpWindow screen
];
647 NSRect aCurScreen
= [pScreen frame
];
648 if( aCurScreen
.origin
.x
!= aNewScreen
.origin
.x
||
649 aCurScreen
.origin
.y
!= aNewScreen
.origin
.y
)
651 NSRect aFrameRect
= [mpWindow frame
];
652 aFrameRect
.origin
.x
+= aNewScreen
.origin
.x
- aCurScreen
.origin
.x
;
653 aFrameRect
.origin
.y
+= aNewScreen
.origin
.y
- aCurScreen
.origin
.y
;
654 [mpWindow setFrame
: aFrameRect display
: NO
];
655 UpdateFrameGeometry();
661 // -----------------------------------------------------------------------
663 void AquaSalFrame::ShowFullScreen( BOOL bFullScreen
, sal_Int32 nDisplay
)
665 if( mbFullScreen
== bFullScreen
)
668 mbFullScreen
= bFullScreen
;
671 // hide the dock and the menubar if we are on the menu screen
672 // which is always on index 0 according to documentation
673 bool bHideMenu
= (nDisplay
== 0);
675 NSRect aNewContentRect
= { { 0, 0 }, { 0, 0 } };
676 // get correct screen
677 NSScreen
* pScreen
= nil
;
678 NSArray
* pScreens
= [NSScreen screens
];
681 if( nDisplay
>= 0 && (unsigned int)nDisplay
< [pScreens count
] )
682 pScreen
= [pScreens objectAtIndex
: nDisplay
];
685 // this means span all screens
687 NSEnumerator
* pEnum
= [pScreens objectEnumerator
];
688 while( (pScreen
= [pEnum nextObject
]) != nil
)
690 NSRect aScreenRect
= [pScreen frame
];
691 if( aScreenRect
.origin
.x
< aNewContentRect
.origin
.x
)
693 aNewContentRect
.size
.width
+= aNewContentRect
.origin
.x
- aScreenRect
.origin
.x
;
694 aNewContentRect
.origin
.x
= aScreenRect
.origin
.x
;
696 if( aScreenRect
.origin
.y
< aNewContentRect
.origin
.y
)
698 aNewContentRect
.size
.height
+= aNewContentRect
.origin
.y
- aScreenRect
.origin
.y
;
699 aNewContentRect
.origin
.y
= aScreenRect
.origin
.y
;
701 if( aScreenRect
.origin
.x
+ aScreenRect
.size
.width
> aNewContentRect
.origin
.x
+ aNewContentRect
.size
.width
)
702 aNewContentRect
.size
.width
= aScreenRect
.origin
.x
+ aScreenRect
.size
.width
- aNewContentRect
.origin
.x
;
703 if( aScreenRect
.origin
.y
+ aScreenRect
.size
.height
> aNewContentRect
.origin
.y
+ aNewContentRect
.size
.height
)
704 aNewContentRect
.size
.height
= aScreenRect
.origin
.y
+ aScreenRect
.size
.height
- aNewContentRect
.origin
.y
;
708 if( aNewContentRect
.size
.width
== 0 && aNewContentRect
.size
.height
== 0 )
711 pScreen
= [mpWindow screen
];
713 pScreen
= [NSScreen mainScreen
];
715 aNewContentRect
= [pScreen frame
];
719 [NSMenu setMenuBarVisible
:NO
];
721 maFullScreenRect
= [mpWindow frame
];
723 //YieldMutexReleaser aRel;
724 [mpWindow setFrame
: [NSWindow frameRectForContentRect
: aNewContentRect styleMask
: mnStyleMask
] display
: mbShown
? YES
: NO
];
727 UpdateFrameGeometry();
730 CallCallback( SALEVENT_MOVERESIZE
, NULL
);
735 //YieldMutexReleaser aRel;
736 [mpWindow setFrame
: maFullScreenRect display
: mbShown
? YES
: NO
];
738 UpdateFrameGeometry();
741 CallCallback( SALEVENT_MOVERESIZE
, NULL
);
743 // show the dock and the menubar
744 [NSMenu setMenuBarVisible
:YES
];
747 // trigger filling our backbuffer
751 // -----------------------------------------------------------------------
753 class PreventSleepTimer
: public AutoTimer
762 virtual ~PreventSleepTimer()
766 virtual void Timeout()
768 UpdateSystemActivity(OverallAct
);
772 void AquaSalFrame::StartPresentation( BOOL bStart
)
776 mpActivityTimer
.reset( new PreventSleepTimer() );
777 [mpWindow setLevel
: NSScreenSaverWindowLevel
];
779 [mpWindow makeMainWindow
];
783 mpActivityTimer
.reset();
784 [mpWindow setLevel
: NSNormalWindowLevel
];
788 // -----------------------------------------------------------------------
790 void AquaSalFrame::SetAlwaysOnTop( BOOL bOnTop
)
794 // -----------------------------------------------------------------------
796 void AquaSalFrame::ToTop(USHORT nFlags
)
798 if( ! (nFlags
& SAL_FRAME_TOTOP_RESTOREWHENMIN
) )
800 if( ! [mpWindow isVisible
] || [mpWindow isMiniaturized
] )
803 if( nFlags
& SAL_FRAME_TOTOP_GRABFOCUS
)
804 [mpWindow makeKeyAndOrderFront
: NSApp
];
806 [mpWindow orderFront
: NSApp
];
809 // -----------------------------------------------------------------------
811 NSCursor
* AquaSalFrame::getCurrentCursor() const
813 NSCursor
* pCursor
= nil
;
814 switch( mePointerStyle
)
816 case POINTER_TEXT
: pCursor
= [NSCursor IBeamCursor
]; break;
817 case POINTER_CROSS
: pCursor
= [NSCursor crosshairCursor
]; break;
819 case POINTER_MOVE
: pCursor
= [NSCursor openHandCursor
]; break;
820 case POINTER_NSIZE
: pCursor
= [NSCursor resizeUpCursor
]; break;
821 case POINTER_SSIZE
: pCursor
= [NSCursor resizeDownCursor
]; break;
822 case POINTER_ESIZE
: pCursor
= [NSCursor resizeRightCursor
]; break;
823 case POINTER_WSIZE
: pCursor
= [NSCursor resizeLeftCursor
]; break;
824 case POINTER_ARROW
: pCursor
= [NSCursor arrowCursor
]; break;
826 case POINTER_VSIZEBAR
:
827 case POINTER_WINDOW_NSIZE
:
828 case POINTER_WINDOW_SSIZE
:
829 pCursor
= [NSCursor resizeUpDownCursor
]; break;
831 case POINTER_HSIZEBAR
:
832 case POINTER_WINDOW_ESIZE
:
833 case POINTER_WINDOW_WSIZE
:
834 pCursor
= [NSCursor resizeLeftRightCursor
]; break;
835 case POINTER_REFHAND
: pCursor
= [NSCursor pointingHandCursor
]; break;
838 pCursor
= GetSalData()->getCursor( mePointerStyle
);
841 DBG_ERROR( "unmapped cursor" );
842 pCursor
= [NSCursor arrowCursor
];
849 void AquaSalFrame::SetPointer( PointerStyle ePointerStyle
)
851 if( ePointerStyle
>= POINTER_COUNT
|| ePointerStyle
== mePointerStyle
)
853 mePointerStyle
= ePointerStyle
;
855 [mpWindow invalidateCursorRectsForView
: mpView
];
858 // -----------------------------------------------------------------------
860 void AquaSalFrame::SetPointerPos( long nX
, long nY
)
862 // FIXME: use Cocoa functions
864 // FIXME: multiscreen support
865 CGPoint aPoint
= { nX
+ maGeometry
.nX
, nY
+ maGeometry
.nY
};
866 CGDirectDisplayID mainDisplayID
= CGMainDisplayID();
867 CGDisplayMoveCursorToPoint( mainDisplayID
, aPoint
);
870 // -----------------------------------------------------------------------
872 void AquaSalFrame::Flush( void )
874 if( !(mbGraphics
&& mpGraphics
&& mpView
&& mbShown
) )
877 [mpView setNeedsDisplay
: YES
];
879 // outside of the application's event loop (e.g. IntroWindow)
880 // nothing would trigger paint event handling
881 // => fall back to synchronous painting
882 if( ImplGetSVData()->maAppData
.mnDispatchLevel
<= 0 )
888 // -----------------------------------------------------------------------
890 void AquaSalFrame::Flush( const Rectangle
& rRect
)
892 if( !(mbGraphics
&& mpGraphics
&& mpView
&& mbShown
) )
895 NSRect aNSRect
= { {rRect
.Left(), rRect
.Top()}, { rRect
.GetWidth(), rRect
.GetHeight() } };
896 VCLToCocoa( aNSRect
, false );
897 [mpView setNeedsDisplayInRect
: aNSRect
];
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 // -----------------------------------------------------------------------
910 void AquaSalFrame::Sync()
912 if( mbGraphics
&& mpGraphics
&& mpView
&& mbShown
)
914 //YieldMutexReleaser aRel;
916 [mpView setNeedsDisplay
: YES
];
921 // -----------------------------------------------------------------------
923 void AquaSalFrame::SetInputContext( SalInputContext
* pContext
)
931 mnICOptions
= pContext
->mnOptions
;
933 if(!(pContext
->mnOptions
& SAL_INPUTCONTEXT_TEXT
))
937 // -----------------------------------------------------------------------
939 void AquaSalFrame::EndExtTextInput( USHORT nFlags
)
943 // -----------------------------------------------------------------------
945 XubString
AquaSalFrame::GetKeyName( USHORT nKeyCode
)
947 static std::map
< USHORT
, rtl::OUString
> aKeyMap
;
948 if( aKeyMap
.empty() )
951 for( i
= KEY_A
; i
<= KEY_Z
; i
++ )
952 aKeyMap
[ i
] = rtl::OUString( sal_Unicode( 'A' + (i
- KEY_A
) ) );
953 for( i
= KEY_0
; i
<= KEY_9
; i
++ )
954 aKeyMap
[ i
] = rtl::OUString( sal_Unicode( '0' + (i
- KEY_0
) ) );
955 for( i
= KEY_F1
; i
<= KEY_F26
; i
++ )
957 rtl::OUStringBuffer
aKey( 3 );
958 aKey
.append( sal_Unicode( 'F' ) );
959 aKey
.append( sal_Int32( i
- KEY_F1
+ 1 ) );
960 aKeyMap
[ i
] = aKey
.makeStringAndClear();
963 aKeyMap
[ KEY_DOWN
] = rtl::OUString( sal_Unicode( 0x21e3 ) );
964 aKeyMap
[ KEY_UP
] = rtl::OUString( sal_Unicode( 0x21e1 ) );
965 aKeyMap
[ KEY_LEFT
] = rtl::OUString( sal_Unicode( 0x21e0 ) );
966 aKeyMap
[ KEY_RIGHT
] = rtl::OUString( sal_Unicode( 0x21e2 ) );
967 aKeyMap
[ KEY_HOME
] = rtl::OUString( sal_Unicode( 0x2196 ) );
968 aKeyMap
[ KEY_END
] = rtl::OUString( sal_Unicode( 0x2198 ) );
969 aKeyMap
[ KEY_PAGEUP
] = rtl::OUString( sal_Unicode( 0x21de ) );
970 aKeyMap
[ KEY_PAGEDOWN
] = rtl::OUString( sal_Unicode( 0x21df ) );
971 aKeyMap
[ KEY_RETURN
] = rtl::OUString( sal_Unicode( 0x21a9 ) );
972 aKeyMap
[ KEY_ESCAPE
] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "esc" ) );
973 aKeyMap
[ KEY_TAB
] = rtl::OUString( sal_Unicode( 0x21e5 ) );
974 aKeyMap
[ KEY_BACKSPACE
]= rtl::OUString( sal_Unicode( 0x232b ) );
975 aKeyMap
[ KEY_SPACE
] = rtl::OUString( sal_Unicode( 0x2423 ) );
976 aKeyMap
[ KEY_DELETE
] = rtl::OUString( sal_Unicode( 0x2326 ) );
977 aKeyMap
[ KEY_ADD
] = rtl::OUString( sal_Unicode( '+' ) );
978 aKeyMap
[ KEY_SUBTRACT
] = rtl::OUString( sal_Unicode( '-' ) );
979 aKeyMap
[ KEY_DIVIDE
] = rtl::OUString( sal_Unicode( '/' ) );
980 aKeyMap
[ KEY_MULTIPLY
] = rtl::OUString( sal_Unicode( '*' ) );
981 aKeyMap
[ KEY_POINT
] = rtl::OUString( sal_Unicode( '.' ) );
982 aKeyMap
[ KEY_COMMA
] = rtl::OUString( sal_Unicode( ',' ) );
983 aKeyMap
[ KEY_LESS
] = rtl::OUString( sal_Unicode( '<' ) );
984 aKeyMap
[ KEY_GREATER
] = rtl::OUString( sal_Unicode( '>' ) );
985 aKeyMap
[ KEY_EQUAL
] = rtl::OUString( sal_Unicode( '=' ) );
986 aKeyMap
[ KEY_OPEN
] = rtl::OUString( sal_Unicode( 0x23cf ) );
988 /* yet unmapped KEYCODES:
989 aKeyMap[ KEY_INSERT ] = rtl::OUString( sal_Unicode( ) );
990 aKeyMap[ KEY_CUT ] = rtl::OUString( sal_Unicode( ) );
991 aKeyMap[ KEY_COPY ] = rtl::OUString( sal_Unicode( ) );
992 aKeyMap[ KEY_PASTE ] = rtl::OUString( sal_Unicode( ) );
993 aKeyMap[ KEY_UNDO ] = rtl::OUString( sal_Unicode( ) );
994 aKeyMap[ KEY_REPEAT ] = rtl::OUString( sal_Unicode( ) );
995 aKeyMap[ KEY_FIND ] = rtl::OUString( sal_Unicode( ) );
996 aKeyMap[ KEY_PROPERTIES ] = rtl::OUString( sal_Unicode( ) );
997 aKeyMap[ KEY_FRONT ] = rtl::OUString( sal_Unicode( ) );
998 aKeyMap[ KEY_CONTEXTMENU ] = rtl::OUString( sal_Unicode( ) );
999 aKeyMap[ KEY_MENU ] = rtl::OUString( sal_Unicode( ) );
1000 aKeyMap[ KEY_HELP ] = rtl::OUString( sal_Unicode( ) );
1001 aKeyMap[ KEY_HANGUL_HANJA ] = rtl::OUString( sal_Unicode( ) );
1002 aKeyMap[ KEY_DECIMAL ] = rtl::OUString( sal_Unicode( ) );
1003 aKeyMap[ KEY_TILDE ] = rtl::OUString( sal_Unicode( ) );
1004 aKeyMap[ KEY_QUOTELEFT ]= rtl::OUString( sal_Unicode( ) );
1009 rtl::OUStringBuffer
aResult( 16 );
1011 USHORT nUnmodifiedCode
= (nKeyCode
& KEY_CODE
);
1012 std::map
< USHORT
, rtl::OUString
>::const_iterator it
= aKeyMap
.find( nUnmodifiedCode
);
1013 if( it
!= aKeyMap
.end() )
1015 if( (nKeyCode
& KEY_SHIFT
) != 0 )
1016 aResult
.append( sal_Unicode( 0x21e7 ) );
1017 if( (nKeyCode
& KEY_MOD1
) != 0 )
1018 aResult
.append( sal_Unicode( 0x2318 ) );
1019 // we do not really handle Alt (see below)
1020 // we map it to MOD3, whichis actually Command
1021 if( (nKeyCode
& (KEY_MOD2
|KEY_MOD3
)) != 0 )
1022 aResult
.append( sal_Unicode( 0x2303 ) );
1024 aResult
.append( it
->second
);
1027 return aResult
.makeStringAndClear();
1030 // -----------------------------------------------------------------------
1032 XubString
AquaSalFrame::GetSymbolKeyName( const XubString
&, USHORT nKeyCode
)
1034 return GetKeyName( nKeyCode
);
1037 // -----------------------------------------------------------------------
1039 static void getAppleScrollBarVariant(void)
1041 bool bIsScrollbarDoubleMax
= true; // default is DoubleMax
1043 CFStringRef AppleScrollBarType
= CFSTR("AppleScrollBarVariant");
1044 if( AppleScrollBarType
)
1046 CFStringRef ScrollBarVariant
= ((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
= ((CFBooleanRef
)CFPreferencesCopyAppValue( jumpScroll
, kCFPreferencesCurrentApplication
));
1075 if( CFGetTypeID( jumpStr
) == CFBooleanGetTypeID() )
1076 ImplGetSVData()->maNWFData
.mbScrollbarJumpPage
= (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 float 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 Font
getFont( NSFont
* pFont
, long nDPIY
, const Font
& rDefault
)
1108 Font
aResult( rDefault
);
1111 aResult
.SetName( GetOUString( [pFont familyName
] ) );
1112 aResult
.SetHeight( static_cast<int>(([pFont pointSize
] * 72.0 / (float)nDPIY
)+0.5) );
1113 aResult
.SetItalic( ([pFont italicAngle
] != 0.0) ? ITALIC_NORMAL
: ITALIC_NONE
);
1120 // on OSX-Aqua the style settings are independent of the frame, so it does
1121 // not really belong here. Since the connection to the Appearance_Manager
1122 // is currently done in salnativewidgets.cxx this would be a good place.
1123 // On the other hand VCL's platform independent code currently only asks
1124 // SalFrames for system settings anyway, so moving the code somewhere else
1125 // doesn't make the anything cleaner for now
1126 void AquaSalFrame::UpdateSettings( AllSettings
& rSettings
)
1130 StyleSettings aStyleSettings
= rSettings
.GetStyleSettings();
1133 Color aBackgroundColor
= Color( 0xEC, 0xEC, 0xEC );
1134 aStyleSettings
.Set3DColors( aBackgroundColor
);
1135 aStyleSettings
.SetFaceColor( aBackgroundColor
);
1136 Color
aInactiveTabColor( aBackgroundColor
);
1137 aInactiveTabColor
.DecreaseLuminance( 32 );
1138 aStyleSettings
.SetInactiveTabColor( aInactiveTabColor
);
1140 aStyleSettings
.SetDialogColor( aBackgroundColor
);
1141 aStyleSettings
.SetLightBorderColor( aBackgroundColor
);
1142 Color
aShadowColor( aStyleSettings
.GetShadowColor() );
1143 aStyleSettings
.SetDarkShadowColor( aShadowColor
);
1144 aShadowColor
.IncreaseLuminance( 32 );
1145 aStyleSettings
.SetShadowColor( aShadowColor
);
1147 // get the system font settings
1148 Font aAppFont
= aStyleSettings
.GetAppFont();
1152 ReleaseGraphics( mpGraphics
);
1154 long nDPIX
= 72, nDPIY
= 72;
1155 mpGraphics
->GetResolution( nDPIX
, nDPIY
);
1156 aAppFont
= getFont( [NSFont systemFontOfSize
: 0], nDPIY
, aAppFont
);
1158 // TODO: better mapping of aqua<->ooo font settings
1159 aStyleSettings
.SetAppFont( aAppFont
);
1160 aStyleSettings
.SetHelpFont( aAppFont
);
1161 aStyleSettings
.SetPushButtonFont( aAppFont
);
1163 Font
aTitleFont( getFont( [NSFont titleBarFontOfSize
: 0], nDPIY
, aAppFont
) );
1164 aStyleSettings
.SetTitleFont( aTitleFont
);
1165 aStyleSettings
.SetFloatTitleFont( aTitleFont
);
1167 Font
aMenuFont( getFont( [NSFont menuFontOfSize
: 0], nDPIY
, aAppFont
) );
1168 aStyleSettings
.SetMenuFont( aMenuFont
);
1170 aStyleSettings
.SetToolFont( aAppFont
);
1172 Font
aLabelFont( getFont( [NSFont labelFontOfSize
: 0], nDPIY
, aAppFont
) );
1173 aStyleSettings
.SetLabelFont( aLabelFont
);
1174 aStyleSettings
.SetInfoFont( aLabelFont
);
1175 aStyleSettings
.SetRadioCheckFont( aLabelFont
);
1176 aStyleSettings
.SetFieldFont( aLabelFont
);
1177 aStyleSettings
.SetGroupFont( aLabelFont
);
1178 aStyleSettings
.SetIconFont( aLabelFont
);
1180 Color
aHighlightColor( getColor( [NSColor selectedTextBackgroundColor
],
1181 aStyleSettings
.GetHighlightColor(), mpWindow
) );
1182 aStyleSettings
.SetHighlightColor( aHighlightColor
);
1183 Color
aHighlightTextColor( getColor( [NSColor selectedTextColor
],
1184 aStyleSettings
.GetHighlightTextColor(), mpWindow
) );
1185 aStyleSettings
.SetHighlightTextColor( aHighlightTextColor
);
1187 Color
aMenuHighlightColor( getColor( [NSColor selectedMenuItemColor
],
1188 aStyleSettings
.GetMenuHighlightColor(), mpWindow
) );
1189 aStyleSettings
.SetMenuHighlightColor( aMenuHighlightColor
);
1190 Color
aMenuHighlightTextColor( getColor( [NSColor selectedMenuItemTextColor
],
1191 aStyleSettings
.GetMenuHighlightTextColor(), mpWindow
) );
1192 aStyleSettings
.SetMenuHighlightTextColor( aMenuHighlightTextColor
);
1194 aStyleSettings
.SetMenuColor( aBackgroundColor
);
1195 Color
aMenuTextColor( getColor( [NSColor textColor
],
1196 aStyleSettings
.GetMenuTextColor(), mpWindow
) );
1197 aStyleSettings
.SetMenuTextColor( aMenuTextColor
);
1198 aStyleSettings
.SetMenuBarTextColor( aMenuTextColor
);
1200 aStyleSettings
.SetCursorBlinkTime( 500 );
1202 // no mnemonics on aqua
1203 aStyleSettings
.SetOptions( aStyleSettings
.GetOptions() | STYLE_OPTION_NOMNEMONICS
);
1205 getAppleScrollBarVariant();
1207 // set scrollbar size
1208 aStyleSettings
.SetScrollBarSize( static_cast<long int>([NSScroller scrollerWidth
]) );
1210 // images in menus false for MacOSX
1211 aStyleSettings
.SetUseImagesInMenus( false );
1213 rSettings
.SetStyleSettings( aStyleSettings
);
1215 [mpView unlockFocus
];
1218 // -----------------------------------------------------------------------
1220 const SystemEnvData
* AquaSalFrame::GetSystemData() const
1225 // -----------------------------------------------------------------------
1227 void AquaSalFrame::Beep( SoundType eSoundType
)
1229 switch( eSoundType
)
1240 // -----------------------------------------------------------------------
1242 void AquaSalFrame::SetPosSize(long nX
, long nY
, long nWidth
, long nHeight
, USHORT nFlags
)
1246 if( [mpWindow isMiniaturized
] )
1247 [mpWindow deminiaturize
: NSApp
]; // expand the window
1249 if (nFlags
& (SAL_FRAME_POSSIZE_X
| SAL_FRAME_POSSIZE_Y
))
1251 mbPositioned
= true;
1252 nEvent
= SALEVENT_MOVE
;
1255 if (nFlags
& (SAL_FRAME_POSSIZE_WIDTH
| SAL_FRAME_POSSIZE_HEIGHT
))
1258 nEvent
= (nEvent
== SALEVENT_MOVE
) ? SALEVENT_MOVERESIZE
: SALEVENT_RESIZE
;
1261 NSRect aFrameRect
= [mpWindow frame
];
1262 NSRect aContentRect
= [NSWindow contentRectForFrameRect
: aFrameRect styleMask
: mnStyleMask
];
1264 // position is always relative to parent frame
1265 NSRect aParentContentRect
;
1269 if( Application::GetSettings().GetLayoutRTL() )
1271 if( (nFlags
& SAL_FRAME_POSSIZE_WIDTH
) != 0 )
1272 nX
= mpParent
->maGeometry
.nWidth
- nWidth
-1 - nX
;
1274 nX
= mpParent
->maGeometry
.nWidth
- static_cast<long int>( aContentRect
.size
.width
-1) - nX
;
1276 NSRect aParentFrameRect
= [mpParent
->mpWindow frame
];
1277 aParentContentRect
= [NSWindow contentRectForFrameRect
: aParentFrameRect styleMask
: mpParent
->mnStyleMask
];
1280 aParentContentRect
= maScreenRect
; // use screen if no parent
1282 CocoaToVCL( aContentRect
);
1283 CocoaToVCL( aParentContentRect
);
1285 bool bPaint
= false;
1286 if( (nFlags
& (SAL_FRAME_POSSIZE_WIDTH
| SAL_FRAME_POSSIZE_HEIGHT
)) != 0 )
1288 if( nWidth
!= aContentRect
.size
.width
|| nHeight
!= aContentRect
.size
.height
)
1292 // use old window pos if no new pos requested
1293 if( (nFlags
& SAL_FRAME_POSSIZE_X
) != 0 )
1294 aContentRect
.origin
.x
= nX
+ aParentContentRect
.origin
.x
;
1295 if( (nFlags
& SAL_FRAME_POSSIZE_Y
) != 0)
1296 aContentRect
.origin
.y
= nY
+ aParentContentRect
.origin
.y
;
1298 // use old size if no new size requested
1299 if( (nFlags
& SAL_FRAME_POSSIZE_WIDTH
) != 0 )
1300 aContentRect
.size
.width
= nWidth
;
1301 if( (nFlags
& SAL_FRAME_POSSIZE_HEIGHT
) != 0)
1302 aContentRect
.size
.height
= nHeight
;
1304 VCLToCocoa( aContentRect
);
1306 // do not display yet, we need to update our backbuffer
1308 //YieldMutexReleaser aRel;
1309 [mpWindow setFrame
: [NSWindow frameRectForContentRect
: aContentRect styleMask
: mnStyleMask
] display
: NO
];
1312 UpdateFrameGeometry();
1315 CallCallback(nEvent
, NULL
);
1317 if( mbShown
&& bPaint
)
1319 // trigger filling our backbuffer
1322 // now inform the system that the views need to be drawn
1323 //YieldMutexReleaser aRel;
1328 void AquaSalFrame::GetWorkArea( Rectangle
& rRect
)
1330 NSScreen
* pScreen
= [mpWindow screen
];
1331 if( pScreen
== nil
)
1332 pScreen
= [NSScreen mainScreen
];
1333 NSRect aRect
= [pScreen visibleFrame
];
1334 CocoaToVCL( aRect
);
1335 rRect
.nLeft
= static_cast<long>(aRect
.origin
.x
);
1336 rRect
.nTop
= static_cast<long>(aRect
.origin
.y
);
1337 rRect
.nRight
= static_cast<long>(aRect
.origin
.x
+ aRect
.size
.width
- 1);
1338 rRect
.nBottom
= static_cast<long>(aRect
.origin
.y
+ aRect
.size
.height
- 1);
1341 SalPointerState
AquaSalFrame::GetPointerState()
1343 SalPointerState state
;
1346 NSPoint aPt
= [mpWindow mouseLocationOutsideOfEventStream
];
1347 CocoaToVCL( aPt
, false );
1348 state
.maPos
= Point(static_cast<long>(aPt
.x
), static_cast<long>(aPt
.y
));
1350 // FIXME: replace Carbon by Cocoa
1351 // Cocoa does not have an equivalent for GetCurrentEventButtonState
1352 // and GetCurrentEventKeyModifiers.
1353 // we could try to get away with tracking all events for modifierKeys
1354 // and all mouse events for button state in VCL_NSApllication::sendEvent,
1355 // but it is unclear whether this will get us the same result.
1356 // leave in GetCurrentEventButtonState and GetCurrentEventKeyModifiers for now
1358 // fill in button state
1359 UInt32 nState
= GetCurrentEventButtonState();
1362 state
.mnState
|= MOUSE_LEFT
; // primary button
1364 state
.mnState
|= MOUSE_RIGHT
; // secondary button
1366 state
.mnState
|= MOUSE_MIDDLE
; // tertiary button
1368 // fill in modifier state
1369 nState
= GetCurrentEventKeyModifiers();
1370 if( nState
& shiftKey
)
1371 state
.mnState
|= KEY_SHIFT
;
1372 if( nState
& controlKey
)
1373 state
.mnState
|= KEY_MOD3
;
1374 if( nState
& optionKey
)
1375 state
.mnState
|= KEY_MOD2
;
1376 if( nState
& cmdKey
)
1377 state
.mnState
|= KEY_MOD1
;
1382 SalFrame::SalIndicatorState
AquaSalFrame::GetIndicatorState()
1384 SalIndicatorState aState
;
1389 void AquaSalFrame::SimulateKeyPress( USHORT
/*nKeyCode*/ )
1393 bool AquaSalFrame::SetPluginParent( SystemParentData
* pNewParent
)
1395 // plugin parent may be killed unexpectedly by
1396 // plugging process;
1402 BOOL
AquaSalFrame::MapUnicodeToKeyCode( sal_Unicode
, LanguageType
, KeyCode
& )
1404 // not supported yet
1408 LanguageType
AquaSalFrame::GetInputLanguage()
1411 return LANGUAGE_DONTKNOW
;
1414 void AquaSalFrame::DrawMenuBar()
1418 void AquaSalFrame::SetMenu( SalMenu
* pSalMenu
)
1420 AquaSalMenu
* pMenu
= static_cast<AquaSalMenu
*>(pSalMenu
);
1421 DBG_ASSERT( ! pMenu
|| pMenu
->mbMenuBar
, "setting non menubar on frame" );
1424 mpMenu
->setMainMenu();
1427 void AquaSalFrame::SetExtendedFrameStyle( SalExtStyle nStyle
)
1429 if( (mnExtStyle
& SAL_FRAME_EXT_STYLE_DOCMODIFIED
) != (nStyle
& SAL_FRAME_EXT_STYLE_DOCMODIFIED
) )
1430 [mpWindow setDocumentEdited
: (nStyle
& SAL_FRAME_EXT_STYLE_DOCMODIFIED
) ? YES
: NO
];
1431 mnExtStyle
= nStyle
;
1434 void AquaSalFrame::SetBackgroundBitmap( SalBitmap
* )
1439 SalBitmap
* AquaSalFrame::SnapShot()
1441 return mpGraphics
? mpGraphics
->getBitmap( 0, 0, maGeometry
.nWidth
, maGeometry
.nHeight
) : NULL
;
1444 SalFrame
* AquaSalFrame::GetParent() const
1449 void AquaSalFrame::SetParent( SalFrame
* pNewParent
)
1451 bool bShown
= mbShown
;
1452 // remove from child list
1454 mpParent
= (AquaSalFrame
*)pNewParent
;
1455 // insert to correct parent and paint
1459 void AquaSalFrame::UpdateFrameGeometry()
1461 // keep in mind that view and window coordinates are lower left
1462 // whereas vcl's are upper left
1464 // update screen rect
1465 NSScreen
* pScreen
= [mpWindow screen
];
1468 maScreenRect
= [pScreen frame
];
1469 NSArray
* pScreens
= [NSScreen screens
];
1471 maGeometry
.nScreenNumber
= [pScreens indexOfObject
: pScreen
];
1474 NSRect aFrameRect
= [mpWindow frame
];
1475 NSRect aContentRect
= [NSWindow contentRectForFrameRect
: aFrameRect styleMask
: mnStyleMask
];
1477 // release old track rect
1478 [mpView removeTrackingRect
: mnTrackingRectTag
];
1479 // install the new track rect
1480 NSRect aTrackRect
= { { 0, 0 }, aContentRect
.size
};
1481 mnTrackingRectTag
= [mpView addTrackingRect
: aTrackRect owner
: mpView userData
: nil assumeInside
: NO
];
1483 // convert to vcl convention
1484 CocoaToVCL( aFrameRect
);
1485 CocoaToVCL( aContentRect
);
1487 maGeometry
.nX
= static_cast<int>(aContentRect
.origin
.x
);
1488 maGeometry
.nY
= static_cast<int>(aContentRect
.origin
.y
);
1490 maGeometry
.nLeftDecoration
= static_cast<unsigned int>(aContentRect
.origin
.x
- aFrameRect
.origin
.x
);
1491 maGeometry
.nRightDecoration
= static_cast<unsigned int>((aFrameRect
.origin
.x
+ aFrameRect
.size
.width
) -
1492 (aContentRect
.origin
.x
+ aContentRect
.size
.width
));
1494 maGeometry
.nTopDecoration
= static_cast<unsigned int>(aContentRect
.origin
.y
- aFrameRect
.origin
.y
);
1495 maGeometry
.nBottomDecoration
= static_cast<unsigned int>((aFrameRect
.origin
.y
+ aFrameRect
.size
.height
) -
1496 (aContentRect
.origin
.y
+ aContentRect
.size
.height
));
1498 maGeometry
.nWidth
= static_cast<unsigned int>(aContentRect
.size
.width
);
1499 maGeometry
.nHeight
= static_cast<unsigned int>(aContentRect
.size
.height
);
1502 // -----------------------------------------------------------------------
1504 void AquaSalFrame::CaptureMouse( BOOL bCapture
)
1507 we'll try to use a pidgin version of capture mouse
1508 on MacOSX (neither carbon nor cocoa) there is a
1509 CaptureMouse equivalent (in Carbon there is TrackMouseLocation
1510 but this is useless to use since it is blocking)
1512 However on cocoa the active frame seems to get mouse events
1513 also outside the window, so we'll try to forward mouse events
1514 to the capture frame in the hope that one of our frames
1517 This will break as soon as the user activates another app, but
1518 a mouse click will normally lead to a release of the mouse anyway.
1520 Let's see how far we get this way. Alternatively we could use one
1521 large overlay window like we did for the carbon implementation,
1522 however that is resource intensive.
1526 s_pCaptureFrame
= this;
1527 else if( ! bCapture
&& s_pCaptureFrame
== this )
1528 s_pCaptureFrame
= NULL
;
1531 void AquaSalFrame::ResetClipRegion()
1533 // release old path and indicate no clipping
1534 CGPathRelease( mrClippingPath
);
1535 mrClippingPath
= NULL
;
1537 if( mpView
&& mbShown
)
1538 [mpView setNeedsDisplay
: YES
];
1541 [mpWindow setOpaque
: YES
];
1542 [mpWindow invalidateShadow
];
1546 void AquaSalFrame::BeginSetClipRegion( ULONG nRects
)
1549 if( mrClippingPath
)
1551 CGPathRelease( mrClippingPath
);
1552 mrClippingPath
= NULL
;
1555 if( maClippingRects
.size() > SAL_CLIPRECT_COUNT
&& nRects
< maClippingRects
.size() )
1557 std::vector
<CGRect
> aEmptyVec
;
1558 maClippingRects
.swap( aEmptyVec
);
1560 maClippingRects
.clear();
1561 maClippingRects
.reserve( nRects
);
1564 void AquaSalFrame::UnionClipRegion( long nX
, long nY
, long nWidth
, long nHeight
)
1566 if( nWidth
&& nHeight
)
1568 NSRect aRect
= { { nX
, nY
}, { nWidth
, nHeight
} };
1569 VCLToCocoa( aRect
, false );
1570 maClippingRects
.push_back( CGRectMake(aRect
.origin
.x
, aRect
.origin
.y
, aRect
.size
.width
, aRect
.size
.height
) );
1574 void AquaSalFrame::EndSetClipRegion()
1576 if( ! maClippingRects
.empty() )
1578 mrClippingPath
= CGPathCreateMutable();
1579 CGPathAddRects( mrClippingPath
, NULL
, &maClippingRects
[0], maClippingRects
.size() );
1581 if( mpView
&& mbShown
)
1582 [mpView setNeedsDisplay
: YES
];
1585 [mpWindow setOpaque
: (mrClippingPath
!= NULL
) ? NO
: YES
];
1586 [mpWindow setBackgroundColor
: [NSColor clearColor
]];
1587 // shadow is invalidated when view gets drawn again