summaryrefslogtreecommitdiffstats
path: root/widget/uikit/nsWindow.mm
diff options
context:
space:
mode:
Diffstat (limited to 'widget/uikit/nsWindow.mm')
-rw-r--r--widget/uikit/nsWindow.mm420
1 files changed, 359 insertions, 61 deletions
diff --git a/widget/uikit/nsWindow.mm b/widget/uikit/nsWindow.mm
index 0c1a38c27c..51b317ee61 100644
--- a/widget/uikit/nsWindow.mm
+++ b/widget/uikit/nsWindow.mm
@@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#import <UIKit/UIEvent.h>
+#import <UIKit/UIKit.h>
#import <UIKit/UIGraphics.h>
#import <UIKit/UIInterface.h>
#import <UIKit/UIScreen.h>
@@ -17,29 +18,41 @@
#include <algorithm>
#include "nsWindow.h"
-#include "nsScreenManager.h"
#include "nsAppShell.h"
+#ifdef ACCESSIBILITY
+# include "nsAccessibilityService.h"
+# include "mozilla/a11y/LocalAccessible.h"
+#endif
#include "nsWidgetsCID.h"
#include "nsGfxCIID.h"
+#include "gfxPlatform.h"
#include "gfxQuartzSurface.h"
#include "gfxUtils.h"
#include "gfxImageSurface.h"
#include "gfxContext.h"
+#include "nsObjCExceptions.h"
#include "nsRegion.h"
-#include "Layers.h"
#include "nsTArray.h"
+#include "TextInputHandler.h"
+#include "UIKitUtils.h"
#include "mozilla/BasicEvents.h"
#include "mozilla/ProfilerLabels.h"
#include "mozilla/TouchEvents.h"
#include "mozilla/Unused.h"
#include "mozilla/dom/MouseEventBinding.h"
+#include "mozilla/gfx/Logging.h"
+#ifdef ACCESSIBILITY
+# include "mozilla/a11y/MUIRootAccessibleProtocol.h"
+#endif
using namespace mozilla;
-using namespace mozilla::dom;
+using namespace mozilla::gfx;
using namespace mozilla::layers;
+using mozilla::dom::Touch;
+using mozilla::widget::UIKitUtils;
#define ALOG(args...) \
fprintf(stderr, args); \
@@ -62,18 +75,22 @@ static CGRect DevPixelsToUIKitPoints(const LayoutDeviceIntRect& aRect,
// Used to retain a Cocoa object for the remainder of a method's execution.
class nsAutoRetainUIKitObject {
public:
- nsAutoRetainUIKitObject(id anObject) { mObject = [anObject retain]; }
+ explicit nsAutoRetainUIKitObject(id anObject) { mObject = [anObject retain]; }
~nsAutoRetainUIKitObject() { [mObject release]; }
private:
id mObject; // [STRONG]
};
-@interface ChildView : UIView {
+#ifdef ACCESSIBILITY
+@interface ChildView : UIView <UIKeyInput, MUIRootAccessibleProtocol> {
+#else
+@interface ChildView : UIView <UIKeyInput> {
+#endif
@public
nsWindow* mGeckoChild; // weak ref
BOOL mWaitingForPaint;
- CFMutableDictionaryRef mTouches;
+ NSMapTable<UITouch*, NSNumber*>* mTouches;
int mNextTouchID;
}
// sets up our view, attaching it to its owning gecko view
@@ -93,10 +110,32 @@ class nsAutoRetainUIKitObject {
touches:(NSSet*)aTouches
widget:(nsWindow*)aWindow;
// Event handling (UIResponder)
-- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event;
-- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event;
-- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event;
-- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event;
+- (void)touchesBegan:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event;
+- (void)touchesCancelled:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event;
+- (void)touchesEnded:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event;
+- (void)touchesMoved:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event;
+
+- (void)activateWindow:(NSNotification*)notification;
+- (void)deactivateWindow:(NSNotification*)notification;
+
+#ifdef ACCESSIBILITY
+// MUIRootAccessible
+- (BOOL)hasRepresentedView;
+- (id)representedView;
+
+// MUIAccessible
+- (BOOL)isAccessibilityElement;
+- (NSString*)accessibilityLabel;
+- (CGRect)accessibilityFrame;
+- (NSString*)accessibilityValue;
+- (uint64_t)accessibilityTraits;
+- (NSInteger)accessibilityElementCount;
+- (nullable id)accessibilityElementAtIndex:(NSInteger)index;
+- (NSInteger)indexOfAccessibilityElement:(id)element;
+- (NSArray* _Nullable)accessibilityElements;
+- (UIAccessibilityContainerType)accessibilityContainerType;
+#endif
+
@end
@implementation ChildView
@@ -120,15 +159,29 @@ class nsAutoRetainUIKitObject {
tapRecognizer.numberOfTapsRequired = 1;
[self addGestureRecognizer:tapRecognizer];
- mTouches =
- CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr);
+ mTouches = [[NSMapTable alloc] init];
mNextTouchID = 0;
+
+ // This is managed with weak references by the notification center so that we
+ // do not need to call removeObserver.
+ // https://developer.apple.com/documentation/foundation/nsnotificationcenter/1415360-addobserver#discussion
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(activateWindow:)
+ name:UIWindowDidBecomeKeyNotification
+ object:nil];
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(deactivateWindow:)
+ name:UIWindowDidResignKeyNotification
+ object:nil];
+
return self;
}
- (void)widgetDestroyed {
mGeckoChild = nullptr;
- CFRelease(mTouches);
+ [mTouches release];
}
- (void)delayedTearDown {
@@ -136,6 +189,30 @@ class nsAutoRetainUIKitObject {
[self release];
}
+- (void)activateWindow:(NSNotification*)notification {
+ ALOG("[[ChildView[%p] activateWindow]", (void*)self);
+
+ if (!mGeckoChild) {
+ return;
+ }
+
+ if (nsIWidgetListener* listener = mGeckoChild->GetWidgetListener()) {
+ listener->WindowActivated();
+ }
+}
+
+- (void)deactivateWindow:(NSNotification*)notification {
+ ALOG("[[ChildView[%p] deactivateWindow]", (void*)self);
+
+ if (!mGeckoChild) {
+ return;
+ }
+
+ if (nsIWidgetListener* listener = mGeckoChild->GetWidgetListener()) {
+ listener->WindowDeactivated();
+ }
+}
+
- (void)sendMouseEvent:(EventMessage)aType
point:(LayoutDeviceIntPoint)aPoint
widget:(nsWindow*)aWindow {
@@ -144,9 +221,8 @@ class nsAutoRetainUIKitObject {
event.mRefPoint = aPoint;
event.mClickCount = 1;
- event.button = MouseButton::ePrimary;
- event.mTime = PR_IntervalNow();
- event.inputSource = MouseEvent_Binding::MOZ_SOURCE_UNKNOWN;
+ event.mButton = MouseButton::ePrimary;
+ event.mInputSource = mozilla::dom::MouseEvent_Binding::MOZ_SOURCE_UNKNOWN;
nsEventStatus status;
aWindow->DispatchEvent(&event, status);
@@ -169,20 +245,20 @@ class nsAutoRetainUIKitObject {
WidgetTouchEvent event(true, aType, aWindow);
// XXX: I think nativeEvent.timestamp * 1000 is probably usable here but
// I don't care that much right now.
- event.mTime = PR_IntervalNow();
event.mTouches.SetCapacity(aTouches.count);
for (UITouch* touch in aTouches) {
LayoutDeviceIntPoint loc = UIKitPointsToDevPixels(
[touch locationInView:self], [self contentScaleFactor]);
- LayoutDeviceIntPoint radius =
- UIKitPointsToDevPixels([touch majorRadius], [touch majorRadius]);
- void* value;
- if (!CFDictionaryGetValueIfPresent(mTouches, touch, (const void**)&value)) {
+ LayoutDeviceIntPoint radius = UIKitPointsToDevPixels(
+ CGPointMake([touch majorRadius], [touch majorRadius]),
+ [self contentScaleFactor]);
+ NSNumber* value = [mTouches objectForKey:touch];
+ if (value == nil) {
// This shouldn't happen.
NS_ASSERTION(false, "Got a touch that we didn't know about");
continue;
}
- int id = reinterpret_cast<int>(value);
+ int id = [value intValue];
RefPtr<Touch> t = new Touch(id, loc, radius, 0.0f, 1.0f);
event.mRefPoint = loc;
event.mTouches.AppendElement(t);
@@ -190,12 +266,12 @@ class nsAutoRetainUIKitObject {
aWindow->DispatchInputEvent(&event);
}
-- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
+- (void)touchesBegan:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event {
ALOG("[ChildView[%p] touchesBegan", self);
if (!mGeckoChild) return;
for (UITouch* touch : touches) {
- CFDictionaryAddValue(mTouches, touch, (void*)mNextTouchID);
+ [mTouches setObject:[NSNumber numberWithInt:mNextTouchID] forKey:touch];
mNextTouchID++;
}
[self sendTouchEvent:eTouchStart
@@ -203,31 +279,31 @@ class nsAutoRetainUIKitObject {
widget:mGeckoChild];
}
-- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event {
+- (void)touchesCancelled:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event {
ALOG("[ChildView[%p] touchesCancelled", self);
[self sendTouchEvent:eTouchCancel touches:touches widget:mGeckoChild];
for (UITouch* touch : touches) {
- CFDictionaryRemoveValue(mTouches, touch);
+ [mTouches removeObjectForKey:touch];
}
- if (CFDictionaryGetCount(mTouches) == 0) {
+ if (mTouches.count == 0) {
mNextTouchID = 0;
}
}
-- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
+- (void)touchesEnded:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event {
ALOG("[ChildView[%p] touchesEnded", self);
if (!mGeckoChild) return;
[self sendTouchEvent:eTouchEnd touches:touches widget:mGeckoChild];
for (UITouch* touch : touches) {
- CFDictionaryRemoveValue(mTouches, touch);
+ [mTouches removeObjectForKey:touch];
}
- if (CFDictionaryGetCount(mTouches) == 0) {
+ if (mTouches.count == 0) {
mNextTouchID = 0;
}
}
-- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
+- (void)touchesMoved:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event {
ALOG("[ChildView[%p] touchesMoved", self);
if (!mGeckoChild) return;
@@ -236,6 +312,17 @@ class nsAutoRetainUIKitObject {
widget:mGeckoChild];
}
+- (BOOL)canBecomeFirstResponder {
+ if (!mGeckoChild) {
+ return NO;
+ }
+
+ if (mGeckoChild->IsVirtualKeyboardDisabled()) {
+ return NO;
+ }
+ return YES;
+}
+
- (void)setNeedsDisplayInRect:(CGRect)aRect {
if ([self isUsingMainThreadOpenGL]) {
// Draw without calling drawRect. This prevent us from
@@ -326,7 +413,8 @@ class nsAutoRetainUIKitObject {
CGContextScaleCTM(aContext, 1.0 / scale, 1.0 / scale);
CGSize viewSize = [self bounds].size;
- gfx::IntSize backingSize(viewSize.width * scale, viewSize.height * scale);
+ gfx::IntSize backingSize(NSToIntRound(viewSize.width * scale),
+ NSToIntRound(viewSize.height * scale));
CGContextSaveGState(aContext);
@@ -339,13 +427,12 @@ class nsAutoRetainUIKitObject {
// Create Cairo objects.
RefPtr<gfxQuartzSurface> targetSurface;
- UniquePtrPtr<gfxContext> targetContext;
+ UniquePtr<gfxContext> targetContext;
if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(
gfx::BackendType::CAIRO)) {
// This is dead code unless you mess with prefs, but keep it around for
// debugging.
targetSurface = new gfxQuartzSurface(aContext, backingSize);
- targetSurface->SetAllowUseAsSource(false);
RefPtr<gfx::DrawTarget> dt =
gfxPlatform::CreateDrawTargetForSurface(targetSurface, backingSize);
if (!dt || !dt->IsValid()) {
@@ -399,6 +486,183 @@ class nsAutoRetainUIKitObject {
CGContextStrokeRect(aContext, aRect);
#endif
}
+
+// UIKeyInput
+
+- (void)insertText:(NSString*)text {
+ if (!mGeckoChild || mGeckoChild->Destroyed()) {
+ return;
+ }
+ widget::TextInputHandler* textInputHandler =
+ mGeckoChild->GetTextInputHandler();
+ if (!textInputHandler) {
+ return;
+ }
+ textInputHandler->InsertText(text);
+}
+
+- (void)deleteBackward {
+ if (!mGeckoChild || mGeckoChild->Destroyed()) {
+ return;
+ }
+ widget::TextInputHandler* textInputHandler =
+ mGeckoChild->GetTextInputHandler();
+ if (!textInputHandler) {
+ return;
+ }
+ textInputHandler->HandleCommand(Command::DeleteCharBackward);
+}
+
+- (BOOL)hasText {
+ if (!mGeckoChild || mGeckoChild->Destroyed()) {
+ return NO;
+ }
+ widget::InputContext context = mGeckoChild->GetInputContext();
+ if (context.mIMEState.mEnabled == mozilla::widget::IMEEnabled::Disabled) {
+ return NO;
+ }
+ return YES;
+}
+
+// UITextInputTraits
+
+- (UIKeyboardType)keyboardType {
+ if (!mGeckoChild || mGeckoChild->Destroyed()) {
+ return UIKeyboardTypeDefault;
+ }
+ return UIKitUtils::GetUIKeyboardType(mGeckoChild->GetInputContext());
+}
+
+- (UIReturnKeyType)returnKeyType {
+ if (!mGeckoChild || mGeckoChild->Destroyed()) {
+ return UIReturnKeyDefault;
+ }
+ return UIKitUtils::GetUIReturnKeyType(mGeckoChild->GetInputContext());
+}
+
+- (UITextAutocapitalizationType)autocapitalizationType {
+ if (!mGeckoChild || mGeckoChild->Destroyed()) {
+ return UITextAutocapitalizationTypeNone;
+ }
+ return UIKitUtils::GetUITextAutocapitalizationType(
+ mGeckoChild->GetInputContext());
+}
+
+- (BOOL)isSecureTextEntry {
+ if (!mGeckoChild || mGeckoChild->Destroyed()) {
+ return NO;
+ }
+ if (mGeckoChild->GetInputContext().IsPasswordEditor()) {
+ return YES;
+ }
+ return NO;
+}
+
+#ifdef ACCESSIBILITY
+// MUIRootAccessible
+
+- (id<MUIRootAccessibleProtocol>)accessible {
+ if (!mGeckoChild) return nil;
+
+ id<MUIRootAccessibleProtocol> nativeAccessible = nil;
+
+ // nsAutoRetainCocoaObject kungFuDeathGrip(self);
+ RefPtr<nsWindow> geckoChild(mGeckoChild);
+ RefPtr<a11y::LocalAccessible> accessible = geckoChild->GetRootAccessible();
+ if (!accessible) return nil;
+
+ accessible->GetNativeInterface((void**)&nativeAccessible);
+
+ return nativeAccessible;
+}
+
+- (BOOL)hasRepresentedView {
+ return YES;
+}
+
+- (id)representedView {
+ return self;
+}
+
+- (BOOL)isAccessibilityElement {
+ if (!mozilla::a11y::ShouldA11yBeEnabled()) {
+ return [super isAccessibilityElement];
+ }
+
+ return [[self accessible] isAccessibilityElement];
+}
+
+- (NSString*)accessibilityLabel {
+ if (!mozilla::a11y::ShouldA11yBeEnabled()) {
+ return [super accessibilityLabel];
+ }
+
+ return [[self accessible] accessibilityLabel];
+}
+
+- (CGRect)accessibilityFrame {
+ // Use the UIView implementation here. We rely on the position of this
+ // frame to place gecko bounds in the right offset.
+ return [super accessibilityFrame];
+}
+
+- (NSString*)accessibilityValue {
+ if (!mozilla::a11y::ShouldA11yBeEnabled()) {
+ return [super accessibilityValue];
+ }
+
+ return [[self accessible] accessibilityValue];
+}
+
+- (uint64_t)accessibilityTraits {
+ if (!mozilla::a11y::ShouldA11yBeEnabled()) {
+ return [super accessibilityTraits];
+ }
+
+ return [[self accessible] accessibilityTraits];
+}
+
+- (NSInteger)accessibilityElementCount {
+ if (!mozilla::a11y::ShouldA11yBeEnabled()) {
+ return [super accessibilityElementCount];
+ }
+
+ return [[self accessible] accessibilityElementCount];
+}
+
+- (nullable id)accessibilityElementAtIndex:(NSInteger)index {
+ if (!mozilla::a11y::ShouldA11yBeEnabled()) {
+ return [super accessibilityElementAtIndex:index];
+ }
+
+ return [[self accessible] accessibilityElementAtIndex:index];
+}
+
+- (NSInteger)indexOfAccessibilityElement:(id)element {
+ if (!mozilla::a11y::ShouldA11yBeEnabled()) {
+ return [super indexOfAccessibilityElement:element];
+ }
+
+ return [[self accessible] indexOfAccessibilityElement:element];
+}
+
+- (NSArray* _Nullable)accessibilityElements {
+ if (!mozilla::a11y::ShouldA11yBeEnabled()) {
+ return [super accessibilityElements];
+ }
+
+ return [[self accessible] accessibilityElements];
+}
+
+- (UIAccessibilityContainerType)accessibilityContainerType {
+ if (!mozilla::a11y::ShouldA11yBeEnabled()) {
+ return [super accessibilityContainerType];
+ }
+
+ return [[self accessible] accessibilityContainerType];
+}
+#endif
+
@end
nsWindow::nsWindow()
@@ -442,20 +706,7 @@ nsresult nsWindow::Create(nsIWidget* aParent, nsNativeWidget aNativeParent,
if (parent == nullptr && nativeParent) parent = nativeParent->mGeckoChild;
if (parent && nativeParent == nullptr) nativeParent = parent->mNativeView;
- // for toplevel windows, bounds are fixed to full screen size
- if (parent == nullptr) {
- if (nsAppShell::gWindow == nil) {
- mBounds = UIKitScreenManager::GetBounds();
- } else {
- CGRect cgRect = [nsAppShell::gWindow bounds];
- mBounds.x = cgRect.origin.x;
- mBounds.y = cgRect.origin.y;
- mBounds.width = cgRect.size.width;
- mBounds.height = cgRect.size.height;
- }
- } else {
- mBounds = aRect;
- }
+ mBounds = aRect;
ALOG("nsWindow[%p]::Create bounds: %d %d %d %d", (void*)this, mBounds.x,
mBounds.y, mBounds.width, mBounds.height);
@@ -487,6 +738,8 @@ nsresult nsWindow::Create(nsIWidget* aParent, nsNativeWidget aNativeParent,
[nsAppShell::gTopLevelViews addObject:mNativeView];
}
+ mTextInputHandler = new widget::TextInputHandler(this);
+
return NS_OK;
}
@@ -498,6 +751,11 @@ void nsWindow::Destroy() {
if (mParent) mParent->mChildren.RemoveElement(this);
+ if (mTextInputHandler) {
+ mTextInputHandler->OnDestroyed();
+ }
+ mTextInputHandler = nullptr;
+
[mNativeView widgetDestroyed];
nsBaseWidget::Destroy();
@@ -507,8 +765,6 @@ void nsWindow::Destroy() {
TearDownView();
nsBaseWidget::OnDestroy();
-
- return NS_OK;
}
void nsWindow::Show(bool aState) {
@@ -595,16 +851,12 @@ void nsWindow::SetSizeMode(nsSizeMode aMode) {
void nsWindow::Invalidate(const LayoutDeviceIntRect& aRect) {
if (!mNativeView || !mVisible) return;
- MOZ_RELEASE_ASSERT(
- GetLayerManager()->GetBackendType() != LayersBackend::LAYERS_WR,
- "Shouldn't need to invalidate with accelerated OMTC layers!");
-
[mNativeView setNeedsLayout];
[mNativeView setNeedsDisplayInRect:DevPixelsToUIKitPoints(
mBounds, BackingScaleFactor())];
}
-void nsWindow::SetFocus(Raise) {
+void nsWindow::SetFocus(Raise, mozilla::dom::CallerType) {
[[mNativeView window] makeKeyWindow];
[mNativeView becomeFirstResponder];
}
@@ -649,10 +901,16 @@ void nsWindow::ReportSizeModeEvent(nsSizeMode aMode) {
}
void nsWindow::ReportSizeEvent() {
+ LayoutDeviceIntRect innerBounds = GetClientBounds();
+
if (mWidgetListener) {
- LayoutDeviceIntRect innerBounds = GetClientBounds();
mWidgetListener->WindowResized(this, innerBounds.width, innerBounds.height);
}
+
+ if (mAttachedWidgetListener) {
+ mAttachedWidgetListener->WindowResized(this, innerBounds.width,
+ innerBounds.height);
+ }
}
LayoutDeviceIntRect nsWindow::GetScreenBounds() {
@@ -672,8 +930,8 @@ LayoutDeviceIntPoint nsWindow::WidgetToScreenOffset() {
temp = [nsAppShell::gWindow convertPoint:temp toWindow:nil];
}
- offset.x += temp.x;
- offset.y += temp.y;
+ offset.x += static_cast<int32_t>(temp.x);
+ offset.y += static_cast<int32_t>(temp.y);
return offset;
}
@@ -682,23 +940,63 @@ nsresult nsWindow::DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
nsEventStatus& aStatus) {
aStatus = nsEventStatus_eIgnore;
nsCOMPtr<nsIWidget> kungFuDeathGrip(aEvent->mWidget);
+ mozilla::Unused << kungFuDeathGrip; // Not used within this function
- if (mWidgetListener)
+ if (mAttachedWidgetListener) {
+ aStatus = mAttachedWidgetListener->HandleEvent(aEvent, mUseAttachedEvents);
+ } else if (mWidgetListener) {
aStatus = mWidgetListener->HandleEvent(aEvent, mUseAttachedEvents);
+ }
return NS_OK;
}
void nsWindow::SetInputContext(const InputContext& aContext,
const InputContextAction& aAction) {
- // TODO: actually show VKB
+ NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
+
+ const bool changingEnabledState =
+ aContext.IsInputAttributeChanged(mInputContext);
+
mInputContext = aContext;
+
+ if (IsVirtualKeyboardDisabled()) {
+ [mNativeView resignFirstResponder];
+ return;
+ }
+
+ [mNativeView becomeFirstResponder];
+
+ if (aAction.UserMightRequestOpenVKB() || changingEnabledState) {
+ // TODO(m_kato):
+ // It is unnecessary to call reloadInputViews with changingEnabledState if
+ // virtual keyboard is disappeared.
+ [mNativeView reloadInputViews];
+ }
+
+ NS_OBJC_END_TRY_IGNORE_BLOCK;
}
-mozilla::widget::InputContext nsWindow::GetInputContext() {
+widget::InputContext nsWindow::GetInputContext() {
+ if (!mTextInputHandler) {
+ InputContext context;
+ context.mIMEState.mEnabled = IMEEnabled::Disabled;
+ context.mIMEState.mOpen = IMEState::OPEN_STATE_NOT_SUPPORTED;
+ return context;
+ }
return mInputContext;
}
+widget::TextEventDispatcherListener*
+nsWindow::GetNativeTextEventDispatcherListener() {
+ return mTextInputHandler;
+}
+
+bool nsWindow::IsVirtualKeyboardDisabled() const {
+ return mInputContext.mIMEState.mEnabled == IMEEnabled::Disabled ||
+ mInputContext.mHTMLInputMode.EqualsLiteral("none");
+}
+
void nsWindow::SetBackgroundColor(const nscolor& aColor) {
mNativeView.backgroundColor = [UIColor colorWithRed:NS_GET_R(aColor)
green:NS_GET_G(aColor)