widget/cocoa/ComplexTextInputPanel.mm

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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  * Modified by Josh Aas of Mozilla Corporation.
    26  */
    28 #import "ComplexTextInputPanel.h"
    30 #include <algorithm>
    31 #include "mozilla/Preferences.h"
    32 #include "nsChildView.h"
    33 #include "nsCocoaFeatures.h"
    35 using namespace mozilla;
    37 #define kInputWindowHeight 20
    39 @implementation ComplexTextInputPanel
    41 + (ComplexTextInputPanel*)sharedComplexTextInputPanel
    42 {
    43   static ComplexTextInputPanel *sComplexTextInputPanel;
    44   if (!sComplexTextInputPanel)
    45     sComplexTextInputPanel = [[ComplexTextInputPanel alloc] init];
    46   return sComplexTextInputPanel;
    47 }
    49 - (id)init
    50 {
    51   // In the original Apple code the style mask is given by a function which is not open source.
    52   // What could possibly be worth hiding in that function, I do not know.
    53   // Courtesy of gdb: stylemask: 011000011111, 0x61f
    54   self = [super initWithContentRect:NSZeroRect styleMask:0x61f backing:NSBackingStoreBuffered defer:YES];
    55   if (!self)
    56     return nil;
    58   // Set the frame size.
    59   NSRect visibleFrame = [[NSScreen mainScreen] visibleFrame];
    60   NSRect frame = NSMakeRect(visibleFrame.origin.x, visibleFrame.origin.y, visibleFrame.size.width, kInputWindowHeight);
    62   [self setFrame:frame display:NO];
    64   mInputTextView = [[NSTextView alloc] initWithFrame:[self.contentView frame]];        
    65   mInputTextView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable | NSViewMaxXMargin | NSViewMinXMargin | NSViewMaxYMargin | NSViewMinYMargin;
    67   NSScrollView* scrollView = [[NSScrollView alloc] initWithFrame:[self.contentView frame]];
    68   scrollView.documentView = mInputTextView;
    69   self.contentView = scrollView;
    70   [scrollView release];
    72   [self setFloatingPanel:YES];
    74   [[NSNotificationCenter defaultCenter] addObserver:self
    75                                            selector:@selector(keyboardInputSourceChanged:)
    76                                                name:NSTextInputContextKeyboardSelectionDidChangeNotification
    77                                              object:nil];
    79   return self;
    80 }
    82 - (void)dealloc
    83 {
    84   [[NSNotificationCenter defaultCenter] removeObserver:self];
    86   [mInputTextView release];
    88   [super dealloc];
    89 }
    91 - (void)keyboardInputSourceChanged:(NSNotification *)notification
    92 {
    93   static int8_t sDoCancel = -1;
    94   if (!sDoCancel || ![self inComposition]) {
    95     return;
    96   }
    97   if (sDoCancel < 0) {
    98     bool cancelComposition = false;
    99     static const char* kPrefName =
   100       "ui.plugin.cancel_composition_at_input_source_changed";
   101     nsresult rv = Preferences::GetBool(kPrefName, &cancelComposition);
   102     NS_ENSURE_SUCCESS(rv, );
   103     sDoCancel = cancelComposition ? 1 : 0;
   104   }
   105   if (sDoCancel) {
   106     [self cancelComposition];
   107   }
   108 }
   110 - (BOOL)interpretKeyEvent:(NSEvent*)event string:(NSString**)string
   111 {
   112   BOOL hadMarkedText = [mInputTextView hasMarkedText];
   114   *string = nil;
   116   if (![[mInputTextView inputContext] handleEvent:event])
   117     return NO;
   119   if ([mInputTextView hasMarkedText]) {
   120     // Don't show the input method window for dead keys
   121     if ([[event characters] length] > 0)
   122       [self orderFront:nil];
   124     return YES;
   125   } else {
   126     [self orderOut:nil];
   128     NSString *text = [[mInputTextView textStorage] string];
   129     if ([text length] > 0)
   130       *string = [[text copy] autorelease];
   131   }
   133   [mInputTextView setString:@""];
   134   return hadMarkedText;
   135 }
   137 - (NSTextInputContext*)inputContext
   138 {
   139   return [mInputTextView inputContext];
   140 }
   142 - (void)cancelComposition
   143 {
   144   [mInputTextView setString:@""];
   145   [self orderOut:nil];
   146 }
   148 - (BOOL)inComposition
   149 {
   150   return [mInputTextView hasMarkedText];
   151 }
   153 - (void)adjustTo:(NSView*)view
   154 {
   155   NSRect viewRect = [view frame];
   156   viewRect.origin.x = 0;
   157   viewRect.origin.y = 0;
   158   viewRect = [view convertRect:viewRect toView:nil];
   159   if (nsCocoaFeatures::OnLionOrLater()) {
   160     viewRect = [[view window] convertRectToScreen:viewRect];
   161   } else {
   162     viewRect.origin = [[view window] convertBaseToScreen:viewRect.origin];
   163   }
   164   NSRect selfRect = [self frame];
   165   CGFloat minWidth = static_cast<CGFloat>(
   166                        Preferences::GetUint("ui.plugin.panel.min-width", 500));
   167   NSRect rect = NSMakeRect(viewRect.origin.x,
   168                            viewRect.origin.y - selfRect.size.height,
   169                            std::max(viewRect.size.width, minWidth),
   170                            selfRect.size.height);
   172   // Adjust to screen.
   173   NSRect screenRect = [[NSScreen mainScreen] visibleFrame];
   174   if (rect.origin.x < screenRect.origin.x) {
   175     rect.origin.x = screenRect.origin.x;
   176   }
   177   if (rect.origin.y < screenRect.origin.y) {
   178     rect.origin.y = screenRect.origin.y;
   179   }
   180   CGFloat xMostOfScreen = screenRect.origin.x + screenRect.size.width;
   181   CGFloat yMostOfScreen = screenRect.origin.y + screenRect.size.height;
   182   CGFloat xMost = rect.origin.x + rect.size.width;
   183   CGFloat yMost = rect.origin.y + rect.size.height;
   184   if (xMostOfScreen < xMost) {
   185     rect.origin.x -= xMost - xMostOfScreen;
   186   }
   187   if (yMostOfScreen < yMost) {
   188     rect.origin.y -= yMost - yMostOfScreen;
   189   }
   191   [self setFrame:rect display:[self isVisible]];
   192 }
   194 @end

mercurial