1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include "rtl/ustrbuf.hxx"
26 #include "vcl/svapp.hxx"
27 #include "vcl/window.hxx"
28 #include "vcl/syswin.hxx"
29 #include <vcl/settings.hxx>
31 #include "osx/saldata.hxx"
32 #include "quartz/salgdi.h"
33 #include "osx/salframe.h"
34 #include "osx/salmenu.h"
35 #include "osx/salinst.h"
36 #include "osx/salframeview.h"
37 #include "osx/a11yfactory.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 AquaSalFrame
* AquaSalFrame::s_pCaptureFrame
= NULL
;
53 AquaSalFrame::AquaSalFrame( SalFrame
* pParent
, sal_uLong salFrameStyle
) :
64 mbFullScreen( false ),
69 mbPresentation( false ),
70 mnStyle( salFrameStyle
),
73 mnLastModifierFlags( 0 ),
76 mePointerStyle( PointerStyle::Arrow
),
77 mnTrackingRectTag( 0 ),
79 mnICOptions( InputContextFlags::NONE
)
81 maSysData
.nSize
= sizeof( SystemEnvData
);
83 mpParent
= dynamic_cast<AquaSalFrame
*>(pParent
);
87 SalData
* pSalData
= GetSalData();
88 pSalData
->maFrames
.push_front( this );
89 pSalData
->maFrameCheck
.insert( this );
92 AquaSalFrame::~AquaSalFrame()
94 // if the frame is destroyed and has the current menubar
95 // set the default menubar
96 if( mpMenu
&& mpMenu
->mbMenuBar
&& AquaSalMenu::pCurrentMenuBar
== mpMenu
)
97 AquaSalMenu::setDefaultMenu();
99 // cleanup clipping stuff
102 [SalFrameView unsetMouseFrame
: this];
104 SalData
* pSalData
= GetSalData();
105 pSalData
->maFrames
.remove( this );
106 pSalData
->maFrameCheck
.erase( this );
107 pSalData
->maPresentationFrames
.remove( this );
109 DBG_ASSERT( this != s_pCaptureFrame
, "capture frame destroyed" );
110 if( this == s_pCaptureFrame
)
111 s_pCaptureFrame
= NULL
;
115 if( mpDockMenuEntry
)
116 // life cycle comment: the menu has ownership of the item, so no release
117 [AquaSalInstance::GetDynamicDockMenu() removeItem
: mpDockMenuEntry
];
119 [AquaA11yFactory revokeView
: mpNSView
];
123 [mpNSWindow release
];
126 void AquaSalFrame::initWindowAndView()
128 // initialize mirroring parameters
129 // FIXME: screens changing
130 NSScreen
* pNSScreen
= [mpNSWindow screen
];
131 if( pNSScreen
== nil
)
132 pNSScreen
= [NSScreen mainScreen
];
133 maScreenRect
= [pNSScreen frame
];
135 // calculate some default geometry
136 NSRect aVisibleRect
= [pNSScreen visibleFrame
];
137 CocoaToVCL( aVisibleRect
);
139 maGeometry
.nX
= static_cast<int>(aVisibleRect
.origin
.x
+ aVisibleRect
.size
.width
/ 10);
140 maGeometry
.nY
= static_cast<int>(aVisibleRect
.origin
.y
+ aVisibleRect
.size
.height
/ 10);
141 maGeometry
.nWidth
= static_cast<unsigned int>(aVisibleRect
.size
.width
* 0.8);
142 maGeometry
.nHeight
= static_cast<unsigned int>(aVisibleRect
.size
.height
* 0.8);
144 // calculate style mask
145 if( (mnStyle
& SAL_FRAME_STYLE_FLOAT
) ||
146 (mnStyle
& SAL_FRAME_STYLE_OWNERDRAWDECORATION
) )
147 mnStyleMask
= NSBorderlessWindowMask
;
148 else if( mnStyle
& SAL_FRAME_STYLE_DEFAULT
)
150 mnStyleMask
= NSTitledWindowMask
|
151 NSMiniaturizableWindowMask
|
152 NSResizableWindowMask
|
153 NSClosableWindowMask
;
154 // make default window "maximized"
155 maGeometry
.nX
= static_cast<int>(aVisibleRect
.origin
.x
);
156 maGeometry
.nY
= static_cast<int>(aVisibleRect
.origin
.y
);
157 maGeometry
.nWidth
= static_cast<int>(aVisibleRect
.size
.width
);
158 maGeometry
.nHeight
= static_cast<int>(aVisibleRect
.size
.height
);
159 mbPositioned
= mbSized
= true;
163 if( (mnStyle
& SAL_FRAME_STYLE_MOVEABLE
) )
165 mnStyleMask
|= NSTitledWindowMask
;
166 if( mpParent
== NULL
)
167 mnStyleMask
|= NSMiniaturizableWindowMask
;
169 if( (mnStyle
& SAL_FRAME_STYLE_SIZEABLE
) )
170 mnStyleMask
|= NSResizableWindowMask
;
171 if( (mnStyle
& SAL_FRAME_STYLE_CLOSEABLE
) )
172 mnStyleMask
|= NSClosableWindowMask
;
173 // documentation says anything other than NSBorderlessWindowMask (=0)
174 // should also include NSTitledWindowMask;
175 if( mnStyleMask
!= 0 )
176 mnStyleMask
|= NSTitledWindowMask
;
179 // #i91990# support GUI-less (daemon) execution
182 mpNSWindow
= [[SalFrameWindow alloc
] initWithSalFrame
: this];
183 mpNSView
= [[SalFrameView alloc
] initWithSalFrame
: this];
185 @
catch ( id exception
)
190 if( (mnStyle
& SAL_FRAME_STYLE_TOOLTIP
) )
191 [mpNSWindow setIgnoresMouseEvents
: YES
];
193 [mpNSWindow setAcceptsMouseMovedEvents
: YES
];
194 [mpNSWindow setHasShadow
: YES
];
196 [mpNSWindow setDelegate
: static_cast<id
<NSWindowDelegate
> >(mpNSWindow
)];
198 if( [mpNSWindow respondsToSelector
: @
selector(setRestorable
:)])
200 objc_msgSend(mpNSWindow
, @
selector(setRestorable
:), NO
);
202 const NSRect aRect
= { NSZeroPoint
, NSMakeSize( maGeometry
.nWidth
, maGeometry
.nHeight
)};
203 mnTrackingRectTag
= [mpNSView addTrackingRect
: aRect owner
: mpNSView userData
: nil assumeInside
: NO
];
205 maSysData
.mpNSView
= mpNSView
;
207 UpdateFrameGeometry();
209 [mpNSWindow setContentView
: mpNSView
];
212 void AquaSalFrame::CocoaToVCL( NSRect
& io_rRect
, bool bRelativeToScreen
)
214 if( bRelativeToScreen
)
215 io_rRect
.origin
.y
= maScreenRect
.size
.height
- (io_rRect
.origin
.y
+io_rRect
.size
.height
);
217 io_rRect
.origin
.y
= maGeometry
.nHeight
- (io_rRect
.origin
.y
+io_rRect
.size
.height
);
220 void AquaSalFrame::VCLToCocoa( NSRect
& io_rRect
, bool bRelativeToScreen
)
222 if( bRelativeToScreen
)
223 io_rRect
.origin
.y
= maScreenRect
.size
.height
- (io_rRect
.origin
.y
+io_rRect
.size
.height
);
225 io_rRect
.origin
.y
= maGeometry
.nHeight
- (io_rRect
.origin
.y
+io_rRect
.size
.height
);
228 void AquaSalFrame::CocoaToVCL( NSPoint
& io_rPoint
, bool bRelativeToScreen
)
230 if( bRelativeToScreen
)
231 io_rPoint
.y
= maScreenRect
.size
.height
- io_rPoint
.y
;
233 io_rPoint
.y
= maGeometry
.nHeight
- io_rPoint
.y
;
236 void AquaSalFrame::VCLToCocoa( NSPoint
& io_rPoint
, bool bRelativeToScreen
)
238 if( bRelativeToScreen
)
239 io_rPoint
.y
= maScreenRect
.size
.height
- io_rPoint
.y
;
241 io_rPoint
.y
= maGeometry
.nHeight
- io_rPoint
.y
;
244 void AquaSalFrame::screenParametersChanged()
246 UpdateFrameGeometry();
249 mpGraphics
->updateResolution();
250 CallCallback( SALEVENT_DISPLAYCHANGED
, 0 );
253 SalGraphics
* AquaSalFrame::AcquireGraphics()
260 mpGraphics
= new AquaSalGraphics
;
261 mpGraphics
->SetWindowGraphics( this );
268 void AquaSalFrame::ReleaseGraphics( SalGraphics
*pGraphics
)
271 DBG_ASSERT( pGraphics
== mpGraphics
, "graphics released on wrong frame" );
275 bool AquaSalFrame::PostEvent( void *pData
)
277 GetSalData()->mpFirstInstance
->PostUserEvent( this, SALEVENT_USEREVENT
, pData
);
281 void AquaSalFrame::SetTitle(const OUString
& rTitle
)
286 // #i113170# may not be the main thread if called from UNO API
287 SalData::ensureThreadAutoreleasePool();
289 NSString
* pTitle
= CreateNSString( rTitle
);
290 [mpNSWindow setTitle
: pTitle
];
292 // create an entry in the dock menu
293 const sal_uLong nAppWindowStyle
= (SAL_FRAME_STYLE_CLOSEABLE
| SAL_FRAME_STYLE_MOVEABLE
);
294 if( mpParent
== NULL
&&
295 (mnStyle
& nAppWindowStyle
) == nAppWindowStyle
)
297 if( mpDockMenuEntry
== NULL
)
299 NSMenu
* pDock
= AquaSalInstance::GetDynamicDockMenu();
300 mpDockMenuEntry
= [pDock insertItemWithTitle
: pTitle
301 action
: @
selector(dockMenuItemTriggered
:)
304 [mpDockMenuEntry setTarget
: mpNSWindow
];
306 // TODO: image (either the generic window image or an icon
307 // check mark (for "main" window ?)
310 [mpDockMenuEntry setTitle
: pTitle
];
317 void AquaSalFrame::SetIcon( sal_uInt16
)
321 void AquaSalFrame::SetRepresentedURL( const OUString
& i_rDocURL
)
323 // #i113170# may not be the main thread if called from UNO API
324 SalData::ensureThreadAutoreleasePool();
326 if( i_rDocURL
.startsWith( "file:" ) )
329 osl_getSystemPathFromFileURL( i_rDocURL
.pData
, &aSysPath
.pData
);
330 NSString
* pStr
= CreateNSString( aSysPath
);
334 [mpNSWindow setRepresentedFilename
: pStr
];
339 void AquaSalFrame::initShow()
342 if( ! mbPositioned
&& ! mbFullScreen
)
344 Rectangle aScreenRect
;
345 GetWorkArea( aScreenRect
);
346 if( mpParent
) // center relative to parent
349 long nNewX
= mpParent
->maGeometry
.nX
+ ((long)mpParent
->maGeometry
.nWidth
- (long)maGeometry
.nWidth
)/2;
350 if( nNewX
< aScreenRect
.Left() )
351 nNewX
= aScreenRect
.Left();
352 if( long(nNewX
+ maGeometry
.nWidth
) > aScreenRect
.Right() )
353 nNewX
= aScreenRect
.Right() - maGeometry
.nWidth
-1;
354 long nNewY
= mpParent
->maGeometry
.nY
+ ((long)mpParent
->maGeometry
.nHeight
- (long)maGeometry
.nHeight
)/2;
355 if( nNewY
< aScreenRect
.Top() )
356 nNewY
= aScreenRect
.Top();
357 if( nNewY
> aScreenRect
.Bottom() )
358 nNewY
= aScreenRect
.Bottom() - maGeometry
.nHeight
-1;
359 SetPosSize( nNewX
- mpParent
->maGeometry
.nX
,
360 nNewY
- mpParent
->maGeometry
.nY
,
361 0, 0, SAL_FRAME_POSSIZE_X
| SAL_FRAME_POSSIZE_Y
);
363 else if( ! (mnStyle
& SAL_FRAME_STYLE_SIZEABLE
) )
366 long nNewX
= (aScreenRect
.GetWidth() - maGeometry
.nWidth
)/2;
367 long nNewY
= (aScreenRect
.GetHeight() - maGeometry
.nHeight
)/2;
368 SetPosSize( nNewX
, nNewY
, 0, 0, SAL_FRAME_POSSIZE_X
| SAL_FRAME_POSSIZE_Y
);
372 // make sure the view is present in the wrapper list before any children receive focus
373 [AquaA11yFactory registerView
: mpNSView
];
376 void AquaSalFrame::SendPaintEvent( const Rectangle
* pRect
)
378 SalPaintEvent
aPaintEvt( 0, 0, maGeometry
.nWidth
, maGeometry
.nHeight
, true );
381 aPaintEvt
.mnBoundX
= pRect
->Left();
382 aPaintEvt
.mnBoundY
= pRect
->Top();
383 aPaintEvt
.mnBoundWidth
= pRect
->GetWidth();
384 aPaintEvt
.mnBoundHeight
= pRect
->GetHeight();
387 CallCallback(SALEVENT_PAINT
, &aPaintEvt
);
390 void AquaSalFrame::Show(bool bVisible
, bool bNoActivate
)
395 // #i113170# may not be the main thread if called from UNO API
396 SalData::ensureThreadAutoreleasePool();
404 CallCallback(SALEVENT_RESIZE
, 0);
405 // trigger filling our backbuffer
408 if( bNoActivate
|| [mpNSWindow canBecomeKeyWindow
] == NO
)
409 [mpNSWindow orderFront
: NSApp
];
411 [mpNSWindow makeKeyAndOrderFront
: NSApp
];
415 /* #i92674# #i96433# we do not want an invisible parent to show up (which adding a visible
416 child implicitly does). However we also do not want a parentless toolbar.
418 HACK: try to decide when we should not insert a child to its parent
419 floaters and ownerdraw windows have not yet shown up in cases where
420 we don't want the parent to become visible
422 if( mpParent
->mbShown
|| (mnStyle
& (SAL_FRAME_STYLE_OWNERDRAWDECORATION
| SAL_FRAME_STYLE_FLOAT
) ) )
424 [mpParent
->mpNSWindow addChildWindow
: mpNSWindow ordered
: NSWindowAbove
];
429 [mpNSWindow makeMainWindow
];
433 // if the frame holding the current menubar gets hidden
434 // show the default menubar
435 if( mpMenu
&& mpMenu
->mbMenuBar
&& AquaSalMenu::pCurrentMenuBar
== mpMenu
)
436 AquaSalMenu::setDefaultMenu();
438 // #i90440# #i94443# work around the focus going back to some other window
439 // if a child gets hidden for a parent window
440 if( mpParent
&& mpParent
->mbShown
&& [mpNSWindow isKeyWindow
] )
441 [mpParent
->mpNSWindow makeKeyAndOrderFront
: NSApp
];
443 [SalFrameView unsetMouseFrame
: this];
444 if( mpParent
&& [mpNSWindow parentWindow
] == mpParent
->mpNSWindow
)
445 [mpParent
->mpNSWindow removeChildWindow
: mpNSWindow
];
447 [mpNSWindow orderOut
: NSApp
];
451 void AquaSalFrame::SetMinClientSize( long nWidth
, long nHeight
)
453 // #i113170# may not be the main thread if called from UNO API
454 SalData::ensureThreadAutoreleasePool();
457 mnMinHeight
= nHeight
;
461 // Always add the decoration as the dimension concerns only
462 // the content rectangle
463 nWidth
+= maGeometry
.nLeftDecoration
+ maGeometry
.nRightDecoration
;
464 nHeight
+= maGeometry
.nTopDecoration
+ maGeometry
.nBottomDecoration
;
466 NSSize aSize
= { static_cast<CGFloat
>(nWidth
), static_cast<CGFloat
>(nHeight
) };
468 // Size of full window (content+structure) although we only
469 // have the client size in arguments
470 [mpNSWindow setMinSize
: aSize
];
474 void AquaSalFrame::SetMaxClientSize( long nWidth
, long nHeight
)
476 // #i113170# may not be the main thread if called from UNO API
477 SalData::ensureThreadAutoreleasePool();
480 mnMaxHeight
= nHeight
;
484 // Always add the decoration as the dimension concerns only
485 // the content rectangle
486 nWidth
+= maGeometry
.nLeftDecoration
+ maGeometry
.nRightDecoration
;
487 nHeight
+= maGeometry
.nTopDecoration
+ maGeometry
.nBottomDecoration
;
489 // Carbon windows can't have a size greater than 32767x32767
490 if (nWidth
>32767) nWidth
=32767;
491 if (nHeight
>32767) nHeight
=32767;
493 NSSize aSize
= { static_cast<CGFloat
>(nWidth
), static_cast<CGFloat
>(nHeight
) };
495 // Size of full window (content+structure) although we only
496 // have the client size in arguments
497 [mpNSWindow setMaxSize
: aSize
];
501 void AquaSalFrame::GetClientSize( long& rWidth
, long& rHeight
)
503 if( mbShown
|| mbInitShow
)
505 rWidth
= maGeometry
.nWidth
;
506 rHeight
= maGeometry
.nHeight
;
515 void AquaSalFrame::SetWindowState( const SalFrameState
* pState
)
517 // #i113170# may not be the main thread if called from UNO API
518 SalData::ensureThreadAutoreleasePool();
523 NSRect aStateRect
= [mpNSWindow frame
];
524 aStateRect
= [NSWindow contentRectForFrameRect
: aStateRect styleMask
: mnStyleMask
];
525 CocoaToVCL( aStateRect
);
526 if( pState
->mnMask
& WINDOWSTATE_MASK_X
)
527 aStateRect
.origin
.x
= float(pState
->mnX
);
528 if( pState
->mnMask
& WINDOWSTATE_MASK_Y
)
529 aStateRect
.origin
.y
= float(pState
->mnY
);
530 if( pState
->mnMask
& WINDOWSTATE_MASK_WIDTH
)
531 aStateRect
.size
.width
= float(pState
->mnWidth
);
532 if( pState
->mnMask
& WINDOWSTATE_MASK_HEIGHT
)
533 aStateRect
.size
.height
= float(pState
->mnHeight
);
534 VCLToCocoa( aStateRect
);
535 aStateRect
= [NSWindow frameRectForContentRect
: aStateRect styleMask
: mnStyleMask
];
537 [mpNSWindow setFrame
: aStateRect display
: NO
];
538 if( pState
->mnState
== WINDOWSTATE_STATE_MINIMIZED
)
539 [mpNSWindow miniaturize
: NSApp
];
540 else if( [mpNSWindow isMiniaturized
] )
541 [mpNSWindow deminiaturize
: NSApp
];
543 /* ZOOMED is not really maximized (actually it toggles between a user set size and
544 the program specified one), but comes closest since the default behavior is
545 "maximized" if the user did not intervene
547 if( pState
->mnState
== WINDOWSTATE_STATE_MAXIMIZED
)
549 if(! [mpNSWindow isZoomed
])
550 [mpNSWindow zoom
: NSApp
];
554 if( [mpNSWindow isZoomed
] )
555 [mpNSWindow zoom
: NSApp
];
560 UpdateFrameGeometry();
562 sal_uInt16 nEvent
= 0;
563 if( pState
->mnMask
& (WINDOWSTATE_MASK_X
| WINDOWSTATE_MASK_Y
) )
566 nEvent
= SALEVENT_MOVE
;
569 if( pState
->mnMask
& (WINDOWSTATE_MASK_WIDTH
| WINDOWSTATE_MASK_HEIGHT
) )
572 nEvent
= (nEvent
== SALEVENT_MOVE
) ? SALEVENT_MOVERESIZE
: SALEVENT_RESIZE
;
574 // send event that we were moved/sized
576 CallCallback( nEvent
, NULL
);
578 if( mbShown
&& mpNSWindow
)
580 // trigger filling our backbuffer
583 // tell the system the views need to be updated
584 [mpNSWindow display
];
588 bool AquaSalFrame::GetWindowState( SalFrameState
* pState
)
593 // #i113170# may not be the main thread if called from UNO API
594 SalData::ensureThreadAutoreleasePool();
596 pState
->mnMask
= WINDOWSTATE_MASK_X
|
598 WINDOWSTATE_MASK_WIDTH
|
599 WINDOWSTATE_MASK_HEIGHT
|
600 WINDOWSTATE_MASK_STATE
;
602 NSRect aStateRect
= [mpNSWindow frame
];
603 aStateRect
= [NSWindow contentRectForFrameRect
: aStateRect styleMask
: mnStyleMask
];
604 CocoaToVCL( aStateRect
);
605 pState
->mnX
= long(aStateRect
.origin
.x
);
606 pState
->mnY
= long(aStateRect
.origin
.y
);
607 pState
->mnWidth
= long(aStateRect
.size
.width
);
608 pState
->mnHeight
= long(aStateRect
.size
.height
);
610 if( [mpNSWindow isMiniaturized
] )
611 pState
->mnState
= WINDOWSTATE_STATE_MINIMIZED
;
612 else if( ! [mpNSWindow isZoomed
] )
613 pState
->mnState
= WINDOWSTATE_STATE_NORMAL
;
615 pState
->mnState
= WINDOWSTATE_STATE_MAXIMIZED
;
620 void AquaSalFrame::SetScreenNumber(unsigned int nScreen
)
625 // #i113170# may not be the main thread if called from UNO API
626 SalData::ensureThreadAutoreleasePool();
628 NSArray
* pScreens
= [NSScreen screens
];
629 NSScreen
* pScreen
= nil
;
630 if( pScreens
&& nScreen
< [pScreens count
] )
632 // get new screen frame
633 pScreen
= [pScreens objectAtIndex
: nScreen
];
634 NSRect aNewScreen
= [pScreen frame
];
636 // get current screen frame
637 pScreen
= [mpNSWindow screen
];
640 NSRect aCurScreen
= [pScreen frame
];
641 if( aCurScreen
.origin
.x
!= aNewScreen
.origin
.x
||
642 aCurScreen
.origin
.y
!= aNewScreen
.origin
.y
)
644 NSRect aFrameRect
= [mpNSWindow frame
];
645 aFrameRect
.origin
.x
+= aNewScreen
.origin
.x
- aCurScreen
.origin
.x
;
646 aFrameRect
.origin
.y
+= aNewScreen
.origin
.y
- aCurScreen
.origin
.y
;
647 [mpNSWindow setFrame
: aFrameRect display
: NO
];
648 UpdateFrameGeometry();
654 void AquaSalFrame::SetApplicationID( const OUString
&/*rApplicationID*/ )
658 void AquaSalFrame::ShowFullScreen( bool bFullScreen
, sal_Int32 nDisplay
)
663 // #i113170# may not be the main thread if called from UNO API
664 SalData::ensureThreadAutoreleasePool();
666 SAL_INFO("vcl.osx", OSL_THIS_FUNC
<< ": mbFullScreen=" << mbFullScreen
<< ", bFullScreen=" << bFullScreen
);
668 if( mbFullScreen
== bFullScreen
)
671 mbFullScreen
= bFullScreen
;
675 // hide the dock and the menubar if we are on the menu screen
676 // which is always on index 0 according to documentation
677 bool bHideMenu
= (nDisplay
== 0);
679 NSRect aNewContentRect
= NSZeroRect
;
680 // get correct screen
681 NSScreen
* pScreen
= nil
;
682 NSArray
* pScreens
= [NSScreen screens
];
685 if( nDisplay
>= 0 && (unsigned int)nDisplay
< [pScreens count
] )
686 pScreen
= [pScreens objectAtIndex
: nDisplay
];
689 // this means span all screens
691 NSEnumerator
* pEnum
= [pScreens objectEnumerator
];
692 while( (pScreen
= [pEnum nextObject
]) != nil
)
694 NSRect aScreenRect
= [pScreen frame
];
695 if( aScreenRect
.origin
.x
< aNewContentRect
.origin
.x
)
697 aNewContentRect
.size
.width
+= aNewContentRect
.origin
.x
- aScreenRect
.origin
.x
;
698 aNewContentRect
.origin
.x
= aScreenRect
.origin
.x
;
700 if( aScreenRect
.origin
.y
< aNewContentRect
.origin
.y
)
702 aNewContentRect
.size
.height
+= aNewContentRect
.origin
.y
- aScreenRect
.origin
.y
;
703 aNewContentRect
.origin
.y
= aScreenRect
.origin
.y
;
705 if( aScreenRect
.origin
.x
+ aScreenRect
.size
.width
> aNewContentRect
.origin
.x
+ aNewContentRect
.size
.width
)
706 aNewContentRect
.size
.width
= aScreenRect
.origin
.x
+ aScreenRect
.size
.width
- aNewContentRect
.origin
.x
;
707 if( aScreenRect
.origin
.y
+ aScreenRect
.size
.height
> aNewContentRect
.origin
.y
+ aNewContentRect
.size
.height
)
708 aNewContentRect
.size
.height
= aScreenRect
.origin
.y
+ aScreenRect
.size
.height
- aNewContentRect
.origin
.y
;
712 if( aNewContentRect
.size
.width
== 0 && aNewContentRect
.size
.height
== 0 )
715 pScreen
= [mpNSWindow screen
];
717 pScreen
= [NSScreen mainScreen
];
719 aNewContentRect
= [pScreen frame
];
723 [NSMenu setMenuBarVisible
:NO
];
725 maFullScreenRect
= [mpNSWindow frame
];
727 [mpNSWindow setFrame
: [NSWindow frameRectForContentRect
: aNewContentRect styleMask
: mnStyleMask
] display
: mbShown
? YES
: NO
];
730 UpdateFrameGeometry();
733 CallCallback( SALEVENT_MOVERESIZE
, NULL
);
738 [mpNSWindow setFrame
: maFullScreenRect display
: mbShown
? YES
: NO
];
740 UpdateFrameGeometry();
743 CallCallback( SALEVENT_MOVERESIZE
, NULL
);
745 // show the dock and the menubar
746 [NSMenu setMenuBarVisible
:YES
];
749 // trigger filling our backbuffer
753 void AquaSalFrame::StartPresentation( bool bStart
)
758 // #i113170# may not be the main thread if called from UNO API
759 SalData::ensureThreadAutoreleasePool();
763 GetSalData()->maPresentationFrames
.push_back( this );
764 IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep
,
765 kIOPMAssertionLevelOn
,
766 CFSTR("LibreOffice presentation running"),
768 [mpNSWindow setLevel
: NSPopUpMenuWindowLevel
];
770 [mpNSWindow makeMainWindow
];
774 GetSalData()->maPresentationFrames
.remove( this );
775 IOPMAssertionRelease(mnAssertionID
);
776 [mpNSWindow setLevel
: NSNormalWindowLevel
];
780 void AquaSalFrame::SetAlwaysOnTop( bool )
784 void AquaSalFrame::ToTop(sal_uInt16 nFlags
)
789 // #i113170# may not be the main thread if called from UNO API
790 SalData::ensureThreadAutoreleasePool();
792 if( ! (nFlags
& SAL_FRAME_TOTOP_RESTOREWHENMIN
) )
794 if( ! [mpNSWindow isVisible
] || [mpNSWindow isMiniaturized
] )
797 if( nFlags
& SAL_FRAME_TOTOP_GRABFOCUS
)
798 [mpNSWindow makeKeyAndOrderFront
: NSApp
];
800 [mpNSWindow orderFront
: NSApp
];
803 NSCursor
* AquaSalFrame::getCurrentCursor() const
805 NSCursor
* pCursor
= nil
;
806 switch( mePointerStyle
)
808 case PointerStyle::Text
: pCursor
= [NSCursor IBeamCursor
]; break;
809 case PointerStyle::Cross
: pCursor
= [NSCursor crosshairCursor
]; break;
810 case PointerStyle::Hand
:
811 case PointerStyle::Move
: pCursor
= [NSCursor openHandCursor
]; break;
812 case PointerStyle::NSize
: pCursor
= [NSCursor resizeUpCursor
]; break;
813 case PointerStyle::SSize
: pCursor
= [NSCursor resizeDownCursor
]; break;
814 case PointerStyle::ESize
: pCursor
= [NSCursor resizeRightCursor
]; break;
815 case PointerStyle::WSize
: pCursor
= [NSCursor resizeLeftCursor
]; break;
816 case PointerStyle::Arrow
: pCursor
= [NSCursor arrowCursor
]; break;
817 case PointerStyle::VSplit
:
818 case PointerStyle::VSizeBar
:
819 case PointerStyle::WindowNSize
:
820 case PointerStyle::WindowSSize
:
821 pCursor
= [NSCursor resizeUpDownCursor
]; break;
822 case PointerStyle::HSplit
:
823 case PointerStyle::HSizeBar
:
824 case PointerStyle::WindowESize
:
825 case PointerStyle::WindowWSize
:
826 pCursor
= [NSCursor resizeLeftRightCursor
]; break;
827 case PointerStyle::RefHand
: pCursor
= [NSCursor pointingHandCursor
]; break;
830 pCursor
= GetSalData()->getCursor( mePointerStyle
);
833 OSL_FAIL( "unmapped cursor" );
834 pCursor
= [NSCursor arrowCursor
];
841 void AquaSalFrame::SetPointer( PointerStyle ePointerStyle
)
846 // #i113170# may not be the main thread if called from UNO API
847 SalData::ensureThreadAutoreleasePool();
849 if( ePointerStyle
== mePointerStyle
)
851 mePointerStyle
= ePointerStyle
;
853 [mpNSWindow invalidateCursorRectsForView
: mpNSView
];
856 void AquaSalFrame::SetPointerPos( long nX
, long nY
)
858 // FIXME: use Cocoa functions
860 // FIXME: multiscreen support
861 CGPoint aPoint
= { static_cast<CGFloat
>(nX
+ maGeometry
.nX
), static_cast<CGFloat
>(nY
+ maGeometry
.nY
) };
862 CGDirectDisplayID mainDisplayID
= CGMainDisplayID();
863 CGDisplayMoveCursorToPoint( mainDisplayID
, aPoint
);
866 void AquaSalFrame::Flush()
868 if( !(mbGraphics
&& mpGraphics
&& mpNSView
&& mbShown
) )
871 // #i113170# may not be the main thread if called from UNO API
872 SalData::ensureThreadAutoreleasePool();
874 [mpNSView setNeedsDisplay
: YES
];
876 // outside of the application's event loop (e.g. IntroWindow)
877 // nothing would trigger paint event handling
878 // => fall back to synchronous painting
879 if( ImplGetSVData()->maAppData
.mnDispatchLevel
<= 0 )
885 void AquaSalFrame::Flush( const Rectangle
& rRect
)
887 if( !(mbGraphics
&& mpGraphics
&& mpNSView
&& mbShown
) )
890 // #i113170# may not be the main thread if called from UNO API
891 SalData::ensureThreadAutoreleasePool();
893 NSRect aNSRect
= { { static_cast<CGFloat
>(rRect
.Left()), static_cast<CGFloat
>(rRect
.Top()) }, { static_cast<CGFloat
>(rRect
.GetWidth()), static_cast<CGFloat
>(rRect
.GetHeight()) } };
894 VCLToCocoa( aNSRect
, false );
895 [mpNSView setNeedsDisplayInRect
: aNSRect
];
897 // outside of the application's event loop (e.g. IntroWindow)
898 // nothing would trigger paint event handling
899 // => fall back to synchronous painting
900 if( ImplGetSVData()->maAppData
.mnDispatchLevel
<= 0 )
906 void AquaSalFrame::Sync()
908 if( mbGraphics
&& mpGraphics
&& mpNSView
&& mbShown
)
910 // #i113170# may not be the main thread if called from UNO API
911 SalData::ensureThreadAutoreleasePool();
913 [mpNSView setNeedsDisplay
: YES
];
918 void AquaSalFrame::SetInputContext( SalInputContext
* pContext
)
922 mnICOptions
= InputContextFlags::NONE
;
926 mnICOptions
= pContext
->mnOptions
;
928 if(!(pContext
->mnOptions
& InputContextFlags::Text
))
932 void AquaSalFrame::EndExtTextInput( sal_uInt16
)
936 OUString
AquaSalFrame::GetKeyName( sal_uInt16 nKeyCode
)
938 static std::map
< sal_uInt16
, OUString
> aKeyMap
;
939 if( aKeyMap
.empty() )
942 for( i
= KEY_A
; i
<= KEY_Z
; i
++ )
943 aKeyMap
[ i
] = OUString( sal_Unicode( 'A' + (i
- KEY_A
) ) );
944 for( i
= KEY_0
; i
<= KEY_9
; i
++ )
945 aKeyMap
[ i
] = OUString( sal_Unicode( '0' + (i
- KEY_0
) ) );
946 for( i
= KEY_F1
; i
<= KEY_F26
; i
++ )
948 OUStringBuffer
aKey( 3 );
950 aKey
.append( sal_Int32( i
- KEY_F1
+ 1 ) );
951 aKeyMap
[ i
] = aKey
.makeStringAndClear();
954 aKeyMap
[ KEY_DOWN
] = OUString( sal_Unicode( 0x21e3 ) );
955 aKeyMap
[ KEY_UP
] = OUString( sal_Unicode( 0x21e1 ) );
956 aKeyMap
[ KEY_LEFT
] = OUString( sal_Unicode( 0x21e0 ) );
957 aKeyMap
[ KEY_RIGHT
] = OUString( sal_Unicode( 0x21e2 ) );
958 aKeyMap
[ KEY_HOME
] = OUString( sal_Unicode( 0x2196 ) );
959 aKeyMap
[ KEY_END
] = OUString( sal_Unicode( 0x2198 ) );
960 aKeyMap
[ KEY_PAGEUP
] = OUString( sal_Unicode( 0x21de ) );
961 aKeyMap
[ KEY_PAGEDOWN
] = OUString( sal_Unicode( 0x21df ) );
962 aKeyMap
[ KEY_RETURN
] = OUString( sal_Unicode( 0x21a9 ) );
963 aKeyMap
[ KEY_ESCAPE
] = "esc";
964 aKeyMap
[ KEY_TAB
] = OUString( sal_Unicode( 0x21e5 ) );
965 aKeyMap
[ KEY_BACKSPACE
]= OUString( sal_Unicode( 0x232b ) );
966 aKeyMap
[ KEY_SPACE
] = OUString( sal_Unicode( 0x2423 ) );
967 aKeyMap
[ KEY_DELETE
] = OUString( sal_Unicode( 0x2326 ) );
968 aKeyMap
[ KEY_ADD
] = "+";
969 aKeyMap
[ KEY_SUBTRACT
] = "-";
970 aKeyMap
[ KEY_DIVIDE
] = "/";
971 aKeyMap
[ KEY_MULTIPLY
] = "*";
972 aKeyMap
[ KEY_POINT
] = ".";
973 aKeyMap
[ KEY_COMMA
] = ",";
974 aKeyMap
[ KEY_LESS
] = "<";
975 aKeyMap
[ KEY_GREATER
] = ">";
976 aKeyMap
[ KEY_EQUAL
] = "=";
977 aKeyMap
[ KEY_OPEN
] = OUString( sal_Unicode( 0x23cf ) );
978 aKeyMap
[ KEY_TILDE
] = "~";
979 aKeyMap
[ KEY_BRACKETLEFT
] = "[";
980 aKeyMap
[ KEY_BRACKETRIGHT
] = "]";
981 aKeyMap
[ KEY_SEMICOLON
] = ";";
982 aKeyMap
[ KEY_QUOTERIGHT
] = "'";
984 /* yet unmapped KEYCODES:
985 aKeyMap[ KEY_INSERT ] = OUString( sal_Unicode( ) );
986 aKeyMap[ KEY_CUT ] = OUString( sal_Unicode( ) );
987 aKeyMap[ KEY_COPY ] = OUString( sal_Unicode( ) );
988 aKeyMap[ KEY_PASTE ] = OUString( sal_Unicode( ) );
989 aKeyMap[ KEY_UNDO ] = OUString( sal_Unicode( ) );
990 aKeyMap[ KEY_REPEAT ] = OUString( sal_Unicode( ) );
991 aKeyMap[ KEY_FIND ] = OUString( sal_Unicode( ) );
992 aKeyMap[ KEY_PROPERTIES ] = OUString( sal_Unicode( ) );
993 aKeyMap[ KEY_FRONT ] = OUString( sal_Unicode( ) );
994 aKeyMap[ KEY_CONTEXTMENU ] = OUString( sal_Unicode( ) );
995 aKeyMap[ KEY_MENU ] = OUString( sal_Unicode( ) );
996 aKeyMap[ KEY_HELP ] = OUString( sal_Unicode( ) );
997 aKeyMap[ KEY_HANGUL_HANJA ] = OUString( sal_Unicode( ) );
998 aKeyMap[ KEY_DECIMAL ] = OUString( sal_Unicode( ) );
999 aKeyMap[ KEY_QUOTELEFT ]= OUString( sal_Unicode( ) );
1000 aKeyMap[ KEY_CAPSLOCK ]= OUString( sal_Unicode( ) );
1001 aKeyMap[ KEY_NUMLOCK ]= OUString( sal_Unicode( ) );
1002 aKeyMap[ KEY_SCROLLLOCK ]= OUString( sal_Unicode( ) );
1007 OUStringBuffer
aResult( 16 );
1009 sal_uInt16 nUnmodifiedCode
= (nKeyCode
& KEY_CODE_MASK
);
1010 std::map
< sal_uInt16
, OUString
>::const_iterator it
= aKeyMap
.find( nUnmodifiedCode
);
1011 if( it
!= aKeyMap
.end() )
1013 if( (nKeyCode
& KEY_SHIFT
) != 0 )
1014 aResult
.append( sal_Unicode( 0x21e7 ) );
1015 if( (nKeyCode
& KEY_MOD1
) != 0 )
1016 aResult
.append( sal_Unicode( 0x2318 ) );
1017 // we do not really handle Alt (see below)
1018 // we map it to MOD3, whichis actually Command
1019 if( (nKeyCode
& (KEY_MOD2
|KEY_MOD3
)) != 0 )
1020 aResult
.append( sal_Unicode( 0x2325 ) );
1022 aResult
.append( it
->second
);
1025 return aResult
.makeStringAndClear();
1028 static void getAppleScrollBarVariant(StyleSettings
&rSettings
)
1030 bool bIsScrollbarDoubleMax
= true; // default is DoubleMax
1032 CFStringRef AppleScrollBarType
= CFSTR("AppleScrollBarVariant");
1033 if( AppleScrollBarType
)
1035 CFStringRef ScrollBarVariant
= static_cast<CFStringRef
>(CFPreferencesCopyAppValue( AppleScrollBarType
, kCFPreferencesCurrentApplication
));
1036 if( ScrollBarVariant
)
1038 if( CFGetTypeID( ScrollBarVariant
) == CFStringGetTypeID() )
1040 // TODO: check for the less important variants "DoubleMin" and "DoubleBoth" too
1041 CFStringRef DoubleMax
= CFSTR("DoubleMax");
1044 if ( !CFStringCompare(ScrollBarVariant
, DoubleMax
, kCFCompareCaseInsensitive
) )
1045 bIsScrollbarDoubleMax
= true;
1047 bIsScrollbarDoubleMax
= false;
1048 CFRelease(DoubleMax
);
1051 CFRelease( ScrollBarVariant
);
1053 CFRelease(AppleScrollBarType
);
1056 GetSalData()->mbIsScrollbarDoubleMax
= bIsScrollbarDoubleMax
;
1058 CFStringRef jumpScroll
= CFSTR("AppleScrollerPagingBehavior");
1061 CFBooleanRef jumpStr
= static_cast<CFBooleanRef
>(CFPreferencesCopyAppValue( jumpScroll
, kCFPreferencesCurrentApplication
));
1064 if( CFGetTypeID( jumpStr
) == CFBooleanGetTypeID() )
1065 rSettings
.SetPrimaryButtonWarpsSlider(jumpStr
== kCFBooleanTrue
);
1066 CFRelease( jumpStr
);
1068 CFRelease( jumpScroll
);
1072 static Color
getColor( NSColor
* pSysColor
, const Color
& rDefault
, NSWindow
* pWin
)
1074 Color
aRet( rDefault
);
1078 NSColor
* pRBGColor
= [pSysColor colorUsingColorSpaceName
: NSDeviceRGBColorSpace device
: [pWin deviceDescription
]];
1081 CGFloat r
= 0, g
= 0, b
= 0, a
= 0;
1082 [pRBGColor getRed
: &r green
: &g blue
: &b alpha
: &a
];
1083 aRet
= Color( int(r
*255.999), int(g
*255.999), int(b
*255.999) );
1085 do not release here; leads to duplicate free in yield
1086 it seems the converted color comes out autoreleased, although this
1088 [pRBGColor release];
1095 static vcl::Font
getFont( NSFont
* pFont
, long nDPIY
, const vcl::Font
& rDefault
)
1097 vcl::Font
aResult( rDefault
);
1100 aResult
.SetName( GetOUString( [pFont familyName
] ) );
1101 aResult
.SetHeight( static_cast<int>(([pFont pointSize
] * 72.0 / (float)nDPIY
)+0.5) );
1102 aResult
.SetItalic( ([pFont italicAngle
] != 0.0) ? ITALIC_NORMAL
: ITALIC_NONE
);
1109 void AquaSalFrame::getResolution( sal_Int32
& o_rDPIX
, sal_Int32
& o_rDPIY
)
1114 ReleaseGraphics( mpGraphics
);
1116 mpGraphics
->GetResolution( o_rDPIX
, o_rDPIY
);
1119 // on OSX-Aqua the style settings are independent of the frame, so it does
1120 // not really belong here. Since the connection to the Appearance_Manager
1121 // is currently done in salnativewidgets.cxx this would be a good place.
1122 // On the other hand VCL's platform independent code currently only asks
1123 // SalFrames for system settings anyway, so moving the code somewhere else
1124 // doesn't make the anything cleaner for now
1125 void AquaSalFrame::UpdateSettings( AllSettings
& rSettings
)
1130 // #i113170# may not be the main thread if called from UNO API
1131 SalData::ensureThreadAutoreleasePool();
1133 [mpNSView lockFocus
];
1135 StyleSettings aStyleSettings
= rSettings
.GetStyleSettings();
1138 Color aBackgroundColor
= Color( 0xEC, 0xEC, 0xEC );
1139 aStyleSettings
.Set3DColors( aBackgroundColor
);
1140 aStyleSettings
.SetFaceColor( aBackgroundColor
);
1141 Color
aInactiveTabColor( aBackgroundColor
);
1142 aInactiveTabColor
.DecreaseLuminance( 32 );
1143 aStyleSettings
.SetInactiveTabColor( aInactiveTabColor
);
1145 aStyleSettings
.SetDialogColor( aBackgroundColor
);
1146 aStyleSettings
.SetLightBorderColor( aBackgroundColor
);
1147 Color
aShadowColor( aStyleSettings
.GetShadowColor() );
1148 aShadowColor
.IncreaseLuminance( 32 );
1149 aStyleSettings
.SetShadowColor( aShadowColor
);
1151 // get the system font settings
1152 vcl::Font aAppFont
= aStyleSettings
.GetAppFont();
1153 sal_Int32 nDPIX
= 72, nDPIY
= 72;
1154 getResolution( nDPIX
, nDPIY
);
1155 aAppFont
= getFont( [NSFont systemFontOfSize
: 0], nDPIY
, aAppFont
);
1157 aStyleSettings
.SetToolbarIconSize( ToolbarIconSize::Large
);
1159 // TODO: better mapping of OS X<->LibreOffice font settings
1160 aStyleSettings
.SetAppFont( aAppFont
);
1161 aStyleSettings
.SetHelpFont( aAppFont
);
1162 aStyleSettings
.SetPushButtonFont( aAppFont
);
1164 vcl::Font
aTitleFont( getFont( [NSFont titleBarFontOfSize
: 0], nDPIY
, aAppFont
) );
1165 aStyleSettings
.SetTitleFont( aTitleFont
);
1166 aStyleSettings
.SetFloatTitleFont( aTitleFont
);
1168 vcl::Font
aMenuFont( getFont( [NSFont menuFontOfSize
: 0], nDPIY
, aAppFont
) );
1169 aStyleSettings
.SetMenuFont( aMenuFont
);
1171 aStyleSettings
.SetToolFont( aAppFont
);
1173 vcl::Font
aLabelFont( getFont( [NSFont labelFontOfSize
: 0], nDPIY
, aAppFont
) );
1174 aStyleSettings
.SetLabelFont( aLabelFont
);
1175 aStyleSettings
.SetInfoFont( aLabelFont
);
1176 aStyleSettings
.SetRadioCheckFont( aLabelFont
);
1177 aStyleSettings
.SetFieldFont( aLabelFont
);
1178 aStyleSettings
.SetGroupFont( aLabelFont
);
1179 aStyleSettings
.SetTabFont( aLabelFont
);
1180 aStyleSettings
.SetIconFont( aLabelFont
);
1182 Color
aHighlightColor( getColor( [NSColor selectedTextBackgroundColor
],
1183 aStyleSettings
.GetHighlightColor(), mpNSWindow
) );
1184 aStyleSettings
.SetHighlightColor( aHighlightColor
);
1185 Color
aHighlightTextColor( getColor( [NSColor selectedTextColor
],
1186 aStyleSettings
.GetHighlightTextColor(), mpNSWindow
) );
1187 aStyleSettings
.SetHighlightTextColor( aHighlightTextColor
);
1189 Color
aMenuHighlightColor( getColor( [NSColor selectedMenuItemColor
],
1190 aStyleSettings
.GetMenuHighlightColor(), mpNSWindow
) );
1191 aStyleSettings
.SetMenuHighlightColor( aMenuHighlightColor
);
1192 Color
aMenuHighlightTextColor( getColor( [NSColor selectedMenuItemTextColor
],
1193 aStyleSettings
.GetMenuHighlightTextColor(), mpNSWindow
) );
1194 aStyleSettings
.SetMenuHighlightTextColor( aMenuHighlightTextColor
);
1196 aStyleSettings
.SetMenuColor( aBackgroundColor
);
1197 Color
aMenuTextColor( getColor( [NSColor textColor
],
1198 aStyleSettings
.GetMenuTextColor(), mpNSWindow
) );
1199 aStyleSettings
.SetMenuTextColor( aMenuTextColor
);
1200 aStyleSettings
.SetMenuBarTextColor( aMenuTextColor
);
1201 aStyleSettings
.SetMenuBarRolloverTextColor( aMenuTextColor
);
1202 aStyleSettings
.SetMenuBarHighlightTextColor(aStyleSettings
.GetMenuHighlightTextColor());
1204 aStyleSettings
.SetCursorBlinkTime( 500 );
1206 // no mnemonics on OS X
1207 aStyleSettings
.SetOptions( aStyleSettings
.GetOptions() | StyleSettingsOptions::NoMnemonics
);
1209 getAppleScrollBarVariant(aStyleSettings
);
1211 // set scrollbar size
1212 aStyleSettings
.SetScrollBarSize( static_cast<long int>([NSScroller scrollerWidthForControlSize
:NSRegularControlSize scrollerStyle
:NSScrollerStyleLegacy
]) );
1213 // images in menus false for MacOSX
1214 aStyleSettings
.SetPreferredUseImagesInMenus( false );
1215 aStyleSettings
.SetHideDisabledMenuItems( true );
1216 aStyleSettings
.SetAcceleratorsInContextMenus( false );
1218 rSettings
.SetStyleSettings( aStyleSettings
);
1220 // don't draw frame around each and every toolbar
1221 ImplGetSVData()->maNWFData
.mbDockingAreaAvoidTBFrames
= true;
1223 [mpNSView unlockFocus
];
1226 const SystemEnvData
* AquaSalFrame::GetSystemData() const
1231 void AquaSalFrame::Beep()
1236 void AquaSalFrame::SetPosSize(long nX
, long nY
, long nWidth
, long nHeight
, sal_uInt16 nFlags
)
1241 // #i113170# may not be the main thread if called from UNO API
1242 SalData::ensureThreadAutoreleasePool();
1244 sal_uInt16 nEvent
= 0;
1246 if( [mpNSWindow isMiniaturized
] )
1247 [mpNSWindow 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
= [mpNSWindow frame
];
1262 NSRect aContentRect
= [NSWindow contentRectForFrameRect
: aFrameRect styleMask
: mnStyleMask
];
1264 // position is always relative to parent frame
1265 NSRect aParentContentRect
;
1269 if( AllSettings::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
->mpNSWindow 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 [mpNSWindow setFrame
: [NSWindow frameRectForContentRect
: aContentRect styleMask
: mnStyleMask
] display
: NO
];
1311 UpdateFrameGeometry();
1314 CallCallback(nEvent
, NULL
);
1316 if( mbShown
&& bPaint
)
1318 // trigger filling our backbuffer
1321 // now inform the system that the views need to be drawn
1322 [mpNSWindow display
];
1326 void AquaSalFrame::GetWorkArea( Rectangle
& rRect
)
1331 // #i113170# may not be the main thread if called from UNO API
1332 SalData::ensureThreadAutoreleasePool();
1334 NSScreen
* pScreen
= [mpNSWindow screen
];
1335 if( pScreen
== nil
)
1336 pScreen
= [NSScreen mainScreen
];
1337 NSRect aRect
= [pScreen visibleFrame
];
1338 CocoaToVCL( aRect
);
1339 rRect
.Left() = static_cast<long>(aRect
.origin
.x
);
1340 rRect
.Top() = static_cast<long>(aRect
.origin
.y
);
1341 rRect
.Right() = static_cast<long>(aRect
.origin
.x
+ aRect
.size
.width
- 1);
1342 rRect
.Bottom() = static_cast<long>(aRect
.origin
.y
+ aRect
.size
.height
- 1);
1345 SalPointerState
AquaSalFrame::GetPointerState()
1347 // #i113170# may not be the main thread if called from UNO API
1348 SalData::ensureThreadAutoreleasePool();
1350 SalPointerState state
;
1354 NSPoint aPt
= [mpNSWindow mouseLocationOutsideOfEventStream
];
1355 CocoaToVCL( aPt
, false );
1356 state
.maPos
= Point(static_cast<long>(aPt
.x
), static_cast<long>(aPt
.y
));
1358 NSEvent
* pCur
= [NSApp currentEvent
];
1359 bool bMouseEvent
= false;
1363 switch( [pCur type
] )
1365 case NSLeftMouseDown
: state
.mnState
|= MOUSE_LEFT
; break;
1366 case NSLeftMouseUp
: break;
1367 case NSRightMouseDown
: state
.mnState
|= MOUSE_RIGHT
; break;
1368 case NSRightMouseUp
: break;
1369 case NSOtherMouseDown
: state
.mnState
|= ([pCur buttonNumber
] == 2) ? MOUSE_MIDDLE
: 0; break;
1370 case NSOtherMouseUp
: break;
1371 case NSMouseMoved
: break;
1372 case NSLeftMouseDragged
: state
.mnState
|= MOUSE_LEFT
; break;
1373 case NSRightMouseDragged
: state
.mnState
|= MOUSE_RIGHT
; break;
1374 case NSOtherMouseDragged
: state
.mnState
|= ([pCur buttonNumber
] == 2) ? MOUSE_MIDDLE
: 0; break;
1377 bMouseEvent
= false;
1383 unsigned int nMask
= (unsigned int)[pCur modifierFlags
];
1384 if( (nMask
& NSShiftKeyMask
) != 0 )
1385 state
.mnState
|= KEY_SHIFT
;
1386 if( (nMask
& NSControlKeyMask
) != 0 )
1387 state
.mnState
|= KEY_MOD3
;
1388 if( (nMask
& NSAlternateKeyMask
) != 0 )
1389 state
.mnState
|= KEY_MOD2
;
1390 if( (nMask
& NSCommandKeyMask
) != 0 )
1391 state
.mnState
|= KEY_MOD1
;
1396 // FIXME: replace Carbon by Cocoa
1397 // Cocoa does not have an equivalent for GetCurrentEventButtonState
1398 // and GetCurrentEventKeyModifiers.
1399 // we could try to get away with tracking all events for modifierKeys
1400 // and all mouse events for button state in VCL_NSApllication::sendEvent,
1401 // but it is unclear whether this will get us the same result.
1402 // leave in GetCurrentEventButtonState and GetCurrentEventKeyModifiers for now
1404 // fill in button state
1405 UInt32 nState
= GetCurrentEventButtonState();
1408 state
.mnState
|= MOUSE_LEFT
; // primary button
1410 state
.mnState
|= MOUSE_RIGHT
; // secondary button
1412 state
.mnState
|= MOUSE_MIDDLE
; // tertiary button
1414 // fill in modifier state
1415 nState
= GetCurrentEventKeyModifiers();
1416 if( nState
& shiftKey
)
1417 state
.mnState
|= KEY_SHIFT
;
1418 if( nState
& controlKey
)
1419 state
.mnState
|= KEY_MOD3
;
1420 if( nState
& optionKey
)
1421 state
.mnState
|= KEY_MOD2
;
1422 if( nState
& cmdKey
)
1423 state
.mnState
|= KEY_MOD1
;
1429 KeyIndicatorState
AquaSalFrame::GetIndicatorState()
1431 return KeyIndicatorState::NONE
;
1434 void AquaSalFrame::SimulateKeyPress( sal_uInt16
/*nKeyCode*/ )
1438 bool AquaSalFrame::SetPluginParent( SystemParentData
* )
1440 // plugin parent may be killed unexpectedly by
1441 // plugging process;
1447 bool AquaSalFrame::MapUnicodeToKeyCode( sal_Unicode
, LanguageType
, vcl::KeyCode
& )
1449 // not supported yet
1453 LanguageType
AquaSalFrame::GetInputLanguage()
1456 return LANGUAGE_DONTKNOW
;
1459 void AquaSalFrame::DrawMenuBar()
1463 void AquaSalFrame::SetMenu( SalMenu
* pSalMenu
)
1465 // #i113170# may not be the main thread if called from UNO API
1466 SalData::ensureThreadAutoreleasePool();
1468 AquaSalMenu
* pMenu
= static_cast<AquaSalMenu
*>(pSalMenu
);
1469 DBG_ASSERT( ! pMenu
|| pMenu
->mbMenuBar
, "setting non menubar on frame" );
1472 mpMenu
->setMainMenu();
1475 void AquaSalFrame::SetExtendedFrameStyle( SalExtStyle nStyle
)
1479 // #i113170# may not be the main thread if called from UNO API
1480 SalData::ensureThreadAutoreleasePool();
1482 if( (mnExtStyle
& SAL_FRAME_EXT_STYLE_DOCMODIFIED
) != (nStyle
& SAL_FRAME_EXT_STYLE_DOCMODIFIED
) )
1483 [mpNSWindow setDocumentEdited
: (nStyle
& SAL_FRAME_EXT_STYLE_DOCMODIFIED
) ? YES
: NO
];
1486 mnExtStyle
= nStyle
;
1489 SalFrame
* AquaSalFrame::GetParent() const
1494 void AquaSalFrame::SetParent( SalFrame
* pNewParent
)
1496 bool bShown
= mbShown
;
1497 // remove from child list
1499 mpParent
= static_cast<AquaSalFrame
*>(pNewParent
);
1500 // insert to correct parent and paint
1504 void AquaSalFrame::UpdateFrameGeometry()
1511 // keep in mind that view and window coordinates are lower left
1512 // whereas vcl's are upper left
1514 // update screen rect
1515 NSScreen
* pScreen
= [mpNSWindow screen
];
1518 maScreenRect
= [pScreen frame
];
1519 NSArray
* pScreens
= [NSScreen screens
];
1521 maGeometry
.nDisplayScreenNumber
= [pScreens indexOfObject
: pScreen
];
1524 NSRect aFrameRect
= [mpNSWindow frame
];
1525 NSRect aContentRect
= [NSWindow contentRectForFrameRect
: aFrameRect styleMask
: mnStyleMask
];
1527 // release old track rect
1528 [mpNSView removeTrackingRect
: mnTrackingRectTag
];
1529 // install the new track rect
1530 NSRect aTrackRect
= { NSZeroPoint
, aContentRect
.size
};
1531 mnTrackingRectTag
= [mpNSView addTrackingRect
: aTrackRect owner
: mpNSView userData
: nil assumeInside
: NO
];
1533 // convert to vcl convention
1534 CocoaToVCL( aFrameRect
);
1535 CocoaToVCL( aContentRect
);
1537 maGeometry
.nX
= static_cast<int>(aContentRect
.origin
.x
);
1538 maGeometry
.nY
= static_cast<int>(aContentRect
.origin
.y
);
1540 maGeometry
.nLeftDecoration
= static_cast<unsigned int>(aContentRect
.origin
.x
- aFrameRect
.origin
.x
);
1541 maGeometry
.nRightDecoration
= static_cast<unsigned int>((aFrameRect
.origin
.x
+ aFrameRect
.size
.width
) -
1542 (aContentRect
.origin
.x
+ aContentRect
.size
.width
));
1544 maGeometry
.nTopDecoration
= static_cast<unsigned int>(aContentRect
.origin
.y
- aFrameRect
.origin
.y
);
1545 maGeometry
.nBottomDecoration
= static_cast<unsigned int>((aFrameRect
.origin
.y
+ aFrameRect
.size
.height
) -
1546 (aContentRect
.origin
.y
+ aContentRect
.size
.height
));
1548 maGeometry
.nWidth
= static_cast<unsigned int>(aContentRect
.size
.width
);
1549 maGeometry
.nHeight
= static_cast<unsigned int>(aContentRect
.size
.height
);
1552 void AquaSalFrame::CaptureMouse( bool bCapture
)
1555 we'll try to use a pidgin version of capture mouse
1556 on MacOSX (neither carbon nor cocoa) there is a
1557 CaptureMouse equivalent (in Carbon there is TrackMouseLocation
1558 but this is useless to use since it is blocking)
1560 However on cocoa the active frame seems to get mouse events
1561 also outside the window, so we'll try to forward mouse events
1562 to the capture frame in the hope that one of our frames
1565 This will break as soon as the user activates another app, but
1566 a mouse click will normally lead to a release of the mouse anyway.
1568 Let's see how far we get this way. Alternatively we could use one
1569 large overlay window like we did for the carbon implementation,
1570 however that is resource intensive.
1574 s_pCaptureFrame
= this;
1575 else if( ! bCapture
&& s_pCaptureFrame
== this )
1576 s_pCaptureFrame
= NULL
;
1579 void AquaSalFrame::ResetClipRegion()
1586 // #i113170# may not be the main thread if called from UNO API
1587 SalData::ensureThreadAutoreleasePool();
1589 // release old path and indicate no clipping
1590 CGPathRelease( mrClippingPath
);
1591 mrClippingPath
= NULL
;
1593 if( mpNSView
&& mbShown
)
1594 [mpNSView setNeedsDisplay
: YES
];
1597 [mpNSWindow setOpaque
: YES
];
1598 [mpNSWindow invalidateShadow
];
1602 void AquaSalFrame::BeginSetClipRegion( sal_uLong nRects
)
1609 // #i113170# may not be the main thread if called from UNO API
1610 SalData::ensureThreadAutoreleasePool();
1613 if( mrClippingPath
)
1615 CGPathRelease( mrClippingPath
);
1616 mrClippingPath
= NULL
;
1619 if( maClippingRects
.size() > SAL_CLIPRECT_COUNT
&& nRects
< maClippingRects
.size() )
1621 std::vector
<CGRect
> aEmptyVec
;
1622 maClippingRects
.swap( aEmptyVec
);
1624 maClippingRects
.clear();
1625 maClippingRects
.reserve( nRects
);
1628 void AquaSalFrame::UnionClipRegion( long nX
, long nY
, long nWidth
, long nHeight
)
1630 // #i113170# may not be the main thread if called from UNO API
1631 SalData::ensureThreadAutoreleasePool();
1633 if( nWidth
&& nHeight
)
1635 NSRect aRect
= { { static_cast<CGFloat
>(nX
), static_cast<CGFloat
>(nY
) }, { static_cast<CGFloat
>(nWidth
), static_cast<CGFloat
>(nHeight
) } };
1636 VCLToCocoa( aRect
, false );
1637 maClippingRects
.push_back( CGRectMake(aRect
.origin
.x
, aRect
.origin
.y
, aRect
.size
.width
, aRect
.size
.height
) );
1641 void AquaSalFrame::EndSetClipRegion()
1648 // #i113170# may not be the main thread if called from UNO API
1649 SalData::ensureThreadAutoreleasePool();
1651 if( ! maClippingRects
.empty() )
1653 mrClippingPath
= CGPathCreateMutable();
1654 CGPathAddRects( mrClippingPath
, NULL
, &maClippingRects
[0], maClippingRects
.size() );
1656 if( mpNSView
&& mbShown
)
1657 [mpNSView setNeedsDisplay
: YES
];
1660 [mpNSWindow setOpaque
: (mrClippingPath
!= NULL
) ? NO
: YES
];
1661 [mpNSWindow setBackgroundColor
: [NSColor clearColor
]];
1662 // shadow is invalidated when view gets drawn again
1666 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */