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"
49 // FIXME: move theming code to salnativewidgets.cxx
50 #include <Carbon/Carbon.h>
53 #include "boost/assert.hpp"
54 #include "vcl/svapp.hxx"
55 #include "rtl/ustrbuf.hxx"
58 #include <CoreFoundation/CoreFoundation.h>
63 // =======================================================================
65 AquaSalFrame
* AquaSalFrame::s_pCaptureFrame
= NULL
;
67 // =======================================================================
69 AquaSalFrame::AquaSalFrame( SalFrame
* pParent
, ULONG salFrameStyle
) :
80 mbFullScreen( false ),
85 mbPresentation( false ),
86 mnStyle( salFrameStyle
),
89 mnLastModifierFlags( 0 ),
92 mePointerStyle( POINTER_ARROW
),
93 mnTrackingRectTag( 0 ),
97 maSysData
.nSize
= sizeof( SystemEnvData
);
99 mpParent
= dynamic_cast<AquaSalFrame
*>(pParent
);
103 SalData
* pSalData
= GetSalData();
104 pSalData
->maFrames
.push_front( this );
105 pSalData
->maFrameCheck
.insert( this );
108 // -----------------------------------------------------------------------
110 AquaSalFrame::~AquaSalFrame()
112 // if the frame is destroyed and has the current menubar
113 // set the default menubar
114 if( mpMenu
&& mpMenu
->mbMenuBar
&& AquaSalMenu::pCurrentMenuBar
== mpMenu
)
115 AquaSalMenu::setDefaultMenu();
117 // cleanup clipping stuff
120 [SalFrameView unsetMouseFrame
: this];
122 SalData
* pSalData
= GetSalData();
123 pSalData
->maFrames
.remove( this );
124 pSalData
->maFrameCheck
.erase( this );
126 DBG_ASSERT( this != s_pCaptureFrame
, "capture frame destroyed" );
127 if( this == s_pCaptureFrame
)
128 s_pCaptureFrame
= NULL
;
133 if( mpDockMenuEntry
)
134 // life cycle comment: the menu has ownership of the item, so no release
135 [AquaSalInstance::GetDynamicDockMenu() removeItem
: mpDockMenuEntry
];
137 [AquaA11yFactory revokeView
: mpView
];
144 // -----------------------------------------------------------------------
146 void AquaSalFrame::initWindowAndView()
148 // initialize mirroring parameters
149 // FIXME: screens changing
150 NSScreen
* pScreen
= [mpWindow screen
];
152 pScreen
= [NSScreen mainScreen
];
153 maScreenRect
= [pScreen frame
];
155 // calculate some default geometry
156 NSRect aVisibleRect
= [pScreen visibleFrame
];
157 CocoaToVCL( aVisibleRect
);
159 maGeometry
.nX
= static_cast<int>(aVisibleRect
.origin
.x
+ aVisibleRect
.size
.width
/ 10);
160 maGeometry
.nY
= static_cast<int>(aVisibleRect
.origin
.y
+ aVisibleRect
.size
.height
/ 10);
161 maGeometry
.nWidth
= static_cast<unsigned int>(aVisibleRect
.size
.width
* 0.8);
162 maGeometry
.nHeight
= static_cast<unsigned int>(aVisibleRect
.size
.height
* 0.8);
164 // calculate style mask
165 if( (mnStyle
& SAL_FRAME_STYLE_FLOAT
) ||
166 (mnStyle
& SAL_FRAME_STYLE_OWNERDRAWDECORATION
) )
167 mnStyleMask
= NSBorderlessWindowMask
;
168 else if( mnStyle
& SAL_FRAME_STYLE_DEFAULT
)
170 mnStyleMask
= NSTitledWindowMask
|
171 NSMiniaturizableWindowMask
|
172 NSResizableWindowMask
|
173 NSClosableWindowMask
;
174 // make default window "maximized"
175 maGeometry
.nX
= static_cast<int>(aVisibleRect
.origin
.x
);
176 maGeometry
.nY
= static_cast<int>(aVisibleRect
.origin
.y
);
177 maGeometry
.nWidth
= static_cast<int>(aVisibleRect
.size
.width
);
178 maGeometry
.nHeight
= static_cast<int>(aVisibleRect
.size
.height
);
179 mbPositioned
= mbSized
= true;
183 if( (mnStyle
& SAL_FRAME_STYLE_MOVEABLE
) )
185 mnStyleMask
|= NSTitledWindowMask
;
186 if( mpParent
== NULL
)
187 mnStyleMask
|= NSMiniaturizableWindowMask
;
189 if( (mnStyle
& SAL_FRAME_STYLE_SIZEABLE
) )
190 mnStyleMask
|= NSResizableWindowMask
;
191 if( (mnStyle
& SAL_FRAME_STYLE_CLOSEABLE
) )
192 mnStyleMask
|= NSClosableWindowMask
;
193 // documentation says anything other than NSBorderlessWindowMask (=0)
194 // should also include NSTitledWindowMask;
195 if( mnStyleMask
!= 0 )
196 mnStyleMask
|= NSTitledWindowMask
;
199 mpWindow
= [[SalFrameWindow alloc
] initWithSalFrame
: this];
200 mpView
= [[SalFrameView alloc
] initWithSalFrame
: this];
201 if( (mnStyle
& SAL_FRAME_STYLE_TOOLTIP
) )
202 [mpWindow setIgnoresMouseEvents
: YES
];
204 [mpWindow setAcceptsMouseMovedEvents
: YES
];
205 [mpWindow setHasShadow
: YES
];
206 [mpWindow setDelegate
: mpWindow
];
208 NSRect aRect
= { { 0,0 }, { maGeometry
.nWidth
, maGeometry
.nHeight
} };
209 mnTrackingRectTag
= [mpView addTrackingRect
: aRect owner
: mpView userData
: nil assumeInside
: NO
];
211 maSysData
.pView
= mpView
;
213 UpdateFrameGeometry();
215 // setContentView causes a display; in multithreaded use this can deadlock
216 //YieldMutexReleaser aRel;
217 [mpWindow setContentView
: mpView
];
220 // -----------------------------------------------------------------------
222 void AquaSalFrame::CocoaToVCL( NSRect
& io_rRect
, bool bRelativeToScreen
)
224 if( bRelativeToScreen
)
225 io_rRect
.origin
.y
= maScreenRect
.size
.height
- (io_rRect
.origin
.y
+io_rRect
.size
.height
);
227 io_rRect
.origin
.y
= maGeometry
.nHeight
- (io_rRect
.origin
.y
+io_rRect
.size
.height
);
230 void AquaSalFrame::VCLToCocoa( NSRect
& io_rRect
, bool bRelativeToScreen
)
232 if( bRelativeToScreen
)
233 io_rRect
.origin
.y
= maScreenRect
.size
.height
- (io_rRect
.origin
.y
+io_rRect
.size
.height
);
235 io_rRect
.origin
.y
= maGeometry
.nHeight
- (io_rRect
.origin
.y
+io_rRect
.size
.height
);
238 void AquaSalFrame::CocoaToVCL( NSPoint
& io_rPoint
, bool bRelativeToScreen
)
240 if( bRelativeToScreen
)
241 io_rPoint
.y
= maScreenRect
.size
.height
- io_rPoint
.y
;
243 io_rPoint
.y
= maGeometry
.nHeight
- io_rPoint
.y
;
246 void AquaSalFrame::VCLToCocoa( NSPoint
& io_rPoint
, bool bRelativeToScreen
)
248 if( bRelativeToScreen
)
249 io_rPoint
.y
= maScreenRect
.size
.height
- io_rPoint
.y
;
251 io_rPoint
.y
= maGeometry
.nHeight
- io_rPoint
.y
;
254 // -----------------------------------------------------------------------
256 void AquaSalFrame::screenParametersChanged()
258 UpdateFrameGeometry();
261 mpGraphics
->updateResolution();
262 CallCallback( SALEVENT_DISPLAYCHANGED
, 0 );
265 // -----------------------------------------------------------------------
267 SalGraphics
* AquaSalFrame::GetGraphics()
274 mpGraphics
= new AquaSalGraphics
;
275 mpGraphics
->SetWindowGraphics( this );
282 // -----------------------------------------------------------------------
284 void AquaSalFrame::ReleaseGraphics( SalGraphics
*pGraphics
)
286 DBG_ASSERT( pGraphics
== mpGraphics
, "graphics released on wrong frame" );
290 // -----------------------------------------------------------------------
292 BOOL
AquaSalFrame::PostEvent( void *pData
)
294 GetSalData()->mpFirstInstance
->PostUserEvent( this, SALEVENT_USEREVENT
, pData
);
298 // -----------------------------------------------------------------------
299 void AquaSalFrame::SetTitle(const XubString
& rTitle
)
301 NSString
* pTitle
= CreateNSString( rTitle
);
302 [mpWindow setTitle
: pTitle
];
304 // create an entry in the dock menu
305 const ULONG nAppWindowStyle
= (SAL_FRAME_STYLE_CLOSEABLE
| SAL_FRAME_STYLE_MOVEABLE
);
306 if( mpParent
== NULL
&&
307 (mnStyle
& nAppWindowStyle
) == nAppWindowStyle
)
309 if( mpDockMenuEntry
== NULL
)
311 NSMenu
* pDock
= AquaSalInstance::GetDynamicDockMenu();
312 mpDockMenuEntry
= [pDock insertItemWithTitle
: pTitle
313 action
: @
selector(dockMenuItemTriggered
:)
316 [mpDockMenuEntry setTarget
: mpWindow
];
318 // TODO: image (either the generic window image or an icon
319 // check mark (for "main" window ?)
322 [mpDockMenuEntry setTitle
: pTitle
];
329 // -----------------------------------------------------------------------
331 void AquaSalFrame::SetIcon( USHORT nIcon
)
335 // -----------------------------------------------------------------------
337 void AquaSalFrame::initShow()
340 if( ! mbPositioned
&& ! mbFullScreen
)
342 Rectangle aScreenRect
;
343 GetWorkArea( aScreenRect
);
344 if( mpParent
) // center relative to parent
347 long nNewX
= mpParent
->maGeometry
.nX
+ (mpParent
->maGeometry
.nWidth
- maGeometry
.nWidth
)/2;
348 if( nNewX
< aScreenRect
.Left() )
349 nNewX
= aScreenRect
.Left();
350 if( long(nNewX
+ maGeometry
.nWidth
) > aScreenRect
.Right() )
351 nNewX
= aScreenRect
.Right() - maGeometry
.nWidth
-1;
352 long nNewY
= mpParent
->maGeometry
.nY
+ (mpParent
->maGeometry
.nHeight
- maGeometry
.nHeight
)/2;
353 if( nNewY
< aScreenRect
.Top() )
354 nNewY
= aScreenRect
.Top();
355 if( nNewY
> aScreenRect
.Bottom() )
356 nNewY
= aScreenRect
.Bottom() - maGeometry
.nHeight
-1;
357 SetPosSize( nNewX
- mpParent
->maGeometry
.nX
,
358 nNewY
- mpParent
->maGeometry
.nY
,
359 0, 0, SAL_FRAME_POSSIZE_X
| SAL_FRAME_POSSIZE_Y
);
361 else if( ! (mnStyle
& SAL_FRAME_STYLE_SIZEABLE
) )
364 long nNewX
= (aScreenRect
.GetWidth() - maGeometry
.nWidth
)/2;
365 long nNewY
= (aScreenRect
.GetHeight() - maGeometry
.nHeight
)/2;
366 SetPosSize( nNewX
, nNewY
, 0, 0, SAL_FRAME_POSSIZE_X
| SAL_FRAME_POSSIZE_Y
);
370 // make sure the view is present in the wrapper list before any children receive focus
371 [AquaA11yFactory registerView
: mpView
];
374 void AquaSalFrame::SendPaintEvent( const Rectangle
* pRect
)
376 SalPaintEvent
aPaintEvt( 0, 0, maGeometry
.nWidth
, maGeometry
.nHeight
, true );
379 aPaintEvt
.mnBoundX
= pRect
->Left();
380 aPaintEvt
.mnBoundY
= pRect
->Top();
381 aPaintEvt
.mnBoundWidth
= pRect
->GetWidth();
382 aPaintEvt
.mnBoundHeight
= pRect
->GetHeight();
385 CallCallback(SALEVENT_PAINT
, &aPaintEvt
);
388 // -----------------------------------------------------------------------
390 void AquaSalFrame::Show(BOOL bVisible
, BOOL bNoActivate
)
398 CallCallback(SALEVENT_RESIZE
, 0);
399 // trigger filling our backbuffer
402 //YieldMutexReleaser aRel;
404 if( bNoActivate
|| [mpWindow canBecomeKeyWindow
] == NO
)
405 [mpWindow orderFront
: NSApp
];
407 [mpWindow makeKeyAndOrderFront
: NSApp
];
411 /* #i92674# #i96433# we do not want an invisible parent to show up (which adding a visible
412 child implicitly does). However we also do not want a parentless toolbar.
414 HACK: try to decide when we should not insert a child to its parent
415 floaters and ownerdraw windows have not yet shown up in cases where
416 we don't want the parent to become visible
418 if( mpParent
->mbShown
|| (mnStyle
& (SAL_FRAME_STYLE_OWNERDRAWDECORATION
| SAL_FRAME_STYLE_FLOAT
) ) )
420 [mpParent
->mpWindow addChildWindow
: mpWindow ordered
: NSWindowAbove
];
425 [mpWindow makeMainWindow
];
429 // if the frame holding the current menubar gets hidden
430 // show the default menubar
431 if( mpMenu
&& mpMenu
->mbMenuBar
&& AquaSalMenu::pCurrentMenuBar
== mpMenu
)
432 AquaSalMenu::setDefaultMenu();
434 //YieldMutexReleaser aRel;
436 // #i90440# #i94443# work around the focus going back to some other window
437 // if a child gets hidden for a parent window
438 if( mpParent
&& mpParent
->mbShown
&& [mpWindow isKeyWindow
] )
439 [mpParent
->mpWindow makeKeyAndOrderFront
: NSApp
];
441 [SalFrameView unsetMouseFrame
: this];
442 if( mpParent
&& [mpWindow parentWindow
] == mpParent
->mpWindow
)
443 [mpParent
->mpWindow removeChildWindow
: mpWindow
];
445 [mpWindow orderOut
: NSApp
];
449 // -----------------------------------------------------------------------
451 void AquaSalFrame::Enable( BOOL bEnable
)
455 // -----------------------------------------------------------------------
457 void AquaSalFrame::SetMinClientSize( long nWidth
, long nHeight
)
460 mnMinHeight
= nHeight
;
464 // Always add the decoration as the dimension concerns only
465 // the content rectangle
466 nWidth
+= maGeometry
.nLeftDecoration
+ maGeometry
.nRightDecoration
;
467 nHeight
+= maGeometry
.nTopDecoration
+ maGeometry
.nBottomDecoration
;
469 NSSize aSize
= { nWidth
, nHeight
};
471 // Size of full window (content+structure) although we only
472 // have the client size in arguments
473 [mpWindow setMinSize
: aSize
];
477 // -----------------------------------------------------------------------
479 void AquaSalFrame::SetMaxClientSize( long nWidth
, long nHeight
)
482 mnMaxHeight
= nHeight
;
486 // Always add the decoration as the dimension concerns only
487 // the content rectangle
488 nWidth
+= maGeometry
.nLeftDecoration
+ maGeometry
.nRightDecoration
;
489 nHeight
+= maGeometry
.nTopDecoration
+ maGeometry
.nBottomDecoration
;
491 // Carbon windows can't have a size greater than 32767x32767
492 if (nWidth
>32767) nWidth
=32767;
493 if (nHeight
>32767) nHeight
=32767;
495 NSSize aSize
= { nWidth
, nHeight
};
497 // Size of full window (content+structure) although we only
498 // have the client size in arguments
499 [mpWindow setMaxSize
: aSize
];
503 // -----------------------------------------------------------------------
505 void AquaSalFrame::SetClientSize( long nWidth
, long nHeight
)
509 NSSize aSize
= { nWidth
, nHeight
};
511 [mpWindow setContentSize
: aSize
];
512 UpdateFrameGeometry();
514 // trigger filling our backbuffer
519 // -----------------------------------------------------------------------
521 void AquaSalFrame::GetClientSize( long& rWidth
, long& rHeight
)
523 if( mbShown
|| mbInitShow
)
525 rWidth
= maGeometry
.nWidth
;
526 rHeight
= maGeometry
.nHeight
;
535 // -----------------------------------------------------------------------
537 void AquaSalFrame::SetWindowState( const SalFrameState
* pState
)
540 NSRect aStateRect
= [mpWindow frame
];
541 aStateRect
= [NSWindow contentRectForFrameRect
: aStateRect styleMask
: mnStyleMask
];
542 CocoaToVCL( aStateRect
);
543 if( pState
->mnMask
& SAL_FRAMESTATE_MASK_X
)
544 aStateRect
.origin
.x
= float(pState
->mnX
);
545 if( pState
->mnMask
& SAL_FRAMESTATE_MASK_Y
)
546 aStateRect
.origin
.y
= float(pState
->mnY
);
547 if( pState
->mnMask
& SAL_FRAMESTATE_MASK_WIDTH
)
548 aStateRect
.size
.width
= float(pState
->mnWidth
);
549 if( pState
->mnMask
& SAL_FRAMESTATE_MASK_HEIGHT
)
550 aStateRect
.size
.height
= float(pState
->mnHeight
);
551 VCLToCocoa( aStateRect
);
552 aStateRect
= [NSWindow frameRectForContentRect
: aStateRect styleMask
: mnStyleMask
];
554 // relase and acquire mutex again since this call can block waiting for an internal lock
556 //YieldMutexReleaser aRel;
557 [mpWindow setFrame
: aStateRect display
: NO
];
560 // FIXME: HTH maximized state ?
563 UpdateFrameGeometry();
566 if( pState
->mnMask
& (SAL_FRAMESTATE_MASK_X
| SAL_FRAMESTATE_MASK_X
) )
569 nEvent
= SALEVENT_MOVE
;
572 if( pState
->mnMask
& (SAL_FRAMESTATE_MASK_WIDTH
| SAL_FRAMESTATE_MASK_HEIGHT
) )
575 nEvent
= (nEvent
== SALEVENT_MOVE
) ? SALEVENT_MOVERESIZE
: SALEVENT_RESIZE
;
577 // send event that we were moved/sized
579 CallCallback( nEvent
, NULL
);
583 // trigger filling our backbuffer
586 // tell the system the views need to be updated
587 //YieldMutexReleaser aRel;
593 // -----------------------------------------------------------------------
595 BOOL
AquaSalFrame::GetWindowState( SalFrameState
* pState
)
597 pState
->mnMask
= SAL_FRAMESTATE_MASK_X
|
598 SAL_FRAMESTATE_MASK_Y
|
599 SAL_FRAMESTATE_MASK_WIDTH
|
600 SAL_FRAMESTATE_MASK_HEIGHT
|
602 SAL_FRAMESTATE_MASK_MAXIMIZED_X
|
603 SAL_FRAMESTATE_MASK_MAXIMIZED_Y
|
604 SAL_FRAMESTATE_MASK_MAXIMIZED_WIDTH
|
605 SAL_FRAMESTATE_MASK_MAXIMIZED_HEIGHT
|
607 SAL_FRAMESTATE_MASK_STATE
;
609 NSRect aStateRect
= [mpWindow frame
];
610 aStateRect
= [NSWindow contentRectForFrameRect
: aStateRect styleMask
: mnStyleMask
];
611 CocoaToVCL( aStateRect
);
612 pState
->mnX
= long(aStateRect
.origin
.x
);
613 pState
->mnY
= long(aStateRect
.origin
.y
);
614 pState
->mnWidth
= long(aStateRect
.size
.width
);
615 pState
->mnHeight
= long(aStateRect
.size
.height
);
617 // FIXME: HTH maximized state ?
619 if( [mpWindow isMiniaturized
] )
620 pState
->mnState
= SAL_FRAMESTATE_MINIMIZED
;
621 else if( ! [mpWindow isZoomed
] )
622 pState
->mnState
= SAL_FRAMESTATE_NORMAL
;
624 pState
->mnState
= SAL_FRAMESTATE_MAXIMIZED
;
629 // -----------------------------------------------------------------------
631 void AquaSalFrame::SetScreenNumber(unsigned int nScreen
)
633 NSArray
* pScreens
= [NSScreen screens
];
635 NSScreen
* pScreen
= nil
;
636 if( pScreens
&& nScreen
< [pScreens count
] )
638 // get new screen frame
639 pScreen
= [pScreens objectAtIndex
: nScreen
];
640 NSRect aNewScreen
= [pScreen frame
];
642 // get current screen frame
643 pScreen
= [mpWindow screen
];
646 NSRect aCurScreen
= [pScreen frame
];
647 if( aCurScreen
.origin
.x
!= aNewScreen
.origin
.x
||
648 aCurScreen
.origin
.y
!= aNewScreen
.origin
.y
)
650 NSRect aFrameRect
= [mpWindow frame
];
651 aFrameRect
.origin
.x
+= aNewScreen
.origin
.x
- aCurScreen
.origin
.x
;
652 aFrameRect
.origin
.y
+= aNewScreen
.origin
.y
- aCurScreen
.origin
.y
;
653 [mpWindow setFrame
: aFrameRect display
: NO
];
654 UpdateFrameGeometry();
660 // -----------------------------------------------------------------------
662 void AquaSalFrame::ShowFullScreen( BOOL bFullScreen
, sal_Int32 nDisplay
)
664 if( mbFullScreen
== bFullScreen
)
667 mbFullScreen
= bFullScreen
;
670 // hide the dock and the menubar if we are on the menu screen
671 // which is always on index 0 according to documentation
672 bool bHideMenu
= (nDisplay
== 0);
674 NSRect aNewContentRect
= { { 0, 0 }, { 0, 0 } };
675 // get correct screen
676 NSScreen
* pScreen
= nil
;
677 NSArray
* pScreens
= [NSScreen screens
];
680 if( nDisplay
>= 0 && (unsigned int)nDisplay
< [pScreens count
] )
681 pScreen
= [pScreens objectAtIndex
: nDisplay
];
684 // this means span all screens
686 NSEnumerator
* pEnum
= [pScreens objectEnumerator
];
687 while( (pScreen
= [pEnum nextObject
]) != nil
)
689 NSRect aScreenRect
= [pScreen frame
];
690 if( aScreenRect
.origin
.x
< aNewContentRect
.origin
.x
)
692 aNewContentRect
.size
.width
+= aNewContentRect
.origin
.x
- aScreenRect
.origin
.x
;
693 aNewContentRect
.origin
.x
= aScreenRect
.origin
.x
;
695 if( aScreenRect
.origin
.y
< aNewContentRect
.origin
.y
)
697 aNewContentRect
.size
.height
+= aNewContentRect
.origin
.y
- aScreenRect
.origin
.y
;
698 aNewContentRect
.origin
.y
= aScreenRect
.origin
.y
;
700 if( aScreenRect
.origin
.x
+ aScreenRect
.size
.width
> aNewContentRect
.origin
.x
+ aNewContentRect
.size
.width
)
701 aNewContentRect
.size
.width
= aScreenRect
.origin
.x
+ aScreenRect
.size
.width
- aNewContentRect
.origin
.x
;
702 if( aScreenRect
.origin
.y
+ aScreenRect
.size
.height
> aNewContentRect
.origin
.y
+ aNewContentRect
.size
.height
)
703 aNewContentRect
.size
.height
= aScreenRect
.origin
.y
+ aScreenRect
.size
.height
- aNewContentRect
.origin
.y
;
707 if( aNewContentRect
.size
.width
== 0 && aNewContentRect
.size
.height
== 0 )
710 pScreen
= [mpWindow screen
];
712 pScreen
= [NSScreen mainScreen
];
714 aNewContentRect
= [pScreen frame
];
718 [NSMenu setMenuBarVisible
:NO
];
720 maFullScreenRect
= [mpWindow frame
];
722 //YieldMutexReleaser aRel;
723 [mpWindow setFrame
: [NSWindow frameRectForContentRect
: aNewContentRect styleMask
: mnStyleMask
] display
: mbShown
? YES
: NO
];
726 UpdateFrameGeometry();
729 CallCallback( SALEVENT_MOVERESIZE
, NULL
);
734 //YieldMutexReleaser aRel;
735 [mpWindow setFrame
: maFullScreenRect display
: mbShown
? YES
: NO
];
737 UpdateFrameGeometry();
740 CallCallback( SALEVENT_MOVERESIZE
, NULL
);
742 // show the dock and the menubar
743 [NSMenu setMenuBarVisible
:YES
];
746 // trigger filling our backbuffer
750 // -----------------------------------------------------------------------
752 void AquaSalFrame::StartPresentation( BOOL bStart
)
756 [mpWindow setLevel
: NSScreenSaverWindowLevel
];
758 [mpWindow makeMainWindow
];
762 [mpWindow setLevel
: NSNormalWindowLevel
];
766 // -----------------------------------------------------------------------
768 void AquaSalFrame::SetAlwaysOnTop( BOOL bOnTop
)
772 // -----------------------------------------------------------------------
774 void AquaSalFrame::ToTop(USHORT nFlags
)
776 if( ! (nFlags
& SAL_FRAME_TOTOP_RESTOREWHENMIN
) )
778 if( ! [mpWindow isVisible
] || [mpWindow isMiniaturized
] )
781 if( nFlags
& SAL_FRAME_TOTOP_GRABFOCUS
)
782 [mpWindow makeKeyAndOrderFront
: NSApp
];
784 [mpWindow orderFront
: NSApp
];
787 // -----------------------------------------------------------------------
789 NSCursor
* AquaSalFrame::getCurrentCursor() const
791 NSCursor
* pCursor
= nil
;
792 switch( mePointerStyle
)
794 case POINTER_TEXT
: pCursor
= [NSCursor IBeamCursor
]; break;
795 case POINTER_CROSS
: pCursor
= [NSCursor crosshairCursor
]; break;
797 case POINTER_MOVE
: pCursor
= [NSCursor openHandCursor
]; break;
798 case POINTER_NSIZE
: pCursor
= [NSCursor resizeUpCursor
]; break;
799 case POINTER_SSIZE
: pCursor
= [NSCursor resizeDownCursor
]; break;
800 case POINTER_ESIZE
: pCursor
= [NSCursor resizeRightCursor
]; break;
801 case POINTER_WSIZE
: pCursor
= [NSCursor resizeLeftCursor
]; break;
802 case POINTER_ARROW
: pCursor
= [NSCursor arrowCursor
]; break;
804 case POINTER_VSIZEBAR
:
805 case POINTER_WINDOW_NSIZE
:
806 case POINTER_WINDOW_SSIZE
:
807 pCursor
= [NSCursor resizeUpDownCursor
]; break;
809 case POINTER_HSIZEBAR
:
810 case POINTER_WINDOW_ESIZE
:
811 case POINTER_WINDOW_WSIZE
:
812 pCursor
= [NSCursor resizeLeftRightCursor
]; break;
813 case POINTER_REFHAND
: pCursor
= [NSCursor pointingHandCursor
]; break;
816 pCursor
= GetSalData()->getCursor( mePointerStyle
);
819 DBG_ERROR( "unmapped cursor" );
820 pCursor
= [NSCursor arrowCursor
];
827 void AquaSalFrame::SetPointer( PointerStyle ePointerStyle
)
829 if( ePointerStyle
>= POINTER_COUNT
|| ePointerStyle
== mePointerStyle
)
831 mePointerStyle
= ePointerStyle
;
833 [mpWindow invalidateCursorRectsForView
: mpView
];
836 // -----------------------------------------------------------------------
838 void AquaSalFrame::SetPointerPos( long nX
, long nY
)
840 // FIXME: use Cocoa functions
842 // FIXME: multiscreen support
843 CGPoint aPoint
= { nX
+ maGeometry
.nX
, nY
+ maGeometry
.nY
};
844 CGDirectDisplayID mainDisplayID
= CGMainDisplayID();
845 CGDisplayMoveCursorToPoint( mainDisplayID
, aPoint
);
848 // -----------------------------------------------------------------------
850 void AquaSalFrame::Flush( void )
852 if( !(mbGraphics
&& mpGraphics
&& mpView
&& mbShown
) )
855 [mpView setNeedsDisplay
: YES
];
857 // outside of the application's event loop (e.g. IntroWindow)
858 // nothing would trigger paint event handling
859 // => fall back to synchronous painting
860 if( ImplGetSVData()->maAppData
.mnDispatchLevel
<= 0 )
866 // -----------------------------------------------------------------------
868 void AquaSalFrame::Flush( const Rectangle
& rRect
)
870 if( !(mbGraphics
&& mpGraphics
&& mpView
&& mbShown
) )
873 NSRect aNSRect
= { {rRect
.Left(), rRect
.Top()}, { rRect
.GetWidth(), rRect
.GetHeight() } };
874 VCLToCocoa( aNSRect
, false );
875 [mpView setNeedsDisplayInRect
: aNSRect
];
877 // outside of the application's event loop (e.g. IntroWindow)
878 // nothing would trigger paint event handling
879 // => fall back to synchronous painting
880 if( ImplGetSVData()->maAppData
.mnDispatchLevel
<= 0 )
886 // -----------------------------------------------------------------------
888 void AquaSalFrame::Sync()
890 if( mbGraphics
&& mpGraphics
&& mpView
&& mbShown
)
892 //YieldMutexReleaser aRel;
894 [mpView setNeedsDisplay
: YES
];
899 // -----------------------------------------------------------------------
901 void AquaSalFrame::SetInputContext( SalInputContext
* pContext
)
909 mnICOptions
= pContext
->mnOptions
;
911 if(!(pContext
->mnOptions
& SAL_INPUTCONTEXT_TEXT
))
915 // -----------------------------------------------------------------------
917 void AquaSalFrame::EndExtTextInput( USHORT nFlags
)
921 // -----------------------------------------------------------------------
923 XubString
AquaSalFrame::GetKeyName( USHORT nKeyCode
)
925 static std::map
< USHORT
, rtl::OUString
> aKeyMap
;
926 if( aKeyMap
.empty() )
929 for( i
= KEY_A
; i
<= KEY_Z
; i
++ )
930 aKeyMap
[ i
] = rtl::OUString( sal_Unicode( 'A' + (i
- KEY_A
) ) );
931 for( i
= KEY_0
; i
<= KEY_9
; i
++ )
932 aKeyMap
[ i
] = rtl::OUString( sal_Unicode( '0' + (i
- KEY_0
) ) );
933 for( i
= KEY_F1
; i
<= KEY_F26
; i
++ )
935 rtl::OUStringBuffer
aKey( 3 );
936 aKey
.append( sal_Unicode( 'F' ) );
937 aKey
.append( sal_Int32( i
- KEY_F1
+ 1 ) );
938 aKeyMap
[ i
] = aKey
.makeStringAndClear();
941 aKeyMap
[ KEY_DOWN
] = rtl::OUString( sal_Unicode( 0x21e3 ) );
942 aKeyMap
[ KEY_UP
] = rtl::OUString( sal_Unicode( 0x21e1 ) );
943 aKeyMap
[ KEY_LEFT
] = rtl::OUString( sal_Unicode( 0x21e0 ) );
944 aKeyMap
[ KEY_RIGHT
] = rtl::OUString( sal_Unicode( 0x21e2 ) );
945 aKeyMap
[ KEY_HOME
] = rtl::OUString( sal_Unicode( 0x2196 ) );
946 aKeyMap
[ KEY_END
] = rtl::OUString( sal_Unicode( 0x2198 ) );
947 aKeyMap
[ KEY_PAGEUP
] = rtl::OUString( sal_Unicode( 0x21de ) );
948 aKeyMap
[ KEY_PAGEDOWN
] = rtl::OUString( sal_Unicode( 0x21df ) );
949 aKeyMap
[ KEY_RETURN
] = rtl::OUString( sal_Unicode( 0x21a9 ) );
950 aKeyMap
[ KEY_ESCAPE
] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "esc" ) );
951 aKeyMap
[ KEY_TAB
] = rtl::OUString( sal_Unicode( 0x21e5 ) );
952 aKeyMap
[ KEY_BACKSPACE
]= rtl::OUString( sal_Unicode( 0x232b ) );
953 aKeyMap
[ KEY_SPACE
] = rtl::OUString( sal_Unicode( 0x2423 ) );
954 aKeyMap
[ KEY_DELETE
] = rtl::OUString( sal_Unicode( 0x2326 ) );
955 aKeyMap
[ KEY_ADD
] = rtl::OUString( sal_Unicode( '+' ) );
956 aKeyMap
[ KEY_SUBTRACT
] = rtl::OUString( sal_Unicode( '-' ) );
957 aKeyMap
[ KEY_DIVIDE
] = rtl::OUString( sal_Unicode( '/' ) );
958 aKeyMap
[ KEY_MULTIPLY
] = rtl::OUString( sal_Unicode( '*' ) );
959 aKeyMap
[ KEY_POINT
] = rtl::OUString( sal_Unicode( '.' ) );
960 aKeyMap
[ KEY_COMMA
] = rtl::OUString( sal_Unicode( ',' ) );
961 aKeyMap
[ KEY_LESS
] = rtl::OUString( sal_Unicode( '<' ) );
962 aKeyMap
[ KEY_GREATER
] = rtl::OUString( sal_Unicode( '>' ) );
963 aKeyMap
[ KEY_EQUAL
] = rtl::OUString( sal_Unicode( '=' ) );
964 aKeyMap
[ KEY_OPEN
] = rtl::OUString( sal_Unicode( 0x23cf ) );
966 /* yet unmapped KEYCODES:
967 aKeyMap[ KEY_INSERT ] = rtl::OUString( sal_Unicode( ) );
968 aKeyMap[ KEY_CUT ] = rtl::OUString( sal_Unicode( ) );
969 aKeyMap[ KEY_COPY ] = rtl::OUString( sal_Unicode( ) );
970 aKeyMap[ KEY_PASTE ] = rtl::OUString( sal_Unicode( ) );
971 aKeyMap[ KEY_UNDO ] = rtl::OUString( sal_Unicode( ) );
972 aKeyMap[ KEY_REPEAT ] = rtl::OUString( sal_Unicode( ) );
973 aKeyMap[ KEY_FIND ] = rtl::OUString( sal_Unicode( ) );
974 aKeyMap[ KEY_PROPERTIES ] = rtl::OUString( sal_Unicode( ) );
975 aKeyMap[ KEY_FRONT ] = rtl::OUString( sal_Unicode( ) );
976 aKeyMap[ KEY_CONTEXTMENU ] = rtl::OUString( sal_Unicode( ) );
977 aKeyMap[ KEY_MENU ] = rtl::OUString( sal_Unicode( ) );
978 aKeyMap[ KEY_HELP ] = rtl::OUString( sal_Unicode( ) );
979 aKeyMap[ KEY_HANGUL_HANJA ] = rtl::OUString( sal_Unicode( ) );
980 aKeyMap[ KEY_DECIMAL ] = rtl::OUString( sal_Unicode( ) );
981 aKeyMap[ KEY_TILDE ] = rtl::OUString( sal_Unicode( ) );
982 aKeyMap[ KEY_QUOTELEFT ]= rtl::OUString( sal_Unicode( ) );
987 rtl::OUStringBuffer
aResult( 16 );
989 USHORT nUnmodifiedCode
= (nKeyCode
& KEY_CODE
);
990 std::map
< USHORT
, rtl::OUString
>::const_iterator it
= aKeyMap
.find( nUnmodifiedCode
);
991 if( it
!= aKeyMap
.end() )
993 if( (nKeyCode
& KEY_SHIFT
) != 0 )
994 aResult
.append( sal_Unicode( 0x21e7 ) );
995 if( (nKeyCode
& KEY_MOD1
) != 0 )
996 aResult
.append( sal_Unicode( 0x2318 ) );
997 // we do not really handle Alt (see below)
998 // we map it to MOD3, whichis actually Command
999 if( (nKeyCode
& (KEY_MOD2
|KEY_MOD3
)) != 0 )
1000 aResult
.append( sal_Unicode( 0x2303 ) );
1002 aResult
.append( it
->second
);
1005 return aResult
.makeStringAndClear();
1008 // -----------------------------------------------------------------------
1010 XubString
AquaSalFrame::GetSymbolKeyName( const XubString
&, USHORT nKeyCode
)
1012 return GetKeyName( nKeyCode
);
1015 // -----------------------------------------------------------------------
1017 static void getAppleScrollBarVariant(void)
1019 bool bIsScrollbarDoubleMax
= true; // default is DoubleMax
1021 CFStringRef AppleScrollBarType
= CFSTR("AppleScrollBarVariant");
1022 if( AppleScrollBarType
)
1024 CFStringRef ScrollBarVariant
= ((CFStringRef
)CFPreferencesCopyAppValue( AppleScrollBarType
, kCFPreferencesCurrentApplication
));
1025 if( ScrollBarVariant
)
1027 if( CFGetTypeID( ScrollBarVariant
) == CFStringGetTypeID() )
1029 // TODO: check for the less important variants "DoubleMin" and "DoubleBoth" too
1030 CFStringRef DoubleMax
= CFSTR("DoubleMax");
1033 if ( !CFStringCompare(ScrollBarVariant
, DoubleMax
, kCFCompareCaseInsensitive
) )
1034 bIsScrollbarDoubleMax
= true;
1036 bIsScrollbarDoubleMax
= false;
1037 CFRelease(DoubleMax
);
1040 CFRelease( ScrollBarVariant
);
1042 CFRelease(AppleScrollBarType
);
1045 GetSalData()->mbIsScrollbarDoubleMax
= bIsScrollbarDoubleMax
;
1047 CFStringRef jumpScroll
= CFSTR("AppleScrollerPagingBehavior");
1050 CFBooleanRef jumpStr
= ((CFBooleanRef
)CFPreferencesCopyAppValue( jumpScroll
, kCFPreferencesCurrentApplication
));
1053 if( CFGetTypeID( jumpStr
) == CFBooleanGetTypeID() )
1054 ImplGetSVData()->maNWFData
.mbScrollbarJumpPage
= (jumpStr
== kCFBooleanTrue
);
1055 CFRelease( jumpStr
);
1057 CFRelease( jumpScroll
);
1061 static Color
getColor( NSColor
* pSysColor
, const Color
& rDefault
, NSWindow
* pWin
)
1063 Color
aRet( rDefault
);
1067 NSColor
* pRBGColor
= [pSysColor colorUsingColorSpaceName
: NSDeviceRGBColorSpace device
: [pWin deviceDescription
]];
1070 float r
= 0, g
= 0, b
= 0, a
= 0;
1071 [pRBGColor getRed
: &r green
: &g blue
: &b alpha
: &a
];
1072 aRet
= Color( int(r
*255.999), int(g
*255.999), int(b
*255.999) );
1074 do not release here; leads to duplicate free in yield
1075 it seems the converted color comes out autoreleased, although this
1077 [pRBGColor release];
1084 static Font
getFont( NSFont
* pFont
, long nDPIY
, const Font
& rDefault
)
1086 Font
aResult( rDefault
);
1089 aResult
.SetName( GetOUString( [pFont familyName
] ) );
1090 aResult
.SetHeight( static_cast<int>(([pFont pointSize
] * 72.0 / (float)nDPIY
)+0.5) );
1091 aResult
.SetItalic( ([pFont italicAngle
] != 0.0) ? ITALIC_NORMAL
: ITALIC_NONE
);
1098 // on OSX-Aqua the style settings are independent of the frame, so it does
1099 // not really belong here. Since the connection to the Appearance_Manager
1100 // is currently done in salnativewidgets.cxx this would be a good place.
1101 // On the other hand VCL's platform independent code currently only asks
1102 // SalFrames for system settings anyway, so moving the code somewhere else
1103 // doesn't make the anything cleaner for now
1104 void AquaSalFrame::UpdateSettings( AllSettings
& rSettings
)
1108 StyleSettings aStyleSettings
= rSettings
.GetStyleSettings();
1111 Color aBackgroundColor
= Color( 0xEC, 0xEC, 0xEC );
1112 aStyleSettings
.Set3DColors( aBackgroundColor
);
1113 aStyleSettings
.SetFaceColor( aBackgroundColor
);
1114 Color
aInactiveTabColor( aBackgroundColor
);
1115 aInactiveTabColor
.DecreaseLuminance( 32 );
1116 aStyleSettings
.SetInactiveTabColor( aInactiveTabColor
);
1118 aStyleSettings
.SetDialogColor( aBackgroundColor
);
1119 aStyleSettings
.SetLightBorderColor( aBackgroundColor
);
1120 Color
aShadowColor( aStyleSettings
.GetShadowColor() );
1121 aStyleSettings
.SetDarkShadowColor( aShadowColor
);
1122 aShadowColor
.IncreaseLuminance( 32 );
1123 aStyleSettings
.SetShadowColor( aShadowColor
);
1125 // get the system font settings
1126 Font aAppFont
= aStyleSettings
.GetAppFont();
1130 ReleaseGraphics( mpGraphics
);
1132 long nDPIX
= 72, nDPIY
= 72;
1133 mpGraphics
->GetResolution( nDPIX
, nDPIY
);
1134 aAppFont
= getFont( [NSFont systemFontOfSize
: 0], nDPIY
, aAppFont
);
1136 // TODO: better mapping of aqua<->ooo font settings
1137 aStyleSettings
.SetAppFont( aAppFont
);
1138 aStyleSettings
.SetHelpFont( aAppFont
);
1139 aStyleSettings
.SetPushButtonFont( aAppFont
);
1141 Font
aTitleFont( getFont( [NSFont titleBarFontOfSize
: 0], nDPIY
, aAppFont
) );
1142 aStyleSettings
.SetTitleFont( aTitleFont
);
1143 aStyleSettings
.SetFloatTitleFont( aTitleFont
);
1145 Font
aMenuFont( getFont( [NSFont menuFontOfSize
: 0], nDPIY
, aAppFont
) );
1146 aStyleSettings
.SetMenuFont( aMenuFont
);
1148 aStyleSettings
.SetToolFont( aAppFont
);
1150 Font
aLabelFont( getFont( [NSFont labelFontOfSize
: 0], nDPIY
, aAppFont
) );
1151 aStyleSettings
.SetLabelFont( aLabelFont
);
1152 aStyleSettings
.SetInfoFont( aLabelFont
);
1153 aStyleSettings
.SetRadioCheckFont( aLabelFont
);
1154 aStyleSettings
.SetFieldFont( aLabelFont
);
1155 aStyleSettings
.SetGroupFont( aLabelFont
);
1156 aStyleSettings
.SetIconFont( aLabelFont
);
1158 Color
aHighlightColor( getColor( [NSColor selectedTextBackgroundColor
],
1159 aStyleSettings
.GetHighlightColor(), mpWindow
) );
1160 aStyleSettings
.SetHighlightColor( aHighlightColor
);
1161 Color
aHighlightTextColor( getColor( [NSColor selectedTextColor
],
1162 aStyleSettings
.GetHighlightTextColor(), mpWindow
) );
1163 aStyleSettings
.SetHighlightTextColor( aHighlightTextColor
);
1165 Color
aMenuHighlightColor( getColor( [NSColor selectedMenuItemColor
],
1166 aStyleSettings
.GetMenuHighlightColor(), mpWindow
) );
1167 aStyleSettings
.SetMenuHighlightColor( aMenuHighlightColor
);
1168 Color
aMenuHighlightTextColor( getColor( [NSColor selectedMenuItemTextColor
],
1169 aStyleSettings
.GetMenuHighlightTextColor(), mpWindow
) );
1170 aStyleSettings
.SetMenuHighlightTextColor( aMenuHighlightTextColor
);
1172 aStyleSettings
.SetMenuColor( aBackgroundColor
);
1173 Color
aMenuTextColor( getColor( [NSColor textColor
],
1174 aStyleSettings
.GetMenuTextColor(), mpWindow
) );
1175 aStyleSettings
.SetMenuTextColor( aMenuTextColor
);
1177 aStyleSettings
.SetCursorBlinkTime( 500 );
1179 // no mnemonics on aqua
1180 aStyleSettings
.SetOptions( aStyleSettings
.GetOptions() | STYLE_OPTION_NOMNEMONICS
);
1182 getAppleScrollBarVariant();
1184 // set scrollbar size
1185 aStyleSettings
.SetScrollBarSize( [NSScroller scrollerWidth
] );
1187 rSettings
.SetStyleSettings( aStyleSettings
);
1189 [mpView unlockFocus
];
1192 // -----------------------------------------------------------------------
1194 const SystemEnvData
* AquaSalFrame::GetSystemData() const
1199 // -----------------------------------------------------------------------
1201 void AquaSalFrame::Beep( SoundType eSoundType
)
1206 // -----------------------------------------------------------------------
1208 void AquaSalFrame::SetPosSize(long nX
, long nY
, long nWidth
, long nHeight
, USHORT nFlags
)
1212 if( [mpWindow isMiniaturized
] )
1213 [mpWindow deminiaturize
: NSApp
]; // expand the window
1215 if (nFlags
& (SAL_FRAME_POSSIZE_X
| SAL_FRAME_POSSIZE_Y
))
1217 mbPositioned
= true;
1218 nEvent
= SALEVENT_MOVE
;
1221 if (nFlags
& (SAL_FRAME_POSSIZE_WIDTH
| SAL_FRAME_POSSIZE_HEIGHT
))
1224 nEvent
= (nEvent
== SALEVENT_MOVE
) ? SALEVENT_MOVERESIZE
: SALEVENT_RESIZE
;
1227 NSRect aFrameRect
= [mpWindow frame
];
1228 NSRect aContentRect
= [NSWindow contentRectForFrameRect
: aFrameRect styleMask
: mnStyleMask
];
1230 // position is always relative to parent frame
1231 NSRect aParentContentRect
;
1235 if( Application::GetSettings().GetLayoutRTL() )
1237 if( (nFlags
& SAL_FRAME_POSSIZE_WIDTH
) != 0 )
1238 nX
= mpParent
->maGeometry
.nWidth
- nWidth
-1 - nX
;
1240 nX
= mpParent
->maGeometry
.nWidth
- aContentRect
.size
.width
-1 - nX
;
1242 NSRect aParentFrameRect
= [mpParent
->mpWindow frame
];
1243 aParentContentRect
= [NSWindow contentRectForFrameRect
: aParentFrameRect styleMask
: mpParent
->mnStyleMask
];
1246 aParentContentRect
= maScreenRect
; // use screen if no parent
1248 CocoaToVCL( aContentRect
);
1249 CocoaToVCL( aParentContentRect
);
1251 bool bPaint
= false;
1252 if( (nFlags
& (SAL_FRAME_POSSIZE_WIDTH
| SAL_FRAME_POSSIZE_HEIGHT
)) != 0 )
1254 if( nWidth
!= aContentRect
.size
.width
|| nHeight
!= aContentRect
.size
.height
)
1258 // use old window pos if no new pos requested
1259 if( (nFlags
& SAL_FRAME_POSSIZE_X
) != 0 )
1260 aContentRect
.origin
.x
= nX
+ aParentContentRect
.origin
.x
;
1261 if( (nFlags
& SAL_FRAME_POSSIZE_Y
) != 0)
1262 aContentRect
.origin
.y
= nY
+ aParentContentRect
.origin
.y
;
1264 // use old size if no new size requested
1265 if( (nFlags
& SAL_FRAME_POSSIZE_WIDTH
) != 0 )
1266 aContentRect
.size
.width
= nWidth
;
1267 if( (nFlags
& SAL_FRAME_POSSIZE_HEIGHT
) != 0)
1268 aContentRect
.size
.height
= nHeight
;
1270 VCLToCocoa( aContentRect
);
1272 // do not display yet, we need to update our backbuffer
1274 //YieldMutexReleaser aRel;
1275 [mpWindow setFrame
: [NSWindow frameRectForContentRect
: aContentRect styleMask
: mnStyleMask
] display
: NO
];
1278 UpdateFrameGeometry();
1281 CallCallback(nEvent
, NULL
);
1283 if( mbShown
&& bPaint
)
1285 // trigger filling our backbuffer
1288 // now inform the system that the views need to be drawn
1289 //YieldMutexReleaser aRel;
1294 void AquaSalFrame::GetWorkArea( Rectangle
& rRect
)
1296 NSScreen
* pScreen
= [mpWindow screen
];
1297 if( pScreen
== nil
)
1298 pScreen
= [NSScreen mainScreen
];
1299 NSRect aRect
= [pScreen visibleFrame
];
1300 CocoaToVCL( aRect
);
1301 rRect
.nLeft
= static_cast<long>(aRect
.origin
.x
);
1302 rRect
.nTop
= static_cast<long>(aRect
.origin
.y
);
1303 rRect
.nRight
= static_cast<long>(aRect
.origin
.x
+ aRect
.size
.width
- 1);
1304 rRect
.nBottom
= static_cast<long>(aRect
.origin
.y
+ aRect
.size
.height
- 1);
1307 SalPointerState
AquaSalFrame::GetPointerState()
1309 SalPointerState state
;
1312 NSPoint aPt
= [mpWindow mouseLocationOutsideOfEventStream
];
1313 CocoaToVCL( aPt
, false );
1314 state
.maPos
= Point(static_cast<long>(aPt
.x
), static_cast<long>(aPt
.y
));
1316 // FIXME: replace Carbon by Cocoa
1317 // Cocoa does not have an equivalent for GetCurrentEventButtonState
1318 // and GetCurrentEventKeyModifiers.
1319 // we could try to get away with tracking all events for modifierKeys
1320 // and all mouse events for button state in VCL_NSApllication::sendEvent,
1321 // but it is unclear whether this will get us the same result.
1322 // leave in GetCurrentEventButtonState and GetCurrentEventKeyModifiers for now
1324 // fill in button state
1325 UInt32 nState
= GetCurrentEventButtonState();
1328 state
.mnState
|= MOUSE_LEFT
; // primary button
1330 state
.mnState
|= MOUSE_RIGHT
; // secondary button
1332 state
.mnState
|= MOUSE_MIDDLE
; // tertiary button
1334 // fill in modifier state
1335 nState
= GetCurrentEventKeyModifiers();
1336 if( nState
& shiftKey
)
1337 state
.mnState
|= KEY_SHIFT
;
1338 if( nState
& controlKey
)
1339 state
.mnState
|= KEY_MOD3
;
1340 if( nState
& optionKey
)
1341 state
.mnState
|= KEY_MOD2
;
1342 if( nState
& cmdKey
)
1343 state
.mnState
|= KEY_MOD1
;
1348 SalFrame::SalIndicatorState
AquaSalFrame::GetIndicatorState()
1350 SalIndicatorState aState
;
1355 void AquaSalFrame::SimulateKeyPress( USHORT
/*nKeyCode*/ )
1359 bool AquaSalFrame::SetPluginParent( SystemParentData
* pNewParent
)
1361 // plugin parent may be killed unexpectedly by
1362 // plugging process;
1368 BOOL
AquaSalFrame::MapUnicodeToKeyCode( sal_Unicode
, LanguageType
, KeyCode
& )
1370 // not supported yet
1374 LanguageType
AquaSalFrame::GetInputLanguage()
1377 return LANGUAGE_DONTKNOW
;
1380 void AquaSalFrame::DrawMenuBar()
1384 void AquaSalFrame::SetMenu( SalMenu
* pSalMenu
)
1386 AquaSalMenu
* pMenu
= static_cast<AquaSalMenu
*>(pSalMenu
);
1387 DBG_ASSERT( ! pMenu
|| pMenu
->mbMenuBar
, "setting non menubar on frame" );
1390 mpMenu
->setMainMenu();
1393 void AquaSalFrame::SetExtendedFrameStyle( SalExtStyle nStyle
)
1395 if( (mnExtStyle
& SAL_FRAME_EXT_STYLE_DOCMODIFIED
) != (nStyle
& SAL_FRAME_EXT_STYLE_DOCMODIFIED
) )
1396 [mpWindow setDocumentEdited
: (nStyle
& SAL_FRAME_EXT_STYLE_DOCMODIFIED
) ? YES
: NO
];
1397 mnExtStyle
= nStyle
;
1400 void AquaSalFrame::SetBackgroundBitmap( SalBitmap
* )
1405 SalBitmap
* AquaSalFrame::SnapShot()
1407 return mpGraphics
? mpGraphics
->getBitmap( 0, 0, maGeometry
.nWidth
, maGeometry
.nHeight
) : NULL
;
1410 SalFrame
* AquaSalFrame::GetParent() const
1415 void AquaSalFrame::SetParent( SalFrame
* pNewParent
)
1417 bool bShown
= mbShown
;
1418 // remove from child list
1420 mpParent
= (AquaSalFrame
*)pNewParent
;
1421 // insert to correct parent and paint
1425 void AquaSalFrame::UpdateFrameGeometry()
1427 // keep in mind that view and window coordinates are lower left
1428 // whereas vcl's are upper left
1430 // update screen rect
1431 NSScreen
* pScreen
= [mpWindow screen
];
1434 maScreenRect
= [pScreen frame
];
1435 NSArray
* pScreens
= [NSScreen screens
];
1437 maGeometry
.nScreenNumber
= [pScreens indexOfObject
: pScreen
];
1440 NSRect aFrameRect
= [mpWindow frame
];
1441 NSRect aContentRect
= [NSWindow contentRectForFrameRect
: aFrameRect styleMask
: mnStyleMask
];
1443 // release old track rect
1444 [mpView removeTrackingRect
: mnTrackingRectTag
];
1445 // install the new track rect
1446 NSRect aTrackRect
= { { 0, 0 }, aContentRect
.size
};
1447 mnTrackingRectTag
= [mpView addTrackingRect
: aTrackRect owner
: mpView userData
: nil assumeInside
: NO
];
1449 // convert to vcl convention
1450 CocoaToVCL( aFrameRect
);
1451 CocoaToVCL( aContentRect
);
1453 maGeometry
.nX
= static_cast<int>(aContentRect
.origin
.x
);
1454 maGeometry
.nY
= static_cast<int>(aContentRect
.origin
.y
);
1456 maGeometry
.nLeftDecoration
= static_cast<unsigned int>(aContentRect
.origin
.x
- aFrameRect
.origin
.x
);
1457 maGeometry
.nRightDecoration
= static_cast<unsigned int>((aFrameRect
.origin
.x
+ aFrameRect
.size
.width
) -
1458 (aContentRect
.origin
.x
+ aContentRect
.size
.width
));
1460 maGeometry
.nTopDecoration
= static_cast<unsigned int>(aContentRect
.origin
.y
- aFrameRect
.origin
.y
);
1461 maGeometry
.nBottomDecoration
= static_cast<unsigned int>((aFrameRect
.origin
.y
+ aFrameRect
.size
.height
) -
1462 (aContentRect
.origin
.y
+ aContentRect
.size
.height
));
1464 maGeometry
.nWidth
= static_cast<unsigned int>(aContentRect
.size
.width
);
1465 maGeometry
.nHeight
= static_cast<unsigned int>(aContentRect
.size
.height
);
1468 // -----------------------------------------------------------------------
1470 void AquaSalFrame::CaptureMouse( BOOL bCapture
)
1473 we'll try to use a pidgin version of capture mouse
1474 on MacOSX (neither carbon nor cocoa) there is a
1475 CaptureMouse equivalent (in Carbon there is TrackMouseLocation
1476 but this is useless to use since it is blocking)
1478 However on cocoa the active frame seems to get mouse events
1479 also outside the window, so we'll try to forward mouse events
1480 to the capture frame in the hope that one of our frames
1483 This will break as soon as the user activates another app, but
1484 a mouse click will normally lead to a release of the mouse anyway.
1486 Let's see how far we get this way. Alternatively we could use one
1487 large overlay window like we did for the carbon implementation,
1488 however that is resource intensive.
1492 s_pCaptureFrame
= this;
1493 else if( ! bCapture
&& s_pCaptureFrame
== this )
1494 s_pCaptureFrame
= NULL
;
1497 void AquaSalFrame::ResetClipRegion()
1499 // release old path and indicate no clipping
1500 CGPathRelease( mrClippingPath
);
1501 mrClippingPath
= NULL
;
1503 if( mpView
&& mbShown
)
1504 [mpView setNeedsDisplay
: YES
];
1507 [mpWindow setOpaque
: YES
];
1508 [mpWindow invalidateShadow
];
1512 void AquaSalFrame::BeginSetClipRegion( ULONG nRects
)
1515 if( mrClippingPath
)
1517 CGPathRelease( mrClippingPath
);
1518 mrClippingPath
= NULL
;
1521 if( maClippingRects
.size() > SAL_CLIPRECT_COUNT
&& nRects
< maClippingRects
.size() )
1523 std::vector
<CGRect
> aEmptyVec
;
1524 maClippingRects
.swap( aEmptyVec
);
1526 maClippingRects
.clear();
1527 maClippingRects
.reserve( nRects
);
1530 void AquaSalFrame::UnionClipRegion( long nX
, long nY
, long nWidth
, long nHeight
)
1532 if( nWidth
&& nHeight
)
1534 NSRect aRect
= { { nX
, nY
}, { nWidth
, nHeight
} };
1535 VCLToCocoa( aRect
, false );
1536 maClippingRects
.push_back( CGRectMake(aRect
.origin
.x
, aRect
.origin
.y
, aRect
.size
.width
, aRect
.size
.height
) );
1540 void AquaSalFrame::EndSetClipRegion()
1542 if( ! maClippingRects
.empty() )
1544 mrClippingPath
= CGPathCreateMutable();
1545 CGPathAddRects( mrClippingPath
, NULL
, &maClippingRects
[0], maClippingRects
.size() );
1547 if( mpView
&& mbShown
)
1548 [mpView setNeedsDisplay
: YES
];
1551 [mpWindow setOpaque
: (mrClippingPath
!= NULL
) ? NO
: YES
];
1552 [mpWindow setBackgroundColor
: [NSColor clearColor
]];
1553 // shadow is invalidated when view gets drawn again