1/************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24// MARKER(update_precomp.py): autogen include statement, do not remove 25#include "precompiled_vcl.hxx" 26 27#include <sal/alloca.h> 28 29#include "vcl/window.hxx" 30#include "vcl/svapp.hxx" 31 32#include "aqua/salinst.h" 33#include "aqua/salgdi.h" 34#include "aqua/salframe.h" 35#include "aqua/salframeview.h" 36#include "aqua/aqua11yfactory.h" 37 38#define WHEEL_EVENT_FACTOR 1.5 39 40// for allowing fullscreen support on deployment targets < OSX 10.7 41#if !defined(MAC_OS_X_VERSION_10_7) 42 #define NSWindowCollectionBehaviorFullScreenPrimary (1 << 7) 43 #define NSWindowCollectionBehaviorFullScreenAuxiliary (1 << 8) 44// #define NSFullScreenWindowMask (1 << 14) 45#endif 46 47 48static sal_uInt16 ImplGetModifierMask( unsigned int nMask ) 49{ 50 sal_uInt16 nRet = 0; 51 if( (nMask & NSShiftKeyMask) != 0 ) 52 nRet |= KEY_SHIFT; 53 if( (nMask & NSControlKeyMask) != 0 ) 54 nRet |= KEY_MOD3; 55 if( (nMask & NSAlternateKeyMask) != 0 ) 56 nRet |= KEY_MOD2; 57 if( (nMask & NSCommandKeyMask) != 0 ) 58 nRet |= KEY_MOD1; 59 return nRet; 60} 61 62static sal_uInt16 ImplMapCharCode( sal_Unicode aCode ) 63{ 64 static sal_uInt16 aKeyCodeMap[ 128 ] = 65 { 66 0, 0, 0, 0, 0, 0, 0, 0, 67 KEY_BACKSPACE, KEY_TAB, KEY_RETURN, 0, 0, KEY_RETURN, 0, 0, 68 0, 0, 0, 0, 0, 0, 0, 0, 69 0, KEY_TAB, 0, KEY_ESCAPE, 0, 0, 0, 0, 70 KEY_SPACE, 0, 0, 0, 0, 0, 0, 0, 71 0, 0, KEY_MULTIPLY, KEY_ADD, KEY_COMMA, KEY_SUBTRACT, KEY_POINT, KEY_DIVIDE, 72 KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, 73 KEY_8, KEY_9, 0, 0, KEY_LESS, KEY_EQUAL, KEY_GREATER, 0, 74 0, KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, 75 KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, 76 KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, 77 KEY_X, KEY_Y, KEY_Z, 0, 0, 0, 0, 0, 78 KEY_QUOTELEFT, KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, 79 KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, 80 KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, 81 KEY_X, KEY_Y, KEY_Z, 0, 0, 0, KEY_TILDE, KEY_BACKSPACE 82 }; 83 84 // Note: the mapping 0x7f should by rights be KEY_DELETE 85 // however if you press "backspace" 0x7f is reported 86 // whereas for "delete" 0xf728 gets reported 87 88 // Note: the mapping of 0x19 to KEY_TAB is because for unknown reasons 89 // tab alone is reported as 0x09 (as expected) but shift-tab is 90 // reported as 0x19 (end of medium) 91 92 static sal_uInt16 aFunctionKeyCodeMap[ 128 ] = 93 { 94 KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_F1, KEY_F2, KEY_F3, KEY_F4, 95 KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12, 96 KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17, KEY_F18, KEY_F19, KEY_F20, 97 KEY_F21, KEY_F22, KEY_F23, KEY_F24, KEY_F25, KEY_F26, 0, 0, 98 0, 0, 0, 0, 0, 0, 0, KEY_INSERT, 99 KEY_DELETE, KEY_HOME, 0, KEY_END, KEY_PAGEUP, KEY_PAGEDOWN, 0, 0, 100 0, 0, 0, 0, 0, KEY_MENU, 0, 0, 101 0, 0, 0, 0, 0, 0, 0, 0, 102 0, 0, 0, KEY_UNDO, KEY_REPEAT, KEY_FIND, KEY_HELP, 0, 103 0, 0, 0, 0, 0, 0, 0, 0, 104 0, 0, 0, 0, 0, 0, 0, 0, 105 0, 0, 0, 0, 0, 0, 0, 0, 106 0, 0, 0, 0, 0, 0, 0, 0, 107 0, 0, 0, 0, 0, 0, 0, 0, 108 0, 0, 0, 0, 0, 0, 0, 0, 109 0, 0, 0, 0, 0, 0, 0, 0 110 }; 111 112 sal_uInt16 nKeyCode = 0; 113 if( aCode < sizeof( aKeyCodeMap) / sizeof( aKeyCodeMap[0] ) ) 114 nKeyCode = aKeyCodeMap[ aCode ]; 115 else if( aCode >= 0xf700 && aCode < 0xf780 ) 116 nKeyCode = aFunctionKeyCodeMap[ aCode - 0xf700 ]; 117 return nKeyCode; 118} 119 120// store the frame the mouse last entered 121static AquaSalFrame* s_pMouseFrame = NULL; 122// store the last pressed button for enter/exit events 123// which lack that information 124static sal_uInt16 s_nLastButton = 0; 125 126// combinations of keys we need to handle ourselves 127static const struct ExceptionalKey 128{ 129 const sal_uInt16 nKeyCode; 130 const unsigned int nModifierMask; 131} aExceptionalKeys[] = 132{ 133 { KEY_D, NSControlKeyMask | NSShiftKeyMask | NSAlternateKeyMask }, 134 { KEY_D, NSCommandKeyMask | NSShiftKeyMask | NSAlternateKeyMask } 135}; 136 137static AquaSalFrame* getMouseContainerFrame() 138{ 139 NSInteger nWindows = 0; 140 NSCountWindows( &nWindows ); 141 NSInteger* pWindows = (NSInteger*)alloca( nWindows * sizeof(NSInteger) ); 142 // note: NSWindowList is supposed to be in z-order front to back 143 NSWindowList( nWindows, pWindows ); 144 AquaSalFrame* pDispatchFrame = NULL; 145 for(int i = 0; i < nWindows && ! pDispatchFrame; i++ ) 146 { 147 NSWindow* pWin = [NSApp windowWithWindowNumber: pWindows[i]]; 148 if( pWin && [pWin isMemberOfClass: [SalFrameWindow class]] && [(SalFrameWindow*)pWin containsMouse] ) 149 pDispatchFrame = [(SalFrameWindow*)pWin getSalFrame]; 150 } 151 return pDispatchFrame; 152} 153 154@implementation SalFrameWindow 155-(id)initWithSalFrame: (AquaSalFrame*)pFrame 156{ 157 mDraggingDestinationHandler = nil; 158 mpFrame = pFrame; 159 NSRect aRect = NSMakeRect( pFrame->maGeometry.nX, pFrame->maGeometry.nY, 160 pFrame->maGeometry.nWidth, pFrame->maGeometry.nHeight); 161 pFrame->VCLToCocoa( aRect ); 162 NSWindow* pNSWindow = [super initWithContentRect: aRect styleMask: mpFrame->getStyleMask() backing: NSBackingStoreBuffered defer: NO ]; 163 [pNSWindow useOptimizedDrawing: YES]; // OSX recommendation when there are no overlapping subviews within the receiver 164 165 // enable OSX>=10.7 fullscreen options if available and useful 166 bool bAllowFullScreen = (0 == (mpFrame->mnStyle & (SAL_FRAME_STYLE_DIALOG | SAL_FRAME_STYLE_TOOLTIP | SAL_FRAME_STYLE_SYSTEMCHILD | SAL_FRAME_STYLE_FLOAT | SAL_FRAME_STYLE_TOOLWINDOW | SAL_FRAME_STYLE_INTRO))); 167 bAllowFullScreen &= (0 == (~mpFrame->mnStyle & (SAL_FRAME_STYLE_SIZEABLE))); 168 bAllowFullScreen &= (mpFrame->mpParent == NULL); 169 const SEL setCollectionBehavior = @selector(setCollectionBehavior:); 170 if( bAllowFullScreen && [pNSWindow respondsToSelector: setCollectionBehavior]) 171 { 172 const int bMode= (bAllowFullScreen ? NSWindowCollectionBehaviorFullScreenPrimary : NSWindowCollectionBehaviorFullScreenAuxiliary); 173 [pNSWindow performSelector:setCollectionBehavior withObject:(id)bMode]; 174 } 175 176 // disable OSX>=10.7 window restoration until we support it directly 177 const SEL setRestorable = @selector(setRestorable:); 178 if( [pNSWindow respondsToSelector: setRestorable]) { 179 [pNSWindow performSelector:setRestorable withObject:(id)NO]; 180 } 181 182 return pNSWindow; 183} 184 185-(AquaSalFrame*)getSalFrame 186{ 187 return mpFrame; 188} 189 190-(void)displayIfNeeded 191{ 192 if( GetSalData() && GetSalData()->mpFirstInstance ) 193 { 194 vos::IMutex* pMutex = GetSalData()->mpFirstInstance->GetYieldMutex(); 195 if( pMutex ) 196 { 197 pMutex->acquire(); 198 [super displayIfNeeded]; 199 pMutex->release(); 200 } 201 } 202} 203 204-(BOOL)containsMouse 205{ 206 // is this event actually inside that NSWindow ? 207 NSPoint aPt = [NSEvent mouseLocation]; 208 NSRect aFrameRect = [self frame]; 209 BOOL bInRect = NSPointInRect( aPt, aFrameRect ); 210 return bInRect; 211} 212 213-(BOOL)canBecomeKeyWindow 214{ 215 if( (mpFrame->mnStyle & 216 ( SAL_FRAME_STYLE_FLOAT | 217 SAL_FRAME_STYLE_TOOLTIP | 218 SAL_FRAME_STYLE_INTRO 219 )) == 0 ) 220 return YES; 221 if( (mpFrame->mnStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) != 0 ) 222 return YES; 223 if( mpFrame->mbFullScreen ) 224 return YES; 225 if( (mpFrame->mnStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE) ) 226 return YES; 227 return [super canBecomeKeyWindow]; 228} 229 230-(void)windowDidBecomeKey: (NSNotification*)pNotification 231{ 232 (void)pNotification; 233 YIELD_GUARD; 234 235 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 236 { 237 static const sal_uLong nGuessDocument = SAL_FRAME_STYLE_MOVEABLE| 238 SAL_FRAME_STYLE_SIZEABLE| 239 SAL_FRAME_STYLE_CLOSEABLE; 240 241 if( mpFrame->mpMenu ) 242 mpFrame->mpMenu->setMainMenu(); 243 else if( ! mpFrame->mpParent && 244 ( (mpFrame->mnStyle & nGuessDocument) == nGuessDocument || // set default menu for e.g. help 245 mpFrame->mbFullScreen ) ) // ser default menu for e.g. presentation 246 { 247 AquaSalMenu::setDefaultMenu(); 248 } 249 #if 0 250 // FIXME: we should disable menus while in modal mode 251 // however from down here there is currently no reliable way to 252 // find out when to do this 253 if( (mpFrame->mpParent && mpFrame->mpParent->GetWindow()->IsInModalMode()) ) 254 AquaSalMenu::enableMainMenu( false ); 255 #endif 256 mpFrame->CallCallback( SALEVENT_GETFOCUS, 0 ); 257 mpFrame->SendPaintEvent(); // repaint controls as active 258 } 259} 260 261-(void)windowDidResignKey: (NSNotification*)pNotification 262{ 263 (void)pNotification; 264 YIELD_GUARD; 265 266 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 267 { 268 mpFrame->CallCallback(SALEVENT_LOSEFOCUS, 0); 269 mpFrame->SendPaintEvent(); // repaint controls as inactive 270 } 271} 272 273-(void)windowDidChangeScreen: (NSNotification*)pNotification 274{ 275 (void)pNotification; 276 YIELD_GUARD; 277 278 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 279 mpFrame->screenParametersChanged(); 280} 281 282-(void)windowDidMove: (NSNotification*)pNotification 283{ 284 (void)pNotification; 285 YIELD_GUARD; 286 287 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 288 { 289 mpFrame->UpdateFrameGeometry(); 290 mpFrame->CallCallback( SALEVENT_MOVE, 0 ); 291 } 292} 293 294-(void)windowDidResize: (NSNotification*)pNotification 295{ 296 (void)pNotification; 297 YIELD_GUARD; 298 299 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 300 { 301 mpFrame->UpdateFrameGeometry(); 302 mpFrame->CallCallback( SALEVENT_RESIZE, 0 ); 303 mpFrame->SendPaintEvent(); 304 } 305} 306 307-(void)windowDidMiniaturize: (NSNotification*)pNotification 308{ 309 (void)pNotification; 310 YIELD_GUARD; 311 312 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 313 { 314 mpFrame->mbShown = false; 315 mpFrame->UpdateFrameGeometry(); 316 mpFrame->CallCallback( SALEVENT_RESIZE, 0 ); 317 } 318} 319 320-(void)windowDidDeminiaturize: (NSNotification*)pNotification 321{ 322 (void)pNotification; 323 YIELD_GUARD; 324 325 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 326 { 327 mpFrame->mbShown = true; 328 mpFrame->UpdateFrameGeometry(); 329 mpFrame->CallCallback( SALEVENT_RESIZE, 0 ); 330 } 331} 332 333-(BOOL)windowShouldClose: (NSNotification*)pNotification 334{ 335 (void)pNotification; 336 YIELD_GUARD; 337 338 BOOL bRet = YES; 339 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 340 { 341 // #i84461# end possible input 342 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 ); 343 if( AquaSalFrame::isAlive( mpFrame ) ) 344 { 345 mpFrame->CallCallback( SALEVENT_CLOSE, 0 ); 346 bRet = NO; // application will close the window or not, AppKit shouldn't 347 } 348 } 349 350 return bRet; 351} 352 353-(void)windowDidEnterFullScreen: (NSNotification*)pNotification 354{ 355 YIELD_GUARD; 356 357 if( !mpFrame || !AquaSalFrame::isAlive( mpFrame)) 358 return; 359 mpFrame->mbFullScreen = true; 360 (void)pNotification; 361} 362 363-(void)windowDidExitFullScreen: (NSNotification*)pNotification 364{ 365 YIELD_GUARD; 366 367 if( !mpFrame || !AquaSalFrame::isAlive( mpFrame)) 368 return; 369 mpFrame->mbFullScreen = false; 370 (void)pNotification; 371} 372 373-(void)dockMenuItemTriggered: (id)sender 374{ 375 (void)sender; 376 YIELD_GUARD; 377 378 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 379 mpFrame->ToTop( SAL_FRAME_TOTOP_RESTOREWHENMIN | SAL_FRAME_TOTOP_GRABFOCUS ); 380} 381 382-(::com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessibleContext >)accessibleContext 383{ 384 return mpFrame -> GetWindow() -> GetAccessible() -> getAccessibleContext(); 385} 386 387-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender 388{ 389 return [mDraggingDestinationHandler draggingEntered: sender]; 390} 391 392-(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender 393{ 394 return [mDraggingDestinationHandler draggingUpdated: sender]; 395} 396 397-(void)draggingExited:(id <NSDraggingInfo>)sender 398{ 399 [mDraggingDestinationHandler draggingExited: sender]; 400} 401 402-(BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender 403{ 404 return [mDraggingDestinationHandler prepareForDragOperation: sender]; 405} 406 407-(BOOL)performDragOperation:(id <NSDraggingInfo>)sender 408{ 409 return [mDraggingDestinationHandler performDragOperation: sender]; 410} 411 412-(void)concludeDragOperation:(id <NSDraggingInfo>)sender 413{ 414 [mDraggingDestinationHandler concludeDragOperation: sender]; 415} 416 417-(void)registerDraggingDestinationHandler:(id)theHandler 418{ 419 mDraggingDestinationHandler = theHandler; 420} 421 422-(void)unregisterDraggingDestinationHandler:(id)theHandler 423{ 424 (void)theHandler; 425 mDraggingDestinationHandler = nil; 426} 427 428@end 429 430@implementation SalFrameView 431+(void)unsetMouseFrame: (AquaSalFrame*)pFrame 432{ 433 if( pFrame == s_pMouseFrame ) 434 s_pMouseFrame = NULL; 435} 436 437-(id)initWithSalFrame: (AquaSalFrame*)pFrame 438{ 439 if ((self = [super initWithFrame: [NSWindow contentRectForFrameRect: [pFrame->getNSWindow() frame] styleMask: pFrame->mnStyleMask]]) != nil) 440 { 441 mDraggingDestinationHandler = nil; 442 mpFrame = pFrame; 443 mMarkedRange = NSMakeRange(NSNotFound, 0); 444 mSelectedRange = NSMakeRange(NSNotFound, 0); 445 mpReferenceWrapper = nil; 446 mpMouseEventListener = nil; 447 mpLastSuperEvent = nil; 448 } 449 450 mfLastMagnifyTime = 0.0; 451 return self; 452} 453 454-(AquaSalFrame*)getSalFrame 455{ 456 return mpFrame; 457} 458 459-(void)resetCursorRects 460{ 461 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 462 { 463 // FIXME: does this leak the returned NSCursor of getCurrentCursor ? 464 const NSRect aRect = { NSZeroPoint, NSMakeSize( mpFrame->maGeometry.nWidth, mpFrame->maGeometry.nHeight) }; 465 [self addCursorRect: aRect cursor: mpFrame->getCurrentCursor()]; 466 } 467} 468 469-(BOOL)acceptsFirstResponder 470{ 471 return YES; 472} 473 474-(BOOL)acceptsFirstMouse: (NSEvent*)pEvent 475{ 476 (void)pEvent; 477 return YES; 478} 479 480-(BOOL)isOpaque 481{ 482 if( !mpFrame) 483 return YES; 484 if( !AquaSalFrame::isAlive( mpFrame)) 485 return YES; 486 if( !mpFrame->getClipPath()) 487 return YES; 488 return NO; 489} 490 491// helper class similar to a vos::OGuard for the SalYieldMutex 492// the difference is that it only does tryToAcquire instead of acquire 493// so dreaded deadlocks like #i93512# are prevented 494class TryGuard 495{ 496public: 497 TryGuard() { mbGuarded = ImplSalYieldMutexTryToAcquire(); } 498 ~TryGuard() { if( mbGuarded ) ImplSalYieldMutexRelease(); } 499 bool IsGuarded() { return mbGuarded; } 500private: 501 bool mbGuarded; 502}; 503 504-(void)drawRect: (NSRect)aRect 505{ 506 // HOTFIX: #i93512# prevent deadlocks if any other thread already has the SalYieldMutex 507 TryGuard aTryGuard; 508 if( !aTryGuard.IsGuarded() ) 509 { 510 // NOTE: the mpFrame access below is not guarded yet! 511 // TODO: mpFrame et al need to be guarded by an independent mutex 512 AquaSalGraphics* pGraphics = (mpFrame && AquaSalFrame::isAlive(mpFrame)) ? mpFrame->mpGraphics : NULL; 513 if( pGraphics ) 514 { 515 // we did not get the mutex so we cannot draw now => request to redraw later 516 // convert the NSRect to a CGRect for Refreshrect() 517 const CGRect aCGRect = {{aRect.origin.x,aRect.origin.y},{aRect.size.width,aRect.size.height}}; 518 pGraphics->RefreshRect( aCGRect ); 519 } 520 return; 521 } 522 523 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 524 { 525 if( mpFrame->mpGraphics ) 526 { 527 mpFrame->mpGraphics->UpdateWindow( aRect ); 528 if( mpFrame->getClipPath() ) 529 [mpFrame->getNSWindow() invalidateShadow]; 530 } 531 } 532} 533 534-(void)sendMouseEventToFrame: (NSEvent*)pEvent button:(sal_uInt16)nButton eventtype:(sal_uInt16)nEvent 535{ 536 YIELD_GUARD; 537 538 AquaSalFrame* pDispatchFrame = AquaSalFrame::GetCaptureFrame(); 539 bool bIsCaptured = false; 540 if( pDispatchFrame ) 541 { 542 bIsCaptured = true; 543 if( nEvent == SALEVENT_MOUSELEAVE ) // no leave events if mouse is captured 544 nEvent = SALEVENT_MOUSEMOVE; 545 } 546 else if( s_pMouseFrame ) 547 pDispatchFrame = s_pMouseFrame; 548 else 549 pDispatchFrame = mpFrame; 550 551 /* #i81645# Cocoa reports mouse events while a button is pressed 552 to the window in which it was first pressed. This is reasonable and fine and 553 gets one around most cases where on other platforms one uses CaptureMouse or XGrabPointer, 554 however vcl expects mouse events to occur in the window the mouse is over, unless the 555 mouse is explicitly captured. So we need to find the window the mouse is actually 556 over for conformance with other platforms. 557 */ 558 if( ! bIsCaptured && nButton && pDispatchFrame && AquaSalFrame::isAlive( pDispatchFrame ) ) 559 { 560 // is this event actually inside that NSWindow ? 561 NSPoint aPt = [NSEvent mouseLocation]; 562 NSRect aFrameRect = [pDispatchFrame->getNSWindow() frame]; 563 564 if ( ! NSPointInRect( aPt, aFrameRect ) ) 565 { 566 // no, it is not 567 // now we need to find the one it may be in 568 /* #i93756# we ant to get enumerate the application windows in z-order 569 to check if any contains the mouse. This could be elegantly done with this 570 code: 571 572 // use NSApp to check windows in ZOrder whether they contain the mouse pointer 573 NSWindow* pWindow = [NSApp makeWindowsPerform: @selector(containsMouse) inOrder: YES]; 574 if( pWindow && [pWindow isMemberOfClass: [SalFrameWindow class]] ) 575 pDispatchFrame = [(SalFrameWindow*)pWindow getSalFrame]; 576 577 However if a non SalFrameWindow is on screen (like e.g. the file dialog) 578 it can be hit with the containsMouse selector, which it doesn't support. 579 Sadly NSApplication:makeWindowsPerform does not check (for performance reasons 580 I assume) whether a window supports a selector before sending it. 581 */ 582 AquaSalFrame* pMouseFrame = getMouseContainerFrame(); 583 if( pMouseFrame ) 584 pDispatchFrame = pMouseFrame; 585 } 586 } 587 588 if( pDispatchFrame && AquaSalFrame::isAlive( pDispatchFrame ) ) 589 { 590 pDispatchFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 ); 591 pDispatchFrame->mnLastModifierFlags = [pEvent modifierFlags]; 592 593 NSPoint aPt = [NSEvent mouseLocation]; 594 pDispatchFrame->CocoaToVCL( aPt ); 595 596 sal_uInt16 nModMask = ImplGetModifierMask( [pEvent modifierFlags] ); 597 // #i82284# emulate ctrl left 598 if( nModMask == KEY_MOD3 && nButton == MOUSE_LEFT ) 599 { 600 nModMask = 0; 601 nButton = MOUSE_RIGHT; 602 } 603 604 SalMouseEvent aEvent; 605 aEvent.mnTime = pDispatchFrame->mnLastEventTime; 606 aEvent.mnX = static_cast<long>(aPt.x) - pDispatchFrame->maGeometry.nX; 607 aEvent.mnY = static_cast<long>(aPt.y) - pDispatchFrame->maGeometry.nY; 608 aEvent.mnButton = nButton; 609 aEvent.mnCode = aEvent.mnButton | nModMask; 610 611 // --- RTL --- (mirror mouse pos) 612 if( Application::GetSettings().GetLayoutRTL() ) 613 aEvent.mnX = pDispatchFrame->maGeometry.nWidth-1-aEvent.mnX; 614 615 pDispatchFrame->CallCallback( nEvent, &aEvent ); 616 } 617} 618 619-(void)mouseDown: (NSEvent*)pEvent 620{ 621 if ( mpMouseEventListener != nil && 622 [mpMouseEventListener respondsToSelector: @selector(mouseDown:)]) 623 { 624 [mpMouseEventListener mouseDown: [pEvent copyWithZone: NULL]]; 625 } 626 627 s_nLastButton = MOUSE_LEFT; 628 [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEBUTTONDOWN]; 629} 630 631-(void)mouseDragged: (NSEvent*)pEvent 632{ 633 if ( mpMouseEventListener != nil && 634 [mpMouseEventListener respondsToSelector: @selector(mouseDragged:)]) 635 { 636 [mpMouseEventListener mouseDragged: [pEvent copyWithZone: NULL]]; 637 } 638 s_nLastButton = MOUSE_LEFT; 639 [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEMOVE]; 640} 641 642-(void)mouseUp: (NSEvent*)pEvent 643{ 644 s_nLastButton = 0; 645 [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEBUTTONUP]; 646} 647 648-(void)mouseMoved: (NSEvent*)pEvent 649{ 650 s_nLastButton = 0; 651 [self sendMouseEventToFrame:pEvent button:0 eventtype:SALEVENT_MOUSEMOVE]; 652} 653 654-(void)mouseEntered: (NSEvent*)pEvent 655{ 656 s_pMouseFrame = mpFrame; 657 658 // #i107215# the only mouse events we get when inactive are enter/exit 659 // actually we would like to have all of them, but better none than some 660 if( [NSApp isActive] ) 661 [self sendMouseEventToFrame:pEvent button:s_nLastButton eventtype:SALEVENT_MOUSEMOVE]; 662} 663 664-(void)mouseExited: (NSEvent*)pEvent 665{ 666 if( s_pMouseFrame == mpFrame ) 667 s_pMouseFrame = NULL; 668 669 // #i107215# the only mouse events we get when inactive are enter/exit 670 // actually we would like to have all of them, but better none than some 671 if( [NSApp isActive] ) 672 [self sendMouseEventToFrame:pEvent button:s_nLastButton eventtype:SALEVENT_MOUSELEAVE]; 673} 674 675-(void)rightMouseDown: (NSEvent*)pEvent 676{ 677 s_nLastButton = MOUSE_RIGHT; 678 [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEBUTTONDOWN]; 679} 680 681-(void)rightMouseDragged: (NSEvent*)pEvent 682{ 683 s_nLastButton = MOUSE_RIGHT; 684 [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEMOVE]; 685} 686 687-(void)rightMouseUp: (NSEvent*)pEvent 688{ 689 s_nLastButton = 0; 690 [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEBUTTONUP]; 691} 692 693-(void)otherMouseDown: (NSEvent*)pEvent 694{ 695 if( [pEvent buttonNumber] == 2 ) 696 { 697 s_nLastButton = MOUSE_MIDDLE; 698 [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEBUTTONDOWN]; 699 } 700 else 701 s_nLastButton = 0; 702} 703 704-(void)otherMouseDragged: (NSEvent*)pEvent 705{ 706 if( [pEvent buttonNumber] == 2 ) 707 { 708 s_nLastButton = MOUSE_MIDDLE; 709 [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEMOVE]; 710 } 711 else 712 s_nLastButton = 0; 713} 714 715-(void)otherMouseUp: (NSEvent*)pEvent 716{ 717 s_nLastButton = 0; 718 if( [pEvent buttonNumber] == 2 ) 719 [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEBUTTONUP]; 720} 721 722- (void)magnifyWithEvent: (NSEvent*)pEvent 723{ 724 YIELD_GUARD; 725 726 // TODO: ?? -(float)magnification; 727 if( AquaSalFrame::isAlive( mpFrame ) ) 728 { 729 const NSTimeInterval fMagnifyTime = [pEvent timestamp]; 730 mpFrame->mnLastEventTime = static_cast<sal_uLong>( fMagnifyTime * 1000.0 ); 731 mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; 732 733 // check if this is a new series of magnify events 734 static const NSTimeInterval fMaxDiffTime = 0.3; 735 const bool bNewSeries = (fMagnifyTime - mfLastMagnifyTime > fMaxDiffTime); 736 737 if( bNewSeries ) 738 mfMagnifyDeltaSum = 0.0; 739 mfMagnifyDeltaSum += [pEvent deltaZ]; 740 741 mfLastMagnifyTime = [pEvent timestamp]; 742 // TODO: change to 0.1 when COMMAND_WHEEL_ZOOM handlers allow finer zooming control 743 static const float fMagnifyFactor = 0.25; 744 static const float fMinMagnifyStep = 15.0 / fMagnifyFactor; 745 if( fabs(mfMagnifyDeltaSum) <= fMinMagnifyStep ) 746 return; 747 748 // adapt NSEvent-sensitivity to application expectations 749 // TODO: rather make COMMAND_WHEEL_ZOOM handlers smarter 750 const float fDeltaZ = mfMagnifyDeltaSum * fMagnifyFactor; 751 int nDeltaZ = FRound( fDeltaZ ); 752 if( !nDeltaZ ) 753 { 754 // handle new series immediately 755 if( !bNewSeries ) 756 return; 757 nDeltaZ = (fDeltaZ >= 0.0) ? +1 : -1; 758 } 759 // eventually give credit for delta sum 760 mfMagnifyDeltaSum -= nDeltaZ / fMagnifyFactor; 761 762 NSPoint aPt = [NSEvent mouseLocation]; 763 mpFrame->CocoaToVCL( aPt ); 764 765 SalWheelMouseEvent aEvent; 766 aEvent.mnTime = mpFrame->mnLastEventTime; 767 aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; 768 aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; 769 aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); 770 aEvent.mnCode |= KEY_MOD1; // we want zooming, no scrolling 771 aEvent.mbDeltaIsPixel = TRUE; 772 773 // --- RTL --- (mirror mouse pos) 774 if( Application::GetSettings().GetLayoutRTL() ) 775 aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX; 776 777 aEvent.mnDelta = nDeltaZ; 778 aEvent.mnNotchDelta = (nDeltaZ >= 0) ? +1 : -1; 779 if( aEvent.mnDelta == 0 ) 780 aEvent.mnDelta = aEvent.mnNotchDelta; 781 aEvent.mbHorz = FALSE; 782 aEvent.mnScrollLines = nDeltaZ; 783 if( aEvent.mnScrollLines == 0 ) 784 aEvent.mnScrollLines = 1; 785 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); 786 } 787} 788 789- (void)rotateWithEvent: (NSEvent*)pEvent 790{ 791 //Rotation : -(float)rotation; 792 // TODO: create new CommandType so rotation is available to the applications 793 (void)pEvent; 794} 795 796- (void)swipeWithEvent: (NSEvent*)pEvent 797{ 798 YIELD_GUARD; 799 800 if( AquaSalFrame::isAlive( mpFrame ) ) 801 { 802 mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 ); 803 mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; 804 805 // merge pending scroll wheel events 806 CGFloat dX = 0.0; 807 CGFloat dY = 0.0; 808 for(;;) 809 { 810 dX += [pEvent deltaX]; 811 dY += [pEvent deltaY]; 812 NSEvent* pNextEvent = [NSApp nextEventMatchingMask: NSScrollWheelMask 813 untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES ]; 814 if( !pNextEvent ) 815 break; 816 pEvent = pNextEvent; 817 } 818 819 NSPoint aPt = [NSEvent mouseLocation]; 820 mpFrame->CocoaToVCL( aPt ); 821 822 SalWheelMouseEvent aEvent; 823 aEvent.mnTime = mpFrame->mnLastEventTime; 824 aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; 825 aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; 826 aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); 827 aEvent.mbDeltaIsPixel = TRUE; 828 829 // --- RTL --- (mirror mouse pos) 830 if( Application::GetSettings().GetLayoutRTL() ) 831 aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX; 832 833 if( dX != 0.0 ) 834 { 835 aEvent.mnDelta = static_cast<long>(floor(dX)); 836 aEvent.mnNotchDelta = (dX < 0) ? -1 : +1; 837 if( aEvent.mnDelta == 0 ) 838 aEvent.mnDelta = aEvent.mnNotchDelta; 839 aEvent.mbHorz = TRUE; 840 aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; 841 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); 842 } 843 if( dY != 0.0 && AquaSalFrame::isAlive( mpFrame )) 844 { 845 aEvent.mnDelta = static_cast<long>(floor(dY)); 846 aEvent.mnNotchDelta = (dY < 0) ? -1 : +1; 847 if( aEvent.mnDelta == 0 ) 848 aEvent.mnDelta = aEvent.mnNotchDelta; 849 aEvent.mbHorz = FALSE; 850 aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; 851 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); 852 } 853 } 854} 855 856-(void)scrollWheel: (NSEvent*)pEvent 857{ 858 YIELD_GUARD; 859 860 if( AquaSalFrame::isAlive( mpFrame ) ) 861 { 862 mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 ); 863 mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; 864 865 // merge pending scroll wheel events 866 CGFloat dX = 0.0; 867 CGFloat dY = 0.0; 868 for(;;) 869 { 870 dX += [pEvent deltaX]; 871 dY += [pEvent deltaY]; 872 NSEvent* pNextEvent = [NSApp nextEventMatchingMask: NSScrollWheelMask 873 untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES ]; 874 if( !pNextEvent ) 875 break; 876 pEvent = pNextEvent; 877 } 878 879 NSPoint aPt = [NSEvent mouseLocation]; 880 mpFrame->CocoaToVCL( aPt ); 881 882 SalWheelMouseEvent aEvent; 883 aEvent.mnTime = mpFrame->mnLastEventTime; 884 aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; 885 aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; 886 aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); 887 aEvent.mbDeltaIsPixel = TRUE; 888 889 // --- RTL --- (mirror mouse pos) 890 if( Application::GetSettings().GetLayoutRTL() ) 891 aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX; 892 893 if( dX != 0.0 ) 894 { 895 aEvent.mnDelta = static_cast<long>(floor(dX)); 896 aEvent.mnNotchDelta = (dX < 0) ? -1 : +1; 897 if( aEvent.mnDelta == 0 ) 898 aEvent.mnDelta = aEvent.mnNotchDelta; 899 aEvent.mbHorz = TRUE; 900 aEvent.mnScrollLines = (dX > 0) ? +dX/WHEEL_EVENT_FACTOR : -dX/WHEEL_EVENT_FACTOR; 901 if( aEvent.mnScrollLines == 0 ) 902 aEvent.mnScrollLines = 1; 903 904 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); 905 } 906 if( dY != 0.0 && AquaSalFrame::isAlive( mpFrame ) ) 907 { 908 aEvent.mnDelta = static_cast<long>(floor(dY)); 909 aEvent.mnNotchDelta = (dY < 0) ? -1 : +1; 910 if( aEvent.mnDelta == 0 ) 911 aEvent.mnDelta = aEvent.mnNotchDelta; 912 aEvent.mbHorz = FALSE; 913 aEvent.mnScrollLines = (dY > 0) ? +dY/WHEEL_EVENT_FACTOR : -dY/WHEEL_EVENT_FACTOR; 914 if( aEvent.mnScrollLines < 1 ) 915 aEvent.mnScrollLines = 1; 916 917 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); 918 } 919 } 920} 921 922 923-(void)keyDown: (NSEvent*)pEvent 924{ 925 YIELD_GUARD; 926 927 if( AquaSalFrame::isAlive( mpFrame ) ) 928 { 929 mpLastEvent = pEvent; 930 mbInKeyInput = true; 931 mbNeedSpecialKeyHandle = false; 932 mbKeyHandled = false; 933 934 mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 ); 935 mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; 936 937 if( ! [self handleKeyDownException: pEvent] ) 938 { 939 NSArray* pArray = [NSArray arrayWithObject: pEvent]; 940 [self interpretKeyEvents: pArray]; 941 } 942 943 mbInKeyInput = false; 944 } 945} 946 947-(BOOL)handleKeyDownException:(NSEvent*)pEvent 948{ 949 // check for a very special set of modified characters 950 NSString* pUnmodifiedString = [pEvent charactersIgnoringModifiers]; 951 952 if( pUnmodifiedString && [pUnmodifiedString length] == 1 ) 953 { 954 /* #i103102# key events with command and alternate don't make it through 955 interpretKeyEvents (why ?). Try to dispatch them here first, 956 if not successful continue normally 957 */ 958 if( (mpFrame->mnLastModifierFlags & (NSAlternateKeyMask | NSCommandKeyMask)) 959 == (NSAlternateKeyMask | NSCommandKeyMask) ) 960 { 961 if( [self sendSingleCharacter: mpLastEvent] ) 962 return YES; 963 } 964 unichar keyChar = [pUnmodifiedString characterAtIndex: 0]; 965 sal_uInt16 nKeyCode = ImplMapCharCode( keyChar ); 966 967 // Caution: should the table grow to more than 5 or 6 entries, 968 // we must consider moving it to a kind of hash map 969 const unsigned int nExceptions = sizeof( aExceptionalKeys ) / sizeof( aExceptionalKeys[0] ); 970 for( unsigned int i = 0; i < nExceptions; i++ ) 971 { 972 if( nKeyCode == aExceptionalKeys[i].nKeyCode && 973 (mpFrame->mnLastModifierFlags & aExceptionalKeys[i].nModifierMask) 974 == aExceptionalKeys[i].nModifierMask ) 975 { 976 [self sendKeyInputAndReleaseToFrame: nKeyCode character: 0]; 977 978 return YES; 979 } 980 } 981 } 982 return NO; 983} 984 985-(void)flagsChanged: (NSEvent*)pEvent 986{ 987 YIELD_GUARD; 988 989 if( AquaSalFrame::isAlive( mpFrame ) ) 990 { 991 mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 ); 992 mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; 993 } 994} 995 996-(void)insertText:(id)aString 997{ 998 YIELD_GUARD; 999 1000 if( AquaSalFrame::isAlive( mpFrame ) ) 1001 { 1002 NSString* pInsert = nil; 1003 if( [aString isMemberOfClass: [NSAttributedString class]] ) 1004 pInsert = [aString string]; 1005 else 1006 pInsert = aString; 1007 1008 int nLen = 0; 1009 if( pInsert && ( nLen = [pInsert length] ) > 0 ) 1010 { 1011 OUString aInsertString( GetOUString( pInsert ) ); 1012 // aCharCode initializer is safe since aInsertString will at least contain '\0' 1013 sal_Unicode aCharCode = *aInsertString.getStr(); 1014 1015 if( nLen == 1 && 1016 aCharCode < 0x80 && 1017 aCharCode > 0x1f && 1018 ! [self hasMarkedText ] 1019 ) 1020 { 1021 sal_uInt16 nKeyCode = ImplMapCharCode( aCharCode ); 1022 unsigned int nLastModifiers = mpFrame->mnLastModifierFlags; 1023 1024 // #i99567# 1025 // find out the unmodified key code 1026 1027 // sanity check 1028 if( mpLastEvent && ( [mpLastEvent type] == NSKeyDown || [mpLastEvent type] == NSKeyUp ) ) 1029 { 1030 // get unmodified string 1031 NSString* pUnmodifiedString = [mpLastEvent charactersIgnoringModifiers]; 1032 if( pUnmodifiedString && [pUnmodifiedString length] == 1 ) 1033 { 1034 // map the unmodified key code 1035 unichar keyChar = [pUnmodifiedString characterAtIndex: 0]; 1036 nKeyCode = ImplMapCharCode( keyChar ); 1037 } 1038 nLastModifiers = [mpLastEvent modifierFlags]; 1039 1040 } 1041 // #i99567# 1042 // applications and vcl's edit fields ignore key events with ALT 1043 // however we're at a place where we know text should be inserted 1044 // so it seems we need to strip the Alt modifier here 1045 if( (nLastModifiers & (NSControlKeyMask | NSAlternateKeyMask | NSCommandKeyMask)) 1046 == NSAlternateKeyMask ) 1047 { 1048 nLastModifiers = 0; 1049 } 1050 [self sendKeyInputAndReleaseToFrame: nKeyCode character: aCharCode modifiers: nLastModifiers]; 1051 } 1052 else 1053 { 1054 SalExtTextInputEvent aEvent; 1055 aEvent.mnTime = mpFrame->mnLastEventTime; 1056 aEvent.maText = aInsertString; 1057 aEvent.mpTextAttr = NULL; 1058 aEvent.mnCursorPos = aInsertString.getLength(); 1059 aEvent.mnDeltaStart = 0; 1060 aEvent.mnCursorFlags = 0; 1061 aEvent.mbOnlyCursor = FALSE; 1062 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, &aEvent ); 1063 if( AquaSalFrame::isAlive( mpFrame ) ) 1064 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 ); 1065 } 1066 } 1067 else 1068 { 1069 SalExtTextInputEvent aEvent; 1070 aEvent.mnTime = mpFrame->mnLastEventTime; 1071 aEvent.maText = String(); 1072 aEvent.mpTextAttr = NULL; 1073 aEvent.mnCursorPos = 0; 1074 aEvent.mnDeltaStart = 0; 1075 aEvent.mnCursorFlags = 0; 1076 aEvent.mbOnlyCursor = FALSE; 1077 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, &aEvent ); 1078 if( AquaSalFrame::isAlive( mpFrame ) ) 1079 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 ); 1080 1081 } 1082 mbKeyHandled = true; 1083 [self unmarkText]; 1084 } 1085} 1086 1087-(void)insertTab: (id)aSender 1088{ 1089 (void)aSender; 1090 [self sendKeyInputAndReleaseToFrame: KEY_TAB character: '\t' modifiers: 0]; 1091} 1092 1093-(void)insertBacktab: (id)aSender 1094{ 1095 (void)aSender; 1096 [self sendKeyInputAndReleaseToFrame: (KEY_TAB | KEY_SHIFT) character: '\t' modifiers: 0]; 1097} 1098 1099-(void)moveLeft: (id)aSender 1100{ 1101 (void)aSender; 1102 [self sendKeyInputAndReleaseToFrame: KEY_LEFT character: 0 modifiers: 0]; 1103} 1104 1105-(void)moveLeftAndModifySelection: (id)aSender 1106{ 1107 (void)aSender; 1108 [self sendKeyInputAndReleaseToFrame: KEY_LEFT character: 0 modifiers: NSShiftKeyMask]; 1109} 1110 1111-(void)moveBackwardAndModifySelection: (id)aSender 1112{ 1113 (void)aSender; 1114 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_BACKWARD character: 0 modifiers: 0]; 1115} 1116 1117-(void)moveRight: (id)aSender 1118{ 1119 (void)aSender; 1120 [self sendKeyInputAndReleaseToFrame: KEY_RIGHT character: 0 modifiers: 0]; 1121} 1122 1123-(void)moveRightAndModifySelection: (id)aSender 1124{ 1125 (void)aSender; 1126 [self sendKeyInputAndReleaseToFrame: KEY_RIGHT character: 0 modifiers: NSShiftKeyMask]; 1127} 1128 1129-(void)moveForwardAndModifySelection: (id)aSender 1130{ 1131 (void)aSender; 1132 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_FORWARD character: 0 modifiers: 0]; 1133} 1134 1135-(void)moveWordLeft: (id)aSender 1136{ 1137 (void)aSender; 1138 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_BACKWARD character: 0 modifiers: 0]; 1139} 1140 1141-(void)moveWordBackward: (id)aSender 1142{ 1143 (void)aSender; 1144 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_BACKWARD character: 0 modifiers: 0]; 1145} 1146 1147-(void)moveWordBackwardAndModifySelection: (id)aSender 1148{ 1149 (void)aSender; 1150 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_BACKWARD character: 0 modifiers: 0]; 1151} 1152 1153-(void)moveWordLeftAndModifySelection: (id)aSender 1154{ 1155 (void)aSender; 1156 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_BACKWARD character: 0 modifiers: 0]; 1157} 1158 1159-(void)moveWordRight: (id)aSender 1160{ 1161 (void)aSender; 1162 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_FORWARD character: 0 modifiers: 0]; 1163} 1164 1165-(void)moveWordForward: (id)aSender 1166{ 1167 (void)aSender; 1168 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_FORWARD character: 0 modifiers: 0]; 1169} 1170 1171-(void)moveWordForwardAndModifySelection: (id)aSender 1172{ 1173 (void)aSender; 1174 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_FORWARD character: 0 modifiers: 0]; 1175} 1176 1177-(void)moveWordRightAndModifySelection: (id)aSender 1178{ 1179 (void)aSender; 1180 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_FORWARD character: 0 modifiers: 0]; 1181} 1182 1183-(void)moveToEndOfLine: (id)aSender 1184{ 1185 (void)aSender; 1186 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_LINE character: 0 modifiers: 0]; 1187} 1188 1189-(void)moveToRightEndOfLine: (id)aSender 1190{ 1191 (void)aSender; 1192 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_LINE character: 0 modifiers: 0]; 1193} 1194 1195-(void)moveToEndOfLineAndModifySelection: (id)aSender 1196{ 1197 (void)aSender; 1198 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_LINE character: 0 modifiers: 0]; 1199} 1200 1201-(void)moveToRightEndOfLineAndModifySelection: (id)aSender 1202{ 1203 (void)aSender; 1204 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_LINE character: 0 modifiers: 0]; 1205} 1206 1207-(void)moveToBeginningOfLine: (id)aSender 1208{ 1209 (void)aSender; 1210 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE character: 0 modifiers: 0]; 1211} 1212 1213-(void)moveToLeftEndOfLine: (id)aSender 1214{ 1215 (void)aSender; 1216 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE character: 0 modifiers: 0]; 1217} 1218 1219-(void)moveToBeginningOfLineAndModifySelection: (id)aSender 1220{ 1221 (void)aSender; 1222 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE character: 0 modifiers: 0]; 1223} 1224 1225-(void)moveToLeftEndOfLineAndModifySelection: (id)aSender 1226{ 1227 (void)aSender; 1228 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE character: 0 modifiers: 0]; 1229} 1230 1231-(void)moveToEndOfParagraph: (id)aSender 1232{ 1233 (void)aSender; 1234 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH character: 0 modifiers: 0]; 1235} 1236 1237-(void)moveToEndOfParagraphAndModifySelection: (id)aSender 1238{ 1239 (void)aSender; 1240 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH character: 0 modifiers: 0]; 1241} 1242 1243-(void)moveParagraphForward: (id)aSender 1244{ 1245 (void)aSender; 1246 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH character: 0 modifiers: 0]; 1247} 1248 1249-(void)moveParagraphForwardAndModifySelection: (id)aSender 1250{ 1251 (void)aSender; 1252 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH character: 0 modifiers: 0]; 1253} 1254 1255-(void)moveToBeginningOfParagraph: (id)aSender 1256{ 1257 (void)aSender; 1258 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0]; 1259} 1260 1261-(void)moveParagraphBackward: (id)aSender 1262{ 1263 (void)aSender; 1264 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0]; 1265} 1266 1267-(void)moveToBeginningOfParagraphAndModifySelection: (id)aSender 1268{ 1269 (void)aSender; 1270 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0]; 1271} 1272 1273-(void)moveParagraphBackwardAndModifySelection: (id)aSender 1274{ 1275 (void)aSender; 1276 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0]; 1277} 1278 1279-(void)moveToEndOfDocument: (id)aSender 1280{ 1281 (void)aSender; 1282 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT character: 0 modifiers: 0]; 1283} 1284 1285-(void)scrollToEndOfDocument: (id)aSender 1286{ 1287 (void)aSender; 1288 // this is not exactly what we should do, but it makes "End" and "Shift-End" behave consistent 1289 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT character: 0 modifiers: 0]; 1290} 1291 1292-(void)moveToEndOfDocumentAndModifySelection: (id)aSender 1293{ 1294 (void)aSender; 1295 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT character: 0 modifiers: 0]; 1296} 1297 1298-(void)moveToBeginningOfDocument: (id)aSender 1299{ 1300 (void)aSender; 1301 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT character: 0 modifiers: 0]; 1302} 1303 1304-(void)scrollToBeginningOfDocument: (id)aSender 1305{ 1306 (void)aSender; 1307 // this is not exactly what we should do, but it makes "Home" and "Shift-Home" behave consistent 1308 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT character: 0 modifiers: 0]; 1309} 1310 1311-(void)moveToBeginningOfDocumentAndModifySelection: (id)aSender 1312{ 1313 (void)aSender; 1314 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT character: 0 modifiers: 0]; 1315} 1316 1317-(void)moveUp: (id)aSender 1318{ 1319 (void)aSender; 1320 [self sendKeyInputAndReleaseToFrame: KEY_UP character: 0 modifiers: 0]; 1321} 1322 1323-(void)moveDown: (id)aSender 1324{ 1325 (void)aSender; 1326 [self sendKeyInputAndReleaseToFrame: KEY_DOWN character: 0 modifiers: 0]; 1327} 1328 1329-(void)insertNewline: (id)aSender 1330{ 1331 (void)aSender; 1332 // #i91267# make enter and shift-enter work by evaluating the modifiers 1333 [self sendKeyInputAndReleaseToFrame: KEY_RETURN character: '\n' modifiers: mpFrame->mnLastModifierFlags]; 1334} 1335 1336-(void)deleteBackward: (id)aSender 1337{ 1338 (void)aSender; 1339 [self sendKeyInputAndReleaseToFrame: KEY_BACKSPACE character: '\b' modifiers: 0]; 1340} 1341 1342-(void)deleteForward: (id)aSender 1343{ 1344 (void)aSender; 1345 [self sendKeyInputAndReleaseToFrame: KEY_DELETE character: 0x7f modifiers: 0]; 1346} 1347 1348-(void)deleteBackwardByDecomposingPreviousCharacter: (id)aSender 1349{ 1350 (void)aSender; 1351 [self sendKeyInputAndReleaseToFrame: KEY_BACKSPACE character: '\b' modifiers: 0]; 1352} 1353 1354-(void)deleteWordBackward: (id)aSender 1355{ 1356 (void)aSender; 1357 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_WORD_BACKWARD character: 0 modifiers: 0]; 1358} 1359 1360-(void)deleteWordForward: (id)aSender 1361{ 1362 (void)aSender; 1363 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_WORD_FORWARD character: 0 modifiers: 0]; 1364} 1365 1366-(void)deleteToBeginningOfLine: (id)aSender 1367{ 1368 (void)aSender; 1369 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_LINE character: 0 modifiers: 0]; 1370} 1371 1372-(void)deleteToEndOfLine: (id)aSender 1373{ 1374 (void)aSender; 1375 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_END_OF_LINE character: 0 modifiers: 0]; 1376} 1377 1378-(void)deleteToBeginningOfParagraph: (id)aSender 1379{ 1380 (void)aSender; 1381 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0]; 1382} 1383 1384-(void)deleteToEndOfParagraph: (id)aSender 1385{ 1386 (void)aSender; 1387 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_END_OF_PARAGRAPH character: 0 modifiers: 0]; 1388} 1389 1390-(void)insertLineBreak: (id)aSender 1391{ 1392 (void)aSender; 1393 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::INSERT_LINEBREAK character: 0 modifiers: 0]; 1394} 1395 1396-(void)insertParagraphSeparator: (id)aSender 1397{ 1398 (void)aSender; 1399 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::INSERT_PARAGRAPH character: 0 modifiers: 0]; 1400} 1401 1402-(void)selectWord: (id)aSender 1403{ 1404 (void)aSender; 1405 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD character: 0 modifiers: 0]; 1406} 1407 1408-(void)selectLine: (id)aSender 1409{ 1410 (void)aSender; 1411 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_LINE character: 0 modifiers: 0]; 1412} 1413 1414-(void)selectParagraph: (id)aSender 1415{ 1416 (void)aSender; 1417 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_PARAGRAPH character: 0 modifiers: 0]; 1418} 1419 1420-(void)selectAll: (id)aSender 1421{ 1422 (void)aSender; 1423 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_ALL character: 0 modifiers: 0]; 1424} 1425 1426-(void)cancelOperation: (id)aSender 1427{ 1428 (void)aSender; 1429 [self sendKeyInputAndReleaseToFrame: KEY_ESCAPE character: 0x1b modifiers: 0]; 1430} 1431 1432-(void)noop: (id)aSender 1433{ 1434 (void)aSender; 1435 if( ! mbKeyHandled ) 1436 { 1437 if( ! [self sendSingleCharacter:mpLastEvent] ) 1438 { 1439 /* prevent recursion */ 1440 if( mpLastEvent != mpLastSuperEvent && [NSApp respondsToSelector: @selector(sendSuperEvent:)] ) 1441 { 1442 id pLastSuperEvent = mpLastSuperEvent; 1443 mpLastSuperEvent = mpLastEvent; 1444 [NSApp performSelector:@selector(sendSuperEvent:) withObject: mpLastEvent]; 1445 mpLastSuperEvent = pLastSuperEvent; 1446 1447 std::map< NSEvent*, bool >::iterator it = GetSalData()->maKeyEventAnswer.find( mpLastEvent ); 1448 if( it != GetSalData()->maKeyEventAnswer.end() ) 1449 it->second = true; 1450 } 1451 } 1452 } 1453} 1454 1455-(BOOL)sendKeyInputAndReleaseToFrame: (sal_uInt16)nKeyCode character: (sal_Unicode)aChar 1456{ 1457 return [self sendKeyInputAndReleaseToFrame: nKeyCode character: aChar modifiers: mpFrame->mnLastModifierFlags]; 1458} 1459 1460-(BOOL)sendKeyInputAndReleaseToFrame: (sal_uInt16)nKeyCode character: (sal_Unicode)aChar modifiers: (unsigned int)nMod 1461{ 1462 return [self sendKeyToFrameDirect: nKeyCode character: aChar modifiers: nMod] || 1463 [self sendSingleCharacter: mpLastEvent]; 1464} 1465 1466-(BOOL)sendKeyToFrameDirect: (sal_uInt16)nKeyCode character: (sal_Unicode)aChar modifiers: (unsigned int)nMod 1467{ 1468 YIELD_GUARD; 1469 1470 long nRet = 0; 1471 if( AquaSalFrame::isAlive( mpFrame ) ) 1472 { 1473 SalKeyEvent aEvent; 1474 aEvent.mnTime = mpFrame->mnLastEventTime; 1475 aEvent.mnCode = nKeyCode | ImplGetModifierMask( nMod ); 1476 aEvent.mnCharCode = aChar; 1477 aEvent.mnRepeat = FALSE; 1478 nRet = mpFrame->CallCallback( SALEVENT_KEYINPUT, &aEvent ); 1479 std::map< NSEvent*, bool >::iterator it = GetSalData()->maKeyEventAnswer.find( mpLastEvent ); 1480 if( it != GetSalData()->maKeyEventAnswer.end() ) 1481 it->second = nRet ? true : false; 1482 if( AquaSalFrame::isAlive( mpFrame ) ) 1483 mpFrame->CallCallback( SALEVENT_KEYUP, &aEvent ); 1484 } 1485 return nRet ? YES : NO; 1486} 1487 1488 1489-(BOOL)sendSingleCharacter: (NSEvent *)pEvent 1490{ 1491 NSString* pUnmodifiedString = [pEvent charactersIgnoringModifiers]; 1492 1493 if( pUnmodifiedString && [pUnmodifiedString length] == 1 ) 1494 { 1495 unichar keyChar = [pUnmodifiedString characterAtIndex: 0]; 1496 sal_uInt16 nKeyCode = ImplMapCharCode( keyChar ); 1497 if( nKeyCode != 0 ) 1498 { 1499 // don't send unicodes in the private use area 1500 if( keyChar >= 0xf700 && keyChar < 0xf780 ) 1501 keyChar = 0; 1502 BOOL bRet = [self sendKeyToFrameDirect: nKeyCode character: keyChar modifiers: mpFrame->mnLastModifierFlags]; 1503 mbInKeyInput = false; 1504 1505 return bRet; 1506 } 1507 } 1508 return NO; 1509} 1510 1511 1512// NSTextInput protocol 1513- (NSArray *)validAttributesForMarkedText 1514{ 1515 return [NSArray arrayWithObjects:NSUnderlineStyleAttributeName, nil]; 1516} 1517 1518- (BOOL)hasMarkedText 1519{ 1520 BOOL bHasMarkedText; 1521 1522 bHasMarkedText = ( mMarkedRange.location != NSNotFound ) && 1523 ( mMarkedRange.length != 0 ); 1524 // hack to check keys like "Control-j" 1525 if( mbInKeyInput ) 1526 { 1527 mbNeedSpecialKeyHandle = true; 1528 } 1529 1530 // FIXME: 1531 // #i106901# 1532 // if we come here outside of mbInKeyInput, this is likely to be because 1533 // of the keyboard viewer. For unknown reasons having no marked range 1534 // in this case causes a crash. So we say we have a marked range anyway 1535 // This is a hack, since it is not understood what a) causes that crash 1536 // and b) why we should have a marked range at this point. 1537 if( ! mbInKeyInput ) 1538 bHasMarkedText = YES; 1539 1540 return bHasMarkedText; 1541} 1542 1543- (NSRange)markedRange 1544{ 1545 // FIXME: 1546 // #i106901# 1547 // if we come here outside of mbInKeyInput, this is likely to be because 1548 // of the keyboard viewer. For unknown reasons having no marked range 1549 // in this case causes a crash. So we say we have a marked range anyway 1550 // This is a hack, since it is not understood what a) causes that crash 1551 // and b) why we should have a marked range at this point. 1552 if( ! mbInKeyInput ) 1553 return NSMakeRange( 0, 0 ); 1554 1555 return [self hasMarkedText] ? mMarkedRange : NSMakeRange( NSNotFound, 0 ); 1556} 1557 1558- (NSRange)selectedRange 1559{ 1560 return mSelectedRange; 1561} 1562 1563- (void)setMarkedText:(id)aString selectedRange:(NSRange)selRange 1564{ 1565 if( ![aString isKindOfClass:[NSAttributedString class]] ) 1566 aString = [[[NSAttributedString alloc] initWithString:aString] autorelease]; 1567 NSRange rangeToReplace = [self hasMarkedText] ? [self markedRange] : [self selectedRange]; 1568 if( rangeToReplace.location == NSNotFound ) 1569 { 1570 mMarkedRange = NSMakeRange( selRange.location, [aString length] ); 1571 mSelectedRange = NSMakeRange( selRange.location, selRange.length ); 1572 } 1573 else 1574 { 1575 mMarkedRange = NSMakeRange( rangeToReplace.location, [aString length] ); 1576 mSelectedRange = NSMakeRange( rangeToReplace.location + selRange.location, selRange.length ); 1577 } 1578 1579 int len = [aString length]; 1580 SalExtTextInputEvent aInputEvent; 1581 aInputEvent.mnTime = mpFrame->mnLastEventTime; 1582 aInputEvent.mnDeltaStart = 0; 1583 aInputEvent.mbOnlyCursor = FALSE; 1584 if( len > 0 ) { 1585 NSString *pString = [aString string]; 1586 OUString aInsertString( GetOUString( pString ) ); 1587 std::vector<sal_uInt16> aInputFlags = std::vector<sal_uInt16>( std::max( 1, len ), 0 ); 1588 for ( int i = 0; i < len; i++ ) 1589 { 1590 unsigned int nUnderlineValue; 1591 NSRange effectiveRange; 1592 1593 effectiveRange = NSMakeRange(i, 1); 1594 nUnderlineValue = [[aString attribute:NSUnderlineStyleAttributeName atIndex:i effectiveRange:&effectiveRange] unsignedIntValue]; 1595 1596 switch (nUnderlineValue & 0xff) { 1597 case NSUnderlineStyleSingle: 1598 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_UNDERLINE; 1599 break; 1600 case NSUnderlineStyleThick: 1601 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_UNDERLINE | SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT; 1602 break; 1603 case NSUnderlineStyleDouble: 1604 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_BOLDUNDERLINE; 1605 break; 1606 default: 1607 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT; 1608 break; 1609 } 1610 } 1611 1612 aInputEvent.maText = aInsertString; 1613 aInputEvent.mnCursorPos = selRange.location; 1614 aInputEvent.mpTextAttr = &aInputFlags[0]; 1615 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void *)&aInputEvent ); 1616 } else { 1617 aInputEvent.maText = String(); 1618 aInputEvent.mnCursorPos = 0; 1619 aInputEvent.mnCursorFlags = 0; 1620 aInputEvent.mpTextAttr = 0; 1621 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void *)&aInputEvent ); 1622 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 ); 1623 } 1624 mbKeyHandled= true; 1625} 1626 1627- (void)unmarkText 1628{ 1629 mSelectedRange = mMarkedRange = NSMakeRange(NSNotFound, 0); 1630} 1631 1632- (NSAttributedString *)attributedSubstringFromRange:(NSRange)theRange 1633{ 1634 (void)theRange; 1635 // FIXME 1636 return nil; 1637} 1638 1639- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint 1640{ 1641 (void)thePoint; 1642 // FIXME 1643 return 0; 1644} 1645 1646#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) 1647/* build target 10.5 or greater */ 1648- (NSInteger)conversationIdentifier 1649#else 1650/* build target 10.4 */ 1651- (long)conversationIdentifier 1652#endif 1653{ 1654 return (long)self; 1655} 1656 1657- (void)doCommandBySelector:(SEL)aSelector 1658{ 1659 if( AquaSalFrame::isAlive( mpFrame ) ) 1660 { 1661 #if OSL_DEBUG_LEVEL > 1 1662 // fprintf( stderr, "SalFrameView: doCommandBySelector %s\n", (char*)aSelector ); 1663 #endif 1664 if( (mpFrame->mnICOptions & SAL_INPUTCONTEXT_TEXT) != 0 && 1665 aSelector != NULL && [self respondsToSelector: aSelector] ) 1666 { 1667 [self performSelector: aSelector]; 1668 } 1669 else 1670 { 1671 [self sendSingleCharacter:mpLastEvent]; 1672 } 1673 } 1674 1675 mbKeyHandled = true; 1676} 1677 1678-(void)clearLastEvent 1679{ 1680 mpLastEvent = nil; 1681} 1682 1683- (NSRect)firstRectForCharacterRange:(NSRange)theRange 1684{ 1685 (void)theRange; 1686 SalExtTextInputPosEvent aPosEvent; 1687 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void *)&aPosEvent ); 1688 1689 NSRect rect; 1690 1691 rect.origin.x = aPosEvent.mnX + mpFrame->maGeometry.nX; 1692 rect.origin.y = aPosEvent.mnY + mpFrame->maGeometry.nY + 4; // add some space for underlines 1693 rect.size.width = aPosEvent.mnWidth; 1694 rect.size.height = aPosEvent.mnHeight; 1695 1696 mpFrame->VCLToCocoa( rect ); 1697 return rect; 1698} 1699 1700-(id)parentAttribute { 1701 return mpFrame->getNSWindow(); 1702} 1703 1704-(::com::sun::star::accessibility::XAccessibleContext *)accessibleContext 1705{ 1706 if ( mpReferenceWrapper == nil ) { 1707 // some frames never become visible .. 1708 Window *pWindow = mpFrame -> GetWindow(); 1709 if ( ! pWindow ) 1710 return nil; 1711 1712 mpReferenceWrapper = new ReferenceWrapper; 1713 mpReferenceWrapper -> rAccessibleContext = pWindow -> /*GetAccessibleChildWindow( 0 ) ->*/ GetAccessible() -> getAccessibleContext(); 1714 [ AquaA11yFactory insertIntoWrapperRepository: self forAccessibleContext: mpReferenceWrapper -> rAccessibleContext ]; 1715 } 1716 return [ super accessibleContext ]; 1717} 1718 1719-(NSWindow*)windowForParent 1720{ 1721 return mpFrame->getNSWindow(); 1722} 1723 1724-(void)registerMouseEventListener: (id)theListener 1725{ 1726 mpMouseEventListener = theListener; 1727} 1728 1729-(void)unregisterMouseEventListener: (id)theListener 1730{ 1731 (void)theListener; 1732 mpMouseEventListener = nil; 1733} 1734 1735-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender 1736{ 1737 return [mDraggingDestinationHandler draggingEntered: sender]; 1738} 1739 1740-(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender 1741{ 1742 return [mDraggingDestinationHandler draggingUpdated: sender]; 1743} 1744 1745-(void)draggingExited:(id <NSDraggingInfo>)sender 1746{ 1747 [mDraggingDestinationHandler draggingExited: sender]; 1748} 1749 1750-(BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender 1751{ 1752 return [mDraggingDestinationHandler prepareForDragOperation: sender]; 1753} 1754 1755-(BOOL)performDragOperation:(id <NSDraggingInfo>)sender 1756{ 1757 return [mDraggingDestinationHandler performDragOperation: sender]; 1758} 1759 1760-(void)concludeDragOperation:(id <NSDraggingInfo>)sender 1761{ 1762 [mDraggingDestinationHandler concludeDragOperation: sender]; 1763} 1764 1765-(void)registerDraggingDestinationHandler:(id)theHandler 1766{ 1767 mDraggingDestinationHandler = theHandler; 1768} 1769 1770-(void)unregisterDraggingDestinationHandler:(id)theHandler 1771{ 1772 (void)theHandler; 1773 mDraggingDestinationHandler = nil; 1774} 1775 1776@end 1777 1778