📄 hiwebview.m
字号:
/* * Copyright (C) 2005 Apple Computer, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#ifndef __LP64__#import "HIWebView.h"#import "CarbonWindowAdapter.h"#import "HIViewAdapter.h"#import "WebHTMLViewInternal.h"#import "WebKit.h"#import <objc/objc-runtime.h>#import <WebKitSystemInterface.h>@interface NSWindow (AppKitSecretsHIWebViewKnows)- (void)_removeWindowRef;@end@interface NSView (AppKitSecretsHIWebViewKnows)- (void)_clearDirtyRectsForTree;@endextern "C" void HIWebViewRegisterClass();@interface MenuItemProxy : NSObject <NSValidatedUserInterfaceItem>{ int _tag; SEL _action;}- (id)initWithAction:(SEL)action;- (SEL)action;- (int)tag;@end@implementation MenuItemProxy- (id)initWithAction:(SEL)action{ [super init]; if (self == nil) return nil; _action = action; return self;}- (SEL)action{ return _action;}- (int)tag { return 0;}@endstruct HIWebView{ HIViewRef fViewRef; WebView* fWebView; NSView* fFirstResponder; CarbonWindowAdapter * fKitWindow; bool fIsComposited; CFRunLoopObserverRef fUpdateObserver;};typedef struct HIWebView HIWebView;static const OSType NSAppKitPropertyCreator = 'akit';/*These constants are not used. Commented out to make the compiler happy.static const OSType NSViewCarbonControlViewPropertyTag = 'view';static const OSType NSViewCarbonControlAutodisplayPropertyTag = 'autd';static const OSType NSViewCarbonControlFirstResponderViewPropertyTag = 'frvw';*/static const OSType NSCarbonWindowPropertyTag = 'win ';#ifdef BUILDING_ON_TIGERconst int typeByteCount = typeSInt32;#endifstatic SEL _NSSelectorForHICommand( const HICommand* hiCommand );static const EventTypeSpec kEvents[] = { { kEventClassHIObject, kEventHIObjectConstruct }, { kEventClassHIObject, kEventHIObjectDestruct }, { kEventClassMouse, kEventMouseUp }, { kEventClassMouse, kEventMouseMoved }, { kEventClassMouse, kEventMouseDragged }, { kEventClassMouse, kEventMouseWheelMoved }, { kEventClassKeyboard, kEventRawKeyDown }, { kEventClassKeyboard, kEventRawKeyRepeat }, { kEventClassCommand, kEventCommandProcess }, { kEventClassCommand, kEventCommandUpdateStatus }, { kEventClassControl, kEventControlInitialize }, { kEventClassControl, kEventControlDraw }, { kEventClassControl, kEventControlHitTest }, { kEventClassControl, kEventControlGetPartRegion }, { kEventClassControl, kEventControlGetData }, { kEventClassControl, kEventControlBoundsChanged }, { kEventClassControl, kEventControlActivate }, { kEventClassControl, kEventControlDeactivate }, { kEventClassControl, kEventControlOwningWindowChanged }, { kEventClassControl, kEventControlClick }, { kEventClassControl, kEventControlContextualMenuClick }, { kEventClassControl, kEventControlSetFocusPart }};#define kHIViewBaseClassID CFSTR( "com.apple.hiview" )#define kHIWebViewClassID CFSTR( "com.apple.HIWebView" )static HIWebView* HIWebViewConstructor( HIViewRef inView );static void HIWebViewDestructor( HIWebView* view );static OSStatus HIWebViewEventHandler( EventHandlerCallRef inCallRef, EventRef inEvent, void * inUserData );static UInt32 GetBehaviors();static ControlKind GetKind();static void Draw( HIWebView* inView, RgnHandle limitRgn, CGContextRef inContext );static ControlPartCode HitTest( HIWebView* view, const HIPoint* where );static OSStatus GetRegion( HIWebView* view, ControlPartCode inPart, RgnHandle outRgn );static void BoundsChanged( HIWebView* inView, UInt32 inOptions, const HIRect* inOriginalBounds, const HIRect* inCurrentBounds );static void OwningWindowChanged( HIWebView* view, WindowRef oldWindow, WindowRef newWindow );static void ActiveStateChanged( HIWebView* view );static OSStatus Click( HIWebView* inView, EventRef inEvent );static OSStatus ContextMenuClick( HIWebView* inView, EventRef inEvent );static OSStatus MouseUp( HIWebView* inView, EventRef inEvent );static OSStatus MouseMoved( HIWebView* inView, EventRef inEvent );static OSStatus MouseDragged( HIWebView* inView, EventRef inEvent );static OSStatus MouseWheelMoved( HIWebView* inView, EventRef inEvent );static OSStatus ProcessCommand( HIWebView* inView, const HICommand* inCommand );static OSStatus UpdateCommandStatus( HIWebView* inView, const HICommand* inCommand );static OSStatus SetFocusPart( HIWebView* view, ControlPartCode desiredFocus, RgnHandle invalidRgn, Boolean focusEverything, ControlPartCode* actualFocus );static NSView* AdvanceFocus( HIWebView* view, bool forward );static void RelinquishFocus( HIWebView* view, bool inAutodisplay );static WindowRef GetWindowRef( HIWebView* inView );static void SyncFrame( HIWebView* inView );static OSStatus WindowHandler( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData );static void StartUpdateObserver( HIWebView* view );static void StopUpdateObserver( HIWebView* view );static inline void HIRectToQDRect( const HIRect* inRect, Rect* outRect ){ outRect->top = (SInt16)CGRectGetMinY( *inRect ); outRect->left = (SInt16)CGRectGetMinX( *inRect ); outRect->bottom = (SInt16)CGRectGetMaxY( *inRect ); outRect->right = (SInt16)CGRectGetMaxX( *inRect );}//----------------------------------------------------------------------------------// HIWebViewCreate//----------------------------------------------------------------------------------//OSStatusHIWebViewCreate(HIViewRef* outControl){ HIWebViewRegisterClass(); return HIObjectCreate(kHIWebViewClassID, NULL, (HIObjectRef*)outControl);}//----------------------------------------------------------------------------------// HIWebViewGetWebView//----------------------------------------------------------------------------------//WebView*HIWebViewGetWebView( HIViewRef inView ){ HIWebView* view = (HIWebView*)HIObjectDynamicCast( (HIObjectRef)inView, kHIWebViewClassID ); WebView* result = NULL; if ( view ) result = view->fWebView; return result;}//----------------------------------------------------------------------------------// HIWebViewConstructor//----------------------------------------------------------------------------------//static HIWebView*HIWebViewConstructor( HIViewRef inView ){ HIWebView* view = (HIWebView*)malloc( sizeof( HIWebView ) ); if ( view ) { NSRect frame = { { 0, 0 }, { 400, 400 } }; view->fViewRef = inView; WebView *webView = [[WebView alloc] initWithFrame: frame]; CFRetain(webView); [webView release]; view->fWebView = webView; [HIViewAdapter bindHIViewToNSView:inView nsView:view->fWebView]; view->fFirstResponder = NULL; view->fKitWindow = NULL; view->fIsComposited = false; view->fUpdateObserver = NULL; } return view;}//----------------------------------------------------------------------------------// HIWebViewDestructor//----------------------------------------------------------------------------------//static voidHIWebViewDestructor( HIWebView* inView ){ [HIViewAdapter unbindNSView:inView->fWebView]; CFRelease(inView->fWebView); free(inView);}//----------------------------------------------------------------------------------// HIWebViewRegisterClass//----------------------------------------------------------------------------------//voidHIWebViewRegisterClass(){ static bool sRegistered; if ( !sRegistered ) { HIObjectRegisterSubclass( kHIWebViewClassID, kHIViewBaseClassID, 0, HIWebViewEventHandler, GetEventTypeCount( kEvents ), kEvents, 0, NULL ); sRegistered = true; }}//----------------------------------------------------------------------------------// GetBehaviors//----------------------------------------------------------------------------------//static UInt32GetBehaviors(){ return kControlSupportsDataAccess | kControlSupportsGetRegion | kControlGetsFocusOnClick;}//----------------------------------------------------------------------------------// Draw//----------------------------------------------------------------------------------//static voidDraw( HIWebView* inView, RgnHandle limitRgn, CGContextRef inContext ){ HIRect bounds; Rect drawRect; HIRect hiRect; bool createdContext = false; if (!inView->fIsComposited) { GrafPtr port; Rect portRect; GetPort( &port ); GetPortBounds( port, &portRect ); CreateCGContextForPort( port, &inContext ); SyncCGContextOriginWithPort( inContext, port ); CGContextTranslateCTM( inContext, 0, (portRect.bottom - portRect.top) ); CGContextScaleCTM( inContext, 1, -1 ); createdContext = true; } HIViewGetBounds( inView->fViewRef, &bounds ); CGContextRef savedContext = WKNSWindowOverrideCGContext(inView->fKitWindow, inContext); [NSGraphicsContext setCurrentContext:[inView->fKitWindow graphicsContext]]; GetRegionBounds( limitRgn, &drawRect ); if ( !inView->fIsComposited ) OffsetRect( &drawRect, (SInt16)-bounds.origin.x, (SInt16)-bounds.origin.y ); hiRect.origin.x = drawRect.left; hiRect.origin.y = bounds.size.height - drawRect.bottom; // flip y hiRect.size.width = drawRect.right - drawRect.left; hiRect.size.height = drawRect.bottom - drawRect.top;// printf( "Drawing: drawRect is (%g %g) (%g %g)\n", hiRect.origin.x, hiRect.origin.y,// hiRect.size.width, hiRect.size.height ); // FIXME: We need to do layout before Carbon has decided what region needs drawn. // In Cocoa we make sure to do layout and invalidate any new regions before draw, so everything // can be drawn in one pass. Doing a layout here will cause new regions to be invalidated, but they // will not all be drawn in this pass since we already have a fixed rect we are going to display. NSView <WebDocumentView> *documentView = [[[inView->fWebView mainFrame] frameView] documentView]; if ([documentView isKindOfClass:[WebHTMLView class]]) [(WebHTMLView *)documentView _web_layoutIfNeededRecursive]; if ( inView->fIsComposited ) [inView->fWebView displayIfNeededInRect: *(NSRect*)&hiRect]; else [inView->fWebView displayRect:*(NSRect*)&hiRect]; WKNSWindowRestoreCGContext(inView->fKitWindow, savedContext); if ( !inView->fIsComposited ) { HIViewRef view; HIViewFindByID( HIViewGetRoot( GetControlOwner( inView->fViewRef ) ), kHIViewWindowGrowBoxID, &view ); if ( view ) { HIRect frame; HIViewGetBounds( view, &frame ); HIViewConvertRect( &frame, view, NULL ); hiRect.origin.x = drawRect.left; hiRect.origin.y = drawRect.top; hiRect.size.width = drawRect.right - drawRect.left; hiRect.size.height = drawRect.bottom - drawRect.top; HIViewConvertRect( &hiRect, inView->fViewRef, NULL ); if ( CGRectIntersectsRect( frame, hiRect ) ) HIViewSetNeedsDisplay( view, true ); } } if ( createdContext ) { CGContextSynchronize( inContext ); CGContextRelease( inContext ); }}//----------------------------------------------------------------------------------// HitTest//----------------------------------------------------------------------------------//static ControlPartCodeHitTest( HIWebView* view, const HIPoint* where ){ HIRect bounds; HIViewGetBounds( view->fViewRef, &bounds ); if ( CGRectContainsPoint( bounds, *where ) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -