1/* 2 * Copyright (C) 2009 Apple Inc. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#if USE(PLUGIN_HOST_PROCESS) 27 28#import "WebTextInputWindowController.h" 29 30#import <WebKitSystemInterface.h> 31 32@interface WebTextInputView : NSTextView { 33} 34@end 35 36@implementation WebTextInputView 37 38- (NSArray *)validAttributesForMarkedText 39{ 40 // Let TSM know that a bottom input window would be created for marked text. 41 NSArray *regularAttributes = [super validAttributesForMarkedText]; 42 NSMutableArray *floatingWindowAttributes = [NSMutableArray arrayWithArray:regularAttributes]; 43 [floatingWindowAttributes addObject:@"__NSUsesFloatingInputWindow"]; 44 return floatingWindowAttributes; 45} 46 47@end 48 49@interface WebTextInputPanel : NSPanel { 50 NSTextView *_inputTextView; 51} 52 53- (NSTextInputContext *)_inputContext; 54- (BOOL)_interpretKeyEvent:(NSEvent *)event string:(NSString **)string; 55 56@end 57 58#define inputWindowHeight 20 59 60@implementation WebTextInputPanel 61 62- (void)dealloc 63{ 64 [[NSNotificationCenter defaultCenter] removeObserver:self]; 65 66 [_inputTextView release]; 67 68 [super dealloc]; 69} 70 71- (id)init 72{ 73 self = [super initWithContentRect:NSZeroRect styleMask:WKGetInputPanelWindowStyle() backing:NSBackingStoreBuffered defer:YES]; 74 if (!self) 75 return nil; 76 77 // Set the frame size. 78 NSRect visibleFrame = [[NSScreen mainScreen] visibleFrame]; 79 NSRect frame = NSMakeRect(visibleFrame.origin.x, visibleFrame.origin.y, visibleFrame.size.width, inputWindowHeight); 80 81 [self setFrame:frame display:NO]; 82 83 _inputTextView = [[WebTextInputView alloc] initWithFrame:[self.contentView frame]]; 84 _inputTextView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable | NSViewMaxXMargin | NSViewMinXMargin | NSViewMaxYMargin | NSViewMinYMargin; 85 86 NSScrollView* scrollView = [[NSScrollView alloc] initWithFrame:[self.contentView frame]]; 87 scrollView.documentView = _inputTextView; 88 self.contentView = scrollView; 89 [scrollView release]; 90 91 [self setFloatingPanel:YES]; 92 93 [[NSNotificationCenter defaultCenter] addObserver:self 94 selector:@selector(_keyboardInputSourceChanged:) 95 name:NSTextInputContextKeyboardSelectionDidChangeNotification 96 object:nil]; 97 98 return self; 99} 100 101- (void)_keyboardInputSourceChanged:(NSNotification *)notification 102{ 103 [_inputTextView setString:@""]; 104 [self orderOut:nil]; 105} 106 107- (BOOL)_interpretKeyEvent:(NSEvent *)event string:(NSString **)string 108{ 109#pragma clang diagnostic push 110#pragma clang diagnostic ignored "-Wdeprecated-declarations" 111 BOOL hadMarkedText = [_inputTextView hasMarkedText]; 112#pragma clang diagnostic pop 113 114 *string = nil; 115 116 // Let TSM know that a bottom input window would be created for marked text. 117 // FIXME: Can be removed once we can rely on __NSUsesFloatingInputWindow (or a better API) being available everywhere. 118 EventRef carbonEvent = (EventRef)[event eventRef]; 119 if (carbonEvent) { 120 Boolean ignorePAH = true; 121 SetEventParameter(carbonEvent, 'iPAH', typeBoolean, sizeof(ignorePAH), &ignorePAH); 122 } 123 124 if (![[_inputTextView inputContext] handleEvent:event]) 125 return NO; 126 127#pragma clang diagnostic push 128#pragma clang diagnostic ignored "-Wdeprecated-declarations" 129 if ([_inputTextView hasMarkedText]) { 130#pragma clang diagnostic pop 131 // Don't show the input method window for dead keys 132 if ([[event characters] length] > 0) 133 [self orderFront:nil]; 134 135 return YES; 136 } 137 138 if (hadMarkedText) { 139 [self orderOut:nil]; 140 141 NSString *text = [[_inputTextView textStorage] string]; 142 if ([text length] > 0) 143 *string = [[text copy] autorelease]; 144 } 145 146 [_inputTextView setString:@""]; 147 return hadMarkedText; 148} 149 150- (NSTextInputContext *)_inputContext 151{ 152 return [_inputTextView inputContext]; 153} 154 155@end 156 157@implementation WebTextInputWindowController 158 159+ (WebTextInputWindowController *)sharedTextInputWindowController 160{ 161 static WebTextInputWindowController *textInputWindowController; 162 if (!textInputWindowController) 163 textInputWindowController = [[WebTextInputWindowController alloc] init]; 164 165 return textInputWindowController; 166} 167 168- (id)init 169{ 170 self = [super init]; 171 if (!self) 172 return nil; 173 174 _panel = [[WebTextInputPanel alloc] init]; 175 176 return self; 177} 178 179- (NSTextInputContext *)inputContext 180{ 181 return [_panel _inputContext]; 182} 183 184- (BOOL)interpretKeyEvent:(NSEvent *)event string:(NSString **)string 185{ 186 return [_panel _interpretKeyEvent:event string:string]; 187} 188 189@end 190 191#endif // USE(PLUGIN_HOST_PROCESS) 192 193